diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2012-04-15 22:16:30 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@gmail.com> | 2012-04-15 22:16:30 (GMT) |
commit | 0db176f8f6cfaf3277e6ef41d92b09a01b263f27 (patch) | |
tree | 9c881aaab525015223b7219c8fa12910e66354e9 /Lib | |
parent | 8a1d04c64372d4706572671a21ff9d3e4a6374ca (diff) | |
download | cpython-0db176f8f6cfaf3277e6ef41d92b09a01b263f27.zip cpython-0db176f8f6cfaf3277e6ef41d92b09a01b263f27.tar.gz cpython-0db176f8f6cfaf3277e6ef41d92b09a01b263f27.tar.bz2 |
Issue #14386: Expose the dict_proxy internal type as types.MappingProxyType
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/test/test_descr.py | 4 | ||||
-rw-r--r-- | Lib/test/test_types.py | 184 | ||||
-rw-r--r-- | Lib/types.py | 1 |
3 files changed, 184 insertions, 5 deletions
diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index 3051e57..c0c7414 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -4574,11 +4574,11 @@ class DictProxyTests(unittest.TestCase): self.assertEqual(type(C.__dict__), type(B.__dict__)) def test_repr(self): - # Testing dict_proxy.__repr__. + # Testing mappingproxy.__repr__. # We can't blindly compare with the repr of another dict as ordering # of keys and values is arbitrary and may differ. r = repr(self.C.__dict__) - self.assertTrue(r.startswith('dict_proxy('), r) + self.assertTrue(r.startswith('mappingproxy('), r) self.assertTrue(r.endswith(')'), r) for k, v in self.C.__dict__.items(): self.assertIn('{!r}: {!r}'.format(k, v), r) diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py index 8a98a03..9a2e0d4 100644 --- a/Lib/test/test_types.py +++ b/Lib/test/test_types.py @@ -1,9 +1,11 @@ # Python test set -- part 6, built-in types from test.support import run_unittest, run_with_locale -import unittest -import sys +import collections import locale +import sys +import types +import unittest class TypesTests(unittest.TestCase): @@ -569,8 +571,184 @@ class TypesTests(unittest.TestCase): self.assertGreater(tuple.__itemsize__, 0) +class MappingProxyTests(unittest.TestCase): + mappingproxy = types.MappingProxyType + + def test_constructor(self): + class userdict(dict): + pass + + mapping = {'x': 1, 'y': 2} + self.assertEqual(self.mappingproxy(mapping), mapping) + mapping = userdict(x=1, y=2) + self.assertEqual(self.mappingproxy(mapping), mapping) + mapping = collections.ChainMap({'x': 1}, {'y': 2}) + self.assertEqual(self.mappingproxy(mapping), mapping) + + self.assertRaises(TypeError, self.mappingproxy, 10) + self.assertRaises(TypeError, self.mappingproxy, ("a", "tuple")) + self.assertRaises(TypeError, self.mappingproxy, ["a", "list"]) + + def test_methods(self): + attrs = set(dir(self.mappingproxy({}))) - set(dir(object())) + self.assertEqual(attrs, { + '__contains__', + '__getitem__', + '__iter__', + '__len__', + 'copy', + 'get', + 'items', + 'keys', + 'values', + }) + + def test_get(self): + view = self.mappingproxy({'a': 'A', 'b': 'B'}) + self.assertEqual(view['a'], 'A') + self.assertEqual(view['b'], 'B') + self.assertRaises(KeyError, view.__getitem__, 'xxx') + self.assertEqual(view.get('a'), 'A') + self.assertIsNone(view.get('xxx')) + self.assertEqual(view.get('xxx', 42), 42) + + def test_missing(self): + class dictmissing(dict): + def __missing__(self, key): + return "missing=%s" % key + + view = self.mappingproxy(dictmissing(x=1)) + self.assertEqual(view['x'], 1) + self.assertEqual(view['y'], 'missing=y') + self.assertEqual(view.get('x'), 1) + self.assertEqual(view.get('y'), None) + self.assertEqual(view.get('y', 42), 42) + self.assertTrue('x' in view) + self.assertFalse('y' in view) + + def test_customdict(self): + class customdict(dict): + def __contains__(self, key): + if key == 'magic': + return True + else: + return dict.__contains__(self, key) + + def __iter__(self): + return iter(('iter',)) + + def __len__(self): + return 500 + + def copy(self): + return 'copy' + + def keys(self): + return 'keys' + + def items(self): + return 'items' + + def values(self): + return 'values' + + def __getitem__(self, key): + return "getitem=%s" % dict.__getitem__(self, key) + + def get(self, key, default=None): + return "get=%s" % dict.get(self, key, 'default=%r' % default) + + custom = customdict({'key': 'value'}) + view = self.mappingproxy(custom) + self.assertTrue('key' in view) + self.assertTrue('magic' in view) + self.assertFalse('xxx' in view) + self.assertEqual(view['key'], 'getitem=value') + self.assertRaises(KeyError, view.__getitem__, 'xxx') + self.assertEqual(tuple(view), ('iter',)) + self.assertEqual(len(view), 500) + self.assertEqual(view.copy(), 'copy') + self.assertEqual(view.get('key'), 'get=value') + self.assertEqual(view.get('xxx'), 'get=default=None') + self.assertEqual(view.items(), 'items') + self.assertEqual(view.keys(), 'keys') + self.assertEqual(view.values(), 'values') + + def test_chainmap(self): + d1 = {'x': 1} + d2 = {'y': 2} + mapping = collections.ChainMap(d1, d2) + view = self.mappingproxy(mapping) + self.assertTrue('x' in view) + self.assertTrue('y' in view) + self.assertFalse('z' in view) + self.assertEqual(view['x'], 1) + self.assertEqual(view['y'], 2) + self.assertRaises(KeyError, view.__getitem__, 'z') + self.assertEqual(tuple(sorted(view)), ('x', 'y')) + self.assertEqual(len(view), 2) + copy = view.copy() + self.assertIsNot(copy, mapping) + self.assertIsInstance(copy, collections.ChainMap) + self.assertEqual(copy, mapping) + self.assertEqual(view.get('x'), 1) + self.assertEqual(view.get('y'), 2) + self.assertIsNone(view.get('z')) + self.assertEqual(tuple(sorted(view.items())), (('x', 1), ('y', 2))) + self.assertEqual(tuple(sorted(view.keys())), ('x', 'y')) + self.assertEqual(tuple(sorted(view.values())), (1, 2)) + + def test_contains(self): + view = self.mappingproxy(dict.fromkeys('abc')) + self.assertTrue('a' in view) + self.assertTrue('b' in view) + self.assertTrue('c' in view) + self.assertFalse('xxx' in view) + + def test_views(self): + mapping = {} + view = self.mappingproxy(mapping) + keys = view.keys() + values = view.values() + items = view.items() + self.assertEqual(list(keys), []) + self.assertEqual(list(values), []) + self.assertEqual(list(items), []) + mapping['key'] = 'value' + self.assertEqual(list(keys), ['key']) + self.assertEqual(list(values), ['value']) + self.assertEqual(list(items), [('key', 'value')]) + + def test_len(self): + for expected in range(6): + data = dict.fromkeys('abcde'[:expected]) + self.assertEqual(len(data), expected) + view = self.mappingproxy(data) + self.assertEqual(len(view), expected) + + def test_iterators(self): + keys = ('x', 'y') + values = (1, 2) + items = tuple(zip(keys, values)) + view = self.mappingproxy(dict(items)) + self.assertEqual(set(view), set(keys)) + self.assertEqual(set(view.keys()), set(keys)) + self.assertEqual(set(view.values()), set(values)) + self.assertEqual(set(view.items()), set(items)) + + def test_copy(self): + original = {'key1': 27, 'key2': 51, 'key3': 93} + view = self.mappingproxy(original) + copy = view.copy() + self.assertEqual(type(copy), dict) + self.assertEqual(copy, original) + original['key1'] = 70 + self.assertEqual(view['key1'], 70) + self.assertEqual(copy['key1'], 27) + + def test_main(): - run_unittest(TypesTests) + run_unittest(TypesTests, MappingProxyTests) if __name__ == '__main__': test_main() diff --git a/Lib/types.py b/Lib/types.py index ab354d1..08cbb83 100644 --- a/Lib/types.py +++ b/Lib/types.py @@ -12,6 +12,7 @@ def _f(): pass FunctionType = type(_f) LambdaType = type(lambda: None) # Same as FunctionType CodeType = type(_f.__code__) +MappingProxyType = type(type.__dict__) def _g(): yield 1 |