-
Notifications
You must be signed in to change notification settings - Fork 640
Add an explicit error message if a function signature uses a keyword for an argument name #3317
Description
There are some fancy cases where callables will have dynamically-assigned __signature__ attributes, for example in Pydantic. The problem is that inspect.Parameter only checks whether the name is an identifier (which ensures that the code parses) but allows keywords like from (which will raise a SyntaxError after parsing). Here's some example code to trigger the problem:
from pydantic import BaseModel, Field
class Model(BaseModel):
source: None = Field(None, alias="from")from inspect import Signature, Parameter as P
def f(source):
pass
f.__signature__ = Signature(
parameters=[P("from", P.KEYWORD_ONLY)], # would be invalid syntax!
return_annotation=P.empty,
)While upstream fixes like pydantic/pydantic#4012 will make this less likely, and it has been fixed permanently in CPython 3.11, we currently give confusing errors on this case. For example, running the ghostwriter on the code above will produce:
Traceback (most recent call last):
...
File "hypothesis/extra/ghostwriter.py", line 912, in magic
black.parsing.InvalidInput: Cannot parse: 20:7: @given(from=...)I therefore plan to audit all our uses of inspect.signature() (and the legacy getfullargspec 😬) to ensure that we always raise an error with a more helpful message in such cases, e.g. "Signature contains a parameter named {name!r}, but this is a SyntaxError because {name} is a keyword. This can only happen if someone manually creates an invalid signature!".