I've read in few places that generally, Python doesn't provide backward compatibility, which means that any newer version of Python may break code that worked fine for earlier versions. If so, what is my way as a developer to know what versions of Python can execute my code successfully? Is there any set of rules/guarantees regarding this? Or should I just tell my users: Just run this with Python 3.8 (for example) - no more no less...?
-
1Python only ever broke compatibility between Python 2 and 3. If you have something that runs on Python 3.8, it will also work on every following version. – Erez Dec 23 '21 at 21:29
-
They do make an effort to maintain compatibility withiin the major versions (Python 2.x, Python 3.x). Breaking changes between minor versions are very rare. Sometimes a new standard library capability will be introduced, and you need to be aware of that. `math.product`, for instance, is post-3.7. – Tim Roberts Dec 23 '21 at 21:30
-
Are you making a pip package? theres setup.py files for that, a script? a read me probably, an executable? include the python you need with it – Sayse Dec 23 '21 at 21:32
-
1For some information about compatibility policy: https://www.python.org/dev/peps/pep-0387/ – j1-lee Dec 23 '21 at 21:32
-
2All of the code I wrote for Python 3.4 still runs with Python 3.9. Could you tell us some of the few places that claim, that generally, Python doesn't provide backward compatibility? – Matthias Dec 23 '21 at 21:33
-
2@Erez: They do break compatibility in small ways between minor versions (and once in a while, even between micro versions, where not changing something leaves a worse bug in place, e.g. [the change from 3.5.0 to 3.5.1 that broke code that called `vars` on `namedtuple`s](https://stackoverflow.com/a/34166604/364696)). Another example was `async` and `await` becoming keywords in 3.7 IIRC (which broke the `pika` package, where `0.11` used `async` as a variable name, and required the `0.12` release of `pika`). – ShadowRanger Dec 23 '21 at 21:33
3 Answers
99% of the time, if it works on Python 3.x, it'll work on 3.y where y >= x
. Enabling warnings when running your code on the older version should pop DeprecationWarning
s when you use a feature that's deprecated (and therefore likely to change/be removed in later Python versions). Aside from that, you can read the What's New docs for each version between the known good version and the later versions, in particular the Deprecated and Removed sections of each.
Beyond that, the only solution is good unit and component tests (you are using those, right? ) that you rerun on newer releases to verify stuff still works & behavior doesn't change.

- 143,180
- 12
- 188
- 271
-
I don't fully understand the thing you said with the DepracationWarning - my question is about running the code with **newer** versions... ? – YoavKlein Dec 23 '21 at 22:01
-
@YoavKlein: If you run the code with *older* versions, with warnings enabled, it will raise `DeprecationWarning`s for features that *will* change or go away in *newer* versions. If your code is relying on deprecated features in older versions, you'll want to change it now, so it works in the newer versions too. Moving your testing forward a minor version at a time will help find any/all deprecated features (assuming said deprecations were tagged with warnings; not all can be). – ShadowRanger Dec 23 '21 at 22:06
-
Now I got you. What is the scope of features that is guaranteed to raise this warning? All the Python constructs and standard library functions/classes? Can I rely on that? – YoavKlein Dec 23 '21 at 22:08
-
1@YoavKlein: They make a strong effort to do it for everything that could break existing, working code. There are occasions where it's not possible (implementation can make it difficult/quirky/highly non-performant in some cases), but there's usually some sort of warning from code that will change, and a note in the What's New for everything (even when a `DeprecationWarning` can't be raised). That said, nothing will guarantee safety save proper testing, sorry. – ShadowRanger Dec 23 '21 at 22:13
-
They often do break existing working code. This is what RedHat had to solve to upgrade to Python3.9: https://bugzilla.redhat.com/show_bug.cgi?id=1785415 – user23952 Dec 23 '21 at 23:00
-
@user23952: Most of those tickets seem to be "use newer version of package". If they were using C extensions, those must rebuild (and sometimes break) from release to release. But [the link](https://fedoraproject.org/wiki/Changes/Python3.9#Upgrade.2Fcompatibility_impact) in your own ticket does acknowledge "User written Python 3 scripts/applications may require a small amount of porting, but mostly Python 3.8 is forward compatible with Python 3.9." The problem with my blanket "99% of the time it works" is that if you have a hundred dependencies, one of them is likely to not work. C'est la vie. – ShadowRanger Dec 23 '21 at 23:07
-
@ShadowRanger it's mostly small and easily fixable things, yes. It can still be a major problem for a large-scale project. People routinely quit or move to new tasks, code is left unmaintained. Someone runs old code with a new version of Python. Maybe it doesn't run, maybe it fails the unit tests, or maybe, as bugs often go, it fails in production in some subtle manner. See this mailing list for example: https://mail.python.org/archives/list/python-dev@python.org/thread/EYLXCGGJOUMZSE5X35ILW3UNTJM3MCRE/ – user23952 Dec 23 '21 at 23:16
According to PEP387, section "Making Incompatible Changes", before incompatible changes are made, a deprecation warning should appear in at least two minor Python versions of the same major version, or one minor version in an older major version. After that, it's a free game, in principle. This made me cringe with regards to safety. Who knows if people run airplanes on Python and if they don't always read the python-dev list. So if you have something that passes 100% coverage unit tests without deprecation warnings, your code should be safe for the next two minor releases.
You can avoid this issue and many others by containerizing your deployments.

- 578
- 3
- 10
-
Anyone responsible for software that runs planes is _responsible for software that runs planes_. :) – Cyphase Oct 17 '22 at 19:42
tox is great for running unit tests against multiple Python versions. That’s useful for at least 2 major cases:
- You want to ensure compatibility for a certain set of Python versions, say 3.7+, and to be told if you make any breaking changes.
- You don’t really know what versions your code supports, but want to establish a baseline of supported versions for future work.
I don’t use it for internal projects where I can control over the environment where my code will be running. It’s lovely for people publishing apps or libraries to PyPI, though.

- 30,189
- 5
- 49
- 65