What is wrong with using object as a type in Python?

Viewed 204

The following program works, but gives a MyPy error:

from typing import Type, TypeVar, Any, Optional


T = TypeVar('T')


def check(element: Any, types: Type[T] = object) -> Optional[T]:
    if not isinstance(element, types):
        return None
    return element


print(check(123, int))
print(check(123, object))

MyPy complains:

main.py:7: error: Incompatible default for argument "types" (default has type "Type[object]", argument has type "Type[T]")
Found 1 error in 1 file (checked 1 source file)

What am I doing wrong?

Replacing object with Type[object] mysteriously works.

2 Answers

You're using the type variable in the wrong place, it should be used with element not types.

from typing import Optional, Type, TypeVar

T = TypeVar('T')

def check(element: T, types: Type = object) -> Optional[T]:
    if not isinstance(element, types):
        return None
    return element

The problem was that the default value has to fit for every possible substitution for T. Since it doesn't the right way to solve this is to define overloads, one with the Type[T] producing Optional[T] and one with Literal[object] and producing Any. Then in the combined declaration, the default can be provided.

This was addressed by Guido here.

Related