A story about configuration
Steps to handling traits during a "Transition and Deprecation Period".
- If the argument is prefixed with
ServerApp
, pass this trait toServerApp
. - If the argument is prefixed with
NotebookApp
,- If the argument is a trait of
NotebookApp
andServerApp
:- Raise a warning—for the extension developers—that there's redundant traits.
- Pass trait to
NotebookApp
.
- If the argument is a trait of just
ServerApp
only (i.e. the trait moved fromNotebookApp
toServerApp
):- Raise a
"DeprecationWarning: this trait has moved"
for the user. - Migrate/write the trait to a new config file if it came from a config file.
- Pass trait to
ServerApp
.
- Raise a
- If the argument is a trait of
NotebookApp
only, pass trait toNotebookApp
. - If the argument is not found in any object, raise a
"Trait not found."
error.
- If the argument is a trait of
- If the argument is prefixed with
ExtensionApp
:- If the argument is a trait of
ExtensionApp
and eitherNotebookApp
orServerApp
,- Raise a warning—for the extension developers—that there's redundant traits.
- Pass trait to Step 2 above.
- If the argument is not a trait of
ExtensionApp
, but is a trait of eitherNotebookApp
orServerApp
(i.e. the trait moved fromExtensionApp
toNotebookApp
/ServerApp
):- Raise a
"DeprecationWarning: this trait has moved"
for the user. - Migrate/write the trait to a new config file if it came from a config file.
- Pass trait to Step 2 above.
- Raise a
- If the argument is not a trait of
ExtensionApp
and not a trait of eitherNotebookApp
orServerApp
, raise a"Trait not found."
error.
- If the argument is a trait of
Valid for traitlets 4.3.x
Here's a snapshot of how JupyterApp's are initialized. The order of operations we care about goes as follows:
argv
is parsed.parse_command_line()
is called andargv
is passed to this method.load_config_file()
is called to load traits from various files.
# Pulled from Traitlets 4.3.2
@catch_config_error
def initialize(self, argv=None):
# don't hook up crash handler before parsing command-line
if argv is None:
argv = sys.argv[1:]
if argv:
subc = self._find_subcommand(argv[0])
if subc:
self.argv = argv
self.subcommand = subc
return
self.parse_command_line(argv)
cl_config = deepcopy(self.config)
if self._dispatching:
return
self.migrate_config()
self.load_config_file()
# enforce cl-opts override configfile opts:
self.update_config(cl_config)
if allow_insecure_writes:
issue_insecure_write_warning()