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

Tuple[AnyStr] always get converted into Tuple[unicode] in Py2 #6761

Closed
gsnedders opened this issue May 3, 2019 · 3 comments
Closed

Tuple[AnyStr] always get converted into Tuple[unicode] in Py2 #6761

gsnedders opened this issue May 3, 2019 · 3 comments

Comments

@gsnedders
Copy link

  • Are you reporting a bug, or opening a feature request?
    A bug.

  • Please insert below the code you are checking with mypy,
    or a mock-up repro if the source is private. We would appreciate
    if you try to simplify your case to a minimal repro.

from typing import AnyStr, Union, Text, Tuple


def anystr_func(s):
    # type: (AnyStr) -> AnyStr
    return s

def anystr_tuple_func(s):
    # type: (AnyStr) -> Tuple[AnyStr]
    return (s,)

class Foo(object):
    def __init__(self, s):
        # type: (AnyStr) -> None
        reveal_type(s)
        self.s = s  # type: Union[bytes, Text]
        reveal_type(self.s)
        self.t = anystr_func(s)  # type: Union[bytes, Text]
        reveal_type(self.t)
        self.u = anystr_tuple_func(s)  # type: Tuple[Union[bytes, Text]]
        reveal_type(self.u)
  • What is the actual behavior/output?
foo.py:15: error: Revealed type is 'builtins.str*'
foo.py:15: error: Revealed type is 'builtins.unicode*'
foo.py:17: error: Revealed type is 'builtins.str'
foo.py:17: error: Revealed type is 'builtins.unicode'
foo.py:19: error: Revealed type is 'builtins.str'
foo.py:19: error: Revealed type is 'builtins.unicode'
foo.py:21: error: Revealed type is 'Tuple[builtins.unicode]'
  • What is the behavior/output you expect?
foo.py:15: error: Revealed type is 'builtins.str*'
foo.py:15: error: Revealed type is 'builtins.unicode*'
foo.py:17: error: Revealed type is 'builtins.str'
foo.py:17: error: Revealed type is 'builtins.unicode'
foo.py:19: error: Revealed type is 'builtins.str'
foo.py:19: error: Revealed type is 'builtins.unicode'
foo.py:21: error: Revealed type is 'Tuple[builtins.str]'
foo.py:21: error: Revealed type is 'Tuple[builtins.unicode]'
  • What are the versions of mypy and Python you are using?
    Do you see the same issue after installing mypy from Git master?

Python 3.7.3, mypy 0.701

Yes (as of b29a433)

  • What are the mypy flags you are using? (For example --strict-optional)

--py2. Note I get the expected output with both str and bytes without --py2.


To be slightly more concrete, this came about trying to figure out what was going on with code calling os.path.split (which is (AnyStr) -> Tuple[AnyStr, AnyStr]), and not getting the results I was expecting.

@gsnedders
Copy link
Author

Oh, so the problem here actually is passing a Union[bytes, Text] to the AnyStr:

def anystr_func(s):
    # type: (AnyStr) -> AnyStr
    return s

def foo(s):
    # type: (Union[bytes, Text]) -> None
    reveal_type(s)
    reveal_type(anystr_func(s))

gives:

foo2.py:35: error: Revealed type is 'Union[builtins.str, builtins.unicode]'
foo2.py:36: error: Revealed type is 'builtins.unicode*'

@ilevkivskyi
Copy link
Member

For technical reasons, on Python 2 str is considered a subtype of unicode (I know this is bad) and therefore the union gets simplified. It is unlikely this will be ever fixed. On Python 3 however mypy says:

Value of type variable "AnyStr" of "anystr_func" cannot be "Union[bytes, str]"

Maybe we should allow union math for this case the same way as we do for overloads?

@JukkaL
Copy link
Collaborator

JukkaL commented Mar 31, 2022

Closing due to Python 2 feature freeze (#12237).

@JukkaL JukkaL closed this as completed Mar 31, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants