undefined name 'unicode' in "wrong" sys.version_info branch
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Pyflakes |
New
|
Undecided
|
Unassigned |
Bug Description
pyflakes makes it hard to check code that works on python 2 and 3 because some names are only defined in one version.
For example, take this little module:
import sys
def type_is_str(var):
''' returns True if the given variable is a str (or unicode string when using python 2)'''
if type(var) == str:
return True
elif sys.version_info[0] < 3 and type(var) == unicode: # python 2 also uses the 'unicode' type
return True
else:
return False
pyflakes3 errors out with
undefined name 'unicode'
while pyflakes2 validates this code successfully (because unicode is a valid name in py2).
Can you make pyflakes a bit more intelligent so that it skips branches for the "wrong" version? Or, if that is too hard, add a way to skip a line marked with a special comment like
# PYFLAKES:IGNORE
?
(The py3 testing was done with python3-
For what it's worth, your 'type_is_str" is wrong way to check if something is a string. You shouldn't use "type(x) == T". You should instead use "isinstance(x, T)". The more common way to do this is to define
if PY3:
string_types = (str,)
else:
string_types = (str, unicode) # You can also use basestring
and then check "isinstance(var, string_types)" in your code.
As to the issue itself, Pyflakes would have to become significantly smarter to be able to parse all the different ways that people check for Python 3. It would need to be able to parse "sys.version_ info[0] < 3", and similar constructs in full enough generality to catch every way that people write it, but in a static way. I'm not saying it can't be done, but Pyflakes would have to be about 100x smarter than it is now to be able to handle this sort of thing. I recommend factoring all your Python 2/3 logic into a single file and then don't bother testing that file with pyflakes. Or use a library like six or future.