I'm looking at some software that is wanting to bring in Python 3.6 for use in an environment where 3.5 is the standard. Reading up on Python's documentation I can't find anything about whether:
- 3.5 is representative of a semantic version number
- 3.6 would represent a forwards compatible upgrade (ie: code written for a 3.5 runtime is guaranteed to work in a 3.6 runtime)
The fact that this page about porting to 3.7 exists makes me think strongly no but I can't see official docs on what the version numbers mean (if anything, ala Linux kernel versioning)
In the more general sense - is there a PEP around compatibility standards within the 3.X release stream?
The short answer is "No", the long answer is "They strive for something close to it".
As a rule, micro versions match semantic versioning rules; they're not supposed to break anything or add features, just fix bugs. This isn't always the case (e.g. 3.5.1 broke
vars()on anamedtuple, because it caused a bug that was worse than the break when it came up), but it's very rare for code (especially Python level stuff, as opposed to C extensions) to break across a micro boundary.Minor versions mostly "add features", but they will also make backwards incompatible changes with prior warning. For example,
asyncandawaitbecame keywords in Python 3.7, which meant code using them as variable names broke, but with warnings enabled, you would have seen aDeprecationWarningin 3.6. Many syntax changes are initially introduced as optional imports from the special__future__module, with documented timelines for becoming the default behavior.None of the changes made in minor releases are broad changes; I doubt any individual deprecation or syntax change has affected even 1% of existing source code, but it does happen. If you've got a hundred third party dependencies, and you're jumping a minor version or two, there is a non-trivial chance that one of them will be broken by the change (example:
pikaprior to0.12usedasyncas a variable name, and broke on Python 3.7; they released new versions that fixed the bug, but of course, moving from0.11and lower to0.12and higher changed their own API in ways that might break your code).Major versions are roughly as you'd expect; backwards incompatible changes are expected/allowed (though they're generally not made frivolously; the bigger the change, the bigger the benefit).
Point is, it's close to semantic versioning, but in the interests of not having major releases every few years, while also not letting the language stagnate due to strict compatibility constraints, minor releases are allowed to break small amounts of existing code as long as there is warning (typically in the form of actual warnings from code using deprecated behavior, notes on the What's New documentation, and sometimes
__future__support to ease the migration path).This is all officially documented (with slightly less detail) in their Development Cycle documentation: