Skip to content

Reusable hooking mechanism for Python code #3393

@nvaccessAuto

Description

@nvaccessAuto

Reported by jteh on 2013-08-02 07:20
We need to come up with a simple, reusable hooking mechanism so code can register hooks for various tasks. For example, add-ons may wish to tweak speech output or respond to configuration profile switches.

There are existing frameworks for this like PubSub. However, from what I've been able to find, they can publish and subscribe, but they can't really synchronously hook; e.g. changing speech output. Also, they tend to use arbitrary text strings and I tend to think some sort of object to register with for each hook is nicer.

Requirements:

  1. Simple.
  2. Synchronous.
  3. A hook should be able to take arguments, return values and maybe raise exceptions.
  4. Depending on the hook point, code should perhaps be able to decide to stop executing later hooks.
  5. Hooks need to be possible in both modules and class instances.
  6. It'd be nice if code wanting to hook didn't have to explicitly register and unregister hooks. For example, if a hooking instance dies, the hook dies. This avoids boilerplate and stupid errors.

The easiest implementation is to have an object for each hook which has methods to register and unregister hooks. However, that fails requirement 6.

Another option is to have a decorator which you use to implement a hook; e.g.

@config.ProfileSwitchListener
def onConfigProfileSwitch():
 ...

Unfortunately, doing this in a way that satisfies both requirements 5 and 6 is pretty tricky. I haven't come up with a way yet.

Metadata

Metadata

Assignees

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions