From b2fdae9d86cd91fc75ca6a91f772cf805d536f42 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sat, 22 Apr 2023 08:13:02 -0700 Subject: [3.11] gh-103556: [inspect.Signature] disallow pos-or-kw params without default after pos-only with default (GH-103557) (#103675) --- Lib/inspect.py | 10 +++--- Lib/test/test_inspect.py | 40 ++++++++++++++++++---- .../2023-04-15-12-19-14.gh-issue-103556.TEf-2m.rst | 3 ++ 3 files changed, 41 insertions(+), 12 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2023-04-15-12-19-14.gh-issue-103556.TEf-2m.rst diff --git a/Lib/inspect.py b/Lib/inspect.py index bc49e68..75d33f2 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -2978,7 +2978,7 @@ class Signature: if __validate_parameters__: params = OrderedDict() top_kind = _POSITIONAL_ONLY - kind_defaults = False + seen_default = False for param in parameters: kind = param.kind @@ -2993,21 +2993,19 @@ class Signature: kind.description) raise ValueError(msg) elif kind > top_kind: - kind_defaults = False top_kind = kind if kind in (_POSITIONAL_ONLY, _POSITIONAL_OR_KEYWORD): if param.default is _empty: - if kind_defaults: + if seen_default: # No default for this parameter, but the - # previous parameter of the same kind had - # a default + # previous parameter of had a default msg = 'non-default argument follows default ' \ 'argument' raise ValueError(msg) else: # There is a default for this parameter. - kind_defaults = True + seen_default = True if name in params: msg = 'duplicate parameter name: {!r}'.format(name) diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py index 9f597e2..efcbd63 100644 --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -2301,18 +2301,43 @@ class TestSignatureObject(unittest.TestCase): self.assertEqual(str(S()), '()') self.assertEqual(repr(S().parameters), 'mappingproxy(OrderedDict())') - def test(po, pk, pod=42, pkd=100, *args, ko, **kwargs): + def test(po, /, pk, pkd=100, *args, ko, kod=10, **kwargs): pass + sig = inspect.signature(test) - po = sig.parameters['po'].replace(kind=P.POSITIONAL_ONLY) - pod = sig.parameters['pod'].replace(kind=P.POSITIONAL_ONLY) + self.assertTrue(repr(sig).startswith(' {42:'ham'}: pass foo_partial = functools.partial(foo, a=1) diff --git a/Misc/NEWS.d/next/Library/2023-04-15-12-19-14.gh-issue-103556.TEf-2m.rst b/Misc/NEWS.d/next/Library/2023-04-15-12-19-14.gh-issue-103556.TEf-2m.rst new file mode 100644 index 0000000..fe2267b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-04-15-12-19-14.gh-issue-103556.TEf-2m.rst @@ -0,0 +1,3 @@ +Now creating :class:`inspect.Signature` objects with positional-only +parameter with a default followed by a positional-or-keyword parameter +without one is impossible. -- cgit v0.12