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
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
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 })
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
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
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
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)
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
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)
def test_utils_helpers_canonical_names(raw): assert canonicalize_name(raw) == "a-b-c"
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