mirror of
https://github.com/jupyter/notebook.git
synced 2024-12-27 04:20:22 +08:00
Apply JSON config updates recursively
This commit is contained in:
parent
6786f86c63
commit
425d5a1c02
@ -9,6 +9,25 @@ from tornado import web
|
||||
|
||||
from ...base.handlers import IPythonHandler, json_errors
|
||||
|
||||
def recursive_update(target, new):
|
||||
"""Recursively update one dictionary using another.
|
||||
|
||||
None values will delete their keys.
|
||||
"""
|
||||
for k, v in new.items():
|
||||
if isinstance(v, dict):
|
||||
if k not in target:
|
||||
target[k] = {}
|
||||
recursive_update(target[k], v)
|
||||
if not target[k]:
|
||||
# Prune empty subdicts
|
||||
del target[k]
|
||||
|
||||
elif v is None:
|
||||
target.pop(k, None)
|
||||
|
||||
else:
|
||||
target[k] = v
|
||||
|
||||
class ConfigHandler(IPythonHandler):
|
||||
SUPPORTED_METHODS = ('GET', 'PUT', 'PATCH')
|
||||
@ -46,11 +65,8 @@ class ConfigHandler(IPythonHandler):
|
||||
else:
|
||||
section = {}
|
||||
|
||||
for k, v in self.get_json_body().items():
|
||||
if v is None:
|
||||
section.pop(k, None)
|
||||
else:
|
||||
section[k] = v
|
||||
update = self.get_json_body()
|
||||
recursive_update(section, update)
|
||||
|
||||
with io.open(filename, 'w', encoding='utf-8') as f:
|
||||
json.dump(section, f)
|
||||
|
@ -1,5 +1,5 @@
|
||||
# coding: utf-8
|
||||
"""Test the kernel specs webservice API."""
|
||||
"""Test the config webservice API."""
|
||||
|
||||
import json
|
||||
|
||||
@ -32,7 +32,7 @@ class ConfigAPI(object):
|
||||
return self._req('PATCH', section, json.dumps(values))
|
||||
|
||||
class APITest(NotebookTestBase):
|
||||
"""Test the kernelspec web service API"""
|
||||
"""Test the config web service API"""
|
||||
def setUp(self):
|
||||
self.config_api = ConfigAPI(self.base_url())
|
||||
|
||||
@ -46,18 +46,22 @@ class APITest(NotebookTestBase):
|
||||
self.assertEqual(r.json(), sample)
|
||||
|
||||
def test_modify(self):
|
||||
sample = {'foo': 'bar', 'baz': 73}
|
||||
sample = {'foo': 'bar', 'baz': 73,
|
||||
'sub': {'a': 6, 'b': 7}, 'sub2': {'c': 8}}
|
||||
self.config_api.set('example', sample)
|
||||
|
||||
r = self.config_api.modify('example', {'foo': None, # should delete foo
|
||||
'baz': 75,
|
||||
'wib': [1,2,3],
|
||||
'sub': {'a': 8, 'b': None, 'd': 9},
|
||||
'sub2': {'c': None} # should delete sub2
|
||||
})
|
||||
self.assertEqual(r.status_code, 204)
|
||||
|
||||
r = self.config_api.get('example')
|
||||
self.assertEqual(r.status_code, 200)
|
||||
self.assertEqual(r.json(), {'baz': 75, 'wib': [1,2,3]})
|
||||
self.assertEqual(r.json(), {'baz': 75, 'wib': [1,2,3],
|
||||
'sub': {'a': 8, 'd': 9}})
|
||||
|
||||
def test_get_unknown(self):
|
||||
# We should get an empty config dictionary instead of a 404
|
||||
|
Loading…
Reference in New Issue
Block a user