On Fri, 2019-08-02 at 11:47 +0200, Fabio Valentini wrote:
> > Hmm. I never really chipped into the ~ discussion, but it just occurred
> > to me it intersects with a discussion I care quite a lot about: RPM
> > version comparison. Especially RPM version comparison when all you have
> > to deal with is a string that represents an RPM N(E)VR(A) somehow
> > (that's 'name', 'epoch', 'version',
'release', 'arch').
> >
> > This is a corner case quite a few of us run into (it can happen for
> > e.g. when you're working off a fedmsg which just gives you a NEVRA
> > string) and it has some surprising properties, like: there isn't really
> > a 'good' standard way to do it. RPM doesn't expose this in its
public
> > APIs. The best way anyone seems to know of to do it in Python, for
> > instance, is using `hawkey.split_nevra`...only hawkey is a bit weird,
> > it's provided by libdnf and is not in pypi, which means running tests
> > on code that uses it using standard stuff like tox-in-a-container is
> > difficult. Also, DNF folks have suggested they want it to go away.
> >
> > You can split a N(E)VR(A) string into components quite easily and
> > reliably with standard string manipulations, but comparing the
> > components the way RPM does it is difficult to re-implement...and of
> > course, the more weird rules like ~ we introduce, the harder it gets.
> >
> > Anyhow, it occurred to me to try out how hawkey.split_nevra handles
> > this tilde scenario, and the answer seems to be "a bit oddly":
> >
> > > > > tildenevra =
hawkey.split_nevra('systemd-243~rc1-1.fc31')
> > > > > releasenevra = hawkey.split_nevra('systemd-243-1.fc31')
> > > > > releasenevra > tildenevra
> > True
> > > > > releasenevra.version
> > '243'
> > > > > tildenevra.version
> > '243~rc1'
> > > > > releasenevra.version > tildenevra.version
> > False
> > > > > tildenevra.version > releasenevra.version
> > True
> >
> > So...basically, it thinks the entire NEVRA object you get from the
> > string 'systemd-243-1.fc31' is "higher versioned" than the
NEVRA object
> > you get from the string 'systemd-243~rc1-1.fc31'. Which is good,
that's
> > correct. However, it thinks the version component of 'systemd-243~rc1-
> > 1.fc31' is higher than the version component of
'systemd-243-1.fc31'.
> > Which I believe is wrong, and also, it's a bit baffling, because if it
> > thinks that, I don't understand how it gets to the (correct) conclusion
> > that the entire tildenevra is lower versioned than the releasenevra,
> > since the 'name' and 'epoch' ('systemd' and 0,
respectively) are the
> > same for both...
> >
> > Anyone see what I'm missing?
> >
(snip)
> You have to be careful with comparisons here. if the .version attribute is
> just a string, then python will do just a string comparison (which is
> sometimes wrong compared to RPM version comparisons).
>
> Fabio
>
Also, you can use rpm.labelCompare() from the RPM python bindings to check
for version ordering, since rpm.labelCompare() gives you a total order over
(epoch, version, release) string triples. It's easy to wrap that inside an
"idiomatic" python NEVR class that has the desired ordering properties and
overrides >,<, etc. correctly.
I hope this helps.
Thanks. I was actually assuming the version property wasn't just a
string but was some more sophisticated object with custom comparisons,
but apparently not.
rpm.labelCompare sounds like it could definitely be very useful, thanks
for that.
--
Adam Williamson
Fedora QA Community Monkey
IRC: adamw | Twitter: AdamW_Fedora | XMPP: adamw AT happyassassin . net
http://www.happyassassin.net