Make core extendable by making classes and initializations configurable by txomon · Pull Request #938 · pallets/click
I'm disappointed that I haven't been able to get time to try other versions/variants of this which I'm interested in exploring. C'est la vie, but sorry all the same.
What I actually care about and what can be done to push this forward:
- Should this
Comand.command_classbe an instance attribute (Command.command_class) rather than a class attribute? - What does usage look like? Can we add some test-cases for this functionality which demonstrate custom Context, custom Command, and custom MultiCommand or Group classes? That would show what the interface is and how to use it.
- I'd want narrative docs long-term. But! I think it's a bit much to demand them for an initial version. I'd like to know enough to write such narrative docs myself.
- Can this usage be supported by the
click.commandandclick.groupdecorators? e.g.click.command(cls=MyCustomClass)?
The basic issue that I'm hung up on is that it seems all of the usage is predicated on creating a class heirarchy which mimics the click classes -- you need CustomCmd(Command), CustomMultiCmd(MultiCommand), and CustomGroup(Group) each of which sets command_class = CustomCmd, right? Or am I mistaken about that?
And you get in MRO-related trouble quickly if you try to setup CustomMultiCmd(CustomCmd, MultiCommand) because you may want to override behavior in CustomCmd which you would like CustomMultiCommand to inherit from MultiCommand.
Could we just make command_class an instance attribute, rather than a class attribute, so that I can have
@click.group('mycmd', command_class=CustomCommandClass) def cli(): pass @cli.command('foocmd', cls=CustomCommandClass) def foo(): pass # by omitting `command_class` from `bar` and `cls` from `baz`, can we sanely allow # `mycmd foo` to have one behavior, and `mycmd bar baz` to have another? @cli.group('bargroup', cls=CustomGroupClass) def bar(): pass @bar.command('baz') def baz(): pass
?
Where/how/why does that break down?
If the intent is that users modify global state by setting Command.command_class = CustomCmd, I would argue very strongly that that's bad interface/API design. So I don't want that to be the answer, and if that's the current plan, then we should figure out better usage and then what changes need to be made to support it.
A lot of this boils down to "I'm struggling to see what usage looks like."
So some example of usage would go a long way, I think. Ideally in the form of a test case -- and if it can't be put into a test case, please explain why, because that may be a sign of a problem.