It's astounding to me that there is no way to get `pylint` or `flake8` to not try to follow a conditional import which is known to be incompatible with the version of Python currently running those linters.
This
try:
import package.py2
except SyntaxError:
import package.py3
or this
import sys
if sys.version_info < (3,):
import package.py2
else:
import package.py3
are perfectly good patterns for making portable code which also does not require `exec` or `eval`.
This is much more preferable. It keeps each version of the implementation
exposed to IDEs and linters which support that language version, instead of hiding them in programmatically opaque strings, and
looking like normal, clean, straightforward, and idiomatic code for humans.
And yet in both of these cases and any other variant I have been able to think of which did not involve putting `exec` or `eval` into the per-version files, `pylint` and `flake8` try to import both files and get syntax errors.
I get that resolving whether a conditional import applies is hard. Equivalent to the halting problem and may use information impossible to know during linting. Even the provable and simple cases would take effort to code. So it is reasonable to lint all imports, even conditional ones.
But this is well within the checking those linters already implement. Trivial, reliable heuristic. Especially the top variant, a one-liner import within a try block that catches precisely syntax errors.
And this is obviously a nicer way to handle syntax portability issues than `exec` or `eval`, when all the best practices at balanced in.













