From 4fc79e11976c2a503748e111174d07b5c392e408 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sun, 11 Mar 2018 10:06:51 -0400 Subject: [PATCH 01/20] prep for warehouse release --- pipenv/patched/piptools/repositories/pypi.py | 2 +- pipenv/project.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pipenv/patched/piptools/repositories/pypi.py b/pipenv/patched/piptools/repositories/pypi.py index e637e6e3..d2e6935c 100755 --- a/pipenv/patched/piptools/repositories/pypi.py +++ b/pipenv/patched/piptools/repositories/pypi.py @@ -30,7 +30,7 @@ except ImportError: class PyPIRepository(BaseRepository): - DEFAULT_INDEX_URL = 'https://pypi.python.org/simple' + DEFAULT_INDEX_URL = 'https://pypi.org/simple' """ The PyPIRepository will use the provided Finder instance to lookup diff --git a/pipenv/project.py b/pipenv/project.py index 8ea1d472..8fd6d043 100644 --- a/pipenv/project.py +++ b/pipenv/project.py @@ -415,7 +415,7 @@ class Project(object): sources = [{u'url': PIPENV_TEST_INDEX, u'verify_ssl': True, u'name': u'custom'}] else: # Default source. - pypi_source = {u'url': u'https://pypi.python.org/simple', u'verify_ssl': True, u'name': 'pypi'} + pypi_source = {u'url': u'https://pypi.org/simple', u'verify_ssl': True, u'name': 'pypi'} sources = [pypi_source] for i, index in enumerate(indexes): From 6707b0c19bb68e267ef423391b244dafca1c288b Mon Sep 17 00:00:00 2001 From: Stefane Fermigier Date: Mon, 16 Apr 2018 12:36:40 +0200 Subject: [PATCH 02/20] I believe this tox config is more correct this way --- docs/advanced.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/advanced.rst b/docs/advanced.rst index 10ae790b..6a879e76 100644 --- a/docs/advanced.rst +++ b/docs/advanced.rst @@ -474,7 +474,6 @@ and external testing:: [testenv:flake8-py3] basepython = python3.4 commands= - {[testenv]deps} pipenv install --dev pipenv run flake8 --version pipenv run flake8 setup.py docs project test From 55121bd2aec64d7fdf776647419ab24a21b5160b Mon Sep 17 00:00:00 2001 From: Gasper Zejn Date: Fri, 20 Apr 2018 12:10:09 +0200 Subject: [PATCH 03/20] Fix progress.py to obey PIPENV_COLORBLIND and not use any colors. Crayon library is used in progress.py to set up BAR_FILLED_CHAR as module global, and since progress is imported in core before crayons.disable() call takes effect, the BAR_FILLED_CHARS is green even though PIPENV_COLORBLIND is set. To make this work as advertised, PIPENV_COLORBLIND is checked in progress.py too. --- pipenv/core.py | 2 +- pipenv/progress.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pipenv/core.py b/pipenv/core.py index 9e761ff7..57974de6 100644 --- a/pipenv/core.py +++ b/pipenv/core.py @@ -103,7 +103,7 @@ else: STARTING_LABEL = ' ' # Enable shell completion. click_completion.init() -# Disable colors, for the soulless. +# Disable colors, for the color blind and others who do not prefer colors. if PIPENV_COLORBLIND: crayons.disable() # Disable spinner, for cleaner build logs (the unworthy). diff --git a/pipenv/progress.py b/pipenv/progress.py index 7d6dc31e..14bb721f 100644 --- a/pipenv/progress.py +++ b/pipenv/progress.py @@ -13,11 +13,12 @@ import os import sys import time import crayons +from .environments import PIPENV_COLORBLIND STREAM = sys.stderr MILL_TEMPLATE = '%s %s %i/%i\r' DOTS_CHAR = '.' -if os.name != 'nt': +if os.name != 'nt' and not PIPENV_COLORBLIND: BAR_FILLED_CHAR = str(crayons.green('▉', bold=True)) BAR_EMPTY_CHAR = str(crayons.black('▉')) else: From 8bf64918e36044021b276e4aebf41aac1c76bee3 Mon Sep 17 00:00:00 2001 From: Frost Ming Date: Fri, 20 Apr 2018 21:19:38 +0800 Subject: [PATCH 04/20] Do not destroy lock early --- pipenv/core.py | 2 -- pipenv/project.py | 8 -------- 2 files changed, 10 deletions(-) diff --git a/pipenv/core.py b/pipenv/core.py index 9e761ff7..d8948b4c 100644 --- a/pipenv/core.py +++ b/pipenv/core.py @@ -1000,8 +1000,6 @@ def do_lock( ) sys.exit(1) cached_lockfile = project.lockfile_content - if write: - project.destroy_lockfile() if write: # Alert the user of progress. click.echo( diff --git a/pipenv/project.py b/pipenv/project.py index 70e05006..ade9cd87 100644 --- a/pipenv/project.py +++ b/pipenv/project.py @@ -668,14 +668,6 @@ class Project(object): return found_source raise SourceNotFound(name or url) - def destroy_lockfile(self): - """Deletes the lockfile.""" - try: - return os.remove(self.lockfile_location) - - except OSError: - pass - def get_package_name_in_pipfile(self, package_name, dev=False): """Get the equivalent package name in pipfile""" key = 'dev-packages' if dev else 'packages' From 33945de1eb597b0ffcd99d9d9f6d4d3a0d5e6404 Mon Sep 17 00:00:00 2001 From: Gasper Zejn Date: Fri, 20 Apr 2018 17:22:29 +0200 Subject: [PATCH 05/20] Obey both color-blind and hide-emoji flags. --- pipenv/progress.py | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/pipenv/progress.py b/pipenv/progress.py index 14bb721f..1a0593b1 100644 --- a/pipenv/progress.py +++ b/pipenv/progress.py @@ -13,17 +13,31 @@ import os import sys import time import crayons -from .environments import PIPENV_COLORBLIND +from .environments import (PIPENV_COLORBLIND, PIPENV_HIDE_EMOJIS) STREAM = sys.stderr MILL_TEMPLATE = '%s %s %i/%i\r' DOTS_CHAR = '.' -if os.name != 'nt' and not PIPENV_COLORBLIND: - BAR_FILLED_CHAR = str(crayons.green('▉', bold=True)) - BAR_EMPTY_CHAR = str(crayons.black('▉')) +if os.name != 'nt': + if PIPENV_HIDE_EMOJIS: + if PIPENV_COLORBLIND: + BAR_FILLED_CHAR = '=' + BAR_EMPTY_CHAR = '-' + else: + BAR_FILLED_CHAR = str(crayons.green('=', bold=True)) + BAR_EMPTY_CHAR = str(crayons.black('-')) + else: + if PIPENV_COLORBLIND: + BAR_FILLED_CHAR = str(crayons.white('▉', bold=True)) + BAR_EMPTY_CHAR = str(crayons.black('▉')) + else: + BAR_FILLED_CHAR = str(crayons.green('▉', bold=True)) + BAR_EMPTY_CHAR = str(crayons.black('▉')) + else: BAR_FILLED_CHAR = '=' BAR_EMPTY_CHAR = '-' + if (sys.version_info[0] >= 3) and (os.name != 'nt'): BAR_TEMPLATE = u' %s%s%s %i/%i — {0}\r'.format(crayons.black('%s')) else: From 7423d235c674a73c8dbb77be86af04d13273cd6f Mon Sep 17 00:00:00 2001 From: Gasper Zejn Date: Fri, 20 Apr 2018 20:29:21 +0200 Subject: [PATCH 06/20] Fix: don't use crayons for colorblind. --- pipenv/progress.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pipenv/progress.py b/pipenv/progress.py index 1a0593b1..256bec9d 100644 --- a/pipenv/progress.py +++ b/pipenv/progress.py @@ -28,8 +28,8 @@ if os.name != 'nt': BAR_EMPTY_CHAR = str(crayons.black('-')) else: if PIPENV_COLORBLIND: - BAR_FILLED_CHAR = str(crayons.white('▉', bold=True)) - BAR_EMPTY_CHAR = str(crayons.black('▉')) + BAR_FILLED_CHAR = '▉' + BAR_EMPTY_CHAR = ' ' else: BAR_FILLED_CHAR = str(crayons.green('▉', bold=True)) BAR_EMPTY_CHAR = str(crayons.black('▉')) From 75d575b82f3a77af45c5f78f6d2c47e904020e73 Mon Sep 17 00:00:00 2001 From: Dave Hunt Date: Wed, 25 Apr 2018 14:21:41 +0100 Subject: [PATCH 07/20] Only depend on requests[security] and ordereddict for Python 2.6 Fixes #2055 --- setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 996dc998..50f1a91b 100644 --- a/setup.py +++ b/setup.py @@ -28,8 +28,8 @@ required = [ 'virtualenv-clone>=0.2.5', 'virtualenv', 'pathlib2==2.1.0;python_version<"3.4"', - 'requests[security];python_version<"3.0"', - 'ordereddict;python_version<"3.0"', + 'requests[security];python_version<"2.7"', + 'ordereddict;python_version<"2.7"', ] From 3f13e8dfd3daacb64755d21f92b48e25d6f8fd82 Mon Sep 17 00:00:00 2001 From: Ben Kraft Date: Wed, 25 Apr 2018 11:43:04 -0700 Subject: [PATCH 08/20] Mention --keep-outdated in docs for importing When importing from requirements.txt, it may be useful to keep the versions of packages you have for the moment, while unpinning them for the future. This is already supported via `--keep-outdated`; this commit adds a mention to the docs. Fixes #908. --- docs/basics.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/basics.rst b/docs/basics.rst index 78ac66c1..b563de62 100644 --- a/docs/basics.rst +++ b/docs/basics.rst @@ -172,9 +172,10 @@ pipenv will automatically import the contents of this file and create a ``Pipfil You can also specify ``$ pipenv install -r path/to/requirements.txt`` to import a requirements file. -Note, that when importing a requirements file, they often have version numbers pinned, which you likely won't want -in your ``Pipfile``, so you'll have to manually update your ``Pipfile`` afterwards to reflect this. - +If your requirements file has version numbers pinned, you'll likely want to edit the new ``Pipfile`` +to remove those, and let ``pipenv`` keep track of pinning. If you want to keep the pinned versions +in your ``Pipfile.lock`` for now, run ``pipenv lock --keep-outdated``. Make sure to +`upgrade <#initialization>`_ soon! .. _specifying_versions: From 8991c0901f4bdc6c58b5ace68c9cdc106f95cd08 Mon Sep 17 00:00:00 2001 From: Dan Ryan Date: Wed, 25 Apr 2018 21:58:43 -0400 Subject: [PATCH 09/20] Shellquote paths to requirements files - Allows for windows paths with spaces in them - Fixes #2054 Signed-off-by: Dan Ryan --- HISTORY.txt | 1 + pipenv/core.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/HISTORY.txt b/HISTORY.txt index abc03e3c..df018f32 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -10,6 +10,7 @@ - Remove GPL'ed code. - Make imports lazy to improve initial load time. - Extra path searching for python at runtime. + - Shellquote paths to requirement files in case of spaces on windows. - Require `--python` values to exist when passing a path. - Bugfix for environment variable expansion in 'unlocked' pipfiles. - Bugfix for `--deploy` flag. diff --git a/pipenv/core.py b/pipenv/core.py index 89108d56..8965668d 100644 --- a/pipenv/core.py +++ b/pipenv/core.py @@ -1476,7 +1476,7 @@ def pip_install( if package_name.startswith('-e '): install_reqs = ' -e "{0}"'.format(package_name.split('-e ')[1]) elif r: - install_reqs = ' -r {0}'.format(r) + install_reqs = ' -r {0}'.format(escape_grouped_arguments(r)) else: install_reqs = ' "{0}"'.format(package_name) # Skip hash-checking mode, when appropriate. From d2eeac7729693e9c2f7ba38949f0628065061bd7 Mon Sep 17 00:00:00 2001 From: Dan Ryan Date: Thu, 26 Apr 2018 02:10:04 -0400 Subject: [PATCH 10/20] Fix travis.yml Signed-off-by: Dan Ryan --- .travis.yml | 2 +- pipenv/__version__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e10d2400..3c3855b5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,7 +19,7 @@ install: - "pip install -e . --upgrade --upgrade-strategy=only-if-needed" - "pipenv install --dev" - 'pip install -e "$(pwd)" --upgrade' - - 'pipenv install --deploy --system --dev' + - 'pipenv install --system --dev' script: - 'pipenv run time pytest -v -n 4 -m "$TEST_SUITE" tests' diff --git a/pipenv/__version__.py b/pipenv/__version__.py index 6b0d1446..d58e2474 100644 --- a/pipenv/__version__.py +++ b/pipenv/__version__.py @@ -2,4 +2,4 @@ # // ) ) / / // ) ) //___) ) // ) ) || / / # //___/ / / / //___/ / // // / / || / / # // / / // ((____ // / / ||/ / -__version__ = '11.10.1.dev5' +__version__ = '11.10.1' From e53b4441adc6d8bc706a68f0a43df4356025d28a Mon Sep 17 00:00:00 2001 From: Dan Ryan Date: Thu, 26 Apr 2018 10:52:15 -0400 Subject: [PATCH 11/20] Patch requests imports Signed-off-by: Dan Ryan --- .../notpip/_vendor/requests/packages.py | 6 +++--- .../_post-pip-update-requests-imports.patch | 21 +++++++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 tasks/vendoring/patches/patched/_post-pip-update-requests-imports.patch diff --git a/pipenv/patched/notpip/_vendor/requests/packages.py b/pipenv/patched/notpip/_vendor/requests/packages.py index 9582fa73..928d1bb9 100644 --- a/pipenv/patched/notpip/_vendor/requests/packages.py +++ b/pipenv/patched/notpip/_vendor/requests/packages.py @@ -4,13 +4,13 @@ import sys # I don't like it either. Just look the other way. :) for package in ('urllib3', 'idna', 'chardet'): - vendored_package = "pip._vendor." + package + vendored_package = "pip9._vendor." + package locals()[package] = __import__(vendored_package) # This traversal is apparently necessary such that the identities are # preserved (requests.packages.urllib3.* is urllib3.*) for mod in list(sys.modules): if mod == vendored_package or mod.startswith(vendored_package + '.'): - unprefixed_mod = mod[len("pip._vendor."):] - sys.modules['pip._vendor.requests.packages.' + unprefixed_mod] = sys.modules[mod] + unprefixed_mod = mod[len("pip9._vendor."):] + sys.modules['pip9._vendor.requests.packages.' + unprefixed_mod] = sys.modules[mod] # Kinda cool, though, right? diff --git a/tasks/vendoring/patches/patched/_post-pip-update-requests-imports.patch b/tasks/vendoring/patches/patched/_post-pip-update-requests-imports.patch new file mode 100644 index 00000000..bdccfd6d --- /dev/null +++ b/tasks/vendoring/patches/patched/_post-pip-update-requests-imports.patch @@ -0,0 +1,21 @@ +diff --git a/pipenv/patched/notpip/_vendor/requests/packages.py b/pipenv/patched/notpip/_vendor/requests/packages.py +index 9582fa7..928d1bb 100644 +--- a/pipenv/patched/notpip/_vendor/requests/packages.py ++++ b/pipenv/patched/notpip/_vendor/requests/packages.py +@@ -4,13 +4,13 @@ import sys + # I don't like it either. Just look the other way. :) + + for package in ('urllib3', 'idna', 'chardet'): +- vendored_package = "pip._vendor." + package ++ vendored_package = "pip9._vendor." + package + locals()[package] = __import__(vendored_package) + # This traversal is apparently necessary such that the identities are + # preserved (requests.packages.urllib3.* is urllib3.*) + for mod in list(sys.modules): + if mod == vendored_package or mod.startswith(vendored_package + '.'): +- unprefixed_mod = mod[len("pip._vendor."):] +- sys.modules['pip._vendor.requests.packages.' + unprefixed_mod] = sys.modules[mod] ++ unprefixed_mod = mod[len("pip9._vendor."):] ++ sys.modules['pip9._vendor.requests.packages.' + unprefixed_mod] = sys.modules[mod] + + # Kinda cool, though, right? From fbf8d3ccbad234d9e1c441f10e1c9930e015d7fc Mon Sep 17 00:00:00 2001 From: Dan Ryan Date: Thu, 26 Apr 2018 16:56:09 -0400 Subject: [PATCH 12/20] Update lockfile Signed-off-by: Dan Ryan --- Pipfile.lock | 136 ++++++++++----------------------------------------- 1 file changed, 27 insertions(+), 109 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index 91d17404..1cd23a3f 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,14 +1,14 @@ { "_meta": { "hash": { - "sha256": "bc81bb0e64d7ed1eed2627819b4a806d8cba554c1e0398191ba1ba32a216ed2a" + "sha256": "65984957a775e890014e30415431347075837fb78fc5940451d3fb4f4eae475c" }, "pipfile-spec": 6, "requires": {}, "sources": [ { "name": "pypi", - "url": "https://pypi.python.org/simple", + "url": "https://pypi.org/simple", "verify_ssl": true } ] @@ -29,13 +29,6 @@ ], "version": "==1.4" }, - "asn1crypto": { - "hashes": [ - "sha256:2f1adbb7546ed199e3c90ef23ec95c5cf3585bac7d11fb7eb562a3fe89c64e87", - "sha256:9d5c20441baf0cb60a4ac34cc447c6c189024b6b4c6cd7877034f4965c464e49" - ], - "version": "==0.24.0" - }, "attrs": { "hashes": [ "sha256:1c7960ccfd6a005cd9f7ba884e6316b5e430a3f1a6c37c5f87d8b43f83b54ec9", @@ -50,45 +43,20 @@ ], "version": "==2.5.3" }, + "black": { + "hashes": [ + "sha256:0461c7a52b5beb378936bf642753dec7a45305c96c6129d540b9c53227121a5a", + "sha256:7183263650ba3071034e90b40a1ea74abccbd32cf525cef6d7914479dbe7f2fb" + ], + "markers": "python_version >= '3.5'", + "version": "==18.3a0" + }, "certifi": { "hashes": [ - "sha256:14131608ad2fd56836d33a71ee60fa1c82bc9d2c8d98b7bdbc631fe1b3cd1296", - "sha256:edbc3f203427eef571f79a7692bb160a2b0f7ccaa31953e99bd17e307cf63f7d" + "sha256:13e698f54293db9f89122b0581843a782ad0934a4fe0172d2a980ba77fc61bb7", + "sha256:9fa520c1bacfb634fa7af20a76bcbd3d5fb390481724c597da32c719a7dca4b0" ], - "version": "==2018.1.18" - }, - "cffi": { - "hashes": [ - "sha256:151b7eefd035c56b2b2e1eb9963c90c6302dc15fbd8c1c0a83a163ff2c7d7743", - "sha256:1553d1e99f035ace1c0544050622b7bc963374a00c467edafac50ad7bd276aef", - "sha256:1b0493c091a1898f1136e3f4f991a784437fac3673780ff9de3bcf46c80b6b50", - "sha256:2ba8a45822b7aee805ab49abfe7eec16b90587f7f26df20c71dd89e45a97076f", - "sha256:3c85641778460581c42924384f5e68076d724ceac0f267d66c757f7535069c93", - "sha256:3eb6434197633b7748cea30bf0ba9f66727cdce45117a712b29a443943733257", - "sha256:4c91af6e967c2015729d3e69c2e51d92f9898c330d6a851bf8f121236f3defd3", - "sha256:770f3782b31f50b68627e22f91cb182c48c47c02eb405fd689472aa7b7aa16dc", - "sha256:79f9b6f7c46ae1f8ded75f68cf8ad50e5729ed4d590c74840471fc2823457d04", - "sha256:7a33145e04d44ce95bcd71e522b478d282ad0eafaf34fe1ec5bbd73e662f22b6", - "sha256:857959354ae3a6fa3da6651b966d13b0a8bed6bbc87a0de7b38a549db1d2a359", - "sha256:87f37fe5130574ff76c17cab61e7d2538a16f843bb7bca8ebbc4b12de3078596", - "sha256:95d5251e4b5ca00061f9d9f3d6fe537247e145a8524ae9fd30a2f8fbce993b5b", - "sha256:9d1d3e63a4afdc29bd76ce6aa9d58c771cd1599fbba8cf5057e7860b203710dd", - "sha256:a36c5c154f9d42ec176e6e620cb0dd275744aa1d804786a71ac37dc3661a5e95", - "sha256:ae5e35a2c189d397b91034642cb0eab0e346f776ec2eb44a49a459e6615d6e2e", - "sha256:b0f7d4a3df8f06cf49f9f121bead236e328074de6449866515cea4907bbc63d6", - "sha256:b75110fb114fa366b29a027d0c9be3709579602ae111ff61674d28c93606acca", - "sha256:ba5e697569f84b13640c9e193170e89c13c6244c24400fc57e88724ef610cd31", - "sha256:be2a9b390f77fd7676d80bc3cdc4f8edb940d8c198ed2d8c0be1319018c778e1", - "sha256:d5d8555d9bfc3f02385c1c37e9f998e2011f0db4f90e250e5bc0c0a85a813085", - "sha256:e55e22ac0a30023426564b1059b035973ec82186ddddbac867078435801c7801", - "sha256:e90f17980e6ab0f3c2f3730e56d1fe9bcba1891eeea58966e89d352492cc74f4", - "sha256:ecbb7b01409e9b782df5ded849c178a0aa7c906cf8c5a67368047daab282b184", - "sha256:ed01918d545a38998bfa5902c7c00e0fee90e957ce036a4000a88e3fe2264917", - "sha256:edabd457cd23a02965166026fd9bfd196f4324fe6032e866d0f3bd0301cd486f", - "sha256:fdf1c1dc5bafc32bc5d08b054f94d659422b05aba244d6be4ddc1c72d9aa70fb" - ], - "markers": "platform_python_implementation != 'pypy'", - "version": "==1.11.5" + "version": "==2018.4.16" }, "chardet": { "hashes": [ @@ -120,28 +88,6 @@ "markers": "python_version < '3.2'", "version": "==3.5.0" }, - "cryptography": { - "hashes": [ - "sha256:3f3b65d5a16e6b52fba63dc860b62ca9832f51f1a2ae5083c78b6840275f12dd", - "sha256:551a3abfe0c8c6833df4192a63371aa2ff43afd8f570ed345d31f251d78e7e04", - "sha256:5cb990056b7cadcca26813311187ad751ea644712022a3976443691168781b6f", - "sha256:60bda7f12ecb828358be53095fc9c6edda7de8f1ef571f96c00b2363643fa3cd", - "sha256:6fef51ec447fe9f8351894024e94736862900d3a9aa2961528e602eb65c92bdb", - "sha256:77d0ad229d47a6e0272d00f6bf8ac06ce14715a9fd02c9a97f5a2869aab3ccb2", - "sha256:808fe471b1a6b777f026f7dc7bd9a4959da4bfab64972f2bbe91e22527c1c037", - "sha256:9b62fb4d18529c84b961efd9187fecbb48e89aa1a0f9f4161c61b7fc42a101bd", - "sha256:9e5bed45ec6b4f828866ac6a6bedf08388ffcfa68abe9e94b34bb40977aba531", - "sha256:9fc295bf69130a342e7a19a39d7bbeb15c0bcaabc7382ec33ef3b2b7d18d2f63", - "sha256:abd070b5849ed64e6d349199bef955ee0ad99aefbad792f0c587f8effa681a5e", - "sha256:ba6a774749b6e510cffc2fb98535f717e0e5fd91c7c99a61d223293df79ab351", - "sha256:c332118647f084c983c6a3e1dba0f3bcb051f69d12baccac68db8d62d177eb8a", - "sha256:d6f46e862ee36df81e6342c2177ba84e70f722d9dc9c6c394f9f1f434c4a5563", - "sha256:db6013746f73bf8edd9c3d1d3f94db635b9422f503db3fc5ef105233d4c011ab", - "sha256:f57008eaff597c69cf692c3518f6d4800f0309253bb138b526a37fe9ef0c7471", - "sha256:f6c821ac253c19f2ad4c8691633ae1d1a17f120d5b01ea1d256d7b602bc59887" - ], - "version": "==2.2.2" - }, "docutils": { "hashes": [ "sha256:02aec4bd92ab067f6ff27a38a38a41173bf01bed8f89157768c1573f53e474a6", @@ -157,7 +103,7 @@ "sha256:6bd0f6ad48ec2aa117d3d141940d484deccda84d4fcd884f5c3d93c23ecd8c79", "sha256:8ad8c4783bf61ded74527bffb48ed9b54166685e4230386a9ed9b1279e2df5b1" ], - "markers": "python_version < '3'", + "markers": "python_version < '3.4'", "version": "==1.1.6" }, "execnet": { @@ -185,10 +131,10 @@ }, "flask": { "hashes": [ - "sha256:0749df235e3ff61ac108f69ac178c9770caeaccad2509cb762ce1f65570a8856", - "sha256:49f44461237b69ecd901cc7ce66feea0319b9158743dd27a2899962ab214dac1" + "sha256:7fab1062d11dd0038434e790d18c5b9133fd9e6b7257d707c4578ccc1e38b67c", + "sha256:b1883637bbee4dc7bc98d900792d0a304d609fce0f5bd9ca91d1b6457e5918dd" ], - "version": "==0.12.2" + "version": "==1.0" }, "funcsigs": { "hashes": [ @@ -212,13 +158,6 @@ ], "version": "==1.0.0" }, - "ipaddress": { - "hashes": [ - "sha256:200d8686011d470b5e4de207d803445deee427455cd0cb7c982b68cf82524f81" - ], - "markers": "python_version < '3'", - "version": "==1.0.19" - }, "itsdangerous": { "hashes": [ "sha256:cbb3fcf8d3e33df861709ecaf89d9e6629cff0a217bc2848f1b41cd30d360519" @@ -261,25 +200,18 @@ ], "version": "==4.1.0" }, - "ordereddict": { - "hashes": [ - "sha256:1c35b4ac206cef2d24816c89f89cf289dd3d38cf7c449bb3fab7bf6d43f01b1f" - ], - "version": "==1.1" - }, "pathlib2": { "hashes": [ "sha256:24e0b33e1333b55e73c9d1e9a8342417d519f7789a9d3b440f4acd00ea45157e", "sha256:deb3a960c1d55868dfbcac98432358b92ba89d95029cddd4040db1f27405055c" ], - "markers": "python_version < '3.4'", "version": "==2.1.0" }, "pbr": { "hashes": [ "sha256:4e8a0ed6a8705a26768f4c3da26026013b157821fe5f95881599556ea9d91c19", "sha256:dae4aaa78eafcad10ce2581fc34d694faa616727837fd8e55c1a00951ad6744f" - ], + ], "version": "==4.0.2" }, "pipenv": { @@ -295,10 +227,9 @@ }, "pluggy": { "hashes": [ - "sha256:714306e9b9a7b24ee4c1e3ff6463d7f652cdd30f4693121b31572e2fe1fdaea3", + "sha256:7f8ae7f5bdf75671a718d2daf0a64b7885f74510bcd98b1a0bb420eb9a9d0cff", "sha256:d345c8fe681115900d6da8d048ba67c25df42973bda370783cd58826442dcd7c", - "sha256:e160a7fcf25762bb60efc7e171d4497ff1d8d2d75a3d0df7a21b76821ecbf5c5", - "sha256:7f8ae7f5bdf75671a718d2daf0a64b7885f74510bcd98b1a0bb420eb9a9d0cff" + "sha256:e160a7fcf25762bb60efc7e171d4497ff1d8d2d75a3d0df7a21b76821ecbf5c5" ], "version": "==0.6.0" }, @@ -318,12 +249,6 @@ ], "version": "==2.3.1" }, - "pycparser": { - "hashes": [ - "sha256:99a8ca03e29851d96616ad0404b4aad7d9ee16f25c9f9708a11faf2810f7b226" - ], - "version": "==2.18" - }, "pyflakes": { "hashes": [ "sha256:08bd6a50edf8cffa9fa09a463063c425ecaaf10d1eb0335a7e8b1401aef89e6f", @@ -338,20 +263,13 @@ ], "version": "==2.2.0" }, - "pyopenssl": { - "hashes": [ - "sha256:07a2de1a54de07448732a81e38a55df7da109b2f47f599f8bb35b0cbec69d4bd", - "sha256:2c10cfba46a52c0b0950118981d61e72c1e5b1aac451ca1bc77de1a679456773" - ], - "version": "==17.5.0" - }, "pytest": { "hashes": [ - "sha256:6266f87ab64692112e5477eba395cfedda53b1933ccd29478e671e73b420c19c", - "sha256:fae491d1874f199537fd5872b5e1f0e74a009b979df9d53d1553fd03da1703e1" + "sha256:54713b26c97538db6ff0703a12b19aeaeb60b5e599de542e7fca0ec83b9038e8", + "sha256:829230122facf05a5f81a6d4dfe6454a04978ea3746853b2b84567ecf8e5c526" ], "index": "pypi", - "version": "==3.5.0" + "version": "==3.5.1" }, "pytest-forked": { "hashes": [ @@ -455,10 +373,10 @@ }, "tqdm": { "hashes": [ - "sha256:597e7526c85df881d51e094360181a84533aede1cb3f5a1cada8bbd4de557efd", - "sha256:fe3d218d5b61993d415aa2a9db6dd64c0e4cefb90164ebb197ef3b1d99f531dc" - ], - "version": "==4.23.0" + "sha256:22c760d05b2eb6e96a91ad7ed1b03c9c97e6256fb7716410c27c2cb3265a5913", + "sha256:d7bfa112a55290a5e2d0c3263a09b17b24240686fbf20d1ef7c5e8edfbb71ad0" + ], + "version": "==4.23.1" }, "twine": { "hashes": [ From 828269f3f076ac2fe2cf0d203e8470d1731b3136 Mon Sep 17 00:00:00 2001 From: Dan Ryan Date: Thu, 26 Apr 2018 19:54:40 -0400 Subject: [PATCH 13/20] Update pypi urls for pip and pipfile Signed-off-by: Dan Ryan --- .../patched/notpip/_vendor/distlib/index.py | 2 +- .../notpip/_vendor/distlib/locators.py | 6 +- pipenv/patched/notpip/index.py | 2 +- pipenv/patched/notpip/models/index.py | 2 +- pipenv/patched/pipfile/api.py | 2 +- pipenv/vendor/pip9/_vendor/distlib/index.py | 2 +- .../vendor/pip9/_vendor/distlib/locators.py | 6 +- pipenv/vendor/pip9/index.py | 2 +- pipenv/vendor/pip9/models/index.py | 2 +- .../patched/_post-pip-update-pypi-uri.patch | 57 ++++++++++++++++ .../patched/pipfile-update-pypi-uri.patch | 13 ++++ .../patches/vendor/pip-update-pypi-uri.patch | 67 +++++++++++++++++++ 12 files changed, 150 insertions(+), 13 deletions(-) create mode 100644 tasks/vendoring/patches/patched/_post-pip-update-pypi-uri.patch create mode 100644 tasks/vendoring/patches/patched/pipfile-update-pypi-uri.patch create mode 100644 tasks/vendoring/patches/vendor/pip-update-pypi-uri.patch diff --git a/pipenv/patched/notpip/_vendor/distlib/index.py b/pipenv/patched/notpip/_vendor/distlib/index.py index 6803dd28..25b96f99 100644 --- a/pipenv/patched/notpip/_vendor/distlib/index.py +++ b/pipenv/patched/notpip/_vendor/distlib/index.py @@ -22,7 +22,7 @@ from .util import cached_property, zip_dir, ServerProxy logger = logging.getLogger(__name__) -DEFAULT_INDEX = 'https://pypi.python.org/pypi' +DEFAULT_INDEX = 'https://pypi.org/pypi' DEFAULT_REALM = 'pypi' class PackageIndex(object): diff --git a/pipenv/patched/notpip/_vendor/distlib/locators.py b/pipenv/patched/notpip/_vendor/distlib/locators.py index 14789ef5..c25f629e 100644 --- a/pipenv/patched/notpip/_vendor/distlib/locators.py +++ b/pipenv/patched/notpip/_vendor/distlib/locators.py @@ -36,7 +36,7 @@ logger = logging.getLogger(__name__) HASHER_HASH = re.compile('^(\w+)=([a-f0-9]+)') CHARSET = re.compile(r';\s*charset\s*=\s*(.*)\s*$', re.I) HTML_CONTENT_TYPE = re.compile('text/html|application/x(ht)?ml') -DEFAULT_INDEX = 'https://pypi.python.org/pypi' +DEFAULT_INDEX = 'https://pypi.org/pypi' def get_all_distribution_names(url=None): """ @@ -193,7 +193,7 @@ class Locator(object): is_wheel = basename.endswith('.whl') if is_wheel: compatible = is_compatible(Wheel(basename), self.wheel_tags) - return (t.scheme != 'https', 'pypi.python.org' in t.netloc, + return (t.scheme != 'https', 'pypi.org' in t.netloc, is_wheel, compatible, basename) def prefer_url(self, url1, url2): @@ -1037,7 +1037,7 @@ class AggregatingLocator(Locator): # versions which don't conform to PEP 426 / PEP 440. default_locator = AggregatingLocator( JSONLocator(), - SimpleScrapingLocator('https://pypi.python.org/simple/', + SimpleScrapingLocator('https://pypi.org/simple/', timeout=3.0), scheme='legacy') diff --git a/pipenv/patched/notpip/index.py b/pipenv/patched/notpip/index.py index 48aaa35f..bf1cba9c 100644 --- a/pipenv/patched/notpip/index.py +++ b/pipenv/patched/notpip/index.py @@ -921,7 +921,7 @@ class Link(object): def __init__(self, url, comes_from=None, requires_python=None): """ - Object representing a parsed link from https://pypi.python.org/simple/* + Object representing a parsed link from https://pypi.org/simple/* url: url of the resource pointed to (href of the link) diff --git a/pipenv/patched/notpip/models/index.py b/pipenv/patched/notpip/models/index.py index db324287..25fd488d 100644 --- a/pipenv/patched/notpip/models/index.py +++ b/pipenv/patched/notpip/models/index.py @@ -13,4 +13,4 @@ class Index(object): return urllib_parse.urljoin(self.url, path) -PyPI = Index('https://pypi.python.org/') +PyPI = Index('https://pypi.org/') diff --git a/pipenv/patched/pipfile/api.py b/pipenv/patched/pipfile/api.py index 18a1ea23..e8fa0277 100644 --- a/pipenv/patched/pipfile/api.py +++ b/pipenv/patched/pipfile/api.py @@ -10,7 +10,7 @@ import os DEFAULT_SOURCE = { - u'url': u'https://pypi.python.org/simple', + u'url': u'https://pypi.org/simple', u'verify_ssl': True, u'name': u'pypi', } diff --git a/pipenv/vendor/pip9/_vendor/distlib/index.py b/pipenv/vendor/pip9/_vendor/distlib/index.py index 6803dd28..25b96f99 100644 --- a/pipenv/vendor/pip9/_vendor/distlib/index.py +++ b/pipenv/vendor/pip9/_vendor/distlib/index.py @@ -22,7 +22,7 @@ from .util import cached_property, zip_dir, ServerProxy logger = logging.getLogger(__name__) -DEFAULT_INDEX = 'https://pypi.python.org/pypi' +DEFAULT_INDEX = 'https://pypi.org/pypi' DEFAULT_REALM = 'pypi' class PackageIndex(object): diff --git a/pipenv/vendor/pip9/_vendor/distlib/locators.py b/pipenv/vendor/pip9/_vendor/distlib/locators.py index 14789ef5..c25f629e 100644 --- a/pipenv/vendor/pip9/_vendor/distlib/locators.py +++ b/pipenv/vendor/pip9/_vendor/distlib/locators.py @@ -36,7 +36,7 @@ logger = logging.getLogger(__name__) HASHER_HASH = re.compile('^(\w+)=([a-f0-9]+)') CHARSET = re.compile(r';\s*charset\s*=\s*(.*)\s*$', re.I) HTML_CONTENT_TYPE = re.compile('text/html|application/x(ht)?ml') -DEFAULT_INDEX = 'https://pypi.python.org/pypi' +DEFAULT_INDEX = 'https://pypi.org/pypi' def get_all_distribution_names(url=None): """ @@ -193,7 +193,7 @@ class Locator(object): is_wheel = basename.endswith('.whl') if is_wheel: compatible = is_compatible(Wheel(basename), self.wheel_tags) - return (t.scheme != 'https', 'pypi.python.org' in t.netloc, + return (t.scheme != 'https', 'pypi.org' in t.netloc, is_wheel, compatible, basename) def prefer_url(self, url1, url2): @@ -1037,7 +1037,7 @@ class AggregatingLocator(Locator): # versions which don't conform to PEP 426 / PEP 440. default_locator = AggregatingLocator( JSONLocator(), - SimpleScrapingLocator('https://pypi.python.org/simple/', + SimpleScrapingLocator('https://pypi.org/simple/', timeout=3.0), scheme='legacy') diff --git a/pipenv/vendor/pip9/index.py b/pipenv/vendor/pip9/index.py index 18269223..3a502999 100644 --- a/pipenv/vendor/pip9/index.py +++ b/pipenv/vendor/pip9/index.py @@ -881,7 +881,7 @@ class Link(object): def __init__(self, url, comes_from=None, requires_python=None): """ - Object representing a parsed link from https://pypi.python.org/simple/* + Object representing a parsed link from https://pypi.org/simple/* url: url of the resource pointed to (href of the link) diff --git a/pipenv/vendor/pip9/models/index.py b/pipenv/vendor/pip9/models/index.py index db324287..25fd488d 100644 --- a/pipenv/vendor/pip9/models/index.py +++ b/pipenv/vendor/pip9/models/index.py @@ -13,4 +13,4 @@ class Index(object): return urllib_parse.urljoin(self.url, path) -PyPI = Index('https://pypi.python.org/') +PyPI = Index('https://pypi.org/') diff --git a/tasks/vendoring/patches/patched/_post-pip-update-pypi-uri.patch b/tasks/vendoring/patches/patched/_post-pip-update-pypi-uri.patch new file mode 100644 index 00000000..58adff3e --- /dev/null +++ b/tasks/vendoring/patches/patched/_post-pip-update-pypi-uri.patch @@ -0,0 +1,57 @@ +diff --git a/pipenv/patched/notpip/_vendor/distlib/index.py b/pipenv/patched/notpip/_vendor/distlib/index.py +index 6803dd2..25b96f9 100644 +--- a/pipenv/patched/notpip/_vendor/distlib/index.py ++++ b/pipenv/patched/notpip/_vendor/distlib/index.py +@@ -22,7 +22,7 @@ from .util import cached_property, zip_dir, ServerProxy + + logger = logging.getLogger(__name__) + +-DEFAULT_INDEX = 'https://pypi.python.org/pypi' ++DEFAULT_INDEX = 'https://pypi.org/pypi' + DEFAULT_REALM = 'pypi' + + class PackageIndex(object): +diff --git a/pipenv/patched/notpip/_vendor/distlib/locators.py b/pipenv/patched/notpip/_vendor/distlib/locators.py +index 14789ef..c25f629 100644 +--- a/pipenv/patched/notpip/_vendor/distlib/locators.py ++++ b/pipenv/patched/notpip/_vendor/distlib/locators.py +@@ -36,7 +36,7 @@ logger = logging.getLogger(__name__) + HASHER_HASH = re.compile('^(\w+)=([a-f0-9]+)') + CHARSET = re.compile(r';\s*charset\s*=\s*(.*)\s*$', re.I) + HTML_CONTENT_TYPE = re.compile('text/html|application/x(ht)?ml') +-DEFAULT_INDEX = 'https://pypi.python.org/pypi' ++DEFAULT_INDEX = 'https://pypi.org/pypi' + + def get_all_distribution_names(url=None): + """ +@@ -193,7 +193,7 @@ class Locator(object): + is_wheel = basename.endswith('.whl') + if is_wheel: + compatible = is_compatible(Wheel(basename), self.wheel_tags) +- return (t.scheme != 'https', 'pypi.python.org' in t.netloc, ++ return (t.scheme != 'https', 'pypi.org' in t.netloc, + is_wheel, compatible, basename) + + def prefer_url(self, url1, url2): +@@ -1037,7 +1037,7 @@ class AggregatingLocator(Locator): + # versions which don't conform to PEP 426 / PEP 440. + default_locator = AggregatingLocator( + JSONLocator(), +- SimpleScrapingLocator('https://pypi.python.org/simple/', ++ SimpleScrapingLocator('https://pypi.org/simple/', + timeout=3.0), + scheme='legacy') + +diff --git a/pipenv/patched/notpip/index.py b/pipenv/patched/notpip/index.py +index 48aaa35..bf1cba9 100644 +--- a/pipenv/patched/notpip/index.py ++++ b/pipenv/patched/notpip/index.py +@@ -921,7 +921,7 @@ class Link(object): + + def __init__(self, url, comes_from=None, requires_python=None): + """ +- Object representing a parsed link from https://pypi.python.org/simple/* ++ Object representing a parsed link from https://pypi.org/simple/* + + url: + url of the resource pointed to (href of the link) diff --git a/tasks/vendoring/patches/patched/pipfile-update-pypi-uri.patch b/tasks/vendoring/patches/patched/pipfile-update-pypi-uri.patch new file mode 100644 index 00000000..ecbe2aac --- /dev/null +++ b/tasks/vendoring/patches/patched/pipfile-update-pypi-uri.patch @@ -0,0 +1,13 @@ +diff --git a/pipenv/patched/pipfile/api.py b/pipenv/patched/pipfile/api.py +index 18a1ea2..e8fa027 100644 +--- a/pipenv/patched/pipfile/api.py ++++ b/pipenv/patched/pipfile/api.py +@@ -10,7 +10,7 @@ import os + + + DEFAULT_SOURCE = { +- u'url': u'https://pypi.python.org/simple', ++ u'url': u'https://pypi.org/simple', + u'verify_ssl': True, + u'name': u'pypi', + } diff --git a/tasks/vendoring/patches/vendor/pip-update-pypi-uri.patch b/tasks/vendoring/patches/vendor/pip-update-pypi-uri.patch new file mode 100644 index 00000000..719062b3 --- /dev/null +++ b/tasks/vendoring/patches/vendor/pip-update-pypi-uri.patch @@ -0,0 +1,67 @@ +diff --git a/pipenv/vendor/pip9/_vendor/distlib/index.py b/pipenv/vendor/pip9/_vendor/distlib/index.py +index 6803dd2..25b96f9 100644 +--- a/pipenv/vendor/pip9/_vendor/distlib/index.py ++++ b/pipenv/vendor/pip9/_vendor/distlib/index.py +@@ -22,7 +22,7 @@ from .util import cached_property, zip_dir, ServerProxy + + logger = logging.getLogger(__name__) + +-DEFAULT_INDEX = 'https://pypi.python.org/pypi' ++DEFAULT_INDEX = 'https://pypi.org/pypi' + DEFAULT_REALM = 'pypi' + + class PackageIndex(object): +diff --git a/pipenv/vendor/pip9/_vendor/distlib/locators.py b/pipenv/vendor/pip9/_vendor/distlib/locators.py +index 14789ef..c25f629 100644 +--- a/pipenv/vendor/pip9/_vendor/distlib/locators.py ++++ b/pipenv/vendor/pip9/_vendor/distlib/locators.py +@@ -36,7 +36,7 @@ logger = logging.getLogger(__name__) + HASHER_HASH = re.compile('^(\w+)=([a-f0-9]+)') + CHARSET = re.compile(r';\s*charset\s*=\s*(.*)\s*$', re.I) + HTML_CONTENT_TYPE = re.compile('text/html|application/x(ht)?ml') +-DEFAULT_INDEX = 'https://pypi.python.org/pypi' ++DEFAULT_INDEX = 'https://pypi.org/pypi' + + def get_all_distribution_names(url=None): + """ +@@ -193,7 +193,7 @@ class Locator(object): + is_wheel = basename.endswith('.whl') + if is_wheel: + compatible = is_compatible(Wheel(basename), self.wheel_tags) +- return (t.scheme != 'https', 'pypi.python.org' in t.netloc, ++ return (t.scheme != 'https', 'pypi.org' in t.netloc, + is_wheel, compatible, basename) + + def prefer_url(self, url1, url2): +@@ -1037,7 +1037,7 @@ class AggregatingLocator(Locator): + # versions which don't conform to PEP 426 / PEP 440. + default_locator = AggregatingLocator( + JSONLocator(), +- SimpleScrapingLocator('https://pypi.python.org/simple/', ++ SimpleScrapingLocator('https://pypi.org/simple/', + timeout=3.0), + scheme='legacy') + +diff --git a/pipenv/vendor/pip9/index.py b/pipenv/vendor/pip9/index.py +index 1826922..3a50299 100644 +--- a/pipenv/vendor/pip9/index.py ++++ b/pipenv/vendor/pip9/index.py +@@ -881,7 +881,7 @@ class Link(object): + + def __init__(self, url, comes_from=None, requires_python=None): + """ +- Object representing a parsed link from https://pypi.python.org/simple/* ++ Object representing a parsed link from https://pypi.org/simple/* + + url: + url of the resource pointed to (href of the link) +diff --git a/pipenv/vendor/pip9/models/index.py b/pipenv/vendor/pip9/models/index.py +index db32428..25fd488 100644 +--- a/pipenv/vendor/pip9/models/index.py ++++ b/pipenv/vendor/pip9/models/index.py +@@ -13,4 +13,4 @@ class Index(object): + return urllib_parse.urljoin(self.url, path) + + +-PyPI = Index('https://pypi.python.org/') ++PyPI = Index('https://pypi.org/') From 4a5bc94c47ff2be49b0825b8417c97b83f4bd8d6 Mon Sep 17 00:00:00 2001 From: Dan Ryan Date: Thu, 26 Apr 2018 23:08:49 -0400 Subject: [PATCH 14/20] Update history Signed-off-by: Dan Ryan --- HISTORY.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/HISTORY.txt b/HISTORY.txt index df018f32..9a9967e7 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -11,6 +11,7 @@ - Make imports lazy to improve initial load time. - Extra path searching for python at runtime. - Shellquote paths to requirement files in case of spaces on windows. + - Update PyPI urls. - Require `--python` values to exist when passing a path. - Bugfix for environment variable expansion in 'unlocked' pipfiles. - Bugfix for `--deploy` flag. From 373073027fab4cc8459eb442562799d9832b3dcd Mon Sep 17 00:00:00 2001 From: Dan Ryan Date: Thu, 26 Apr 2018 23:28:54 -0400 Subject: [PATCH 15/20] Capture package data Signed-off-by: Dan Ryan --- setup.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/setup.py b/setup.py index 50f1a91b..5954684e 100644 --- a/setup.py +++ b/setup.py @@ -113,6 +113,18 @@ setup( 'pipenv-resolver=pipenv.resolver:main', ] }, + package_data={ + "pipenv.vendor.requests": ["*.pem"], + "pipenv.vendor.certifi": ["*.pem"], + "pipenv.patched.notpip._vendor.certifi": ["*.pem"], + "pipenv.patched.notpip._vendor.requests": ["*.pem"], + "pipenv.patched.notpip._vendor.distlib._backport": ["sysconfig.cfg"], + "pipenv.patched.notpip._vendor.distlib": ["t32.exe", "t64.exe", "w32.exe", "w64.exe"], + "pipenv.vendor.pip9._vendor.certifi": ["*.pem"], + "pipenv.vendor.pip9._vendor.requests": ["*.pem"], + "pipenv.vendor.pip9._vendor.distlib._backport": ["sysconfig.cfg"], + "pipenv.vendor.pip9._vendor.distlib": ["t32.exe", "t64.exe", "w32.exe", "w64.exe"], + }, install_requires=required, extras_require={}, include_package_data=True, From bd057000b2ce4a1af8466f6f9745bf3ad9d49249 Mon Sep 17 00:00:00 2001 From: Tzu-ping Chung Date: Fri, 27 Apr 2018 15:13:23 +0800 Subject: [PATCH 16/20] Implement utility to write to lockfile atomically --- pipenv/core.py | 3 ++- pipenv/utils.py | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/pipenv/core.py b/pipenv/core.py index 423176e1..f6bebbcb 100644 --- a/pipenv/core.py +++ b/pipenv/core.py @@ -25,6 +25,7 @@ import six from .cmdparse import ScriptEmptyError from .project import Project, SourceNotFound from .utils import ( + atomic_open_for_write, convert_deps_from_pip, convert_deps_to_pip, is_required_version, @@ -1165,7 +1166,7 @@ def do_lock( ] if write: # Write out the lockfile. - with open(project.lockfile_location, 'w') as f: + with atomic_open_for_write(project.lockfile_location) as f: simplejson.dump( lockfile, f, indent=4, separators=(',', ': '), sort_keys=True ) diff --git a/pipenv/utils.py b/pipenv/utils.py index 10e3ae75..4e7fc028 100644 --- a/pipenv/utils.py +++ b/pipenv/utils.py @@ -1323,3 +1323,41 @@ def split_argument(req, short=None, long_=None): index, more_req = remaining_line[0], ' '.join(remaining_line[1:]) req = '{0} {1}'.format(req, more_req) return req, index + + +@contextmanager +def atomic_open_for_write(target, binary=False): + """Atomically open `target` for writing. + + This is based on Lektor's `atomic_open()` utility, but simplified a lot + to handle only writing, and skip many multi-process/thread edge cases + handled by Werkzeug. + + How this works: + + * Create a temp file (in the same directory of the actual target), and + yield for surrounding code to write to it. + * If some thing goes wrong, try to remove the temp file. The actual target + is not touched whatsoever. + * If everything goes well, close the temp file, and replace the actual + target with this new file. + """ + fd, tmp = tempfile.mkstemp( + dir=os.path.dirname(target), + prefix='.__atomic-write', + ) + os.chmod(tmp, 0o644) + f = os.fdopen(fd, 'wb' if binary else 'w') + try: + yield f + except BaseException: + f.close() + try: + os.remove(tmp) + except OSError: + pass + raise + else: + f.close() + os.remove(target) # This is needed on Windows. + os.rename(tmp, target) # No os.replace() on Python 2. From 0944eb56d84ee1060a8e8b8292f36839d761c66c Mon Sep 17 00:00:00 2001 From: Tzu-ping Chung Date: Fri, 27 Apr 2018 15:31:46 +0800 Subject: [PATCH 17/20] Ignore errors when removing old file --- pipenv/utils.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pipenv/utils.py b/pipenv/utils.py index 4e7fc028..2c815b6f 100644 --- a/pipenv/utils.py +++ b/pipenv/utils.py @@ -1359,5 +1359,8 @@ def atomic_open_for_write(target, binary=False): raise else: f.close() - os.remove(target) # This is needed on Windows. + try: + os.remove(target) # This is needed on Windows. + except OSError: + pass os.rename(tmp, target) # No os.replace() on Python 2. From 1a196c1c9fa71ea459c4de1a44d1b02d8577e838 Mon Sep 17 00:00:00 2001 From: Grey Baker Date: Fri, 27 Apr 2018 22:17:34 +0100 Subject: [PATCH 18/20] Allow pyenv installs in non-interactive sessions in PIPENV_YES is set --- pipenv/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipenv/core.py b/pipenv/core.py index 8965668d..13898f22 100644 --- a/pipenv/core.py +++ b/pipenv/core.py @@ -461,7 +461,7 @@ def ensure_python(three=None, python=None): if not PYENV_INSTALLED: abort() else: - if (not PIPENV_DONT_USE_PYENV) and (SESSION_IS_INTERACTIVE): + if (not PIPENV_DONT_USE_PYENV) and (SESSION_IS_INTERACTIVE or PIPENV_YES): version_map = { # TODO: Keep this up to date! # These versions appear incompatible with pew: From 824dcb74e2e01b7966f6e054494c542772ec8577 Mon Sep 17 00:00:00 2001 From: Tom Eastman Date: Sat, 28 Apr 2018 09:48:44 +1200 Subject: [PATCH 19/20] Suggest pip as the first recommended installation method instead of Homebrew. --- docs/index.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index 28a8b745..06d59eda 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -45,9 +45,9 @@ The problems that Pipenv seeks to solve are multi-faceted: Install Pipenv Today! --------------------- -If you're on MacOS, use can install Pipenv easily with Homebrew:: +Just use pip:: - $ brew install pipenv + $ pip install pipenv Or, if you're using Ubuntu 17.10:: @@ -56,9 +56,9 @@ Or, if you're using Ubuntu 17.10:: $ sudo apt update $ sudo apt install pipenv -Otherwise, just use pip:: +Otherwise, if you're on MacOS, you can install Pipenv easily with Homebrew:: - $ pip install pipenv + $ brew install pipenv ✨🍰✨ From e8a8ac428f44fd404dd4dd85a7b4b678a8893aed Mon Sep 17 00:00:00 2001 From: Dan Ryan Date: Mon, 30 Apr 2018 00:03:48 -0400 Subject: [PATCH 20/20] Make sure we are not in a virtualenv if aborting - Fixes #2078 Signed-off-by: Dan Ryan --- pipenv/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipenv/core.py b/pipenv/core.py index a759c857..0254eb8d 100644 --- a/pipenv/core.py +++ b/pipenv/core.py @@ -1352,7 +1352,7 @@ def do_init( do_lock(system=system, pre=pre, keep_outdated=keep_outdated) # Write out the lockfile if it doesn't exist. if not project.lockfile_exists and not skip_lock: - if system or allow_global: + if system or allow_global and not PIPENV_VIRTUALENV: click.echo( '{0}: --system is intended to be used for Pipfile installation, ' 'not installation of specific packages. Aborting.'.format(