Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

functools: Add typing for decorated function arguments in cache API #9768

Closed
wants to merge 7 commits into from

Conversation

asvetlov
Copy link
Contributor

functools.cache() and functools.lru_cache() are affected.

@github-actions

This comment has been minimized.

@asvetlov
Copy link
Contributor Author

Interesting.
The diff demonstrates that types from instancemethods (and functools.partial objects maybe) are not deducted well.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions
Copy link
Contributor

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

pip (https://github.com/pypa/pip)
+ src/pip/_internal/metadata/base.py:406: error: Too few arguments  [call-arg]
+ src/pip/_internal/models/link.py:220: error: Missing positional argument "url" in call to "__call__" of "_lru_cache_wrapper"  [call-arg]
+ src/pip/_internal/models/link.py:220: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "str"; expected "Type[LinkHash]"  [arg-type]
+ src/pip/_internal/models/link.py:408: error: Missing positional argument "url" in call to "__call__" of "_lru_cache_wrapper"  [call-arg]
+ src/pip/_internal/models/link.py:408: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "str"; expected "Type[LinkHash]"  [arg-type]
+ src/pip/_internal/req/req_install.py:505: error: Too few arguments  [call-arg]
+ src/pip/_internal/req/req_install.py:531: error: Too few arguments  [call-arg]
+ src/pip/_internal/index/package_finder.py:890: error: Too few arguments  [call-arg]
+ src/pip/_internal/index/package_finder.py:890: error: Argument 1 has incompatible type "str"; expected "PackageFinder"  [arg-type]
+ src/pip/_internal/index/package_finder.py:908: error: Too few arguments  [call-arg]
+ src/pip/_internal/index/package_finder.py:909: error: Argument 1 has incompatible type "Optional[str]"; expected "PackageFinder"  [arg-type]
+ src/pip/_internal/self_outdated_check.py:177: error: Too few arguments  [call-arg]
+ src/pip/_internal/self_outdated_check.py:177: error: Argument 1 has incompatible type "str"; expected "PackageFinder"  [arg-type]
+ src/pip/_internal/wheel_builder.py:79: error: Too few arguments  [call-arg]
+ src/pip/_internal/distributions/sdist.py:114: error: Too few arguments  [call-arg]
+ src/pip/_internal/resolution/resolvelib/factory.py:279: error: Too few arguments  [call-arg]
+ src/pip/_internal/resolution/resolvelib/factory.py:604: error: Too few arguments  [call-arg]
+ src/pip/_internal/resolution/resolvelib/factory.py:604: error: Argument 1 has incompatible type "NormalizedName"; expected "PackageFinder"  [arg-type]
+ src/pip/_internal/commands/list.py:236: error: Too few arguments  [call-arg]
+ src/pip/_internal/commands/list.py:236: error: Argument 1 has incompatible type "NormalizedName"; expected "PackageFinder"  [arg-type]
+ src/pip/_internal/commands/index.py:119: error: Too few arguments  [call-arg]

dacite (https://github.com/konradhalas/dacite)
+ dacite/core.py:51: error: Argument "localns" to "get_type_hints" has incompatible type "Optional[FrozenDict]"; expected "Optional[Dict[str, Any]]"  [arg-type]

ibis (https://github.com/ibis-project/ibis)
+ ibis/backends/polars/__init__.py:240: error: Missing positional argument "cls" in call to "__call__" of "_lru_cache_wrapper"  [call-arg]
+ ibis/backends/datafusion/__init__.py:283: error: Missing positional argument "cls" in call to "__call__" of "_lru_cache_wrapper"  [call-arg]
+ ibis/backends/pandas/__init__.py:187: error: Missing positional argument "cls" in call to "__call__" of "_lru_cache_wrapper"  [call-arg]
+ ibis/backends/base/sql/__init__.py:376: error: Missing positional argument "cls" in call to "__call__" of "_lru_cache_wrapper"  [call-arg]
+ ibis/backends/duckdb/tests/conftest.py:19: error: Too few arguments  [call-arg]
+ ibis/backends/duckdb/tests/conftest.py:19: error: Argument 1 has incompatible type "Path"; expected "TestConf"  [arg-type]
+ ibis/backends/snowflake/tests/conftest.py:35: error: Too few arguments  [call-arg]
+ ibis/backends/snowflake/tests/conftest.py:35: error: Argument 1 has incompatible type "Path"; expected "TestConf"  [arg-type]

rich (https://github.com/Textualize/rich)
+ rich/theme.py:25: error: Missing positional argument "style_definition" in call to "__call__" of "_lru_cache_wrapper"  [call-arg]
+ rich/theme.py:25: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "str"; expected "Type[Style]"  [arg-type]
+ rich/theme.py:54: error: Missing positional argument "style_definition" in call to "__call__" of "_lru_cache_wrapper"  [call-arg]
+ rich/theme.py:54: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "str"; expected "Type[Style]"  [arg-type]
+ rich/style.py:147: error: Missing positional argument "color" in call to "__call__" of "_lru_cache_wrapper"  [call-arg]
+ rich/style.py:147: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "str"; expected "Type[Color]"  [arg-type]
+ rich/style.py:368: error: Too few arguments  [call-arg]
+ rich/style.py:368: error: Argument 1 has incompatible type "ColorSystem"; expected "Color"  [arg-type]
+ rich/style.py:371: error: Too few arguments  [call-arg]
+ rich/style.py:371: error: Argument 1 has incompatible type "ColorSystem"; expected "Color"  [arg-type]
+ rich/style.py:391: error: Missing positional argument "style_definition" in call to "__call__" of "_lru_cache_wrapper"  [call-arg]
+ rich/style.py:391: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "str"; expected "Type[Style]"  [arg-type]
+ rich/style.py:527: error: Missing positional argument "color" in call to "__call__" of "_lru_cache_wrapper"  [call-arg]
+ rich/style.py:527: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "str"; expected "Type[Color]"  [arg-type]
+ rich/style.py:554: error: Missing positional argument "color" in call to "__call__" of "_lru_cache_wrapper"  [call-arg]
+ rich/style.py:554: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "str"; expected "Type[Color]"  [arg-type]
+ rich/style.py:735: error: Too few arguments  [call-arg]
+ rich/style.py:735: error: Argument 1 has incompatible type "Optional[Style]"; expected "Style"  [arg-type]
+ rich/segment.py:169: error: Too few arguments  [call-arg]
+ rich/segment.py:169: error: Argument 2 has incompatible type "int"; expected "Type[Segment]"  [arg-type]
+ rich/markup.py:157: error: Missing positional argument "style" in call to "__call__" of "_lru_cache_wrapper"  [call-arg]
+ rich/markup.py:157: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "str"; expected "Type[Style]"  [arg-type]
+ rich/markup.py:214: error: Missing positional argument "style" in call to "__call__" of "_lru_cache_wrapper"  [call-arg]
+ rich/markup.py:214: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "str"; expected "Type[Style]"  [arg-type]
+ rich/jupyter.py:72: error: Too few arguments  [call-arg]
+ rich/jupyter.py:72: error: Argument 1 has incompatible type "TerminalTheme"; expected "Style"  [arg-type]
+ rich/console.py:1471: error: Missing positional argument "style_definition" in call to "__call__" of "_lru_cache_wrapper"  [call-arg]
+ rich/console.py:1471: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "str"; expected "Type[Style]"  [arg-type]
+ rich/console.py:2207: error: Too few arguments  [call-arg]
+ rich/console.py:2207: error: Argument 1 has incompatible type "TerminalTheme"; expected "Style"  [arg-type]
+ rich/console.py:2219: error: Too few arguments  [call-arg]
+ rich/console.py:2219: error: Argument 1 has incompatible type "TerminalTheme"; expected "Style"  [arg-type]
+ rich/color.py:552: error: Too few arguments  [call-arg]
+ rich/color.py:552: error: Argument 1 has incompatible type "ColorTriplet"; expected "Palette"  [arg-type]
+ rich/color.py:565: error: Too few arguments  [call-arg]
+ rich/color.py:565: error: Argument 1 has incompatible type "ColorTriplet"; expected "Palette"  [arg-type]
+ rich/ansi.py:172: error: Missing positional argument "style_definition" in call to "__call__" of "_lru_cache_wrapper"  [call-arg]
+ rich/ansi.py:172: error: Argument 1 to "__call__" of "_lru_cache_wrapper" has incompatible type "str"; expected "Type[Style]"  [arg-type]
+ rich/progress_bar.py:144: error: Too few arguments  [call-arg]
+ rich/progress_bar.py:145: error: Argument 1 has incompatible type "Style"; expected "ProgressBar"  [arg-type]
+ rich/progress_bar.py:145: error: Argument 2 has incompatible type "Style"; expected "ProgressBar"  [arg-type]
+ rich/progress_bar.py:145: error: Argument 3 has incompatible type "Optional[str]"; expected "Style"  [arg-type]
+ rich/progress_bar.py:145: error: Argument 4 has incompatible type "bool"; expected "Style"  [arg-type]

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:605: error: Signature of "get_all_values" incompatible with supertype "Solver"  [override]

cloud-init (https://github.com/canonical/cloud-init)
+ cloudinit/distros/freebsd.py:210: error: Too few arguments  [call-arg]
+ cloudinit/distros/freebsd.py:231: error: Too few arguments  [call-arg]

jax (https://github.com/google/jax)
+ jax/_src/sharding.py:138: error: Signature of "devices_indices_map" incompatible with supertype "Sharding"  [override]
+ jax/_src/sharding.py:149: error: Signature of "shard_shape" incompatible with supertype "Sharding"  [override]
+ jax/_src/sharding.py:353: error: Signature of "_to_xla_op_sharding" incompatible with supertype "XLACompatibleSharding"  [override]
+ jax/_src/sharding.py:507: error: Signature of "devices_indices_map" incompatible with supertype "XLACompatibleSharding"  [override]
+ jax/_src/sharding.py:507: error: Signature of "devices_indices_map" incompatible with supertype "Sharding"  [override]
+ jax/_src/sharding.py:519: error: Signature of "shard_shape" incompatible with supertype "XLACompatibleSharding"  [override]
+ jax/_src/sharding.py:519: error: Signature of "shard_shape" incompatible with supertype "Sharding"  [override]
+ jax/_src/sharding.py:596: error: Signature of "_to_xla_op_sharding" incompatible with supertype "XLACompatibleSharding"  [override]
+ jax/_src/sharding.py:692: error: Signature of "devices_indices_map" incompatible with supertype "XLACompatibleSharding"  [override]
+ jax/_src/sharding.py:692: error: Signature of "devices_indices_map" incompatible with supertype "Sharding"  [override]
+ jax/_src/interpreters/pxla.py:1943: error: Too few arguments  [call-arg]
+ jax/_src/interpreters/pxla.py:3158: error: Too few arguments  [call-arg]
+ jax/_src/interpreters/pxla.py:3158: note: Error code "call-arg" not covered by "type: ignore" comment
+ jax/_src/interpreters/pxla.py:3169: error: Too few arguments  [call-arg]
+ jax/_src/interpreters/pxla.py:3169: note: Error code "call-arg" not covered by "type: ignore" comment
+ jax/_src/interpreters/pxla.py:3855: error: Too few arguments  [call-arg]
+ jax/_src/pjit.py:2237: error: Too few arguments  [call-arg]
+ jax/_src/pjit.py:2237: error: Argument 1 has incompatible type "int"; expected "NamedSharding"  [arg-type]
+ jax/experimental/gda_serialization/serialization.py:51: error: Too few arguments  [call-arg]
+ jax/experimental/gda_serialization/serialization.py:51: error: Argument 1 has incompatible type "Tuple[int, ...]"; expected "XLACompatibleSharding"  [arg-type]

pandas (https://github.com/pandas-dev/pandas)
+ pandas/core/dtypes/cast.py:587: error: Unused "type: ignore" comment
+ pandas/core/groupby/ops.py:541: error: Too few arguments  [call-arg]
+ pandas/core/groupby/ops.py:541: error: Argument 1 has incompatible type "str"; expected "WrappedCythonOp"  [arg-type]
+ pandas/core/groupby/ops.py:541: error: Argument 2 has incompatible type "str"; expected "Type[WrappedCythonOp]"  [arg-type]
+ pandas/core/groupby/ops.py:541: error: Argument 4 has incompatible type "bool"; expected "str"  [arg-type]

pydantic (https://github.com/samuelcolvin/pydantic)
+ pydantic/tools.py:30: error: Unused "type: ignore" comment

aiohttp (https://github.com/aio-libs/aiohttp)
+ aiohttp/connector.py:931: error: Too few arguments  [call-arg]
+ aiohttp/connector.py:931: error: Argument 1 has incompatible type "bool"; expected "TCPConnector"  [arg-type]
+ aiohttp/connector.py:937: error: Too few arguments  [call-arg]
+ aiohttp/connector.py:937: error: Argument 1 has incompatible type "bool"; expected "TCPConnector"  [arg-type]
+ aiohttp/connector.py:938: error: Too few arguments  [call-arg]
+ aiohttp/connector.py:938: error: Argument 1 has incompatible type "bool"; expected "TCPConnector"  [arg-type]

pylint (https://github.com/pycqa/pylint)
+ pylint/utils/file_state.py:93: error: Too few arguments  [call-arg]
+ pylint/utils/file_state.py:93: error: Argument 1 has incompatible type "str"; expected "MessageDefinitionStore"  [arg-type]
+ pylint/message/message_definition_store.py:79: error: Too few arguments  [call-arg]
+ pylint/message/message_definition_store.py:79: error: Argument 1 has incompatible type "str"; expected "MessageDefinitionStore"  [arg-type]
+ pylint/message/message_definition_store.py:88: error: Too few arguments  [call-arg]
+ pylint/message/message_definition_store.py:89: error: Argument 1 has incompatible type "str"; expected "MessageDefinitionStore"  [arg-type]
+ pylint/lint/message_state_handler.py:131: error: Too few arguments  [call-arg]
+ pylint/lint/message_state_handler.py:131: error: Argument 1 has incompatible type "str"; expected "MessageDefinitionStore"  [arg-type]
+ pylint/lint/message_state_handler.py:159: error: Too few arguments  [call-arg]
+ pylint/lint/message_state_handler.py:159: error: Argument 1 has incompatible type "str"; expected "MessageDefinitionStore"  [arg-type]
+ pylint/lint/pylinter.py:1335: error: Too few arguments  [call-arg]
+ pylint/lint/pylinter.py:1335: error: Argument 1 has incompatible type "str"; expected "MessageDefinitionStore"  [arg-type]
+ pylint/lint/pylinter.py:1362: error: Too few arguments  [call-arg]
+ pylint/lint/pylinter.py:1362: error: Argument 1 has incompatible type "str"; expected "MessageDefinitionStore"  [arg-type]
+ pylint/checkers/format.py:451: error: Too few arguments  [call-arg]
+ pylint/checkers/format.py:452: error: Argument 1 has incompatible type "str"; expected "MessageDefinitionStore"  [arg-type]

mypy (https://github.com/python/mypy)
+ mypy/find_sources.py:161: error: Too few arguments  [call-arg]
+ mypy/find_sources.py:161: error: Argument 1 has incompatible type "str"; expected "SourceFinder"  [arg-type]
+ mypy/find_sources.py:203: error: Too few arguments  [call-arg]
+ mypy/find_sources.py:203: error: Argument 1 has incompatible type "str"; expected "SourceFinder"  [arg-type]

paroxython (https://github.com/laowantong/paroxython)
+ paroxython/assess_costs.py:85: error: Incompatible types in assignment (expression has type "_lru_cache_wrapper[[int, int], float]", variable has type "Callable[[LearningCostAssessor, int, int], float]")  [assignment]
+ paroxython/assess_costs.py:85: note: "_lru_cache_wrapper[[int, int], float].__call__" has type "Callable[[Arg(int, 'start'), Arg(int, 'stop')], float]"
+ paroxython/assess_costs.py:89: error: "Callable[[LearningCostAssessor, LearningCostAssessor, TaxonName], float]" has no attribute "cache_clear"  [attr-defined]
+ paroxython/assess_costs.py:128: error: Too few arguments  [call-arg]
+ paroxython/assess_costs.py:128: error: Argument 1 has incompatible type "TaxonName"; expected "LearningCostAssessor"  [arg-type]
+ paroxython/recommend_programs.py:296: error: Too few arguments  [call-arg]
+ paroxython/recommend_programs.py:296: error: Argument 1 has incompatible type "TaxonName"; expected "LearningCostAssessor"  [arg-type]
+ paroxython/map_taxonomy.py:243: error: Too few arguments  [call-arg]
+ paroxython/map_taxonomy.py:243: error: Argument 1 has incompatible type "LabelName"; expected "Taxonomy"  [arg-type]

isort (https://github.com/pycqa/isort)
+ isort/deprecated/finders.py:302: error: Too few arguments  [call-arg]
+ isort/deprecated/finders.py:302: error: Argument 1 has incompatible type "str"; expected "RequirementsFinder"  [arg-type]
+ isort/deprecated/finders.py:333: error: Too few arguments  [call-arg]
+ isort/deprecated/finders.py:333: error: Argument 1 has incompatible type "str"; expected "RequirementsFinder"  [arg-type]

materialize (https://github.com/MaterializeInc/materialize)
+ misc/python/materialize/mzbuild.py:436: error: Too few arguments  [call-arg]
+ misc/python/materialize/mzbuild.py:606: error: Too few arguments  [call-arg]
+ misc/python/materialize/cli/mzimage.py:39: error: Too few arguments  [call-arg]
+ misc/python/materialize/cli/mzimage.py:47: error: Too few arguments  [call-arg]

psycopg (https://github.com/psycopg/psycopg)
+ psycopg/psycopg/rows.py:146: error: Argument 2 to "__call__" of "_lru_cache_wrapper" has incompatible type "*Generator[Optional[bytes], None, None]"; expected "bytes"  [arg-type]

jinja (https://github.com/pallets/jinja)
+ src/jinja2/environment.py:1186: error: Unused "type: ignore" comment
+ src/jinja2/environment.py:1201: error: Unused "type: ignore" comment

@asvetlov
Copy link
Contributor Author

Instancemethod seems working, but classmethod does not.

@AlexWaygood
Copy link
Member

There was a previous attempt at doing something like this in #7771 that was quite promising, but the author closed the PR

@AlexWaygood
Copy link
Member

See this issue for some discussion on this, as well:

@AlexWaygood AlexWaygood changed the title Add typing for decorated function arguments in cache API functools: Add typing for decorated function arguments in cache API Feb 22, 2023
@overload
def __get__(self, __instance: None, __owner: type[_S] | None = ...) -> _lru_cache_wrapper[_P, _T]: ...
@overload
def __get__(self, __instance: _S, __owner: type[_S] | None = ...) -> Callable[Concatenate[_S, _P], _T]: ...

Choose a reason for hiding this comment

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

It seems you have this backward. I think it should be this:

Suggested change
def __get__(self, __instance: _S, __owner: type[_S] | None = ...) -> Callable[Concatenate[_S, _P], _T]: ...
def __get__(self: _lru_cache_wrapper[Concatenate[_S, _Q], _T], __instance: _S, __owner: type[_S] | None = ...) -> Callable[_Q, _T]: ...

Where _Q = ParamSpec("_Q"). You'd also want to change the one for 3.8 below.

@WMOkiishi
Copy link

@asvetlov any chance you could see what effect my suggested changes would have on the primer output? I can, of course, make my own PR if you don't have the bandwidth at the moment, but I figured it would be polite to bring it up here first.

@jakkdl
Copy link

jakkdl commented Jul 17, 2023

@asvetlov any chance you could see what effect my suggested changes would have on the primer output? I can, of course, make my own PR if you don't have the bandwidth at the moment, but I figured it would be polite to bring it up here first.

asvetlov seems to have dropped this, so you can go ahead. I might try to give it a stab myself otherwise.

@WMOkiishi
Copy link

I might try to give it a stab myself otherwise.

Go for it! I don't think I really have the time to work on that right now.

@srittau
Copy link
Collaborator

srittau commented Jan 16, 2024

There are now non-trivial merge conflicts.

@jakkdl
Copy link

jakkdl commented Jan 17, 2024

I think the PR can be closed.

@AlexWaygood AlexWaygood closed this Feb 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants