Skip to content

Commit

Permalink
Merge pull request #2887 from python-poetry/fix-transitive-extras
Browse files Browse the repository at this point in the history
Fix and improve handling of extras while resolving dependencies
  • Loading branch information
sdispater authored Sep 18, 2020
2 parents b32051f + 55ebb9c commit 5acf8fa
Show file tree
Hide file tree
Showing 59 changed files with 1,835 additions and 1,085 deletions.
19 changes: 10 additions & 9 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 5 additions & 4 deletions poetry/console/commands/debug/resolve.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class DebugResolveCommand(InitCommand):

def handle(self):
from poetry.core.packages.project_package import ProjectPackage
from poetry.factory import Factory
from poetry.io.null_io import NullIO
from poetry.puzzle import Solver
from poetry.repositories.pool import Pool
Expand Down Expand Up @@ -59,16 +60,16 @@ def handle(self):

for constraint in requirements:
name = constraint.pop("name")
dep = package.add_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)
constraint["extras"] = extras

package.add_dependency(Factory.create_dependency(name, constraint))

package.python_versions = self.option("python") or (
self.poetry.package.python_versions
Expand Down Expand Up @@ -122,7 +123,7 @@ def handle(self):

pkg = op.package
row = [
"<c1>{}</c1>".format(pkg.name),
"<c1>{}</c1>".format(pkg.complete_name),
"<b>{}</b>".format(pkg.version),
"",
]
Expand Down
2 changes: 1 addition & 1 deletion poetry/console/commands/init.py
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ def _parse_requirements(
pair["extras"] = extras

package = Provider.get_package_from_vcs(
"git", url.url, reference=pair.get("rev")
"git", url.url, rev=pair.get("rev")
)
pair["name"] = package.name
result.append(pair)
Expand Down
37 changes: 32 additions & 5 deletions poetry/console/commands/show.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ def handle(self):

from poetry.core.semver import Version
from poetry.repositories.installed_repository import InstalledRepository
from poetry.utils.helpers import get_package_version_display_string

package = self.argument("package")

Expand Down Expand Up @@ -144,12 +145,31 @@ def handle(self):
if not self.option("outdated") or update_status != "up-to-date":
name_length = max(name_length, current_length)
version_length = max(
version_length, len(locked.full_pretty_version)
version_length,
len(
get_package_version_display_string(
locked, root=self.poetry.file.parent
)
),
)
latest_length = max(
latest_length,
len(
get_package_version_display_string(
latest, root=self.poetry.file.parent
)
),
)
latest_length = max(latest_length, len(latest.full_pretty_version))
else:
name_length = max(name_length, current_length)
version_length = max(version_length, len(locked.full_pretty_version))
version_length = max(
version_length,
len(
get_package_version_display_string(
locked, root=self.poetry.file.parent
)
),
)

write_version = name_length + version_length + 3 <= width
write_latest = name_length + version_length + latest_length + 3 <= width
Expand Down Expand Up @@ -185,7 +205,10 @@ def handle(self):
)
if write_version:
line += " <b>{:{}}</b>".format(
locked.full_pretty_version, version_length
get_package_version_display_string(
locked, root=self.poetry.file.parent
),
version_length,
)
if show_latest:
latest = latest_packages[locked.pretty_name]
Expand All @@ -199,7 +222,11 @@ def handle(self):
color = "yellow"

line += " <fg={}>{:{}}</>".format(
color, latest.full_pretty_version, latest_length
color,
get_package_version_display_string(
latest, root=self.poetry.file.parent
),
latest_length,
)

if write_description:
Expand Down
Empty file modified poetry/factory.py
100644 → 100755
Empty file.
56 changes: 34 additions & 22 deletions poetry/inspection/info.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ def __init__(
self.requires_python = requires_python
self.files = files or []
self._cache_version = cache_version
self._source_type = None
self._source_url = None
self._source_reference = None

@property
def cache_version(self): # type: () -> Optional[str]
Expand Down Expand Up @@ -136,7 +139,13 @@ def to_package(
"Unable to retrieve the package version for {}".format(name)
)

package = Package(name=name, version=self.version)
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 "*"
Expand Down Expand Up @@ -166,14 +175,9 @@ def to_package(
# 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
if dependency not in package.requires:
package.requires.append(dependency)

return package
Expand All @@ -197,7 +201,7 @@ def _from_distribution(
with requires.open(encoding="utf-8") as f:
requirements = parse_requires(f.read())

return cls(
info = cls(
name=dist.name,
version=dist.version,
summary=dist.summary,
Expand All @@ -206,6 +210,11 @@ def _from_distribution(
requires_python=dist.requires_python,
)

info._source_type = "file"
info._source_url = Path(dist.filename).resolve().as_posix()

return info

@classmethod
def _from_sdist_file(cls, path): # type: (Path) -> PackageInfo
"""
Expand Down Expand Up @@ -501,23 +510,26 @@ def from_directory(
"""
project_package = cls._get_poetry_package(path)
if project_package:
return cls.from_package(project_package)
info = cls.from_package(project_package)
else:
info = cls.from_metadata(path)

info = cls.from_metadata(path)
if not info or info.requires_dist is None:
try:
if disable_build:
info = cls.from_setup_files(path)
else:
info = cls._pep517_metadata(path)
except PackageInfoError:
if not info:
raise

if info and info.requires_dist is not None:
# return only if requirements are discovered
return info
# we discovered PkgInfo but no requirements were listed

try:
if disable_build:
return cls.from_setup_files(path)
return cls._pep517_metadata(path)
except PackageInfoError as e:
if info:
# we discovered PkgInfo but no requirements were listed
return info
raise e
info._source_type = "directory"
info._source_url = path.as_posix()

return info

@classmethod
def from_sdist(cls, path): # type: (Path) -> PackageInfo
Expand Down
4 changes: 2 additions & 2 deletions poetry/installation/executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,7 @@ def _install_git(self, operation):
git.checkout(package.source_reference, src_dir)

# Now we just need to install from the source directory
package.source_url = str(src_dir)
package._source_url = str(src_dir)

return self._install_directory(operation)

Expand Down Expand Up @@ -599,7 +599,7 @@ def _download_link(self, operation, link):

def _download_archive(self, operation, link): # type: (Operation, Link) -> Path
response = self._authenticator.request(
"get", link.url, stream=True, io=self._sections.get(id(operation))
"get", link.url, stream=True, io=self._sections.get(id(operation), self._io)
)
wheel_size = response.headers.get("content-length")
operation_message = self.get_operation_message(operation)
Expand Down
4 changes: 2 additions & 2 deletions poetry/installation/pip_installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,8 +261,8 @@ def install_git(self, package):

# Now we just need to install from the source directory
pkg = Package(package.name, package.version)
pkg.source_type = "directory"
pkg.source_url = str(src_dir)
pkg._source_type = "directory"
pkg._source_url = str(src_dir)
pkg.develop = package.develop

self.install_directory(pkg)
12 changes: 6 additions & 6 deletions poetry/mixology/incompatibility.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,18 @@ def __init__(
# Short-circuit in the common case of a two-term incompatibility with
# two different packages (for example, a dependency).
or len(terms) == 2
and terms[0].dependency.name != terms[-1].dependency.name
and terms[0].dependency.complete_name != terms[-1].dependency.complete_name
):
pass
else:
# Coalesce multiple terms about the same package if possible.
by_name = {} # type: Dict[str, Dict[str, Term]]
for term in terms:
if term.dependency.name not in by_name:
by_name[term.dependency.name] = {}
if term.dependency.complete_name not in by_name:
by_name[term.dependency.complete_name] = {}

by_ref = by_name[term.dependency.name]
ref = term.dependency.name
by_ref = by_name[term.dependency.complete_name]
ref = term.dependency.complete_name

if ref in by_ref:
by_ref[ref] = by_ref[ref].intersect(term)
Expand Down Expand Up @@ -432,7 +432,7 @@ def _try_requires_forbidden(

def _terse(self, term, allow_every=False):
if allow_every and term.constraint.is_any():
return "every version of {}".format(term.dependency.name)
return "every version of {}".format(term.dependency.complete_name)

return str(term.dependency)

Expand Down
Loading

0 comments on commit 5acf8fa

Please sign in to comment.