Publish.utils.collect bug or misleading docs


I’m having an issue where I’m calling Publish.utils.collect and passing a selection of plugins that I want it to consider.
instances = pyblish.util.collect(plugins=pluginsToUse)
(The pluginsToUse variable contains a list of plugins gathered by the but then filtered down to what I want.)

However it is returning me instances from all plugins in the registered path not just the ones I passed, so the plugins kwarg seems to have no effect.It seems that this should be possible according to the following page:

If I made the following change to the pyblish util module, then it works the way I want it to, but obviously I don’t want to modify the Pyblish code:
line num: 134

def _convenience(order, *args, **kwargs):
    plugins = kwargs.get("plugins")
    if not plugins:
        plugins = [p for p in
                   if p.order < order]```

    args = list(args)
    if len(args) > 1:
        args[1] = plugins
        kwargs["plugins"] = plugins
    return publish(*args, **kwargs)``

Is this a bug or is it behaving normally?


Thanks for reporting this @Philip_Scadding, it sounds like you’re using it right, but aren’t getting expected results. I’ll take a closer look.

We’ve seen this too and worked around it. Should have reported it though :slight_smile:

Oh, but please do! If you can commit this to your own fork of the project, and submit a pull-request, we could have this fixed with flying colors.

Let me know if you need any help with that, and welcome to the project!

Feel free to reference this issue in the commit message.

OK thanks Marcus, I think have created a pull request, I must admit I’ve only done that a couple of times before.
I realise that my “fix” wasn’t quite right.
The list of plugins provided by the kwargs should also be filtered by order, so even if you pass a plugin that has an order in the range of validate it shouldn’t run if you have passed it to collect.

code as it now stands.

def _convenience(order, *args, **kwargs):
    plugins = kwargs.get("plugins") if "plugins" in kwargs else
    plugins = [p for p in plugins
               if p.order < order]

    args = list(args)
    if len(args) > 1:
        args[1] = plugins
        kwargs["plugins"] = plugins
    return publish(*args, **kwargs)

That’s quite allright, @Philip_Scadding, this is well enough to get the ball rolling.

I would also admit that the code - with *args and **kwargs in this way - isn’t terribly pretty. It stems from backwards compatibility as this module has gone through quite a bit of change since it was first introduced.

I’d be happy to continue from here, I think this is a good opportunity for some refactoring of this module, and to introduce a series of tests such that this doesn’t happen again.

Thanks for this!