8000 gh-102378: don't bother stripping `/` from __text_signature__ by davidhewitt · Pull Request #102379 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

gh-102378: don't bother stripping / from __text_signature__ #102379

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 17 additions & 40 deletions Lib/inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -2106,26 +2106,21 @@ def _signature_strip_non_python_syntax(signature):
Private helper function. Takes a signature in Argument Clinic's
extended signature format.

Returns a tuple of three things:
* that signature re-rendered in standard Python syntax,
Returns a tuple of two things:
* that signature re-rendered in standard Python syntax, and
* the index of the "self" parameter (generally 0), or None if
the function does not have a "self" parameter, and
* the index of the last "positional only" parameter,
or None if the signature has no positional-only parameters.
the function does not have a "self" parameter.
"""

if not signature:
return signature, None, None
return signature, None

self_parameter = None
last_positional_only = None

lines = [l.encode('ascii') for l in signature.split('\n') if l]
generator = iter(lines).__next__
token_stream = tokenize.tokenize(generator)

delayed_comma = False
skip_next_comma = False
text = []
add = text.append

Expand All @@ -2142,35 +2137,18 @@ def _signature_strip_non_python_syntax(signature):

if type == OP:
if string == ',':
if skip_next_comma:
skip_next_comma = False
else:
assert not delayed_comma
delayed_comma = True
current_parameter += 1
continue

if string == '/':
assert not skip_next_comma
assert last_positional_only is None
skip_next_comma = True
last_positional_only = current_parameter - 1
continue
current_parameter += 1

if (type == ERRORTOKEN) and (string == '$'):
assert self_parameter is None
self_parameter = current_parameter
continue

if delayed_comma:
delayed_comma = False
if not ((type == OP) and (string == ')')):
add(', ')
add(string)
if (string == ','):
add(' ')
clean_signature = ''.join(text)
return clean_signature, self_parameter, last_positional_only
return clean_signature, self_parameter


def _signature_fromstr(cls, obj, s, skip_bound_arg=True):
Expand All @@ -2179,8 +2157,7 @@ def _signature_fromstr(cls, obj, s, skip_bound_arg=True):
"""
Parameter = cls._parameter_cls

clean_signature, self_parameter, last_positional_only = \
_signature_strip_non_python_syntax(s)
clean_signature, self_parameter = _signature_strip_non_python_syntax(s)

program = "def foo" + clean_signature + ": pass"

Expand Down Expand Up @@ -2269,17 +2246,17 @@ def p(name_node, default_node, default=empty):
parameters.append(Parameter(name, kind, default=default, annotation=empty))

# non-keyword-only parameters
args = reversed(f.args.args)
defaults = reversed(f.args.defaults)
iter = itertools.zip_longest(args, defaults, fillvalue=None)
if last_positional_only is not None:
kind = Parameter.POSITIONAL_ONLY
else:
kind = Parameter.POSITIONAL_OR_KEYWORD
for i, (name, default) in enumerate(reversed(list(iter))):
total_non_kw_args = len(f.args.posonlyargs) + len(f.args.args)
required_non_kw_args = total_non_kw_args - len(f.args.defaults)
defaults = itertools.chain(itertools.repeat(None, required_non_kw_args), f.args.defaults)

kind = Parameter.POSITIONAL_ONLY
for (name, default) in zip(f.args.posonlyargs, defaults):
p(name, default)

kind = Parameter.POSITIONAL_OR_KEYWORD
for (name, default) in zip(f.args.args, defaults):
p(name, default)
if i == last_positional_only:
kind = Parameter.POSITIONAL_OR_KEYWORD

# *args
if f.args.vararg:
Expand Down
23 changes: 7 additions & 16 deletions Lib/test/test_inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -4230,56 +4230,47 @@ def foo(a): pass

class TestSignaturePrivateHelpers(unittest.TestCase):
def _strip_non_python_syntax(self, input,
clean_signature, self_parameter, last_positional_only):
clean_signature, self_parameter):
computed_clean_signature, \
computed_self_parameter, \
computed_last_positional_only = \
computed_self_parameter = \
inspect._signature_strip_non_python_syntax(input)
self.assertEqual(computed_clean_signature, clean_signature)
self.assertEqual(computed_self_parameter, self_parameter)
self.assertEqual(computed_last_positional_only, last_positional_only)

def test_signature_strip_non_python_syntax(self):
self._strip_non_python_syntax(
"($module, /, path, mode, *, dir_fd=None, " +
"effective_ids=False,\n follow_symlinks=True)",
"(module, path, mode, *, dir_fd=None, " +
"(module, /, path, mode, *, dir_fd=None, " +
"effective_ids=False, follow_symlinks=True)",
0,
0)

self._strip_non_python_syntax(
"($module, word, salt, /)",
"(module, word, salt)",
0,
2)
"(module, word, salt, /)",
0)

self._strip_non_python_syntax(
"(x, y=None, z=None, /)",
"(x, y=None, z=None)",
None,
2)
"(x, y=None, z=None, /)",
None)

self._strip_non_python_syntax(
"(x, y=None, z=None)",
"(x, y=None, z=None)",
None,
None)

self._strip_non_python_syntax(
"(x,\n y=None,\n z = None )",
"(x, y=None, z=None)",
None,
None)

self._strip_non_python_syntax(
"",
"",
None,
None)

self._strip_non_python_syntax(
None,
None,
None,
None)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Private helper method ``inspect._signature_strip_non_python_syntax`` will no longer strip ``/`` from the input string.
0