Skip to content

[ISSUE] Merge proposal #2

@loehnertj

Description

@loehnertj

Description

Hello TechnoBro, I have a maybe somewhat unusual proposal to make.

Some time ago, I wrote an adhoc event library for a GUI toolkit I created. Long story short, it went through some iterations and eventually came about to look much like Eventic, minus the async support, plus some other goodies.

Since it proved useful on its own, I now thought about splitting it out as its own package. While searching for a name, stumbled upon your project. Now, I could just ignore it and go ahead with my own, but I thought maybe it's better to join forces and make one great typed event library instead of two good ones. :-)

You can look at my module here: https://github.com/loehnertj/ascii_designer/blob/master/src/ascii_designer/event.py

I already took the effort of looking through both modules to make a rough comparison. Both do the same basic task of turning a method or function into an event forwarder that can be subscribed to. Funnily enough, the overall code structure is nearly the same. However you have some features I don't have (async support, with-subscription, .once) and I have some you don't have. Categorizing a bit, these are:


Docs, nonbreaking changes

  • Extensive docstring, going into some particulars that I didn't see covered in your docs at first glance.
  • using functool.update_wrapper for improved introspetion of decorated function (copy docstring + signature e.g. for sphinx)

Stricter requirements for event signature, runtime checking

  • upon invoke, calls the wrapped (empty) function to make sure that call has right signature
  • event arguments must be marked positional-only or keyword-only, they cannot be ambigous. (opt-in, "strict mode") - The reasoning is that the subscriber otherwise cannot know how the emitter will pass the argument - by-position or by-name - this check enforces certainty.
  • Forbid arguments with default values - again because meaning of these would not be well-defined. Applies to event signature, not to handler functions.
  • explicit convention for self argument (for method). In the current implementation it's forbidden, however with today's experience I'd rather make it mandatory but ignored, since this plays better with typecheckers.
  • All these rules are checked upon construction of Event, using inspect.signature.

Configurable exception policy

Requiring exception handling in subscribers is bad, because people (me included) keep forgetting it. In my version, exceptions in handlers are caught and handled. Exception policy can be configured by a decorator parameter @event(exceptions=...):

  • "log" (default) emits a logging.error message with the traceback.
  • "print" prints the exception (using traceback.print_exception).
  • "raise" raises any exception immediately. No subsequent listeners are
    called. Event Invoker must be prepared for exceptions.
  • "group" calls all listeners, then raises an ExceptionGroup if any
    failed. The error is always an ExceptionGroup, even in case of a single
    error. Event invoker must catch it.
  • (... note how there is no "silently discard it" option... ;-))

Canceling processing

Any event handler may raise a special CancelEvent exception in order to stop handling of the event at this point.


I think it would be cool to take all of this over into Eventic, to make it into something really great and not clutter PyPI more than necessary. :-) I'm also ready to do all the work on this. Since both modules are structured almost identical, I hope it should'nt be to hard, and mostly boil down to thoroughly unittesting everything.

However before starting to to churn out PR's, I'd rather hereby ask first,if you are interested in cooperating on that, or if you rather wouldn't. The latter is also OK. In this case I won't bother you further and publish my library separately. What do you say?

Best regards, Johannes

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions