[ty] Completely ignore typeshed's stub for Any (#20079)

This commit is contained in:
Alex Waygood 2025-08-25 15:27:55 +01:00 committed by GitHub
parent d0bcf56bd9
commit a04823cfad
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 134 additions and 105 deletions

View file

@ -137,6 +137,22 @@ from unittest.mock import MagicMock
x: int = MagicMock()
```
## Runtime properties
`typing.Any` is a class at runtime on Python 3.11+, and `typing_extensions.Any` is always a class.
On earlier versions of Python, `typing.Any` was an instance of `typing._SpecialForm`, but this is
not currently modeled by ty. We currently infer `Any` has having all attributes a class would have
on all versions of Python:
```py
from typing import Any
from ty_extensions import TypeOf, static_assert, is_assignable_to
reveal_type(Any.__base__) # revealed: type | None
reveal_type(Any.__bases__) # revealed: tuple[type, ...]
static_assert(is_assignable_to(TypeOf[Any], type))
```
## Invalid
`Any` cannot be parameterized:
@ -144,7 +160,32 @@ x: int = MagicMock()
```py
from typing import Any
# error: [invalid-type-form] "Type `typing.Any` expected no type parameter"
# error: [invalid-type-form] "Special form `typing.Any` expected no type parameter"
def f(x: Any[int]):
reveal_type(x) # revealed: Unknown
```
`Any` cannot be called (this leads to a `TypeError` at runtime):
```py
Any() # error: [call-non-callable] "Object of type `typing.Any` is not callable"
```
`Any` also cannot be used as a metaclass (under the hood, this leads to an implicit call to `Any`):
```py
class F(metaclass=Any): ... # error: [invalid-metaclass] "Metaclass type `typing.Any` is not callable"
```
And `Any` cannot be used in `isinstance()` checks:
```py
# error: [invalid-argument-type] "`typing.Any` cannot be used with `isinstance()`: This call will raise `TypeError` at runtime"
isinstance("", Any)
```
But `issubclass()` checks are fine:
```py
issubclass(object, Any) # no error!
```

View file

@ -221,11 +221,11 @@ static_assert(is_assignable_to(type[Unknown], Meta))
static_assert(is_assignable_to(Meta, type[Any]))
static_assert(is_assignable_to(Meta, type[Unknown]))
class AnyMeta(metaclass=Any): ...
static_assert(is_assignable_to(type[AnyMeta], type))
static_assert(is_assignable_to(type[AnyMeta], type[object]))
static_assert(is_assignable_to(type[AnyMeta], type[Any]))
def _(x: Any):
class AnyMeta(metaclass=x): ...
static_assert(is_assignable_to(type[AnyMeta], type))
static_assert(is_assignable_to(type[AnyMeta], type[object]))
static_assert(is_assignable_to(type[AnyMeta], type[Any]))
from typing import TypeVar, Generic, Any