Skip to content
This repository has been archived by the owner on Jan 12, 2021. It is now read-only.

Commit

Permalink
Merge pull request #224 from dephell/unapply-markers
Browse files Browse the repository at this point in the history
Unapply markers
  • Loading branch information
orsinium committed Jul 15, 2019
2 parents 9add2ee + cb42883 commit 5456f77
Show file tree
Hide file tree
Showing 9 changed files with 107 additions and 18 deletions.
5 changes: 5 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
language: python
dist: xenial

# do not run Travis for PR's twice (as for push and as for PR)
branches:
only:
- master

before_install:
# show a little bit more information about environment
- sudo apt-get install -y tree
Expand Down
6 changes: 4 additions & 2 deletions dephell/commands/deps_install.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ def __call__(self) -> bool:
def _get_install_remove(self, graph, python) -> Tuple[list, list]:
# get installed packages
installed_root = InstalledConverter().load(paths=python.lib_paths)
installed = {dep.name: str(dep.constraint).strip('=') for dep in installed_root.dependencies}
installed = dict()
for dep in installed_root.dependencies:
installed[dep.name] = [c.strip('=') for c in str(dep.constraint).split(' || ')]

# plan what we will install and what we will remove
install = []
Expand All @@ -82,7 +84,7 @@ def _get_install_remove(self, graph, python) -> Tuple[list, list]:
continue
# installed the same version, skip
version = req.version.strip('=')
if version == installed[req.name]:
if version in installed[req.name]:
continue
# installed old version, remove it and install new
self.logger.debug('dependency will be updated', extra=dict(
Expand Down
5 changes: 3 additions & 2 deletions dephell/controllers/_dependency.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from ..models.constraint import Constraint
from ..models.dependency import Dependency
from ..models.extra_dependency import ExtraDependency
from ..models.marker_tracker import MarkerTracker
from ..repositories import get_repo


Expand Down Expand Up @@ -63,7 +64,7 @@ def from_requirement(cls, source, req, *, url=None, envs=None, marker: Union[Mar
constraint=constraint,
repo=get_repo(link, default=default_repo),
link=link,
marker=marker,
marker=MarkerTracker().apply(source=source, markers=marker),
editable=editable,
envs=envs,
)
Expand Down Expand Up @@ -114,7 +115,7 @@ def from_params(cls, *, raw_name: str, constraint,
repo=repo,
raw_name=raw_name,
constraint=constraint,
marker=marker,
marker=MarkerTracker().apply(source=source, markers=marker),
envs=envs,
**kwargs,
)
Expand Down
8 changes: 5 additions & 3 deletions dephell/converters/poetry.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,9 +270,11 @@ def _add_repositories(section, root: RootDependency):
added = []
sources = tomlkit.aot()
if section.get('source'):
old = list(section['source'])
added = []
for source in old:
if hasattr(section, 'item'):
old_sources = section.item('source')
else:
old_sources = section['source']
for source in old_sources:
if source['name'] in urls:
if source['url'] != urls[source['name']]:
source['url'] = urls[source['name']]
Expand Down
2 changes: 2 additions & 0 deletions dephell/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from .git_release import GitRelease
from .group import Group
from .groups import Groups
from .marker_tracker import MarkerTracker
from .release import Release
from .requirement import Requirement
from .root import RootDependency
Expand All @@ -24,6 +25,7 @@
'GitRelease',
'Group',
'Groups',
'MarkerTracker',
'Release',
'Requirement',
'RootDependency',
Expand Down
14 changes: 6 additions & 8 deletions dephell/models/dependency.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from .constraint import Constraint
from .group import Group
from .groups import Groups
from .marker_tracker import MarkerTracker


@attr.s(cmp=False)
Expand All @@ -35,7 +36,7 @@ class Dependency:
editable = attr.ib(type=bool, default=False, repr=False)
prereleases = attr.ib(type=bool, default=False, repr=False)
# https://github.com/pypa/packaging/blob/master/packaging/markers.py
marker = attr.ib(type=Markers, factory=Markers, repr=False)
marker = attr.ib(type=MarkerTracker, factory=MarkerTracker, repr=False)
envs = attr.ib(type=set, factory=set, repr=False) # which root extras cause this dep
inherited_envs = attr.ib(type=set, factory=set, repr=False) # envs of parents
locations = attr.ib(type=set, factory=set, repr=False) # package places on disk
Expand Down Expand Up @@ -123,7 +124,7 @@ def locked(self) -> bool:
def python_compat(self) -> bool:
if not self.marker:
return True
needed = self.marker.python_version
needed = self.marker.markers.python_version
if needed is None:
return True

Expand Down Expand Up @@ -169,6 +170,7 @@ def unlock(self) -> None:

def unapply(self, name: str) -> None:
self.constraint.unapply(name)
self.marker.unapply(name)
if self.locked:
self.unlock()

Expand All @@ -188,7 +190,7 @@ def __str__(self) -> str:
if self.constraint:
result += str(self.constraint)

marker = deepcopy(self.marker)
marker = Markers(str(self.marker))
if self.envs - {'main'}:
extra_markers = {'extra == "{}"'.format(env) for env in self.envs - {'main'}}
marker &= Markers(' or '.join(extra_markers))
Expand Down Expand Up @@ -227,11 +229,7 @@ def __iadd__(self, dep: 'Dependency') -> 'Dependency':
self.link = dep.link
self.repo = dep.repo

if dep.marker is not None and self.marker is not None:
self.marker |= dep.marker
else:
self.marker = None

self.marker.merge(dep.marker)
self.envs.update(dep.envs)
if 'main' in self.envs and 'dev' in self.envs:
self.envs.remove('dev')
Expand Down
53 changes: 53 additions & 0 deletions dephell/models/marker_tracker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# external
from dephell_markers import Markers, OrMarker


class MarkerTracker:
def __init__(self):
self._markers = dict()

@property
def markers(self) -> Markers:
if len(self._markers) == 1:
return next(iter(self._markers.values()))
container = Markers()
markers = [m._marker for m in self._markers.values() if m._marker]
container._marker = OrMarker(*markers)
return container

def apply(self, *, source, markers) -> 'MarkerTracker':
if not markers:
return self
if type(source) is not str:
source = source.name
if source in self._markers:
raise ValueError('marker for given source already added')
if type(markers) is str:
markers = Markers(markers)
self._markers[source] = markers
return self

def merge(self, other: 'MarkerTracker') -> None:
for source, marker in other._markers.items():
self._markers[source] = marker

def unapply(self, source) -> None:
if type(source) is not str:
source = source.name
if source in self._markers:
del self._markers[source]

def __getattr__(self, name):
if name not in dir(Markers):
raise AttributeError(name)
return getattr(self.markers, name)

def __bool__(self) -> bool:
return any(marker for marker in self._markers.values())

def __str__(self) -> str:
return str(self.markers)

def __repr__(self):
markers = map(repr, self._markers.values())
return '{}({})'.format(type(self).__name__, ', '.join(markers))
22 changes: 22 additions & 0 deletions tests/test_models/test_marker_tracker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# project
from dephell.models import MarkerTracker


def test_apply():
mt = MarkerTracker()
mt.apply(source='sname', markers='python_version >= "3.5"')
assert len(mt._markers) == 1
assert str(mt._markers['sname']) == 'python_version >= "3.5"'


def test_str():
mt = MarkerTracker()
mt.apply(source='sname', markers='python_version >= "3.5"')
assert str(mt) == 'python_version >= "3.5"'


def test_bool():
mt = MarkerTracker()
assert bool(mt) is False
mt.apply(source='sname', markers='python_version >= "3.5"')
assert bool(mt) is True
10 changes: 7 additions & 3 deletions tests/test_resolving/test_python_compat.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
# external
import pytest
from dephell_markers import Markers
from dephell_specifier import RangeSpecifier

# project
from dephell.models import Dependency, Group, Release
from dephell.models import Dependency, Group, MarkerTracker, Release


@pytest.mark.parametrize('pdep, prel, ok', [
Expand All @@ -30,8 +29,13 @@ def test_python_compat(pdep: str, prel: str, ok: bool):
raw_name='pathlib2',
constraint=None,
repo=None,
marker=Markers(RangeSpecifier(pdep).to_marker('python_version')),
marker=MarkerTracker().apply(
source='root',
markers=RangeSpecifier(pdep).to_marker('python_version'),
),
)
assert 'python_version' in str(dep.marker)
assert bool(dep.marker) is True
release = Release(
raw_name='pathlib2',
version='2.3.3',
Expand Down

0 comments on commit 5456f77

Please sign in to comment.