summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorBarry Warsaw <barry@python.org>2012-06-03 20:18:47 (GMT)
committerBarry Warsaw <barry@python.org>2012-06-03 20:18:47 (GMT)
commit409da157d7ff2a49892e20a94a3fc83475845d22 (patch)
tree734314ff314990b3f3b9bb6f8de2e2f4ee0b54dc /Lib
parent82ffabdfa4de985690c76fd7498a77e9604e1747 (diff)
downloadcpython-409da157d7ff2a49892e20a94a3fc83475845d22.zip
cpython-409da157d7ff2a49892e20a94a3fc83475845d22.tar.gz
cpython-409da157d7ff2a49892e20a94a3fc83475845d22.tar.bz2
Eric Snow's implementation of PEP 421.
Issue 14673: Add sys.implementation
Diffstat (limited to 'Lib')
-rw-r--r--Lib/test/test_sys.py18
-rw-r--r--Lib/test/test_types.py143
-rw-r--r--Lib/types.py1
3 files changed, 161 insertions, 1 deletions
diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py
index b024d9a..a9c3616 100644
--- a/Lib/test/test_sys.py
+++ b/Lib/test/test_sys.py
@@ -581,6 +581,24 @@ class SysModuleTest(unittest.TestCase):
expected = None
self.check_fsencoding(fs_encoding, expected)
+ def test_implementation(self):
+ # This test applies to all implementations equally.
+
+ levels = {'alpha': 0xA, 'beta': 0xB, 'candidate': 0xC, 'release': 0xF}
+
+ self.assertTrue(hasattr(sys.implementation, 'name'))
+ self.assertTrue(hasattr(sys.implementation, 'version'))
+ self.assertTrue(hasattr(sys.implementation, 'hexversion'))
+ self.assertTrue(hasattr(sys.implementation, 'cache_tag'))
+
+ version = sys.implementation.version
+ self.assertEqual(version[:2], (version.major, version.minor))
+
+ hexversion = (version.major << 24 | version.minor << 16 |
+ version.micro << 8 | levels[version.releaselevel] << 4 |
+ version.serial << 0)
+ self.assertEqual(sys.implementation.hexversion, hexversion)
+
class SizeofTest(unittest.TestCase):
diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py
index 51b594c..31ebd9c 100644
--- a/Lib/test/test_types.py
+++ b/Lib/test/test_types.py
@@ -996,8 +996,149 @@ class ClassCreationTests(unittest.TestCase):
X = types.new_class("X", (int(), C))
+class SimpleNamespaceTests(unittest.TestCase):
+
+ def test_constructor(self):
+ ns1 = types.SimpleNamespace()
+ ns2 = types.SimpleNamespace(x=1, y=2)
+ ns3 = types.SimpleNamespace(**dict(x=1, y=2))
+
+ with self.assertRaises(TypeError):
+ types.SimpleNamespace(1, 2, 3)
+
+ self.assertEqual(len(ns1.__dict__), 0)
+ self.assertEqual(vars(ns1), {})
+ self.assertEqual(len(ns2.__dict__), 2)
+ self.assertEqual(vars(ns2), {'y': 2, 'x': 1})
+ self.assertEqual(len(ns3.__dict__), 2)
+ self.assertEqual(vars(ns3), {'y': 2, 'x': 1})
+
+ def test_unbound(self):
+ ns1 = vars(types.SimpleNamespace())
+ ns2 = vars(types.SimpleNamespace(x=1, y=2))
+
+ self.assertEqual(ns1, {})
+ self.assertEqual(ns2, {'y': 2, 'x': 1})
+
+ def test_underlying_dict(self):
+ ns1 = types.SimpleNamespace()
+ ns2 = types.SimpleNamespace(x=1, y=2)
+ ns3 = types.SimpleNamespace(a=True, b=False)
+ mapping = ns3.__dict__
+ del ns3
+
+ self.assertEqual(ns1.__dict__, {})
+ self.assertEqual(ns2.__dict__, {'y': 2, 'x': 1})
+ self.assertEqual(mapping, dict(a=True, b=False))
+
+ def test_attrget(self):
+ ns = types.SimpleNamespace(x=1, y=2, w=3)
+
+ self.assertEqual(ns.x, 1)
+ self.assertEqual(ns.y, 2)
+ self.assertEqual(ns.w, 3)
+ with self.assertRaises(AttributeError):
+ ns.z
+
+ def test_attrset(self):
+ ns1 = types.SimpleNamespace()
+ ns2 = types.SimpleNamespace(x=1, y=2, w=3)
+ ns1.a = 'spam'
+ ns1.b = 'ham'
+ ns2.z = 4
+ ns2.theta = None
+
+ self.assertEqual(ns1.__dict__, dict(a='spam', b='ham'))
+ self.assertEqual(ns2.__dict__, dict(x=1, y=2, w=3, z=4, theta=None))
+
+ def test_attrdel(self):
+ ns1 = types.SimpleNamespace()
+ ns2 = types.SimpleNamespace(x=1, y=2, w=3)
+
+ with self.assertRaises(AttributeError):
+ del ns1.spam
+ with self.assertRaises(AttributeError):
+ del ns2.spam
+
+ del ns2.y
+ self.assertEqual(vars(ns2), dict(w=3, x=1))
+ ns2.y = 'spam'
+ self.assertEqual(vars(ns2), dict(w=3, x=1, y='spam'))
+ del ns2.y
+ self.assertEqual(vars(ns2), dict(w=3, x=1))
+
+ ns1.spam = 5
+ self.assertEqual(vars(ns1), dict(spam=5))
+ del ns1.spam
+ self.assertEqual(vars(ns1), {})
+
+ def test_repr(self):
+ ns1 = types.SimpleNamespace(x=1, y=2, w=3)
+ ns2 = types.SimpleNamespace()
+ ns2.x = "spam"
+ ns2._y = 5
+
+ self.assertEqual(repr(ns1), "namespace(w=3, x=1, y=2)")
+ self.assertEqual(repr(ns2), "namespace(_y=5, x='spam')")
+
+ def test_nested(self):
+ ns1 = types.SimpleNamespace(a=1, b=2)
+ ns2 = types.SimpleNamespace()
+ ns3 = types.SimpleNamespace(x=ns1)
+ ns2.spam = ns1
+ ns2.ham = '?'
+ ns2.spam = ns3
+
+ self.assertEqual(vars(ns1), dict(a=1, b=2))
+ self.assertEqual(vars(ns2), dict(spam=ns3, ham='?'))
+ self.assertEqual(ns2.spam, ns3)
+ self.assertEqual(vars(ns3), dict(x=ns1))
+ self.assertEqual(ns3.x.a, 1)
+
+ def test_recursive(self):
+ ns1 = types.SimpleNamespace(c='cookie')
+ ns2 = types.SimpleNamespace()
+ ns3 = types.SimpleNamespace(x=1)
+ ns1.spam = ns1
+ ns2.spam = ns3
+ ns3.spam = ns2
+
+ self.assertEqual(ns1.spam, ns1)
+ self.assertEqual(ns1.spam.spam, ns1)
+ self.assertEqual(ns1.spam.spam, ns1.spam)
+ self.assertEqual(ns2.spam, ns3)
+ self.assertEqual(ns3.spam, ns2)
+ self.assertEqual(ns2.spam.spam, ns2)
+
+ def test_recursive_repr(self):
+ ns1 = types.SimpleNamespace(c='cookie')
+ ns2 = types.SimpleNamespace()
+ ns3 = types.SimpleNamespace(x=1)
+ ns1.spam = ns1
+ ns2.spam = ns3
+ ns3.spam = ns2
+
+ self.assertEqual(repr(ns1),
+ "namespace(c='cookie', spam=namespace(...))")
+ self.assertEqual(repr(ns2),
+ "namespace(spam=namespace(spam=namespace(...), x=1))")
+
+ def test_as_dict(self):
+ ns = types.SimpleNamespace(spam='spamspamspam')
+
+ with self.assertRaises(TypeError):
+ len(ns)
+ with self.assertRaises(TypeError):
+ iter(ns)
+ with self.assertRaises(TypeError):
+ 'spam' in ns
+ with self.assertRaises(TypeError):
+ ns['spam']
+
+
def test_main():
- run_unittest(TypesTests, MappingProxyTests, ClassCreationTests)
+ run_unittest(TypesTests, MappingProxyTests, ClassCreationTests,
+ SimpleNamespaceTests)
if __name__ == '__main__':
test_main()
diff --git a/Lib/types.py b/Lib/types.py
index 2bfcd9b..cfd09ea 100644
--- a/Lib/types.py
+++ b/Lib/types.py
@@ -13,6 +13,7 @@ FunctionType = type(_f)
LambdaType = type(lambda: None) # Same as FunctionType
CodeType = type(_f.__code__)
MappingProxyType = type(type.__dict__)
+SimpleNamespace = type(sys.implementation)
def _g():
yield 1