Beispiel #1
0
def build_wheel(target_directory: str, requirement: str) -> str:
    logger = StreamLogger(sys.stdout)
    requirement_parser = RequirementParser(logger=logger)
    package_directory = os.path.join(ROOT, "unittests", "data")
    escaped_requirement = shlex.quote(requirement)
    target_directory = os.path.abspath(target_directory)
    with tempfile.TemporaryDirectory() as build_directory:
        os.chdir(build_directory)
        nix = Nix(logger=logger)
        nix.shell(
            command=f"pip wheel {escaped_requirement} --find-links {package_directory} --no-deps",
            derivation_path=DERIVATION_PATH,
            nix_arguments=dict(),
        )
        try:
            parsed_requirement = requirement_parser.parse(requirement)
        except ParsingFailed:
            for path in os.listdir("."):
                if path.endswith(".whl"):
                    wheel_path = path
                    break
                else:
                    raise Exception("Build process did not produce .whl file")
        else:
            for path in os.listdir("."):
                if path.endswith(".whl") and parsed_requirement.name() in path:
                    wheel_path = path
                    break
                else:
                    raise Exception("Build process did not produce .whl file")

        target_file_name = os.path.basename(wheel_path)
        target_path = os.path.join(target_directory, target_file_name)
        shutil.move(wheel_path, target_path)
    return target_file_name
def test_can_understand_wheel_dependecies(
        current_platform: TargetPlatform,
        requirement_parser: RequirementParser):
    runtime_dependencies = RequirementSet(current_platform)
    runtime_dependency = requirement_parser.parse("runtime_dependency")
    runtime_dependencies.add(runtime_dependency)
    build_dependencies = RequirementSet(current_platform)
    build_dependency = requirement_parser.parse("build_dependency")
    build_dependencies.add(build_dependency)
    wheel = Wheel(
        name="testpackage",
        version="",
        deps=runtime_dependencies,
        target_platform=current_platform,
        license="",
        homepage="",
        description="",
        build_dependencies=build_dependencies,
    )
    requirement = requirement_parser.parse("testpackage")
    dependency_graph = DependencyGraph()
    dependency_graph.import_wheel(wheel, requirement_parser)

    assert dependency_graph.is_buildtime_dependency(requirement,
                                                    build_dependency)
    assert dependency_graph.is_runtime_dependency(requirement,
                                                  runtime_dependency)
 def check_dependency_graph(self, dependency_graph: DependencyGraph,
                            requirement_parser: RequirementParser):
     self.assertTrue(
         dependency_graph.is_runtime_dependency(
             requirement_parser.parse("django"),
             requirement_parser.parse("pytz"),
         ))
Beispiel #4
0
def test_that_to_line_reproduces_path_correctly(
        requirement_parser: RequirementParser):
    line = "path/to/requirement#egg=test-requirement"
    requirement = requirement_parser.parse(line)
    requirement = requirement_parser.parse(requirement.to_line())
    assert isinstance(requirement, UrlRequirement)
    assert requirement.url() == "file://path/to/requirement"
def test_that_requirement_parser_does_not_choke_on_sys_dot_platform(
        requirement_parser: RequirementParser, logger: Logger):
    line = 'macfsevents ; sys.platform == "darwin"'
    requirement = requirement_parser.parse(line)
    assert requirement.name() == "macfsevents"
    assert "WARNING" in get_logger_output(logger)
    assert "PEP 508" in get_logger_output(logger)
def test_can_parse_enum_requirement_from_issue_363(
    requirement_parser: RequirementParser,
):
    requirement = requirement_parser.parse(
        "enum34 (>=1.0.4) ; (python_version=='2.7' or python_version=='2.6' or python_version=='3.3')"
    )
    assert requirement.name() == "enum34"
def test_can_parse_pyinotify_requirement_from_issue_363(
    requirement_parser: RequirementParser,
):
    requirement = requirement_parser.parse(
        "pyinotify (>=0.9.6) ; (sys_platform!='win32' and sys_platform!='darwin' and sys_platform!='sunos5')"
    )
    assert requirement.name() == "pyinotify"
def test_pip_with_data_directory_index_can_download_six(
    pip_from_data_directory: VirtualenvPip,
    download_dir: str,
    requirement_parser: RequirementParser,
    current_platform: TargetPlatform,
) -> None:
    requirements = RequirementSet(current_platform)
    requirements.add(requirement_parser.parse("six"))
    pip_from_data_directory.download_sources(requirements, download_dir)
def test_pip_without_index_cannot_download_six(
    pip_without_index: VirtualenvPip,
    download_dir: str,
    requirement_parser: RequirementParser,
    current_platform: TargetPlatform,
) -> None:
    requirements = RequirementSet(current_platform)
    requirements.add(requirement_parser.parse("six"))
    with pytest.raises(PipFailed):
        pip_without_index.download_sources(requirements, download_dir)
Beispiel #10
0
    def import_wheel(self, wheel: Wheel,
                     requirement_parser: RequirementParser) -> None:
        dependent = requirement_parser.parse(wheel.name)
        for runtime_dependency in wheel.runtime_dependencies(
                wheel.target_platform()):

            self.set_runtime_dependency(dependent, runtime_dependency)
        for build_dependency in wheel.build_dependencies(
                wheel.target_platform()):
            self.set_buildtime_dependency(dependent, build_dependency)
def test_external_dependencies_from_graph_are_retrieved(
    requirement_parser: RequirementParser, ) -> None:
    dependency_graph = DependencyGraph()
    requirement = requirement_parser.parse("testpackage")
    external_dependency = ExternalDependency("external")
    dependency_graph.set_external_dependency(dependent=requirement,
                                             dependency=external_dependency)
    retriever = RequirementDependencyRetriever(dependency_graph)
    assert external_dependency in retriever.get_external_dependency_for_requirement(
        requirement)
Beispiel #12
0
def test_can_add_build_dependencies_to_wheel(
    wheel: Wheel,
    current_platform: TargetPlatform,
    requirement_parser: RequirementParser,
):
    build_dependencies = RequirementSet(current_platform)
    build_dependencies.add(requirement_parser.parse("dep1"))
    build_dependencies.add(requirement_parser.parse("dep2"))
    wheel.add_build_dependencies(build_dependencies)
    assert "dep1" in wheel.build_dependencies(current_platform)
    assert "dep2" in wheel.build_dependencies(current_platform)
Beispiel #13
0
def test_pip_downloads_sources_to_target_directory(
    pip: Pip,
    project_dir: str,
    current_platform: TargetPlatform,
    requirement_parser: RequirementParser,
):
    download_path = os.path.join(project_dir, "download")
    requirements = RequirementSet(current_platform)
    requirements.add(requirement_parser.parse("six"))
    pip.download_sources(requirements=requirements, target_directory=download_path)
    assert list_files(download_path)
 def build_dependencies_from_setup_cfg(
         self, target_platform: TargetPlatform,
         requirement_parser: RequirementParser) -> RequirementSet:
     setup_requires = self.setup_cfg.get("options",
                                         {}).get("setup_requires")
     requirements = RequirementSet(target_platform)
     if isinstance(setup_requires, str):
         requirements.add(requirement_parser.parse(setup_requires))
     elif isinstance(setup_requires, list):
         for requirement_string in setup_requires:
             try:
                 requirement = requirement_parser.parse(requirement_string)
             except ParsingFailed as e:
                 self.logger.warning(
                     "Failed to parse build dependency of `{name}`".format(
                         name=self.name))
                 self.logger.warning(
                     "Possible reason: `{reason}`".format(reason=e.reason))
             else:
                 if requirement.applies_to_target(target_platform):
                     requirements.add(requirement)
     return requirements
Beispiel #15
0
def test_that_extras_are_preserved_when_converting_to_and_from_a_file(
    requirement_parser: RequirementParser,
    requirement_set: RequirementSet,
    current_platform: TargetPlatform,
    project_dir: str,
    logger: Logger,
):
    requirement_set.add(requirement_parser.parse("req[extra1]"))
    requirements_file = requirement_set.to_file(project_dir, current_platform,
                                                requirement_parser, logger)
    new_requirements_set = RequirementSet.from_file(requirements_file,
                                                    current_platform,
                                                    requirement_parser, logger)
    requirement = new_requirements_set["req"]
    assert requirement.extras() == {"extra1"}
Beispiel #16
0
def test_freeze_respects_additional_python_path(
    pip: Pip,
    project_dir: str,
    current_platform: TargetPlatform,
    requirement_parser: RequirementParser,
):
    prefix = os.path.join(project_dir, "custom-prefix")
    download_dir = os.path.join(project_dir, "download")
    requirements = RequirementSet(current_platform)
    requirements.add(requirement_parser.parse("six"))
    pip.download_sources(requirements, download_dir)
    pip.install(
        requirements, target_directory=prefix, source_directories=[download_dir]
    )
    freeze_without_six = pip.freeze([])
    freeze_with_six = pip.freeze(python_path=[prefix])
    assert len(freeze_without_six) < len(freeze_with_six)
Beispiel #17
0
def test_can_install_generated_packages(
    pip,
    current_platform: TargetPlatform,
    requirement_parser: RequirementParser,
    target_directory: Path,
    install_target: Path,
    package_generator: PackageGenerator,
):
    package_generator.generate_setuptools_package(name="testpackage")
    requirements = RequirementSet(current_platform)
    requirements.add(requirement_parser.parse("testpackage"))
    pip.install(
        requirements,
        source_directories=[str(target_directory)],
        target_directory=str(install_target),
    )
    assert "testpackage" in pip.freeze(python_path=[str(install_target)])
Beispiel #18
0
def test_pip_can_install_wheels_previously_downloaded(
    pip: Pip,
    project_dir: str,
    current_platform: TargetPlatform,
    requirement_parser: RequirementParser,
    download_dir: Path,
    wheels_dir: Path,
):
    requirements = RequirementSet(current_platform)
    requirements.add(requirement_parser.parse("six"))
    pip.download_sources(requirements, download_dir)
    pip.build_wheels(
        requirements=requirements,
        source_directories=[download_dir],
        target_directory=wheels_dir,
    )
    assert wheels_dir.list_files()
    assert any(map(lambda x: x.endswith(".whl"), wheels_dir.list_files()))
Beispiel #19
0
def test_can_generate_packages_with_requirements(
    package_generator: PackageGenerator,
    requirement_parser: RequirementParser,
    pip: Pip,
    target_directory: Path,
    install_target: Path,
    current_platform: TargetPlatform,
):
    package_generator.generate_setuptools_package(
        name="testpackage", install_requires=["other-package"])
    package_generator.generate_setuptools_package(name="other-package")
    requirements = RequirementSet(target_platform=current_platform)
    requirements.add(requirement_parser.parse("testpackage"))
    pip.install(
        requirements,
        source_directories=[target_directory],
        target_directory=install_target,
    )
    assert "other-package" in pip.freeze([install_target])
Beispiel #20
0
def test_can_generate_valid_packages_with_extras_require(
    package_generator: PackageGenerator,
    requirement_parser: RequirementParser,
    pip: Pip,
    target_directory: Path,
    install_target: Path,
    current_platform: TargetPlatform,
):
    package_generator.generate_setuptools_package(
        name="testpackage", extras_require={"extra": ["extrapackage"]})
    package_generator.generate_setuptools_package(name="extrapackage")
    requirements = RequirementSet(target_platform=current_platform)
    requirements.add(requirement_parser.parse("testpackage[extra]"))
    pip.install(
        requirements,
        source_directories=[target_directory],
        target_directory=install_target,
    )
    installed_packages = pip.freeze([install_target])
    assert "extrapackage" in installed_packages
Beispiel #21
0
 def from_file(
     constructor,
     requirements_file: RequirementsFile,
     target_platform: TargetPlatform,
     requirement_parser: RequirementParser,
     logger: Logger,
 ) -> "RequirementSet":
     file_lines = requirements_file.read().splitlines()
     requirements_set = constructor(target_platform)
     for line in file_lines:
         try:
             requirement = requirement_parser.parse(line)
         except ParsingFailed:
             detected_requirements = constructor._handle_non_requirement_line(
                 line, target_platform, requirement_parser, logger
             )
             requirements_set += detected_requirements
         else:
             requirements_set.add(requirement)
     return requirements_set
 def build_dependencies_from_pyproject_toml(
         self, target_platform: TargetPlatform,
         requirement_parser: RequirementParser) -> RequirementSet:
     requirement_set = RequirementSet(target_platform)
     if self.pyproject_toml is None:
         pass
     else:
         for build_input in self.pyproject_toml.get("build-system",
                                                    {}).get("requires", []):
             try:
                 requirement = requirement_parser.parse(build_input)
             except ParsingFailed as e:
                 self.logger.warning(
                     "Failed to parse build dependency of `{name}`".format(
                         name=self.name))
                 self.logger.warning(
                     "Possible reason: `{reason}`".format(reason=e.reason))
             else:
                 if requirement.applies_to_target(target_platform):
                     requirement_set.add(requirement)
     return requirement_set
Beispiel #23
0
    def _extract_deps(
        constructor,
        deps: Iterable[str],
        target_platform: TargetPlatform,
        requirement_parser: RequirementParser,
        current_wheel_name: str,
    ) -> RequirementSet:
        """Get dependent packages from metadata.

        Note that this is currently very rough stuff. I consider only the
        first 'requires' dataset in 'run_requires'. Other requirement sets
        like 'test_requires' are completely ignored.
        """
        extracted_deps = RequirementSet(target_platform)
        for dep_string in deps:
            dependency = requirement_parser.parse(dep_string)
            if not constructor._valid_dependency(current_wheel_name,
                                                 dependency.name()):
                continue
            extracted_deps.add(dependency)
        return extracted_deps
Beispiel #24
0
def test_install_to_target_directory_does_not_install_to_default_directory(
    pip: Pip,
    project_dir: str,
    download_dir: Path,
    current_platform: TargetPlatform,
    requirement_parser: RequirementParser,
):
    requirements = RequirementSet(current_platform)
    requirements.add(requirement_parser.parse("six"))
    target_directory = Path(project_dir) / "target-directory"
    target_directory.ensure_directory()
    pip.download_sources(requirements, download_dir)

    assert not target_directory.list_files()

    pip.install(
        requirements,
        source_directories=[download_dir],
        target_directory=target_directory,
    )

    assert target_directory.list_files()
Beispiel #25
0
def test_can_generate_valid_packages_with_two_runtime_dependencies(
    package_generator: PackageGenerator,
    requirement_parser: RequirementParser,
    pip: Pip,
    target_directory: Path,
    install_target: Path,
    current_platform: TargetPlatform,
):
    package_generator.generate_setuptools_package(
        name="testpackage", install_requires=["dependency1", "dependency2"])
    package_generator.generate_setuptools_package(name="dependency1")
    package_generator.generate_setuptools_package(name="dependency2")
    requirements = RequirementSet(target_platform=current_platform)
    requirements.add(requirement_parser.parse("testpackage"))
    pip.install(
        requirements,
        source_directories=[target_directory],
        target_directory=install_target,
    )
    installed_packages = pip.freeze([install_target])
    assert "dependency1" in installed_packages
    assert "dependency2" in installed_packages
Beispiel #26
0
def requirement_parser(logger):
    return RequirementParser(logger=logger)
Beispiel #27
0
 def requirement_parser(self) -> RequirementParser:
     return RequirementParser(self.logger())
Beispiel #28
0
def requirement(request: Any,
                requirement_parser: RequirementParser) -> Requirement:
    return requirement_parser.parse(request.param)
Beispiel #29
0
def six_requirements(current_platform: TargetPlatform,
                     requirement_parser: RequirementParser) -> RequirementSet:
    requirements = RequirementSet(current_platform)
    requirements.add(requirement_parser.parse("six == 1.12.0"))
    return requirements
Beispiel #30
0
 def setUp(self) -> None:
     self.logger = StreamLogger(output=sys.stdout)
     self.nix = Nix(logger=self.logger)
     self.assertNotEqual(self.name_of_testcase, "undefined")
     self.requirement_parser = RequirementParser(self.logger)