def test_single_marker(): m = parse_marker('sys_platform == "darwin"') assert isinstance(m, SingleMarker) assert m.name == "sys_platform" assert m.constraint_string == "==darwin" m = parse_marker('python_version in "2.7, 3.0, 3.1"') assert isinstance(m, SingleMarker) assert m.name == "python_version" assert m.constraint_string == "in 2.7, 3.0, 3.1" assert str(m.constraint) == ">=2.7.0,<2.8.0 || >=3.0.0,<3.2.0" m = parse_marker('"2.7" in python_version') assert isinstance(m, SingleMarker) assert m.name == "python_version" assert m.constraint_string == "in 2.7" assert str(m.constraint) == ">=2.7.0,<2.8.0" m = parse_marker('python_version not in "2.7, 3.0, 3.1"') assert isinstance(m, SingleMarker) assert m.name == "python_version" assert m.constraint_string == "not in 2.7, 3.0, 3.1" assert str(m.constraint) == "<2.7.0 || >=2.8.0,<3.0.0 || >=3.2.0"
def test_single_marker_intersect_with_multi_with_duplicate(): m = parse_marker('python_version < "4.0"') intersection = m.intersect( parse_marker('sys_platform == "darwin" and python_version < "4.0"')) assert str( intersection) == 'sys_platform == "darwin" and python_version < "4.0"'
def test_marker_union_intersect_single_marker(): m = parse_marker('sys_platform == "darwin" or python_version < "3.4"') intersection = m.intersect( parse_marker('implementation_name == "cpython"')) assert str(intersection) == ( 'sys_platform == "darwin" and implementation_name == "cpython" ' 'or python_version < "3.4" and implementation_name == "cpython"')
def test_single_marker_intersect_with_multi_compacts_constraint(): m = parse_marker('python_version < "3.6"') intersection = m.intersect( parse_marker( 'implementation_name == "cpython" and python_version < "3.4"')) assert (str(intersection) == 'implementation_name == "cpython" and python_version < "3.4"')
def test_marker_union(): m = parse_marker( 'sys_platform == "darwin" or implementation_name == "cpython"') assert isinstance(m, MarkerUnion) assert m.markers == [ parse_marker('sys_platform == "darwin"'), parse_marker('implementation_name == "cpython"'), ]
def test_multi_marker_intersect_multi(): m = parse_marker( 'sys_platform == "darwin" and implementation_name == "cpython"') intersection = m.intersect( parse_marker('python_version >= "3.6" and os_name == "Windows"')) assert str(intersection) == ( 'sys_platform == "darwin" and implementation_name == "cpython" ' 'and python_version >= "3.6" and os_name == "Windows"')
def test_multi_marker_union_with_union(): m = parse_marker( 'sys_platform == "darwin" and implementation_name == "cpython"') intersection = m.union( parse_marker('python_version >= "3.6" or os_name == "Windows"')) assert str(intersection) == ( 'python_version >= "3.6" or os_name == "Windows"' ' or sys_platform == "darwin" and implementation_name == "cpython"')
def test_multi_marker(): m = parse_marker( 'sys_platform == "darwin" and implementation_name == "cpython"') assert isinstance(m, MultiMarker) assert m.markers == [ parse_marker('sys_platform == "darwin"'), parse_marker('implementation_name == "cpython"'), ]
def test_marker_union_union_with_union(): m = parse_marker('sys_platform == "darwin" or python_version < "3.4"') union = m.union( parse_marker( 'implementation_name == "cpython" or os_name == "Windows"')) assert str(union) == ( 'sys_platform == "darwin" or python_version < "3.4" ' 'or implementation_name == "cpython" or os_name == "Windows"')
def test_marker_union_intersect_marker_union_drops_unnecessary_markers(): m = parse_marker('python_version >= "2.7" and python_version < "2.8" ' 'or python_version >= "3.4" and python_version < "4.0"') m2 = parse_marker('python_version >= "2.7" and python_version < "2.8" ' 'or python_version >= "3.4" and python_version < "4.0"') intersection = m.intersect(m2) expected = ('python_version >= "2.7" and python_version < "2.8" ' 'or python_version >= "3.4" and python_version < "4.0"') assert expected == str(intersection)
def test_single_marker_intersect_with_multi(): m = parse_marker('sys_platform == "darwin"') intersection = m.intersect( parse_marker( 'implementation_name == "cpython" and python_version >= "3.6"')) assert ( str(intersection) == 'implementation_name == "cpython" and python_version >= "3.6" and sys_platform == "darwin"' )
def test_multi_marker_intersect_multi_with_overlapping_constraints(): m = parse_marker('sys_platform == "darwin" and python_version < "3.6"') intersection = m.intersect( parse_marker( 'python_version <= "3.4" and os_name == "Windows" and sys_platform == "darwin"' )) assert str(intersection) == ( 'sys_platform == "darwin" and python_version <= "3.4" and os_name == "Windows"' )
def test_multi_marker_is_empty_is_contradictory(): m = parse_marker( 'sys_platform == "linux" and python_version >= "3.5" and python_version < "2.8"' ) assert m.is_empty() m = parse_marker('sys_platform == "linux" and sys_platform == "win32"') assert m.is_empty()
def test_single_marker_union_with_union(): m = parse_marker('sys_platform == "darwin"') union = m.union( parse_marker( 'implementation_name == "cpython" or python_version >= "3.6"')) assert ( str(union) == 'implementation_name == "cpython" or python_version >= "3.6" or sys_platform == "darwin"' )
def test_multi_marker_removes_duplicates(): m = parse_marker('sys_platform == "win32" and sys_platform == "win32"') assert 'sys_platform == "win32"' == str(m) m = parse_marker( 'sys_platform == "darwin" and implementation_name == "cpython" ' 'and sys_platform == "darwin" and implementation_name == "cpython"') assert 'sys_platform == "darwin" and implementation_name == "cpython"' == str( m)
def test_marker_str_conversion_skips_empty_and_any(): union = MarkerUnion( parse_marker("<empty>"), parse_marker( 'sys_platform == "darwin" or python_version <= "3.6" or os_name == "Windows"' ), parse_marker(""), ) assert str(union) == ( 'sys_platform == "darwin" or python_version <= "3.6" or os_name == "Windows"' )
def test_single_marker_union(): m = parse_marker('sys_platform == "darwin"') intersection = m.union(parse_marker('implementation_name == "cpython"')) assert (str(intersection) == 'sys_platform == "darwin" or implementation_name == "cpython"') m = parse_marker('python_version >= "3.4"') intersection = m.union(parse_marker('python_version < "3.6"')) assert str( intersection) == 'python_version >= "3.4" or python_version < "3.6"'
def test_marker_union_intersect_single_with_overlapping_constraints(): m = parse_marker('sys_platform == "darwin" or python_version < "3.4"') intersection = m.intersect(parse_marker('python_version <= "3.6"')) assert ( str(intersection) == 'sys_platform == "darwin" and python_version <= "3.6" or python_version < "3.4"' ) m = parse_marker('sys_platform == "darwin" or python_version < "3.4"') intersection = m.intersect(parse_marker('sys_platform == "darwin"')) assert ( str(intersection) == 'sys_platform == "darwin" or python_version < "3.4" and sys_platform == "darwin"' )
def test_solver_does_not_raise_conflict_for_locked_conditional_dependencies( solver, repo, package ): package.python_versions = "~2.7 || ^3.4" package.add_dependency("A", {"version": "^1.0", "python": "^3.6"}) package.add_dependency("B", "^1.0") package_a = get_package("A", "1.0.0") package_a.python_versions = ">=3.6" package_a.marker = parse_marker( 'python_version >= "3.6" and python_version < "4.0"' ) package_b = get_package("B", "1.0.0") repo.add_package(package_a) repo.add_package(package_b) solver._locked = Repository([package_a]) ops = solver.solve(use_latest=[package_b.name]) check_solver_result( ops, [ {"job": "install", "package": package_a}, {"job": "install", "package": package_b}, ], )
def test_exclude(marker, excluded, expected): m = parse_marker(marker) if expected == "*": assert m.exclude(excluded).is_any() else: assert expected == str(m.exclude(excluded))
def test_marker_union_deduplicate(): m = parse_marker( 'sys_platform == "darwin" or implementation_name == "cpython" or sys_platform == "darwin"' ) assert str( m) == 'sys_platform == "darwin" or implementation_name == "cpython"'
def test_solver_returns_extras_if_requested(solver, repo, package): package.add_dependency("A") package.add_dependency("B", {"version": "*", "extras": ["foo"]}) package_a = get_package("A", "1.0") package_b = get_package("B", "1.0") package_c = get_package("C", "1.0") dep = get_dependency("C", "^1.0", optional=True) dep.marker = parse_marker("extra == 'foo'") package_b.extras = {"foo": [dep]} package_b.requires.append(dep) repo.add_package(package_a) repo.add_package(package_b) repo.add_package(package_c) ops = solver.solve() check_solver_result( ops, [ {"job": "install", "package": package_c}, {"job": "install", "package": package_a}, {"job": "install", "package": package_b}, ], ) assert ops[-1].package.marker.is_any() assert ops[0].package.marker.is_any()
def python_versions(self, value): self._python_versions = value self._python_constraint = parse_constraint(value) if not self._python_constraint.is_any(): self.marker = self.marker.intersect( parse_marker( self._create_nested_marker("python_version", self._python_constraint)))
def test_convert_markers(): marker = parse_marker( 'sys_platform == "win32" and python_version < "3.6" ' 'or sys_platform == "win32" and python_version < "3.6" and python_version >= "3.3" ' 'or sys_platform == "win32" and python_version < "3.3"') converted = convert_markers(marker) assert converted["python_version"] == [ [("<", "3.6")], [("<", "3.6"), (">=", "3.3")], [("<", "3.3")], ] marker = parse_marker('python_version == "2.7" or python_version == "2.6"') converted = convert_markers(marker) assert converted["python_version"] == [[("==", "2.7")], [("==", "2.6")]]
def test_marker_union_union_duplicates(): m = parse_marker('sys_platform == "darwin" or python_version < "3.4"') union = m.union( parse_marker('sys_platform == "darwin" or os_name == "Windows"')) assert str(union) == ( 'sys_platform == "darwin" or python_version < "3.4" or os_name == "Windows"' ) m = parse_marker('sys_platform == "darwin" or python_version < "3.4"') union = m.union( parse_marker( 'sys_platform == "darwin" or os_name == "Windows" or python_version <= "3.6"' )) assert str(union) == ( 'sys_platform == "darwin" or python_version <= "3.6" or os_name == "Windows"' )
def python_versions(self, value): self._python_versions = value if value == "*" or value == VersionRange(): value = "~2.7 || >=3.4" self._python_constraint = parse_constraint(value) self._python_marker = parse_marker( create_nested_marker("python_version", self._python_constraint))
def test_single_marker_union_with_union_duplicate(): m = parse_marker('sys_platform == "darwin"') union = m.union( parse_marker('sys_platform == "darwin" or python_version >= "3.6"')) assert str(union) == 'sys_platform == "darwin" or python_version >= "3.6"' m = parse_marker('python_version >= "3.7"') union = m.union( parse_marker('sys_platform == "darwin" or python_version >= "3.6"')) assert str(union) == 'sys_platform == "darwin" or python_version >= "3.6"' m = parse_marker('python_version <= "3.6"') union = m.union( parse_marker('sys_platform == "darwin" or python_version < "3.4"')) assert str(union) == 'sys_platform == "darwin" or python_version <= "3.6"'
def _get_info_from_urls( self, urls ): # type: (Dict[str, List[str]]) -> Dict[str, Union[str, List, None]] # Checking wheels first as they are more likely to hold # the necessary information if "bdist_wheel" in urls: # Check fo a universal wheel wheels = urls["bdist_wheel"] universal_wheel = None universal_python2_wheel = None universal_python3_wheel = None platform_specific_wheels = [] for wheel in wheels: link = Link(wheel) m = wheel_file_re.match(link.filename) if not m: continue pyver = m.group("pyver") abi = m.group("abi") plat = m.group("plat") if abi == "none" and plat == "any": # Universal wheel if pyver == "py2.py3": # Any Python universal_wheel = wheel elif pyver == "py2": universal_python2_wheel = wheel else: universal_python3_wheel = wheel else: platform_specific_wheels.append(wheel) if universal_wheel is not None: return self._get_info_from_wheel(universal_wheel) info = {} if universal_python2_wheel and universal_python3_wheel: info = self._get_info_from_wheel(universal_python2_wheel) py3_info = self._get_info_from_wheel(universal_python3_wheel) if py3_info["requires_dist"]: if not info["requires_dist"]: info["requires_dist"] = py3_info["requires_dist"] return info py2_requires_dist = set( dependency_from_pep_508(r).to_pep_508() for r in info["requires_dist"]) py3_requires_dist = set( dependency_from_pep_508(r).to_pep_508() for r in py3_info["requires_dist"]) base_requires_dist = py2_requires_dist & py3_requires_dist py2_only_requires_dist = py2_requires_dist - py3_requires_dist py3_only_requires_dist = py3_requires_dist - py2_requires_dist # Normalizing requires_dist requires_dist = list(base_requires_dist) for requirement in py2_only_requires_dist: dep = dependency_from_pep_508(requirement) dep.marker = dep.marker.intersect( parse_marker("python_version == '2.7'")) requires_dist.append(dep.to_pep_508()) for requirement in py3_only_requires_dist: dep = dependency_from_pep_508(requirement) dep.marker = dep.marker.intersect( parse_marker("python_version >= '3'")) requires_dist.append(dep.to_pep_508()) info["requires_dist"] = sorted(list(set(requires_dist))) if info: return info # Prefer non platform specific wheels if universal_python3_wheel: return self._get_info_from_wheel(universal_python3_wheel) if universal_python2_wheel: return self._get_info_from_wheel(universal_python2_wheel) if platform_specific_wheels and "sdist" not in urls: # Pick the first wheel available and hope for the best return self._get_info_from_wheel(platform_specific_wheels[0]) return self._get_info_from_sdist(urls["sdist"][0])
def locked_repository(self, with_dev_reqs=False ): # type: (bool) -> poetry.repositories.Repository """ Searches and returns a repository of locked packages. """ if not self.is_locked(): return poetry.repositories.Repository() lock_data = self.lock_data packages = poetry.repositories.Repository() if with_dev_reqs: locked_packages = lock_data["package"] else: locked_packages = [ p for p in lock_data["package"] if p["category"] == "main" ] if not locked_packages: return packages for info in locked_packages: package = poetry.packages.Package(info["name"], info["version"], info["version"]) package.description = info.get("description", "") package.category = info["category"] package.optional = info["optional"] if "hashes" in lock_data["metadata"]: # Old lock so we create dummy files from the hashes package.files = [{ "name": h, "hash": h } for h in lock_data["metadata"]["hashes"][info["name"]]] else: package.files = lock_data["metadata"]["files"][info["name"]] package.python_versions = info["python-versions"] extras = info.get("extras", {}) if extras: for name, deps in extras.items(): package.extras[name] = [] for dep in deps: m = re.match(r"^(.+?)(?:\s+\((.+)\))?$", dep) dep_name = m.group(1) constraint = m.group(2) or "*" package.extras[name].append( poetry.packages.Dependency(dep_name, constraint)) if "marker" in info: package.marker = parse_marker(info["marker"]) else: # Compatibility for old locks if "requirements" in info: dep = poetry.packages.Dependency("foo", "0.0.0") for name, value in info["requirements"].items(): if name == "python": dep.python_versions = value elif name == "platform": dep.platform = value split_dep = dep.to_pep_508(False).split(";") if len(split_dep) > 1: package.marker = parse_marker(split_dep[1].strip()) for dep_name, constraint in info.get("dependencies", {}).items(): if isinstance(constraint, list): for c in constraint: package.add_dependency(dep_name, c) continue package.add_dependency(dep_name, constraint) if "source" in info: package.source_type = info["source"]["type"] package.source_url = info["source"]["url"] package.source_reference = info["source"]["reference"] packages.add_package(package) return packages
def add_dependency( self, name, # type: str constraint=None, # type: Union[str, dict, None] category="main", # type: str ): # type: (...) -> Dependency if constraint is None: constraint = "*" if isinstance(constraint, dict): optional = constraint.get("optional", False) python_versions = constraint.get("python") platform = constraint.get("platform") markers = constraint.get("markers") allows_prereleases = constraint.get("allows-prereleases", False) if "git" in constraint: # VCS dependency dependency = VCSDependency( name, "git", constraint["git"], branch=constraint.get("branch", None), tag=constraint.get("tag", None), rev=constraint.get("rev", None), optional=optional, ) elif "file" in constraint: file_path = Path(constraint["file"]) dependency = FileDependency( name, file_path, category=category, base=self.root_dir ) elif "path" in constraint: path = Path(constraint["path"]) if self.root_dir: is_file = (self.root_dir / path).is_file() else: is_file = path.is_file() if is_file: dependency = FileDependency( name, path, category=category, optional=optional, base=self.root_dir, ) else: dependency = DirectoryDependency( name, path, category=category, optional=optional, base=self.root_dir, develop=constraint.get("develop", True), ) else: version = constraint["version"] dependency = Dependency( name, version, optional=optional, category=category, allows_prereleases=allows_prereleases, source_name=constraint.get("source"), ) if not markers: marker = AnyMarker() if python_versions: dependency.python_versions = python_versions marker = marker.intersect( parse_marker( create_nested_marker( "python_version", dependency.python_constraint ) ) ) if platform: marker = marker.intersect( parse_marker( create_nested_marker( "sys_platform", parse_generic_constraint(platform) ) ) ) else: marker = parse_marker(markers) if not marker.is_any(): dependency.marker = marker if "extras" in constraint: for extra in constraint["extras"]: dependency.extras.append(extra) else: dependency = Dependency(name, constraint, category=category) if category == "dev": self.dev_requires.append(dependency) else: self.requires.append(dependency) return dependency