Skip to content

Commit

Permalink
properly merge nested dicts
Browse files Browse the repository at this point in the history
  • Loading branch information
thraxil committed May 4, 2016
1 parent 53a3d24 commit 76891ed
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 7 deletions.
34 changes: 27 additions & 7 deletions expvar/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import inspect
import json


from django.conf import settings
from django.http import HttpResponse
from django.views.generic import View
Expand All @@ -12,16 +11,36 @@

def run_single_class(name, obj):
if not issubclass(obj, ExpVar):
return dict()
return []
if name == "ExpVar":
# skip the parent class
return dict()
return []
c = obj()
return {c.get_name(): c.value()}
name = c.get_name()
value = c.value()
evars = []
if isinstance(value, dict):
for k, v in value.items():
evars.append(([name, k], v))
else:
evars = [([name], value)]
return evars


def insert_nested_key(keys, value, d):
current = d
for k in keys[:-1]:
if k in current:
current = current[k]
else:
current[k] = dict()
current = current[k]
current[keys[-1]] = value
return d


def load_expvars_from_app(app):
d = dict()
d = []
a = None
try:
a = importlib.import_module("{}.vars".format(app))
Expand All @@ -30,7 +49,7 @@ def load_expvars_from_app(app):
pass
if a is not None:
for name, obj in inspect.getmembers(a, inspect.isclass):
d.update(run_single_class(name, obj))
d.extend(run_single_class(name, obj))
return d


Expand All @@ -39,7 +58,8 @@ def get(self, request):
d = dict()
for app in settings.INSTALLED_APPS:
appvars = load_expvars_from_app(app)
d.update(appvars)
for keys, v in appvars:
d = insert_nested_key(keys, v, d)
return HttpResponse(
json.dumps(d),
content_type="application/json",
Expand Down
10 changes: 10 additions & 0 deletions testapp/main/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,13 @@ def test_main_expvar(self):
d = json.loads(smart_str(r.content))
self.assertIn('example1', d)
self.assertEqual(d['example1'], 42)


class ExtendTest(TestCase):
def test_memory(self):
r = self.client.get(reverse('expvar'))
d = json.loads(smart_str(r.content))
self.assertIn('memory', d)
m = d['memory']
self.assertIn('New', m)
self.assertEqual(m['New'], 78)
7 changes: 7 additions & 0 deletions testapp/main/vars.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ class PlainExpVar(expvar.ExpVar):
name = "plain"


class ExtendMemory(expvar.ExpVar):
name = "memory"

def value(self):
return {"New": 78}


class Other(object):
""" this one exists to make sure it doesn't barf on a
non-ExpVar object """
Expand Down

0 comments on commit 76891ed

Please sign in to comment.