Reputation: 2800
How can I statically determine whether a Python source file supports Python 3?
The question may be impossible to answer as stated there, so I'll be more specific:
My application for this is to pick a version of flake8 to run that won't give spurious SyntaxErrors. For that reason, I'm looking for (at least) some heuristic that will tell me whether I should run a Python 3 copy of flake8, or a Python 2 copy.
I'm using flake8 from my editor, which shows me lint errors as I type, and I'm most concerned with the fact that sometimes I lose naming errors (such as F821), as a side effect of pyflakes/flake8 thinking that something is a syntax error that's in fact correct syntax: when it encounters a syntax error it (understandably) appears to give up with things like naming errors.
Upvotes: 0
Views: 157
Reputation: 601679
If you only care about SyntaxError
(which you specifically mention in your question), you can simply try to compile the file with Python 2 and 3:
python -m compileall
python3 -m compileall
If either of these commands fails, you at least know that the code does not work with that Python version. The reverse is of course not true: If the code compiles in a specific version of Python, that doesn't guarantee you that it will work correctly in that version of Python. It just tells you there are no SyntaxError
s.
Upvotes: 0
Reputation: 1122042
This is nigh impossible. There are way too many codepaths to test.
Moreover, code can be written to run on both Python 2 and 3, and flake8 doesn't always like the tricks used to make this possible, unless the project specifically tests with flake8 and has marked such sites to be excluded. So you could either have false positives (errors in both the Python 2 and Python 3 versions of flake8) or the code will simply work on Python 2 and 3 without any warnings.
You could use tox
to manage version support for a given project instead; have tox figure out what flake8 command to use (which may be multiple):
[tox]
envlist = py27,py35,flake8-27,flake8-35
# ...
[testenv:flake8-27]
basepython=python2.7
deps=flake8
commands=
flake8 projectdir
[testenv:flake8-35]
basepython=python3.5
deps=flake8
commands=
flake8 projectdir
and use tox -e flake8-27
or tox -e flake8-35
.
Upvotes: 3