GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Add type signatures to `lru_cache` using descriptor protocol (not ready to merge) by alwaysmpe · Pull Request #13043 · python/typeshed

Conversation

@alwaysmpe

@alwaysmpe alwaysmpe commented Nov 18, 2024 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

This is an alternate approach to #13033 (appologies for multiple PRs, tricky problem).

That approach tries to solve the problem using multiple overloads but has some limitations, this has different limitations.

This changes lru_cache callable signature to use ParamSpec. Also provides descriptor protocol __get__ functions that match the behaviour of methods/classmethods/staticmethods as appropriate to bind the first parameter in the call signature. This is more robust/resistant to false positives because the first parameter should only be bindable as a method if it matches the type of object through which its accessed, likewise binding of classmethods. And a pure member variable should not use descriptor getters. This possibly depends on a very precise interpretation of the typing standard so I may be wrong.

So far from what I've found in pyright this works well with a few exceptions. overloads don't behave well with this cache. staticmethods that take as a first argument the type of the enclosing class have the first parameter bound when accessed through both the class and an instance. staticmethods that take as a first argument an instance of the enclosing class have the first parameter bound when accessed through an instance.

From what I've found in mypy, if cache is combined with property it causes a type error. Overloads cause problems. Likewise problem with staticmethod taking enclosing type or instance as first parameter.

The overload problem may be fixable in type checkers but I believe Eric from pyright has a proposal to clarify the typing spec for overloads, so nothing is likely to change before that. The staticmethod problem isn't very fixable.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@alwaysmpe
Add types to lru_cache by implementing descriptor protocol
155f837
WIP

Tidy

Fix ignores
@alwaysmpe alwaysmpe mentioned this pull request Nov 18, 2024
Add type signatures to lru_cache using overloads (not ready to merge) #13033
Closed
@pre-commit-ci
[pre-commit.ci] auto fixes from pre-commit.com hooks
d309de4
@github-actions

github-actions Bot commented Nov 18, 2024

Copy link
Copy Markdown
Contributor

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

dacite (https://github.com/konradhalas/dacite)
+ dacite/types.py:19: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "Callable[[type[Any]], type[Any]]"; expected "Never"  [arg-type]
+ dacite/types.py:27: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "Callable[[type[Any]], bool]"; expected "Never"  [arg-type]
+ dacite/types.py:29: error: "Never" not callable  [misc]
+ dacite/types.py:32: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "Callable[[type[T] | type[None]], T]"; expected "Never"  [arg-type]
+ dacite/types.py:34: error: "Never" not callable  [misc]
+ dacite/types.py:41: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "Callable[[type[Any]], bool]"; expected "Never"  [arg-type]
+ dacite/types.py:46: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "Callable[[type[Any]], bool]"; expected "Never"  [arg-type]
+ dacite/types.py:48: error: "Never" not callable  [misc]
+ dacite/types.py:59: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "Callable[[type[Any]], bool]"; expected "Never"  [arg-type]
+ dacite/types.py:61: error: "Never" not callable  [misc]
+ dacite/types.py:64: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "Callable[[type[Any]], bool]"; expected "Never"  [arg-type]
+ dacite/types.py:69: error: "Never" not callable  [misc]
+ dacite/types.py:74: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "Callable[[type[Any]], bool]"; expected "Never"  [arg-type]
+ dacite/types.py:79: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "Callable[[type[Any]], type[Any]]"; expected "Never"  [arg-type]
+ dacite/types.py:84: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "Callable[[type[Any]], bool]"; expected "Never"  [arg-type]
+ dacite/types.py:89: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "Callable[[type[Any]], type[Any] | Any]"; expected "Never"  [arg-type]
+ dacite/types.py:106: error: "Never" not callable  [misc]
+ dacite/types.py:107: error: "Never" not callable  [misc]
+ dacite/types.py:108: error: "Never" not callable  [misc]
+ dacite/types.py:109: error: "Never" not callable  [misc]
+ dacite/types.py:112: error: "Never" not callable  [misc]
+ dacite/types.py:114: error: "Never" not callable  [misc]
+ dacite/types.py:115: error: "Never" not callable  [misc]
+ dacite/types.py:125: error: "Never" not callable  [misc]
+ dacite/types.py:130: error: "Never" not callable  [misc]
+ dacite/types.py:131: error: "Never" not callable  [misc]
+ dacite/types.py:132: error: "Never" not callable  [misc]
+ dacite/types.py:133: error: "Never" not callable  [misc]
+ dacite/types.py:134: error: "Never" not callable  [misc]
+ dacite/types.py:135: error: "Never" not callable  [misc]
+ dacite/types.py:136: error: "Never" not callable  [misc]
+ dacite/types.py:137: error: "Never" not callable  [misc]
+ dacite/types.py:138: error: "Never" not callable  [misc]
+ dacite/types.py:143: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "Callable[[type[Any]], bool]"; expected "Never"  [arg-type]
+ dacite/types.py:145: error: "Never" not callable  [misc]
+ dacite/types.py:147: error: "Never" not callable  [misc]
+ dacite/types.py:154: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "Callable[[type[Any], tuple[Any, ...]], tuple[Any, ...]]"; expected "Never"  [arg-type]
+ dacite/types.py:166: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "Callable[[type[Any], type[Any]], bool]"; expected "Never"  [arg-type]
+ dacite/types.py:168: error: "Never" not callable  [misc]
+ dacite/types.py:169: error: "Never" not callable  [misc]
+ dacite/types.py:176: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "Callable[[type[Any]], bool]"; expected "Never"  [arg-type]
+ dacite/exceptions.py:6: error: "Never" not callable  [misc]
+ dacite/dataclasses.py:19: error: "Never" not callable  [misc]
+ dacite/dataclasses.py:24: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "Callable[[type[T]], list[Field[Any]]]"; expected "Never"  [arg-type]
+ dacite/dataclasses.py:30: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "Callable[[type[T]], bool]"; expected "Never"  [arg-type]
+ dacite/core.py:51: error: "Never" not callable  [misc]
+ dacite/core.py:51: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "Callable[[object | Callable[..., Any] | FunctionType | BuiltinFunctionType | MethodType | Module | WrapperDescriptorType | MethodWrapperType | MethodDescriptorType, dict[str, Any] | None, Mapping[str, Any] | None, bool], dict[str, Any]]"; expected "Never"  [arg-type]
+ dacite/core.py:54: error: "Never" not callable  [misc]
+ dacite/core.py:79: error: "Never" not callable  [misc]
+ dacite/core.py:88: error: "Never" not callable  [misc]
+ dacite/core.py:89: error: "Never" not callable  [misc]
+ dacite/core.py:92: error: "Never" not callable  [misc]
+ dacite/core.py:94: error: "Never" not callable  [misc]
+ dacite/core.py:96: error: "Never" not callable  [misc]
+ dacite/core.py:98: error: "Never" not callable  [misc]
+ dacite/core.py:98: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type overloaded function; expected "Never"  [arg-type]
+ dacite/core.py:101: error: "Never" not callable  [misc]
+ dacite/core.py:102: error: "Never" not callable  [misc]
+ dacite/core.py:103: error: "Never" not callable  [misc]
+ dacite/core.py:111: error: "Never" not callable  [misc]
+ dacite/core.py:112: error: "Never" not callable  [misc]
+ dacite/core.py:140: error: "Never" not callable  [misc]
+ dacite/core.py:141: error: "Never" not callable  [misc]
+ dacite/core.py:143: error: "Never" not callable  [misc]
+ dacite/core.py:146: error: "Never" not callable  [misc]
+ dacite/core.py:152: error: "Never" not callable  [misc]
+ dacite/core.py:153: error: "Never" not callable  [misc]

pylint (https://github.com/pycqa/pylint)
+ pylint/checkers/utils.py:2312: error: "_lru_cache_wrapper" expects 2 type arguments, but 1 given  [type-arg]
+ pylint/checkers/utils.py:2312: error: Missing type parameters for generic type "_lru_cache_wrapper"  [type-arg]

psycopg (https://github.com/psycopg/psycopg)
+ psycopg/psycopg/rows.py:143: error: Argument 2 to "__call__" of "_lru_cache_wrapper" has incompatible type "*Generator[bytes | None, None, None]"; expected "bytes"  [arg-type]
+ psycopg/psycopg/types/enum.py:153: error: Need type annotation for "loader"  [var-annotated]
+ psycopg/psycopg/types/enum.py:153: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "str"; expected "Never"  [arg-type]
+ psycopg/psycopg/types/enum.py:153: error: Argument 2 to "__call__" of "_lru_cache_wrapper" has incompatible type "type[E]"; expected "Never"  [arg-type]
+ psycopg/psycopg/types/enum.py:153: error: Argument 3 to "__call__" of "_lru_cache_wrapper" has incompatible type "tuple[tuple[bytes, E], ...]"; expected "Never"  [arg-type]
+ psycopg/psycopg/types/enum.py:156: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "str"; expected "Never"  [arg-type]
+ psycopg/psycopg/types/enum.py:156: error: Argument 2 to "__call__" of "_lru_cache_wrapper" has incompatible type "type[E]"; expected "Never"  [arg-type]
+ psycopg/psycopg/types/enum.py:156: error: Argument 3 to "__call__" of "_lru_cache_wrapper" has incompatible type "tuple[tuple[bytes, E], ...]"; expected "Never"  [arg-type]
+ psycopg/psycopg/types/enum.py:161: error: Need type annotation for "dumper"  [var-annotated]
+ psycopg/psycopg/types/enum.py:161: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "type[E]"; expected "Never"  [arg-type]
+ psycopg/psycopg/types/enum.py:161: error: Argument 2 to "__call__" of "_lru_cache_wrapper" has incompatible type "int"; expected "Never"  [arg-type]
+ psycopg/psycopg/types/enum.py:161: error: Argument 3 to "__call__" of "_lru_cache_wrapper" has incompatible type "tuple[tuple[E, bytes], ...]"; expected "Never"  [arg-type]
+ psycopg/psycopg/types/enum.py:164: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "type[E]"; expected "Never"  [arg-type]
+ psycopg/psycopg/types/enum.py:164: error: Argument 2 to "__call__" of "_lru_cache_wrapper" has incompatible type "int"; expected "Never"  [arg-type]
+ psycopg/psycopg/types/enum.py:164: error: Argument 3 to "__call__" of "_lru_cache_wrapper" has incompatible type "tuple[tuple[E, bytes], ...]"; expected "Never"  [arg-type]

prefect (https://github.com/PrefectHQ/prefect)
- src/prefect/settings/legacy.py:105: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "type[PrefectBaseSettings]"; expected "Hashable"  [arg-type]
- src/prefect/settings/legacy.py:105: note: Following member(s) of "PrefectBaseSettings" have conflicts:
- src/prefect/settings/legacy.py:105: note:     Expected:
- src/prefect/settings/legacy.py:105: note:         def __hash__() -> int
- src/prefect/settings/legacy.py:105: note:     Got:
- src/prefect/settings/legacy.py:105: note:         def __hash__(self: object) -> int
- src/prefect/settings/legacy.py:105: note:     Expected:
- src/prefect/settings/legacy.py:105: note:         def __hash__() -> int
- src/prefect/settings/legacy.py:105: note:     Got:
- src/prefect/settings/legacy.py:105: note:         def __hash__(self: object) -> int
- src/prefect/settings/legacy.py:136: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "type[PrefectBaseSettings]"; expected "Hashable"  [arg-type]
- src/prefect/settings/legacy.py:136: note: Following member(s) of "PrefectBaseSettings" have conflicts:
- src/prefect/settings/legacy.py:136: note:     Expected:
- src/prefect/settings/legacy.py:136: note:         def __hash__() -> int
- src/prefect/settings/legacy.py:136: note:     Got:
- src/prefect/settings/legacy.py:136: note:         def __hash__(self: object) -> int
- src/prefect/settings/legacy.py:136: note:     Expected:
- src/prefect/settings/legacy.py:136: note:         def __hash__() -> int
- src/prefect/settings/legacy.py:136: note:     Got:
- src/prefect/settings/legacy.py:136: note:         def __hash__(self: object) -> int

ibis (https://github.com/ibis-project/ibis)
+ ibis/backends/tests/test_temporal.py:2162: error: Argument "exclude" to "__call__" of "_lru_cache_wrapper" has incompatible type "tuple[str, str]"; expected "tuple[str]"  [arg-type]
+ ibis/backends/tests/test_temporal.py:2180: error: Argument "exclude" to "__call__" of "_lru_cache_wrapper" has incompatible type "tuple[str, str, str, str, str, str]"; expected "tuple[str]"  [arg-type]

pandas (https://github.com/pandas-dev/pandas)
+ pandas/core/dtypes/cast.py:591: error: Unused "type: ignore" comment  [unused-ignore]
+ pandas/core/apply.py:1004: error: Unused "type: ignore" comment  [unused-ignore]

twine (https://github.com/pypa/twine)
+ twine/auth.py:93: error: Invalid self argument "Resolver" to attribute function "username" with type "Callable[[VarArg(Never), KwArg(Never)], Never]"  [misc]
+ twine/settings.py:135: error: Invalid self argument "Resolver" to attribute function "username" with type "Callable[[VarArg(Never), KwArg(Never)], Never]"  [misc]
+ twine/settings.py:140: error: Invalid self argument "Resolver" to attribute function "password" with type "Callable[[VarArg(Never), KwArg(Never)], Never]"  [misc]

jinja (https://github.com/pallets/jinja)
+ src/jinja2/environment.py:1190: error: Argument 2 to "__call__" of "_lru_cache_wrapper" has incompatible type "str"; expected "Never"  [arg-type]
+ src/jinja2/environment.py:1191: error: Argument 3 to "__call__" of "_lru_cache_wrapper" has incompatible type "str"; expected "Never"  [arg-type]
+ src/jinja2/environment.py:1192: error: Argument 4 to "__call__" of "_lru_cache_wrapper" has incompatible type "str"; expected "Never"  [arg-type]
+ src/jinja2/environment.py:1193: error: Argument 5 to "__call__" of "_lru_cache_wrapper" has incompatible type "str"; expected "Never"  [arg-type]
+ src/jinja2/environment.py:1194: error: Argument 6 to "__call__" of "_lru_cache_wrapper" has incompatible type "str"; expected "Never"  [arg-type]
+ src/jinja2/environment.py:1195: error: Argument 7 to "__call__" of "_lru_cache_wrapper" has incompatible type "str"; expected "Never"  [arg-type]
+ src/jinja2/environment.py:1196: error: Argument 8 to "__call__" of "_lru_cache_wrapper" has incompatible type "Optional[str]"; expected "Never"  [arg-type]
+ src/jinja2/environment.py:1197: error: Argument 9 to "__call__" of "_lru_cache_wrapper" has incompatible type "Optional[str]"; expected "Never"  [arg-type]
+ src/jinja2/environment.py:1198: error: Argument 10 to "__call__" of "_lru_cache_wrapper" has incompatible type "bool"; expected "Never"  [arg-type]
+ src/jinja2/environment.py:1199: error: Argument 11 to "__call__" of "_lru_cache_wrapper" has incompatible type "bool"; expected "Never"  [arg-type]
+ src/jinja2/environment.py:1200: error: Argument 12 to "__call__" of "_lru_cache_wrapper" has incompatible type "Literal['\n', '\r\n', '\r']"; expected "Never"  [arg-type]
+ src/jinja2/environment.py:1201: error: Argument 13 to "__call__" of "_lru_cache_wrapper" has incompatible type "bool"; expected "Never"  [arg-type]
+ src/jinja2/environment.py:1202: error: Argument 14 to "__call__" of "_lru_cache_wrapper" has incompatible type "FrozenSet[Union[str, Type[Extension]]]"; expected "Never"  [arg-type]
+ src/jinja2/environment.py:1203: error: Argument 15 to "__call__" of "_lru_cache_wrapper" has incompatible type "bool"; expected "Never"  [arg-type]
+ src/jinja2/environment.py:1205: error: Argument 17 to "__call__" of "_lru_cache_wrapper" has incompatible type "Optional[Callable[..., Any]]"; expected "Never"  [arg-type]
+ src/jinja2/environment.py:1206: error: Argument 18 to "__call__" of "_lru_cache_wrapper" has incompatible type "Union[bool, Callable[[Optional[str]], bool]]"; expected "Never"  [arg-type]
+ src/jinja2/environment.py:1207: error: Argument 19 to "__call__" of "_lru_cache_wrapper" has incompatible type "None"; expected "Never"  [arg-type]
+ src/jinja2/environment.py:1208: error: Argument 20 to "__call__" of "_lru_cache_wrapper" has incompatible type "int"; expected "Never"  [arg-type]
+ src/jinja2/environment.py:1209: error: Argument 21 to "__call__" of "_lru_cache_wrapper" has incompatible type "bool"; expected "Never"  [arg-type]
+ src/jinja2/environment.py:1210: error: Argument 22 to "__call__" of "_lru_cache_wrapper" has incompatible type "None"; expected "Never"  [arg-type]
+ src/jinja2/environment.py:1211: error: Argument 23 to "__call__" of "_lru_cache_wrapper" has incompatible type "bool"; expected "Never"  [arg-type]

jax (https://github.com/google/jax)
+ jax/_src/dtypes.py:385: error: Unused "type: ignore" comment  [unused-ignore]
+ jax/_src/dtypes.py:386: error: Unused "type: ignore" comment  [unused-ignore]

mitmproxy (https://github.com/mitmproxy/mitmproxy)
+ mitmproxy/connection.py:193: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "str"; expected "Never"  [arg-type]
+ mitmproxy/utils/asyncio_utils.py:62: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "Any | str"; expected "tuple[Any, ...] | None"  [arg-type]
+ mitmproxy/tools/console/common.py:811: error: Argument "error_message" to "__call__" of "_lru_cache_wrapper" has incompatible type "str | None"; expected "str"  [arg-type]
+ mitmproxy/tools/console/common.py:848: error: Incompatible types in assignment (expression has type "_lru_cache_wrapper[Callable[[NamedArg(RenderMode, 'render_mode'), NamedArg(bool, 'focused'), NamedArg(str, 'marked'), NamedArg(str | None, 'is_replay'), NamedArg(str, 'request_method'), NamedArg(str, 'request_scheme'), NamedArg(str, 'request_host'), NamedArg(str, 'request_path'), NamedArg(str, 'request_url'), NamedArg(str, 'request_http_version'), NamedArg(float, 'request_timestamp'), NamedArg(bool, 'request_is_push_promise'), NamedArg(bool, 'intercepted'), NamedArg(int | None, 'response_code'), NamedArg(str | None, 'response_reason'), NamedArg(int | None, 'response_content_length'), NamedArg(str | None, 'response_content_type'), NamedArg(float | None, 'duration'), NamedArg(str | None, 'error_message')], Any], Callable[[NamedArg(RenderMode, 'render_mode'), NamedArg(bool, 'focused'), NamedArg(str, 'marked'), NamedArg(str | None, 'is_replay'), NamedArg(str, 'request_method'), NamedArg(str, 'request_scheme'), NamedArg(str, 'request_host'), NamedArg(str, 'request_path'), NamedArg(str, 'request_url'), NamedArg(str, 'request_http_version'), NamedArg(float, 'request_timestamp'), NamedArg(bool, 'request_is_push_promise'), NamedArg(bool, 'intercepted'), NamedArg(int | None, 'response_code'), NamedArg(str | None, 'response_reason'), NamedArg(int | None, 'response_content_length'), NamedArg(str | None, 'response_content_type'), NamedArg(float | None, 'duration'), NamedArg(str | None, 'error_message')], Any]]", variable has type "_lru_cache_wrapper[Callable[[NamedArg(RenderMode, 'render_mode'), NamedArg(bool, 'focused'), NamedArg(str, 'marked'), NamedArg(bool, 'is_replay'), NamedArg(str, 'request_method'), NamedArg(str, 'request_scheme'), NamedArg(str, 'request_host'), NamedArg(str, 'request_path'), NamedArg(str, 'request_url'), NamedArg(str, 'request_http_version'), NamedArg(float, 'request_timestamp'), NamedArg(bool, 'request_is_push_promise'), NamedArg(bool, 'intercepted'), NamedArg(int | None, 'response_code'), NamedArg(str | None, 'response_reason'), NamedArg(int | None, 'response_content_length'), NamedArg(str | None, 'response_content_type'), NamedArg(float | None, 'duration'), NamedArg(str | None, 'error_message')], Any], Callable[[NamedArg(RenderMode, 'render_mode'), NamedArg(bool, 'focused'), NamedArg(str, 'marked'), NamedArg(bool, 'is_replay'), NamedArg(str, 'request_method'), NamedArg(str, 'request_scheme'), NamedArg(str, 'request_host'), NamedArg(str, 'request_path'), NamedArg(str, 'request_url'), NamedArg(str, 'request_http_version'), NamedArg(float, 'request_timestamp'), NamedArg(bool, 'request_is_push_promise'), NamedArg(bool, 'intercepted'), NamedArg(int | None, 'response_code'), NamedArg(str | None, 'response_reason'), NamedArg(int | None, 'response_content_length'), NamedArg(str | None, 'response_content_type'), NamedArg(float | None, 'duration'), NamedArg(str | None, 'error_message')], Any]]")  [assignment]
+ mitmproxy/tools/console/common.py:853: error: Argument "is_replay" to "__call__" of "_lru_cache_wrapper" has incompatible type "str | None"; expected "bool"  [arg-type]
+ mitmproxy/test/tflow.py:134: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "str"; expected "Never"  [arg-type]
+ mitmproxy/test/tflow.py:235: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "str"; expected "Never"  [arg-type]
+ mitmproxy/proxy/server.py:582: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "str"; expected "Never"  [arg-type]
+ mitmproxy/proxy/mode_servers.py:115: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "str"; expected "Never"  [arg-type]
+ mitmproxy/addons/clientplayback.py:98: error: Need type annotation for "mode"  [var-annotated]
+ mitmproxy/addons/proxyserver.py:109: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "str"; expected "Never"  [arg-type]
+ mitmproxy/master.py:135: error: Need type annotation for "mode"  [var-annotated]

cki-lib (https://gitlab.com/cki-project/cki-lib)
+ cki_lib/gitlab.py:95: error: Too many arguments for "__call__" of "_lru_cache_wrapper"  [call-arg]
+ cki_lib/gitlab.py:95: note: Looks like the first special argument in a method is not named "self", "cls", or "mcs", maybe it is missing?

rich (https://github.com/Textualize/rich)
+ rich/progress_bar.py:145: error: Argument 3 to "__call__" of "_lru_cache_wrapper" has incompatible type "str | None"; expected "str"  [arg-type]

schemathesis (https://github.com/schemathesis/schemathesis)
+ src/schemathesis/stateful/state_machine.py: note: In class "APIStateMachine":
+ src/schemathesis/stateful/state_machine.py:68: error: Signature of "_to_test_case" incompatible with supertype "RuleBasedStateMachine"  [override]
+ src/schemathesis/stateful/state_machine.py:68: note:      Superclass:
+ src/schemathesis/stateful/state_machine.py:68: note:          _lru_cache_wrapper[Callable[[Type[RuleBasedStateMachine]], Any], Callable[[Type[RuleBasedStateMachine]], Any]]
+ src/schemathesis/stateful/state_machine.py:68: note:      Subclass:
+ src/schemathesis/stateful/state_machine.py:68: note:          _lru_cache_wrapper[Callable[[Type[APIStateMachine]], type], Callable[[Type[APIStateMachine]], type]]
+ src/schemathesis/specs/openapi/stateful/__init__.py: note: In function "create_state_machine":
+ src/schemathesis/specs/openapi/stateful/__init__.py:79: error: Argument 2 to "__call__" of "_lru_cache_wrapper" has incompatible type "Tuple[Any, ...]"; expected "Iterator[str]"  [arg-type]
+ src/schemathesis/specs/openapi/stateful/__init__.py:79: note: "tuple" is missing following "Iterator" protocol member:
+ src/schemathesis/specs/openapi/stateful/__init__.py:79: note:     __next__
+ src/schemathesis/specs/openapi/stateful/__init__.py: note: At top level:

pip (https://github.com/pypa/pip)
+ src/pip/_internal/index/package_finder.py:902: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "str | None"; expected "str"  [arg-type]
+ src/pip/_internal/resolution/resolvelib/provider.py:242: error: Signature of "is_satisfied_by" incompatible with supertype "AbstractProvider"  [override]
+ src/pip/_internal/resolution/resolvelib/provider.py:242: note:      Superclass:
+ src/pip/_internal/resolution/resolvelib/provider.py:242: note:          def is_satisfied_by(self, requirement: Requirement, candidate: Candidate) -> bool
+ src/pip/_internal/resolution/resolvelib/provider.py:242: note:      Subclass:
+ src/pip/_internal/resolution/resolvelib/provider.py:242: note:          _lru_cache_wrapper[Callable[[PipProvider, Requirement, Candidate], bool], Callable[[PipProvider, Requirement, Candidate], bool]]

pydantic (https://github.com/pydantic/pydantic)
+ pydantic/v1/tools.py:37: error: Unused "type: ignore" comment  [unused-ignore]
- pydantic/networks.py:107: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "type[_BaseUrl]"; expected "Hashable"  [arg-type]
- pydantic/networks.py:107: note: Following member(s) of "_BaseUrl" have conflicts:
- pydantic/networks.py:107: note:     Expected:
- pydantic/networks.py:107: note:         def __hash__() -> int
- pydantic/networks.py:107: note:     Got:
- pydantic/networks.py:107: note:         def __hash__(self: object) -> int
- pydantic/networks.py:291: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "type[_BaseMultiHostUrl]"; expected "Hashable"  [arg-type]
- pydantic/networks.py:291: note: Following member(s) of "_BaseMultiHostUrl" have conflicts:
- pydantic/networks.py:291: note:     Expected:
- pydantic/networks.py:291: note:         def __hash__() -> int
- pydantic/networks.py:291: note:     Got:
- pydantic/networks.py:291: note:         def __hash__(self: object) -> int

manticore (https://github.com/trailofbits/manticore)
+ manticore/core/smtlib/solver.py:505: error: Signature of "can_be_true" incompatible with supertype "Solver"  [override]
+ manticore/core/smtlib/solver.py:505: note:      Superclass:
+ manticore/core/smtlib/solver.py:505: note:          def can_be_true(self, constraints: Any, expression: Any = ...) -> bool
+ manticore/core/smtlib/solver.py:505: note:      Subclass:
+ manticore/core/smtlib/solver.py:505: note:          _lru_cache_wrapper[Callable[[SMTLIBSolver, ConstraintSet, bool | Bool], bool], Callable[[SMTLIBSolver, ConstraintSet, bool | Bool], bool]]
+ manticore/core/smtlib/solver.py:605: error: Signature of "get_all_values" incompatible with supertype "Solver"  [override]
+ manticore/core/smtlib/solver.py:605: note:      Superclass:
+ manticore/core/smtlib/solver.py:605: note:          def get_all_values(self, constraints: Any, x: Any, maxcnt: Any = ..., silent: Any = ...) -> Any
+ manticore/core/smtlib/solver.py:605: note:      Subclass:
+ manticore/core/smtlib/solver.py:605: note:          _lru_cache_wrapper[Callable[[SMTLIBSolver, ConstraintSet, Any, int | None, bool], Any], Callable[[SMTLIBSolver, ConstraintSet, Any, int | None, bool], Any]]

core (https://github.com/home-assistant/core)
+ homeassistant/util/unit_conversion.py:387: error: Signature of "converter_factory" incompatible with supertype "BaseUnitConverter"  [override]
+ homeassistant/util/unit_conversion.py:387: note:      Superclass:
+ homeassistant/util/unit_conversion.py:387: note:          _lru_cache_wrapper[Callable[[type[BaseUnitConverter], str | None, str | None], Callable[[float], float]], Callable[[type[BaseUnitConverter], str | None, str | None], Callable[[float], float]]]
+ homeassistant/util/unit_conversion.py:387: note:      Subclass:
+ homeassistant/util/unit_conversion.py:387: note:          _lru_cache_wrapper[Callable[[type[SpeedConverter], str | None, str | None], Callable[[float], float]], Callable[[type[SpeedConverter], str | None, str | None], Callable[[float], float]]]
+ homeassistant/util/unit_conversion.py:401: error: Signature of "converter_factory_allow_none" incompatible with supertype "BaseUnitConverter"  [override]
+ homeassistant/util/unit_conversion.py:401: note:      Superclass:
+ homeassistant/util/unit_conversion.py:401: note:          _lru_cache_wrapper[Callable[[type[BaseUnitConverter], str | None, str | None], Callable[[float | None], float | None]], Callable[[type[BaseUnitConverter], str | None, str | None], Callable[[float | None], float | None]]]
+ homeassistant/util/unit_conversion.py:401: note:      Subclass:
+ homeassistant/util/unit_conversion.py:401: note:          _lru_cache_wrapper[Callable[[type[SpeedConverter], str | None, str | None], Callable[[float | None], float | None]], Callable[[type[SpeedConverter], str | None, str | None], Callable[[float | None], float | None]]]
+ homeassistant/util/unit_conversion.py:467: error: Signature of "converter_factory" incompatible with supertype "BaseUnitConverter"  [override]
+ homeassistant/util/unit_conversion.py:467: note:      Superclass:
+ homeassistant/util/unit_conversion.py:467: note:          _lru_cache_wrapper[Callable[[type[BaseUnitConverter], str | None, str | None], Callable[[float], float]], Callable[[type[BaseUnitConverter], str | None, str | None], Callable[[float], float]]]
+ homeassistant/util/unit_conversion.py:467: note:      Subclass:
+ homeassistant/util/unit_conversion.py:467: note:          _lru_cache_wrapper[Callable[[type[TemperatureConverter], str | None, str | None], Callable[[float], float]], Callable[[type[TemperatureConverter], str | None, str | None], Callable[[float], float]]]
+ homeassistant/util/unit_conversion.py:481: error: Signature of "converter_factory_allow_none" incompatible with supertype "BaseUnitConverter"  [override]
+ homeassistant/util/unit_conversion.py:481: note:      Superclass:
+ homeassistant/util/unit_conversion.py:481: note:          _lru_cache_wrapper[Callable[[type[BaseUnitConverter], str | None, str | None], Callable[[float | None], float | None]], Callable[[type[BaseUnitConverter], str | None, str | None], Callable[[float | None], float | None]]]
+ homeassistant/util/unit_conversion.py:481: note:      Subclass:
+ homeassistant/util/unit_conversion.py:481: note:          _lru_cache_wrapper[Callable[[type[TemperatureConverter], str | None, str | None], Callable[[float | None], float | None]], Callable[[type[TemperatureConverter], str | None, str | None], Callable[[float | None], float | None]]]
+ homeassistant/core.py:1511: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "EventType[_DataT] | str"; expected "Never"  [arg-type]
+ homeassistant/core.py:1529: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "EventType[_DataT] | str"; expected "Never"  [arg-type]
+ homeassistant/auth/__init__.py:655: error: Invalid self argument "_lru_cache_wrapper[partial[dict[str, Any]], partial[dict[str, Any]]]" to attribute function "__call__" with type "Callable[[_lru_cache_wrapper[Callable[_P, _R], _W], **_P], _R]"  [misc]
+ homeassistant/components/xiaomi_aqara/config_flow.py:216: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "str | None"; expected "str"  [arg-type]
+ homeassistant/helpers/llm.py:408: error: Invalid self argument "_lru_cache_wrapper[partial[str], partial[str]]" to attribute function "__call__" with type "Callable[[_lru_cache_wrapper[Callable[_P, _R], _W], **_P], _R]"  [misc]
+ homeassistant/components/mqtt_room/sensor.py:199: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "Any | None"; expected "str"  [arg-type]
+ homeassistant/components/esphome/update.py:63: error: "Never" has no attribute "get_entry_data"  [attr-defined]
+ homeassistant/components/esphome/update.py:63: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "HomeAssistant"; expected "Never"  [arg-type]
+ homeassistant/components/esphome/light.py:178: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "tuple[int, ...]"; expected "list[int]"  [arg-type]
+ homeassistant/components/esphome/light.py:187: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "tuple[int, ...]"; expected "list[int]"  [arg-type]
+ homeassistant/components/esphome/light.py:198: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "tuple[int, ...]"; expected "list[int]"  [arg-type]
+ homeassistant/components/esphome/light.py:207: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "tuple[int, ...]"; expected "list[int]"  [arg-type]
+ homeassistant/components/esphome/light.py:208: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "tuple[int, ...]"; expected "list[int]"  [arg-type]
+ homeassistant/components/esphome/light.py:213: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "tuple[int, ...]"; expected "list[int]"  [arg-type]
+ homeassistant/components/esphome/light.py:225: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "tuple[int, ...]"; expected "list[int]"  [arg-type]
+ homeassistant/components/esphome/light.py:242: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "tuple[int, ...]"; expected "list[int]"  [arg-type]
+ homeassistant/components/esphome/light.py:247: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "tuple[int, ...]"; expected "list[int]"  [arg-type]
+ homeassistant/components/esphome/light.py:261: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "tuple[int, ...]"; expected "list[int]"  [arg-type]
+ homeassistant/components/esphome/light.py:342: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "tuple[int, ...]"; expected "list[int]"  [arg-type]
+ homeassistant/components/esphome/__init__.py:61: error: Need type annotation for "domain_data"  [var-annotated]
+ homeassistant/components/esphome/__init__.py:61: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "HomeAssistant"; expected "Never"  [arg-type]
+ homeassistant/components/esphome/__init__.py:89: error: "Never" has no attribute "get_or_create_store"  [attr-defined]
+ homeassistant/components/esphome/__init__.py:89: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "HomeAssistant"; expected "Never"  [arg-type]
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

alwaysmpe
alwaysmpe commented Nov 18, 2024
View reviewed changes

@alwaysmpe alwaysmpe left a comment

Copy link
Copy Markdown
Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have noted where this fails the tests I've added, may be something I've missed but tried quite hard to break it.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread stdlib/@tests/test_cases/check_lru_cache.py
Comment on lines +137 to +146
# incorrect type error. If a static method
# takes the type of the enclosing class as
# the first argument there's a false positive.
CFnCls.st_fn_clst_arg(CFnCls)
CFnSubCls.st_fn_clst_arg(CFnSubCls)
# If a static method takes an instance of the
# enclosing class as its first argument,
# there's an error if accessed via an instance.
CFnSubCls.st_fn_self_t_arg(CFnSubCls())
CFnSubCls().st_fn_self_t_arg(CFnSubCls())

@alwaysmpe alwaysmpe Nov 18, 2024

Copy link
Copy Markdown
Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This probably isn't fixable but may be acceptable. Error in both mypy & pyright.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread stdlib/@tests/test_cases/check_lru_cache.py Outdated

if TYPE_CHECKING:
# This is not correctly rejected.
no_cache(Unhashable(), 2) # type: ignore[arg-type] # pyright: ignore[reportArgumentType]

@alwaysmpe alwaysmpe Nov 18, 2024

Copy link
Copy Markdown
Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This approach loses the previous hashable requirement so this is a false negative.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread stdlib/@tests/test_cases/check_lru_cache.py
Comment on lines +203 to +204
assert_type(fn_overload(1), int)
assert_type(fn_overload("1"), str)

@alwaysmpe alwaysmpe Nov 18, 2024

Copy link
Copy Markdown
Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overloads don't work well with this change. In pyright types are resolved as int | str but cache_clear is correctly accessible.

Mypy correctly resolves return type but cache_clear isn't accessible.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread stdlib/@tests/test_cases/check_lru_cache.py

def set_member(lhs: MemberVarBound[..., Any], rhs: MemberVarBound[..., Any]) -> None:
lhs.member_fn = rhs.equals
lhs.member_fn(rhs)

@alwaysmpe alwaysmpe Nov 18, 2024

Copy link
Copy Markdown
Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mypy doesn't resolve the callable type signature but pyright does, so this raises an error in mypy. Not sure why.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread stdlib/@tests/test_cases/check_lru_cache.py
assert_type(cfn_inst.fn(1), int)
assert_type(CFnCls.st_fn(1), int)
assert_type(CFnCls.cls_fn(1), int)
assert_type(cfn_inst.prp_fn, int)

@alwaysmpe alwaysmpe Nov 18, 2024

Copy link
Copy Markdown
Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mypy is erroring on using property with cache. pyright is fine. Not sure why. There's also cached_property but this is a valid use case too.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@alwaysmpe

alwaysmpe commented Nov 18, 2024 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Author

Looking at primer output:

dacite errors are same as alternate approach, erroring because they're using a TypeVar bound to Callable without any type parameters, so the implicit type arguments are Never (the empty type), so I lean towards true positive error

pylint errors because the class template arguments have changed.

prefect errors lost because there's nolonger a hashable requirement.

twine is erroring because they're combining cache and property.

jinja seems to be a problem, they're using *args but only one parameter is accepted.

Not sure why mitmproxy/connection.py:193 is erroring

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@alwaysmpe

alwaysmpe commented Nov 25, 2024

Copy link
Copy Markdown
Author

Closing this. The correct approach is for builtin descriptor type definitions to match their runtime descriptor protocol behaviour but mypy (and I believe other type checkers) don't currently understand it correctly. So I'll try to fix that first. If interested I discuss this on typing forum

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@alwaysmpe alwaysmpe closed this Nov 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

1 participant

@alwaysmpe
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.