diff --git a/stdlib/@tests/test_cases/builtins/check_dict.py b/stdlib/@tests/test_cases/builtins/check_dict.py index 96c60e779038..dd4569eccbe5 100644 --- a/stdlib/@tests/test_cases/builtins/check_dict.py +++ b/stdlib/@tests/test_cases/builtins/check_dict.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import Dict, Generic, Iterable, TypeVar +from typing import Any, Dict, Generic, Iterable, TypeVar, Union from typing_extensions import assert_type # These do follow `__init__` overloads order: @@ -57,3 +57,93 @@ def test_iterable_tuple_overload(x: Iterable[tuple[int, str]]) -> dict[int, str] dict(["foo", "bar", "baz"]) # type: ignore dict([b"foo", b"bar", b"baz"]) # type: ignore + +# Exploring corner cases of dict.get() +d_any: dict[str, Any] = {} +d_str: dict[str, str] = {} +any_value: Any = None +str_value = "value" +int_value = 1 + +assert_type(d_any["key"], Any) +assert_type(d_any.get("key"), Union[Any, None]) +assert_type(d_any.get("key", None), Any) +assert_type(d_any.get("key", any_value), Any) +assert_type(d_any.get("key", str_value), Any) +assert_type(d_any.get("key", int_value), Any) + +assert_type(d_str["key"], str) +assert_type(d_str.get("key"), Union[str, None]) +assert_type(d_str.get("key", None), Union[str, None]) +# Pyright has str instead of Any here +assert_type(d_str.get("key", any_value), Any) # pyright: ignore[reportAssertTypeFailure] +assert_type(d_str.get("key", str_value), str) +assert_type(d_str.get("key", int_value), Union[str, int]) + +# Now with context! +result: str +result = d_any["key"] +result = d_any.get("key") # type: ignore[assignment] +result = d_any.get("key", None) +result = d_any.get("key", any_value) +result = d_any.get("key", str_value) +result = d_any.get("key", int_value) + +result = d_str["key"] +result = d_str.get("key") # type: ignore[assignment] +result = d_str.get("key", None) # type: ignore[arg-type] +result = d_str.get("key", any_value) +result = d_str.get("key", str_value) +result = d_str.get("key", int_value) # type: ignore[arg-type] + + +# Return values also make things weird + +# Pyright doesn't have a version of no-any-return, +# and mypy doesn't have a type: ignore that pyright will ignore. +# def test1() -> str: +# return d_any["key"] # mypy: ignore[no-any-return] + + +def test2() -> str: + return d_any.get("key") # type: ignore[return-value] + + +# def test3() -> str: +# return d_any.get("key", None) # mypy: ignore[no-any-return] +# +# +# def test4() -> str: +# return d_any.get("key", any_value) # mypy: ignore[no-any-return] +# +# +# def test5() -> str: +# return d_any.get("key", str_value) # mypy: ignore[no-any-return] +# +# +# def test6() -> str: +# return d_any.get("key", int_value) # mypy: ignore[no-any-return] + + +def test7() -> str: + return d_str["key"] + + +def test8() -> str: + return d_str.get("key") # type: ignore[return-value] + + +def test9() -> str: + return d_str.get("key", None) # type: ignore[arg-type] + + +def test10() -> str: + return d_str.get("key", any_value) + + +def test11() -> str: + return d_str.get("key", str_value) + + +def test12() -> str: + return d_str.get("key", int_value) # type: ignore[arg-type]