Example #1
0
def _get_python3_reqs(reqs):
    """Filters out the reqs that are less than our minimum version."""
    results = []
    for req in reqs:
        if not req.markers:
            results.append(req)
        else:
            req_markers = markers.Marker(req.markers)
            if req_markers.evaluate({
                    'python_version': MIN_PY_VERSION,
            }):
                results.append(req)
    return results
Example #2
0
def _find_constraint(req, constraints):
    """Return the constraint matching the markers for req.

    Given a requirement, find the constraint with matching markers.
    If none match, find a constraint without any markers at all.
    Otherwise return None.
    """
    if req.markers:
        req_markers = markers.Marker(req.markers)
        for constraint_setting, _ in constraints:
            if constraint_setting.markers == req.markers:
                return constraint_setting
            if not constraint_setting.markers:
                # There is no point in performing the complex
                # comparison for a constraint that has no markers, so
                # we skip it here. If we find no closer match then the
                # loop at the end of the function will look for a
                # constraint without a marker and use that.
                continue
            # NOTE(dhellmann): This is a very naive attempt to check
            # marker compatibility that relies on internal
            # implementation details of the packaging library.  The
            # best way to ensure the constraint and requirements match
            # is to use the same marker string in the corresponding
            # lines.
            c_markers = markers.Marker(constraint_setting.markers)
            env = {
                str(var): str(val)
                for var, op, val in c_markers._markers  # WARNING: internals
            }
            if req_markers.evaluate(env):
                return constraint_setting
    # Try looking for a constraint without any markers.
    for constraint_setting, _ in constraints:
        if not constraint_setting.markers:
            return constraint_setting
    return None
Example #3
0
def collect_extensions(parent='.') -> Iterator[WinExt]:
    """Collect all directories that contain a 'module.yml' recursively.

    The 'include' directory of each module is added by default to the include
    path, and 'include' directories from other extensions are added to the
    include path if they are listed in the 'modules'
    """

    # This is somewhat confusing, because the 'modules' key in the yaml
    # files specifies the dependencies for that module, the the 'modules'
    # variable contains the actual module configurations.
    modules = {}
    dependencies = {}
    build_order = ('.i', '.mc', '.rc', '.cpp')

    for dir in find_directories(parent):
        yml = os.path.join(parent, dir, 'module.yml')
        with open(yml) as fh:
            cfg = yaml.load(fh)

        if yml is None:
            raise ValueError('Invalid configuration file')

        name = dir.replace(os.sep, '.')
        modules[name] = cfg  # Module configuration
        dependencies[name] = set(cfg.setdefault('modules',
                                                []))  # Module dependencies

    external_modules = []
    for name in toposort_flatten(dependencies):
        src = os.path.join(parent, name.replace('.', os.sep), 'src')
        sources = []

        try:
            files = os.listdir(src)
        except FileNotFoundError:
            external_modules += [
                name
            ]  # Add this to external_modules for later generation
            continue

        for item in build_order:  # Add all sources present in the 'src' directory
            for fname in files:
                if fname.endswith(item):
                    sources.append(os.path.join(src, fname))

        include_dirs = []
        f = set()
        q = deque([name])
        i = 0

        # Simple dependency resolver algorithm:
        while q:
            i += 1
            assert i < 500  # To avoid infinite loop

            dep = q.popleft().replace('.', os.sep)  # Take one module
            include_dirs.extend([  # Add the include directories
                os.path.join(parent, dep, 'src'),
                os.path.join(parent, dep, 'include')
            ])
            f.add(dep.replace(os.sep,
                              '.'))  # Add the module's dependencies to the set
            q.extend([d for d in dependencies[name] if d not in f
                      ])  # Queue modules not already in the set for processing

        cfg = modules[name]
        del cfg['modules']  # Remove the 'modules' (depenencies) key

        # If the cfg has environment_markers, then parse it
        # NOTE: currently does not support removing dependencies
        if 'environment_markers' in cfg:
            marker = markers.Marker(cfg['environment_markers'])
            if not marker.evaluate():
                print('skipping: {} due to environment failure'.format(name))
                continue
            else:
                del cfg['environment_markers']

        if sys.version_info < (3, 5):
            cfg.setdefault('extra_link_args', []).append(get_link_arg())

        with suppress(KeyError):
            for i, depend in enumerate(cfg['depends']):
                cfg['depends'][i] = os.path.join(name, 'include', depend)

        for config_option in ['export_symbol_file', 'pch_header']:
            with suppress(KeyError):
                cfg[config_option] = os.path.join(
                    name.replace('.', os.sep), 'include', cfg[config_option])

        build_temp_library_dirs = set(
            [os.path.join(os.path.dirname(d), 'src') for d in include_dirs])

        cfg.setdefault('libraries', []).extend(
            set([
                get_implib_basename(os.path.dirname(d))
                for d in include_dirs[2:]
            ]))

        yield WinExt(
            name,
            sources=sources,
            include_dirs=copy(include_dirs),
            external_modules=copy(external_modules),
            build_temp_library_dirs=list(build_temp_library_dirs),
            **cfg)

        print('collected: {}'.format(name))
Example #4
0
 def marker(self):
     """Return environment marker."""
     if not self._marker:
         assert markers, 'Package packaging is needed for environment markers'
         self._marker = markers.Marker(self.raw)
     return self._marker