mirror of
https://github.com/kennethreitz/pipenv.git
synced 2026-06-05 22:50:18 +00:00
Merge branch 'master' into issue-2747
This commit is contained in:
@@ -10,5 +10,6 @@ steps:
|
||||
- bash: |
|
||||
export GIT_SSL_CAINFO=$(python -m certifi)
|
||||
export LANG=C.UTF-8
|
||||
python -m pip install check-manifest
|
||||
check-manifest
|
||||
python -m pip install --upgrade setuptools twine readme_renderer[md]
|
||||
python setup.py sdist
|
||||
twine check dist/*
|
||||
|
||||
@@ -16,8 +16,9 @@ steps:
|
||||
export PIP_PROCESS_DEPENDENCY_LINKS="1"
|
||||
echo "Path $PATH"
|
||||
echo "Installing Pipenv…"
|
||||
pip install -e "$(pwd)" --upgrade
|
||||
pip install -e "$(pwd)[test]" --upgrade
|
||||
pipenv install --deploy --dev
|
||||
pipenv run pip install -e "$(pwd)[test]" --upgrade
|
||||
echo pipenv --venv && echo pipenv --py && echo pipenv run python --version
|
||||
displayName: Make Virtualenv
|
||||
|
||||
|
||||
@@ -10,9 +10,8 @@ jobs:
|
||||
maxParallel: 4
|
||||
matrix:
|
||||
${{ if eq(parameters.vmImage, 'vs2017-win2016') }}:
|
||||
# TODO remove once vs2017-win2016 has Python 3.7
|
||||
Python37:
|
||||
python.version: '>= 3.7.0-b2'
|
||||
python.version: '>= 3.7.2'
|
||||
python.architecture: x64
|
||||
${{ if ne(parameters.vmImage, 'vs2017-win2016' )}}:
|
||||
Python37:
|
||||
@@ -33,7 +32,7 @@ jobs:
|
||||
pip install certifi
|
||||
export GIT_SSL_CAINFO=$(python -m certifi)
|
||||
export LANG=C.UTF-8
|
||||
python -m pip install --upgrade invoke requests parver
|
||||
python -m pip install --upgrade invoke requests parver bs4 vistir towncrier pip setuptools wheel --upgrade-strategy=eager
|
||||
python -m invoke vendoring.update
|
||||
|
||||
- template: ./run-manifest-check.yml
|
||||
|
||||
@@ -8,6 +8,7 @@ trigger:
|
||||
exclude:
|
||||
- docs/*
|
||||
- news/*
|
||||
- peeps/*
|
||||
- README.md
|
||||
- pipenv/*.txt
|
||||
- CHANGELOG.rst
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
steps:
|
||||
- script: |
|
||||
virtualenv D:\.venv
|
||||
D:\.venv\Scripts\pip.exe install -e . && D:\.venv\Scripts\pipenv install --dev
|
||||
D:\.venv\Scripts\pip.exe install -e .[test] && D:\.venv\Scripts\pipenv install --dev && D:\.venv\Scripts\pipenv run pip install -e .[test]
|
||||
echo D:\.venv\Scripts\pipenv --venv && echo D:\.venv\Scripts\pipenv --py && echo D:\.venv\Scripts\pipenv run python --version
|
||||
displayName: Make Virtualenv
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
steps:
|
||||
- script: 'python -m pip install --upgrade pip && python -m pip install -e .'
|
||||
- script: 'python -m pip install --upgrade pip && python -m pip install -e .[test]'
|
||||
displayName: Upgrade Pip & Install Pipenv
|
||||
|
||||
@@ -8,6 +8,7 @@ trigger:
|
||||
exclude:
|
||||
- docs/*
|
||||
- news/*
|
||||
- peeps/*
|
||||
- README.md
|
||||
- pipenv/*.txt
|
||||
- CHANGELOG.rst
|
||||
|
||||
@@ -153,3 +153,8 @@ venv.bak/
|
||||
|
||||
# Custom rules (everything added below won't be overriden by 'Generate .gitignore File' if you use 'Update' option)
|
||||
.vs/slnx.sqlite
|
||||
|
||||
# mypy/typing section
|
||||
typeshed/
|
||||
.dmypy.json
|
||||
mypyhtml/
|
||||
|
||||
+12
@@ -13,3 +13,15 @@
|
||||
[submodule "tests/test_artifacts/git/dateutil"]
|
||||
path = tests/test_artifacts/git/dateutil
|
||||
url = https://github.com/dateutil/dateutil
|
||||
[submodule "tests/test_artifacts/git/pyinstaller"]
|
||||
path = tests/test_artifacts/git/pyinstaller
|
||||
url = https://github.com/pyinstaller/pyinstaller.git
|
||||
[submodule "tests/test_artifacts/git/jinja2"]
|
||||
path = tests/test_artifacts/git/jinja2
|
||||
url = https://github.com/pallets/jinja.git
|
||||
[submodule "tests/test_artifacts/git/flask"]
|
||||
path = tests/test_artifacts/git/flask
|
||||
url = https://github.com/pallets/flask.git
|
||||
[submodule "tests/test_artifacts/git/requests-2.18.4"]
|
||||
path = tests/test_artifacts/git/requests-2.18.4
|
||||
url = https://github.com/requests/requests
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
2018.7.1.dev0 (2018-07-15)
|
||||
==========================
|
||||
|
||||
|
||||
Features & Improvements
|
||||
-----------------------
|
||||
|
||||
- Updated test-pypi addon to better support json-api access (forward compatibility).
|
||||
Improved testing process for new contributors. `#2568 <https://github.com/pypa/pipenv/issues/2568>`_
|
||||
|
||||
|
||||
Behavior Changes
|
||||
----------------
|
||||
|
||||
- Virtual environment activation for ``run`` is revised to improve interpolation
|
||||
with other Python discovery tools. `#2503 <https://github.com/pypa/pipenv/issues/2503>`_
|
||||
|
||||
- Improve terminal coloring to display better in Powershell. `#2511 <https://github.com/pypa/pipenv/issues/2511>`_
|
||||
|
||||
- Invoke ``virtualenv`` directly for virtual environment creation, instead of depending on ``pew``. `#2518 <https://github.com/pypa/pipenv/issues/2518>`_
|
||||
|
||||
- ``pipenv --help`` will now include short help descriptions. `#2542 <https://github.com/pypa/pipenv/issues/2542>`_
|
||||
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- Fix subshell invocation on Windows for Python 2. `#2515 <https://github.com/pypa/pipenv/issues/2515>`_
|
||||
|
||||
- Fixed a bug which sometimes caused pipenv to throw a ``TypeError`` or to run into encoding issues when writing lockfiles on python 2. `#2561 <https://github.com/pypa/pipenv/issues/2561>`_
|
||||
|
||||
- Improve quoting logic for ``pipenv run`` so it works better with Windows
|
||||
built-in commands. `#2563 <https://github.com/pypa/pipenv/issues/2563>`_
|
||||
|
||||
- Fixed a bug related to parsing vcs requirements with both extras and subdirectory fragments.
|
||||
Corrected an issue in the ``requirementslib`` parser which led to some markers being discarded rather than evaluated. `#2564 <https://github.com/pypa/pipenv/issues/2564>`_
|
||||
|
||||
|
||||
Vendored Libraries
|
||||
------------------
|
||||
|
||||
- Pew is no longer vendored. Entry point ``pewtwo``, packages ``pipenv.pew`` and
|
||||
``pipenv.patched.pew`` are removed. `#2521 <https://github.com/pypa/pipenv/issues/2521>`_
|
||||
|
||||
|
||||
Improved Documentation
|
||||
----------------------
|
||||
|
||||
- Simplified the test configuration process. `#2568 <https://github.com/pypa/pipenv/issues/2568>`_
|
||||
|
||||
+136
-101
@@ -1,3 +1,39 @@
|
||||
2018.11.26 (2018-11-26)
|
||||
=======================
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- Environment variables are expanded correctly before running scripts on POSIX. `#3178 <https://github.com/pypa/pipenv/issues/3178>`_
|
||||
- Pipenv will no longer disable user-mode installation when the ``--system`` flag is passed in. `#3222 <https://github.com/pypa/pipenv/issues/3222>`_
|
||||
- Fixed an issue with attempting to render unicode output in non-unicode locales. `#3223 <https://github.com/pypa/pipenv/issues/3223>`_
|
||||
- Fixed a bug which could cause failures to occur when parsing python entries from global pyenv version files. `#3224 <https://github.com/pypa/pipenv/issues/3224>`_
|
||||
- Fixed an issue which prevented the parsing of named extras sections from certain ``setup.py`` files. `#3230 <https://github.com/pypa/pipenv/issues/3230>`_
|
||||
- Correctly detect the virtualenv location inside an activated virtualenv. `#3231 <https://github.com/pypa/pipenv/issues/3231>`_
|
||||
- Fixed a bug which caused spinner frames to be written to stdout during locking operations which could cause redirection pipes to fail. `#3239 <https://github.com/pypa/pipenv/issues/3239>`_
|
||||
- Fixed a bug that editable pacakges can't be uninstalled correctly. `#3240 <https://github.com/pypa/pipenv/issues/3240>`_
|
||||
- Corrected an issue with installation timeouts which caused dependency resolution to fail for longer duration resolution steps. `#3244 <https://github.com/pypa/pipenv/issues/3244>`_
|
||||
- Adding normal pep 508 compatible markers is now fully functional when using VCS dependencies. `#3249 <https://github.com/pypa/pipenv/issues/3249>`_
|
||||
- Updated ``requirementslib`` and ``pythonfinder`` for multiple bugfixes. `#3254 <https://github.com/pypa/pipenv/issues/3254>`_
|
||||
- Pipenv will now ignore hashes when installing with ``--skip-lock``. `#3255 <https://github.com/pypa/pipenv/issues/3255>`_
|
||||
- Fixed an issue where pipenv could crash when multiple pipenv processes attempted to create the same directory. `#3257 <https://github.com/pypa/pipenv/issues/3257>`_
|
||||
- Fixed an issue which sometimes prevented successful creation of project pipfiles. `#3260 <https://github.com/pypa/pipenv/issues/3260>`_
|
||||
- ``pipenv install`` will now unset the ``PYTHONHOME`` environment variable when not combined with ``--system``. `#3261 <https://github.com/pypa/pipenv/issues/3261>`_
|
||||
- Pipenv will ensure that warnings do not interfere with the resolution process by suppressing warnings' usage of standard output and writing to standard error instead. `#3273 <https://github.com/pypa/pipenv/issues/3273>`_
|
||||
- Fixed an issue which prevented variables from the environment, such as ``PIPENV_DEV`` or ``PIPENV_SYSTEM``, from being parsed and implemented correctly. `#3278 <https://github.com/pypa/pipenv/issues/3278>`_
|
||||
- Clear pythonfinder cache after Python install. `#3287 <https://github.com/pypa/pipenv/issues/3287>`_
|
||||
- Fixed a race condition in hash resolution for dependencies for certain dependencies with missing cache entries or fresh Pipenv installs. `#3289 <https://github.com/pypa/pipenv/issues/3289>`_
|
||||
- Pipenv will now respect top-level pins over VCS dependency locks. `#3296 <https://github.com/pypa/pipenv/issues/3296>`_
|
||||
|
||||
Vendored Libraries
|
||||
------------------
|
||||
|
||||
- Update vendored dependencies to resolve resolution output parsing and python finding:
|
||||
- ``pythonfinder 1.1.9 -> 1.1.10``
|
||||
- ``requirementslib 1.3.1 -> 1.3.3``
|
||||
- ``vistir 0.2.3 -> 0.2.5`` `#3280 <https://github.com/pypa/pipenv/issues/3280>`_
|
||||
|
||||
|
||||
2018.11.14 (2018-11-14)
|
||||
=======================
|
||||
|
||||
@@ -91,33 +127,33 @@ Bug Fixes
|
||||
---------
|
||||
|
||||
- Fixed a bug in ``pipenv clean`` which caused global packages to sometimes be inadvertently targeted for cleanup. `#2849 <https://github.com/pypa/pipenv/issues/2849>`_
|
||||
|
||||
|
||||
- Fix broken backport imports for vendored vistir. `#2950 <https://github.com/pypa/pipenv/issues/2950>`_,
|
||||
`#2955 <https://github.com/pypa/pipenv/issues/2955>`_,
|
||||
`#2961 <https://github.com/pypa/pipenv/issues/2961>`_
|
||||
|
||||
|
||||
- Fixed a bug with importing local vendored dependencies when running ``pipenv graph``. `#2952 <https://github.com/pypa/pipenv/issues/2952>`_
|
||||
|
||||
|
||||
- Fixed a bug which caused executable discovery to fail when running inside a virtualenv. `#2957 <https://github.com/pypa/pipenv/issues/2957>`_
|
||||
|
||||
|
||||
- Fix parsing of outline tables. `#2971 <https://github.com/pypa/pipenv/issues/2971>`_
|
||||
|
||||
|
||||
- Fixed a bug which caused ``verify_ssl`` to fail to drop through to ``pip install`` correctly as ``trusted-host``. `#2979 <https://github.com/pypa/pipenv/issues/2979>`_
|
||||
|
||||
|
||||
- Fixed a bug which caused canonicalized package names to fail to resolve against PyPI. `#2989 <https://github.com/pypa/pipenv/issues/2989>`_
|
||||
|
||||
|
||||
- Enhanced CI detection to detect Azure Devops builds. `#2993 <https://github.com/pypa/pipenv/issues/2993>`_
|
||||
|
||||
|
||||
- Fixed a bug which prevented installing pinned versions which used redirection symbols from the command line. `#2998 <https://github.com/pypa/pipenv/issues/2998>`_
|
||||
|
||||
|
||||
- Fixed a bug which prevented installing the local directory in non-editable mode. `#3005 <https://github.com/pypa/pipenv/issues/3005>`_
|
||||
|
||||
|
||||
|
||||
Vendored Libraries
|
||||
------------------
|
||||
|
||||
- Updated ``requirementslib`` to version ``1.1.9``. `#2989 <https://github.com/pypa/pipenv/issues/2989>`_
|
||||
|
||||
|
||||
- Upgraded ``pythonfinder => 1.1.1`` and ``vistir => 0.1.7``. `#3007 <https://github.com/pypa/pipenv/issues/3007>`_
|
||||
|
||||
|
||||
@@ -129,55 +165,55 @@ Features & Improvements
|
||||
|
||||
- Added environment variables `PIPENV_VERBOSE` and `PIPENV_QUIET` to control
|
||||
output verbosity without needing to pass options. `#2527 <https://github.com/pypa/pipenv/issues/2527>`_
|
||||
|
||||
|
||||
- Updated test-pypi addon to better support json-api access (forward compatibility).
|
||||
Improved testing process for new contributors. `#2568 <https://github.com/pypa/pipenv/issues/2568>`_
|
||||
|
||||
|
||||
- Greatly enhanced python discovery functionality:
|
||||
|
||||
- Added pep514 (windows launcher/finder) support for python discovery.
|
||||
- Introduced architecture discovery for python installations which support different architectures. `#2582 <https://github.com/pypa/pipenv/issues/2582>`_
|
||||
|
||||
|
||||
- Added support for ``pipenv shell`` on msys and cygwin/mingw/git bash for Windows. `#2641 <https://github.com/pypa/pipenv/issues/2641>`_
|
||||
|
||||
|
||||
- Enhanced resolution of editable and VCS dependencies. `#2643 <https://github.com/pypa/pipenv/issues/2643>`_
|
||||
|
||||
|
||||
- Deduplicate and refactor CLI to use stateful arguments and object passing. See `this issue <https://github.com/pallets/click/issues/108>`_ for reference. `#2814 <https://github.com/pypa/pipenv/issues/2814>`_
|
||||
|
||||
|
||||
|
||||
Behavior Changes
|
||||
----------------
|
||||
|
||||
- Virtual environment activation for ``run`` is revised to improve interpolation
|
||||
with other Python discovery tools. `#2503 <https://github.com/pypa/pipenv/issues/2503>`_
|
||||
|
||||
|
||||
- Improve terminal coloring to display better in Powershell. `#2511 <https://github.com/pypa/pipenv/issues/2511>`_
|
||||
|
||||
|
||||
- Invoke ``virtualenv`` directly for virtual environment creation, instead of depending on ``pew``. `#2518 <https://github.com/pypa/pipenv/issues/2518>`_
|
||||
|
||||
|
||||
- ``pipenv --help`` will now include short help descriptions. `#2542 <https://github.com/pypa/pipenv/issues/2542>`_
|
||||
|
||||
|
||||
- Add ``COMSPEC`` to fallback option (along with ``SHELL`` and ``PYENV_SHELL``)
|
||||
if shell detection fails, improving robustness on Windows. `#2651 <https://github.com/pypa/pipenv/issues/2651>`_
|
||||
|
||||
|
||||
- Fallback to shell mode if `run` fails with Windows error 193 to handle non-executable commands. This should improve usability on Windows, where some users run non-executable files without specifying a command, relying on Windows file association to choose the current command. `#2718 <https://github.com/pypa/pipenv/issues/2718>`_
|
||||
|
||||
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- Fixed a bug which prevented installation of editable requirements using ``ssh://`` style urls `#1393 <https://github.com/pypa/pipenv/issues/1393>`_
|
||||
|
||||
|
||||
- VCS Refs for locked local editable dependencies will now update appropriately to the latest hash when running ``pipenv update``. `#1690 <https://github.com/pypa/pipenv/issues/1690>`_
|
||||
|
||||
|
||||
- ``.tar.gz`` and ``.zip`` artifacts will now have dependencies installed even when they are missing from the lockfile. `#2173 <https://github.com/pypa/pipenv/issues/2173>`_
|
||||
|
||||
|
||||
- The command line parser will now handle multiple ``-e/--editable`` dependencies properly via click's option parser to help mitigate future parsing issues. `#2279 <https://github.com/pypa/pipenv/issues/2279>`_
|
||||
|
||||
|
||||
- Fixed the ability of pipenv to parse ``dependency_links`` from ``setup.py`` when ``PIP_PROCESS_DEPENDENCY_LINKS`` is enabled. `#2434 <https://github.com/pypa/pipenv/issues/2434>`_
|
||||
|
||||
|
||||
- Fixed a bug which could cause ``-i/--index`` arguments to sometimes be incorrectly picked up in packages. This is now handled in the command line parser. `#2494 <https://github.com/pypa/pipenv/issues/2494>`_
|
||||
|
||||
|
||||
- Fixed non-deterministic resolution issues related to changes to the internal package finder in ``pip 10``. `#2499 <https://github.com/pypa/pipenv/issues/2499>`_,
|
||||
`#2529 <https://github.com/pypa/pipenv/issues/2529>`_,
|
||||
`#2589 <https://github.com/pypa/pipenv/issues/2589>`_,
|
||||
@@ -191,51 +227,51 @@ Bug Fixes
|
||||
`#2879 <https://github.com/pypa/pipenv/issues/2879>`_,
|
||||
`#2894 <https://github.com/pypa/pipenv/issues/2894>`_,
|
||||
`#2933 <https://github.com/pypa/pipenv/issues/2933>`_
|
||||
|
||||
|
||||
- Fix subshell invocation on Windows for Python 2. `#2515 <https://github.com/pypa/pipenv/issues/2515>`_
|
||||
|
||||
|
||||
- Fixed a bug which sometimes caused pipenv to throw a ``TypeError`` or to run into encoding issues when writing lockfiles on python 2. `#2561 <https://github.com/pypa/pipenv/issues/2561>`_
|
||||
|
||||
|
||||
- Improve quoting logic for ``pipenv run`` so it works better with Windows
|
||||
built-in commands. `#2563 <https://github.com/pypa/pipenv/issues/2563>`_
|
||||
|
||||
|
||||
- Fixed a bug related to parsing vcs requirements with both extras and subdirectory fragments.
|
||||
Corrected an issue in the ``requirementslib`` parser which led to some markers being discarded rather than evaluated. `#2564 <https://github.com/pypa/pipenv/issues/2564>`_
|
||||
|
||||
|
||||
- Fixed multiple issues with finding the correct system python locations. `#2582 <https://github.com/pypa/pipenv/issues/2582>`_
|
||||
|
||||
|
||||
- Catch JSON decoding error to prevent exception when the lock file is of
|
||||
invalid format. `#2607 <https://github.com/pypa/pipenv/issues/2607>`_
|
||||
|
||||
|
||||
- Fixed a rare bug which could sometimes cause errors when installing packages with custom sources. `#2610 <https://github.com/pypa/pipenv/issues/2610>`_
|
||||
|
||||
|
||||
- Update requirementslib to fix a bug which could raise an ``UnboundLocalError`` when parsing malformed VCS URIs. `#2617 <https://github.com/pypa/pipenv/issues/2617>`_
|
||||
|
||||
|
||||
- Fixed an issue which prevented passing multiple ``--ignore`` parameters to ``pipenv check``. `#2632 <https://github.com/pypa/pipenv/issues/2632>`_
|
||||
|
||||
|
||||
- Fixed a bug which caused attempted hashing of ``ssh://`` style URIs which could cause failures during installation of private ssh repositories.
|
||||
- Corrected path conversion issues which caused certain editable VCS paths to be converted to ``ssh://`` URIs improperly. `#2639 <https://github.com/pypa/pipenv/issues/2639>`_
|
||||
|
||||
|
||||
- Fixed a bug which caused paths to be formatted incorrectly when using ``pipenv shell`` in bash for windows. `#2641 <https://github.com/pypa/pipenv/issues/2641>`_
|
||||
|
||||
|
||||
- Dependency links to private repositories defined via ``ssh://`` schemes will now install correctly and skip hashing as long as ``PIP_PROCESS_DEPENDENCY_LINKS=1``. `#2643 <https://github.com/pypa/pipenv/issues/2643>`_
|
||||
|
||||
|
||||
- Fixed a bug which sometimes caused pipenv to parse the ``trusted_host`` argument to pip incorrectly when parsing source URLs which specify ``verify_ssl = false``. `#2656 <https://github.com/pypa/pipenv/issues/2656>`_
|
||||
|
||||
|
||||
- Prevent crashing when a virtual environment in ``WORKON_HOME`` is faulty. `#2676 <https://github.com/pypa/pipenv/issues/2676>`_
|
||||
|
||||
|
||||
- Fixed virtualenv creation failure when a .venv file is present in the project root. `#2680 <https://github.com/pypa/pipenv/issues/2680>`_
|
||||
|
||||
|
||||
- Fixed a bug which could cause the ``-e/--editable`` argument on a dependency to be accidentally parsed as a dependency itself. `#2714 <https://github.com/pypa/pipenv/issues/2714>`_
|
||||
|
||||
|
||||
- Correctly pass `verbose` and `debug` flags to the resolver subprocess so it generates appropriate output. This also resolves a bug introduced by the fix to #2527. `#2732 <https://github.com/pypa/pipenv/issues/2732>`_
|
||||
|
||||
|
||||
- All markers are now included in ``pipenv lock --requirements`` output. `#2748 <https://github.com/pypa/pipenv/issues/2748>`_
|
||||
|
||||
|
||||
- Fixed a bug in marker resolution which could cause duplicate and non-deterministic markers. `#2760 <https://github.com/pypa/pipenv/issues/2760>`_
|
||||
|
||||
|
||||
- Fixed a bug in the dependency resolver which caused regular issues when handling ``setup.py`` based dependency resolution. `#2766 <https://github.com/pypa/pipenv/issues/2766>`_
|
||||
|
||||
|
||||
- Updated vendored dependencies:
|
||||
- ``pip-tools`` (updated and patched to latest w/ ``pip 18.0`` compatibilty)
|
||||
- ``pip 10.0.1 => 18.0``
|
||||
@@ -257,24 +293,24 @@ Bug Fixes
|
||||
- ``vistir 0.1.4 => 0.1.6`` `#2802 <https://github.com/pypa/pipenv/issues/2802>`_,
|
||||
`#2867 <https://github.com/pypa/pipenv/issues/2867>`_,
|
||||
`#2880 <https://github.com/pypa/pipenv/issues/2880>`_
|
||||
|
||||
|
||||
- Fixed a bug where `pipenv` crashes when the `WORKON_HOME` directory does not exist. `#2877 <https://github.com/pypa/pipenv/issues/2877>`_
|
||||
|
||||
|
||||
- Fixed pip is not loaded from pipenv's patched one but the system one `#2912 <https://github.com/pypa/pipenv/issues/2912>`_
|
||||
|
||||
|
||||
- Fixed various bugs related to ``pip 18.1`` release which prevented locking, installation, and syncing, and dumping to a ``requirements.txt`` file. `#2924 <https://github.com/pypa/pipenv/issues/2924>`_
|
||||
|
||||
|
||||
|
||||
Vendored Libraries
|
||||
------------------
|
||||
|
||||
- Pew is no longer vendored. Entry point ``pewtwo``, packages ``pipenv.pew`` and
|
||||
``pipenv.patched.pew`` are removed. `#2521 <https://github.com/pypa/pipenv/issues/2521>`_
|
||||
|
||||
|
||||
- Update ``pythonfinder`` to major release ``1.0.0`` for integration. `#2582 <https://github.com/pypa/pipenv/issues/2582>`_
|
||||
|
||||
|
||||
- Update requirementslib to fix a bug which could raise an ``UnboundLocalError`` when parsing malformed VCS URIs. `#2617 <https://github.com/pypa/pipenv/issues/2617>`_
|
||||
|
||||
|
||||
- - Vendored new libraries ``vistir`` and ``pip-shims``, ``tomlkit``, ``modutil``, and ``plette``.
|
||||
|
||||
- Update vendored libraries:
|
||||
@@ -289,7 +325,7 @@ Vendored Libraries
|
||||
- ``pythonfinder`` to ``1.0.2``
|
||||
- ``pipdeptree`` to ``0.13.0``
|
||||
- ``python-dotenv`` to ``0.9.1`` `#2639 <https://github.com/pypa/pipenv/issues/2639>`_
|
||||
|
||||
|
||||
- Updated vendored dependencies:
|
||||
- ``pip-tools`` (updated and patched to latest w/ ``pip 18.0`` compatibilty)
|
||||
- ``pip 10.0.1 => 18.0``
|
||||
@@ -310,31 +346,31 @@ Vendored Libraries
|
||||
- ``tomlkit 0.4.2 => 0.4.4``
|
||||
- ``vistir 0.1.4 => 0.1.6`` `#2902 <https://github.com/pypa/pipenv/issues/2902>`_,
|
||||
`#2935 <https://github.com/pypa/pipenv/issues/2935>`_
|
||||
|
||||
|
||||
|
||||
Improved Documentation
|
||||
----------------------
|
||||
|
||||
- Simplified the test configuration process. `#2568 <https://github.com/pypa/pipenv/issues/2568>`_
|
||||
|
||||
|
||||
- Updated documentation to use working fortune cookie addon. `#2644 <https://github.com/pypa/pipenv/issues/2644>`_
|
||||
|
||||
|
||||
- Added additional information about troubleshooting ``pipenv shell`` by using the the ``$PIPENV_SHELL`` environment variable. `#2671 <https://github.com/pypa/pipenv/issues/2671>`_
|
||||
|
||||
|
||||
- Added a link to ``PEP-440`` version specifiers in the documentation for additional detail. `#2674 <https://github.com/pypa/pipenv/issues/2674>`_
|
||||
|
||||
|
||||
- Added simple example to README.md for installing from git. `#2685 <https://github.com/pypa/pipenv/issues/2685>`_
|
||||
|
||||
|
||||
- Stopped recommending `--system` for Docker contexts. `#2762 <https://github.com/pypa/pipenv/issues/2762>`_
|
||||
|
||||
|
||||
- Fixed the example url for doing "pipenv install -e
|
||||
some-repo-url#egg=something", it was missing the "egg=" in the fragment
|
||||
identifier. `#2792 <https://github.com/pypa/pipenv/issues/2792>`_
|
||||
|
||||
|
||||
- Fixed link to the "be cordial" essay in the contribution documentation. `#2793 <https://github.com/pypa/pipenv/issues/2793>`_
|
||||
|
||||
|
||||
- Clarify `pipenv install` documentation `#2844 <https://github.com/pypa/pipenv/issues/2844>`_
|
||||
|
||||
|
||||
- Replace reference to uservoice with PEEP-000 `#2909 <https://github.com/pypa/pipenv/issues/2909>`_
|
||||
|
||||
|
||||
@@ -345,73 +381,73 @@ Features & Improvements
|
||||
-----------------------
|
||||
|
||||
- All calls to ``pipenv shell`` are now implemented from the ground up using `shellingham <https://github.com/sarugaku/shellingham>`_, a custom library which was purpose built to handle edge cases and shell detection. `#2371 <https://github.com/pypa/pipenv/issues/2371>`_
|
||||
|
||||
|
||||
- Added support for python 3.7 via a few small compatibility / bugfixes. `#2427 <https://github.com/pypa/pipenv/issues/2427>`_,
|
||||
`#2434 <https://github.com/pypa/pipenv/issues/2434>`_,
|
||||
`#2436 <https://github.com/pypa/pipenv/issues/2436>`_
|
||||
|
||||
|
||||
- Added new flag ``pipenv --support`` to replace the diagnostic command ``python -m pipenv.help``. `#2477 <https://github.com/pypa/pipenv/issues/2477>`_,
|
||||
`#2478 <https://github.com/pypa/pipenv/issues/2478>`_
|
||||
|
||||
|
||||
- Improved import times and CLI runtimes with minor tweaks. `#2485 <https://github.com/pypa/pipenv/issues/2485>`_
|
||||
|
||||
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- Fixed an ongoing bug which sometimes resolved incompatible versions into lockfiles. `#1901 <https://github.com/pypa/pipenv/issues/1901>`_
|
||||
|
||||
|
||||
- Fixed a bug which caused errors when creating virtualenvs which contained leading dash characters. `#2415 <https://github.com/pypa/pipenv/issues/2415>`_
|
||||
|
||||
|
||||
- Fixed a logic error which caused ``--deploy --system`` to overwrite editable vcs packages in the pipfile before installing, which caused any installation to fail by default. `#2417 <https://github.com/pypa/pipenv/issues/2417>`_
|
||||
|
||||
|
||||
- Updated requirementslib to fix an issue with properly quoting markers in VCS requirements. `#2419 <https://github.com/pypa/pipenv/issues/2419>`_
|
||||
|
||||
|
||||
- Installed new vendored jinja2 templates for ``click-completion`` which were causing template errors for users with completion enabled. `#2422 <https://github.com/pypa/pipenv/issues/2422>`_
|
||||
|
||||
|
||||
- Added support for python 3.7 via a few small compatibility / bugfixes. `#2427 <https://github.com/pypa/pipenv/issues/2427>`_
|
||||
|
||||
|
||||
- Fixed an issue reading package names from ``setup.py`` files in projects which imported utilities such as ``versioneer``. `#2433 <https://github.com/pypa/pipenv/issues/2433>`_
|
||||
|
||||
|
||||
- Pipenv will now ensure that its internal package names registry files are written with unicode strings. `#2450 <https://github.com/pypa/pipenv/issues/2450>`_
|
||||
|
||||
|
||||
- Fixed a bug causing requirements input as relative paths to be output as absolute paths or URIs.
|
||||
Fixed a bug affecting normalization of ``git+git@host`` uris. `#2453 <https://github.com/pypa/pipenv/issues/2453>`_
|
||||
|
||||
|
||||
- Pipenv will now always use ``pathlib2`` for ``Path`` based filesystem interactions by default on ``python<3.5``. `#2454 <https://github.com/pypa/pipenv/issues/2454>`_
|
||||
|
||||
|
||||
- Fixed a bug which prevented passing proxy PyPI indexes set with ``--pypi-mirror`` from being passed to pip during virtualenv creation, which could cause the creation to freeze in some cases. `#2462 <https://github.com/pypa/pipenv/issues/2462>`_
|
||||
|
||||
|
||||
- Using the ``python -m pipenv.help`` command will now use proper encoding for the host filesystem to avoid encoding issues. `#2466 <https://github.com/pypa/pipenv/issues/2466>`_
|
||||
|
||||
|
||||
- The new ``jinja2`` templates for ``click_completion`` will now be included in pipenv source distributions. `#2479 <https://github.com/pypa/pipenv/issues/2479>`_
|
||||
|
||||
|
||||
- Resolved a long-standing issue with re-using previously generated ``InstallRequirement`` objects for resolution which could cause ``PKG-INFO`` file information to be deleted, raising a ``TypeError``. `#2480 <https://github.com/pypa/pipenv/issues/2480>`_
|
||||
|
||||
|
||||
- Resolved an issue parsing usernames from private PyPI URIs in ``Pipfiles`` by updating ``requirementslib``. `#2484 <https://github.com/pypa/pipenv/issues/2484>`_
|
||||
|
||||
|
||||
|
||||
Vendored Libraries
|
||||
------------------
|
||||
|
||||
- All calls to ``pipenv shell`` are now implemented from the ground up using `shellingham <https://github.com/sarugaku/shellingham>`_, a custom library which was purpose built to handle edge cases and shell detection. `#2371 <https://github.com/pypa/pipenv/issues/2371>`_
|
||||
|
||||
|
||||
- Updated requirementslib to fix an issue with properly quoting markers in VCS requirements. `#2419 <https://github.com/pypa/pipenv/issues/2419>`_
|
||||
|
||||
|
||||
- Installed new vendored jinja2 templates for ``click-completion`` which were causing template errors for users with completion enabled. `#2422 <https://github.com/pypa/pipenv/issues/2422>`_
|
||||
|
||||
|
||||
- Add patch to ``prettytoml`` to support Python 3.7. `#2426 <https://github.com/pypa/pipenv/issues/2426>`_
|
||||
|
||||
|
||||
- Patched ``prettytoml.AbstractTable._enumerate_items`` to handle ``StopIteration`` errors in preparation of release of python 3.7. `#2427 <https://github.com/pypa/pipenv/issues/2427>`_
|
||||
|
||||
|
||||
- Fixed an issue reading package names from ``setup.py`` files in projects which imported utilities such as ``versioneer``. `#2433 <https://github.com/pypa/pipenv/issues/2433>`_
|
||||
|
||||
|
||||
- Updated ``requirementslib`` to version ``1.0.9`` `#2453 <https://github.com/pypa/pipenv/issues/2453>`_
|
||||
|
||||
|
||||
- Unraveled a lot of old, unnecessary patches to ``pip-tools`` which were causing non-deterministic resolution errors. `#2480 <https://github.com/pypa/pipenv/issues/2480>`_
|
||||
|
||||
|
||||
- Resolved an issue parsing usernames from private PyPI URIs in ``Pipfiles`` by updating ``requirementslib``. `#2484 <https://github.com/pypa/pipenv/issues/2484>`_
|
||||
|
||||
|
||||
|
||||
Improved Documentation
|
||||
----------------------
|
||||
@@ -576,11 +612,11 @@ Improved Documentation
|
||||
----------------------
|
||||
|
||||
- Update documentation wording to clarify Pipenv's overall role in the packaging ecosystem. `#2194 <https://github.com/pypa/pipenv/issues/2194>`_
|
||||
|
||||
|
||||
- Added contribution documentation and guidelines. `#2205 <https://github.com/pypa/pipenv/issues/2205>`_
|
||||
|
||||
|
||||
- Added instructions for supervisord compatibility. `#2215 <https://github.com/pypa/pipenv/issues/2215>`_
|
||||
|
||||
|
||||
- Fixed broken links to development philosophy and contribution documentation. `#2248 <https://github.com/pypa/pipenv/issues/2248>`_
|
||||
|
||||
|
||||
@@ -618,7 +654,6 @@ Vendored Libraries
|
||||
* certifi from version ``2018.1.16`` to ``2018.4.16``.
|
||||
* packaging from version ``16.8`` to ``17.1``.
|
||||
* six from version ``1.10.0`` to ``1.11.0``.
|
||||
* requirementslib from version ``0.2.0`` to ``1.0.1``.
|
||||
* requirementslib from version ``0.2.0`` to ``1.0.1``.
|
||||
|
||||
In addition, scandir was vendored and patched to avoid importing host system binaries when falling back to pathlib2. `#2368 <https://github.com/pypa/pipenv/issues/2368>`_
|
||||
|
||||
|
||||
@@ -1,16 +1,11 @@
|
||||
[dev-packages]
|
||||
pipenv = {path = ".", editable = true}
|
||||
pipenv = {path = ".", editable = true, extras = ["test"]}
|
||||
"flake8" = ">=3.3.0,<4"
|
||||
pytest = "*"
|
||||
mock = "*"
|
||||
sphinx = "<=1.5.5"
|
||||
twine = "*"
|
||||
sphinx-click = "*"
|
||||
pytest-xdist = "*"
|
||||
click = "*"
|
||||
pytest-pypy = {path = "./tests/pytest-pypi", editable = true}
|
||||
pytest-tap = "*"
|
||||
flaky = "*"
|
||||
pytest-pypi = {path = "./tests/pytest-pypi", editable = true}
|
||||
stdeb = {version="*", markers="sys_platform == 'linux'"}
|
||||
black = {version="*", markers="python_version >= '3.6'"}
|
||||
pytz = "*"
|
||||
@@ -21,6 +16,7 @@ jedi = "*"
|
||||
isort = "*"
|
||||
rope = "*"
|
||||
passa = {editable = true, git = "https://github.com/sarugaku/passa.git"}
|
||||
bs4 = "*"
|
||||
|
||||
[packages]
|
||||
|
||||
|
||||
Generated
+226
-231
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "6acc712d82698e574727d19b22d05bf46565ecaa414e288fd0d79e385f8fdd10"
|
||||
"sha256": "d7119fe8fa7be8224ff46509352efbd76dd17accf6a57580dbaf5762e613468b"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {},
|
||||
@@ -36,14 +36,6 @@
|
||||
],
|
||||
"version": "==1.4.3"
|
||||
},
|
||||
"argparse": {
|
||||
"hashes": [
|
||||
"sha256:62b089a55be1d8949cd2bc7e0df0bddb9e028faefc8c32038cc84862aefdd6e4",
|
||||
"sha256:c31647edb69fd3d465a847ea3157d37bed1f95f19760b11a47aa91c04b666314"
|
||||
],
|
||||
"markers": "python_version == '2.6'",
|
||||
"version": "==1.4.0"
|
||||
},
|
||||
"arpeggio": {
|
||||
"hashes": [
|
||||
"sha256:a5258b84f76661d558492fa87e42db634df143685a0e51802d59cae7daad8732",
|
||||
@@ -53,10 +45,10 @@
|
||||
},
|
||||
"atomicwrites": {
|
||||
"hashes": [
|
||||
"sha256:0312ad34fcad8fac3704d441f7b317e50af620823353ec657a53e981f92920c0",
|
||||
"sha256:ec9ae8adaae229e4f8446952d204a3e4b5fdd2d099f9be3aaf556120135fb3ee"
|
||||
"sha256:03472c30eb2c5d1ba9227e4c2ca66ab8287fbfbbda3888aa93dc2e28fc6811b4",
|
||||
"sha256:75a9445bac02d8d058d5e1fe689654ba5a6556a1dfd8ce6ec55a0ed79866cfa6"
|
||||
],
|
||||
"version": "==1.2.1"
|
||||
"version": "==1.3.0"
|
||||
},
|
||||
"attrs": {
|
||||
"hashes": [
|
||||
@@ -72,6 +64,38 @@
|
||||
],
|
||||
"version": "==2.6.0"
|
||||
},
|
||||
"backports.functools-lru-cache": {
|
||||
"hashes": [
|
||||
"sha256:9d98697f088eb1b0fa451391f91afb5e3ebde16bbdb272819fd091151fda4f1a",
|
||||
"sha256:f0b0e4eba956de51238e17573b7087e852dfe9854afd2e9c873f73fc0ca0a6dd"
|
||||
],
|
||||
"markers": "python_version < '3'",
|
||||
"version": "==1.5"
|
||||
},
|
||||
"backports.shutil-get-terminal-size": {
|
||||
"hashes": [
|
||||
"sha256:0975ba55054c15e346944b38956a4c9cbee9009391e41b86c68990effb8c1f64",
|
||||
"sha256:713e7a8228ae80341c70586d1cc0a8caa5207346927e23d09dcbcaf18eadec80"
|
||||
],
|
||||
"markers": "python_version < '3.3'",
|
||||
"version": "==1.0.0"
|
||||
},
|
||||
"backports.weakref": {
|
||||
"hashes": [
|
||||
"sha256:81bc9b51c0abc58edc76aefbbc68c62a787918ffe943a37947e162c3f8e19e82",
|
||||
"sha256:bc4170a29915f8b22c9e7c4939701859650f2eb84184aee80da329ac0b9825c2"
|
||||
],
|
||||
"markers": "python_version < '3.3'",
|
||||
"version": "==1.0.post1"
|
||||
},
|
||||
"beautifulsoup4": {
|
||||
"hashes": [
|
||||
"sha256:034740f6cb549b4e932ae1ab975581e6103ac8f942200a0e9759065984391858",
|
||||
"sha256:945065979fb8529dd2f37dbb58f00b661bdbcbebf954f93b32fdf5263ef35348",
|
||||
"sha256:ba6d5c59906a85ac23dadfe5c88deaf3e179ef565f4898671253e50a78680718"
|
||||
],
|
||||
"version": "==4.7.1"
|
||||
},
|
||||
"black": {
|
||||
"hashes": [
|
||||
"sha256:817243426042db1d36617910df579a54f1afd659adb96fc5032fcf4b36209739",
|
||||
@@ -83,10 +107,17 @@
|
||||
},
|
||||
"bleach": {
|
||||
"hashes": [
|
||||
"sha256:48d39675b80a75f6d1c3bdbffec791cf0bbbab665cf01e20da701c77de278718",
|
||||
"sha256:73d26f018af5d5adcdabf5c1c974add4361a9c76af215fe32fdec8a6fc5fb9b9"
|
||||
"sha256:213336e49e102af26d9cde77dd2d0397afabc5a6bf2fed985dc35b5d1e285a16",
|
||||
"sha256:3fdf7f77adcf649c9911387df51254b813185e32b2c6619f690b593a617e19fa"
|
||||
],
|
||||
"version": "==3.0.2"
|
||||
"version": "==3.1.0"
|
||||
},
|
||||
"bs4": {
|
||||
"hashes": [
|
||||
"sha256:36ecea1fd7cc5c0c6e4a1ff075df26d50da647b75376626cc186e2212886dd3a"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.0.1"
|
||||
},
|
||||
"cerberus": {
|
||||
"hashes": [
|
||||
@@ -96,47 +127,10 @@
|
||||
},
|
||||
"certifi": {
|
||||
"hashes": [
|
||||
"sha256:339dc09518b07e2fa7eda5450740925974815557727d6bd35d319c1524a04a4c",
|
||||
"sha256:6d58c986d22b038c8c0df30d639f23a3e6d172a05c3583e766f4c0b785c0986a"
|
||||
"sha256:47f9c83ef4c0c621eaef743f133f09fa8a74a9b75f037e8624f83bd1b6626cb7",
|
||||
"sha256:993f830721089fef441cdfeb4b2c8c9df86f0c63239f06bd025a76a7daddb033"
|
||||
],
|
||||
"version": "==2018.10.15"
|
||||
},
|
||||
"cffi": {
|
||||
"hashes": [
|
||||
"sha256:151b7eefd035c56b2b2e1eb9963c90c6302dc15fbd8c1c0a83a163ff2c7d7743",
|
||||
"sha256:1553d1e99f035ace1c0544050622b7bc963374a00c467edafac50ad7bd276aef",
|
||||
"sha256:1b0493c091a1898f1136e3f4f991a784437fac3673780ff9de3bcf46c80b6b50",
|
||||
"sha256:2ba8a45822b7aee805ab49abfe7eec16b90587f7f26df20c71dd89e45a97076f",
|
||||
"sha256:3bb6bd7266598f318063e584378b8e27c67de998a43362e8fce664c54ee52d30",
|
||||
"sha256:3c85641778460581c42924384f5e68076d724ceac0f267d66c757f7535069c93",
|
||||
"sha256:3eb6434197633b7748cea30bf0ba9f66727cdce45117a712b29a443943733257",
|
||||
"sha256:495c5c2d43bf6cebe0178eb3e88f9c4aa48d8934aa6e3cddb865c058da76756b",
|
||||
"sha256:4c91af6e967c2015729d3e69c2e51d92f9898c330d6a851bf8f121236f3defd3",
|
||||
"sha256:57b2533356cb2d8fac1555815929f7f5f14d68ac77b085d2326b571310f34f6e",
|
||||
"sha256:770f3782b31f50b68627e22f91cb182c48c47c02eb405fd689472aa7b7aa16dc",
|
||||
"sha256:79f9b6f7c46ae1f8ded75f68cf8ad50e5729ed4d590c74840471fc2823457d04",
|
||||
"sha256:7a33145e04d44ce95bcd71e522b478d282ad0eafaf34fe1ec5bbd73e662f22b6",
|
||||
"sha256:857959354ae3a6fa3da6651b966d13b0a8bed6bbc87a0de7b38a549db1d2a359",
|
||||
"sha256:87f37fe5130574ff76c17cab61e7d2538a16f843bb7bca8ebbc4b12de3078596",
|
||||
"sha256:95d5251e4b5ca00061f9d9f3d6fe537247e145a8524ae9fd30a2f8fbce993b5b",
|
||||
"sha256:9d1d3e63a4afdc29bd76ce6aa9d58c771cd1599fbba8cf5057e7860b203710dd",
|
||||
"sha256:a36c5c154f9d42ec176e6e620cb0dd275744aa1d804786a71ac37dc3661a5e95",
|
||||
"sha256:a6a5cb8809091ec9ac03edde9304b3ad82ad4466333432b16d78ef40e0cce0d5",
|
||||
"sha256:ae5e35a2c189d397b91034642cb0eab0e346f776ec2eb44a49a459e6615d6e2e",
|
||||
"sha256:b0f7d4a3df8f06cf49f9f121bead236e328074de6449866515cea4907bbc63d6",
|
||||
"sha256:b75110fb114fa366b29a027d0c9be3709579602ae111ff61674d28c93606acca",
|
||||
"sha256:ba5e697569f84b13640c9e193170e89c13c6244c24400fc57e88724ef610cd31",
|
||||
"sha256:be2a9b390f77fd7676d80bc3cdc4f8edb940d8c198ed2d8c0be1319018c778e1",
|
||||
"sha256:ca1bd81f40adc59011f58159e4aa6445fc585a32bb8ac9badf7a2c1aa23822f2",
|
||||
"sha256:d5d8555d9bfc3f02385c1c37e9f998e2011f0db4f90e250e5bc0c0a85a813085",
|
||||
"sha256:e55e22ac0a30023426564b1059b035973ec82186ddddbac867078435801c7801",
|
||||
"sha256:e90f17980e6ab0f3c2f3730e56d1fe9bcba1891eeea58966e89d352492cc74f4",
|
||||
"sha256:ecbb7b01409e9b782df5ded849c178a0aa7c906cf8c5a67368047daab282b184",
|
||||
"sha256:ed01918d545a38998bfa5902c7c00e0fee90e957ce036a4000a88e3fe2264917",
|
||||
"sha256:edabd457cd23a02965166026fd9bfd196f4324fe6032e866d0f3bd0301cd486f",
|
||||
"sha256:fdf1c1dc5bafc32bc5d08b054f94d659422b05aba244d6be4ddc1c72d9aa70fb"
|
||||
],
|
||||
"version": "==1.11.5"
|
||||
"version": "==2018.11.29"
|
||||
},
|
||||
"chardet": {
|
||||
"hashes": [
|
||||
@@ -153,58 +147,27 @@
|
||||
"index": "pypi",
|
||||
"version": "==7.0"
|
||||
},
|
||||
"cmarkgfm": {
|
||||
"hashes": [
|
||||
"sha256:0186dccca79483e3405217993b83b914ba4559fe9a8396efc4eea56561b74061",
|
||||
"sha256:1a625afc6f62da428df96ec325dc30866cc5781520cbd904ff4ec44cf018171c",
|
||||
"sha256:207b7673ff4e177374c572feeae0e4ef33be620ec9171c08fd22e2b796e03e3d",
|
||||
"sha256:275905bb371a99285c74931700db3f0c078e7603bed383e8cf1a09f3ee05a3de",
|
||||
"sha256:50098f1c4950722521f0671e54139e0edc1837d63c990cf0f3d2c49607bb51a2",
|
||||
"sha256:50ed116d0b60a07df0dc7b180c28569064b9d37d1578d4c9021cff04d725cb63",
|
||||
"sha256:61a72def110eed903cd1848245897bcb80d295cd9d13944d4f9f30cba5b76655",
|
||||
"sha256:64186fb75d973a06df0e6ea12879533b71f6e7ba1ab01ffee7fc3e7534758889",
|
||||
"sha256:665303d34d7f14f10d7b0651082f25ebf7107f29ef3d699490cac16cdc0fc8ce",
|
||||
"sha256:70b18f843aec58e4e64aadce48a897fe7c50426718b7753aaee399e72df64190",
|
||||
"sha256:761ee7b04d1caee2931344ac6bfebf37102ffb203b136b676b0a71a3f0ea3c87",
|
||||
"sha256:811527e9b7280b136734ed6cb6845e5fbccaeaa132ddf45f0246cbe544016957",
|
||||
"sha256:987b0e157f70c72a84f3c2f9ef2d7ab0f26c08f2bf326c12c087ff9eebcb3ff5",
|
||||
"sha256:9fc6a2183d0a9b0974ec7cdcdad42bd78a3be674cc3e65f87dd694419b3b0ab7",
|
||||
"sha256:a3d17ee4ae739fe16f7501a52255c2e287ac817cfd88565b9859f70520afffea",
|
||||
"sha256:ba5b5488719c0f2ced0aa1986376f7baff1a1653a8eb5fdfcf3f84c7ce46ef8d",
|
||||
"sha256:c573ea89dd95d41b6d8cf36799c34b6d5b1eac4aed0212dee0f0a11fb7b01e8f",
|
||||
"sha256:c5f1b9e8592d2c448c44e6bc0d91224b16ea5f8293908b1561de1f6d2d0658b1",
|
||||
"sha256:cbe581456357d8f0674d6a590b1aaf46c11d01dd0a23af147a51a798c3818034",
|
||||
"sha256:cf219bec69e601fe27e3974b7307d2f06082ab385d42752738ad2eb630a47d65",
|
||||
"sha256:cf5014eb214d814a83a7a47407272d5db10b719dbeaf4d3cfe5969309d0fcf4b",
|
||||
"sha256:d08bad67fa18f7e8ff738c090628ee0cbf0505d74a991c848d6d04abfe67b697",
|
||||
"sha256:d6f716d7b1182bf35862b5065112f933f43dd1aa4f8097c9bcfb246f71528a34",
|
||||
"sha256:e08e479102627641c7cb4ece421c6ed4124820b1758765db32201136762282d9",
|
||||
"sha256:e20ac21418af0298437d29599f7851915497ce9f2866bc8e86b084d8911ee061",
|
||||
"sha256:e25f53c37e319241b9a412382140dffac98ca756ba8f360ac7ab5e30cad9670a",
|
||||
"sha256:e8932bddf159064f04e946fbb64693753488de21586f20e840b3be51745c8c09",
|
||||
"sha256:f20900f16377f2109783ae9348d34bc80530808439591c3d3df73d5c7ef1a00c"
|
||||
],
|
||||
"version": "==0.4.2"
|
||||
},
|
||||
"colorama": {
|
||||
"hashes": [
|
||||
"sha256:a3d89af5db9e9806a779a50296b5fdb466e281147c2c235e8225ecc6dbf7bbf3",
|
||||
"sha256:c9b54bebe91a6a803e0772c8561d53f2926bfeb17cd141fbabcb08424086595c"
|
||||
"sha256:05eed71e2e327246ad6b38c540c4a3117230b19679b875190486ddd2d721422d",
|
||||
"sha256:f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48"
|
||||
],
|
||||
"version": "==0.4.0"
|
||||
"version": "==0.4.1"
|
||||
},
|
||||
"configparser": {
|
||||
"hashes": [
|
||||
"sha256:5308b47021bc2340965c371f0f058cc6971a04502638d4244225c49d80db273a"
|
||||
"sha256:5bd5fa2a491dc3cfe920a3f2a107510d65eceae10e9c6e547b90261a4710df32",
|
||||
"sha256:c114ff90ee2e762db972fa205f02491b1f5cf3ff950decd8542c62970c9bedac",
|
||||
"sha256:df28e045fbff307a28795b18df6ac8662be3219435560ddb068c283afab1ea7a"
|
||||
],
|
||||
"markers": "python_version < '3.2'",
|
||||
"version": "==3.5.0"
|
||||
"version": "==3.7.1"
|
||||
},
|
||||
"cursor": {
|
||||
"hashes": [
|
||||
"sha256:8ee9fe5b925e1001f6ae6c017e93682583d2b4d1ef7130a26cfcdf1651c0032c"
|
||||
"sha256:7e728934f555a84a1c8b0850b66efcb580d092acc927b7d15dd43eb27dd4c4c5"
|
||||
],
|
||||
"version": "==1.2.0"
|
||||
"version": "==1.3.1"
|
||||
},
|
||||
"distlib": {
|
||||
"hashes": [
|
||||
@@ -220,6 +183,13 @@
|
||||
],
|
||||
"version": "==0.14"
|
||||
},
|
||||
"entrypoints": {
|
||||
"hashes": [
|
||||
"sha256:589f874b313739ad35be6e0cd7efde2a4e9b6fea91edcc34e58ecbb8dbe56d19",
|
||||
"sha256:c70dd71abe5a8c85e55e12c19bd91ccfeec11a6e99044204511f9ed547d48451"
|
||||
],
|
||||
"version": "==0.3"
|
||||
},
|
||||
"enum34": {
|
||||
"hashes": [
|
||||
"sha256:2d81cbbe0e73112bdfe6ef8576f2238f2ba27dd0d55752a776c41d38b7da2850",
|
||||
@@ -227,7 +197,7 @@
|
||||
"sha256:6bd0f6ad48ec2aa117d3d141940d484deccda84d4fcd884f5c3d93c23ecd8c79",
|
||||
"sha256:8ad8c4783bf61ded74527bffb48ed9b54166685e4230386a9ed9b1279e2df5b1"
|
||||
],
|
||||
"markers": "python_version < '3.4'",
|
||||
"markers": "python_version < '3'",
|
||||
"version": "==1.1.6"
|
||||
},
|
||||
"execnet": {
|
||||
@@ -246,19 +216,18 @@
|
||||
},
|
||||
"flake8": {
|
||||
"hashes": [
|
||||
"sha256:7253265f7abd8b313e3892944044a365e3f4ac3fcdcfb4298f55ee9ddf188ba0",
|
||||
"sha256:c7841163e2b576d435799169b78703ad6ac1bbb0f199994fc05f700b2a90ea37"
|
||||
"sha256:c3ba1e130c813191db95c431a18cb4d20a468e98af7a77e2181b68574481ad36",
|
||||
"sha256:fd9ddf503110bf3d8b1d270e8c673aab29ccb3dd6abf29bae1f54e5116ab4a91"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.5.0"
|
||||
"version": "==3.7.5"
|
||||
},
|
||||
"flaky": {
|
||||
"hashes": [
|
||||
"sha256:4ad7880aef8c35a34ddb394d4fa33047765bca1e3d67d182bf6eba9c8eabf3a2",
|
||||
"sha256:d0533f473a46b916e6db6e84e20b06d8a70656600a0c14e819b0760b63f70226"
|
||||
"sha256:12bd5e41f372b2190e8d754b6e5829c2f11dbc764e10b30f57e59f829c9ca1da",
|
||||
"sha256:a94931c46a33469ec26f09b652bc88f55a8f5cc77807b90ca7bbafef1108fd7d"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.4.0"
|
||||
"version": "==3.5.3"
|
||||
},
|
||||
"flask": {
|
||||
"hashes": [
|
||||
@@ -272,29 +241,31 @@
|
||||
"sha256:330cc27ccbf7f1e992e69fef78261dc7c6569012cf397db8d3de0234e6c937ca",
|
||||
"sha256:a7bb0f2cf3a3fd1ab2732cb49eba4252c2af4240442415b4abce3b87022a8f50"
|
||||
],
|
||||
"markers": "python_version < '3.3'",
|
||||
"markers": "python_version < '3.0'",
|
||||
"version": "==1.0.2"
|
||||
},
|
||||
"future": {
|
||||
"functools32": {
|
||||
"hashes": [
|
||||
"sha256:e39ced1ab767b5936646cedba8bcce582398233d6a627067d4c6a454c90cfedb"
|
||||
"sha256:89d824aa6c358c421a234d7f9ee0bd75933a67c29588ce50aaa3acdf4d403fa0",
|
||||
"sha256:f6253dfbe0538ad2e387bd8fdfd9293c925d63553f5813c4e587745416501e6d"
|
||||
],
|
||||
"version": "==0.16.0"
|
||||
"markers": "python_version >= '2.7' and python_version < '2.8'",
|
||||
"version": "==3.2.3.post2"
|
||||
},
|
||||
"futures": {
|
||||
"hashes": [
|
||||
"sha256:9ec02aa7d674acb8618afb127e27fde7fc68994c0437ad759fa094a574adb265",
|
||||
"sha256:ec0a6cb848cc212002b9828c3e34c675e0c9ff6741dc445cab6fdd4e1085d1f1"
|
||||
],
|
||||
"markers": "python_version < '3' and python_version >= '2.6'",
|
||||
"markers": "python_version < '3.0'",
|
||||
"version": "==3.2.0"
|
||||
},
|
||||
"idna": {
|
||||
"hashes": [
|
||||
"sha256:156a6814fb5ac1fc6850fb002e0852d56c0c8d2531923a51032d1b70760e186e",
|
||||
"sha256:684a38a6f903c1d71d6d5fac066b58d7768af4de2b832e426ec79c30daa94a16"
|
||||
"sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407",
|
||||
"sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"
|
||||
],
|
||||
"version": "==2.7"
|
||||
"version": "==2.8"
|
||||
},
|
||||
"imagesize": {
|
||||
"hashes": [
|
||||
@@ -337,11 +308,11 @@
|
||||
},
|
||||
"jedi": {
|
||||
"hashes": [
|
||||
"sha256:0191c447165f798e6a730285f2eee783fff81b0d3df261945ecb80983b5c3ca7",
|
||||
"sha256:b7493f73a2febe0dc33d51c99b474547f7f6c0b2c8fb2b21f453eef204c12148"
|
||||
"sha256:571702b5bd167911fe9036e5039ba67f820d6502832285cde8c881ab2b2149fd",
|
||||
"sha256:c8481b5e59d34a5c7c42e98f6625e633f6ef59353abea6437472c7ec2093f191"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.13.1"
|
||||
"version": "==0.13.2"
|
||||
},
|
||||
"jinja2": {
|
||||
"hashes": [
|
||||
@@ -395,57 +366,66 @@
|
||||
"sha256:5ce3c71c5545b472da17b72268978914d0252980348636840bd34a00b5cc96c1",
|
||||
"sha256:b158b6df76edd239b8208d481dc46b6afd45a846b7812ff0ce58971cf5bc8bba"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.0.0"
|
||||
},
|
||||
"more-itertools": {
|
||||
"hashes": [
|
||||
"sha256:c187a73da93e7a8acc0001572aebc7e3c69daf7bf6881a2cea10650bd4420092",
|
||||
"sha256:c476b5d3a34e12d40130bc2f935028b5f636df8f372dc2c1c01dc19681b2039e",
|
||||
"sha256:fcbfeaea0be121980e15bc97b3817b5202ca73d0eae185b4550cbfce2a3ebb3d"
|
||||
"sha256:38a936c0a6d98a38bcc2d03fdaaedaba9f412879461dd2ceff8d37564d6522e4",
|
||||
"sha256:c0a5785b1109a6bd7fac76d6837fd1feca158e54e521ccd2ae8bfe393cc9d4fc",
|
||||
"sha256:fe7a7cae1ccb57d33952113ff4fa1bc5f879963600ed74918f1236e212ee50b9"
|
||||
],
|
||||
"version": "==4.3.0"
|
||||
"markers": "python_version <= '2.7'",
|
||||
"version": "==5.0.0"
|
||||
},
|
||||
"packaging": {
|
||||
"hashes": [
|
||||
"sha256:0886227f54515e592aaa2e5a553332c73962917f2831f1b0f9b9f4380a4b9807",
|
||||
"sha256:f95a1e147590f204328170981833854229bb2912ac3d5f89e2a8ccd2834800c9"
|
||||
"sha256:0c98a5d0be38ed775798ece1b9727178c4469d9c3b4ada66e8e6b7849f8732af",
|
||||
"sha256:9e1cbf8c12b1f1ce0bb5344b8d7ecf66a6f8a6e91bcb0c84593ed6d3ab5c4ab3"
|
||||
],
|
||||
"version": "==18.0"
|
||||
"version": "==19.0"
|
||||
},
|
||||
"parso": {
|
||||
"hashes": [
|
||||
"sha256:35704a43a3c113cce4de228ddb39aab374b8004f4f2407d070b6a2ca784ce8a2",
|
||||
"sha256:895c63e93b94ac1e1690f5fdd40b65f07c8171e3e53cbd7793b5b96c0e0a7f24"
|
||||
"sha256:4580328ae3f548b358f4901e38c0578229186835f0fa0846e47369796dd5bcc9",
|
||||
"sha256:68406ebd7eafe17f8e40e15a84b56848eccbf27d7c1feb89e93d8fca395706db"
|
||||
],
|
||||
"version": "==0.3.1"
|
||||
"version": "==0.3.4"
|
||||
},
|
||||
"parver": {
|
||||
"hashes": [
|
||||
"sha256:ac4afff688d19d5e1876bb68d4bccc1a1b6a5cc8bd6a646939a14d366695ba15",
|
||||
"sha256:f025fba8f88a9c776971df6d62b6cf7f37d1108f84c163bda91e157d7d527075"
|
||||
"sha256:1b37a691af145a3a193eff269d53ba5b2ab16dfbb65d47d85360755919f5fe4b",
|
||||
"sha256:72d056b8f8883ac90eef5554a9c8a47fac39d3b66479f3d2c8d5bc21b849cdba"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.1.1"
|
||||
"version": "==0.2.1"
|
||||
},
|
||||
"passa": {
|
||||
"editable": true,
|
||||
"git": "https://github.com/sarugaku/passa.git",
|
||||
"ref": "4f3b8102f122cf0b75e5d7c513a2e61b0b093dcd"
|
||||
"ref": "a2ba0b30c86339cae5ef3a03046fc9c583452c40",
|
||||
"version": "==0.3.1.dev0"
|
||||
},
|
||||
"pathlib2": {
|
||||
"hashes": [
|
||||
"sha256:25199318e8cc3c25dcb45cbe084cc061051336d5a9ea2a12448d3d8cb748f742",
|
||||
"sha256:5887121d7f7df3603bca2f710e7219f3eca0eb69e0b7cc6e0a022e155ac931a7"
|
||||
],
|
||||
"markers": "python_version < '3.5'",
|
||||
"version": "==2.3.3"
|
||||
},
|
||||
"pbr": {
|
||||
"hashes": [
|
||||
"sha256:f59d71442f9ece3dffc17bc36575768e1ee9967756e6b6535f0ee1f0054c3d68",
|
||||
"sha256:f6d5b23f226a2ba58e14e49aa3b1bfaf814d0199144b95d78458212444de1387"
|
||||
"sha256:a7953f66e1f82e4b061f43096a4bcc058f7d3d41de9b94ac871770e8bdd831a2",
|
||||
"sha256:d717573351cfe09f49df61906cd272abaa759b3e91744396b804965ff7bff38b"
|
||||
],
|
||||
"version": "==5.1.1"
|
||||
"version": "==5.1.2"
|
||||
},
|
||||
"pep517": {
|
||||
"hashes": [
|
||||
"sha256:cc663a438fdfe2e88d8d3c5ef2203ac858de34e31b6609b1fc505d611490a926",
|
||||
"sha256:f79bb08fb064dfc5b141204bfeb56a4141a6d504677fab4723036a464fc25cc1"
|
||||
"sha256:43a7aa3902efd305a605c1028e4045968cd012831233ecab633a31d3ba4860a5",
|
||||
"sha256:cb5ca55450b64e80744cd5c32f7d5b8928004042dfea50fdc3f96ad7f27cba96"
|
||||
],
|
||||
"version": "==0.3"
|
||||
"version": "==0.5.0"
|
||||
},
|
||||
"pip-shims": {
|
||||
"hashes": [
|
||||
@@ -456,14 +436,15 @@
|
||||
},
|
||||
"pipenv": {
|
||||
"editable": true,
|
||||
"path": "."
|
||||
"path": ".",
|
||||
"version": "==2018.11.27.dev0"
|
||||
},
|
||||
"pkginfo": {
|
||||
"hashes": [
|
||||
"sha256:5878d542a4b3f237e359926384f1dde4e099c9f5525d236b1840cf704fa8d474",
|
||||
"sha256:a39076cb3eb34c333a0dd390b568e9e1e881c7bf2cc0aee12120636816f55aee"
|
||||
"sha256:7424f2c8511c186cd5424bbf31045b77435b37a8d604990b79d4e70d741148bb",
|
||||
"sha256:a6d9e40ca61ad3ebd0b72fbadd4fba16e4c0e4df0428c041e01e06eb6ee71f32"
|
||||
],
|
||||
"version": "==1.4.2"
|
||||
"version": "==1.5.0.1"
|
||||
},
|
||||
"plette": {
|
||||
"extras": [
|
||||
@@ -477,10 +458,10 @@
|
||||
},
|
||||
"pluggy": {
|
||||
"hashes": [
|
||||
"sha256:447ba94990e8014ee25ec853339faf7b0fc8050cdc3289d4d71f7f410fb90095",
|
||||
"sha256:bde19360a8ec4dfd8a20dcb811780a30998101f078fc7ded6162f0076f50508f"
|
||||
"sha256:8ddc32f03971bfdf900a81961a48ccf2fb677cf7715108f85295c67405798616",
|
||||
"sha256:980710797ff6a041e9a73a5787804f848996ecaa6f8a1b1e08224a5894f2074a"
|
||||
],
|
||||
"version": "==0.8.0"
|
||||
"version": "==0.8.1"
|
||||
},
|
||||
"py": {
|
||||
"hashes": [
|
||||
@@ -491,72 +472,64 @@
|
||||
},
|
||||
"pycodestyle": {
|
||||
"hashes": [
|
||||
"sha256:cbc619d09254895b0d12c2c691e237b2e91e9b2ecf5e84c26b35400f93dcfb83",
|
||||
"sha256:cbfca99bd594a10f674d0cd97a3d802a1fdef635d4361e1a2658de47ed261e3a"
|
||||
"sha256:95a2219d12372f05704562a14ec30bc76b05a5b297b21a5dfe3f6fac3491ae56",
|
||||
"sha256:e40a936c9a450ad81df37f549d676d127b1b66000a6c500caa2b085bc0ca976c"
|
||||
],
|
||||
"version": "==2.4.0"
|
||||
},
|
||||
"pycparser": {
|
||||
"hashes": [
|
||||
"sha256:a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3"
|
||||
],
|
||||
"version": "==2.19"
|
||||
"version": "==2.5.0"
|
||||
},
|
||||
"pyflakes": {
|
||||
"hashes": [
|
||||
"sha256:9a7662ec724d0120012f6e29d6248ae3727d821bba522a0e6b356eff19126a49",
|
||||
"sha256:f661252913bc1dbe7fcfcbf0af0db3f42ab65aabd1a6ca68fe5d466bace94dae"
|
||||
"sha256:5e8c00e30c464c99e0b501dc160b13a14af7f27d4dffb529c556e30a159e231d",
|
||||
"sha256:f277f9ca3e55de669fba45b7393a1449009cff5a37d1af10ebb76c52765269cd"
|
||||
],
|
||||
"version": "==2.0.0"
|
||||
"version": "==2.1.0"
|
||||
},
|
||||
"pygments": {
|
||||
"hashes": [
|
||||
"sha256:78f3f434bcc5d6ee09020f92ba487f95ba50f1e3ef83ae96b9d5ffa1bab25c5d",
|
||||
"sha256:dbae1046def0efb574852fab9e90209b23f556367b5a320c0bcb871c77c3e8cc"
|
||||
"sha256:5ffada19f6203563680669ee7f53b64dabbeb100eb51b61996085e99c03b284a",
|
||||
"sha256:e8218dd399a61674745138520d0d4cf2621d7e032439341bc3f647bff125818d"
|
||||
],
|
||||
"version": "==2.2.0"
|
||||
"version": "==2.3.1"
|
||||
},
|
||||
"pyparsing": {
|
||||
"hashes": [
|
||||
"sha256:40856e74d4987de5d01761a22d1621ae1c7f8774585acae358aa5c5936c6c90b",
|
||||
"sha256:f353aab21fd474459d97b709e527b5571314ee5f067441dc9f88e33eecd96592"
|
||||
"sha256:66c9268862641abcac4a96ba74506e594c884e3f57690a696d21ad8210ed667a",
|
||||
"sha256:f6c5ef0d7480ad048c054c37632c67fca55299990fff127850181659eea33fc3"
|
||||
],
|
||||
"version": "==2.3.0"
|
||||
"version": "==2.3.1"
|
||||
},
|
||||
"pytest": {
|
||||
"hashes": [
|
||||
"sha256:7e258ee50338f4e46957f9e09a0f10fb1c2d05493fa901d113a8dafd0790de4e",
|
||||
"sha256:9332147e9af2dcf46cd7ceb14d5acadb6564744ddff1fe8c17f0ce60ece7d9a2"
|
||||
"sha256:3f193df1cfe1d1609d4c583838bea3d532b18d6160fd3f55c9447fdca30848ec",
|
||||
"sha256:e246cf173c01169b9617fc07264b7b1316e78d7a650055235d6d897bc80d9660"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.8.2"
|
||||
"version": "==3.10.1"
|
||||
},
|
||||
"pytest-forked": {
|
||||
"hashes": [
|
||||
"sha256:e4500cd0509ec4a26535f7d4112a8cc0f17d3a41c29ffd4eab479d2a55b30805",
|
||||
"sha256:f275cb48a73fc61a6710726348e1da6d68a978f0ec0c54ece5a5fae5977e5a08"
|
||||
"sha256:5fe33fbd07d7b1302c95310803a5e5726a4ff7f19d5a542b7ce57c76fed8135f",
|
||||
"sha256:d352aaced2ebd54d42a65825722cb433004b4446ab5d2044851d9cc7a00c9e38"
|
||||
],
|
||||
"version": "==0.2"
|
||||
"version": "==1.0.2"
|
||||
},
|
||||
"pytest-pypy": {
|
||||
"pytest-pypi": {
|
||||
"editable": true,
|
||||
"path": "./tests/pytest-pypi"
|
||||
"path": "./tests/pytest-pypi",
|
||||
"version": "==0.1.1"
|
||||
},
|
||||
"pytest-tap": {
|
||||
"hashes": [
|
||||
"sha256:3b05ec931424bbe44e944726b68f7ef185bb6d25ce9ce21ac52c9af7ffa9b506",
|
||||
"sha256:ca063de56298034302f3cbce55c87a27d7bfa7af7de591cdb9ec6ce45fea5467"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.3"
|
||||
},
|
||||
"pytest-xdist": {
|
||||
"hashes": [
|
||||
"sha256:06aa39361694c9365baaa03bec71159b59ad06c9826c6279ebba368cb3571561",
|
||||
"sha256:1ef0d05c905cfa0c5442c90e9e350e65c6ada120e33a00a066ca51c89f5f869a"
|
||||
"sha256:4a201bb3ee60f5dd6bb40c5209d4e491cecc4d5bafd656cfb10f86178786e568",
|
||||
"sha256:d03d1ff1b008458ed04fa73e642d840ac69b4107c168e06b71037c62d7813dd4"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.23.2"
|
||||
"version": "==1.26.1"
|
||||
},
|
||||
"pytoml": {
|
||||
"hashes": [
|
||||
@@ -566,11 +539,11 @@
|
||||
},
|
||||
"pytz": {
|
||||
"hashes": [
|
||||
"sha256:a061aa0a9e06881eb8b3b2b43f05b9439d6583c206d0a6c340ff72a7b6669053",
|
||||
"sha256:ffb9ef1de172603304d9d2819af6f5ece76f2e85ec10692a524dd876e72bf277"
|
||||
"sha256:32b0891edff07e28efe91284ed9c31e123d84bea3fd98e1f72be2508f43ef8d9",
|
||||
"sha256:d5f05e487007e29e03409f9398d074e158d920d36eb82eaf66fb1136b0c5374c"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2018.5"
|
||||
"version": "==2018.9"
|
||||
},
|
||||
"readme-renderer": {
|
||||
"hashes": [
|
||||
@@ -581,24 +554,24 @@
|
||||
},
|
||||
"requests": {
|
||||
"hashes": [
|
||||
"sha256:65b3a120e4329e33c9889db89c80976c5272f56ea92d3e74da8a463992e3ff54",
|
||||
"sha256:ea881206e59f41dbd0bd445437d792e43906703fff75ca8ff43ccdb11f33f263"
|
||||
"sha256:502a824f31acdacb3a35b6690b5fbf0bc41d63a24a45c4004352b0242707598e",
|
||||
"sha256:7bf2a778576d825600030a110f3c0e3e8edc51dfaafe1c146e39a2027784957b"
|
||||
],
|
||||
"version": "==2.20.1"
|
||||
"version": "==2.21.0"
|
||||
},
|
||||
"requests-toolbelt": {
|
||||
"hashes": [
|
||||
"sha256:42c9c170abc2cacb78b8ab23ac957945c7716249206f90874651971a4acff237",
|
||||
"sha256:f6a531936c6fa4c6cfce1b9c10d5c4f498d16528d2a54a22ca00011205a187b5"
|
||||
"sha256:380606e1d10dc85c3bd47bf5a6095f815ec007be7a8b69c878507068df059e6f",
|
||||
"sha256:968089d4584ad4ad7c171454f0a5c6dac23971e9472521ea3b6d49d610aa6fc0"
|
||||
],
|
||||
"version": "==0.8.0"
|
||||
"version": "==0.9.1"
|
||||
},
|
||||
"requirementslib": {
|
||||
"hashes": [
|
||||
"sha256:441a5bfa487d3f3f5fd5d81c27071d9fd36bb385f538b3a87d20556a80b76f76",
|
||||
"sha256:89e1e02ff0b52ce9c610124eb990ae706e0aee08beef8c718e7b87e470cdceeb"
|
||||
"sha256:c26feee79853dedddab550cf79fb2fa83b4bc1a16eab58f2c870e8314caa6cc5",
|
||||
"sha256:d302b780afbd1d60f49d368b535929d8ff4b6d972797f3777c9560d48abdded7"
|
||||
],
|
||||
"version": "==1.3.1.post1"
|
||||
"version": "==1.4.0"
|
||||
},
|
||||
"resolvelib": {
|
||||
"hashes": [
|
||||
@@ -609,17 +582,34 @@
|
||||
},
|
||||
"rope": {
|
||||
"hashes": [
|
||||
"sha256:a108c445e1cd897fe19272ab7877d172e7faf3d4148c80e7d20faba42ea8f7b2"
|
||||
"sha256:031eb54b3eeec89f4304ede816995ed2b93a21e6fba16bd02aff10a0d6c257b7"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.11.0"
|
||||
"version": "==0.12.0"
|
||||
},
|
||||
"scandir": {
|
||||
"hashes": [
|
||||
"sha256:04b8adb105f2ed313a7c2ef0f1cf7aff4871aa7a1883fa4d8c44b5551ab052d6",
|
||||
"sha256:1444134990356c81d12f30e4b311379acfbbcd03e0bab591de2696a3b126d58e",
|
||||
"sha256:1b5c314e39f596875e5a95dd81af03730b338c277c54a454226978d5ba95dbb6",
|
||||
"sha256:346619f72eb0ddc4cf355ceffd225fa52506c92a2ff05318cfabd02a144e7c4e",
|
||||
"sha256:44975e209c4827fc18a3486f257154d34ec6eaec0f90fef0cca1caa482db7064",
|
||||
"sha256:61859fd7e40b8c71e609c202db5b0c1dbec0d5c7f1449dec2245575bdc866792",
|
||||
"sha256:a5e232a0bf188362fa00123cc0bb842d363a292de7126126df5527b6a369586a",
|
||||
"sha256:c14701409f311e7a9b7ec8e337f0815baf7ac95776cc78b419a1e6d49889a383",
|
||||
"sha256:c7708f29d843fc2764310732e41f0ce27feadde453261859ec0fca7865dfc41b",
|
||||
"sha256:c9009c527929f6e25604aec39b0a43c3f831d2947d89d6caaab22f057b7055c8",
|
||||
"sha256:f5c71e29b4e2af7ccdc03a020c626ede51da471173b4a6ad1e904f2b2e04b4bd"
|
||||
],
|
||||
"markers": "python_version < '3.5'",
|
||||
"version": "==1.9.0"
|
||||
},
|
||||
"six": {
|
||||
"hashes": [
|
||||
"sha256:70e8a77beed4562e7f14fe23a786b54f6296e34344c23bc42f07b15018ff98e9",
|
||||
"sha256:832dc0e10feb1aa2c68dcc57dbb658f1c7e65b9b61af69048abc87a2db00a0eb"
|
||||
"sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c",
|
||||
"sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"
|
||||
],
|
||||
"version": "==1.11.0"
|
||||
"version": "==1.12.0"
|
||||
},
|
||||
"snowballstemmer": {
|
||||
"hashes": [
|
||||
@@ -628,6 +618,13 @@
|
||||
],
|
||||
"version": "==1.2.1"
|
||||
},
|
||||
"soupsieve": {
|
||||
"hashes": [
|
||||
"sha256:afa56bf14907bb09403e5d15fbed6275caa4174d36b975226e3b67a3bb6e2c4b",
|
||||
"sha256:eaed742b48b1f3e2d45ba6f79401b2ed5dc33b2123dfe216adb90d4bfa0ade26"
|
||||
],
|
||||
"version": "==1.8"
|
||||
},
|
||||
"sphinx": {
|
||||
"hashes": [
|
||||
"sha256:11f271e7a9398385ed730e90f0bb41dc3815294bdcd395b46ed2d033bc2e7d87",
|
||||
@@ -638,18 +635,11 @@
|
||||
},
|
||||
"sphinx-click": {
|
||||
"hashes": [
|
||||
"sha256:0550d3e5dcd6244847bd0861ebe64101a2ef302913866e0ccd9095b2aa230051",
|
||||
"sha256:404784f724504e3da2cb056767ba64955c4bfb9bfca8cfedd7142a962bafd70f"
|
||||
"sha256:926da1a7c677ae1b35cf255269ff84fec65d0f92e4863acfa77b92cf8ae32275",
|
||||
"sha256:f0c03d6ea0e4258c9c09646b6f745090ea8dd13e7e045903e4b789dfc02f7846"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.3.0"
|
||||
},
|
||||
"sphinxcontrib-websupport": {
|
||||
"hashes": [
|
||||
"sha256:68ca7ff70785cbe1e7bccc71a48b5b6d965d79ca50629606c7861a21b206d9dd",
|
||||
"sha256:9de47f375baf1ea07cdb3436ff39d7a9c76042c10a769c52353ec46e4e8fc3b9"
|
||||
],
|
||||
"version": "==1.1.0"
|
||||
"version": "==2.0.1"
|
||||
},
|
||||
"stdeb": {
|
||||
"hashes": [
|
||||
@@ -669,45 +659,47 @@
|
||||
"toml": {
|
||||
"hashes": [
|
||||
"sha256:229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c",
|
||||
"sha256:235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e"
|
||||
"sha256:235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e",
|
||||
"sha256:f1db651f9657708513243e61e6cc67d101a39bad662eaa9b5546f789338e07a3"
|
||||
],
|
||||
"version": "==0.10.0"
|
||||
},
|
||||
"tomlkit": {
|
||||
"hashes": [
|
||||
"sha256:82a8fbb8d8c6af72e96ba00b9db3e20ef61be6c79082552c9363f4559702258b",
|
||||
"sha256:a43e0195edc9b3c198cd4b5f0f3d427a395d47c4a76ceba7cc875ed030756c39"
|
||||
"sha256:d6506342615d051bc961f70bfcfa3d29b6616cc08a3ddfd4bc24196f16fd4ec2",
|
||||
"sha256:f077456d35303e7908cc233b340f71e0bec96f63429997f38ca9272b7d64029e"
|
||||
],
|
||||
"version": "==0.5.2"
|
||||
"version": "==0.5.3"
|
||||
},
|
||||
"towncrier": {
|
||||
"editable": true,
|
||||
"git": "https://github.com/hawkowl/towncrier.git",
|
||||
"ref": "47754a607a9b03f06affaf167d65b990786aae25"
|
||||
"ref": "ecd438c9c0ef132a92aba2eecc4dc672ccf9ec63",
|
||||
"version": "==19.2.0"
|
||||
},
|
||||
"tqdm": {
|
||||
"hashes": [
|
||||
"sha256:3c4d4a5a41ef162dd61f1edb86b0e1c7859054ab656b2e7c7b77e7fbf6d9f392",
|
||||
"sha256:5b4d5549984503050883bc126280b386f5f4ca87e6c023c5d015655ad75bdebb"
|
||||
"sha256:d385c95361699e5cf7622485d9b9eae2d4864b21cd5a2374a9c381ffed701021",
|
||||
"sha256:e22977e3ebe961f72362f6ddfb9197cc531c9737aaf5f607ef09740c849ecd05"
|
||||
],
|
||||
"version": "==4.28.1"
|
||||
"version": "==4.31.1"
|
||||
},
|
||||
"twine": {
|
||||
"hashes": [
|
||||
"sha256:7d89bc6acafb31d124e6e5b295ef26ac77030bf098960c2a4c4e058335827c5c",
|
||||
"sha256:fad6f1251195f7ddd1460cb76d6ea106c93adb4e56c41e0da79658e56e547d2c"
|
||||
"sha256:0fb0bfa3df4f62076cab5def36b1a71a2e4acb4d1fa5c97475b048117b1a6446",
|
||||
"sha256:d6c29c933ecfc74e9b1d9fa13aa1f87c5d5770e119f5a4ce032092f0ff5b14dc"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.12.1"
|
||||
"version": "==1.13.0"
|
||||
},
|
||||
"typing": {
|
||||
"hashes": [
|
||||
"sha256:3a887b021a77b292e151afb75323dea88a7bc1b3dfa92176cff8e44c8b68bddf",
|
||||
"sha256:b2c689d54e1144bbcfd191b0832980a21c2dbcf7b5ff7a66248a60c90e951eb8",
|
||||
"sha256:d400a9344254803a2368533e4533a4200d21eb7b6b729c173bc38201a74db3f2"
|
||||
"sha256:4027c5f6127a6267a435201981ba156de91ad0d1d98e9ddc2aa173453453492d",
|
||||
"sha256:57dcf675a99b74d64dacf6fba08fb17cf7e3d5fdff53d4a30ea2a5e7e52543d4",
|
||||
"sha256:a4c8473ce11a65999c8f59cb093e70686b6c84c98df58c1dae9b3b196089858a"
|
||||
],
|
||||
"markers": "python_version < '3.5'",
|
||||
"version": "==3.6.4"
|
||||
"version": "==3.6.6"
|
||||
},
|
||||
"urllib3": {
|
||||
"hashes": [
|
||||
@@ -718,30 +710,33 @@
|
||||
},
|
||||
"virtualenv": {
|
||||
"hashes": [
|
||||
"sha256:686176c23a538ecc56d27ed9d5217abd34644823d6391cbeb232f42bf722baad",
|
||||
"sha256:f899fafcd92e1150f40c8215328be38ff24b519cd95357fa6e78e006c7638208"
|
||||
"sha256:8b9abfc51c38b70f61634bf265e5beacf6fae11fc25d355d1871f49b8e45f0db",
|
||||
"sha256:cceab52aa7d4df1e1871a70236eb2b89fcfe29b6b43510d9738689787c513261"
|
||||
],
|
||||
"version": "==16.1.0"
|
||||
"version": "==16.4.0"
|
||||
},
|
||||
"virtualenv-clone": {
|
||||
"hashes": [
|
||||
"sha256:afce268508aa5596c90dda234abe345deebc401a57d287bcbd76baa140a1aa58"
|
||||
"sha256:217bd3f0880c9f85672c0bcc9ad9e0354ab7dfa89c2f117e63aa878b4279f5bf",
|
||||
"sha256:316c8a05432a7adb5e461709759aca18c51433ffc2c33e2e80c9e51c452d339f",
|
||||
"sha256:f2a07ed255f3abaceef8c8442512d8cdb2ba9f867e212d8a51680c7790a85033"
|
||||
],
|
||||
"version": "==0.4.0"
|
||||
"version": "==0.5.1"
|
||||
},
|
||||
"vistir": {
|
||||
"extras": [
|
||||
"spinner"
|
||||
],
|
||||
"hashes": [
|
||||
"sha256:851bd783f2b85a372e563db741dc689cb9263ce2e067e387facdca0c36b6a6ea",
|
||||
"sha256:b38ffc8ef83f85d81b4efa4cd31ea3bcd37bdb2bc9e8da9f20a40859bc44b57e"
|
||||
"sha256:510408ec63a4b423967fd630bf0885c8d6a1d5d126f8bb1be6aba86a0da5e815",
|
||||
"sha256:fc5cca7a14e92feaa6f85dd91da74d834904280a96a21190aecb4cd1d1048e0e"
|
||||
],
|
||||
"version": "==0.2.4"
|
||||
"version": "==0.3.0"
|
||||
},
|
||||
"webencodings": {
|
||||
"hashes": [
|
||||
"sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"
|
||||
"sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78",
|
||||
"sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"
|
||||
],
|
||||
"version": "==0.5.1"
|
||||
},
|
||||
@@ -754,17 +749,17 @@
|
||||
},
|
||||
"wheel": {
|
||||
"hashes": [
|
||||
"sha256:196c9842d79262bb66fcf59faa4bd0deb27da911dbc7c6cdca931080eb1f0783",
|
||||
"sha256:c93e2d711f5f9841e17f53b0e6c0ff85593f3b416b6eec7a9452041a59a42688"
|
||||
"sha256:12363e6df5678ecf9daf8429f06f97e7106e701405898f24318ce7f0b79c611a",
|
||||
"sha256:b79ffea026bc0dbd940868347ae9eee36789b6496b6623bd2dec7c7c540a8f99"
|
||||
],
|
||||
"version": "==0.32.2"
|
||||
"version": "==0.33.0"
|
||||
},
|
||||
"yaspin": {
|
||||
"hashes": [
|
||||
"sha256:36fdccc5e0637b5baa8892fe2c3d927782df7d504e9020f40eb2c1502518aa5a",
|
||||
"sha256:8e52bf8079a48e2a53f3dfeec9e04addb900c101d1591c85df69cf677d3237e7"
|
||||
"sha256:441f8a6761e347652d04614899fd0a9cfda7439e2d5682e664bd31230c656176",
|
||||
"sha256:d3ebcf8162e0ef8bb5484b8751d5b6d2fbf0720112c81f64614c308576a03b1d"
|
||||
],
|
||||
"version": "==0.14.0"
|
||||
"version": "==0.14.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ Pipenv: Python Development Workflow for Humans
|
||||
[](https://python.org/pypi/pipenv)
|
||||
[](https://python.org/pypi/pipenv)
|
||||
[](https://code.kennethreitz.org/source/pipenv/)
|
||||
[?branchName=master&label=Windows)](https://dev.azure.com/pypa/pipenv/_build/latest?definitionId=9&branchName=master)
|
||||
[?branchName=master&label=Linux)](https://dev.azure.com/pypa/pipenv/_build/latest?definitionId=10&branchName=master)
|
||||
[?branchName=master&label=Linux)](https://dev.azure.com/pypa/pipenv/_build/latest?definitionId=13&branchName=master)
|
||||
[?branchName=master&label=Windows)](https://dev.azure.com/pypa/pipenv/_build/latest?definitionId=12&branchName=master)
|
||||
[](https://python.org/pypi/pipenv)
|
||||
[](https://saythanks.io/to/kennethreitz)
|
||||
|
||||
@@ -13,14 +13,14 @@ Pipenv: Python Development Workflow for Humans
|
||||
|
||||
**Pipenv** is a tool that aims to bring the best of all packaging worlds
|
||||
(bundler, composer, npm, cargo, yarn, etc.) to the Python world.
|
||||
*Windows is a first--class citizen, in our world.*
|
||||
*Windows is a first-class citizen, in our world.*
|
||||
|
||||
It automatically creates and manages a virtualenv for your projects, as
|
||||
well as adds/removes packages from your `Pipfile` as you
|
||||
install/uninstall packages. It also generates the ever--important
|
||||
install/uninstall packages. It also generates the ever-important
|
||||
`Pipfile.lock`, which is used to produce deterministic builds.
|
||||
|
||||

|
||||

|
||||
|
||||
The problems that Pipenv seeks to solve are multi-faceted:
|
||||
|
||||
|
||||
+2
-2
@@ -203,11 +203,11 @@ To make inclusive or exclusive version comparisons you can use: ::
|
||||
$ pipenv install "requests<=2.13" # will install a version equal or lower than 2.13.0
|
||||
$ pipenv install "requests>2.19" # will install 2.19.1 but not 2.19.0
|
||||
|
||||
.. note:: The use of ``" "`` around the package and version specification is highly recommended
|
||||
.. note:: The use of double quotes around the package and version specification (i.e. ``"requests>2.19"``) is highly recommended
|
||||
to avoid issues with `Input and output redirection <https://robots.thoughtbot.com/input-output-redirection-in-the-shell>`_
|
||||
in Unix-based operating systems.
|
||||
|
||||
The use of ``~=`` is preferred over the ``==`` identifier as the former prevents pipenv from updating the packages: ::
|
||||
The use of ``~=`` is preferred over the ``==`` identifier as the latter prevents pipenv from updating the packages: ::
|
||||
|
||||
$ pipenv install "requests~=2.2" # locks the major version of the package (this is equivalent to using ==2.*)
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#
|
||||
import os
|
||||
|
||||
|
||||
# Path hackery to get current version number.
|
||||
here = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
|
||||
+7
-8
@@ -26,10 +26,12 @@ It automatically creates and manages a virtualenv for your projects, as well as
|
||||
|
||||
Pipenv is primarily meant to provide users and developers of applications with an easy method to setup a working environment. For the distinction between libraries and applications and the usage of ``setup.py`` vs ``Pipfile`` to define dependencies, see :ref:`pipfile-vs-setuppy`.
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<iframe src="https://player.vimeo.com/video/233134524" width="700" height="460" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
|
||||
|
||||
.. image:: https://s3.amazonaws.com/media.kennethreitz.com/pipenv.gif
|
||||
:height: 341px
|
||||
:width: 654px
|
||||
:scale: 100 %
|
||||
:alt: a short animation of pipenv at work
|
||||
|
||||
The problems that Pipenv seeks to solve are multi-faceted:
|
||||
|
||||
- You no longer need to use ``pip`` and ``virtualenv`` separately. They work together.
|
||||
@@ -49,7 +51,7 @@ You can quickly play with Pipenv right in your browser:
|
||||
Install Pipenv Today!
|
||||
---------------------
|
||||
|
||||
If you're on MacOS, you can install Pipenv easily with Homebrew::
|
||||
If you're on MacOS, you can install Pipenv easily with Homebrew. You can also use Linuxbrew on Linux using the same command::
|
||||
|
||||
$ brew install pipenv
|
||||
|
||||
@@ -70,9 +72,6 @@ Otherwise, refer to the :ref:`installing-pipenv` chapter for instructions.
|
||||
User Testimonials
|
||||
-----------------
|
||||
|
||||
**Jannis Leidel**, former pip maintainer—
|
||||
*Pipenv is the porcelain I always wanted to build for pip. It fits my brain and mostly replaces virtualenvwrapper and manual pip calls for me. Use it.*
|
||||
|
||||
**David Gang**—
|
||||
*This package manager is really awesome. For the first time I know exactly what my dependencies are which I installed and what the transitive dependencies are. Combined with the fact that installs are deterministic, makes this package manager first class, like cargo*.
|
||||
|
||||
|
||||
+7
-7
@@ -52,16 +52,16 @@ check this by running::
|
||||
$ pip --version
|
||||
pip 9.0.1
|
||||
|
||||
If you installed Python from source, with an installer from `python.org`_, or
|
||||
via `Homebrew`_ you should already have pip. If you're on Linux and installed
|
||||
If you installed Python from source, with an installer from `python.org`_, via `Homebrew`_ or via `Linuxbrew`_ you should already have pip. If you're on Linux and installed
|
||||
using your OS package manager, you may have to `install pip <https://pip.pypa.io/en/stable/installing/>`_ separately.
|
||||
|
||||
If you plan to install Pipenv using Homebrew you can skip this step. The
|
||||
Homebrew installer takes care of pip for you.
|
||||
If you plan to install Pipenv using Homebrew or Linuxbrew you can skip this step. The
|
||||
Homebrew/Linuxbrew installer takes care of pip for you.
|
||||
|
||||
.. _getting started tutorial: https://opentechschool.github.io/python-beginners/en/getting_started.html#what-is-python-exactly
|
||||
.. _python.org: https://python.org
|
||||
.. _Homebrew: https://brew.sh
|
||||
.. _Linuxbrew: https://linuxbrew.sh/
|
||||
.. _Installing Python: http://docs.python-guide.org/en/latest/starting/installation/
|
||||
|
||||
|
||||
@@ -83,13 +83,13 @@ cases.
|
||||
☤ Homebrew Installation of Pipenv
|
||||
---------------------------------
|
||||
|
||||
Homebrew is a popular open-source package management system for macOS.
|
||||
`Homebrew`_ is a popular open-source package management system for macOS. For Linux users, `Linuxbrew`_ is a Linux port of that.
|
||||
|
||||
Installing pipenv via Homebrew will keep pipenv and all of its dependencies in
|
||||
Installing pipenv via Homebrew or Linuxbrew will keep pipenv and all of its dependencies in
|
||||
an isolated virtual environment so it doesn't interfere with the rest of your
|
||||
Python installation.
|
||||
|
||||
Once you have installed `Homebrew`_ simply run::
|
||||
Once you have installed Homebrew or Linuxbrew simply run::
|
||||
|
||||
$ brew install pipenv
|
||||
|
||||
|
||||
+16
-18
@@ -1,28 +1,26 @@
|
||||
alabaster==0.7.10
|
||||
Babel==2.5.0
|
||||
certifi==2017.7.27.1
|
||||
Babel==2.6.0
|
||||
certifi==2018.10.15
|
||||
chardet==3.0.4
|
||||
click==6.7
|
||||
click==7.0
|
||||
docutils==0.14
|
||||
first==2.0.1
|
||||
idna==2.6
|
||||
imagesize==0.7.1
|
||||
idna==2.7
|
||||
imagesize==1.1.0
|
||||
Jinja2==2.10
|
||||
MarkupSafe==1.0
|
||||
pbr==3.1.1
|
||||
pip-tools==1.9.0
|
||||
MarkupSafe==1.1.0
|
||||
pbr==5.1.1
|
||||
-e .
|
||||
Pygments==2.2.0
|
||||
Pygments==2.3.0
|
||||
pythonz-bd==1.11.4
|
||||
pytz==2017.2
|
||||
requests==2.20.0
|
||||
pytz==2018.5
|
||||
requests==2.20.1
|
||||
resumable-urlretrieve==0.1.5
|
||||
semver==2.7.8
|
||||
six==1.10.0
|
||||
six==1.11.0
|
||||
snowballstemmer==1.2.1
|
||||
Sphinx==1.6.3
|
||||
sphinx-click==1.2.0
|
||||
sphinxcontrib-websupport==1.0.1
|
||||
urllib3==1.22
|
||||
virtualenv==15.1.0
|
||||
virtualenv-clone==0.2.6
|
||||
sphinx-click==1.3.0
|
||||
sphinxcontrib-websupport==1.1.0
|
||||
urllib3==1.24.1
|
||||
virtualenv==16.1.0
|
||||
virtualenv-clone==0.4.0
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
Raise `PipenvUsageError` when [[source]] does not contain url field.
|
||||
@@ -0,0 +1 @@
|
||||
Fixed a bug which caused editable package resolution to sometimes fail with an unhelpful setuptools-related error message.
|
||||
@@ -0,0 +1 @@
|
||||
Dependency resolution now writes hashes for local and remote files to the lockfile.
|
||||
@@ -0,0 +1 @@
|
||||
Fixed a bug which prevented ``pipenv graph`` from correctly showing all dependencies when running from within ``pipenv shell``.
|
||||
@@ -0,0 +1 @@
|
||||
Fixed resolution of direct-url dependencies in ``setup.py`` files to respect ``PEP-508`` style URL dependencies.
|
||||
@@ -0,0 +1 @@
|
||||
Added support for resolution of direct-url dependencies in ``setup.py`` files to respect ``PEP-508`` style URL dependencies.
|
||||
@@ -1 +0,0 @@
|
||||
Environment variables are expanded correctly before running scripts on POSIX.
|
||||
@@ -1 +0,0 @@
|
||||
Pipenv will no longer disable user-mode installation when the ``--system`` flag is passed in.
|
||||
@@ -1 +0,0 @@
|
||||
Fixed an issue with attempting to render unicode output in non-unicode locales.
|
||||
@@ -1 +0,0 @@
|
||||
Fixed a bug which could cause failures to occur when parsing python entries from global pyenv version files.
|
||||
@@ -1 +0,0 @@
|
||||
Fixed an issue which prevented the parsing of named extras sections from certain ``setup.py`` files.
|
||||
@@ -1 +0,0 @@
|
||||
Correctly detect the virtualenv location inside an activated virtualenv.
|
||||
@@ -1 +0,0 @@
|
||||
Fixed a bug which caused spinner frames to be written to stdout during locking operations which could cause redirection pipes to fail.
|
||||
@@ -1 +0,0 @@
|
||||
Fixed a bug that editable pacakges can't be uninstalled correctly.
|
||||
@@ -1 +0,0 @@
|
||||
Adding normal pep 508 compatible markers is now fully functional when using VCS dependencies.
|
||||
@@ -1 +0,0 @@
|
||||
Updated ``requirementslib`` and ``pythonfinder`` for multiple bugfixes.
|
||||
@@ -1 +0,0 @@
|
||||
Fixed an issue where pipenv could crash when multiple pipenv processes attempted to create the same directory.
|
||||
@@ -0,0 +1 @@
|
||||
Update pytest-pypi documentation not to be pytest-httpbin documentation.
|
||||
@@ -0,0 +1,3 @@
|
||||
Fixed a bug which caused failures in warning reporting when running pipenv inside a virtualenv under some circumstances.
|
||||
|
||||
- Fixed a bug with package discovery when running ``pipenv clean``.
|
||||
@@ -0,0 +1,5 @@
|
||||
Added full support for resolution of all dependency types including direct URLs, zip archives, tarballs, etc.
|
||||
|
||||
- Improved error handling and formatting.
|
||||
|
||||
- Introduced improved cross platform stream wrappers for better ``stdout`` and ``stderr`` consistency.
|
||||
@@ -0,0 +1,28 @@
|
||||
Updated vendored dependencies:
|
||||
|
||||
- **attrs**: ``18.2.0`` => ``19.1.0``
|
||||
- **certifi**: ``2018.10.15`` => ``2018.11.29``
|
||||
- **cached_property**: ``1.4.3`` => ``1.5.1``
|
||||
- **colorama**: ``0.3.9`` => ``0.4.1``
|
||||
- **idna**: ``2.7`` => ``2.8``
|
||||
- **markupsafe**: ``1.0`` => ``1.1.1``
|
||||
- **orderedmultidict**: ``(new)`` => ``1.0``
|
||||
- **packaging**: ``18.0`` => ``19.0``
|
||||
- **parse**: ``1.9.0`` => ``1.11.1``
|
||||
- **pathlib2**: ``2.3.2`` => ``2.3.3``
|
||||
- **pep517**: ``(new)`` => ``0.5.0``
|
||||
- **pipdeptree**: ``0.13.0`` => ``0.13.2``
|
||||
- **pyparsing**: ``2.2.2`` => ``2.3.1``
|
||||
- **python-dotenv**: ``0.9.1`` => ``0.10.1``
|
||||
- **pythonfinder**: ``1.1.10`` => ``1.2.0``
|
||||
- **pytoml**: ``(new)`` => ``0.1.20``
|
||||
- **requests**: ``2.20.1`` => ``2.21.0``
|
||||
- **requirementslib**: ``1.3.3`` => ``1.4.2``
|
||||
- **shellingham**: ``1.2.7`` => ``1.2.8``
|
||||
- **six**: ``1.11.0`` => ``1.12.0``
|
||||
- **tomlkit**: ``0.5.2`` => ``0.5.3``
|
||||
- **urllib3**: ``1.24`` => ``1.24.1``
|
||||
- **vistir**: ``0.3.0`` => ``0.3.1``
|
||||
- **yaspin**: ``0.14.0`` => ``0.14.1``
|
||||
|
||||
- Removed vendored dependency **cursor**.
|
||||
@@ -0,0 +1 @@
|
||||
Quote command arguments with carets (``^``) on Windows to work around unintended shell escapes.
|
||||
@@ -0,0 +1 @@
|
||||
Handle alternate names for UTF-8 encoding.
|
||||
@@ -0,0 +1 @@
|
||||
Abort pipenv before adding the non-exist package to Pipfile.
|
||||
@@ -0,0 +1 @@
|
||||
Don't normalize the package name user passes in.
|
||||
@@ -0,0 +1 @@
|
||||
Pipenv will now successfully recursively lock VCS sub-dependencies.
|
||||
@@ -0,0 +1 @@
|
||||
Fix a bug where custom virtualenv can not be activated with pipenv shell
|
||||
@@ -0,0 +1 @@
|
||||
Added support for ``--verbose`` output to ``pipenv run``.
|
||||
@@ -0,0 +1 @@
|
||||
Fix a bug that ``--site-packages`` flag is not recognized.
|
||||
@@ -0,0 +1 @@
|
||||
The inline tables won't be rewritten now.
|
||||
@@ -0,0 +1 @@
|
||||
Pipenv will now discover and resolve the intrinsic dependencies of **all** VCS dependencies, whether they are editable or not, to prevent resolution conflicts.
|
||||
@@ -0,0 +1 @@
|
||||
Fix unhashable type error during ``$ pipenv install --selective-upgrade``
|
||||
@@ -0,0 +1 @@
|
||||
Fixed a keyerror which could occur when locking VCS dependencies in some cases.
|
||||
@@ -0,0 +1 @@
|
||||
Fixed a bug that ``ValidationError`` is thrown when some fields are missing in source section.
|
||||
@@ -0,0 +1 @@
|
||||
Fixed the wrong order of old and new hashes in message.
|
||||
@@ -0,0 +1 @@
|
||||
Updated the index names in lock file when source name in Pipfile is changed.
|
||||
@@ -0,0 +1 @@
|
||||
Replace (non-existant) video on docs index.rst with equivalent gif.
|
||||
@@ -0,0 +1 @@
|
||||
Fix bug causing ``[SSL: CERTIFICATE_VERIFY_FAILED]`` when Pipfile ``[[source]]`` has verify_ssl=false and url with custom port.
|
||||
@@ -0,0 +1 @@
|
||||
Clarify wording in Basic Usage example on using double quotes to escape shell redirection
|
||||
@@ -0,0 +1 @@
|
||||
Fix the issue that lock file can't be created when ``PIPENV_PIPFILE`` is not under working directory.
|
||||
@@ -0,0 +1 @@
|
||||
Added the ability for Windows users to enable emojis by setting ``PIPENV_HIDE_EMOJIS=0``.
|
||||
@@ -0,0 +1,9 @@
|
||||
## PEEP-003: Subcommands
|
||||
|
||||
NOT YET ACCEPTED
|
||||
|
||||
Pipenv will automatically run commands like "pipenv deploy" if the "pipenv-deploy" binary is available on the path.
|
||||
|
||||
These subcommands cannot overwrite built-in commands.
|
||||
|
||||
These subcommands will receive environment variables with contextual information.
|
||||
@@ -0,0 +1,9 @@
|
||||
# PEEP-003: Revocation of Power of BDFL
|
||||
|
||||
**ACCEPTED**
|
||||
|
||||
Pipenv will be governed by a board of maintainers (trusted collaborators to the project on GitHub), not a BDFL.
|
||||
|
||||
The BDFL retains his title, however, revokes himself of his powers.
|
||||
|
||||
PEEP approval will be determined by available members of the board of maintainers, in private or public channels.
|
||||
@@ -10,6 +10,7 @@ import warnings
|
||||
|
||||
from .__version__ import __version__
|
||||
|
||||
|
||||
PIPENV_ROOT = os.path.abspath(os.path.dirname(os.path.realpath(__file__)))
|
||||
PIPENV_VENDOR = os.sep.join([PIPENV_ROOT, "vendor"])
|
||||
PIPENV_PATCHED = os.sep.join([PIPENV_ROOT, "patched"])
|
||||
@@ -20,6 +21,7 @@ sys.path.insert(0, PIPENV_PATCHED)
|
||||
|
||||
from pipenv.vendor.urllib3.exceptions import DependencyWarning
|
||||
from pipenv.vendor.vistir.compat import ResourceWarning, fs_str
|
||||
|
||||
warnings.filterwarnings("ignore", category=DependencyWarning)
|
||||
warnings.filterwarnings("ignore", category=ResourceWarning)
|
||||
warnings.filterwarnings("ignore", category=UserWarning)
|
||||
|
||||
+2
-1
@@ -1,4 +1,5 @@
|
||||
from .cli import cli
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
cli(auto_envvar_prefix="PIPENV")
|
||||
cli()
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
# // ) ) / / // ) ) //___) ) // ) ) || / /
|
||||
# //___/ / / / //___/ / // // / / || / /
|
||||
# // / / // ((____ // / / ||/ /
|
||||
__version__ = "2018.11.15.dev0"
|
||||
__version__ = "2018.11.27.dev0"
|
||||
|
||||
+37
-285
@@ -5,39 +5,17 @@ Exposes a standard API that enables compatibility across python versions,
|
||||
operating systems, etc.
|
||||
"""
|
||||
|
||||
import functools
|
||||
import importlib
|
||||
import io
|
||||
import os
|
||||
import six
|
||||
import sys
|
||||
import warnings
|
||||
|
||||
import six
|
||||
import vistir
|
||||
from tempfile import _bin_openflags, gettempdir, _mkstemp_inner, mkdtemp
|
||||
|
||||
try:
|
||||
from tempfile import _infer_return_type
|
||||
except ImportError:
|
||||
from .vendor.vistir.compat import (
|
||||
NamedTemporaryFile, Path, ResourceWarning, TemporaryDirectory
|
||||
)
|
||||
|
||||
def _infer_return_type(*args):
|
||||
_types = set()
|
||||
for arg in args:
|
||||
if isinstance(type(arg), six.string_types):
|
||||
_types.add(str)
|
||||
elif isinstance(type(arg), bytes):
|
||||
_types.add(bytes)
|
||||
elif arg:
|
||||
_types.add(type(arg))
|
||||
return _types.pop()
|
||||
|
||||
|
||||
if sys.version_info[:2] >= (3, 5):
|
||||
try:
|
||||
from pathlib import Path
|
||||
except ImportError:
|
||||
from .vendor.pathlib2 import Path
|
||||
else:
|
||||
from .vendor.pathlib2 import Path
|
||||
|
||||
# Backport required for earlier versions of Python.
|
||||
if sys.version_info < (3, 3):
|
||||
@@ -45,257 +23,14 @@ if sys.version_info < (3, 3):
|
||||
else:
|
||||
from shutil import get_terminal_size
|
||||
|
||||
try:
|
||||
from weakref import finalize
|
||||
except ImportError:
|
||||
try:
|
||||
from .vendor.backports.weakref import finalize
|
||||
except ImportError:
|
||||
|
||||
class finalize(object):
|
||||
def __init__(self, *args, **kwargs):
|
||||
from .utils import logging
|
||||
logging.warn("weakref.finalize unavailable, not cleaning...")
|
||||
|
||||
def detach(self):
|
||||
return False
|
||||
|
||||
|
||||
from vistir.compat import ResourceWarning
|
||||
|
||||
|
||||
warnings.filterwarnings("ignore", category=ResourceWarning)
|
||||
|
||||
|
||||
class TemporaryDirectory(object):
|
||||
|
||||
"""
|
||||
Create and return a temporary directory. This has the same
|
||||
behavior as mkdtemp but can be used as a context manager. For
|
||||
example:
|
||||
|
||||
with TemporaryDirectory() as tmpdir:
|
||||
...
|
||||
|
||||
Upon exiting the context, the directory and everything contained
|
||||
in it are removed.
|
||||
"""
|
||||
|
||||
def __init__(self, suffix="", prefix="", dir=None):
|
||||
if "RAM_DISK" in os.environ:
|
||||
import uuid
|
||||
|
||||
name = uuid.uuid4().hex
|
||||
dir_name = os.path.join(os.environ["RAM_DISK"].strip(), name)
|
||||
os.mkdir(dir_name)
|
||||
self.name = dir_name
|
||||
else:
|
||||
self.name = mkdtemp(suffix, prefix, dir)
|
||||
self._finalizer = finalize(
|
||||
self,
|
||||
self._cleanup,
|
||||
self.name,
|
||||
warn_message="Implicitly cleaning up {!r}".format(self),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def _cleanup(cls, name, warn_message):
|
||||
vistir.path.rmtree(name)
|
||||
warnings.warn(warn_message, ResourceWarning)
|
||||
|
||||
def __repr__(self):
|
||||
return "<{} {!r}>".format(self.__class__.__name__, self.name)
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, exc, value, tb):
|
||||
self.cleanup()
|
||||
|
||||
def cleanup(self):
|
||||
if self._finalizer.detach():
|
||||
vistir.path.rmtree(self.name)
|
||||
|
||||
|
||||
def _sanitize_params(prefix, suffix, dir):
|
||||
"""Common parameter processing for most APIs in this module."""
|
||||
output_type = _infer_return_type(prefix, suffix, dir)
|
||||
if suffix is None:
|
||||
suffix = output_type()
|
||||
if prefix is None:
|
||||
if output_type is str:
|
||||
prefix = "tmp"
|
||||
else:
|
||||
prefix = os.fsencode("tmp")
|
||||
if dir is None:
|
||||
if output_type is str:
|
||||
dir = gettempdir()
|
||||
else:
|
||||
dir = os.fsencode(gettempdir())
|
||||
return prefix, suffix, dir, output_type
|
||||
|
||||
|
||||
class _TemporaryFileCloser:
|
||||
"""
|
||||
A separate object allowing proper closing of a temporary file's
|
||||
underlying file object, without adding a __del__ method to the
|
||||
temporary file.
|
||||
"""
|
||||
|
||||
file = None # Set here since __del__ checks it
|
||||
close_called = False
|
||||
|
||||
def __init__(self, file, name, delete=True):
|
||||
self.file = file
|
||||
self.name = name
|
||||
self.delete = delete
|
||||
|
||||
# NT provides delete-on-close as a primitive, so we don't need
|
||||
# the wrapper to do anything special. We still use it so that
|
||||
# file.name is useful (i.e. not "(fdopen)") with NamedTemporaryFile.
|
||||
if os.name != "nt":
|
||||
|
||||
# Cache the unlinker so we don't get spurious errors at
|
||||
# shutdown when the module-level "os" is None'd out. Note
|
||||
# that this must be referenced as self.unlink, because the
|
||||
# name TemporaryFileWrapper may also get None'd out before
|
||||
# __del__ is called.
|
||||
|
||||
def close(self, unlink=os.unlink):
|
||||
if not self.close_called and self.file is not None:
|
||||
self.close_called = True
|
||||
try:
|
||||
self.file.close()
|
||||
finally:
|
||||
if self.delete:
|
||||
unlink(self.name)
|
||||
|
||||
# Need to ensure the file is deleted on __del__
|
||||
|
||||
def __del__(self):
|
||||
self.close()
|
||||
|
||||
else:
|
||||
|
||||
def close(self):
|
||||
if not self.close_called:
|
||||
self.close_called = True
|
||||
self.file.close()
|
||||
|
||||
|
||||
class _TemporaryFileWrapper:
|
||||
|
||||
"""
|
||||
Temporary file wrapper
|
||||
This class provides a wrapper around files opened for
|
||||
temporary use. In particular, it seeks to automatically
|
||||
remove the file when it is no longer needed.
|
||||
"""
|
||||
|
||||
def __init__(self, file, name, delete=True):
|
||||
self.file = file
|
||||
self.name = name
|
||||
self.delete = delete
|
||||
self._closer = _TemporaryFileCloser(file, name, delete)
|
||||
|
||||
def __getattr__(self, name):
|
||||
# Attribute lookups are delegated to the underlying file
|
||||
# and cached for non-numeric results
|
||||
# (i.e. methods are cached, closed and friends are not)
|
||||
file = self.__dict__["file"]
|
||||
a = getattr(file, name)
|
||||
if hasattr(a, "__call__"):
|
||||
func = a
|
||||
|
||||
@functools.wraps(func)
|
||||
def func_wrapper(*args, **kwargs):
|
||||
return func(*args, **kwargs)
|
||||
|
||||
# Avoid closing the file as long as the wrapper is alive,
|
||||
# see issue #18879.
|
||||
func_wrapper._closer = self._closer
|
||||
a = func_wrapper
|
||||
if not isinstance(a, int):
|
||||
setattr(self, name, a)
|
||||
return a
|
||||
|
||||
# The underlying __enter__ method returns the wrong object
|
||||
# (self.file) so override it to return the wrapper
|
||||
|
||||
def __enter__(self):
|
||||
self.file.__enter__()
|
||||
return self
|
||||
|
||||
# Need to trap __exit__ as well to ensure the file gets
|
||||
# deleted when used in a with statement
|
||||
|
||||
def __exit__(self, exc, value, tb):
|
||||
result = self.file.__exit__(exc, value, tb)
|
||||
self.close()
|
||||
return result
|
||||
|
||||
def close(self):
|
||||
"""
|
||||
Close the temporary file, possibly deleting it.
|
||||
"""
|
||||
self._closer.close()
|
||||
|
||||
# iter() doesn't use __getattr__ to find the __iter__ method
|
||||
|
||||
def __iter__(self):
|
||||
# Don't return iter(self.file), but yield from it to avoid closing
|
||||
# file as long as it's being used as iterator (see issue #23700). We
|
||||
# can't use 'yield from' here because iter(file) returns the file
|
||||
# object itself, which has a close method, and thus the file would get
|
||||
# closed when the generator is finalized, due to PEP380 semantics.
|
||||
for line in self.file:
|
||||
yield line
|
||||
|
||||
|
||||
def NamedTemporaryFile(
|
||||
mode="w+b",
|
||||
buffering=-1,
|
||||
encoding=None,
|
||||
newline=None,
|
||||
suffix=None,
|
||||
prefix=None,
|
||||
dir=None,
|
||||
delete=True,
|
||||
):
|
||||
"""
|
||||
Create and return a temporary file.
|
||||
Arguments:
|
||||
'prefix', 'suffix', 'dir' -- as for mkstemp.
|
||||
'mode' -- the mode argument to io.open (default "w+b").
|
||||
'buffering' -- the buffer size argument to io.open (default -1).
|
||||
'encoding' -- the encoding argument to io.open (default None)
|
||||
'newline' -- the newline argument to io.open (default None)
|
||||
'delete' -- whether the file is deleted on close (default True).
|
||||
The file is created as mkstemp() would do it.
|
||||
Returns an object with a file-like interface; the name of the file
|
||||
is accessible as its 'name' attribute. The file will be automatically
|
||||
deleted when it is closed unless the 'delete' argument is set to False.
|
||||
"""
|
||||
prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir)
|
||||
flags = _bin_openflags
|
||||
# Setting O_TEMPORARY in the flags causes the OS to delete
|
||||
# the file when it is closed. This is only supported by Windows.
|
||||
if os.name == "nt" and delete:
|
||||
flags |= os.O_TEMPORARY
|
||||
if sys.version_info < (3, 5):
|
||||
(fd, name) = _mkstemp_inner(dir, prefix, suffix, flags)
|
||||
else:
|
||||
(fd, name) = _mkstemp_inner(dir, prefix, suffix, flags, output_type)
|
||||
try:
|
||||
file = io.open(
|
||||
fd, mode, buffering=buffering, newline=newline, encoding=encoding
|
||||
)
|
||||
return _TemporaryFileWrapper(file, name, delete)
|
||||
|
||||
except BaseException:
|
||||
os.unlink(name)
|
||||
os.close(fd)
|
||||
raise
|
||||
__all__ = [
|
||||
"NamedTemporaryFile", "Path", "ResourceWarning", "TemporaryDirectory",
|
||||
"get_terminal_size", "getpreferredencoding", "DEFAULT_ENCODING", "canonical_encoding_name",
|
||||
"force_encoding", "UNICODE_TO_ASCII_TRANSLATION_MAP", "decode_output", "fix_utf8"
|
||||
]
|
||||
|
||||
|
||||
def getpreferredencoding():
|
||||
@@ -313,6 +48,16 @@ def getpreferredencoding():
|
||||
DEFAULT_ENCODING = getpreferredencoding()
|
||||
|
||||
|
||||
def canonical_encoding_name(name):
|
||||
import codecs
|
||||
try:
|
||||
codec = codecs.lookup(name)
|
||||
except LookupError:
|
||||
return name
|
||||
else:
|
||||
return codec.name
|
||||
|
||||
|
||||
# From https://github.com/CarlFK/veyepar/blob/5c5de47/dj/scripts/fixunicode.py
|
||||
# MIT LIcensed, thanks Carl!
|
||||
def force_encoding():
|
||||
@@ -324,20 +69,23 @@ def force_encoding():
|
||||
else:
|
||||
if not (stdout_isatty() and stderr_isatty()):
|
||||
return DEFAULT_ENCODING, DEFAULT_ENCODING
|
||||
stdout_encoding = sys.stdout.encoding
|
||||
stderr_encoding = sys.stderr.encoding
|
||||
stdout_encoding = canonical_encoding_name(sys.stdout.encoding)
|
||||
stderr_encoding = canonical_encoding_name(sys.stderr.encoding)
|
||||
if sys.platform == "win32" and sys.version_info >= (3, 1):
|
||||
return DEFAULT_ENCODING, DEFAULT_ENCODING
|
||||
if stdout_encoding.lower() != "utf-8" or stderr_encoding.lower() != "utf-8":
|
||||
if stdout_encoding != "utf-8" or stderr_encoding != "utf-8":
|
||||
|
||||
from ctypes import pythonapi, py_object, c_char_p
|
||||
try:
|
||||
from ctypes import pythonapi, py_object, c_char_p
|
||||
except ImportError:
|
||||
return DEFAULT_ENCODING, DEFAULT_ENCODING
|
||||
try:
|
||||
PyFile_SetEncoding = pythonapi.PyFile_SetEncoding
|
||||
except AttributeError:
|
||||
return DEFAULT_ENCODING, DEFAULT_ENCODING
|
||||
else:
|
||||
PyFile_SetEncoding.argtypes = (py_object, c_char_p)
|
||||
if stdout_encoding.lower() != "utf-8":
|
||||
if stdout_encoding != "utf-8":
|
||||
try:
|
||||
was_set = PyFile_SetEncoding(sys.stdout, "utf-8")
|
||||
except OSError:
|
||||
@@ -347,7 +95,7 @@ def force_encoding():
|
||||
else:
|
||||
stdout_encoding = "utf-8"
|
||||
|
||||
if stderr_encoding.lower() != "utf-8":
|
||||
if stderr_encoding != "utf-8":
|
||||
try:
|
||||
was_set = PyFile_SetEncoding(sys.stderr, "utf-8")
|
||||
except OSError:
|
||||
@@ -366,11 +114,17 @@ OUT_ENCODING, ERR_ENCODING = force_encoding()
|
||||
UNICODE_TO_ASCII_TRANSLATION_MAP = {
|
||||
8230: u"...",
|
||||
8211: u"-",
|
||||
10004: u"x",
|
||||
10008: u"Ok"
|
||||
10004: u"OK",
|
||||
10008: u"x",
|
||||
}
|
||||
|
||||
|
||||
def decode_for_output(output, target=sys.stdout):
|
||||
return vistir.misc.decode_for_output(
|
||||
output, sys.stdout, translation_map=UNICODE_TO_ASCII_TRANSLATION_MAP
|
||||
)
|
||||
|
||||
|
||||
def decode_output(output):
|
||||
if not isinstance(output, six.string_types):
|
||||
return output
|
||||
@@ -384,13 +138,11 @@ def decode_output(output):
|
||||
output = output.translate(UNICODE_TO_ASCII_TRANSLATION_MAP)
|
||||
output = output.encode(DEFAULT_ENCODING, "replace")
|
||||
return vistir.misc.to_text(output, encoding=DEFAULT_ENCODING, errors="replace")
|
||||
return output
|
||||
|
||||
|
||||
def fix_utf8(text):
|
||||
if not isinstance(text, six.string_types):
|
||||
return text
|
||||
from ._compat import decode_output
|
||||
try:
|
||||
text = decode_output(text)
|
||||
except UnicodeDecodeError:
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# -*- coding=utf-8 -*-
|
||||
from __future__ import absolute_import
|
||||
|
||||
from .command import cli
|
||||
|
||||
+46
-38
@@ -4,39 +4,41 @@ from __future__ import absolute_import
|
||||
import os
|
||||
import sys
|
||||
|
||||
import crayons
|
||||
import delegator
|
||||
|
||||
from click import (
|
||||
argument, echo, edit, group, option, pass_context, secho, version_option
|
||||
)
|
||||
|
||||
import click_completion
|
||||
|
||||
from click_didyoumean import DYMCommandCollection
|
||||
import crayons
|
||||
import delegator
|
||||
|
||||
from ..__version__ import __version__
|
||||
from .options import (
|
||||
CONTEXT_SETTINGS, PipenvGroup, code_option, common_options, deploy_option,
|
||||
general_options, install_options, lock_options, pass_state, skip_lock_option,
|
||||
pypi_mirror_option, python_option, requirementstxt_option, sync_options,
|
||||
system_option, three_option, verbose_option, uninstall_options
|
||||
general_options, install_options, lock_options, pass_state,
|
||||
pypi_mirror_option, python_option, requirementstxt_option,
|
||||
skip_lock_option, sync_options, system_option, three_option,
|
||||
uninstall_options, verbose_option
|
||||
)
|
||||
|
||||
|
||||
# Enable shell completion.
|
||||
click_completion.init()
|
||||
|
||||
subcommand_context = CONTEXT_SETTINGS.copy()
|
||||
subcommand_context.update({
|
||||
"ignore_unknown_options": True,
|
||||
"allow_extra_args": True
|
||||
})
|
||||
subcommand_context_no_interspersion = subcommand_context.copy()
|
||||
subcommand_context_no_interspersion["allow_interspersed_args"] = False
|
||||
|
||||
|
||||
@group(cls=PipenvGroup, invoke_without_command=True, context_settings=CONTEXT_SETTINGS)
|
||||
@option("--where", is_flag=True, default=False, help="Output project home information.")
|
||||
@option("--venv", is_flag=True, default=False, help="Output virtualenv information.")
|
||||
@option(
|
||||
"--py", is_flag=True, default=False, help="Output Python interpreter information."
|
||||
)
|
||||
@option(
|
||||
"--envs", is_flag=True, default=False, help="Output Environment Variable options."
|
||||
)
|
||||
@option("--py", is_flag=True, default=False, help="Output Python interpreter information.")
|
||||
@option("--envs", is_flag=True, default=False, help="Output Environment Variable options.")
|
||||
@option("--rm", is_flag=True, default=False, help="Remove the virtualenv.")
|
||||
@option("--bare", is_flag=True, default=False, help="Minimal output.")
|
||||
@option(
|
||||
@@ -66,7 +68,6 @@ def cli(
|
||||
python=False,
|
||||
help=False,
|
||||
py=False,
|
||||
site_packages=False,
|
||||
envs=False,
|
||||
man=False,
|
||||
completion=False,
|
||||
@@ -194,7 +195,7 @@ def cli(
|
||||
)
|
||||
ctx.abort()
|
||||
# --two / --three was passed…
|
||||
if (state.python or state.three is not None) or site_packages:
|
||||
if (state.python or state.three is not None) or state.site_packages:
|
||||
ensure_project(
|
||||
three=state.three,
|
||||
python=state.python,
|
||||
@@ -211,7 +212,7 @@ def cli(
|
||||
|
||||
@cli.command(
|
||||
short_help="Installs provided packages and adds them to Pipfile, or (if no packages are given), installs all packages from Pipfile.",
|
||||
context_settings=dict(ignore_unknown_options=True, allow_extra_args=True),
|
||||
context_settings=subcommand_context,
|
||||
)
|
||||
@system_option
|
||||
@code_option
|
||||
@@ -253,8 +254,10 @@ def install(
|
||||
ctx.abort()
|
||||
|
||||
|
||||
@cli.command(short_help="Un-installs a provided package and removes it from Pipfile.")
|
||||
@option("--skip-lock/--lock", is_flag=True, default=False, help="Lock afterwards.")
|
||||
@cli.command(
|
||||
short_help="Un-installs a provided package and removes it from Pipfile.",
|
||||
context_settings=subcommand_context
|
||||
)
|
||||
@option(
|
||||
"--all-dev",
|
||||
is_flag=True,
|
||||
@@ -273,7 +276,6 @@ def install(
|
||||
def uninstall(
|
||||
ctx,
|
||||
state,
|
||||
skip_lock=False,
|
||||
all_dev=False,
|
||||
all=False,
|
||||
**kwargs
|
||||
@@ -296,7 +298,8 @@ def uninstall(
|
||||
if retcode:
|
||||
sys.exit(retcode)
|
||||
|
||||
@cli.command(short_help="Generates Pipfile.lock.")
|
||||
|
||||
@cli.command(short_help="Generates Pipfile.lock.", context_settings=CONTEXT_SETTINGS)
|
||||
@lock_options
|
||||
@pass_state
|
||||
@pass_context
|
||||
@@ -328,7 +331,7 @@ def lock(
|
||||
|
||||
@cli.command(
|
||||
short_help="Spawns a shell within the virtualenv.",
|
||||
context_settings=dict(ignore_unknown_options=True, allow_extra_args=True),
|
||||
context_settings=subcommand_context,
|
||||
)
|
||||
@option(
|
||||
"--fancy",
|
||||
@@ -387,11 +390,7 @@ def shell(
|
||||
@cli.command(
|
||||
add_help_option=False,
|
||||
short_help="Spawns a command installed into the virtualenv.",
|
||||
context_settings=dict(
|
||||
ignore_unknown_options=True,
|
||||
allow_interspersed_args=False,
|
||||
allow_extra_args=True,
|
||||
),
|
||||
context_settings=subcommand_context_no_interspersion,
|
||||
)
|
||||
@common_options
|
||||
@argument("command")
|
||||
@@ -400,7 +399,6 @@ def shell(
|
||||
def run(state, command, args):
|
||||
"""Spawns a command installed into the virtualenv."""
|
||||
from ..core import do_run
|
||||
|
||||
do_run(
|
||||
command=command, args=args, three=state.three, python=state.python, pypi_mirror=state.pypi_mirror
|
||||
)
|
||||
@@ -408,7 +406,7 @@ def run(state, command, args):
|
||||
|
||||
@cli.command(
|
||||
short_help="Checks for security vulnerabilities and against PEP 508 markers provided in Pipfile.",
|
||||
context_settings=dict(ignore_unknown_options=True, allow_extra_args=True),
|
||||
context_settings=subcommand_context
|
||||
)
|
||||
@option(
|
||||
"--unused",
|
||||
@@ -448,7 +446,7 @@ def check(
|
||||
)
|
||||
|
||||
|
||||
@cli.command(short_help="Runs lock, then sync.")
|
||||
@cli.command(short_help="Runs lock, then sync.", context_settings=CONTEXT_SETTINGS)
|
||||
@option("--bare", is_flag=True, default=False, help="Minimal output.")
|
||||
@option(
|
||||
"--outdated", is_flag=True, default=False, help=u"List out-of-date dependencies."
|
||||
@@ -525,7 +523,10 @@ def update(
|
||||
)
|
||||
|
||||
|
||||
@cli.command(short_help=u"Displays currently-installed dependency graph information.")
|
||||
@cli.command(
|
||||
short_help=u"Displays currently-installed dependency graph information.",
|
||||
context_settings=CONTEXT_SETTINGS
|
||||
)
|
||||
@option("--bare", is_flag=True, default=False, help="Minimal output.")
|
||||
@option("--json", is_flag=True, default=False, help="Output JSON.")
|
||||
@option("--json-tree", is_flag=True, default=False, help="Output JSON in nested tree.")
|
||||
@@ -537,7 +538,10 @@ def graph(bare=False, json=False, json_tree=False, reverse=False):
|
||||
do_graph(bare=bare, json=json, json_tree=json_tree, reverse=reverse)
|
||||
|
||||
|
||||
@cli.command(short_help="View a given module in your editor.", name="open")
|
||||
@cli.command(
|
||||
short_help="View a given module in your editor.", name="open",
|
||||
context_settings=CONTEXT_SETTINGS
|
||||
)
|
||||
@common_options
|
||||
@argument("module", nargs=1)
|
||||
@pass_state
|
||||
@@ -576,7 +580,10 @@ def run_open(state, module, *args, **kwargs):
|
||||
return 0
|
||||
|
||||
|
||||
@cli.command(short_help="Installs all packages specified in Pipfile.lock.")
|
||||
@cli.command(
|
||||
short_help="Installs all packages specified in Pipfile.lock.",
|
||||
context_settings=CONTEXT_SETTINGS
|
||||
)
|
||||
@option("--bare", is_flag=True, default=False, help="Minimal output.")
|
||||
@sync_options
|
||||
@pass_state
|
||||
@@ -609,7 +616,10 @@ def sync(
|
||||
ctx.abort()
|
||||
|
||||
|
||||
@cli.command(short_help="Uninstalls all packages not specified in Pipfile.lock.")
|
||||
@cli.command(
|
||||
short_help="Uninstalls all packages not specified in Pipfile.lock.",
|
||||
context_settings=CONTEXT_SETTINGS
|
||||
)
|
||||
@option("--bare", is_flag=True, default=False, help="Minimal output.")
|
||||
@option("--dry-run", is_flag=True, default=False, help="Just output unneeded packages.")
|
||||
@verbose_option
|
||||
@@ -620,11 +630,9 @@ def sync(
|
||||
def clean(ctx, state, dry_run=False, bare=False, user=False):
|
||||
"""Uninstalls all packages not specified in Pipfile.lock."""
|
||||
from ..core import do_clean
|
||||
do_clean(ctx=ctx, three=state.three, python=state.python, dry_run=dry_run)
|
||||
do_clean(ctx=ctx, three=state.three, python=state.python, dry_run=dry_run,
|
||||
system=state.system)
|
||||
|
||||
|
||||
# Only invoke the "did you mean" when an argument wasn't passed (it breaks those).
|
||||
if "-" not in "".join(sys.argv) and len(sys.argv) > 1:
|
||||
cli = DYMCommandCollection(sources=[cli])
|
||||
if __name__ == "__main__":
|
||||
cli()
|
||||
|
||||
+22
-14
@@ -4,18 +4,23 @@ from __future__ import absolute_import
|
||||
import os
|
||||
|
||||
import click.types
|
||||
|
||||
from click import (
|
||||
BadParameter, Group, Option, argument, echo, make_pass_decorator, option
|
||||
)
|
||||
from click_didyoumean import DYMMixin
|
||||
|
||||
from .. import environments
|
||||
from ..utils import is_valid_url
|
||||
|
||||
|
||||
CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"])
|
||||
CONTEXT_SETTINGS = {
|
||||
"help_option_names": ["-h", "--help"],
|
||||
"auto_envvar_prefix": "PIPENV"
|
||||
}
|
||||
|
||||
|
||||
class PipenvGroup(Group):
|
||||
class PipenvGroup(DYMMixin, Group):
|
||||
"""Custom Group class provides formatted main help"""
|
||||
|
||||
def get_help_option(self, ctx):
|
||||
@@ -117,7 +122,7 @@ def sequential_option(f):
|
||||
return value
|
||||
return option("--sequential", is_flag=True, default=False, expose_value=False,
|
||||
help="Install dependencies one-at-a-time, instead of concurrently.",
|
||||
callback=callback, type=click.types.BOOL)(f)
|
||||
callback=callback, type=click.types.BOOL, show_envvar=True)(f)
|
||||
|
||||
|
||||
def skip_lock_option(f):
|
||||
@@ -127,7 +132,8 @@ def skip_lock_option(f):
|
||||
return value
|
||||
return option("--skip-lock", is_flag=True, default=False, expose_value=False,
|
||||
help=u"Skip locking mechanisms and use the Pipfile instead during operation.",
|
||||
envvar="PIPENV_SKIP_LOCK", callback=callback, type=click.types.BOOL)(f)
|
||||
envvar="PIPENV_SKIP_LOCK", callback=callback, type=click.types.BOOL,
|
||||
show_envvar=True)(f)
|
||||
|
||||
|
||||
def keep_outdated_option(f):
|
||||
@@ -137,7 +143,7 @@ def keep_outdated_option(f):
|
||||
return value
|
||||
return option("--keep-outdated", is_flag=True, default=False, expose_value=False,
|
||||
help=u"Keep out-dated dependencies from being updated in Pipfile.lock.",
|
||||
callback=callback, type=click.types.BOOL)(f)
|
||||
callback=callback, type=click.types.BOOL, show_envvar=True)(f)
|
||||
|
||||
|
||||
def selective_upgrade_option(f):
|
||||
@@ -157,7 +163,7 @@ def ignore_pipfile_option(f):
|
||||
return value
|
||||
return option("--ignore-pipfile", is_flag=True, default=False, expose_value=False,
|
||||
help="Ignore Pipfile when installing, using the Pipfile.lock.",
|
||||
callback=callback, type=click.types.BOOL)(f)
|
||||
callback=callback, type=click.types.BOOL, show_envvar=True)(f)
|
||||
|
||||
|
||||
def dev_option(f):
|
||||
@@ -167,7 +173,7 @@ def dev_option(f):
|
||||
return value
|
||||
return option("--dev", "-d", is_flag=True, default=False, type=click.types.BOOL,
|
||||
help="Install both develop and default packages.", callback=callback,
|
||||
expose_value=False)(f)
|
||||
expose_value=False, show_envvar=True)(f)
|
||||
|
||||
|
||||
def pre_option(f):
|
||||
@@ -208,7 +214,7 @@ def python_option(f):
|
||||
return value
|
||||
return option("--python", default=False, nargs=1, callback=callback,
|
||||
help="Specify which version of Python virtualenv should use.",
|
||||
expose_value=False)(f)
|
||||
expose_value=False, allow_from_autoenv=False)(f)
|
||||
|
||||
|
||||
def pypi_mirror_option(f):
|
||||
@@ -238,7 +244,7 @@ def site_packages_option(f):
|
||||
return value
|
||||
return option("--site-packages", is_flag=True, default=False, type=click.types.BOOL,
|
||||
help="Enable site-packages for the virtualenv.", callback=callback,
|
||||
expose_value=False)(f)
|
||||
expose_value=False, show_envvar=True)(f)
|
||||
|
||||
|
||||
def clear_option(f):
|
||||
@@ -248,7 +254,7 @@ def clear_option(f):
|
||||
return value
|
||||
return option("--clear", is_flag=True, callback=callback, type=click.types.BOOL,
|
||||
help="Clears caches (pipenv, pip, and pip-tools).",
|
||||
expose_value=False)(f)
|
||||
expose_value=False, show_envvar=True)(f)
|
||||
|
||||
|
||||
def system_option(f):
|
||||
@@ -258,7 +264,8 @@ def system_option(f):
|
||||
state.system = value
|
||||
return value
|
||||
return option("--system", is_flag=True, default=False, help="System pip management.",
|
||||
callback=callback, type=click.types.BOOL, expose_value=False)(f)
|
||||
callback=callback, type=click.types.BOOL, expose_value=False,
|
||||
show_envvar=True)(f)
|
||||
|
||||
|
||||
def requirementstxt_option(f):
|
||||
@@ -287,8 +294,9 @@ def code_option(f):
|
||||
if value:
|
||||
state.installstate.code = value
|
||||
return value
|
||||
return option("--code", "-c", nargs=1, default=False, help="Import from codebase.",
|
||||
callback=callback, expose_value=False)(f)
|
||||
return option("--code", "-c", nargs=1, default=False, help="Install packages "
|
||||
"automatically discovered from import statements.", callback=callback,
|
||||
expose_value=False)(f)
|
||||
|
||||
|
||||
def deploy_option(f):
|
||||
@@ -298,7 +306,7 @@ def deploy_option(f):
|
||||
return value
|
||||
return option("--deploy", is_flag=True, default=False, type=click.types.BOOL,
|
||||
help=u"Abort if the Pipfile.lock is out-of-date, or Python version is"
|
||||
" wrong.", callback=callback, expose_value=False)(f)
|
||||
" wrong.", callback=callback, expose_value=False)(f)
|
||||
|
||||
|
||||
def setup_verbosity(ctx, param, value):
|
||||
|
||||
+17
-2
@@ -70,14 +70,29 @@ class Script(object):
|
||||
Foul characters include:
|
||||
|
||||
* Whitespaces.
|
||||
* Carets (^). (pypa/pipenv#3307)
|
||||
* Parentheses in the command. (pypa/pipenv#3168)
|
||||
|
||||
Carets introduce a difficult situation since they are essentially
|
||||
"lossy" when parsed. Consider this in cmd.exe::
|
||||
|
||||
> echo "foo^bar"
|
||||
"foo^bar"
|
||||
> echo foo^^bar
|
||||
foo^bar
|
||||
|
||||
The two commands produce different results, but are both parsed by the
|
||||
shell as `foo^bar`, and there's essentially no sensible way to tell
|
||||
what was actually passed in. This implementation assumes the quoted
|
||||
variation (the first) since it is easier to implement, and arguably
|
||||
the more common case.
|
||||
|
||||
The intended use of this function is to pre-process an argument list
|
||||
before passing it into ``subprocess.Popen(..., shell=True)``.
|
||||
|
||||
See also: https://docs.python.org/3/library/subprocess.html#converting-argument-sequence
|
||||
"""
|
||||
return " ".join(itertools.chain(
|
||||
[_quote_if_contains(self.command, r'[\s()]')],
|
||||
(_quote_if_contains(arg, r'\s') for arg in self.args),
|
||||
[_quote_if_contains(self.command, r'[\s^()]')],
|
||||
(_quote_if_contains(arg, r'[\s^]') for arg in self.args),
|
||||
))
|
||||
|
||||
+238
-138
@@ -1,62 +1,42 @@
|
||||
# -*- coding=utf-8 -*-
|
||||
|
||||
from __future__ import absolute_import, print_function
|
||||
import json as simplejson
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
import sys
|
||||
import time
|
||||
import json as simplejson
|
||||
import warnings
|
||||
|
||||
import click
|
||||
import six
|
||||
import urllib3.util as urllib3_util
|
||||
from pipenv.vendor import vistir
|
||||
|
||||
import click_completion
|
||||
import crayons
|
||||
import dotenv
|
||||
import delegator
|
||||
import dotenv
|
||||
import pipfile
|
||||
import vistir
|
||||
import warnings
|
||||
import six
|
||||
|
||||
import urllib3.util as urllib3_util
|
||||
|
||||
from . import environments, exceptions, pep508checker, progress
|
||||
from ._compat import fix_utf8, decode_for_output
|
||||
from .cmdparse import Script
|
||||
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
|
||||
)
|
||||
from .project import Project, SourceNotFound
|
||||
from .utils import (
|
||||
convert_deps_to_pip,
|
||||
is_required_version,
|
||||
proper_case,
|
||||
pep423_name,
|
||||
venv_resolve_deps,
|
||||
escape_grouped_arguments,
|
||||
python_version,
|
||||
find_windows_executable,
|
||||
prepare_pip_source_args,
|
||||
is_valid_url,
|
||||
is_pypi_url,
|
||||
create_mirror_source,
|
||||
download_file,
|
||||
is_pinned,
|
||||
is_star,
|
||||
parse_indexes,
|
||||
escape_cmd,
|
||||
create_spinner,
|
||||
get_canonical_names
|
||||
convert_deps_to_pip, create_mirror_source, create_spinner, download_file,
|
||||
escape_cmd, escape_grouped_arguments, find_windows_executable,
|
||||
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
|
||||
)
|
||||
from . import environments, pep508checker, progress
|
||||
from .environments import (
|
||||
PIPENV_COLORBLIND,
|
||||
PIPENV_SHELL_FANCY,
|
||||
PIPENV_SKIP_VALIDATION,
|
||||
PIPENV_HIDE_EMOJIS,
|
||||
PIPENV_YES,
|
||||
PIPENV_DEFAULT_PYTHON_VERSION,
|
||||
PIPENV_MAX_SUBPROCESS,
|
||||
PIPENV_DONT_USE_PYENV,
|
||||
SESSION_IS_INTERACTIVE,
|
||||
PIPENV_CACHE_DIR,
|
||||
PIPENV_PYUP_API_KEY,
|
||||
)
|
||||
from ._compat import fix_utf8
|
||||
from . import exceptions
|
||||
|
||||
|
||||
# Packages that should be ignored later.
|
||||
BAD_PACKAGES = (
|
||||
@@ -455,6 +435,11 @@ def ensure_python(three=None, python=None):
|
||||
sp.ok(environments.PIPENV_SPINNER_OK_TEXT.format("Success!"))
|
||||
# Print the results, in a beautiful blue…
|
||||
click.echo(crayons.blue(c.out), err=True)
|
||||
# Clear the pythonfinder caches
|
||||
from .vendor.pythonfinder import Finder
|
||||
finder = Finder(system=False, global_search=True)
|
||||
finder.find_python_version.cache_clear()
|
||||
finder.find_all_python_versions.cache_clear()
|
||||
# Find the newly installed Python, hopefully.
|
||||
version = str(version)
|
||||
path_to_python = find_a_system_python(version)
|
||||
@@ -690,10 +675,10 @@ def batch_install(deps_list, procs, failed_deps_queue,
|
||||
requirements_dir, no_deps=False, ignore_hashes=False,
|
||||
allow_global=False, blocking=False, pypi_mirror=None,
|
||||
nprocs=PIPENV_MAX_SUBPROCESS, retry=True):
|
||||
|
||||
from .vendor.requirementslib.models.utils import strip_extras_markers_from_requirement
|
||||
failed = (not retry)
|
||||
if not failed:
|
||||
label = INSTALL_LABEL if os.name != "nt" else ""
|
||||
label = INSTALL_LABEL if not PIPENV_HIDE_EMOJIS else ""
|
||||
else:
|
||||
label = INSTALL_LABEL2
|
||||
|
||||
@@ -705,6 +690,10 @@ def batch_install(deps_list, procs, failed_deps_queue,
|
||||
trusted_hosts = []
|
||||
# Install these because
|
||||
for dep in deps_list_bar:
|
||||
if dep.req.req:
|
||||
dep.req.req = strip_extras_markers_from_requirement(dep.req.req)
|
||||
if dep.markers:
|
||||
dep.markers = str(strip_extras_markers_from_requirement(dep.get_markers()))
|
||||
index = None
|
||||
if dep.index:
|
||||
index = project.find_source(dep.index)
|
||||
@@ -713,10 +702,18 @@ def batch_install(deps_list, procs, failed_deps_queue,
|
||||
trusted_hosts.append(urllib3_util.parse_url(index.get("url")).host)
|
||||
# Install the module.
|
||||
is_artifact = False
|
||||
if no_deps:
|
||||
link = getattr(dep.req, "link", None)
|
||||
is_wheel = False
|
||||
if link:
|
||||
is_wheel = link.is_wheel
|
||||
if dep.is_file_or_url and (dep.is_direct_url or any(
|
||||
dep.req.uri.endswith(ext) for ext in ["zip", "tar.gz"]
|
||||
)):
|
||||
is_artifact = True
|
||||
elif dep.is_vcs:
|
||||
is_artifact = True
|
||||
needs_deps = not no_deps if no_deps is True else is_artifact
|
||||
|
||||
extra_indexes = []
|
||||
if not index and indexes:
|
||||
@@ -727,19 +724,28 @@ def batch_install(deps_list, procs, failed_deps_queue,
|
||||
with vistir.contextmanagers.temp_environ():
|
||||
if not allow_global:
|
||||
os.environ["PIP_USER"] = vistir.compat.fs_str("0")
|
||||
if "PYTHONHOME" in os.environ:
|
||||
del os.environ["PYTHONHOME"]
|
||||
if not needs_deps:
|
||||
link = getattr(dep.req, "link", None)
|
||||
is_wheel = False
|
||||
if link:
|
||||
is_wheel = link.is_wheel
|
||||
needs_deps = dep.is_file_or_url and not (is_wheel or dep.editable)
|
||||
c = pip_install(
|
||||
dep,
|
||||
ignore_hashes=any([ignore_hashes, dep.editable, dep.is_vcs]),
|
||||
allow_global=allow_global,
|
||||
no_deps=False if is_artifact else no_deps,
|
||||
no_deps=not needs_deps,
|
||||
block=any([dep.editable, dep.is_vcs, blocking]),
|
||||
index=index,
|
||||
requirements_dir=requirements_dir,
|
||||
pypi_mirror=pypi_mirror,
|
||||
trusted_hosts=trusted_hosts,
|
||||
extra_indexes=extra_indexes
|
||||
extra_indexes=extra_indexes,
|
||||
use_pep517=not retry,
|
||||
)
|
||||
if dep.is_vcs:
|
||||
if dep.is_vcs or dep.editable:
|
||||
c.block()
|
||||
if procs.qsize() < nprocs:
|
||||
c.dep = dep
|
||||
@@ -777,7 +783,8 @@ def do_install_dependencies(
|
||||
click.echo(
|
||||
crayons.normal(fix_utf8("Installing dependencies from Pipfile…"), bold=True)
|
||||
)
|
||||
lockfile = project.get_or_create_lockfile()
|
||||
# skip_lock should completely bypass the lockfile (broken in 4dac1676)
|
||||
lockfile = project.get_or_create_lockfile(from_pipfile=True)
|
||||
else:
|
||||
lockfile = project.get_or_create_lockfile()
|
||||
if not bare:
|
||||
@@ -807,6 +814,8 @@ def do_install_dependencies(
|
||||
|
||||
procs = queue.Queue(maxsize=PIPENV_MAX_SUBPROCESS)
|
||||
failed_deps_queue = queue.Queue()
|
||||
if skip_lock:
|
||||
ignore_hashes = True
|
||||
|
||||
install_kwargs = {
|
||||
"no_deps": no_deps, "ignore_hashes": ignore_hashes, "allow_global": allow_global,
|
||||
@@ -817,6 +826,7 @@ def do_install_dependencies(
|
||||
else:
|
||||
install_kwargs["nprocs"] = 1
|
||||
|
||||
# with project.environment.activated():
|
||||
batch_install(
|
||||
deps_list, procs, failed_deps_queue, requirements_dir, **install_kwargs
|
||||
)
|
||||
@@ -1019,9 +1029,12 @@ def do_lock(
|
||||
dev_packages = overwrite_dev(project.packages, dev_packages)
|
||||
# Resolve dev-package dependencies, with pip-tools.
|
||||
for is_dev in [True, False]:
|
||||
pipfile_section = "dev_packages" if is_dev else "packages"
|
||||
pipfile_section = "dev-packages" if is_dev else "packages"
|
||||
lockfile_section = "develop" if is_dev else "default"
|
||||
packages = getattr(project, pipfile_section)
|
||||
if project.pipfile_exists:
|
||||
packages = project.parsed_pipfile.get(pipfile_section, {})
|
||||
else:
|
||||
packages = getattr(project, pipfile_section.replace("-", "_"))
|
||||
|
||||
if write:
|
||||
# Alert the user of progress.
|
||||
@@ -1034,12 +1047,8 @@ def do_lock(
|
||||
err=True,
|
||||
)
|
||||
|
||||
deps = convert_deps_to_pip(
|
||||
packages, project, r=False, include_index=True
|
||||
)
|
||||
# Mutates the lockfile
|
||||
venv_resolve_deps(
|
||||
deps,
|
||||
packages,
|
||||
which=which,
|
||||
project=project,
|
||||
dev=is_dev,
|
||||
@@ -1189,9 +1198,9 @@ def do_init(
|
||||
)
|
||||
else:
|
||||
if old_hash:
|
||||
msg = fix_utf8("Pipfile.lock ({1}) out of date, updating to ({0})…")
|
||||
msg = fix_utf8("Pipfile.lock ({0}) out of date, updating to ({1})…")
|
||||
else:
|
||||
msg = fix_utf8("Pipfile.lock is corrupted, replaced with ({0})…")
|
||||
msg = fix_utf8("Pipfile.lock is corrupted, replaced with ({1})…")
|
||||
click.echo(
|
||||
crayons.red(msg.format(old_hash[-6:], new_hash[-6:]), bold=True),
|
||||
err=True,
|
||||
@@ -1260,12 +1269,12 @@ def pip_install(
|
||||
requirements_dir=None,
|
||||
extra_indexes=None,
|
||||
pypi_mirror=None,
|
||||
trusted_hosts=None
|
||||
trusted_hosts=None,
|
||||
use_pep517=True
|
||||
):
|
||||
from pipenv.patched.notpip._internal import logger as piplogger
|
||||
from .utils import Mapping
|
||||
from .vendor.vistir.compat import Mapping
|
||||
from .vendor.urllib3.util import parse_url
|
||||
|
||||
src = []
|
||||
write_to_tmpfile = False
|
||||
if requirement:
|
||||
@@ -1283,6 +1292,10 @@ def pip_install(
|
||||
crayons.normal("Installing {0!r}".format(requirement.name), bold=True),
|
||||
err=True,
|
||||
)
|
||||
|
||||
if requirement:
|
||||
ignore_hashes = True if not requirement.hashes else ignore_hashes
|
||||
|
||||
# Create files for hash mode.
|
||||
if write_to_tmpfile:
|
||||
if not requirements_dir:
|
||||
@@ -1292,12 +1305,13 @@ def pip_install(
|
||||
prefix="pipenv-", suffix="-requirement.txt", dir=requirements_dir,
|
||||
delete=False
|
||||
)
|
||||
f.write(vistir.misc.to_bytes(requirement.as_line()))
|
||||
line = requirement.as_line(include_hashes=not ignore_hashes)
|
||||
f.write(vistir.misc.to_bytes(line))
|
||||
r = f.name
|
||||
f.close()
|
||||
# Install dependencies when a package is a VCS dependency.
|
||||
|
||||
if requirement and requirement.vcs:
|
||||
no_deps = False
|
||||
# Install dependencies when a package is a non-editable VCS dependency.
|
||||
# Don't specify a source directory when using --system.
|
||||
if not allow_global and ("PIP_SRC" not in os.environ):
|
||||
src.extend(["--src", "{0}".format(project.virtualenv_src_location)])
|
||||
@@ -1343,25 +1357,84 @@ def pip_install(
|
||||
create_mirror_source(pypi_mirror) if is_pypi_url(source["url"]) else source
|
||||
for source in sources
|
||||
]
|
||||
|
||||
line_kwargs = {"as_list": True, "include_hashes": not ignore_hashes}
|
||||
|
||||
# Install dependencies when a package is a VCS dependency.
|
||||
if requirement and requirement.vcs:
|
||||
ignore_hashes = True
|
||||
# Don't specify a source directory when using --system.
|
||||
src_dir = None
|
||||
if "PIP_SRC" in os.environ:
|
||||
src_dir = os.environ["PIP_SRC"]
|
||||
src = ["--src", os.environ["PIP_SRC"]]
|
||||
if not requirement.editable:
|
||||
no_deps = False
|
||||
|
||||
if src_dir is not None:
|
||||
repo = requirement.req.get_vcs_repo(src_dir=src_dir)
|
||||
else:
|
||||
repo = requirement.req.get_vcs_repo()
|
||||
write_to_tmpfile = True
|
||||
line_kwargs["include_markers"] = False
|
||||
line_kwargs["include_hashes"] = False
|
||||
if not requirements_dir:
|
||||
requirements_dir = vistir.path.create_tracked_tempdir(prefix="pipenv",
|
||||
suffix="requirements")
|
||||
f = vistir.compat.NamedTemporaryFile(
|
||||
prefix="pipenv-", suffix="-requirement.txt", dir=requirements_dir,
|
||||
delete=False
|
||||
)
|
||||
line = "-e" if requirement.editable else ""
|
||||
if requirement.editable or requirement.name is not None:
|
||||
name = requirement.name
|
||||
if requirement.extras:
|
||||
name = "{0}{1}".format(name, requirement.extras_as_pip)
|
||||
line = "-e {0}#egg={1}".format(vistir.path.path_to_url(repo.checkout_directory), requirement.name)
|
||||
if repo.subdirectory:
|
||||
line = "{0}&subdirectory={1}".format(line, repo.subdirectory)
|
||||
else:
|
||||
line = requirement.as_line(**line_kwargs)
|
||||
f.write(vistir.misc.to_bytes(line))
|
||||
r = f.name
|
||||
f.close()
|
||||
|
||||
# Create files for hash mode.
|
||||
if write_to_tmpfile and not r:
|
||||
if not requirements_dir:
|
||||
requirements_dir = vistir.path.create_tracked_tempdir(
|
||||
prefix="pipenv", suffix="requirements")
|
||||
f = vistir.compat.NamedTemporaryFile(
|
||||
prefix="pipenv-", suffix="-requirement.txt", dir=requirements_dir,
|
||||
delete=False
|
||||
)
|
||||
ignore_hashes = True if not requirement.hashes else ignore_hashes
|
||||
line = requirement.as_line(include_hashes=not ignore_hashes)
|
||||
line = "{0} {1}".format(line, " ".join(src))
|
||||
f.write(vistir.misc.to_bytes(line))
|
||||
r = f.name
|
||||
f.close()
|
||||
|
||||
if (requirement and requirement.editable) and not r:
|
||||
line_kwargs = {"as_list": True}
|
||||
if requirement.markers:
|
||||
line_kwargs["include_markers"] = False
|
||||
line_kwargs["include_markers"] = False
|
||||
line_kwargs["include_hashes"] = False
|
||||
install_reqs = requirement.as_line(**line_kwargs)
|
||||
if requirement.editable and install_reqs[0].startswith("-e "):
|
||||
req, install_reqs = install_reqs[0], install_reqs[1:]
|
||||
possible_hashes = install_reqs[:]
|
||||
editable_opt, req = req.split(" ", 1)
|
||||
install_reqs = [editable_opt, req] + install_reqs
|
||||
if not all(item.startswith("--hash") for item in install_reqs):
|
||||
ignore_hashes = True
|
||||
|
||||
# hashes must be passed via a file
|
||||
ignore_hashes = True
|
||||
elif r:
|
||||
install_reqs = ["-r", r]
|
||||
with open(r) as f:
|
||||
if "--hash" not in f.read():
|
||||
ignore_hashes = True
|
||||
else:
|
||||
ignore_hashes = True if not requirement.hashes else False
|
||||
install_reqs = requirement.as_line(as_list=True)
|
||||
ignore_hashes = True
|
||||
install_reqs = requirement.as_line(as_list=True, include_hashes=not ignore_hashes)
|
||||
if not requirement.markers:
|
||||
install_reqs = [escape_cmd(r) for r in install_reqs]
|
||||
elif len(install_reqs) > 1:
|
||||
@@ -1382,7 +1455,11 @@ def pip_install(
|
||||
pip_command.extend(prepare_pip_source_args(sources))
|
||||
if not ignore_hashes:
|
||||
pip_command.append("--require-hashes")
|
||||
|
||||
if not use_pep517:
|
||||
from .vendor.packaging.version import parse as parse_version
|
||||
pip_command.append("--no-build-isolation")
|
||||
if project.environment.pip_version >= parse_version("19.0"):
|
||||
pip_command.append("--no-use-pep517")
|
||||
if environments.is_verbose():
|
||||
click.echo("$ {0}".format(pip_command), err=True)
|
||||
cache_dir = vistir.compat.Path(PIPENV_CACHE_DIR)
|
||||
@@ -1401,6 +1478,8 @@ def pip_install(
|
||||
)
|
||||
cmd = Script.parse(pip_command)
|
||||
pip_command = cmd.cmdify()
|
||||
c = None
|
||||
# with project.environment.activated():
|
||||
c = delegator.run(pip_command, block=block, env=pip_config)
|
||||
return c
|
||||
|
||||
@@ -1712,14 +1791,8 @@ def do_install(
|
||||
# Don't search for requirements.txt files if the user provides one
|
||||
if requirements or package_args or project.pipfile_exists:
|
||||
skip_requirements = True
|
||||
# Don't attempt to install develop and default packages if Pipfile is missing
|
||||
if not project.pipfile_exists and not (package_args or dev) and not code:
|
||||
if not (ignore_pipfile or deploy):
|
||||
raise exceptions.PipfileNotFound(project.path_to("Pipfile"))
|
||||
elif ((skip_lock and deploy) or ignore_pipfile) and not project.lockfile_exists:
|
||||
raise exceptions.LockfileNotFound(project.path_to("Pipfile.lock"))
|
||||
concurrent = not sequential
|
||||
# Ensure that virtualenv is available.
|
||||
# Ensure that virtualenv is available and pipfile are available
|
||||
ensure_project(
|
||||
three=three,
|
||||
python=python,
|
||||
@@ -1729,6 +1802,12 @@ def do_install(
|
||||
skip_requirements=skip_requirements,
|
||||
pypi_mirror=pypi_mirror,
|
||||
)
|
||||
# Don't attempt to install develop and default packages if Pipfile is missing
|
||||
if not project.pipfile_exists and not (package_args or dev) and not code:
|
||||
if not (ignore_pipfile or deploy):
|
||||
raise exceptions.PipfileNotFound(project.path_to("Pipfile"))
|
||||
elif ((skip_lock and deploy) or ignore_pipfile) and not project.lockfile_exists:
|
||||
raise exceptions.LockfileNotFound(project.path_to("Pipfile.lock"))
|
||||
# Load the --pre settings from the Pipfile.
|
||||
if not pre:
|
||||
pre = project.settings.get("allow_prereleases")
|
||||
@@ -1814,26 +1893,6 @@ def do_install(
|
||||
for req in import_from_code(code):
|
||||
click.echo(" Found {0}!".format(crayons.green(req)))
|
||||
project.add_package_to_pipfile(req)
|
||||
# Install editable local packages before locking - this gives us access to dist-info
|
||||
if project.pipfile_exists and (
|
||||
# double negatives are for english readability, leave them alone.
|
||||
(not project.lockfile_exists and not deploy)
|
||||
or (not project.virtualenv_exists and not system)
|
||||
):
|
||||
section = (
|
||||
project.editable_packages if not dev else project.editable_dev_packages
|
||||
)
|
||||
for package in section.keys():
|
||||
req = convert_deps_to_pip(
|
||||
{package: section[package]}, project=project, r=False
|
||||
)
|
||||
if req:
|
||||
req = req[0]
|
||||
req = req[len("-e ") :] if req.startswith("-e ") else req
|
||||
if not editable_packages:
|
||||
editable_packages = [req]
|
||||
else:
|
||||
editable_packages.extend([req])
|
||||
# Allow more than one package to be provided.
|
||||
package_args = [p for p in packages] + [
|
||||
"-e {0}".format(pkg) for pkg in editable_packages
|
||||
@@ -1852,7 +1911,7 @@ def do_install(
|
||||
if not is_star(section[package__name]) and is_star(package__val):
|
||||
# Support for VCS dependencies.
|
||||
package_args[i] = convert_deps_to_pip(
|
||||
{packages: section[package__name]}, project=project, r=False
|
||||
{package__name: section[package__name]}, project=project, r=False
|
||||
)[0]
|
||||
except KeyError:
|
||||
pass
|
||||
@@ -1877,9 +1936,9 @@ def do_install(
|
||||
keep_outdated=keep_outdated
|
||||
)
|
||||
|
||||
# This is for if the user passed in dependencies, then we want to maek sure we
|
||||
# This is for if the user passed in dependencies, then we want to make sure we
|
||||
else:
|
||||
from .vendor.requirementslib import Requirement
|
||||
from .vendor.requirementslib.models.requirements import Requirement
|
||||
|
||||
# make a tuple of (display_name, entry)
|
||||
pkg_list = packages + ["-e {0}".format(pkg) for pkg in editable_packages]
|
||||
@@ -1906,6 +1965,8 @@ def do_install(
|
||||
with vistir.contextmanagers.temp_environ(), create_spinner("Installing...") as sp:
|
||||
if not system:
|
||||
os.environ["PIP_USER"] = vistir.compat.fs_str("0")
|
||||
if "PYTHONHOME" in os.environ:
|
||||
del os.environ["PYTHONHOME"]
|
||||
try:
|
||||
pkg_requirement = Requirement.from_line(pkg_line)
|
||||
except ValueError as e:
|
||||
@@ -1927,6 +1988,17 @@ def do_install(
|
||||
extra_indexes=extra_index_url,
|
||||
pypi_mirror=pypi_mirror,
|
||||
)
|
||||
if not c.ok:
|
||||
sp.write_err(vistir.compat.fs_str(
|
||||
"{0}: {1}".format(
|
||||
crayons.red("WARNING"),
|
||||
"Failed installing package {0}".format(pkg_line)
|
||||
),
|
||||
))
|
||||
sp.write_err(vistir.compat.fs_str(
|
||||
"Error text: {0}".format(c.out)
|
||||
))
|
||||
raise RuntimeError(c.err)
|
||||
except (ValueError, RuntimeError) as e:
|
||||
sp.write_err(vistir.compat.fs_str(
|
||||
"{0}: {1}".format(crayons.red("WARNING"), e),
|
||||
@@ -1934,6 +2006,7 @@ def do_install(
|
||||
sp.fail(environments.PIPENV_SPINNER_FAIL_TEXT.format(
|
||||
"Installation Failed",
|
||||
))
|
||||
sys.exit(1)
|
||||
# Warn if --editable wasn't passed.
|
||||
if pkg_requirement.is_vcs and not pkg_requirement.editable:
|
||||
sp.write_err(
|
||||
@@ -1972,12 +2045,20 @@ def do_install(
|
||||
crayons.normal(fix_utf8("…"), bold=True),
|
||||
)
|
||||
))
|
||||
# Add the package to the Pipfile.
|
||||
try:
|
||||
project.add_package_to_pipfile(pkg_requirement, dev)
|
||||
except ValueError as e:
|
||||
import traceback
|
||||
sp.write_err(
|
||||
"{0} {1}".format(
|
||||
crayons.red("Error:", bold=True), traceback.format_exc()
|
||||
)
|
||||
)
|
||||
sp.fail(environments.PIPENV_SPINNER_FAIL_TEXT.format(
|
||||
"Failed adding package to Pipfile"
|
||||
))
|
||||
sp.ok(environments.PIPENV_SPINNER_OK_TEXT.format("Installation Succeeded"))
|
||||
# Add the package to the Pipfile.
|
||||
try:
|
||||
project.add_package_to_pipfile(pkg_requirement, dev)
|
||||
except ValueError as e:
|
||||
raise exceptions.PipfileException(e)
|
||||
# Update project settings with pre preference.
|
||||
if pre:
|
||||
project.update_settings({"allow_prereleases": pre})
|
||||
@@ -2157,11 +2238,6 @@ def do_shell(three=None, python=False, fancy=False, shell_args=None, pypi_mirror
|
||||
three=three, python=python, validate=False, pypi_mirror=pypi_mirror,
|
||||
)
|
||||
|
||||
# Set an environment variable, so we know we're in the environment.
|
||||
os.environ["PIPENV_ACTIVE"] = vistir.misc.fs_str("1")
|
||||
|
||||
os.environ.pop("PIP_SHIMS_BASE_MODULE", None)
|
||||
|
||||
# Support shell compatibility mode.
|
||||
if PIPENV_SHELL_FANCY:
|
||||
fancy = True
|
||||
@@ -2177,6 +2253,13 @@ def do_shell(three=None, python=False, fancy=False, shell_args=None, pypi_mirror
|
||||
shell_args,
|
||||
)
|
||||
|
||||
# Set an environment variable, so we know we're in the environment.
|
||||
# Only set PIPENV_ACTIVE after finishing reading virtualenv_location
|
||||
# otherwise its value will be changed
|
||||
os.environ["PIPENV_ACTIVE"] = vistir.misc.fs_str("1")
|
||||
|
||||
os.environ.pop("PIP_SHIMS_BASE_MODULE", None)
|
||||
|
||||
if fancy:
|
||||
shell.fork(*fork_args)
|
||||
return
|
||||
@@ -2311,22 +2394,42 @@ def do_run(command, args, three=None, python=False, pypi_mirror=None):
|
||||
three=three, python=python, validate=False, pypi_mirror=pypi_mirror,
|
||||
)
|
||||
|
||||
# Set an environment variable, so we know we're in the environment.
|
||||
os.environ["PIPENV_ACTIVE"] = vistir.misc.fs_str("1")
|
||||
|
||||
os.environ.pop("PIP_SHIMS_BASE_MODULE", None)
|
||||
load_dot_env()
|
||||
|
||||
previous_pip_shims_module = os.environ.pop("PIP_SHIMS_BASE_MODULE", None)
|
||||
|
||||
# Activate virtualenv under the current interpreter's environment
|
||||
inline_activate_virtual_environment()
|
||||
|
||||
# Set an environment variable, so we know we're in the environment.
|
||||
# Only set PIPENV_ACTIVE after finishing reading virtualenv_location
|
||||
# such as in inline_activate_virtual_environment
|
||||
# otherwise its value will be changed
|
||||
previous_pipenv_active_value = os.environ.get("PIPENV_ACTIVE")
|
||||
os.environ["PIPENV_ACTIVE"] = vistir.misc.fs_str("1")
|
||||
|
||||
try:
|
||||
script = project.build_script(command, args)
|
||||
cmd_string = ' '.join([script.command] + script.args)
|
||||
if environments.is_verbose():
|
||||
click.echo(crayons.normal("$ {0}".format(cmd_string)), err=True)
|
||||
except ScriptEmptyError:
|
||||
click.echo("Can't run script {0!r}-it's empty?", err=True)
|
||||
run_args = [script]
|
||||
run_kwargs = {}
|
||||
if os.name == "nt":
|
||||
do_run_nt(script)
|
||||
run_fn = do_run_nt
|
||||
else:
|
||||
do_run_posix(script, command=command)
|
||||
run_fn = do_run_posix
|
||||
run_kwargs = {"command": command}
|
||||
try:
|
||||
run_fn(*run_args, **run_kwargs)
|
||||
finally:
|
||||
os.environ.pop("PIPENV_ACTIVE", None)
|
||||
if previous_pipenv_active_value is not None:
|
||||
os.environ["PIPENV_ACTIVE"] = previous_pipenv_active_value
|
||||
if previous_pip_shims_module is not None:
|
||||
os.environ["PIP_SHIMS_BASE_MODULE"] = previous_pip_shims_module
|
||||
|
||||
|
||||
def do_check(
|
||||
@@ -2506,7 +2609,7 @@ def do_graph(bare=False, json=False, json_tree=False, reverse=False):
|
||||
if not project.virtualenv_exists:
|
||||
click.echo(
|
||||
u"{0}: No virtualenv has been created for this project yet! Consider "
|
||||
u"running {1} first to automatically generate one for you or see"
|
||||
u"running {1} first to automatically generate one for you or see "
|
||||
u"{2} for further instructions.".format(
|
||||
crayons.red("Warning", bold=True),
|
||||
crayons.green("`pipenv install`"),
|
||||
@@ -2587,7 +2690,7 @@ def do_sync(
|
||||
):
|
||||
# The lock file needs to exist because sync won't write to it.
|
||||
if not project.lockfile_exists:
|
||||
raise exceptions.LockfileNotFound(project.lockfile_location)
|
||||
raise exceptions.LockfileNotFound("Pipfile.lock")
|
||||
|
||||
# Ensure that virtualenv is available if not system.
|
||||
ensure_project(
|
||||
@@ -2615,34 +2718,32 @@ def do_sync(
|
||||
click.echo(crayons.green("All dependencies are now up-to-date!"))
|
||||
|
||||
|
||||
def do_clean(ctx, three=None, python=None, dry_run=False, bare=False, pypi_mirror=None):
|
||||
def do_clean(
|
||||
ctx, three=None, python=None, dry_run=False, bare=False, pypi_mirror=None,
|
||||
system=False
|
||||
):
|
||||
# Ensure that virtualenv is available.
|
||||
from packaging.utils import canonicalize_name
|
||||
ensure_project(three=three, python=python, validate=False, pypi_mirror=pypi_mirror)
|
||||
ensure_lockfile(pypi_mirror=pypi_mirror)
|
||||
# Make sure that the virtualenv's site packages are configured correctly
|
||||
# otherwise we may end up removing from the global site packages directory
|
||||
installed_package_names = [
|
||||
canonicalize_name(pkg.project_name) for pkg
|
||||
in project.environment.get_installed_packages()
|
||||
]
|
||||
installed_package_names = project.installed_package_names.copy()
|
||||
# Remove known "bad packages" from the list.
|
||||
for bad_package in BAD_PACKAGES:
|
||||
if canonicalize_name(bad_package) in installed_package_names:
|
||||
if environments.is_verbose():
|
||||
click.echo("Ignoring {0}.".format(bad_package), err=True)
|
||||
del installed_package_names[installed_package_names.index(
|
||||
canonicalize_name(bad_package)
|
||||
)]
|
||||
installed_package_names.remove(canonicalize_name(bad_package))
|
||||
# Intelligently detect if --dev should be used or not.
|
||||
develop = [canonicalize_name(k) for k in project.lockfile_content["develop"].keys()]
|
||||
default = [canonicalize_name(k) for k in project.lockfile_content["default"].keys()]
|
||||
for used_package in set(develop + default):
|
||||
locked_packages = {
|
||||
canonicalize_name(pkg) for pkg in project.lockfile_package_names["combined"]
|
||||
}
|
||||
for used_package in locked_packages:
|
||||
if used_package in installed_package_names:
|
||||
del installed_package_names[installed_package_names.index(
|
||||
canonicalize_name(used_package)
|
||||
)]
|
||||
installed_package_names.remove(used_package)
|
||||
failure = False
|
||||
cmd = [which_pip(allow_global=system), "uninstall", "-y", "-qq"]
|
||||
for apparent_bad_package in installed_package_names:
|
||||
if dry_run and not bare:
|
||||
click.echo(apparent_bad_package)
|
||||
@@ -2654,9 +2755,8 @@ def do_clean(ctx, three=None, python=None, dry_run=False, bare=False, pypi_mirro
|
||||
)
|
||||
)
|
||||
# Uninstall the package.
|
||||
c = delegator.run(
|
||||
"{0} uninstall {1} -y".format(which_pip(), apparent_bad_package)
|
||||
)
|
||||
cmd_str = Script.parse(cmd + [apparent_bad_package]).cmdify()
|
||||
c = delegator.run(cmd_str, block=True)
|
||||
if c.return_code != 0:
|
||||
failure = True
|
||||
sys.exit(int(failure))
|
||||
|
||||
+76
-28
@@ -3,22 +3,25 @@
|
||||
import contextlib
|
||||
import importlib
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import operator
|
||||
import pkg_resources
|
||||
import os
|
||||
import site
|
||||
import six
|
||||
import sys
|
||||
|
||||
from distutils.sysconfig import get_python_lib
|
||||
from sysconfig import get_paths
|
||||
|
||||
from cached_property import cached_property
|
||||
import itertools
|
||||
import pkg_resources
|
||||
import six
|
||||
|
||||
import vistir
|
||||
import pipenv
|
||||
|
||||
from .utils import normalize_path
|
||||
from .vendor.cached_property import cached_property
|
||||
import vistir
|
||||
|
||||
from .utils import normalize_path, make_posix
|
||||
|
||||
|
||||
BASE_WORKING_SET = pkg_resources.WorkingSet(sys.path)
|
||||
|
||||
@@ -90,12 +93,16 @@ class Environment(object):
|
||||
deps |= cls.resolve_dist(dist, working_set)
|
||||
return deps
|
||||
|
||||
def add_dist(self, dist_name):
|
||||
dist = pkg_resources.get_distribution(pkg_resources.Requirement(dist_name))
|
||||
def extend_dists(self, dist):
|
||||
extras = self.resolve_dist(dist, self.base_working_set)
|
||||
self.extra_dists.append(dist)
|
||||
if extras:
|
||||
self.extra_dists.extend(extras)
|
||||
|
||||
def add_dist(self, dist_name):
|
||||
dist = pkg_resources.get_distribution(pkg_resources.Requirement(dist_name))
|
||||
self.extend_dists(dist)
|
||||
|
||||
@cached_property
|
||||
def python_version(self):
|
||||
with self.activated():
|
||||
@@ -143,7 +150,7 @@ class Environment(object):
|
||||
'stdlib': '/home/hawk/.pyenv/versions/3.7.1/lib/python3.7'}
|
||||
"""
|
||||
|
||||
prefix = self.prefix.as_posix()
|
||||
prefix = make_posix(self.prefix.as_posix())
|
||||
install_scheme = 'nt' if (os.name == 'nt') else 'posix_prefix'
|
||||
paths = get_paths(install_scheme, vars={
|
||||
'base': prefix,
|
||||
@@ -152,8 +159,8 @@ class Environment(object):
|
||||
paths["PATH"] = paths["scripts"] + os.pathsep + os.defpath
|
||||
if "prefix" not in paths:
|
||||
paths["prefix"] = prefix
|
||||
purelib = get_python_lib(plat_specific=0, prefix=prefix)
|
||||
platlib = get_python_lib(plat_specific=1, prefix=prefix)
|
||||
purelib = make_posix(get_python_lib(plat_specific=0, prefix=prefix))
|
||||
platlib = make_posix(get_python_lib(plat_specific=1, prefix=prefix))
|
||||
if purelib == platlib:
|
||||
lib_dirs = purelib
|
||||
else:
|
||||
@@ -161,7 +168,7 @@ class Environment(object):
|
||||
paths["libdir"] = purelib
|
||||
paths["purelib"] = purelib
|
||||
paths["platlib"] = platlib
|
||||
paths['PYTHONPATH'] = lib_dirs
|
||||
paths['PYTHONPATH'] = os.pathsep.join(["", ".", lib_dirs])
|
||||
paths["libdirs"] = lib_dirs
|
||||
return paths
|
||||
|
||||
@@ -174,19 +181,21 @@ class Environment(object):
|
||||
@property
|
||||
def python(self):
|
||||
"""Path to the environment python"""
|
||||
py = vistir.compat.Path(self.base_paths["scripts"]).joinpath("python").as_posix()
|
||||
py = vistir.compat.Path(self.base_paths["scripts"]).joinpath("python").absolute().as_posix()
|
||||
if not py:
|
||||
return vistir.compat.Path(sys.executable).as_posix()
|
||||
return py
|
||||
|
||||
@cached_property
|
||||
def sys_path(self):
|
||||
"""The system path inside the environment
|
||||
"""
|
||||
The system path inside the environment
|
||||
|
||||
:return: The :data:`sys.path` from the environment
|
||||
:rtype: list
|
||||
"""
|
||||
|
||||
from .vendor.vistir.compat import JSONDecodeError
|
||||
current_executable = vistir.compat.Path(sys.executable).as_posix()
|
||||
if not self.python or self.python == current_executable:
|
||||
return sys.path
|
||||
@@ -194,12 +203,16 @@ class Environment(object):
|
||||
return sys.path
|
||||
cmd_args = [self.python, "-c", "import json, sys; print(json.dumps(sys.path))"]
|
||||
path, _ = vistir.misc.run(cmd_args, return_object=False, nospin=True, block=True, combine_stderr=False, write_to_stdout=False)
|
||||
path = json.loads(path.strip())
|
||||
try:
|
||||
path = json.loads(path.strip())
|
||||
except JSONDecodeError:
|
||||
path = sys.path
|
||||
return path
|
||||
|
||||
@cached_property
|
||||
def sys_prefix(self):
|
||||
"""The prefix run inside the context of the environment
|
||||
"""
|
||||
The prefix run inside the context of the environment
|
||||
|
||||
:return: The python prefix inside the environment
|
||||
:rtype: :data:`sys.prefix`
|
||||
@@ -234,15 +247,33 @@ class Environment(object):
|
||||
return "purelib", purelib
|
||||
return "platlib", self.paths["platlib"]
|
||||
|
||||
@property
|
||||
def pip_version(self):
|
||||
"""
|
||||
Get the pip version in the environment. Useful for knowing which args we can use
|
||||
when installing.
|
||||
"""
|
||||
from .vendor.packaging.version import parse as parse_version
|
||||
pip = next(iter(
|
||||
pkg for pkg in self.get_installed_packages() if pkg.key == "pip"
|
||||
), None)
|
||||
if pip is not None:
|
||||
pip_version = parse_version(pip.version)
|
||||
return parse_version("18.0")
|
||||
|
||||
def get_distributions(self):
|
||||
"""Retrives the distributions installed on the library path of the environment
|
||||
"""
|
||||
Retrives the distributions installed on the library path of the environment
|
||||
|
||||
:return: A set of distributions found on the library path
|
||||
:rtype: iterator
|
||||
"""
|
||||
|
||||
pkg_resources = self.safe_import("pkg_resources")
|
||||
return pkg_resources.find_distributions(self.paths["PYTHONPATH"])
|
||||
libdirs = self.base_paths["libdirs"].split(os.pathsep)
|
||||
dists = (pkg_resources.find_distributions(libdir) for libdir in libdirs)
|
||||
for dist in itertools.chain.from_iterable(dists):
|
||||
yield dist
|
||||
|
||||
def find_egg(self, egg_dist):
|
||||
"""Find an egg by name in the given environment"""
|
||||
@@ -269,21 +300,28 @@ class Environment(object):
|
||||
def dist_is_in_project(self, dist):
|
||||
"""Determine whether the supplied distribution is in the environment."""
|
||||
from .project import _normalized
|
||||
prefix = _normalized(self.base_paths["prefix"])
|
||||
prefixes = [
|
||||
_normalized(prefix) for prefix in self.base_paths["libdirs"].split(os.pathsep)
|
||||
if _normalized(prefix).startswith(_normalized(self.prefix.as_posix()))
|
||||
]
|
||||
location = self.locate_dist(dist)
|
||||
if not location:
|
||||
return False
|
||||
return _normalized(location).startswith(prefix)
|
||||
location = _normalized(make_posix(location))
|
||||
return any(location.startswith(prefix) for prefix in prefixes)
|
||||
|
||||
def get_installed_packages(self):
|
||||
"""Returns all of the installed packages in a given environment"""
|
||||
workingset = self.get_working_set()
|
||||
packages = [pkg for pkg in workingset if self.dist_is_in_project(pkg)]
|
||||
packages = [
|
||||
pkg for pkg in workingset
|
||||
if self.dist_is_in_project(pkg) and pkg.key != "python"
|
||||
]
|
||||
return packages
|
||||
|
||||
@contextlib.contextmanager
|
||||
def get_finder(self, pre=False):
|
||||
from .vendor.pip_shims import Command, cmdoptions, index_group, PackageFinder
|
||||
from .vendor.pip_shims.shims import Command, cmdoptions, index_group, PackageFinder
|
||||
from .environments import PIPENV_CACHE_DIR
|
||||
index_urls = [source.get("url") for source in self.sources]
|
||||
|
||||
@@ -473,6 +511,7 @@ class Environment(object):
|
||||
vendor_dir = parent_path.joinpath("vendor").as_posix()
|
||||
patched_dir = parent_path.joinpath("patched").as_posix()
|
||||
parent_path = parent_path.as_posix()
|
||||
self.add_dist("pip")
|
||||
prefix = self.prefix.as_posix()
|
||||
with vistir.contextmanagers.temp_environ(), vistir.contextmanagers.temp_path():
|
||||
os.environ["PATH"] = os.pathsep.join([
|
||||
@@ -482,12 +521,24 @@ class Environment(object):
|
||||
])
|
||||
os.environ["PYTHONIOENCODING"] = vistir.compat.fs_str("utf-8")
|
||||
os.environ["PYTHONDONTWRITEBYTECODE"] = vistir.compat.fs_str("1")
|
||||
os.environ["PYTHONPATH"] = self.base_paths["PYTHONPATH"]
|
||||
from .environments import PIPENV_USE_SYSTEM
|
||||
if self.is_venv:
|
||||
os.environ["PYTHONPATH"] = self.base_paths["PYTHONPATH"]
|
||||
os.environ["VIRTUAL_ENV"] = vistir.compat.fs_str(prefix)
|
||||
else:
|
||||
if not PIPENV_USE_SYSTEM and not os.environ.get("VIRTUAL_ENV"):
|
||||
os.environ["PYTHONPATH"] = self.base_paths["PYTHONPATH"]
|
||||
os.environ.pop("PYTHONHOME", None)
|
||||
sys.path = self.sys_path
|
||||
sys.prefix = self.sys_prefix
|
||||
site.addsitedir(self.base_paths["purelib"])
|
||||
pip = self.safe_import("pip")
|
||||
pip_vendor = self.safe_import("pip._vendor")
|
||||
pep517_dir = os.path.join(os.path.dirname(pip_vendor.__file__), "pep517")
|
||||
site.addsitedir(pep517_dir)
|
||||
os.environ["PYTHONPATH"] = os.pathsep.join([
|
||||
os.environ.get("PYTHONPATH", self.base_paths["PYTHONPATH"]), pep517_dir
|
||||
])
|
||||
if include_extras:
|
||||
site.addsitedir(parent_path)
|
||||
sys.path.extend([parent_path, patched_dir, vendor_dir])
|
||||
@@ -591,10 +642,7 @@ class Environment(object):
|
||||
monkey_patch.activate()
|
||||
pip_shims = self.safe_import("pip_shims")
|
||||
pathset_base = pip_shims.UninstallPathSet
|
||||
import recursive_monkey_patch
|
||||
recursive_monkey_patch.monkey_patch(
|
||||
PatchedUninstaller, pathset_base
|
||||
)
|
||||
pathset_base._permitted = PatchedUninstaller._permitted
|
||||
dist = next(
|
||||
iter(filter(lambda d: d.project_name == pkgname, self.get_working_set())),
|
||||
None
|
||||
|
||||
+53
-15
@@ -2,15 +2,26 @@
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
from appdirs import user_cache_dir
|
||||
from .vendor.vistir.misc import fs_str
|
||||
|
||||
from ._compat import fix_utf8
|
||||
from .vendor.vistir.misc import fs_str
|
||||
|
||||
|
||||
# HACK: avoid resolver.py uses the wrong byte code files.
|
||||
# I hope I can remove this one day.
|
||||
os.environ["PYTHONDONTWRITEBYTECODE"] = fs_str("1")
|
||||
|
||||
|
||||
def _is_env_truthy(name):
|
||||
"""An environment variable is truthy if it exists and isn't one of (0, false, no, off)
|
||||
"""
|
||||
if name not in os.environ:
|
||||
return False
|
||||
return os.environ.get(name).lower() not in ("0", "false", "no", "off")
|
||||
|
||||
|
||||
PIPENV_IS_CI = bool("CI" in os.environ or "TF_BUILD" in os.environ)
|
||||
|
||||
# HACK: Prevent invalid shebangs with Homebrew-installed Python:
|
||||
@@ -68,13 +79,15 @@ Default is to detect emulators automatically. This should be set if your
|
||||
emulator, e.g. Cmder, cannot be detected correctly.
|
||||
"""
|
||||
|
||||
PIPENV_HIDE_EMOJIS = bool(os.environ.get("PIPENV_HIDE_EMOJIS"))
|
||||
PIPENV_HIDE_EMOJIS = (
|
||||
os.environ.get("PIPENV_HIDE_EMOJIS") is None
|
||||
and (os.name == "nt" or PIPENV_IS_CI)
|
||||
or _is_env_truthy("PIPENV_HIDE_EMOJIS")
|
||||
)
|
||||
"""Disable emojis in output.
|
||||
|
||||
Default is to show emojis. This is automatically set on Windows.
|
||||
"""
|
||||
if os.name == "nt" or PIPENV_IS_CI:
|
||||
PIPENV_HIDE_EMOJIS = True
|
||||
|
||||
PIPENV_IGNORE_VIRTUALENVS = bool(os.environ.get("PIPENV_IGNORE_VIRTUALENVS"))
|
||||
"""If set, Pipenv will always assign a virtual environment for this project.
|
||||
@@ -97,10 +110,9 @@ PIPENV_MAX_DEPTH = int(os.environ.get("PIPENV_MAX_DEPTH", "3")) + 1
|
||||
Default is 3. See also ``PIPENV_NO_INHERIT``.
|
||||
"""
|
||||
|
||||
PIPENV_MAX_RETRIES = int(os.environ.get(
|
||||
"PIPENV_MAX_RETRIES",
|
||||
"1" if PIPENV_IS_CI else "0",
|
||||
))
|
||||
PIPENV_MAX_RETRIES = int(
|
||||
os.environ.get("PIPENV_MAX_RETRIES", "1" if PIPENV_IS_CI else "0")
|
||||
)
|
||||
"""Specify how many retries Pipenv should attempt for network requests.
|
||||
|
||||
Default is 0. Automatically set to 1 on CI environments for robust testing.
|
||||
@@ -222,7 +234,9 @@ Default is to lock dependencies and update ``Pipfile.lock`` on each run.
|
||||
NOTE: This only affects the ``install`` and ``uninstall`` commands.
|
||||
"""
|
||||
|
||||
PIPENV_PYUP_API_KEY = os.environ.get("PIPENV_PYUP_API_KEY", "1ab8d58f-5122e025-83674263-bc1e79e0")
|
||||
PIPENV_PYUP_API_KEY = os.environ.get(
|
||||
"PIPENV_PYUP_API_KEY", "1ab8d58f-5122e025-83674263-bc1e79e0"
|
||||
)
|
||||
|
||||
# Internal, support running in a different Python from sys.executable.
|
||||
PIPENV_PYTHON = os.environ.get("PIPENV_PYTHON")
|
||||
@@ -243,9 +257,9 @@ PIPENV_SKIP_VALIDATION = True
|
||||
|
||||
# Internal, the default shell to use if shell detection fails.
|
||||
PIPENV_SHELL = (
|
||||
os.environ.get("SHELL") or
|
||||
os.environ.get("PYENV_SHELL") or
|
||||
os.environ.get("COMSPEC")
|
||||
os.environ.get("SHELL")
|
||||
or os.environ.get("PYENV_SHELL")
|
||||
or os.environ.get("COMSPEC")
|
||||
)
|
||||
|
||||
# Internal, to tell whether the command line session is interactive.
|
||||
@@ -277,11 +291,35 @@ def is_quiet(threshold=-1):
|
||||
|
||||
|
||||
def is_in_virtualenv():
|
||||
pipenv_active = os.environ.get("PIPENV_ACTIVE")
|
||||
virtual_env = os.environ.get("VIRTUAL_ENV")
|
||||
return (PIPENV_USE_SYSTEM or virtual_env) and not pipenv_active
|
||||
"""
|
||||
Check virtualenv membership dynamically
|
||||
|
||||
:return: True or false depending on whether we are in a regular virtualenv or not
|
||||
:rtype: bool
|
||||
"""
|
||||
|
||||
pipenv_active = os.environ.get("PIPENV_ACTIVE", False)
|
||||
virtual_env = None
|
||||
use_system = False
|
||||
ignore_virtualenvs = bool(os.environ.get("PIPENV_IGNORE_VIRTUALENVS", False))
|
||||
|
||||
if not pipenv_active and not ignore_virtualenvs:
|
||||
virtual_env = os.environ.get("VIRTUAL_ENV")
|
||||
use_system = bool(virtual_env)
|
||||
return (use_system or virtual_env) and not (pipenv_active or ignore_virtualenvs)
|
||||
|
||||
|
||||
PIPENV_SPINNER_FAIL_TEXT = fix_utf8(u"✘ {0}") if not PIPENV_HIDE_EMOJIS else ("{0}")
|
||||
|
||||
PIPENV_SPINNER_OK_TEXT = fix_utf8(u"✔ {0}") if not PIPENV_HIDE_EMOJIS else ("{0}")
|
||||
|
||||
|
||||
def is_type_checking():
|
||||
try:
|
||||
from typing import TYPE_CHECKING
|
||||
except ImportError:
|
||||
return False
|
||||
return TYPE_CHECKING
|
||||
|
||||
|
||||
MYPY_RUNNING = is_type_checking()
|
||||
|
||||
+20
-19
@@ -3,27 +3,21 @@
|
||||
import itertools
|
||||
import sys
|
||||
|
||||
from traceback import format_exception
|
||||
from pprint import pformat
|
||||
from traceback import format_exception, format_tb
|
||||
|
||||
import six
|
||||
|
||||
from . import environments
|
||||
from ._compat import fix_utf8
|
||||
from .patched import crayons
|
||||
from . import environments
|
||||
from .vendor.click.utils import echo as click_echo
|
||||
from .vendor.click._compat import get_text_stderr
|
||||
from .vendor.click.exceptions import (
|
||||
Abort,
|
||||
BadOptionUsage,
|
||||
BadParameter,
|
||||
ClickException,
|
||||
Exit,
|
||||
FileError,
|
||||
MissingParameter,
|
||||
UsageError,
|
||||
Abort, BadOptionUsage, BadParameter, ClickException, Exit, FileError,
|
||||
MissingParameter, UsageError
|
||||
)
|
||||
from .vendor.click.types import Path
|
||||
from .vendor.click.utils import echo as click_echo
|
||||
|
||||
|
||||
def handle_exception(exc_type, exception, traceback, hook=sys.excepthook):
|
||||
@@ -31,8 +25,8 @@ def handle_exception(exc_type, exception, traceback, hook=sys.excepthook):
|
||||
hook(exc_type, exception, traceback)
|
||||
else:
|
||||
exc = format_exception(exc_type, exception, traceback)
|
||||
lines = itertools.chain.from_iterable([l.splitlines() for l in exc])
|
||||
lines = list(lines)[-11:-1]
|
||||
tb = format_tb(traceback, limit=-6)
|
||||
lines = itertools.chain.from_iterable([frame.splitlines() for frame in tb])
|
||||
for line in lines:
|
||||
line = line.strip("'").strip('"').strip("\n").strip()
|
||||
if not line.startswith("File"):
|
||||
@@ -165,7 +159,7 @@ class DeployException(PipenvUsageError):
|
||||
if not message:
|
||||
message = crayons.normal("Aborting deploy", bold=True)
|
||||
extra = kwargs.pop("extra", [])
|
||||
PipenvUsageError.__init__(message=fix_utf8(message), extra=extra, **kwargs)
|
||||
PipenvUsageError.__init__(self, message=fix_utf8(message), extra=extra, **kwargs)
|
||||
|
||||
|
||||
class PipenvOptionsError(PipenvUsageError):
|
||||
@@ -185,7 +179,8 @@ class SystemUsageError(PipenvOptionsError):
|
||||
crayons.red("Warning", bold=True)
|
||||
),
|
||||
]
|
||||
message = crayons.blue("See also: {0}".format(crayons.white("-deploy flag.")))
|
||||
if message is None:
|
||||
message = crayons.blue("See also: {0}".format(crayons.white("--deploy flag.")))
|
||||
super(SystemUsageError, self).__init__(option_name, message=message, ctx=ctx, extra=extra, **kwargs)
|
||||
|
||||
|
||||
@@ -241,11 +236,11 @@ class UninstallError(PipenvException):
|
||||
crayons.yellow("$ {0}".format(command), bold=True)
|
||||
)),]
|
||||
extra.extend([crayons.blue(line.strip()) for line in return_values.splitlines()])
|
||||
if isinstance(package, (tuple, list)):
|
||||
if isinstance(package, (tuple, list, set)):
|
||||
package = " ".join(package)
|
||||
message = "{0} {1}...".format(
|
||||
message = "{0!s} {1!s}...".format(
|
||||
crayons.normal("Failed to uninstall package(s)"),
|
||||
crayons.yellow(package, bold=True)
|
||||
crayons.yellow(str(package), bold=True)
|
||||
)
|
||||
self.exit_code = return_code
|
||||
PipenvException.__init__(self, message=fix_utf8(message), extra=extra)
|
||||
@@ -254,8 +249,14 @@ class UninstallError(PipenvException):
|
||||
|
||||
class InstallError(PipenvException):
|
||||
def __init__(self, package, **kwargs):
|
||||
message = "{0} {1}".format(
|
||||
package_message = ""
|
||||
if package is not None:
|
||||
package_message = crayons.normal("Couldn't install package {0}\n".format(
|
||||
crayons.white(package, bold=True)
|
||||
))
|
||||
message = "{0} {1} {2}".format(
|
||||
crayons.red("ERROR:", bold=True),
|
||||
package_message,
|
||||
crayons.yellow("Package installation failed...")
|
||||
)
|
||||
extra = kwargs.pop("extra", [])
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
|
||||
__author__ = """pyup.io"""
|
||||
__email__ = 'support@pyup.io'
|
||||
__version__ = '1.8.4'
|
||||
__version__ = '1.8.5'
|
||||
|
||||
@@ -6,17 +6,13 @@ from safety import __version__
|
||||
from safety import safety
|
||||
from safety.formatter import report
|
||||
import itertools
|
||||
from safety.util import read_requirements
|
||||
from safety.util import read_requirements, read_vulnerabilities
|
||||
from safety.errors import DatabaseFetchError, DatabaseFileNotFoundError, InvalidKeyError
|
||||
|
||||
|
||||
try:
|
||||
# pip 9
|
||||
from pipenv.patched.notpip import get_installed_distributions
|
||||
from json.decoder import JSONDecodeError
|
||||
except ImportError:
|
||||
# pip 10
|
||||
from pipenv.patched.notpip._internal.utils.misc import get_installed_distributions
|
||||
|
||||
JSONDecodeError = ValueError
|
||||
|
||||
@click.group()
|
||||
@click.version_option(version=__version__)
|
||||
@@ -46,10 +42,17 @@ def cli():
|
||||
help="Read input from one (or multiple) requirement files. Default: empty")
|
||||
@click.option("ignore", "--ignore", "-i", multiple=True, type=str, default=[],
|
||||
help="Ignore one (or multiple) vulnerabilities by ID. Default: empty")
|
||||
def check(key, db, json, full_report, bare, stdin, files, cache, ignore):
|
||||
|
||||
@click.option("--output", "-o", default="",
|
||||
help="Path to where output file will be placed. Default: empty")
|
||||
@click.option("proxyhost", "--proxy-host", "-ph", multiple=False, type=str, default=None,
|
||||
help="Proxy host IP or DNS --proxy-host")
|
||||
@click.option("proxyport", "--proxy-port", "-pp", multiple=False, type=int, default=80,
|
||||
help="Proxy port number --proxy-port")
|
||||
@click.option("proxyprotocol", "--proxy-protocol", "-pr", multiple=False, type=str, default='http',
|
||||
help="Proxy protocol (https or http) --proxy-protocol")
|
||||
def check(key, db, json, full_report, bare, stdin, files, cache, ignore, output, proxyprotocol, proxyhost, proxyport):
|
||||
if files and stdin:
|
||||
click.secho("Can't read from --stdin and --file at the same time, exiting", fg="red")
|
||||
click.secho("Can't read from --stdin and --file at the same time, exiting", fg="red", file=sys.stderr)
|
||||
sys.exit(-1)
|
||||
|
||||
if files:
|
||||
@@ -57,33 +60,72 @@ def check(key, db, json, full_report, bare, stdin, files, cache, ignore):
|
||||
elif stdin:
|
||||
packages = list(read_requirements(sys.stdin))
|
||||
else:
|
||||
packages = get_installed_distributions()
|
||||
|
||||
import pkg_resources
|
||||
packages = [
|
||||
d for d in pkg_resources.working_set
|
||||
if d.key not in {"python", "wsgiref", "argparse"}
|
||||
]
|
||||
proxy_dictionary = {}
|
||||
if proxyhost is not None:
|
||||
if proxyprotocol in ["http", "https"]:
|
||||
proxy_dictionary = {proxyprotocol: "{0}://{1}:{2}".format(proxyprotocol, proxyhost, str(proxyport))}
|
||||
else:
|
||||
click.secho("Proxy Protocol should be http or https only.", fg="red")
|
||||
sys.exit(-1)
|
||||
try:
|
||||
vulns = safety.check(packages=packages, key=key, db_mirror=db, cached=cache, ignore_ids=ignore)
|
||||
click.secho(report(
|
||||
vulns=vulns,
|
||||
full=full_report,
|
||||
json_report=json,
|
||||
bare_report=bare,
|
||||
checked_packages=len(packages),
|
||||
db=db,
|
||||
key=key
|
||||
)
|
||||
)
|
||||
vulns = safety.check(packages=packages, key=key, db_mirror=db, cached=cache, ignore_ids=ignore, proxy=proxy_dictionary)
|
||||
output_report = report(vulns=vulns,
|
||||
full=full_report,
|
||||
json_report=json,
|
||||
bare_report=bare,
|
||||
checked_packages=len(packages),
|
||||
db=db,
|
||||
key=key)
|
||||
|
||||
if output:
|
||||
with open(output, 'w+') as output_file:
|
||||
output_file.write(output_report)
|
||||
else:
|
||||
click.secho(output_report, nl=False if bare and not vulns else True)
|
||||
sys.exit(-1 if vulns else 0)
|
||||
except InvalidKeyError:
|
||||
click.secho("Your API Key '{key}' is invalid. See {link}".format(
|
||||
key=key, link='https://goo.gl/O7Y1rS'),
|
||||
fg="red")
|
||||
fg="red",
|
||||
file=sys.stderr)
|
||||
sys.exit(-1)
|
||||
except DatabaseFileNotFoundError:
|
||||
click.secho("Unable to load vulnerability database from {db}".format(db=db), fg="red")
|
||||
click.secho("Unable to load vulnerability database from {db}".format(db=db), fg="red", file=sys.stderr)
|
||||
sys.exit(-1)
|
||||
except DatabaseFetchError:
|
||||
click.secho("Unable to load vulnerability database", fg="red")
|
||||
click.secho("Unable to load vulnerability database", fg="red", file=sys.stderr)
|
||||
sys.exit(-1)
|
||||
|
||||
|
||||
@cli.command()
|
||||
@click.option("--full-report/--short-report", default=False,
|
||||
help='Full reports include a security advisory (if available). Default: '
|
||||
'--short-report')
|
||||
@click.option("--bare/--not-bare", default=False,
|
||||
help='Output vulnerable packages only. Useful in combination with other tools.'
|
||||
'Default: --not-bare')
|
||||
@click.option("file", "--file", "-f", type=click.File(), required=True,
|
||||
help="Read input from an insecure report file. Default: empty")
|
||||
def review(full_report, bare, file):
|
||||
if full_report and bare:
|
||||
click.secho("Can't choose both --bare and --full-report/--short-report", fg="red")
|
||||
sys.exit(-1)
|
||||
|
||||
try:
|
||||
input_vulns = read_vulnerabilities(file)
|
||||
except JSONDecodeError:
|
||||
click.secho("Not a valid JSON file", fg="red")
|
||||
sys.exit(-1)
|
||||
|
||||
vulns = safety.review(input_vulns)
|
||||
output_report = report(vulns=vulns, full=full_report, bare_report=bare)
|
||||
click.secho(output_report, nl=False if bare and not vulns else True)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
cli()
|
||||
|
||||
@@ -3,6 +3,7 @@ import platform
|
||||
import sys
|
||||
import json
|
||||
import os
|
||||
import textwrap
|
||||
|
||||
# python 2.7 compat
|
||||
try:
|
||||
@@ -110,9 +111,10 @@ class SheetReport(object):
|
||||
|
||||
descr = get_advisory(vuln)
|
||||
|
||||
for chunk in [descr[i:i + 76] for i in range(0, len(descr), 76)]:
|
||||
|
||||
for line in chunk.splitlines():
|
||||
for pn, paragraph in enumerate(descr.replace('\r', '').split('\n\n')):
|
||||
if pn:
|
||||
table.append("│ {:76} │".format(''))
|
||||
for line in textwrap.wrap(paragraph, width=76):
|
||||
try:
|
||||
table.append("│ {:76} │".format(line.encode('utf-8')))
|
||||
except TypeError:
|
||||
|
||||
@@ -9,6 +9,7 @@ import json
|
||||
import time
|
||||
import errno
|
||||
|
||||
|
||||
class Vulnerability(namedtuple("Vulnerability",
|
||||
["name", "spec", "version", "advisory", "vuln_id"])):
|
||||
pass
|
||||
@@ -64,7 +65,7 @@ def write_to_cache(db_name, data):
|
||||
f.write(json.dumps(cache))
|
||||
|
||||
|
||||
def fetch_database_url(mirror, db_name, key, cached):
|
||||
def fetch_database_url(mirror, db_name, key, cached, proxy):
|
||||
|
||||
headers = {}
|
||||
if key:
|
||||
@@ -74,9 +75,8 @@ def fetch_database_url(mirror, db_name, key, cached):
|
||||
cached_data = get_from_cache(db_name=db_name)
|
||||
if cached_data:
|
||||
return cached_data
|
||||
|
||||
url = mirror + db_name
|
||||
r = requests.get(url=url, timeout=REQUEST_TIMEOUT, headers=headers)
|
||||
r = requests.get(url=url, timeout=REQUEST_TIMEOUT, headers=headers, proxies=proxy)
|
||||
if r.status_code == 200:
|
||||
data = r.json()
|
||||
if cached:
|
||||
@@ -94,7 +94,7 @@ def fetch_database_file(path, db_name):
|
||||
return json.loads(f.read())
|
||||
|
||||
|
||||
def fetch_database(full=False, key=False, db=False, cached=False):
|
||||
def fetch_database(full=False, key=False, db=False, cached=False, proxy={}):
|
||||
|
||||
if db:
|
||||
mirrors = [db]
|
||||
@@ -105,7 +105,7 @@ def fetch_database(full=False, key=False, db=False, cached=False):
|
||||
for mirror in mirrors:
|
||||
# mirror can either be a local path or a URL
|
||||
if mirror.startswith("http://") or mirror.startswith("https://"):
|
||||
data = fetch_database_url(mirror, db_name=db_name, key=key, cached=cached)
|
||||
data = fetch_database_url(mirror, db_name=db_name, key=key, cached=cached, proxy=proxy)
|
||||
else:
|
||||
data = fetch_database_file(mirror, db_name=db_name)
|
||||
if data:
|
||||
@@ -120,10 +120,9 @@ def get_vulnerabilities(pkg, spec, db):
|
||||
yield entry
|
||||
|
||||
|
||||
def check(packages, key, db_mirror, cached, ignore_ids):
|
||||
|
||||
def check(packages, key, db_mirror, cached, ignore_ids, proxy):
|
||||
key = key if key else os.environ.get("SAFETY_API_KEY", False)
|
||||
db = fetch_database(key=key, db=db_mirror, cached=cached)
|
||||
db = fetch_database(key=key, db=db_mirror, cached=cached, proxy=proxy)
|
||||
db_full = None
|
||||
vulnerable_packages = frozenset(db.keys())
|
||||
vulnerable = []
|
||||
@@ -152,3 +151,19 @@ def check(packages, key, db_mirror, cached, ignore_ids):
|
||||
)
|
||||
)
|
||||
return vulnerable
|
||||
|
||||
|
||||
def review(vulnerabilities):
|
||||
vulnerable = []
|
||||
for vuln in vulnerabilities:
|
||||
current_vuln = {
|
||||
"name": vuln[0],
|
||||
"spec": vuln[1],
|
||||
"version": vuln[2],
|
||||
"advisory": vuln[3],
|
||||
"vuln_id": vuln[4],
|
||||
}
|
||||
vulnerable.append(
|
||||
Vulnerability(**current_vuln)
|
||||
)
|
||||
return vulnerable
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
from dparse.parser import setuptools_parse_requirements_backport as _parse_requirements
|
||||
from collections import namedtuple
|
||||
import click
|
||||
import sys
|
||||
import json
|
||||
import os
|
||||
Package = namedtuple("Package", ["key", "version"])
|
||||
RequirementFile = namedtuple("RequirementFile", ["path"])
|
||||
|
||||
|
||||
def read_vulnerabilities(fh):
|
||||
return json.load(fh)
|
||||
|
||||
|
||||
def iter_lines(fh, lineno=0):
|
||||
for line in fh.readlines()[lineno:]:
|
||||
yield line
|
||||
@@ -85,7 +91,8 @@ def read_requirements(fh, resolve=False):
|
||||
"Warning: unpinned requirement '{req}' found in {fname}, "
|
||||
"unable to check.".format(req=req.name,
|
||||
fname=fname),
|
||||
fg="yellow"
|
||||
fg="yellow",
|
||||
file=sys.stderr
|
||||
)
|
||||
except ValueError:
|
||||
continue
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import sys
|
||||
import json
|
||||
import os
|
||||
import platform
|
||||
import json
|
||||
import sys
|
||||
|
||||
|
||||
def format_full_version(info):
|
||||
|
||||
+15
-17
@@ -12,31 +12,29 @@ from __future__ import absolute_import
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
import crayons
|
||||
|
||||
from .environments import PIPENV_COLORBLIND, PIPENV_HIDE_EMOJIS
|
||||
|
||||
|
||||
STREAM = sys.stderr
|
||||
MILL_TEMPLATE = "%s %s %i/%i\r"
|
||||
DOTS_CHAR = "."
|
||||
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("-"))
|
||||
if PIPENV_HIDE_EMOJIS:
|
||||
if PIPENV_COLORBLIND:
|
||||
BAR_FILLED_CHAR = "="
|
||||
BAR_EMPTY_CHAR = "-"
|
||||
else:
|
||||
if PIPENV_COLORBLIND:
|
||||
BAR_FILLED_CHAR = "▉"
|
||||
BAR_EMPTY_CHAR = " "
|
||||
else:
|
||||
BAR_FILLED_CHAR = str(crayons.green("▉", bold=True))
|
||||
BAR_EMPTY_CHAR = str(crayons.black("▉"))
|
||||
|
||||
BAR_FILLED_CHAR = str(crayons.green("=", bold=True))
|
||||
BAR_EMPTY_CHAR = str(crayons.black("-"))
|
||||
else:
|
||||
BAR_FILLED_CHAR = "="
|
||||
BAR_EMPTY_CHAR = "-"
|
||||
if PIPENV_COLORBLIND:
|
||||
BAR_FILLED_CHAR = "▉"
|
||||
BAR_EMPTY_CHAR = " "
|
||||
else:
|
||||
BAR_FILLED_CHAR = str(crayons.green("▉", bold=True))
|
||||
BAR_EMPTY_CHAR = str(crayons.black("▉"))
|
||||
|
||||
if (sys.version_info[0] >= 3) and (os.name != "nt"):
|
||||
BAR_TEMPLATE = u" %s%s%s %i/%i — {0}\r".format(crayons.black("%s"))
|
||||
|
||||
+87
-81
@@ -1,54 +1,42 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import base64
|
||||
import fnmatch
|
||||
import glob
|
||||
import hashlib
|
||||
import io
|
||||
import json
|
||||
import operator
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import glob
|
||||
import base64
|
||||
import fnmatch
|
||||
import hashlib
|
||||
from first import first
|
||||
from cached_property import cached_property
|
||||
import operator
|
||||
import pipfile
|
||||
import pipfile.api
|
||||
|
||||
import six
|
||||
import vistir
|
||||
import toml
|
||||
import tomlkit
|
||||
import vistir
|
||||
|
||||
from first import first
|
||||
|
||||
import pipfile
|
||||
import pipfile.api
|
||||
|
||||
from .vendor.cached_property import cached_property
|
||||
|
||||
from .environment import Environment
|
||||
from .cmdparse import Script
|
||||
from .utils import (
|
||||
pep423_name,
|
||||
proper_case,
|
||||
find_requirements,
|
||||
is_editable,
|
||||
cleanup_toml,
|
||||
convert_toml_outline_tables,
|
||||
is_installable_file,
|
||||
is_valid_url,
|
||||
get_url_name,
|
||||
normalize_drive,
|
||||
python_version,
|
||||
safe_expandvars,
|
||||
is_star,
|
||||
get_workon_home,
|
||||
is_virtual_environment,
|
||||
looks_like_dir,
|
||||
get_canonical_names
|
||||
)
|
||||
from .environment import Environment
|
||||
from .environments import (
|
||||
PIPENV_MAX_DEPTH,
|
||||
PIPENV_PIPFILE,
|
||||
PIPENV_VENV_IN_PROJECT,
|
||||
PIPENV_TEST_INDEX,
|
||||
PIPENV_PYTHON,
|
||||
PIPENV_DEFAULT_PYTHON_VERSION,
|
||||
PIPENV_IGNORE_VIRTUALENVS,
|
||||
PIPENV_DEFAULT_PYTHON_VERSION, PIPENV_IGNORE_VIRTUALENVS, PIPENV_MAX_DEPTH,
|
||||
PIPENV_PIPFILE, PIPENV_PYTHON, PIPENV_TEST_INDEX, PIPENV_VENV_IN_PROJECT,
|
||||
is_in_virtualenv
|
||||
)
|
||||
from .vendor.requirementslib.models.utils import get_default_pyproject_backend
|
||||
from .utils import (
|
||||
cleanup_toml, convert_toml_outline_tables, find_requirements,
|
||||
get_canonical_names, get_url_name, get_workon_home, is_editable,
|
||||
is_installable_file, is_star, is_valid_url, is_virtual_environment,
|
||||
looks_like_dir, normalize_drive, pep423_name, proper_case, python_version,
|
||||
safe_expandvars, get_pipenv_dist
|
||||
)
|
||||
|
||||
|
||||
def _normalized(p):
|
||||
@@ -111,6 +99,9 @@ if PIPENV_PIPFILE:
|
||||
|
||||
else:
|
||||
PIPENV_PIPFILE = _normalized(PIPENV_PIPFILE)
|
||||
# Overwrite environment variable so that subprocesses can get the correct path.
|
||||
# See https://github.com/pypa/pipenv/issues/3584
|
||||
os.environ['PIPENV_PIPFILE'] = PIPENV_PIPFILE
|
||||
# (path, file contents) => TOMLFile
|
||||
# keeps track of pipfiles that we've seen so we do not need to re-parse 'em
|
||||
_pipfile_cache = {}
|
||||
@@ -353,7 +344,11 @@ class Project(object):
|
||||
prefix=prefix, is_venv=is_venv, sources=sources, pipfile=self.parsed_pipfile,
|
||||
project=self
|
||||
)
|
||||
self._environment.add_dist("pipenv")
|
||||
pipenv_dist = get_pipenv_dist(pkg="pipenv")
|
||||
if pipenv_dist:
|
||||
self._environment.extend_dists(pipenv_dist)
|
||||
else:
|
||||
self._environment.add_dist("pipenv")
|
||||
return self._environment
|
||||
|
||||
def get_outdated_packages(self):
|
||||
@@ -538,18 +533,19 @@ class Project(object):
|
||||
if not os.path.exists(self.path_to("setup.py")):
|
||||
if not build_system or not build_system.get("requires"):
|
||||
build_system = {
|
||||
"requires": ["setuptools>=38.2.5", "wheel"],
|
||||
"build-backend": "setuptools.build_meta",
|
||||
"requires": ["setuptools>=40.8.0", "wheel"],
|
||||
"build-backend": get_default_pyproject_backend(),
|
||||
}
|
||||
self._build_system = build_system
|
||||
|
||||
@property
|
||||
def build_requires(self):
|
||||
return self._build_system.get("requires", [])
|
||||
return self._build_system.get("requires", ["setuptools>=40.8.0", "wheel"])
|
||||
|
||||
|
||||
@property
|
||||
def build_backend(self):
|
||||
return self._build_system.get("build-backend", None)
|
||||
return self._build_system.get("build-backend", get_default_pyproject_backend())
|
||||
|
||||
@property
|
||||
def settings(self):
|
||||
@@ -616,10 +612,8 @@ class Project(object):
|
||||
|
||||
def _get_editable_packages(self, dev=False):
|
||||
section = "dev-packages" if dev else "packages"
|
||||
# section = "{0}-editable".format(section)
|
||||
packages = {
|
||||
k: v
|
||||
# for k, v in self._pipfile[section].items()
|
||||
for k, v in self.parsed_pipfile.get(section, {}).items()
|
||||
if is_editable(k) or is_editable(v)
|
||||
}
|
||||
@@ -628,10 +622,8 @@ class Project(object):
|
||||
def _get_vcs_packages(self, dev=False):
|
||||
from pipenv.vendor.requirementslib.utils import is_vcs
|
||||
section = "dev-packages" if dev else "packages"
|
||||
# section = "{0}-vcs".format(section)
|
||||
packages = {
|
||||
k: v
|
||||
# for k, v in self._pipfile[section].items()
|
||||
for k, v in self.parsed_pipfile.get(section, {}).items()
|
||||
if is_vcs(v) or is_vcs(k)
|
||||
}
|
||||
@@ -693,7 +685,8 @@ class Project(object):
|
||||
ConfigOptionParser, make_option_group, index_group
|
||||
)
|
||||
|
||||
config_parser = ConfigOptionParser(name=self.name)
|
||||
name = self.name if self.name is not None else "Pipfile"
|
||||
config_parser = ConfigOptionParser(name=name)
|
||||
config_parser.add_option_group(make_option_group(index_group, config_parser))
|
||||
install = config_parser.option_groups[0]
|
||||
indexes = (
|
||||
@@ -742,10 +735,19 @@ class Project(object):
|
||||
source["verify_ssl"] = source["verify_ssl"].lower() == "true"
|
||||
return source
|
||||
|
||||
def get_or_create_lockfile(self):
|
||||
def get_or_create_lockfile(self, from_pipfile=False):
|
||||
from pipenv.vendor.requirementslib.models.lockfile import Lockfile as Req_Lockfile
|
||||
lockfile = None
|
||||
if self.lockfile_exists:
|
||||
if from_pipfile and self.pipfile_exists:
|
||||
lockfile_dict = {
|
||||
"default": self._lockfile["default"].copy(),
|
||||
"develop": self._lockfile["develop"].copy()
|
||||
}
|
||||
lockfile_dict.update({"_meta": self.get_lockfile_meta()})
|
||||
lockfile = Req_Lockfile.from_data(
|
||||
path=self.lockfile_location, data=lockfile_dict, meta_from_project=False
|
||||
)
|
||||
elif self.lockfile_exists:
|
||||
try:
|
||||
lockfile = Req_Lockfile.load(self.lockfile_location)
|
||||
except OSError:
|
||||
@@ -769,29 +771,21 @@ class Project(object):
|
||||
)
|
||||
lockfile._lockfile = lockfile.projectfile.model = _created_lockfile
|
||||
return lockfile
|
||||
elif self.pipfile_exists:
|
||||
lockfile_dict = {
|
||||
"default": self._lockfile["default"].copy(),
|
||||
"develop": self._lockfile["develop"].copy()
|
||||
}
|
||||
lockfile_dict.update({"_meta": self.get_lockfile_meta()})
|
||||
_created_lockfile = Req_Lockfile.from_data(
|
||||
path=self.lockfile_location, data=lockfile_dict, meta_from_project=False
|
||||
)
|
||||
lockfile._lockfile = _created_lockfile
|
||||
return lockfile
|
||||
else:
|
||||
return self.get_or_create_lockfile(from_pipfile=True)
|
||||
|
||||
def get_lockfile_meta(self):
|
||||
from .vendor.plette.lockfiles import PIPFILE_SPEC_CURRENT
|
||||
sources = self.lockfile_content.get("_meta", {}).get("sources", [])
|
||||
if not sources:
|
||||
sources = self.pipfile_sources
|
||||
elif not isinstance(sources, list):
|
||||
if self.lockfile_exists:
|
||||
sources = self.lockfile_content.get("_meta", {}).get("sources", [])
|
||||
else:
|
||||
sources = [dict(source) for source in self.parsed_pipfile["source"]]
|
||||
if not isinstance(sources, list):
|
||||
sources = [sources,]
|
||||
return {
|
||||
"hash": {"sha256": self.calculate_pipfile_hash()},
|
||||
"pipfile-spec": PIPFILE_SPEC_CURRENT,
|
||||
"sources": sources,
|
||||
"sources": [self.populate_source(s) for s in sources],
|
||||
"requires": self.parsed_pipfile.get("requires", {})
|
||||
}
|
||||
|
||||
@@ -867,7 +861,8 @@ class Project(object):
|
||||
return self.pipfile_sources
|
||||
|
||||
def find_source(self, source):
|
||||
"""given a source, find it.
|
||||
"""
|
||||
Given a source, find it.
|
||||
|
||||
source can be a url or an index name.
|
||||
"""
|
||||
@@ -880,23 +875,34 @@ class Project(object):
|
||||
source = self.get_source(url=source)
|
||||
return source
|
||||
|
||||
def get_source(self, name=None, url=None):
|
||||
def get_source(self, name=None, url=None, refresh=False):
|
||||
from .utils import is_url_equal
|
||||
|
||||
def find_source(sources, name=None, url=None):
|
||||
source = None
|
||||
if name:
|
||||
source = [s for s in sources if s.get("name") == name]
|
||||
source = next(iter(
|
||||
s for s in sources if "name" in s and s["name"] == name
|
||||
), None)
|
||||
elif url:
|
||||
source = [s for s in sources if url.startswith(s.get("url"))]
|
||||
if source:
|
||||
return first(source)
|
||||
source = next(iter(
|
||||
s for s in sources
|
||||
if "url" in s and is_url_equal(url, s.get("url", ""))
|
||||
), None)
|
||||
if source is not None:
|
||||
return source
|
||||
|
||||
found_source = find_source(self.sources, name=name, url=url)
|
||||
if found_source:
|
||||
return found_source
|
||||
found_source = find_source(self.pipfile_sources, name=name, url=url)
|
||||
if found_source:
|
||||
return found_source
|
||||
raise SourceNotFound(name or url)
|
||||
sources = (self.sources, self.pipfile_sources)
|
||||
if refresh:
|
||||
self.clear_pipfile_cache()
|
||||
sources = reversed(sources)
|
||||
found = next(
|
||||
iter(find_source(source, name=name, url=url) for source in sources), None
|
||||
)
|
||||
target = next(iter(t for t in (name, url) if t is not None))
|
||||
if found is None:
|
||||
raise SourceNotFound(target)
|
||||
return found
|
||||
|
||||
def get_package_name_in_pipfile(self, package_name, dev=False):
|
||||
"""Get the equivalent package name in pipfile"""
|
||||
@@ -941,17 +947,17 @@ class Project(object):
|
||||
# Don't re-capitalize file URLs or VCSs.
|
||||
if not isinstance(package, Requirement):
|
||||
package = Requirement.from_line(package.strip())
|
||||
_, converted = package.pipfile_entry
|
||||
req_name, converted = package.pipfile_entry
|
||||
key = "dev-packages" if dev else "packages"
|
||||
# Set empty group if it doesn't exist yet.
|
||||
if key not in p:
|
||||
p[key] = {}
|
||||
name = self.get_package_name_in_pipfile(package.name, dev)
|
||||
name = self.get_package_name_in_pipfile(req_name, dev)
|
||||
if name and is_star(converted):
|
||||
# Skip for wildcard version
|
||||
return
|
||||
# Add the package to the group.
|
||||
p[key][name or package.normalized_name] = converted
|
||||
p[key][name or pep423_name(req_name)] = converted
|
||||
# Write Pipfile.
|
||||
self.write_toml(p)
|
||||
|
||||
|
||||
+1
-2
@@ -1,9 +1,8 @@
|
||||
import operator
|
||||
import re
|
||||
|
||||
from .vendor import attr, delegator
|
||||
|
||||
from .environments import PIPENV_INSTALL_TIMEOUT
|
||||
from .vendor import attr, delegator
|
||||
|
||||
|
||||
@attr.s
|
||||
|
||||
+117
-43
@@ -1,17 +1,54 @@
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
os.environ["PIP_PYTHON_PATH"] = str(sys.executable)
|
||||
|
||||
|
||||
def _patch_path():
|
||||
def find_site_path(pkg, site_dir=None):
|
||||
import pkg_resources
|
||||
if site_dir is not None:
|
||||
site_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
working_set = pkg_resources.WorkingSet([site_dir] + sys.path[:])
|
||||
for dist in working_set:
|
||||
root = dist.location
|
||||
base_name = dist.project_name if dist.project_name else dist.key
|
||||
name = None
|
||||
if "top_level.txt" in dist.metadata_listdir(""):
|
||||
name = next(iter([l.strip() for l in dist.get_metadata_lines("top_level.txt") if l is not None]), None)
|
||||
if name is None:
|
||||
name = pkg_resources.safe_name(base_name).replace("-", "_")
|
||||
if not any(pkg == _ for _ in [base_name, name]):
|
||||
continue
|
||||
path_options = [name, "{0}.py".format(name)]
|
||||
path_options = [os.path.join(root, p) for p in path_options if p is not None]
|
||||
path = next(iter(p for p in path_options if os.path.exists(p)), None)
|
||||
if path is not None:
|
||||
return (dist, path)
|
||||
return (None, None)
|
||||
|
||||
|
||||
def _patch_path(pipenv_site=None):
|
||||
import site
|
||||
pipenv_libdir = os.path.dirname(os.path.abspath(__file__))
|
||||
pipenv_site_dir = os.path.dirname(pipenv_libdir)
|
||||
site.addsitedir(pipenv_site_dir)
|
||||
for _dir in ("vendor", "patched"):
|
||||
pipenv_dist = None
|
||||
if pipenv_site is not None:
|
||||
pipenv_dist, pipenv_path = find_site_path("pipenv", site_dir=pipenv_site)
|
||||
else:
|
||||
pipenv_dist, pipenv_path = find_site_path("pipenv", site_dir=pipenv_site_dir)
|
||||
if pipenv_dist is not None:
|
||||
pipenv_dist.activate()
|
||||
else:
|
||||
site.addsitedir(next(iter(
|
||||
sitedir for sitedir in (pipenv_site, pipenv_site_dir)
|
||||
if sitedir is not None
|
||||
), None))
|
||||
if pipenv_path is not None:
|
||||
pipenv_libdir = pipenv_path
|
||||
for _dir in ("vendor", "patched", pipenv_libdir):
|
||||
sys.path.insert(0, os.path.join(pipenv_libdir, _dir))
|
||||
|
||||
|
||||
@@ -23,8 +60,11 @@ def get_parser():
|
||||
parser.add_argument("--verbose", "-v", action="count", default=False)
|
||||
parser.add_argument("--debug", action="store_true", default=False)
|
||||
parser.add_argument("--system", action="store_true", default=False)
|
||||
parser.add_argument("--parse-only", action="store_true", default=False)
|
||||
parser.add_argument("--pipenv-site", metavar="pipenv_site_dir", action="store",
|
||||
default=os.environ.get("PIPENV_SITE_DIR"))
|
||||
parser.add_argument("--requirements-dir", metavar="requirements_dir", action="store",
|
||||
default=os.environ.get("PIPENV_REQ_DIR"))
|
||||
default=os.environ.get("PIPENV_REQ_DIR"))
|
||||
parser.add_argument("packages", nargs="*")
|
||||
return parser
|
||||
|
||||
@@ -40,22 +80,53 @@ def handle_parsed_args(parsed):
|
||||
logging.getLogger("notpip").setLevel(logging.DEBUG)
|
||||
elif parsed.verbose > 0:
|
||||
logging.getLogger("notpip").setLevel(logging.INFO)
|
||||
os.environ["PIPENV_VERBOSITY"] = str(parsed.verbose)
|
||||
if "PIPENV_PACKAGES" in os.environ:
|
||||
parsed.packages += os.environ.get("PIPENV_PACKAGES", "").strip().split("\n")
|
||||
return parsed
|
||||
|
||||
|
||||
def _main(pre, clear, verbose, system, requirements_dir, packages):
|
||||
os.environ["PIP_PYTHON_VERSION"] = ".".join([str(s) for s in sys.version_info[:3]])
|
||||
os.environ["PIP_PYTHON_PATH"] = str(sys.executable)
|
||||
def parse_packages(packages, pre, clear, system, requirements_dir=None):
|
||||
from pipenv.vendor.requirementslib.models.requirements import Requirement
|
||||
from pipenv.vendor.vistir.contextmanagers import cd, temp_path
|
||||
from pipenv.utils import parse_indexes
|
||||
parsed_packages = []
|
||||
for package in packages:
|
||||
indexes, trusted_hosts, line = parse_indexes(package)
|
||||
line = " ".join(line)
|
||||
pf = dict()
|
||||
req = Requirement.from_line(line)
|
||||
if not req.name:
|
||||
with temp_path(), cd(req.req.setup_info.base_dir):
|
||||
sys.path.insert(0, req.req.setup_info.base_dir)
|
||||
req.req._setup_info.get_info()
|
||||
req.update_name_from_path(req.req.setup_info.base_dir)
|
||||
print(os.listdir(req.req.setup_info.base_dir))
|
||||
try:
|
||||
name, entry = req.pipfile_entry
|
||||
except Exception:
|
||||
continue
|
||||
else:
|
||||
if name is not None and entry is not None:
|
||||
pf[name] = entry
|
||||
parsed_packages.append(pf)
|
||||
print("RESULTS:")
|
||||
if parsed_packages:
|
||||
print(json.dumps(parsed_packages))
|
||||
else:
|
||||
print(json.dumps([]))
|
||||
|
||||
|
||||
def resolve_packages(pre, clear, verbose, system, requirements_dir, packages):
|
||||
from pipenv.utils import create_mirror_source, resolve_deps, replace_pypi_sources
|
||||
|
||||
pypi_mirror_source = (
|
||||
create_mirror_source(os.environ["PIPENV_PYPI_MIRROR"])
|
||||
if "PIPENV_PYPI_MIRROR" in os.environ
|
||||
else None
|
||||
)
|
||||
# os.environ["PIP_NO_BUILD_ISOLATION"] = "1"
|
||||
# os.environ["PIP_NO_USE_PEP517"] = "1"
|
||||
# os.environ["PIP_NO_DEPS"] = "1"
|
||||
|
||||
def resolve(packages, pre, project, sources, clear, system, requirements_dir=None):
|
||||
return resolve_deps(
|
||||
@@ -75,15 +146,8 @@ def _main(pre, clear, verbose, system, requirements_dir, packages):
|
||||
if pypi_mirror_source
|
||||
else project.pipfile_sources
|
||||
)
|
||||
results = resolve(
|
||||
packages,
|
||||
pre=pre,
|
||||
project=project,
|
||||
sources=sources,
|
||||
clear=clear,
|
||||
system=system,
|
||||
requirements_dir=requirements_dir,
|
||||
)
|
||||
results = resolve(packages, pre=pre, project=project, sources=sources, clear=clear,
|
||||
system=system, requirements_dir=requirements_dir)
|
||||
print("RESULTS:")
|
||||
if results:
|
||||
print(json.dumps(results))
|
||||
@@ -91,36 +155,46 @@ def _main(pre, clear, verbose, system, requirements_dir, packages):
|
||||
print(json.dumps([]))
|
||||
|
||||
|
||||
def main():
|
||||
_patch_path()
|
||||
import warnings
|
||||
from pipenv.vendor.vistir.compat import ResourceWarning
|
||||
warnings.simplefilter("ignore", category=ResourceWarning)
|
||||
import io
|
||||
import six
|
||||
if six.PY3:
|
||||
import atexit
|
||||
stdout_wrapper = io.TextIOWrapper(sys.stdout.buffer, encoding='utf8')
|
||||
atexit.register(stdout_wrapper.close)
|
||||
stderr_wrapper = io.TextIOWrapper(sys.stderr.buffer, encoding='utf8')
|
||||
atexit.register(stderr_wrapper.close)
|
||||
sys.stdout = stdout_wrapper
|
||||
sys.stderr = stderr_wrapper
|
||||
def _main(pre, clear, verbose, system, requirements_dir, packages, parse_only=False):
|
||||
os.environ["PIP_PYTHON_VERSION"] = ".".join([str(s) for s in sys.version_info[:3]])
|
||||
os.environ["PIP_PYTHON_PATH"] = str(sys.executable)
|
||||
if parse_only:
|
||||
parse_packages(
|
||||
packages,
|
||||
pre=pre,
|
||||
clear=clear,
|
||||
system=system,
|
||||
requirements_dir=requirements_dir,
|
||||
)
|
||||
else:
|
||||
from pipenv._compat import force_encoding
|
||||
force_encoding()
|
||||
os.environ["PIP_DISABLE_PIP_VERSION_CHECK"] = str("1")
|
||||
os.environ["PYTHONIOENCODING"] = str("utf-8")
|
||||
resolve_packages(pre, clear, verbose, system, requirements_dir, packages)
|
||||
|
||||
|
||||
def main():
|
||||
parser = get_parser()
|
||||
parsed, remaining = parser.parse_known_args()
|
||||
# sys.argv = remaining
|
||||
_patch_path(pipenv_site=parsed.pipenv_site)
|
||||
import warnings
|
||||
from pipenv.vendor.vistir.compat import ResourceWarning
|
||||
from pipenv.vendor.vistir.misc import get_wrapped_stream
|
||||
warnings.simplefilter("ignore", category=ResourceWarning)
|
||||
import six
|
||||
if six.PY3:
|
||||
stdout = sys.stdout.buffer
|
||||
stderr = sys.stderr.buffer
|
||||
else:
|
||||
stdout = sys.stdout
|
||||
stderr = sys.stderr
|
||||
sys.stderr = get_wrapped_stream(stderr)
|
||||
sys.stdout = get_wrapped_stream(stdout)
|
||||
from pipenv.vendor import colorama
|
||||
colorama.init()
|
||||
os.environ["PIP_DISABLE_PIP_VERSION_CHECK"] = str("1")
|
||||
os.environ["PYTHONIOENCODING"] = str("utf-8")
|
||||
parsed = handle_parsed_args(parsed)
|
||||
_main(parsed.pre, parsed.clear, parsed.verbose, parsed.system,
|
||||
parsed.requirements_dir, parsed.packages)
|
||||
parsed.requirements_dir, parsed.packages, parse_only=parsed.parse_only)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
_patch_path()
|
||||
from pipenv.vendor import colorama
|
||||
colorama.init()
|
||||
main()
|
||||
|
||||
+3
-3
@@ -5,10 +5,10 @@ import signal
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from .environments import PIPENV_SHELL_EXPLICIT, PIPENV_SHELL, PIPENV_EMULATOR
|
||||
from .vendor.vistir.compat import get_terminal_size, Path
|
||||
from .vendor.vistir.contextmanagers import temp_environ
|
||||
from .environments import PIPENV_EMULATOR, PIPENV_SHELL, PIPENV_SHELL_EXPLICIT
|
||||
from .vendor import shellingham
|
||||
from .vendor.vistir.compat import Path, get_terminal_size
|
||||
from .vendor.vistir.contextmanagers import temp_environ
|
||||
|
||||
|
||||
ShellDetectionFailure = shellingham.ShellDetectionFailure
|
||||
|
||||
+638
-258
File diff suppressed because it is too large
Load Diff
Vendored
+1
-1
@@ -18,7 +18,7 @@ from ._make import (
|
||||
)
|
||||
|
||||
|
||||
__version__ = "18.2.0"
|
||||
__version__ = "19.1.0"
|
||||
|
||||
__title__ = "attrs"
|
||||
__description__ = "Classes Without Boilerplate"
|
||||
|
||||
Vendored
+15
-12
@@ -23,9 +23,9 @@ from . import validators as validators
|
||||
_T = TypeVar("_T")
|
||||
_C = TypeVar("_C", bound=type)
|
||||
|
||||
_ValidatorType = Callable[[Any, Attribute, _T], Any]
|
||||
_ValidatorType = Callable[[Any, Attribute[_T], _T], Any]
|
||||
_ConverterType = Callable[[Any], _T]
|
||||
_FilterType = Callable[[Attribute, Any], bool]
|
||||
_FilterType = Callable[[Attribute[_T], _T], bool]
|
||||
# FIXME: in reality, if multiple validators are passed they must be in a list or tuple,
|
||||
# but those are invariant and so would prevent subtypes of _ValidatorType from working
|
||||
# when passed in a list or tuple.
|
||||
@@ -57,10 +57,10 @@ class Attribute(Generic[_T]):
|
||||
metadata: Dict[Any, Any]
|
||||
type: Optional[Type[_T]]
|
||||
kw_only: bool
|
||||
def __lt__(self, x: Attribute) -> bool: ...
|
||||
def __le__(self, x: Attribute) -> bool: ...
|
||||
def __gt__(self, x: Attribute) -> bool: ...
|
||||
def __ge__(self, x: Attribute) -> bool: ...
|
||||
def __lt__(self, x: Attribute[_T]) -> bool: ...
|
||||
def __le__(self, x: Attribute[_T]) -> bool: ...
|
||||
def __gt__(self, x: Attribute[_T]) -> bool: ...
|
||||
def __ge__(self, x: Attribute[_T]) -> bool: ...
|
||||
|
||||
# NOTE: We had several choices for the annotation to use for type arg:
|
||||
# 1) Type[_T]
|
||||
@@ -167,6 +167,7 @@ def attrs(
|
||||
auto_attribs: bool = ...,
|
||||
kw_only: bool = ...,
|
||||
cache_hash: bool = ...,
|
||||
auto_exc: bool = ...,
|
||||
) -> _C: ...
|
||||
@overload
|
||||
def attrs(
|
||||
@@ -184,14 +185,15 @@ def attrs(
|
||||
auto_attribs: bool = ...,
|
||||
kw_only: bool = ...,
|
||||
cache_hash: bool = ...,
|
||||
auto_exc: bool = ...,
|
||||
) -> Callable[[_C], _C]: ...
|
||||
|
||||
# TODO: add support for returning NamedTuple from the mypy plugin
|
||||
class _Fields(Tuple[Attribute, ...]):
|
||||
def __getattr__(self, name: str) -> Attribute: ...
|
||||
class _Fields(Tuple[Attribute[Any], ...]):
|
||||
def __getattr__(self, name: str) -> Attribute[Any]: ...
|
||||
|
||||
def fields(cls: type) -> _Fields: ...
|
||||
def fields_dict(cls: type) -> Dict[str, Attribute]: ...
|
||||
def fields_dict(cls: type) -> Dict[str, Attribute[Any]]: ...
|
||||
def validate(inst: Any) -> None: ...
|
||||
|
||||
# TODO: add support for returning a proper attrs class from the mypy plugin
|
||||
@@ -212,6 +214,7 @@ def make_class(
|
||||
auto_attribs: bool = ...,
|
||||
kw_only: bool = ...,
|
||||
cache_hash: bool = ...,
|
||||
auto_exc: bool = ...,
|
||||
) -> type: ...
|
||||
|
||||
# _funcs --
|
||||
@@ -223,7 +226,7 @@ def make_class(
|
||||
def asdict(
|
||||
inst: Any,
|
||||
recurse: bool = ...,
|
||||
filter: Optional[_FilterType] = ...,
|
||||
filter: Optional[_FilterType[Any]] = ...,
|
||||
dict_factory: Type[Mapping[Any, Any]] = ...,
|
||||
retain_collection_types: bool = ...,
|
||||
) -> Dict[str, Any]: ...
|
||||
@@ -232,8 +235,8 @@ def asdict(
|
||||
def astuple(
|
||||
inst: Any,
|
||||
recurse: bool = ...,
|
||||
filter: Optional[_FilterType] = ...,
|
||||
tuple_factory: Type[Sequence] = ...,
|
||||
filter: Optional[_FilterType[Any]] = ...,
|
||||
tuple_factory: Type[Sequence[Any]] = ...,
|
||||
retain_collection_types: bool = ...,
|
||||
) -> Tuple[Any, ...]: ...
|
||||
def has(cls: type) -> bool: ...
|
||||
|
||||
Vendored
+21
-25
@@ -20,6 +20,7 @@ else:
|
||||
|
||||
if PY2:
|
||||
from UserDict import IterableUserDict
|
||||
from collections import Mapping, Sequence # noqa
|
||||
|
||||
# We 'bundle' isclass instead of using inspect as importing inspect is
|
||||
# fairly expensive (order of 10-15 ms for a modern machine in 2016)
|
||||
@@ -89,8 +90,27 @@ if PY2:
|
||||
res.data.update(d) # We blocked update, so we have to do it like this.
|
||||
return res
|
||||
|
||||
def just_warn(*args, **kw): # pragma: nocover
|
||||
"""
|
||||
We only warn on Python 3 because we are not aware of any concrete
|
||||
consequences of not setting the cell on Python 2.
|
||||
"""
|
||||
|
||||
else:
|
||||
|
||||
else: # Python 3 and later.
|
||||
from collections.abc import Mapping, Sequence # noqa
|
||||
|
||||
def just_warn(*args, **kw):
|
||||
"""
|
||||
We only warn on Python 3 because we are not aware of any concrete
|
||||
consequences of not setting the cell on Python 2.
|
||||
"""
|
||||
warnings.warn(
|
||||
"Missing ctypes. Some features like bare super() or accessing "
|
||||
"__class__ will not work with slotted classes.",
|
||||
RuntimeWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
|
||||
def isclass(klass):
|
||||
return isinstance(klass, type)
|
||||
@@ -113,30 +133,6 @@ def import_ctypes():
|
||||
return ctypes
|
||||
|
||||
|
||||
if not PY2:
|
||||
|
||||
def just_warn(*args, **kw):
|
||||
"""
|
||||
We only warn on Python 3 because we are not aware of any concrete
|
||||
consequences of not setting the cell on Python 2.
|
||||
"""
|
||||
warnings.warn(
|
||||
"Missing ctypes. Some features like bare super() or accessing "
|
||||
"__class__ will not work with slots classes.",
|
||||
RuntimeWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
|
||||
|
||||
else:
|
||||
|
||||
def just_warn(*args, **kw): # pragma: nocover
|
||||
"""
|
||||
We only warn on Python 3 because we are not aware of any concrete
|
||||
consequences of not setting the cell on Python 2.
|
||||
"""
|
||||
|
||||
|
||||
def make_set_closure_cell():
|
||||
"""
|
||||
Moved into a function for testability.
|
||||
|
||||
Vendored
+79
-27
@@ -409,12 +409,11 @@ def _transform_attrs(cls, these, auto_attribs, kw_only):
|
||||
a.kw_only is False
|
||||
):
|
||||
had_default = True
|
||||
if was_kw_only is True and a.kw_only is False:
|
||||
if was_kw_only is True and a.kw_only is False and a.init is True:
|
||||
raise ValueError(
|
||||
"Non keyword-only attributes are not allowed after a "
|
||||
"keyword-only attribute. Attribute in question: {a!r}".format(
|
||||
a=a
|
||||
)
|
||||
"keyword-only attribute (unless they are init=False). "
|
||||
"Attribute in question: {a!r}".format(a=a)
|
||||
)
|
||||
if was_kw_only is False and a.init is True and a.kw_only is True:
|
||||
was_kw_only = True
|
||||
@@ -454,6 +453,7 @@ class _ClassBuilder(object):
|
||||
"_has_post_init",
|
||||
"_delete_attribs",
|
||||
"_base_attr_map",
|
||||
"_is_exc",
|
||||
)
|
||||
|
||||
def __init__(
|
||||
@@ -466,6 +466,7 @@ class _ClassBuilder(object):
|
||||
auto_attribs,
|
||||
kw_only,
|
||||
cache_hash,
|
||||
is_exc,
|
||||
):
|
||||
attrs, base_attrs, base_map = _transform_attrs(
|
||||
cls, these, auto_attribs, kw_only
|
||||
@@ -483,6 +484,7 @@ class _ClassBuilder(object):
|
||||
self._cache_hash = cache_hash
|
||||
self._has_post_init = bool(getattr(cls, "__attrs_post_init__", False))
|
||||
self._delete_attribs = not bool(these)
|
||||
self._is_exc = is_exc
|
||||
|
||||
self._cls_dict["__attrs_attrs__"] = self._attrs
|
||||
|
||||
@@ -530,6 +532,26 @@ class _ClassBuilder(object):
|
||||
for name, value in self._cls_dict.items():
|
||||
setattr(cls, name, value)
|
||||
|
||||
# Attach __setstate__. This is necessary to clear the hash code
|
||||
# cache on deserialization. See issue
|
||||
# https://github.com/python-attrs/attrs/issues/482 .
|
||||
# Note that this code only handles setstate for dict classes.
|
||||
# For slotted classes, see similar code in _create_slots_class .
|
||||
if self._cache_hash:
|
||||
existing_set_state_method = getattr(cls, "__setstate__", None)
|
||||
if existing_set_state_method:
|
||||
raise NotImplementedError(
|
||||
"Currently you cannot use hash caching if "
|
||||
"you specify your own __setstate__ method."
|
||||
"See https://github.com/python-attrs/attrs/issues/494 ."
|
||||
)
|
||||
|
||||
def cache_hash_set_state(chss_self, _):
|
||||
# clear hash code cache
|
||||
setattr(chss_self, _hash_cache_field, None)
|
||||
|
||||
setattr(cls, "__setstate__", cache_hash_set_state)
|
||||
|
||||
return cls
|
||||
|
||||
def _create_slots_class(self):
|
||||
@@ -582,6 +604,8 @@ class _ClassBuilder(object):
|
||||
"""
|
||||
return tuple(getattr(self, name) for name in state_attr_names)
|
||||
|
||||
hash_caching_enabled = self._cache_hash
|
||||
|
||||
def slots_setstate(self, state):
|
||||
"""
|
||||
Automatically created by attrs.
|
||||
@@ -589,6 +613,13 @@ class _ClassBuilder(object):
|
||||
__bound_setattr = _obj_setattr.__get__(self, Attribute)
|
||||
for name, value in zip(state_attr_names, state):
|
||||
__bound_setattr(name, value)
|
||||
# Clearing the hash code cache on deserialization is needed
|
||||
# because hash codes can change from run to run. See issue
|
||||
# https://github.com/python-attrs/attrs/issues/482 .
|
||||
# Note that this code only handles setstate for slotted classes.
|
||||
# For dict classes, see similar code in _patch_original_class .
|
||||
if hash_caching_enabled:
|
||||
__bound_setattr(_hash_cache_field, None)
|
||||
|
||||
# slots and frozen require __getstate__/__setstate__ to work
|
||||
cd["__getstate__"] = slots_getstate
|
||||
@@ -660,6 +691,7 @@ class _ClassBuilder(object):
|
||||
self._slots,
|
||||
self._cache_hash,
|
||||
self._base_attr_map,
|
||||
self._is_exc,
|
||||
)
|
||||
)
|
||||
|
||||
@@ -710,6 +742,7 @@ def attrs(
|
||||
auto_attribs=False,
|
||||
kw_only=False,
|
||||
cache_hash=False,
|
||||
auto_exc=False,
|
||||
):
|
||||
r"""
|
||||
A class decorator that adds `dunder
|
||||
@@ -815,10 +848,23 @@ def attrs(
|
||||
:param bool cache_hash: Ensure that the object's hash code is computed
|
||||
only once and stored on the object. If this is set to ``True``,
|
||||
hashing must be either explicitly or implicitly enabled for this
|
||||
class. If the hash code is cached, then no attributes of this
|
||||
class which participate in hash code computation may be mutated
|
||||
after object creation.
|
||||
class. If the hash code is cached, avoid any reassignments of
|
||||
fields involved in hash code computation or mutations of the objects
|
||||
those fields point to after object creation. If such changes occur,
|
||||
the behavior of the object's hash code is undefined.
|
||||
:param bool auto_exc: If the class subclasses :class:`BaseException`
|
||||
(which implicitly includes any subclass of any exception), the
|
||||
following happens to behave like a well-behaved Python exceptions
|
||||
class:
|
||||
|
||||
- the values for *cmp* and *hash* are ignored and the instances compare
|
||||
and hash by the instance's ids (N.B. ``attrs`` will *not* remove
|
||||
existing implementations of ``__hash__`` or the equality methods. It
|
||||
just won't add own ones.),
|
||||
- all attributes that are either passed into ``__init__`` or have a
|
||||
default value are additionally available as a tuple in the ``args``
|
||||
attribute,
|
||||
- the value of *str* is ignored leaving ``__str__`` to base classes.
|
||||
|
||||
.. versionadded:: 16.0.0 *slots*
|
||||
.. versionadded:: 16.1.0 *frozen*
|
||||
@@ -838,12 +884,16 @@ def attrs(
|
||||
to each other.
|
||||
.. versionadded:: 18.2.0 *kw_only*
|
||||
.. versionadded:: 18.2.0 *cache_hash*
|
||||
.. versionadded:: 19.1.0 *auto_exc*
|
||||
"""
|
||||
|
||||
def wrap(cls):
|
||||
|
||||
if getattr(cls, "__class__", None) is None:
|
||||
raise TypeError("attrs only works with new-style classes.")
|
||||
|
||||
is_exc = auto_exc is True and issubclass(cls, BaseException)
|
||||
|
||||
builder = _ClassBuilder(
|
||||
cls,
|
||||
these,
|
||||
@@ -853,13 +903,14 @@ def attrs(
|
||||
auto_attribs,
|
||||
kw_only,
|
||||
cache_hash,
|
||||
is_exc,
|
||||
)
|
||||
|
||||
if repr is True:
|
||||
builder.add_repr(repr_ns)
|
||||
if str is True:
|
||||
builder.add_str()
|
||||
if cmp is True:
|
||||
if cmp is True and not is_exc:
|
||||
builder.add_cmp()
|
||||
|
||||
if hash is not True and hash is not False and hash is not None:
|
||||
@@ -874,7 +925,11 @@ def attrs(
|
||||
" hashing must be either explicitly or implicitly "
|
||||
"enabled."
|
||||
)
|
||||
elif hash is True or (hash is None and cmp is True and frozen is True):
|
||||
elif (
|
||||
hash is True
|
||||
or (hash is None and cmp is True and frozen is True)
|
||||
and is_exc is False
|
||||
):
|
||||
builder.add_hash()
|
||||
else:
|
||||
if cache_hash:
|
||||
@@ -1213,7 +1268,9 @@ def _add_repr(cls, ns=None, attrs=None):
|
||||
return cls
|
||||
|
||||
|
||||
def _make_init(attrs, post_init, frozen, slots, cache_hash, base_attr_map):
|
||||
def _make_init(
|
||||
attrs, post_init, frozen, slots, cache_hash, base_attr_map, is_exc
|
||||
):
|
||||
attrs = [a for a in attrs if a.init or a.default is not NOTHING]
|
||||
|
||||
# We cache the generated init methods for the same kinds of attributes.
|
||||
@@ -1222,16 +1279,18 @@ def _make_init(attrs, post_init, frozen, slots, cache_hash, base_attr_map):
|
||||
unique_filename = "<attrs generated init {0}>".format(sha1.hexdigest())
|
||||
|
||||
script, globs, annotations = _attrs_to_init_script(
|
||||
attrs, frozen, slots, post_init, cache_hash, base_attr_map
|
||||
attrs, frozen, slots, post_init, cache_hash, base_attr_map, is_exc
|
||||
)
|
||||
locs = {}
|
||||
bytecode = compile(script, unique_filename, "exec")
|
||||
attr_dict = dict((a.name, a) for a in attrs)
|
||||
globs.update({"NOTHING": NOTHING, "attr_dict": attr_dict})
|
||||
|
||||
if frozen is True:
|
||||
# Save the lookup overhead in __init__ if we need to circumvent
|
||||
# immutability.
|
||||
globs["_cached_setattr"] = _obj_setattr
|
||||
|
||||
eval(bytecode, globs, locs)
|
||||
|
||||
# In order of debuggers like PDB being able to step through the code,
|
||||
@@ -1245,24 +1304,10 @@ def _make_init(attrs, post_init, frozen, slots, cache_hash, base_attr_map):
|
||||
|
||||
__init__ = locs["__init__"]
|
||||
__init__.__annotations__ = annotations
|
||||
|
||||
return __init__
|
||||
|
||||
|
||||
def _add_init(cls, frozen):
|
||||
"""
|
||||
Add a __init__ method to *cls*. If *frozen* is True, make it immutable.
|
||||
"""
|
||||
cls.__init__ = _make_init(
|
||||
cls.__attrs_attrs__,
|
||||
getattr(cls, "__attrs_post_init__", False),
|
||||
frozen,
|
||||
_is_slot_cls(cls),
|
||||
cache_hash=False,
|
||||
base_attr_map={},
|
||||
)
|
||||
return cls
|
||||
|
||||
|
||||
def fields(cls):
|
||||
"""
|
||||
Return the tuple of ``attrs`` attributes for a class.
|
||||
@@ -1348,7 +1393,7 @@ def _is_slot_attr(a_name, base_attr_map):
|
||||
|
||||
|
||||
def _attrs_to_init_script(
|
||||
attrs, frozen, slots, post_init, cache_hash, base_attr_map
|
||||
attrs, frozen, slots, post_init, cache_hash, base_attr_map, is_exc
|
||||
):
|
||||
"""
|
||||
Return a script of an initializer for *attrs* and a dict of globals.
|
||||
@@ -1597,6 +1642,13 @@ def _attrs_to_init_script(
|
||||
init_hash_cache = "self.%s = %s"
|
||||
lines.append(init_hash_cache % (_hash_cache_field, "None"))
|
||||
|
||||
# For exceptions we rely on BaseException.__init__ for proper
|
||||
# initialization.
|
||||
if is_exc:
|
||||
vals = ",".join("self." + a.name for a in attrs if a.init)
|
||||
|
||||
lines.append("BaseException.__init__(self, %s)" % (vals,))
|
||||
|
||||
args = ", ".join(args)
|
||||
if kw_only_args:
|
||||
if PY2:
|
||||
|
||||
Vendored
+3
-3
@@ -1,5 +1,5 @@
|
||||
from typing import Union
|
||||
from typing import Union, Any
|
||||
from . import Attribute, _FilterType
|
||||
|
||||
def include(*what: Union[type, Attribute]) -> _FilterType: ...
|
||||
def exclude(*what: Union[type, Attribute]) -> _FilterType: ...
|
||||
def include(*what: Union[type, Attribute[Any]]) -> _FilterType[Any]: ...
|
||||
def exclude(*what: Union[type, Attribute[Any]]) -> _FilterType[Any]: ...
|
||||
|
||||
Vendored
+113
-1
@@ -136,7 +136,7 @@ class _InValidator(object):
|
||||
def __call__(self, inst, attr, value):
|
||||
try:
|
||||
in_options = value in self.options
|
||||
except TypeError as e: # e.g. `1 in "abc"`
|
||||
except TypeError: # e.g. `1 in "abc"`
|
||||
in_options = False
|
||||
|
||||
if not in_options:
|
||||
@@ -168,3 +168,115 @@ def in_(options):
|
||||
.. versionadded:: 17.1.0
|
||||
"""
|
||||
return _InValidator(options)
|
||||
|
||||
|
||||
@attrs(repr=False, slots=False, hash=True)
|
||||
class _IsCallableValidator(object):
|
||||
def __call__(self, inst, attr, value):
|
||||
"""
|
||||
We use a callable class to be able to change the ``__repr__``.
|
||||
"""
|
||||
if not callable(value):
|
||||
raise TypeError("'{name}' must be callable".format(name=attr.name))
|
||||
|
||||
def __repr__(self):
|
||||
return "<is_callable validator>"
|
||||
|
||||
|
||||
def is_callable():
|
||||
"""
|
||||
A validator that raises a :class:`TypeError` if the initializer is called
|
||||
with a value for this particular attribute that is not callable.
|
||||
|
||||
.. versionadded:: 19.1.0
|
||||
|
||||
:raises TypeError: With a human readable error message containing the
|
||||
attribute (of type :class:`attr.Attribute`) name.
|
||||
"""
|
||||
return _IsCallableValidator()
|
||||
|
||||
|
||||
@attrs(repr=False, slots=True, hash=True)
|
||||
class _DeepIterable(object):
|
||||
member_validator = attrib(validator=is_callable())
|
||||
iterable_validator = attrib(
|
||||
default=None, validator=optional(is_callable())
|
||||
)
|
||||
|
||||
def __call__(self, inst, attr, value):
|
||||
"""
|
||||
We use a callable class to be able to change the ``__repr__``.
|
||||
"""
|
||||
if self.iterable_validator is not None:
|
||||
self.iterable_validator(inst, attr, value)
|
||||
|
||||
for member in value:
|
||||
self.member_validator(inst, attr, member)
|
||||
|
||||
def __repr__(self):
|
||||
iterable_identifier = (
|
||||
""
|
||||
if self.iterable_validator is None
|
||||
else " {iterable!r}".format(iterable=self.iterable_validator)
|
||||
)
|
||||
return (
|
||||
"<deep_iterable validator for{iterable_identifier}"
|
||||
" iterables of {member!r}>"
|
||||
).format(
|
||||
iterable_identifier=iterable_identifier,
|
||||
member=self.member_validator,
|
||||
)
|
||||
|
||||
|
||||
def deep_iterable(member_validator, iterable_validator=None):
|
||||
"""
|
||||
A validator that performs deep validation of an iterable.
|
||||
|
||||
:param member_validator: Validator to apply to iterable members
|
||||
:param iterable_validator: Validator to apply to iterable itself
|
||||
(optional)
|
||||
|
||||
.. versionadded:: 19.1.0
|
||||
|
||||
:raises TypeError: if any sub-validators fail
|
||||
"""
|
||||
return _DeepIterable(member_validator, iterable_validator)
|
||||
|
||||
|
||||
@attrs(repr=False, slots=True, hash=True)
|
||||
class _DeepMapping(object):
|
||||
key_validator = attrib(validator=is_callable())
|
||||
value_validator = attrib(validator=is_callable())
|
||||
mapping_validator = attrib(default=None, validator=optional(is_callable()))
|
||||
|
||||
def __call__(self, inst, attr, value):
|
||||
"""
|
||||
We use a callable class to be able to change the ``__repr__``.
|
||||
"""
|
||||
if self.mapping_validator is not None:
|
||||
self.mapping_validator(inst, attr, value)
|
||||
|
||||
for key in value:
|
||||
self.key_validator(inst, attr, key)
|
||||
self.value_validator(inst, attr, value[key])
|
||||
|
||||
def __repr__(self):
|
||||
return (
|
||||
"<deep_mapping validator for objects mapping {key!r} to {value!r}>"
|
||||
).format(key=self.key_validator, value=self.value_validator)
|
||||
|
||||
|
||||
def deep_mapping(key_validator, value_validator, mapping_validator=None):
|
||||
"""
|
||||
A validator that performs deep validation of a dictionary.
|
||||
|
||||
:param key_validator: Validator to apply to dictionary keys
|
||||
:param value_validator: Validator to apply to dictionary values
|
||||
:param mapping_validator: Validator to apply to top-level mapping
|
||||
attribute (optional)
|
||||
|
||||
.. versionadded:: 19.1.0
|
||||
|
||||
:raises TypeError: if any sub-validators fail
|
||||
"""
|
||||
return _DeepMapping(key_validator, value_validator, mapping_validator)
|
||||
|
||||
Vendored
+10
@@ -12,3 +12,13 @@ def optional(
|
||||
) -> _ValidatorType[Optional[_T]]: ...
|
||||
def in_(options: Container[_T]) -> _ValidatorType[_T]: ...
|
||||
def and_(*validators: _ValidatorType[_T]) -> _ValidatorType[_T]: ...
|
||||
def deep_iterable(
|
||||
member_validator: _ValidatorType[_T],
|
||||
iterable_validator: Optional[_ValidatorType[_T]],
|
||||
) -> _ValidatorType[_T]: ...
|
||||
def deep_mapping(
|
||||
key_validator: _ValidatorType[_T],
|
||||
value_validator: _ValidatorType[_T],
|
||||
mapping_validator: Optional[_ValidatorType[_T]],
|
||||
) -> _ValidatorType[_T]: ...
|
||||
def is_callable() -> _ValidatorType[_T]: ...
|
||||
|
||||
Vendored
+1
-1
@@ -2,7 +2,7 @@
|
||||
|
||||
__author__ = "Daniel Greenfeld"
|
||||
__email__ = "pydanny@gmail.com"
|
||||
__version__ = "1.4.3"
|
||||
__version__ = "1.5.1"
|
||||
__license__ = "BSD"
|
||||
|
||||
from time import time
|
||||
|
||||
Vendored
+2
-2
@@ -1,3 +1,3 @@
|
||||
from .core import where, old_where
|
||||
from .core import where
|
||||
|
||||
__version__ = "2018.10.15"
|
||||
__version__ = "2018.11.29"
|
||||
|
||||
Vendored
+242
@@ -4268,3 +4268,245 @@ rYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0EAwMDaAAwZQIwJsdpW9zV
|
||||
57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtkAjEA2zQg
|
||||
Mgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
# Issuer: CN=GTS Root R1 O=Google Trust Services LLC
|
||||
# Subject: CN=GTS Root R1 O=Google Trust Services LLC
|
||||
# Label: "GTS Root R1"
|
||||
# Serial: 146587175971765017618439757810265552097
|
||||
# MD5 Fingerprint: 82:1a:ef:d4:d2:4a:f2:9f:e2:3d:97:06:14:70:72:85
|
||||
# SHA1 Fingerprint: e1:c9:50:e6:ef:22:f8:4c:56:45:72:8b:92:20:60:d7:d5:a7:a3:e8
|
||||
# SHA256 Fingerprint: 2a:57:54:71:e3:13:40:bc:21:58:1c:bd:2c:f1:3e:15:84:63:20:3e:ce:94:bc:f9:d3:cc:19:6b:f0:9a:54:72
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFWjCCA0KgAwIBAgIQbkepxUtHDA3sM9CJuRz04TANBgkqhkiG9w0BAQwFADBH
|
||||
MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM
|
||||
QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy
|
||||
MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl
|
||||
cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEB
|
||||
AQUAA4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaM
|
||||
f/vo27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vX
|
||||
mX7wCl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7
|
||||
zUjwTcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0P
|
||||
fyblqAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtc
|
||||
vfaHszVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4
|
||||
Zor8Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUsp
|
||||
zBmkMiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOO
|
||||
Rc92wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYW
|
||||
k70paDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+
|
||||
DVrNVjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgF
|
||||
lQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV
|
||||
HQ4EFgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBADiW
|
||||
Cu49tJYeX++dnAsznyvgyv3SjgofQXSlfKqE1OXyHuY3UjKcC9FhHb8owbZEKTV1
|
||||
d5iyfNm9dKyKaOOpMQkpAWBz40d8U6iQSifvS9efk+eCNs6aaAyC58/UEBZvXw6Z
|
||||
XPYfcX3v73svfuo21pdwCxXu11xWajOl40k4DLh9+42FpLFZXvRq4d2h9mREruZR
|
||||
gyFmxhE+885H7pwoHyXa/6xmld01D1zvICxi/ZG6qcz8WpyTgYMpl0p8WnK0OdC3
|
||||
d8t5/Wk6kjftbjhlRn7pYL15iJdfOBL07q9bgsiG1eGZbYwE8na6SfZu6W0eX6Dv
|
||||
J4J2QPim01hcDyxC2kLGe4g0x8HYRZvBPsVhHdljUEn2NIVq4BjFbkerQUIpm/Zg
|
||||
DdIx02OYI5NaAIFItO/Nis3Jz5nu2Z6qNuFoS3FJFDYoOj0dzpqPJeaAcWErtXvM
|
||||
+SUWgeExX6GjfhaknBZqlxi9dnKlC54dNuYvoS++cJEPqOba+MSSQGwlfnuzCdyy
|
||||
F62ARPBopY+Udf90WuioAnwMCeKpSwughQtiue+hMZL77/ZRBIls6Kl0obsXs7X9
|
||||
SQ98POyDGCBDTtWTurQ0sR8WNh8M5mQ5Fkzc4P4dyKliPUDqysU0ArSuiYgzNdws
|
||||
E3PYJ/HQcu51OyLemGhmW/HGY0dVHLqlCFF1pkgl
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
# Issuer: CN=GTS Root R2 O=Google Trust Services LLC
|
||||
# Subject: CN=GTS Root R2 O=Google Trust Services LLC
|
||||
# Label: "GTS Root R2"
|
||||
# Serial: 146587176055767053814479386953112547951
|
||||
# MD5 Fingerprint: 44:ed:9a:0e:a4:09:3b:00:f2:ae:4c:a3:c6:61:b0:8b
|
||||
# SHA1 Fingerprint: d2:73:96:2a:2a:5e:39:9f:73:3f:e1:c7:1e:64:3f:03:38:34:fc:4d
|
||||
# SHA256 Fingerprint: c4:5d:7b:b0:8e:6d:67:e6:2e:42:35:11:0b:56:4e:5f:78:fd:92:ef:05:8c:84:0a:ea:4e:64:55:d7:58:5c:60
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFWjCCA0KgAwIBAgIQbkepxlqz5yDFMJo/aFLybzANBgkqhkiG9w0BAQwFADBH
|
||||
MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM
|
||||
QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy
|
||||
MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl
|
||||
cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEB
|
||||
AQUAA4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3Lv
|
||||
CvptnfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3Kg
|
||||
GjSY6Dlo7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9Bu
|
||||
XvAuMC6C/Pq8tBcKSOWIm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOd
|
||||
re7kRXuJVfeKH2JShBKzwkCX44ofR5GmdFrS+LFjKBC4swm4VndAoiaYecb+3yXu
|
||||
PuWgf9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7MkogwTZq9TwtImoS1
|
||||
mKPV+3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJGr61K
|
||||
8YzodDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqj
|
||||
x5RWIr9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsR
|
||||
nTKaG73VululycslaVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0
|
||||
kzCqgc7dGtxRcw1PcOnlthYhGXmy5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9Ok
|
||||
twIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV
|
||||
HQ4EFgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQADggIBALZp
|
||||
8KZ3/p7uC4Gt4cCpx/k1HUCCq+YEtN/L9x0Pg/B+E02NjO7jMyLDOfxA325BS0JT
|
||||
vhaI8dI4XsRomRyYUpOM52jtG2pzegVATX9lO9ZY8c6DR2Dj/5epnGB3GFW1fgiT
|
||||
z9D2PGcDFWEJ+YF59exTpJ/JjwGLc8R3dtyDovUMSRqodt6Sm2T4syzFJ9MHwAiA
|
||||
pJiS4wGWAqoC7o87xdFtCjMwc3i5T1QWvwsHoaRc5svJXISPD+AVdyx+Jn7axEvb
|
||||
pxZ3B7DNdehyQtaVhJ2Gg/LkkM0JR9SLA3DaWsYDQvTtN6LwG1BUSw7YhN4ZKJmB
|
||||
R64JGz9I0cNv4rBgF/XuIwKl2gBbbZCr7qLpGzvpx0QnRY5rn/WkhLx3+WuXrD5R
|
||||
RaIRpsyF7gpo8j5QOHokYh4XIDdtak23CZvJ/KRY9bb7nE4Yu5UC56GtmwfuNmsk
|
||||
0jmGwZODUNKBRqhfYlcsu2xkiAhu7xNUX90txGdj08+JN7+dIPT7eoOboB6BAFDC
|
||||
5AwiWVIQ7UNWhwD4FFKnHYuTjKJNRn8nxnGbJN7k2oaLDX5rIMHAnuFl2GqjpuiF
|
||||
izoHCBy69Y9Vmhh1fuXsgWbRIXOhNUQLgD1bnF5vKheW0YMjiGZt5obicDIvUiLn
|
||||
yOd/xCxgXS/Dr55FBcOEArf9LAhST4Ldo/DUhgkC
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
# Issuer: CN=GTS Root R3 O=Google Trust Services LLC
|
||||
# Subject: CN=GTS Root R3 O=Google Trust Services LLC
|
||||
# Label: "GTS Root R3"
|
||||
# Serial: 146587176140553309517047991083707763997
|
||||
# MD5 Fingerprint: 1a:79:5b:6b:04:52:9c:5d:c7:74:33:1b:25:9a:f9:25
|
||||
# SHA1 Fingerprint: 30:d4:24:6f:07:ff:db:91:89:8a:0b:e9:49:66:11:eb:8c:5e:46:e5
|
||||
# SHA256 Fingerprint: 15:d5:b8:77:46:19:ea:7d:54:ce:1c:a6:d0:b0:c4:03:e0:37:a9:17:f1:31:e8:a0:4e:1e:6b:7a:71:ba:bc:e5
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICDDCCAZGgAwIBAgIQbkepx2ypcyRAiQ8DVd2NHTAKBggqhkjOPQQDAzBHMQsw
|
||||
CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU
|
||||
MBIGA1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw
|
||||
MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp
|
||||
Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQA
|
||||
IgNiAAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout
|
||||
736GjOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2A
|
||||
DDL24CejQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud
|
||||
DgQWBBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEAgFuk
|
||||
fCPAlaUs3L6JbyO5o91lAFJekazInXJ0glMLfalAvWhgxeG4VDvBNhcl2MG9AjEA
|
||||
njWSdIUlUfUk7GRSJFClH9voy8l27OyCbvWFGFPouOOaKaqW04MjyaR7YbPMAuhd
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
# Issuer: CN=GTS Root R4 O=Google Trust Services LLC
|
||||
# Subject: CN=GTS Root R4 O=Google Trust Services LLC
|
||||
# Label: "GTS Root R4"
|
||||
# Serial: 146587176229350439916519468929765261721
|
||||
# MD5 Fingerprint: 5d:b6:6a:c4:60:17:24:6a:1a:99:a8:4b:ee:5e:b4:26
|
||||
# SHA1 Fingerprint: 2a:1d:60:27:d9:4a:b1:0a:1c:4d:91:5c:cd:33:a0:cb:3e:2d:54:cb
|
||||
# SHA256 Fingerprint: 71:cc:a5:39:1f:9e:79:4b:04:80:25:30:b3:63:e1:21:da:8a:30:43:bb:26:66:2f:ea:4d:ca:7f:c9:51:a4:bd
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICCjCCAZGgAwIBAgIQbkepyIuUtui7OyrYorLBmTAKBggqhkjOPQQDAzBHMQsw
|
||||
CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU
|
||||
MBIGA1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw
|
||||
MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp
|
||||
Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQA
|
||||
IgNiAATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzu
|
||||
hXyiQHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/l
|
||||
xKvRHYqjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud
|
||||
DgQWBBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNnADBkAjBqUFJ0
|
||||
CMRw3J5QdCHojXohw0+WbhXRIjVhLfoIN+4Zba3bssx9BzT1YBkstTTZbyACMANx
|
||||
sbqjYAuG7ZoIapVon+Kz4ZNkfF6Tpt95LY2F45TPI11xzPKwTdb+mciUqXWi4w==
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
# Issuer: CN=UCA Global G2 Root O=UniTrust
|
||||
# Subject: CN=UCA Global G2 Root O=UniTrust
|
||||
# Label: "UCA Global G2 Root"
|
||||
# Serial: 124779693093741543919145257850076631279
|
||||
# MD5 Fingerprint: 80:fe:f0:c4:4a:f0:5c:62:32:9f:1c:ba:78:a9:50:f8
|
||||
# SHA1 Fingerprint: 28:f9:78:16:19:7a:ff:18:25:18:aa:44:fe:c1:a0:ce:5c:b6:4c:8a
|
||||
# SHA256 Fingerprint: 9b:ea:11:c9:76:fe:01:47:64:c1:be:56:a6:f9:14:b5:a5:60:31:7a:bd:99:88:39:33:82:e5:16:1a:a0:49:3c
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFRjCCAy6gAwIBAgIQXd+x2lqj7V2+WmUgZQOQ7zANBgkqhkiG9w0BAQsFADA9
|
||||
MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxGzAZBgNVBAMMElVDQSBH
|
||||
bG9iYWwgRzIgUm9vdDAeFw0xNjAzMTEwMDAwMDBaFw00MDEyMzEwMDAwMDBaMD0x
|
||||
CzAJBgNVBAYTAkNOMREwDwYDVQQKDAhVbmlUcnVzdDEbMBkGA1UEAwwSVUNBIEds
|
||||
b2JhbCBHMiBSb290MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxeYr
|
||||
b3zvJgUno4Ek2m/LAfmZmqkywiKHYUGRO8vDaBsGxUypK8FnFyIdK+35KYmToni9
|
||||
kmugow2ifsqTs6bRjDXVdfkX9s9FxeV67HeToI8jrg4aA3++1NDtLnurRiNb/yzm
|
||||
VHqUwCoV8MmNsHo7JOHXaOIxPAYzRrZUEaalLyJUKlgNAQLx+hVRZ2zA+te2G3/R
|
||||
VogvGjqNO7uCEeBHANBSh6v7hn4PJGtAnTRnvI3HLYZveT6OqTwXS3+wmeOwcWDc
|
||||
C/Vkw85DvG1xudLeJ1uK6NjGruFZfc8oLTW4lVYa8bJYS7cSN8h8s+1LgOGN+jIj
|
||||
tm+3SJUIsUROhYw6AlQgL9+/V087OpAh18EmNVQg7Mc/R+zvWr9LesGtOxdQXGLY
|
||||
D0tK3Cv6brxzks3sx1DoQZbXqX5t2Okdj4q1uViSukqSKwxW/YDrCPBeKW4bHAyv
|
||||
j5OJrdu9o54hyokZ7N+1wxrrFv54NkzWbtA+FxyQF2smuvt6L78RHBgOLXMDj6Dl
|
||||
NaBa4kx1HXHhOThTeEDMg5PXCp6dW4+K5OXgSORIskfNTip1KnvyIvbJvgmRlld6
|
||||
iIis7nCs+dwp4wwcOxJORNanTrAmyPPZGpeRaOrvjUYG0lZFWJo8DA+DuAUlwznP
|
||||
O6Q0ibd5Ei9Hxeepl2n8pndntd978XplFeRhVmUCAwEAAaNCMEAwDgYDVR0PAQH/
|
||||
BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFIHEjMz15DD/pQwIX4wV
|
||||
ZyF0Ad/fMA0GCSqGSIb3DQEBCwUAA4ICAQATZSL1jiutROTL/7lo5sOASD0Ee/oj
|
||||
L3rtNtqyzm325p7lX1iPyzcyochltq44PTUbPrw7tgTQvPlJ9Zv3hcU2tsu8+Mg5
|
||||
1eRfB70VVJd0ysrtT7q6ZHafgbiERUlMjW+i67HM0cOU2kTC5uLqGOiiHycFutfl
|
||||
1qnN3e92mI0ADs0b+gO3joBYDic/UvuUospeZcnWhNq5NXHzJsBPd+aBJ9J3O5oU
|
||||
b3n09tDh05S60FdRvScFDcH9yBIw7m+NESsIndTUv4BFFJqIRNow6rSn4+7vW4LV
|
||||
PtateJLbXDzz2K36uGt/xDYotgIVilQsnLAXc47QN6MUPJiVAAwpBVueSUmxX8fj
|
||||
y88nZY41F7dXyDDZQVu5FLbowg+UMaeUmMxq67XhJ/UQqAHojhJi6IjMtX9Gl8Cb
|
||||
EGY4GjZGXyJoPd/JxhMnq1MGrKI8hgZlb7F+sSlEmqO6SWkoaY/X5V+tBIZkbxqg
|
||||
DMUIYs6Ao9Dz7GjevjPHF1t/gMRMTLGmhIrDO7gJzRSBuhjjVFc2/tsvfEehOjPI
|
||||
+Vg7RE+xygKJBJYoaMVLuCaJu9YzL1DV/pqJuhgyklTGW+Cd+V7lDSKb9triyCGy
|
||||
YiGqhkCyLmTTX8jjfhFnRR8F/uOi77Oos/N9j/gMHyIfLXC0uAE0djAA5SN4p1bX
|
||||
UB+K+wb1whnw0A==
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
# Issuer: CN=UCA Extended Validation Root O=UniTrust
|
||||
# Subject: CN=UCA Extended Validation Root O=UniTrust
|
||||
# Label: "UCA Extended Validation Root"
|
||||
# Serial: 106100277556486529736699587978573607008
|
||||
# MD5 Fingerprint: a1:f3:5f:43:c6:34:9b:da:bf:8c:7e:05:53:ad:96:e2
|
||||
# SHA1 Fingerprint: a3:a1:b0:6f:24:61:23:4a:e3:36:a5:c2:37:fc:a6:ff:dd:f0:d7:3a
|
||||
# SHA256 Fingerprint: d4:3a:f9:b3:54:73:75:5c:96:84:fc:06:d7:d8:cb:70:ee:5c:28:e7:73:fb:29:4e:b4:1e:e7:17:22:92:4d:24
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFWjCCA0KgAwIBAgIQT9Irj/VkyDOeTzRYZiNwYDANBgkqhkiG9w0BAQsFADBH
|
||||
MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBF
|
||||
eHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwHhcNMTUwMzEzMDAwMDAwWhcNMzgxMjMx
|
||||
MDAwMDAwWjBHMQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNV
|
||||
BAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwggIiMA0GCSqGSIb3DQEB
|
||||
AQUAA4ICDwAwggIKAoICAQCpCQcoEwKwmeBkqh5DFnpzsZGgdT6o+uM4AHrsiWog
|
||||
D4vFsJszA1qGxliG1cGFu0/GnEBNyr7uaZa4rYEwmnySBesFK5pI0Lh2PpbIILvS
|
||||
sPGP2KxFRv+qZ2C0d35qHzwaUnoEPQc8hQ2E0B92CvdqFN9y4zR8V05WAT558aop
|
||||
O2z6+I9tTcg1367r3CTueUWnhbYFiN6IXSV8l2RnCdm/WhUFhvMJHuxYMjMR83dk
|
||||
sHYf5BA1FxvyDrFspCqjc/wJHx4yGVMR59mzLC52LqGj3n5qiAno8geK+LLNEOfi
|
||||
c0CTuwjRP+H8C5SzJe98ptfRr5//lpr1kXuYC3fUfugH0mK1lTnj8/FtDw5lhIpj
|
||||
VMWAtuCeS31HJqcBCF3RiJ7XwzJE+oJKCmhUfzhTA8ykADNkUVkLo4KRel7sFsLz
|
||||
KuZi2irbWWIQJUoqgQtHB0MGcIfS+pMRKXpITeuUx3BNr2fVUbGAIAEBtHoIppB/
|
||||
TuDvB0GHr2qlXov7z1CymlSvw4m6WC31MJixNnI5fkkE/SmnTHnkBVfblLkWU41G
|
||||
sx2VYVdWf6/wFlthWG82UBEL2KwrlRYaDh8IzTY0ZRBiZtWAXxQgXy0MoHgKaNYs
|
||||
1+lvK9JKBZP8nm9rZ/+I8U6laUpSNwXqxhaN0sSZ0YIrO7o1dfdRUVjzyAfd5LQD
|
||||
fwIDAQABo0IwQDAdBgNVHQ4EFgQU2XQ65DA9DfcS3H5aBZ8eNJr34RQwDwYDVR0T
|
||||
AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBADaN
|
||||
l8xCFWQpN5smLNb7rhVpLGsaGvdftvkHTFnq88nIua7Mui563MD1sC3AO6+fcAUR
|
||||
ap8lTwEpcOPlDOHqWnzcSbvBHiqB9RZLcpHIojG5qtr8nR/zXUACE/xOHAbKsxSQ
|
||||
VBcZEhrxH9cMaVr2cXj0lH2RC47skFSOvG+hTKv8dGT9cZr4QQehzZHkPJrgmzI5
|
||||
c6sq1WnIeJEmMX3ixzDx/BR4dxIOE/TdFpS/S2d7cFOFyrC78zhNLJA5wA3CXWvp
|
||||
4uXViI3WLL+rG761KIcSF3Ru/H38j9CHJrAb+7lsq+KePRXBOy5nAliRn+/4Qh8s
|
||||
t2j1da3Ptfb/EX3C8CSlrdP6oDyp+l3cpaDvRKS+1ujl5BOWF3sGPjLtx7dCvHaj
|
||||
2GU4Kzg1USEODm8uNBNA4StnDG1KQTAYI1oyVZnJF+A83vbsea0rWBmirSwiGpWO
|
||||
vpaQXUJXxPkUAzUrHC1RVwinOt4/5Mi0A3PCwSaAuwtCH60NryZy2sy+s6ODWA2C
|
||||
xR9GUeOcGMyNm43sSet1UNWMKFnKdDTajAshqx7qG+XH/RU+wBeq+yNuJkbL+vmx
|
||||
cmtpzyKEC2IPrNkZAJSidjzULZrtBJ4tBmIQN1IchXIbJ+XMxjHsN+xjWZsLHXbM
|
||||
fjKaiJUINlK73nZfdklJrX+9ZSCyycErdhh2n1ax
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
# Issuer: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036
|
||||
# Subject: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036
|
||||
# Label: "Certigna Root CA"
|
||||
# Serial: 269714418870597844693661054334862075617
|
||||
# MD5 Fingerprint: 0e:5c:30:62:27:eb:5b:bc:d7:ae:62:ba:e9:d5:df:77
|
||||
# SHA1 Fingerprint: 2d:0d:52:14:ff:9e:ad:99:24:01:74:20:47:6e:6c:85:27:27:f5:43
|
||||
# SHA256 Fingerprint: d4:8d:3d:23:ee:db:50:a4:59:e5:51:97:60:1c:27:77:4b:9d:7b:18:c9:4d:5a:05:95:11:a1:02:50:b9:31:68
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAw
|
||||
WjELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAw
|
||||
MiA0ODE0NjMwODEwMDAzNjEZMBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0x
|
||||
MzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjdaMFoxCzAJBgNVBAYTAkZSMRIwEAYD
|
||||
VQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYzMDgxMDAwMzYxGTAX
|
||||
BgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw
|
||||
ggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sO
|
||||
ty3tRQgXstmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9M
|
||||
CiBtnyN6tMbaLOQdLNyzKNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPu
|
||||
I9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8JXrJhFwLrN1CTivngqIkicuQstDuI7pm
|
||||
TLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16XdG+RCYyKfHx9WzMfgIh
|
||||
C59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq4NYKpkDf
|
||||
ePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3Yz
|
||||
IoejwpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWT
|
||||
Co/1VTp2lc5ZmIoJlXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1k
|
||||
JWumIWmbat10TWuXekG9qxf5kBdIjzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5
|
||||
hwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp//TBt2dzhauH8XwIDAQABo4IB
|
||||
GjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
|
||||
FBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of
|
||||
1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczov
|
||||
L3d3d3cuY2VydGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilo
|
||||
dHRwOi8vY3JsLmNlcnRpZ25hLmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYr
|
||||
aHR0cDovL2NybC5kaGlteW90aXMuY29tL2NlcnRpZ25hcm9vdGNhLmNybDANBgkq
|
||||
hkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOItOoldaDgvUSILSo3L
|
||||
6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxPTGRG
|
||||
HVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH6
|
||||
0BGM+RFq7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncB
|
||||
lA2c5uk5jR+mUYyZDDl34bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdi
|
||||
o2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1
|
||||
gPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS6Cvu5zHbugRqh5jnxV/v
|
||||
faci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaYtlu3zM63
|
||||
Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayh
|
||||
jWZSaX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw
|
||||
3kAP+HwV96LOPNdeE4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0=
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
Vendored
-17
@@ -8,14 +8,6 @@ certifi.py
|
||||
This module returns the installation location of cacert.pem.
|
||||
"""
|
||||
import os
|
||||
import warnings
|
||||
|
||||
|
||||
class DeprecatedBundleWarning(DeprecationWarning):
|
||||
"""
|
||||
The weak security bundle is being deprecated. Please bother your service
|
||||
provider to get them to stop using cross-signed roots.
|
||||
"""
|
||||
|
||||
|
||||
def where():
|
||||
@@ -24,14 +16,5 @@ def where():
|
||||
return os.path.join(f, 'cacert.pem')
|
||||
|
||||
|
||||
def old_where():
|
||||
warnings.warn(
|
||||
"The weak security bundle has been removed. certifi.old_where() is now an alias "
|
||||
"of certifi.where(). Please update your code to use certifi.where() instead. "
|
||||
"certifi.old_where() will be removed in 2018.",
|
||||
DeprecatedBundleWarning
|
||||
)
|
||||
return where()
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(where())
|
||||
|
||||
Vendored
-1
@@ -25,4 +25,3 @@ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
Vendored
+1
-2
@@ -3,5 +3,4 @@ from .initialise import init, deinit, reinit, colorama_text
|
||||
from .ansi import Fore, Back, Style, Cursor
|
||||
from .ansitowin32 import AnsiToWin32
|
||||
|
||||
__version__ = '0.3.9'
|
||||
|
||||
__version__ = '0.4.1'
|
||||
|
||||
+32
-11
@@ -13,14 +13,6 @@ if windll is not None:
|
||||
winterm = WinTerm()
|
||||
|
||||
|
||||
def is_stream_closed(stream):
|
||||
return not hasattr(stream, 'closed') or stream.closed
|
||||
|
||||
|
||||
def is_a_tty(stream):
|
||||
return hasattr(stream, 'isatty') and stream.isatty()
|
||||
|
||||
|
||||
class StreamWrapper(object):
|
||||
'''
|
||||
Wraps a stream (such as stdout), acting as a transparent proxy for all
|
||||
@@ -36,9 +28,38 @@ class StreamWrapper(object):
|
||||
def __getattr__(self, name):
|
||||
return getattr(self.__wrapped, name)
|
||||
|
||||
def __enter__(self, *args, **kwargs):
|
||||
# special method lookup bypasses __getattr__/__getattribute__, see
|
||||
# https://stackoverflow.com/questions/12632894/why-doesnt-getattr-work-with-exit
|
||||
# thus, contextlib magic methods are not proxied via __getattr__
|
||||
return self.__wrapped.__enter__(*args, **kwargs)
|
||||
|
||||
def __exit__(self, *args, **kwargs):
|
||||
return self.__wrapped.__exit__(*args, **kwargs)
|
||||
|
||||
def write(self, text):
|
||||
self.__convertor.write(text)
|
||||
|
||||
def isatty(self):
|
||||
stream = self.__wrapped
|
||||
if 'PYCHARM_HOSTED' in os.environ:
|
||||
if stream is not None and (stream is sys.__stdout__ or stream is sys.__stderr__):
|
||||
return True
|
||||
try:
|
||||
stream_isatty = stream.isatty
|
||||
except AttributeError:
|
||||
return False
|
||||
else:
|
||||
return stream_isatty()
|
||||
|
||||
@property
|
||||
def closed(self):
|
||||
stream = self.__wrapped
|
||||
try:
|
||||
return stream.closed
|
||||
except AttributeError:
|
||||
return True
|
||||
|
||||
|
||||
class AnsiToWin32(object):
|
||||
'''
|
||||
@@ -68,12 +89,12 @@ class AnsiToWin32(object):
|
||||
|
||||
# should we strip ANSI sequences from our output?
|
||||
if strip is None:
|
||||
strip = conversion_supported or (not is_stream_closed(wrapped) and not is_a_tty(wrapped))
|
||||
strip = conversion_supported or (not self.stream.closed and not self.stream.isatty())
|
||||
self.strip = strip
|
||||
|
||||
# should we should convert ANSI sequences into win32 calls?
|
||||
if convert is None:
|
||||
convert = conversion_supported and not is_stream_closed(wrapped) and is_a_tty(wrapped)
|
||||
convert = conversion_supported and not self.stream.closed and self.stream.isatty()
|
||||
self.convert = convert
|
||||
|
||||
# dict of ansi codes to win32 functions and parameters
|
||||
@@ -149,7 +170,7 @@ class AnsiToWin32(object):
|
||||
def reset_all(self):
|
||||
if self.convert:
|
||||
self.call_win32('m', (0,))
|
||||
elif not self.strip and not is_stream_closed(self.wrapped):
|
||||
elif not self.strip and not self.stream.closed:
|
||||
self.wrapped.write(Style.RESET_ALL)
|
||||
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user