I’ve noticed that RPM packages sometimes have requirements where version numbers are suffixed with double tildes. For example python3-django-5.1.7-2.fc42
has this requirement (among others):
(python3.13dist(asgiref) < 4~~ with python3.13dist(asgiref) >= 3.8.1)
I fail to google up the meaning of 4~~
rather than a plain 4
. Does anyone here know?
I think it is meant to be a rough ASCII approximation to the math relation ≈ (almost equal to).
Thank you! That sounds plausible, but what would that actually mean? What versions of python3.13dist(asgiref)
does python3-django
allow, and what versions doesn’t it allow? It needs to be at least 3.8.1 obviously, but what exactly is the upper limit?
FWIW, here is what I could find.
Excerpted from fedoraproject.org – wiki – non-numeric versions:
Non-Numeric Versions
There are three cases in which non-numeric versions occur in the Version field:
Pre-release packages
Post-release packages
Snapshot packagesPre-Release Packages
Non-numeric versioned “pre-release” packages can be problematic so they must be treated with care. These are cases where the upstream “pre-release” version has letters rather than simple numbers in their version. Often they have tags like alpha, beta, rc, or letters like a and b denoting that it is a version before the “final” number. We need to follow a special scheme to ensure proper ordering in the Version field.
Version Tag for Pre-Release Packages: %{X}~%{alphatag}
Where %{X} is the software version that the pre-release will become, and %{alphatag} is the string indicating the pre-release state. In this case, the tilde ‘~’ is used as not only a separator, but also an indicator for RPM to consider it lower than a package that just has %{X} in the Version field.
I also see a commit where a ~
was changed to ~~
for “dev” packages (“pre” packages continue to use the ~
separator):
if self.pre:
rpm_suffix = '~{}'.format(''.join(str(x) for x in self.pre))
elif self.dev:
- rpm_suffix = '~{}'.format(''.join(str(x) for x in self.dev))
+ rpm_suffix = '~~{}'.format(''.join(str(x) for x in self.dev))
elif self.post:
rpm_suffix = '^post{}'.format(self.post[1])
else:
Edit: That documentation I found was a draft. Here is the current/official documentation: Versioning Guidelines :: Fedora Docs
Thanks again! I think I understand now.
I was aware of using ~
as a separator to mark prerelease versions as earlier than the final release. But I had always thought of it as a thing splitting a full release number in a left and right side. The commit you found made me realise a tilde simply means a version before whatever is to the left, even if that part itself contains a tilde. Some experiments with rpmdev-vercmp
seems to confirm that. Add to that the fact that a version that is a prefix of another version is considered less, the “empty” prerelease before the second tilde in my 4~~
example becomes less than any actual prerelese. And the empty field after the second tilde becomes less than any version with an empty prerelease but a non-empty dev part in the terms of the Python script.
So < 4~~
is used to say "before major version 4 or any prerelese, development, or other preliminary variant of version 4”. An actual version 3 in other words.
In retrospect it almost looks obvious, but I didn’t realize it.
It would break if anyone would make an “pre-dev” version numbered 4~~~
. But let’s hope that doesn’t happen.