Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Make Any a proper class instead of an alias to object() #13520

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

grievejia
Copy link
Contributor

At runtime, typing.Any is an actual class, not an object. Currently typeshed says Any = object() which seems wrong given it's not valid Python to use object() as type annotations, e.g.

def test0() -> object(): ...  # ERROR! `object()` is not a valid type

MyAny = object()
def test1() -> MyAny:  # ERROR! `MyAny` is not a valid type

from typing import Any
def test2() -> Any: ...  # This should be OK, but it's not if we strictly follow the `Any = object()` alias

I'm guessing that existing type checkers probably had some special cases for typing.Any to make it work. But if we define it right we could probably get rid of the special cases.

We ran into this issue when working on Pyre2.

This comment has been minimized.

@JelleZijlstra
Copy link
Member

This is technically more accurate but as you can see it interacts poorly with the existing special casing in some type checkers. Any is a type system primitive and needs to be special-cased in type checkers anyway; it might make more practical sense to stick with the existing definition.

@hauntsaninja
Copy link
Collaborator

From a mypy perspective, based on primer this is actually probably an improvement (at least on 3.11+, and maybe depending on what you think TypeForm semantics should be).

pyright seems pretty unhappy though.

Copy link
Contributor

Diff from mypy_primer, showing the effect of this PR on open source code:

sphinx (https://github.com/sphinx-doc/sphinx)
+ sphinx/config.py:631: error: Unused "type: ignore" comment  [unused-ignore]

ibis (https://github.com/ibis-project/ibis)
- ibis/expr/operations/__init__.py:13: error: Incompatible import of "Any" (imported name has type "type[ibis.expr.operations.reductions.Any]", local name has type "<typing special form>")  [assignment]
+ ibis/expr/operations/__init__.py:13: error: Incompatible import of "Any" (imported name has type "type[ibis.expr.operations.reductions.Any]", local name has type "type[typing.Any]")  [assignment]
- ibis/expr/types/logical.py:333: error: "<typing special form>" not callable  [operator]
+ ibis/expr/types/logical.py:333: error: Too many arguments for "Any"  [call-arg]
+ ibis/expr/types/logical.py:333: error: Unexpected keyword argument "where" for "Any"  [call-arg]
+ note: "Any" defined here
+ ibis/expr/types/logical.py:340: error: "Any" has no attribute "to_expr"  [attr-defined]
- ibis/backends/polars/compiler.py:745: error: No overload variant of "register" of "_SingleDispatchCallable" matches argument types "object", "Callable[[Any, KwArg(Any)], Any]"  [call-overload]
- ibis/backends/polars/compiler.py:745: note: Possible overload variants:
- ibis/backends/polars/compiler.py:745: note:     def register(self, cls: type[Any], func: None = ...) -> Callable[[Callable[..., Any]], Callable[..., Any]]
- ibis/backends/polars/compiler.py:745: note:     def register(self, cls: Callable[..., Any], func: None = ...) -> Callable[..., Any]
- ibis/backends/polars/compiler.py:745: note:     def register(self, cls: type[Any], func: Callable[..., Any]) -> Callable[..., Any]

prefect (https://github.com/PrefectHQ/prefect)
- src/prefect/server/events/actions.py:101: error: Unsupported left operand type for | ("<typing special form>")  [operator]
+ src/prefect/server/events/actions.py:101: error: Unsupported left operand type for | ("type[Any]")  [operator]

artigraph (https://github.com/artigraph/artigraph)
- src/arti/internal/type_hints.py:54: error: Non-overlapping identity check (left operand type: "type", right operand type: "<typing special form>")  [comparison-overlap]
- src/arti/internal/type_hints.py:55: error: Non-overlapping identity check (left operand type: "type", right operand type: "<typing special form>")  [comparison-overlap]

steam.py (https://github.com/Gobot1234/steam.py)
- steam/ext/commands/converters.py:510: error: Incompatible types in assignment (expression has type "<typing special form>", variable has type "type[T]")  [assignment]
+ steam/ext/commands/converters.py:510: error: Incompatible types in assignment (expression has type "type[Any]", variable has type "type[T]")  [assignment]

hydra-zen (https://github.com/mit-ll-responsible-ai/hydra-zen)
- src/hydra_zen/structured_configs/_implementations.py:3252: error: List comprehension has incompatible type List[tuple[str, Any | <typing special form>, Any | Field[Any]]]; expected List[tuple[str, type] | tuple[str, type, Any]]  [misc]

mypy (https://github.com/python/mypy)
+ mypy/stubgenc.py:764: error: Unused "type: ignore" comment  [unused-ignore]

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants