mirror of
https://github.com/kennethreitz/pipenv.git
synced 2026-06-05 22:50:18 +00:00
Merge branch 'master' into fix-queue
This commit is contained in:
@@ -1,4 +1,22 @@
|
||||
steps:
|
||||
- task: UsePythonVersion@0
|
||||
inputs:
|
||||
versionSpec: $(python.version)
|
||||
architecture: '$(python.architecture)'
|
||||
addToPath: true
|
||||
displayName: Use Python $(python.version)
|
||||
|
||||
- template: install-dependencies.yml
|
||||
|
||||
- script: |
|
||||
echo '##vso[task.setvariable variable=PIPENV_DEFAULT_PYTHON_VERSION]'$(python.version)
|
||||
env:
|
||||
PYTHON_VERSION: $(python.version)
|
||||
|
||||
- template: create-virtualenv.yml
|
||||
parameters:
|
||||
python_version: $(python.version)
|
||||
|
||||
- script: |
|
||||
python -m pip install --upgrade wheel pip setuptools twine readme_renderer[md]
|
||||
python setup.py sdist bdist_wheel
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
parameters:
|
||||
python_version: ''
|
||||
|
||||
steps:
|
||||
|
||||
- script: |
|
||||
@@ -29,10 +32,13 @@ steps:
|
||||
- script: |
|
||||
echo "Python path: $(PY_EXE)"
|
||||
echo "GIT_SSL_CAINFO: $(GIT_SSL_CAINFO)"
|
||||
echo "PIPENV PYTHON VERSION: $PIPENV_DEFAULT_PYTHON_VERSION"
|
||||
echo "PIPENV PYTHON VERSION: $(python.version)"
|
||||
echo "python_version: ${{ parameters.python_version }}"
|
||||
git submodule sync
|
||||
git submodule update --init --recursive
|
||||
$(PY_EXE) -m pipenv install --deploy --dev --python="$(PY_EXE)"
|
||||
env:
|
||||
PIPENV_DEFAULT_PYTHON_VERSION: $(python.version)
|
||||
PIPENV_DEFAULT_PYTHON_VERSION: ${{ parameters.python_version }}
|
||||
PYTHONWARNINGS: 'ignore:DEPRECATION'
|
||||
PIPENV_NOSPIN: '1'
|
||||
displayName: Make Virtualenv
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
parameters:
|
||||
python_version: ''
|
||||
|
||||
steps:
|
||||
- script: |
|
||||
# Fix Git SSL errors
|
||||
echo "Using pipenv python version: $PIPENV_DEFAULT_PYTHON_VERSION"
|
||||
echo "Using pipenv python version: $(PIPENV_DEFAULT_PYTHON_VERSION)"
|
||||
git submodule sync && git submodule update --init --recursive
|
||||
pipenv run pytest --junitxml=test-results.xml
|
||||
displayName: Run integration tests
|
||||
env:
|
||||
PY_EXE: $(PY_EXE)
|
||||
GIT_SSL_CAINFO: $(GIT_SSL_CAINFO)
|
||||
LANG: $(LANG)
|
||||
PIP_PROCESS_DEPENDENCY_LINKS: $(PIP_PROCESS_DEPENDENCY_LINKS)
|
||||
PIPENV_DEFAULT_PYTHON_VERSION: $(PIPENV_DEFAULT_PYTHON_VERSION)
|
||||
PYTHONWARNINGS: ignore:DEPRECATION
|
||||
PIPENV_NOSPIN: '1'
|
||||
PIPENV_DEFAULT_PYTHON_VERSION: ${{ parameters.python_version }}
|
||||
|
||||
@@ -1,16 +1,21 @@
|
||||
parameters:
|
||||
python_version: ''
|
||||
|
||||
steps:
|
||||
- powershell: |
|
||||
subst T: "$env:TEMP"
|
||||
Write-Host "##vso[task.setvariable variable=TEMP]T:\"
|
||||
Write-Host "##vso[task.setvariable variable=TMP]T:\"
|
||||
Write-Host "##vso[task.setvariable variable=PIPENV_DEFAULT_PYTHON_VERSION]$env:PYTHON_VERSION"
|
||||
Write-Host "##vso[task.setvariable variable=PIPENV_NOSPIN]1"
|
||||
displayName: Fix Temp Variable
|
||||
env:
|
||||
PYTHON_VERSION: ${{ parameters.python_version }}
|
||||
|
||||
- script: |
|
||||
echo "Using pipenv python version: $PIPENV_DEFAULT_PYTHON_VERSION"
|
||||
git submodule sync && git submodule update --init --recursive
|
||||
pipenv run pytest -ra --ignore=pipenv\patched --ignore=pipenv\vendor --junitxml=test-results.xml tests
|
||||
displayName: Run integration tests
|
||||
env:
|
||||
PIPENV_DEFAULT_PYTHON_VERSION: $(PIPENV_DEFAULT_PYTHON_VERSION)
|
||||
PYTHONWARNINGS: 'ignore:DEPRECATION'
|
||||
PIPENV_NOSPIN: '1'
|
||||
|
||||
@@ -9,18 +9,22 @@ steps:
|
||||
- template: install-dependencies.yml
|
||||
|
||||
- script: |
|
||||
echo '##vso[task.setvariable variable=PIPENV_DEFAULT_PYTHON_VERSION]$PYTHON_VERSION'
|
||||
echo '##vso[task.setvariable variable=PIPENV_DEFAULT_PYTHON_VERSION]'$(python.version)
|
||||
env:
|
||||
PYTHON_VERSION: $(python.version)
|
||||
|
||||
- template: create-virtualenv.yml
|
||||
parameters:
|
||||
python.version: $(python.version)
|
||||
python_version: $(python.version)
|
||||
|
||||
- ${{ if eq(parameters.vmImage, 'windows-2019') }}:
|
||||
- template: run-tests-windows.yml
|
||||
parameters:
|
||||
python_version: $(python.version)
|
||||
- ${{ if ne(parameters.vmImage, 'windows-2019') }}:
|
||||
- template: run-tests-linux.yml
|
||||
parameters:
|
||||
python_version: $(python.version)
|
||||
|
||||
- task: PublishTestResults@2
|
||||
displayName: Publish Test Results
|
||||
|
||||
@@ -1,4 +1,25 @@
|
||||
parameters:
|
||||
python_version: ''
|
||||
|
||||
steps:
|
||||
- task: UsePythonVersion@0
|
||||
inputs:
|
||||
versionSpec: $(python.version)
|
||||
architecture: '$(python.architecture)'
|
||||
addToPath: true
|
||||
displayName: Use Python $(python.version)
|
||||
|
||||
- template: install-dependencies.yml
|
||||
|
||||
- script: |
|
||||
echo '##vso[task.setvariable variable=PIPENV_DEFAULT_PYTHON_VERSION]'$(python.version)
|
||||
env:
|
||||
PYTHON_VERSION: $(python.version)
|
||||
|
||||
- template: create-virtualenv.yml
|
||||
parameters:
|
||||
python_version: $(python.version)
|
||||
|
||||
- script: |
|
||||
python -m pip install --upgrade invoke requests parver bs4 vistir towncrier pip setuptools wheel --upgrade-strategy=eager
|
||||
python -m invoke vendoring.update
|
||||
@@ -7,6 +28,6 @@ steps:
|
||||
PY_EXE: $(PY_EXE)
|
||||
GIT_SSL_CAINFO: $(GIT_SSL_CAINFO)
|
||||
LANG: $(LANG)
|
||||
PIPENV_DEFAULT_PYTHON_VERSION: $(PIPENV_DEFAULT_PYTHON_VERSION)
|
||||
PIPENV_DEFAULT_PYTHON_VERSION: '${{ parameters.python_version }}'
|
||||
PYTHONWARNINGS: ignore:DEPRECATION
|
||||
PIPENV_NOSPIN: '1'
|
||||
|
||||
@@ -25,3 +25,6 @@
|
||||
[submodule "tests/test_artifacts/git/requests-2.18.4"]
|
||||
path = tests/test_artifacts/git/requests-2.18.4
|
||||
url = https://github.com/requests/requests
|
||||
[submodule "tests/pypi"]
|
||||
path = tests/pypi
|
||||
url = https://github.com/sarugaku/pipenv-test-artifacts.git
|
||||
|
||||
Generated
+47
-146
@@ -61,36 +61,20 @@
|
||||
},
|
||||
"babel": {
|
||||
"hashes": [
|
||||
"sha256:6778d85147d5d85345c14a26aada5e478ab04e39b078b0745ee6870c2b5cf669",
|
||||
"sha256:8cba50f48c529ca3fa18cf81fa9403be176d374ac4d60738b839122dfaaa3d23"
|
||||
"sha256:af92e6106cb7c55286b25b38ad7695f8b4efb36a90ba483d7f7a6628c46158ab",
|
||||
"sha256:e86135ae101e31e2c8ec20a4e0c5220f4eed12487d5cf3f78be7e98d3a57fc28"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==2.6.0"
|
||||
"version": "==2.7.0"
|
||||
},
|
||||
"backports.functools-lru-cache": {
|
||||
"hashes": [
|
||||
"sha256:9d98697f088eb1b0fa451391f91afb5e3ebde16bbdb272819fd091151fda4f1a",
|
||||
"sha256:f0b0e4eba956de51238e17573b7087e852dfe9854afd2e9c873f73fc0ca0a6dd"
|
||||
],
|
||||
"markers": "python_version == '2.7'",
|
||||
"markers": "python_version < '3'",
|
||||
"version": "==1.5"
|
||||
},
|
||||
"backports.shutil-get-terminal-size": {
|
||||
"hashes": [
|
||||
"sha256:0975ba55054c15e346944b38956a4c9cbee9009391e41b86c68990effb8c1f64",
|
||||
"sha256:713e7a8228ae80341c70586d1cc0a8caa5207346927e23d09dcbcaf18eadec80"
|
||||
],
|
||||
"markers": "python_version == '2.7'",
|
||||
"version": "==1.0.0"
|
||||
},
|
||||
"backports.weakref": {
|
||||
"hashes": [
|
||||
"sha256:81bc9b51c0abc58edc76aefbbc68c62a787918ffe943a37947e162c3f8e19e82",
|
||||
"sha256:bc4170a29915f8b22c9e7c4939701859650f2eb84184aee80da329ac0b9825c2"
|
||||
],
|
||||
"markers": "python_version == '2.7'",
|
||||
"version": "==1.0.post1"
|
||||
},
|
||||
"beautifulsoup4": {
|
||||
"hashes": [
|
||||
"sha256:034740f6cb549b4e932ae1ab975581e6103ac8f942200a0e9759065984391858",
|
||||
@@ -121,19 +105,6 @@
|
||||
],
|
||||
"version": "==0.0.1"
|
||||
},
|
||||
"cached-property": {
|
||||
"hashes": [
|
||||
"sha256:3a026f1a54135677e7da5ce819b0c690f156f37976f3e30c5430740725203d7f",
|
||||
"sha256:9217a59f14a5682da7c4b8829deadbfc194ac22e9908ccf7c8820234e80a1504"
|
||||
],
|
||||
"version": "==1.5.1"
|
||||
},
|
||||
"cerberus": {
|
||||
"hashes": [
|
||||
"sha256:0be48fc0dc84f83202a5309c0aa17cd5393e70731a1698a50d118b762fbe6875"
|
||||
],
|
||||
"version": "==1.3.1"
|
||||
},
|
||||
"certifi": {
|
||||
"hashes": [
|
||||
"sha256:59b7658e26ca9c7339e00f8f4636cdfe59d34fa37b9b04f6f9e9926b3cece1a5",
|
||||
@@ -168,14 +139,16 @@
|
||||
"sha256:8be81d89d6e7b4c0d4e44bcc525845f6da25821de80cb5e06e7e0238a2899e32",
|
||||
"sha256:da60d0014fd8c55eb48c1c5354352e363e2d30bbf7057e5e171a468390184c75"
|
||||
],
|
||||
"markers": "python_version == '2.7'",
|
||||
"markers": "python_version < '3'",
|
||||
"version": "==3.7.4"
|
||||
},
|
||||
"distlib": {
|
||||
"contextlib2": {
|
||||
"hashes": [
|
||||
"sha256:ecb3d0e4f71d0fa7f38db6bcc276c7c9a1c6638a516d726495934a553eb3fbe0"
|
||||
"sha256:509f9419ee91cdd00ba34443217d5ca51f5a364a404e1dce9e8979cea969ca48",
|
||||
"sha256:f5260a6e679d2ff42ec91ec5252f4eeffdcf21053db9113bd0a8e4d953769c00"
|
||||
],
|
||||
"version": "==0.2.9.post0"
|
||||
"markers": "python_version < '3'",
|
||||
"version": "==0.5.5"
|
||||
},
|
||||
"docutils": {
|
||||
"hashes": [
|
||||
@@ -211,13 +184,6 @@
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==1.6.0"
|
||||
},
|
||||
"first": {
|
||||
"hashes": [
|
||||
"sha256:8d8e46e115ea8ac652c76123c0865e3ff18372aef6f03c22809ceefcea9dec86",
|
||||
"sha256:ff285b08c55f8c97ce4ea7012743af2495c9f1291785f163722bd36f6af6d3bf"
|
||||
],
|
||||
"version": "==2.0.2"
|
||||
},
|
||||
"flake8": {
|
||||
"hashes": [
|
||||
"sha256:859996073f341f2670741b51ec1e67a01da142831aa1fdc6242dbf88dffbe661",
|
||||
@@ -236,17 +202,17 @@
|
||||
},
|
||||
"flask": {
|
||||
"hashes": [
|
||||
"sha256:2271c0070dbcb5275fad4a82e29f23ab92682dc45f9dfbc22c02ba9b9322ce48",
|
||||
"sha256:a080b744b7e345ccfcbc77954861cb05b3c63786e93f2b3875e0913d44b43f05"
|
||||
"sha256:ad7c6d841e64296b962296c2c2dabc6543752985727af86a975072dea984b6f3",
|
||||
"sha256:e7d32475d1de5facaa55e3958bc4ec66d3762076b074296aa50ef8fdc5b9df61"
|
||||
],
|
||||
"version": "==1.0.2"
|
||||
"version": "==1.0.3"
|
||||
},
|
||||
"funcsigs": {
|
||||
"hashes": [
|
||||
"sha256:330cc27ccbf7f1e992e69fef78261dc7c6569012cf397db8d3de0234e6c937ca",
|
||||
"sha256:a7bb0f2cf3a3fd1ab2732cb49eba4252c2af4240442415b4abce3b87022a8f50"
|
||||
],
|
||||
"markers": "python_version < '3.3'",
|
||||
"markers": "python_version < '3.0'",
|
||||
"version": "==1.0.2"
|
||||
},
|
||||
"functools32": {
|
||||
@@ -280,6 +246,14 @@
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==1.1.0"
|
||||
},
|
||||
"importlib-metadata": {
|
||||
"hashes": [
|
||||
"sha256:027cfc6524613de726789072f95d2e4cc64dd1dee8096d42d13f2ead5bd302f5",
|
||||
"sha256:0d05199e1f0b1a8707a1b9c46476d4a49807fb56cb1b0737db1d37feb42fe31d"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==0.15"
|
||||
},
|
||||
"incremental": {
|
||||
"hashes": [
|
||||
"sha256:717e12246dddf231a349175f48d74d93e2897244939173b01974ab6661406b9f",
|
||||
@@ -297,11 +271,11 @@
|
||||
},
|
||||
"isort": {
|
||||
"hashes": [
|
||||
"sha256:1349c6f7c2a0f7539f5f2ace51a9a8e4a37086ce4de6f78f5f53fb041d0a3cd5",
|
||||
"sha256:f09911f6eb114e5592abe635aded8bf3d2c3144ebcfcaf81ee32e7af7b7d1870"
|
||||
"sha256:c40744b6bc5162bbb39c1257fe298b7a393861d50978b565f3ccd9cb9de0182a",
|
||||
"sha256:f57abacd059dc3bd666258d1efb0377510a89777fda3e3274e3c01f7c03ae22d"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==4.3.18"
|
||||
"version": "==4.3.20"
|
||||
},
|
||||
"itsdangerous": {
|
||||
"hashes": [
|
||||
@@ -423,7 +397,7 @@
|
||||
"sha256:25199318e8cc3c25dcb45cbe084cc061051336d5a9ea2a12448d3d8cb748f742",
|
||||
"sha256:5887121d7f7df3603bca2f710e7219f3eca0eb69e0b7cc6e0a022e155ac931a7"
|
||||
],
|
||||
"markers": "python_version < '3.5'",
|
||||
"markers": "python_version < '3.6'",
|
||||
"version": "==2.3.3"
|
||||
},
|
||||
"pbr": {
|
||||
@@ -433,21 +407,6 @@
|
||||
],
|
||||
"version": "==5.2.0"
|
||||
},
|
||||
"pep517": {
|
||||
"hashes": [
|
||||
"sha256:43a7aa3902efd305a605c1028e4045968cd012831233ecab633a31d3ba4860a5",
|
||||
"sha256:cb5ca55450b64e80744cd5c32f7d5b8928004042dfea50fdc3f96ad7f27cba96"
|
||||
],
|
||||
"version": "==0.5.0"
|
||||
},
|
||||
"pip-shims": {
|
||||
"hashes": [
|
||||
"sha256:3bc24ec050a6b9eea35419467237e4f47eaf806dadc9999bf887355c377edea7",
|
||||
"sha256:edb4cf3c509eab2f36b55c1ac1a59a4c485ccd537cc87934d74950880f641256"
|
||||
],
|
||||
"markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==0.3.2"
|
||||
},
|
||||
"pipenv": {
|
||||
"editable": true,
|
||||
"extras": [
|
||||
@@ -463,24 +422,13 @@
|
||||
],
|
||||
"version": "==1.5.0.1"
|
||||
},
|
||||
"plette": {
|
||||
"extras": [
|
||||
"validation"
|
||||
],
|
||||
"hashes": [
|
||||
"sha256:c0e3553c1e581d8423daccbd825789c6e7f29b7d9e00e5331b12e1642a1a26d3",
|
||||
"sha256:dde5d525cf5f0cbad4d938c83b93db17887918daf63c13eafed257c4f61b07b4"
|
||||
],
|
||||
"markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==0.2.2"
|
||||
},
|
||||
"pluggy": {
|
||||
"hashes": [
|
||||
"sha256:25a1bc1d148c9a640211872b4ff859878d422bccb59c9965e04eed468a0aa180",
|
||||
"sha256:964cedd2b27c492fbf0b7f58b3284a09cf7f99b0f715941fb24a439b3af1bd1a"
|
||||
"sha256:0825a152ac059776623854c1543d65a4ad408eb3d33ee114dff91e57ec6ae6fc",
|
||||
"sha256:b9817417e95936bf75d85d3f8767f7df6cdde751fc40aed3bb3074cbcb77757c"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==0.11.0"
|
||||
"version": "==0.12.0"
|
||||
},
|
||||
"py": {
|
||||
"hashes": [
|
||||
@@ -508,10 +456,11 @@
|
||||
},
|
||||
"pygments": {
|
||||
"hashes": [
|
||||
"sha256:5ffada19f6203563680669ee7f53b64dabbeb100eb51b61996085e99c03b284a",
|
||||
"sha256:e8218dd399a61674745138520d0d4cf2621d7e032439341bc3f647bff125818d"
|
||||
"sha256:36586500a94cd97f8c2c19d251cdb78868d1a822e0e491bfc1d811766aedb772",
|
||||
"sha256:b437bc0d04dc36f1f5b3592985b3e0a3d0af46b7c39199231706d19a4ee63344"
|
||||
],
|
||||
"version": "==2.3.1"
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==2.4.1"
|
||||
},
|
||||
"pyparsing": {
|
||||
"hashes": [
|
||||
@@ -555,12 +504,6 @@
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==1.28.0"
|
||||
},
|
||||
"pytoml": {
|
||||
"hashes": [
|
||||
"sha256:ca2d0cb127c938b8b76a9a0d0f855cf930c1d50cc3a0af6d3595b566519a1013"
|
||||
],
|
||||
"version": "==0.1.20"
|
||||
},
|
||||
"pytz": {
|
||||
"hashes": [
|
||||
"sha256:303879e36b721603cc54604edcac9d20401bdbe31e1e4fdee5b9f98d5d31dfda",
|
||||
@@ -577,11 +520,11 @@
|
||||
},
|
||||
"requests": {
|
||||
"hashes": [
|
||||
"sha256:502a824f31acdacb3a35b6690b5fbf0bc41d63a24a45c4004352b0242707598e",
|
||||
"sha256:7bf2a778576d825600030a110f3c0e3e8edc51dfaafe1c146e39a2027784957b"
|
||||
"sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4",
|
||||
"sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==2.21.0"
|
||||
"version": "==2.22.0"
|
||||
},
|
||||
"requests-toolbelt": {
|
||||
"hashes": [
|
||||
@@ -590,21 +533,6 @@
|
||||
],
|
||||
"version": "==0.9.1"
|
||||
},
|
||||
"requirementslib": {
|
||||
"hashes": [
|
||||
"sha256:a5bcff2861eea9358e90d6a4234f0bf4ad0ba730f86a4ea4680f53365b7b4735",
|
||||
"sha256:ae0c2fce1b33c9c7b171895ab11472bd7be9c45f6214aad97ceaf83511d78d93"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==1.5.0"
|
||||
},
|
||||
"resolvelib": {
|
||||
"hashes": [
|
||||
"sha256:6c4c6690b0bdd78bcc002e1a5d1b6abbde58c694a6ea1838f165b20d2c943db7",
|
||||
"sha256:8734e53271ef98f38a2c99324d5e7905bc00c97dc3fc5bb7d83c82a979e71c04"
|
||||
],
|
||||
"version": "==0.2.2"
|
||||
},
|
||||
"rope": {
|
||||
"hashes": [
|
||||
"sha256:6b728fdc3e98a83446c27a91fc5d56808a004f8beab7a31ab1d7224cecc7d969",
|
||||
@@ -671,17 +599,16 @@
|
||||
},
|
||||
"sphinxcontrib-websupport": {
|
||||
"hashes": [
|
||||
"sha256:4044751a075b6560f155c96f9fec6bc5198cd5307e5db9f77c7b1c5247ac9a09",
|
||||
"sha256:c1b918b1b41cde045cdb9755941086b4ce4ebbfd7bff41d10ffb6d325779cbf9"
|
||||
"sha256:1501befb0fdf1d1c29a800fdbf4ef5dc5369377300ddbdd16d2cd40e54c6eefc",
|
||||
"sha256:e02f717baf02d0b6c3dd62cf81232ffca4c9d5c331e03766982e3ff9f1d2bc3f"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==1.1.1.dev20190321"
|
||||
"version": "==1.1.2"
|
||||
},
|
||||
"stdeb": {
|
||||
"hashes": [
|
||||
"sha256:0ed2c2cc6b8ba21da7d646c6f37ca60b22e9e4950e3cec6bcd9c2e7e57e3747e"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "sys_platform == 'linux'",
|
||||
"version": "==0.8.5"
|
||||
},
|
||||
@@ -700,14 +627,6 @@
|
||||
],
|
||||
"version": "==0.10.0"
|
||||
},
|
||||
"tomlkit": {
|
||||
"hashes": [
|
||||
"sha256:d6506342615d051bc961f70bfcfa3d29b6616cc08a3ddfd4bc24196f16fd4ec2",
|
||||
"sha256:f077456d35303e7908cc233b340f71e0bec96f63429997f38ca9272b7d64029e"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==0.5.3"
|
||||
},
|
||||
"towncrier": {
|
||||
"hashes": [
|
||||
"sha256:48251a1ae66d2cf7e6fa5552016386831b3e12bb3b2d08eb70374508c17a8196",
|
||||
@@ -742,11 +661,11 @@
|
||||
},
|
||||
"urllib3": {
|
||||
"hashes": [
|
||||
"sha256:2393a695cd12afedd0dcb26fe5d50d0cf248e5a66f75dbd89a3d4eb333a61af4",
|
||||
"sha256:a637e5fae88995b256e3409dc4d52c2e2e0ba32c42a6365fee8bbd2238de3cfb"
|
||||
"sha256:b246607a25ac80bedac05c6f282e3cdaf3afb65420fd024ac94435cabe6e18d1",
|
||||
"sha256:dbe59173209418ae49d485b87d1681aefa36252ee85884c31346debd19463232"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3' and python_version < '4'",
|
||||
"version": "==1.24.3"
|
||||
"version": "==1.25.3"
|
||||
},
|
||||
"virtualenv": {
|
||||
"hashes": [
|
||||
@@ -764,17 +683,6 @@
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==0.5.3"
|
||||
},
|
||||
"vistir": {
|
||||
"extras": [
|
||||
"spinner"
|
||||
],
|
||||
"hashes": [
|
||||
"sha256:00af96b75157b299616f47657ed34368e92e01d039100368c9dcd94897e3c109",
|
||||
"sha256:bbe040ce656f1de9b5f75c953abe49af4d1ba6fdf8f1f4b8db3e63cfd2dad24a"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==0.4.1"
|
||||
},
|
||||
"wcwidth": {
|
||||
"hashes": [
|
||||
"sha256:3df37372226d6e63e1b1e1eda15c594bca98a22d33a23832a90998faa96bc65e",
|
||||
@@ -797,20 +705,13 @@
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==0.15.4"
|
||||
},
|
||||
"wheel": {
|
||||
"zipp": {
|
||||
"hashes": [
|
||||
"sha256:5e79117472686ac0c4aef5bad5172ea73a1c2d1646b808c35926bd26bdfb0c08",
|
||||
"sha256:62fcfa03d45b5b722539ccbc07b190e4bfff4bb9e3a4d470dd9f6a0981002565"
|
||||
"sha256:8c1019c6aad13642199fbe458275ad6a84907634cc9f0989877ccc4a2840139d",
|
||||
"sha256:ca943a7e809cc12257001ccfb99e3563da9af99d52f261725e96dfe0f9275bc3"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==0.33.4"
|
||||
},
|
||||
"yaspin": {
|
||||
"hashes": [
|
||||
"sha256:8e6d2e2b207ba18510f190e04a25273a32d1f192af9c9a77ebe46deaca799dfa",
|
||||
"sha256:94b7602f0dc59d26a15e63cefff6aaf644c58dd77fc4e1ef675d3ba2c302ed06"
|
||||
],
|
||||
"version": "==0.14.3"
|
||||
"markers": "python_version >= '2.7'",
|
||||
"version": "==0.5.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+25
-6
@@ -18,6 +18,9 @@ trigger:
|
||||
- .gitattributes
|
||||
- .editorconfig
|
||||
|
||||
variables:
|
||||
- group: CI
|
||||
|
||||
jobs:
|
||||
- job: TestLinux
|
||||
pool:
|
||||
@@ -38,12 +41,28 @@ jobs:
|
||||
- template: .azure-pipelines/steps/run-tests.yml
|
||||
parameters:
|
||||
vmImage: 'Ubuntu-16.04'
|
||||
- template: .azure-pipelines/steps/run-vendor-scripts.yml
|
||||
parameters:
|
||||
vmImage: 'Ubuntu-16.04'
|
||||
- template: .azure-pipelines/steps/build-package.yml
|
||||
parameters:
|
||||
vmImage: 'Ubuntu-16.04'
|
||||
|
||||
- job: TestVendoring
|
||||
pool:
|
||||
vmImage: 'Ubuntu-16.04'
|
||||
variables:
|
||||
python.version: '3.7.2'
|
||||
python.architecture: x64
|
||||
steps:
|
||||
- template: .azure-pipelines/steps/run-vendor-scripts.yml
|
||||
parameters:
|
||||
vmImage: 'Ubuntu-16.04'
|
||||
|
||||
- job: TestPackaging
|
||||
pool:
|
||||
vmImage: 'Ubuntu-16.04'
|
||||
variables:
|
||||
python.version: '3.7.2'
|
||||
python.architecture: x64
|
||||
steps:
|
||||
- template: .azure-pipelines/steps/build-package.yml
|
||||
parameters:
|
||||
vmImage: 'Ubuntu-16.04'
|
||||
|
||||
- job: TestWindows
|
||||
pool:
|
||||
|
||||
@@ -128,10 +128,15 @@ Three ways of running the tests are as follows:
|
||||
|
||||
1. ``make test`` (which uses ``docker``)
|
||||
2. ``./run-tests.sh`` or ``run-tests.bat``
|
||||
3. Using pipenv::
|
||||
3. Using pipenv:
|
||||
|
||||
pipenv install --dev
|
||||
pipenv run pytest
|
||||
.. code-block:: console
|
||||
|
||||
$ git clone https://github.com/pypa/pipenv.git
|
||||
$ cd pipenv
|
||||
$ git submodule sync && git submodule update --init --recursive
|
||||
$ pipenv install --dev
|
||||
$ pipenv run pytest
|
||||
|
||||
For the last two, it is important that your environment is setup correctly, and
|
||||
this may take some work, for example, on a specific Mac installation, the following
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
Added a new environment variable, ``PIPENV_RESOLVE_VCS``, to toggle dependency resolution off for non-editable VCS, file, and URL based dependencies.
|
||||
@@ -0,0 +1 @@
|
||||
Pipenv will no longer inadvertently set ``editable=True`` on all vcs dependencies.
|
||||
@@ -0,0 +1,2 @@
|
||||
The ``--keep-outdated`` argument to ``pipenv install`` and ``pipenv lock`` will now drop specifier constraints when encountering editable dependencies.
|
||||
- In addition, ``--keep-outdated`` will retain specifiers that would otherwise be dropped from any entries that have not been updated.
|
||||
@@ -0,0 +1,3 @@
|
||||
Allow overriding PIP_EXISTS_ACTION evironment variable (value is passed to pip install).
|
||||
Possible values here: https://pip.pypa.io/en/stable/reference/pip/#exists-action-option
|
||||
Useful when you need to `PIP_EXISTS_ACTION=i` (ignore existing packages) - great for CI environments, where you need really fast setup.
|
||||
@@ -316,7 +316,10 @@ def lock(
|
||||
from ..core import ensure_project, do_init, do_lock
|
||||
|
||||
# Ensure that virtualenv is available.
|
||||
ensure_project(three=state.three, python=state.python, pypi_mirror=state.pypi_mirror)
|
||||
ensure_project(
|
||||
three=state.three, python=state.python, pypi_mirror=state.pypi_mirror,
|
||||
warn=(not state.quiet)
|
||||
)
|
||||
if state.installstate.requirementstxt:
|
||||
do_init(
|
||||
dev=state.installstate.dev,
|
||||
@@ -330,6 +333,7 @@ def lock(
|
||||
pre=state.installstate.pre,
|
||||
keep_outdated=state.installstate.keep_outdated,
|
||||
pypi_mirror=state.pypi_mirror,
|
||||
write=not state.quiet,
|
||||
)
|
||||
|
||||
|
||||
|
||||
+31
-4
@@ -6,7 +6,7 @@ import os
|
||||
import click.types
|
||||
|
||||
from click import (
|
||||
BadParameter, Group, Option, argument, echo, make_pass_decorator, option
|
||||
BadParameter, BadArgumentUsage, Group, Option, argument, echo, make_pass_decorator, option
|
||||
)
|
||||
from click_didyoumean import DYMMixin
|
||||
|
||||
@@ -56,6 +56,7 @@ class State(object):
|
||||
self.index = None
|
||||
self.extra_index_urls = []
|
||||
self.verbose = False
|
||||
self.quiet = False
|
||||
self.pypi_mirror = None
|
||||
self.python = None
|
||||
self.two = None
|
||||
@@ -231,12 +232,32 @@ def verbose_option(f):
|
||||
def callback(ctx, param, value):
|
||||
state = ctx.ensure_object(State)
|
||||
if value:
|
||||
if state.quiet:
|
||||
raise BadArgumentUsage(
|
||||
"--verbose and --quiet are mutually exclusive! Please choose one!",
|
||||
ctx=ctx
|
||||
)
|
||||
state.verbose = True
|
||||
setup_verbosity(ctx, param, value)
|
||||
setup_verbosity(ctx, param, 1)
|
||||
return option("--verbose", "-v", is_flag=True, expose_value=False,
|
||||
callback=callback, help="Verbose mode.", type=click.types.BOOL)(f)
|
||||
|
||||
|
||||
def quiet_option(f):
|
||||
def callback(ctx, param, value):
|
||||
state = ctx.ensure_object(State)
|
||||
if value:
|
||||
if state.verbose:
|
||||
raise BadArgumentUsage(
|
||||
"--verbose and --quiet are mutually exclusive! Please choose one!",
|
||||
ctx=ctx
|
||||
)
|
||||
state.quiet = True
|
||||
setup_verbosity(ctx, param, -1)
|
||||
return option("--quiet", "-q", is_flag=True, expose_value=False,
|
||||
callback=callback, help="Quiet mode.", type=click.types.BOOL)(f)
|
||||
|
||||
|
||||
def site_packages_option(f):
|
||||
def callback(ctx, param, value):
|
||||
state = ctx.ensure_object(State)
|
||||
@@ -313,8 +334,14 @@ def setup_verbosity(ctx, param, value):
|
||||
if not value:
|
||||
return
|
||||
import logging
|
||||
logging.getLogger("pip").setLevel(logging.INFO)
|
||||
environments.PIPENV_VERBOSITY = 1
|
||||
loggers = ("pip", "piptools")
|
||||
if value == 1:
|
||||
for logger in loggers:
|
||||
logging.getLogger(logger).setLevel(logging.INFO)
|
||||
elif value == -1:
|
||||
for logger in loggers:
|
||||
logging.getLogger(logger).setLevel(logging.CRITICAL)
|
||||
environments.PIPENV_VERBOSITY = value
|
||||
|
||||
|
||||
def validate_python_path(ctx, param, value):
|
||||
|
||||
+23
-19
@@ -26,7 +26,7 @@ from .environments import (
|
||||
PIPENV_CACHE_DIR, PIPENV_COLORBLIND, PIPENV_DEFAULT_PYTHON_VERSION,
|
||||
PIPENV_DONT_USE_PYENV, PIPENV_HIDE_EMOJIS, PIPENV_MAX_SUBPROCESS,
|
||||
PIPENV_PYUP_API_KEY, PIPENV_SHELL_FANCY, PIPENV_SKIP_VALIDATION,
|
||||
PIPENV_YES, SESSION_IS_INTERACTIVE
|
||||
PIPENV_YES, SESSION_IS_INTERACTIVE, PIP_EXISTS_ACTION
|
||||
)
|
||||
from .project import Project, SourceNotFound
|
||||
from .utils import (
|
||||
@@ -35,7 +35,7 @@ from .utils import (
|
||||
get_canonical_names, is_pinned, is_pypi_url, is_required_version, is_star,
|
||||
is_valid_url, parse_indexes, pep423_name, prepare_pip_source_args,
|
||||
proper_case, python_version, venv_resolve_deps, run_command,
|
||||
is_python_command, find_python
|
||||
is_python_command, find_python, make_posix, interrupt_handled_subprocess
|
||||
)
|
||||
|
||||
|
||||
@@ -371,6 +371,9 @@ def ensure_python(three=None, python=None):
|
||||
if not python:
|
||||
python = PIPENV_DEFAULT_PYTHON_VERSION
|
||||
path_to_python = find_a_system_python(python)
|
||||
if environments.is_verbose():
|
||||
click.echo(u"Using python: {0}".format(python), err=True)
|
||||
click.echo(u"Path to python: {0}".format(path_to_python), err=True)
|
||||
if not path_to_python and python is not None:
|
||||
# We need to install Python.
|
||||
click.echo(
|
||||
@@ -884,11 +887,13 @@ def do_create_virtualenv(python=None, site_packages=False, pypi_mirror=None):
|
||||
)
|
||||
|
||||
# Default to using sys.executable, if Python wasn't provided.
|
||||
using_string = u"Using"
|
||||
if not python:
|
||||
python = sys.executable
|
||||
using_string = "Using default python from"
|
||||
click.echo(
|
||||
u"{0} {1} {3} {2}".format(
|
||||
crayons.normal("Using", bold=True),
|
||||
crayons.normal(using_string, bold=True),
|
||||
crayons.red(python, bold=True),
|
||||
crayons.normal(fix_utf8("to create virtualenv…"), bold=True),
|
||||
crayons.green("({0})".format(python_version(python))),
|
||||
@@ -918,21 +923,19 @@ def do_create_virtualenv(python=None, site_packages=False, pypi_mirror=None):
|
||||
pip_config = {}
|
||||
|
||||
# Actually create the virtualenv.
|
||||
error = None
|
||||
with create_spinner(u"Creating virtual environment...") as sp:
|
||||
c = vistir.misc.run(
|
||||
cmd, verbose=False, return_object=True, write_to_stdout=False,
|
||||
combine_stderr=False, block=True, nospin=True, env=pip_config,
|
||||
with interrupt_handled_subprocess(cmd, combine_stderr=False, env=pip_config) as c:
|
||||
click.echo(crayons.blue(u"{0}".format(c.out)), err=True)
|
||||
if c.returncode != 0:
|
||||
error = c.err if environments.is_verbose() else exceptions.prettify_exc(c.err)
|
||||
sp.fail(environments.PIPENV_SPINNER_FAIL_TEXT.format(u"Failed creating virtual environment"))
|
||||
else:
|
||||
sp.green.ok(environments.PIPENV_SPINNER_OK_TEXT.format(u"Successfully created virtual environment!"))
|
||||
if error is not None:
|
||||
raise exceptions.VirtualenvCreationException(
|
||||
extra=crayons.red("{0}".format(error))
|
||||
)
|
||||
click.echo(crayons.blue(u"{0}".format(c.out)), err=True)
|
||||
if c.returncode != 0:
|
||||
sp.fail(environments.PIPENV_SPINNER_FAIL_TEXT.format(u"Failed creating virtual environment"))
|
||||
error = c.err if environments.is_verbose() else exceptions.prettify_exc(c.err)
|
||||
raise exceptions.VirtualenvCreationException(
|
||||
extra=crayons.red("{0}".format(error))
|
||||
)
|
||||
else:
|
||||
|
||||
sp.green.ok(environments.PIPENV_SPINNER_OK_TEXT.format(u"Successfully created virtual environment!"))
|
||||
|
||||
# Associate project directory with the environment.
|
||||
# This mimics Pew's "setproject".
|
||||
@@ -1393,6 +1396,8 @@ def pip_install(
|
||||
src_dir = os.environ["PIP_SRC"]
|
||||
src = ["--src", os.environ["PIP_SRC"]]
|
||||
if not requirement.editable:
|
||||
# Leave this off becauase old lockfiles don't have all deps included
|
||||
# TODO: When can it be turned back on?
|
||||
no_deps = False
|
||||
|
||||
if src_dir is not None:
|
||||
@@ -1411,7 +1416,7 @@ def pip_install(
|
||||
prefix="pipenv-", suffix="-requirement.txt", dir=requirements_dir,
|
||||
delete=False
|
||||
)
|
||||
line = "-e" if requirement.editable else ""
|
||||
line = "-e " if requirement.editable else ""
|
||||
if requirement.editable or requirement.name is not None:
|
||||
name = requirement.name
|
||||
if requirement.extras:
|
||||
@@ -1507,7 +1512,7 @@ def pip_install(
|
||||
"PIP_DESTINATION_DIR": vistir.misc.fs_str(
|
||||
cache_dir.joinpath("pkgs").as_posix()
|
||||
),
|
||||
"PIP_EXISTS_ACTION": vistir.misc.fs_str("w"),
|
||||
"PIP_EXISTS_ACTION": vistir.misc.fs_str(PIP_EXISTS_ACTION or "w"),
|
||||
"PATH": vistir.misc.fs_str(os.environ.get("PATH")),
|
||||
}
|
||||
if src:
|
||||
@@ -1639,7 +1644,6 @@ def system_which(command, mult=False):
|
||||
return result
|
||||
|
||||
|
||||
|
||||
def format_help(help):
|
||||
"""Formats the help string."""
|
||||
help = help.replace("Options:", str(crayons.normal("Options:", bold=True)))
|
||||
|
||||
+16
-4
@@ -126,7 +126,7 @@ PIPENV_MAX_ROUNDS = int(os.environ.get("PIPENV_MAX_ROUNDS", "16"))
|
||||
Default is 16, an arbitrary number that works most of the time.
|
||||
"""
|
||||
|
||||
PIPENV_MAX_SUBPROCESS = int(os.environ.get("PIPENV_MAX_SUBPROCESS", "16"))
|
||||
PIPENV_MAX_SUBPROCESS = int(os.environ.get("PIPENV_MAX_SUBPROCESS", "8"))
|
||||
"""How many subprocesses should Pipenv use when installing.
|
||||
|
||||
Default is 16, an arbitrary number that seems to work.
|
||||
@@ -150,14 +150,12 @@ environments.
|
||||
if PIPENV_IS_CI:
|
||||
PIPENV_NOSPIN = True
|
||||
|
||||
PIPENV_SPINNER = "dots"
|
||||
PIPENV_SPINNER = "dots" if not os.name == "nt" else "bouncingBar"
|
||||
"""Sets the default spinner type.
|
||||
|
||||
Spinners are identitcal to the node.js spinners and can be found at
|
||||
https://github.com/sindresorhus/cli-spinners
|
||||
"""
|
||||
if os.name == "nt":
|
||||
PIPENV_SPINNER = "bouncingBar"
|
||||
|
||||
PIPENV_PIPFILE = os.environ.get("PIPENV_PIPFILE")
|
||||
"""If set, this specifies a custom Pipfile location.
|
||||
@@ -236,6 +234,20 @@ Default is to lock dependencies and update ``Pipfile.lock`` on each run.
|
||||
NOTE: This only affects the ``install`` and ``uninstall`` commands.
|
||||
"""
|
||||
|
||||
PIP_EXISTS_ACTION = os.environ.get("PIP_EXISTS_ACTION", "w")
|
||||
"""Specifies the value for pip's --exists-action option
|
||||
|
||||
Defaullts to (w)ipe
|
||||
"""
|
||||
|
||||
PIPENV_RESOLVE_VCS = _is_env_truthy(os.environ.get("PIPENV_RESOLVE_VCS", 'true'))
|
||||
"""Tells Pipenv whether to resolve all VCS dependencies in full.
|
||||
|
||||
As of Pipenv 2018.11.26, only editable VCS dependencies were resolved in full.
|
||||
To retain this behavior and avoid handling any conflicts that arise from the new
|
||||
approach, you may set this to '0', 'off', or 'false'.
|
||||
"""
|
||||
|
||||
PIPENV_PYUP_API_KEY = os.environ.get(
|
||||
"PIPENV_PYUP_API_KEY", "1ab8d58f-5122e025-83674263-bc1e79e0"
|
||||
)
|
||||
|
||||
@@ -70,7 +70,7 @@ def clean_requires_python(candidates):
|
||||
all_candidates = []
|
||||
py_version = parse_version(os.environ.get('PIP_PYTHON_VERSION', '.'.join(map(str, sys.version_info[:3]))))
|
||||
for c in candidates:
|
||||
if c.requires_python:
|
||||
if getattr(c, "requires_python", None):
|
||||
# Old specifications had people setting this to single digits
|
||||
# which is effectively the same as '>=digit,<digit+1'
|
||||
if c.requires_python.isdigit():
|
||||
|
||||
+24
-3
@@ -1,3 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import absolute_import, print_function
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
@@ -106,9 +109,14 @@ class Entry(object):
|
||||
self.pipfile = project.parsed_pipfile.get(pipfile_section, {})
|
||||
self.lockfile = project.lockfile_content.get(section, {})
|
||||
self.pipfile_dict = self.pipfile.get(self.pipfile_name, {})
|
||||
self.lockfile_dict = self.lockfile.get(name, entry_dict)
|
||||
if self.dev and self.name in project.lockfile_content.get("default", {}):
|
||||
self.lockfile_dict = project.lockfile_content["default"][name]
|
||||
else:
|
||||
self.lockfile_dict = self.lockfile.get(name, entry_dict)
|
||||
self.resolver = resolver
|
||||
self.reverse_deps = reverse_deps
|
||||
self._original_markers = None
|
||||
self._markers = None
|
||||
self._entry = None
|
||||
self._lockfile_entry = None
|
||||
self._pipfile_entry = None
|
||||
@@ -232,6 +240,10 @@ class Entry(object):
|
||||
entry_extras.extend(list(self.lockfile_entry.extras))
|
||||
self._entry.req.extras = entry_extras
|
||||
self.entry_dict["extras"] = self.entry.extras
|
||||
if self.original_markers and not self.markers:
|
||||
original_markers = self.marker_to_str(self.original_markers)
|
||||
self.markers = original_markers
|
||||
self.entry_dict["markers"] = self.marker_to_str(original_markers)
|
||||
entry_hashes = set(self.entry.hashes)
|
||||
locked_hashes = set(self.lockfile_entry.hashes)
|
||||
if entry_hashes != locked_hashes and not self.is_updated:
|
||||
@@ -248,6 +260,10 @@ class Entry(object):
|
||||
self._lockfile_entry = self.make_requirement(self.name, self.lockfile_dict)
|
||||
return self._lockfile_entry
|
||||
|
||||
@lockfile_entry.setter
|
||||
def lockfile_entry(self, entry):
|
||||
self._lockfile_entry = entry
|
||||
|
||||
@property
|
||||
def pipfile_entry(self):
|
||||
if self._pipfile_entry is None:
|
||||
@@ -359,6 +375,7 @@ class Entry(object):
|
||||
|
||||
@property
|
||||
def updated_specifier(self):
|
||||
# type: () -> str
|
||||
return self.entry.specifiers
|
||||
|
||||
@property
|
||||
@@ -373,7 +390,7 @@ class Entry(object):
|
||||
return None
|
||||
|
||||
def validate_specifiers(self):
|
||||
if self.is_in_pipfile:
|
||||
if self.is_in_pipfile and not self.pipfile_entry.editable:
|
||||
return self.pipfile_entry.requirement.specifier.contains(self.updated_version)
|
||||
return True
|
||||
|
||||
@@ -550,8 +567,11 @@ class Entry(object):
|
||||
constraint.check_if_exists(False)
|
||||
except Exception:
|
||||
from pipenv.exceptions import DependencyConflict
|
||||
from pipenv.environments import is_verbose
|
||||
if is_verbose():
|
||||
print("Tried constraint: {0!r}".format(constraint), file=sys.stderr)
|
||||
msg = (
|
||||
"Cannot resolve conflicting version {0}{1} while {1}{2} is "
|
||||
"Cannot resolve conflicting version {0}{1} while {2}{3} is "
|
||||
"locked.".format(
|
||||
self.name, self.updated_specifier, self.old_name, self.old_specifiers
|
||||
)
|
||||
@@ -624,6 +644,7 @@ def clean_results(results, resolver, project, dev=False):
|
||||
|
||||
def clean_outdated(results, resolver, project, dev=False):
|
||||
from pipenv.vendor.requirementslib.models.requirements import Requirement
|
||||
from pipenv.environments import is_verbose
|
||||
if not project.lockfile_exists:
|
||||
return results
|
||||
lockfile = project.lockfile_content
|
||||
|
||||
+64
-13
@@ -6,6 +6,7 @@ import logging
|
||||
import os
|
||||
import posixpath
|
||||
import re
|
||||
import signal
|
||||
import shutil
|
||||
import stat
|
||||
import sys
|
||||
@@ -25,13 +26,15 @@ six.add_move(six.MovedAttribute("Set", "collections", "collections.abc")) # noq
|
||||
from six.moves import Mapping, Sequence, Set
|
||||
from six.moves.urllib.parse import urlparse
|
||||
from .vendor.vistir.compat import ResourceWarning, lru_cache
|
||||
from .vendor.vistir.misc import fs_str
|
||||
from .vendor.vistir.misc import fs_str, run
|
||||
|
||||
import crayons
|
||||
import parse
|
||||
|
||||
from . import environments
|
||||
from .exceptions import PipenvUsageError, ResolutionFailure, RequirementError, PipenvCmdError
|
||||
from .exceptions import (
|
||||
PipenvUsageError, RequirementError, PipenvCmdError, ResolutionFailure
|
||||
)
|
||||
from .pep508checker import lookup
|
||||
from .vendor.urllib3 import util as urllib3_util
|
||||
|
||||
@@ -398,7 +401,6 @@ class Resolver(object):
|
||||
):
|
||||
# type: (...) -> Tuple[Requirement, Dict[str, str], Dict[str, str]]
|
||||
from .vendor.requirementslib.models.requirements import Requirement
|
||||
from .exceptions import ResolutionFailure
|
||||
if index_lookup is None:
|
||||
index_lookup = {}
|
||||
if markers_lookup is None:
|
||||
@@ -444,6 +446,7 @@ class Resolver(object):
|
||||
# type: (Requirement, Optional["Resolver"]) -> Tuple[Set[str], Dict[str, Dict[str, Union[str, bool, List[str]]]]]
|
||||
from .vendor.requirementslib.models.utils import _requirement_to_str_lowercase_name
|
||||
from .vendor.requirementslib.models.requirements import Requirement
|
||||
from requirementslib.utils import is_installable_dir
|
||||
constraints = set() # type: Set[str]
|
||||
locked_deps = dict() # type: Dict[str, Dict[str, Union[str, bool, List[str]]]]
|
||||
if (req.is_file_or_url or req.is_vcs) and not req.is_wheel:
|
||||
@@ -463,7 +466,16 @@ class Resolver(object):
|
||||
setup_info = req.req.setup_info
|
||||
setup_info.get_info()
|
||||
locked_deps[pep423_name(name)] = entry
|
||||
requirements = [v for v in getattr(setup_info, "requires", {}).values()]
|
||||
requirements = []
|
||||
# Allow users to toggle resolution off for non-editable VCS packages
|
||||
# but leave it on for local, installable folders on the filesystem
|
||||
if environments.PIPENV_RESOLVE_VCS or (
|
||||
req.editable or parsed_line.is_wheel or (
|
||||
req.is_file_or_url and parsed_line.is_local and
|
||||
is_installable_dir(parsed_line.path)
|
||||
)
|
||||
):
|
||||
requirements = [v for v in getattr(setup_info, "requires", {}).values()]
|
||||
for r in requirements:
|
||||
if getattr(r, "url", None) and not getattr(r, "editable", False):
|
||||
if r is not None:
|
||||
@@ -953,9 +965,9 @@ def create_spinner(text, nospin=None, spinner_name=None):
|
||||
if nospin is None:
|
||||
nospin = environments.PIPENV_NOSPIN
|
||||
with spin.create_spinner(
|
||||
spinner_name=spinner_name,
|
||||
start_text=fs_str(text),
|
||||
nospin=nospin, write_to_stdout=False
|
||||
spinner_name=spinner_name,
|
||||
start_text=fs_str(text),
|
||||
nospin=nospin, write_to_stdout=False
|
||||
) as sp:
|
||||
yield sp
|
||||
|
||||
@@ -1744,7 +1756,7 @@ def translate_markers(pipfile_entry):
|
||||
marker_set = set()
|
||||
if "markers" in new_pipfile:
|
||||
marker_str = new_pipfile.pop("markers")
|
||||
if marker_str is not None:
|
||||
if marker_str:
|
||||
marker = str(Marker(marker_str))
|
||||
if 'extra' not in marker:
|
||||
marker_set.add(marker)
|
||||
@@ -1797,13 +1809,15 @@ def clean_resolved_dep(dep, is_top_level=False, pipfile_entry=None):
|
||||
|
||||
# If a package is **PRESENT** in the pipfile but has no markers, make sure we
|
||||
# **NEVER** include markers in the lockfile
|
||||
if "markers" in dep:
|
||||
if "markers" in dep and dep.get("markers", "").strip():
|
||||
# First, handle the case where there is no top level dependency in the pipfile
|
||||
if not is_top_level:
|
||||
try:
|
||||
lockfile["markers"] = translate_markers(dep)["markers"]
|
||||
except TypeError:
|
||||
pass
|
||||
translated = translate_markers(dep).get("markers", "").strip()
|
||||
if translated:
|
||||
try:
|
||||
lockfile["markers"] = translated
|
||||
except TypeError:
|
||||
pass
|
||||
# otherwise make sure we are prioritizing whatever the pipfile says about the markers
|
||||
# If the pipfile says nothing, then we should put nothing in the lockfile
|
||||
else:
|
||||
@@ -2090,3 +2104,40 @@ def make_marker_from_specifier(spec):
|
||||
specset = cleanup_pyspecs(SpecifierSet(spec))
|
||||
marker_str = " and ".join([format_pyversion(pv) for pv in specset])
|
||||
return Marker(marker_str)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def interrupt_handled_subprocess(
|
||||
cmd, verbose=False, return_object=True, write_to_stdout=False, combine_stderr=True,
|
||||
block=True, nospin=True, env=None
|
||||
):
|
||||
"""Given a :class:`subprocess.Popen` instance, wrap it in exception handlers.
|
||||
|
||||
Terminates the subprocess when and if a `SystemExit` or `KeyboardInterrupt` are
|
||||
processed.
|
||||
|
||||
Arguments:
|
||||
:param str cmd: A command to run
|
||||
:param bool verbose: Whether to run with verbose mode enabled, default False
|
||||
:param bool return_object: Whether to return a subprocess instance or a 2-tuple, default True
|
||||
:param bool write_to_stdout: Whether to write directly to stdout, default False
|
||||
:param bool combine_stderr: Whether to combine stdout and stderr, default True
|
||||
:param bool block: Whether the subprocess should be a blocking subprocess, default True
|
||||
:param bool nospin: Whether to suppress the spinner with the subprocess, default True
|
||||
:param Optional[Dict[str, str]] env: A dictionary to merge into the subprocess environment
|
||||
:return: A subprocess, wrapped in exception handlers, as a context manager
|
||||
:rtype: :class:`subprocess.Popen` obj: An instance of a running subprocess
|
||||
"""
|
||||
obj = run(
|
||||
cmd, verbose=verbose, return_object=True, write_to_stdout=False,
|
||||
combine_stderr=False, block=True, nospin=True, env=env,
|
||||
)
|
||||
try:
|
||||
yield obj
|
||||
except (SystemExit, KeyboardInterrupt):
|
||||
if os.name == "nt":
|
||||
os.kill(obj.pid, signal.CTRL_BREAK_EVENT)
|
||||
else:
|
||||
os.kill(obj.pid, signal.SIGINT)
|
||||
obj.wait()
|
||||
raise
|
||||
|
||||
Vendored
+1
-1
@@ -62,7 +62,7 @@ KNOWN_EXTS = {"exe", "py", "fish", "sh", ""}
|
||||
KNOWN_EXTS = KNOWN_EXTS | set(
|
||||
filter(None, os.environ.get("PATHEXT", "").split(os.pathsep))
|
||||
)
|
||||
PY_MATCH_STR = r"((?P<implementation>{0})(?:\d?(?:\.\d[cpm]{{0,3}}))?(?:-?[\d\.]+)*[^z])".format(
|
||||
PY_MATCH_STR = r"((?P<implementation>{0})(?:\d?(?:\.\d[cpm]{{0,3}}))?(?:-?[\d\.]+)*[^zw])".format(
|
||||
"|".join(PYTHON_IMPLEMENTATIONS)
|
||||
)
|
||||
EXE_MATCH_STR = r"{0}(?:\.(?P<ext>{1}))?".format(PY_MATCH_STR, "|".join(KNOWN_EXTS))
|
||||
|
||||
Vendored
+11
-1
@@ -87,10 +87,19 @@ if six.PY2: # pragma: no cover
|
||||
self.errno = errno.EACCES
|
||||
super(PermissionError, self).__init__(*args, **kwargs)
|
||||
|
||||
class TimeoutError(OSError):
|
||||
"""Timeout expired."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.errno = errno.ETIMEDOUT
|
||||
super(TimeoutError, self).__init__(*args, **kwargs)
|
||||
|
||||
class IsADirectoryError(OSError):
|
||||
"""The command does not work on directories"""
|
||||
|
||||
pass
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.errno = errno.EISDIR
|
||||
super(IsADirectoryError, self).__init__(*args, **kwargs)
|
||||
|
||||
class FileExistsError(OSError):
|
||||
def __init__(self, *args, **kwargs):
|
||||
@@ -105,6 +114,7 @@ else: # pragma: no cover
|
||||
PermissionError,
|
||||
IsADirectoryError,
|
||||
FileExistsError,
|
||||
TimeoutError,
|
||||
)
|
||||
from io import StringIO
|
||||
|
||||
|
||||
Vendored
+18
-3
@@ -6,6 +6,7 @@ import json
|
||||
import locale
|
||||
import logging
|
||||
import os
|
||||
import signal
|
||||
import subprocess
|
||||
import sys
|
||||
from collections import OrderedDict
|
||||
@@ -20,6 +21,7 @@ from .compat import (
|
||||
Iterable,
|
||||
Path,
|
||||
StringIO,
|
||||
TimeoutError,
|
||||
fs_str,
|
||||
is_bytes,
|
||||
partialmethod,
|
||||
@@ -185,6 +187,7 @@ def _read_streams(stream_dict):
|
||||
return results
|
||||
|
||||
|
||||
|
||||
def get_stream_results(cmd_instance, verbose, maxlen, spinner=None, stdout_allowed=False):
|
||||
stream_results = {"stdout": [], "stderr": []}
|
||||
streams = {"stderr": cmd_instance.stderr, "stdout": cmd_instance.stdout}
|
||||
@@ -194,11 +197,22 @@ def get_stream_results(cmd_instance, verbose, maxlen, spinner=None, stdout_allow
|
||||
stderr_line = stream_contents["stderr"]
|
||||
if not (stdout_line or stderr_line):
|
||||
break
|
||||
last_changed = 0
|
||||
display_line = ""
|
||||
for stream_name in stream_contents.keys():
|
||||
if stream_contents[stream_name] and stream_name in stream_results:
|
||||
line = stream_contents[stream_name]
|
||||
stream_results[stream_name].append(line)
|
||||
display_line = fs_str("{0}".format(line))
|
||||
display_line = (
|
||||
fs_str("{0}".format(line))
|
||||
if stream_name == "stderr"
|
||||
else display_line
|
||||
)
|
||||
if display_line and last_changed < 100:
|
||||
last_changed = 0
|
||||
display_line = ""
|
||||
elif display_line:
|
||||
last_changed += 1
|
||||
if len(display_line) > maxlen:
|
||||
display_line = "{0}...".format(display_line[:maxlen])
|
||||
if verbose:
|
||||
@@ -290,9 +304,10 @@ def _create_subprocess(
|
||||
else:
|
||||
try:
|
||||
c.out, c.err = c.communicate()
|
||||
except (SystemExit, TimeoutError):
|
||||
except (SystemExit, KeyboardInterrupt, TimeoutError):
|
||||
c.terminate()
|
||||
c.out, c.err = c.communicate()
|
||||
raise
|
||||
if not block:
|
||||
c.wait()
|
||||
c.out = to_text("{0}".format(c.out)) if c.out else fs_str("")
|
||||
@@ -371,7 +386,7 @@ def run(
|
||||
spinner=sp,
|
||||
combine_stderr=combine_stderr,
|
||||
start_text=start_text,
|
||||
write_to_stdout=True,
|
||||
write_to_stdout=write_to_stdout,
|
||||
)
|
||||
|
||||
|
||||
|
||||
Vendored
-2
@@ -41,7 +41,6 @@ if os.name == "nt": # pragma: no cover
|
||||
"""
|
||||
spinner.fail()
|
||||
spinner.stop()
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
else: # pragma: no cover
|
||||
@@ -55,7 +54,6 @@ else: # pragma: no cover
|
||||
"""
|
||||
spinner.red.fail("✘")
|
||||
spinner.stop()
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
CLEAR_LINE = chr(27) + "[K"
|
||||
|
||||
+11
-3
@@ -1,7 +1,15 @@
|
||||
rem imdisk -a -s 964515b -m R: -p "/FS:NTFS /Y"
|
||||
rem If you want to use a ramdisk, use this section:
|
||||
|
||||
rem imdisk -a -s 4G -m R: -p "FS:NTFS /y"
|
||||
rem if you are using a ram disk, you should comment the following substitution line out
|
||||
subst R: %TEMP%
|
||||
|
||||
set TMP=R:\\
|
||||
set TEMP=R:\\
|
||||
set WORKON_HOME=R:\\
|
||||
set RAM_DISK=R:\\
|
||||
|
||||
virtualenv R:\.venv
|
||||
R:\.venv\Scripts\pip install -e .[test] --upgrade --upgrade-strategy=only-if-needed
|
||||
R:\.venv\Scripts\pipenv install --dev
|
||||
git submodule sync && git submodule update --init --recursive
|
||||
SET RAM_DISK=R: && R:\.venv\Scripts\pipenv run pytest -n auto -v tests --tap-stream > report.tap
|
||||
R:\.venv\Scripts\pipenv run pytest -n auto -v tests
|
||||
|
||||
+16
-36
@@ -7,6 +7,8 @@ set -eo pipefail
|
||||
export PYTHONIOENCODING="utf-8"
|
||||
export LANG=C.UTF-8
|
||||
export PIP_PROCESS_DEPENDENCY_LINKS="1"
|
||||
# Let's use a temporary cache directory
|
||||
export PIPENV_CACHE_DIR=`mktemp -d 2>/dev/null || mktemp -d -t 'pipenv_cache'`
|
||||
|
||||
prefix() {
|
||||
sed "s/^/ $1: /"
|
||||
@@ -25,49 +27,27 @@ fi
|
||||
if [[ ! -z "$HOME" ]]; then
|
||||
export PATH="${HOME}/.local/bin:${PATH}"
|
||||
fi
|
||||
# pip uninstall -y pipenv
|
||||
pip install certifi
|
||||
export GIT_SSL_CAINFO=$(python -m certifi)
|
||||
echo "Path: $PATH"
|
||||
echo "Installing Pipenv…"
|
||||
PIP_USER="1" python -m pip install --upgrade setuptools
|
||||
PIP_USER="1" python3 -m pip install --upgrade setuptools
|
||||
python -m pip install -e "$(pwd)" --upgrade && python3 -m pip install -e "$(pwd)" --upgrade
|
||||
python3 -m pipenv install --deploy --dev --system
|
||||
|
||||
# Otherwise, we're on a development machine.
|
||||
# First, try MacOS…
|
||||
if [[ $(python -c "import sys; print(sys.platform)") == "darwin" ]]; then
|
||||
|
||||
echo "Clearing Caches…"
|
||||
rm -fr ~/Library/Caches/pip
|
||||
rm -fr ~/Library/Caches/pipenv
|
||||
|
||||
# Otherwise, assume Linux…
|
||||
else
|
||||
echo "Clearing Caches…"
|
||||
rm -fr ~/.cache/pip
|
||||
rm -fr ~/.cache/pipenv
|
||||
fi
|
||||
python -m pip install --upgrade -e "$(pwd)" setuptools wheel pip
|
||||
VENV_CMD="python -m pipenv --venv"
|
||||
RM_CMD="pipenv --rm"
|
||||
echo "$ PIPENV_PYTHON=2.7 $VENV_CMD && PIPENV_PYTHON=2.7 $RM_CMD"
|
||||
echo "$ PIPENV_PYTHON=3.7 $VENV_CMD && PIPENV_PYTHON=3.7 $RM_CMD"
|
||||
{ PIPENV_PYTHON=2.7 $VENV_CMD && PIPENV_PYTHON=2.7 $RM_CMD ; PIPENV_PYTHON=3.7 $VENV_CMD && PIPENV_PYTHON=3.7 $RM_CMD ; }
|
||||
|
||||
echo "Installing dependencies…"
|
||||
PIPENV_PYTHON=2.7 python3 -m pipenv --venv && pipenv --rm && pipenv install --dev
|
||||
PIPENV_PYTHON=3.7 python3 -m pipenv --venv && pipenv --rm && pipenv install --dev
|
||||
PIPENV_PYTHON=2.7 python3 -m pipenv run pip install --upgrade -e .[test]
|
||||
PIPENV_PYTHON=3.7 python3 -m pipenv run pip install --upgrade -e .[test]
|
||||
INSTALL_CMD="python -m pipenv install --deploy --dev"
|
||||
echo "$ PIPENV_PYTHON=2.7 $INSTALL_CMD"
|
||||
echo "$ PIPENV_PYTHON=3.7 $INSTALL_CMD"
|
||||
|
||||
{ ( PIPENV_PYTHON=2.7 $INSTALL_CMD & ); PIPENV_PYTHON=3.7 $INSTALL_CMD ; }
|
||||
echo "$ git submodule sync && git submodule update --init --recursive"
|
||||
|
||||
git submodule sync && git submodule update --init --recursive
|
||||
|
||||
echo "$ pipenv run time pytest -v -n auto tests -m \"$TEST_SUITE\""
|
||||
# PIPENV_PYTHON=2.7 pipenv run time pytest -v -n auto tests -m "$TEST_SUITE" | prefix 2.7 &
|
||||
# PIPENV_PYTHON=3.6 pipenv run time pytest -v -n auto tests -m "$TEST_SUITE" | prefix 3.6
|
||||
# Better to run them sequentially.
|
||||
PIPENV_PYTHON=2.7 python3 -m pipenv run time pytest
|
||||
PIPENV_PYTHON=3.7 python3 -m pipenv run time pytest
|
||||
|
||||
# test revendoring
|
||||
pip3 install --upgrade invoke requests parver vistir
|
||||
python3 -m invoke vendoring.update
|
||||
# Cleanup junk.
|
||||
rm -fr .venv
|
||||
echo "$ pipenv run time pytest"
|
||||
PIPENV_PYTHON=2.7 python -m pipenv run time pytest
|
||||
PIPENV_PYTHON=3.7 python -m pipenv run time pytest
|
||||
|
||||
@@ -608,7 +608,7 @@ index 9b4b4c2..8875543 100644
|
||||
+ all_candidates = []
|
||||
+ py_version = parse_version(os.environ.get('PIP_PYTHON_VERSION', '.'.join(map(str, sys.version_info[:3]))))
|
||||
+ for c in candidates:
|
||||
+ if c.requires_python:
|
||||
+ if getattr(c, "requires_python", None):
|
||||
+ # Old specifications had people setting this to single digits
|
||||
+ # which is effectively the same as '>=digit,<digit+1'
|
||||
+ if c.requires_python.isdigit():
|
||||
|
||||
@@ -17,6 +17,7 @@ from vistir.contextmanagers import temp_environ
|
||||
from vistir.path import mkdir_p, create_tracked_tempdir, handle_remove_readonly
|
||||
|
||||
from pipenv._compat import Path
|
||||
from pipenv.cmdparse import Script
|
||||
from pipenv.exceptions import VirtualenvActivationException
|
||||
from pipenv.vendor import delegator, requests, toml, tomlkit
|
||||
from pytest_pypi.app import prepare_fixtures
|
||||
@@ -111,6 +112,8 @@ def pytest_runtest_setup(item):
|
||||
sys.version_info < (3, 0)
|
||||
):
|
||||
pytest.skip('test only runs on python 3')
|
||||
if item.get_closest_marker('skip_osx') is not None and sys.platform == 'darwin':
|
||||
pytest.skip('test does not apply on OSX')
|
||||
if item.get_closest_marker('lte_py36') is not None and (
|
||||
sys.version_info >= (3, 7)
|
||||
):
|
||||
@@ -329,8 +332,10 @@ class _PipenvInstance(object):
|
||||
|
||||
with TemporaryDirectory(prefix='pipenv-', suffix='-cache') as tempdir:
|
||||
os.environ['PIPENV_CACHE_DIR'] = fs_str(tempdir.name)
|
||||
c = delegator.run('pipenv {0}'.format(cmd), block=block,
|
||||
cwd=os.path.abspath(self.path))
|
||||
c = delegator.run(
|
||||
'pipenv {0}'.format(cmd), block=block,
|
||||
cwd=os.path.abspath(self.path), env=os.environ.copy()
|
||||
)
|
||||
if 'PIPENV_CACHE_DIR' in os.environ:
|
||||
del os.environ['PIPENV_CACHE_DIR']
|
||||
|
||||
|
||||
@@ -217,6 +217,7 @@ def test_install_parse_error(PipenvInstance, pypi):
|
||||
@pytest.mark.code
|
||||
@pytest.mark.check
|
||||
@pytest.mark.unused
|
||||
@pytest.mark.skip_osx
|
||||
@pytest.mark.needs_internet(reason='required by check')
|
||||
def test_check_unused(PipenvInstance, pypi):
|
||||
with PipenvInstance(chdir=True, pypi=pypi) as p:
|
||||
|
||||
@@ -70,12 +70,12 @@ def test_venv_file(venv_name, PipenvInstance, pypi):
|
||||
venv_loc = Path(c.out.strip()).absolute()
|
||||
assert venv_loc.exists()
|
||||
assert venv_loc.joinpath('.project').exists()
|
||||
venv_path = venv_loc.as_posix()
|
||||
venv_path = normalize_drive(venv_loc.as_posix())
|
||||
if os.path.sep in venv_name:
|
||||
venv_expected_path = Path(p.path).joinpath(venv_name).absolute().as_posix()
|
||||
else:
|
||||
venv_expected_path = Path(workon_home.name).joinpath(venv_name).absolute().as_posix()
|
||||
assert venv_path == venv_expected_path
|
||||
assert venv_path == normalize_drive(venv_expected_path)
|
||||
|
||||
|
||||
@pytest.mark.dotvenv
|
||||
|
||||
@@ -28,8 +28,9 @@ def test_basic_setup(PipenvInstance, pypi):
|
||||
assert "certifi" in p.lockfile["default"]
|
||||
|
||||
|
||||
@pytest.mark.install
|
||||
@flaky
|
||||
@pytest.mark.install
|
||||
@pytest.mark.skip_osx
|
||||
def test_basic_install(PipenvInstance, pypi):
|
||||
with PipenvInstance(pypi=pypi) as p:
|
||||
c = p.pipenv("install requests")
|
||||
@@ -42,8 +43,8 @@ def test_basic_install(PipenvInstance, pypi):
|
||||
assert "certifi" in p.lockfile["default"]
|
||||
|
||||
|
||||
@pytest.mark.install
|
||||
@flaky
|
||||
@pytest.mark.install
|
||||
def test_mirror_install(PipenvInstance, pypi):
|
||||
with temp_environ(), PipenvInstance(chdir=True, pypi=pypi) as p:
|
||||
mirror_url = os.environ.pop(
|
||||
@@ -68,9 +69,9 @@ def test_mirror_install(PipenvInstance, pypi):
|
||||
assert "certifi" in p.lockfile["default"]
|
||||
|
||||
|
||||
@flaky
|
||||
@pytest.mark.install
|
||||
@pytest.mark.needs_internet
|
||||
@flaky
|
||||
def test_bad_mirror_install(PipenvInstance, pypi):
|
||||
with temp_environ(), PipenvInstance(chdir=True) as p:
|
||||
# This demonstrates that the mirror parameter is being used
|
||||
@@ -79,8 +80,8 @@ def test_bad_mirror_install(PipenvInstance, pypi):
|
||||
assert c.return_code != 0
|
||||
|
||||
|
||||
@pytest.mark.complex
|
||||
@pytest.mark.lock
|
||||
@pytest.mark.complex
|
||||
@pytest.mark.skip(reason="Does not work unless you can explicitly install into py2")
|
||||
def test_complex_lock(PipenvInstance, pypi):
|
||||
with PipenvInstance(pypi=pypi) as p:
|
||||
@@ -91,9 +92,9 @@ def test_complex_lock(PipenvInstance, pypi):
|
||||
assert "futures" in p.lockfile[u"default"]
|
||||
|
||||
|
||||
@flaky
|
||||
@pytest.mark.dev
|
||||
@pytest.mark.run
|
||||
@flaky
|
||||
def test_basic_dev_install(PipenvInstance, pypi):
|
||||
with PipenvInstance(pypi=pypi) as p:
|
||||
c = p.pipenv("install requests --dev")
|
||||
@@ -109,9 +110,9 @@ def test_basic_dev_install(PipenvInstance, pypi):
|
||||
assert c.return_code == 0
|
||||
|
||||
|
||||
@flaky
|
||||
@pytest.mark.dev
|
||||
@pytest.mark.install
|
||||
@flaky
|
||||
def test_install_without_dev(PipenvInstance, pypi):
|
||||
"""Ensure that running `pipenv install` doesn't install dev packages"""
|
||||
with PipenvInstance(pypi=pypi, chdir=True) as p:
|
||||
@@ -136,8 +137,8 @@ pytz = "*"
|
||||
assert c.return_code == 0
|
||||
|
||||
|
||||
@pytest.mark.install
|
||||
@flaky
|
||||
@pytest.mark.install
|
||||
def test_install_without_dev_section(PipenvInstance, pypi):
|
||||
with PipenvInstance(pypi=pypi) as p:
|
||||
with open(p.pipfile_path, "w") as f:
|
||||
@@ -156,9 +157,9 @@ six = "*"
|
||||
assert c.return_code == 0
|
||||
|
||||
|
||||
@flaky
|
||||
@pytest.mark.extras
|
||||
@pytest.mark.install
|
||||
@flaky
|
||||
def test_extras_install(PipenvInstance, pypi):
|
||||
with PipenvInstance(pypi=pypi, chdir=True) as p:
|
||||
c = p.pipenv("install requests[socks]")
|
||||
@@ -173,9 +174,9 @@ def test_extras_install(PipenvInstance, pypi):
|
||||
assert "pysocks" in p.lockfile["default"]
|
||||
|
||||
|
||||
@pytest.mark.install
|
||||
@pytest.mark.pin
|
||||
@flaky
|
||||
@pytest.mark.pin
|
||||
@pytest.mark.install
|
||||
def test_windows_pinned_pipfile(PipenvInstance, pypi):
|
||||
with PipenvInstance(pypi=pypi) as p:
|
||||
with open(p.pipfile_path, "w") as f:
|
||||
@@ -190,10 +191,10 @@ requests = "==2.19.1"
|
||||
assert "requests" in p.lockfile["default"]
|
||||
|
||||
|
||||
@flaky
|
||||
@pytest.mark.install
|
||||
@pytest.mark.resolver
|
||||
@pytest.mark.backup_resolver
|
||||
@flaky
|
||||
def test_backup_resolver(PipenvInstance, pypi):
|
||||
with PipenvInstance(pypi=pypi) as p:
|
||||
with open(p.pipfile_path, "w") as f:
|
||||
@@ -208,9 +209,9 @@ def test_backup_resolver(PipenvInstance, pypi):
|
||||
assert "ibm-db-sa-py3" in p.lockfile["default"]
|
||||
|
||||
|
||||
@flaky
|
||||
@pytest.mark.run
|
||||
@pytest.mark.alt
|
||||
@flaky
|
||||
def test_alternative_version_specifier(PipenvInstance, pypi):
|
||||
with PipenvInstance(pypi=pypi) as p:
|
||||
with open(p.pipfile_path, "w") as f:
|
||||
@@ -233,9 +234,9 @@ requests = {version = "*"}
|
||||
assert c.return_code == 0
|
||||
|
||||
|
||||
@flaky
|
||||
@pytest.mark.run
|
||||
@pytest.mark.alt
|
||||
@flaky
|
||||
def test_outline_table_specifier(PipenvInstance, pypi):
|
||||
with PipenvInstance(pypi=pypi) as p:
|
||||
with open(p.pipfile_path, "w") as f:
|
||||
@@ -297,6 +298,7 @@ def test_requirements_to_pipfile(PipenvInstance, pypi):
|
||||
|
||||
|
||||
@pytest.mark.install
|
||||
@pytest.mark.skip_osx
|
||||
@pytest.mark.requirements
|
||||
def test_skip_requirements_when_pipfile(PipenvInstance, pypi):
|
||||
"""Ensure requirements.txt is NOT imported when
|
||||
|
||||
@@ -140,7 +140,7 @@ def test_resolver_unique_markers(PipenvInstance, pypi):
|
||||
This verifies that we clean that successfully.
|
||||
"""
|
||||
with PipenvInstance(chdir=True, pypi=pypi) as p:
|
||||
c = p.pipenv('install vcrpy==1.11.0')
|
||||
c = p.pipenv('install vcrpy==2.0.1')
|
||||
assert c.return_code == 0
|
||||
c = p.pipenv('lock')
|
||||
assert c.return_code == 0
|
||||
@@ -148,7 +148,7 @@ def test_resolver_unique_markers(PipenvInstance, pypi):
|
||||
yarl = p.lockfile['default']['yarl']
|
||||
assert 'markers' in yarl
|
||||
# Two possible marker sets are ok here
|
||||
assert yarl['markers'] in ["python_version in '3.4, 3.5, 3.6'", "python_version >= '3.4.1'"]
|
||||
assert yarl['markers'] in ["python_version in '3.4, 3.5, 3.6'", "python_version >= '3.4'"]
|
||||
|
||||
|
||||
@pytest.mark.project
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
||||
@@ -5,6 +8,7 @@ import pytest
|
||||
|
||||
from flaky import flaky
|
||||
from vistir.compat import Path
|
||||
from vistir.misc import to_text
|
||||
from pipenv.utils import temp_environ
|
||||
|
||||
|
||||
@@ -122,6 +126,21 @@ def test_keep_outdated_doesnt_upgrade_pipfile_pins(PipenvInstance, pypi):
|
||||
assert p.lockfile["default"]["urllib3"]["version"] == "==1.21.1"
|
||||
|
||||
|
||||
def test_keep_outdated_keeps_markers_not_removed(PipenvInstance, pypi):
|
||||
with PipenvInstance(chdir=True, pypi=pypi) as p:
|
||||
c = p.pipenv("install six click")
|
||||
assert c.ok
|
||||
lockfile = Path(p.lockfile_path)
|
||||
lockfile_content = lockfile.read_text()
|
||||
lockfile_json = json.loads(lockfile_content)
|
||||
assert "six" in lockfile_json["default"]
|
||||
lockfile_json["default"]["six"]["markers"] = "python_version >= '2.7'"
|
||||
lockfile.write_text(to_text(json.dumps(lockfile_json)))
|
||||
c = p.pipenv("lock --keep-outdated")
|
||||
assert c.ok
|
||||
assert p.lockfile["default"]["six"].get("markers", "") == "python_version >= '2.7'"
|
||||
|
||||
|
||||
@pytest.mark.lock
|
||||
@pytest.mark.keep_outdated
|
||||
def test_keep_outdated_doesnt_update_satisfied_constraints(PipenvInstance, pypi):
|
||||
@@ -577,18 +596,20 @@ def test_lock_no_warnings(PipenvInstance, pypi):
|
||||
@pytest.mark.lock
|
||||
@pytest.mark.install
|
||||
@pytest.mark.skipif(sys.version_info >= (3, 5), reason="scandir doesn't get installed on python 3.5+")
|
||||
def test_lock_missing_cache_entries_gets_all_hashes(monkeypatch, PipenvInstance, pypi, tmpdir):
|
||||
def test_lock_missing_cache_entries_gets_all_hashes(PipenvInstance, pypi, tmpdir):
|
||||
"""
|
||||
Test locking pathlib2 on python2.7 which needs `scandir`, but fails to resolve when
|
||||
using a fresh dependency cache.
|
||||
"""
|
||||
|
||||
with monkeypatch.context() as m:
|
||||
monkeypatch.setattr("pipenv.patched.piptools.locations.CACHE_DIR", tmpdir.strpath)
|
||||
with temp_environ():
|
||||
os.environ["PIPENV_CACHE_DIR"] = str(tmpdir.strpath)
|
||||
with PipenvInstance(pypi=pypi, chdir=True) as p:
|
||||
p._pipfile.add("pathlib2", "*")
|
||||
assert "pathlib2" in p.pipfile["packages"]
|
||||
c = p.pipenv("install")
|
||||
assert c.return_code == 0, (c.err, ("\n".join(["{0}: {1}\n".format(k, v) for k, v in os.environ.items()])))
|
||||
c = p.pipenv("lock --clear")
|
||||
assert c.return_code == 0, c.err
|
||||
assert "pathlib2" in p.lockfile["default"]
|
||||
assert "scandir" in p.lockfile["default"]
|
||||
|
||||
@@ -10,6 +10,7 @@ from pipenv.patched import pipfile
|
||||
from pipenv.project import Project
|
||||
from pipenv.utils import temp_environ
|
||||
from pipenv.vendor.vistir.path import is_in_path
|
||||
from pipenv.vendor.delegator import run as delegator_run
|
||||
import pipenv.environments
|
||||
|
||||
|
||||
@@ -173,22 +174,38 @@ def test_include_editable_packages(PipenvInstance, pypi, testsroot, pathlib_tmpd
|
||||
@pytest.mark.virtualenv
|
||||
def test_run_in_virtualenv_with_global_context(PipenvInstance, pypi, virtualenv):
|
||||
with PipenvInstance(chdir=True, pypi=pypi, venv_root=virtualenv.as_posix(), ignore_virtualenvs=False, venv_in_project=False) as p:
|
||||
c = p.pipenv('run pip freeze')
|
||||
assert c.return_code == 0
|
||||
assert 'Creating a virtualenv' not in c.err
|
||||
c = delegator_run(
|
||||
"pipenv run pip freeze", cwd=os.path.abspath(p.path),
|
||||
env=os.environ.copy()
|
||||
)
|
||||
assert c.return_code == 0, (c.out, c.err)
|
||||
assert 'Creating a virtualenv' not in c.err, c.err
|
||||
project = Project()
|
||||
assert project.virtualenv_location == virtualenv.as_posix()
|
||||
c = p.pipenv("run pip install click")
|
||||
assert c.return_code == 0
|
||||
assert "Courtesy Notice" in c.err
|
||||
c = p.pipenv("install six")
|
||||
assert c.return_code == 0
|
||||
c = p.pipenv('run python -c "import click;print(click.__file__)"')
|
||||
assert c.return_code == 0
|
||||
assert is_in_path(c.out.strip(), str(virtualenv))
|
||||
c = p.pipenv("clean --dry-run")
|
||||
assert c.return_code == 0
|
||||
assert "click" in c.out
|
||||
assert project.virtualenv_location == virtualenv.as_posix(), (
|
||||
project.virtualenv_location, virtualenv.as_posix()
|
||||
)
|
||||
c = delegator_run(
|
||||
"pipenv run pip install click", cwd=os.path.abspath(p.path),
|
||||
env=os.environ.copy()
|
||||
)
|
||||
assert c.return_code == 0, (c.out, c.err)
|
||||
assert "Courtesy Notice" in c.err, (c.out, c.err)
|
||||
c = delegator_run(
|
||||
"pipenv install six", cwd=os.path.abspath(p.path), env=os.environ.copy()
|
||||
)
|
||||
assert c.return_code == 0, (c.out, c.err)
|
||||
c = delegator_run(
|
||||
'pipenv run python -c "import click;print(click.__file__)"',
|
||||
cwd=os.path.abspath(p.path), env=os.environ.copy()
|
||||
)
|
||||
assert c.return_code == 0, (c.out, c.err)
|
||||
assert is_in_path(c.out.strip(), str(virtualenv)), (c.out.strip(), str(virtualenv))
|
||||
c = delegator_run(
|
||||
"pipenv clean --dry-run", cwd=os.path.abspath(p.path),
|
||||
env=os.environ.copy()
|
||||
)
|
||||
assert c.return_code == 0, (c.out, c.err)
|
||||
assert "click" in c.out, c.out
|
||||
|
||||
|
||||
@pytest.mark.project
|
||||
|
||||
Submodule
+1
Submodule tests/pypi added at f3260ec6bf
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,190 +0,0 @@
|
||||
{
|
||||
"info": {
|
||||
"author": "Ethan Furman",
|
||||
"author_email": "ethan@stoneleaf.us",
|
||||
"bugtrack_url": null,
|
||||
"classifiers": [
|
||||
"Development Status :: 5 - Production/Stable",
|
||||
"Intended Audience :: Developers",
|
||||
"License :: OSI Approved :: BSD License",
|
||||
"Programming Language :: Python",
|
||||
"Programming Language :: Python :: 2.4",
|
||||
"Programming Language :: Python :: 2.5",
|
||||
"Programming Language :: Python :: 2.6",
|
||||
"Programming Language :: Python :: 2.7",
|
||||
"Programming Language :: Python :: 3.3",
|
||||
"Programming Language :: Python :: 3.4",
|
||||
"Programming Language :: Python :: 3.5",
|
||||
"Topic :: Software Development"
|
||||
],
|
||||
"description": "enum --- support for enumerations\n========================================\n\nAn enumeration is a set of symbolic names (members) bound to unique, constant\nvalues. Within an enumeration, the members can be compared by identity, and\nthe enumeration itself can be iterated over.\n\n from enum import Enum\n\n class Fruit(Enum):\n apple = 1\n banana = 2\n orange = 3\n\n list(Fruit)\n # [<Fruit.apple: 1>, <Fruit.banana: 2>, <Fruit.orange: 3>]\n\n len(Fruit)\n # 3\n\n Fruit.banana\n # <Fruit.banana: 2>\n\n Fruit['banana']\n # <Fruit.banana: 2>\n\n Fruit(2)\n # <Fruit.banana: 2>\n\n Fruit.banana is Fruit['banana'] is Fruit(2)\n # True\n\n Fruit.banana.name\n # 'banana'\n\n Fruit.banana.value\n # 2\n\nRepository and Issue Tracker at https://bitbucket.org/stoneleaf/enum34.",
|
||||
"description_content_type": null,
|
||||
"docs_url": null,
|
||||
"download_url": "",
|
||||
"downloads": {
|
||||
"last_day": -1,
|
||||
"last_month": -1,
|
||||
"last_week": -1
|
||||
},
|
||||
"home_page": "https://bitbucket.org/stoneleaf/enum34",
|
||||
"keywords": "",
|
||||
"license": "BSD License",
|
||||
"maintainer": "",
|
||||
"maintainer_email": "",
|
||||
"name": "enum34",
|
||||
"package_url": "https://pypi.org/project/enum34/",
|
||||
"platform": "UNKNOWN",
|
||||
"project_url": "https://pypi.org/project/enum34/",
|
||||
"project_urls": {
|
||||
"Homepage": "https://bitbucket.org/stoneleaf/enum34"
|
||||
},
|
||||
"release_url": "https://pypi.org/project/enum34/1.1.6/",
|
||||
"requires_dist": null,
|
||||
"requires_python": "",
|
||||
"summary": "Python 3.4 Enum backported to 3.3, 3.2, 3.1, 2.7, 2.6, 2.5, and 2.4",
|
||||
"version": "1.1.6"
|
||||
},
|
||||
"last_serial": 2117417,
|
||||
"releases": {
|
||||
"1.1.6": [
|
||||
{
|
||||
"comment_text": "",
|
||||
"digests": {
|
||||
"md5": "68f6982cc07dde78f4b500db829860bd",
|
||||
"sha256": "6bd0f6ad48ec2aa117d3d141940d484deccda84d4fcd884f5c3d93c23ecd8c79"
|
||||
},
|
||||
"downloads": -1,
|
||||
"filename": "enum34-1.1.6-py2-none-any.whl",
|
||||
"has_sig": false,
|
||||
"md5_digest": "68f6982cc07dde78f4b500db829860bd",
|
||||
"packagetype": "bdist_wheel",
|
||||
"python_version": "py2",
|
||||
"requires_python": null,
|
||||
"size": 12427,
|
||||
"upload_time": "2016-05-16T03:31:13",
|
||||
"url": "https://files.pythonhosted.org/packages/c5/db/e56e6b4bbac7c4a06de1c50de6fe1ef3810018ae11732a50f15f62c7d050/enum34-1.1.6-py2-none-any.whl"
|
||||
},
|
||||
{
|
||||
"comment_text": "",
|
||||
"digests": {
|
||||
"md5": "a63ecb4f0b1b85fb69be64bdea999b43",
|
||||
"sha256": "644837f692e5f550741432dd3f223bbb9852018674981b1664e5dc339387588a"
|
||||
},
|
||||
"downloads": -1,
|
||||
"filename": "enum34-1.1.6-py3-none-any.whl",
|
||||
"has_sig": false,
|
||||
"md5_digest": "a63ecb4f0b1b85fb69be64bdea999b43",
|
||||
"packagetype": "bdist_wheel",
|
||||
"python_version": "py3",
|
||||
"requires_python": null,
|
||||
"size": 12428,
|
||||
"upload_time": "2016-05-16T03:31:19",
|
||||
"url": "https://files.pythonhosted.org/packages/af/42/cb9355df32c69b553e72a2e28daee25d1611d2c0d9c272aa1d34204205b2/enum34-1.1.6-py3-none-any.whl"
|
||||
},
|
||||
{
|
||||
"comment_text": "",
|
||||
"digests": {
|
||||
"md5": "5f13a0841a61f7fc295c514490d120d0",
|
||||
"sha256": "8ad8c4783bf61ded74527bffb48ed9b54166685e4230386a9ed9b1279e2df5b1"
|
||||
},
|
||||
"downloads": -1,
|
||||
"filename": "enum34-1.1.6.tar.gz",
|
||||
"has_sig": false,
|
||||
"md5_digest": "5f13a0841a61f7fc295c514490d120d0",
|
||||
"packagetype": "sdist",
|
||||
"python_version": "source",
|
||||
"requires_python": null,
|
||||
"size": 40048,
|
||||
"upload_time": "2016-05-16T03:31:30",
|
||||
"url": "https://files.pythonhosted.org/packages/bf/3e/31d502c25302814a7c2f1d3959d2a3b3f78e509002ba91aea64993936876/enum34-1.1.6.tar.gz"
|
||||
},
|
||||
{
|
||||
"comment_text": "",
|
||||
"digests": {
|
||||
"md5": "61ad7871532d4ce2d77fac2579237a9e",
|
||||
"sha256": "2d81cbbe0e73112bdfe6ef8576f2238f2ba27dd0d55752a776c41d38b7da2850"
|
||||
},
|
||||
"downloads": -1,
|
||||
"filename": "enum34-1.1.6.zip",
|
||||
"has_sig": false,
|
||||
"md5_digest": "61ad7871532d4ce2d77fac2579237a9e",
|
||||
"packagetype": "sdist",
|
||||
"python_version": "source",
|
||||
"requires_python": null,
|
||||
"size": 44773,
|
||||
"upload_time": "2016-05-16T03:31:48",
|
||||
"url": "https://files.pythonhosted.org/packages/e8/26/a6101edcf724453845c850281b96b89a10dac6bd98edebc82634fccce6a5/enum34-1.1.6.zip"
|
||||
}
|
||||
]
|
||||
},
|
||||
"urls": [
|
||||
{
|
||||
"comment_text": "",
|
||||
"digests": {
|
||||
"md5": "68f6982cc07dde78f4b500db829860bd",
|
||||
"sha256": "6bd0f6ad48ec2aa117d3d141940d484deccda84d4fcd884f5c3d93c23ecd8c79"
|
||||
},
|
||||
"downloads": -1,
|
||||
"filename": "enum34-1.1.6-py2-none-any.whl",
|
||||
"has_sig": false,
|
||||
"md5_digest": "68f6982cc07dde78f4b500db829860bd",
|
||||
"packagetype": "bdist_wheel",
|
||||
"python_version": "py2",
|
||||
"requires_python": null,
|
||||
"size": 12427,
|
||||
"upload_time": "2016-05-16T03:31:13",
|
||||
"url": "https://files.pythonhosted.org/packages/c5/db/e56e6b4bbac7c4a06de1c50de6fe1ef3810018ae11732a50f15f62c7d050/enum34-1.1.6-py2-none-any.whl"
|
||||
},
|
||||
{
|
||||
"comment_text": "",
|
||||
"digests": {
|
||||
"md5": "a63ecb4f0b1b85fb69be64bdea999b43",
|
||||
"sha256": "644837f692e5f550741432dd3f223bbb9852018674981b1664e5dc339387588a"
|
||||
},
|
||||
"downloads": -1,
|
||||
"filename": "enum34-1.1.6-py3-none-any.whl",
|
||||
"has_sig": false,
|
||||
"md5_digest": "a63ecb4f0b1b85fb69be64bdea999b43",
|
||||
"packagetype": "bdist_wheel",
|
||||
"python_version": "py3",
|
||||
"requires_python": null,
|
||||
"size": 12428,
|
||||
"upload_time": "2016-05-16T03:31:19",
|
||||
"url": "https://files.pythonhosted.org/packages/af/42/cb9355df32c69b553e72a2e28daee25d1611d2c0d9c272aa1d34204205b2/enum34-1.1.6-py3-none-any.whl"
|
||||
},
|
||||
{
|
||||
"comment_text": "",
|
||||
"digests": {
|
||||
"md5": "5f13a0841a61f7fc295c514490d120d0",
|
||||
"sha256": "8ad8c4783bf61ded74527bffb48ed9b54166685e4230386a9ed9b1279e2df5b1"
|
||||
},
|
||||
"downloads": -1,
|
||||
"filename": "enum34-1.1.6.tar.gz",
|
||||
"has_sig": false,
|
||||
"md5_digest": "5f13a0841a61f7fc295c514490d120d0",
|
||||
"packagetype": "sdist",
|
||||
"python_version": "source",
|
||||
"requires_python": null,
|
||||
"size": 40048,
|
||||
"upload_time": "2016-05-16T03:31:30",
|
||||
"url": "https://files.pythonhosted.org/packages/bf/3e/31d502c25302814a7c2f1d3959d2a3b3f78e509002ba91aea64993936876/enum34-1.1.6.tar.gz"
|
||||
},
|
||||
{
|
||||
"comment_text": "",
|
||||
"digests": {
|
||||
"md5": "61ad7871532d4ce2d77fac2579237a9e",
|
||||
"sha256": "2d81cbbe0e73112bdfe6ef8576f2238f2ba27dd0d55752a776c41d38b7da2850"
|
||||
},
|
||||
"downloads": -1,
|
||||
"filename": "enum34-1.1.6.zip",
|
||||
"has_sig": false,
|
||||
"md5_digest": "61ad7871532d4ce2d77fac2579237a9e",
|
||||
"packagetype": "sdist",
|
||||
"python_version": "source",
|
||||
"requires_python": null,
|
||||
"size": 44773,
|
||||
"upload_time": "2016-05-16T03:31:48",
|
||||
"url": "https://files.pythonhosted.org/packages/e8/26/a6101edcf724453845c850281b96b89a10dac6bd98edebc82634fccce6a5/enum34-1.1.6.zip"
|
||||
}
|
||||
]
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user