Überprüfung auf eine Version - python

Ihr könnt euch noch daran erinnern, das es da eine kleine Verwirrung gab, als Microsoft nach Windows 8 dann Windows 10 angekündigt hatte? Eines der Gerüchte war, dass man davon ausgegangen ist das viele Programme (sowohl von externen Entwicklern als auch von Microsoft selber) bei der Versionsabfrage einfach auf die erste Stelle des Versions-Strings geschaut haben. Und da ist die 9 dann schon von Windows 95 und Windows 98 belegt.

Jetzt aber mal ein anderes Beispiel, wo jemand etwas zu einfach gedacht hat. Das Beispiel ist etwas älter, es wurde noch nicht über Python 3.10 gesprochen.

def run_as_command():
    version = ".".join(str(v) for v in sys.version_info[:2])
    if float(version) < 3.6:
        print(" xxx requires Python version 3.6+.")
        sys.exit(0)

Was passiert hier? Schauen wir uns das ganze doch mal an, interessant sind in dem Beispiel die Zeilen 2 und 3. In Zeile 2 wird die Version ausgelesen und in einen String gespeichert, um dann in Zeile 3 als Fließkomma-Wert auf Größe gegen einen anderen Fließkomma-Wert auf Größe verglichen zu werden.

[name@rechner ~]$ ipython
Python 3.10.2 (main, Jan 15 2022, 19:56:27) [GCC 11.1.0]
Type 'copyright', 'credits' or 'license' for more information
IPython 8.1.1 -- An enhanced Interactive Python. Type '?' for help.
In [1]: import sys
In [2]: version = ".".join(str(v) for v in sys.version_info[:2])
In [3]: version
Out[3]: '3.10'
In [4]: float(version)
Out[4]: 3.1

Und da sehen wir den Salat auch schon: Warum ist die 0 aus dem String verschwunden? Ganz einfach: Eine am Ende einer Komma-Zahl stehende 0 hat keinen Wert und wird daher weggelassen. Sprich

1,1 == 1,10 == 1,10000000000000

Was hätte der Entwickler jetzt machen können? Nun, zum einen hätte er sich mal den Inhalt von 'sys.version_info' anschauen können:

In [5]: sys.version_info
Out[5]: sys.version_info(major=3, minor=10, micro=2, releaselevel='final', serial=0)

D.h. man kann z.B. sowas machen um an die Werte zu kommen:

In [11]: sys.version_info.major
Out[11]: 3

In [12]: sys.version_info.minor
Out[12]: 10

oder auch:

In [22]: required_major, required_minor=3,6
In [23]: if(required_major == sys.version_info.major) & (required_minor < sys.version_info.minor):
    ...:     print("go")
    ...: else:
    ...:     print("no go")
    ...: 
go
 
# gegenprobe
In [24]: required_major, required_minor=3,12
In [25]: if(required_major == sys.version_info.major) & (required_minor < sys.version_info.minor):
    ...:     print("go")
    ...: else:
    ...:     print("no go")
    ...: 
no go