summaryrefslogtreecommitdiffstats
path: root/pydist/generate_fallback_list.py
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 16:08:06 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 16:08:06 +0000
commitba6d96469df143b52295f8e79da648bf8a597407 (patch)
tree5ea0c3374f5c53209ad02008dcdddfc8ccae92e5 /pydist/generate_fallback_list.py
parentInitial commit. (diff)
downloaddh-python-upstream.tar.xz
dh-python-upstream.zip
Adding upstream version 5.20230130+deb12u1.upstream/5.20230130+deb12u1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'pydist/generate_fallback_list.py')
-rwxr-xr-xpydist/generate_fallback_list.py156
1 files changed, 156 insertions, 0 deletions
diff --git a/pydist/generate_fallback_list.py b/pydist/generate_fallback_list.py
new file mode 100755
index 0000000..5f9e480
--- /dev/null
+++ b/pydist/generate_fallback_list.py
@@ -0,0 +1,156 @@
+#! /usr/bin/python3
+# Copyright © 2010-2015 Piotr Ożarowski <piotr@debian.org>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+import re
+import sys
+try:
+ from distro_info import DistroInfo # python3-distro-info package
+except ImportError:
+ DistroInfo = None
+from gzip import decompress
+from os import chdir, mkdir
+from os.path import dirname, exists, isdir, join, split
+from urllib.request import urlopen
+
+if '--ubuntu' in sys.argv and DistroInfo:
+ SOURCES = [
+ 'http://archive.ubuntu.com/ubuntu/dists/%s/Contents-amd64.gz' %
+ DistroInfo('ubuntu').devel(),
+ ]
+else:
+ SOURCES = [
+ 'http://ftp.debian.org/debian/dists/unstable/main/Contents-all.gz',
+ 'http://ftp.debian.org/debian/dists/unstable/main/Contents-amd64.gz',
+ ]
+
+IGNORED_PKGS = {'python-setuptools', 'python3-setuptools', 'pypy-setuptools'}
+OVERRIDES = {
+ 'cpython2': {
+ 'python': 'python',
+ 'setuptools': 'python-pkg-resources',
+ 'wsgiref': 'python (>= 2.5) | python-wsgiref',
+ 'argparse': 'python (>= 2.7) | python-argparse',
+ # not recognized due to .pth file (egg-info is in PIL/ and not in *-packages/)
+ 'pil': 'python-pil',
+ 'Pillow': 'python-pil'},
+ 'cpython3': {
+ 'pil': 'python3-pil',
+ 'Pillow': 'python3-pil',
+ 'pylint': 'pylint',
+ 'setuptools': 'python3-pkg-resources',
+ 'argparse': 'python3 (>= 3.2)'},
+ 'pypy': {}
+}
+
+public_egg = re.compile(r'''
+ /usr/
+ (
+ (?P<cpython2>
+ (lib/python2\.[0-9]/((site)|(dist))-packages)|
+ (share/python-support/[^/]+)
+ )|
+ (?P<cpython3>
+ (lib/python3/dist-packages)
+ )|
+ (?P<pypy>
+ (lib/pypy/dist-packages)
+ )
+ )
+ /[^/]*\.(dist|egg)-info
+''', re.VERBOSE).match
+
+skip_sensible_names = True if '--skip-sensible-names' in sys.argv else False
+
+chdir(dirname(__file__))
+if isdir('../dhpython'):
+ sys.path.append('..')
+else:
+ sys.path.append('/usr/share/dh-python/dhpython/')
+from dhpython.pydist import sensible_pname
+
+data = ''
+if not isdir('cache'):
+ mkdir('cache')
+for source in SOURCES:
+ cache_fpath = join('cache', split(source)[-1])
+ if not exists(cache_fpath):
+ with urlopen(source) as fp:
+ source_data = fp.read()
+ with open(cache_fpath, 'wb') as fp:
+ fp.write(source_data)
+ else:
+ with open(cache_fpath, 'rb') as fp:
+ source_data = fp.read()
+ try:
+ data += str(decompress(source_data), encoding='UTF-8')
+ except UnicodeDecodeError as e: # Ubuntu
+ data += str(decompress(source_data), encoding='ISO-8859-15')
+
+result = {
+ 'cpython3': {}
+}
+
+# Contents file doesn't contain comment these days
+is_header = not data.startswith('bin')
+for line in data.splitlines():
+ if is_header:
+ if line.startswith('FILE'):
+ is_header = False
+ continue
+ try:
+ path, desc = line.rsplit(maxsplit=1)
+ except ValueError:
+ # NOTE(jamespage) some lines in Ubuntu are not parseable.
+ continue
+ path = '/' + path.rstrip()
+ section, pkg_name = desc.rsplit('/', 1)
+ if pkg_name in IGNORED_PKGS:
+ continue
+ match = public_egg(path)
+ if match:
+ egg_name = [i.split('-', 1)[0] for i in path.split('/')
+ if i.endswith(('.egg-info', '.dist-info'))][0]
+ if egg_name.endswith('.egg'):
+ egg_name = egg_name[:-4]
+
+ impl = next(key for key, value in match.groupdict().items() if value)
+
+ if skip_sensible_names and\
+ sensible_pname(impl, egg_name) == pkg_name:
+ continue
+
+ if impl not in result:
+ continue
+
+ processed = result[impl]
+ if egg_name not in processed:
+ processed[egg_name] = pkg_name
+
+for impl, details in result.items():
+ with open('{}_fallback'.format(impl), 'w') as fp:
+ overrides = OVERRIDES[impl]
+ lines = []
+ for egg, value in overrides.items():
+ lines.append('{} {}\n'.format(egg, value))
+ lines.extend(
+ '{} {}\n'.format(egg, pkg) for egg, pkg in details.items() if egg not in overrides
+ )
+ fp.writelines(sorted(lines))