示例#1
0
    def all_classifiers(self):
        classifiers = copy.copy(self.classifiers)

        # Automatically set python classifiers
        if self.python_versions == "*":
            python_constraint = parse_constraint("~2.7 || ^3.4")
        else:
            python_constraint = self.python_constraint

        for version in sorted(self.AVAILABLE_PYTHONS):
            if len(version) == 1:
                constraint = parse_constraint(version + ".*")
            else:
                constraint = Version.parse(version)

            if python_constraint.allows_any(constraint):
                classifiers.append(
                    "Programming Language :: Python :: {}".format(version)
                )

        # Automatically set license classifiers
        if self.license:
            classifiers.append(self.license.classifier)

        classifiers = set(classifiers)

        return sorted(classifiers)
示例#2
0
def format_python_constraint(constraint):
    """
    This helper will help in transforming
    disjunctive constraint into proper constraint.
    """
    if isinstance(constraint, Version) and constraint.precision < 3:
        # Transform 3.6 or 3
        if constraint.precision == 2:
            # 3.6
            constraint = parse_constraint("~{}.{}".format(
                constraint.major, constraint.minor))
        else:
            constraint = parse_constraint("^{}.0".format(constraint.major))

    if not isinstance(constraint, VersionUnion):
        return str(constraint)

    formatted = []
    accepted = []

    for version in PYTHON_VERSION:
        version_constraint = parse_constraint(version)
        matches = constraint.allows_any(version_constraint)
        if not matches:
            formatted.append("!=" + version)
        else:
            accepted.append(version)

    # Checking lower bound
    low = accepted[0]

    formatted.insert(0, ">=" + ".".join(low.split(".")[:2]))

    return ", ".join(formatted)
示例#3
0
    def all_classifiers(self):
        classifiers = copy.copy(self.classifiers)

        # Automatically set python classifiers
        if self.python_versions == "*":
            python_constraint = parse_constraint("~2.7 || ^3.4")
        else:
            python_constraint = self.python_constraint

        for version in sorted(self.AVAILABLE_PYTHONS):
            if len(version) == 1:
                constraint = parse_constraint(version + ".*")
            else:
                constraint = Version.parse(version)

            if python_constraint.allows_any(constraint):
                classifiers.append(
                    "Programming Language :: Python :: {}".format(version)
                )

        # Automatically set license classifiers
        if self.license:
            classifiers.append(self.license.classifier)

        classifiers = set(classifiers)

        return sorted(classifiers)
示例#4
0
def format_python_constraint(constraint):
    """
    This helper will help in transforming
    disjunctive constraint into proper constraint.
    """
    if isinstance(constraint, Version) and constraint.precision < 3:
        # Transform 3.6 or 3
        if constraint.precision == 2:
            # 3.6
            constraint = parse_constraint(
                "~{}.{}".format(constraint.major, constraint.minor)
            )
        else:
            constraint = parse_constraint("^{}.0".format(constraint.major))

    if not isinstance(constraint, VersionUnion):
        return str(constraint)

    formatted = []
    accepted = []

    for version in PYTHON_VERSION:
        version_constraint = parse_constraint(version)
        matches = constraint.allows_any(version_constraint)
        if not matches:
            formatted.append("!=" + version)
        else:
            accepted.append(version)

    # Checking lower bound
    low = accepted[0]

    formatted.insert(0, ">=" + ".".join(low.split(".")[:2]))

    return ", ".join(formatted)
示例#5
0
    def find_best_candidate(
        self,
        package_name,  # type: str
        target_package_version=None,  # type:  Union[str, None]
        allow_prereleases=False,  # type: bool
    ):  # type: (...) -> Union[Package, bool]
        """
        Given a package name and optional version,
        returns the latest Package that matches
        """
        if target_package_version:
            constraint = parse_constraint(target_package_version)
        else:
            constraint = parse_constraint("*")

        candidates = self._pool.find_packages(
            package_name, constraint, allow_prereleases=allow_prereleases
        )

        if not candidates:
            return False

        dependency = Dependency(package_name, constraint)

        # Select highest version if we have many
        package = candidates[0]
        for candidate in candidates:
            if candidate.is_prerelease() and not dependency.allows_prereleases():
                continue

            # Select highest version of the two
            if package.version < candidate.version:
                package = candidate

        return package
示例#6
0
    def __init__(
            self,
            name,  # type: str
            constraint,  # type: str
            optional=False,  # type: bool
            category="main",  # type: str
            allows_prereleases=False,  # type: bool
    ):
        self._name = canonicalize_name(name)
        self._pretty_name = name

        try:
            if not isinstance(constraint, VersionConstraint):
                self._constraint = parse_constraint(constraint)
            else:
                self._constraint = constraint
        except ValueError:
            self._constraint = parse_constraint("*")

        self._pretty_constraint = str(constraint)
        self._optional = optional
        self._category = category
        self._allows_prereleases = allows_prereleases

        self._python_versions = "*"
        self._python_constraint = parse_constraint("*")
        self._platform = "*"
        self._platform_constraint = EmptyConstraint()

        self._extras = []
        self._in_extras = []

        self._activated = not self._optional

        self.is_root = False
示例#7
0
    def find_best_candidate(
            self,
            package_name,  # type: str
            target_package_version=None,  # type:  Union[str, None]
            allow_prereleases=False,  # type: bool
    ):  # type: (...) -> Union[Package, bool]
        """
        Given a package name and optional version,
        returns the latest Package that matches
        """
        if target_package_version:
            constraint = parse_constraint(target_package_version)
        else:
            constraint = parse_constraint("*")

        candidates = self._pool.find_packages(
            package_name, constraint, allow_prereleases=allow_prereleases)

        if not candidates:
            return False

        dependency = Dependency(package_name, constraint)

        # Select highest version if we have many
        package = candidates[0]
        for candidate in candidates:
            if candidate.is_prerelease(
            ) and not dependency.allows_prereleases():
                continue

            # Select highest version of the two
            if package.version < candidate.version:
                package = candidate

        return package
示例#8
0
    def handle(self):
        from poetry.packages import Dependency
        from poetry.packages import ProjectPackage
        from poetry.puzzle import Solver
        from poetry.repositories.repository import Repository
        from poetry.semver import parse_constraint

        packages = self.argument("package")

        if not packages:
            package = self.poetry.package
        else:
            requirements = self._determine_requirements(packages)
            requirements = self._format_requirements(requirements)

            # validate requirements format
            for constraint in requirements.values():
                parse_constraint(constraint)

            dependencies = []
            for name, constraint in requirements.items():
                dep = Dependency(name, constraint)
                extras = []
                for extra in self.option("extras"):
                    if " " in extra:
                        extras += [e.strip() for e in extra.split(" ")]
                    else:
                        extras.append(extra)

                for ex in extras:
                    dep.extras.append(ex)

                dependencies.append(dep)

            package = ProjectPackage(self.poetry.package.name,
                                     self.poetry.package.version)

            package.python_versions = (self.option("python")
                                       or self.poetry.package.python_versions)
            for dep in dependencies:
                package.requires.append(dep)

        solver = Solver(package, self.poetry.pool, Repository(), Repository(),
                        self.output)

        ops = solver.solve()

        self.line("")
        self.line("Resolution results:")
        self.line("")

        for op in ops:
            package = op.package
            self.line("  - <info>{}</info> (<comment>{}</comment>)".format(
                package.name, package.version))
            if package.requirements:
                for req_name, req_value in package.requirements.items():
                    self.line("    - {}: {}".format(req_name, req_value))
示例#9
0
    def handle(self):
        from poetry.layouts import layout
        from poetry.semver import parse_constraint
        from poetry.utils._compat import Path
        from poetry.utils.env import SystemEnv
        from poetry.vcs.git import GitConfig

        if self.option("src"):
            layout_ = layout("src")
        else:
            layout_ = layout("standard")

        path = Path.cwd() / Path(self.argument("path"))
        name = self.option("name")
        if not name:
            name = path.name

        if path.exists():
            if list(path.glob("*")):
                # Directory is not empty. Aborting.
                raise RuntimeError("Destination <fg=yellow>{}</> "
                                   "exists and is not empty".format(path))

        readme_format = "rst"

        config = GitConfig()
        author = None
        if config.get("user.name"):
            author = config["user.name"]
            author_email = config.get("user.email")
            if author_email:
                author += " <{}>".format(author_email)

        current_env = SystemEnv(Path(sys.executable))
        default_python = "^{}".format(".".join(
            str(v) for v in current_env.version_info[:2]))

        dev_dependencies = {}
        python_constraint = parse_constraint(default_python)
        if parse_constraint("<3.5").allows_any(python_constraint):
            dev_dependencies["pytest"] = "^4.6"
        if parse_constraint(">=3.5").allows_all(python_constraint):
            dev_dependencies["pytest"] = "^5.2"

        layout_ = layout_(
            name,
            "0.1.0",
            author=author,
            readme_format=readme_format,
            python=default_python,
            dev_dependencies=dev_dependencies,
        )
        layout_.create(path)

        self.line("Created package <info>{}</> in <fg=blue>{}</>".format(
            module_name(name), path.relative_to(Path.cwd())))
示例#10
0
def test_format_python_constraint_single_version():
    constraint = parse_constraint("3.6")

    result = format_python_constraint(constraint)

    assert result == ">=3.6,<3.7"

    constraint = parse_constraint("3")

    result = format_python_constraint(constraint)

    assert result == ">=3.0,<4.0"
示例#11
0
    def _determine_requirements(self,
                                requires):  # type: (List[str]) -> List[str]
        from poetry.semver import parse_constraint

        if not requires:
            return []

        requires = self._parse_name_version_pairs(requires)
        for requirement in requires:
            if "version" in requirement:
                parse_constraint(requirement["version"])

        return requires
示例#12
0
文件: helpers.py 项目: ofek/poetry
def format_python_constraint(constraint):
    """
    This helper will help in transforming
    disjunctive constraint into proper constraint.
    """
    if not isinstance(constraint, VersionUnion):
        return str(constraint)

    formatted = []
    accepted = []

    for version in PYTHON_VERSION:
        version_constraint = parse_constraint(version)
        matches = constraint.allows_any(version_constraint)
        if not matches:
            formatted.append('!=' + version)
        else:
            accepted.append(version)

    # Checking lower bound
    low = accepted[0]

    formatted.insert(0, '>=' + '.'.join(low.split('.')[:2]))

    return ', '.join(formatted)
示例#13
0
    def set_env(self, event, event_name, _):  # type: (PreHandleEvent, str, _) -> None
        from poetry.semver import parse_constraint
        from poetry.utils.env import EnvManager

        command = event.command.config.handler  # type: EnvCommand
        if not isinstance(command, EnvCommand):
            return

        io = event.io
        poetry = command.poetry

        env_manager = EnvManager(poetry.config)

        # Checking compatibility of the current environment with
        # the python dependency specified in pyproject.toml
        current_env = env_manager.get(poetry.file.parent)
        supported_python = poetry.package.python_constraint
        current_python = parse_constraint(
            ".".join(str(v) for v in current_env.version_info[:3])
        )

        if not supported_python.allows(current_python):
            raise RuntimeError(
                "The current Python version ({}) is not supported by the project ({})\n"
                "Please activate a compatible Python version.".format(
                    current_python, poetry.package.python_versions
                )
            )

        env = env_manager.create_venv(poetry.file.parent, io, poetry.package.name)

        if env.is_venv() and io.is_verbose():
            io.write_line("Using virtualenv: <comment>{}</>".format(env.path))

        command.set_env(env)
示例#14
0
    def get_release_info(self, name, version):  # type: (str, str) -> dict
        """
        Return the release information given a package name and a version.

        The information is returned from the cache if it exists
        or retrieved from the remote server.
        """
        if self._disable_cache:
            return self._get_release_info(name, version)

        cached = self._cache.remember_forever(
            "{}:{}".format(name, version),
            lambda: self._get_release_info(name, version))

        cache_version = cached.get("_cache_version", "0.0.0")
        if parse_constraint(cache_version) != self.CACHE_VERSION:
            # The cache must be updated
            self._log(
                "The cache for {} {} is outdated. Refreshing.".format(
                    name, version),
                level="debug",
            )
            cached = self._get_release_info(name, version)

            self._cache.forever("{}:{}".format(name, version), cached)

        return cached
示例#15
0
def get_aiida_version_poetry(pyproject):
    """Get AiiDA version that this plugin is compatible with from a pyproject.toml.
    """
    from poetry.semver import parse_constraint  # pylint: disable=import-outside-toplevel

    try:
        deps = pyproject['tool']['poetry']['dependencies']
    except KeyError:
        return None

    for name, data in deps.items():
        if name not in ['aiida-core', 'aiida_core', 'aiida']:
            continue

        try:  # data is either a dict {"version": ..., "extras": ["..", ], }
            version = data['version']
        except TypeError:  # or directly the version string
            version = data

        break
    else:
        print('  >> WARNING! AiiDA version not specified')
        return None

    try:
        return str(parse_constraint(version))
    except ValueError:
        print(
            '  >> WARNING: Invalid version encountered in Poetry pyproject.toml for aiida-core'
        )

    return None
示例#16
0
def get_aiida_version_poetry(pyproject):
    """Get AiiDA version that this plugin is compatible with from a pyproject.toml.
    """

    try:
        deps = pyproject["tool"]["poetry"]["dependencies"]
    except KeyError:
        return None

    for name, data in deps.items():
        if name not in ["aiida-core", "aiida_core", "aiida"]:
            continue

        try:  # data is either a dict {"version": ..., "extras": ["..", ], }
            version = data["version"]
        except TypeError:  # or directly the version string
            version = data

        break
    else:
        print("  >> WARNING! AiiDA version not specified")
        return None

    from poetry.semver import parse_constraint

    try:
        return str(parse_constraint(version))
    except ValueError:
        print(
            "  >> WARNING: Invalid version encountered in Poetry pyproject.toml for aiida-core"
        )

    return None
示例#17
0
    def solve_in_compatibility_mode(self, constraints, use_latest=None):
        locked = {}
        for package in self._locked.packages:
            locked[package.name] = DependencyPackage(package.to_dependency(),
                                                     package)

        packages = []
        depths = []
        for constraint in constraints:
            constraint = parse_constraint(constraint)
            intersection = constraint.intersect(
                self._package.python_constraint)

            self._provider.debug(
                "<comment>Retrying dependency resolution "
                "for Python ({}).</comment>".format(intersection))
            with self._package.with_python_versions(str(intersection)):
                _packages, _depths = self._solve(use_latest=use_latest)
                for index, package in enumerate(_packages):
                    if package not in packages:
                        packages.append(package)
                        depths.append(_depths[index])
                        continue
                    else:
                        idx = packages.index(package)
                        pkg = packages[idx]
                        depths[idx] = max(depths[idx], _depths[index])
                        pkg.marker = pkg.marker.union(package.marker)

                        for dep in package.requires:
                            if dep not in pkg.requires:
                                pkg.requires.append(dep)

        return packages, depths
示例#18
0
文件: solver.py 项目: shawegit/poetry
    def solve_in_compatibility_mode(self, constraints, use_latest=None):
        locked = {}
        for package in self._locked.packages:
            locked[package.name] = package

        packages = []
        depths = []
        for constraint in constraints:
            constraint = parse_constraint(constraint)
            intersection = constraint.intersect(self._package.python_constraint)

            self._provider.debug(
                "<comment>Retrying dependency resolution "
                "for Python ({}).</comment>".format(intersection)
            )
            with self._package.with_python_versions(str(intersection)):
                _packages, _depths = self._solve(use_latest=use_latest)
                for index, package in enumerate(_packages):
                    if package not in packages:
                        packages.append(package)
                        depths.append(_depths[index])
                        continue

                    current_package = packages[packages.index(package)]
                    for dep in package.requires:
                        if dep not in current_package.requires:
                            current_package.requires.append(dep)

        return packages, depths
示例#19
0
    def _get_lock_data(self):  # type: () -> dict
        if not self._lock.exists():
            raise RuntimeError("No lockfile found. Unable to read locked packages")

        try:
            lock_data = self._lock.read()
        except TOMLKitError as e:
            raise RuntimeError("Unable to read the lock file ({}).".format(e))

        lock_version = Version.parse(lock_data["metadata"].get("lock-version", "1.0"))
        current_version = Version.parse(self._VERSION)
        accepted_versions = parse_constraint(
            "^{}".format(Version(current_version.major, current_version.minor))
        )
        lock_version_allowed = accepted_versions.allows(lock_version)
        if lock_version_allowed and current_version < lock_version:
            logger.warning(
                "The lock file might not be compatible with the current version of Poetry.\n"
                "Upgrade Poetry to ensure the lock file is read properly or, alternatively, "
                "regenerate the lock file with the `poetry lock` command."
            )
        elif not lock_version_allowed:
            raise RuntimeError(
                "The lock file is not compatible with the current version of Poetry.\n"
                "Upgrade Poetry to be able to read the lock file or, alternatively, "
                "regenerate the lock file with the `poetry lock` command."
            )

        return lock_data
示例#20
0
    def _filter_operations(
            self, ops, repo):  # type: (List[Operation], Repository) -> None
        extra_packages = [p.name for p in self._get_extra_packages(repo)]
        for op in ops:
            if isinstance(op, Update):
                package = op.target_package
            else:
                package = op.package

            if op.job_type == "uninstall":
                continue

            if package.name in self._develop and package.source_type == "directory":
                package.develop = True
                if op.skipped:
                    op.unskip()

            python = Version.parse(".".join(
                [str(i) for i in self._venv.version_info[:3]]))
            if "python" in package.requirements:
                python_constraint = parse_constraint(
                    package.requirements["python"])
                if not python_constraint.allows(python):
                    # Incompatible python versions
                    op.skip("Not needed for the current python version")
                    continue

            if not package.python_constraint.allows(python):
                op.skip("Not needed for the current python version")
                continue

            if "platform" in package.requirements:
                platform_constraint = GenericConstraint.parse(
                    package.requirements["platform"])
                if not platform_constraint.matches(
                        GenericConstraint("=", sys.platform)):
                    # Incompatible systems
                    op.skip("Not needed for the current platform")
                    continue

            if self._update:
                extras = {}
                for extra, deps in self._package.extras.items():
                    extras[extra] = [dep.name for dep in deps]
            else:
                extras = {}
                for extra, deps in self._locker.lock_data.get("extras",
                                                              {}).items():
                    extras[extra] = [dep.lower() for dep in deps]

            # If a package is optional and not requested
            # in any extra we skip it
            if package.optional:
                if package.name not in extra_packages:
                    op.skip("Not required")

            # If the package is a dev package and dev packages
            # are not requests, we skip it
            if package.category == "dev" and not self.is_dev_mode():
                op.skip("Dev dependencies not requested")
示例#21
0
    def __init__(self, requirement_string):
        try:
            req = REQUIREMENT.parseString(requirement_string)
        except ParseException as e:
            raise InvalidRequirement(
                'Invalid requirement, parse error at "{0!r}"'.format(
                    requirement_string[e.loc : e.loc + 8]
                )
            )

        self.name = req.name
        if req.url:
            parsed_url = urlparse.urlparse(req.url)
            if not (parsed_url.scheme and parsed_url.netloc) or (
                not parsed_url.scheme and not parsed_url.netloc
            ):
                raise InvalidRequirement("Invalid URL given")
            self.url = req.url
        else:
            self.url = None

        self.extras = set(req.extras.asList() if req.extras else [])
        constraint = req.specifier
        if not constraint:
            constraint = "*"

        self.constraint = parse_constraint(constraint)
        self.pretty_constraint = constraint

        self.marker = req.marker if req.marker else None
示例#22
0
    def __init__(self, requirement_string):
        try:
            req = REQUIREMENT.parseString(requirement_string)
        except ParseException as e:
            raise InvalidRequirement(
                'Invalid requirement, parse error at "{0!r}"'.format(
                    requirement_string[e.loc : e.loc + 8]
                )
            )

        self.name = req.name
        if req.url:
            parsed_url = urlparse.urlparse(req.url)
            if not (parsed_url.scheme and parsed_url.netloc) or (
                not parsed_url.scheme and not parsed_url.netloc
            ):
                raise InvalidRequirement("Invalid URL given")
            self.url = req.url
        else:
            self.url = None

        self.extras = set(req.extras.asList() if req.extras else [])
        constraint = req.specifier
        if not constraint:
            constraint = "*"

        self.constraint = parse_constraint(constraint)
        self.pretty_constraint = constraint

        self.marker = req.marker if req.marker else None
示例#23
0
def get_python_constraint_from_marker(
    marker, ):  # type: (BaseMarker) -> VersionConstraint
    python_marker = marker.only("python_version")
    if python_marker.is_any():
        return VersionRange()

    if python_marker.is_empty():
        return EmptyConstraint()

    markers = convert_markers(marker)

    ors = []
    for or_ in markers["python_version"]:
        ands = []
        for op, version in or_:
            # Expand python version
            if op == "==":
                version = "~" + version
                op = ""
            elif op == "!=":
                version += ".*"
            elif op in ("<=", ">"):
                parsed_version = Version.parse(version)
                if parsed_version.precision == 1:
                    if op == "<=":
                        op = "<"
                        version = parsed_version.next_major.text
                    elif op == ">":
                        op = ">="
                        version = parsed_version.next_major.text
                elif parsed_version.precision == 2:
                    if op == "<=":
                        op = "<"
                        version = parsed_version.next_minor.text
                    elif op == ">":
                        op = ">="
                        version = parsed_version.next_minor.text
            elif op in ("in", "not in"):
                versions = []
                for v in re.split("[ ,]+", version):
                    split = v.split(".")
                    if len(split) in [1, 2]:
                        split.append("*")
                        op_ = "" if op == "in" else "!="
                    else:
                        op_ = "==" if op == "in" else "!="

                    versions.append(op_ + ".".join(split))

                glue = " || " if op == "in" else ", "
                if versions:
                    ands.append(glue.join(versions))

                continue

            ands.append("{}{}".format(op, version))

        ors.append(" ".join(ands))

    return parse_constraint(" || ".join(ors))
示例#24
0
    def initialize(self, i, o):
        from poetry.semver import parse_constraint
        from poetry.utils.env import Env

        super(EnvCommand, self).initialize(i, o)

        # Checking compatibility of the current environment with
        # the python dependency specified in pyproject.toml
        current_env = Env.get()
        supported_python = self.poetry.package.python_constraint
        current_python = parse_constraint(".".join(
            str(v) for v in current_env.version_info[:3]))

        if not supported_python.allows(current_python):
            raise RuntimeError(
                "The current Python version ({}) is not supported by the project ({})\n"
                "Please activate a compatible Python version.".format(
                    current_python, self.poetry.package.python_versions))

        self._env = Env.create_venv(o,
                                    self.poetry.package.name,
                                    cwd=self.poetry.file.parent)

        if self._env.is_venv() and o.is_verbose():
            o.writeln("Using virtualenv: <comment>{}</>".format(
                self._env.path))
示例#25
0
    def __init__(
            self,
            name,  # type: str
            constraint,  # type: str
            optional=False,  # type: bool
            category="main",  # type: str
            allows_prereleases=False,  # type: bool
            source_name=None,  # type: Optional[str]
            global_options=[],  # type: list[str]
    ):
        self._name = canonicalize_name(name)
        self._pretty_name = name

        try:
            if not isinstance(constraint, VersionConstraint):
                self._constraint = parse_constraint(constraint)
            else:
                self._constraint = constraint
        except ValueError:
            self._constraint = parse_constraint("*")

        self._pretty_constraint = str(constraint)
        self._optional = optional
        self._category = category

        if isinstance(self._constraint, VersionRange) and self._constraint.min:
            allows_prereleases = (allows_prereleases
                                  or self._constraint.min.is_prerelease())

        self._allows_prereleases = allows_prereleases
        self._source_name = source_name

        self._python_versions = "*"
        self._python_constraint = parse_constraint("*")
        self._transitive_python_versions = None
        self._transitive_python_constraint = None
        self._transitive_marker = None

        self._extras = []
        self._in_extras = []

        self.global_opts = list(global_options)

        self._activated = not self._optional

        self.is_root = False
        self.marker = AnyMarker()
示例#26
0
    def find_packages(self,
                      name,
                      constraint=None,
                      extras=None,
                      allow_prereleases=False):
        packages = []

        if constraint is None:
            constraint = "*"

        if not isinstance(constraint, VersionConstraint):
            constraint = parse_constraint(constraint)

        if isinstance(constraint, VersionRange):
            if (constraint.max is not None and constraint.max.is_prerelease()
                    or constraint.min is not None
                    and constraint.min.is_prerelease()):
                allow_prereleases = True

        key = name
        if not constraint.is_any():
            key = "{}:{}".format(key, str(constraint))

        if self._cache.store("matches").has(key):
            versions = self._cache.store("matches").get(key)
        else:
            page = self._get("/{}/".format(
                canonicalize_name(name).replace(".", "-")))
            if page is None:
                return []

            versions = []
            for version in page.versions:
                if version.is_prerelease() and not allow_prereleases:
                    continue

                if constraint.allows(version):
                    versions.append(version)

            self._cache.store("matches").put(key, versions, 5)

        for version in versions:
            package = Package(name, version)
            package.source_type = "legacy"
            package.source_reference = self.name
            package.source_url = self._url

            if extras is not None:
                package.requires_extras = extras

            packages.append(package)

        self._log(
            "{} packages found for {} {}".format(len(packages), name,
                                                 str(constraint)),
            level="debug",
        )

        return packages
示例#27
0
 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)))
示例#28
0
    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))
示例#29
0
    def __init__(self, name, version, pretty_version=None):
        super(ProjectPackage, self).__init__(name, version, pretty_version)

        self.build = None
        self.packages = []
        self.include = []
        self.exclude = []

        if self._python_versions == "*":
            self._python_constraint = parse_constraint("~2.7 || >=3.4")
示例#30
0
    def find_packages(
            self,
            name,  # type: str
            constraint=None,  # type: Union[VersionConstraint, str, None]
            extras=None,  # type: Union[list, None]
            allow_prereleases=False,  # type: bool
    ):  # type: (...) -> List[Package]
        """
        Find packages on the remote server.
        """
        if constraint is None:
            constraint = "*"

        if not isinstance(constraint, VersionConstraint):
            constraint = parse_constraint(constraint)

        if isinstance(constraint, VersionRange):
            if (constraint.max is not None and constraint.max.is_prerelease()
                    or constraint.min is not None
                    and constraint.min.is_prerelease()):
                allow_prereleases = True

        info = self.get_package_info(name)

        packages = []

        for version, release in info["releases"].items():
            if not release:
                # Bad release
                self._log(
                    "No release information found for {}-{}, skipping".format(
                        name, version),
                    level="debug",
                )
                continue

            package = Package(name, version)

            if package.is_prerelease() and not allow_prereleases:
                continue

            if not constraint or (constraint
                                  and constraint.allows(package.version)):
                if extras is not None:
                    package.requires_extras = extras

                packages.append(package)

        self._log(
            "{} packages found for {} {}".format(len(packages), name,
                                                 str(constraint)),
            level="debug",
        )

        return packages
示例#31
0
文件: package.py 项目: uSpike/poetry
    def __init__(self, name, version, pretty_version=None):
        """
        Creates a new in memory package.
        """
        self._pretty_name = name
        self._name = canonicalize_name(name)

        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.homepage = None
        self.repository_url = None
        self.keywords = []
        self._license = None
        self.readme = None

        self.source_type = ""
        self.source_reference = ""
        self.source_url = ""

        self.requires = []
        self.dev_requires = []
        self.extras = {}
        self.requires_extras = []

        self.category = "main"
        self.hashes = []
        self.optional = False

        # Requirements for making it mandatory
        self.requirements = {}

        self.build = None
        self.include = []
        self.exclude = []

        self.classifiers = []

        self._python_versions = "*"
        self._python_constraint = parse_constraint("*")
        self._platform = "*"
        self._platform_constraint = EmptyConstraint()

        self.root_dir = None

        self.develop = False
示例#32
0
    def __init__(
        self,
        name,  # type: str
        constraint,  # type: str
        optional=False,  # type: bool
        category="main",  # type: str
        allows_prereleases=False,  # type: bool
    ):
        self._name = canonicalize_name(name)
        self._pretty_name = name

        try:
            if not isinstance(constraint, VersionConstraint):
                self._constraint = parse_constraint(constraint)
            else:
                self._constraint = constraint
        except ValueError:
            self._constraint = parse_constraint("*")

        self._pretty_constraint = str(constraint)
        self._optional = optional
        self._category = category

        if isinstance(self._constraint, VersionRange) and self._constraint.min:
            allows_prereleases = (
                allows_prereleases or self._constraint.min.is_prerelease()
            )

        self._allows_prereleases = allows_prereleases

        self._python_versions = "*"
        self._python_constraint = parse_constraint("*")
        self._platform = "*"
        self._platform_constraint = EmptyConstraint()

        self._extras = []
        self._in_extras = []

        self._activated = not self._optional

        self.is_root = False
示例#33
0
    def find_packages(
        self,
        name,  # type: str
        constraint=None,  # type: Union[VersionConstraint, str, None]
        extras=None,  # type: Union[list, None]
        allow_prereleases=False,  # type: bool
    ):  # type: (...) -> List[Package]
        """
        Find packages on the remote server.
        """
        if constraint is None:
            constraint = "*"

        if not isinstance(constraint, VersionConstraint):
            constraint = parse_constraint(constraint)

        info = self.get_package_info(name)

        packages = []

        for version, release in info["releases"].items():
            if not release:
                # Bad release
                self._log(
                    "No release information found for {}-{}, skipping".format(
                        name, version
                    ),
                    level="debug",
                )
                continue

            package = Package(name, version)

            if (
                package.is_prerelease()
                and not allow_prereleases
                and not constraint.allows(package.version)
            ):
                continue

            if not constraint or (constraint and constraint.allows(package.version)):
                if extras is not None:
                    package.requires_extras = extras

                packages.append(package)

        self._log(
            "{} packages found for {} {}".format(len(packages), name, str(constraint)),
            level="debug",
        )

        return packages
示例#34
0
    def __init__(self, name, version, pretty_version=None):
        """
        Creates a new in memory package.
        """
        self._pretty_name = name
        self._name = canonicalize_name(name)

        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.source_name = ""
        self.source_type = ""
        self.source_reference = ""
        self.source_url = ""

        self.requires = []
        self.dev_requires = []
        self.extras = {}
        self.requires_extras = []

        self.category = "main"
        self.hashes = []
        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 = True
示例#35
0
    def check_version(self, poet, python_version):

        python_constraint = self.poet.package.python_constraint
        wished_constraint = parse_constraint(python_version)

        if python_constraint.allows(wished_constraint):
            return True
        else:
            raise RhymException(
                "The specified python version {} doesn't feet with pytproject.toml constraint : {}".format(
                    python_version, python_constraint
                )
            )
示例#36
0
    def find_packages(
        self, name, constraint=None, extras=None, allow_prereleases=False
    ):
        name = name.lower()
        packages = []
        if extras is None:
            extras = []

        if constraint is None:
            constraint = "*"

        if not isinstance(constraint, VersionConstraint):
            constraint = parse_constraint(constraint)

        if isinstance(constraint, VersionRange):
            if (
                constraint.max is not None
                and constraint.max.is_prerelease()
                or constraint.min is not None
                and constraint.min.is_prerelease()
            ):
                allow_prereleases = True

        for package in self.packages:
            if name == package.name:
                if (
                    package.is_prerelease()
                    and not allow_prereleases
                    and not package.source_type
                ):
                    # If prereleases are not allowed and the package is a prerelease
                    # and is a standard package then we skip it
                    continue

                if constraint.allows(package.version):
                    for dep in package.requires:
                        for extra in extras:
                            if extra not in package.extras:
                                continue

                            reqs = package.extras[extra]
                            for req in reqs:
                                if req.name == dep.name:
                                    dep.activate()

                    if extras:
                        package.requires_extras = extras

                    packages.append(package)

        return packages
示例#37
0
    def get_update_status(self, latest, package):
        from poetry.semver import parse_constraint

        if latest.full_pretty_version == package.full_pretty_version:
            return "up-to-date"

        constraint = parse_constraint("^" + package.pretty_version)

        if latest.version and constraint.allows(latest.version):
            # It needs an immediate semver-compliant upgrade
            return "semver-safe-update"

        # it needs an upgrade but has potential BC breaks so is not urgent
        return "update-possible"
示例#38
0
    def __init__(self, name, version, pretty_version=None):
        """
        Creates a new in memory package.
        """
        self._pretty_name = name
        self._name = canonicalize_name(name)

        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.homepage = None
        self.repository_url = None
        self.keywords = []
        self._license = None
        self.readme = None

        self.source_type = ""
        self.source_reference = ""
        self.source_url = ""

        self.requires = []
        self.dev_requires = []
        self.extras = {}
        self.requires_extras = []

        self.category = "main"
        self.hashes = []
        self.optional = False

        # Requirements for making it mandatory
        self.requirements = {}

        self.classifiers = []

        self._python_versions = "*"
        self._python_constraint = parse_constraint("*")
        self._platform = "*"
        self._platform_constraint = EmptyConstraint()

        self.root_dir = None

        self.develop = False
示例#39
0
文件: show.py 项目: shawegit/poetry
    def get_update_status(self, latest, package):
        from poetry.semver import parse_constraint

        if latest.full_pretty_version == package.full_pretty_version:
            return "up-to-date"

        constraint = parse_constraint("^" + package.pretty_version)

        if latest.version and constraint.allows(latest.version):
            # It needs an immediate semver-compliant upgrade
            return "semver-safe-update"

        # it needs an upgrade but has potential BC breaks so is not urgent
        return "update-possible"
示例#40
0
    def find_packages(
        self, name, constraint=None, extras=None, allow_prereleases=False
    ):
        packages = []

        if constraint is not None and not isinstance(constraint, VersionConstraint):
            constraint = parse_constraint(constraint)

        key = name
        if constraint:
            key = "{}:{}".format(key, str(constraint))

        if self._cache.store("matches").has(key):
            versions = self._cache.store("matches").get(key)
        else:
            page = self._get("/{}/".format(canonicalize_name(name).replace(".", "-")))
            if page is None:
                return []

            versions = []
            for version in page.versions:
                if not constraint or (constraint and constraint.allows(version)):
                    versions.append(version)

            self._cache.store("matches").put(key, versions, 5)

        for version in versions:
            package = Package(name, version)
            package.source_type = "legacy"
            package.source_url = self._url

            if extras is not None:
                package.requires_extras = extras

            packages.append(package)

        self._log(
            "{} packages found for {} {}".format(len(packages), name, str(constraint)),
            level="debug",
        )

        return packages
示例#41
0
    def find_packages(
        self, name, constraint=None, extras=None, allow_prereleases=False
    ):
        name = name.lower()
        packages = []
        if extras is None:
            extras = []

        if constraint is None:
            constraint = "*"

        if not isinstance(constraint, VersionConstraint):
            constraint = parse_constraint(constraint)

        for package in self.packages:
            if name == package.name:
                if (
                    package.is_prerelease()
                    and not allow_prereleases
                    and not constraint.allows(package.version)
                ):
                    continue

                if constraint is None or constraint.allows(package.version):
                    for dep in package.requires:
                        for extra in extras:
                            if extra not in package.extras:
                                continue

                            reqs = package.extras[extra]
                            for req in reqs:
                                if req.name == dep.name:
                                    dep.activate()

                    packages.append(package)

        return packages
示例#42
0
def test_parse_constraint_tilde(input, constraint):
    assert parse_constraint(input) == constraint
示例#43
0
def test_format_python_constraint():
    constraint = parse_constraint("~2.7 || ^3.6")

    result = format_python_constraint(constraint)

    assert result == ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"
示例#44
0
    def _filter_operations(
        self, ops, repo
    ):  # type: (List[Operation], Repository) -> None
        extra_packages = [p.name for p in self._get_extra_packages(repo)]
        for op in ops:
            if isinstance(op, Update):
                package = op.target_package
            else:
                package = op.package

            if op.job_type == "uninstall":
                continue

            if package.name in self._develop and package.source_type == "directory":
                package.develop = True
                if op.skipped:
                    op.unskip()

            python = Version.parse(
                ".".join([str(i) for i in self._venv.version_info[:3]])
            )
            if "python" in package.requirements:
                python_constraint = parse_constraint(package.requirements["python"])
                if not python_constraint.allows(python):
                    # Incompatible python versions
                    op.skip("Not needed for the current python version")
                    continue

            if not package.python_constraint.allows(python):
                op.skip("Not needed for the current python version")
                continue

            if "platform" in package.requirements:
                platform_constraint = GenericConstraint.parse(
                    package.requirements["platform"]
                )
                if not platform_constraint.matches(
                    GenericConstraint("=", sys.platform)
                ):
                    # Incompatible systems
                    op.skip("Not needed for the current platform")
                    continue

            if self._update:
                extras = {}
                for extra, deps in self._package.extras.items():
                    extras[extra] = [dep.name for dep in deps]
            else:
                extras = {}
                for extra, deps in self._locker.lock_data.get("extras", {}).items():
                    extras[extra] = [dep.lower() for dep in deps]

            # If a package is optional and not requested
            # in any extra we skip it
            if package.optional:
                if package.name not in extra_packages:
                    op.skip("Not required")

            # If the package is a dev package and dev packages
            # are not requests, we skip it
            if package.category == "dev" and not self.is_dev_mode():
                op.skip("Dev dependencies not requested")
示例#45
0
文件: add.py 项目: singulared/poetry
    def handle(self):
        from poetry.installation import Installer
        from poetry.semver import parse_constraint
        from tomlkit import inline_table

        packages = self.argument("name")
        is_dev = self.option("dev")

        if (self.option("git") or self.option("path") or self.option("extras")) and len(
            packages
        ) > 1:
            raise ValueError(
                "You can only specify one package "
                "when using the --git or --path options"
            )

        if self.option("git") and self.option("path"):
            raise RuntimeError("--git and --path cannot be used at the same time")

        section = "dependencies"
        if is_dev:
            section = "dev-dependencies"

        original_content = self.poetry.file.read()
        content = self.poetry.file.read()
        poetry_content = content["tool"]["poetry"]

        if section not in poetry_content:
            poetry_content[section] = {}

        for name in packages:
            for key in poetry_content[section]:
                if key.lower() == name.lower():
                    raise ValueError("Package {} is already present".format(name))

        if self.option("git") or self.option("path"):
            requirements = {packages[0]: ""}
        else:
            requirements = self._determine_requirements(
                packages, allow_prereleases=self.option("allow-prereleases")
            )
            requirements = self._format_requirements(requirements)

            # validate requirements format
            for constraint in requirements.values():
                parse_constraint(constraint)

        for name, _constraint in requirements.items():
            constraint = inline_table()
            constraint["version"] = _constraint

            if self.option("git"):
                del constraint["version"]

                constraint["git"] = self.option("git")
            elif self.option("path"):
                del constraint["version"]

                constraint["path"] = self.option("path")

            if self.option("optional"):
                constraint["optional"] = True

            if self.option("allow-prereleases"):
                constraint["allows-prereleases"] = True

            if self.option("extras"):
                extras = []
                for extra in self.option("extras"):
                    if " " in extra:
                        extras += [e.strip() for e in extra.split(" ")]
                    else:
                        extras.append(extra)

                constraint["extras"] = self.option("extras")

            if self.option("python"):
                constraint["python"] = self.option("python")

            if self.option("platform"):
                constraint["platform"] = self.option("platform")

            if len(constraint) == 1 and "version" in constraint:
                constraint = constraint["version"]

            poetry_content[section][name] = constraint

        # Write new content
        self.poetry.file.write(content)

        # Cosmetic new line
        self.line("")

        # Update packages
        self.reset_poetry()

        installer = Installer(
            self.output,
            self.venv,
            self.poetry.package,
            self.poetry.locker,
            self.poetry.pool,
        )

        installer.dry_run(self.option("dry-run"))
        installer.update(True)
        installer.whitelist(requirements)

        try:
            status = installer.run()
        except Exception:
            self.poetry.file.write(original_content)

            raise

        if status != 0 or self.option("dry-run"):
            # Revert changes
            if not self.option("dry-run"):
                self.error(
                    "\n"
                    "Addition failed, reverting pyproject.toml "
                    "to its original content."
                )

            self.poetry.file.write(original_content)

        return status
示例#46
0
文件: show.py 项目: shawegit/poetry
    def handle(self):
        from poetry.packages.constraints.generic_constraint import GenericConstraint
        from poetry.repositories.installed_repository import InstalledRepository
        from poetry.semver import Version
        from poetry.semver import parse_constraint

        package = self.argument("package")

        if self.option("tree"):
            self.init_styles()

        if self.option("outdated"):
            self.input.set_option("latest", True)

        locked_repo = self.poetry.locker.locked_repository(True)

        # Show tree view if requested
        if self.option("tree") and not package:
            requires = self.poetry.package.requires + self.poetry.package.dev_requires
            packages = locked_repo.packages
            for package in packages:
                for require in requires:
                    if package.name == require.name:
                        self.display_package_tree(package, locked_repo)
                        break

            return 0

        table = self.table(style="compact")
        table.get_style().set_vertical_border_char("")
        locked_packages = locked_repo.packages

        if package:
            pkg = None
            for locked in locked_packages:
                if package.lower() == locked.name:
                    pkg = locked
                    break

            if not pkg:
                raise ValueError("Package {} not found".format(package))

            if self.option("tree"):
                self.display_package_tree(pkg, locked_repo)

                return 0

            rows = [
                ["<info>name</>", " : <fg=cyan>{}</>".format(pkg.pretty_name)],
                ["<info>version</>", " : <comment>{}</>".format(pkg.pretty_version)],
                ["<info>description</>", " : {}".format(pkg.description)],
            ]

            table.add_rows(rows)
            table.render()

            if pkg.requires:
                self.line("")
                self.line("<info>dependencies</info>")
                for dependency in pkg.requires:
                    self.line(
                        " - {} <comment>{}</>".format(
                            dependency.pretty_name, dependency.pretty_constraint
                        )
                    )

            return 0

        show_latest = self.option("latest")
        show_all = self.option("all")
        terminal = self.get_application().terminal
        width = terminal.width
        name_length = version_length = latest_length = 0
        latest_packages = {}
        installed_repo = InstalledRepository.load(self.venv)
        skipped = []

        platform = sys.platform
        python = Version.parse(".".join([str(i) for i in self._venv.version_info[:3]]))

        # Computing widths
        for locked in locked_packages:
            python_constraint = parse_constraint(locked.requirements.get("python", "*"))
            platform_constraint = GenericConstraint.parse(
                locked.requirements.get("platform", "*")
            )
            if not python_constraint.allows(python) or not platform_constraint.matches(
                GenericConstraint("=", platform)
            ):
                skipped.append(locked)

                if not show_all:
                    continue

            current_length = len(locked.pretty_name)
            if not self.output.is_decorated():
                installed_status = self.get_installed_status(locked, installed_repo)

                if installed_status == "not-installed":
                    current_length += 4

            name_length = max(name_length, current_length)
            version_length = max(version_length, len(locked.full_pretty_version))
            if show_latest:
                latest = self.find_latest_package(locked)
                if not latest:
                    latest = locked

                latest_packages[locked.pretty_name] = latest
                latest_length = max(latest_length, len(latest.full_pretty_version))

        write_version = name_length + version_length + 3 <= width
        write_latest = name_length + version_length + latest_length + 3 <= width
        write_description = name_length + version_length + latest_length + 24 <= width

        for locked in locked_packages:
            color = "green"
            name = locked.pretty_name
            install_marker = ""
            if locked in skipped:
                if not show_all:
                    continue

                color = "black;options=bold"
            else:
                installed_status = self.get_installed_status(locked, installed_repo)
                if installed_status == "not-installed":
                    color = "red"

                    if not self.output.is_decorated():
                        # Non installed in non decorated mode
                        install_marker = " (!)"

            line = "<fg={}>{:{}}{}</>".format(
                color, name, name_length - len(install_marker), install_marker
            )
            if write_version:
                line += " <comment>{:{}}</comment>".format(
                    locked.full_pretty_version, version_length
                )
            if show_latest and write_latest:
                latest = latest_packages[locked.pretty_name]

                update_status = self.get_update_status(latest, locked)
                color = "green"
                if update_status == "semver-safe-update":
                    color = "red"
                elif update_status == "update-possible":
                    color = "yellow"

                line += " <fg={}>{:{}}</>".format(
                    color, latest.pretty_version, latest_length
                )
                if self.option("outdated") and update_status == "up-to-date":
                    continue

            if write_description:
                description = locked.description
                remaining = width - name_length - version_length - 4
                if show_latest:
                    remaining -= latest_length

                if len(locked.description) > remaining:
                    description = description[: remaining - 3] + "..."

                line += " " + description

            self.line(line)
示例#47
0
文件: wheel.py 项目: shawegit/poetry
 def supports_python2(self):
     return self._package.python_constraint.allows_any(
         parse_constraint(">=2.0.0 <3.0.0")
     )
示例#48
0
文件: solver.py 项目: shawegit/poetry
    def _get_tags_for_package(self, package, graph, depth=0):
        categories = ["dev"]
        optionals = [True]
        python_versions = []
        platforms = []
        _depths = [0]

        children = graph["children"]
        found = False
        for child in children:
            if child["name"] == package.name:
                category = child["category"]
                optional = child["optional"]
                python_version = child["python_version"]
                platform = child["platform"]
                _depths.append(depth)
            else:
                (
                    category,
                    optional,
                    python_version,
                    platform,
                    _depth,
                ) = self._get_tags_for_package(package, child, depth=depth + 1)

                _depths.append(_depth)

            categories.append(category)
            optionals.append(optional)
            if python_version is not None:
                python_versions.append(python_version)

            if platform is not None:
                platforms.append(platform)

        if "main" in categories:
            category = "main"
        else:
            category = "dev"

        optional = all(optionals)

        if not python_versions:
            python_version = None
        else:
            # Find the least restrictive constraint
            python_version = python_versions[0]
            for constraint in python_versions[1:]:
                previous = parse_constraint(python_version)
                current = parse_constraint(constraint)

                if python_version == "*":
                    continue
                elif constraint == "*":
                    python_version = constraint
                elif current.allows_all(previous):
                    python_version = constraint

        if not platforms:
            platform = None
        else:
            platform = platforms[0]
            for constraint in platforms[1:]:
                previous = GenericConstraint.parse(platform)
                current = GenericConstraint.parse(constraint)

                if platform == "*":
                    continue
                elif constraint == "*":
                    platform = constraint
                elif current.matches(previous):
                    platform = constraint

        depth = max(*(_depths + [0]))

        return category, optional, python_version, platform, depth
示例#49
0
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
    )
示例#50
0
def test_parse_constraint_wildcard(input, constraint):
    assert parse_constraint(input) == constraint
示例#51
0
def test_versions_are_sortable(unsorted, sorted_):
    unsorted = [parse_constraint(u) for u in unsorted]
    sorted_ = [parse_constraint(s) for s in sorted_]

    assert sorted(unsorted) == sorted_
示例#52
0
def test_constraints_keep_version_precision(input, expected):
    assert str(parse_constraint(input)) == expected
示例#53
0
def test_parse_constraints_negative_wildcard(input, constraint):
    assert parse_constraint(input) == constraint
示例#54
0
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),
    )
示例#55
0
    def handle(self):
        from poetry.packages import Dependency
        from poetry.packages import ProjectPackage
        from poetry.puzzle import Solver
        from poetry.repositories.repository import Repository
        from poetry.semver import parse_constraint

        packages = self.argument("package")

        if not packages:
            package = self.poetry.package
        else:
            requirements = self._determine_requirements(packages)
            requirements = self._format_requirements(requirements)

            # validate requirements format
            for constraint in requirements.values():
                parse_constraint(constraint)

            dependencies = []
            for name, constraint in requirements.items():
                dep = Dependency(name, constraint)
                extras = []
                for extra in self.option("extras"):
                    if " " in extra:
                        extras += [e.strip() for e in extra.split(" ")]
                    else:
                        extras.append(extra)

                for ex in extras:
                    dep.extras.append(ex)

                dependencies.append(dep)

            package = ProjectPackage(
                self.poetry.package.name, self.poetry.package.version
            )

            package.python_versions = (
                self.option("python") or self.poetry.package.python_versions
            )
            for dep in dependencies:
                package.requires.append(dep)

        solver = Solver(
            package, self.poetry.pool, Repository(), Repository(), self.output
        )

        ops = solver.solve()

        self.line("")
        self.line("Resolution results:")
        self.line("")

        for op in ops:
            package = op.package
            self.line(
                "  - <info>{}</info> (<comment>{}</comment>)".format(
                    package.name, package.version
                )
            )
            if package.requirements:
                for req_name, req_value in package.requirements.items():
                    self.line("    - {}: {}".format(req_name, req_value))
示例#56
0
def test_parse_constraint_caret(input, constraint):
    assert parse_constraint(input) == constraint
示例#57
0
 def python_versions(self, value):
     self._python_versions = value
     self._python_constraint = parse_constraint(value)
示例#58
0
文件: solver.py 项目: shawegit/poetry
    def _build_graph(
        self, package, packages, previous=None, previous_dep=None, dep=None
    ):
        if not previous:
            category = "dev"
            optional = True
            python_version = "*"
            platform = "*"
        else:
            category = dep.category
            optional = dep.is_optional() and not dep.is_activated()
            python_version = str(
                parse_constraint(previous["python_version"]).intersect(
                    previous_dep.python_constraint
                )
            )
            platform = str(
                previous_dep.platform
                if GenericConstraint.parse(previous["platform"]).matches(
                    previous_dep.platform_constraint
                )
                and previous_dep.platform != "*"
                else previous["platform"]
            )

        graph = {
            "name": package.name,
            "category": category,
            "optional": optional,
            "python_version": python_version,
            "platform": platform,
            "children": [],
        }

        if previous_dep and previous_dep is not dep and previous_dep.name == dep.name:
            return graph

        for dependency in package.all_requires:
            if dependency.is_optional():
                if not package.is_root() and (
                    not previous_dep or not previous_dep.extras
                ):
                    continue

                is_activated = False
                for group, extras in package.extras.items():
                    if dep:
                        extras = previous_dep.extras
                    elif package.is_root():
                        extras = package.extras
                    else:
                        extras = []

                    if group in extras:
                        is_activated = True
                        break

                if not is_activated:
                    continue

            for pkg in packages:
                if pkg.name == dependency.name:
                    # If there is already a child with this name
                    # we merge the requirements
                    existing = None
                    for child in graph["children"]:
                        if (
                            child["name"] == pkg.name
                            and child["category"] == dependency.category
                        ):
                            existing = child
                            continue

                    child_graph = self._build_graph(
                        pkg, packages, graph, dependency, dep or dependency
                    )

                    if existing:
                        existing["python_version"] = str(
                            parse_constraint(existing["python_version"]).union(
                                parse_constraint(child_graph["python_version"])
                            )
                        )
                        continue

                    graph["children"].append(child_graph)

        return graph