Skip to content

Commit

Permalink
Fix complicated export case
Browse files Browse the repository at this point in the history
By treating different python version ranges independently, we buy the
flexibility needed to make better decisions.
  • Loading branch information
dimbleby committed May 29, 2022
1 parent 27034d6 commit d261745
Showing 1 changed file with 44 additions and 4 deletions.
48 changes: 44 additions & 4 deletions src/poetry/packages/locker.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@
from poetry.core.packages.url_dependency import URLDependency
from poetry.core.packages.vcs_dependency import VCSDependency
from poetry.core.semver.helpers import parse_constraint
from poetry.core.semver.util import constraint_regions
from poetry.core.semver.version import Version
from poetry.core.toml.file import TOMLFile
from poetry.core.version.markers import AnyMarker
from poetry.core.version.markers import SingleMarker
from poetry.core.version.markers import parse_marker
from poetry.core.version.requirements import InvalidRequirement
from tomlkit import array
Expand Down Expand Up @@ -49,6 +52,30 @@
logger = logging.getLogger(__name__)


def get_python_version_region_markers(packages: list[Package]) -> list[BaseMarker]:
regions = constraint_regions([package.python_constraint for package in packages])

markers = []
for region in regions:
min_operator = ">=" if region.include_min else ">"
lo = (
SingleMarker("python_full_version", f"{min_operator} {region.min}")
if region.min is not None
else AnyMarker()
)

max_operator = "<=" if region.include_max else "<"
hi = (
SingleMarker("python_full_version", f"{max_operator} {region.max}")
if region.max is not None
else AnyMarker()
)

markers.append(lo.intersect(hi))

return markers


class Locker:

_VERSION = "1.1"
Expand Down Expand Up @@ -279,12 +306,25 @@ def __walk_dependencies(
):
continue

require = deepcopy(require)
require.marker = require.marker.intersect(
base_marker = require.marker.intersect(
requirement.marker.without_extras()
)
if not require.marker.is_empty():
dependencies.append(require)

if not base_marker.is_empty():
# So as to give ourselves enough flexibility in choosing a solution,
# we need to split the world up into the python version ranges that
# this package might care about.
#
# We create a marker for all of the possible regions, and add a
# requirement for each separately.
candidates = packages_by_name.get(require.name, [])
region_markers = get_python_version_region_markers(candidates)
for region_marker in region_markers:
marker = region_marker.intersect(base_marker)
if not marker.is_empty():
require2 = deepcopy(require)
require2.marker = marker
dependencies.append(require2)

key = locked_package
if key not in nested_dependencies:
Expand Down

0 comments on commit d261745

Please sign in to comment.