Server IP : 85.214.239.14 / Your IP : 3.148.104.191 Web Server : Apache/2.4.62 (Debian) System : Linux h2886529.stratoserver.net 4.9.0 #1 SMP Tue Jan 9 19:45:01 MSK 2024 x86_64 User : www-data ( 33) PHP Version : 7.4.18 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, MySQL : OFF | cURL : OFF | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : OFF Directory : /proc/3/root/usr/share/dh-python/dhpython/ |
Upload File : |
# Copyright © 2010-2013 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 logging from functools import partial from os.path import exists, join from dhpython import PKG_PREFIX_MAP, MINPYCDEP from dhpython.pydist import parse_pydep, parse_requires_dist, guess_dependency from dhpython.version import default, supported, VersionRange log = logging.getLogger('dhpython') class Dependencies: """Store relations (dependencies, etc.) between packages.""" def __init__(self, package, impl='cpython3', bdep=None): self.impl = impl self.package = package bdep = self.bdep = bdep or {} self.is_debug_package = dbgpkg = package.endswith('-dbg') # TODO: move it to PyPy and CPython{2,3} classes self.ipkg_vtpl = 'python%s-dbg' if dbgpkg else 'python%s' if impl == 'cpython3': self.ipkg_tpl = 'python3-dbg' if dbgpkg else 'python3' elif impl == 'cpython2': self.ipkg_tpl = 'python2-dbg' if dbgpkg else 'python2' elif impl == 'pypy': self.ipkg_tpl = 'pypy-dbg' if dbgpkg else 'pypy' self.ipkg_vtpl = 'pypy%s-dbg' if dbgpkg else 'pypy%s' if impl == 'pypy': self.ipkg_tpl_ma = self.ipkg_tpl self.ipkg_vtpl_ma = self.ipkg_vtpl else: self.ipkg_tpl_ma = self.ipkg_tpl + ':any' self.ipkg_vtpl_ma = self.ipkg_vtpl + ':any' self.python_dev_in_bd = 'python-dev' in bdep or\ 'python-all-dev' in bdep or\ 'python2-dev' in bdep or\ 'python2-all-dev' in bdep or\ 'python2.7-dev' in bdep or\ 'python3-dev' in bdep or\ 'python3-all-dev' in bdep self.depends = set() self.recommends = [] self.suggests = [] self.enhances = [] self.breaks = [] self.rtscripts = [] def export_to(self, dh): """Fill in debhelper's substvars.""" prefix = PKG_PREFIX_MAP.get(self.impl, 'misc') for i in sorted(self.depends): dh.addsubstvar(self.package, '{}:Depends'.format(prefix), i) for i in sorted(self.recommends): dh.addsubstvar(self.package, '{}:Recommends'.format(prefix), i) for i in sorted(self.suggests): dh.addsubstvar(self.package, '{}:Suggests'.format(prefix), i) for i in sorted(self.enhances): dh.addsubstvar(self.package, '{}:Enhances'.format(prefix), i) for i in sorted(self.breaks): dh.addsubstvar(self.package, '{}:Breaks'.format(prefix), i) for i in sorted(self.rtscripts): dh.add_rtupdate(self.package, i) def __str__(self): return "D=%s; R=%s; S=%s; E=%s, B=%s; RT=%s" %\ (self.depends, self.recommends, self.suggests, self.enhances, self.breaks, self.rtscripts) def depend(self, value): if value and value not in self.depends: self.depends.add(value) def recommend(self, value): if value and value not in self.recommends: self.recommends.append(value) def suggest(self, value): if value and value not in self.suggests: self.suggests.append(value) def enhance(self, value): if value and value not in self.enhances: self.enhances.append(value) def break_(self, value): if value and value not in self.breaks: self.breaks.append(value) def rtscript(self, value): if value not in self.rtscripts: self.rtscripts.append(value) def parse(self, stats, options): log.debug('generating dependencies for package %s', self.package) tpl = self.ipkg_tpl vtpl = self.ipkg_vtpl tpl_ma = self.ipkg_tpl_ma vtpl_ma = self.ipkg_vtpl_ma vrange = options.vrange if vrange and any((stats['compile'], stats['public_vers'], stats['ext_vers'], stats['ext_no_version'], stats['shebangs'])): if any((stats['compile'], stats['public_vers'], stats['shebangs'])): tpl_tmp = tpl_ma else: tpl_tmp = tpl minv = vrange.minver # note it's an open interval (i.e. do not add 1 here!): maxv = vrange.maxver if minv == maxv: self.depend(vtpl % minv) minv = maxv = None if minv: self.depend("%s (>= %s~)" % (tpl_tmp, minv)) if maxv: self.depend("%s (<< %s)" % (tpl_tmp, maxv)) if self.impl == 'cpython2' and stats['public_vers']: # additional Depends to block python package transitions sorted_vers = sorted(stats['public_vers']) minv = sorted_vers[0] maxv = sorted_vers[-1] if minv <= default(self.impl): self.depend("%s (>= %s~)" % (tpl_ma, minv)) if maxv >= default(self.impl): self.depend("%s (<< %s)" % (tpl_ma, maxv + 1)) if self.impl == 'pypy' and stats.get('ext_soabi'): # TODO: make sure alternative is used only for the same extension names # ie. for foo.ABI1.so, foo.ABI2.so, bar.ABI3,so, bar.ABI4.so generate: # pypy-abi-ABI1 | pypy-abi-ABI2, pypy-abi-ABI3 | pypy-abi-ABI4 self.depend('|'.join(soabi.replace('-', '-abi-') for soabi in sorted(stats['ext_soabi']))) if stats['ext_vers']: # TODO: what about extensions with stable ABI? sorted_vers = sorted(stats['ext_vers']) minv = sorted_vers[0] maxv = sorted_vers[-1] #self.depend('|'.join(vtpl % i for i in stats['ext_vers'])) if minv <= default(self.impl): self.depend("%s (>= %s~)" % (tpl, minv)) if maxv >= default(self.impl): self.depend("%s (<< %s)" % (tpl, maxv + 1)) # make sure py{,3}compile binary is available if stats['compile'] and self.impl in MINPYCDEP: self.depend(MINPYCDEP[self.impl]) for ipreter in stats['shebangs']: self.depend("%s%s" % (ipreter, '' if self.impl == 'pypy' else ':any')) supported_versions = supported(self.impl) default_version = default(self.impl) for private_dir, details in stats['private_dirs'].items(): versions = list(i.version for i in details.get('shebangs', []) if i.version and i.version.minor) for v in versions: if v in supported_versions: self.depend(vtpl_ma % v) else: log.info('dependency on %s (from shebang) ignored' ' - it\'s not supported anymore', vtpl % v) # /usr/bin/python{,3} shebang → add python{,3} to Depends if any(True for i in details.get('shebangs', []) if i.version is None or i.version.minor is None): self.depend(tpl_ma) extensions = False if self.python_dev_in_bd: extensions = sorted(details.get('ext_vers', set())) #self.depend('|'.join(vtpl % i for i in extensions)) if extensions: self.depend("%s (>= %s~)" % (tpl, extensions[0])) self.depend("%s (<< %s)" % (tpl, extensions[-1] + 1)) elif details.get('ext_no_version'): # assume unrecognized extension was built for default interpreter version self.depend("%s (>= %s~)" % (tpl, default_version)) self.depend("%s (<< %s)" % (tpl, default_version + 1)) if details.get('compile'): if self.impl in MINPYCDEP: self.depend(MINPYCDEP[self.impl]) args = '' if extensions: args += "-V %s" % VersionRange(minver=extensions[0], maxver=extensions[-1]) elif len(versions) == 1: # only one version from shebang #if versions[0] in supported_versions: args += "-V %s" % versions[0] # ... otherwise compile with default version elif details.get('ext_no_version'): # assume unrecognized extension was built for default interpreter version args += "-V %s" % default_version elif vrange: args += "-V %s" % vrange if vrange.minver == vrange.maxver: self.depend(vtpl % vrange.minver) else: if vrange.minver: # minimum version specified self.depend("%s (>= %s~)" % (tpl_ma, vrange.minver)) if vrange.maxver: # maximum version specified self.depend("%s (<< %s)" % (tpl_ma, vrange.maxver + 1)) for regex in options.regexpr or []: args += " -X '%s'" % regex.pattern.replace("'", r"'\''") self.rtscript((private_dir, args)) section_options = { 'depends_sec': options.depends_section, 'recommends_sec': options.recommends_section, 'suggests_sec': options.suggests_section, } guess_deps = partial(guess_dependency, impl=self.impl, bdep=self.bdep, accept_upstream_versions=options.accept_upstream_versions) if options.guess_deps: for fn in stats['requires.txt']: # TODO: should options.recommends and options.suggests be # removed from requires.txt? deps = parse_pydep(self.impl, fn, bdep=self.bdep, **section_options) [self.depend(i) for i in deps['depends']] [self.recommend(i) for i in deps['recommends']] [self.suggest(i) for i in deps['suggests']] for fpath in stats['egg-info']: with open(fpath, 'r', encoding='utf-8') as fp: for line in fp: if line.startswith('Requires: '): req = line[10:].strip() self.depend(guess_deps(req=req)) for fpath in stats['dist-info']: deps = parse_requires_dist(self.impl, fpath, bdep=self.bdep, **section_options) [self.depend(i) for i in deps['depends']] [self.recommend(i) for i in deps['recommends']] [self.suggest(i) for i in deps['suggests']] # add dependencies from --depends for item in options.depends or []: self.depend(guess_deps(req=item)) # add dependencies from --recommends for item in options.recommends or []: self.recommend(guess_deps(req=item)) # add dependencies from --suggests for item in options.suggests or []: self.suggest(guess_deps(req=item)) # add dependencies from --requires for fn in options.requires or []: fpath = join('debian', self.package, fn) if not exists(fpath): fpath = fn if not exists(fpath): log.warn('cannot find requirements file: %s', fn) continue deps = parse_pydep(self.impl, fpath, bdep=self.bdep, **section_options) [self.depend(i) for i in deps['depends']] [self.recommend(i) for i in deps['recommends']] [self.suggest(i) for i in deps['suggests']] log.debug(self)