Functions related to dundermethods¶

Working with dundermethods can be tricky, because when python searches for a dundermethod, it doesn’t use the same mechanism as it does for normal attribute access. Normal attribute access like obj.attr will look for attr in the instance’s namespace (i.e. obj.__dict__) and the class’s namespace (i.e. type(obj).__dict__ plus the __dict__ of every parent class). Dundermethods, on the other hand, are only searched for in the class namespace - not the instance namespace. Defining a dundermethod in the instance namespace won’t work:

class Demo:
    pass

obj = Demo()
obj.__len__ = lambda self: 0

print(len(obj))  # throws TypeError: object of type 'Demo' has no len()

And neither will defining a dundermethod in a metaclass:

class DemoMeta(type):
    def __len__(cls):
        return 0

class Demo(metaclass=DemoMeta):
    pass

obj = Demo()

print(len(obj))  # throws TypeError: object of type 'Demo' has no len()

So if you wanted to implement your own len function, you wouldn’t have an easy way of accessing the relevant __len__ method - obj.__len__ would be incorrect because it would search the instance namespace, and type(obj).__len__ would be incorrect because it would search the metaclass namespace. That’s where these functions come in - get_bound_dundermethod(obj) or get_class_dundermethod(type(obj)) would do the work for you.

introspection.DUNDERMETHOD_NAMES = {'__abs__', '__add__', '__aenter__', '__aexit__', '__aiter__', '__and__', '__anext__', '__await__', '__bool__', '__bytes__', '__call__', '__ceil__', '__class_getitem__', '__complex__', '__contains__', '__del__', '__delattr__', '__delete__', '__delitem__', '__delslice__', '__dir__', '__div__', '__divmod__', '__enter__', '__eq__', '__exit__', '__float__', '__floor__', '__floordiv__', '__format__', '__fspath__', '__ge__', '__get__', '__getattr__', '__getattribute__', '__getitem__', '__getnewargs__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__iand__', '__ifloordiv__', '__ilshift__', '__imatmul__', '__imod__', '__imul__', '__index__', '__init__', '__init_subclass__', '__instancecheck__', '__int__', '__invert__', '__ior__', '__ipow__', '__irshift__', '__isub__', '__iter__', '__itruediv__', '__ixor__', '__le__', '__len__', '__length_hint__', '__lshift__', '__lt__', '__matmul__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__next__', '__or__', '__pos__', '__pow__', '__prepare__', '__radd__', '__rand__', '__rdiv__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rfloordiv__', '__rlshift__', '__rmatmul__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__set__', '__set_name__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__sub__', '__subclasscheck__', '__subclasses__', '__truediv__', '__trunc__', '__xor__'}¶

A set containing the names of all dundermethods available in python 3.9.

introspection.AUGMENTED_ASSIGNMENT_DUNDERMETHOD_NAMES = {'__iadd__', '__iand__', '__ifloordiv__', '__ilshift__', '__imatmul__', '__imod__', '__imul__', '__ior__', '__ipow__', '__irshift__', '__isub__', '__itruediv__', '__ixor__'}¶

A set containing the names of all augmented assignment dundermethods available in python 3.9.

New in version 1.1.

introspection.iter_class_dundermethods(cls, *, start=None, start_after=None, bound=None)¶

Yields all dundermethods implemented by the given class as (method_name, method) tuples.

(For the purpose of this function, “implemented” simply means “exists”. Even if the method’s value is None or anything else, it will still be yielded.)

If multiple classes in the MRO implement the same dundermethod, both methods will be yielded. Methods implemented by subclasses will always be yielded before methods implemented by parent classes.

You can skip some classes in the MRO by specifying start or start_after. If start is not None, iteration will begin at that class. If start_after is not None, iteration will begin after that class. Passing both at the same time is not allowed.

You can cause the iteration to stop early by passing in a class as the upper bound. The MRO will only be iterated up to the bound, excluding the bound class itself. This is useful for excluding dundermethods implemented in object.

Parameters
  • cls (type) – The class whose dundermethods to yield

  • start (Optional[type], default: None) – Where to start iterating through the class’s MRO

  • start_after (Optional[type], default: None) – Where to start iterating through the class’s MRO

  • bound (Optional[type], default: None) – Where to stop iterating through the class’s MRO

Return type

Iterator[Tuple[str, Any]]

Returns

An iterator yielding (method_name, method) tuples

Raises

TypeError – If cls is not a class

introspection.class_implements_dundermethod(cls, method_name, *, start=None, start_after=None, bound=None)¶

Checks whether the given class implements a certain dundermethod.

The method is considered implemented if any of the classes in the MRO have an entry for method_name in their __dict__. The only exceptions are methods from NONEABLE_DUNDERMETHOD_NAMES, which are considered not implemented if their value is None.

Note that object implements various dundermethods, including some unexpected ones like __lt__. Remember to pass in bound=object if you wish to exclude these.

For details about start, start_after and bound, see iter_class_dundermethods().

New in version 1.4: The start and start_after parameters.

Parameters
  • cls (type) – A class

  • method_name (str) – The name of a dundermethod

  • start (Optional[type], default: None) – Where to start searching through the class’s MRO

  • start_after (Optional[type], default: None) – Where to start searching through the class’s MRO

  • bound (Optional[type], default: None) – Where to stop searching through the class’s MRO

Return type

bool

Returns

A boolean indicating whether the class implements that dundermethod

Raises

TypeError – If cls is not a class

introspection.class_implements_any_dundermethod(cls, methods, *, start=None, start_after=None, bound=None)¶

Checks whether the given class implements at least one of the given dundermethods.

For details about start, start_after and bound, see iter_class_dundermethods().

New in version 1.4: The start and start_after parameters.

Parameters
  • cls (type) – A class

  • methods (Iterable[str]) – The names of a bunch of dundermethods

  • start (Optional[type], default: None) – Where to start searching through the class’s MRO

  • start_after (Optional[type], default: None) – Where to start searching through the class’s MRO

  • bound (Optional[type], default: None) – Where to stop searching through the class’s MRO

Return type

bool

Returns

A boolean indicating whether the class implements any of those dundermethods

Raises

TypeError – If cls is not a class

introspection.class_implements_dundermethods(cls, methods, *, start=None, start_after=None, bound=None)¶

Checks whether the given class implements all given dundermethods.

For details about start, start_after and bound, see iter_class_dundermethods().

New in version 1.4: The start and start_after parameters.

Parameters
  • cls (type) – A class

  • methods (Iterable[str]) – The names of a bunch of dundermethods

  • start (Optional[type], default: None) – Where to start searching through the class’s MRO

  • start_after (Optional[type], default: None) – Where to start searching through the class’s MRO

  • bound (Optional[type], default: None) – Where to stop searching through the class’s MRO

Return type

bool

Returns

A boolean indicating whether the class implements all those dundermethods

Raises

TypeError – If cls is not a class

introspection.collect_class_dundermethods(cls, *, start=None, start_after=None, bound=None)¶

Generates a dict of the form {method_name: method} containing all dundermethods implemented by the given class.

If multiple classes in the MRO implement the same dundermethod, only the first implementation is included in the result.

For details about start, start_after and bound, see iter_class_dundermethods().

New in version 1.4: The start and start_after parameters.

Parameters
  • cls (type) – The class whose dundermethods to collect

  • start (Optional[type], default: None) – Where to start iterating through the class’s MRO

  • start_after (Optional[type], default: None) – Where to start iterating through the class’s MRO

  • bound (Optional[type], default: None) – Where to stop iterating through the class’s MRO

Return type

Dict[str, Any]

Returns

A {method_name: method} dict

Raises

TypeError – If cls is not a class

introspection.get_class_dundermethod(cls, method_name, *, start=None, start_after=None, bound=None)¶

Retrieves a class’s implementation of the given dundermethod.

For details about start, start_after and bound, see iter_class_dundermethods().

New in version 1.4: The start and start_after parameters.

Parameters
  • cls (type) – A class

  • method_name (str) – The name of a dundermethod

  • start (Optional[type], default: None) – Where to start searching through the class’s MRO

  • start_after (Optional[type], default: None) – Where to start searching through the class’s MRO

  • bound (Optional[type], default: None) – Where to stop searching through the class’s MRO

Return type

Optional[Callable]

Returns

The function object for the given method_name

Raises
  • TypeError – If cls is not a class

  • AttributeError – If cls does not implement that dundermethod

introspection.get_bound_dundermethod(instance, method_name, *, start=None, start_after=None, bound=None)¶

Retrieves an instance’s implementation of the given dundermethod.

Some dundermethods (for example __hash__) can be explicitly disabled by setting them to None. In such a case, this function will throw an AttributeError.

For details about start, start_after and bound, see iter_class_dundermethods().

New in version 1.1.

New in version 1.4: The start and start_after parameters.

Parameters
  • instance (Any) – Any object

  • method_name (str) – The name of a dundermethod

  • start (Optional[type], default: None) – Where to start searching through the class’s MRO

  • start_after (Optional[type], default: None) – Where to start searching through the class’s MRO

  • bound (Optional[type], default: None) – Where to stop searching through the class’s MRO

Return type

Optional[Callable]

Returns

A bound method for the given method_name

Raises

AttributeError – If instance does not implement that dundermethod

introspection.call_dundermethod(instance, method_name, *args, **kwargs)¶

Given an instance and the name of a dundermethod, calls the object’s corresponding dundermethod. Excess arguments are passed to the dundermethod.

Examples:

>>> call_dundermethod('foo', '__len__')
3
>>> call_dundermethod([1], '__add__', [2])
[1, 2]

Alternatively, you can use the functions in the introspection.dunder module:

>>> introspection.dunder.__len__('foo')
3
>>> introspection.dunder.add([1], [2])
[1, 2]

New in version 1.4.

Table of Contents

Contents:

  • Function Signatures
  • The call stack
  • Functions related to classes
  • Functions related to dundermethods
  • Introspecting the typing module
  • Misc. functions

Navigation

Introspection documentation Functions related to classes Introspecting the typing module

Quick search