[Python-checkins] r59028 - in sandbox/trunk/pep362: pep362.py tests/test_pep362.py
brett.cannon
python-checkins at python.org
Sat Nov 17 04:47:49 CET 2007
Author: brett.cannon
Date: Sat Nov 17 04:47:49 2007
New Revision: 59028
Modified:
sandbox/trunk/pep362/pep362.py
sandbox/trunk/pep362/tests/test_pep362.py
Log:
Add __getitem__ to Signature along with __iter__. This removes the need for
Signature.parameters.
Modified: sandbox/trunk/pep362/pep362.py
==============================================================================
--- sandbox/trunk/pep362/pep362.py (original)
+++ sandbox/trunk/pep362/pep362.py Sat Nov 17 04:47:49 2007
@@ -1,4 +1,5 @@
import inspect
+from operator import attrgetter
class BindError(TypeError):
@@ -50,8 +51,6 @@
"""Object to represent the signature of a function/method.
Attributes:
- * parameters
- Sequence of Parameter objects.
* name
Name of the function/method.
* var_args
@@ -90,7 +89,7 @@
except AttributeError:
# Needed only for tuple parameters.
argspec = inspect.getargspec(func)
- parameters = []
+ parameters = {}
# Parameter information.
pos_count = func_code.co_argcount
@@ -118,7 +117,7 @@
has_annotation, annotation = self._find_annotation(func, name)
param = Parameter(name, index, has_default=False,
has_annotation=has_annotation, annotation=annotation)
- parameters.append(param)
+ parameters[name] = param
# ... w/ defaults.
for offset, name in enumerate(positional[non_default_count:]):
name = self._convert_name(name)
@@ -128,7 +127,7 @@
has_default=True, default_value=default_value,
has_annotation=has_annotation,
annotation=annotation)
- parameters.append(param)
+ parameters[name] = param
# Keyword-only parameters.
for offset, name in enumerate(keyword_only):
has_annotation, annotation = self._find_annotation(func, name)
@@ -143,7 +142,7 @@
default_value=default_value,
has_annotation=has_annotation,
annotation=annotation)
- parameters.append(param)
+ parameters[name] = param
# Variable parameters.
index = pos_count + keyword_only_count
self.var_annotations = dict()
@@ -168,13 +167,19 @@
else:
self.var_kw_args = ''
- self.parameters = tuple(parameters)
+ self._parameters = parameters
# Return annotation.
if hasattr(func, '__annotations__'):
if 'return' in func.__annotations__:
self.return_annotation = func.__annotations__['return']
+ def __getitem__(self, key):
+ return self._parameters[key]
+
+ def __iter__(self):
+ return iter(sorted(self._parameters.values(), key=attrgetter('position')))
+
def _find_annotation(self, func, name):
"""Return True if an annotation exists for the named parameter along
with its annotation, else return False and None."""
@@ -207,14 +212,14 @@
positional = []
keyword_only = {}
- for param in self.parameters:
+ for param in self:
if not param.keyword_only:
positional.append(param)
else:
keyword_only[param.name] = param
# Positional arguments.
- if not self.parameters and args and self.var_args:
+ if not self._parameters and args and self.var_args:
bindings[self.var_args] = args
args = tuple()
for index, position_arg in enumerate(args[:]):
Modified: sandbox/trunk/pep362/tests/test_pep362.py
==============================================================================
--- sandbox/trunk/pep362/tests/test_pep362.py (original)
+++ sandbox/trunk/pep362/tests/test_pep362.py Sat Nov 17 04:47:49 2007
@@ -66,19 +66,34 @@
class SignatureObjectTests(unittest.TestCase):
+ def test_getitem(self):
+ # __getitem__() should return the Parameter object for the name
+ # parameter.
+ sig = pep362.Signature(pep362_fodder.default_args)
+ self.failUnless(sig['a'])
+ param = sig['a']
+ self.failUnlessEqual(param.name, 'a')
+
+ def test_iter(self):
+ # The iterator should return all Parameter objects in the proper order.
+ sig = pep362.Signature(pep362_fodder.default_args)
+ params = list(sig)
+ self.failUnlessEqual(len(params), 1)
+ self.failUnlessEqual(params[0].name, 'a')
+
def test_no_args(self):
# Test a function with no arguments.
sig = pep362.Signature(pep362_fodder.no_args)
self.failUnlessEqual('no_args', sig.name)
self.failUnless(not sig.var_args)
self.failUnless(not sig.var_kw_args)
- self.failUnlessEqual(0, len(sig.parameters))
+ self.failUnlessEqual(0, len(list(sig)))
def test_var_args(self):
# Test the var_args attribute.
sig = pep362.Signature(pep362_fodder.var_args)
self.failUnlessEqual('args', sig.var_args)
- self.failUnlessEqual(0, len(sig.parameters))
+ self.failUnlessEqual(0, len(list(sig)))
sig = pep362.Signature(pep362_fodder.no_args)
self.failUnlessEqual('', sig.var_args)
@@ -87,7 +102,7 @@
sig = pep362.Signature(pep362_fodder.var_kw_args)
self.failUnlessEqual('var_kw_args', sig.name)
self.failUnlessEqual('kwargs', sig.var_kw_args)
- self.failUnlessEqual(0, len(sig.parameters))
+ self.failUnlessEqual(0, len(list(sig)))
sig = pep362.Signature(pep362_fodder.no_args)
self.failUnlessEqual('', sig.var_kw_args)
@@ -95,7 +110,7 @@
# A function with positional arguments should work.
sig = pep362.Signature(pep362_fodder.no_default_args)
self.failUnlessEqual('no_default_args', sig.name)
- param = sig.parameters[0]
+ param = sig['a']
self.failUnlessEqual('a', param.name)
self.failUnlessEqual(0, param.position)
self.failUnless(not hasattr(param, 'default_value'))
@@ -104,7 +119,7 @@
# Default parameters for a function should work.
sig = pep362.Signature(pep362_fodder.default_args)
self.failUnlessEqual('default_args', sig.name)
- param = sig.parameters[0]
+ param = sig['a']
self.failUnlessEqual('a', param.name)
self.failUnlessEqual(0, param.position)
self.failUnlessEqual(42, param.default_value)
@@ -114,7 +129,7 @@
# A function with a tuple as a parameter should work.
sig = pep362.Signature(pep362_py2_fodder.tuple_args)
self.failUnlessEqual('tuple_args', sig.name)
- param = sig.parameters[0]
+ param = list(sig)[0]
self.failUnless(isinstance(param.name, tuple))
self.failUnlessEqual(('a', ('b',)), param.name)
self.failUnlessEqual(0, param.position)
@@ -125,7 +140,7 @@
# A default argument for a tuple parameter needs to work.
sig = pep362.Signature(pep362_py2_fodder.default_tuple_args)
self.failUnlessEqual('default_tuple_args', sig.name)
- param = sig.parameters[0]
+ param = list(sig)[0]
self.failUnlessEqual(('a', ('b',)), param.name)
self.failUnlessEqual(0, param.position)
self.failUnlessEqual((1, (2,)), param.default_value)
@@ -134,7 +149,7 @@
def test_keyword_only(self):
# Is a function containing keyword-only parameters handled properly?
sig = pep362.Signature(pep362_py3k_fodder.keyword_only)
- param = sig.parameters[0]
+ param = sig['a']
self.failUnlessEqual(param.name, 'a')
self.failUnless(param.keyword_only)
self.failUnlessEqual(param.position, 0)
@@ -143,7 +158,7 @@
def test_keyword_only_default(self):
# Default arguments can work for keyword-only parameters.
sig = pep362.Signature(pep362_py3k_fodder.keyword_only_default)
- param = sig.parameters[0]
+ param = sig['a']
self.failUnlessEqual(param.name, 'a')
self.failUnless(param.keyword_only)
self.failUnlessEqual(param.position, 0)
@@ -153,7 +168,7 @@
def test_annotations(self):
# Make sure the proper annotation is found.
sig = pep362.Signature(pep362_py3k_fodder.arg_annotation)
- param = sig.parameters[0]
+ param = sig['a']
self.failUnlessEqual(param.name, 'a')
self.failUnlessEqual(param.annotation, int)
@@ -161,7 +176,7 @@
def test_annotations_default(self):
# Annotations with a default value should work.
sig = pep362.Signature(pep362_py3k_fodder.arg_annotation_default)
- param = sig.parameters[0]
+ param = sig['a']
self.failUnlessEqual(param.name, 'a')
self.failUnlessEqual(param.annotation, int)
self.failUnlessEqual(param.default_value, 42)
@@ -170,7 +185,7 @@
def test_annotation_keyword_only(self):
# Keyword-only parameters can have an annotation.
sig = pep362.Signature(pep362_py3k_fodder.arg_annotation_keyword_only)
- param = sig.parameters[0]
+ param = sig['a']
self.failUnlessEqual(param.name, 'a')
self.failUnlessEqual(param.annotation, int)
self.failUnless(param.keyword_only)
@@ -279,8 +294,8 @@
(('b', ('c',)), 1, False, None),
('d', 2, True, 0),
(('e', ('f',)), 3, True, (4, (5,))))
- self.failUnlessEqual(len(sig.parameters), len(expect))
- for param, check in zip(sig.parameters, expect):
+ self.failUnlessEqual(len(list(sig)), len(expect))
+ for param, check in zip(list(sig), expect):
name, pos, has_default, default_value = check
self.failUnlessEqual(param.name, name)
self.failUnlessEqual(param.position, pos)
@@ -324,11 +339,11 @@
('d', 1, False, True, 0, False, None),
('g', 2, True, False, None, True, int),
('h', 3, True, True, 8, True, int))
- self.failUnlessEqual(len(sig.parameters), len(expected),
+ self.failUnlessEqual(len(list(sig)), len(expected),
"len(%r) != len(%r)" % ([param.name
- for param in sig.parameters],
+ for param in sig],
[expect[0] for expect in expected]))
- for param, check in zip(sig.parameters, expected):
+ for param, check in zip(sig, expected):
name, pos, kw_only, has_default, default, has_anno, anno = check
self.failUnlessEqual(param.name, name)
self.failUnlessEqual(param.position, pos)
More information about the Python-checkins
mailing list