Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    goodboy
    @goodboy
    if you have an old caller then the impl's default is used
    Ronny Pfannschmidt
    @RonnyPfannschmidt
    if another pluging not under our controll doesnt have the handling for the default, it would break on a old caller
    in addition different plugins may have different defaults
    goodboy
    @goodboy

    if another pluging not under our controll doesnt have the handling for the default, it would break on a old caller

    What would be an example of this?

    if it doesn't have handling for the default why would it break under and old caller?
    Ronny Pfannschmidt
    @RonnyPfannschmidt
    the old caller doesnt pass the argument, the new impl expects it bam
    goodboy
    @goodboy
    right but if that impl does have a default then that would be used?
    Ronny Pfannschmidt
    @RonnyPfannschmidt
    yes, which begs the question - how do plugins keep the defaults in sync?
    goodboy
    @goodboy
    yes, indeed the money question
    Ronny Pfannschmidt
    @RonnyPfannschmidt
    hmm, screw it - i decided new hook names will be the way to go
    goodboy
    @goodboy
    @RonnyPfannschmidt :)
    occam's razor ;)
    Michal Konvalinka
    @dwich

    Hi, I'm trying to implement pluggy into my app. I went through the docs, read "toy example" and "complete example", tried my own example implementation and implemented pluggy into my app. I have a question if I understand PluginManager correctly. The "toy example" shows that in order to register plugins to host you have to have direct access to the PM instance. The "complete example" shows that plugin doesn't need to have direct access to PM instance, the PM is just in the host and will scan available python packages and load plugins from them. Is that right?

    My use case is somewhere in the middle - I'd like to register hooks from the plugin (not from host) via PM that I can instantiate using just the project_name. I was wondering - is there a way to use PM as a singleton / module variable / global variable so I can instantiate it just with the project_name anywhere in the code without having direct access to the PM instance that was created in the host app? When I read the docs, I thought it could be possible but I found out it's probably not.

    What I tried to achieve in the plugin code:

    import pluggy; pm = pluggy.PluginManager('my_app')
    # class MyPlugin1...; class MyPlugin2
    pm.register(MyPlugin1()); pm.register(MyPlugin2())
    # Now app (host) that uses "my_app" as a name for pluggy plugins, knows about my hooks.
    Ronny Pfannschmidt
    @RonnyPfannschmidt
    @dwich to me its not clear waht you are asking for at all
    Michal Konvalinka
    @dwich

    @RonnyPfannschmidt I would like to have a host app and extend it using plugins. In order to extend a host, plugins need an access to plugin manager instance and hookimpl from host and both (PM and hookimpl) need to be imported into plugin. My idea is - get PM instance and hookimpl in a similar way how python logging gets logger instance: mylogger = logging.getLogger('myapp')

    I wrote an example Gist here:
    https://gist.github.com/dwich/401e76aec27b832b1b1fe30f83816e11

    goodboy
    @goodboy
    @dwich at some level some code has to make the PM scan for plugins
    if you want plugins to be able to to register themselves then you need to define a hook which does this
    or you need to load plugins using the entry point system
    but still at some level the plugin manager needs to be called to do this in the host
    goodboy
    @goodboy
    your gist looks correct
    usually it's the host's responsibility to provide access to the PM
    so if you want a factory function for it then provide it in the host's api
    doing a read on how pytest does it is probably a good place to start
    particularly if you want plugins to be loaded by a host implicitly then consider using setuptools entry points
    Michal Konvalinka
    @dwich

    Thank you for explanation. If I understand it correctly, there are two ways how a plugin can be registered - 1) using direct access to PM or 2) using setuptools entrypoint.

    If I use the setuptools entrypoint, I need to name the python package as a plugin so the host can recognise it. I'm not developing primarily a plugin for host app so I don't want to name that python package as a plugin for that host.

    The only way left is to import and directly use PM instance which is what I would like to avoid in a long run, therefore I'm looking for similar way that python logging uses: pluggy= pluggy.get_pm('my_app'). If pluggy doesn't have this at the moment, I'll try to wrap it somehow. Thanks anyway, pluggy is useful package for me! :)

    goodboy
    @goodboy
    @dwich if this is an api you'd find useful we could consider it but honestly it would be such a light wrapper it's almost a bit superfluous
    goodboy
    @goodboy
    Like I mentioned before some code has to do plugin scanning and loading. Whether it's the plugin loading itself via a hook or something the host project scans by for default is up to you. If you only have one instance of a pm for your host then feel free to wrap it in a factory function like you've mentioned:
    import host_project
    
    pm = host_project.get_pm('my_app')
    pm.register(plugin)
    Tarcísio Fischer
    @tarcisiofischer

    I was told once that I cannot get a specific hook from a specific plugin.
    But today, I just found out the function get_plugin, so I get curious... It seems that I can indeed get a specific hook from a specific plugin by doing:

    pm.get_plugin('plugin_name').my_hook() I'm able to call a hook from a specific plugin.

    I was just wondering (and asking here): Is there any issue on doing this? Is it possible that I'm missing something, and this is not a good thing to do?

    Ronny Pfannschmidt
    @RonnyPfannschmidt
    You are just calling a method there comply outside of the pluggy mechanism
    If you have both use cases it tends to be better to have a better named method you invoke on the plugin and having the hook use that as well
    Tarcísio Fischer
    @tarcisiofischer
    In this case, I'm just trying to build a map of results that'll be consumed to check if hooks should indeed run.
    Think something like this (Although it is not exactly the use case, but seems a fairly simplier case to explain):
    plugins_that_should_run_specific_hook = []
    for plugin_name in available_plugin_names:
        if pm.get_plugin(plugin_name).hook_should_run(): # User defined hook that may return True or False, depending on the runtime configuration
            plugins_that_should_run_specific_hook.append(plugin_name)
    
    # (...)
    
    for plugin_name in plugins_that_should_run_specific_hook:
          pm.get_plugin(plugin_name).hook_run()
    Anyway, I don't understand why there is a method that does exactly what I need, but I should not use it (Despite the fact it is public to be used)
    (AFAIU, you are saying that I shouldn't use get_plugin(plugin_name).my_hook(), is that it?)
    Tarcísio Fischer
    @tarcisiofischer
    I'm open to suggestions :)
    Ronny Pfannschmidt
    @RonnyPfannschmidt
    That sounds like you wanted something similar to the fspath base plugin exclusion pytest uses for contests
    I'm still on a walk with the toddler, he just felt asleep
    Tarcísio Fischer
    @tarcisiofischer
    oh, no problem. Sorry for the noise
    Ronny Pfannschmidt
    @RonnyPfannschmidt
    Don't worry
    the subset_hook_caller can be called with removed plugins
    @tarcisiofischer are you working on a pytest plugin or something completely own
    its potentially a use case that should have better support in pytest
    eh pluggy
    Tarcísio Fischer
    @tarcisiofischer
    Its something completely own
    well
    tbf, get_plugin(plugin_name) works to me
    I was just wondering why it is not advisable to use it, taking in consideration it's on the public interface
    goodboy
    @goodboy
    @tarcisiofischer i think this is fine to use if you're doing a project that is just relying on pluggy
    though I feel like we have a better built in mechanism for what you're trying to do - but could be wrong
    i guess you're issue is that you have hooks that are dynamically determining whether or not they are fit to run on each hook call?
    in theory all this should be determined at register time