Example #1
0
 def test_pypy(self):
     sorted(Interpreter.parse('pypy').items()) == \
         [('debug', None), ('name', 'pypy'), ('options', ()), ('path', ''), ('version', None)]
     sorted(Interpreter.parse('#! /usr/bin/pypy --foo').items()) == \
         [('debug', None), ('name', 'pypy'), ('options', ('--foo',)), ('path', '/usr/bin/'), ('version', None)]
     Interpreter('pypy').sitedir(
         version='2.0') == '/usr/lib/pypy/dist-packages/'
Example #2
0
 def test_python34(self):
     i = Interpreter('python3.4')
     self.assertEqual(i.soabi(), 'cpython-34m')
     self.assertEqual(i.check_extname('foo.so'), r'foo.cpython-34m-MYARCH.so')
     self.assertIsNone(i.check_extname('foo.cpython-32m.so'))  # different version
     self.assertIsNone(i.check_extname('foo.cpython-34m-OTHER.so'))  # different architecture
     self.assertEqual(i.check_extname('foo.cpython-34m.so'), r'foo.cpython-34m-MYARCH.so')
     self.assertIsNone(i.check_extname('foo.abi3.so'))
     self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), r'foo/bar/baz.cpython-34m-MYARCH.so')
Example #3
0
 def test_python27dbg(self):
     i = Interpreter('python2.7-dbg')
     self.assertEqual(i.soabi(), '')
     self.assertEqual(i.check_extname('foo.so'), 'foo.MYARCH_d.so')
     self.assertEqual(i.check_extname('foo_d.so'), 'foo.MYARCH_d.so')
     self.assertIsNone(i.check_extname('foo.MYARCH_d.so'))
     self.assertIsNone(
         i.check_extname('foo.OTHER_d.so'))  # different architecture
     self.assertEqual(i.check_extname('foo/bar/bazmodule.so'),
                      'foo/bar/baz.MYARCH_d.so')
Example #4
0
def fix_locations(package, interpreter, versions, options):
    """Move files to the right location."""
    # make a copy since we change version later
    interpreter = Interpreter(interpreter)

    for version in versions:
        interpreter.version = version

        dstdir = interpreter.sitedir(package)
        for srcdir in interpreter.old_sitedirs(package):
            if isdir(srcdir):
                # TODO: what about relative symlinks?
                log.debug('moving files from %s to %s', srcdir, dstdir)
                share_files(srcdir, dstdir, interpreter, options)
                try:
                    os.removedirs(srcdir)
                except OSError:
                    pass

        # do the same with debug locations
        dstdir = interpreter.sitedir(package, gdb=True)
        for srcdir in interpreter.old_sitedirs(package, gdb=True):
            if isdir(srcdir):
                log.debug('moving files from %s to %s', srcdir, dstdir)
                share_files(srcdir, dstdir, interpreter, options)
                try:
                    os.removedirs(srcdir)
                except OSError:
                    pass
Example #5
0
 def test_python36(self):
     i = Interpreter('python3.6')
     self.assertEqual(i.soabi(), 'cpython-36m')
     self.assertEqual(i.check_extname('foo.so'),
                      r'foo.cpython-36m-MYARCH.so')
     self.assertIsNone(
         i.check_extname('foo.cpython-32m.so'))  # different version
     self.assertIsNone(i.check_extname(
         'foo.cpython-36m-OTHER.so'))  # different architecture
     self.assertEqual(i.check_extname('foo.cpython-36m.so'),
                      r'foo.cpython-36m-MYARCH.so')
     self.assertIsNone(i.check_extname('foo.abi3.so'))
     self.assertEqual(i.check_extname('foo/bar/bazmodule.so'),
                      r'foo/bar/baz.cpython-36m-MYARCH.so')
Example #6
0
def fix_locations(package, interpreter, versions, options):
    """Move files to the right location."""
    # make a copy since we change version later
    interpreter = Interpreter(interpreter)

    for version in versions:
        interpreter.version = version

        dstdir = interpreter.sitedir(package)
        for srcdir in interpreter.old_sitedirs(package):
            if isdir(srcdir):
                # TODO: what about relative symlinks?
                log.debug('moving files from %s to %s', srcdir, dstdir)
                share_files(srcdir, dstdir, interpreter, options)
                parent_dir = '/'.join(srcdir.split('/')[:-1])
                while parent_dir:
                    if exists(parent_dir):
                        if os.listdir(parent_dir):
                            break
                        os.rmdir(parent_dir)
                    parent_dir = dirname(parent_dir)

        # do the same with debug locations
        dstdir = interpreter.sitedir(package, gdb=True)
        for srcdir in interpreter.old_sitedirs(package, gdb=True):
            if isdir(srcdir):
                log.debug('moving files from %s to %s', srcdir, dstdir)
                share_files(srcdir, dstdir, interpreter, options)
                parent_dir = '/'.join(srcdir.split('/')[:-1])
                while parent_dir:
                    if exists(parent_dir):
                        if os.listdir(parent_dir):
                            break
                        os.rmdir(parent_dir)
                    parent_dir = dirname(parent_dir)
Example #7
0
 def test_python32dbg(self):
     i = Interpreter('python3.2-dbg')
     self.assertEqual(i.soabi(), 'cpython-32dmu')
     self.assertEqual(i.check_extname('foo.so'), r'foo.cpython-32dmu.so')
     self.assertIsNone(
         i.check_extname('foo.cpython-33m.so'))  # different version
     self.assertIsNone(i.check_extname(
         'foo.cpython-32dmu-OTHER.so'))  # different architecture
     self.assertIsNone(i.check_extname('foo.abi3.so'))
     self.assertEqual(i.check_extname('foo/bar/bazmodule.so'),
                      r'foo/bar/bazmodule.cpython-32dmu.so')
Example #8
0
def get_requested_versions(impl, vrange=None, available=None):
    """Return a set of requested and supported Python versions.

    :param impl: interpreter implementation
    :param available: if set to `True`, return installed versions only,
        if set to `False`, return requested versions that are not installed.
        By default returns all requested versions.
    :type available: bool

    >>> sorted(get_requested_versions('cpython3', '')) == sorted(supported('cpython3'))
    True
    >>> sorted(get_requested_versions('cpython3', '-')) == sorted(supported('cpython3'))
    True
    >>> get_requested_versions('cpython3', '>= 5.0')
    set()
    """
    if isinstance(vrange, str):
        vrange = VersionRange(vrange)

    if not vrange:
        versions = set(supported(impl))
    else:
        minv = Version(major=0, minor=0) if vrange.minver is None else vrange.minver
        maxv = Version(major=99, minor=99) if vrange.maxver is None else vrange.maxver
        if minv == maxv:
            versions = set([minv] if minv in supported(impl) else tuple())
        else:
            versions = set(v for v in supported(impl) if minv <= v < maxv)

    if available is not None:
        # to avoid circular imports
        global Interpreter
        if Interpreter is None:
            from dhpython.interpreter import Interpreter
    if available:
        interpreter = Interpreter(impl=impl)
        versions = set(v for v in versions
                       if exists(interpreter.binary(v)))
    elif available is False:
        interpreter = Interpreter(impl=impl)
        versions = set(v for v in versions
                       if not exists(interpreter.binary(v)))

    return versions
Example #9
0
 def test_python27dbg(self):
     i = Interpreter('python2.7-dbg')
     self.assertEqual(i.soabi(), '')
     self.assertEqual(i.check_extname('foo.so'), 'foo.MYARCH_d.so')
     self.assertEqual(i.check_extname('foo_d.so'), 'foo.MYARCH_d.so')
     self.assertIsNone(i.check_extname('foo.MYARCH_d.so'))
     self.assertIsNone(i.check_extname('foo.OTHER_d.so'))  # different architecture
     self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), 'foo/bar/bazmodule.MYARCH_d.so')
Example #10
0
 def test_python32dbg(self):
     i = Interpreter('python3.2-dbg')
     self.assertEqual(i.soabi(), 'cpython-32dmu')
     self.assertEqual(i.check_extname('foo.so'), r'foo.cpython-32dmu.so')
     self.assertIsNone(i.check_extname('foo.cpython-33m.so'))  # different version
     self.assertIsNone(i.check_extname('foo.cpython-32dmu-OTHER.so'))  # different architecture
     self.assertIsNone(i.check_extname('foo.abi3.so'))
     self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), r'foo/bar/bazmodule.cpython-32dmu.so')
Example #11
0
 def handle_bin_dir(self, dpath, file_names):
     if self.options.no_shebang_rewrite or self.options.ignore_shebangs:
         return
     for fn in file_names:
         fpath = join(dpath, fn)
         if fix_shebang(fpath, self.options.shebang):
             try:
                 res = Interpreter.from_file(fpath)
             except Exception as e:
                 log.debug('cannot parse shebang %s: %s', fpath, e)
             else:
                 self.result['shebangs'].add(res)
Example #12
0
 def handle_bin_dir(self, dpath, file_names):
     if self.options.no_shebang_rewrite or self.options.ignore_shebangs:
         return
     for fn in file_names:
         fpath = join(dpath, fn)
         if fix_shebang(fpath, self.options.shebang):
             try:
                 res = Interpreter.from_file(fpath)
             except Exception as e:
                 log.debug('cannot parse shebang %s: %s', fpath, e)
             else:
                 self.result['shebangs'].add(res)
Example #13
0
 def test_python26dbg(self):
     i = Interpreter('python2.6-dbg')
     self.assertEqual(i.soabi(), '')
     self.assertIsNone(i.check_extname('foo_d.so'))
     self.assertEqual(i.check_extname('foo.so'), 'foo_d.so')
     self.assertEqual(i.check_extname('foo/bar/bazmodule.so'),
                      'foo/bar/bazmodule_d.so')
Example #14
0
def fix_locations(package, interpreter, versions, options):
    """Move files to the right location."""
    # make a copy since we change version later
    interpreter = Interpreter(interpreter)

    for version in versions:
        interpreter.version = version

        dstdir = interpreter.sitedir(package)
        for srcdir in interpreter.old_sitedirs(package):
            if isdir(srcdir):
                # TODO: what about relative symlinks?
                log.debug('moving files from %s to %s', srcdir, dstdir)
                share_files(srcdir, dstdir, interpreter, options)
                parent_dir = '/'.join(srcdir.split('/')[:-1])
                while parent_dir:
                    if exists(parent_dir):
                        if os.listdir(parent_dir):
                            break
                        os.rmdir(parent_dir)
                    parent_dir = dirname(parent_dir)

        # do the same with debug locations
        dstdir = interpreter.sitedir(package, gdb=True)
        for srcdir in interpreter.old_sitedirs(package, gdb=True):
            if isdir(srcdir):
                log.debug('moving files from %s to %s', srcdir, dstdir)
                share_files(srcdir, dstdir, interpreter, options)
                parent_dir = '/'.join(srcdir.split('/')[:-1])
                while parent_dir:
                    if exists(parent_dir):
                        if os.listdir(parent_dir):
                            break
                        os.rmdir(parent_dir)
                    parent_dir = dirname(parent_dir)
Example #15
0
def fix_locations(package, interpreter, versions, options):
    """Move files to the right location."""
    # make a copy since we change version later
    interpreter = Interpreter(interpreter)

    for version in versions:
        interpreter.version = version

        dstdir = interpreter.sitedir(package)
        for srcdir in interpreter.old_sitedirs(package):
            if isdir(srcdir):
                # TODO: what about relative symlinks?
                log.debug('moving files from %s to %s', srcdir, dstdir)
                share_files(srcdir, dstdir, interpreter, options)
                try:
                    os.removedirs(srcdir)
                except OSError:
                    pass

        # do the same with debug locations
        dstdir = interpreter.sitedir(package, gdb=True)
        for srcdir in interpreter.old_sitedirs(package, gdb=True):
            if isdir(srcdir):
                log.debug('moving files from %s to %s', srcdir, dstdir)
                share_files(srcdir, dstdir, interpreter, options)
                try:
                    os.removedirs(srcdir)
                except OSError:
                    pass
Example #16
0
def get_requested_versions(impl, vrange=None, available=None):
    """Return a set of requested and supported Python versions.

    :param impl: interpreter implementation
    :param available: if set to `True`, return installed versions only,
        if set to `False`, return requested versions that are not installed.
        By default returns all requested versions.
    :type available: bool

    >>> sorted(get_requested_versions('cpython3', '')) == sorted(supported('cpython3'))
    True
    >>> sorted(get_requested_versions('cpython3', '-')) == sorted(supported('cpython3'))
    True
    >>> get_requested_versions('cpython3', '>= 5.0')
    set()
    """
    if isinstance(vrange, str):
        vrange = VersionRange(vrange)

    if not vrange:
        versions = set(supported(impl))
    else:
        minv = Version(major=0,
                       minor=0) if vrange.minver is None else vrange.minver
        maxv = Version(major=99,
                       minor=99) if vrange.maxver is None else vrange.maxver
        if minv == maxv:
            versions = set([minv] if minv in supported(impl) else tuple())
        else:
            versions = set(v for v in supported(impl) if minv <= v < maxv)

    if available is not None:
        # to avoid circular imports
        global Interpreter
        if Interpreter is None:
            from dhpython.interpreter import Interpreter
    if available:
        interpreter = Interpreter(impl=impl)
        versions = set(v for v in versions if exists(interpreter.binary(v)))
    elif available is False:
        interpreter = Interpreter(impl=impl)
        versions = set(v for v in versions
                       if not exists(interpreter.binary(v)))

    return versions
Example #17
0
    def __init__(self, interpreter, package, dpath=None, options=None):
        self.interpreter = interpreter
        self.impl = interpreter.impl

        self.package = package

        if not dpath:
            self.proot = "debian/%s" % self.package
        else:
            dpath = dpath.strip('/')
            self.proot = join('debian', self.package, dpath)
        self.dpath = dpath
        del dpath

        self.options = options
        self.result = {'requires.txt': set(),
                       'egg-info': set(),
                       'nsp.txt': set(),
                       'shebangs': set(),
                       'public_vers': set(),
                       'private_dirs': {},
                       'compile': False,
                       'ext_vers': set(),
                       'ext_no_version': set()}

        for root, dirs, file_names in os.walk(self.proot):
            if interpreter.should_ignore(root):
                del dirs[:]
                continue

            self.current_private_dir = self.current_pub_version = None
            version = interpreter.parse_public_dir(root)
            if version:
                self.current_dir_is_public = True
                if version is True:
                    version = None
                else:
                    self.current_pub_version = version
            else:
                self.current_dir_is_public = False

            if self.current_dir_is_public:
                if root.endswith('-packages'):
                    if version is not None:
                        self.result['public_vers'].add(version)
                    for name in ('test', 'tests'):
                        if name in dirs:
                            log.debug('removing dist-packages/%s (too common name)', name)
                            rmtree(join(root, name))
                            dirs.remove(name)
            else:
                self.current_private_dir = self.check_private_dir(root)
                if not self.current_private_dir:
                    # i.e. not a public dir and not a private dir
                    is_bin_dir = self.is_bin_dir(root)
                    if is_bin_dir:
                        self.handle_bin_dir(root, file_names)
                    else:  # not a public, private or bin directory
                        # continue with a subdirectory
                        continue

            for name in dirs:
                dpath = join(root, name)
                if self.is_unwanted_dir(dpath):
                    rmtree(dpath)
                    dirs.remove(name)
                    continue

            if self.is_egg_dir(root):
                self.handle_egg_dir(root, file_names)
                continue

            # check files
            for fn in sorted(file_names):
                # sorted() to make sure .so files are handled before .so.foo
                fpath = join(root, fn)

                if self.is_unwanted_file(fpath):
                    log.debug('removing unwanted: %s', fpath)
                    os.remove(fpath)
                    continue

                if self.is_egg_file(fpath):
                    self.handle_egg_file(fpath)
                    continue

                if not exists(fpath):
                    # possibly removed while handling .so symlinks
                    if islink(fpath) and '.so.' in split(fpath)[-1]:
                        # dangling symlink to (now removed/renamed) .so file
                        # which wasn't removed yet (see test203's quux.so.0)
                        log.info('removing dangling symlink: %s', fpath)
                        os.remove(fpath)
                    continue

                fext = splitext(fn)[-1][1:]
                if fext == 'so':
                    if not self.options.no_ext_rename:
                        fpath = self.rename_ext(fpath)
                    ver = self.handle_ext(fpath)
                    ver = ver or version
                    if ver:
                        self.current_result.setdefault('ext_vers', set()).add(ver)
                    else:
                        self.current_result.setdefault('ext_no_version', set()).add(fpath)

                if self.current_private_dir:
                    if exists(fpath) and fext != 'so':
                        mode = os.stat(fpath)[ST_MODE]
                        if mode & S_IXUSR or mode & S_IXGRP or mode & S_IXOTH:
                            if (options.no_shebang_rewrite or
                                fix_shebang(fpath, self.options.shebang)) and \
                                    not self.options.ignore_shebangs:
                                try:
                                    res = Interpreter.from_file(fpath)
                                except Exception as e:
                                    log.debug('cannot parse shebang %s: %s', fpath, e)
                                else:
                                    self.current_result.setdefault('shebangs', set()).add(res)

                if fext == 'py' and self.handle_public_module(fpath) is not False:
                    self.current_result['compile'] = True

            if not dirs:
                # try to remove directory if it's empty (and its parent if it's empty afterwards)
                while root:
                    try:
                        os.rmdir(root)
                        log.debug('removing empty directory: %s', root)
                    except Exception:
                        break
                    root = root.rsplit('/', 1)[0]

                    if not root.startswith(self.proot):
                        break

        log.debug("package %s details = %s", package, self.result)
Example #18
0
 def test_version(self):
     i = Interpreter(impl='cpython2')
     self.assertEqual(str(i), 'python')
     self.assertEqual(i.binary('2.7'), '/usr/bin/python2.7')
Example #19
0
 def test_python31dbg(self):
     i = Interpreter('python3.1-dbg')
     self.assertEqual(i.soabi(), '')
     self.assertIsNone(i.check_extname('foo.so'))
     self.assertIsNone(i.check_extname('foo.abi3.so'))
     self.assertIsNone(i.check_extname('foo/bar/bazmodule.so'))
Example #20
0
 def test_python31dbg(self):
     i = Interpreter('python3.1-dbg')
     self.assertEqual(i.soabi(), '')
     self.assertIsNone(i.check_extname('foo.so'))
     self.assertIsNone(i.check_extname('foo.abi3.so'))
     self.assertIsNone(i.check_extname('foo/bar/bazmodule.so'))
Example #21
0
 def test_python26dbg(self):
     i = Interpreter('python2.6-dbg')
     self.assertEqual(i.soabi(), '')
     self.assertIsNone(i.check_extname('foo_d.so'))
     self.assertEqual(i.check_extname('foo.so'), 'foo_d.so')
     self.assertEqual(i.check_extname('foo/bar/bazmodule.so'), 'foo/bar/bazmodule_d.so')
Example #22
0
 def test_pypy(self):
     sorted(Interpreter.parse('pypy').items()) == \
         [('debug', None), ('name', 'pypy'), ('options', ()), ('path', ''), ('version', None)]
     sorted(Interpreter.parse('#! /usr/bin/pypy --foo').items()) == \
         [('debug', None), ('name', 'pypy'), ('options', ('--foo',)), ('path', '/usr/bin/'), ('version', None)]
     Interpreter('pypy').sitedir(version='2.0') == '/usr/lib/pypy/dist-packages/'
Example #23
0
 def test_version(self):
     i = Interpreter(impl='cpython2')
     self.assertEqual(str(i), 'python')
     self.assertEqual(i.binary('2.7'), '/usr/bin/python2.7')
Example #24
0
    def __init__(self, interpreter, package, dpath=None, options=None):
        self.interpreter = interpreter
        self.impl = interpreter.impl

        self.package = package

        if not dpath:
            self.proot = "debian/%s" % self.package
        else:
            dpath = dpath.strip('/')
            self.proot = join('debian', self.package, dpath)
        self.dpath = dpath
        del dpath

        self.options = options
        self.result = {
            'requires.txt': set(),
            'nsp.txt': set(),
            'shebangs': set(),
            'public_vers': set(),
            'private_dirs': {},
            'compile': False,
            'ext_vers': set(),
            'ext_no_version': set()
        }

        for root, dirs, file_names in os.walk(self.proot):
            if interpreter.should_ignore(root):
                del dirs[:]
                continue

            self.current_private_dir = None
            self.current_pub_version = version = interpreter.parse_public_version(
                root)
            if self.current_pub_version:  # i.e. a public site-packages directory
                if root.endswith('-packages'):
                    self.result['public_vers'].add(version)
            else:
                self.current_private_dir = self.check_private_dir(root)
                if not self.current_private_dir:
                    # i.e. not a public dir and not a private dir
                    is_bin_dir = self.is_bin_dir(root)
                    if is_bin_dir:
                        self.handle_bin_dir(root, file_names)
                    else:  # not a public, private or bin directory
                        # continue with a subdirectory
                        continue

            for name in dirs:
                dpath = join(root, name)
                if self.is_unwanted_dir(dpath):
                    rmtree(dpath)
                    dirs.remove(name)
                    continue

            if self.is_egg_dir(root):
                self.handle_egg_dir(root, file_names)
                continue

            # check files
            for fn in sorted(file_names):
                # sorted() to make sure .so files are handled before .so.foo
                fpath = join(root, fn)

                if self.is_unwanted_file(fpath):
                    log.debug('removing unwanted: %s', fpath)
                    os.remove(fpath)
                    continue

                if self.is_egg_file(fpath):
                    self.handle_egg_file(fpath)
                    continue

                if not exists(fpath):
                    # possibly removed while handling .so symlinks
                    if islink(fpath) and '.so.' in split(fpath)[-1]:
                        # dangling symlink to (now removed/renamed) .so file
                        # which wasn't removed yet (see test203's quux.so.0)
                        log.info('removing dangling symlink: %s', fpath)
                        os.remove(fpath)
                    continue

                fext = splitext(fn)[-1][1:]
                if fext == 'so':
                    if not self.options.no_ext_rename:
                        fpath = self.rename_ext(fpath)
                    ver = self.handle_ext(fpath)
                    ver = ver or version
                    if ver:
                        self.current_result.setdefault('ext_vers',
                                                       set()).add(ver)
                    else:
                        self.current_result.setdefault('ext_no_version',
                                                       set()).add(fpath)

                if self.current_private_dir:
                    if exists(fpath) and fext != 'so':
                        mode = os.stat(fpath)[ST_MODE]
                        if mode & S_IXUSR or mode & S_IXGRP or mode & S_IXOTH:
                            if (options.no_shebang_rewrite or
                                fix_shebang(fpath, self.options.shebang)) and \
                                    not self.options.ignore_shebangs:
                                try:
                                    res = Interpreter.from_file(fpath)
                                except Exception as e:
                                    log.debug('cannot parse shebang %s: %s',
                                              fpath, e)
                                else:
                                    self.current_result.setdefault(
                                        'shebangs', set()).add(res)

                if fext == 'py' and self.handle_public_module(
                        fpath) is not False:
                    self.current_result['compile'] = True

        log.debug("package %s details = %s", package, self.result)