Skip to content

inspect.Parameter checks that name is an identifier, but does not check for keywords #92062

Closed

Description

@Zac-HD

Consider the following code:

def send(from):
    ...

This parses, but it doesn't compile: from is a keyword and so the code is syntactially invalid.

The problem is that inspect.Parameter checks that the given name is an identifier, but doesn't check that it's not a keyword. You can thus create invalid signatures, which cause considerable confusion on downstream introspection:

def f(source):
    pass

from inspect import Signature, Parameter
f.__signature__ = Signature([Parameter("from", P.KEYWORD_ONLY)], return_annotation=None)

# Or, as the real-world motivation,
class Model(pydantic.BaseModel):
    source: None = pydantic.Field(None, alias="from")

We're fixing this downstream in HypothesisWorks/hypothesis#3317 and pydantic/pydantic#4012, but I think that inspect.Parameter("from", ...) should also raise an error, just as if the provided name was not an identifier at all.

Activity

  1. added
    type-bugAn unexpected behavior, bug, or error
    on Apr 29, 2022
  2. added
    type-featureA feature request or enhancement
    and removed
    type-bugAn unexpected behavior, bug, or error
    on Apr 29, 2022
  3. added
    stdlibStandard Library Python modules in the Lib/ directory
    on Apr 29, 2022
  4. added a commit that references this issue on Apr 30, 2022
  5. JelleZijlstra commented on Apr 30, 2022

    @JelleZijlstra
    Member

    I can see a scenario where this will break things: we try to get the signature for a function implemented in C that takes a positional-only argument with a name that happens to be a keyword. I can't find any instances of that pattern in typeshed or CPython, but they may exist elsewhere.

  6. Zac-HD commented on Apr 30, 2022

    @Zac-HD
    ContributorAuthor

    Hmm, that makes sense. I'll tighten the check to only apply if the kind is not P.POSITIONAL_ONLY, since I don't expect this to weaken it as a check on Python code 👍

  7. added a commit that references this issue on Apr 30, 2022
  8. Zac-HD commented on May 2, 2022

    @Zac-HD
    ContributorAuthor

    I think we're fine to continue ignoring unicode names which normalize to keywords, since that's the existing behaviour of keyword.iskeyword and does actually work at runtime:

    >>> def f(def):  # non-ASCII "e" in argument name
    ...     print(locals())
    ... f(1)
    {'def': 1}
  9. added a commit that references this issue on May 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibStandard Library Python modules in the Lib/ directorytype-featureA feature request or enhancement

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions