diff --git a/pipenv/utils.py b/pipenv/utils.py index 2c815b6f..2b1d3b39 100644 --- a/pipenv/utils.py +++ b/pipenv/utils.py @@ -47,6 +47,12 @@ from contextlib import contextmanager from .pep508checker import lookup from .environments import PIPENV_MAX_ROUNDS, PIPENV_CACHE_DIR +from prettytoml.elements.abstracttable import AbstractTable +try: + from collections.abc import Mapping +except ImportError: + from collections import Mapping + if six.PY2: class ResourceWarning(Warning): @@ -639,6 +645,8 @@ def is_star(val): def is_pinned(val): + if isinstance(val, Mapping) or isinstance(val, AbstractTable): + val = val.get('version') return isinstance(val, six.string_types) and val.startswith('==') diff --git a/tests/integration/test_lock.py b/tests/integration/test_lock.py index 29d472e5..f71e02b3 100644 --- a/tests/integration/test_lock.py +++ b/tests/integration/test_lock.py @@ -50,6 +50,43 @@ flask = "==0.12.2" assert req in d.out +@pytest.mark.lock +def test_lock_keep_outdated(PipenvInstance, pypi): + + with PipenvInstance(pypi=pypi) as p: + with open(p.pipfile_path, 'w') as f: + contents = """ +[packages] +requests = {version = "==2.14.0"} +PyTest = "==3.1.0" + """.strip() + f.write(contents) + + c = p.pipenv('lock') + assert c.return_code == 0 + lock = p.lockfile + assert 'requests' in lock['default'] + assert lock['default']['requests']['version'] == "==2.14.0" + assert 'pytest' in lock['default'] + assert lock['default']['pytest']['version'] == "==3.1.0" + + with open(p.pipfile_path, 'w') as f: + updated_contents = """ +[packages] +requests = {version = "==2.18.4"} +PyTest = "*" + """.strip() + f.write(updated_contents) + + c = p.pipenv('lock --keep-outdated') + assert c.return_code == 0 + lock = p.lockfile + assert 'requests' in lock['default'] + assert lock['default']['requests']['version'] == "==2.18.4" + assert 'pytest' in lock['default'] + assert lock['default']['pytest']['version'] == "==3.1.0" + + @pytest.mark.lock @pytest.mark.complex @pytest.mark.needs_internet