Skip to content

Commit ef943ba

Browse files
author
Brian Luft
committed
adds support for declaring options in subclasses, with overrides via inheritance
1 parent c2de099 commit ef943ba

File tree

2 files changed

+69
-4
lines changed

2 files changed

+69
-4
lines changed

pyflot/__init__.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,24 @@
1-
from functools import partial, wraps
1+
import collections
2+
from functools import partial
3+
import inspect
24
import json
35

46

7+
def update(d, u):
8+
"""
9+
Recursively update nested dicts
10+
11+
Credit: Alex Martelli
12+
"""
13+
for k, v in u.iteritems():
14+
if isinstance(v, collections.Mapping):
15+
r = update(d.get(k, {}), v)
16+
d[k] = r
17+
else:
18+
d[k] = u[k]
19+
return d
20+
21+
522
class MissingDataException(Exception):
623
"""Exception raised when a series does not contain
724
any data points"""
@@ -29,6 +46,15 @@ def __init__(self):
2946
self._series = []
3047
self._options = {}
3148

49+
#apply any options specified starting with the top
50+
#of the inheritance chain
51+
bases = list(inspect.getmro(self.__class__))
52+
bases.reverse()
53+
for base in bases:
54+
if hasattr(base, 'options'):
55+
update(self._options, base.options)
56+
57+
3258
@property
3359
def series_json(self):
3460
"""

tests/__init__.py

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,16 @@
1010
)
1111
S1, = SERIES
1212

13+
FAKE_NESTED_OPTIONS = {
14+
'level1': {
15+
'level2': {
16+
'a':1,
17+
'level3': {
18+
'b':2}}},
19+
'c':3}
20+
21+
22+
1323
class TestFlot(unittest.TestCase):
1424

1525
def setUp(self):
@@ -64,11 +74,40 @@ def test_series_json(self):
6474
self.assertEqual(json.dumps([series]), self.flot.series_json)
6575

6676
def test_series_with_label_json(self):
67-
"make sure series with label converts to JSON properly"
77+
"make sure series with label converts to JSON properly"
6878
series = {'data': S1, 'label': 'label1'}
6979
self.flot.add_series(S1, 'label1')
7080
self.assertEqual(json.dumps([series]), self.flot.series_json)
71-
72-
def test_options_json(self):
81+
82+
def test_empty_options_json(self):
7383
"make sure conversion to JSON works for default options"
7484
self.assertEqual("{}", self.flot.options_json)
85+
86+
def test_options(self):
87+
"make sure options are applied correctly for a Flot subclass"
88+
class MyFlot(Flot):
89+
options = FAKE_NESTED_OPTIONS
90+
91+
f = MyFlot()
92+
self.assertEqual(f._options, FAKE_NESTED_OPTIONS)
93+
self.assertEqual(f.options_json,
94+
json.dumps(FAKE_NESTED_OPTIONS))
95+
96+
def test_options_inheritance(self):
97+
"make sure options in an inheritance chain are applied correctly"
98+
class MyFlot(Flot):
99+
options = FAKE_NESTED_OPTIONS
100+
101+
class AnotherFlot(MyFlot):
102+
options = {
103+
'level1': {
104+
'd': 4,
105+
'level2': {
106+
'a': 10}}}
107+
108+
f = AnotherFlot()
109+
self.assertEqual(f._options,
110+
{'level1': {'d': 4, 'level2': {'a':10, 'level3': {'b':2}}}, 'c':3})
111+
#TODO will the dumped dict string match work across platforms?
112+
self.assertEqual(f.options_json,
113+
'{"level1": {"level2": {"a": 10, "level3": {"b": 2}}, "d": 4}, "c": 3}')

0 commit comments

Comments
 (0)