commit bac3947224b96b5bba98f5e1a5e12ad6acc20a96 Author: Damian Johnson atagar@torproject.org Date: Thu Sep 21 12:23:19 2017 -0700
Support multiple extra entries on versions
https://trac.torproject.org/projects/tor/ticket/22110 https://gitweb.torproject.org/torspec.git/commit/?id=b50917d --- docs/change_log.rst | 1 + stem/version.py | 29 +++++++++++++++++------------ test/unit/version.py | 11 +++++++++++ 3 files changed, 29 insertions(+), 12 deletions(-)
diff --git a/docs/change_log.rst b/docs/change_log.rst index 2e421c4f..415a8bfe 100644 --- a/docs/change_log.rst +++ b/docs/change_log.rst @@ -62,6 +62,7 @@ The following are only available within Stem's `git repository * Added :func:`~stem.manual.database` to get a cursor for the manual cache * Failed to parse torrcs without a port on ipv6 exit policy entries * Resilient to 'Tor' prefix in 'GETINFO version' result (:spec:`c5ff1b1`) + * Added a **all_extra** parameter to :class:`stem.version.Version` and support for multiple parenthetical entries (:trac:`22110`, :spec:`b50917d`) * Closing controller connection faster when under heavy event load * More succinct trace level logging
diff --git a/stem/version.py b/stem/version.py index 4f0ffb9c..87070093 100644 --- a/stem/version.py +++ b/stem/version.py @@ -94,6 +94,8 @@ except ImportError: # cache for the get_system_tor_version function VERSION_CACHE = {}
+VERSION_PATTERN = re.compile(r'^([0-9]+).([0-9]+).([0-9]+)(.[0-9]+)?(-\S*)?(( (\S*))*)$') +
def get_system_tor_version(tor_cmd = 'tor'): """ @@ -156,13 +158,17 @@ class Version(object): https://gitweb.torproject.org/torspec.git/tree/version-spec.txt`_, such as "0.1.4" or "0.2.2.23-alpha (git-7dcd105be34a4f44)".
+ .. versionchanged:: 1.6.0 + Added all_extra parameter.. + :var int major: major version :var int minor: minor version :var int micro: micro version :var int patch: patch level (**None** if undefined) :var str status: status tag such as 'alpha' or 'beta-dev' (**None** if undefined) - :var str extra: extra information without its parentheses such as + :var str extra: first extra information without its parentheses such as 'git-8be6058d8f31e578' (**None** if undefined) + :var list all_extra: all extra information entries, without their parentheses :var str git_commit: git commit id (**None** if it wasn't provided)
:param str version_str: version to be parsed @@ -172,11 +178,11 @@ class Version(object):
def __init__(self, version_str): self.version_str = version_str - version_parts = re.match(r'^([0-9]+).([0-9]+).([0-9]+)(.[0-9]+)?(-\S*)?( (\S*))?$', version_str) + version_parts = VERSION_PATTERN.match(version_str) self._hash = None
if version_parts: - major, minor, micro, patch, status, extra = version_parts.groups() + major, minor, micro, patch, status, extra_str, _ = version_parts.groups()
# The patch and status matches are optional (may be None) and have an extra # proceeding period or dash if they exist. Stripping those off. @@ -187,20 +193,19 @@ class Version(object): if status: status = status[1:]
- if extra: - extra = extra[2:-1] - self.major = int(major) self.minor = int(minor) self.micro = int(micro) self.patch = patch self.status = status - self.extra = extra - - if extra and re.match('^git-[0-9a-f]{16}$', extra): - self.git_commit = extra[4:] - else: - self.git_commit = None + self.all_extra = [entry[1:-1] for entry in extra_str.strip().split()] if extra_str else [] + self.extra = self.all_extra[0] if self.all_extra else None + self.git_commit = None + + for extra in self.all_extra: + if extra and re.match('^git-[0-9a-f]{16}$', extra): + self.git_commit = extra[4:] + break else: raise ValueError("'%s' isn't a properly formatted tor version" % version_str)
diff --git a/test/unit/version.py b/test/unit/version.py index 2518a41b..f8c51f95 100644 --- a/test/unit/version.py +++ b/test/unit/version.py @@ -81,6 +81,16 @@ class TestVersion(unittest.TestCase): self.assertRaises(ValueError, stem.version.Version, '12.3') self.assertRaises(ValueError, stem.version.Version, '1.-2.3')
+ def test_with_multiple_extra(self): + """ + Parse a version with multiple 'extra' fields. + """ + + version = Version('0.1.2 (release) (git-73ff13ab3cc9570d)') + self.assert_versions_match(version, 0, 1, 2, None, None, 'release') + self.assertEqual(['release', 'git-73ff13ab3cc9570d'], version.all_extra) + self.assertEqual('73ff13ab3cc9570d', version.git_commit) + def test_comparison(self): """ Tests comparision between Version instances. @@ -224,6 +234,7 @@ class TestVersion(unittest.TestCase): self.assertEqual(extra, version.extra)
if extra is None: + self.assertEqual([], version.all_extra) self.assertEqual(None, version.git_commit)
def assert_version_is_greater(self, first_version, second_version):
tor-commits@lists.torproject.org