Make ExtensionHooks easier to implement and manage.

Review Request #7680 — Created Oct. 7, 2015 and submitted — Latest diff uploaded

Information

Djblets
release-0.10.x

Reviewers

ExtensionHooks have always been pretty simple. Constructing them will
initialize them, shutting down will permanently destroy them, and
subclasses only needed to override __init__() and shutdown(). This was
almost too simple.

Once destroyed, a hook had to be re-constructed in order to be
re-enabled, invalidating any signal connections that may exist or other
registered data. Extensions that needed finer-grained state management
had to do it entirely within the hook through its own custom
enabled/disabled states, which still left them initialized and
registered on the extension.

This change improves this in a couple key ways. First, initialization
can now live in initialize(), which does not need to call the parent
method (unless inheriting from another ExtensionHook that defines
initialize()). The shutdown code in shutdown() no longer needs to call
the parent method either.

ExtensionHooks can be disabled by calling disable_hook(), and then
re-enabled (with new state) by calling enable_hook(). The instance will
remain around, but the hook's registration and state will be properly
handled. The hook can also be instantiated with start_enabled=False to
create the hook instance without enabling it, allowing the extension to
do that later in its process.

Along with all this, I've fleshed out the docs quite a bit.

Djblets and Review Board unit tests pass.