Esempio n. 1
0
def check(requirements_paths=[], metadata=[], projects=[]):
    """Return True if all of the specified dependencies have been ported to Python 3.

    The requirements_paths argument takes a sequence of file paths to
    requirements files. The 'metadata' argument takes a sequence of strings
    representing metadata. The 'projects' argument takes a sequence of project
    names.

    Any project that is not listed on PyPI will be considered ported.
    """
    dependencies = main.projects_from_requirements(requirements_paths)
    dependencies.extend(main.projects_from_metadata(metadata))
    dependencies.extend(projects)
    dependencies = set(name.lower() for name in dependencies)

    pypy_projects = pypi.all_pypy_projects()
    all_projects = pypi.all_projects()

    for dependency in dependencies:
        if dependency in all_projects and dependency not in pypy_projects:
            if not pypi.is_pure_python(dependency):
                return False
    return True
Esempio n. 2
0
def blocking_dependencies(projects, pypy_projects):
    """Starting from 'projects', find all projects which are blocking PyPy usage.

    Any project in 'pypy_projects' is considered ported and thus will not have
    its dependencies searched. Version requirements are also ignored as it is
    assumed that if a project is updating to support PyPy then they will be
    willing to update to the latest version of their dependencies. The only
    dependencies checked are those required to run the project.

    """
    log = logging.getLogger('ciu')
    check = []
    evaluated = set()
    for project in projects:
        log.info('Checking top-level project: {0} ...'.format(project))
        try:
            dist = distlib.locators.locate(project)
        except AttributeError:
            # This is a work around. //bitbucket.org/pypa/distlib/issue/59/ .
            log.warning('{0} found but had to be skipped.'.format(project))
            continue

        if not dist:
            log.warning('{0} not found'.format(project))
            continue

        project = dist.name.lower()  # PyPI can be forgiving about name formats.

        if project not in pypy_projects:
            check.append(project)

    reasons = LowerDict((project, None) for project in check if not pypi.is_pure_python(project))
    thread_pool_executor = concurrent.futures.ThreadPoolExecutor(
            max_workers=ciu.CPU_COUNT)

    with thread_pool_executor as executor:
        while len(check) > 0:
            new_check = []
            for parent, deps in zip(check, executor.map(dependencies, check)):
                if deps is None:
                    # Can't find any results for a project, so ignore it so as
                    # to not accidentally consider indefinitely that a project
                    # can't port.
                    del reasons[parent]
                    continue

                log.info('Dependencies of {0}: {1}'.format(project, deps))

                for dep in deps:
                    log.info('Checking dependency: {0} ...'.format(dep))
                    if dep in evaluated:
                        log.info('{0} already checked'.format(dep))
                        continue
                    else:
                        evaluated.add(dep)

                    if dep in pypy_projects:
                        continue

                    if not pypi.is_pure_python(dep):
                        reasons[dep] = parent

                    new_check.append(dep)
            check = new_check
    return reasons_to_paths(reasons)
Esempio n. 3
0
 def test_pure_python_with_no_wheels(self):
     self.assertFalse(pypi.is_pure_python('ipaddr'))
Esempio n. 4
0
 def test_is_not_pure_python(self):
     self.assertFalse(pypi.is_pure_python('cryptography'))
Esempio n. 5
0
 def test_is_pure_python(self):
     self.assertTrue(pypi.is_pure_python('urllib3'))