From 2f51ae58f7e24a3bc73c24e97d9b37a2b2e8c476 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20O=C5=BCarowski?= <piotr@debian.org> Date: Sat, 30 Jun 2012 00:42:55 +0200 Subject: [PATCH] translate Python version numbers into Debian ones for those require.txt items that have a pydist file with (uscan like) rules or PEP386 flag (Closes: #653740) --- debian/changelog | 3 ++ debpython/pydist.py | 72 +++++++++++++++++++++++++++----- tests/t1/Makefile | 1 + tests/t1/debian/pydist-overrides | 2 +- tests/t1/debian/rules | 2 +- 5 files changed, 68 insertions(+), 12 deletions(-) diff --git a/debian/changelog b/debian/changelog index 3fa39dd..2d6a160 100644 --- a/debian/changelog +++ b/debian/changelog @@ -13,6 +13,9 @@ python-defaults (2.7.3-1) unstable; urgency=low (example: --shebang /usr/bin/python2.6) - no longer generates python2.X | python2.Y depenendies for public modules (Closes: 625740) + - translate Python version numbers into Debian ones for those + require.txt items that have a pydist file with (uscan like) rules + or PEP386 flag (Closes: #653740) * pyversions, dh_python2, pycompile: allow to override system's list of supported Python versions via DEBPYTHON_SUPPORTED and default Python version via DEBPYTHON_DEFAULT env. variables diff --git a/debpython/pydist.py b/debpython/pydist.py index 1549196..2db8372 100644 --- a/debpython/pydist.py +++ b/debpython/pydist.py @@ -24,6 +24,7 @@ import logging import os import re from os.path import exists, isdir, join +from string import maketrans from subprocess import PIPE, Popen from debpython.version import vrepr, getver, get_requested_versions from debpython.tools import memoize @@ -41,7 +42,7 @@ PYDIST_RE = re.compile(r""" ;\s* (?P<standard>PEP386)? # PEP-386 mode \s* - (?P<rules>s/.*)? # translator rules + (?P<rules>(?:s|tr|y).*)? # translator rules )? """, re.VERBOSE) REQUIRES_RE = re.compile(r''' @@ -117,13 +118,13 @@ def guess_dependency(req, version=None): req = safe_name(name) + rest data = load() - req_dict = REQUIRES_RE.match(req) - if not req_dict: + req_d = REQUIRES_RE.match(req) + if not req_d: log.info('please ask dh_python2 author to fix REQUIRES_RE ' 'or your upstream author to fix requires.txt') raise Exception('requirement is not valid: %s' % req) - req_dict = req_dict.groupdict() - name = req_dict['name'] + req_d = req_d.groupdict() + name = req_d['name'] details = data.get(name.lower()) if details: for item in details: @@ -134,12 +135,13 @@ def guess_dependency(req, version=None): if not item['dependency']: return # this requirement should be ignored if item['dependency'].endswith(')'): - # no need to translate versions if version is hardcoded in Debian - # dependency - return item['dependency'] - if req_dict['version']: - # FIXME: translate it (rules, versions) + # no need to translate versions if version is hardcoded in + # Debian dependency return item['dependency'] + if req_d['version'] and (item['standard'] or item['rules']) and\ + req_d['operator'] not in (None, '=='): + v = _translate(req_d['version'], item['rules'], item['standard']) + return "%s (%s %s)" % (item['dependency'], req_d['operator'], v) else: return item['dependency'] @@ -231,3 +233,53 @@ def sensible_pname(egg_name): def ci_regexp(name): """Return case insensitive dpkg -S regexp.""" return ''.join("[%s%s]" % (i.upper(), i) if i.isalpha() else i for i in name.lower()) + + +PRE_VER_RE = re.compile(r'[-.]?(alpha|beta|rc|dev|a|b|c)') +GROUP_RE = re.compile(r'\$(\d+)') + + +def _pl2py(pattern): + """Convert Perl RE patterns used in uscan to Python's + + >>> print _pl2py('foo$3') + foo\g<3> + """ + return GROUP_RE.sub(r'\\g<\1>', pattern) + + +def _translate(version, rules, standard): + """Translate Python version into Debian one. + + >>> _translate('1.C2betac', ['s/c//gi'], None) + '1.2beta' + >>> _translate('5-fooa1.2beta3-fooD', + ... ['s/^/1:/', 's/-foo//g', 's:([A-Z]):+$1:'], 'PEP386') + '1:5~a1.2~beta3+D' + >>> _translate('x.y.x.z', ['tr/xy/ab/', 'y,z,Z,'], None) + 'a.b.a.Z' + """ + for rule in rules: + # uscan supports s, tr and y operations + if rule.startswith(('tr', 'y')): + # Note: no support for escaped separator in the pattern + pos = 1 if rule.startswith('y') else 2 + tmp = rule[pos + 1:].split(rule[pos]) + version = version.translate(maketrans(tmp[0], tmp[1])) + elif rule.startswith('s'): + # uscan supports: g, u and x flags + tmp = rule[2:].split(rule[1]) + pattern = re.compile(tmp[0]) + count = 1 + if tmp[2:]: + flags = tmp[2] + if 'g' in flags: + count = 0 + if 'i' in flags: + pattern = re.compile(tmp[0], re.I) + version = pattern.sub(_pl2py(tmp[1]), version, count) + else: + log.warn('unknown rule ignored: %s', rule) + if standard == 'PEP386': + version = PRE_VER_RE.sub('~\g<1>', version) + return version diff --git a/tests/t1/Makefile b/tests/t1/Makefile index b66038c..585f962 100644 --- a/tests/t1/Makefile +++ b/tests/t1/Makefile @@ -5,6 +5,7 @@ DPY=$(DEBPYTHON_DEFAULT) check: grep -q "Depends: .*python-mako" debian/python-foo/DEBIAN/control + grep -q 'python-foo (>= 2:0.1~rc2)' debian/python-foo/DEBIAN/control test -f debian/python-foo/usr/lib/python2.6/dist-packages/foo/__init__.py test ! -f debian/python-foo/usr/lib/python2.6/dist-packages/foo/spam.py grep -q "Depends: .*python (<<" debian/python-foo/DEBIAN/control diff --git a/tests/t1/debian/pydist-overrides b/tests/t1/debian/pydist-overrides index fd6c9d7..6957b0b 100644 --- a/tests/t1/debian/pydist-overrides +++ b/tests/t1/debian/pydist-overrides @@ -1,5 +1,5 @@ Mako python-mako (>= 0.2) SQLAlchemy python-sqlalchemy (>= 0.6) -Foo python-foo +Foo python-foo; PEP386 s/^/2:/ Bar python-bar Baz diff --git a/tests/t1/debian/rules b/tests/t1/debian/rules index 9372870..d0cc758 100755 --- a/tests/t1/debian/rules +++ b/tests/t1/debian/rules @@ -12,5 +12,5 @@ override_dh_pysupport: DH_VERBOSE=1 ../../dh_python2\ --depends 'SQLAlchemy >= 0.6.1'\ --recommends Mako\ - --suggests 'Foo >= 0.1'\ + --suggests 'Foo >= 0.1rc2'\ --suggests 'bar >= 1.0' -- GitLab