New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Question about hook call order #250
Comments
Hey @tlambert03. The call time order is LIFO relative to registration as mentioned in the docs. So if you want a specific order currently you'd have to register hooks last to first in order to get that order when invoking. We don't have a public API for ordering currently but it might be something useful? I've thought about offering a generator API which allows for controlling which hooks are invoked by yielding them in the order desired - this might play with #50 potentially. If you're concerned about order it may be more sensible to build a small *ordered hook protocol" much like Hope this helps! |
Thanks for the response! Definitely helpful to get your thoughts on this. I think my case is along the lines of #50 (though actually... after reading that, I'm now slightly confused about my understanding of the I'm contemplating using pluggy as the plugin manager for napari, a multidimensional image/data viewer. The first hook we're discussing would be an file reader plugin, where plugins can add support for different file formats. Plugins would implement a hook that accepts a filepath (
it's not immediately clear how to use an ordered hook protocol to allow the end user to reoderd the hooks, while also using the (sorry accidentally hit the close button). |
Hey @tlambert03 , @goodboy Maybe the next kind of hookimpl API could be helpful: from pluggy import PluginManager, HookimplMarker
hookimpl = HookimplMarker("myproject")
class Plugin1:
@hookimpl(before=['Plugin3'])
def myhook(self, args):
return 1
class Plugin2:
@hookimpl(before=['Plugin1'])
def myhook(self, args):
return 2
class Plugin3:
@hookimpl(after=['Plugin2'])
def myhook(self, args):
return 3
pm = PluginManager("myproject")
pm.register(Plugin1())
pm.register(Plugin2())
pm.register(Plugin3())
assert pm.hook.myhook(args=()) == [2, 1, 3] Implementation could be pretty easy based on a projection of partially ordered set to strict order. Tryfirst/trylast also could be in place but have to be less strict than the defined order. Please share your thoughts. |
Having topologies is a long desired feature, what's lacking is a actually sensible implementation |
What about introducing public API to allow subclasses of For example, I'm working on being able to execute plugins that have dependencies on other plugins. Right now I have a subclass of Example: class DagPluginManager(PluginManager):
def __init__(self, project_name):
super().__init__(project_name)
self._dag = SimpleDirectedGraph()
self._inner_hookexec = self._dag_exec
def _dag_exec(self, _, hook_impls, caller_kwargs, __):
# execute plugins in custom order based on graph Obviously this approach is pretty fragile since it relies on internal API and some implementation details, which is why I want to help implement something that isn't fragile. Wdyt? |
Having a dag of plugins both for conditional and for unconditional activation and ordering is a long wanted feature Unfortunately there is a number of caveats and not enough time Im happy to provide input, but I can't work on it myself anytime soon |
Rather than overhauling |
instead of replacing multicall, i would suggest to have something that orders the items added baed on a better topology right now we have tryfirst/trylast and the hookwrapper vs normal hook order whats needed as well would be to have something like before/after/requires to add the extra items |
❓ Question
I'm new to pluggy, and trying to decide whether to use it as the plugin manager in a project I work on (looks great!). One of the main things I find myself wanting more control over is the exact order in which implementations of a specific hook are called (beyond simply registering an
@hookimpl
withtrylast
ortryfirst
). Specifically, I would ultimately like to let the end user reorder plugin implementations of specific hooks after plugin registration.To accomplish that I find myself tempted to write methods to reorder
_HookCaller._nonwrappers
... but because that is a private attribute, I am hesitant to do so and wonder if I am maybe misunderstanding a fundamental design principle here. Is that a valid approach, or discouraged?The text was updated successfully, but these errors were encountered: