def to_package( self, name=None, extras=None, root_dir=None ): # type: (Optional[str], Optional[List[str]], Optional[Path]) -> Package """ Create a new `poetry.core.packages.package.Package` instance using metadata from this instance. :param name: Name to use for the package, if not specified name from this instance is used. :param extras: Extras to activate for this package. :param root_dir: Optional root directory to use for the package. If set, dependency strings will be parsed relative to this directory. """ name = name or self.name if not self.version: # The version could not be determined, so we raise an error since it is mandatory. raise RuntimeError( "Unable to retrieve the package version for {}".format(name) ) package = Package(name=name, version=self.version) package.description = self.summary package.root_dir = root_dir package.python_versions = self.requires_python or "*" package.files = self.files for req in self.requires_dist or []: try: # Attempt to parse the PEP-508 requirement string dependency = dependency_from_pep_508(req, relative_to=root_dir) except InvalidMarker: # Invalid marker, We strip the markers hoping for the best req = req.split(";")[0] dependency = dependency_from_pep_508(req, relative_to=root_dir) except ValueError: # Likely unable to parse constraint so we skip it self._log( "Invalid constraint ({}) found in {}-{} dependencies, " "skipping".format(req, package.name, package.version), level="warning", ) continue if dependency.in_extras: # this dependency is required by an extra package for extra in dependency.in_extras: if extra not in package.extras: # this is the first time we encounter this extra for this package package.extras[extra] = [] # Activate extra dependencies if specified if extras and extra in extras: dependency.activate() package.extras[extra].append(dependency) if not dependency.is_optional() or dependency.is_activated(): # we skip add only if the dependency is option and was not activated as part of an extra package.requires.append(dependency) return package
def test_package_clone(f): # TODO(nic): this test is not future-proof, in that any attributes added # to the Package object and not filled out in this test setup might # cause comparisons to match that otherwise should not. A factory method # to create a Package object with all fields fully randomized would be the # most rigorous test for this, but that's likely overkill. p = Package( "lol_wut", "3.141.5926535", pretty_version="③.⑭.⑮", source_type="git", source_url="http://some.url", source_reference="fe4d2adabf3feb5d32b70ab5c105285fa713b10c", source_resolved_reference="fe4d2adabf3feb5d32b70ab5c105285fa713b10c", features=["abc", "def"], ) p.files = (["file1", "file2", "file3"],) p.homepage = "https://some.other.url" p.repository_url = "http://bug.farm" p.documentation_url = "http://lorem.ipsum/dolor/sit.amet" p2 = p.clone() assert p == p2 assert p.__dict__ == p2.__dict__
def to_package( self, name=None, extras=None, root_dir=None ): # type: (Optional[str], Optional[List[str]], Optional[Path]) -> Package """ Create a new `poetry.core.packages.package.Package` instance using metadata from this instance. :param name: Name to use for the package, if not specified name from this instance is used. :param extras: Extras to activate for this package. :param root_dir: Optional root directory to use for the package. If set, dependency strings will be parsed relative to this directory. """ name = name or self.name if not self.version: # The version could not be determined, so we raise an error since it is mandatory. raise RuntimeError( "Unable to retrieve the package version for {}".format(name) ) package = Package( name=name, version=self.version, source_type=self._source_type, source_url=self._source_url, source_reference=self._source_reference, ) package.description = self.summary package.root_dir = root_dir package.python_versions = self.requires_python or "*" package.files = self.files if root_dir or (self._source_type in {"directory"} and self._source_url): # this is a local poetry project, this means we can extract "richer" requirement information # eg: development requirements etc. poetry_package = self._get_poetry_package(path=root_dir or self._source_url) if poetry_package: package.extras = poetry_package.extras package.requires = poetry_package.requires return package seen_requirements = set() for req in self.requires_dist or []: try: # Attempt to parse the PEP-508 requirement string dependency = dependency_from_pep_508(req, relative_to=root_dir) except InvalidMarker: # Invalid marker, We strip the markers hoping for the best req = req.split(";")[0] dependency = dependency_from_pep_508(req, relative_to=root_dir) except ValueError: # Likely unable to parse constraint so we skip it self._log( "Invalid constraint ({}) found in {}-{} dependencies, " "skipping".format(req, package.name, package.version), level="warning", ) continue if dependency.in_extras: # this dependency is required by an extra package for extra in dependency.in_extras: if extra not in package.extras: # this is the first time we encounter this extra for this package package.extras[extra] = [] package.extras[extra].append(dependency) req = dependency.to_pep_508(with_extras=True) if req not in seen_requirements: package.requires.append(dependency) seen_requirements.add(req) return package