Merge branch 'bugfix/3148' of github.com:pypa/pipenv into bugfix/3148

This commit is contained in:
Dan Ryan
2019-02-20 17:02:04 -05:00
214 changed files with 11314 additions and 4057 deletions
+2 -1
View File
@@ -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
+1
View File
@@ -8,6 +8,7 @@ trigger:
exclude:
- docs/*
- news/*
- peeps/*
- README.md
- pipenv/*.txt
- CHANGELOG.rst
+1 -1
View File
@@ -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
+1
View File
@@ -8,6 +8,7 @@ trigger:
exclude:
- docs/*
- news/*
- peeps/*
- README.md
- pipenv/*.txt
- CHANGELOG.rst
+5
View File
@@ -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/
-50
View File
@@ -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
View File
@@ -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>`_
+2 -7
View File
@@ -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 = "*"
Generated
+210 -231
View File
@@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
"sha256": "f0a57ba6f180e7312f799a460a9d2790c9c26c3556eff2b5d1fe7d9b9174d05b"
"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,13 +64,37 @@
],
"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:194ec62a25438adcb3fdb06378b26559eda1ea8a747367d34c33cef9c7f48d57",
"sha256:90f8e61121d6ae58362ce3bed8cd997efb00c914eae0ff3d363c32f9a9822d10",
"sha256:f0abd31228055d698bb392a826528ea08ebb9959e6bea17c606fd9c9009db938"
"sha256:034740f6cb549b4e932ae1ab975581e6103ac8f942200a0e9759065984391858",
"sha256:945065979fb8529dd2f37dbb58f00b661bdbcbebf954f93b32fdf5263ef35348",
"sha256:ba6d5c59906a85ac23dadfe5c88deaf3e179ef565f4898671253e50a78680718"
],
"version": "==4.6.3"
"version": "==4.7.1"
},
"black": {
"hashes": [
@@ -91,10 +107,10 @@
},
"bleach": {
"hashes": [
"sha256:48d39675b80a75f6d1c3bdbffec791cf0bbbab665cf01e20da701c77de278718",
"sha256:73d26f018af5d5adcdabf5c1c974add4361a9c76af215fe32fdec8a6fc5fb9b9"
"sha256:213336e49e102af26d9cde77dd2d0397afabc5a6bf2fed985dc35b5d1e285a16",
"sha256:3fdf7f77adcf649c9911387df51254b813185e32b2c6619f690b593a617e19fa"
],
"version": "==3.0.2"
"version": "==3.1.0"
},
"bs4": {
"hashes": [
@@ -111,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": [
@@ -168,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": [
@@ -235,6 +183,13 @@
],
"version": "==0.14"
},
"entrypoints": {
"hashes": [
"sha256:589f874b313739ad35be6e0cd7efde2a4e9b6fea91edcc34e58ecbb8dbe56d19",
"sha256:c70dd71abe5a8c85e55e12c19bd91ccfeec11a6e99044204511f9ed547d48451"
],
"version": "==0.3"
},
"enum34": {
"hashes": [
"sha256:2d81cbbe0e73112bdfe6ef8576f2238f2ba27dd0d55752a776c41d38b7da2850",
@@ -242,7 +197,7 @@
"sha256:6bd0f6ad48ec2aa117d3d141940d484deccda84d4fcd884f5c3d93c23ecd8c79",
"sha256:8ad8c4783bf61ded74527bffb48ed9b54166685e4230386a9ed9b1279e2df5b1"
],
"markers": "python_version < '3.4'",
"markers": "python_version < '3'",
"version": "==1.1.6"
},
"execnet": {
@@ -261,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": [
@@ -287,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": [
@@ -352,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": [
@@ -410,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": [
@@ -471,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": [
@@ -492,10 +458,10 @@
},
"pluggy": {
"hashes": [
"sha256:447ba94990e8014ee25ec853339faf7b0fc8050cdc3289d4d71f7f410fb90095",
"sha256:bde19360a8ec4dfd8a20dcb811780a30998101f078fc7ded6162f0076f50508f"
"sha256:8ddc32f03971bfdf900a81961a48ccf2fb677cf7715108f85295c67405798616",
"sha256:980710797ff6a041e9a73a5787804f848996ecaa6f8a1b1e08224a5894f2074a"
],
"version": "==0.8.0"
"version": "==0.8.1"
},
"py": {
"hashes": [
@@ -506,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": [
@@ -581,11 +539,11 @@
},
"pytz": {
"hashes": [
"sha256:a061aa0a9e06881eb8b3b2b43f05b9439d6583c206d0a6c340ff72a7b6669053",
"sha256:ffb9ef1de172603304d9d2819af6f5ece76f2e85ec10692a524dd876e72bf277"
"sha256:32b0891edff07e28efe91284ed9c31e123d84bea3fd98e1f72be2508f43ef8d9",
"sha256:d5f05e487007e29e03409f9398d074e158d920d36eb82eaf66fb1136b0c5374c"
],
"index": "pypi",
"version": "==2018.5"
"version": "==2018.9"
},
"readme-renderer": {
"hashes": [
@@ -596,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:c2c00c7bd3bd4984c97d10cd4d143efbe33b5ed9e55961bea30ca7a9a4927289",
"sha256:dc6b692e8dee03d6e90c29db1e337b0bf8152cce84a57f0fb4765e596afde4e0"
"sha256:c26feee79853dedddab550cf79fb2fa83b4bc1a16eab58f2c870e8314caa6cc5",
"sha256:d302b780afbd1d60f49d368b535929d8ff4b6d972797f3777c9560d48abdded7"
],
"version": "==1.3.3"
"version": "==1.4.0"
},
"resolvelib": {
"hashes": [
@@ -624,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": [
@@ -643,6 +618,13 @@
],
"version": "==1.2.1"
},
"soupsieve": {
"hashes": [
"sha256:afa56bf14907bb09403e5d15fbed6275caa4174d36b975226e3b67a3bb6e2c4b",
"sha256:eaed742b48b1f3e2d45ba6f79401b2ed5dc33b2123dfe216adb90d4bfa0ade26"
],
"version": "==1.8"
},
"sphinx": {
"hashes": [
"sha256:11f271e7a9398385ed730e90f0bb41dc3815294bdcd395b46ed2d033bc2e7d87",
@@ -653,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": [
@@ -684,7 +659,8 @@
"toml": {
"hashes": [
"sha256:229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c",
"sha256:235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e"
"sha256:235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e",
"sha256:f1db651f9657708513243e61e6cc67d101a39bad662eaa9b5546f789338e07a3"
],
"version": "==0.10.0"
},
@@ -698,31 +674,32 @@
"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": [
@@ -733,26 +710,28 @@
},
"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:3a1020fb7be000b268af96641ced9ead844b1f75840c41e20e473647688fc630",
"sha256:6d2005ad670f77bd9c9b5415c4e2a4a20dce5b0cf0e0d11598eb463b2e0ebe44"
"sha256:510408ec63a4b423967fd630bf0885c8d6a1d5d126f8bb1be6aba86a0da5e815",
"sha256:fc5cca7a14e92feaa6f85dd91da74d834904280a96a21190aecb4cd1d1048e0e"
],
"version": "==0.2.5"
"version": "==0.3.0"
},
"webencodings": {
"hashes": [
@@ -770,17 +749,17 @@
},
"wheel": {
"hashes": [
"sha256:029703bf514e16c8271c3821806a1c171220cc5bdd325cbf4e7da1e056a01db6",
"sha256:1e53cdb3f808d5ccd0df57f964263752aa74ea7359526d3da6c02114ec1e1d44"
"sha256:12363e6df5678ecf9daf8429f06f97e7106e701405898f24318ce7f0b79c611a",
"sha256:b79ffea026bc0dbd940868347ae9eee36789b6496b6623bd2dec7c7c540a8f99"
],
"version": "==0.32.3"
"version": "==0.33.0"
},
"yaspin": {
"hashes": [
"sha256:36fdccc5e0637b5baa8892fe2c3d927782df7d504e9020f40eb2c1502518aa5a",
"sha256:8e52bf8079a48e2a53f3dfeec9e04addb900c101d1591c85df69cf677d3237e7"
"sha256:441f8a6761e347652d04614899fd0a9cfda7439e2d5682e664bd31230c656176",
"sha256:d3ebcf8162e0ef8bb5484b8751d5b6d2fbf0720112c81f64614c308576a03b1d"
],
"version": "==0.14.0"
"version": "==0.14.1"
}
}
}
+4 -4
View File
@@ -4,8 +4,8 @@ Pipenv: Python Development Workflow for Humans
[![image](https://img.shields.io/pypi/v/pipenv.svg)](https://python.org/pypi/pipenv)
[![image](https://img.shields.io/pypi/l/pipenv.svg)](https://python.org/pypi/pipenv)
[![image](https://badge.buildkite.com/79c7eccf056b17c3151f3c4d0e4c4b8b724539d84f1e037b9b.svg?branch=master)](https://code.kennethreitz.org/source/pipenv/)
[![VSTS build status (Windows)](https://dev.azure.com/pypa/pipenv/_apis/build/status/pipenv%20CI%20(Windows)?branchName=master&label=Windows)](https://dev.azure.com/pypa/pipenv/_build/latest?definitionId=9&branchName=master)
[![VSTS build status (Linux)](https://dev.azure.com/pypa/pipenv/_apis/build/status/pipenv%20CI%20(Linux)?branchName=master&label=Linux)](https://dev.azure.com/pypa/pipenv/_build/latest?definitionId=10&branchName=master)
[![Azure Pipelines build status (Linux)](https://dev.azure.com/pypa/pipenv/_apis/build/status/pipenv%20CI%20(Linux)?branchName=master&label=Linux)](https://dev.azure.com/pypa/pipenv/_build/latest?definitionId=13&branchName=master)
[![Azure Pipelines build status (Windows)](https://dev.azure.com/pypa/pipenv/_apis/build/status/pipenv%20CI%20(Windows)?branchName=master&label=Windows)](https://dev.azure.com/pypa/pipenv/_build/latest?definitionId=12&branchName=master)
[![image](https://img.shields.io/pypi/pyversions/pipenv.svg)](https://python.org/pypi/pipenv)
[![image](https://img.shields.io/badge/Say%20Thanks-!-1EAEDB.svg)](https://saythanks.io/to/kennethreitz)
@@ -13,11 +13,11 @@ 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.
![image](http://media.kennethreitz.com.s3.amazonaws.com/pipenv.gif)
+1
View File
@@ -18,6 +18,7 @@
#
import os
# Path hackery to get current version number.
here = os.path.abspath(os.path.dirname(__file__))
+1 -1
View File
@@ -49,7 +49,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
+7 -7
View File
@@ -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
View File
@@ -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
+1
View File
@@ -0,0 +1 @@
Raise `PipenvUsageError` when [[source]] does not contain url field.
+1
View File
@@ -0,0 +1 @@
Added support for resolution of direct-url dependencies in ``setup.py`` files to respect ``PEP-508`` style URL dependencies.
-1
View File
@@ -1 +0,0 @@
Environment variables are expanded correctly before running scripts on POSIX.
-1
View File
@@ -1 +0,0 @@
Pipenv will no longer disable user-mode installation when the ``--system`` flag is passed in.
-1
View File
@@ -1 +0,0 @@
Fixed an issue with attempting to render unicode output in non-unicode locales.
-1
View File
@@ -1 +0,0 @@
Fixed a bug which could cause failures to occur when parsing python entries from global pyenv version files.
-1
View File
@@ -1 +0,0 @@
Fixed an issue which prevented the parsing of named extras sections from certain ``setup.py`` files.
-1
View File
@@ -1 +0,0 @@
Correctly detect the virtualenv location inside an activated virtualenv.
-1
View File
@@ -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
View File
@@ -1 +0,0 @@
Fixed a bug that editable pacakges can't be uninstalled correctly.
-1
View File
@@ -1 +0,0 @@
Adding normal pep 508 compatible markers is now fully functional when using VCS dependencies.
-1
View File
@@ -1 +0,0 @@
Updated ``requirementslib`` and ``pythonfinder`` for multiple bugfixes.
-1
View File
@@ -1 +0,0 @@
Pipenv will now ignore hashes when installing with ``--skip-lock``.
-1
View File
@@ -1 +0,0 @@
Fixed an issue where pipenv could crash when multiple pipenv processes attempted to create the same directory.
-1
View File
@@ -1 +0,0 @@
Fixed an issue which sometimes prevented successful creation of project pipfiles.
-1
View File
@@ -1 +0,0 @@
``pipenv install`` will now unset the ``PYTHONHOME`` environment variable when not combined with ``--system``.
-1
View File
@@ -1 +0,0 @@
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.
-1
View File
@@ -1 +0,0 @@
Fixed an issue which prevented variables from the environment, such as ``PIPENV_DEV`` or ``PIPENV_SYSTEM``, from being parsed and implemented correctly.
-4
View File
@@ -1,4 +0,0 @@
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`
-1
View File
@@ -1 +0,0 @@
Clear pythonfinder cache after Python install
-1
View File
@@ -1 +0,0 @@
Fixed a race condition in hash resolution for dependencies for certain dependencies with missing cache entries or fresh Pipenv installs.
-1
View File
@@ -1 +0,0 @@
Pipenv will now respect top-level pins over VCS dependency locks.
+1
View File
@@ -0,0 +1 @@
Quote command arguments with carets (``^``) on Windows to work around unintended shell escapes.
+1
View File
@@ -0,0 +1 @@
Handle alternate names for UTF-8 encoding.
+1
View File
@@ -0,0 +1 @@
Abort pipenv before adding the non-exist package to Pipfile.
+1
View File
@@ -0,0 +1 @@
Don't normalize the package name user passes in.
+1
View File
@@ -0,0 +1 @@
Fix a bug where custom virtualenv can not be activated with pipenv shell
+1
View File
@@ -0,0 +1 @@
Added support for ``--verbose`` output to ``pipenv run``.
+1
View File
@@ -0,0 +1 @@
Fix a bug that ``--site-packages`` flag is not recognized.
+1
View File
@@ -0,0 +1 @@
The inline tables won't be rewritten now.
+1
View File
@@ -0,0 +1 @@
Fix unhashable type error during ``$ pipenv install --selective-upgrade``
+1
View File
@@ -0,0 +1 @@
Fix a bug that ``ValidationError`` is thrown when some fields are missing in source section.
+1
View File
@@ -0,0 +1 @@
Fix the wrong order of old and new hashes in message.
+1
View File
@@ -0,0 +1 @@
Update the index names in lock file when source name in Pipfile is changed.
+9
View File
@@ -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.
+2
View File
@@ -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)
+1
View File
@@ -1,4 +1,5 @@
from .cli import cli
if __name__ == "__main__":
cli()
+1 -1
View File
@@ -2,4 +2,4 @@
# // ) ) / / // ) ) //___) ) // ) ) || / /
# //___/ / / / //___/ / // // / / || / /
# // / / // ((____ // / / ||/ /
__version__ = "2018.11.15.dev0"
__version__ = "2018.11.27.dev0"
+34 -10
View File
@@ -9,11 +9,16 @@ import functools
import importlib
import io
import os
import six
import sys
import warnings
import six
import vistir
from .vendor.vistir.compat import NamedTemporaryFile, Path, ResourceWarning, TemporaryDirectory
from .vendor.vistir.compat import (
NamedTemporaryFile, Path, ResourceWarning, TemporaryDirectory
)
# Backport required for earlier versions of Python.
if sys.version_info < (3, 3):
@@ -26,8 +31,8 @@ warnings.filterwarnings("ignore", category=ResourceWarning)
__all__ = [
"NamedTemporaryFile", "Path", "ResourceWarning", "TemporaryDirectory",
"get_terminal_size", "getpreferredencoding", "DEFAULT_ENCODING", "force_encoding",
"UNICODE_TO_ASCII_TRANSLATION_MAP", "decode_output", "fix_utf8"
"get_terminal_size", "getpreferredencoding", "DEFAULT_ENCODING", "canonical_encoding_name",
"force_encoding", "UNICODE_TO_ASCII_TRANSLATION_MAP", "decode_output", "fix_utf8"
]
@@ -46,6 +51,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():
@@ -57,20 +72,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:
@@ -80,7 +98,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:
@@ -104,6 +122,12 @@ UNICODE_TO_ASCII_TRANSLATION_MAP = {
}
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
+1
View File
@@ -1,3 +1,4 @@
# -*- coding=utf-8 -*-
from __future__ import absolute_import
from .command import cli
+12 -13
View File
@@ -4,23 +4,23 @@ 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
import crayons
import delegator
from click_didyoumean import DYMCommandCollection
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
)
@@ -70,7 +70,6 @@ def cli(
python=False,
help=False,
py=False,
site_packages=False,
envs=False,
man=False,
completion=False,
@@ -198,7 +197,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,
@@ -261,7 +260,6 @@ def install(
short_help="Un-installs a provided package and removes it from Pipfile.",
context_settings=subcommand_context
)
@option("--skip-lock/--lock", is_flag=True, default=False, help="Lock afterwards.")
@option(
"--all-dev",
is_flag=True,
@@ -280,7 +278,6 @@ def install(
def uninstall(
ctx,
state,
skip_lock=False,
all_dev=False,
all=False,
**kwargs
@@ -303,6 +300,7 @@ def uninstall(
if retcode:
sys.exit(retcode)
@cli.command(short_help="Generates Pipfile.lock.", context_settings=CONTEXT_SETTINGS)
@lock_options
@pass_state
@@ -402,8 +400,8 @@ def shell(
@pass_state
def run(state, command, args):
"""Spawns a command installed into the virtualenv."""
from ..core import do_run
from ..core import do_run, warn_in_virtualenv
warn_in_virtualenv()
do_run(
command=command, args=args, three=state.three, python=state.python, pypi_mirror=state.pypi_mirror
)
@@ -632,7 +630,8 @@ 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).
+1
View File
@@ -4,6 +4,7 @@ from __future__ import absolute_import
import os
import click.types
from click import (
BadParameter, Group, Option, argument, echo, make_pass_decorator, option
)
+17 -2
View File
@@ -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),
))
+199 -102
View File
@@ -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
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 = (
@@ -695,7 +675,7 @@ 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 ""
@@ -710,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)
@@ -718,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:
@@ -734,24 +726,24 @@ def batch_install(deps_list, procs, failed_deps_queue,
os.environ["PIP_USER"] = vistir.compat.fs_str("0")
if "PYTHONHOME" in os.environ:
del os.environ["PYTHONHOME"]
if no_deps:
if not needs_deps:
link = getattr(dep.req, "link", None)
is_wheel = False
if link:
is_wheel = link.is_wheel
is_non_editable_vcs = (dep.is_vcs and not dep.editable)
no_deps = not (dep.is_file_or_url and not (is_wheel or dep.editable))
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=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 or dep.editable:
c.block()
@@ -834,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
)
@@ -1036,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.
@@ -1206,9 +1202,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,
@@ -1277,12 +1273,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.urllib3.util import parse_url
src = []
write_to_tmpfile = False
if requirement:
@@ -1312,9 +1308,11 @@ def pip_install(
f.write(vistir.misc.to_bytes(requirement.as_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.
if not requirement.editable:
no_deps = False
# 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)])
@@ -1360,16 +1358,72 @@ 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:
# 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:]
editable_opt, req = req.split(" ", 1)
install_reqs = [editable_opt, req] + install_reqs
if not all(item.startswith("--hash") for item in install_reqs):
if not any(item.startswith("--hash") for item in install_reqs):
ignore_hashes = True
elif r:
install_reqs = ["-r", r]
@@ -1378,7 +1432,7 @@ def pip_install(
ignore_hashes = True
else:
ignore_hashes = True if not requirement.hashes else False
install_reqs = requirement.as_line(as_list=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:
@@ -1399,7 +1453,9 @@ def pip_install(
pip_command.extend(prepare_pip_source_args(sources))
if not ignore_hashes:
pip_command.append("--require-hashes")
if not use_pep517:
pip_command.append("--no-build-isolation")
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)
@@ -1418,6 +1474,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
@@ -1849,7 +1907,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
@@ -1874,9 +1932,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]
@@ -1926,6 +1984,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),
@@ -1933,6 +2002,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(
@@ -1971,12 +2041,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})
@@ -2156,11 +2234,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
@@ -2176,6 +2249,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
@@ -2310,22 +2390,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(
@@ -2505,7 +2605,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`"),
@@ -2586,7 +2686,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(
@@ -2614,34 +2714,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)
@@ -2653,9 +2751,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))
+33 -12
View File
@@ -3,23 +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 pkg_resources
import six
import vistir
import pipenv
from cached_property import cached_property
from .utils import normalize_path
BASE_WORKING_SET = pkg_resources.WorkingSet(sys.path)
@@ -161,7 +163,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
@@ -242,7 +244,7 @@ class Environment(object):
"""
pkg_resources = self.safe_import("pkg_resources")
return pkg_resources.find_distributions(self.paths["PYTHONPATH"])
return pkg_resources.find_distributions(self.paths["libdirs"])
def find_egg(self, egg_dist):
"""Find an egg by name in the given environment"""
@@ -269,16 +271,22 @@ 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"]
if _normalized(self.prefix).startswith(_normalized(prefix))
]
location = self.locate_dist(dist)
if not location:
return False
return _normalized(location).startswith(prefix)
return any(_normalized(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
@@ -473,6 +481,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 +491,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])
+31 -5
View File
@@ -2,9 +2,11 @@
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.
@@ -278,13 +280,37 @@ 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 or PIPENV_IGNORE_VIRTUALENVS
"""
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()
+11 -17
View File
@@ -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):
@@ -241,11 +235,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)
+2 -2
View File
@@ -1,8 +1,8 @@
# -*- coding: utf-8 -*-
import sys
import json
import os
import platform
import json
import sys
def format_full_version(info):
+3
View File
@@ -12,9 +12,12 @@ 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 = "."
+54 -55
View File
@@ -1,54 +1,41 @@
# -*- 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 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 .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
)
def _normalized(p):
@@ -694,7 +681,7 @@ class Project(object):
)
name = self.name if self.name is not None else "Pipfile"
config_parser = ConfigOptionParser(name=self.name)
config_parser = ConfigOptionParser(name=name)
config_parser.add_option_group(make_option_group(index_group, config_parser))
install = config_parser.option_groups[0]
indexes = (
@@ -793,7 +780,7 @@ class Project(object):
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", {})
}
@@ -869,7 +856,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.
"""
@@ -882,23 +870,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"""
@@ -943,17 +942,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
View File
@@ -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
View File
@@ -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
View File
@@ -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
+495 -285
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -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
+2 -2
View File
@@ -1,3 +1,3 @@
from .core import where, old_where
from .core import where
__version__ = "2018.10.15"
__version__ = "2018.11.29"
+242
View File
@@ -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-----
-17
View File
@@ -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())
-1
View File
@@ -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.
+1 -2
View File
@@ -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
View File
@@ -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)
-2
View File
@@ -78,5 +78,3 @@ def wrap_stream(stream, convert, strip, autoreset, wrap):
if wrapper.should_wrap():
stream = wrapper.stream
return stream
+7 -11
View File
@@ -89,11 +89,6 @@ else:
]
_SetConsoleTitleW.restype = wintypes.BOOL
handles = {
STDOUT: _GetStdHandle(STDOUT),
STDERR: _GetStdHandle(STDERR),
}
def _winapi_test(handle):
csbi = CONSOLE_SCREEN_BUFFER_INFO()
success = _GetConsoleScreenBufferInfo(
@@ -101,17 +96,18 @@ else:
return bool(success)
def winapi_test():
return any(_winapi_test(h) for h in handles.values())
return any(_winapi_test(h) for h in
(_GetStdHandle(STDOUT), _GetStdHandle(STDERR)))
def GetConsoleScreenBufferInfo(stream_id=STDOUT):
handle = handles[stream_id]
handle = _GetStdHandle(stream_id)
csbi = CONSOLE_SCREEN_BUFFER_INFO()
success = _GetConsoleScreenBufferInfo(
handle, byref(csbi))
return csbi
def SetConsoleTextAttribute(stream_id, attrs):
handle = handles[stream_id]
handle = _GetStdHandle(stream_id)
return _SetConsoleTextAttribute(handle, attrs)
def SetConsoleCursorPosition(stream_id, position, adjust=True):
@@ -129,11 +125,11 @@ else:
adjusted_position.Y += sr.Top
adjusted_position.X += sr.Left
# Resume normal processing
handle = handles[stream_id]
handle = _GetStdHandle(stream_id)
return _SetConsoleCursorPosition(handle, adjusted_position)
def FillConsoleOutputCharacter(stream_id, char, length, start):
handle = handles[stream_id]
handle = _GetStdHandle(stream_id)
char = c_char(char.encode())
length = wintypes.DWORD(length)
num_written = wintypes.DWORD(0)
@@ -144,7 +140,7 @@ else:
def FillConsoleOutputAttribute(stream_id, attr, length, start):
''' FillConsoleOutputAttribute( hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten )'''
handle = handles[stream_id]
handle = _GetStdHandle(stream_id)
attribute = wintypes.WORD(attr)
length = wintypes.DWORD(length)
num_written = wintypes.DWORD(0)
+9 -2
View File
@@ -44,6 +44,7 @@ class WinTerm(object):
def reset_all(self, on_stderr=None):
self.set_attrs(self._default)
self.set_console(attrs=self._default)
self._light = 0
def fore(self, fore=None, light=False, on_stderr=False):
if fore is None:
@@ -122,12 +123,15 @@ class WinTerm(object):
if mode == 0:
from_coord = csbi.dwCursorPosition
cells_to_erase = cells_in_screen - cells_before_cursor
if mode == 1:
elif mode == 1:
from_coord = win32.COORD(0, 0)
cells_to_erase = cells_before_cursor
elif mode == 2:
from_coord = win32.COORD(0, 0)
cells_to_erase = cells_in_screen
else:
# invalid mode
return
# fill the entire screen with blanks
win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord)
# now set the buffer's attributes accordingly
@@ -147,12 +151,15 @@ class WinTerm(object):
if mode == 0:
from_coord = csbi.dwCursorPosition
cells_to_erase = csbi.dwSize.X - csbi.dwCursorPosition.X
if mode == 1:
elif mode == 1:
from_coord = win32.COORD(0, csbi.dwCursorPosition.Y)
cells_to_erase = csbi.dwCursorPosition.X
elif mode == 2:
from_coord = win32.COORD(0, csbi.dwCursorPosition.Y)
cells_to_erase = csbi.dwSize.X
else:
# invalid mode
return
# fill the entire screen with blanks
win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord)
# now set the buffer's attributes accordingly
+5
View File
@@ -1,4 +1,9 @@
import sys
try:
from StringIO import StringIO # noqa
except ImportError:
from io import StringIO # noqa
PY2 = sys.version_info[0] == 2
WIN = sys.platform.startswith('win')
text_type = unicode if PY2 else str # noqa
+54
View File
@@ -0,0 +1,54 @@
import os
class UndefinedValueError(Exception):
pass
class Undefined(object):
"""Class to represent undefined type. """
pass
# Reference instance to represent undefined values
undefined = Undefined()
def _cast_boolean(value):
"""
Helper to convert config values to boolean as ConfigParser do.
"""
_BOOLEANS = {'1': True, 'yes': True, 'true': True, 'on': True,
'0': False, 'no': False, 'false': False, 'off': False, '': False}
value = str(value)
if value.lower() not in _BOOLEANS:
raise ValueError('Not a boolean: %s' % value)
return _BOOLEANS[value.lower()]
def getenv(option, default=undefined, cast=undefined):
"""
Return the value for option or default if defined.
"""
# We can't avoid __contains__ because value may be empty.
if option in os.environ:
value = os.environ[option]
else:
if isinstance(default, Undefined):
raise UndefinedValueError('{} not found. Declare it as envvar or define a default value.'.format(option))
value = default
if isinstance(cast, Undefined):
return value
if cast is bool:
value = _cast_boolean(value)
elif cast is list:
value = [x for x in value.split(',') if x]
else:
value = cast(value)
return value
+126 -88
View File
@@ -2,47 +2,90 @@
from __future__ import absolute_import, print_function, unicode_literals
import codecs
import fileinput
import io
import os
import re
import shutil
import sys
from subprocess import Popen, PIPE, STDOUT
from subprocess import Popen
import tempfile
import warnings
from collections import OrderedDict
from collections import OrderedDict, namedtuple
from contextlib import contextmanager
from .compat import StringIO
from .compat import StringIO, PY2, WIN, text_type
__escape_decoder = codecs.getdecoder('unicode_escape')
__posix_variable = re.compile('\$\{[^\}]*\}')
__posix_variable = re.compile(r'\$\{[^\}]*\}')
_binding = re.compile(
r"""
(
\s* # leading whitespace
(?:export{0}+)? # export
( '[^']+' # single-quoted key
| [^=\#\s]+ # or unquoted key
)?
(?:
(?:{0}*={0}*) # equal sign
( '(?:\\'|[^'])*' # single-quoted value
| "(?:\\"|[^"])*" # or double-quoted value
| [^\#\r\n]* # or unquoted value
)
)?
\s* # trailing whitespace
(?:\#[^\r\n]*)? # comment
(?:\r|\n|\r\n)? # newline
)
""".format(r'[^\S\r\n]'),
re.MULTILINE | re.VERBOSE,
)
_escape_sequence = re.compile(r"\\[\\'\"abfnrtv]")
def decode_escaped(escaped):
return __escape_decoder(escaped)[0]
Binding = namedtuple('Binding', 'key value original')
def parse_line(line):
line = line.strip()
def decode_escapes(string):
def decode_match(match):
return codecs.decode(match.group(0), 'unicode-escape')
# Ignore lines with `#` or which doesn't have `=` in it.
if not line or line.startswith('#') or '=' not in line:
return None, None
return _escape_sequence.sub(decode_match, string)
k, v = line.split('=', 1)
if k.startswith('export '):
(_, _, k) = k.partition('export ')
def is_surrounded_by(string, char):
return (
len(string) > 1
and string[0] == string[-1] == char
)
# Remove any leading and trailing spaces in key, value
k, v = k.strip(), v.strip()
if v:
v = v.encode('unicode-escape').decode('ascii')
quoted = v[0] == v[-1] in ['"', "'"]
if quoted:
v = decode_escaped(v[1:-1])
def parse_binding(string, position):
match = _binding.match(string, position)
(matched, key, value) = match.groups()
if key is None or value is None:
key = None
value = None
else:
value_quoted = is_surrounded_by(value, "'") or is_surrounded_by(value, '"')
if value_quoted:
value = decode_escapes(value[1:-1])
else:
value = value.strip()
return (Binding(key=key, value=value, original=matched), match.end())
return k, v
def parse_stream(stream):
string = stream.read()
position = 0
length = len(string)
while position < length:
(binding, position) = parse_binding(string, position)
yield binding
class DotEnv():
@@ -52,19 +95,17 @@ class DotEnv():
self._dict = None
self.verbose = verbose
@contextmanager
def _get_stream(self):
self._is_file = False
if isinstance(self.dotenv_path, StringIO):
return self.dotenv_path
if os.path.exists(self.dotenv_path):
self._is_file = True
return io.open(self.dotenv_path)
if self.verbose:
warnings.warn("File doesn't exist {}".format(self.dotenv_path))
return StringIO('')
yield self.dotenv_path
elif os.path.isfile(self.dotenv_path):
with io.open(self.dotenv_path) as stream:
yield stream
else:
if self.verbose:
warnings.warn("File doesn't exist {}".format(self.dotenv_path))
yield StringIO('')
def dict(self):
"""Return dotenv as dict"""
@@ -76,17 +117,10 @@ class DotEnv():
return self._dict
def parse(self):
f = self._get_stream()
for line in f:
key, value = parse_line(line)
if not key:
continue
yield key, value
if self._is_file:
f.close()
with self._get_stream() as stream:
for mapping in parse_stream(stream):
if mapping.key is not None and mapping.value is not None:
yield mapping.key, mapping.value
def set_as_environment_variables(self, override=False):
"""
@@ -95,13 +129,12 @@ class DotEnv():
for k, v in self.dict().items():
if k in os.environ and not override:
continue
# With Python 2 on Windows, ensuree environment variables are
# system strings to avoid "TypeError: environment can only contain
# strings" in Python's subprocess module.
if sys.version_info.major < 3 and sys.platform == 'win32':
from pipenv.utils import fs_str
k = fs_str(k)
v = fs_str(v)
# With Python2 on Windows, force environment variables to str to avoid
# "TypeError: environment can only contain strings" in Python's subprocess.py.
if PY2 and WIN:
if isinstance(k, text_type) or isinstance(v, text_type):
k = k.encode('ascii')
v = v.encode('ascii')
os.environ[k] = v
return True
@@ -127,6 +160,20 @@ def get_key(dotenv_path, key_to_get):
return DotEnv(dotenv_path, verbose=True).get(key_to_get)
@contextmanager
def rewrite(path):
try:
with tempfile.NamedTemporaryFile(mode="w+", delete=False) as dest:
with io.open(path) as source:
yield (source, dest)
except BaseException:
if os.path.isfile(dest.name):
os.unlink(dest.name)
raise
else:
shutil.move(dest.name, path)
def set_key(dotenv_path, key_to_set, value_to_set, quote_mode="always"):
"""
Adds or Updates a key/value to the given .env
@@ -142,20 +189,19 @@ def set_key(dotenv_path, key_to_set, value_to_set, quote_mode="always"):
if " " in value_to_set:
quote_mode = "always"
line_template = '{}="{}"' if quote_mode == "always" else '{}={}'
line_template = '{}="{}"\n' if quote_mode == "always" else '{}={}\n'
line_out = line_template.format(key_to_set, value_to_set)
replaced = False
for line in fileinput.input(dotenv_path, inplace=True):
k, v = parse_line(line)
if k == key_to_set:
replaced = True
line = line_out
print(line, end='')
if not replaced:
with io.open(dotenv_path, "a") as f:
f.write("{}\n".format(line_out))
with rewrite(dotenv_path) as (source, dest):
replaced = False
for mapping in parse_stream(source):
if mapping.key == key_to_set:
dest.write(line_out)
replaced = True
else:
dest.write(mapping.original)
if not replaced:
dest.write(line_out)
return True, key_to_set, value_to_set
@@ -167,18 +213,17 @@ def unset_key(dotenv_path, key_to_unset, quote_mode="always"):
If the .env path given doesn't exist, fails
If the given key doesn't exist in the .env, fails
"""
removed = False
if not os.path.exists(dotenv_path):
warnings.warn("can't delete from %s - it doesn't exist." % dotenv_path)
return None, key_to_unset
for line in fileinput.input(dotenv_path, inplace=True):
k, v = parse_line(line)
if k == key_to_unset:
removed = True
line = ''
print(line, end='')
removed = False
with rewrite(dotenv_path) as (source, dest):
for mapping in parse_stream(source):
if mapping.key == key_to_unset:
removed = True
else:
dest.write(mapping.original)
if not removed:
warnings.warn("key %s not removed from %s - key doesn't exist." % (key_to_unset, dotenv_path))
@@ -194,7 +239,7 @@ def resolve_nested_variables(values):
first search in environ, if not found,
then look into the dotenv variables
"""
ret = os.getenv(name, values.get(name, ""))
ret = os.getenv(name, new_values.get(name, ""))
return ret
def _re_sub_callback(match_object):
@@ -204,10 +249,12 @@ def resolve_nested_variables(values):
"""
return _replacement(match_object.group()[2:-1])
for k, v in values.items():
values[k] = __posix_variable.sub(_re_sub_callback, v)
new_values = {}
return values
for k, v in values.items():
new_values[k] = __posix_variable.sub(_re_sub_callback, v)
return new_values
def _walk_to_root(path):
@@ -248,7 +295,7 @@ def find_dotenv(filename='.env', raise_error_if_not_found=False, usecwd=False):
for dirname in _walk_to_root(path):
check_path = os.path.join(dirname, filename)
if os.path.exists(check_path):
if os.path.isfile(check_path):
return check_path
if raise_error_if_not_found:
@@ -292,19 +339,10 @@ def run_command(command, env):
cmd_env.update(env)
p = Popen(command,
stdin=PIPE,
stdout=PIPE,
stderr=STDOUT,
universal_newlines=True,
bufsize=0,
shell=False,
env=cmd_env)
try:
out, _ = p.communicate()
print(out)
except Exception:
warnings.warn('An error occured, running the command:')
out, _ = p.communicate()
warnings.warn(out)
_, _ = p.communicate()
return p.returncode
+1 -1
View File
@@ -1 +1 @@
__version__ = "0.9.1"
__version__ = "0.10.1"
Vendored Executable → Regular
View File
Vendored Executable → Regular
View File
Vendored Executable → Regular
View File
Vendored Executable → Regular
+1 -4
View File
@@ -267,10 +267,7 @@ def alabel(label):
try:
label = label.encode('ascii')
try:
ulabel(label)
except IDNAError:
raise IDNAError('The label {0} is not a valid A-label'.format(label))
ulabel(label)
if not valid_label_length(label):
raise IDNAError('Label too long')
return label
Vendored Executable → Regular
+104 -18
View File
@@ -1,6 +1,6 @@
# This file is automatically generated by tools/idna-data
__version__ = "10.0.0"
__version__ = "11.0.0"
scripts = {
'Greek': (
0x37000000374,
@@ -49,7 +49,7 @@ scripts = {
0x30210000302a,
0x30380000303c,
0x340000004db6,
0x4e0000009feb,
0x4e0000009ff0,
0xf9000000fa6e,
0xfa700000fada,
0x200000002a6d7,
@@ -62,7 +62,7 @@ scripts = {
'Hebrew': (
0x591000005c8,
0x5d0000005eb,
0x5f0000005f5,
0x5ef000005f5,
0xfb1d0000fb37,
0xfb380000fb3d,
0xfb3e0000fb3f,
@@ -248,6 +248,7 @@ joining_types = {
0x6fb: 68,
0x6fc: 68,
0x6ff: 68,
0x70f: 84,
0x710: 82,
0x712: 68,
0x713: 68,
@@ -522,6 +523,7 @@ joining_types = {
0x1875: 68,
0x1876: 68,
0x1877: 68,
0x1878: 68,
0x1880: 85,
0x1881: 85,
0x1882: 85,
@@ -690,6 +692,70 @@ joining_types = {
0x10bad: 68,
0x10bae: 68,
0x10baf: 85,
0x10d00: 76,
0x10d01: 68,
0x10d02: 68,
0x10d03: 68,
0x10d04: 68,
0x10d05: 68,
0x10d06: 68,
0x10d07: 68,
0x10d08: 68,
0x10d09: 68,
0x10d0a: 68,
0x10d0b: 68,
0x10d0c: 68,
0x10d0d: 68,
0x10d0e: 68,
0x10d0f: 68,
0x10d10: 68,
0x10d11: 68,
0x10d12: 68,
0x10d13: 68,
0x10d14: 68,
0x10d15: 68,
0x10d16: 68,
0x10d17: 68,
0x10d18: 68,
0x10d19: 68,
0x10d1a: 68,
0x10d1b: 68,
0x10d1c: 68,
0x10d1d: 68,
0x10d1e: 68,
0x10d1f: 68,
0x10d20: 68,
0x10d21: 68,
0x10d22: 82,
0x10d23: 68,
0x10f30: 68,
0x10f31: 68,
0x10f32: 68,
0x10f33: 82,
0x10f34: 68,
0x10f35: 68,
0x10f36: 68,
0x10f37: 68,
0x10f38: 68,
0x10f39: 68,
0x10f3a: 68,
0x10f3b: 68,
0x10f3c: 68,
0x10f3d: 68,
0x10f3e: 68,
0x10f3f: 68,
0x10f40: 68,
0x10f41: 68,
0x10f42: 68,
0x10f43: 68,
0x10f44: 68,
0x10f45: 85,
0x10f51: 68,
0x10f52: 68,
0x10f53: 68,
0x10f54: 82,
0x110bd: 85,
0x110cd: 85,
0x1e900: 68,
0x1e901: 68,
0x1e902: 68,
@@ -1034,14 +1100,15 @@ codepoint_classes = {
0x52d0000052e,
0x52f00000530,
0x5590000055a,
0x56100000587,
0x56000000587,
0x58800000589,
0x591000005be,
0x5bf000005c0,
0x5c1000005c3,
0x5c4000005c6,
0x5c7000005c8,
0x5d0000005eb,
0x5f0000005f3,
0x5ef000005f3,
0x6100000061b,
0x62000000640,
0x64100000660,
@@ -1054,12 +1121,13 @@ codepoint_classes = {
0x7100000074b,
0x74d000007b2,
0x7c0000007f6,
0x7fd000007fe,
0x8000000082e,
0x8400000085c,
0x8600000086b,
0x8a0000008b5,
0x8b6000008be,
0x8d4000008e2,
0x8d3000008e2,
0x8e300000958,
0x96000000964,
0x96600000970,
@@ -1077,6 +1145,7 @@ codepoint_classes = {
0x9e0000009e4,
0x9e6000009f2,
0x9fc000009fd,
0x9fe000009ff,
0xa0100000a04,
0xa0500000a0b,
0xa0f00000a11,
@@ -1136,8 +1205,7 @@ codepoint_classes = {
0xbd000000bd1,
0xbd700000bd8,
0xbe600000bf0,
0xc0000000c04,
0xc0500000c0d,
0xc0000000c0d,
0xc0e00000c11,
0xc1200000c29,
0xc2a00000c3a,
@@ -1276,7 +1344,7 @@ codepoint_classes = {
0x17dc000017de,
0x17e0000017ea,
0x18100000181a,
0x182000001878,
0x182000001879,
0x1880000018ab,
0x18b0000018f6,
0x19000000191f,
@@ -1544,11 +1612,11 @@ codepoint_classes = {
0x309d0000309f,
0x30a1000030fb,
0x30fc000030ff,
0x31050000312f,
0x310500003130,
0x31a0000031bb,
0x31f000003200,
0x340000004db6,
0x4e0000009feb,
0x4e0000009ff0,
0xa0000000a48d,
0xa4d00000a4fe,
0xa5000000a60d,
@@ -1655,8 +1723,10 @@ codepoint_classes = {
0xa7a50000a7a6,
0xa7a70000a7a8,
0xa7a90000a7aa,
0xa7af0000a7b0,
0xa7b50000a7b6,
0xa7b70000a7b8,
0xa7b90000a7ba,
0xa7f70000a7f8,
0xa7fa0000a828,
0xa8400000a874,
@@ -1664,8 +1734,7 @@ codepoint_classes = {
0xa8d00000a8da,
0xa8e00000a8f8,
0xa8fb0000a8fc,
0xa8fd0000a8fe,
0xa9000000a92e,
0xa8fd0000a92e,
0xa9300000a954,
0xa9800000a9c1,
0xa9cf0000a9da,
@@ -1743,7 +1812,7 @@ codepoint_classes = {
0x10a0500010a07,
0x10a0c00010a14,
0x10a1500010a18,
0x10a1900010a34,
0x10a1900010a36,
0x10a3800010a3b,
0x10a3f00010a40,
0x10a6000010a7d,
@@ -1756,6 +1825,11 @@ codepoint_classes = {
0x10b8000010b92,
0x10c0000010c49,
0x10cc000010cf3,
0x10d0000010d28,
0x10d3000010d3a,
0x10f0000010f1d,
0x10f2700010f28,
0x10f3000010f51,
0x1100000011047,
0x1106600011070,
0x1107f000110bb,
@@ -1763,10 +1837,11 @@ codepoint_classes = {
0x110f0000110fa,
0x1110000011135,
0x1113600011140,
0x1114400011147,
0x1115000011174,
0x1117600011177,
0x11180000111c5,
0x111ca000111cd,
0x111c9000111cd,
0x111d0000111db,
0x111dc000111dd,
0x1120000011212,
@@ -1786,7 +1861,7 @@ codepoint_classes = {
0x1132a00011331,
0x1133200011334,
0x113350001133a,
0x1133c00011345,
0x1133b00011345,
0x1134700011349,
0x1134b0001134e,
0x1135000011351,
@@ -1796,6 +1871,7 @@ codepoint_classes = {
0x1137000011375,
0x114000001144b,
0x114500001145a,
0x1145e0001145f,
0x11480000114c6,
0x114c7000114c8,
0x114d0000114da,
@@ -1807,15 +1883,17 @@ codepoint_classes = {
0x116500001165a,
0x11680000116b8,
0x116c0000116ca,
0x117000001171a,
0x117000001171b,
0x1171d0001172c,
0x117300001173a,
0x118000001183b,
0x118c0000118ea,
0x118ff00011900,
0x11a0000011a3f,
0x11a4700011a48,
0x11a5000011a84,
0x11a8600011a9a,
0x11a9d00011a9e,
0x11ac000011af9,
0x11c0000011c09,
0x11c0a00011c37,
@@ -1831,6 +1909,13 @@ codepoint_classes = {
0x11d3c00011d3e,
0x11d3f00011d48,
0x11d5000011d5a,
0x11d6000011d66,
0x11d6700011d69,
0x11d6a00011d8f,
0x11d9000011d92,
0x11d9300011d99,
0x11da000011daa,
0x11ee000011ef7,
0x120000001239a,
0x1248000012544,
0x130000001342f,
@@ -1845,11 +1930,12 @@ codepoint_classes = {
0x16b5000016b5a,
0x16b6300016b78,
0x16b7d00016b90,
0x16e6000016e80,
0x16f0000016f45,
0x16f5000016f7f,
0x16f8f00016fa0,
0x16fe000016fe2,
0x17000000187ed,
0x17000000187f2,
0x1880000018af3,
0x1b0000001b11f,
0x1b1700001b2fc,
Vendored Executable → Regular
View File
Vendored Executable → Regular
+1 -1
View File
@@ -1,2 +1,2 @@
__version__ = '2.7'
__version__ = '2.8'
Vendored Executable → Regular
+343 -317
View File
File diff suppressed because it is too large Load Diff
+10 -4
View File
@@ -4,18 +4,24 @@
from __future__ import absolute_import, division, print_function
__all__ = [
"__title__", "__summary__", "__uri__", "__version__", "__author__",
"__email__", "__license__", "__copyright__",
"__title__",
"__summary__",
"__uri__",
"__version__",
"__author__",
"__email__",
"__license__",
"__copyright__",
]
__title__ = "packaging"
__summary__ = "Core utilities for Python packages"
__uri__ = "https://github.com/pypa/packaging"
__version__ = "18.0"
__version__ = "19.0"
__author__ = "Donald Stufft and individual contributors"
__email__ = "donald@stufft.io"
__license__ = "BSD or Apache License, Version 2.0"
__copyright__ = "Copyright 2014-2018 %s" % __author__
__copyright__ = "Copyright 2014-2019 %s" % __author__
+16 -4
View File
@@ -4,11 +4,23 @@
from __future__ import absolute_import, division, print_function
from .__about__ import (
__author__, __copyright__, __email__, __license__, __summary__, __title__,
__uri__, __version__
__author__,
__copyright__,
__email__,
__license__,
__summary__,
__title__,
__uri__,
__version__,
)
__all__ = [
"__title__", "__summary__", "__uri__", "__version__", "__author__",
"__email__", "__license__", "__copyright__",
"__title__",
"__summary__",
"__uri__",
"__version__",
"__author__",
"__email__",
"__license__",
"__copyright__",
]
+4 -3
View File
@@ -12,9 +12,9 @@ PY3 = sys.version_info[0] == 3
# flake8: noqa
if PY3:
string_types = str,
string_types = (str,)
else:
string_types = basestring,
string_types = (basestring,)
def with_metaclass(meta, *bases):
@@ -27,4 +27,5 @@ def with_metaclass(meta, *bases):
class metaclass(meta):
def __new__(cls, name, this_bases, d):
return meta(name, bases, d)
return type.__new__(metaclass, 'temporary_class', (), {})
return type.__new__(metaclass, "temporary_class", (), {})
-2
View File
@@ -5,7 +5,6 @@ from __future__ import absolute_import, division, print_function
class Infinity(object):
def __repr__(self):
return "Infinity"
@@ -38,7 +37,6 @@ Infinity = Infinity()
class NegativeInfinity(object):
def __repr__(self):
return "-Infinity"
+42 -47
View File
@@ -17,8 +17,11 @@ from .specifiers import Specifier, InvalidSpecifier
__all__ = [
"InvalidMarker", "UndefinedComparison", "UndefinedEnvironmentName",
"Marker", "default_environment",
"InvalidMarker",
"UndefinedComparison",
"UndefinedEnvironmentName",
"Marker",
"default_environment",
]
@@ -42,7 +45,6 @@ class UndefinedEnvironmentName(ValueError):
class Node(object):
def __init__(self, value):
self.value = value
@@ -57,62 +59,52 @@ class Node(object):
class Variable(Node):
def serialize(self):
return str(self)
class Value(Node):
def serialize(self):
return '"{0}"'.format(self)
class Op(Node):
def serialize(self):
return str(self)
VARIABLE = (
L("implementation_version") |
L("platform_python_implementation") |
L("implementation_name") |
L("python_full_version") |
L("platform_release") |
L("platform_version") |
L("platform_machine") |
L("platform_system") |
L("python_version") |
L("sys_platform") |
L("os_name") |
L("os.name") | # PEP-345
L("sys.platform") | # PEP-345
L("platform.version") | # PEP-345
L("platform.machine") | # PEP-345
L("platform.python_implementation") | # PEP-345
L("python_implementation") | # undocumented setuptools legacy
L("extra")
L("implementation_version")
| L("platform_python_implementation")
| L("implementation_name")
| L("python_full_version")
| L("platform_release")
| L("platform_version")
| L("platform_machine")
| L("platform_system")
| L("python_version")
| L("sys_platform")
| L("os_name")
| L("os.name")
| L("sys.platform") # PEP-345
| L("platform.version") # PEP-345
| L("platform.machine") # PEP-345
| L("platform.python_implementation") # PEP-345
| L("python_implementation") # PEP-345
| L("extra") # undocumented setuptools legacy
)
ALIASES = {
'os.name': 'os_name',
'sys.platform': 'sys_platform',
'platform.version': 'platform_version',
'platform.machine': 'platform_machine',
'platform.python_implementation': 'platform_python_implementation',
'python_implementation': 'platform_python_implementation'
"os.name": "os_name",
"sys.platform": "sys_platform",
"platform.version": "platform_version",
"platform.machine": "platform_machine",
"platform.python_implementation": "platform_python_implementation",
"python_implementation": "platform_python_implementation",
}
VARIABLE.setParseAction(lambda s, l, t: Variable(ALIASES.get(t[0], t[0])))
VERSION_CMP = (
L("===") |
L("==") |
L(">=") |
L("<=") |
L("!=") |
L("~=") |
L(">") |
L("<")
L("===") | L("==") | L(">=") | L("<=") | L("!=") | L("~=") | L(">") | L("<")
)
MARKER_OP = VERSION_CMP | L("not in") | L("in")
@@ -152,8 +144,11 @@ def _format_marker(marker, first=True):
# where the single item is itself it's own list. In that case we want skip
# the rest of this function so that we don't get extraneous () on the
# outside.
if (isinstance(marker, list) and len(marker) == 1 and
isinstance(marker[0], (list, tuple))):
if (
isinstance(marker, list)
and len(marker) == 1
and isinstance(marker[0], (list, tuple))
):
return _format_marker(marker[0])
if isinstance(marker, list):
@@ -239,20 +234,20 @@ def _evaluate_markers(markers, environment):
def format_full_version(info):
version = '{0.major}.{0.minor}.{0.micro}'.format(info)
version = "{0.major}.{0.minor}.{0.micro}".format(info)
kind = info.releaselevel
if kind != 'final':
if kind != "final":
version += kind[0] + str(info.serial)
return version
def default_environment():
if hasattr(sys, 'implementation'):
if hasattr(sys, "implementation"):
iver = format_full_version(sys.implementation.version)
implementation_name = sys.implementation.name
else:
iver = '0'
implementation_name = ''
iver = "0"
implementation_name = ""
return {
"implementation_name": implementation_name,
@@ -270,13 +265,13 @@ def default_environment():
class Marker(object):
def __init__(self, marker):
try:
self._markers = _coerce_parse_result(MARKER.parseString(marker))
except ParseException as e:
err_str = "Invalid marker: {0!r}, parse error at {1!r}".format(
marker, marker[e.loc:e.loc + 8])
marker, marker[e.loc : e.loc + 8]
)
raise InvalidMarker(err_str)
def __str__(self):
+21 -13
View File
@@ -38,8 +38,8 @@ IDENTIFIER = Combine(ALPHANUM + ZeroOrMore(IDENTIFIER_END))
NAME = IDENTIFIER("name")
EXTRA = IDENTIFIER
URI = Regex(r'[^ ]+')("url")
URL = (AT + URI)
URI = Regex(r"[^ ]+")("url")
URL = AT + URI
EXTRAS_LIST = EXTRA + ZeroOrMore(COMMA + EXTRA)
EXTRAS = (LBRACKET + Optional(EXTRAS_LIST) + RBRACKET)("extras")
@@ -48,17 +48,18 @@ VERSION_PEP440 = Regex(Specifier._regex_str, re.VERBOSE | re.IGNORECASE)
VERSION_LEGACY = Regex(LegacySpecifier._regex_str, re.VERBOSE | re.IGNORECASE)
VERSION_ONE = VERSION_PEP440 ^ VERSION_LEGACY
VERSION_MANY = Combine(VERSION_ONE + ZeroOrMore(COMMA + VERSION_ONE),
joinString=",", adjacent=False)("_raw_spec")
VERSION_MANY = Combine(
VERSION_ONE + ZeroOrMore(COMMA + VERSION_ONE), joinString=",", adjacent=False
)("_raw_spec")
_VERSION_SPEC = Optional(((LPAREN + VERSION_MANY + RPAREN) | VERSION_MANY))
_VERSION_SPEC.setParseAction(lambda s, l, t: t._raw_spec or '')
_VERSION_SPEC.setParseAction(lambda s, l, t: t._raw_spec or "")
VERSION_SPEC = originalTextFor(_VERSION_SPEC)("specifier")
VERSION_SPEC.setParseAction(lambda s, l, t: t[1])
MARKER_EXPR = originalTextFor(MARKER_EXPR())("marker")
MARKER_EXPR.setParseAction(
lambda s, l, t: Marker(s[t._original_start:t._original_end])
lambda s, l, t: Marker(s[t._original_start : t._original_end])
)
MARKER_SEPARATOR = SEMICOLON
MARKER = MARKER_SEPARATOR + MARKER_EXPR
@@ -66,8 +67,7 @@ MARKER = MARKER_SEPARATOR + MARKER_EXPR
VERSION_AND_MARKER = VERSION_SPEC + Optional(MARKER)
URL_AND_MARKER = URL + Optional(MARKER)
NAMED_REQUIREMENT = \
NAME + Optional(EXTRAS) + (URL_AND_MARKER | VERSION_AND_MARKER)
NAMED_REQUIREMENT = NAME + Optional(EXTRAS) + (URL_AND_MARKER | VERSION_AND_MARKER)
REQUIREMENT = stringStart + NAMED_REQUIREMENT + stringEnd
# pyparsing isn't thread safe during initialization, so we do it eagerly, see
@@ -92,15 +92,21 @@ class Requirement(object):
try:
req = REQUIREMENT.parseString(requirement_string)
except ParseException as e:
raise InvalidRequirement("Parse error at \"{0!r}\": {1}".format(
requirement_string[e.loc:e.loc + 8], e.msg
))
raise InvalidRequirement(
'Parse error at "{0!r}": {1}'.format(
requirement_string[e.loc : e.loc + 8], e.msg
)
)
self.name = req.name
if req.url:
parsed_url = urlparse.urlparse(req.url)
if not (parsed_url.scheme and parsed_url.netloc) or (
not parsed_url.scheme and not parsed_url.netloc):
if parsed_url.scheme == "file":
if urlparse.urlunparse(parsed_url) != req.url:
raise InvalidRequirement("Invalid URL given")
elif not (parsed_url.scheme and parsed_url.netloc) or (
not parsed_url.scheme and not parsed_url.netloc
):
raise InvalidRequirement("Invalid URL: {0}".format(req.url))
self.url = req.url
else:
@@ -120,6 +126,8 @@ class Requirement(object):
if self.url:
parts.append("@ {0}".format(self.url))
if self.marker:
parts.append(" ")
if self.marker:
parts.append("; {0}".format(self.marker))
+21 -46
View File
@@ -19,7 +19,6 @@ class InvalidSpecifier(ValueError):
class BaseSpecifier(with_metaclass(abc.ABCMeta, object)):
@abc.abstractmethod
def __str__(self):
"""
@@ -84,10 +83,7 @@ class _IndividualSpecifier(BaseSpecifier):
if not match:
raise InvalidSpecifier("Invalid specifier: '{0}'".format(spec))
self._spec = (
match.group("operator").strip(),
match.group("version").strip(),
)
self._spec = (match.group("operator").strip(), match.group("version").strip())
# Store whether or not this Specifier should accept prereleases
self._prereleases = prereleases
@@ -99,11 +95,7 @@ class _IndividualSpecifier(BaseSpecifier):
else ""
)
return "<{0}({1!r}{2})>".format(
self.__class__.__name__,
str(self),
pre,
)
return "<{0}({1!r}{2})>".format(self.__class__.__name__, str(self), pre)
def __str__(self):
return "{0}{1}".format(*self._spec)
@@ -194,8 +186,9 @@ class _IndividualSpecifier(BaseSpecifier):
# If our version is a prerelease, and we were not set to allow
# prereleases, then we'll store it for later incase nothing
# else matches this specifier.
if (parsed_version.is_prerelease and not
(prereleases or self.prereleases)):
if parsed_version.is_prerelease and not (
prereleases or self.prereleases
):
found_prereleases.append(version)
# Either this is not a prerelease, or we should have been
# accepting prereleases from the beginning.
@@ -213,8 +206,7 @@ class _IndividualSpecifier(BaseSpecifier):
class LegacySpecifier(_IndividualSpecifier):
_regex_str = (
r"""
_regex_str = r"""
(?P<operator>(==|!=|<=|>=|<|>))
\s*
(?P<version>
@@ -225,10 +217,8 @@ class LegacySpecifier(_IndividualSpecifier):
# them, and a comma since it's a version separator.
)
"""
)
_regex = re.compile(
r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE)
_regex = re.compile(r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE)
_operators = {
"==": "equal",
@@ -269,13 +259,13 @@ def _require_version_compare(fn):
if not isinstance(prospective, Version):
return False
return fn(self, prospective, spec)
return wrapped
class Specifier(_IndividualSpecifier):
_regex_str = (
r"""
_regex_str = r"""
(?P<operator>(~=|==|!=|<=|>=|<|>|===))
(?P<version>
(?:
@@ -367,10 +357,8 @@ class Specifier(_IndividualSpecifier):
)
)
"""
)
_regex = re.compile(
r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE)
_regex = re.compile(r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE)
_operators = {
"~=": "compatible",
@@ -397,8 +385,7 @@ class Specifier(_IndividualSpecifier):
prefix = ".".join(
list(
itertools.takewhile(
lambda x: (not x.startswith("post") and not
x.startswith("dev")),
lambda x: (not x.startswith("post") and not x.startswith("dev")),
_version_split(spec),
)
)[:-1]
@@ -407,8 +394,9 @@ class Specifier(_IndividualSpecifier):
# Add the prefix notation to the end of our string
prefix += ".*"
return (self._get_operator(">=")(prospective, spec) and
self._get_operator("==")(prospective, prefix))
return self._get_operator(">=")(prospective, spec) and self._get_operator("==")(
prospective, prefix
)
@_require_version_compare
def _compare_equal(self, prospective, spec):
@@ -428,7 +416,7 @@ class Specifier(_IndividualSpecifier):
# Shorten the prospective version to be the same length as the spec
# so that we can determine if the specifier is a prefix of the
# prospective version or not.
prospective = prospective[:len(spec)]
prospective = prospective[: len(spec)]
# Pad out our two sides with zeros so that they both equal the same
# length.
@@ -567,27 +555,17 @@ def _pad_version(left, right):
right_split.append(list(itertools.takewhile(lambda x: x.isdigit(), right)))
# Get the rest of our versions
left_split.append(left[len(left_split[0]):])
right_split.append(right[len(right_split[0]):])
left_split.append(left[len(left_split[0]) :])
right_split.append(right[len(right_split[0]) :])
# Insert our padding
left_split.insert(
1,
["0"] * max(0, len(right_split[0]) - len(left_split[0])),
)
right_split.insert(
1,
["0"] * max(0, len(left_split[0]) - len(right_split[0])),
)
left_split.insert(1, ["0"] * max(0, len(right_split[0]) - len(left_split[0])))
right_split.insert(1, ["0"] * max(0, len(left_split[0]) - len(right_split[0])))
return (
list(itertools.chain(*left_split)),
list(itertools.chain(*right_split)),
)
return (list(itertools.chain(*left_split)), list(itertools.chain(*right_split)))
class SpecifierSet(BaseSpecifier):
def __init__(self, specifiers="", prereleases=None):
# Split on , to break each indidivual specifier into it's own item, and
# strip each item to remove leading/trailing whitespace.
@@ -721,10 +699,7 @@ class SpecifierSet(BaseSpecifier):
# given version is contained within all of them.
# Note: This use of all() here means that an empty set of specifiers
# will always return True, this is an explicit design decision.
return all(
s.contains(item, prereleases=prereleases)
for s in self._specs
)
return all(s.contains(item, prereleases=prereleases) for s in self._specs)
def filter(self, iterable, prereleases=None):
# Determine if we're forcing a prerelease or not, if we're not forcing
+1 -7
View File
@@ -36,13 +36,7 @@ def canonicalize_version(version):
# Release segment
# NB: This strips trailing '.0's to normalize
parts.append(
re.sub(
r'(\.0)+$',
'',
".".join(str(x) for x in version.release)
)
)
parts.append(re.sub(r"(\.0)+$", "", ".".join(str(x) for x in version.release)))
# Pre-release
if version.pre is not None:
+14 -35
View File
@@ -10,14 +10,11 @@ import re
from ._structures import Infinity
__all__ = [
"parse", "Version", "LegacyVersion", "InvalidVersion", "VERSION_PATTERN"
]
__all__ = ["parse", "Version", "LegacyVersion", "InvalidVersion", "VERSION_PATTERN"]
_Version = collections.namedtuple(
"_Version",
["epoch", "release", "dev", "pre", "post", "local"],
"_Version", ["epoch", "release", "dev", "pre", "post", "local"]
)
@@ -40,7 +37,6 @@ class InvalidVersion(ValueError):
class _BaseVersion(object):
def __hash__(self):
return hash(self._key)
@@ -70,7 +66,6 @@ class _BaseVersion(object):
class LegacyVersion(_BaseVersion):
def __init__(self, version):
self._version = str(version)
self._key = _legacy_cmpkey(self._version)
@@ -126,12 +121,14 @@ class LegacyVersion(_BaseVersion):
return False
_legacy_version_component_re = re.compile(
r"(\d+ | [a-z]+ | \.| -)", re.VERBOSE,
)
_legacy_version_component_re = re.compile(r"(\d+ | [a-z]+ | \.| -)", re.VERBOSE)
_legacy_version_replacement_map = {
"pre": "c", "preview": "c", "-": "final-", "rc": "c", "dev": "@",
"pre": "c",
"preview": "c",
"-": "final-",
"rc": "c",
"dev": "@",
}
@@ -215,10 +212,7 @@ VERSION_PATTERN = r"""
class Version(_BaseVersion):
_regex = re.compile(
r"^\s*" + VERSION_PATTERN + r"\s*$",
re.VERBOSE | re.IGNORECASE,
)
_regex = re.compile(r"^\s*" + VERSION_PATTERN + r"\s*$", re.VERBOSE | re.IGNORECASE)
def __init__(self, version):
# Validate the version and parse it into pieces
@@ -230,18 +224,11 @@ class Version(_BaseVersion):
self._version = _Version(
epoch=int(match.group("epoch")) if match.group("epoch") else 0,
release=tuple(int(i) for i in match.group("release").split(".")),
pre=_parse_letter_version(
match.group("pre_l"),
match.group("pre_n"),
),
pre=_parse_letter_version(match.group("pre_l"), match.group("pre_n")),
post=_parse_letter_version(
match.group("post_l"),
match.group("post_n1") or match.group("post_n2"),
),
dev=_parse_letter_version(
match.group("dev_l"),
match.group("dev_n"),
match.group("post_l"), match.group("post_n1") or match.group("post_n2")
),
dev=_parse_letter_version(match.group("dev_l"), match.group("dev_n")),
local=_parse_local_version(match.group("local")),
)
@@ -395,12 +382,7 @@ def _cmpkey(epoch, release, pre, post, dev, local):
# re-reverse it back into the correct order and make it a tuple and use
# that for our sorting key.
release = tuple(
reversed(list(
itertools.dropwhile(
lambda x: x == 0,
reversed(release),
)
))
reversed(list(itertools.dropwhile(lambda x: x == 0, reversed(release))))
)
# We need to "trick" the sorting algorithm to put 1.0.dev0 before 1.0a0.
@@ -433,9 +415,6 @@ def _cmpkey(epoch, release, pre, post, dev, local):
# - Numeric segments sort numerically
# - Shorter versions sort before longer versions when the prefixes
# match exactly
local = tuple(
(i, "") if isinstance(i, int) else (-Infinity, i)
for i in local
)
local = tuple((i, "") if isinstance(i, int) else (-Infinity, i) for i in local)
return epoch, release, pre, post, dev, local

Some files were not shown because too many files have changed in this diff Show More