[Python-ideas] Add support for version objects

Serhiy Storchaka storchaka at gmail.com
Sat May 28 03:45:59 EDT 2016

On 28.05.16 05:28, Robert Collins wrote:
> On 28 May 2016 at 07:37, Donald Stufft <donald at stufft.io> wrote:
>> To be honest though, I don’t see a lot of benefit to adding it to the standard library.
> Same. Further, I don't see any need for the stdlib itself to use it -
> so its not being drawn in as a dependency, or do you have something in
> mind Serhiy?

My use case is the need of testing versions of libraries, mainly for 
testing, but not only.

For example Tkinter provides version in two forms: _tkinter.TK_VERSION 
is a string ('8.6') and tkinter.TkVersion is a decimal number (8.6). 
Both forms wouldn't work for Tk 8.10. We need to convert string version 
to a tuple of integers. In Lib/tkinter/test/support.py:

     tcl_version = tuple(map(int, _tkinter.TCL_VERSION.split('.')))

But two digits is not enough, because the behavior often depends on the 
pathlevel number. We need to retrieve and parse runtime version. In 

     tkversion = root.tk.eval('info patchlevel')
     if tuple(map(int, tkversion.split('.'))) < (8, 4, 14):

This code doesn't work with alpha, beta and rc versions. There is more 
correct complex code in Lib/tkinter/test/support.py:

     tcl = tkinter.Tcl()
     patchlevel = tcl.call('info', 'patchlevel')
     m = re.fullmatch(r'(\d+)\.(\d+)([ab.])(\d+)', patchlevel)
     major, minor, releaselevel, serial = m.groups()
     major, minor, serial = int(major), int(minor), int(serial)
     releaselevel = {'a':'alpha','b':'beta','.':'final'}[releaselevel]
     if releaselevel == 'final':
         _tk_patchlevel = major, minor, serial, releaselevel, 0
         _tk_patchlevel = major, minor, 0, releaselevel, serial

I think it is worth to provide structured comparable version in the 
tkinter module.

But this is just one library. There are similar problems with other 
libraries. zlib tests contain following complicated code:

     v = (zlib.ZLIB_RUNTIME_VERSION + ".0").split(".", 4)
     supports_wbits_0 = int(v[0]) > 1 or int(v[0]) == 1 \
         and (int(v[1]) > 2 or int(v[1]) == 2
         and (int(v[2]) > 3 or int(v[2]) == 3 and int(v[3]) >= 5))

It is so complex because zlib.ZLIB_RUNTIME_VERSION can contain not only 
digits (like "").

See also complex _requires_unix_version() and requires_mac_ver() in 

There is other code that parses string representation to a tuple of 
numbers. While parsing code can be library specific, I think it is worth 
to provide standard type for representing the result. Libraries provide 
versions as string at Python level, but they often provide separate 
version components, thus we can create version object without parsing 
string representation.

More information about the Python-ideas mailing list