Skip to content

Fix inspect.signature() of operator.{attrgetter,itemgetter,methodcaller} instances #118285

Closed

Description

@dgilland

Bug report

Bug description:

On Python 3.12.3 and 3.11.9, it looks like the inspect.Signature object for operator's attrgetter, itemgetter, and methodcaller classes doesn't match their __call__ method signature:

>>> import inspect
>>> import operator
>>> inspect.signature(operator.attrgetter("spam"))
<Signature (*args, **kwargs)>
>>> inspect.signature(operator.itemgetter("spam"))
<Signature (*args, **kwargs)>
>>> inspect.signature(operator.methodcaller("spam"))
<Signature (*args, **kwargs)>

but their __call__ methods only accept a single argument:

# attrgetter / itemgetter
    def __call__(self, obj):
        return self._call(obj)

# methodcaller
    def __call__(self, obj):
        return getattr(obj, self._name)(*self._args, **self._kwargs)

CPython versions tested on:

3.11, 3.12

Operating systems tested on:

macOS

Linked PRs

Activity

  1. changed the title [-]inspect signature of operator.{attrgetter,itemgetter,methodcaller} doesn't match __call__ definition[/-] [+]Fix inspect.signature() of operator.{attrgetter,itemgetter,methodcaller} instances[/+] on Apr 25, 2024
  2. added
    interpreter-core(Objects, Python, Grammar, and Parser dirs)
    stdlibStandard Library Python modules in the Lib/ directory
    on Apr 26, 2024
  3. terryjreedy commented on Apr 26, 2024

    @terryjreedy
    Member

    The signatures of the getter/caller classes are the signature of their .__init__ methods, and inspect.signature returns these properly. The signature of callable instances should, it seems, match that of the .__call__ methods, but, as you tested, it does not. However, while the operator callables (functions and these 3 classes) are all initially defined in python, they are all replaced with C implementations, when possible, with try: from _operator import *. After this, itemgetter.__call__, for instance, is a 'wrapper_descriptor' and itemgetter(s).__call__ is a 'method_wrapper'. Perhaps the C code for the call methods was never revised to use argument-clinic.

  4. added a commit that references this issue on Apr 26, 2024
  5. added a commit that references this issue on Apr 29, 2024
  6. serhiy-storchaka commented on Apr 29, 2024

    @serhiy-storchaka
    Member

    Actually, the operator module was initially implemented in C. The Python implementation was added later, partially as a fallback for alternative Python implementations (although Jython, PyPy, and other already had their own implementations), partially as experiment (which failed in my opinion).

    Now inspect.signature() returns <Signature (*args, **kwargs)> for custom callable objects implemented in C instead of raising a ValueError. It was perhaps not intentional change, but it may be too later to change this again, some code can already rely on this. At least not in 3.11 (which is in the security fixes mode) or 3.12.

    In any case, I added a simple way to specify signature for callables implemented in C and implemented it for the operator callables. Whether make inspect.signature() raising a ValueError by default is an open question.

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-bugAn unexpected behavior, bug, or error

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions