From: Zac Hatfield-Dodds Date: Tue, 3 May 2022 20:52:30 +0000 (-0600) Subject: gh-92062: `inspect.Parameter` checks whether `name` is a keyword (GH-92065) X-Git-Tag: v3.11.0b1~72 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=65f88a6ef74c9b01017438e88e31570b02f1df9c;p=thirdparty%2FPython%2Fcpython.git gh-92062: `inspect.Parameter` checks whether `name` is a keyword (GH-92065) Fixes #92062. --- diff --git a/Lib/inspect.py b/Lib/inspect.py index 5bc9c04b22e2..6e744712f014 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -149,6 +149,7 @@ import token import types import functools import builtins +from keyword import iskeyword from operator import attrgetter from collections import namedtuple, OrderedDict @@ -1645,7 +1646,7 @@ class Traceback(_Traceback): instance = super().__new__(cls, filename, lineno, function, code_context, index) instance.positions = positions return instance - + def __repr__(self): return ('Traceback(filename={!r}, lineno={!r}, function={!r}, ' 'code_context={!r}, index={!r}, positions={!r})'.format( @@ -1683,7 +1684,7 @@ def getframeinfo(frame, context=1): frame, *positions = (frame, lineno, *positions[1:]) else: frame, *positions = (frame, *positions) - + lineno = positions[0] if not isframe(frame): @@ -2707,7 +2708,10 @@ class Parameter: self._kind = _POSITIONAL_ONLY name = 'implicit{}'.format(name[1:]) - if not name.isidentifier(): + # It's possible for C functions to have a positional-only parameter + # where the name is a keyword, so for compatibility we'll allow it. + is_keyword = iskeyword(name) and self._kind is not _POSITIONAL_ONLY + if is_keyword or not name.isidentifier(): raise ValueError('{!r} is not a valid parameter name'.format(name)) self._name = name diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py index 115e97b77e07..fe0259ab609c 100644 --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -3604,6 +3604,9 @@ class TestParameterObject(unittest.TestCase): with self.assertRaisesRegex(ValueError, 'not a valid parameter name'): inspect.Parameter('1', kind=inspect.Parameter.VAR_KEYWORD) + with self.assertRaisesRegex(ValueError, 'not a valid parameter name'): + inspect.Parameter('from', kind=inspect.Parameter.VAR_KEYWORD) + with self.assertRaisesRegex(TypeError, 'name must be a str'): inspect.Parameter(None, kind=inspect.Parameter.VAR_KEYWORD) diff --git a/Misc/NEWS.d/next/Library/2022-04-29-18-15-23.gh-issue-92062.X2c_Rj.rst b/Misc/NEWS.d/next/Library/2022-04-29-18-15-23.gh-issue-92062.X2c_Rj.rst new file mode 100644 index 000000000000..1ccb779a6d1d --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-04-29-18-15-23.gh-issue-92062.X2c_Rj.rst @@ -0,0 +1,2 @@ +:class:`inspect.Parameter` now raises :exc:`ValueError` if ``name`` is +a keyword, in addition to the existing check that it is an identifier.