Skip to content

[ty] Infer nonlocal types as unions of all reachable bindings #18750

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

Merged
merged 29 commits into from
Jun 26, 2025

Conversation

sharkdp
Copy link
Contributor

@sharkdp sharkdp commented Jun 18, 2025

Summary

This PR includes a behavioral change to how we infer types for nonlocal uses of symbols within a module. Where we would previously use the type that a use at the end of the scope would see, we now consider all reachable bindings and union the results:

x = None

def f():
    reveal_type(x)  # previously `Unknown | Literal[1]`, now `Unknown | None | Literal[1]`

f()

x = 1

f()

This helps especially in cases where the the end of the scope is not reachable:

def outer(x: int):
    def inner():
        reveal_type(x)  # previously `Unknown`, now `int`

    raise ValueError

This PR also proposes to skip the boundness analysis of nonlocal uses. This is consistent with the "all reachable bindings" strategy, because the implicit x = <unbound> binding is also always reachable, and we would have to emit "possibly-unresolved" diagnostics for every nonlocal use otherwise. Changing this behavior allows common use-cases like the following to type check without any errors:

def outer(flag: bool):
    if flag:
        x = 1

        def inner():
            print(x)  # previously: possibly-unresolved-reference, now: no error

closes astral-sh/ty#210
closes astral-sh/ty#607
closes astral-sh/ty#699

Follow up

It is now possible to resolve the following TODO, but I would like to do that as a follow-up, because it requires some changes to how we treat implicit attribute assignments, which could result in ecosystem changes that I'd like to see separately.

// TODO: Fix how we determine the public types of symbols in a
// function-like scope: https://github.com/astral-sh/ruff/issues/15777
//
// In the meantime, visit the function body, but treat the last statement
// specially if it is a return. If it is, this would cause all definitions
// in the function to be marked as non-visible with our current treatment
// of terminal statements. Since we currently model the externally visible
// definitions in a function scope as the set of bindings that are visible
// at the end of the body, we then consider this function to have no
// externally visible definitions. To get around this, we take a flow
// snapshot just before processing the return statement, and use _that_ as
// the "end-of-body" state that we resolve external references against.
if let Some((last_stmt, first_stmts)) = body.split_last() {
builder.visit_body(first_stmts);
let pre_return_state = matches!(last_stmt, ast::Stmt::Return(_))
.then(|| builder.flow_snapshot());
builder.visit_stmt(last_stmt);
let reachability = builder.current_use_def_map().reachability;
if let Some(pre_return_state) = pre_return_state {
builder.flow_restore(pre_return_state);
builder.current_use_def_map_mut().reachability = reachability;
}
}

Ecosystem analysis

Full report

  • This change obviously removes a lot of possibly-unresolved-reference diagnostics (7818) because we do not analyze boundness for nonlocal uses of symbols inside modules anymore.
  • As the primary goal here, this change also removes a lot of false-positive unresolved-reference diagnostics (231) in scenarios like this:
    def _(flag: bool):
        if flag:
            x = 1
    
            def inner():
                x
    
            raise
  • This change also introduces some new false positives for cases like:
    def _():
        x = None
    
        x = "test"
    
        def inner():
            x.upper()  # Attribute `upper` on type `Unknown | None | Literal["test"]` is possibly unbound
    We have test cases for these situations and it's plausible that we can improve this in a follow-up.

Test Plan

New Markdown tests

@sharkdp sharkdp added the ty Multi-file analysis & type inference label Jun 18, 2025
@sharkdp sharkdp changed the title David/public types [ty] Infer public types as unions of all reachable bindings Jun 18, 2025
Copy link
Contributor

github-actions bot commented Jun 18, 2025

mypy_primer results

Changes were detected when running on open source projects
pytest-robotframework (https://github.com/detachhead/pytest-robotframework)
+ warning[unused-ignore-comment] pytest_robotframework/_internal/robot/listeners_and_suite_visitors.py:673:33: Unused `ty: ignore` directive: 'possibly-unresolved-reference'
+ warning[unused-ignore-comment] pytest_robotframework/_internal/robot/listeners_and_suite_visitors.py:690:40: Unused `ty: ignore` directive: 'possibly-unresolved-reference'
- Found 183 diagnostics
+ Found 185 diagnostics

mypy_primer (https://github.com/hauntsaninja/mypy_primer)
- error[unresolved-reference] mypy_primer/main.py:175:67: Name `shard_costs` used when not defined
- Found 10 diagnostics
+ Found 9 diagnostics

git-revise (https://github.com/mystor/git-revise)
- warning[possibly-unresolved-reference] gitrevise/utils.py:102:34: Name `pat_is_comment_line` used when possibly not defined
- Found 2 diagnostics
+ Found 1 diagnostic

parso (https://github.com/davidhalter/parso)
- warning[possibly-unresolved-reference] parso/python/errors.py:323:36: Name `base_name` used when possibly not defined
- warning[possibly-unresolved-reference] parso/python/errors.py:323:58: Name `base_name` used when possibly not defined
- warning[possibly-unresolved-reference] parso/python/tokenize.py:385:43: Name `spos` used when possibly not defined
- warning[possibly-unresolved-reference] parso/python/tree.py:422:31: Name `dct` used when possibly not defined
- warning[possibly-unresolved-reference] parso/python/tree.py:426:25: Name `recurse` used when possibly not defined
- Found 77 diagnostics
+ Found 72 diagnostics

pyp (https://github.com/hauntsaninja/pyp)
- error[unresolved-reference] pyp.py:652:24: Name `line_to_node` used when not defined
- Found 9 diagnostics
+ Found 8 diagnostics

python-chess (https://github.com/niklasf/python-chess)
- warning[possibly-unresolved-reference] chess/engine.py:962:25: Name `cmd` used when possibly not defined
- Found 20 diagnostics
+ Found 19 diagnostics

paroxython (https://github.com/laowantong/paroxython)
- warning[possibly-unresolved-reference] paroxython/__init__.py:36:33: Name `ParoxythonMagics` used when possibly not defined
- warning[possibly-unresolved-reference] paroxython/__init__.py:55:26: Name `main` used when possibly not defined
- warning[possibly-unresolved-reference] paroxython/__init__.py:62:21: Name `display` used when possibly not defined
- warning[possibly-unresolved-reference] paroxython/__init__.py:62:29: Name `Markdown` used when possibly not defined
- Found 15 diagnostics
+ Found 11 diagnostics

beartype (https://github.com/beartype/beartype)
- warning[possibly-unresolved-reference] beartype/_util/hint/pep/proposal/pep484604.py:47:33: Name `HintPep604ItemTypes` used when possibly not defined
- warning[possibly-unresolved-reference] beartype/_util/hint/pep/proposal/pep484604.py:112:33: Name `HintPep604Type` used when possibly not defined
- warning[possibly-unresolved-reference] beartype/_util/hint/pep/proposal/pep649.py:223:9: Name `_MODULE_NAME_TO_ANNOTATIONS` used when possibly not defined
- warning[possibly-unresolved-reference] beartype/_util/hint/pep/proposal/pep649.py:224:9: Name `_MODULE_NAME_TO_HINTABLE_BASENAME_TO_ANNOTATIONS` used when possibly not defined
- warning[possibly-unresolved-reference] beartype/_util/hint/pep/proposal/pep649.py:243:33: Name `CallableOrClassTypes` used when possibly not defined
- warning[possibly-unresolved-reference] beartype/_util/hint/pep/proposal/pep649.py:247:27: Name `get_object_module_name_or_none` used when possibly not defined
- warning[possibly-unresolved-reference] beartype/_util/hint/pep/proposal/pep649.py:256:21: Name `_MODULE_NAME_TO_HINTABLE_BASENAME_TO_ANNOTATIONS` used when possibly not defined
- warning[possibly-unresolved-reference] beartype/_util/hint/pep/proposal/pep649.py:257:38: Name `SENTINEL` used when possibly not defined
- warning[possibly-unresolved-reference] beartype/_util/hint/pep/proposal/pep649.py:260:56: Name `SENTINEL` used when possibly not defined
- warning[possibly-unresolved-reference] beartype/_util/hint/pep/proposal/pep649.py:264:25: Name `_MODULE_NAME_TO_HINTABLE_BASENAME_TO_ANNOTATIONS` used when possibly not defined
- warning[possibly-unresolved-reference] beartype/_util/hint/pep/proposal/pep649.py:272:37: Name `get_object_basename_scoped` used when possibly not defined
- warning[possibly-unresolved-reference] beartype/_util/hint/pep/proposal/pep649.py:279:40: Name `SENTINEL` used when possibly not defined
- warning[possibly-unresolved-reference] beartype/_util/hint/pep/proposal/pep649.py:282:48: Name `SENTINEL` used when possibly not defined
- warning[possibly-unresolved-reference] beartype/_util/hint/pep/proposal/pep649.py:288:21: Name `_get_pep649_hintable_annotations_or_none_uncached` used when possibly not defined
- warning[possibly-unresolved-reference] beartype/_util/hint/pep/proposal/pep649.py:303:35: Name `ModuleType` used when possibly not defined
- warning[possibly-unresolved-reference] beartype/_util/hint/pep/proposal/pep649.py:305:27: Name `get_module_name` used when possibly not defined
- warning[possibly-unresolved-reference] beartype/_util/hint/pep/proposal/pep649.py:311:34: Name `_MODULE_NAME_TO_ANNOTATIONS` used when possibly not defined
- warning[possibly-unresolved-reference] beartype/_util/hint/pep/proposal/pep649.py:312:30: Name `SENTINEL` used when possibly not defined
- warning[possibly-unresolved-reference] beartype/_util/hint/pep/proposal/pep649.py:315:42: Name `SENTINEL` used when possibly not defined
- warning[possibly-unresolved-reference] beartype/_util/hint/pep/proposal/pep649.py:321:17: Name `_get_pep649_hintable_annotations_or_none_uncached` used when possibly not defined
- warning[possibly-unresolved-reference] beartype/_util/hint/pep/proposal/pep649.py:324:13: Name `_MODULE_NAME_TO_ANNOTATIONS` used when possibly not defined
- warning[possibly-unresolved-reference] beartype/_util/hint/pep/proposal/pep649.py:335:16: Name `_get_pep649_hintable_annotations_or_none_uncached` used when possibly not defined
- warning[possibly-unresolved-reference] beartype/_util/hint/pep/proposal/pep649.py:375:36: Name `Format` used when possibly not defined
- warning[possibly-unresolved-reference] beartype/_util/hint/pep/proposal/pep649.py:487:35: Name `_ANNOTATE_FORMATS_VALUELIKE` used when possibly not defined
- warning[possibly-unresolved-reference] beartype/_util/hint/pep/proposal/pep649.py:495:36: Name `Format` used when possibly not defined
- warning[possibly-unresolved-reference] beartype/_util/hint/pep/proposal/pep649.py:860:20: Name `get_annotations` used when possibly not defined
- warning[possibly-unresolved-reference] beartype/_util/hint/pep/proposal/pep649.py:860:53: Name `Format` used when possibly not defined
- warning[possibly-unresolved-reference] beartype/typing/_typingpep544.py:690:16: Name `_generic_class_getitem_old` used when possibly not defined
- Found 581 diagnostics
+ Found 553 diagnostics

pyinstrument (https://github.com/joerick/pyinstrument)
+ error[unresolved-attribute] pyinstrument/context_manager.py:56:54: Type `((...) -> Unknown) | None` has no attribute `__qualname__`
+ error[unresolved-attribute] pyinstrument/context_manager.py:56:77: Type `((...) -> Unknown) | None` has no attribute `__code__`
+ error[unresolved-attribute] pyinstrument/context_manager.py:56:105: Type `((...) -> Unknown) | None` has no attribute `__code__`
+ error[call-non-callable] pyinstrument/context_manager.py:59:28: Object of type `None` is not callable
- error[unresolved-reference] pyinstrument/magic/magic.py:258:31: Name `old_custom_tb` used when not defined
- error[unresolved-reference] pyinstrument/magic/magic.py:259:40: Name `old_custom_exceptions` used when not defined
- error[unresolved-reference] pyinstrument/vendor/appdirs.py:99:33: Name `_get_win_folder` used when not defined
- error[unresolved-reference] pyinstrument/vendor/appdirs.py:152:33: Name `_get_win_folder` used when not defined
- error[unresolved-reference] pyinstrument/vendor/appdirs.py:319:33: Name `_get_win_folder` used when not defined
- warning[possibly-unresolved-reference] pyinstrument/vendor/decorator.py:57:16: Name `FullArgSpec` used when possibly not defined
- Found 52 diagnostics
+ Found 50 diagnostics

anyio (https://github.com/agronholm/anyio)
- warning[possibly-unresolved-reference] src/anyio/abc/_sockets.py:77:67: Name `remote_port` used when possibly not defined
- warning[possibly-unbound-attribute] src/anyio/from_thread.py:211:27: Attribute `cancel` on type `Unknown | None` is possibly unbound
+ warning[possibly-unbound-attribute] src/anyio/from_thread.py:211:27: Attribute `cancel` on type `Unknown | CancelScope | None` is possibly unbound
- error[unresolved-reference] src/anyio/pytest_plugin.py:90:12: Name `has_backend_arg` used when not defined
- error[unresolved-reference] src/anyio/pytest_plugin.py:93:12: Name `has_request_arg` used when not defined
- warning[possibly-unresolved-reference] src/anyio/pytest_plugin.py:139:25: Name `backend_name` used when possibly not defined
- warning[possibly-unresolved-reference] src/anyio/pytest_plugin.py:139:39: Name `backend_options` used when possibly not defined
- error[unresolved-reference] src/anyio/pytest_plugin.py:140:29: Name `original_func` used when not defined
- Found 100 diagnostics
+ Found 94 diagnostics

Expression (https://github.com/cognitedata/Expression)
- error[unresolved-reference] expression/core/result.py:121:56: Name `value` used when not defined
- Found 235 diagnostics
+ Found 234 diagnostics

aioredis (https://github.com/aio-libs/aioredis)
- warning[possibly-unresolved-reference] aioredis/connection.py:455:32: Name `hiredis` used when possibly not defined
- warning[possibly-unresolved-reference] aioredis/connection.py:468:24: Name `hiredis` used when possibly not defined
- Found 22 diagnostics
+ Found 20 diagnostics

attrs (https://github.com/python-attrs/attrs)
- warning[possibly-unresolved-reference] tests/test_slots.py:94:16: Name `asizeof` used when possibly not defined
- warning[possibly-unresolved-reference] tests/test_slots.py:94:41: Name `asizeof` used when possibly not defined
- warning[possibly-unresolved-reference] tests/test_slots.py:257:16: Name `asizeof` used when possibly not defined
- warning[possibly-unresolved-reference] tests/test_slots.py:257:30: Name `asizeof` used when possibly not defined
- warning[possibly-unresolved-reference] tests/test_slots.py:401:16: Name `asizeof` used when possibly not defined
- warning[possibly-unresolved-reference] tests/test_slots.py:401:30: Name `asizeof` used when possibly not defined
- Found 608 diagnostics
+ Found 602 diagnostics

aiortc (https://github.com/aiortc/aiortc)
- warning[possibly-unresolved-reference] src/aiortc/contrib/signaling.py:126:17: Name `connected` used when possibly not defined
- warning[possibly-unresolved-reference] src/aiortc/contrib/signaling.py:183:17: Name `connected` used when possibly not defined
- warning[possibly-unresolved-reference] src/aiortc/rtcpeerconnection.py:105:43: Name `c` used when possibly not defined
- warning[possibly-unresolved-reference] src/aiortc/rtcsctptransport.py:743:68: Name `prefix` used when possibly not defined
- Found 102 diagnostics
+ Found 98 diagnostics

speedrun.com_global_scoreboard_webapp (https://github.com/Avasam/speedrun.com_global_scoreboard_webapp)
- warning[possibly-unresolved-reference] backend/models/core_models.py:242:18: Name `Schedule` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:243:13: Name `Schedule` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:243:35: Name `Schedule` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:254:24: Name `Schedule` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:266:13: Name `TimeSlot` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:289:17: Name `Schedule` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:290:17: Name `Schedule` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:292:25: Name `Schedule` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:293:25: Name `Schedule` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:319:33: Name `TimeSlot` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:341:17: Name `ScheduleGroup` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:343:29: Name `ScheduleGroup` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:344:29: Name `ScheduleGroup` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:347:17: Name `Schedule` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:348:17: Name `Schedule` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:350:25: Name `Schedule` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:351:25: Name `Schedule` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:363:34: Name `Schedule` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:365:25: Name `Schedule` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:366:25: Name `Schedule` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:377:29: Name `ScheduleGroup` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:377:86: Name `Schedule` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:378:25: Name `ScheduleGroup` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:378:73: Name `Schedule` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:380:27: Name `ScheduleGroup` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:380:42: Name `Schedule` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:396:18: Name `ScheduleGroup` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:397:13: Name `ScheduleGroup` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:397:40: Name `ScheduleGroup` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:401:30: Name `ScheduleGroup` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:415:17: Name `ScheduleGroup` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:416:17: Name `ScheduleGroup` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:418:25: Name `ScheduleGroup` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:419:25: Name `ScheduleGroup` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:432:40: Name `ScheduleGroup` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:434:25: Name `ScheduleGroup` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:435:25: Name `ScheduleGroup` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:446:17: Name `Registration` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:447:17: Name `Registration` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:449:25: Name `Registration` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:453:13: Name `Schedule` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:455:25: Name `Schedule` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:456:25: Name `Schedule` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:473:35: Name `Participant` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:489:17: Name `Registration` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:490:17: Name `Registration` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:492:25: Name `Registration` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:496:13: Name `Schedule` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:498:25: Name `Schedule` used when possibly not defined
- warning[possibly-unresolved-reference] backend/models/core_models.py:499:25: Name `Schedule` used when possibly not defined
- Found 116 diagnostics
+ Found 66 diagnostics

graphql-core (https://github.com/graphql-python/graphql-core)
- warning[possibly-unresolved-reference] src/graphql/execution/execute.py:1062:38: Name `completed_item` used when possibly not defined
+ warning[unused-ignore-comment] src/graphql/execution/execute.py:1249:47: Unused blanket `type: ignore` directive
- warning[possibly-unresolved-reference] src/graphql/execution/execute.py:1449:40: Name `incremental_result` used when possibly not defined
+ warning[possibly-unbound-attribute] src/graphql/execution/execute.py:2200:20: Attribute `map_source_to_response` on type `Unknown | list[GraphQLError] | ExecutionContext` is possibly unbound
- error[unresolved-reference] src/graphql/execution/execute.py:2283:30: Name `awaitable_event_stream` used when not defined
- error[unresolved-reference] src/graphql/language/visitor.py:341:44: Name `enter_list` used when not defined
- error[unresolved-reference] src/graphql/language/visitor.py:354:44: Name `leave_list` used when not defined
+ error[unresolved-attribute] src/graphql/utilities/lexicographic_sort_schema.py:124:51: Type `GraphQLNamedType` has no attribute `interfaces`
+ error[unresolved-attribute] src/graphql/utilities/lexicographic_sort_schema.py:125:48: Type `GraphQLNamedType` has no attribute `fields`
+ error[unresolved-attribute] src/graphql/utilities/lexicographic_sort_schema.py:132:51: Type `GraphQLNamedType` has no attribute `interfaces`
+ error[unresolved-attribute] src/graphql/utilities/lexicographic_sort_schema.py:133:48: Type `GraphQLNamedType` has no attribute `fields`
+ error[unresolved-attribute] src/graphql/utilities/lexicographic_sort_schema.py:138:76: Type `GraphQLNamedType` has no attribute `types`
+ error[unresolved-attribute] src/graphql/utilities/lexicographic_sort_schema.py:159:54: Type `GraphQLNamedType` has no attribute `fields`
- warning[possibly-unresolved-reference] tests/language/test_visitor.py:111:17: Name `visited` used when possibly not defined
- warning[possibly-unresolved-reference] tests/language/test_visitor.py:117:17: Name `visited` used when possibly not defined
- warning[possibly-unresolved-reference] tests/language/test_visitor.py:123:17: Name `visited` used when possibly not defined
- warning[possibly-unresolved-reference] tests/language/test_visitor.py:129:17: Name `visited` used when possibly not defined
- warning[possibly-unresolved-reference] tests/language/test_visitor.py:137:17: Name `visited` used when possibly not defined
- warning[possibly-unresolved-reference] tests/language/test_visitor.py:144:17: Name `visited` used when possibly not defined
- warning[possibly-unresolved-reference] tests/language/test_visitor.py:151:17: Name `visited` used when possibly not defined
- warning[possibly-unresolved-reference] tests/language/test_visitor.py:158:17: Name `visited` used when possibly not defined
- warning[possibly-unresolved-reference] tests/language/test_visitor.py:165:17: Name `visited` used when possibly not defined
- warning[possibly-unresolved-reference] tests/language/test_visitor.py:171:17: Name `visited` used when possibly not defined
- warning[possibly-unresolved-reference] tests/language/test_visitor.py:177:17: Name `visited` used when possibly not defined
- warning[possibly-unresolved-reference] tests/language/test_visitor.py:183:17: Name `visited` used when possibly not defined
- error[unresolved-reference] tests/utils/assert_equal_awaitables_or_values.py:21:67: Name `awaitable_items` used when not defined
- Found 381 diagnostics
+ Found 371 diagnostics

starlette (https://github.com/encode/starlette)
- warning[possibly-unresolved-reference] starlette/_utils.py:80:35: Name `BaseExceptionGroup` used when possibly not defined
- warning[possibly-unresolved-reference] starlette/responses.py:275:25: Name `task_group` used when possibly not defined
- warning[possibly-unresolved-reference] starlette/templating.py:119:10: Name `pass_context` used when possibly not defined
- Found 173 diagnostics
+ Found 170 diagnostics

rich (https://github.com/Textualize/rich)
- warning[possibly-unresolved-reference] examples/listdir.py:23:45: Name `root_path` used when possibly not defined
- warning[possibly-unresolved-reference] examples/suppress.py:19:9: Name `click` used when possibly not defined
- warning[possibly-unresolved-reference] rich/ansi.py:225:16: Name `os` used when possibly not defined
- warning[possibly-unresolved-reference] rich/ansi.py:226:9: Name `stdout` used when possibly not defined
- error[invalid-return-type] rich/console.py:575:16: Return type does not match returned value: expected `WindowsConsoleFeatures`, found `WindowsConsoleFeatures | None`
+ error[invalid-return-type] rich/console.py:575:16: Return type does not match returned value: expected `WindowsConsoleFeatures`, found `None | WindowsConsoleFeatures`
- warning[possibly-unresolved-reference] rich/logging.py:287:9: Name `log` used when possibly not defined
- warning[possibly-unresolved-reference] rich/logging.py:291:13: Name `log` used when possibly not defined
- warning[possibly-unresolved-reference] rich/palette.py:92:34: Name `colorsys` used when possibly not defined
- warning[possibly-unresolved-reference] rich/palette.py:93:34: Name `colorsys` used when possibly not defined
- warning[possibly-unresolved-reference] rich/palette.py:94:31: Name `Color` used when possibly not defined
- warning[possibly-unresolved-reference] rich/palette.py:95:29: Name `Color` used when possibly not defined
- warning[possibly-unresolved-reference] rich/palette.py:96:27: Name `Segment` used when possibly not defined
- warning[possibly-unresolved-reference] rich/palette.py:96:40: Name `Style` used when possibly not defined
- warning[possibly-unresolved-reference] rich/palette.py:97:23: Name `Segment` used when possibly not defined
- warning[possibly-unresolved-reference] rich/pretty.py:62:27: Name `_attr_module` used when possibly not defined
- warning[possibly-unresolved-reference] rich/pretty.py:67:12: Name `_attr_module` used when possibly not defined
- warning[possibly-unresolved-reference] rich/pretty.py:735:37: Name `attr_fields` used when possibly not defined
- warning[possibly-unresolved-reference] rich/syntax.py:516:35: Name `line_tokenize` used when possibly not defined
- warning[possibly-unresolved-reference] rich/syntax.py:518:35: Name `line_start` used when possibly not defined
- warning[possibly-unresolved-reference] rich/syntax.py:518:53: Name `line_start` used when possibly not defined
- warning[possibly-unresolved-reference] rich/syntax.py:534:32: Name `line_end` used when possibly not defined
- warning[possibly-unresolved-reference] rich/syntax.py:534:56: Name `line_end` used when possibly not defined
- warning[possibly-unresolved-reference] rich/table.py:845:20: Name `header_row` used when possibly not defined
- warning[possibly-unresolved-reference] rich/table.py:847:22: Name `footer_row` used when possibly not defined
- warning[possibly-unresolved-reference] rich/table.py:851:60: Name `row_height` used when possibly not defined
- warning[possibly-unresolved-reference] rich/table.py:853:63: Name `row_height` used when possibly not defined
- warning[possibly-unresolved-reference] rich/table.py:854:59: Name `row_height` used when possibly not defined
- warning[possibly-unresolved-reference] rich/table.py:968:13: Name `console` used when possibly not defined
- warning[possibly-unresolved-reference] rich/table.py:969:13: Name `console` used when possibly not defined
- warning[possibly-unresolved-reference] rich/table.py:969:26: Name `highlight` used when possibly not defined
- warning[possibly-unresolved-reference] rich/table.py:970:13: Name `console` used when possibly not defined
- warning[possibly-unresolved-reference] rich/traceback.py:894:9: Name `bar` used when possibly not defined
- warning[possibly-unresolved-reference] rich/traceback.py:897:9: Name `foo` used when possibly not defined
- warning[possibly-unresolved-reference] tests/test_windows_renderer.py:20:28: Name `LegacyWindowsTerm` used when possibly not defined
- warning[possibly-unresolved-reference] tests/test_windows_renderer.py:26:5: Name `legacy_windows_render` used when possibly not defined
- warning[possibly-unresolved-reference] tests/test_windows_renderer.py:33:5: Name `legacy_windows_render` used when possibly not defined
- warning[possibly-unresolved-reference] tests/test_windows_renderer.py:46:5: Name `legacy_windows_render` used when possibly not defined
- warning[possibly-unresolved-reference] tests/test_windows_renderer.py:54:5: Name `legacy_windows_render` used when possibly not defined
- warning[possibly-unresolved-reference] tests/test_windows_renderer.py:57:9: Name `WindowsCoordinates` used when possibly not defined
- warning[possibly-unresolved-reference] tests/test_windows_renderer.py:64:5: Name `legacy_windows_render` used when possibly not defined
- warning[possibly-unresolved-reference] tests/test_windows_renderer.py:72:5: Name `legacy_windows_render` used when possibly not defined
- warning[possibly-unresolved-reference] tests/test_windows_renderer.py:74:61: Name `WindowsCoordinates` used when possibly not defined
- warning[possibly-unresolved-reference] tests/test_windows_renderer.py:91:5: Name `legacy_windows_render` used when possibly not defined
- warning[possibly-unresolved-reference] tests/test_windows_renderer.py:107:5: Name `legacy_windows_render` used when possibly not defined
- warning[possibly-unresolved-reference] tests/test_windows_renderer.py:115:5: Name `legacy_windows_render` used when possibly not defined
- warning[possibly-unresolved-reference] tests/test_windows_renderer.py:123:5: Name `legacy_windows_render` used when possibly not defined
- warning[possibly-unresolved-reference] tests/test_windows_renderer.py:131:5: Name `legacy_windows_render` used when possibly not defined
- warning[possibly-unresolved-reference] tests/test_windows_renderer.py:139:5: Name `legacy_windows_render` used when possibly not defined
- Found 374 diagnostics
+ Found 327 diagnostics

kornia (https://github.com/kornia/kornia)
- warning[possibly-unresolved-reference] kornia/feature/dedode/transformer/layers/attention.py:89:19: Name `unbind` used when possibly not defined
- warning[possibly-unresolved-reference] kornia/feature/dedode/transformer/layers/attention.py:91:13: Name `memory_efficient_attention` used when possibly not defined
- warning[possibly-unresolved-reference] kornia/feature/dedode/transformer/layers/block.py:168:27: Name `scaled_index_add` used when possibly not defined
- warning[possibly-unresolved-reference] kornia/feature/dedode/transformer/layers/block.py:186:21: Name `fmha` used when possibly not defined
- warning[possibly-unresolved-reference] kornia/feature/dedode/transformer/layers/block.py:191:23: Name `index_select_cat` used when possibly not defined
- Found 804 diagnostics
+ Found 799 diagnostics

dedupe (https://github.com/dedupeio/dedupe)
- warning[possibly-unresolved-reference] dedupe/training.py:306:21: Name `covered_sample_matches` used when possibly not defined
- warning[possibly-unresolved-reference] dedupe/training.py:306:46: Name `sample_match_cover` used when possibly not defined
- warning[possibly-unresolved-reference] dedupe/training.py:307:25: Name `covered_comparisons` used when possibly not defined
- Found 62 diagnostics
+ Found 59 diagnostics

trio (https://github.com/python-trio/trio)
- error[invalid-type-form] src/trio/_core/_io_kqueue.py:150:30: List literals are not allowed in this context in a type expression
+ error[invalid-argument-type] src/trio/_core/_io_kqueue.py:287:58: Argument is incorrect: Expected `bool`, found `ClosedResourceError`
- error[invalid-type-form] src/trio/_core/_io_windows.py:931:29: List literals are not allowed in this context in a type expression
- warning[possibly-unresolved-reference] src/trio/_core/_run.py:140:25: Name `get_pretty_function_description` used when possibly not defined
- error[unresolved-reference] src/trio/_core/_tests/test_guest_mode.py:70:13: Name `todo` used when not defined
- error[unresolved-reference] src/trio/_core/_tests/test_guest_mode.py:71:9: Name `todo` used when not defined
- error[unresolved-reference] src/trio/_core/_tests/test_guest_mode.py:80:13: Name `todo` used when not defined
- error[unresolved-reference] src/trio/_core/_tests/test_guest_mode.py:81:9: Name `todo` used when not defined
- error[unresolved-reference] src/trio/_core/_tests/test_guest_mode.py:85:9: Name `todo` used when not defined
- warning[possibly-unresolved-reference] src/trio/_deprecate.py:93:17: Name `thing` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_highlevel_open_unix_stream.py:61:19: Name `AF_UNIX` used when possibly not defined
- error[unresolved-reference] src/trio/_subprocess.py:763:26: Name `killer_cscope` used when not defined
+ error[call-non-callable] src/trio/_subprocess.py:764:31: Object of type `None` is not callable
- warning[possibly-unresolved-reference] src/trio/_subprocess_platform/waitid.py:17:9: Name `waitid` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_subprocess_platform/waitid.py:57:18: Name `waitid_ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_subprocess_platform/waitid.py:58:15: Name `waitid_cffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_subprocess_platform/waitid.py:59:25: Name `waitid_ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_sync.py:99:36: Name `task` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_dtls.py:36:11: Name `SSL` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_dtls.py:36:23: Name `SSL` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_dtls.py:42:11: Name `SSL` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_dtls.py:42:23: Name `SSL` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_exports.py:306:28: Name `cache` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_highlevel_serve_listeners.py:120:19: Name `error` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_highlevel_serve_listeners.py:123:25: Name `error` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_socket.py:667:27: Name `local` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_ssl.py:208:15: Name `SSL` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_ssl.py:208:27: Name `SSL` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_ssl.py:225:28: Name `SSL` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_ssl.py:227:22: Name `SSL` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_ssl.py:277:24: Name `SSL` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_ssl.py:281:24: Name `SSL` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_ssl.py:301:28: Name `SSL` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_ssl.py:316:36: Name `SSL` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_ssl.py:325:40: Name `SSL` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:29:15: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:29:37: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:29:60: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:30:5: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:31:5: Name `WaitForMultipleObjects_sync` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:32:5: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:36:15: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:36:37: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:36:60: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:37:15: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:37:37: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:37:60: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:38:5: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:39:5: Name `WaitForMultipleObjects_sync` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:40:5: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:41:5: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:45:15: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:45:37: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:45:60: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:46:15: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:46:37: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:46:60: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:47:5: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:48:5: Name `WaitForMultipleObjects_sync` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:49:5: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:50:5: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:54:15: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:54:37: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:54:60: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:55:15: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:55:37: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:55:60: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:56:5: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:58:9: Name `WaitForMultipleObjects_sync` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:59:5: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:63:15: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:63:37: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:63:60: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:64:15: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:64:37: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:64:60: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:65:5: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:67:9: Name `WaitForMultipleObjects_sync` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:68:5: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:80:15: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:80:37: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:80:60: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:85:13: Name `WaitForMultipleObjects_sync` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:91:9: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:94:5: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:98:15: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:98:37: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:98:60: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:99:15: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:99:37: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:99:60: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:104:13: Name `WaitForMultipleObjects_sync` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:109:9: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:112:5: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:113:5: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:117:15: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:117:37: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:117:60: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:118:15: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:118:37: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:118:60: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:123:13: Name `WaitForMultipleObjects_sync` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:128:9: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:131:5: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:132:5: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:141:14: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:141:36: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:141:59: Name `ffi` used when possibly not defined
+ warning[unused-ignore-comment] src/trio/_tests/test_wait_for_object.py:164:52: Unused blanket `type: ignore` directive
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:142:5: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:143:11: Name `WaitForSingleObject` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:144:5: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:148:14: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:148:36: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:148:59: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:149:22: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:150:5: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:151:11: Name `WaitForSingleObject` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:152:5: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:156:14: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:156:36: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:156:59: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:157:5: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:159:15: Name `WaitForSingleObject` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:179:41: Name `Handle` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:181:9: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:185:14: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:185:36: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:185:59: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:189:28: Name `WaitForSingleObject` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:192:5: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:199:14: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:199:36: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:199:59: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:200:22: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:204:28: Name `WaitForSingleObject` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:207:5: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:216:14: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:216:36: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:216:59: Name `ffi` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:220:15: Name `WaitForSingleObject` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_tests/test_wait_for_object.py:222:5: Name `kernel32` used when possibly not defined
- warning[possibly-unresolved-reference] src/trio/_util.py:226:29: Name `objname` used when possibly not defined
- Found 1008 diagnostics
+ Found 871 diagnostics

dulwich (https://github.com/dulwich/dulwich)
+ warning[possibly-unbound-attribute] dulwich/client.py:1687:13: Attribute `close` on type `Unknown | None | socket` is possibly unbound
- warning[possibly-unresolved-reference] dulwich/merge.py:125:20: Name `_merge3_to_bytes` used when possibly not defined
- warning[possibly-unresolved-reference] dulwich/merge.py:147:24: Name `_merge3_to_bytes` used when possibly not defined
- warning[possibly-unresolved-reference] dulwich/merge.py:159:24: Name `_merge3_to_bytes` used when possibly not defined
- warning[possibly-unresolved-reference] dulwich/merge.py:177:22: Name `_merge3_to_bytes` used when possibly not defined
- warning[possibly-unresolved-reference] dulwich/notes.py:242:43: Name `update_tree` used when possibly not defined
- warning[possibly-unresolved-reference] dulwich/notes.py:252:39: Name `update_tree` used when possibly not defined
- warning[possibly-unresolved-reference] dulwich/pack.py:391:28: Name `mmap` used when possibly not defined
- warning[possibly-unresolved-reference] dulwich/pack.py:391:55: Name `mmap` used when possibly not defined
- warning[possibly-unresolved-reference] dulwich/porcelain.py:1127:38: Name `entry` used when possibly not defined
- warning[possibly-unresolved-reference] dulwich/porcelain.py:1162:42: Name `o` used when possibly not defined
+ error[invalid-argument-type] dulwich/porcelain.py:1649:64: Argument to function `parse_reftuples` is incorrect: Expected `bytes | list[bytes]`, found `Unknown | None | list[Unknown]`
+ error[invalid-argument-type] dulwich/porcelain.py:1745:54: Argument to function `parse_reftuples` is incorrect: Expected `bytes | list[bytes]`, found `Unknown | None | list[Unknown]`
+ warning[possibly-unbound-attribute] dulwich/porcelain.py:2094:9: Attribute `write` on type `Unknown | None | TextIO` is possibly unbound
+ warning[possibly-unbound-attribute] dulwich/porcelain.py:2095:9: Attribute `flush` on type `Unknown | None | TextIO` is possibly unbound
+ warning[possibly-unbound-attribute] dulwich/porcelain.py:2120:9: Attribute `write` on type `Unknown | None | TextIO` is possibly unbound
+ warning[possibly-unbound-attribute] dulwich/porcelain.py:2121:9: Attribute `flush` on type `Unknown | None | TextIO` is possibly unbound
- warning[possibly-unresolved-reference] dulwich/server.py:998:17: Name `writer` used when possibly not defined
- warning[possibly-unresolved-reference] dulwich/tests/utils.py:109:31: Name `sha` used when possibly not defined
- Found 153 diagnostics
+ Found 148 diagnostics

mypy-protobuf (https://github.com/dropbox/mypy-protobuf)
+ warning[possibly-unbound-attribute] test/generated/testproto/test_pb2.pyi:396:25: Attribute `service` on type `<module 'google.protobuf'> | Unknown` is possibly unbound
+ warning[possibly-unbound-attribute] test/generated/testproto/test_pb2.pyi:405:25: Attribute `service` on type `<module 'google.protobuf'> | Unknown` is possibly unbound
+ warning[possibly-unbound-attribute] test/generated/testproto/test_pb2.pyi:414:37: Attribute `service` on type `<module 'google.protobuf'> | Unknown` is possibly unbound
+ warning[possibly-unbound-attribute] test/generated/testproto/test_pb2.pyi:418:25: Attribute `service` on type `<module 'google.protobuf'> | Unknown` is possibly unbound
+ warning[possibly-unbound-attribute] test/generated/testproto/test_pb2.pyi:426:25: Attribute `service` on type `<module 'google.protobuf'> | Unknown` is possibly unbound
+ warning[possibly-unbound-attribute] test/generated/testproto/test_pb2.pyi:437:25: Attribute `service` on type `<module 'google.protobuf'> | Unknown` is possibly unbound
+ warning[possibly-unbound-attribute] test/generated/testproto/test_pb2.pyi:443:37: Attribute `service` on type `<module 'google.protobuf'> | Unknown` is possibly unbound
+ warning[possibly-unbound-attribute] test/generated/testproto/test_pb2.pyi:447:25: Attribute `service` on type `<module 'google.protobuf'> | Unknown` is possibly unbound
- Found 46 diagnostics
+ Found 54 diagnostics

comtypes (https://github.com/enthought/comtypes)
- warning[possibly-unresolved-reference] comtypes/_comobject.py:74:9: Name `_acquire` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/_comobject.py:77:9: Name `_release` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/_comobject.py:81:9: Name `_acquire` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/_comobject.py:84:9: Name `_release` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/_memberspec.py:385:32: Name `putref` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/_memberspec.py:386:28: Name `put` used when possibly not defined
- error[unresolved-reference] comtypes/_memberspec.py:588:46: Name `interface` used when not defined
- warning[possibly-unresolved-reference] comtypes/test/test_comserver.py:141:16: Name `Dispatch` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/test/test_comserver.py:162:16: Name `Dispatch` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/test/test_dispifc_records.py:24:35: Name `ComtypesCppTestSrvLib` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/test/test_dispifc_records.py:29:23: Name `ComtypesCppTestSrvLib` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/test/test_dispifc_records.py:37:23: Name `ComtypesCppTestSrvLib` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/test/test_dispifc_records.py:51:23: Name `ComtypesCppTestSrvLib` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/test/test_dispifc_records.py:68:25: Name `ComtypesCppTestSrvLib` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/test/test_dispifc_records.py:75:14: Name `ComtypesCppTestSrvLib` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/test/test_dispifc_safearrays.py:27:35: Name `ComtypesCppTestSrvLib` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/test/test_dispifc_safearrays.py:32:23: Name `ComtypesCppTestSrvLib` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/test/test_dispinterface.py:40:13: Name `EnsureDispatch` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/test/test_dispinterface.py:67:13: Name `Dispatch` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/test/test_excel.py:71:37: Name `xlRangeValueDefault` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/test/test_midl_safearray_create.py:46:25: Name `IDispSafearrayParamTest` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/test/test_midl_safearray_create.py:50:23: Name `IDispSafearrayParamTest` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/test/test_midl_safearray_create.py:52:61: Name `IDispSafearrayParamTest` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/test/test_midl_safearray_create.py:59:57: Name `IDispSafearrayParamTest` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/test/test_midl_safearray_create.py:64:14: Name `StructRecordParamTest` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/test/test_midl_safearray_create.py:66:18: Name `StructRecordParamTest` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/test/test_midl_safearray_create.py:70:53: Name `StructRecordParamTest` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/test/test_midl_safearray_create.py:77:49: Name `StructRecordParamTest` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/test/test_recordinfo.py:19:45: Name `StructRecordParamTest` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/test/test_recordinfo.py:25:14: Name `StructRecordParamTest` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/test/test_recordinfo.py:35:19: Name `StructRecordParamTest` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/test/test_recordinfo.py:43:29: Name `StructRecordParamTest` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/test/test_recordinfo.py:49:13: Name `StructRecordParamTest` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/test/test_recordinfo.py:55:20: Name `StructRecordParamTest` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/test/test_recordinfo.py:60:29: Name `StructRecordParamTest` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/test/test_recordinfo.py:72:19: Name `StructRecordParamTest` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/test/test_win32com_interop.py:67:5: Name `_pack` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/test/test_win32com_interop.py:76:26: Name `unpack` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/test/test_win32com_interop.py:82:26: Name `unpack` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/test/test_win32com_interop.py:88:26: Name `unpack` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/test/test_win32com_interop.py:97:26: Name `unpack` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/test/test_win32com_interop.py:115:12: Name `_PyCom_PyObjectFromIUnknown` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/test/test_win32com_interop.py:137:16: Name `win32com` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/test/test_win32com_interop.py:153:16: Name `win32com` used when possibly not defined
- warning[possibly-unresolved-reference] comtypes/test/test_word.py:69:31: Name `Word` used when possibly not defined
- Found 530 diagnostics
+ Found 485 diagnostics

alerta (https://github.com/alerta/alerta)
- warning[possibly-unresolved-reference] alerta/app.py:107:14: Name `Celery` used when possibly not defined
- warning[possibly-unresolved-reference] alerta/auth/utils.py:24:16: Name `bcrypt` used when possibly not defined
- warning[possibly-unresolved-reference] alerta/auth/utils.py:24:40: Name `bcrypt` used when possibly not defined
- warning[possibly-unresolved-reference] alerta/auth/utils.py:27:16: Name `bcrypt` used when possibly not defined
+ warning[possibly-unbound-attribute] alerta/database/backends/mongodb/base.py:805:28: Attribute `where` on type `Unknown | None | (Unknown & ~AlwaysFalsy)` is possibly unbound
+ warning[possibly-unbound-attribute] alerta/database/backends/mongodb/base.py:843:28: Attribute `where` on type `Unknown | None | (Unknown & ~AlwaysFalsy)` is possibly unbound
- warning[possibly-unresolved-reference] alerta/utils/mailer.py:38:15: Name `MIMEMultipart` used when possibly not defined
- warning[possibly-unresolved-reference] alerta/utils/mailer.py:44:20: Name `MIMEText` used when possibly not defined
- warning[possibly-unresolved-reference] alerta/utils/mailer.py:49:19: Name `ssl` used when possibly not defined
- warning[possibly-unresolved-reference] alerta/utils/mailer.py:55:22: Name `smtplib` used when possibly not defined
- warning[possibly-unresolved-reference] alerta/utils/mailer.py:58:22: Name `smtplib` used when possibly not defined
- warning[possibly-unresolved-reference] alerta/utils/mailer.py:72:16: Name `smtplib` used when possibly not defined
- warning[possibly-unresolved-reference] alerta/utils/mailer.py:74:26: Name `socket` used when possibly not defined
- warning[possibly-unresolved-reference] alerta/utils/mailer.py:74:41: Name `socket` used when possibly not defined
- error[unresolved-reference] alerta/webhooks/custom.py:51:92: Name `alert` used when not defined
+ warning[unused-ignore-comment] alerta/webhooks/custom.py:50:123: Unused blanket `type: ignore` directive
- Found 458 diagnostics
+ Found 448 diagnostics

pyjwt (https://github.com/jpadilla/pyjwt)
- warning[possibly-unresolved-reference] jwt/algorithms.py:157:26: Name `RSAAlgorithm` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algorithms.py:157:39: Name `RSAAlgorithm` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algorithms.py:158:26: Name `RSAAlgorithm` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algorithms.py:158:39: Name `RSAAlgorithm` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algorithms.py:159:26: Name `RSAAlgorithm` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algorithms.py:159:39: Name `RSAAlgorithm` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algorithms.py:160:26: Name `ECAlgorithm` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algorithms.py:160:38: Name `ECAlgorithm` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algorithms.py:161:27: Name `ECAlgorithm` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algorithms.py:161:39: Name `ECAlgorithm` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algorithms.py:162:26: Name `ECAlgorithm` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algorithms.py:162:38: Name `ECAlgorithm` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algorithms.py:163:26: Name `ECAlgorithm` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algorithms.py:163:38: Name `ECAlgorithm` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algorithms.py:164:26: Name `ECAlgorithm` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algorithms.py:165:21: Name `ECAlgorithm` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algorithms.py:167:26: Name `RSAPSSAlgorithm` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algorithms.py:167:42: Name `RSAPSSAlgorithm` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algorithms.py:168:26: Name `RSAPSSAlgorithm` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algorithms.py:168:42: Name `RSAPSSAlgorithm` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algorithms.py:169:26: Name `RSAPSSAlgorithm` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algorithms.py:169:42: Name `RSAPSSAlgorithm` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algorithms.py:170:26: Name `OKPAlgorithm` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algorithms.py:183:35: Name `AllowedKeys` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algorithms.py:199:38: Name `hashes` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algorithms.py:201:22: Name `hashes` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algorithms.py:201:54: Name `default_backend` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algorithms.py:207:42: Name `PublicKeyTypes` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algorithms.py:207:59: Name `PrivateKeyTypes` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algorithms.py:386:31: Name `hashes` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algorithms.py:387:31: Name `hashes` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algorithms.py:388:31: Name `hashes` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algorithms.py:392:43: Name `hashes` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algorithms.py:395:36: Name `AllowedRSAKeys` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algorithms.py:395:69: Name `AllowedRSAKeys` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algorithms.py:406:33: Name `PublicKeyTypes` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algorithms.py:406:50: Name `load_ssh_public_key` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algorithms.py:408:33: Name `RSAPublicKey` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algorithms.py:410:34: Name `PrivateKeyTypes` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algorithms.py:410:52: Name `load_pem_private_key` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algorithms.py:414:33: Name `RSAPrivateKey` used when possibly not defined
- warning[possibly-unresolved-reference] jwt/algori...*[Comment body truncated]*

@sharkdp sharkdp force-pushed the david/public-types branch from a0e9746 to 70742b3 Compare June 23, 2025 08:55
sharkdp added a commit that referenced this pull request Jun 23, 2025
## Summary

As far as I can tell, the two existing tests did the exact same thing.
Remove the redundant test, and add tests for all combinations of
declared/not-declared and local/"public" use of the name.

Proposing this as a separate PR before the behavior might change via
#18750
@sharkdp sharkdp force-pushed the david/public-types branch from 70742b3 to 1af17e0 Compare June 23, 2025 13:10
Copy link

codspeed-hq bot commented Jun 23, 2025

CodSpeed WallTime Performance Report

Merging #18750 will not alter performance

Comparing david/public-types (4226670) with main (2362263)

Summary

✅ 8 untouched benchmarks

This comment was marked as off-topic.

@sharkdp sharkdp force-pushed the david/public-types branch from c173689 to 403108d Compare June 24, 2025 13:16
@sharkdp sharkdp force-pushed the david/public-types branch from 00fda72 to 78d8b69 Compare June 25, 2025 10:42
@@ -1651,7 +1651,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
if let Some(builder) = self.context.report_lint(&CONFLICTING_DECLARATIONS, node) {
builder.into_diagnostic(format_args!(
"Conflicting declared types for `{place}`: {}",
conflicting.display(db)
conflicting.iter().map(|ty| ty.display(db)).join(", ")
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can't easily get this to work with TypeArrayDisplay, so just join it manually.

Copy link
Member

Choose a reason for hiding this comment

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

I added this function yesterday, which could possibly be generalised:

/// List the problematic class bases in a human-readable format.
fn describe_problematic_class_bases(&self, db: &dyn Db) -> String {
let num_bases = self.len();
debug_assert!(num_bases >= 2);
let mut bad_base_names = self.0.values().map(|info| info.originating_base.name(db));
let final_base = bad_base_names.next_back().unwrap();
let penultimate_base = bad_base_names.next_back().unwrap();
let mut buffer = String::new();
for base_name in bad_base_names {
buffer.push('`');
buffer.push_str(base_name);
buffer.push_str("`, ");
}
buffer.push('`');
buffer.push_str(penultimate_base);
buffer.push_str("` and `");
buffer.push_str(final_base);
buffer.push('`');
buffer
}

its behaviour is that if you have a list of two types A and B, it creates the string "`A` and `B`", if you have a list of three types A, B and C, it creates the string "`A`, `B` and `C`", for four types it creates the string "`A`, `B`, `C` and `D`", etc.

Copy link
Member

Choose a reason for hiding this comment

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

I guess a generalised version would be something like this (untested):

fn describe_types_list<'db, I, IT, D>(db: &'db dyn Db, types: I) -> String
where
    I: IntoIterator<IntoIter = IT>,
    IT: ExactSizeIterator<Item = D> + DoubleEndedIterator,
    D: std::fmt::Display,
{
    let types = types.into_iter();
    debug_assert!(types.len() >= 2);

    let final_type = types.next_back().unwrap();
    let penultimate_type = types.next_back().unwrap();

    let mut buffer = String::new();

    for type in types {
        buffer.push('`');
        buffer.push_str(type);
        buffer.push_str("`, ");
    }

    buffer.push('`');
    buffer.push_str(penultimate_type);
    buffer.push_str("` and `");
    buffer.push_str(final_type);
    buffer.push('`');

    buffer
}

Copy link
Member

Choose a reason for hiding this comment

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

if you have a list of three types A, B and C, it creates the string "`A`, `B` and `C`", for four types it creates the string "`A`, `B`, `C` and `D`", etc.

I see we are Oxford comma nemeses... 🐂

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thank you, Alex. I'll keep this for a follow-up.

@sharkdp sharkdp marked this pull request as ready for review June 25, 2025 12:25
@sharkdp sharkdp requested review from carljm and dcreager as code owners June 25, 2025 12:25
@sharkdp sharkdp marked this pull request as draft June 25, 2025 13:34
@sharkdp

This comment was marked as resolved.

@sharkdp sharkdp force-pushed the david/public-types branch from 0c77760 to d055a0d Compare June 25, 2025 14:12
@sharkdp sharkdp force-pushed the david/public-types branch from d1c15ca to 4226670 Compare June 26, 2025 10:03
@sharkdp sharkdp changed the title [ty] Infer public types as unions of all reachable bindings [ty] Infer nonlocal types as unions of all reachable bindings Jun 26, 2025
@sharkdp sharkdp merged commit b01003f into main Jun 26, 2025
36 of 37 checks passed
@sharkdp sharkdp deleted the david/public-types branch June 26, 2025 10:24
dcreager added a commit that referenced this pull request Jun 26, 2025
* main:
  [ty] Add regression-benchmark for attribute-assignment hang (#18957)
  [ty] Format conflicting types as an enumeration (#18956)
  [ty] Prevent union builder construction for just one declaration (#18954)
  [ty] Infer nonlocal types as unions of all reachable bindings (#18750)
  [`pyflakes`] Mark `F504`/`F522`/`F523` autofix as unsafe if there's a call with side effect (#18839)
  [`playground`] Add ruff logo docs link to Header.tsx (#18947)
  [ty] Reduce the overwhelming complexity of `TypeInferenceBuilder::infer_call_expression` (#18943)
  [ty] Add subdiagnostic about empty bodies in more cases (#18942)
  [ty] Move search path resolution to `Options::to_program_settings` (#18937)
  [`flake8-errmsg`] Extend `EM101` to support byte strings (#18867)
  Move big rule implementations (#18931)
  [`pylint`] Allow fix with comments and document performance implications (`PLW3301`) (#18936)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ecosystem-analyzer ty Multi-file analysis & type inference
Projects
None yet
4 participants