Esempio n. 1
0
    def run(self):
        prev_syspath = sys.path[:]
        try:
            # build release
            build = self.reinitialize_command('build')
            self.run_command('build')
            sys.path.insert(0, build.build_lib)

            # XXX maybe we could pass the verbose argument of pysetup here
            logger = logging.getLogger('packaging')
            verbose = logger.getEffectiveLevel() >= logging.DEBUG
            verbosity = verbose + 1

            # run the tests
            if self.runner:
                resolve_name(self.runner)()
            elif self.suite:
                runner = unittest.TextTestRunner(verbosity=verbosity)
                runner.run(resolve_name(self.suite)())
            elif self.get_ut_with_discovery():
                ut = self.get_ut_with_discovery()
                test_suite = ut.TestLoader().discover(os.curdir)
                runner = ut.TextTestRunner(verbosity=verbosity)
                runner.run(test_suite)
        finally:
            sys.path[:] = prev_syspath
Esempio n. 2
0
 def check_hooks_resolvable(self):
     for options in self.distribution.command_options.values():
         for hook_kind in ("pre_hook", "post_hook"):
             if hook_kind not in options:
                 break
             for hook_name in options[hook_kind][1].values():
                 try:
                     resolve_name(hook_name)
                 except ImportError:
                     self.warn('name %r cannot be resolved', hook_name)
Esempio n. 3
0
def new_compiler(plat=None, compiler=None, dry_run=False, force=False):
    """Generate an instance of some CCompiler subclass for the supplied
    platform/compiler combination.  'plat' defaults to 'os.name'
    (eg. 'posix', 'nt'), and 'compiler' defaults to the default compiler
    for that platform.  Currently only 'posix' and 'nt' are supported, and
    the default compilers are "traditional Unix interface" (UnixCCompiler
    class) and Visual C++ (MSVCCompiler class).  Note that it's perfectly
    possible to ask for a Unix compiler object under Windows, and a
    Microsoft compiler object under Unix -- if you supply a value for
    'compiler', 'plat' is ignored.
    """
    if plat is None:
        plat = os.name

    try:
        if compiler is None:
            compiler = get_default_compiler(plat)

        cls = _COMPILERS[compiler]
    except KeyError:
        msg = "don't know how to compile C/C++ code on platform '%s'" % plat
        if compiler is not None:
            msg = msg + " with '%s' compiler" % compiler
        raise PackagingPlatformError(msg)

    if isinstance(cls, str):
        cls = resolve_name(cls)
        _COMPILERS[compiler] = cls

    return cls(dry_run, force)
Esempio n. 4
0
    def run_command_hooks(self, cmd_obj, hook_kind):
        """Run hooks registered for that command and phase.

        *cmd_obj* is a finalized command object; *hook_kind* is either
        'pre_hook' or 'post_hook'.
        """
        if hook_kind not in ('pre_hook', 'post_hook'):
            raise ValueError('invalid hook kind: %r' % hook_kind)

        hooks = getattr(cmd_obj, hook_kind, None)

        if hooks is None:
            return

        for hook in hooks.values():
            if isinstance(hook, str):
                try:
                    hook_obj = resolve_name(hook)
                except ImportError as e:
                    raise PackagingModuleError(e)
            else:
                hook_obj = hook

            if not callable(hook_obj):
                raise PackagingOptionError('hook %r is not callable' % hook)

            logger.info('running %s %s for command %s',
                        hook_kind, hook, cmd_obj.get_command_name())
            hook_obj(cmd_obj)
Esempio n. 5
0
def use_command(testcase, fullname):
    """Register command at *fullname* for the duration of a test."""
    set_command(fullname)
    # XXX maybe set_command should return the class object
    name = resolve_name(fullname).get_command_name()
    # XXX maybe we need a public API to remove commands
    testcase.addCleanup(_COMMANDS.__delitem__, name)
Esempio n. 6
0
def get_command_class(name):
    """Return the registered command"""
    try:
        cls = _COMMANDS[name]
    except KeyError:
        raise PackagingModuleError("Invalid command %s" % name)
    if isinstance(cls, str):
        cls = resolve_name(cls)
        _COMMANDS[name] = cls
    return cls
Esempio n. 7
0
def show_compilers():
    """Print list of available compilers (used by the "--help-compiler"
    options to "build", "build_ext", "build_clib").
    """
    from packaging.fancy_getopt import FancyGetopt
    compilers = []

    for name, cls in _COMPILERS.items():
        if isinstance(cls, str):
            cls = resolve_name(cls)
            _COMPILERS[name] = cls

        compilers.append(("compiler=" + name, None, cls.description))

    compilers.sort()
    pretty_printer = FancyGetopt(compilers)
    pretty_printer.print_help("List of available compilers:")
Esempio n. 8
0
    def finalize_options(self):
        if self.manifest is None:
            self.manifest = "MANIFEST"

        self.ensure_string_list('formats')
        if self.formats is None:
            try:
                self.formats = [self.default_format[os.name]]
            except KeyError:
                raise PackagingPlatformError("don't know how to create source "
                       "distributions on platform %s" % os.name)

        bad_format = self._check_archive_formats(self.formats)
        if bad_format:
            raise PackagingOptionError("unknown archive format '%s'" \
                        % bad_format)

        if self.dist_dir is None:
            self.dist_dir = "dist"

        if self.filelist is None:
            self.filelist = Manifest()

        if self.manifest_builders is None:
            self.manifest_builders = []
        else:
            if isinstance(self.manifest_builders, str):
                self.manifest_builders = self.manifest_builders.split(',')
            builders = []
            for builder in self.manifest_builders:
                builder = builder.strip()
                if builder == '':
                    continue
                try:
                    builder = resolve_name(builder)
                except ImportError as e:
                    raise PackagingModuleError(e)

                builders.append(builder)

            self.manifest_builders = builders
Esempio n. 9
0
def set_command(location):
    cls = resolve_name(location)
    # XXX we want to do the duck-type checking here
    _COMMANDS[cls.get_command_name()] = cls
Esempio n. 10
0
    def _read_setup_cfg(self, parser, cfg_filename):
        cfg_directory = os.path.dirname(os.path.abspath(cfg_filename))
        content = {}
        for section in parser.sections():
            content[section] = dict(parser.items(section))

        # global setup hooks are called first
        if 'global' in content:
            if 'setup_hooks' in content['global']:
                setup_hooks = split_multiline(content['global']['setup_hooks'])

                # add project directory to sys.path, to allow hooks to be
                # distributed with the project
                sys.path.insert(0, cfg_directory)
                try:
                    for line in setup_hooks:
                        try:
                            hook = resolve_name(line)
                        except ImportError as e:
                            logger.warning('cannot find setup hook: %s',
                                           e.args[0])
                        else:
                            self.setup_hooks.append(hook)
                    self.run_hooks(content)
                finally:
                    sys.path.pop(0)

        metadata = self.dist.metadata

        # setting the metadata values
        if 'metadata' in content:
            for key, value in content['metadata'].items():
                key = key.replace('_', '-')
                if metadata.is_multi_field(key):
                    value = split_multiline(value)

                if key == 'project-url':
                    value = [(label.strip(), url.strip())
                             for label, url in
                             [v.split(',') for v in value]]

                if key == 'description-file':
                    if 'description' in content['metadata']:
                        msg = ("description and description-file' are "
                               "mutually exclusive")
                        raise PackagingOptionError(msg)

                    filenames = value.split()

                    # concatenate all files
                    value = []
                    for filename in filenames:
                        # will raise if file not found
                        with open(filename) as description_file:
                            value.append(description_file.read().strip())
                        # add filename as a required file
                        if filename not in metadata.requires_files:
                            metadata.requires_files.append(filename)
                    value = '\n'.join(value).strip()
                    key = 'description'

                if metadata.is_metadata_field(key):
                    metadata[key] = self._convert_metadata(key, value)

        if 'files' in content:
            files = content['files']
            self.dist.package_dir = files.pop('packages_root', None)

            files = dict((key, split_multiline(value)) for key, value in
                         files.items())

            self.dist.packages = []

            packages = files.get('packages', [])
            if isinstance(packages, str):
                packages = [packages]

            for package in packages:
                if ':' in package:
                    dir_, package = package.split(':')
                    self.dist.package_dir[package] = dir_
                self.dist.packages.append(package)

            self.dist.py_modules = files.get('modules', [])
            if isinstance(self.dist.py_modules, str):
                self.dist.py_modules = [self.dist.py_modules]
            self.dist.scripts = files.get('scripts', [])
            if isinstance(self.dist.scripts, str):
                self.dist.scripts = [self.dist.scripts]

            self.dist.package_data = {}
            # bookkeeping for the loop below
            firstline = True
            prev = None

            for line in files.get('package_data', []):
                if '=' in line:
                    # package name -- file globs or specs
                    key, value = line.split('=')
                    prev = self.dist.package_data[key.strip()] = value.split()
                elif firstline:
                    # invalid continuation on the first line
                    raise PackagingOptionError(
                        'malformed package_data first line: %r (misses "=")' %
                        line)
                else:
                    # continuation, add to last seen package name
                    prev.extend(line.split())

                firstline = False

            self.dist.data_files = []
            for data in files.get('data_files', []):
                data = data.split('=')
                if len(data) != 2:
                    continue
                key, value = data
                values = [v.strip() for v in value.split(',')]
                self.dist.data_files.append((key, values))

            # manifest template
            self.dist.extra_files = files.get('extra_files', [])

            resources = []
            for rule in files.get('resources', []):
                glob, destination = rule.split('=', 1)
                rich_glob = glob.strip().split(' ', 1)
                if len(rich_glob) == 2:
                    prefix, suffix = rich_glob
                else:
                    assert len(rich_glob) == 1
                    prefix = ''
                    suffix = glob
                if destination == '<exclude>':
                    destination = None
                resources.append(
                    (prefix.strip(), suffix.strip(), destination.strip()))
                self.dist.data_files = get_resources_dests(
                    cfg_directory, resources)

        ext_modules = self.dist.ext_modules
        for section_key in content:
            # no str.partition in 2.4 :(
            labels = section_key.split(':')
            if len(labels) == 2 and labels[0] == 'extension':
                values_dct = content[section_key]
                if 'name' in values_dct:
                    raise PackagingOptionError(
                        'extension name should be given as [extension: name], '
                        'not as key')
                name = labels[1].strip()
                _check_name(name, self.dist.packages)
                ext_modules.append(Extension(
                    name,
                    _pop_values(values_dct, 'sources'),
                    _pop_values(values_dct, 'include_dirs'),
                    _pop_values(values_dct, 'define_macros'),
                    _pop_values(values_dct, 'undef_macros'),
                    _pop_values(values_dct, 'library_dirs'),
                    _pop_values(values_dct, 'libraries'),
                    _pop_values(values_dct, 'runtime_library_dirs'),
                    _pop_values(values_dct, 'extra_objects'),
                    _pop_values(values_dct, 'extra_compile_args'),
                    _pop_values(values_dct, 'extra_link_args'),
                    _pop_values(values_dct, 'export_symbols'),
                    _pop_values(values_dct, 'swig_opts'),
                    _pop_values(values_dct, 'depends'),
                    values_dct.pop('language', None),
                    values_dct.pop('optional', None),
                    **values_dct))
Esempio n. 11
0
def set_compiler(location):
    """Add or change a compiler"""
    cls = resolve_name(location)
    # XXX we want to check the class here
    _COMPILERS[cls.name] = cls