-
-
Notifications
You must be signed in to change notification settings - Fork 200
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
allow default json files in a .d directory #452
Conversation
traitlets/config/manager.py
Outdated
for path in sorted(paths): | ||
name, ext = os.path.splitext(path) | ||
abspath = os.path.join(directory, path) | ||
if ext == ".json" and name not in data: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why the name not in data
here? Shouldn't all files be loaded?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for that, leftover from refactoring the code. The idea is that the .json file overrride any values that are set in the .d directory files, but instead I just swapped the order (first read the directory, then read the .json).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps could do a discovery phase and then a load phase, and let bad configs not cause the whole stack to fail, a la:
from glob import glob
...
def get(self, section_name):
"""Retrieve the config data for the specified section.
Returns the data as a dictionary, or an empty dictionary if the file
doesn't exist.
"""
paths = [self.file_name(section_name)]
if self.read_directory:
pattern = os.path.join(self.directory(section_name), '*.json')
paths = sorted(glob(pattern)) + paths
data = {}
for path in paths:
try:
if os.path.isfile(path):
with io.open(path, encoding='utf-8') as f:
recursive_update(data, json.load(f))
except Exception as err:
self.log.error(
'Couldn\'t update %s configuration from %s: %s',
section_name, path, err)
return data
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, good idea. I think this is an artifact from a misunderstanding, i thought the 'dict' foo.d/bar.json would to into data['bar']. I'll update it.
Not sure if it should accept errors, since it would mean a bad config.
This is also implemented in #242, which applies to standard traitlets config instead of the JSONConfigManager used exclusively for extensions and frontend config. I realize that we have a bit of complication here. The BaseJSONConfigManager as it is used for nbconfig is not at all related to traitlets, and probably doesn't belong in the traitlets package. @blink1073 what do you think about whether this should be in traitlets, since it isn't related to traits at all? Should JupyterLab's extension loading live in jupyterlab instead? |
Didn't see #242. |
I think it should go in the |
💯 on getting this ready for some of the upcoming big releases. I guess I would prefer the whole shooting match of #242, but since discussion is happening here... On this PR, I like how all of the I guess it comes down to how the ordering should work. Given this (admittedly weird) file layout:
If each loader handled its own
vs the "big discovery" of #242 which i think would mean:
The py/json flipflop inside a configuration path due to file naming seems a bit counter to the Zen of Jupyter Config, but it's all pretty crazy at this point! |
The failed travis is an issue with pytest and python 3.3. The other versions do build. |
I'd say replace the py 3.3 test with a 3.6 one and update |
I think that makes sense, shall I do a separate PR for that? |
Yeah that sounds good, thanks! |
# {section_name}.json take precedence. | ||
# The idea behind this is that installing a Python package may | ||
# put a json file somewhere in the a .d directory, while the | ||
# .json file is probably a user configuration. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!
If #462 gets merged I can trigger travis. |
I've added some unittests assuming py.test, I hope that's fine. |
Yes, |
Great. I'm really looking forward to seeing this (or equivalent functionality) being release. It would mean it is possible that a |
The |
Ah, indeed, most widget use the post-link as well, but that prevents noarch. So you can also use this PR for enabling the serverextension? |
I believe so, using {
"NotebookApp": {
"nbserver_extensions": {
"jupyterlab": true
}
} Are we not merging down to that level? |
Yes, I can confirm that works. |
Awesome! |
Actually, we had said earlier in the thread that the class should probably move to |
I don't. How do you want to not break old code, import the BaseJSONConfigManager from the manager.py file with a deprecation warning? Or just leave it untouched here? |
Or, we get this merged, then consider moving it. Otherwise I'm afraid this functionality wil never get out. |
I think we should be able to get a Notebook 5.3 out with this in it by the end of this month. Looking at the open issues for 5.0 in this repo I am less confident in a release. @minrk, thoughts? |
traitlets 5.0 is not very close to release, and without a lot of help, it's not going to be soon. There are way too many much higher priority things to deal with right now. I would encourage you as much as possible to take non-traitlets-specific config (e.g. jupyterlab extensions) entirely out of the traitlets repo. |
Ok, we can close this then (continued here jupyter/notebook#3116) |
@minrk, none of this is specific to JupyterLab. In fact, JupyterLab extensions use an entirely different mechanism. This is to make it easier for notebook and server extensions. |
The reason JupyterLab came up in this conversation is that it uses a server extension. |
This allows to have in addition to a single
foobar.json
file afoobar.d
directory, where all '*.json' files will be read, and used as default values.Would make implementing jupyter/notebook#2824 trivial.