Beispiel #1
0
    def dependencies(self) -> list[Dependency]:
        if self._dependencies is None:
            # avoid circular dependency when loading DirectoryDependency
            from poetry.core.packages.dependency import Dependency
            from poetry.core.packages.directory_dependency import DirectoryDependency
            from poetry.core.packages.file_dependency import FileDependency

            self._dependencies = []
            for requirement in self.requires:
                dependency = None
                try:
                    dependency = Dependency.create_from_pep_508(requirement)
                except ValueError:
                    # PEP 517 requires can be path if not PEP 508
                    path = Path(requirement)
                    # compatibility Python < 3.8
                    # https://docs.python.org/3/library/pathlib.html#methods
                    with suppress(OSError):
                        if path.is_file():
                            dependency = FileDependency(name=canonicalize_name(
                                path.name),
                                                        path=path)
                        elif path.is_dir():
                            dependency = DirectoryDependency(
                                name=canonicalize_name(path.name), path=path)

                if dependency is None:
                    # skip since we could not determine requirement
                    continue

                self._dependencies.append(dependency)

        return self._dependencies
Beispiel #2
0
    def from_package(cls, package: "Package") -> "Metadata":
        from poetry.core.utils.helpers import canonicalize_name
        from poetry.core.utils.helpers import normalize_version
        from poetry.core.version.helpers import format_python_constraint

        meta = cls()

        meta.name = canonicalize_name(package.name)
        meta.version = normalize_version(package.version.text)
        meta.summary = package.description
        if package.readme:
            with package.readme.open(encoding="utf-8") as f:
                meta.description = f.read()

        meta.keywords = ",".join(package.keywords)
        meta.home_page = package.homepage or package.repository_url
        meta.author = package.author_name
        meta.author_email = package.author_email

        if package.license:
            meta.license = package.license.id

        meta.classifiers = package.all_classifiers

        # Version 1.2
        meta.maintainer = package.maintainer_name
        meta.maintainer_email = package.maintainer_email

        # Requires python
        if package.python_versions != "*":
            meta.requires_python = format_python_constraint(
                package.python_constraint)

        meta.requires_dist = [d.to_pep_508() for d in package.requires]

        # Version 2.1
        if package.readme:
            if package.readme.suffix == ".rst":
                meta.description_content_type = "text/x-rst"
            elif package.readme.suffix in [".md", ".markdown"]:
                meta.description_content_type = "text/markdown"
            else:
                meta.description_content_type = "text/plain"

        meta.provides_extra = [e for e in package.extras]

        if package.urls:
            for name, url in package.urls.items():
                if name == "Homepage" and meta.home_page == url:
                    continue

                meta.project_urls += ("{}, {}".format(name, url), )

        return meta
Beispiel #3
0
    def normalize(cls, policy: str) -> list[str]:
        if boolean_validator(policy):
            if boolean_normalizer(policy):
                return [":all:"]
            else:
                return [":none:"]

        return list({
            name.strip() if cls.is_reserved(name) else canonicalize_name(name)
            for name in policy.strip().split(",") if name
        })
Beispiel #4
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.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 = True
    def remove_dependency(self, name: str) -> None:
        from poetry.core.utils.helpers import canonicalize_name

        name = canonicalize_name(name)

        dependencies = []
        for dependency in self.dependencies:
            if dependency.name == name:
                continue

            dependencies.append(dependency)

        self._dependencies = dependencies
Beispiel #6
0
    def from_package(cls, package: Package) -> Metadata:
        from poetry.core.utils.helpers import canonicalize_name
        from poetry.core.utils.helpers import normalize_version
        from poetry.core.version.helpers import format_python_constraint

        meta = cls()

        meta.name = canonicalize_name(package.name)
        meta.version = normalize_version(package.version.text)
        meta.summary = package.description
        if package.readmes:
            descriptions = []
            for readme in package.readmes:
                with readme.open(encoding="utf-8") as f:
                    descriptions.append(f.read())
            meta.description = "\n".join(descriptions)

        meta.keywords = ",".join(package.keywords)
        meta.home_page = package.homepage or package.repository_url
        meta.author = package.author_name
        meta.author_email = package.author_email

        if package.license:
            meta.license = package.license.id

        meta.classifiers = tuple(package.all_classifiers)

        # Version 1.2
        meta.maintainer = package.maintainer_name
        meta.maintainer_email = package.maintainer_email

        # Requires python
        if package.python_versions != "*":
            meta.requires_python = format_python_constraint(package.python_constraint)

        meta.requires_dist = [d.to_pep_508() for d in package.requires]

        # Version 2.1
        if package.readmes:
            meta.description_content_type = readme_content_type(package.readmes[0])

        meta.provides_extra = list(package.extras)

        if package.urls:
            for name, url in package.urls.items():
                if name == "Homepage" and meta.home_page == url:
                    continue

                meta.project_urls += (f"{name}, {url}",)

        return meta
Beispiel #7
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]
    ):
        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._activated = not self._optional

        self.is_root = False
        self.marker = AnyMarker()
    def load(cls,
             env: Env,
             with_dependencies: bool = False) -> "InstalledRepository":
        """
        Load installed packages.
        """
        from poetry.core.packages.dependency import Dependency

        repo = cls()
        seen = set()

        for entry in reversed(env.sys_path):
            for distribution in sorted(
                    metadata.distributions(path=[entry]),
                    key=lambda d: str(d._path),
            ):
                name = canonicalize_name(distribution.metadata["name"])

                if name in seen:
                    continue

                path = Path(str(distribution._path))

                try:
                    path.relative_to(_VENDORS)
                except ValueError:
                    pass
                else:
                    continue

                package = cls.create_package_from_distribution(
                    distribution, env)

                if with_dependencies:
                    for require in distribution.metadata.get_all(
                            "requires-dist", []):
                        dep = Dependency.create_from_pep_508(require)
                        package.add_dependency(dep)

                seen.add(package.name)
                repo.add_package(package)

        return repo
Beispiel #9
0
    def __init__(
        self,
        name,  # type: str
        source_type=None,  # type: Optional[str]
        source_url=None,  # type: Optional[str]
        source_reference=None,  # type: Optional[str]
        source_resolved_reference=None,  # type: Optional[str]
        features=None,  # type: Optional[List[str]]
    ):
        self._pretty_name = name
        self._name = canonicalize_name(name)
        self._source_type = source_type
        self._source_url = source_url
        self._source_reference = source_reference
        self._source_resolved_reference = source_resolved_reference

        if not features:
            features = []

        self._features = frozenset(features)
    def __init__(
        self,
        name: str,
        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,
    ):
        from poetry.core.utils.helpers import canonicalize_name

        self._pretty_name = name
        self._name = canonicalize_name(name)
        self._source_type = source_type
        self._source_url = source_url
        self._source_reference = source_reference
        self._source_resolved_reference = source_resolved_reference

        if not features:
            features = []

        self._features = frozenset(features)
Beispiel #11
0
    def create_package_from_distribution(cls, distribution: "Distribution",
                                         env: "Env") -> Package:
        # We first check for a direct_url.json file to determine
        # the type of package.
        path = Path(str(distribution._path))

        if (path.name.endswith(".dist-info")
                and path.joinpath("direct_url.json").exists()):
            return cls.create_package_from_pep610(distribution)

        is_standard_package = env.is_path_relative_to_lib(path)

        source_type = None
        source_url = None
        source_reference = None
        source_resolved_reference = None
        if is_standard_package:
            if path.name.endswith(".dist-info"):
                paths = cls.get_package_paths(
                    env=env, name=distribution.metadata["name"])
                if paths:
                    is_editable_package = False
                    for src in paths:
                        if cls.is_vcs_package(src, env):
                            (
                                source_type,
                                source_url,
                                source_reference,
                            ) = cls.get_package_vcs_properties_from_path(src)
                            break

                        if not (is_editable_package
                                or env.is_path_relative_to_lib(src)):
                            is_editable_package = True
                    else:
                        # TODO: handle multiple source directories?
                        if is_editable_package:
                            source_type = "directory"
                            source_url = paths.pop().as_posix()
        else:
            if cls.is_vcs_package(path, env):
                (
                    source_type,
                    source_url,
                    source_reference,
                ) = cls.get_package_vcs_properties_from_path(
                    env.path / "src" /
                    canonicalize_name(distribution.metadata["name"]))
            else:
                # If not, it's a path dependency
                source_type = "directory"
                source_url = str(path.parent)

        package = Package(
            distribution.metadata["name"],
            distribution.metadata["version"],
            source_type=source_type,
            source_url=source_url,
            source_reference=source_reference,
            source_resolved_reference=source_resolved_reference,
        )
        package.description = distribution.metadata.get("summary", "")

        return package
Beispiel #12
0
    def allows(self, package_name: str) -> bool:
        if ":all:" in self.packages:
            return False

        return (not self.packages or ":none:" in self.packages
                or canonicalize_name(package_name) not in self.packages)
Beispiel #13
0
def test_utils_helpers_canonical_names(raw):
    assert canonicalize_name(raw) == "a-b-c"
Beispiel #14
0
    def load(cls,
             env: Env,
             with_dependencies: bool = False) -> InstalledRepository:
        """
        Load installed packages.
        """
        from poetry.core.packages.dependency import Dependency

        repo = cls()
        seen = set()
        skipped = set()

        for entry in reversed(env.sys_path):
            if not entry.strip():
                logger.debug(
                    "Project environment contains an empty path in <c1>sys_path</>,"
                    " ignoring.")
                continue

            for distribution in sorted(
                    metadata.distributions(  # type: ignore[no-untyped-call]
                        path=[entry], ),
                    key=lambda d: str(d._path),  # type: ignore[attr-defined]
            ):
                path = Path(str(
                    distribution._path))  # type: ignore[attr-defined]

                if path in skipped:
                    continue

                try:
                    name = canonicalize_name(distribution.metadata["name"])
                except TypeError:
                    logger.warning(
                        "Project environment contains an invalid distribution"
                        " (<c1>%s</>). Consider removing it manually or recreate the"
                        " environment.",
                        path,
                    )
                    skipped.add(path)
                    continue

                if name in seen:
                    continue

                try:
                    path.relative_to(_VENDORS)
                except ValueError:
                    pass
                else:
                    continue

                package = cls.create_package_from_distribution(
                    distribution, env)

                if with_dependencies:
                    for require in distribution.metadata.get_all(
                            "requires-dist", []):
                        dep = Dependency.create_from_pep_508(require)
                        package.add_dependency(dep)

                seen.add(package.name)
                repo.add_package(package)

        return repo