-
Notifications
You must be signed in to change notification settings - Fork 280
perf: use version.__replace__ in specifier comparison #999
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
perf: use version.__replace__ in specifier comparison #999
Conversation
001fbe4 to
eddb254
Compare
|
Would this also make sense to add to this PR? diff --git a/src/packaging/specifiers.py b/src/packaging/specifiers.py
index f027aeb..2ba5541 100644
--- a/src/packaging/specifiers.py
+++ b/src/packaging/specifiers.py
@@ -420,7 +420,7 @@ class Specifier(BaseSpecifier):
if spec.endswith(".*"):
# In the case of prefix matching we want to ignore local segment.
normalized_prospective = canonicalize_version(
- prospective.public, strip_trailing_zero=False
+ _public_version(prospective), strip_trailing_zero=False
)
# Get the normalized version string ignoring the trailing .*
normalized_spec = canonicalize_version(spec[:-2], strip_trailing_zero=False)Also Full patch:diff --git a/src/packaging/specifiers.py b/src/packaging/specifiers.py
index f027aeb..18edd34 100644
--- a/src/packaging/specifiers.py
+++ b/src/packaging/specifiers.py
@@ -285,11 +285,13 @@ class Specifier(BaseSpecifier):
# The == specifier can include a trailing .*, if it does we
# want to remove before parsing.
if operator == "==" and version.endswith(".*"):
- version = version[:-2]
+ version_object = Version(version[:-2])
+ else:
+ version_object = self._get_spec_version(version)
# Parse the version, and if it is a pre-release than this
# specifier allows pre-releases.
- if Version(version).is_prerelease:
+ if version_object.is_prerelease:
return True
return False
@@ -351,7 +353,7 @@ class Specifier(BaseSpecifier):
return operator, version
canonical_version = canonicalize_version(
- version,
+ version if version.endswith(".*") else self._get_spec_version(version),
strip_trailing_zero=(operator != "~="),
)
@@ -420,7 +422,7 @@ class Specifier(BaseSpecifier):
if spec.endswith(".*"):
# In the case of prefix matching we want to ignore local segment.
normalized_prospective = canonicalize_version(
- prospective.public, strip_trailing_zero=False
+ _public_version(prospective), strip_trailing_zero=False
)
# Get the normalized version string ignoring the trailing .*
normalized_spec = canonicalize_version(spec[:-2], strip_trailing_zero=False) |
Yes, turns out there were two places I was missing public and base version calls where I could have been using them.
I would need to carefully go over this, the one-element cache is always called with the same value at the moment (assuming you don't mutate the specifier, in which case the cache invalidates itself when you call |
Takes advantage of being able to strip parts of a
Versionand get aVersionwithout having to revalidate a version string.Not had chance to benchmark this yet, but should significantly improve performance of specifier comparison when local, pre, post, or dev parts are involved.