[red-knot] Callable types are disjoint from literals#17160
Conversation
| ( | ||
| Type::Callable(_), | ||
| Type::StringLiteral(_) | Type::BytesLiteral(_) | Type::SliceLiteral(_), | ||
| ) | ||
| | ( | ||
| Type::StringLiteral(_) | Type::BytesLiteral(_) | Type::SliceLiteral(_), | ||
| Type::Callable(_), | ||
| ) => { | ||
| // A callable type is disjoint from other literal types. For example, | ||
| // `Type::StringLiteral` must be an instance of exactly `str`, not a subclass | ||
| // of `str`, and `str` is not callable. The same applies to other literal types. | ||
| true | ||
| } |
There was a problem hiding this comment.
Other literals are handled directly with a catch-all combination:
BooleanLiteral:ruff/crates/red_knot_python_semantic/src/types.rs
Line 1311 in c2bb5d5
IntLiteral:ruff/crates/red_knot_python_semantic/src/types.rs
Line 1320 in c2bb5d5
LiteralString:ruff/crates/red_knot_python_semantic/src/types.rs
Line 1339 in c2bb5d5
|
AlexWaygood
left a comment
There was a problem hiding this comment.
Thank you! One interesting thing to note is that Callable types are not necessarily disjoint from ModuleLiteral types, as it is possible for a module to be a subclass of types.ModuleType (you have to manually inject it into sys.modules at runtime, but once it's imported in another module it would be recognised by red-knot as a ModuleLiteral type). And that subclass of types.ModuleType could possibly be callable.
This isn't something you get wrong in this PR, just something you might find interesting!
* origin/main: (35 commits) [red-knot] Callable types are disjoint from literals (#17160) [red-knot] Fix inference for `pow` between two literal integers (#17161) [red-knot] Add GitHub PR annotations when mdtests fail in CI (#17150) [red-knot] Fix equivalence of differently ordered unions that contain `Callable` types (#17145) [red-knot] Add initial set of tests for unreachable code (#17159) [`airflow`] Move `AIR302` to `AIR301` and `AIR303` to `AIR302` (#17151) ruff_db: simplify lifetimes on `DiagnosticDisplay` [red-knot] Detect division-by-zero in unions and intersections (#17157) [`airflow`] Add autofix infrastructure to `AIR302` name checks (#16965) [`flake8-bandit`] Mark `str` and `list[str]` literals as trusted input (`S603`) (#17136) [`airflow`] Add autofix for `AIR302` attribute checks (#16977) [`airflow`] Extend `AIR302` with additional symbols (#17085) [`airflow`] Move `AIR301` to `AIR002` (#16978) [`airflow`] Add autofix for `AIR302` method checks (#16976) ruff_db: switch diagnostic rendering over to `std::fmt::Display` [red-knot] Add 'Goto type definition' to the playground (#17055) red_knot_ide: update snapshots red_knot_python_semantic: remove comment about `TypeCheckDiagnostic` ruff_db: delete most of the old diagnostic code red_knot: use `Diagnostic` inside of red knot ...
* origin/main: (82 commits) [red-knot] Fix more [redundant-cast] false positives (#17170) [red-knot] Three-argument type-calls take 'str' as the first argument (#17168) Control flow: `return` and `raise` (#17121) Bump 0.11.3 (#17173) [red-knot] Improve `Debug` implementation for `semantic_index::SymbolTable` (#17172) [red-knot] Fix `str(…)` calls (#17163) [red-knot] visibility_constraint analysis for match cases (#17077) [red-knot] Fix playground crashes when diagnostics are stale (#17165) [red-knot] Callable types are disjoint from literals (#17160) [red-knot] Fix inference for `pow` between two literal integers (#17161) [red-knot] Add GitHub PR annotations when mdtests fail in CI (#17150) [red-knot] Fix equivalence of differently ordered unions that contain `Callable` types (#17145) [red-knot] Add initial set of tests for unreachable code (#17159) [`airflow`] Move `AIR302` to `AIR301` and `AIR303` to `AIR302` (#17151) ruff_db: simplify lifetimes on `DiagnosticDisplay` [red-knot] Detect division-by-zero in unions and intersections (#17157) [`airflow`] Add autofix infrastructure to `AIR302` name checks (#16965) [`flake8-bandit`] Mark `str` and `list[str]` literals as trusted input (`S603`) (#17136) [`airflow`] Add autofix for `AIR302` attribute checks (#16977) [`airflow`] Extend `AIR302` with additional symbols (#17085) ...
## Summary A callable type is disjoint from other literal types. For example, `Type::StringLiteral` must be an instance of exactly `str`, not a subclass of `str`, and `str` is not callable. The same applies to other literal types. This should hopefully fix astral-sh#17144, I couldn't produce any failures after running property tests multiple times. ## Test Plan Add test cases for disjointness check between callable and other literal types. Run property tests multiple times.
Summary
A callable type is disjoint from other literal types. For example,
Type::StringLiteralmust be an instance of exactlystr, not a subclass ofstr, andstris not callable. The same applies to other literal types.This should hopefully fix #17144, I couldn't produce any failures after running property tests multiple times.
Test Plan
Add test cases for disjointness check between callable and other literal types.
Run property tests multiple times.