def v250() -> Version: return Version.parse("2.5.0")
def test_parse_invalid(input): with pytest.raises(ParseVersionError): Version.parse(input)
def v010(): return Version.parse("0.1.0")
def _get_release_info(self, name: str, version: str) -> dict: page = self._get("/{}/".format( canonicalize_name(name).replace(".", "-"))) if page is None: raise PackageNotFound('No package named "{}"'.format(name)) data = PackageInfo( name=name, version=version, summary="", platform=None, requires_dist=[], requires_python=None, files=[], cache_version=str(self.CACHE_VERSION), ) links = list(page.links_for_version(Version.parse(version))) if not links: raise PackageNotFound( 'No valid distribution links found for package: "{}" version: "{}"' .format(name, version)) urls = defaultdict(list) files = [] for link in links: if link.is_wheel: urls["bdist_wheel"].append(link.url) elif link.filename.endswith( (".tar.gz", ".zip", ".bz2", ".xz", ".Z", ".tar")): urls["sdist"].append(link.url) file_hash = "{}:{}".format(link.hash_name, link.hash) if link.hash else None if not link.hash or (link.hash_name not in ("sha256", "sha384", "sha512") and hasattr(hashlib, link.hash_name)): with temporary_directory() as temp_dir: filepath = Path(temp_dir) / link.filename self._download(link.url, str(filepath)) known_hash = (getattr(hashlib, link.hash_name)() if link.hash_name else None) required_hash = hashlib.sha256() chunksize = 4096 with filepath.open("rb") as f: while True: chunk = f.read(chunksize) if not chunk: break if known_hash: known_hash.update(chunk) required_hash.update(chunk) if not known_hash or known_hash.hexdigest() == link.hash: file_hash = "{}:{}".format(required_hash.name, required_hash.hexdigest()) files.append({"file": link.filename, "hash": file_hash}) data.files = files info = self._get_info_from_urls(urls) data.summary = info.summary data.requires_dist = info.requires_dist data.requires_python = info.requires_python return data.asdict()
def test_union(): v = Version.parse("1.2.3") assert v.union(v) == v result = v.union(Version.parse("0.8.0")) assert result.allows(v) assert result.allows(Version.parse("0.8.0")) assert not result.allows(Version.parse("1.1.4")) range = VersionRange(Version.parse("1.1.4"), Version.parse("1.2.4")) assert v.union(range) == range union = Version.parse("1.1.4").union( VersionRange(Version.parse("1.1.4"), Version.parse("1.2.4"))) assert union == VersionRange(Version.parse("1.1.4"), Version.parse("1.2.4"), include_min=True) result = v.union( VersionRange(Version.parse("0.0.3"), Version.parse("1.1.4"))) assert result.allows(v) assert result.allows(Version.parse("0.1.0"))
def remove(self, python): # type: (str) -> Env venv_path = self._poetry.config.get("virtualenvs.path") if venv_path is None: venv_path = Path(CACHE_DIR) / "virtualenvs" else: venv_path = Path(venv_path) cwd = self._poetry.file.parent envs_file = TomlFile(venv_path / self.ENVS_FILE) base_env_name = self.generate_env_name(self._poetry.package.name, str(cwd)) if python.startswith(base_env_name): venvs = self.list() for venv in venvs: if venv.path.name == python: # Exact virtualenv name if not envs_file.exists(): self.remove_venv(venv.path) return venv venv_minor = ".".join( str(v) for v in venv.version_info[:2]) base_env_name = self.generate_env_name(cwd.name, str(cwd)) envs = envs_file.read() current_env = envs.get(base_env_name) if not current_env: self.remove_venv(venv.path) return venv if current_env["minor"] == venv_minor: del envs[base_env_name] envs_file.write(envs) self.remove_venv(venv.path) return venv raise ValueError( '<warning>Environment "{}" does not exist.</warning>'.format( python)) try: python_version = Version.parse(python) python = "python{}".format(python_version.major) if python_version.precision > 1: python += ".{}".format(python_version.minor) except ValueError: # Executable in PATH or full executable path pass try: python_version = decode( subprocess.check_output( list_to_shell_command([ python, "-c", "\"import sys; print('.'.join([str(s) for s in sys.version_info[:3]]))\"", ]), shell=True, )) except CalledProcessError as e: raise EnvCommandError(e) python_version = Version.parse(python_version.strip()) minor = "{}.{}".format(python_version.major, python_version.minor) name = "{}-py{}".format(base_env_name, minor) venv = venv_path / name if not venv.exists(): raise ValueError( '<warning>Environment "{}" does not exist.</warning>'.format( name)) if envs_file.exists(): envs = envs_file.read() current_env = envs.get(base_env_name) if current_env is not None: current_minor = current_env["minor"] if current_minor == minor: del envs[base_env_name] envs_file.write(envs) self.remove_venv(venv) return VirtualEnv(venv)
def test_self_update_should_install_all_necessary_elements( app, http, mocker, environ, tmp_dir ): os.environ["POETRY_HOME"] = tmp_dir command = app.find("self update") version = Version.parse(__version__).next_minor.text mocker.patch( "poetry.repositories.pypi_repository.PyPiRepository.find_packages", return_value=[Package("poetry", version)], ) mocker.patch.object(command, "_check_recommended_installation", return_value=None) mocker.patch.object( command, "_get_release_name", return_value="poetry-{}-darwin".format(version) ) mocker.patch("subprocess.check_output", return_value=b"Python 3.8.2") http.register_uri( "GET", command.BASE_URL + "/{}/poetry-{}-darwin.sha256sum".format(version, version), body=FIXTURES.joinpath("poetry-1.0.5-darwin.sha256sum").read_bytes(), ) http.register_uri( "GET", command.BASE_URL + "/{}/poetry-{}-darwin.tar.gz".format(version, version), body=FIXTURES.joinpath("poetry-1.0.5-darwin.tar.gz").read_bytes(), ) tester = CommandTester(command) tester.execute() bin_ = Path(tmp_dir).joinpath("bin") lib = Path(tmp_dir).joinpath("lib") assert bin_.exists() script = bin_.joinpath("poetry") assert script.exists() expected_script = """\ # -*- coding: utf-8 -*- import glob import sys import os lib = os.path.normpath(os.path.join(os.path.realpath(__file__), "../..", "lib")) vendors = os.path.join(lib, "poetry", "_vendor") current_vendors = os.path.join( vendors, "py{}".format(".".join(str(v) for v in sys.version_info[:2])) ) sys.path.insert(0, lib) sys.path.insert(0, current_vendors) if __name__ == "__main__": from poetry.console import main main() """ if not WINDOWS: expected_script = "#!/usr/bin/env python\n" + expected_script assert expected_script == script.read_text() if WINDOWS: bat = bin_.joinpath("poetry.bat") expected_bat = '@echo off\r\npython "{}" %*\r\n'.format( str(script).replace(os.environ.get("USERPROFILE", ""), "%USERPROFILE%") ) assert bat.exists() with bat.open(newline="") as f: assert expected_bat == f.read() assert lib.exists() assert lib.joinpath("poetry").exists()
def test_parse_valid(text, version): parsed = Version.parse(text) assert parsed == version assert parsed.text == text
def test_parse_invalid(value): with pytest.raises(InvalidVersion): Version.parse(value)
def __init__( self, name: str, version: Union[str, "Version"], pretty_version: Optional[str] = None, source_type: Optional[str] = None, source_url: Optional[str] = None, source_reference: Optional[str] = None, source_resolved_reference: Optional[str] = None, features: Optional[List[str]] = None, develop: bool = False, ) -> None: """ Creates a new in memory package. """ from poetry.core.semver.version import Version from poetry.core.version.markers import AnyMarker super(Package, self).__init__( name, source_type=source_type, source_url=source_url, source_reference=source_reference, source_resolved_reference=source_resolved_reference, features=features, ) if not isinstance(version, Version): self._version = Version.parse(version) self._pretty_version = pretty_version or version else: self._version = version self._pretty_version = pretty_version or self._version.text self.description = "" self._authors = [] self._maintainers = [] self.homepage = None self.repository_url = None self.documentation_url = None self.keywords = [] self._license = None self.readme = None self.requires = [] self.dev_requires = [] self.extras = {} self.requires_extras = [] self.category = "main" self.files = [] self.optional = False self.classifiers = [] self._python_versions = "*" self._python_constraint = parse_constraint("*") self._python_marker = AnyMarker() self.platform = None self.marker = AnyMarker() self.root_dir = None self.develop = develop
import pytest from poetry.core.semver.empty_constraint import EmptyConstraint from poetry.core.semver.version import Version from poetry.core.semver.version_range import VersionRange from poetry.core.version.exceptions import InvalidVersion from poetry.core.version.pep440 import ReleaseTag @pytest.mark.parametrize( "text,version", [ ("1.0.0", Version.from_parts(1, 0, 0)), ("1", Version.from_parts(1, 0, 0)), ("1.0", Version.from_parts(1, 0, 0)), ("1b1", Version.from_parts(1, 0, 0, pre=ReleaseTag("beta", 1))), ("1.0b1", Version.from_parts(1, 0, 0, pre=ReleaseTag("beta", 1))), ("1.0.0b1", Version.from_parts(1, 0, 0, pre=ReleaseTag("beta", 1))), ("1.0.0-b1", Version.from_parts(1, 0, 0, pre=ReleaseTag("beta", 1))), ("1.0.0-beta.1", Version.from_parts(1, 0, 0, pre=ReleaseTag("beta", 1))), ("1.0.0+1", Version.from_parts(1, 0, 0, local=1)), ("1.0.0-1", Version.from_parts(1, 0, 0, post=ReleaseTag("post", 1))), ("1.0.0.0", Version.from_parts(1, 0, 0, extra=0)), ("1.0.0-post", Version.from_parts(1, 0, 0, post=ReleaseTag("post"))), ("1.0.0-post1", Version.from_parts(1, 0, 0, post=ReleaseTag("post", 1))), ("0.6c", Version.from_parts(0, 6, 0, pre=ReleaseTag("rc", 0))), ("0.6pre", Version.from_parts(0, 6, 0, pre=ReleaseTag("preview", 0))), ], ) def test_parse_valid(text, version): parsed = Version.parse(text)
def get_pip_version(self) -> Version: from pip import __version__ return Version.parse(__version__)
def v300b1() -> Version: return Version.parse("3.0.0b1")
def v300() -> Version: return Version.parse("3.0.0")
def get_pip_version(self): # type: () -> Version from pip import __version__ return Version.parse(__version__)
from poetry.core.semver.helpers import parse_constraint from poetry.core.semver.version import Version from poetry.core.semver.version_range import VersionRange from poetry.core.semver.version_union import VersionUnion @pytest.mark.parametrize( "input,constraint", [ ("*", VersionRange()), ("*.*", VersionRange()), ("v*.*", VersionRange()), ("*.x.*", VersionRange()), ("x.X.x.*", VersionRange()), # ('!=1.0.0', Constraint('!=', '1.0.0.0')), (">1.0.0", VersionRange(min=Version(1, 0, 0))), ("<1.2.3", VersionRange(max=Version(1, 2, 3))), ("<=1.2.3", VersionRange(max=Version(1, 2, 3), include_max=True)), (">=1.2.3", VersionRange(min=Version(1, 2, 3), include_min=True)), ("=1.2.3", Version(1, 2, 3)), ("1.2.3", Version(1, 2, 3)), ("=1.0", Version(1, 0, 0)), ("1.2.3b5", Version(1, 2, 3, pre="b5")), (">= 1.2.3", VersionRange(min=Version(1, 2, 3), include_min=True)), (">dev", VersionRange(min=Version(0, 0, pre="dev"))), # Issue 206 ], ) def test_parse_constraint(input, constraint): assert parse_constraint(input) == constraint
def activate(self, python, io): # type: (str, IO) -> Env venv_path = self._poetry.config.get("virtualenvs.path") if venv_path is None: venv_path = Path(CACHE_DIR) / "virtualenvs" else: venv_path = Path(venv_path) cwd = self._poetry.file.parent envs_file = TomlFile(venv_path / self.ENVS_FILE) try: python_version = Version.parse(python) python = "python{}".format(python_version.major) if python_version.precision > 1: python += ".{}".format(python_version.minor) except ValueError: # Executable in PATH or full executable path pass try: python_version = decode( subprocess.check_output( list_to_shell_command([ python, "-c", "\"import sys; print('.'.join([str(s) for s in sys.version_info[:3]]))\"", ]), shell=True, )) except CalledProcessError as e: raise EnvCommandError(e) python_version = Version.parse(python_version.strip()) minor = "{}.{}".format(python_version.major, python_version.minor) patch = python_version.text create = False is_root_venv = self._poetry.config.get("virtualenvs.in-project") # If we are required to create the virtual environment in the root folder, # create or recreate it if needed if is_root_venv: create = False venv = self._poetry.file.parent / ".venv" if venv.exists(): # We need to check if the patch version is correct _venv = VirtualEnv(venv) current_patch = ".".join( str(v) for v in _venv.version_info[:3]) if patch != current_patch: create = True self.create_venv(io, executable=python, force=create) return self.get(reload=True) envs = tomlkit.document() base_env_name = self.generate_env_name(self._poetry.package.name, str(cwd)) if envs_file.exists(): envs = envs_file.read() current_env = envs.get(base_env_name) if current_env is not None: current_minor = current_env["minor"] current_patch = current_env["patch"] if current_minor == minor and current_patch != patch: # We need to recreate create = True name = "{}-py{}".format(base_env_name, minor) venv = venv_path / name # Create if needed if not venv.exists() or venv.exists() and create: in_venv = os.environ.get("VIRTUAL_ENV") is not None if in_venv or not venv.exists(): create = True if venv.exists(): # We need to check if the patch version is correct _venv = VirtualEnv(venv) current_patch = ".".join( str(v) for v in _venv.version_info[:3]) if patch != current_patch: create = True self.create_venv(io, executable=python, force=create) # Activate envs[base_env_name] = {"minor": minor, "patch": patch} envs_file.write(envs) return self.get(reload=True)
def test_parse_constraint_multi(input): assert parse_constraint(input) == VersionRange( Version(2, 0, 0), Version(3, 0, 0), include_min=False, include_max=True )
def create_venv(self, io, name=None, executable=None, force=False ): # type: (IO, Optional[str], Optional[str], bool) -> Env if self._env is not None and not force: return self._env cwd = self._poetry.file.parent env = self.get(reload=True) if not env.is_sane(): force = True if env.is_venv() and not force: # Already inside a virtualenv. return env create_venv = self._poetry.config.get("virtualenvs.create") root_venv = self._poetry.config.get("virtualenvs.in-project") venv_path = self._poetry.config.get("virtualenvs.path") if root_venv: venv_path = cwd / ".venv" elif venv_path is None: venv_path = Path(CACHE_DIR) / "virtualenvs" else: venv_path = Path(venv_path) if not name: name = self._poetry.package.name python_patch = ".".join([str(v) for v in sys.version_info[:3]]) python_minor = ".".join([str(v) for v in sys.version_info[:2]]) if executable: python_patch = decode( subprocess.check_output( list_to_shell_command([ executable, "-c", "\"import sys; print('.'.join([str(s) for s in sys.version_info[:3]]))\"", ]), shell=True, ).strip()) python_minor = ".".join(python_patch.split(".")[:2]) supported_python = self._poetry.package.python_constraint if not supported_python.allows(Version.parse(python_patch)): # The currently activated or chosen Python version # is not compatible with the Python constraint specified # for the project. # If an executable has been specified, we stop there # and notify the user of the incompatibility. # Otherwise, we try to find a compatible Python version. if executable: raise NoCompatiblePythonVersionFound( self._poetry.package.python_versions, python_patch) io.write_line( "<warning>The currently activated Python version {} " "is not supported by the project ({}).\n" "Trying to find and use a compatible version.</warning> ". format(python_patch, self._poetry.package.python_versions)) for python_to_try in reversed( sorted( self._poetry.package.AVAILABLE_PYTHONS, key=lambda v: (v.startswith("3"), -len(v), v), )): if len(python_to_try) == 1: if not parse_constraint("^{}.0".format( python_to_try)).allows_any(supported_python): continue elif not supported_python.allows_all( parse_constraint(python_to_try + ".*")): continue python = "python" + python_to_try if io.is_debug(): io.write_line("<debug>Trying {}</debug>".format(python)) try: python_patch = decode( subprocess.check_output( list_to_shell_command([ python, "-c", "\"import sys; print('.'.join([str(s) for s in sys.version_info[:3]]))\"", ]), stderr=subprocess.STDOUT, shell=True, ).strip()) except CalledProcessError: continue if not python_patch: continue if supported_python.allows(Version.parse(python_patch)): io.write_line("Using <c1>{}</c1> ({})".format( python, python_patch)) executable = python python_minor = ".".join(python_patch.split(".")[:2]) break if not executable: raise NoCompatiblePythonVersionFound( self._poetry.package.python_versions) if root_venv: venv = venv_path else: name = self.generate_env_name(name, str(cwd)) name = "{}-py{}".format(name, python_minor.strip()) venv = venv_path / name if not venv.exists(): if create_venv is False: io.write_line("<fg=black;bg=yellow>" "Skipping virtualenv creation, " "as specified in config file." "</>") return SystemEnv(Path(sys.prefix)) io.write_line("Creating virtualenv <c1>{}</> in {}".format( name, str(venv_path))) self.build_venv(venv, executable=executable) else: if force: if not env.is_sane(): io.write_line( "<warning>The virtual environment found in {} seems to be broken.</warning>" .format(env.path)) io.write_line("Recreating virtualenv <c1>{}</> in {}".format( name, str(venv))) self.remove_venv(venv) self.build_venv(venv, executable=executable) elif io.is_very_verbose(): io.write_line( "Virtualenv <c1>{}</> already exists.".format(name)) # venv detection: # stdlib venv may symlink sys.executable, so we can't use realpath. # but others can symlink *to* the venv Python, # so we can't just use sys.executable. # So we just check every item in the symlink tree (generally <= 3) p = os.path.normcase(sys.executable) paths = [p] while os.path.islink(p): p = os.path.normcase( os.path.join(os.path.dirname(p), os.readlink(p))) paths.append(p) p_venv = os.path.normcase(str(venv)) if any(p.startswith(p_venv) for p in paths): # Running properly in the virtualenv, don't need to do anything return SystemEnv(Path(sys.prefix), self.get_base_prefix()) return VirtualEnv(venv)
def test_parse_constraint_multi_wilcard(input): assert parse_constraint(input) == VersionUnion( VersionRange(Version(2, 7, 0), Version(3, 0, 0), True, False), VersionRange(Version(3, 2, 0), None, True, False), )
from poetry.core.semver.version import Version from poetry.core.semver.version_range import VersionRange from poetry.core.semver.version_union import VersionUnion from poetry.core.version.pep440 import ReleaseTag @pytest.mark.parametrize( "input,constraint", [ ("*", VersionRange()), ("*.*", VersionRange()), ("v*.*", VersionRange()), ("*.x.*", VersionRange()), ("x.X.x.*", VersionRange()), # ('!=1.0.0', Constraint('!=', '1.0.0.0')), (">1.0.0", VersionRange(min=Version.from_parts(1, 0, 0))), ("<1.2.3", VersionRange(max=Version.from_parts(1, 2, 3))), ("<=1.2.3", VersionRange(max=Version.from_parts(1, 2, 3), include_max=True)), (">=1.2.3", VersionRange(min=Version.from_parts(1, 2, 3), include_min=True)), ("=1.2.3", Version.from_parts(1, 2, 3)), ("1.2.3", Version.from_parts(1, 2, 3)), ("=1.0", Version.from_parts(1, 0, 0)), ("1.2.3b5", Version.from_parts(1, 2, 3, pre=ReleaseTag("beta", 5))), (">= 1.2.3", VersionRange(min=Version.from_parts(1, 2, 3), include_min=True)), ( ">dev", VersionRange(min=Version.from_parts(0, 0, dev=ReleaseTag("dev"))), ), # Issue 206 ], ) def test_parse_constraint(input, constraint):
("demo-0.1.0.tar.gz", Package("demo", "0.1.0")), ("demo-0.1.0.egg", Package("demo", "0.1.0")), ("demo-0.1.0_invalid-py2.py3-none-any.whl", None), # invalid version ("demo-0.1.0_invalid.egg", None), # invalid version ("no-package-at-all.txt", None), ], ) def test_link_package_data(filename: str, expected: Package | None) -> None: link = Link(f"https://example.org/{filename}") assert LinkSource.link_package_data(link) == expected @pytest.mark.parametrize( "name, expected", [ ("demo", {Version.parse("0.1.0"), Version.parse("0.1.1")}), ("invalid", set()), ], ) def test_versions(name: str, expected: set[Version], link_source: LinkSource) -> None: assert set(link_source.versions(name)) == expected def test_packages(link_source: LinkSource) -> None: expected = { Package("demo", "0.1.0"), Package("demo", "0.1.0"), Package("demo", "0.1.1"), } assert set(link_source.packages) == expected
import pytest from poetry.core.semver.empty_constraint import EmptyConstraint from poetry.core.semver.exceptions import ParseVersionError from poetry.core.semver.version import Version from poetry.core.semver.version_range import VersionRange @pytest.mark.parametrize( "input,version", [ ("1.0.0", Version(1, 0, 0)), ("1", Version(1, 0, 0)), ("1.0", Version(1, 0, 0)), ("1b1", Version(1, 0, 0, pre="beta1")), ("1.0b1", Version(1, 0, 0, pre="beta1")), ("1.0.0b1", Version(1, 0, 0, pre="beta1")), ("1.0.0-b1", Version(1, 0, 0, pre="beta1")), ("1.0.0-beta.1", Version(1, 0, 0, pre="beta1")), ("1.0.0+1", Version(1, 0, 0, build="1")), ("1.0.0-1", Version(1, 0, 0, build="1")), ("1.0.0.0", Version(1, 0, 0)), ("1.0.0-post", Version(1, 0, 0)), ("1.0.0-post1", Version(1, 0, 0, build="1")), ("0.6c", Version(0, 6, 0, pre="rc0")), ("0.6pre", Version(0, 6, 0, pre="rc0")), ], ) def test_parse_valid(input, version): parsed = Version.parse(input)
def test_links_for_version( version_string: str, filenames: Iterable[str], link_source: LinkSource ) -> None: version = Version.parse(version_string) expected = {Link(f"{link_source.url}/{name}") for name in filenames} assert set(link_source.links_for_version("demo", version)) == expected
def test_parse_valid(input, version): parsed = Version.parse(input) assert parsed == version assert parsed.text == input
import pytest from poetry.core.semver.helpers import parse_constraint from poetry.core.semver.version import Version from poetry.core.semver.version_range import VersionRange from poetry.core.semver.version_union import VersionUnion from poetry.core.version.pep440 import ReleaseTag @pytest.mark.parametrize( "constraint,version", [ ( "~=3.8", VersionRange( min=Version.from_parts(3, 8), max=Version.from_parts(4, 0), include_min=True, ), ), ( "== 3.8.*", VersionRange( min=Version.from_parts(3, 8), max=Version.from_parts(3, 9, 0), include_min=True, ), ), ( "~= 3.8", VersionRange(
def test_equality(): assert Version.parse("1.2.3") == Version.parse("01.2.3") assert Version.parse("1.2.3") == Version.parse("1.02.3") assert Version.parse("1.2.3") == Version.parse("1.2.03") assert Version.parse("1.2.3-1") == Version.parse("1.2.3-01") assert Version.parse("1.2.3+1") == Version.parse("1.2.3+01")
in_project_venv_dir: Path, in_project: bool | None, ): poetry.config.config["virtualenvs"]["in-project"] = in_project venv = manager.get() if in_project is False: assert venv.path != in_project_venv_dir else: assert venv.path == in_project_venv_dir def build_venv(path: Path | str, **__: Any) -> None: os.mkdir(str(path)) VERSION_3_7_1 = Version.parse("3.7.1") def check_output_wrapper( version: Version = VERSION_3_7_1, ) -> Callable[[str, Any, Any], str]: def check_output(cmd: str, *args: Any, **kwargs: Any) -> str: if "sys.version_info[:3]" in cmd: return version.text elif "sys.version_info[:2]" in cmd: return f"{version.major}.{version.minor}" elif '-c "import sys; print(sys.executable)"' in cmd: return f"/usr/bin/{cmd.split()[0]}" else: return str(Path("/prefix")) return check_output
def v080(): return Version.parse("0.8.0")
def v234() -> Version: return Version.parse("2.3.4")