Skip to content

bool |= bool complains about incompatible assignment type #1793

Closed

Description

@asottile

From python/mypy#4386

I couldn't find any definitive specification on this other than PEP 285

Here's the input program (which I expect to cause no linting errors)

x = True
x |= False

However it results in the following:

$ mypy test.py
test.py:2: error: Incompatible types in assignment (expression has type "int", variable has type "bool")
$ pip freeze -l
mypy==0.560
psutil==5.4.2
typed-ast==1.1.0

It seems that PEP 285 is implemented faithfully in the versions of python I was able to check:

$ echo -n '2.6 2.7 3.4 3.5 3.6' | xargs -d' ' --replace -- bash -xc "python{} -c 'assert type(False | True) is bool'"
+ python2.6 -c 'assert type(False | True) is bool'
+ python2.7 -c 'assert type(False | True) is bool'
+ python3.4 -c 'assert type(False | True) is bool'
+ python3.5 -c 'assert type(False | True) is bool'
+ python3.6 -c 'assert type(False | True) is bool'

This patch to typeshed makes the above pass:

$ git diff stdlib/3
diff --git a/stdlib/3/builtins.pyi b/stdlib/3/builtins.pyi
index f2cea0f..74eb806 100644
--- a/stdlib/3/builtins.pyi
+++ b/stdlib/3/builtins.pyi
@@ -537,6 +537,30 @@ class memoryview(Sized, Container[bytes]):
 
 class bool(int):
     def __init__(self, o: object = ...) -> None: ...
+    @overload  # type: ignore
+    def __and__(self, x: bool) -> bool: ...
+    @overload  # type: ignore
+    def __and__(self, x: int) -> int: ...
+    @overload  # type: ignore
+    def __or__(self, x: bool) -> bool: ...
+    @overload  # type: ignore
+    def __or__(self, x: int) -> int: ...
+    @overload  # type: ignore
+    def __xor__(self, x: bool) -> bool: ...
+    @overload  # type: ignore
+    def __xor__(self, x: int) -> int: ...
+    @overload  # type: ignore
+    def __rand__(self, x: bool) -> bool: ...
+    @overload  # type: ignore
+    def __rand__(self, x: int) -> int: ...
+    @overload  # type: ignore
+    def __ror__(self, x: bool) -> bool: ...
+    @overload  # type: ignore
+    def __ror__(self, x: int) -> int: ...
+    @overload  # type: ignore
+    def __rxor__(self, x: bool) -> bool: ...
+    @overload  # type: ignore
+    def __rxor__(self, x: int) -> int: ...
 
 class slice:
     start = ...  # type: Optional[int]

though I'm concerned about the # type: ignore (bool does after all violate LSP ala python/mypy#1237 so maybe this is correct?)

If this seems OK, I'll turn it into a PR :)

Activity

  1. JelleZijlstra commented on Dec 19, 2017

    @JelleZijlstra
    Member

    This sounds reasonable (if slightly unfortunate). Presumably you'll need the same change in the Python 2 stubs.

  2. asottile commented on Dec 19, 2017

    @asottile
    ContributorAuthor

    yep -- I had that patch for python2 as well (just showed the git diff -- stdlib/3 in the issue so it was less noisy). I'll submit a PR

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions