[Python-checkins] cpython: inspect.Signature: ensure that non-default params don't follow default ones
yury.selivanov
python-checkins at python.org
Wed Jan 29 16:58:50 CET 2014
http://hg.python.org/cpython/rev/ca974997280d
changeset: 88811:ca974997280d
user: Yury Selivanov <yselivanov at sprymix.com>
date: Wed Jan 29 10:58:16 2014 -0500
summary:
inspect.Signature: ensure that non-default params don't follow default ones #20427
files:
Lib/inspect.py | 21 ++++++++++++++++++++-
Lib/test/test_inspect.py | 13 ++++++++++++-
2 files changed, 32 insertions(+), 2 deletions(-)
diff --git a/Lib/inspect.py b/Lib/inspect.py
--- a/Lib/inspect.py
+++ b/Lib/inspect.py
@@ -1924,6 +1924,7 @@
if __validate_parameters__:
params = OrderedDict()
top_kind = _POSITIONAL_ONLY
+ kind_defaults = False
for idx, param in enumerate(parameters):
kind = param.kind
@@ -1933,9 +1934,27 @@
msg = 'wrong parameter order: {} before {}'
msg = msg.format(top_kind, kind)
raise ValueError(msg)
- else:
+ elif kind > top_kind:
+ kind_defaults = False
top_kind = kind
+ if (kind in (_POSITIONAL_ONLY, _POSITIONAL_OR_KEYWORD) and
+ not param._partial_kwarg):
+ # If we have a positional-only or positional-or-keyword
+ # parameter, that does not have its default value set
+ # by 'functools.partial' or other "partial" signature:
+ if param.default is _empty:
+ if kind_defaults:
+ # No default for this parameter, but the
+ # previous parameter of the same kind had
+ # a default
+ msg = 'non-default argument follows default ' \
+ 'argument'
+ raise ValueError(msg)
+ else:
+ # There is a default for this parameter.
+ kind_defaults = True
+
if name in params:
msg = 'duplicate parameter name: {!r}'.format(name)
raise ValueError(msg)
diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py
--- a/Lib/test/test_inspect.py
+++ b/Lib/test/test_inspect.py
@@ -1522,11 +1522,13 @@
self.assertEqual(str(S()), '()')
- def test(po, pk, *args, ko, **kwargs):
+ def test(po, pk, pod=42, pkd=100, *args, ko, **kwargs):
pass
sig = inspect.signature(test)
po = sig.parameters['po'].replace(kind=P.POSITIONAL_ONLY)
+ pod = sig.parameters['pod'].replace(kind=P.POSITIONAL_ONLY)
pk = sig.parameters['pk']
+ pkd = sig.parameters['pkd']
args = sig.parameters['args']
ko = sig.parameters['ko']
kwargs = sig.parameters['kwargs']
@@ -1549,6 +1551,15 @@
with self.assertRaisesRegex(ValueError, 'duplicate parameter name'):
S((po, pk, args, kwargs2, ko))
+ with self.assertRaisesRegex(ValueError, 'follows default argument'):
+ S((pod, po))
+
+ with self.assertRaisesRegex(ValueError, 'follows default argument'):
+ S((po, pkd, pk))
+
+ with self.assertRaisesRegex(ValueError, 'follows default argument'):
+ S((pkd, pk))
+
def test_signature_immutability(self):
def test(a):
pass
--
Repository URL: http://hg.python.org/cpython
More information about the Python-checkins
mailing list