|
1 | 1 | from __future__ import annotations |
2 | 2 |
|
3 | 3 | import os |
4 | | -from typing import Any, Dict, Generic, Iterable, Mapping, TypeVar, Union |
| 4 | +from typing import Any, Dict, Generic, Iterable, Literal, Mapping, TypeVar, Union |
5 | 5 | from typing_extensions import Self, assert_type |
6 | 6 |
|
7 | 7 | ################################################################### |
@@ -74,35 +74,49 @@ def test_iterable_tuple_overload(x: Iterable[tuple[int, str]]) -> dict[int, str] |
74 | 74 | assert_type(d_any.get("key"), Union[Any, None]) |
75 | 75 | assert_type(d_any.get("key", None), Union[Any, None]) |
76 | 76 | assert_type(d_any.get("key", any_value), Any) |
77 | | -assert_type(d_any.get("key", str_value), Any) |
78 | | -assert_type(d_any.get("key", int_value), Any) |
| 77 | +assert_type(d_any.get("key", str_value), Union[Any, str]) |
| 78 | +assert_type(d_any.get("key", int_value), Union[Any, int]) |
79 | 79 |
|
80 | 80 | assert_type(d_str["key"], str) |
81 | 81 | assert_type(d_str.get("key"), Union[str, None]) |
82 | 82 | assert_type(d_str.get("key", None), Union[str, None]) |
83 | 83 | # Pyright has str instead of Any here |
84 | | -assert_type(d_str.get("key", any_value), Any) # pyright: ignore[reportAssertTypeFailure] |
| 84 | +assert_type(d_str.get("key", any_value), Union[str, Any]) |
85 | 85 | assert_type(d_str.get("key", str_value), str) |
86 | 86 | assert_type(d_str.get("key", int_value), Union[str, int]) |
87 | 87 |
|
88 | 88 | # Now with context! |
89 | 89 | result: str |
90 | 90 | result = d_any["key"] |
91 | 91 | result = d_any.get("key") # type: ignore[assignment] |
92 | | -result = d_any.get("key", None) # type: ignore[assignment] |
| 92 | +# FIXME: https://github.com/python/mypy/issues/20576 prevents using ignore[assignment] here |
| 93 | +result = d_any.get("key", None) # type: ignore |
93 | 94 | result = d_any.get("key", any_value) |
94 | 95 | result = d_any.get("key", str_value) |
95 | | -result = d_any.get("key", int_value) |
| 96 | +# FIXME: https://github.com/python/mypy/issues/20576 prevents using ignore[assignment] here |
| 97 | +result = d_any.get("key", int_value) # type: ignore |
96 | 98 |
|
97 | 99 | result = d_str["key"] |
98 | 100 | result = d_str.get("key") # type: ignore[assignment] |
99 | | -result = d_str.get("key", None) # type: ignore[assignment] |
100 | | -# Pyright has str | None here, see https://github.com/microsoft/pyright/discussions/9570 |
101 | | -result = d_str.get("key", any_value) # pyright: ignore[reportAssignmentType] |
| 101 | +# FIXME: https://github.com/python/mypy/issues/20576 prevents using ignore[assignment] here |
| 102 | +result = d_str.get("key", None) # type: ignore |
| 103 | +result = d_str.get("key", any_value) |
102 | 104 | result = d_str.get("key", str_value) |
103 | 105 | result = d_str.get("key", int_value) # type: ignore[arg-type] |
104 | 106 |
|
105 | 107 |
|
| 108 | +def test_get_literal(d: dict[Literal["foo", "bar"], int], dynamic_key: str) -> None: |
| 109 | + # Note: annotations also allow using keys of a disjoint type (e.g., int), |
| 110 | + # linters / type checkers are free to issue warnings in such cases. |
| 111 | + # statically, a .get(arg) is superfluous if the intersection of the |
| 112 | + # dict key type and the argument type is empty. |
| 113 | + # So we only test a case with non-empty intersection here. |
| 114 | + |
| 115 | + # check that dict wth Literal keys can get/pop a string key. |
| 116 | + d.get(dynamic_key) |
| 117 | + d.pop(dynamic_key) |
| 118 | + |
| 119 | + |
106 | 120 | # Return values also make things weird |
107 | 121 |
|
108 | 122 | # Pyright doesn't have a version of no-any-return, |
@@ -140,11 +154,13 @@ def test8() -> str: |
140 | 154 |
|
141 | 155 |
|
142 | 156 | def test9() -> str: |
143 | | - return d_str.get("key", None) # type: ignore[return-value] |
| 157 | + # FIXME: https://github.com/python/mypy/issues/20576 prevents using ignore[return-value] here |
| 158 | + return d_str.get("key", None) # type: ignore |
144 | 159 |
|
145 | 160 |
|
146 | 161 | def test10() -> str: |
147 | | - return d_str.get("key", any_value) # type: ignore[no-any-return] |
| 162 | + # OK, return is Union[str, Any] |
| 163 | + return d_str.get("key", any_value) |
148 | 164 |
|
149 | 165 |
|
150 | 166 | def test11() -> str: |
|
0 commit comments