* Every type is compatible with :data:`Any`.
* :data:`Any` is compatible with every type.
+ .. versionchanged:: 3.11
+ :data:`Any` can now be used as a base class. This can be useful for
+ avoiding type checker errors with classes that can duck type anywhere or
+ are highly dynamic.
+
.. data:: Never
The `bottom type <https://en.wikipedia.org/wiki/Bottom_type>`_,
f.register(list[int] | str, lambda arg: "types.UnionTypes(types.GenericAlias)")
with self.assertRaisesRegex(TypeError, "Invalid first argument to "):
f.register(typing.List[float] | bytes, lambda arg: "typing.Union[typing.GenericAlias]")
- with self.assertRaisesRegex(TypeError, "Invalid first argument to "):
- f.register(typing.Any, lambda arg: "typing.Any")
self.assertEqual(f([1]), "default")
self.assertEqual(f([1.0]), "default")
f.register(list[int] | str)
with self.assertRaisesRegex(TypeError, "Invalid first argument to "):
f.register(typing.List[int] | str)
- with self.assertRaisesRegex(TypeError, "Invalid first argument to "):
- f.register(typing.Any)
def test_register_genericalias_annotation(self):
@functools.singledispatch
@f.register
def _(arg: typing.List[float] | bytes):
return "typing.Union[typing.GenericAlias]"
- with self.assertRaisesRegex(TypeError, "Invalid annotation for 'arg'"):
- @f.register
- def _(arg: typing.Any):
- return "typing.Any"
self.assertEqual(f([1]), "default")
self.assertEqual(f([1.0]), "default")
self.assertIn(types.UnionType.__doc__.strip().splitlines()[0], doc)
def test_special_form(self):
- self.assertEqual(pydoc.describe(typing.Any), '_SpecialForm')
- doc = pydoc.render_doc(typing.Any, renderer=pydoc.plaintext)
+ self.assertEqual(pydoc.describe(typing.NoReturn), '_SpecialForm')
+ doc = pydoc.render_doc(typing.NoReturn, renderer=pydoc.plaintext)
self.assertIn('_SpecialForm in module typing', doc)
- if typing.Any.__doc__:
- self.assertIn('Any = typing.Any', doc)
- self.assertIn(typing.Any.__doc__.strip().splitlines()[0], doc)
+ if typing.NoReturn.__doc__:
+ self.assertIn('NoReturn = typing.NoReturn', doc)
+ self.assertIn(typing.NoReturn.__doc__.strip().splitlines()[0], doc)
else:
- self.assertIn('Any = class _SpecialForm(_Final)', doc)
+ self.assertIn('NoReturn = class _SpecialForm(_Final)', doc)
def test_typing_pydoc(self):
def foo(data: typing.List[typing.Any],
with self.assertRaises(TypeError):
isinstance(42, Any)
- def test_any_subclass_type_error(self):
- with self.assertRaises(TypeError):
- issubclass(Employee, Any)
- with self.assertRaises(TypeError):
- issubclass(Any, Employee)
-
def test_repr(self):
self.assertEqual(repr(Any), 'typing.Any')
with self.assertRaises(TypeError):
Any[int] # Any is not a generic type.
- def test_cannot_subclass(self):
- with self.assertRaises(TypeError):
- class A(Any):
- pass
- with self.assertRaises(TypeError):
- class A(type(Any)):
- pass
+ def test_can_subclass(self):
+ class Mock(Any): pass
+ self.assertTrue(issubclass(Mock, Any))
+ self.assertIsInstance(Mock(), Mock)
+
+ class Something: pass
+ self.assertFalse(issubclass(Something, Any))
+ self.assertNotIsInstance(Something(), Mock)
+
+ class MockSomething(Something, Mock): pass
+ self.assertTrue(issubclass(MockSomething, Any))
+ ms = MockSomething()
+ self.assertIsInstance(ms, MockSomething)
+ self.assertIsInstance(ms, Something)
+ self.assertIsInstance(ms, Mock)
def test_cannot_instantiate(self):
with self.assertRaises(TypeError):
return self._getitem(self, *parameters)
-@_SpecialForm
-def Any(self, parameters):
+class _AnyMeta(type):
+ def __instancecheck__(self, obj):
+ if self is Any:
+ raise TypeError("typing.Any cannot be used with isinstance()")
+ return super().__instancecheck__(obj)
+
+ def __repr__(self):
+ return "typing.Any"
+
+
+class Any(metaclass=_AnyMeta):
"""Special type indicating an unconstrained type.
- Any is compatible with every type.
Note that all the above statements are true from the point of view of
static type checkers. At runtime, Any should not be used with instance
- or class checks.
+ checks.
"""
- raise TypeError(f"{self} is not subscriptable")
+ def __new__(cls, *args, **kwargs):
+ if cls is Any:
+ raise TypeError("Any cannot be instantiated")
+ return super().__new__(cls, *args, **kwargs)
+
@_SpecialForm
def NoReturn(self, parameters):
--- /dev/null
+Allow subclassing of :class:`typing.Any`. Patch by Shantanu Jain.