[Python-checkins] r53903 - sandbox/trunk/pep362/pep362.py sandbox/trunk/pep362/pep362_fodder.py sandbox/trunk/pep362/test_pep362.py

brett.cannon python-checkins at python.org
Sun Feb 25 17:03:08 CET 2007


Author: brett.cannon
Date: Sun Feb 25 17:03:03 2007
New Revision: 53903

Modified:
   sandbox/trunk/pep362/pep362.py
   sandbox/trunk/pep362/pep362_fodder.py
   sandbox/trunk/pep362/test_pep362.py
Log:
Handle tuple arguments (or at least enough to pass a test).


Modified: sandbox/trunk/pep362/pep362.py
==============================================================================
--- sandbox/trunk/pep362/pep362.py	(original)
+++ sandbox/trunk/pep362/pep362.py	Sun Feb 25 17:03:03 2007
@@ -182,8 +182,6 @@
         positional = []
         keyword_only = {}
 
-        # XXX Tuple parameters.
-
         for param in self.parameters:
             if not param.keyword_only:
                 positional.append(param)
@@ -204,7 +202,7 @@
                     break
                 else:
                     raise BindError("too many positional arguments")
-            bindings[param.name] = position_arg
+            self._tuple_bind(bindings, param.name, position_arg)
         # Keyword arguments & default values.
         else:
             for positional_param in positional:
@@ -252,6 +250,31 @@
 
         return bindings
 
+    def _tuple_bind(self, bindings, possible_tuple, value):
+        """Where a tuple could be a parameter, handle binding the values to the
+        tuple and storing into the bindings mapping."""
+        if not isinstance(possible_tuple, tuple):
+            bindings[possible_tuple] = value
+        else:
+            # Need to make sure that value is as long as the parameter, but not
+            # vice-versa.
+            error_msg = "not enough values to unpack for %r"
+            tuple_iter = iter(possible_tuple)
+            try:
+                value_iter = iter(value)
+            except TypeError:
+                raise BindError(error_msg % possible_tuple)
+            while True:
+                try:
+                    sub_param = tuple_iter.next()
+                except StopIteration:
+                    break
+                try:
+                    sub_value = value_iter.next()
+                except StopIteration:
+                    raise BindError(error_msg % possible_tuple)
+                self._tuple_bind(bindings, sub_param, sub_value)
+
 
 def signature(func):
     """Return a Signature object for the function or method.

Modified: sandbox/trunk/pep362/pep362_fodder.py
==============================================================================
--- sandbox/trunk/pep362/pep362_fodder.py	(original)
+++ sandbox/trunk/pep362/pep362_fodder.py	Sun Feb 25 17:03:03 2007
@@ -14,7 +14,7 @@
     pass
 
 def tuple_args((a, (b,))):
-    pass
+    return a, b
 
 def default_tuple_args((a, (b,))=(1, (2,))):
     pass

Modified: sandbox/trunk/pep362/test_pep362.py
==============================================================================
--- sandbox/trunk/pep362/test_pep362.py	(original)
+++ sandbox/trunk/pep362/test_pep362.py	Sun Feb 25 17:03:03 2007
@@ -257,23 +257,22 @@
         self.failUnlessRaises(pep362.BindError, sig.bind, a=0, b=1)
         self.failUnlessRaises(pep362.BindError, sig.bind, b=1)
 
-    def XXX_test_tuple_parameter(self):
+    def test_tuple_parameter(self):
         sig = pep362.Signature(pep362_fodder.tuple_args)
-        binding = sig.bind((1, (2,)))
-        self.failUnlessEqual({('a', ('b',)):(1, (2,))}, binding)
         arg = (1, ((2,),))
         binding = sig.bind(arg)
-        self.failUnlessEqual({('a', ('b',)):arg}, binding)
+        self.failUnlessEqual({'a':1, 'b':(2,)}, binding)
         self.failUnlessRaises(pep362.BindError, sig.bind, (1,2,3))
         self.failUnlessRaises(pep362.BindError, sig.bind, (1, 2))
 
     def XXX_test_default_tuple_parameter(self):
         sig = pep362.Signature(pep362_fodder.default_tuple_args)
         binding = sig.bind()
-        self.failUnlessEqual({('a', ('b',)):(1, (2,))}, binding)
+        self.failUnlessEqual({'a':1, 'b':(2,)}, binding)
         arg = (0, (1,))
+        a, b = arg
         binding = sig.bind(arg)
-        self.failUnlessEqual({('a', ('b',)):arg}, binding)
+        self.failUnlessEqual({'a':a, 'b':b}, binding)
 
     def XXX_test_all_parameter_types(self):
         sig = pep362.Signature(pep362_fodder.all_args)


More information about the Python-checkins mailing list