summaryrefslogtreecommitdiff
path: root/templates
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2020-09-20 09:10:45 +0300
committerLars Wirzenius <liw@liw.fi>2020-09-20 09:28:54 +0300
commit4e6bf4a43bcbaef46beb685d505aab3a657d1483 (patch)
tree8a1bbb998e50e8fee5a6143354b46e628375f1d6 /templates
parent5af231e686849eb05115cd627f935ac674321dad (diff)
downloadsubplot-4e6bf4a43bcbaef46beb685d505aab3a657d1483.tar.gz
feat: Context classes can declare namespaces for groups of values
This will enable easier separation of values stored in the context by different Subplot libraries, with less risk of accidental name clashes.
Diffstat (limited to 'templates')
-rw-r--r--templates/python/context.py30
-rw-r--r--templates/python/context_tests.py53
2 files changed, 83 insertions, 0 deletions
diff --git a/templates/python/context.py b/templates/python/context.py
index fac49de..f7af624 100644
--- a/templates/python/context.py
+++ b/templates/python/context.py
@@ -5,6 +5,7 @@ import logging
class Context:
def __init__(self):
self._vars = {}
+ self._ns = {}
def as_dict(self):
return dict(self._vars)
@@ -27,3 +28,32 @@ class Context:
def __repr__(self):
return repr(self._vars)
+
+ def declare(self, name):
+ if name not in self._ns:
+ self._ns[name] = NameSpace(name)
+ return self._ns[name]
+
+
+class NameSpace:
+ def __init__(self, name):
+ self.name = name
+ self._dict = {}
+
+ def as_dict(self):
+ return dict(self._dict)
+
+ def get(self, key, default=None):
+ return self._dict.get(key, default)
+
+ def __setitem__(self, key, value):
+ self._dict[key] = value
+
+ def __getitem__(self, key):
+ return self._dict[key]
+
+ def __contains__(self, key):
+ return key in self._dict
+
+ def __delitem__(self, key):
+ del self._dict[key]
diff --git a/templates/python/context_tests.py b/templates/python/context_tests.py
index c358f6e..ff4e558 100644
--- a/templates/python/context_tests.py
+++ b/templates/python/context_tests.py
@@ -52,4 +52,57 @@ class ContextTests(unittest.TestCase):
self.assertTrue("bar" in repr(ctx))
+class ContextNamepaceTests(unittest.TestCase):
+ def test_explicit_namespaces_are_empty_dicts_initially(self):
+ ctx = Context()
+ ns = ctx.declare("foo")
+ self.assertEqual(ns.as_dict(), {})
+
+ def test_declaring_explicit_namespaces_is_idempotent(self):
+ ctx = Context()
+ ns1 = ctx.declare("foo")
+ ns2 = ctx.declare("foo")
+ self.assertEqual(id(ns1), id(ns2))
+
+ def test_knows_their_name(self):
+ ctx = Context()
+ ns = ctx.declare("foo")
+ self.assertEqual(ns.name, "foo")
+
+ def test_sets_key(self):
+ ctx = Context()
+ ns = ctx.declare("foo")
+ ns["bar"] = "yo"
+ self.assertEqual(ns["bar"], "yo")
+
+ def test_gets(self):
+ ctx = Context()
+ ns = ctx.declare("foo")
+ ns["bar"] = "yo"
+ self.assertEqual(ns.get("bar", "argh"), "yo")
+
+ def test_gets_with_default(self):
+ ctx = Context()
+ ns = ctx.declare("foo")
+ self.assertEqual(ns.get("bar", "yo"), "yo")
+
+ def test_does_not_contain_key(self):
+ ctx = Context()
+ ns = ctx.declare("foo")
+ self.assertFalse("bar" in ns)
+
+ def test_contains_key(self):
+ ctx = Context()
+ ns = ctx.declare("foo")
+ ns["bar"] = "yo"
+ self.assertTrue("bar" in ns)
+
+ def test_deletes(self):
+ ctx = Context()
+ ns = ctx.declare("foo")
+ ns["bar"] = "yo"
+ del ns["bar"]
+ self.assertFalse("bar" in ns)
+
+
unittest.main()