menu

Questions & Answers

Checking Python standard library function/method calls for compatibility with old Python versions

I have a set of scripts and utility modules that were written for a recent version of Python 3. Now suddenly, I have a need to make sure that all this code works properly under an older version of Python 3. I can't get the user to update to a more recent Python version -- that's not an option. So I need to identify all the instances where I've used some functionality that was introduced since the old version they have installed, so I can remove it or develop workarounds.

Approach #1: eyeball all the code and compare against documentation. Not ideal when there's this much code to look at.

Approach #2: create a virtual environment locally based on the old version in question using pyenv, run everything, see where it fails, and make fixes. I'm doing this anyway, because backporting to the older Python will also mean going backwards in a number of needed third-party modules from PyPi, and I'll need to make sure that the suite still functions properly. But I don't think it's a good way to identify all my version incompatibilities, because much of the code is only exercised based on particular characteristics of input data, and it'd be hard to make sure I exercise all the code (I don't yet have good unit tests that ensure every line will get executed).

Approach #3: in my virtual environment based on the older version, I used pyenv to install the pylint module, then used this pylint module to check my code. It ran; but it didn't identify issues with standard library calls. For example, I know that several of my functions call subprocess.run() with the "check_output=" Boolean argument, which didn't become available until version 3.7. I expected the 3.6 pylint run to spot this and yell at me; but it didn't. Does pylint not check standard library calls against definitions?

Anyway, this is all I've thought of so far. Any ideas gratefully appreciated. Thanks.

Comments:
2023-01-25 00:30:15
No, I don't think pylint does what you want. pyright or mypy may catch this, but it would be a mess if the library wasn't correctly annotated to begin with.
2023-01-25 00:30:15
"I don't yet have good unit tests that ensure every line will get executed" <-- this is really the correct solution: good unit tests combined with a coverage checker so that you know your code is being thoroughly exercised. If you have the option, I would consider prioritizing work on your test suite; once you have that in place identifying 2 vs 3 issues will pretty much happen by virtue of running the tests.
2023-01-25 00:30:15
@larsks according to the first paragraph, it's old 3 vs. new 3, not 2 vs. 3.
2023-01-25 00:30:15
Eh, same comment, regardless of versions.
Answers(0) :