Skip to content

Conversation

@randolf-scholz
Copy link
Contributor

This PR aims to formalize the behavior of Literal? types (Instance with last_known_value) by treating them as-if they were AnyOf-types (see python/typing#566)

For example, Literal["x"]? is treated as-if it were AnyOf[str, Literal["x"]].

New Tests

  • JoinSuite.test_mixed_literal_types tests join between Literal? and other types.
  • MeetSuite.test_mixed_literal_types tests meet between Literal? and other types
  • TypeOpsSuite.test_simplified_union_with_mixed_str_literals2 tests simplified unions containing Literal? types
  • SubtypingSuite.test_literal tests subtype checks with Literal? types
  • RestrictionSuite: new test suite for testing the restrict_subtype_away method.
  • testJoinLiteralInstanceAndEnum tests join between Literal? and StrEnum

@github-actions
Copy link
Contributor

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:183: error: "Collection[Any]" has no attribute "state"  [attr-defined]
+ src/prefect/server/services/task_run_recorder.py:183: error: "object" has no attribute "state"  [attr-defined]
- src/prefect/server/services/task_run_recorder.py:186: error: "Collection[Any]" has no attribute "id"  [attr-defined]
+ src/prefect/server/services/task_run_recorder.py:186: error: "object" has no attribute "id"  [attr-defined]
- src/prefect/server/services/task_run_recorder.py:192: error: "Collection[Any]" has no attribute "keys"  [attr-defined]
+ src/prefect/server/services/task_run_recorder.py:192: 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]

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

Labels

None yet

Projects

None yet

1 participant