pythonpython-2.7python-typingmypy

trouble understanding the behavior of str() in mypy with --py2 flag


I have a piece of code

1. b = u'\xe6' #type: unicode
2. c = str(b) #type: str
3. d = c #type: str

I run this with the python 2 flag in mypy.

My expectation is that there should be an error at line 2. str(b) returns a type unicode and c has an expected type of str therefore there should be a type incompatibility issue. But no errors thrown.

On the other hand if I explicitly do

1. b = u'\xe6' #type: unicode
2. c = str(b) #type: unicode
3. d = c #type: str

Then there is an error at line 3, stating cannot assign unicode to str, which is somewhat expected.

So the issue is in my understanding of str(), shouldn't str() return the same type as its input? or does it implicitly cast everything to str, if yes then shouldn't there be an error at line 2 instead of line 3 in the second example.

From the current behavior, str() adopts the type of the variable that it is being assigned to.


Solution

  • str returns an object of type str. Under rare and unusual circumstances, it may return an instance of a subclass of str, but it definitely doesn't return an object of whatever type you passed in.

    Line 2 passes type checking in snippet 2 because mypy has a specific special case that says str is compatible with unicode on Python 2, but not vice versa.