Skip to content

Conversation

@mtshiba
Copy link
Contributor

@mtshiba mtshiba commented Apr 13, 2025

Summary

This PR closes astral-sh/ty#128.

FunctionType::inferred_return_type is added to infer the return type of a function when its return type is not specified.

TODOs

  • infer simple function's return type
    - [ ] infer generator's return type
    - [ ] infer coroutine's return type
    - [ ] infer lambda function's return type

Test Plan

New test cases are added to mdtest/function/return_type.md.

@github-actions
Copy link
Contributor

github-actions bot commented Apr 13, 2025

mypy_primer results

Changes were detected when running on open source projects
attrs (https://github.com/python-attrs/attrs)
- src/attr/_make.py:469:35: warning[possibly-missing-attribute] Attribute `init` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:469:59: warning[possibly-missing-attribute] Attribute `kw_only` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:481:16: warning[possibly-missing-attribute] Attribute `alias` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:483:70: warning[possibly-missing-attribute] Attribute `name` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:487:19: warning[possibly-missing-attribute] Attribute `name` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:1581:5: error[invalid-assignment] Object of type `tuple[Unknown, ...]` is not assignable to `list[Attribute | Unknown]`
+ src/attr/_make.py:1581:5: error[invalid-assignment] Object of type `tuple[Unknown, ...]` is not assignable to `list[Attribute]`
- src/attr/_make.py:1582:29: warning[possibly-missing-attribute] Attribute `hash` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:1582:48: warning[possibly-missing-attribute] Attribute `hash` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:1582:67: warning[possibly-missing-attribute] Attribute `eq` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:1620:16: warning[possibly-missing-attribute] Attribute `eq_key` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:1621:32: warning[possibly-missing-attribute] Attribute `name` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:1622:35: warning[possibly-missing-attribute] Attribute `eq_key` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:1624:57: warning[possibly-missing-attribute] Attribute `name` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:1627:62: warning[possibly-missing-attribute] Attribute `name` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:2162:12: warning[possibly-missing-attribute] Attribute `validator` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:2165:21: warning[possibly-missing-attribute] Attribute `name` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:2166:26: warning[possibly-missing-attribute] Attribute `on_setattr` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:2167:13: warning[possibly-missing-attribute] Attribute `on_setattr` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:2171:20: warning[possibly-missing-attribute] Attribute `alias` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:2173:34: warning[possibly-missing-attribute] Attribute `default` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:2174:48: warning[possibly-missing-attribute] Attribute `default` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:2176:12: warning[possibly-missing-attribute] Attribute `converter` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:2176:55: warning[possibly-missing-attribute] Attribute `converter` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:2177:35: warning[possibly-missing-attribute] Attribute `converter` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:2179:25: warning[possibly-missing-attribute] Attribute `converter` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:2181:12: warning[possibly-missing-attribute] Attribute `init` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:2183:58: warning[possibly-missing-attribute] Attribute `name` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:2193:66: warning[possibly-missing-attribute] Attribute `name` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:2204:56: warning[possibly-missing-attribute] Attribute `default` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:2214:62: warning[possibly-missing-attribute] Attribute `name` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:2225:14: warning[possibly-missing-attribute] Attribute `default` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:2227:16: warning[possibly-missing-attribute] Attribute `kw_only` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:2239:62: warning[possibly-missing-attribute] Attribute `name` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:2247:16: warning[possibly-missing-attribute] Attribute `kw_only` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:2254:54: warning[possibly-missing-attribute] Attribute `name` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:2272:62: warning[possibly-missing-attribute] Attribute `name` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:2288:52: warning[possibly-missing-attribute] Attribute `default` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:2290:16: warning[possibly-missing-attribute] Attribute `kw_only` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:2302:62: warning[possibly-missing-attribute] Attribute `name` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:2308:12: warning[possibly-missing-attribute] Attribute `init` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:2309:16: warning[possibly-missing-attribute] Attribute `type` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:2310:41: warning[possibly-missing-attribute] Attribute `type` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:2346:33: warning[possibly-missing-attribute] Attribute `name` on type `Attribute | Unknown` may be missing
- src/attr/_make.py:2346:60: warning[possibly-missing-attribute] Attribute `init` on type `Attribute | Unknown` may be missing
+ src/attr/_make.py:1582:29: error[unresolved-attribute] Type `Attribute` has no attribute `hash`
+ src/attr/_make.py:1582:48: error[unresolved-attribute] Type `Attribute` has no attribute `hash`
+ src/attr/_make.py:1582:67: error[unresolved-attribute] Type `Attribute` has no attribute `eq`
+ src/attr/_make.py:1620:16: error[unresolved-attribute] Type `Attribute` has no attribute `eq_key`
+ src/attr/_make.py:1621:32: error[unresolved-attribute] Type `Attribute` has no attribute `name`
+ src/attr/_make.py:1622:35: error[unresolved-attribute] Type `Attribute` has no attribute `eq_key`
+ src/attr/_make.py:1624:57: error[unresolved-attribute] Type `Attribute` has no attribute `name`
+ src/attr/_make.py:1627:62: error[unresolved-attribute] Type `Attribute` has no attribute `name`
+ src/attr/_make.py:2162:12: error[unresolved-attribute] Type `Attribute` has no attribute `validator`
+ src/attr/_make.py:2165:21: error[unresolved-attribute] Type `Attribute` has no attribute `name`
+ src/attr/_make.py:2166:26: error[unresolved-attribute] Type `Attribute` has no attribute `on_setattr`
+ src/attr/_make.py:2167:13: error[unresolved-attribute] Type `Attribute` has no attribute `on_setattr`
+ src/attr/_make.py:2171:20: error[unresolved-attribute] Type `Attribute` has no attribute `alias`
+ src/attr/_make.py:2173:34: error[unresolved-attribute] Type `Attribute` has no attribute `default`
+ src/attr/_make.py:2174:48: error[unresolved-attribute] Type `Attribute` has no attribute `default`
+ src/attr/_make.py:2176:12: error[unresolved-attribute] Type `Attribute` has no attribute `converter`
+ src/attr/_make.py:2176:55: error[unresolved-attribute] Type `Attribute` has no attribute `converter`
+ src/attr/_make.py:2177:35: error[unresolved-attribute] Type `Attribute` has no attribute `converter`
+ src/attr/_make.py:2179:25: error[unresolved-attribute] Type `Attribute` has no attribute `converter`
+ src/attr/_make.py:2181:12: error[unresolved-attribute] Type `Attribute` has no attribute `init`
+ src/attr/_make.py:2183:58: error[unresolved-attribute] Type `Attribute` has no attribute `name`
+ src/attr/_make.py:2193:66: error[unresolved-attribute] Type `Attribute` has no attribute `name`
+ src/attr/_make.py:2204:56: error[unresolved-attribute] Type `Attribute` has no attribute `default`
+ src/attr/_make.py:2214:62: error[unresolved-attribute] Type `Attribute` has no attribute `name`
+ src/attr/_make.py:2225:14: error[unresolved-attribute] Type `Attribute` has no attribute `default`
+ src/attr/_make.py:2227:16: error[unresolved-attribute] Type `Attribute` has no attribute `kw_only`
+ src/attr/_make.py:2239:62: error[unresolved-attribute] Type `Attribute` has no attribute `name`
+ src/attr/_make.py:2247:16: error[unresolved-attribute] Type `Attribute` has no attribute `kw_only`
+ src/attr/_make.py:2254:54: error[unresolved-attribute] Type `Attribute` has no attribute `name`
+ src/attr/_make.py:2272:62: error[unresolved-attribute] Type `Attribute` has no attribute `name`
+ src/attr/_make.py:2288:52: error[unresolved-attribute] Type `Attribute` has no attribute `default`
+ src/attr/_make.py:2290:16: error[unresolved-attribute] Type `Attribute` has no attribute `kw_only`
+ src/attr/_make.py:2302:62: error[unresolved-attribute] Type `Attribute` has no attribute `name`
+ src/attr/_make.py:2308:12: error[unresolved-attribute] Type `Attribute` has no attribute `init`
+ src/attr/_make.py:2309:16: error[unresolved-attribute] Type `Attribute` has no attribute `type`
+ src/attr/_make.py:2310:41: error[unresolved-attribute] Type `Attribute` has no attribute `type`
+ src/attr/_make.py:2346:33: error[unresolved-attribute] Type `Attribute` has no attribute `name`
+ src/attr/_make.py:2346:60: error[unresolved-attribute] Type `Attribute` has no attribute `init`
+ src/attr/_make.py:2614:1: error[invalid-assignment] Implicit shadowing of class `Attribute`
+ src/attr/_make.py:2829:1: error[invalid-assignment] Implicit shadowing of class `Factory`
+ src/attr/_make.py:2948:1: error[invalid-assignment] Implicit shadowing of class `Converter`
- Found 550 diagnostics
+ Found 548 diagnostics

parso (https://github.com/davidhalter/parso)
+ parso/__init__.py:58:26: error[invalid-argument-type] Argument to bound method `parse` is incorrect: Expected `str | bytes`, found `Unknown | None`
+ parso/python/errors.py:783:12: warning[possibly-missing-attribute] Attribute `type` on type `Unknown | (Unknown & ~None) | None` may be missing
+ parso/python/errors.py:784:26: warning[possibly-missing-attribute] Attribute `type` on type `Unknown | (Unknown & ~None) | None` may be missing
+ parso/python/errors.py:784:54: warning[possibly-missing-attribute] Attribute `children` on type `Unknown | (Unknown & ~None) | None` may be missing
+ parso/python/errors.py:1166:20: warning[possibly-missing-attribute] Attribute `type` on type `Unknown | (Unknown & ~None) | None` may be missing
+ parso/python/errors.py:1167:34: warning[possibly-missing-attribute] Attribute `type` on type `Unknown | (Unknown & ~None) | None` may be missing
+ parso/python/errors.py:1167:62: warning[possibly-missing-attribute] Attribute `children` on type `Unknown | (Unknown & ~None) | None` may be missing
+ parso/python/prefix.py:83:17: warning[possibly-missing-attribute] Attribute `match` on type `Unknown | LiteralString | Pattern[str]` may be missing
+ parso/python/prefix.py:84:19: warning[possibly-missing-attribute] Attribute `group` on type `Unknown | Match[str] | None` may be missing
+ parso/python/prefix.py:85:17: warning[possibly-missing-attribute] Attribute `group` on type `Unknown | Match[str] | None` may be missing
+ parso/python/prefix.py:96:17: warning[possibly-missing-attribute] Attribute `end` on type `Unknown | Match[str] | None` may be missing
- parso/python/tokenize.py:109:9: error[invalid-assignment] Method `__setitem__` of type `bound method dict[PythonVersionInfo, TokenCollection].__setitem__(key: PythonVersionInfo, value: TokenCollection, /) -> None` cannot be called with a key of type `tuple[Unknown, ...]` and a value of type `Unknown` on object of type `dict[PythonVersionInfo, TokenCollection]`
+ parso/python/tokenize.py:109:9: error[invalid-assignment] Method `__setitem__` of type `bound method dict[PythonVersionInfo, TokenCollection].__setitem__(key: PythonVersionInfo, value: TokenCollection, /) -> None` cannot be called with a key of type `tuple[Unknown, ...]` and a value of type `TokenCollection` on object of type `dict[PythonVersionInfo, TokenCollection]`
+ parso/python/tokenize.py:588:21: error[invalid-assignment] Object of type `(Pattern[Unknown] & ~AlwaysFalsy) | Pattern[Unknown] | None` is not assignable to `Pattern[Unknown]`
- Found 75 diagnostics
+ Found 87 diagnostics

stone (https://github.com/dropbox/stone)
+ stone/cli.py:168:19: error[unresolved-attribute] Type `ModuleType` has no attribute `api`
+ stone/ir/api.py:122:32: error[unsupported-operator] Operator `+` is unsupported between objects of type `None | Literal[""] | Unknown` and `Literal["\n"]`
+ test/test_python_gen.py:528:26: warning[possibly-missing-attribute] Attribute `get_a` on type `None | Unknown | (Unknown & ~str) | bytes` may be missing
+ test/test_python_gen.py:532:26: warning[possibly-missing-attribute] Attribute `_tag` on type `None | Unknown | (Unknown & ~str) | bytes` may be missing
+ test/test_python_gen.py:533:31: warning[possibly-missing-attribute] Attribute `_tag` on type `None | Unknown | (Unknown & ~str) | bytes` may be missing
+ test/test_python_gen.py:538:26: warning[possibly-missing-attribute] Attribute `_tag` on type `None | Unknown | (Unknown & ~str) | bytes` may be missing
+ test/test_python_gen.py:539:31: warning[possibly-missing-attribute] Attribute `_tag` on type `None | Unknown | (Unknown & ~str) | bytes` may be missing
+ test/test_python_gen.py:543:26: warning[possibly-missing-attribute] Attribute `get_c` on type `None | Unknown | (Unknown & ~str) | bytes` may be missing
+ test/test_python_gen.py:550:26: warning[possibly-missing-attribute] Attribute `get_d` on type `None | Unknown | (Unknown & ~str) | bytes` may be missing
+ test/test_python_gen.py:555:26: warning[possibly-missing-attribute] Attribute `get_d` on type `None | Unknown | (Unknown & ~str) | bytes` may be missing
+ test/test_python_gen.py:567:26: warning[possibly-missing-attribute] Attribute `_tag` on type `None | Unknown | (Unknown & ~str) | bytes` may be missing
+ test/test_python_gen.py:568:31: warning[possibly-missing-attribute] Attribute `_tag` on type `None | Unknown | (Unknown & ~str) | bytes` may be missing
+ test/test_python_gen.py:577:26: warning[possibly-missing-attribute] Attribute `_tag` on type `None | Unknown | (Unknown & ~str) | bytes` may be missing
+ test/test_python_gen.py:578:31: warning[possibly-missing-attribute] Attribute `_tag` on type `None | Unknown | (Unknown & ~str) | bytes` may be missing
+ test/test_python_gen.py:579:26: warning[possibly-missing-attribute] Attribute `_value` on type `None | Unknown | (Unknown & ~str) | bytes` may be missing
+ test/test_python_gen.py:582:26: warning[possibly-missing-attribute] Attribute `_tag` on type `None | Unknown | (Unknown & ~str) | bytes` may be missing
+ test/test_python_gen.py:583:31: warning[possibly-missing-attribute] Attribute `_tag` on type `None | Unknown | (Unknown & ~str) | bytes` may be missing
+ test/test_python_gen.py:584:26: warning[possibly-missing-attribute] Attribute `_value` on type `None | Unknown | (Unknown & ~str) | bytes` may be missing
+ test/test_python_gen.py:588:26: warning[possibly-missing-attribute] Attribute `_tag` on type `None | Unknown | (Unknown & ~str) | bytes` may be missing
+ test/test_python_gen.py:589:31: warning[possibly-missing-attribute] Attribute `_tag` on type `None | Unknown | (Unknown & ~str) | bytes` may be missing
+ test/test_python_gen.py:592:31: warning[possibly-missing-attribute] Attribute `_value` on type `None | Unknown | (Unknown & ~str) | bytes` may be missing
+ test/test_python_gen.py:593:26: warning[possibly-missing-attribute] Attribute `_value` on type `None | Unknown | (Unknown & ~str) | bytes` may be missing
- Found 86 diagnostics
+ Found 108 diagnostics

spack (https://github.com/spack/spack)
+ lib/spack/spack/cmd/__init__.py:550:13: warning[possibly-missing-attribute] Attribute `write` on type `Unknown | None` may be missing
+ lib/spack/spack/cmd/__init__.py:554:5: warning[possibly-missing-attribute] Attribute `write` on type `Unknown | None` may be missing
+ lib/spack/spack/cmd/__init__.py:555:5: warning[possibly-missing-attribute] Attribute `flush` on type `Unknown | None` may be missing
+ lib/spack/spack/cmd/info.py:364:25: error[unsupported-operator] Operator `+` is unsupported between objects of type `None | @Todo` and `Literal[4]`
+ lib/spack/spack/cmd/info.py:382:5: error[unsupported-operator] Operator `+=` is unsupported between objects of type `None` and `Literal[4]`
+ lib/spack/spack/llnl/util/filesystem.py:137:29: warning[possibly-missing-attribute] Attribute `st_mode` on type `Any | None` may be missing
+ lib/spack/spack/llnl/util/filesystem.py:138:34: warning[possibly-missing-attribute] Attribute `st_atime_ns` on type `Any | None` may be missing
+ lib/spack/spack/llnl/util/filesystem.py:138:50: warning[possibly-missing-attribute] Attribute `st_mtime_ns` on type `Any | None` may be missing
+ lib/spack/spack/reporters/extract.py:113:13: warning[possibly-missing-attribute] Attribute `append` on type `Unknown | None | str | list[Unknown]` may be missing
+ lib/spack/spack/solver/core.py:255:17: error[invalid-argument-type] Argument is incorrect: Expected `str`, found `tuple[Unknown, ...] | NodeArgument | NodeFlag | Unknown | str | (Unknown & ~AlwaysFalsy)`
+ lib/spack/spack/solver/core.py:255:57: error[invalid-argument-type] Argument is incorrect: Expected `str`, found `tuple[Unknown, ...] | NodeArgument | NodeFlag | Unknown | str | (Unknown & ~AlwaysFalsy)`
+ lib/spack/spack/solver/core.py:259:17: error[invalid-argument-type] Argument is incorrect: Expected `str`, found `tuple[Unknown, ...] | NodeArgument | NodeFlag | Unknown | str | (Unknown & ~AlwaysFalsy)`
+ lib/spack/spack/solver/core.py:260:17: error[invalid-argument-type] Argument is incorrect: Expected `str`, found `tuple[Unknown, ...] | NodeArgument | NodeFlag | Unknown | str | (Unknown & ~AlwaysFalsy)`
+ lib/spack/spack/solver/core.py:261:17: error[invalid-argument-type] Argument is incorrect: Expected `str`, found `tuple[Unknown, ...] | NodeArgument | NodeFlag | Unknown | str | (Unknown & ~AlwaysFalsy)`
+ lib/spack/spack/solver/core.py:262:17: error[invalid-argument-type] Argument is incorrect: Expected `str`, found `tuple[Unknown, ...] | NodeArgument | NodeFlag | Unknown | str | (Unknown & ~AlwaysFalsy)`
+ lib/spack/spack/test/stage.py:857:33: error[non-subscriptable] Cannot subscript object of type `None` with no `__getitem__` method
+ lib/spack/spack/test/stage.py:858:13: error[non-subscriptable] Cannot subscript object of type `None` with no `__getitem__` method
+ lib/spack/spack/util/executable.py:328:17: warning[possibly-missing-attribute] Attribute `close` on type `@Todo | int | (Unknown & ~str)` may be missing
+ lib/spack/spack/util/executable.py:330:17: warning[possibly-missing-attribute] Attribute `close` on type `@Todo | int | (Unknown & ~str)` may be missing
+ lib/spack/spack/util/executable.py:332:17: warning[possibly-missing-attribute] Attribute `close` on type `@Todo | int | (Unknown & ~str)` may be missing
+ lib/spack/spack/util/gcs.py:239:47: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `Message[str, str]`, found `dict[Unknown | str, Unknown] | Unknown`
+ lib/spack/spack/util/gpg.py:83:9: error[call-non-callable] Object of type `None` is not callable
+ lib/spack/spack/util/module_cmd.py:96:12: warning[possibly-missing-attribute] Attribute `split` on type `str | None` may be missing
+ lib/spack/spack/util/module_cmd.py:147:16: warning[possibly-missing-attribute] Attribute `split` on type `str | None` may be missing
+ lib/spack/spack/util/web.py:430:48: error[invalid-argument-type] Argument to bound method `__call__` is incorrect: Expected `_ReadableStream`, found `None | Unknown`
+ lib/spack/spack/vendor/attr/_compat.py:160:16: error[non-subscriptable] Cannot subscript object of type `None` with no `__getitem__` method
+ lib/spack/spack/vendor/attr/_make.py:593:24: error[invalid-argument-type] Argument to class `property` is incorrect: Expected `((Any, /) -> Any) | None`, found `tuple[Unknown | itemgetter[Unknown], list[Unknown], dict[Unknown, Unknown]]`
+ lib/spack/spack/vendor/attr/_make.py:593:36: error[invalid-argument-type] Argument to class `property` is incorrect: Expected `((Any, /) -> Any) | None`, found `list[Unknown] | @Todo`
+ lib/spack/spack/vendor/attr/_make.py:669:39: error[not-iterable] Object of type `itemgetter[Unknown]` is not iterable
- Found 7512 diagnostics
+ Found 7541 diagnostics

werkzeug (https://github.com/pallets/werkzeug)
+ tests/test_test.py:724:9: error[invalid-assignment] Implicit shadowing of class `app`
- Found 367 diagnostics
+ Found 368 diagnostics

paasta (https://github.com/yelp/paasta)
+ paasta_tools/cli/cmds/start_stop_restart.py:270:21: error[invalid-argument-type] Argument to function `get_latest_deployment_tag` is incorrect: Expected `dict[str, str]`, found `list[str]`
+ paasta_tools/cli/cmds/validate.py:1018:49: error[invalid-argument-type] Argument to function `paasta_validate_soa_configs` is incorrect: Expected `str`, found `None | Unknown | str`
- paasta_tools/paastaapi/model_utils.py:275:29: error[unsupported-operator] Operator `in` is not supported for types `Unknown` and `None`, in comparing `Unknown & ~None` with `None | Unknown`
+ paasta_tools/paastaapi/model_utils.py:275:29: error[unsupported-operator] Operator `in` is not supported for types `Divergent` and `None`, in comparing `(Divergent & ~None) | (Unknown & ~None)` with `None | Unknown`
- paasta_tools/tron_tools.py:1096:17: error[invalid-argument-type] Argument to function `build_spark_command` is incorrect: Expected `str`, found `Unknown | list[TronSecretVolume] | bool | str | None`
+ paasta_tools/tron_tools.py:1096:17: error[invalid-argument-type] Argument to function `build_spark_command` is incorrect: Expected `str`, found `Unknown | str | list[str] | None | list[TronSecretVolume] | bool`
- Found 913 diagnostics
+ Found 915 diagnostics

pytest (https://github.com/pytest-dev/pytest)
+ src/_pytest/doctest.py:152:51: error[not-iterable] Object of type `(Any & ~AlwaysFalsy) | (Notset & ~AlwaysFalsy) | list[Unknown | str]` may not be iterable
+ src/_pytest/logging.py:625:20: error[no-matching-overload] No overload of function `getattr` matches arguments
+ src/_pytest/logging.py:670:41: error[no-matching-overload] No overload of function `abspath` matches arguments
+ src/_pytest/logging.py:684:13: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str | None`, found `(Any & ~AlwaysFalsy) | (Notset & ~AlwaysFalsy) | None`
+ src/_pytest/logging.py:684:30: error[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `str | None`, found `(Any & ~AlwaysFalsy) | (Notset & ~AlwaysFalsy) | None`
+ src/_pytest/main.py:407:54: error[not-iterable] Object of type `(Any & ~AlwaysFalsy) | (Notset & ~AlwaysFalsy)` may not be iterable
+ src/_pytest/main.py:418:54: error[not-iterable] Object of type `(Any & ~AlwaysFalsy) | (Notset & ~AlwaysFalsy)` may not be iterable
+ src/_pytest/main.py:442:31: error[invalid-argument-type] Argument to class `tuple` is incorrect: Expected `Iterable[object]`, found `(Any & ~AlwaysFalsy) | (Notset & ~AlwaysFalsy) | list[Unknown]`
+ src/_pytest/python.py:500:13: error[invalid-argument-type] Argument to function `import_path` is incorrect: Expected `str | ImportMode`, found `Any | Notset`
+ src/_pytest/runner.py:382:17: error[invalid-argument-type] Argument to bound method `_loadconftestmodules` is incorrect: Expected `str | ImportMode`, found `Any | Notset`
+ src/_pytest/unittest.py:142:26: warning[possibly-missing-attribute] Attribute `__unittest_skip_why__` on type `Unknown | None` may be missing
+ src/_pytest/unittest.py:183:26: warning[possibly-missing-attribute] Attribute `__unittest_skip_why__` on type `None | Any` may be missing
+ testing/acceptance_test.py:1482:5: warning[possibly-missing-attribute] Attribute `close` on type `IO[str] | None` may be missing
+ testing/acceptance_test.py:1484:12: warning[possibly-missing-attribute] Attribute `read` on type `IO[str] | None` may be missing
+ testing/acceptance_test.py:1488:5: warning[possibly-missing-attribute] Attribute `close` on type `IO[str] | None` may be missing
+ testing/python/fixtures.py:716:16: warning[possibly-missing-attribute] Attribute `__name__` on type `Unknown | None` may be missing
+ testing/python/fixtures.py:936:15: error[unresolved-attribute] Type `None` has no attribute `module`
+ testing/python/fixtures.py:1552:18: error[unresolved-attribute] Type `None` has no attribute `module`
+ testing/python/fixtures.py:2254:18: error[unresolved-attribute] Type `None` has no attribute `pluginmanager`
+ testing/python/fixtures.py:2755:18: error[unresolved-attribute] Type `None` has no attribute `module`
+ testing/python/fixtures.py:2801:18: error[unresolved-attribute] Type `None` has no attribute `module`
+ testing/python/fixtures.py:3006:18: error[unresolved-attribute] Type `None` has no attribute `module`
+ testing/python/fixtures.py:3167:18: error[unresolved-attribute] Type `None` has no attribute `module`
+ testing/python/fixtures.py:3189:18: error[unresolved-attribute] Type `None` has no attribute `module`
+ testing/python/fixtures.py:3288:18: error[unresolved-attribute] Type `None` has no attribute `module`
+ testing/python/integration.py:179:13: error[unresolved-attribute] Type `None` has no attribute `location`
+ testing/python/integration.py:179:58: error[unresolved-attribute] Type `None` has no attribute `when`
+ testing/python/integration.py:323:20: error[invalid-argument-type] Argument to function `len` is incorrect: Expected `Sized`, found `None`
+ testing/python/integration.py:324:16: error[non-subscriptable] Cannot subscript object of type `None` with no `__getitem__` method
+ testing/test_assertion.py:409:45: error[invalid-argument-type] Argument to function `pytest_assertrepr_compare` is incorrect: Expected `Config`, found `Config`
+ testing/test_collection.py:519:22: error[unresolved-attribute] Type `None` has no attribute `result`
+ testing/test_config.py:2170:14: error[unresolved-attribute] Type `None` has no attribute `config`
+ testing/test_debugging.py:33:15: error[unresolved-attribute] Type `RunResult` has no attribute `reprec`
+ testing/test_mark.py:695:20: error[invalid-argument-type] Argument to function `len` is incorrect: Expected `Sized`, found `None`
+ testing/test_mark.py:877:16: error[non-subscriptable] Cannot subscript object of type `None` with no `__getitem__` method
+ testing/test_mark.py:925:20: error[invalid-argument-type] Argument to function `len` is incorrect: Expected `Sized`, found `None`
+ testing/test_mark.py:954:37: error[unresolved-attribute] Type `None` has no attribute `items`
+ testing/test_mark.py:1107:16: error[invalid-argument-type] Argument to function `len` is incorrect: Expected `Sized`, found `None`
+ testing/test_pluginmanager.py:311:16: error[unresolved-attribute] Type `None` has no attribute `__name__`
+ testing/test_pytester.py:652:39: error[invalid-argument-type] Argument to bound method `communicate` is incorrect: Expected `str | None`, found `Literal[b"input\n2ndline"]`
+ testing/test_pytester.py:653:12: error[unresolved-attribute] Type `str` has no attribute `decode`
+ testing/test_pytester.py:666:12: error[unresolved-attribute] Type `str` has no attribute `decode`
+ testing/test_runner.py:1120:27: error[unresolved-attribute] Type `None` has no attribute `longrepr`
+ testing/test_runner.py:1121:29: error[unresolved-attribute] Type `None` has no attribute `longreprtext`
+ testing/test_runner_xunit.py:60:12: error[unresolved-attribute] Type `None` has no attribute `module`
+ testing/test_runner_xunit.py:79:12: error[unresolved-attribute] Type `None` has no attribute `module`
+ testing/test_unittest.py:129:16: error[unresolved-attribute] Type `None` has no attribute `module`
- Found 485 diagnostics
+ Found 532 diagnostics

scrapy (https://github.com/scrapy/scrapy)
+ scrapy/core/downloader/__init__.py:209:20: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `request_reached_downloader`
+ scrapy/core/downloader/__init__.py:260:24: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `response_downloaded`
+ scrapy/core/downloader/handlers/__init__.py:54:46: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `engine_stopped`
+ scrapy/core/downloader/handlers/http11.py:473:20: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `headers_received`
+ scrapy/core/downloader/handlers/http11.py:664:20: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `bytes_received`
+ scrapy/core/engine.py:178:56: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `engine_started`
+ scrapy/core/engine.py:217:56: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `engine_stopped`
+ scrapy/core/engine.py:340:41: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `scheduler_empty`
+ scrapy/core/engine.py:420:13: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `request_scheduled`
+ scrapy/core/engine.py:430:17: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `request_dropped`
+ scrapy/core/engine.py:489:28: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `response_received`
+ scrapy/core/engine.py:524:13: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_opened`
+ scrapy/core/engine.py:537:13: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_idle`
+ scrapy/core/engine.py:608:24: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_closed`
+ scrapy/core/scraper.py:367:20: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_error`
+ scrapy/core/scraper.py:505:24: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `item_dropped`
+ scrapy/core/scraper.py:521:24: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `item_error`
+ scrapy/core/scraper.py:534:24: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `item_scraped`
+ scrapy/crawler.py:105:53: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `engine_stopped`
+ scrapy/downloadermiddlewares/downloadtimeout.py:29:57: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_opened`
+ scrapy/downloadermiddlewares/httpauth.py:32:57: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_opened`
+ scrapy/downloadermiddlewares/httpcache.py:63:57: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_opened`
+ scrapy/downloadermiddlewares/httpcache.py:64:57: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_closed`
+ scrapy/downloadermiddlewares/httpcompression.py:69:51: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_opened`
+ scrapy/downloadermiddlewares/offsite.py:35:57: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_opened`
+ scrapy/downloadermiddlewares/offsite.py:36:61: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `request_scheduled`
+ scrapy/downloadermiddlewares/useragent.py:27:57: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_opened`
+ scrapy/extensions/closespider.py:64:62: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_error`
+ scrapy/extensions/closespider.py:66:61: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `response_received`
+ scrapy/extensions/closespider.py:68:64: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_opened`
+ scrapy/extensions/closespider.py:70:63: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `item_scraped`
+ scrapy/extensions/closespider.py:75:52: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_opened`
+ scrapy/extensions/closespider.py:78:51: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `item_scraped`
+ scrapy/extensions/closespider.py:81:60: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_closed`
+ scrapy/extensions/corestats.py:29:57: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_opened`
+ scrapy/extensions/corestats.py:30:57: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_closed`
+ scrapy/extensions/corestats.py:31:56: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `item_scraped`
+ scrapy/extensions/corestats.py:32:56: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `item_dropped`
+ scrapy/extensions/corestats.py:33:61: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `response_received`
+ scrapy/extensions/feedexport.py:458:55: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_opened`
+ scrapy/extensions/feedexport.py:459:56: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_closed`
+ scrapy/extensions/feedexport.py:460:56: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `item_scraped`
+ scrapy/extensions/feedexport.py:536:57: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `feed_exporter_closed`
+ scrapy/extensions/feedexport.py:569:17: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `feed_slot_closed`
+ scrapy/extensions/logstats.py:42:57: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_opened`
+ scrapy/extensions/logstats.py:43:57: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_closed`
+ scrapy/extensions/memdebug.py:34:57: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_closed`
+ scrapy/extensions/memusage.py:54:61: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `engine_started`
+ scrapy/extensions/memusage.py:55:61: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `engine_stopped`
+ scrapy/extensions/periodic_log.py:92:57: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_opened`
+ scrapy/extensions/periodic_log.py:93:57: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_closed`
+ scrapy/extensions/spiderstate.py:31:59: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_closed`
+ scrapy/extensions/spiderstate.py:32:59: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_opened`
+ scrapy/extensions/statsmailer.py:39:57: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_closed`
+ scrapy/extensions/telnet.py:60:60: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `engine_started`
+ scrapy/extensions/telnet.py:61:59: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `engine_stopped`
+ scrapy/extensions/throttle.py:36:61: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_opened`
+ scrapy/extensions/throttle.py:38:47: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `response_downloaded`
+ scrapy/spidermiddlewares/referer.py:348:62: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `request_scheduled`
+ scrapy/spiders/__init__.py:82:45: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_closed`
+ scrapy/utils/benchserver.py:18:36: error[invalid-argument-type] Argument to bound method `randint` is incorrect: Expected `int`, found `Unknown | str | None`
+ scrapy/utils/benchserver.py:18:58: error[invalid-argument-type] Argument to function `__new__` is incorrect: Expected `SupportsIndex`, found `Unknown | str | None`
+ tests/mockserver/http_resources.py:97:40: error[invalid-argument-type] Argument to bound method `randint` is incorrect: Expected `int`, found `Unknown | None`
+ tests/mockserver/http_resources.py:97:62: error[invalid-argument-type] Argument to function `__new__` is incorrect: Expected `SupportsIndex`, found `Unknown | None`
+ tests/mockserver/http_resources.py:99:27: error[invalid-argument-type] Argument to function `__new__` is incorrect: Expected `SupportsIndex`, found `Unknown | None`
+ tests/mockserver/http_resources.py:99:34: error[unsupported-operator] Operator `-` is unsupported between objects of type `Unknown | None` and `Unknown | None`
+ tests/mockserver/http_resources.py:101:15: error[unsupported-operator] Operator `*` is unsupported between objects of type `int | float` and `Unknown | None`
+ tests/spiders.py:514:56: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `bytes_received`
+ tests/spiders.py:543:58: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `headers_received`
+ tests/test_commands.py:49:59: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `BaseSettings`
+ tests/test_crawl.py:209:55: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `item_scraped`
+ tests/test_crawl.py:229:55: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `item_scraped`
+ tests/test_crawl.py:445:51: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `item_scraped`
+ tests/test_crawl.py:549:51: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `item_scraped`
+ tests/test_engine.py:127:53: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_idle`
+ tests/test_engine.py:164:57: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `item_scraped`
+ tests/test_engine.py:165:55: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `item_error`
+ tests/test_engine.py:166:61: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `headers_received`
+ tests/test_engine.py:167:59: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `bytes_received`
+ tests/test_engine.py:168:62: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `request_scheduled`
+ tests/test_engine.py:169:60: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `request_dropped`
+ tests/test_engine.py:171:35: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `request_reached_downloader`
+ tests/test_engine.py:174:39: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `response_downloaded`
+ tests/test_engine.py:179:39: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `engine_stopped`
+ tests/test_engine.py:359:16: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `engine_started`
+ tests/test_engine.py:360:16: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `engine_stopped`
+ tests/test_engine.py:361:16: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_opened`
+ tests/test_engine.py:362:16: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_idle`
+ tests/test_engine.py:363:16: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_closed`
+ tests/test_engine.py:364:16: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `headers_received`
+ tests/test_engine.py:367:13: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_opened`
+ tests/test_engine.py:369:69: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_idle`
+ tests/test_engine.py:373:33: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_closed`
+ tests/test_engine.py:416:33: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_closed`
+ tests/test_engine.py:623:45: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `request_scheduled`
+ tests/test_engine.py:632:48: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `request_scheduled`
+ tests/test_engine.py:716:20: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_closed`
+ tests/test_engine_loop.py:83:44: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `request_reached_downloader`
+ tests/test_engine_loop.py:111:44: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `request_reached_downloader`
+ tests/test_engine_loop.py:184:44: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `request_reached_downloader`
+ tests/test_engine_loop.py:344:59: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `scheduler_empty`
+ tests/test_extension_statsmailer.py:64:9: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_closed`
+ tests/test_feedexport.py:1348:29: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `feedexport`
+ tests/test_feedexport.py:1352:29: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `feedexport`
+ tests/test_feedexport.py:2813:20: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `feed_exporter_closed`
+ tests/test_feedexport.py:2816:46: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `feed_slot_closed`
+ tests/test_pipeline_crawl.py:102:56: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `item_scraped`
+ tests/test_pipelines.py:112:56: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `item_scraped`
+ tests/test_pipelines.py:185:51: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `item_scraped`
+ tests/test_pipelines.py:221:51: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `item_scraped`
+ tests/test_pipelines.py:295:51: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `item_scraped`
+ tests/test_proxy_connect.py:100:9: error[invalid-assignment] Method `__setitem__` of type `bound method _Environ[str].__setitem__(key: str, value: str) -> None` cannot be called with a key of type `Literal["https_proxy"]` and a value of type `Literal[b""]` on object of type `_Environ[str]`
+ tests/test_request_attribute_binding.py:134:56: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `response_received`
+ tests/test_signals.py:32:45: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `scheduler_empty`
+ tests/test_signals.py:58:56: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `item_scraped`
+ tests/test_spider.py:82:47: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_opened`
+ tests/test_spider.py:84:20: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `spider_closed`
+ tests/test_spider_start.py:34:45: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `item_scraped`
+ tests/test_spidermiddleware_process_start.py:119:45: error[unresolved-attribute] Type `tuple[Unknown, Unknown, Unknown]` has no attribute `item_scraped`
- Found 1059 diagnostics
+ Found 1178 diagnostics

alerta (https://github.com/alerta/alerta)
+ alerta/commands.py:92:27: warning[possibly-missing-attribute] Attribute `key` on type `@Todo | ApiKey | None` may be missing
+ alerta/commands.py:92:40: warning[possibly-missing-attribute] Attribute `user` on type `@Todo | ApiKey | None` may be missing
+ alerta/commands.py:191:27: warning[possibly-missing-attribute] Attribute `id` on type `User | None` may be missing
+ alerta/commands.py:191:37: warning[possibly-missing-attribute] Attribute `login` on type `User | None` may be missing
+ alerta/database/base.py:56:48: error[unresolved-attribute] Type `ModuleType` has no attribute `Backend`
+ alerta/database/base.py:470:61: error[unresolved-attribute] Type `ModuleType` has no attribute `Alerts`
+ alerta/database/base.py:471:67: error[unresolved-attribute] Type `ModuleType` has no attribute `Blackouts`
+ alerta/database/base.py:472:69: error[unresolved-attribute] Type `ModuleType` has no attribute `Heartbeats`
+ alerta/database/base.py:473:60: error[unresolved-attribute] Type `ModuleType` has no attribute `ApiKeys`
+ alerta/database/base.py:474:59: error[unresolved-attribute] Type `ModuleType` has no attribute `Users`
+ alerta/database/base.py:475:61: error[unresolved-attribute] Type `ModuleType` has no attribute `Groups`
+ alerta/database/base.py:476:65: error[unresolved-attribute] Type `ModuleType` has no attribute `Permissions`
+ alerta/database/base.py:477:67: error[unresolved-attribute] Type `ModuleType` has no attribute `Customers`
+ alerta/models/alarms/__init__.py:34:50: error[unresolved-attribute] Type `ModuleType` has no attribute `StateMachine`
+ alerta/models/metrics.py:152:22: warning[possibly-missing-attribute] Attribute `count` on type `Unknown | None` may be missing
+ alerta/models/metrics.py:245:22: warning[possibly-missing-attribute] Attribute `count` on type `Unknown | None` may be missing
+ alerta/models/metrics.py:246:27: warning[possibly-missing-attribute] Attribute `total_time` on type `Unknown | None` may be missing
+ alerta/utils/config.py:81:13: error[unsupported-operator] Operator `*` is unsupported between objects of type `bool | list[str] | str | @Todo | None` and `Literal[60]`
+ alerta/utils/config.py:82:16: error[unsupported-operator] Operator `*` is unsupported between objects of type `bool | list[str] | str | @Todo | None` and `Literal[60]`
+ alerta/utils/config.py:87:13: error[unsupported-operator] Operator `*` is unsupported between objects of type `bool | list[str] | str | @Todo | None` and `Literal[60]`
+ alerta/utils/config.py:88:16: error[unsupported-operator] Operator `*` is unsupported between objects of type `bool | list[str] | str | @Todo | None` and `Literal[60]`
+ alerta/views/alerts.py:333:25: warning[possibly-missing-attribute] Attribute `is_on` on type `Unknown | None` may be missing
+ alerta/views/alerts.py:348:25: warning[possibly-missing-attribute] Attribute `is_on` on type `Unknown | None` may be missing
+ alerta/views/alerts.py:394:21: warning[possibly-missing-attribute] Attribute `is_on` on type `Unknown | None` may be missing
- Found 513 diagnostics
+ Found 537 diagnostics

dulwich (https://github.com/dulwich/dulwich)
+ dulwich/cli.py:820:21: error[invalid-argument-type] Argument to function `log` is incorrect: Expected `TextIO`, found `Unknown | Pager`
+ dulwich/cli.py:920:29: error[invalid-argument-type] Argument to function `diff` is incorrect: Expected `BinaryIO`, found `Unknown | ColorizedDiffStream`
+ dulwich/cli.py:934:29: error[invalid-argument-type] Argument to function `diff` is incorrect: Expected `BinaryIO`, found `Unknown | ColorizedDiffStream`
+ dulwich/cli.py:944:29: error[invalid-argument-type] Argument to function `diff` is incorrect: Expected `BinaryIO`, found `Unknown | ColorizedDiffStream`
+ dulwich/cli.py:1336:62: error[invalid-argument-type] Argument to function `show` is incorrect: Expected `TextIO`, found `Unknown | ColorizedDiffStream`
+ dulwich/cli.py:1765:21: error[invalid-argument-type] Argument to function `ls_tree` is incorrect: Expected `TextIO`, found `Unknown | Pager`
+ dulwich/greenthreads.py:132:9: error[invalid-assignment] Object of type `set[Unknown | bytes]` is not assignable to `list[Unknown | bytes]`
+ dulwich/object_store.py:2074:13: error[invalid-argument-type] Argument to function `_collect_ancestors` is incorrect: Expected `frozenset[Unknown | bytes]`, found `set[Unknown]`
+ dulwich/porcelain.py:2295:17: error[invalid-argument-type] Argument to function `update_working_tree` is incorrect: Expected `BlobNormalizer | None`, found `FilterBlobNormalizer`
+ dulwich/porcelain.py:4089:13: error[invalid-argument-type] Argument to function `update_working_tree` is incorrect: Expected `BlobNormalizer | None`, found `FilterBlobNormalizer`
- Found 180 diagnostics
+ Found 190 diagnostics

ignite (https://github.com/pytorch/ignite)
+ examples/cifar10/main.py:72:73: warning[possibly-missing-attribute] Attribute `sampler` on type `Unknown | _MpDeviceLoader` may be missing
+ examples/cifar10_qat/main.py:68:73: warning[possibly-missing-attribute] Attribute `sampler` on type `Unknown | _MpDeviceLoader` may be missing
+ examples/transformers/main.py:72:73: warning[possibly-missing-attribute] Attribute `sampler` on type `Unknown | _MpDeviceLoader` may be missing
+ tests/ignite/engine/test_create_supervised.py:135:18: error[not-iterable] Object of type `int` is not iterable
+ tests/ignite/engine/test_create_supervised.py:135:18: error[not-iterable] Object of type `None` is not iterable
+ tests/ignite/engine/test_create_supervised.py:150:30: error[non-subscriptable] Cannot subscript object of type `int` with no `__getitem__` method
+ tests/ignite/engine/test_create_supervised.py:150:30: error[non-subscriptable] Cannot subscript object of type `None` with no `__getitem__` method
+ tests/ignite/engine/test_create_supervised.py:157:20: error[non-subscriptable] Cannot subscript object of type `int` with no `__getitem__` method
+ tests/ignite/engine/test_create_supervised.py:157:20: error[non-subscriptable] Cannot subscript object of type `None` with no `__getitem__` method
+ tests/ignite/engine/test_create_supervised.py:302:21: error[not-iterable] Object of type `int` is not iterable
+ tests/ignite/engine/test_create_supervised.py:302:21: error[not-iterable] Object of type `None` is not iterable
+ tests/ignite/engine/test_deterministic.py:41:31: error[not-iterable] Object of type `None` is not iterable
+ tests/ignite/engine/test_deterministic.py:57:17: warning[possibly-missing-attribute] Attribute `set_epoch` on type `None | Unknown` may be missing
+ tests/ignite/engine/test_deterministic.py:62:31: error[not-iterable] Object of type `None` is not iterable
+ tests/ignite/engine/test_deterministic.py:80:17: warning[possibly-missing-attribute] Attribute `set_epoch` on type `None | Unknown` may be missing
+ tests/ignite/metrics/test_maximum_mean_discrepancy.py:153:24: warning[possibly-missing-attribute] Attribute `cpu` on type `Unknown | list[int | float] | list[str] | list[Any]` may be missing
+ tests/ignite/metrics/test_maximum_mean_discrepancy.py:154:24: warning[possibly-missing-attribute] Attribute `cpu` on type `Unknown | list[int | float] | list[str] | list[Any]` may be missing
- Found 2153 diagnostics
+ Found 2170 diagnostics

graphql-core (https://github.com/graphql-python/graphql-core)
+ tests/language/test_schema_parser.py:260:21: error[non-subscriptable] Cannot subscript object of type `DefinitionNode` with no `__getitem__` method
+ tests/language/test_schema_parser.py:267:21: error[non-subscriptable] Cannot subscript object of type `DefinitionNode` with no `__getitem__` method
+ tests/language/test_schema_parser.py:289:21: error[non-subscriptable] Cannot subscript object of type `DefinitionNode` with no `__getitem__` method
+ tests/language/test_schema_parser.py:296:21: error[non-subscriptable] Cannot subscript object of type `DefinitionNode` with no `__getitem__` method
- Found 346 diagnostics
+ Found 350 diagnostics

aiohttp-devtools (https://github.com/aio-libs/aiohttp-devtools)
+ tests/test_runserver_logs.py:162:21: error[invalid-argument-type] Argument to bound method `format` is incorrect: Expected `LogRecord`, found `Record`
+ tests/test_runserver_logs.py:168:21: error[invalid-argument-type] Argument to bound method `format` is incorrect: Expected `LogRecord`, found `Record`
+ tests/test_runserver_logs.py:174:21: error[invalid-argument-type] Argument to bound method `format` is incorrect: Expected `LogRecord`, found `Record`
+ tests/test_runserver_logs.py:180:21: error[invalid-argument-type] Argument to bound method `format` is incorrect: Expected `LogRecord`, found `Record`
+ tests/test_runserver_logs.py:185:21: error[invalid-argument-type] Argument to bound method `format` is incorrect: Expected `LogRecord`, found `Record`
+ tests/test_runserver_logs.py:192:21: error[invalid-argument-type] Argument to bound method `format` is incorrect: Expected `LogRecord`, found `Record`
+ tests/test_runserver_logs.py:198:21: error[invalid-argument-type] Argument to bound method `format` is incorrect: Expected `LogRecord`, found `Record`
- Found 122 diagnostics
+ Found 129 diagnostics

pybind11 (https://github.com/pybind/pybind11)
+ tests/test_cpp_conduit.py:100:11: warning[possibly-missing-attribute] Attribute `Traveler` on type `Unknown | ModuleType` may be missing
+ tests/test_cpp_conduit.py:102:12: warning[possibly-missing-attribute] Attribute `get_luggage` on type `Unknown | ModuleType` may be missing
+ tests/test_cpp_conduit.py:106:11: warning[possibly-missing-attribute] Attribute `PremiumTraveler` on type `Unknown | ModuleType` may be missing
+ tests/test_cpp_conduit.py:108:12: warning[possibly-missing-attribute] Attribute `get_luggage` on type `Unknown | ModuleType` may be missing
+ tests/test_cpp_conduit.py:109:12: warning[possibly-missing-attribute] Attribute `get_points` on type `Unknown | ModuleType` may be missing
+ tests/test_cpp_conduit.py:114:12: warning[possibly-missing-attribute] Attribute `get_luggage` on type `Unknown | ModuleType` may be missing
+ tests/test_cpp_conduit.py:118:11: warning[possibly-missing-attribute] Attribute `Traveler` on type `Unknown | ModuleType` may be missing
+ tests/test_cpp_conduit.py:124:12: warning[possibly-missing-attribute] Attribute `get_luggage` on type `Unknown | ModuleType` may be missing
+ tests/test_cpp_conduit.py:125:12: warning[possibly-missing-attribute] Attribute `get_points` on type `Unknown | ModuleType` may be missing
+ tests/test_cpp_conduit.py:129:11: warning[possibly-missing-attribute] Attribute `PremiumTraveler` on type `Unknown | ModuleType` may be missing
+ tests/test_cpp_conduit.py:135:45: error[unresolved-attribute] Type `ModuleType` has no attribute `Traveler`
+ tests/test_cpp_conduit.py:139:12: warning[possibly-missing-attribute] Attribute `GetLuggage` on type `Unknown | ModuleType` may be missing
+ tests/test_cpp_conduit.py:144:35: error[unresolved-attribute] Type `ModuleType` has no attribute `PremiumTraveler`
+ tests/test_cpp_conduit.py:148:12: warning[possibly-missing-attribute] Attribute `GetLuggage` on type `Unknown | ModuleType` may be missing
+ tests/test_cpp_conduit.py:149:12: warning[possibly-missing-attribute] Attribute `GetPoints` on type `Unknown | ModuleType` may be missing
+ tests/test_cpp_conduit.py:165:5: warning[possibly-missing-attribute] Attribute `wrap_very_lonely_traveler` on type `Unknown | ModuleType` may be missing
+ tests/test_cpp_conduit.py:167:12: warning[possibly-missing-attribute] Attribute `VeryLonelyTraveler` on type `Unknown | ModuleType` may be missing
+ tests/test_cpp_conduit.py:183:9: warning[possibly-missing-attribute] Attribute `wrap_very_lonely_traveler` on type `Unknown | ModuleType` may be missing
+ tests/test_multiple_interpreters.py:87:26: error[not-iterable] Object of type `None` is not iterable
+ tests/test_multiple_interpreters.py:119:12: error[unsupported-operator] Operator `in` is not supported for types `str` and `None`, in comparing `Literal["does not support loading in subinterpreters"]` with `None | str`
+ tests/test_multiple_interpreters.py:180:26: error[not-iterable] Object of type `None` is not iterable
+ tests/test_multiple_interpreters.py:194:17: error[too-many-positional-arguments] Too many positional arguments to function `create`: expected 0, got 1
+ tests/test_pytypes.py:1163:12: error[non-subscriptable] Cannot subscript object of type `None` with no `__getitem__` method
+ tests/test_pytypes.py:1164:12: error[non-subscriptable] Cannot subscript object of type `None` with no `__getitem__` method
+ tests/test_pytypes.py:1165:12: error[non-subscriptable] Cannot subscript object of type `None` with no `__getitem__` method
+ tests/test_pytypes.py:1168:9: error[non-subscriptable] Cannot subscript object of type `None` with no `__getitem__` method
+ tests/test_pytypes.py:1200:12: error[non-subscriptable] Cannot subscript object of type `None` with no `__getitem__` method
+ tests/test_pytypes.py:1202:9: error[non-subscriptable] Cannot subscript object of type `None` with no `__getitem__` method
+ tests/test_pytypes.py:1215:12: error[non-subscriptable] Cannot subscript object of type `None` with no `__getitem__` method
+ tests/test_pytypes.py:1232:12: error[non-subscriptable] Cannot subscript object of type `None` with no `__getitem__` method
+ tests/test_pytypes.py:1245:12: error[non-subscriptable] Cannot subscript object of type `None` with no `__getitem__` method
- Found 215 diagnostics
+ Found 246 diagnostics

tornado (https://github.com/tornadoweb/tornado)
+ tornado/test/circlerefs_test.py:89:25: error[not-iterable] Object of type `object` is not iterable
+ tornado/test/circlerefs_test.py:91:25: error[not-iterable] Object of type `object` is not iterable
+ tornado/test/process_test.py:108:25: warning[possibly-missing-attribute] Attribute `body` on type `HTTPResponse | None` may be missing
+ tornado/test/process_test.py:121:31: warning[possibly-missing-attribute] Attribute `body` on type `HTTPResponse | None` may be missing
+ tornado/test/process_test.py:123:32: warning[possibly-missing-attribute] Attribute `body` on type `HTTPResponse | None` may be missing
- Found 250 diagnostics
+ Found 255 diagnostics

pip (https://github.com/pypa/pip)
+ src/pip/_vendor/cachecontrol/serialize.py:36:45: error[invalid-argument-type] Argument to function `len` is incorrect: Expected `Sized`, found `None | (Unknown & ~AlwaysTruthy) | Literal[b""] | Unknown`
+ src/pip/_vendor/pygments/sphinxext.py:108:26: warning[possibly-missing-attribute] Attribute `filenames` on type `Unknown | None` may be missing
+ src/pip/_vendor/pygments/sphinxext.py:108:48: warning[possibly-missing-attribute] Attribute `alias_filenames` on type `Unknown | None` may be missing
+ src/pip/_vendor/pygments/sphinxext.py:111:46: warning[possibly-missing-attribute] Attribute `url` on type `Unknown | None` may be missing
+ src/pip/_vendor/pyproject_hooks/_in_process/_in_process.py:139:16: warning[possibly-missing-attribute] Attribute `get_requires_for_build_wheel` on type `ModuleType | Any` may be missing
+ src/pip/_vendor/pyproject_hooks/_in_process/_in_process.py:153:16: warning[possibly-missing-attribute] Attribute `get_requires_for_build_editable` on type `ModuleType | Any` may be missing
+ src/pip/_vendor/pyproject_hooks/_in_process/_in_process.py:170:16: warning[possibly-missing-attribute] Attribute `prepare_metadata_for_build_wheel` on type `ModuleType | Any` may be missing
+ src/pip/_vendor/pyproject_hooks/_in_process/_in_process.py:178:20: warning[possibly-missing-attribute] Attribute `build_wheel` on type `ModuleType | Any` may be missing
+ src/pip/_vendor/pyproject_hooks/_in_process/_in_process.py:195:16: warning[possibly-missing-attribute] Attribute `prepare_metadata_for_build_editable` on type `ModuleType | Any` may be missing
+ src/pip/_vendor/pyproject_hooks/_in_process/_in_process.py:200:26: warning[possibly-missing-attribute] Attribute `build_editable` on type `ModuleType | Any` may be missing
+ src/pip/_vendor/pyproject_hooks/_in_process/_in_process.py:280:12: warning[possibly-missing-attribute] Attribute `build_wheel` on type `ModuleType | Any` may be missing
+ src/pip/_vendor/pyproject_hooks/_in_process/_in_process.py:294:16: warning[possibly-missing-attribute] Attribute `build_editable` on type `ModuleType | Any` may be missing
+ src/pip/_vendor/pyproject_hooks/_in_process/_in_process.py:313:16: warning[possibly-missing-attribute] Attribute `get_requires_for_build_sdist` on type `ModuleType | Any` may be missing
+ src/pip/_vendor/pyproject_hooks/_in_process/_in_process.py:335:16: warning[possibly-missing-attribute] Attribute `build_sdist` on type `ModuleType | Any` may be missing
+ src/pip/_vendor/requests/models.py:121:26: error[not-iterable] Object of type `None | list[Unknown]` may not be iterable
+ src/pip/_vendor/requests/models.py:155:27: error[not-iterable] Object of type `None | list[Unknown]` may not be iterable
+ src/pip/_vendor/requests/models.py:173:21: error[not-iterable] Object of type `None | list[Unknown]` may not be iterable
+ src/pip/_vendor/requests/models.py:602:17: error[call-non-callable] Object of type `tuple[str, str]` is not callable
+ src/pip/_vendor/requests/sessions.py:80:5: error[no-matching-overload] No overload of bound method `update` matches arguments
+ src/pip/_vendor/requests/utils.py:615:31: error[invalid-argument-type] Argument to class `str` is incorrect: Expected `str`, found `None | Unknown | Literal["ISO-8859-1", "utf-8"]`
+ src/pip/_vendor/urllib3/contrib/_securetransport/bindings.py:136:5: warning[possibly-missing-attribute] Attribute `SecItemImport` on type `CDLL | None` may be missing
+ src/pip/_vendor/urllib3/contrib/_securetransport/bindings.py:146:5: warning[possibly-missing-attribute] Attribute `SecItemImport` on type `CDLL | None` may be missing
+ src/pip/_vendor/urllib3/contrib/_securetransport/bindings.py:148:5: warning[possibly-missing-attribute] Attribute `SecCertificateGetTypeID` on type `CDLL | None` may be missing
+ src/pip/_vendor/urllib3/contrib/_securetransport/bindings.py:149:5: warning[possibly-missing-attribute] Attribute `SecCertificateGetTypeID` on type `CDLL | None` may be missing
+ src/pip/_vendor/urllib3/contrib/_securetransport/bindings.py:151:5: warning[possibly-missing-attribute] Attribute `SecIdentityGetTypeID` on type `CDLL | None` may be missing
+ src/pip/_vendor/urllib3/contrib/_securetransport/bindings.py:152:5: warning[possibly-missing-attribute] Attribute `SecIdentityGetTypeID` on type `CDLL | None` may be missing
+ src/pip/_vendor/urllib3/contrib/_securetransport/bindings.py:154:5: warning[possibly-missing-attribute] Attribute `SecKeyGetTypeID` on type `CDLL | None` may be missing
+ src/pip/_vendor/urllib3/contrib/_securetransport/bindings.py:155:5: warning[possibly-missing-attribute] Attribute `SecKeyGetTypeID` on type `CDLL | None` may be missing
+ src/pip/_vendor/urllib3/contrib/_securetransport/bindings.py:157:5: warning[possibly-missing-attribute] Attribute `SecCertificateCreateWithData` on type `CDLL | None` may be missing
+ src/pip/_vendor/urllib3/contrib/_securetransport/bindings.py:158:5: warning[possibly-missing-attribute] Attribute `SecCertificateCreateWithData` on type `CDLL | None` may be missing
+ src/pip/_vendor/urllib3/contrib/_securetransport/bindings.py:160:5: warning[possibly-missing-attribute] Attribute `SecCertificateCopyData` on type `CDLL | None` may be missing
+ src/pip/_vendor/urllib3/contrib/_securetransport/bindings.py:161:5: warning[possibly-missing-attribute] Attribute `SecCertificateCopyData` on type `CDLL | None` may be missing
+ src/pip/_vendor/urllib3/contrib/_securetransport/bindings.py:163:5: warning[possibly-missing-attribute] Attribute `SecCopyErrorMessageString` on type `CDLL | None` may be missing
+ src/pip/_vendor/urllib3/contrib/_securetransport/bindings.py:164:5: warning[possibly-missing-attribute] Attribute `SecCopyErrorMessageString` on type `CDLL | None` may be missing
+ src/pip/_vendor/urllib3/contrib/_securetransport/bindings.py:166:5: warning[possibly-missing-attr...*[Comment body truncated]*

@mtshiba

This comment was marked as resolved.

@AlexWaygood AlexWaygood added the ty Multi-file analysis & type inference label Apr 13, 2025
@sharkdp

This comment was marked as resolved.

@mtshiba
Copy link
Contributor Author

mtshiba commented Apr 15, 2025

If a function contains a yield expression, i.e. if it is a generator, current type inference is incorrect. But supporting this requires solving another issues, so I will leave it as a TODO for now.

As for return type inference for normal functions, I think the work is completed.

@AlexWaygood AlexWaygood removed their request for review April 15, 2025 17:42
@mtshiba mtshiba force-pushed the infer-return-type branch 4 times, most recently from 3ba99d1 to 35f4a75 Compare May 8, 2025 15:56
@MichaReiser MichaReiser changed the title [red-knot] infer function's return type [ty] infer function's return type May 8, 2025
@mtshiba mtshiba force-pushed the infer-return-type branch from 404c1da to 80f2b5c Compare May 8, 2025 17:35
@carljm
Copy link
Contributor

carljm commented May 9, 2025

Sorry that I haven't gotten around to reviewing this PR yet. There's just been a lot to do, and providing this feature is lower on my priority list than some other features. But I realize that places a burden on you to keep it up to date with (rapidly changing) main branch. But I will try to find time to review it soon.

@mtshiba mtshiba force-pushed the infer-return-type branch from 0a16b46 to 126aef8 Compare May 11, 2025 12:18
@mtshiba mtshiba force-pushed the infer-return-type branch from 91c66c1 to 22e8594 Compare May 11, 2025 12:45
@mtshiba mtshiba force-pushed the infer-return-type branch from 22e8594 to 391ee91 Compare May 11, 2025 12:50
Copy link
Contributor

@carljm carljm left a comment

Choose a reason for hiding this comment

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

Partial review here; plane is landing now so submitting the comments I have. Will come back to this later.

Thank you for working on this, and sorry for the slow review! It's a very useful feature.

@mtshiba
Copy link
Contributor Author

mtshiba commented Sep 25, 2025

Parts not directly related to this PR have been moved to #20566, which aims to make recursive type inference converge more generally.

The handling of recursive type inference in this PR should be replaced with something more sophisticated, but I think it's best to land this PR first and complete it in #20566.

@mtshiba mtshiba marked this pull request as ready for review September 25, 2025 06:23
@mtshiba mtshiba requested a review from carljm September 25, 2025 06:25
Copy link
Contributor

@carljm carljm left a comment

Choose a reason for hiding this comment

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

This is looking good! Some comments and questions inline.

I will be a bit hesitant to land this before type-of-self lands, because type-of-self is critical, and the more new type information we introduce, the more blockers we encounter there. (This already happened with the dict literal inference PR.)

Comment on lines +626 to +630
/// When using `ScopeInference` during type inference,
/// use this method to get the cycle recovery type so that divergent types are propagated.
pub(super) fn cycle_recovery(&self) -> Option<Type<'db>> {
self.fallback_type()
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we need this method if it's just an alias for fallback_type() method?

if let Some(previous_cycle_value) = callee_ty.infer_return_type(db) {
// In fixed-point iteration of return type inference, the return type must be monotonically widened and not "oscillate".
// Here, monotonicity is guaranteed by pre-unioning the type of the previous iteration into the current result.
union = union.add(previous_cycle_value.recursive_type_normalized(db, &visitor));
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
union = union.add(previous_cycle_value.recursive_type_normalized(db, &visitor));
// TODO: this means that every `infer_return_type` creates a self-cycle that must be iterated.
// Instead, have Salsa provide both previous and current value so we can do this in the
// recovery function.
union = union.add(previous_cycle_value.recursive_type_normalized(db, &visitor));

// In the following cases, the bound type may not be the same as the RHS value type.
if let AnyNodeRef::ExprAttribute(ast::ExprAttribute { value, attr, .. }) = node {
let value_ty = self.try_expression_type(value).unwrap_or_else(|| {
let value_ty = self.try_expression_type(value.as_ref()).unwrap_or_else(|| {
Copy link
Contributor

Choose a reason for hiding this comment

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

We could probably implement Into<ExpressionNodeKey> for &Box<Expr> to avoid the need for this?

Comment on lines +4765 to +4774
self.infer_optional_expression(ret.value.as_deref(), TypeContext::default());
let range = ret
.value
.as_ref()
.map_or(ret.range(), |value| value.range());
let expression = ret
.value
.as_ref()
.map(|expr| ExpressionNodeKey::from(&**expr));
self.record_returnee(expression, range);
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we need to store the expression key instead of storing the type directly?

.filter_map(|returnee| {
match returnee
.expression
.map_or(Type::none(self.db()), |expression| {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why would we fallback to Type::none here?

It seems like we should just expect here, we should always have inferred a type for every returnee expression.

if visitor.level() == 0 && self == visitor.div {
// int | Divergent = int | (int | (int | ...)) = int
return Type::Never;
} else if visitor.level() >= 1 && self.has_divergent_type(db, visitor.div) {
Copy link
Contributor

Choose a reason for hiding this comment

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

If the level >= 1 and self does not contain visitor.div, do we need to keep walking self recursively, or could we just short-circuit and return self? It seems we will not change anything in the visit.

It's not really clear to me that we even need all the many added recursive_type_normalized methods in this PR, and all the level and visit_no_shift stuff either. Wouldn't it be an equivalent implementation if we just match on unions here, visit all their elements, and for any other type, check has_divergent_type and return div if so?

}

/// Infers this method scope's types and returns the inferred return type.
#[salsa::tracked(cycle_fn=return_type_cycle_recover, cycle_initial=return_type_cycle_initial, heap_size=get_size2::heap_size)]
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this need to be a separate Salsa query, or could we just infer the return type of self.function(db)?

We could add the union with Unknown here rather than inside ScopeInference::infer_return_type.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ty Multi-file analysis & type inference

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Return type inference

5 participants