Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

False negatives with dict.__(r)or__ #10678

Closed
adamtheturtle opened this issue Sep 7, 2023 · 7 comments · Fixed by #10679
Closed

False negatives with dict.__(r)or__ #10678

adamtheturtle opened this issue Sep 7, 2023 · 7 comments · Fixed by #10679
Labels
stubs: false negative Type checkers do not report an error, but should

Comments

@adamtheturtle
Copy link
Contributor

I have code equivalent to the following:

from requests.structures import CaseInsensitiveDict

CaseInsensitiveDict() | dict()

mypy does not error.

My environment has:

  • mypy==1.5.1
  • types-requests==2.31.0.2
  • Python 3.11.5

At runtime I get:

TypeError: unsupported operand type(s) for |: 'CaseInsensitiveDict' and 'dict'

I would expect an [operator] error. For example, if I swap the CaseInsensitiveDict() for 1, I get:

error: Unsupported operand types for | ("int" and "dict[str, str]")  [operator]

I am happy to contribute, but I'm not sure what change is needed. I imagine a change is needed in https://github.com/python/typeshed/blob/main/stubs/requests/requests/structures.pyi.

@AlexWaygood
Copy link
Member

In actual fact, the issue is our stubs for dict.__or__ and dict.__ror__:

typeshed/stdlib/builtins.pyi

Lines 1122 to 1129 in aa39b99

@overload
def __or__(self, __value: Mapping[_KT, _VT]) -> dict[_KT, _VT]: ...
@overload
def __or__(self, __value: Mapping[_T1, _T2]) -> dict[_KT | _T1, _VT | _T2]: ...
@overload
def __ror__(self, __value: Mapping[_KT, _VT]) -> dict[_KT, _VT]: ...
@overload
def __ror__(self, __value: Mapping[_T1, _T2]) -> dict[_KT | _T1, _VT | _T2]: ...

We currently claim that dict.__(r)or__ accepts any Mapping, but this isn't actually true. At runtime, the object passed to dict.__or__ has to be an instance of dict (and requests.structures.CaseInsensitiveDict is not a subclass of dict).

Ideally we'd make this change, but I think we tried it recently, and it caused an unfortunate number of false positives:

diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi
index 71cccee16..cf4f857c5 100644
--- a/stdlib/builtins.pyi
+++ b/stdlib/builtins.pyi
@@ -1120,13 +1120,13 @@ class dict(MutableMapping[_KT, _VT], Generic[_KT, _VT]):
     if sys.version_info >= (3, 9):
         def __class_getitem__(cls, __item: Any) -> GenericAlias: ...
         @overload
-        def __or__(self, __value: Mapping[_KT, _VT]) -> dict[_KT, _VT]: ...
+        def __or__(self, __value: dict[_KT, _VT]) -> dict[_KT, _VT]: ...
         @overload
-        def __or__(self, __value: Mapping[_T1, _T2]) -> dict[_KT | _T1, _VT | _T2]: ...
+        def __or__(self, __value: dict[_T1, _T2]) -> dict[_KT | _T1, _VT | _T2]: ...
         @overload
-        def __ror__(self, __value: Mapping[_KT, _VT]) -> dict[_KT, _VT]: ...
+        def __ror__(self, __value: dict[_KT, _VT]) -> dict[_KT, _VT]: ...
         @overload
-        def __ror__(self, __value: Mapping[_T1, _T2]) -> dict[_KT | _T1, _VT | _T2]: ...
+        def __ror__(self, __value: dict[_T1, _T2]) -> dict[_KT | _T1, _VT | _T2]: ...
         # dict.__ior__ should be kept roughly in line with MutableMapping.update()
         @overload  # type: ignore[misc]
         def __ior__(self, __value: SupportsKeysAndGetItem[_KT, _VT]) -> Self: ...

@AlexWaygood AlexWaygood added the stubs: false negative Type checkers do not report an error, but should label Sep 7, 2023
@AlexWaygood AlexWaygood changed the title No error for False negatives with dict.__(r)or__ Sep 7, 2023
@AlexWaygood
Copy link
Member

Okay, making the type hints more accurate here is actually less disruptive than I thought it would be! See #10679 (comment)

@adamtheturtle
Copy link
Contributor Author

Thank you for picking this up so quickly.

@sobolevn

This comment was marked as off-topic.

@sobolevn sobolevn reopened this Oct 11, 2023
@AlexWaygood

This comment was marked as off-topic.

@AlexWaygood

This comment was marked as off-topic.

@sobolevn

This comment was marked as off-topic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stubs: false negative Type checkers do not report an error, but should
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants