Uh oh!
There was an error while loading. Please reload this page.
Fix meet_types for literal and instance - #19605
Conversation
This comment has been minimized.
This comment has been minimized.
randolf-scholz
commented
Aug 7, 2025
The first operator failure seems like a bug in typeshed to me: python/typeshed#9004 |
This comment has been minimized.
This comment has been minimized.
1 similar comment
This comment has been minimized.
This comment has been minimized.
Hm, the fromtypingimportLiteral, cast
type PDDatetimeUnitOptions=Literal["s", "ms", "ns"]
time_unit=cast(PDDatetimeUnitOptions, "s") # [redundant-cast]Is the current behavior of emitting redundant cast here intentional? It seems formally incorrect, since In comparison, |
This comment has been minimized.
This comment has been minimized.
2f41cab to
35ec958Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
randolf-scholz
commented
Aug 11, 2025
Repro for the pyinstrument change: fromtypingimportTypedDict, Literal
type AsyncMode=Literal["enabled", "disabled", "strict"]
classOptions(TypedDict, total=False):
async_mode: AsyncModedeftest(kwargs: Options, d: dict[Literal["async_mode"], AsyncMode]) ->None:
reveal_type(kwargs)
reveal_type(kwargs.get)
reveal_type(d.get)
reveal_type(kwargs.get("async_mode", "disabled"))
# master: AsyncMode# feature: "Literal['enabled'] | Literal['strict'] | Literal['disabled']?"I believe the problem here is not the new reveal_type(kwargs.get)
# mypy: Overload# def (str) -> object,# def (str, default: object) -> object,# def [_T] (str, default: _T`1) -> object)"# pyright: Overload# def (k: Literal['async_mode']) -> (AsyncMode | None)# def [T] (k: Literal['async_mode'], default: T | AsyncMode) -> (T | AsyncMode)# def [T] (k: str) -> (Any | None), (k: str, default: Any | T) -> (Any | T)Basically, we want here to pick the second signature shown by pyright, and use the minimal solution |
1fd8382 to
2059a1aCompare
This comment has been minimized.
This comment has been minimized.
2059a1a to
44b65ffCompare
This comment has been minimized.
This comment has been minimized.
44b65ff to
178e8f6Compare
This comment has been minimized.
This comment has been minimized.
178e8f6 to
cb6a089Compare
This comment has been minimized.
This comment has been minimized.
1 similar comment
This comment has been minimized.
This comment has been minimized.
c96d66e to
55456baCompare
This comment has been minimized.
This comment has been minimized.
Diff from mypy_primer, showing the effect of this PR on open source code: pyinstrument (https://github.com/joerick/pyinstrument)
- pyinstrument/context_manager.py:40: error: Argument 1 to "Profiler" has incompatible type "**dict[str, Literal['enabled', 'disabled', 'strict'] | float | bool | None]"; expected "float" [arg-type]+ pyinstrument/context_manager.py:40: error: Argument 1 to "Profiler" has incompatible type "**dict[str, Literal['enabled', 'strict'] | float | str | bool | None]"; expected "float" [arg-type]- pyinstrument/context_manager.py:40: error: Argument 1 to "Profiler" has incompatible type "**dict[str, Literal['enabled', 'disabled', 'strict'] | float | bool | None]"; expected "Literal['enabled', 'disabled', 'strict']" [arg-type]+ pyinstrument/context_manager.py:40: error: Argument 1 to "Profiler" has incompatible type "**dict[str, Literal['enabled', 'strict'] | float | str | bool | None]"; expected "Literal['enabled', 'disabled', 'strict']" [arg-type]- pyinstrument/context_manager.py:40: error: Argument 1 to "Profiler" has incompatible type "**dict[str, Literal['enabled', 'disabled', 'strict'] | float | bool | None]"; expected "bool | None" [arg-type]+ pyinstrument/context_manager.py:40: error: Argument 1 to "Profiler" has incompatible type "**dict[str, Literal['enabled', 'strict'] | float | str | bool | None]"; expected "bool | None" [arg-type]
prefect (https://github.com/PrefectHQ/prefect)
- src/prefect/server/services/task_run_recorder.py:181: error: "Collection[Any]" has no attribute "state" [attr-defined]+ src/prefect/server/services/task_run_recorder.py:181: error: "object" has no attribute "state" [attr-defined]- src/prefect/server/services/task_run_recorder.py:184: error: "Collection[Any]" has no attribute "id" [attr-defined]+ src/prefect/server/services/task_run_recorder.py:184: error: "object" has no attribute "id" [attr-defined]- src/prefect/server/services/task_run_recorder.py:190: error: "Collection[Any]" has no attribute "keys" [attr-defined]+ src/prefect/server/services/task_run_recorder.py:190: error: "object" has no attribute "keys" [attr-defined]- src/prefect/concurrency/_asyncio.py:112: error: R? has no attribute "json" [attr-defined]+ src/prefect/task_worker.py:370: error: Argument 1 to "submit" of "Executor" has incompatible type "Callable[[Callable[_P, _T], **_P], _T]"; expected "Callable[[Callable[[Task[P, R], UUID | None, TaskRun | None, dict[str, Any] | None, PrefectFuture[Any] | Any | Iterable[PrefectFuture[Any] | Any] | None, Literal['state', 'result'], dict[str, set[RunInput]] | None, dict[str, Any] | None], R | State[Any] | None], Task[[VarArg(Any), KwArg(Any)], Any], UUID, TaskRun, dict[Any, Any], list[Any], str, Any | None], Any | State[Any] | None]" [arg-type]
operator (https://github.com/canonical/operator)
+ ops/model.py:809: error: Unsupported operand types for - ("set[tuple[Literal['tcp', 'udp', 'icmp'], int | None]]" and "set[tuple[str, int] | tuple[Literal['tcp', 'udp', 'icmp'], int | None]]") [operator]+ ops/model.py:811: error: Incompatible types in assignment (expression has type "str", variable has type "Literal['tcp', 'udp', 'icmp']") [assignment]
discord.py (https://github.com/Rapptz/discord.py)
- discord/app_commands/transformers.py:139: error: Incompatible types in assignment (expression has type "list[dict[str, Any]]", target has type "str | int") [assignment]+ discord/app_commands/transformers.py:139: error: Incompatible types in assignment (expression has type "list[dict[str, Any]]", target has type "bool | str | int") [assignment]- discord/app_commands/transformers.py:141: error: Incompatible types in assignment (expression has type "list[int]", target has type "str | int") [assignment]+ discord/app_commands/transformers.py:141: error: Incompatible types in assignment (expression has type "list[int]", target has type "bool | str | int") [assignment]- discord/app_commands/transformers.py:149: error: Incompatible types in assignment (expression has type "int | float", target has type "str | int") [assignment]+ discord/app_commands/transformers.py:149: error: Incompatible types in assignment (expression has type "int | float", target has type "bool | str | int") [assignment]- discord/app_commands/transformers.py:151: error: Incompatible types in assignment (expression has type "int | float", target has type "str | int") [assignment]+ discord/app_commands/transformers.py:151: error: Incompatible types in assignment (expression has type "int | float", target has type "bool | str | int") [assignment]
dedupe (https://github.com/dedupeio/dedupe)
- dedupe/api.py:1547: error: Redundant cast to "Literal['match', 'distinct']" [redundant-cast] |
randolf-scholz
commented
Dec 19, 2025
Resubmitted with clean history as #20444 |
meet_typesgives unexpected results when meeting literal and Instance #19560Literal?types. #19625New Tests
JoinSuite.test_mixed_literal_typestests join betweenLiteral?and other types.MeetSuite.test_mixed_literal_typestests meet betweenLiteral?and other typesTypeOpsSuite.test_simplified_union_with_mixed_str_literals2tests simplified unions containingLiteral?typesSubtypingSuite.test_literaltests subtype checks withLiteral?typesRestrictionSuite: new test suite for testing therestrict_subtype_awaymethod.testJoinLiteralInstanceAndEnumtests join betweenLiteral?andStrEnum