Serhiy Storchaka added the comment:

I thought that more verbose but straightforward code would be more acceptable. 
Well, here is smaller and clever patch. Tests are the same.

----------
Added file: http://bugs.python.org/file36886/collections_pos_only_params2.patch

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue22609>
_______________________________________
diff -r f592a4073672 Lib/collections/__init__.py
--- a/Lib/collections/__init__.py       Sat Oct 11 01:43:35 2014 -0500
+++ b/Lib/collections/__init__.py       Sat Oct 11 22:30:05 2014 +0300
@@ -16,6 +16,19 @@ from _weakref import proxy as _proxy
 from itertools import repeat as _repeat, chain as _chain, starmap as _starmap
 from reprlib import recursive_repr as _recursive_repr
 
+def _wrap_dict_update(wrapped):
+    # Can't use functools.wraps due to circular import
+    def wrapper(*args, **kwds):
+        if kwds:
+            wrapped(*args, kwds=kwds)
+        else:
+            wrapped(*args)
+    for attr in ('__module__', '__name__', '__qualname__', '__doc__',
+                 '__annotations__'):
+        setattr(wrapper, attr, getattr(wrapped, attr))
+    del attr
+    return wrapper
+
 
################################################################################
 ### OrderedDict
 
################################################################################
@@ -55,14 +68,13 @@ class OrderedDict(dict):
     # Individual links are kept alive by the hard reference in self.__map.
     # Those hard references disappear when a key is deleted from an 
OrderedDict.
 
-    def __init__(self, *args, **kwds):
+    @_wrap_dict_update
+    def __init__(self, *args, kwds={}):
         '''Initialize an ordered dictionary.  The signature is the same as
         regular dictionaries, but keyword arguments are not recommended because
         their insertion order is arbitrary.
 
         '''
-        if len(args) > 1:
-            raise TypeError('expected at most 1 arguments, got %d' % len(args))
         try:
             self.__root
         except AttributeError:
@@ -479,7 +491,8 @@ class Counter(dict):
     #   http://code.activestate.com/recipes/259174/
     #   Knuth, TAOCP Vol. II section 4.6.3
 
-    def __init__(self, iterable=None, **kwds):
+    @_wrap_dict_update
+    def __init__(self, iterable=None, *, kwds={}):
         '''Create a new, empty Counter object.  And if given, count elements
         from an input iterable.  Or, initialize the count from another mapping
         of elements to their counts.
@@ -542,7 +555,8 @@ class Counter(dict):
         raise NotImplementedError(
             'Counter.fromkeys() is undefined.  Use Counter(iterable) instead.')
 
-    def update(self, iterable=None, **kwds):
+    @_wrap_dict_update
+    def update(self, iterable=None, *, kwds=None):
         '''Like dict.update() but add counts instead of replacing them.
 
         Source can be an iterable, a dictionary, or another Counter instance.
@@ -575,7 +589,8 @@ class Counter(dict):
         if kwds:
             self.update(kwds)
 
-    def subtract(self, iterable=None, **kwds):
+    @_wrap_dict_update
+    def subtract(self, iterable=None, *, kwds=None):
         '''Like dict.update() but subtracts counts instead of replacing them.
         Counts can be reduced below zero.  Both the inputs and outputs are
         allowed to contain zero and negative counts.
@@ -898,12 +913,13 @@ class ChainMap(MutableMapping):
 class UserDict(MutableMapping):
 
     # Start by filling-out the abstract methods
-    def __init__(self, dict=None, **kwargs):
+    @_wrap_dict_update
+    def __init__(self, dict=None, *, kwds=None):
         self.data = {}
         if dict is not None:
             self.update(dict)
-        if len(kwargs):
-            self.update(kwargs)
+        if kwds:
+            self.update(kwds)
     def __len__(self): return len(self.data)
     def __getitem__(self, key):
         if key in self.data:
diff -r f592a4073672 Lib/test/test_collections.py
--- a/Lib/test/test_collections.py      Sat Oct 11 01:43:35 2014 -0500
+++ b/Lib/test/test_collections.py      Sat Oct 11 22:30:05 2014 +0300
@@ -1137,6 +1137,28 @@ class TestCounter(unittest.TestCase):
         self.assertEqual(c.setdefault('e', 5), 5)
         self.assertEqual(c['e'], 5)
 
+    def test_init(self):
+        self.assertEqual(list(Counter(self=42).items()), [('self', 42)])
+        self.assertEqual(list(Counter(iterable=42).items()), [('iterable', 
42)])
+        self.assertEqual(list(Counter(iterable=None).items()), [('iterable', 
None)])
+        self.assertRaises(TypeError, Counter, 42)
+        self.assertRaises(TypeError, Counter, (), ())
+        self.assertRaises(TypeError, Counter.__init__)
+
+    def test_update(self):
+        c = Counter()
+        c.update(self=42)
+        self.assertEqual(list(c.items()), [('self', 42)])
+        c = Counter()
+        c.update(iterable=42)
+        self.assertEqual(list(c.items()), [('iterable', 42)])
+        c = Counter()
+        c.update(iterable=None)
+        self.assertEqual(list(c.items()), [('iterable', None)])
+        self.assertRaises(TypeError, Counter().update, 42)
+        self.assertRaises(TypeError, Counter().update, {}, {})
+        self.assertRaises(TypeError, Counter.update)
+
     def test_copying(self):
         # Check that counters are copyable, deepcopyable, picklable, and
         #have a repr/eval round-trip
@@ -1258,6 +1280,16 @@ class TestCounter(unittest.TestCase):
         c.subtract('aaaabbcce')
         self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1))
 
+        c = Counter()
+        c.subtract(self=42)
+        self.assertEqual(list(c.items()), [('self', -42)])
+        c = Counter()
+        c.subtract(iterable=42)
+        self.assertEqual(list(c.items()), [('iterable', -42)])
+        self.assertRaises(TypeError, Counter().subtract, 42)
+        self.assertRaises(TypeError, Counter().subtract, {}, {})
+        self.assertRaises(TypeError, Counter.subtract)
+
     def test_unary(self):
         c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40)
         self.assertEqual(dict(+c), dict(c=5, d=10, e=15, g=40))
@@ -1308,8 +1340,11 @@ class TestOrderedDict(unittest.TestCase)
                                           c=3, e=5).items()), pairs)           
     # mixed input
 
         # make sure no positional args conflict with possible kwdargs
-        
self.assertEqual(inspect.getargspec(OrderedDict.__dict__['__init__']).args,
-                         ['self'])
+        self.assertEqual(list(OrderedDict(self=42).items()), [('self', 42)])
+        self.assertEqual(list(OrderedDict(other=42).items()), [('other', 42)])
+        self.assertRaises(TypeError, OrderedDict, 42)
+        self.assertRaises(TypeError, OrderedDict, (), ())
+        self.assertRaises(TypeError, OrderedDict.__init__)
 
         # Make sure that direct calls to __init__ do not clear previous 
contents
         d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)])
@@ -1354,6 +1389,10 @@ class TestOrderedDict(unittest.TestCase)
         self.assertEqual(list(d.items()),
             [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 
7)])
 
+        self.assertRaises(TypeError, OrderedDict().update, 42)
+        self.assertRaises(TypeError, OrderedDict().update, (), ())
+        self.assertRaises(TypeError, OrderedDict.update)
+
     def test_abc(self):
         self.assertIsInstance(OrderedDict(), MutableMapping)
         self.assertTrue(issubclass(OrderedDict, MutableMapping))
@@ -1600,6 +1639,24 @@ class SubclassMappingTests(mapping_tests
         d = self._empty_mapping()
         self.assertRaises(KeyError, d.popitem)
 
+class TestUserDict(unittest.TestCase):
+
+    def test_init(self):
+        self.assertEqual(list(UserDict(self=42).items()), [('self', 42)])
+        self.assertEqual(list(UserDict(dict=42).items()), [('dict', 42)])
+        self.assertEqual(list(UserDict(dict=None).items()), [('dict', None)])
+        self.assertRaises(TypeError, UserDict, 42)
+        self.assertRaises(TypeError, UserDict, (), ())
+        self.assertRaises(TypeError, UserDict.__init__)
+
+    def test_update(self):
+        d = UserDict()
+        d.update(self=42)
+        self.assertEqual(list(d.items()), [('self', 42)])
+        self.assertRaises(TypeError, UserDict().update, 42)
+        self.assertRaises(TypeError, UserDict().update, {}, {})
+        self.assertRaises(TypeError, UserDict.update)
+
 
 
################################################################################
 ### Run tests
@@ -1611,7 +1668,8 @@ def test_main(verbose=None):
     NamedTupleDocs = doctest.DocTestSuite(module=collections)
     test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs,
                     TestCollectionABCs, TestCounter, TestChainMap,
-                    TestOrderedDict, GeneralMappingTests, SubclassMappingTests]
+                    TestOrderedDict, GeneralMappingTests, SubclassMappingTests,
+                    TestUserDict,]
     support.run_unittest(*test_classes)
     support.run_doctest(collections, verbose)
 
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to