Skip to content

Union was callable in 0.770 but is not in 0.780 #8953

Closed

Description

@feuGeneA

Using version 0.770, I had some code passing type checking just fine, but now using 0.780 the same code yields "object" not callable. the code in question is the expression Union[bytes, str](returned).

Did 0.780 change a Union from callable to non-callable? Or was it always non-callable and just not flagged before? Or what?

 4Jun13:16:39 /$ mypy --version
mypy 0.770

 4Jun13:16:45 /$ mypy -c "from typing import Union; Union[str, bytes]('')"
Success: no issues found in 1 source file

 4Jun13:17:01 /$ pip install --upgrade mypy
Collecting mypy
  Using cached mypy-0.780-cp37-cp37m-manylinux1_x86_64.whl (20.2 MB)
Requirement already satisfied, skipping upgrade: typing-extensions>=3.7.4 in /home/gene/.pythonz/pythons/CPython-3.7.2/lib/python3.7/site-packages (from mypy) (3.7.4.2)
Requirement already satisfied, skipping upgrade: mypy-extensions<0.5.0,>=0.4.3 in /home/gene/.pythonz/pythons/CPython-3.7.2/lib/python3.7/site-packages (from mypy) (0.4.3)
Requirement already satisfied, skipping upgrade: typed-ast<1.5.0,>=1.4.0 in /home/gene/.pythonz/pythons/CPython-3.7.2/lib/python3.7/site-packages (from mypy) (1.4.1)
Installing collected packages: mypy
  Attempting uninstall: mypy
    Found existing installation: mypy 0.770
    Uninstalling mypy-0.770:
      Successfully uninstalled mypy-0.770
Successfully installed mypy-0.780

 4Jun13:17:29 /$ mypy -c "from typing import Union; Union[str, bytes]('')"
<string>:1: error: "object" not callable
Found 1 error in 1 file (checked 1 source file)

I checked the release notes for 0.780 and didn't see anything that seemed relevant to me...

I'm not sure what behavior to expect. I don't have that good of a grasp of Python type checking. Should a Union be callable, the way any other type like int or str are? Or not? 🤷‍♂️

I'm using Python 3.7.something. (3.7.2 locally, possibly a different version in my CI, where this is also happening.)

Activity

  1. JelleZijlstra commented on Jun 4, 2020

    @JelleZijlstra
    Member

    Mypy generally doesn't like using types in a runtime context. Union[bytes, str](returned) doesn't work at runtime either, at least in 3.6 (it throws TypeError: Cannot instantiate typing.Union). I'm not sure what it could mean either.

  2. jstasiak commented on Jun 4, 2020

    @jstasiak
    Contributor

    Not knowing anything about the code using this I'd interpret it as equivalent to cast(Union[bytes, str], returned), I'm curious how far off am I.

  3. hauntsaninja commented on Jun 4, 2020

    @hauntsaninja
    Collaborator

    Yes, this was always not callable and is now flagged.
    The relevant change was to typeshed, not mypy: python/typeshed#3933.

    Note this applies to some simpler types like typing.List as well. Type checkers will now correctly complain about code that fails at runtime like:

    ~/delete λ cat test89.py 
    from typing import List
    List()                                                                               
    ~/delete λ python3.9 test89.py
    Traceback (most recent call last):
      File "/Users/shantanu/delete/test89.py", line 2, in <module>
        List()
      File "/Users/shantanu/.pyenv/versions/3.9-dev/lib/python3.9/typing.py", line 614, in __call__
        raise TypeError(f"Type {self._name} cannot be instantiated; "
    TypeError: Type List cannot be instantiated; use list() instead
    

    @jstasiak it's possible in theory mypy could learn those semantics, but it would need to be supported by CPython first so that it doesn't crash at runtime. I feel it's unlikely CPython will make that change, since Union[bytes, str](x) looks more like it's meant to do something at runtime than cast(Union[bytes, str], x).

  4. jstasiak commented on Jun 4, 2020

    @jstasiak
    Contributor

    Oh sure, I'm not proposing Mypy and Python implement this, I'm just trying to guess the intended meaning of the code in the report.

  5. JukkaL commented on Jun 8, 2020

    @JukkaL
    Collaborator

    There seems to be nothing to do here; mypy seems to be behaving now as expected, as a false negative was fixed in 0.780.

  6. added a commit that references this issue on Jun 8, 2020
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