Python Forum
Python 2.7 LooseVersion version comparison unexpectedly fails
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Python 2.7 LooseVersion version comparison unexpectedly fails
#1
Hello all,

I have written some tests for LooseVersion from which some seem to be failing unexpectedly.

Code:
from distutils.version import LooseVersion

failed_tests = []

# the tests at hand: the bool at the end is the expected result
# 3   <  3.0: False
# 3   == 3.0: True
# 3   >= 3.0: True
# 3.0 <= 3  : True
# 3.0 == 3  : True
# 3.0 >  3  : False

# must invert the boolean logic with not for the tests in the middle...
if     (LooseVersion('3')   <  LooseVersion('3.0')):
    failed_tests.append(('3 < 3.0', False))
if not (LooseVersion('3')   == LooseVersion('3.0')):
    failed_tests.append(('3 == 3.0', True))
if not (LooseVersion('3')   >= LooseVersion('3.0')):
    failed_tests.append(('3 >= 3.0', True))
if not (LooseVersion('3.0') <= LooseVersion('3')):
    failed_tests.append(('3.0 <= 3', True))
if not (LooseVersion('3.0') == LooseVersion('3')):
    failed_tests.append(('3.0 == 3', True))
if     (LooseVersion('3.0') >  LooseVersion('3')):
    failed_tests.append(('3.0 > 3', False))

if failed_tests:
    print
    print 'Failed tests: ' + str(len(failed_tests))
    for test_string, expected_result in failed_tests:
        print test_string + ': ' + str(expected_result)
    print
    raise ValueError('Some tests failed!')
The above tests should not be failing, but they do:
Error:
12:43:59 [INF][ print]: Failed tests: 6 12:43:59 [INF][ print]: 3 < 3.0: False 12:43:59 [INF][ print]: 3 == 3.0: True 12:43:59 [INF][ print]: 3 >= 3.0: True 12:43:59 [INF][ print]: 3.0 <= 3: True 12:43:59 [INF][ print]: 3.0 == 3: True 12:43:59 [INF][ print]: 3.0 > 3: False
Why is this happening and how do you fix this? Is this a bug? Are my tests bugged?

I really stared at the code for some time, but I cannot find the reason.

See https://github.com/python/cpython/blob/m...version.py for how the regex etc. looks like.

I also tried StrictVersion, which fails with:

Error:
13:03:26 [ERR][ python]: File "C:\Users\Kawu\AppData\Roaming\MySQL\Workbench\modules\jpa_export_plugin_grt.py", line 267, in export_jpa_annotated_classes 13:03:26 [ERR][ python]: if (StrictVersion('3') < StrictVersion('3.0')): 13:03:26 [ERR][ python]: File "C:\Program Files\MySQL\MySQL Workbench 8.0 CE\Python\Lib\distutils\version.py", line 40, in __init__ 13:03:26 [ERR][ python]: self.parse(vstring) 13:03:26 [ERR][ python]: File "C:\Program Files\MySQL\MySQL Workbench 8.0 CE\Python\Lib\distutils\version.py", line 107, in parse 13:03:26 [ERR][ python]: raise ValueError, "invalid version number '%s'" % vstring 13:03:26 [ERR][ python]: ValueError: invalid version number '3'
StrictVersion considers simple numbers as invalid, so I cannot go with StrictVersion anyway, because I need to compare version numbers without minor/sub numbers.

Can anyone help me please?

Kawu
Reply
#2
Remember that a floating point number is made up of an exponent and mantissa, therefore is an approximation of the integer value. In addition, those numbers are represented as base 2 in hardware as sum of 10's, 100's, 1000's, etc.

from docs: https://docs.python.org/3/tutorial/floatingpoint.html
Quote:Unfortunately, most decimal fractions cannot be represented exactly as binary fractions. A consequence is that, in general, the decimal floating-point numbers you enter are only approximated by the binary floating-point numbers actually stored in the machine.

The difference may be miniscule, but it's still there.
Reply
#3
I don't think there is anything mysterious here, considering the instances' data
>>> a, b = LooseVersion('3'), LooseVersion('3.0')
>>> a.__dict__
{'version': [3], 'vstring': '3'}
>>> b.__dict__
{'version': [3, 0], 'vstring': '3.0'}
>>> [3] < [3, 0]
True
Reply
#4
Hmmm. I understand the problem now.

Thanks.

But I wonder:

Does it make sense for an out-of-the-box version comparison facility to define that

[3] < [3, 0] < [3, 0, 0] < [3, 0, 0, 0] ...

?

Karsten
Reply
#5
current version of python is 3.7.1. 2.7 is rapidly approaching EOL, just over a year left.
Reply
#6
Thanks for the info.

I cannot upgrade Python on my own. I am solely using Python for my MySQL Workbench project. That software comes with an interpreter of their choice.

I will be asking them about a Python 3 upgrade.

Thanks for helping.

Karsten
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  run part of a script with a different version of Python jdog 2 395 Jan-09-2024, 08:49 PM
Last Post: jdog
  How to find out from outside Python (in Windows) the current version of Python? pstein 4 680 Oct-04-2023, 10:01 AM
Last Post: snippsat
  Anaconda 2.4.2: The JupyterLab 3.5.3 fails to run the python code of the Geographical jamalnuman 0 313 Aug-23-2023, 07:48 AM
Last Post: jamalnuman
  How to resolve version conflicts in Python? taeefnajib 0 873 Apr-27-2023, 08:37 PM
Last Post: taeefnajib
  Python venv and PIP version issue JanOlvegg 2 1,200 Feb-22-2023, 02:22 AM
Last Post: JanOlvegg
  Python Version upgrade nitinkukreja 1 855 Feb-04-2023, 10:27 PM
Last Post: Larz60+
Photo String comparison in a csv file in Python Pandas fleafy 2 1,108 Nov-18-2022, 09:38 PM
Last Post: fleafy
  Can't update new python version on Pycharm GOKUUUU 6 3,711 Jul-23-2022, 09:24 PM
Last Post: GOKUUUU
  Building python (3.9.5) with different libexpat version (2.4.6) raghupcr 0 1,261 Feb-25-2022, 11:29 AM
Last Post: raghupcr
  Python keeps running the old version of the code quest 2 3,646 Jan-20-2022, 07:34 AM
Last Post: ThiefOfTime

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020