summaryrefslogtreecommitdiff
path: root/versionpredicate.py
diff options
context:
space:
mode:
authorfdrake <devnull@localhost>2005-03-20 20:44:11 +0000
committerfdrake <devnull@localhost>2005-03-20 20:44:11 +0000
commitd7747b86726e8db7759ffeb29c25adba205bf13c (patch)
tree86a6033385b08e33e2a221aed82e8e4f5413ee11 /versionpredicate.py
parentb0702cde2185f45ee1256d5ac32a767cb4039e28 (diff)
downloaddecorator-d7747b86726e8db7759ffeb29c25adba205bf13c.tar.gz
add Andy Harrington's version qualifier checking code
Diffstat (limited to 'versionpredicate.py')
-rw-r--r--versionpredicate.py98
1 files changed, 98 insertions, 0 deletions
diff --git a/versionpredicate.py b/versionpredicate.py
new file mode 100644
index 0000000..ef72954
--- /dev/null
+++ b/versionpredicate.py
@@ -0,0 +1,98 @@
+"""Module for parsing and testing package version predicate strings.
+"""
+import re
+import operator
+
+import distutils.version
+
+re_validPackage = re.compile(r"(?i)^\s*([a-z_]\w*(?:\.[a-z_]\w*)*)(.*)")
+# (package) (rest)
+
+re_paren = re.compile(r"^\s*\((.*)\)\s*$") # (list) inside of parentheses
+re_splitComparison = re.compile(r"^\s*(<=|>=|<|>|!=|==)\s*([^\s,]+)\s*$")
+# (comp) (version)
+
+def splitUp(pred):
+ """Parse a single version comparison.
+ Return (comparison string, StrictVersion)
+ """
+ res = re_splitComparison.match(pred)
+ if not res:
+ raise ValueError, "Bad package restriction syntax: " + pred
+ comp, verStr = res.groups()
+ return (comp, distutils.version.StrictVersion(verStr))
+
+compmap = {"<": operator.lt, "<=": operator.le, "==": operator.eq,
+ ">": operator.gt, ">=": operator.ge, "!=": operator.ne}
+
+class VersionPredicate:
+ """Parse and test package version predicates.
+
+ >>> v = VersionPredicate("pyepat.abc (>1.0, <3333.3a1, !=1555.1b3)")
+ >>> print v
+ pyepat.abc (> 1.0, < 3333.3a1, != 1555.1b3)
+ >>> v.satisfied_by("1.1")
+ True
+ >>> v.satisfied_by("1.4")
+ True
+ >>> v.satisfied_by("1.0")
+ False
+ >>> v.satisfied_by("4444.4")
+ False
+ >>> v.satisfied_by("1555.1b3")
+ False
+ >>> v = VersionPredicate("pat( == 0.1 ) ")
+ >>> v.satisfied_by("0.1")
+ True
+ >>> v.satisfied_by("0.2")
+ False
+ >>> v = VersionPredicate("p1.p2.p3.p4(>=1.0, <=1.3a1, !=1.2zb3)")
+ Traceback (most recent call last):
+ ...
+ ValueError: invalid version number '1.2zb3'
+
+ """
+
+ def __init__(self, versionPredicateStr):
+ """Parse a version predicate string.
+ """
+ # Fields:
+ # name: package name
+ # pred: list of (comparison string, StrictVersion)
+
+ versionPredicateStr = versionPredicateStr.strip()
+ if not versionPredicateStr:
+ raise ValueError, "Empty package restriction"
+ match = re_validPackage.match(versionPredicateStr)
+ if not match:
+ raise ValueError, "Bad package name in " + versionPredicateStr
+ self.name, paren = match.groups()
+ paren = paren.strip()
+ if paren:
+ match = re_paren.match(paren)
+ if not match:
+ raise ValueError, "Expected parenthesized list: " + paren
+ str = match.groups()[0]
+ self.pred = [splitUp(aPred) for aPred in str.split(",")]
+ if not self.pred:
+ raise ValueError("Empty Parenthesized list in %r"
+ % versionPredicateStr )
+ else:
+ self.pred=[]
+
+ def __str__(self):
+ if self.pred:
+ seq = [cond + " " + str(ver) for cond, ver in self.pred]
+ return self.name + " (" + ", ".join(seq) + ")"
+ else:
+ return self.name
+
+ def satisfied_by(self, version):
+ """True if version is compatible with all the predicates in self.
+ The parameter version must be acceptable to the StrictVersion
+ constructor. It may be either a string or StrictVersion.
+ """
+ for cond, ver in self.pred:
+ if not compmap[cond](version, ver):
+ return False
+ return True