I'm trying to understand how Python's type annotations work (e.g. List
and Dict
- not list
or dict
). Specifically I'm interested in how isinstance(list(), List)
works, so that I can create my own custom annotations.
I see that List
is defined as:
class List(list, MutableSequence[T], extra=list):
. . .
I'm familiar with metaclass = xxx
but I can't find any documentation on this extra = xxx
. Is this a keyword or just an argument, and if so, where does it come from and does it do what I'm after? Is it even relevant for isinstance
?
The isinstance() function checks if the object (first argument) is an instance or subclass of classinfo class (second argument). The syntax of isinstance() is: isinstance(object, classinfo)
The isinstance() takes two parameters: object - object to be checked. classinfo - class, type, or tuple of classes and types.
The isinstance () function returns True if the specified object is of the specified type, otherwise False. If the type parameter is a tuple, this function will return True if the object is one of the types in the tuple. Required. An object. The issubclass () function, to check if an object is a subclass of another object.
Python isinstance() Method. The isinstance() method checks if the object is an instance of the specified class or any of its subclass. Syntax: isinstance(object, classinfo) Parameters: object: An object to be checked. classinfo: The class name or a tuple of class names. Return Value:
The isinstance()
and issubclass()
have hooks in object.__instancecheck__()
and object.__subclasscheck__()
that the typing
generics also use.
If you want to provide your own generics, you really want to study the typing
module source code, specifically how GenericMeta
and Generic
are used to define the other Generic types like List
; mostly such checks are delegated to abc.ABCMeta.__subclasshook__
. You can define your own ABC with such a hook, then define a Generic that subclasses it.
It is the GenericMeta
metaclass here that also gives the extra
keyword argument meaning. Such internals are still sparsely documented because the typing
implementation is still in flux, the module is still provisional. The extra
argument is stored as __extra__
and is used in a custom __subclasshook__
implementation; for extra=list
it simply comes down to translating isinstance(something, List)
to isinstance(something, list)
.
Note that support for run-time checks is deliberately limited; static type checkers will not actually run those hooks. See the structural subtyping discussion in the mypy tracker for further discussion on how the developers are thinking about how to provide better support for complex custom classes that may or may not implement enough methods to be deemed a mapping or a sequence or similar.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With