-
-
Notifications
You must be signed in to change notification settings - Fork 203
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
Cannot instantiate a subcommand if it inherits the same baseclass with a parent-cmd #474
Comments
...conflict when cmds inherit same class!
This seems like the right behavior. You have instantiated two singleton instances in the same processes without clearing the singleton. That rightly results in an error because the application singleton must be cleared before you attempt to instantiate another one. The |
The behavior of the It's the sub-command behavior that does not make sense. Clearing singleton before launching each command, cancels the whole purpose of a singletons. |
That's untrue. If subcommand didn't work, it wouldn't be how most Jupyter and IPython commands are implemented today. A subcommand is an alternate application that should be instantiated as the singleton, e.g. |
I see your point: But i'm not launching 2 sub-commands either. There has to be a way out of this, than incidentally forbidding parent & sub-commands to inherit a common baseclass. |
I realized that the title of this issue might have been a little misleading. |
There is. We don't forbid subcommands from having a common base class, and IPython subcommands generally do share a base class (BaseIPythonApp). Here's a rough simplification of how IPython subcommands are launched: from traitlets.config import Application
from traitlets import Unicode
class MyBaseApp(Application):
common_config = Unicode(config=True)
class MySubApp(MyBaseApp):
def start(self):
print("subapp!")
class MyMainApp(MyBaseApp):
subcommands = {
'subapp': (
MySubApp,
"launch subapp",
),
}
def start(self):
if self.subapp is not None:
return self.subapp.start()
print("main!")
if __name__ == '__main__':
MyMainApp.launch_instance(['subapp']) The instance on MyMainApp is explicitly cleared when initializing the subcommand's Application object to avoid this kind of conflict. The subapp takes over the global instance. |
On IPython the above code still raises:
|
I noticed that the same problem is reported on my OP, related to But if run it through plain python REPL i got this exception:
So my initial posting still holds. |
Calling One change that probably does make sense, and should fix both cases: subapp uses |
Problem
As currently implemented (till 5.x), subapps are actually constructed in
ìnitialize_subcommands()
by invokingSingletonConfigurable.instance()
. And that makes sense, to make it easily to locate a command instance, regardless of its position in the "command chain".But since this
SingletonConfigurable.instance()
class-method store the new instance to all baseclasses, this leads easily to clashes in case 2 subcommands share the same baseclass (which is always the case, sinceApplication
is a common parent).Actually from within IPython you cannot even use any sub-command at all:
To signify the problem, here is a trivial example that fails even in pure python REPL:
Anothe side-effect is that test-cases on sub-commands require spurious
clear_instances()
invocations to work (seetest_application.test_subcommands_instanciation()
).Possible Mitigations
Either:
initialize_subcommands()
not to useSingleton.instance()
(or use a new method instead?), orSingleton.instance()
andclear_instances()
not to set/clear newly instanciated app to allmro()
classe-attributes.I would prefer (2), assuming there is not some blocker reason for why
instance()
behaves like that.Of course it might be that my understanding is totally broken here.
The text was updated successfully, but these errors were encountered: