Velocity Reviews > Version Number Comparison Function

# Version Number Comparison Function

Keith
Guest
Posts: n/a

 03-25-2005
Is there a function for comparing version numbers?

E.g.

0.1.0 < 0.1.2
1.876b < 1.876c
3.2.2 < 3.4

Keith

Christos TZOTZIOY Georgiou
Guest
Posts: n/a

 03-25-2005
On 25 Mar 2005 07:34:38 -0800, rumours say that "Keith"
<(E-Mail Removed)> might have written:

>Is there a function for comparing version numbers?
>
>E.g.
>
>0.1.0 < 0.1.2
>1.876b < 1.876c
>3.2.2 < 3.4
>
>Keith

Convert your version numbers into tuples:

(0, 1, 0) < (0, 1, 2)
(1, 876, 'b') < (1, 876, 'c')
(3, 2, 2) < (3, 4)

All of the above are True.
--
TZOTZIOY, I speak England very best.
"Be strict when sending and tolerant when receiving." (from RFC195
I really should keep that in mind when talking with people, actually...

Bill Mill
Guest
Posts: n/a

 03-25-2005
On 25 Mar 2005 07:34:38 -0800, Keith <(E-Mail Removed)> wrote:
> Is there a function for comparing version numbers?
>
> E.g.
>
> 0.1.0 < 0.1.2
> 1.876b < 1.876c
> 3.2.2 < 3.4
>

Not by default AFAIK. How about something like (untested):

def test_version(v1, v2):
v1, v2 = v1.split('.'), v2.split('.')
for x, y in zip(v1, v2):
if x < y: return v1
if y > x: return v2

It assumes that v1 and v2 have the same amount of '.'s and that all of
the version numbers are of the same length (i.e. 1.1000 would be <
1.999). How general do you need to be?

Peace
Bill Mill
bill.mill at gmail.com

Fredrik Lundh
Guest
Posts: n/a

 03-25-2005
"Keith" wrote:

> Is there a function for comparing version numbers?
>
> E.g.
>
> 0.1.0 < 0.1.2
> 1.876b < 1.876c
> 3.2.2 < 3.4

the following works for many common cases:

import re

def cmpver(a, b):
def fixup(i):
try:
return int(i)
except ValueError:
return i
a = map(fixup, re.findall("\d+|\w+", a))
b = map(fixup, re.findall("\d+|\w+", b))
return cmp(a, b) # -1 if a<b, 0 if a=b, 1 if a>b

>>> cmpver("0.1.0", "0.1.2")

-1
>>> cmpver("1.876b", "1.876c")

-1
>>> cmpver("3.2.2", "3.4")

-1

ymmv.

</F>

Keith
Guest
Posts: n/a

 03-25-2005
I can't assume there are the same number of '.'s or there are the same
number of digits per version.

I don't know how the tuple comparison works offhand. But that seems
like it would work if you split it.

The suggestion with the "re" module seems generic enough and looks like
it will work as is.

Thanks.

Dan Sommers
Guest
Posts: n/a

 03-25-2005
On 25 Mar 2005 07:34:38 -0800,
"Keith" <(E-Mail Removed)> wrote:

> Is there a function for comparing version numbers?
> E.g.

> 0.1.0 < 0.1.2
> 1.876b < 1.876c
> 3.2.2 < 3.4

How about a simple string comparison?

Python 2.3.3 (#1, Mar 9 2004, 14:21:31)
[GCC 3.3 20030304 (Apple Computer, Inc. build 1493)] on darwin
>>> '0.1.0' < '0.1.2'

True
>>> '1.876b' < '1.876c'

True
>>> '3.2.2' < '3.4'

True
>>>

Beyond that, there seems to be sufficient variation between version
number schemes, and something "interesting" often happens immediately
before the final version (e.g. "1.0rc4" becomes "1.0"), that you may
have to know something more about where you particular version numbers
come from.

Regards,
Dan

--
Dan Sommers
<http://www.tombstonezero.net/dan/>
μ₀ × ε₀ × c² = 1

Mark Rowe
Guest
Posts: n/a

 03-25-2005

On Mar 26, 2005, at 3:34 AM, Keith wrote:

> Is there a function for comparing version numbers?
>
> E.g.
>
> 0.1.0 < 0.1.2
> 1.876b < 1.876c
> 3.2.2 < 3.4

FWIW,

>>> from distutils import version
>>> version_list = "3.4 3.2.2 1.867c 1.867b 0.1.2 0.1.0".split()
>>> version_list = map(version.LooseVersion, version_list)
>>> version_list.sort()
>>> print version_list

[LooseVersion ('0.1.0'), LooseVersion ('0.1.2'), LooseVersion
('1.867b'), LooseVersion ('1.867c'), LooseVersion ('3.2.2'),
LooseVersion ('3.4')]
>>> print ' < '.join(map(str, version_list))

0.1.0 < 0.1.2 < 1.867b < 1.867c < 3.2.2 < 3.4
>>>

It should be noted that distutils.version provides a StrictVersion
class that offers less flexible but more predictable ordering -- see
the module docstrings for more details.

Regards,

Mark Rowe
<http://bdash.net.nz/>

Robert Kern
Guest
Posts: n/a

 03-25-2005
[Pardon the piggybacking. My news-server does not see the OP's message.]

Fredrik Lundh wrote:
> "Keith" wrote:
>
>
>>Is there a function for comparing version numbers?
>>
>>E.g.
>>
>>0.1.0 < 0.1.2
>>1.876b < 1.876c
>>3.2.2 < 3.4

distutils has a set of version classes with comparisons.

In [1]:from distutils import version

In [2]:version?
Type: module
Base Class: <type 'module'>
String Form: <module 'distutils.version' from
'/System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/distutils/version.pyc'>
Namespace: Interactive
File:
/System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/distutils/version.py
Docstring:
Provides classes to represent module version numbers (one class for
each style of version numbering). There are currently two such classes
implemented: StrictVersion and LooseVersion.

Every version number class implements the following interface:
* the 'parse' method takes a string and parses it to some internal
representation; if the string is an invalid version number,
'parse' raises a ValueError exception
* the class constructor takes an optional string argument which,
if supplied, is passed to 'parse'
* __str__ reconstructs the string that was passed to 'parse' (or
an equivalent string -- ie. one that will generate an equivalent
version number instance)
* __repr__ generates Python code to recreate the version number
instance
* __cmp__ compares the current instance with either another instance
of the same class or a string (which will be parsed to an instance
of the same class, thus must follow the same rules)

--
Robert Kern
http://www.velocityreviews.com/forums/(E-Mail Removed)

"In the fields of hell where the grass grows high
Are the graves of dreams allowed to die."
-- Richard Harter

Keith
Guest
Posts: n/a

 03-25-2005
distutils is one of the places I looked:
http://www.python.org/doc/2.3.5/lib/...distutils.html

But I didn't see the functions documented. I am new to Python so I
didn't know where else to look.

Using distutils seems like it would be the most generic and supported
way to compare version numbers.

Robert Kern
Guest
Posts: n/a

 03-25-2005
Keith wrote:
> distutils is one of the places I looked:
> http://www.python.org/doc/2.3.5/lib/...distutils.html
>
> But I didn't see the functions documented. I am new to Python so I
> didn't know where else to look.

The source! I don't think they're documented elsewhere.

> Using distutils seems like it would be the most generic and supported
> way to compare version numbers.

Indeed.

--
Robert Kern
(E-Mail Removed)

"In the fields of hell where the grass grows high
Are the graves of dreams allowed to die."
-- Richard Harter