def test_convert_dependencies(): package = Package("foo", "1.2.3") result = SdistBuilder.convert_dependencies( package, [ Dependency("A", "^1.0"), Dependency("B", "~1.0"), Dependency("C", "1.2.3"), VCSDependency("D", "git", "https://github.com/sdispater/d.git"), Dependency("E", "^1.0"), Dependency("F", "^1.0,!=1.3"), ], ) main = [ "A>=1.0,<2.0", "B>=1.0,<1.1", "C==1.2.3", "D @ git+https://github.com/sdispater/d.git@master", "E>=1.0,<2.0", "F>=1.0,<2.0,!=1.3", ] extras = {} assert result == (main, extras) package = Package("foo", "1.2.3") package.extras = {"bar": [Dependency("A", "*")]} result = SdistBuilder.convert_dependencies( package, [ Dependency("A", ">=1.2", optional=True), Dependency("B", "~1.0"), Dependency("C", "1.2.3"), ], ) main = ["B>=1.0,<1.1", "C==1.2.3"] extras = {"bar": ["A>=1.2"]} assert result == (main, extras) c = Dependency("C", "1.2.3") c.python_versions = "~2.7 || ^3.6" d = Dependency("D", "3.4.5", optional=True) d.python_versions = "~2.7 || ^3.4" package.extras = {"baz": [Dependency("D", "*")]} result = SdistBuilder.convert_dependencies( package, [ Dependency("A", ">=1.2", optional=True), Dependency("B", "~1.0"), c, d ], ) main = ["B>=1.0,<1.1"] extra_python = (':python_version >= "2.7" and python_version < "2.8" ' 'or python_version >= "3.6" and python_version < "4.0"') extra_d_dependency = ( 'baz:python_version >= "2.7" and python_version < "2.8" ' 'or python_version >= "3.4" and python_version < "4.0"') extras = {extra_python: ["C==1.2.3"], extra_d_dependency: ["D==3.4.5"]} assert result == (main, extras)
def to_package( self, name: Optional[str] = None, extras: Optional[List[str]] = None, root_dir: Optional[Path] = None, ) -> 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.create_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.create_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
def to_package( self, name: str | None = None, extras: list[str] | None = None, root_dir: Path | None = None, ) -> 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 name: raise RuntimeError("Unable to create package with no name") if not self.version: # The version could not be determined, so we raise an error since it is # mandatory. raise RuntimeError( f"Unable to retrieve the package version for {name}") package = Package( name=name, version=self.version, source_type=self._source_type, source_url=self._source_url, source_reference=self._source_reference, ) if self.summary is not None: package.description = self.summary package.root_dir = root_dir package.python_versions = self.requires_python or "*" package.files = self.files # If this is a local poetry project, we can extract "richer" requirement # information, eg: development requirements etc. if root_dir is not None: path = root_dir elif self._source_type == "directory" and self._source_url is not None: path = Path(self._source_url) else: path = None if path is not None: poetry_package = self._get_poetry_package(path=path) if poetry_package: package.extras = poetry_package.extras for dependency in poetry_package.requires: package.add_dependency(dependency) return package seen_requirements = set() for req in self.requires_dist or []: try: # Attempt to parse the PEP-508 requirement string dependency = Dependency.create_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.create_from_pep_508( req, relative_to=root_dir) except ValueError: # Likely unable to parse constraint so we skip it logger.debug( f"Invalid constraint ({req}) found in" f" {package.name}-{package.version} dependencies, skipping", ) 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.add_dependency(dependency) seen_requirements.add(req) return package