Avoid spurious errors when an imported version is consistent with pkg_resources

but not parseable; also improve related error reporting. fixes ticket:2499

Signed-off-by: Daira Hopwood <daira@jacaranda.org>
This commit is contained in:
Daira Hopwood 2015-09-12 00:59:51 +01:00
parent be5ead141e
commit a4dfc31a19
2 changed files with 23 additions and 2 deletions

View File

@ -146,7 +146,8 @@ def get_platform():
from allmydata.util import verlib from allmydata.util import verlib
def normalized_version(verstr, what=None): def normalized_version(verstr, what=None):
try: try:
return verlib.NormalizedVersion(verlib.suggest_normalized_version(verstr)) suggested = verlib.suggest_normalized_version(verstr) or verstr
return verlib.NormalizedVersion(suggested)
except (StandardError, verlib.IrrationalVersionError): except (StandardError, verlib.IrrationalVersionError):
cls, value, trace = sys.exc_info() cls, value, trace = sys.exc_info()
raise PackagingError, ("could not parse %s due to %s: %s" raise PackagingError, ("could not parse %s due to %s: %s"
@ -351,6 +352,11 @@ def cross_check(pkg_resources_vers_and_locs, imported_vers_and_locs_list):
% (name, pr_ver, pr_loc, imp_comment)) % (name, pr_ver, pr_loc, imp_comment))
continue continue
# If the pkg_resources version is identical to the imported version, don't attempt
# to normalize them, since it is unnecessary and may fail (ticket #2499).
if imp_ver != 'unknown' and pr_ver == imp_ver:
continue
try: try:
pr_normver = normalized_version(pr_ver) pr_normver = normalized_version(pr_ver)
except Exception, e: except Exception, e:

View File

@ -91,17 +91,24 @@ class CheckRequirement(unittest.TestCase):
self.failIfEqual(errors, []) self.failIfEqual(errors, [])
self.failUnlessEqual([e for e in errors if "was not found by pkg_resources" not in e], []) self.failUnlessEqual([e for e in errors if "was not found by pkg_resources" not in e], [])
def test_cross_check_ticket_1355(self): def test_cross_check_unparseable_versions(self):
# The bug in #1355 is triggered when a version string from either pkg_resources or import # The bug in #1355 is triggered when a version string from either pkg_resources or import
# is not parseable at all by normalized_version. # is not parseable at all by normalized_version.
res = cross_check({"foo": ("unparseable", "")}, [("foo", ("1.0", "", None))]) res = cross_check({"foo": ("unparseable", "")}, [("foo", ("1.0", "", None))])
self.failUnlessEqual(len(res), 1) self.failUnlessEqual(len(res), 1)
self.failUnlessIn("by pkg_resources could not be parsed", res[0]) self.failUnlessIn("by pkg_resources could not be parsed", res[0])
self.failUnlessIn("due to IrrationalVersionError", res[0])
res = cross_check({"foo": ("1.0", "")}, [("foo", ("unparseable", "", None))]) res = cross_check({"foo": ("1.0", "")}, [("foo", ("unparseable", "", None))])
self.failUnlessEqual(len(res), 1) self.failUnlessEqual(len(res), 1)
self.failUnlessIn(") could not be parsed", res[0]) self.failUnlessIn(") could not be parsed", res[0])
self.failUnlessIn("due to IrrationalVersionError", res[0])
# However, an error should not be triggered when the version strings are unparseable
# but equal (#2499).
res = cross_check({"foo": ("unparseable", "")}, [("foo", ("unparseable", "", None))])
self.failUnlessEqual(res, [])
def test_cross_check(self): def test_cross_check(self):
res = cross_check({}, []) res = cross_check({}, [])
@ -134,10 +141,18 @@ class CheckRequirement(unittest.TestCase):
res = cross_check({"zope.interface": ("1.0", "")}, [("zope.interface", ("unknown", "", None))]) res = cross_check({"zope.interface": ("1.0", "")}, [("zope.interface", ("unknown", "", None))])
self.failUnlessEqual(res, []) self.failUnlessEqual(res, [])
res = cross_check({"zope.interface": ("unknown", "")}, [("zope.interface", ("unknown", "", None))])
self.failUnlessEqual(len(res), 1)
self.failUnlessIn("could not be parsed", res[0])
res = cross_check({"foo": ("1.0", "")}, [("foo", ("unknown", "", None))]) res = cross_check({"foo": ("1.0", "")}, [("foo", ("unknown", "", None))])
self.failUnlessEqual(len(res), 1) self.failUnlessEqual(len(res), 1)
self.failUnlessIn("could not find a version number", res[0]) self.failUnlessIn("could not find a version number", res[0])
res = cross_check({"foo": ("unknown", "")}, [("foo", ("unknown", "", None))])
self.failUnlessEqual(len(res), 1)
self.failUnlessIn("could not be parsed", res[0])
# When pkg_resources and import both find a package, there is only a warning if both # When pkg_resources and import both find a package, there is only a warning if both
# the version and the path fail to match. # the version and the path fail to match.