Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 170659 - handling of version components that start with 0
Summary: handling of version components that start with 0
Status: RESOLVED FIXED
Alias: None
Product: Gentoo Hosted Projects
Classification: Unclassified
Component: PMS/EAPI (show other bugs)
Hardware: All All
: High normal (vote)
Assignee: PMS/EAPI
URL:
Whiteboard:
Keywords:
: 207515 (view as bug list)
Depends on:
Blocks:
 
Reported: 2007-03-12 22:15 UTC by SpanKY
Modified: 2008-01-26 17:38 UTC (History)
3 users (show)

See Also:
Package list:
Runtime testing required: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description SpanKY gentoo-dev 2007-03-12 22:15:43 UTC
currently portage has the behavior that numbers that start with 0 are compared as floats rather than integers ... the comparison does cause a few discrepancies (probably less than 10 in the current tree)

comparing by float, portage says:
dev-perl/WWW-Mechanize-1.0301 is older than dev-perl/WWW-Mechanize-1.16

comparing by int, the pms says the opposite
Comment 1 Stephen Bennett (RETIRED) gentoo-dev 2007-03-12 22:29:05 UTC
Is this behaviour really desirable? As far as I can recall, last time I checked the only ebuilds using this behaviour were some now removed perl modules. That may of course have changed, or I may just be wrong. Personally, I view the float comparison as a nasty hack to be dumped at a reasonable opportunity.
Comment 2 Ciaran McCreesh 2007-03-12 22:32:37 UTC
It's also inconsistent for Perl things as soon as the leading zero becomes a one... The whole leading-zero comparison is inconsistent, ill-defined and illogical.
Comment 3 SpanKY gentoo-dev 2007-03-12 22:56:56 UTC
i'd agree it can be illogical, but this difference needs to be at least noted in the spec i think

plus we need to fix portage
Comment 4 Stefan Huszics 2007-03-28 19:36:11 UTC
Im seeing the error in the following ebuilds

dev-perl/MailTools-1.67
dev-perl/MailTools-1.74

which both DEPEND=">=virtual/perl-libnet-1.0703

of course virtual/perl-libnet exsists only as version 1.19 & 1.20 in the tree.

Apparently fixing the depend line in the ebuild manually also ends in tears
http://bugs.gentoo.org/show_bug.cgi?id=165971

In short, its apparently a problem right now.
Comment 5 Ciaran McCreesh 2007-04-15 03:40:04 UTC
Ok. Someone please come up with an algorithm that can explain the following ordering:

0_pre
00
0
1_alpha_alpha
1_alpha
1_alpha1_alpha
1_alpha1_beta_pre
1_alpha1_beta
1_alpha1
1_alpha1-r1
1_alpha10
1_alpha10-r1
1_alpha10-r2
1_alpha10_p1
1_alpha10_p1-r1
1_alpha11
1_beta
1_beta10
1_beta10-r1
1_beta10_p1
1_beta10_p1-r1
1_beta11
1_pre
1_pre10
1_pre10-r1
1_pre10_p1
1_pre10_p1-r1
1_pre11
1_rc
1_rc10
1_rc10-r1
1_rc10_p1
1_rc10_p1-r1
1_rc11
0001
01
1
001
1-r1
1_p1
1p
1.0
1.00
1.0a
1.0.0
1.001
1.010
1.01
1.02
1.020
1.021
1.1_alpha3
1.1
1.1-r1
1.1.1
1.1.2
1.2_alpha
1.2_beta
1.2_beta10
1.2_beta10_p1
1.2_beta11
1.2
1.2-r1
1.10
1.11
1.100
1.101
1.201
2_alpha
10
100

Note in particular this part:

0001
01
1
001

To obtain that list, I created ebuilds for a dummy package with all of those version numbers and then ran equery list, which is supposed to stick them out in order.

Cc:ing the Portage people in the hopes that they can explain just what the heck is going on...
Comment 6 Zac Medico gentoo-dev 2007-04-16 01:48:10 UTC
(In reply to comment #5)
> Note in particular this part:
> 
> 0001
> 01
> 1
> 001

The version comparison code does not distinguish between any of those.  It simply strips all of the leading zeros in that case.  Proof:

#!/usr/bin/env python
test_versions = ["0001", "01", "1", "001"]
from portage_versions import vercmp
for x in test_versions:
	for y in test_versions:
		if x == y:
			continue
		print "%s = vercmp('%s', '%s')" % (vercmp(x, y), x, y)
Comment 7 Ciaran McCreesh 2007-04-16 02:09:17 UTC
Alright, so what's the algorithm? It's not float-like, since 1.1 != 1.10, and it's not integer, since 1.01 != 1.1, and it's not string, since 1.010 < 1.01.
Comment 8 Zac Medico gentoo-dev 2007-04-16 02:19:08 UTC
It's an integer comparison, with the leading zeros ignored.  The float-like behavior is only triggered when the zeros come after a period.
Comment 9 Ciaran McCreesh 2007-04-16 02:21:23 UTC
(In reply to comment #8)
> It's an integer comparison, with the leading zeros ignored.  The float-like
> behavior is only triggered when the zeros come after a period.

So what's the behaviour then? It's not float-like because 1.10 != 1.1.
Comment 10 Zac Medico gentoo-dev 2007-04-16 02:38:30 UTC
Float comparison is only triggered when both components being compared come after a period and both begin with zero.
Comment 11 Ciaran McCreesh 2007-04-16 02:42:59 UTC
(In reply to comment #10)
> Float comparison is only triggered when both components being compared come
> after a period and both begin with zero.

So going back to comment #0, why is 1.0301 < 1.16? That's not both beginning with a zero.
Comment 12 Zac Medico gentoo-dev 2007-04-16 02:52:50 UTC
(In reply to comment #10)
> Float comparison is only triggered when both components being compared come
> after a period and both begin with zero.

I said that wrong.  I should have said "Float comparison is only triggered when both components being compared come after a period and either component begins with a zero".
Comment 13 Ciaran McCreesh 2007-04-16 03:15:55 UTC
Hrm. Are these two equal too then?

1.010
1.01
Comment 14 Zac Medico gentoo-dev 2007-04-16 03:45:14 UTC
Yes, 1.010 and 1.01 trigger the float comparison code which considers them equal.
Comment 15 Ciaran McCreesh 2007-04-17 07:10:12 UTC
Alright, please look at r163.  I thiiiink that matches up with the mess that Portage uses...
Comment 16 Danny van Dyk (RETIRED) gentoo-dev 2007-04-30 18:12:22 UTC
Fixed in SVN as of r163.
Comment 17 SpanKY gentoo-dev 2008-01-26 09:47:16 UTC
*** Bug 207515 has been marked as a duplicate of this bug. ***
Comment 18 Björn Michaelsen 2008-01-26 10:38:54 UTC
The current description makes:
1.22<1.050
1.6<1.22
1.050<1.6
Ebuilds version comparisons are not transitive, making it impossible to find a best match in this case (those versions cant be ordered). This is not only strange, it leads to undefined behavior. For example a package manager might always "update" between the versions above, as each is of the versions is higher than one other. Thats clearly broken.

Proposal:
- A missing version component is always less than any given version component.
- Version components with a leading zero are always less than version components starting with [1-9].
- Two Version components with leading zeros are always stripped from leading zeros and are then string compared.
- Version components with no leading zero are compared as integers.

The last sentence is the only difference to the behavior in r174 of PMS. However the current description for that case leads to undefined behavior anyway.

That comparison is transitive and as close to the original behavior as possible: 
- It only makes 1.01 < 1.1
- It keeps 1.01 == 1.001 and 1.0100 < 1.000050
- It keeps 1.23 > 1.9

Please reopen this bug. The current state (r174) is no solution. Thanks.
Comment 19 David Leverton 2008-01-26 13:15:06 UTC
(In reply to comment #18)
> The current description makes:
> 1.22<1.050

I don't see how you get that from the text... certainly none of the implementations do it:

[dleverton@shiny-one ~] $ python
Python 2.4.4 (#1, Oct 27 2007, 11:37:00)
[GCC 4.1.2 (Gentoo 4.1.2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import portage_versions
>>> portage_versions.vercmp("1.22", "1.050")
170
>>> import paludis
>>> paludis.VersionSpec("1.22") > paludis.VersionSpec("1.050")
True
>>> import pkgcore.ebuild.cpv as cpv
>>> cpv.native_CPV("foo", "bar", "1.22") > cpv.native_CPV("foo", "bar", "1.050")
True
>>> cpv.cpy_CPV("foo", "bar", "1.22") > cpv.cpy_CPV("foo", "bar", "1.050")
True
Comment 20 Björn Michaelsen 2008-01-26 17:38:55 UTC
@David: Yes, sorry. I misunderstood the text. (I read "strip leading zeroes" instead of "strip tailing zeroes".)
I will ponder a bit about this, before raising my voice again.