Esempio n. 1
0
def trace_requirements(requirements):
    """given an iterable of pip InstallRequirements,
    return the set of required packages, given their transitive requirements.
    """
    requirements = tuple(pretty_req(r) for r in requirements)
    working_set = fresh_working_set()

    # breadth-first traversal:
    from collections import deque
    queue = deque(requirements)
    seen = set()
    errors = []
    result = []
    while queue:
        req = queue.popleft()
        req_id = str(
            req
        )  # InstallRequirement doesn't implement hash/equality, so we compare using str()
        if req_id in seen:
            logger.debug('already analyzed: %s', req)
            continue
        else:
            seen.add(req_id)

        logger.debug('tracing: %s', req)
        if req_cycle(req):
            logger.warn('Circular dependency! %s', req)
            continue

        try:
            dist = working_set.find(req.req)
        except pkg_resources.VersionConflict as conflict:
            dist = conflict.args[0]
            errors.append('Error: version conflict: %s (%s) <-> %s' %
                          (dist, timid_relpath(dist.location), req))

        if dist is None:
            errors.append('Error: unmet dependency: %s' % req)
            continue

        result.append(dist_to_req(dist))

        for dist_req in sorted(dist.requires(), key=lambda req: req.key):
            from pip.req import InstallRequirement
            dist_req = InstallRequirement(dist_req, req)

            logger.debug('adding sub-requirement %s', dist_req)
            queue.append(dist_req)

    if errors:
        raise InstallationError('\n'.join(errors))

    return result
Esempio n. 2
0
def trace_requirements(requirements):
    """given an iterable of pip InstallRequirements,
    return the set of required packages, given their transitive requirements.
    """
    requirements = tuple(pretty_req(r) for r in requirements)
    working_set = fresh_working_set()

    # breadth-first traversal:
    from collections import deque
    queue = deque(requirements)
    seen = set()
    errors = []
    result = []
    while queue:
        req = queue.popleft()
        req_id = str(req)  # InstallRequirement doesn't implement hash/equality, so we compare using str()
        if req_id in seen:
            logger.debug('already analyzed: %s', req)
            continue
        else:
            seen.add(req_id)

        logger.debug('tracing: %s', req)
        if req_cycle(req):
            logger.warn('Circular dependency! %s', req)
            continue

        try:
            dist = working_set.find(req.req)
        except pkg_resources.VersionConflict as conflict:
            dist = conflict.args[0]
            errors.append('Error: version conflict: %s (%s) <-> %s' % (
                dist, timid_relpath(dist.location), req
            ))

        if dist is None:
            errors.append('Error: unmet dependency: %s' % req)
            continue

        result.append(dist_to_req(dist))

        for dist_req in sorted(dist.requires(), key=lambda req: req.key):
            from pip.req import InstallRequirement
            dist_req = InstallRequirement(dist_req, req)

            logger.debug('adding sub-requirement %s', dist_req)
            queue.append(dist_req)

    if errors:
        raise InstallationError('\n'.join(errors))

    return result
Esempio n. 3
0
def trace_requirements(requirements):
    """given an iterable of pip InstallRequirements,
    return the set of required packages, given their transitive requirements.
    """
    requirements = tuple(pretty_req(r) for r in requirements)
    working_set = fresh_working_set()

    # breadth-first traversal:
    from collections import deque
    queue = deque(requirements)
    queued = {_package_req_to_pkg_resources_req(req.req) for req in queue}
    errors = []
    result = []
    while queue:
        req = queue.popleft()

        logger.debug('tracing: %s', req)
        try:
            dist = working_set.find_normalized(
                _package_req_to_pkg_resources_req(req.req))
        except pkg_resources.VersionConflict as conflict:
            dist = conflict.args[0]
            errors.append('Error: version conflict: {} ({}) <-> {}'.format(
                dist, timid_relpath(dist.location), req))

        assert dist is not None, 'Should be unreachable in pip8+'
        result.append(dist_to_req(dist))

        # TODO: pip does no validation of extras. should we?
        extras = [extra for extra in req.extras if extra in dist.extras]
        for sub_req in sorted(dist.requires(extras=extras),
                              key=lambda req: req.key):
            sub_req = InstallRequirement(sub_req, req)

            if req_cycle(sub_req):
                logger.warning('Circular dependency! %s', sub_req)
                continue
            elif sub_req.req in queued:
                logger.debug('already queued: %s', sub_req)
                continue
            else:
                logger.debug('adding sub-requirement %s', sub_req)
                queue.append(sub_req)
                queued.add(sub_req.req)

    if errors:
        raise InstallationError('\n'.join(errors))

    return result
Esempio n. 4
0
def trace_requirements(requirements):
    """given an iterable of pip InstallRequirements,
    return the set of required packages, given their transitive requirements.
    """
    requirements = tuple(pretty_req(r) for r in requirements)
    working_set = fresh_working_set()

    # breadth-first traversal:
    from collections import deque
    queue = deque(requirements)
    queued = {_package_req_to_pkg_resources_req(req.req) for req in queue}
    errors = []
    result = []
    while queue:
        req = queue.popleft()

        logger.debug('tracing: %s', req)
        try:
            dist = working_set.find_normalized(_package_req_to_pkg_resources_req(req.req))
        except pkg_resources.VersionConflict as conflict:
            dist = conflict.args[0]
            errors.append('Error: version conflict: {} ({}) <-> {}'.format(
                dist, timid_relpath(dist.location), req
            ))

        assert dist is not None, 'Should be unreachable in pip8+'
        result.append(dist_to_req(dist))

        # TODO: pip does no validation of extras. should we?
        extras = [extra for extra in req.extras if extra in dist.extras]
        for sub_req in sorted(dist.requires(extras=extras), key=lambda req: req.key):
            sub_req = InstallRequirement(sub_req, req)

            if req_cycle(sub_req):
                logger.warning('Circular dependency! %s', sub_req)
                continue
            elif sub_req.req in queued:
                logger.debug('already queued: %s', sub_req)
                continue
            else:
                logger.debug('adding sub-requirement %s', sub_req)
                queue.append(sub_req)
                queued.add(sub_req.req)

    if errors:
        raise InstallationError('\n'.join(errors))

    return result