mirror of
https://github.com/enpaul/tox-poetry-installer.git
synced 2025-10-28 07:00:43 +00:00
Compare commits
41 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4de5fea0e3 | |||
| 33119df752 | |||
| 498cb4a3d2 | |||
| 0a363d1848 | |||
| 429992cff9 | |||
| 216ee8b095 | |||
| e96f4fb5e5 | |||
| eebd16383d | |||
| add4ec62eb | |||
| 0c25ca965e | |||
| 6a5e955fce | |||
| d910b6ee8d | |||
| e37c166a8b | |||
| 3d6d39eca8 | |||
| b9b0eba90f | |||
| df8312f5ee | |||
| 1f102b16cb | |||
| a7cde7a9ab | |||
| b0bee11272 | |||
| accb4c3278 | |||
| ea183553c4 | |||
| 5c5536581b | |||
| b6ef671e67 | |||
| 99c10482fc | |||
| b32a212e82 | |||
| b6415888d9 | |||
| eba268a127 | |||
| d8d483e849 | |||
| c14313b7b0 | |||
| d1f161e0fa | |||
| 2961b55c9a | |||
| d4fb7046d8 | |||
| 8c4e596316 | |||
| 50f6e3d151 | |||
| 106d1bf6cf | |||
| b57b78d4e2 | |||
| 33e81f742a | |||
| 3a262d718c | |||
| 5979ec7a8a | |||
| c7bb3d35ea | |||
| 961e6f6acd |
10
.github/workflows/ci.yaml
vendored
10
.github/workflows/ci.yaml
vendored
@@ -17,14 +17,16 @@ jobs:
|
|||||||
toxenv: py37
|
toxenv: py37
|
||||||
- version: 3.8
|
- version: 3.8
|
||||||
toxenv: py38
|
toxenv: py38
|
||||||
|
- version: 3.9
|
||||||
|
toxenv: py39
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Set up Python ${{ matrix.python.version }}
|
- name: Set up Python ${{ matrix.python.version }}
|
||||||
uses: actions/setup-python@v1
|
uses: actions/setup-python@v1
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python.version }}
|
python-version: ${{ matrix.python.version }}
|
||||||
- name: Install tox
|
- name: Install project
|
||||||
run: pip install "tox>=3.20.0,<3.21.0" --upgrade
|
run: pip install .
|
||||||
- name: Run tests via ${{ matrix.python.toxenv }}
|
- name: Run tests via ${{ matrix.python.toxenv }}
|
||||||
run: tox -e ${{ matrix.python.toxenv }}
|
run: tox -e ${{ matrix.python.toxenv }}
|
||||||
Check:
|
Check:
|
||||||
@@ -35,7 +37,7 @@ jobs:
|
|||||||
uses: actions/setup-python@v1
|
uses: actions/setup-python@v1
|
||||||
with:
|
with:
|
||||||
python-version: 3.8
|
python-version: 3.8
|
||||||
- name: Install tox requirements
|
- name: Install project
|
||||||
run: pip install "tox>=3.20.0,<3.21.0" --upgrade
|
run: pip install .
|
||||||
- name: Run meta checks
|
- name: Run meta checks
|
||||||
run: tox -e static -e static-tests -e security
|
run: tox -e static -e static-tests -e security
|
||||||
|
|||||||
@@ -1,28 +1,48 @@
|
|||||||
---
|
---
|
||||||
|
# All of the pre-commit hooks here actually use the `pytyhon` pre-commit language
|
||||||
|
# setting. However, for the python language setting, pre-commit will create and manage
|
||||||
|
# a cached virtual environment for each hook ID and do a bare `pip install <repo>` into
|
||||||
|
# the venv to setup the hook. This can result in conflicting dependency versions between
|
||||||
|
# the version installed to the pre-commit venv and the version installed to the Poetry
|
||||||
|
# venv specified in the lockfile.
|
||||||
|
#
|
||||||
|
# The solution is to specify `language: system` for all hooks and then install the
|
||||||
|
# required dependencies to the Poetry venv. The `system` language skips the isolated
|
||||||
|
# venv creation and looks for the entrypoint specified by the hook in the global
|
||||||
|
# environment which, if running in the Poetry venv, will find the entrypoint provided
|
||||||
|
# by the Poetry-managed dependency.
|
||||||
|
#
|
||||||
repos:
|
repos:
|
||||||
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
|
rev: v3.3.0
|
||||||
|
hooks:
|
||||||
|
- id: end-of-file-fixer
|
||||||
|
language: system
|
||||||
|
- id: fix-encoding-pragma
|
||||||
|
args:
|
||||||
|
- "--remove"
|
||||||
|
language: system
|
||||||
|
- id: trailing-whitespace
|
||||||
|
language: system
|
||||||
|
- id: check-merge-conflict
|
||||||
|
language: system
|
||||||
|
|
||||||
- repo: https://github.com/psf/black
|
- repo: https://github.com/psf/black
|
||||||
rev: 20.8b1
|
rev: 20.8b1
|
||||||
hooks:
|
hooks:
|
||||||
- id: black
|
- id: black
|
||||||
language_version: python3
|
language: system
|
||||||
|
|
||||||
- repo: https://github.com/asottile/blacken-docs
|
- repo: https://github.com/asottile/blacken-docs
|
||||||
rev: v0.5.0
|
rev: v1.8.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: blacken-docs
|
- id: blacken-docs
|
||||||
additional_dependencies: [black==20.8b1]
|
language: system
|
||||||
language_version: python3
|
|
||||||
|
|
||||||
- repo: https://github.com/asottile/reorder_python_imports
|
- repo: https://github.com/asottile/reorder_python_imports
|
||||||
rev: v2.3.5
|
rev: v2.3.6
|
||||||
hooks:
|
hooks:
|
||||||
- id: reorder-python-imports
|
- id: reorder-python-imports
|
||||||
language_version: python3
|
args:
|
||||||
|
- "--unclassifiable-application-module=tox_poetry_installer"
|
||||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
language: system
|
||||||
rev: v2.0.0
|
|
||||||
hooks:
|
|
||||||
- id: end-of-file-fixer
|
|
||||||
- id: fix-encoding-pragma
|
|
||||||
args: [--remove]
|
|
||||||
- id: trailing-whitespace
|
|
||||||
|
|||||||
2
Makefile
2
Makefile
@@ -33,4 +33,4 @@ test: ## Run the project testsuite(s)
|
|||||||
poetry run tox --recreate
|
poetry run tox --recreate
|
||||||
|
|
||||||
publish: wheel source ## Build and upload to pypi (requires $PYPI_API_KEY be set)
|
publish: wheel source ## Build and upload to pypi (requires $PYPI_API_KEY be set)
|
||||||
poetry publish --username __token__ --password $(PYPI_API_KEY)
|
@poetry publish --username __token__ --password $(PYPI_API_KEY)
|
||||||
|
|||||||
247
README.md
247
README.md
@@ -15,7 +15,10 @@ dependencies to be installed using [Poetry](https://python-poetry.org/) from its
|
|||||||
|
|
||||||
* [Installation](#installation)
|
* [Installation](#installation)
|
||||||
* [Quick Start](#quick-start)
|
* [Quick Start](#quick-start)
|
||||||
* [Usage Examples](#usage-examples)
|
* [Reference and Usage](#reference-and-usage)
|
||||||
|
* [Config Option Reference](#config-option-reference)
|
||||||
|
* [Error Reference](#error-reference)
|
||||||
|
* [Example Config](#example-config)
|
||||||
* [Known Drawbacks and Problems](#known-drawbacks-and-problems)
|
* [Known Drawbacks and Problems](#known-drawbacks-and-problems)
|
||||||
* [Why would I use this?](#why-would-i-use-this) (What problems does this solve?)
|
* [Why would I use this?](#why-would-i-use-this) (What problems does this solve?)
|
||||||
* [Developing](#developing)
|
* [Developing](#developing)
|
||||||
@@ -46,7 +49,7 @@ Confirm that the plugin is installed, and Tox recognizes it, by checking the Tox
|
|||||||
~ $: poetry run tox --version
|
~ $: poetry run tox --version
|
||||||
3.20.0 imported from .venv/lib64/python3.8/site-packages/tox/__init__.py
|
3.20.0 imported from .venv/lib64/python3.8/site-packages/tox/__init__.py
|
||||||
registered plugins:
|
registered plugins:
|
||||||
tox-poetry-installer-0.2.2 at .venv/lib64/python3.8/site-packages/tox_poetry_installer.py
|
tox-poetry-installer-0.5.0 at .venv/lib64/python3.8/site-packages/tox_poetry_installer.py
|
||||||
```
|
```
|
||||||
|
|
||||||
If using Pip, ensure that the plugin is installed to the same environment as Tox:
|
If using Pip, ensure that the plugin is installed to the same environment as Tox:
|
||||||
@@ -57,186 +60,140 @@ If using Pip, ensure that the plugin is installed to the same environment as Tox
|
|||||||
~ $: /path/to/my/automation/virtualenv/bin/pip install tox-poetry-installer
|
~ $: /path/to/my/automation/virtualenv/bin/pip install tox-poetry-installer
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Note:** While it is possible to install this plugin using Tox's
|
||||||
|
[`requires`](https://tox.readthedocs.io/en/latest/config.html#conf-requires)
|
||||||
|
configuration option, it is not recommended. Dependencies from the `requires` option are
|
||||||
|
installed using the default Tox installation backend which opens up the
|
||||||
|
[possibility of transient dependency problems](#why-would-i-use-this) in your automation
|
||||||
|
environment.
|
||||||
|
|
||||||
|
|
||||||
## Quick Start
|
## Quick Start
|
||||||
|
|
||||||
To require a Tox environment install all it's dependencies from the Poetry lockfile, add the
|
To add dependencies from the lockfile to a Tox environment, add the option `locked_deps`
|
||||||
`require_locked_deps = true` option to the environment configuration and remove all version
|
to the environment configuration and list names of dependencies (with no version
|
||||||
specifiers from the dependency list. The versions to install will be taken from the lockfile
|
specifier) under it:
|
||||||
directly:
|
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
[testenv]
|
[testenv]
|
||||||
description = Run the tests
|
description = Some very cool tests
|
||||||
require_locked_deps = true
|
locked_deps =
|
||||||
deps =
|
|
||||||
pytest
|
|
||||||
pytest-cov
|
|
||||||
black
|
black
|
||||||
pylint
|
pylint
|
||||||
mypy
|
mypy
|
||||||
commands = ...
|
commands = ...
|
||||||
```
|
```
|
||||||
|
|
||||||
To require specific dependencies be installed from the Poetry lockfile, and let the rest be
|
The standard `deps` option can be used in parallel with the `locked_deps` option to
|
||||||
installed using the default Tox installation backend, add the suffix `@poetry` to the dependencies.
|
install unlocked dependencies (dependencies not in the lockfile) alongside locked
|
||||||
In the example below the `pytest`, `pytest-cov`, and `black` dependencies will be installed from
|
dependencies:
|
||||||
the lockfile while `pylint` and `mypy` will be installed using the versions specified here:
|
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
[testenv]
|
[testenv]
|
||||||
description = Run the tests
|
description = Some very cool tests
|
||||||
require_locked_deps = true
|
locked_deps =
|
||||||
|
black
|
||||||
|
pylint
|
||||||
|
mypy
|
||||||
deps =
|
deps =
|
||||||
pytest@poetry
|
pytest == 6.1.1
|
||||||
pytest-cov@poetry
|
pytest-cov >= 2.10, <2.11
|
||||||
black@poetry
|
|
||||||
pylint >=2.5.0
|
|
||||||
mypy == 0.770
|
|
||||||
commands = ...
|
commands = ...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Alternatively, to quickly install all Poetry dev-dependencies to a Tox environment, add the
|
||||||
|
`install_dev_deps = true` option to the environment configuration.
|
||||||
|
|
||||||
**Note:** Regardless of the settings outlined above, all dependencies of the project package (the
|
**Note:** Regardless of the settings outlined above, all dependencies of the project package (the
|
||||||
one Tox is testing) will always be installed from the lockfile.
|
one Tox is testing) will always be installed from the lockfile.
|
||||||
|
|
||||||
|
|
||||||
## Usage Examples
|
## Reference and Usage
|
||||||
|
|
||||||
After installing the plugin to a project your Tox automation is already benefiting from the
|
### Config Option Reference
|
||||||
lockfile: when Tox installs your project package to one of your environments, all the dependencies
|
|
||||||
of your project package will be installed using the versions specified in the lockfile. This
|
|
||||||
happens automatically and requires no configuration changes.
|
|
||||||
|
|
||||||
But what about the rest of your Tox environment dependencies?
|
All options listed below are Tox environment options and can be applied to one or more
|
||||||
|
environment sections of the `tox.ini` file. They cannot be applied to the global Tox
|
||||||
|
configuration section.
|
||||||
|
|
||||||
Let's use an example `tox.ini` file, below, that defines two environments: the main `testenv` for
|
**NOTE:** Environment settings applied to the main `testenv` environment will be
|
||||||
running the project tests and `testenv:check` for running some other helpful tools:
|
inherited by child environments (i.e. `testenv:foo`) unless they are explicitly
|
||||||
|
overridden by the child environment's configuration.
|
||||||
|
|
||||||
|
| Option | Type | Default | Usage |
|
||||||
|
|:----------------------|:----------------|:--------|:-----------------------------------------------|
|
||||||
|
| `locked_deps` | Multi-line list | `[]` | Names of packages in the Poetry lockfile to install to the Tox environment. All dependencies specified here (and their dependencies) will be installed to the Tox environment using the version the Poetry lockfile specifies for them. |
|
||||||
|
| `require_locked_deps` | Bool | `false` | Indicates whether the environment should allow unlocked dependencies (dependencies not in the Poetry lockfile) to be installed alongside locked dependencies. If `true` then installation of unlocked dependencies will be blocked and an error will be raised if the `deps` option specifies any values. |
|
||||||
|
| `install_dev_deps` | Bool | `false` | Indicates whether all Poetry development dependencies should be installed to the environment. Provides a quick and easy way to install all dev-dependencies without needing to specify them individually. |
|
||||||
|
|
||||||
|
### Error Reference
|
||||||
|
|
||||||
|
* `LockedDepVersionConflictError` - Indicates that a locked dependency included a PEP-508 version
|
||||||
|
specifier (i.e. `pytest >=6.0, <6.1`). Locked dependencies always take their version from the
|
||||||
|
Poetry lockfile so specifying a specific version for a locked dependency is not supported.
|
||||||
|
* `LockedDepNotFoundError` - Indicates that a locked dependency could not be found in the Poetry
|
||||||
|
lockfile. This can be solved by [adding the dependency using Poetry](https://python-poetry.org/docs/cli/#add).
|
||||||
|
* `ExtraNotFoundError` - Indicates that the Tox `extras` option specified a project extra that
|
||||||
|
Poetry does not know about. This may be due to a misconfigured `pyproject.toml` or out of date
|
||||||
|
lockfile.
|
||||||
|
* `LockedDepsRequiredError` - Indicates that an environment with `require_locked_deps = true` also
|
||||||
|
specified unlocked dependencies using Tox's `deps` option. This can be solved by either setting
|
||||||
|
`require_locked_deps = false` (the default) or removing the `deps` option from the environment
|
||||||
|
configuration.
|
||||||
|
|
||||||
|
### Example Config
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
[tox]
|
[tox]
|
||||||
envlist = py37, static
|
envlist = py, foo, bar, baz
|
||||||
isolated_build = true
|
isolated_build = true
|
||||||
|
|
||||||
|
# The base testenv will always use locked dependencies and only ever installs the project package
|
||||||
|
# (and its dependencies) and the two pytest dependencies listed below
|
||||||
[testenv]
|
[testenv]
|
||||||
description = Run the tests
|
description = Some very cool tests
|
||||||
deps =
|
|
||||||
pytest == 5.3.0
|
|
||||||
commands = ...
|
|
||||||
|
|
||||||
[testenv:check]
|
|
||||||
description = Static formatting and quality enforcement
|
|
||||||
deps =
|
|
||||||
pylint >=2.4.4,<2.6.0
|
|
||||||
mypy == 0.770
|
|
||||||
black --pre
|
|
||||||
commands = ...
|
|
||||||
```
|
|
||||||
|
|
||||||
Let's focus on the `testenv:check` environment first. In this project there's no reason that any
|
|
||||||
of these tools should be a different version than what a human developer is using when installing
|
|
||||||
from the lockfile. We can require that these dependencies be installed from the lockfile by adding
|
|
||||||
the option `require_locked_deps = true` to the environment config, but this will cause an error:
|
|
||||||
|
|
||||||
```ini
|
|
||||||
[testenv:check]
|
|
||||||
description = Static formatting and quality enforcement
|
|
||||||
require_locked_deps = true
|
require_locked_deps = true
|
||||||
deps =
|
locked_deps =
|
||||||
pylint >=2.4.4,<2.6.0
|
pytest
|
||||||
mypy == 0.770
|
pytest-cov
|
||||||
black --pre
|
|
||||||
commands = ...
|
commands = ...
|
||||||
```
|
|
||||||
|
|
||||||
Running Tox using this config gives us this error:
|
# This environment also requires locked dependencies, but the "skip_install" setting means that
|
||||||
|
# the project dependencies will not be installed to the environment from the lockfile
|
||||||
```
|
[testenv:foo]
|
||||||
tox_poetry_installer.LockedDepVersionConflictError: Locked dependency 'pylint >=2.4.4,<2.6.0' cannot include version specifier
|
description = FOObarbaz
|
||||||
```
|
skip_install = true
|
||||||
|
|
||||||
This is because we told the Tox environment to require all dependencies be locked, but then also
|
|
||||||
specified a specific version constraint for Pylint. With the `require_locked_deps = true` setting
|
|
||||||
Tox expects all dependencies to take their version from the lockfile, so when it gets conflicting
|
|
||||||
information it errors. We can fix this by simply removing all version specifiers from the
|
|
||||||
environment dependency list:
|
|
||||||
|
|
||||||
```ini
|
|
||||||
[testenv:check]
|
|
||||||
description = Static formatting and quality enforcement
|
|
||||||
require_locked_deps = true
|
require_locked_deps = true
|
||||||
deps =
|
locked_deps =
|
||||||
pylint
|
requests
|
||||||
|
toml
|
||||||
|
ruamel.yaml
|
||||||
|
commands = ...
|
||||||
|
|
||||||
|
# This environment allows unlocked dependencies to be installed ad-hoc. Below, the "mypy" and
|
||||||
|
# "pylint" dependencies (and their dependencies) will be installed from the Poetry lockfile but the
|
||||||
|
# "black" dependency will be installed using the default Tox backend. Note, this environment does
|
||||||
|
# not specify "require_locked_deps = true" to allow the unlocked "black" dependency without raising
|
||||||
|
# an error.
|
||||||
|
[testenv:bar]
|
||||||
|
description = fooBARbaz
|
||||||
|
locked_deps =
|
||||||
mypy
|
mypy
|
||||||
|
pylint
|
||||||
|
deps =
|
||||||
black
|
black
|
||||||
commands = ...
|
commands = ...
|
||||||
```
|
|
||||||
|
|
||||||
Now all the dependencies will be installed from the lockfile. If Poetry updates the lockfile with
|
# This environment requires locked dependencies but does not specify any. Instead it specifies the
|
||||||
a new version then that updated version will be automatically installed when the Tox environment is
|
# "install_dev_deps = true" option which will cause all of the Poetry dev-dependencies to be
|
||||||
recreated.
|
# installed from the lockfile.
|
||||||
|
[testenv:baz]
|
||||||
Now let's look at the `testenv` environment. Let's make the same changes to the `testenv`
|
description = foobarBAZ
|
||||||
environment that we made to `testenv:check` above; remove the PyTest version and add
|
install_dev_deps = true
|
||||||
`require_locked_deps = true`. Then imagine that we want to add the
|
|
||||||
[Requests](https://requests.readthedocs.io/en/master/) library to the test environment: we
|
|
||||||
can add `requests` as a dependency of the test environment, but this will cause an error:
|
|
||||||
|
|
||||||
```ini
|
|
||||||
[testenv]
|
|
||||||
description = Run the tests
|
|
||||||
require_locked_deps = true
|
require_locked_deps = true
|
||||||
deps =
|
|
||||||
pytest
|
|
||||||
requests
|
|
||||||
commands = ...
|
commands = ...
|
||||||
```
|
```
|
||||||
|
|
||||||
Running Tox with this config gives us this error:
|
|
||||||
|
|
||||||
```
|
|
||||||
tox_poetry_installer.LockedDepNotFoundError: No version of locked dependency 'requests' found in the project lockfile
|
|
||||||
```
|
|
||||||
|
|
||||||
This is because `requests` is not in our lockfile yet. Tox will refuse to install a dependency
|
|
||||||
that isn't in the lockfile to an an environment that specifies `require_locked_deps = true`. We
|
|
||||||
can fix this by running `poetry add requests --dev` to add it to the lockfile.
|
|
||||||
|
|
||||||
Now let's combine dependencies from the lockfile with dependencies that are
|
|
||||||
specified in-line in the Tox environment configuration.
|
|
||||||
[This isn't generally recommended](#why-would-i-use-this), but it is a valid use case and
|
|
||||||
fully supported by this plugin. Let's modify the `testenv` configuration to install PyTest
|
|
||||||
from the lockfile but then install an older version of the Requests library.
|
|
||||||
|
|
||||||
The first thing to do is remove the `require_locked_deps = true` setting so that we can install
|
|
||||||
Requests as an unlocked dependency. Then we can add our version specifier to the `requests`
|
|
||||||
entry in the dependency list:
|
|
||||||
|
|
||||||
```ini
|
|
||||||
[testenv]
|
|
||||||
description = Run the tests
|
|
||||||
deps =
|
|
||||||
pytest
|
|
||||||
requests >=2.2.0,<2.10.0
|
|
||||||
commands = ...
|
|
||||||
```
|
|
||||||
|
|
||||||
However we still want `pytest` to be installed from the lockfile, so the final step is to tell Tox
|
|
||||||
to install it from the lockfile by adding the suffix `@poetry` to the `pytest` entry in the
|
|
||||||
dependency list:
|
|
||||||
|
|
||||||
```ini
|
|
||||||
[testenv]
|
|
||||||
description = Run the tests
|
|
||||||
deps =
|
|
||||||
pytest@poetry
|
|
||||||
requests >=2.2.0,<2.10.0
|
|
||||||
commands = ...
|
|
||||||
```
|
|
||||||
|
|
||||||
Now when the `testenv` environment is created it will install PyTest (and all of its dependencies)
|
|
||||||
from the lockfile while it will install Requests (and all of its dependencies) using the default
|
|
||||||
Tox installation backend.
|
|
||||||
|
|
||||||
|
|
||||||
## Known Drawbacks and Problems
|
## Known Drawbacks and Problems
|
||||||
|
|
||||||
@@ -249,11 +206,11 @@ Tox installation backend.
|
|||||||
* [`indexserver`](https://tox.readthedocs.io/en/latest/config.html#conf-indexserver)
|
* [`indexserver`](https://tox.readthedocs.io/en/latest/config.html#conf-indexserver)
|
||||||
* [`usedevelop`](https://tox.readthedocs.io/en/latest/config.html#conf-indexserver)
|
* [`usedevelop`](https://tox.readthedocs.io/en/latest/config.html#conf-indexserver)
|
||||||
|
|
||||||
* Tox environments automatically inherit their settings from the main `testenv` environment. This
|
* Tox will not automatically detect changes to the locked dependencies and so
|
||||||
means that if the `require_locked_deps = true` is specified for the `testenv` environment then
|
environments will not be automatically rebuilt when locked dependencies are changed.
|
||||||
all environments will also require locked dependencies. This can be overwritten by explicitly
|
When changing the locked dependencies (or their versions) the environments will need to
|
||||||
specifying `require_locked_deps = false` on child environments where unlocked dependencies are
|
be manually rebuilt using either the `-r`/`--recreate` CLI option or the
|
||||||
needed.
|
`recreate = true` option in `tox.ini`.
|
||||||
|
|
||||||
* There are a handful of packages that cannot be installed from the lockfile, whether as specific
|
* There are a handful of packages that cannot be installed from the lockfile, whether as specific
|
||||||
dependencies or as transient dependencies (dependencies of dependencies). This is due to
|
dependencies or as transient dependencies (dependencies of dependencies). This is due to
|
||||||
@@ -368,7 +325,7 @@ dependencies:
|
|||||||
[testenv]
|
[testenv]
|
||||||
description = Some very cool tests
|
description = Some very cool tests
|
||||||
require_locked_deps = true
|
require_locked_deps = true
|
||||||
deps =
|
locked_deps =
|
||||||
foo
|
foo
|
||||||
bar
|
bar
|
||||||
baz
|
baz
|
||||||
@@ -453,7 +410,7 @@ for usage in production environments.
|
|||||||
- [ ] Find and implement a way to mitigate the [UNSAFE_DEPENDENCIES issue](https://github.com/python-poetry/poetry/issues/1584) in Poetry.
|
- [ ] Find and implement a way to mitigate the [UNSAFE_DEPENDENCIES issue](https://github.com/python-poetry/poetry/issues/1584) in Poetry.
|
||||||
([#6](https://github.com/enpaul/tox-poetry-installer/issues/6))
|
([#6](https://github.com/enpaul/tox-poetry-installer/issues/6))
|
||||||
- [ ] Fix logging to make proper use of Tox's logging reporter infrastructure ([#3](https://github.com/enpaul/tox-poetry-installer/issues/3))
|
- [ ] Fix logging to make proper use of Tox's logging reporter infrastructure ([#3](https://github.com/enpaul/tox-poetry-installer/issues/3))
|
||||||
- [ ] Add configuration option for installing all dev-dependencies to a testenv ([#14](https://github.com/enpaul/tox-poetry-installer/issues/14))
|
- [X] Add configuration option for installing all dev-dependencies to a testenv ([#14](https://github.com/enpaul/tox-poetry-installer/issues/14))
|
||||||
|
|
||||||
### Path to Stable
|
### Path to Stable
|
||||||
|
|
||||||
|
|||||||
483
poetry.lock
generated
483
poetry.lock
generated
@@ -49,15 +49,15 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "attrs"
|
name = "attrs"
|
||||||
version = "20.2.0"
|
version = "20.3.0"
|
||||||
description = "Classes Without Boilerplate"
|
description = "Classes Without Boilerplate"
|
||||||
category = "dev"
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "sphinx", "sphinx-rtd-theme", "pre-commit"]
|
dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "furo", "sphinx", "pre-commit"]
|
||||||
docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"]
|
docs = ["furo", "sphinx", "zope.interface"]
|
||||||
tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"]
|
tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"]
|
||||||
tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six"]
|
tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six"]
|
||||||
|
|
||||||
@@ -107,6 +107,17 @@ typing-extensions = ">=3.7.4"
|
|||||||
colorama = ["colorama (>=0.4.3)"]
|
colorama = ["colorama (>=0.4.3)"]
|
||||||
d = ["aiohttp (>=3.3.2)", "aiohttp-cors"]
|
d = ["aiohttp (>=3.3.2)", "aiohttp-cors"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "blacken-docs"
|
||||||
|
version = "1.8.0"
|
||||||
|
description = "Run `black` on python code blocks in documentation files"
|
||||||
|
category = "dev"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.6.1"
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
black = ">=19.3b0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cachecontrol"
|
name = "cachecontrol"
|
||||||
version = "0.12.6"
|
version = "0.12.6"
|
||||||
@@ -147,7 +158,7 @@ msgpack = ["msgpack-python (>=0.5,<0.6)"]
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "certifi"
|
name = "certifi"
|
||||||
version = "2020.6.20"
|
version = "2020.11.8"
|
||||||
description = "Python package for providing Mozilla's CA Bundle."
|
description = "Python package for providing Mozilla's CA Bundle."
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
@@ -155,7 +166,7 @@ python-versions = "*"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cffi"
|
name = "cffi"
|
||||||
version = "1.14.3"
|
version = "1.14.4"
|
||||||
description = "Foreign Function Interface for Python calling C code."
|
description = "Foreign Function Interface for Python calling C code."
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
@@ -214,7 +225,7 @@ pylev = ">=1.3,<2.0"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "colorama"
|
name = "colorama"
|
||||||
version = "0.4.3"
|
version = "0.4.4"
|
||||||
description = "Cross-platform colored terminal text."
|
description = "Cross-platform colored terminal text."
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
@@ -241,7 +252,7 @@ python-versions = ">=3.6,<4.0"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cryptography"
|
name = "cryptography"
|
||||||
version = "3.1.1"
|
version = "3.2.1"
|
||||||
description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers."
|
description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers."
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
@@ -260,11 +271,11 @@ test = ["pytest (>=3.6.0,<3.9.0 || >3.9.0,<3.9.1 || >3.9.1,<3.9.2 || >3.9.2)", "
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dataclasses"
|
name = "dataclasses"
|
||||||
version = "0.6"
|
version = "0.8"
|
||||||
description = "A backport of the dataclasses module for Python 3.6"
|
description = "A backport of the dataclasses module for Python 3.6"
|
||||||
category = "dev"
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = ">=3.6, <3.7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "decorator"
|
name = "decorator"
|
||||||
@@ -319,7 +330,7 @@ smmap = ">=3.0.1,<4"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gitpython"
|
name = "gitpython"
|
||||||
version = "3.1.9"
|
version = "3.1.11"
|
||||||
description = "Python Git Library"
|
description = "Python Git Library"
|
||||||
category = "dev"
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
@@ -348,7 +359,7 @@ lxml = ["lxml"]
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "identify"
|
name = "identify"
|
||||||
version = "1.5.6"
|
version = "1.5.10"
|
||||||
description = "File identification library for Python"
|
description = "File identification library for Python"
|
||||||
category = "dev"
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
@@ -382,11 +393,11 @@ testing = ["packaging", "pep517", "importlib-resources (>=1.3)"]
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "importlib-resources"
|
name = "importlib-resources"
|
||||||
version = "3.0.0"
|
version = "3.3.0"
|
||||||
description = "Read resources from Python packages"
|
description = "Read resources from Python packages"
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
|
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7"
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
zipp = {version = ">=0.4", markers = "python_version < \"3.8\""}
|
zipp = {version = ">=0.4", markers = "python_version < \"3.8\""}
|
||||||
@@ -396,7 +407,7 @@ docs = ["sphinx", "rst.linker", "jaraco.packaging"]
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iniconfig"
|
name = "iniconfig"
|
||||||
version = "1.0.1"
|
version = "1.1.1"
|
||||||
description = "iniconfig: brain-dead simple config-ini parsing"
|
description = "iniconfig: brain-dead simple config-ini parsing"
|
||||||
category = "dev"
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
@@ -404,7 +415,7 @@ python-versions = "*"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ipython"
|
name = "ipython"
|
||||||
version = "7.18.1"
|
version = "7.19.0"
|
||||||
description = "IPython: Productive Interactive Computing"
|
description = "IPython: Productive Interactive Computing"
|
||||||
category = "dev"
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
@@ -443,7 +454,7 @@ python-versions = "*"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "isort"
|
name = "isort"
|
||||||
version = "5.6.3"
|
version = "5.6.4"
|
||||||
description = "A Python utility / library to sort Python imports."
|
description = "A Python utility / library to sort Python imports."
|
||||||
category = "dev"
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
@@ -471,32 +482,32 @@ testing = ["Django (<3.1)", "colorama", "docopt", "pytest (>=3.9.0,<5.0.0)"]
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jeepney"
|
name = "jeepney"
|
||||||
version = "0.4.3"
|
version = "0.6.0"
|
||||||
description = "Low-level, pure Python DBus protocol wrapper."
|
description = "Low-level, pure Python DBus protocol wrapper."
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.5"
|
python-versions = ">=3.6"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
dev = ["testpath"]
|
test = ["pytest", "pytest-trio", "pytest-asyncio", "testpath", "trio"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "keyring"
|
name = "keyring"
|
||||||
version = "21.4.0"
|
version = "21.5.0"
|
||||||
description = "Store and access your passwords safely."
|
description = "Store and access your passwords safely."
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.6"
|
python-versions = ">=3.6"
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
importlib-metadata = {version = "*", markers = "python_version < \"3.8\""}
|
importlib-metadata = {version = ">=1", markers = "python_version < \"3.8\""}
|
||||||
jeepney = {version = ">=0.4.2", markers = "sys_platform == \"linux\""}
|
jeepney = {version = ">=0.4.2", markers = "sys_platform == \"linux\""}
|
||||||
pywin32-ctypes = {version = "<0.1.0 || >0.1.0,<0.1.1 || >0.1.1", markers = "sys_platform == \"win32\""}
|
pywin32-ctypes = {version = "<0.1.0 || >0.1.0,<0.1.1 || >0.1.1", markers = "sys_platform == \"win32\""}
|
||||||
SecretStorage = {version = ">=3", markers = "sys_platform == \"linux\""}
|
SecretStorage = {version = ">=3.2", markers = "sys_platform == \"linux\""}
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"]
|
docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"]
|
||||||
testing = ["pytest (>=3.5,<3.7.3 || >3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-black (>=0.3.7)", "pytest-cov", "pytest-mypy"]
|
testing = ["pytest (>=3.5,<3.7.3 || >3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "jaraco.test (>=3.2.0)", "pytest-black (>=0.3.7)", "pytest-mypy"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy-object-proxy"
|
name = "lazy-object-proxy"
|
||||||
@@ -595,7 +606,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pathspec"
|
name = "pathspec"
|
||||||
version = "0.8.0"
|
version = "0.8.1"
|
||||||
description = "Utility library for gitignore style pattern matching of file paths."
|
description = "Utility library for gitignore style pattern matching of file paths."
|
||||||
category = "dev"
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
@@ -603,7 +614,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pbr"
|
name = "pbr"
|
||||||
version = "5.5.0"
|
version = "5.5.1"
|
||||||
description = "Python Build Reasonableness"
|
description = "Python Build Reasonableness"
|
||||||
category = "dev"
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
@@ -630,7 +641,7 @@ python-versions = "*"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pkginfo"
|
name = "pkginfo"
|
||||||
version = "1.5.0.1"
|
version = "1.6.1"
|
||||||
description = "Query metadatdata from sdists / bdists / installed packages."
|
description = "Query metadatdata from sdists / bdists / installed packages."
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
@@ -655,7 +666,7 @@ dev = ["pre-commit", "tox"]
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "poetry"
|
name = "poetry"
|
||||||
version = "1.1.2"
|
version = "1.1.4"
|
||||||
description = "Python dependency management and packaging made easy."
|
description = "Python dependency management and packaging made easy."
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
@@ -693,7 +704,7 @@ importlib-metadata = {version = ">=1.7.0,<2.0.0", markers = "python_version >= \
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pre-commit"
|
name = "pre-commit"
|
||||||
version = "2.7.1"
|
version = "2.9.2"
|
||||||
description = "A framework for managing and maintaining multi-language pre-commit hooks."
|
description = "A framework for managing and maintaining multi-language pre-commit hooks."
|
||||||
category = "dev"
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
@@ -709,9 +720,21 @@ pyyaml = ">=5.1"
|
|||||||
toml = "*"
|
toml = "*"
|
||||||
virtualenv = ">=20.0.8"
|
virtualenv = ">=20.0.8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pre-commit-hooks"
|
||||||
|
version = "3.3.0"
|
||||||
|
description = "Some out-of-the-box hooks for pre-commit."
|
||||||
|
category = "dev"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.6.1"
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
"ruamel.yaml" = ">=0.15"
|
||||||
|
toml = "*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "prompt-toolkit"
|
name = "prompt-toolkit"
|
||||||
version = "3.0.7"
|
version = "3.0.8"
|
||||||
description = "Library for building powerful interactive command lines in Python"
|
description = "Library for building powerful interactive command lines in Python"
|
||||||
category = "dev"
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
@@ -746,7 +769,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pygments"
|
name = "pygments"
|
||||||
version = "2.7.1"
|
version = "2.7.2"
|
||||||
description = "Pygments is a syntax highlighting package written in Python."
|
description = "Pygments is a syntax highlighting package written in Python."
|
||||||
category = "dev"
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
@@ -785,7 +808,7 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pytest"
|
name = "pytest"
|
||||||
version = "6.1.1"
|
version = "6.1.2"
|
||||||
description = "pytest: simple powerful testing with Python"
|
description = "pytest: simple powerful testing with Python"
|
||||||
category = "dev"
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
@@ -839,7 +862,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "2020.10.11"
|
version = "2020.11.13"
|
||||||
description = "Alternative regular expression module, to replace re."
|
description = "Alternative regular expression module, to replace re."
|
||||||
category = "dev"
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
@@ -847,7 +870,7 @@ python-versions = "*"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "reorder-python-imports"
|
name = "reorder-python-imports"
|
||||||
version = "2.3.5"
|
version = "2.3.6"
|
||||||
description = "Tool for reordering python imports"
|
description = "Tool for reordering python imports"
|
||||||
category = "dev"
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
@@ -858,7 +881,7 @@ python-versions = ">=3.6.1"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "requests"
|
name = "requests"
|
||||||
version = "2.24.0"
|
version = "2.25.0"
|
||||||
description = "Python HTTP for Humans."
|
description = "Python HTTP for Humans."
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
@@ -868,7 +891,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
|||||||
certifi = ">=2017.4.17"
|
certifi = ">=2017.4.17"
|
||||||
chardet = ">=3.0.2,<4"
|
chardet = ">=3.0.2,<4"
|
||||||
idna = ">=2.5,<3"
|
idna = ">=2.5,<3"
|
||||||
urllib3 = ">=1.21.1,<1.25.0 || >1.25.0,<1.25.1 || >1.25.1,<1.26"
|
urllib3 = ">=1.21.1,<1.27"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)"]
|
security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)"]
|
||||||
@@ -885,6 +908,29 @@ python-versions = "*"
|
|||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
requests = ">=2.0.1,<3.0.0"
|
requests = ">=2.0.1,<3.0.0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ruamel.yaml"
|
||||||
|
version = "0.16.12"
|
||||||
|
description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order"
|
||||||
|
category = "dev"
|
||||||
|
optional = false
|
||||||
|
python-versions = "*"
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
"ruamel.yaml.clib" = {version = ">=0.1.2", markers = "platform_python_implementation == \"CPython\" and python_version < \"3.9\""}
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
docs = ["ryd"]
|
||||||
|
jinja2 = ["ruamel.yaml.jinja2 (>=0.2)"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ruamel.yaml.clib"
|
||||||
|
version = "0.2.2"
|
||||||
|
description = "C version of reader, parser and emitter for ruamel.yaml derived from libyaml"
|
||||||
|
category = "dev"
|
||||||
|
optional = false
|
||||||
|
python-versions = "*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "safety"
|
name = "safety"
|
||||||
version = "1.9.0"
|
version = "1.9.0"
|
||||||
@@ -901,15 +947,15 @@ requests = "*"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "secretstorage"
|
name = "secretstorage"
|
||||||
version = "3.1.2"
|
version = "3.3.0"
|
||||||
description = "Python bindings to FreeDesktop.org Secret Service API"
|
description = "Python bindings to FreeDesktop.org Secret Service API"
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.5"
|
python-versions = ">=3.6"
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
cryptography = "*"
|
cryptography = ">=2.0"
|
||||||
jeepney = ">=0.4.2"
|
jeepney = ">=0.6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "shellingham"
|
name = "shellingham"
|
||||||
@@ -949,11 +995,11 @@ pbr = ">=2.0.0,<2.1.0 || >2.1.0"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml"
|
name = "toml"
|
||||||
version = "0.10.1"
|
version = "0.10.2"
|
||||||
description = "Python Library for Tom's Obvious, Minimal Language"
|
description = "Python Library for Tom's Obvious, Minimal Language"
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tomlkit"
|
name = "tomlkit"
|
||||||
@@ -988,7 +1034,7 @@ testing = ["flaky (>=3.4.0)", "freezegun (>=0.3.11)", "pathlib2 (>=2.3.3)", "psu
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "traitlets"
|
name = "traitlets"
|
||||||
version = "5.0.4"
|
version = "5.0.5"
|
||||||
description = "Traitlets Python configuration system"
|
description = "Traitlets Python configuration system"
|
||||||
category = "dev"
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
@@ -1018,7 +1064,7 @@ python-versions = "*"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "urllib3"
|
name = "urllib3"
|
||||||
version = "1.25.10"
|
version = "1.26.2"
|
||||||
description = "HTTP library with thread-safe connection pooling, file post, and more."
|
description = "HTTP library with thread-safe connection pooling, file post, and more."
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
@@ -1026,12 +1072,12 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4"
|
|||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
brotli = ["brotlipy (>=0.6.0)"]
|
brotli = ["brotlipy (>=0.6.0)"]
|
||||||
secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "pyOpenSSL (>=0.14)", "ipaddress"]
|
secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"]
|
||||||
socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7,<2.0)"]
|
socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7,<2.0)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "virtualenv"
|
name = "virtualenv"
|
||||||
version = "20.0.33"
|
version = "20.2.1"
|
||||||
description = "Virtual Python Environment builder"
|
description = "Virtual Python Environment builder"
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
@@ -1041,7 +1087,7 @@ python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7"
|
|||||||
appdirs = ">=1.4.3,<2"
|
appdirs = ">=1.4.3,<2"
|
||||||
distlib = ">=0.3.1,<1"
|
distlib = ">=0.3.1,<1"
|
||||||
filelock = ">=3.0.0,<4"
|
filelock = ">=3.0.0,<4"
|
||||||
importlib-metadata = {version = ">=0.12,<3", markers = "python_version < \"3.8\""}
|
importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""}
|
||||||
importlib-resources = {version = ">=1.0", markers = "python_version < \"3.7\""}
|
importlib-resources = {version = ">=1.0", markers = "python_version < \"3.7\""}
|
||||||
six = ">=1.9.0,<2"
|
six = ">=1.9.0,<2"
|
||||||
|
|
||||||
@@ -1075,7 +1121,7 @@ python-versions = "*"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zipp"
|
name = "zipp"
|
||||||
version = "3.3.0"
|
version = "3.4.0"
|
||||||
description = "Backport of pathlib-compatible object wrapper for zip files"
|
description = "Backport of pathlib-compatible object wrapper for zip files"
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
@@ -1087,8 +1133,8 @@ testing = ["pytest (>=3.5,<3.7.3 || >3.7.3)", "pytest-checkdocs (>=1.2.3)", "pyt
|
|||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "1.1"
|
lock-version = "1.1"
|
||||||
python-versions = "^3.6"
|
python-versions = "^3.6.1"
|
||||||
content-hash = "7a39fcfcd48beaae95e52dfa774b2a8880f6f55fbd22a589957d59cc63523e12"
|
content-hash = "8eea42cb6c60df03376bb264b444ccd0a63a211122edc6625284d57204295273"
|
||||||
|
|
||||||
[metadata.files]
|
[metadata.files]
|
||||||
appdirs = [
|
appdirs = [
|
||||||
@@ -1112,8 +1158,8 @@ atomicwrites = [
|
|||||||
{file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"},
|
{file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"},
|
||||||
]
|
]
|
||||||
attrs = [
|
attrs = [
|
||||||
{file = "attrs-20.2.0-py2.py3-none-any.whl", hash = "sha256:fce7fc47dfc976152e82d53ff92fa0407700c21acd20886a13777a0d20e655dc"},
|
{file = "attrs-20.3.0-py2.py3-none-any.whl", hash = "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6"},
|
||||||
{file = "attrs-20.2.0.tar.gz", hash = "sha256:26b54ddbbb9ee1d34d5d3668dd37d6cf74990ab23c828c2888dccdceee395594"},
|
{file = "attrs-20.3.0.tar.gz", hash = "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700"},
|
||||||
]
|
]
|
||||||
backcall = [
|
backcall = [
|
||||||
{file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"},
|
{file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"},
|
||||||
@@ -1126,6 +1172,10 @@ bandit = [
|
|||||||
black = [
|
black = [
|
||||||
{file = "black-20.8b1.tar.gz", hash = "sha256:1c02557aa099101b9d21496f8a914e9ed2222ef70336404eeeac8edba836fbea"},
|
{file = "black-20.8b1.tar.gz", hash = "sha256:1c02557aa099101b9d21496f8a914e9ed2222ef70336404eeeac8edba836fbea"},
|
||||||
]
|
]
|
||||||
|
blacken-docs = [
|
||||||
|
{file = "blacken_docs-1.8.0-py2.py3-none-any.whl", hash = "sha256:ed41c95311286f7a74a3400fd6bb746c0fee571772d875d56a2462213841be02"},
|
||||||
|
{file = "blacken_docs-1.8.0.tar.gz", hash = "sha256:1a7ddc1525dee3accaeb53a61d9f80791c2d8a27553388f5a2f11fc1c91b4acd"},
|
||||||
|
]
|
||||||
cachecontrol = [
|
cachecontrol = [
|
||||||
{file = "CacheControl-0.12.6-py2.py3-none-any.whl", hash = "sha256:10d056fa27f8563a271b345207402a6dcce8efab7e5b377e270329c62471b10d"},
|
{file = "CacheControl-0.12.6-py2.py3-none-any.whl", hash = "sha256:10d056fa27f8563a271b345207402a6dcce8efab7e5b377e270329c62471b10d"},
|
||||||
{file = "CacheControl-0.12.6.tar.gz", hash = "sha256:be9aa45477a134aee56c8fac518627e1154df063e85f67d4f83ce0ccc23688e8"},
|
{file = "CacheControl-0.12.6.tar.gz", hash = "sha256:be9aa45477a134aee56c8fac518627e1154df063e85f67d4f83ce0ccc23688e8"},
|
||||||
@@ -1139,46 +1189,44 @@ cachy = [
|
|||||||
{file = "cachy-0.3.0.tar.gz", hash = "sha256:186581f4ceb42a0bbe040c407da73c14092379b1e4c0e327fdb72ae4a9b269b1"},
|
{file = "cachy-0.3.0.tar.gz", hash = "sha256:186581f4ceb42a0bbe040c407da73c14092379b1e4c0e327fdb72ae4a9b269b1"},
|
||||||
]
|
]
|
||||||
certifi = [
|
certifi = [
|
||||||
{file = "certifi-2020.6.20-py2.py3-none-any.whl", hash = "sha256:8fc0819f1f30ba15bdb34cceffb9ef04d99f420f68eb75d901e9560b8749fc41"},
|
{file = "certifi-2020.11.8-py2.py3-none-any.whl", hash = "sha256:1f422849db327d534e3d0c5f02a263458c3955ec0aae4ff09b95f195c59f4edd"},
|
||||||
{file = "certifi-2020.6.20.tar.gz", hash = "sha256:5930595817496dd21bb8dc35dad090f1c2cd0adfaf21204bf6732ca5d8ee34d3"},
|
{file = "certifi-2020.11.8.tar.gz", hash = "sha256:f05def092c44fbf25834a51509ef6e631dc19765ab8a57b4e7ab85531f0a9cf4"},
|
||||||
]
|
]
|
||||||
cffi = [
|
cffi = [
|
||||||
{file = "cffi-1.14.3-2-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:3eeeb0405fd145e714f7633a5173318bd88d8bbfc3dd0a5751f8c4f70ae629bc"},
|
{file = "cffi-1.14.4-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ebb253464a5d0482b191274f1c8bf00e33f7e0b9c66405fbffc61ed2c839c775"},
|
||||||
{file = "cffi-1.14.3-2-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:cb763ceceae04803adcc4e2d80d611ef201c73da32d8f2722e9d0ab0c7f10768"},
|
{file = "cffi-1.14.4-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:2c24d61263f511551f740d1a065eb0212db1dbbbbd241db758f5244281590c06"},
|
||||||
{file = "cffi-1.14.3-2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:44f60519595eaca110f248e5017363d751b12782a6f2bd6a7041cba275215f5d"},
|
{file = "cffi-1.14.4-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9f7a31251289b2ab6d4012f6e83e58bc3b96bd151f5b5262467f4bb6b34a7c26"},
|
||||||
{file = "cffi-1.14.3-2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c53af463f4a40de78c58b8b2710ade243c81cbca641e34debf3396a9640d6ec1"},
|
{file = "cffi-1.14.4-cp27-cp27m-win32.whl", hash = "sha256:5cf4be6c304ad0b6602f5c4e90e2f59b47653ac1ed9c662ed379fe48a8f26b0c"},
|
||||||
{file = "cffi-1.14.3-2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:33c6cdc071ba5cd6d96769c8969a0531be2d08c2628a0143a10a7dcffa9719ca"},
|
{file = "cffi-1.14.4-cp27-cp27m-win_amd64.whl", hash = "sha256:f60567825f791c6f8a592f3c6e3bd93dd2934e3f9dac189308426bd76b00ef3b"},
|
||||||
{file = "cffi-1.14.3-2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c11579638288e53fc94ad60022ff1b67865363e730ee41ad5e6f0a17188b327a"},
|
{file = "cffi-1.14.4-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:c6332685306b6417a91b1ff9fae889b3ba65c2292d64bd9245c093b1b284809d"},
|
||||||
{file = "cffi-1.14.3-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:3cb3e1b9ec43256c4e0f8d2837267a70b0e1ca8c4f456685508ae6106b1f504c"},
|
{file = "cffi-1.14.4-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:d9efd8b7a3ef378dd61a1e77367f1924375befc2eba06168b6ebfa903a5e59ca"},
|
||||||
{file = "cffi-1.14.3-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:f0620511387790860b249b9241c2f13c3a80e21a73e0b861a2df24e9d6f56730"},
|
{file = "cffi-1.14.4-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:51a8b381b16ddd370178a65360ebe15fbc1c71cf6f584613a7ea08bfad946698"},
|
||||||
{file = "cffi-1.14.3-cp27-cp27m-win32.whl", hash = "sha256:005f2bfe11b6745d726dbb07ace4d53f057de66e336ff92d61b8c7e9c8f4777d"},
|
{file = "cffi-1.14.4-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:1d2c4994f515e5b485fd6d3a73d05526aa0fcf248eb135996b088d25dfa1865b"},
|
||||||
{file = "cffi-1.14.3-cp27-cp27m-win_amd64.whl", hash = "sha256:2f9674623ca39c9ebe38afa3da402e9326c245f0f5ceff0623dccdac15023e05"},
|
{file = "cffi-1.14.4-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:af5c59122a011049aad5dd87424b8e65a80e4a6477419c0c1015f73fb5ea0293"},
|
||||||
{file = "cffi-1.14.3-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:09e96138280241bd355cd585148dec04dbbedb4f46128f340d696eaafc82dd7b"},
|
{file = "cffi-1.14.4-cp35-cp35m-win32.whl", hash = "sha256:594234691ac0e9b770aee9fcdb8fa02c22e43e5c619456efd0d6c2bf276f3eb2"},
|
||||||
{file = "cffi-1.14.3-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:3363e77a6176afb8823b6e06db78c46dbc4c7813b00a41300a4873b6ba63b171"},
|
{file = "cffi-1.14.4-cp35-cp35m-win_amd64.whl", hash = "sha256:64081b3f8f6f3c3de6191ec89d7dc6c86a8a43911f7ecb422c60e90c70be41c7"},
|
||||||
{file = "cffi-1.14.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:0ef488305fdce2580c8b2708f22d7785ae222d9825d3094ab073e22e93dfe51f"},
|
{file = "cffi-1.14.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f803eaa94c2fcda012c047e62bc7a51b0bdabda1cad7a92a522694ea2d76e49f"},
|
||||||
{file = "cffi-1.14.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:0b1ad452cc824665ddc682400b62c9e4f5b64736a2ba99110712fdee5f2505c4"},
|
{file = "cffi-1.14.4-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:105abaf8a6075dc96c1fe5ae7aae073f4696f2905fde6aeada4c9d2926752362"},
|
||||||
{file = "cffi-1.14.3-cp35-cp35m-win32.whl", hash = "sha256:85ba797e1de5b48aa5a8427b6ba62cf69607c18c5d4eb747604b7302f1ec382d"},
|
{file = "cffi-1.14.4-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:0638c3ae1a0edfb77c6765d487fee624d2b1ee1bdfeffc1f0b58c64d149e7eec"},
|
||||||
{file = "cffi-1.14.3-cp35-cp35m-win_amd64.whl", hash = "sha256:e66399cf0fc07de4dce4f588fc25bfe84a6d1285cc544e67987d22663393926d"},
|
{file = "cffi-1.14.4-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:7c6b1dece89874d9541fc974917b631406233ea0440d0bdfbb8e03bf39a49b3b"},
|
||||||
{file = "cffi-1.14.3-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:15f351bed09897fbda218e4db5a3d5c06328862f6198d4fb385f3e14e19decb3"},
|
{file = "cffi-1.14.4-cp36-cp36m-win32.whl", hash = "sha256:155136b51fd733fa94e1c2ea5211dcd4c8879869008fc811648f16541bf99668"},
|
||||||
{file = "cffi-1.14.3-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4d7c26bfc1ea9f92084a1d75e11999e97b62d63128bcc90c3624d07813c52808"},
|
{file = "cffi-1.14.4-cp36-cp36m-win_amd64.whl", hash = "sha256:6bc25fc545a6b3d57b5f8618e59fc13d3a3a68431e8ca5fd4c13241cd70d0009"},
|
||||||
{file = "cffi-1.14.3-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:23e5d2040367322824605bc29ae8ee9175200b92cb5483ac7d466927a9b3d537"},
|
{file = "cffi-1.14.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a7711edca4dcef1a75257b50a2fbfe92a65187c47dab5a0f1b9b332c5919a3fb"},
|
||||||
{file = "cffi-1.14.3-cp36-cp36m-win32.whl", hash = "sha256:a624fae282e81ad2e4871bdb767e2c914d0539708c0f078b5b355258293c98b0"},
|
{file = "cffi-1.14.4-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:00e28066507bfc3fe865a31f325c8391a1ac2916219340f87dfad602c3e48e5d"},
|
||||||
{file = "cffi-1.14.3-cp36-cp36m-win_amd64.whl", hash = "sha256:de31b5164d44ef4943db155b3e8e17929707cac1e5bd2f363e67a56e3af4af6e"},
|
{file = "cffi-1.14.4-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:798caa2a2384b1cbe8a2a139d80734c9db54f9cc155c99d7cc92441a23871c03"},
|
||||||
{file = "cffi-1.14.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:f92cdecb618e5fa4658aeb97d5eb3d2f47aa94ac6477c6daf0f306c5a3b9e6b1"},
|
{file = "cffi-1.14.4-cp37-cp37m-win32.whl", hash = "sha256:00a1ba5e2e95684448de9b89888ccd02c98d512064b4cb987d48f4b40aa0421e"},
|
||||||
{file = "cffi-1.14.3-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:22399ff4870fb4c7ef19fff6eeb20a8bbf15571913c181c78cb361024d574579"},
|
{file = "cffi-1.14.4-cp37-cp37m-win_amd64.whl", hash = "sha256:9cc46bc107224ff5b6d04369e7c595acb700c3613ad7bcf2e2012f62ece80c35"},
|
||||||
{file = "cffi-1.14.3-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:f4eae045e6ab2bb54ca279733fe4eb85f1effda392666308250714e01907f394"},
|
{file = "cffi-1.14.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:df5169c4396adc04f9b0a05f13c074df878b6052430e03f50e68adf3a57aa28d"},
|
||||||
{file = "cffi-1.14.3-cp37-cp37m-win32.whl", hash = "sha256:b0358e6fefc74a16f745afa366acc89f979040e0cbc4eec55ab26ad1f6a9bfbc"},
|
{file = "cffi-1.14.4-cp38-cp38-manylinux1_i686.whl", hash = "sha256:9ffb888f19d54a4d4dfd4b3f29bc2c16aa4972f1c2ab9c4ab09b8ab8685b9c2b"},
|
||||||
{file = "cffi-1.14.3-cp37-cp37m-win_amd64.whl", hash = "sha256:6642f15ad963b5092d65aed022d033c77763515fdc07095208f15d3563003869"},
|
{file = "cffi-1.14.4-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8d6603078baf4e11edc4168a514c5ce5b3ba6e3e9c374298cb88437957960a53"},
|
||||||
{file = "cffi-1.14.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:2791f68edc5749024b4722500e86303a10d342527e1e3bcac47f35fbd25b764e"},
|
{file = "cffi-1.14.4-cp38-cp38-win32.whl", hash = "sha256:b4e248d1087abf9f4c10f3c398896c87ce82a9856494a7155823eb45a892395d"},
|
||||||
{file = "cffi-1.14.3-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:529c4ed2e10437c205f38f3691a68be66c39197d01062618c55f74294a4a4828"},
|
{file = "cffi-1.14.4-cp38-cp38-win_amd64.whl", hash = "sha256:ec80dc47f54e6e9a78181ce05feb71a0353854cc26999db963695f950b5fb375"},
|
||||||
{file = "cffi-1.14.3-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:8f0f1e499e4000c4c347a124fa6a27d37608ced4fe9f7d45070563b7c4c370c9"},
|
{file = "cffi-1.14.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:840793c68105fe031f34d6a086eaea153a0cd5c491cde82a74b420edd0a2b909"},
|
||||||
{file = "cffi-1.14.3-cp38-cp38-win32.whl", hash = "sha256:3b8eaf915ddc0709779889c472e553f0d3e8b7bdf62dab764c8921b09bf94522"},
|
{file = "cffi-1.14.4-cp39-cp39-manylinux1_i686.whl", hash = "sha256:b18e0a9ef57d2b41f5c68beefa32317d286c3d6ac0484efd10d6e07491bb95dd"},
|
||||||
{file = "cffi-1.14.3-cp38-cp38-win_amd64.whl", hash = "sha256:bbd2f4dfee1079f76943767fce837ade3087b578aeb9f69aec7857d5bf25db15"},
|
{file = "cffi-1.14.4-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:045d792900a75e8b1e1b0ab6787dd733a8190ffcf80e8c8ceb2fb10a29ff238a"},
|
||||||
{file = "cffi-1.14.3-cp39-cp39-manylinux1_i686.whl", hash = "sha256:cc75f58cdaf043fe6a7a6c04b3b5a0e694c6a9e24050967747251fb80d7bce0d"},
|
{file = "cffi-1.14.4-cp39-cp39-win32.whl", hash = "sha256:ba4e9e0ae13fc41c6b23299545e5ef73055213e466bd107953e4a013a5ddd7e3"},
|
||||||
{file = "cffi-1.14.3-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:bf39a9e19ce7298f1bd6a9758fa99707e9e5b1ebe5e90f2c3913a47bc548747c"},
|
{file = "cffi-1.14.4-cp39-cp39-win_amd64.whl", hash = "sha256:f032b34669220030f905152045dfa27741ce1a6db3324a5bc0b96b6c7420c87b"},
|
||||||
{file = "cffi-1.14.3-cp39-cp39-win32.whl", hash = "sha256:d80998ed59176e8cba74028762fbd9b9153b9afc71ea118e63bbf5d4d0f9552b"},
|
{file = "cffi-1.14.4.tar.gz", hash = "sha256:1a465cbe98a7fd391d47dce4b8f7e5b921e6cd805ef421d04f5f66ba8f06086c"},
|
||||||
{file = "cffi-1.14.3-cp39-cp39-win_amd64.whl", hash = "sha256:c150eaa3dadbb2b5339675b88d4573c1be3cb6f2c33a6c83387e10cc0bf05bd3"},
|
|
||||||
{file = "cffi-1.14.3.tar.gz", hash = "sha256:f92f789e4f9241cd262ad7a555ca2c648a98178a953af117ef7fad46aa1d5591"},
|
|
||||||
]
|
]
|
||||||
cfgv = [
|
cfgv = [
|
||||||
{file = "cfgv-3.2.0-py2.py3-none-any.whl", hash = "sha256:32e43d604bbe7896fe7c248a9c2276447dbef840feb28fe20494f62af110211d"},
|
{file = "cfgv-3.2.0-py2.py3-none-any.whl", hash = "sha256:32e43d604bbe7896fe7c248a9c2276447dbef840feb28fe20494f62af110211d"},
|
||||||
@@ -1201,8 +1249,8 @@ clikit = [
|
|||||||
{file = "clikit-0.6.2.tar.gz", hash = "sha256:442ee5db9a14120635c5990bcdbfe7c03ada5898291f0c802f77be71569ded59"},
|
{file = "clikit-0.6.2.tar.gz", hash = "sha256:442ee5db9a14120635c5990bcdbfe7c03ada5898291f0c802f77be71569ded59"},
|
||||||
]
|
]
|
||||||
colorama = [
|
colorama = [
|
||||||
{file = "colorama-0.4.3-py2.py3-none-any.whl", hash = "sha256:7d73d2a99753107a36ac6b455ee49046802e59d9d076ef8e47b61499fa29afff"},
|
{file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"},
|
||||||
{file = "colorama-0.4.3.tar.gz", hash = "sha256:e96da0d330793e2cb9485e9ddfd918d456036c7149416295932478192f4436a1"},
|
{file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"},
|
||||||
]
|
]
|
||||||
coverage = [
|
coverage = [
|
||||||
{file = "coverage-5.3-cp27-cp27m-macosx_10_13_intel.whl", hash = "sha256:bd3166bb3b111e76a4f8e2980fa1addf2920a4ca9b2b8ca36a3bc3dedc618270"},
|
{file = "coverage-5.3-cp27-cp27m-macosx_10_13_intel.whl", hash = "sha256:bd3166bb3b111e76a4f8e2980fa1addf2920a4ca9b2b8ca36a3bc3dedc618270"},
|
||||||
@@ -1245,32 +1293,32 @@ crashtest = [
|
|||||||
{file = "crashtest-0.3.1.tar.gz", hash = "sha256:42ca7b6ce88b6c7433e2ce47ea884e91ec93104a4b754998be498a8e6c3d37dd"},
|
{file = "crashtest-0.3.1.tar.gz", hash = "sha256:42ca7b6ce88b6c7433e2ce47ea884e91ec93104a4b754998be498a8e6c3d37dd"},
|
||||||
]
|
]
|
||||||
cryptography = [
|
cryptography = [
|
||||||
{file = "cryptography-3.1.1-cp27-cp27m-macosx_10_10_x86_64.whl", hash = "sha256:65beb15e7f9c16e15934569d29fb4def74ea1469d8781f6b3507ab896d6d8719"},
|
{file = "cryptography-3.2.1-cp27-cp27m-macosx_10_10_x86_64.whl", hash = "sha256:6dc59630ecce8c1f558277ceb212c751d6730bd12c80ea96b4ac65637c4f55e7"},
|
||||||
{file = "cryptography-3.1.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:983c0c3de4cb9fcba68fd3f45ed846eb86a2a8b8d8bc5bb18364c4d00b3c61fe"},
|
{file = "cryptography-3.2.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:75e8e6684cf0034f6bf2a97095cb95f81537b12b36a8fedf06e73050bb171c2d"},
|
||||||
{file = "cryptography-3.1.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:e97a3b627e3cb63c415a16245d6cef2139cca18bb1183d1b9375a1c14e83f3b3"},
|
{file = "cryptography-3.2.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:4e7268a0ca14536fecfdf2b00297d4e407da904718658c1ff1961c713f90fd33"},
|
||||||
{file = "cryptography-3.1.1-cp27-cp27m-win32.whl", hash = "sha256:cb179acdd4ae1e4a5a160d80b87841b3d0e0be84af46c7bb2cd7ece57a39c4ba"},
|
{file = "cryptography-3.2.1-cp27-cp27m-win32.whl", hash = "sha256:7117319b44ed1842c617d0a452383a5a052ec6aa726dfbaffa8b94c910444297"},
|
||||||
{file = "cryptography-3.1.1-cp27-cp27m-win_amd64.whl", hash = "sha256:b372026ebf32fe2523159f27d9f0e9f485092e43b00a5adacf732192a70ba118"},
|
{file = "cryptography-3.2.1-cp27-cp27m-win_amd64.whl", hash = "sha256:a733671100cd26d816eed39507e585c156e4498293a907029969234e5e634bc4"},
|
||||||
{file = "cryptography-3.1.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:680da076cad81cdf5ffcac50c477b6790be81768d30f9da9e01960c4b18a66db"},
|
{file = "cryptography-3.2.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:a75f306a16d9f9afebfbedc41c8c2351d8e61e818ba6b4c40815e2b5740bb6b8"},
|
||||||
{file = "cryptography-3.1.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:5d52c72449bb02dd45a773a203196e6d4fae34e158769c896012401f33064396"},
|
{file = "cryptography-3.2.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:5849d59358547bf789ee7e0d7a9036b2d29e9a4ddf1ce5e06bb45634f995c53e"},
|
||||||
{file = "cryptography-3.1.1-cp35-abi3-macosx_10_10_x86_64.whl", hash = "sha256:f0e099fc4cc697450c3dd4031791559692dd941a95254cb9aeded66a7aa8b9bc"},
|
{file = "cryptography-3.2.1-cp35-abi3-macosx_10_10_x86_64.whl", hash = "sha256:bd717aa029217b8ef94a7d21632a3bb5a4e7218a4513d2521c2a2fd63011e98b"},
|
||||||
{file = "cryptography-3.1.1-cp35-abi3-manylinux1_x86_64.whl", hash = "sha256:a7597ffc67987b37b12e09c029bd1dc43965f75d328076ae85721b84046e9ca7"},
|
{file = "cryptography-3.2.1-cp35-abi3-manylinux1_x86_64.whl", hash = "sha256:efe15aca4f64f3a7ea0c09c87826490e50ed166ce67368a68f315ea0807a20df"},
|
||||||
{file = "cryptography-3.1.1-cp35-abi3-manylinux2010_x86_64.whl", hash = "sha256:4549b137d8cbe3c2eadfa56c0c858b78acbeff956bd461e40000b2164d9167c6"},
|
{file = "cryptography-3.2.1-cp35-abi3-manylinux2010_x86_64.whl", hash = "sha256:32434673d8505b42c0de4de86da8c1620651abd24afe91ae0335597683ed1b77"},
|
||||||
{file = "cryptography-3.1.1-cp35-abi3-manylinux2014_aarch64.whl", hash = "sha256:89aceb31cd5f9fc2449fe8cf3810797ca52b65f1489002d58fe190bfb265c536"},
|
{file = "cryptography-3.2.1-cp35-abi3-manylinux2014_aarch64.whl", hash = "sha256:7b8d9d8d3a9bd240f453342981f765346c87ade811519f98664519696f8e6ab7"},
|
||||||
{file = "cryptography-3.1.1-cp35-cp35m-win32.whl", hash = "sha256:559d622aef2a2dff98a892eef321433ba5bc55b2485220a8ca289c1ecc2bd54f"},
|
{file = "cryptography-3.2.1-cp35-cp35m-win32.whl", hash = "sha256:d3545829ab42a66b84a9aaabf216a4dce7f16dbc76eb69be5c302ed6b8f4a29b"},
|
||||||
{file = "cryptography-3.1.1-cp35-cp35m-win_amd64.whl", hash = "sha256:451cdf60be4dafb6a3b78802006a020e6cd709c22d240f94f7a0696240a17154"},
|
{file = "cryptography-3.2.1-cp35-cp35m-win_amd64.whl", hash = "sha256:a4e27ed0b2504195f855b52052eadcc9795c59909c9d84314c5408687f933fc7"},
|
||||||
{file = "cryptography-3.1.1-cp36-abi3-win32.whl", hash = "sha256:762bc5a0df03c51ee3f09c621e1cee64e3a079a2b5020de82f1613873d79ee70"},
|
{file = "cryptography-3.2.1-cp36-abi3-win32.whl", hash = "sha256:13b88a0bd044b4eae1ef40e265d006e34dbcde0c2f1e15eb9896501b2d8f6c6f"},
|
||||||
{file = "cryptography-3.1.1-cp36-abi3-win_amd64.whl", hash = "sha256:b12e715c10a13ca1bd27fbceed9adc8c5ff640f8e1f7ea76416352de703523c8"},
|
{file = "cryptography-3.2.1-cp36-abi3-win_amd64.whl", hash = "sha256:07ca431b788249af92764e3be9a488aa1d39a0bc3be313d826bbec690417e538"},
|
||||||
{file = "cryptography-3.1.1-cp36-cp36m-win32.whl", hash = "sha256:21b47c59fcb1c36f1113f3709d37935368e34815ea1d7073862e92f810dc7499"},
|
{file = "cryptography-3.2.1-cp36-cp36m-win32.whl", hash = "sha256:a035a10686532b0587d58a606004aa20ad895c60c4d029afa245802347fab57b"},
|
||||||
{file = "cryptography-3.1.1-cp36-cp36m-win_amd64.whl", hash = "sha256:48ee615a779ffa749d7d50c291761dc921d93d7cf203dca2db663b4f193f0e49"},
|
{file = "cryptography-3.2.1-cp36-cp36m-win_amd64.whl", hash = "sha256:d26a2557d8f9122f9bf445fc7034242f4375bd4e95ecda007667540270965b13"},
|
||||||
{file = "cryptography-3.1.1-cp37-cp37m-win32.whl", hash = "sha256:b2bded09c578d19e08bd2c5bb8fed7f103e089752c9cf7ca7ca7de522326e921"},
|
{file = "cryptography-3.2.1-cp37-cp37m-win32.whl", hash = "sha256:545a8550782dda68f8cdc75a6e3bf252017aa8f75f19f5a9ca940772fc0cb56e"},
|
||||||
{file = "cryptography-3.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:f99317a0fa2e49917689b8cf977510addcfaaab769b3f899b9c481bbd76730c2"},
|
{file = "cryptography-3.2.1-cp37-cp37m-win_amd64.whl", hash = "sha256:55d0b896631412b6f0c7de56e12eb3e261ac347fbaa5d5e705291a9016e5f8cb"},
|
||||||
{file = "cryptography-3.1.1-cp38-cp38-win32.whl", hash = "sha256:ab010e461bb6b444eaf7f8c813bb716be2d78ab786103f9608ffd37a4bd7d490"},
|
{file = "cryptography-3.2.1-cp38-cp38-win32.whl", hash = "sha256:3cd75a683b15576cfc822c7c5742b3276e50b21a06672dc3a800a2d5da4ecd1b"},
|
||||||
{file = "cryptography-3.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:99d4984aabd4c7182050bca76176ce2dbc9fa9748afe583a7865c12954d714ba"},
|
{file = "cryptography-3.2.1-cp38-cp38-win_amd64.whl", hash = "sha256:d25cecbac20713a7c3bc544372d42d8eafa89799f492a43b79e1dfd650484851"},
|
||||||
{file = "cryptography-3.1.1.tar.gz", hash = "sha256:9d9fc6a16357965d282dd4ab6531013935425d0dc4950df2e0cf2a1b1ac1017d"},
|
{file = "cryptography-3.2.1.tar.gz", hash = "sha256:d3d5e10be0cf2a12214ddee45c6bd203dab435e3d83b4560c03066eda600bfe3"},
|
||||||
]
|
]
|
||||||
dataclasses = [
|
dataclasses = [
|
||||||
{file = "dataclasses-0.6-py3-none-any.whl", hash = "sha256:454a69d788c7fda44efd71e259be79577822f5e3f53f029a22d08004e951dc9f"},
|
{file = "dataclasses-0.8-py3-none-any.whl", hash = "sha256:0201d89fa866f68c8ebd9d08ee6ff50c0b255f8ec63a71c16fda7af82bb887bf"},
|
||||||
{file = "dataclasses-0.6.tar.gz", hash = "sha256:6988bd2b895eef432d562370bb707d540f32f7360ab13da45340101bc2307d84"},
|
{file = "dataclasses-0.8.tar.gz", hash = "sha256:8479067f342acf957dc82ec415d355ab5edb7e7646b90dc6e2fd1d96ad084c97"},
|
||||||
]
|
]
|
||||||
decorator = [
|
decorator = [
|
||||||
{file = "decorator-4.4.2-py2.py3-none-any.whl", hash = "sha256:41fa54c2a0cc4ba648be4fd43cff00aedf5b9465c9bf18d64325bc225f08f760"},
|
{file = "decorator-4.4.2-py2.py3-none-any.whl", hash = "sha256:41fa54c2a0cc4ba648be4fd43cff00aedf5b9465c9bf18d64325bc225f08f760"},
|
||||||
@@ -1293,16 +1341,16 @@ gitdb = [
|
|||||||
{file = "gitdb-4.0.5.tar.gz", hash = "sha256:c9e1f2d0db7ddb9a704c2a0217be31214e91a4fe1dea1efad19ae42ba0c285c9"},
|
{file = "gitdb-4.0.5.tar.gz", hash = "sha256:c9e1f2d0db7ddb9a704c2a0217be31214e91a4fe1dea1efad19ae42ba0c285c9"},
|
||||||
]
|
]
|
||||||
gitpython = [
|
gitpython = [
|
||||||
{file = "GitPython-3.1.9-py3-none-any.whl", hash = "sha256:138016d519bf4dd55b22c682c904ed2fd0235c3612b2f8f65ce218ff358deed8"},
|
{file = "GitPython-3.1.11-py3-none-any.whl", hash = "sha256:6eea89b655917b500437e9668e4a12eabdcf00229a0df1762aabd692ef9b746b"},
|
||||||
{file = "GitPython-3.1.9.tar.gz", hash = "sha256:a03f728b49ce9597a6655793207c6ab0da55519368ff5961e4a74ae475b9fa8e"},
|
{file = "GitPython-3.1.11.tar.gz", hash = "sha256:befa4d101f91bad1b632df4308ec64555db684c360bd7d2130b4807d49ce86b8"},
|
||||||
]
|
]
|
||||||
html5lib = [
|
html5lib = [
|
||||||
{file = "html5lib-1.1-py2.py3-none-any.whl", hash = "sha256:0d78f8fde1c230e99fe37986a60526d7049ed4bf8a9fadbad5f00e22e58e041d"},
|
{file = "html5lib-1.1-py2.py3-none-any.whl", hash = "sha256:0d78f8fde1c230e99fe37986a60526d7049ed4bf8a9fadbad5f00e22e58e041d"},
|
||||||
{file = "html5lib-1.1.tar.gz", hash = "sha256:b2e5b40261e20f354d198eae92afc10d750afb487ed5e50f9c4eaf07c184146f"},
|
{file = "html5lib-1.1.tar.gz", hash = "sha256:b2e5b40261e20f354d198eae92afc10d750afb487ed5e50f9c4eaf07c184146f"},
|
||||||
]
|
]
|
||||||
identify = [
|
identify = [
|
||||||
{file = "identify-1.5.6-py2.py3-none-any.whl", hash = "sha256:3139bf72d81dfd785b0a464e2776bd59bdc725b4cc10e6cf46b56a0db931c82e"},
|
{file = "identify-1.5.10-py2.py3-none-any.whl", hash = "sha256:cc86e6a9a390879dcc2976cef169dd9cc48843ed70b7380f321d1b118163c60e"},
|
||||||
{file = "identify-1.5.6.tar.gz", hash = "sha256:969d844b7a85d32a5f9ac4e163df6e846d73c87c8b75847494ee8f4bd2186421"},
|
{file = "identify-1.5.10.tar.gz", hash = "sha256:943cd299ac7f5715fcb3f684e2fc1594c1e0f22a90d15398e5888143bd4144b5"},
|
||||||
]
|
]
|
||||||
idna = [
|
idna = [
|
||||||
{file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"},
|
{file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"},
|
||||||
@@ -1313,36 +1361,36 @@ importlib-metadata = [
|
|||||||
{file = "importlib_metadata-1.7.0.tar.gz", hash = "sha256:90bb658cdbbf6d1735b6341ce708fc7024a3e14e99ffdc5783edea9f9b077f83"},
|
{file = "importlib_metadata-1.7.0.tar.gz", hash = "sha256:90bb658cdbbf6d1735b6341ce708fc7024a3e14e99ffdc5783edea9f9b077f83"},
|
||||||
]
|
]
|
||||||
importlib-resources = [
|
importlib-resources = [
|
||||||
{file = "importlib_resources-3.0.0-py2.py3-none-any.whl", hash = "sha256:d028f66b66c0d5732dae86ba4276999855e162a749c92620a38c1d779ed138a7"},
|
{file = "importlib_resources-3.3.0-py2.py3-none-any.whl", hash = "sha256:a3d34a8464ce1d5d7c92b0ea4e921e696d86f2aa212e684451cb1482c8d84ed5"},
|
||||||
{file = "importlib_resources-3.0.0.tar.gz", hash = "sha256:19f745a6eca188b490b1428c8d1d4a0d2368759f32370ea8fb89cad2ab1106c3"},
|
{file = "importlib_resources-3.3.0.tar.gz", hash = "sha256:7b51f0106c8ec564b1bef3d9c588bc694ce2b92125bbb6278f4f2f5b54ec3592"},
|
||||||
]
|
]
|
||||||
iniconfig = [
|
iniconfig = [
|
||||||
{file = "iniconfig-1.0.1-py3-none-any.whl", hash = "sha256:80cf40c597eb564e86346103f609d74efce0f6b4d4f30ec8ce9e2c26411ba437"},
|
{file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"},
|
||||||
{file = "iniconfig-1.0.1.tar.gz", hash = "sha256:e5f92f89355a67de0595932a6c6c02ab4afddc6fcdc0bfc5becd0d60884d3f69"},
|
{file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"},
|
||||||
]
|
]
|
||||||
ipython = [
|
ipython = [
|
||||||
{file = "ipython-7.18.1-py3-none-any.whl", hash = "sha256:2e22c1f74477b5106a6fb301c342ab8c64bb75d702e350f05a649e8cb40a0fb8"},
|
{file = "ipython-7.19.0-py3-none-any.whl", hash = "sha256:c987e8178ced651532b3b1ff9965925bfd445c279239697052561a9ab806d28f"},
|
||||||
{file = "ipython-7.18.1.tar.gz", hash = "sha256:a331e78086001931de9424940699691ad49dfb457cea31f5471eae7b78222d5e"},
|
{file = "ipython-7.19.0.tar.gz", hash = "sha256:cbb2ef3d5961d44e6a963b9817d4ea4e1fa2eb589c371a470fed14d8d40cbd6a"},
|
||||||
]
|
]
|
||||||
ipython-genutils = [
|
ipython-genutils = [
|
||||||
{file = "ipython_genutils-0.2.0-py2.py3-none-any.whl", hash = "sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8"},
|
{file = "ipython_genutils-0.2.0-py2.py3-none-any.whl", hash = "sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8"},
|
||||||
{file = "ipython_genutils-0.2.0.tar.gz", hash = "sha256:eb2e116e75ecef9d4d228fdc66af54269afa26ab4463042e33785b887c628ba8"},
|
{file = "ipython_genutils-0.2.0.tar.gz", hash = "sha256:eb2e116e75ecef9d4d228fdc66af54269afa26ab4463042e33785b887c628ba8"},
|
||||||
]
|
]
|
||||||
isort = [
|
isort = [
|
||||||
{file = "isort-5.6.3-py3-none-any.whl", hash = "sha256:2c1d044a96c74367ab12188593d134c596747d97aec43b9cdb12eea83b6889d2"},
|
{file = "isort-5.6.4-py3-none-any.whl", hash = "sha256:dcab1d98b469a12a1a624ead220584391648790275560e1a43e54c5dceae65e7"},
|
||||||
{file = "isort-5.6.3.tar.gz", hash = "sha256:3820dd92c3214290cda6351f2ae2cedd5170759bc434af600eaad4f7a82a6ade"},
|
{file = "isort-5.6.4.tar.gz", hash = "sha256:dcaeec1b5f0eca77faea2a35ab790b4f3680ff75590bfcb7145986905aab2f58"},
|
||||||
]
|
]
|
||||||
jedi = [
|
jedi = [
|
||||||
{file = "jedi-0.17.2-py2.py3-none-any.whl", hash = "sha256:98cc583fa0f2f8304968199b01b6b4b94f469a1f4a74c1560506ca2a211378b5"},
|
{file = "jedi-0.17.2-py2.py3-none-any.whl", hash = "sha256:98cc583fa0f2f8304968199b01b6b4b94f469a1f4a74c1560506ca2a211378b5"},
|
||||||
{file = "jedi-0.17.2.tar.gz", hash = "sha256:86ed7d9b750603e4ba582ea8edc678657fb4007894a12bcf6f4bb97892f31d20"},
|
{file = "jedi-0.17.2.tar.gz", hash = "sha256:86ed7d9b750603e4ba582ea8edc678657fb4007894a12bcf6f4bb97892f31d20"},
|
||||||
]
|
]
|
||||||
jeepney = [
|
jeepney = [
|
||||||
{file = "jeepney-0.4.3-py3-none-any.whl", hash = "sha256:d6c6b49683446d2407d2fe3acb7a368a77ff063f9182fe427da15d622adc24cf"},
|
{file = "jeepney-0.6.0-py3-none-any.whl", hash = "sha256:aec56c0eb1691a841795111e184e13cad504f7703b9a64f63020816afa79a8ae"},
|
||||||
{file = "jeepney-0.4.3.tar.gz", hash = "sha256:3479b861cc2b6407de5188695fa1a8d57e5072d7059322469b62628869b8e36e"},
|
{file = "jeepney-0.6.0.tar.gz", hash = "sha256:7d59b6622675ca9e993a6bd38de845051d315f8b0c72cca3aef733a20b648657"},
|
||||||
]
|
]
|
||||||
keyring = [
|
keyring = [
|
||||||
{file = "keyring-21.4.0-py3-none-any.whl", hash = "sha256:4e34ea2fdec90c1c43d6610b5a5fafa1b9097db1802948e90caf5763974b8f8d"},
|
{file = "keyring-21.5.0-py3-none-any.whl", hash = "sha256:12de23258a95f3b13e5b167f7a641a878e91eab8ef16fafc077720a95e6115bb"},
|
||||||
{file = "keyring-21.4.0.tar.gz", hash = "sha256:9aeadd006a852b78f4b4ef7c7556c2774d2432bbef8ee538a3e9089ac8b11466"},
|
{file = "keyring-21.5.0.tar.gz", hash = "sha256:207bd66f2a9881c835dad653da04e196c678bf104f8252141d2d3c4f31051579"},
|
||||||
]
|
]
|
||||||
lazy-object-proxy = [
|
lazy-object-proxy = [
|
||||||
{file = "lazy-object-proxy-1.4.3.tar.gz", hash = "sha256:f3900e8a5de27447acbf900b4750b0ddfd7ec1ea7fbaf11dfa911141bc522af0"},
|
{file = "lazy-object-proxy-1.4.3.tar.gz", hash = "sha256:f3900e8a5de27447acbf900b4750b0ddfd7ec1ea7fbaf11dfa911141bc522af0"},
|
||||||
@@ -1432,12 +1480,12 @@ pastel = [
|
|||||||
{file = "pastel-0.2.1.tar.gz", hash = "sha256:e6581ac04e973cac858828c6202c1e1e81fee1dc7de7683f3e1ffe0bfd8a573d"},
|
{file = "pastel-0.2.1.tar.gz", hash = "sha256:e6581ac04e973cac858828c6202c1e1e81fee1dc7de7683f3e1ffe0bfd8a573d"},
|
||||||
]
|
]
|
||||||
pathspec = [
|
pathspec = [
|
||||||
{file = "pathspec-0.8.0-py2.py3-none-any.whl", hash = "sha256:7d91249d21749788d07a2d0f94147accd8f845507400749ea19c1ec9054a12b0"},
|
{file = "pathspec-0.8.1-py2.py3-none-any.whl", hash = "sha256:aa0cb481c4041bf52ffa7b0d8fa6cd3e88a2ca4879c533c9153882ee2556790d"},
|
||||||
{file = "pathspec-0.8.0.tar.gz", hash = "sha256:da45173eb3a6f2a5a487efba21f050af2b41948be6ab52b6a1e3ff22bb8b7061"},
|
{file = "pathspec-0.8.1.tar.gz", hash = "sha256:86379d6b86d75816baba717e64b1a3a3469deb93bb76d613c9ce79edc5cb68fd"},
|
||||||
]
|
]
|
||||||
pbr = [
|
pbr = [
|
||||||
{file = "pbr-5.5.0-py2.py3-none-any.whl", hash = "sha256:5adc0f9fc64319d8df5ca1e4e06eea674c26b80e6f00c530b18ce6a6592ead15"},
|
{file = "pbr-5.5.1-py2.py3-none-any.whl", hash = "sha256:b236cde0ac9a6aedd5e3c34517b423cd4fd97ef723849da6b0d2231142d89c00"},
|
||||||
{file = "pbr-5.5.0.tar.gz", hash = "sha256:14bfd98f51c78a3dd22a1ef45cf194ad79eee4a19e8e1a0d5c7f8e81ffe182ea"},
|
{file = "pbr-5.5.1.tar.gz", hash = "sha256:5fad80b613c402d5b7df7bd84812548b2a61e9977387a80a5fc5c396492b13c9"},
|
||||||
]
|
]
|
||||||
pexpect = [
|
pexpect = [
|
||||||
{file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"},
|
{file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"},
|
||||||
@@ -1448,28 +1496,32 @@ pickleshare = [
|
|||||||
{file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"},
|
{file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"},
|
||||||
]
|
]
|
||||||
pkginfo = [
|
pkginfo = [
|
||||||
{file = "pkginfo-1.5.0.1-py2.py3-none-any.whl", hash = "sha256:a6d9e40ca61ad3ebd0b72fbadd4fba16e4c0e4df0428c041e01e06eb6ee71f32"},
|
{file = "pkginfo-1.6.1-py2.py3-none-any.whl", hash = "sha256:ce14d7296c673dc4c61c759a0b6c14bae34e34eb819c0017bb6ca5b7292c56e9"},
|
||||||
{file = "pkginfo-1.5.0.1.tar.gz", hash = "sha256:7424f2c8511c186cd5424bbf31045b77435b37a8d604990b79d4e70d741148bb"},
|
{file = "pkginfo-1.6.1.tar.gz", hash = "sha256:a6a4ac943b496745cec21f14f021bbd869d5e9b4f6ec06918cffea5a2f4b9193"},
|
||||||
]
|
]
|
||||||
pluggy = [
|
pluggy = [
|
||||||
{file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"},
|
{file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"},
|
||||||
{file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"},
|
{file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"},
|
||||||
]
|
]
|
||||||
poetry = [
|
poetry = [
|
||||||
{file = "poetry-1.1.2-py2.py3-none-any.whl", hash = "sha256:79331ccedcf0710a4b589ba988725d8159518350f883ea290c280623e41dbc43"},
|
{file = "poetry-1.1.4-py2.py3-none-any.whl", hash = "sha256:a0fd73af8831f8d8e910fa9c58af71194ed2d17e43e04cbf5db3087305027d38"},
|
||||||
{file = "poetry-1.1.2.tar.gz", hash = "sha256:acb153b63ebcf01ccc1b42ff2d20e6c8d07cb4aa4914fededcdbbd7546150408"},
|
{file = "poetry-1.1.4.tar.gz", hash = "sha256:946a5a1173be607c7c5c593358a0fb0c0d6af4400c978929ecdb19c3a37b53a8"},
|
||||||
]
|
]
|
||||||
poetry-core = [
|
poetry-core = [
|
||||||
{file = "poetry-core-1.0.0.tar.gz", hash = "sha256:6a664ff389b9f45382536f8fa1611a0cb4d2de7c5a5c885db1f0c600cd11fbd5"},
|
{file = "poetry-core-1.0.0.tar.gz", hash = "sha256:6a664ff389b9f45382536f8fa1611a0cb4d2de7c5a5c885db1f0c600cd11fbd5"},
|
||||||
{file = "poetry_core-1.0.0-py2.py3-none-any.whl", hash = "sha256:769288e0e1b88dfcceb3185728f0b7388b26d5f93d6c22d2dcae372da51d200d"},
|
{file = "poetry_core-1.0.0-py2.py3-none-any.whl", hash = "sha256:769288e0e1b88dfcceb3185728f0b7388b26d5f93d6c22d2dcae372da51d200d"},
|
||||||
]
|
]
|
||||||
pre-commit = [
|
pre-commit = [
|
||||||
{file = "pre_commit-2.7.1-py2.py3-none-any.whl", hash = "sha256:810aef2a2ba4f31eed1941fc270e72696a1ad5590b9751839c90807d0fff6b9a"},
|
{file = "pre_commit-2.9.2-py2.py3-none-any.whl", hash = "sha256:949b13efb7467ae27e2c8f9e83434dacf2682595124d8902554a4e18351e5781"},
|
||||||
{file = "pre_commit-2.7.1.tar.gz", hash = "sha256:c54fd3e574565fe128ecc5e7d2f91279772ddb03f8729645fa812fe809084a70"},
|
{file = "pre_commit-2.9.2.tar.gz", hash = "sha256:e31c04bc23741194a7c0b983fe512801e151a0638c6001c49f2bd034f8a664a1"},
|
||||||
|
]
|
||||||
|
pre-commit-hooks = [
|
||||||
|
{file = "pre_commit_hooks-3.3.0-py2.py3-none-any.whl", hash = "sha256:2190d72ac867bd9b8880de32d9304ec54182c89720cce56f22742890ed8ba90f"},
|
||||||
|
{file = "pre_commit_hooks-3.3.0.tar.gz", hash = "sha256:1e18c0451279fb88653c7b9f8fd73ccc35925e95b636c5b64095538f68a23b06"},
|
||||||
]
|
]
|
||||||
prompt-toolkit = [
|
prompt-toolkit = [
|
||||||
{file = "prompt_toolkit-3.0.7-py3-none-any.whl", hash = "sha256:83074ee28ad4ba6af190593d4d4c607ff525272a504eb159199b6dd9f950c950"},
|
{file = "prompt_toolkit-3.0.8-py3-none-any.whl", hash = "sha256:7debb9a521e0b1ee7d2fe96ee4bd60ef03c6492784de0547337ca4433e46aa63"},
|
||||||
{file = "prompt_toolkit-3.0.7.tar.gz", hash = "sha256:822f4605f28f7d2ba6b0b09a31e25e140871e96364d1d377667b547bb3bf4489"},
|
{file = "prompt_toolkit-3.0.8.tar.gz", hash = "sha256:25c95d2ac813909f813c93fde734b6e44406d1477a9faef7c915ff37d39c0a8c"},
|
||||||
]
|
]
|
||||||
ptyprocess = [
|
ptyprocess = [
|
||||||
{file = "ptyprocess-0.6.0-py2.py3-none-any.whl", hash = "sha256:d7cc528d76e76342423ca640335bd3633420dc1366f258cb31d05e865ef5ca1f"},
|
{file = "ptyprocess-0.6.0-py2.py3-none-any.whl", hash = "sha256:d7cc528d76e76342423ca640335bd3633420dc1366f258cb31d05e865ef5ca1f"},
|
||||||
@@ -1484,8 +1536,8 @@ pycparser = [
|
|||||||
{file = "pycparser-2.20.tar.gz", hash = "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0"},
|
{file = "pycparser-2.20.tar.gz", hash = "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0"},
|
||||||
]
|
]
|
||||||
pygments = [
|
pygments = [
|
||||||
{file = "Pygments-2.7.1-py3-none-any.whl", hash = "sha256:307543fe65c0947b126e83dd5a61bd8acbd84abec11f43caebaf5534cbc17998"},
|
{file = "Pygments-2.7.2-py3-none-any.whl", hash = "sha256:88a0bbcd659fcb9573703957c6b9cff9fab7295e6e76db54c9d00ae42df32773"},
|
||||||
{file = "Pygments-2.7.1.tar.gz", hash = "sha256:926c3f319eda178d1bd90851e4317e6d8cdb5e292a3386aac9bd75eca29cf9c7"},
|
{file = "Pygments-2.7.2.tar.gz", hash = "sha256:381985fcc551eb9d37c52088a32914e00517e57f4a21609f48141ba08e193fa0"},
|
||||||
]
|
]
|
||||||
pylev = [
|
pylev = [
|
||||||
{file = "pylev-1.3.0-py2.py3-none-any.whl", hash = "sha256:1d29a87beb45ebe1e821e7a3b10da2b6b2f4c79b43f482c2df1a1f748a6e114e"},
|
{file = "pylev-1.3.0-py2.py3-none-any.whl", hash = "sha256:1d29a87beb45ebe1e821e7a3b10da2b6b2f4c79b43f482c2df1a1f748a6e114e"},
|
||||||
@@ -1500,8 +1552,8 @@ pyparsing = [
|
|||||||
{file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"},
|
{file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"},
|
||||||
]
|
]
|
||||||
pytest = [
|
pytest = [
|
||||||
{file = "pytest-6.1.1-py3-none-any.whl", hash = "sha256:7a8190790c17d79a11f847fba0b004ee9a8122582ebff4729a082c109e81a4c9"},
|
{file = "pytest-6.1.2-py3-none-any.whl", hash = "sha256:4288fed0d9153d9646bfcdf0c0428197dba1ecb27a33bb6e031d002fa88653fe"},
|
||||||
{file = "pytest-6.1.1.tar.gz", hash = "sha256:8f593023c1a0f916110285b6efd7f99db07d59546e3d8c36fc60e2ab05d3be92"},
|
{file = "pytest-6.1.2.tar.gz", hash = "sha256:c0a7e94a8cdbc5422a51ccdad8e6f1024795939cc89159a0ae7f0b316ad3823e"},
|
||||||
]
|
]
|
||||||
pytest-cov = [
|
pytest-cov = [
|
||||||
{file = "pytest-cov-2.10.1.tar.gz", hash = "sha256:47bd0ce14056fdd79f93e1713f88fad7bdcc583dcd7783da86ef2f085a0bb88e"},
|
{file = "pytest-cov-2.10.1.tar.gz", hash = "sha256:47bd0ce14056fdd79f93e1713f88fad7bdcc583dcd7783da86ef2f085a0bb88e"},
|
||||||
@@ -1525,53 +1577,104 @@ pyyaml = [
|
|||||||
{file = "PyYAML-5.3.1.tar.gz", hash = "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d"},
|
{file = "PyYAML-5.3.1.tar.gz", hash = "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d"},
|
||||||
]
|
]
|
||||||
regex = [
|
regex = [
|
||||||
{file = "regex-2020.10.11-cp27-cp27m-win32.whl", hash = "sha256:4f5c0fe46fb79a7adf766b365cae56cafbf352c27358fda811e4a1dc8216d0db"},
|
{file = "regex-2020.11.13-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:8b882a78c320478b12ff024e81dc7d43c1462aa4a3341c754ee65d857a521f85"},
|
||||||
{file = "regex-2020.10.11-cp27-cp27m-win_amd64.whl", hash = "sha256:39a5ef30bca911f5a8a3d4476f5713ed4d66e313d9fb6755b32bec8a2e519635"},
|
{file = "regex-2020.11.13-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:a63f1a07932c9686d2d416fb295ec2c01ab246e89b4d58e5fa468089cab44b70"},
|
||||||
{file = "regex-2020.10.11-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:7c4fc5a8ec91a2254bb459db27dbd9e16bba1dabff638f425d736888d34aaefa"},
|
{file = "regex-2020.11.13-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:6e4b08c6f8daca7d8f07c8d24e4331ae7953333dbd09c648ed6ebd24db5a10ee"},
|
||||||
{file = "regex-2020.10.11-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:d537e270b3e6bfaea4f49eaf267984bfb3628c86670e9ad2a257358d3b8f0955"},
|
{file = "regex-2020.11.13-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:bba349276b126947b014e50ab3316c027cac1495992f10e5682dc677b3dfa0c5"},
|
||||||
{file = "regex-2020.10.11-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:a8240df4957a5b0e641998a5d78b3c4ea762c845d8cb8997bf820626826fde9a"},
|
{file = "regex-2020.11.13-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:56e01daca75eae420bce184edd8bb341c8eebb19dd3bce7266332258f9fb9dd7"},
|
||||||
{file = "regex-2020.10.11-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:4302153abb96859beb2c778cc4662607a34175065fc2f33a21f49eb3fbd1ccd3"},
|
{file = "regex-2020.11.13-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:6a8ce43923c518c24a2579fda49f093f1397dad5d18346211e46f134fc624e31"},
|
||||||
{file = "regex-2020.10.11-cp36-cp36m-win32.whl", hash = "sha256:c077c9d04a040dba001cf62b3aff08fd85be86bccf2c51a770c77377662a2d55"},
|
{file = "regex-2020.11.13-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:1ab79fcb02b930de09c76d024d279686ec5d532eb814fd0ed1e0051eb8bd2daa"},
|
||||||
{file = "regex-2020.10.11-cp36-cp36m-win_amd64.whl", hash = "sha256:46ab6070b0d2cb85700b8863b3f5504c7f75d8af44289e9562195fe02a8dd72d"},
|
{file = "regex-2020.11.13-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:9801c4c1d9ae6a70aeb2128e5b4b68c45d4f0af0d1535500884d644fa9b768c6"},
|
||||||
{file = "regex-2020.10.11-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:d629d750ebe75a88184db98f759633b0a7772c2e6f4da529f0027b4a402c0e2f"},
|
{file = "regex-2020.11.13-cp36-cp36m-win32.whl", hash = "sha256:49cae022fa13f09be91b2c880e58e14b6da5d10639ed45ca69b85faf039f7a4e"},
|
||||||
{file = "regex-2020.10.11-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:8e7ef296b84d44425760fe813cabd7afbb48c8dd62023018b338bbd9d7d6f2f0"},
|
{file = "regex-2020.11.13-cp36-cp36m-win_amd64.whl", hash = "sha256:749078d1eb89484db5f34b4012092ad14b327944ee7f1c4f74d6279a6e4d1884"},
|
||||||
{file = "regex-2020.10.11-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:e490f08897cb44e54bddf5c6e27deca9b58c4076849f32aaa7a0b9f1730f2c20"},
|
{file = "regex-2020.11.13-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b2f4007bff007c96a173e24dcda236e5e83bde4358a557f9ccf5e014439eae4b"},
|
||||||
{file = "regex-2020.10.11-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:850339226aa4fec04916386577674bb9d69abe0048f5d1a99f91b0004bfdcc01"},
|
{file = "regex-2020.11.13-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:38c8fd190db64f513fe4e1baa59fed086ae71fa45083b6936b52d34df8f86a88"},
|
||||||
{file = "regex-2020.10.11-cp37-cp37m-win32.whl", hash = "sha256:60c4f64d9a326fe48e8738c3dbc068e1edc41ff7895a9e3723840deec4bc1c28"},
|
{file = "regex-2020.11.13-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5862975b45d451b6db51c2e654990c1820523a5b07100fc6903e9c86575202a0"},
|
||||||
{file = "regex-2020.10.11-cp37-cp37m-win_amd64.whl", hash = "sha256:8ba3efdd60bfee1aa784dbcea175eb442d059b576934c9d099e381e5a9f48930"},
|
{file = "regex-2020.11.13-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:262c6825b309e6485ec2493ffc7e62a13cf13fb2a8b6d212f72bd53ad34118f1"},
|
||||||
{file = "regex-2020.10.11-cp38-cp38-manylinux1_i686.whl", hash = "sha256:2308491b3e6c530a3bb38a8a4bb1dc5fd32cbf1e11ca623f2172ba17a81acef1"},
|
{file = "regex-2020.11.13-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:bafb01b4688833e099d79e7efd23f99172f501a15c44f21ea2118681473fdba0"},
|
||||||
{file = "regex-2020.10.11-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:b8806649983a1c78874ec7e04393ef076805740f6319e87a56f91f1767960212"},
|
{file = "regex-2020.11.13-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:e32f5f3d1b1c663af7f9c4c1e72e6ffe9a78c03a31e149259f531e0fed826512"},
|
||||||
{file = "regex-2020.10.11-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:a2a31ee8a354fa3036d12804730e1e20d58bc4e250365ead34b9c30bbe9908c3"},
|
{file = "regex-2020.11.13-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:3bddc701bdd1efa0d5264d2649588cbfda549b2899dc8d50417e47a82e1387ba"},
|
||||||
{file = "regex-2020.10.11-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:d9d53518eeed12190744d366ec4a3f39b99d7daa705abca95f87dd8b442df4ad"},
|
{file = "regex-2020.11.13-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:02951b7dacb123d8ea6da44fe45ddd084aa6777d4b2454fa0da61d569c6fa538"},
|
||||||
{file = "regex-2020.10.11-cp38-cp38-win32.whl", hash = "sha256:3d5a8d007116021cf65355ada47bf405656c4b3b9a988493d26688275fde1f1c"},
|
{file = "regex-2020.11.13-cp37-cp37m-win32.whl", hash = "sha256:0d08e71e70c0237883d0bef12cad5145b84c3705e9c6a588b2a9c7080e5af2a4"},
|
||||||
{file = "regex-2020.10.11-cp38-cp38-win_amd64.whl", hash = "sha256:f579caecbbca291b0fcc7d473664c8c08635da2f9b1567c22ea32311c86ef68c"},
|
{file = "regex-2020.11.13-cp37-cp37m-win_amd64.whl", hash = "sha256:1fa7ee9c2a0e30405e21031d07d7ba8617bc590d391adfc2b7f1e8b99f46f444"},
|
||||||
{file = "regex-2020.10.11-cp39-cp39-manylinux1_i686.whl", hash = "sha256:8c8c42aa5d3ac9a49829c4b28a81bebfa0378996f9e0ca5b5ab8a36870c3e5ee"},
|
{file = "regex-2020.11.13-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:baf378ba6151f6e272824b86a774326f692bc2ef4cc5ce8d5bc76e38c813a55f"},
|
||||||
{file = "regex-2020.10.11-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:c529ba90c1775697a65b46c83d47a2d3de70f24d96da5d41d05a761c73b063af"},
|
{file = "regex-2020.11.13-cp38-cp38-manylinux1_i686.whl", hash = "sha256:e3faaf10a0d1e8e23a9b51d1900b72e1635c2d5b0e1bea1c18022486a8e2e52d"},
|
||||||
{file = "regex-2020.10.11-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:6cf527ec2f3565248408b61dd36e380d799c2a1047eab04e13a2b0c15dd9c767"},
|
{file = "regex-2020.11.13-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:2a11a3e90bd9901d70a5b31d7dd85114755a581a5da3fc996abfefa48aee78af"},
|
||||||
{file = "regex-2020.10.11-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:671c51d352cfb146e48baee82b1ee8d6ffe357c292f5e13300cdc5c00867ebfc"},
|
{file = "regex-2020.11.13-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:d1ebb090a426db66dd80df8ca85adc4abfcbad8a7c2e9a5ec7513ede522e0a8f"},
|
||||||
{file = "regex-2020.10.11-cp39-cp39-win32.whl", hash = "sha256:a63907332531a499b8cdfd18953febb5a4c525e9e7ca4ac147423b917244b260"},
|
{file = "regex-2020.11.13-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:b2b1a5ddae3677d89b686e5c625fc5547c6e492bd755b520de5332773a8af06b"},
|
||||||
{file = "regex-2020.10.11-cp39-cp39-win_amd64.whl", hash = "sha256:1a16afbfadaadc1397353f9b32e19a65dc1d1804c80ad73a14f435348ca017ad"},
|
{file = "regex-2020.11.13-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:2c99e97d388cd0a8d30f7c514d67887d8021541b875baf09791a3baad48bb4f8"},
|
||||||
{file = "regex-2020.10.11.tar.gz", hash = "sha256:463e770c48da76a8da82b8d4a48a541f314e0df91cbb6d873a341dbe578efafd"},
|
{file = "regex-2020.11.13-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:c084582d4215593f2f1d28b65d2a2f3aceff8342aa85afd7be23a9cad74a0de5"},
|
||||||
|
{file = "regex-2020.11.13-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:a3d748383762e56337c39ab35c6ed4deb88df5326f97a38946ddd19028ecce6b"},
|
||||||
|
{file = "regex-2020.11.13-cp38-cp38-win32.whl", hash = "sha256:7913bd25f4ab274ba37bc97ad0e21c31004224ccb02765ad984eef43e04acc6c"},
|
||||||
|
{file = "regex-2020.11.13-cp38-cp38-win_amd64.whl", hash = "sha256:6c54ce4b5d61a7129bad5c5dc279e222afd00e721bf92f9ef09e4fae28755683"},
|
||||||
|
{file = "regex-2020.11.13-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1862a9d9194fae76a7aaf0150d5f2a8ec1da89e8b55890b1786b8f88a0f619dc"},
|
||||||
|
{file = "regex-2020.11.13-cp39-cp39-manylinux1_i686.whl", hash = "sha256:4902e6aa086cbb224241adbc2f06235927d5cdacffb2425c73e6570e8d862364"},
|
||||||
|
{file = "regex-2020.11.13-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:7a25fcbeae08f96a754b45bdc050e1fb94b95cab046bf56b016c25e9ab127b3e"},
|
||||||
|
{file = "regex-2020.11.13-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:d2d8ce12b7c12c87e41123997ebaf1a5767a5be3ec545f64675388970f415e2e"},
|
||||||
|
{file = "regex-2020.11.13-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:f7d29a6fc4760300f86ae329e3b6ca28ea9c20823df123a2ea8693e967b29917"},
|
||||||
|
{file = "regex-2020.11.13-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:717881211f46de3ab130b58ec0908267961fadc06e44f974466d1887f865bd5b"},
|
||||||
|
{file = "regex-2020.11.13-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:3128e30d83f2e70b0bed9b2a34e92707d0877e460b402faca908c6667092ada9"},
|
||||||
|
{file = "regex-2020.11.13-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:8f6a2229e8ad946e36815f2a03386bb8353d4bde368fdf8ca5f0cb97264d3b5c"},
|
||||||
|
{file = "regex-2020.11.13-cp39-cp39-win32.whl", hash = "sha256:f8f295db00ef5f8bae530fc39af0b40486ca6068733fb860b42115052206466f"},
|
||||||
|
{file = "regex-2020.11.13-cp39-cp39-win_amd64.whl", hash = "sha256:a15f64ae3a027b64496a71ab1f722355e570c3fac5ba2801cafce846bf5af01d"},
|
||||||
|
{file = "regex-2020.11.13.tar.gz", hash = "sha256:83d6b356e116ca119db8e7c6fc2983289d87b27b3fac238cfe5dca529d884562"},
|
||||||
]
|
]
|
||||||
reorder-python-imports = [
|
reorder-python-imports = [
|
||||||
{file = "reorder_python_imports-2.3.5-py2.py3-none-any.whl", hash = "sha256:6e8d3baba68c409ec87242757cf579a7ad2b133d1efed498be987b97ee385ac3"},
|
{file = "reorder_python_imports-2.3.6-py2.py3-none-any.whl", hash = "sha256:1299c31adf341eba2c17543e3cc7fab7389766e726ab54d20440917b5b96b5c5"},
|
||||||
{file = "reorder_python_imports-2.3.5.tar.gz", hash = "sha256:7c46593d39899e3fb249248b448bde93ee7417889904f015c0c5a738c23fd0e0"},
|
{file = "reorder_python_imports-2.3.6.tar.gz", hash = "sha256:2ea16d2253536e7f90427b383cd046e46977ca25aae82464883eee882bc7d21b"},
|
||||||
]
|
]
|
||||||
requests = [
|
requests = [
|
||||||
{file = "requests-2.24.0-py2.py3-none-any.whl", hash = "sha256:fe75cc94a9443b9246fc7049224f75604b113c36acb93f87b80ed42c44cbb898"},
|
{file = "requests-2.25.0-py2.py3-none-any.whl", hash = "sha256:e786fa28d8c9154e6a4de5d46a1d921b8749f8b74e28bde23768e5e16eece998"},
|
||||||
{file = "requests-2.24.0.tar.gz", hash = "sha256:b3559a131db72c33ee969480840fff4bb6dd111de7dd27c8ee1f820f4f00231b"},
|
{file = "requests-2.25.0.tar.gz", hash = "sha256:7f1a0b932f4a60a1a65caa4263921bb7d9ee911957e0ae4a23a6dd08185ad5f8"},
|
||||||
]
|
]
|
||||||
requests-toolbelt = [
|
requests-toolbelt = [
|
||||||
{file = "requests-toolbelt-0.9.1.tar.gz", hash = "sha256:968089d4584ad4ad7c171454f0a5c6dac23971e9472521ea3b6d49d610aa6fc0"},
|
{file = "requests-toolbelt-0.9.1.tar.gz", hash = "sha256:968089d4584ad4ad7c171454f0a5c6dac23971e9472521ea3b6d49d610aa6fc0"},
|
||||||
{file = "requests_toolbelt-0.9.1-py2.py3-none-any.whl", hash = "sha256:380606e1d10dc85c3bd47bf5a6095f815ec007be7a8b69c878507068df059e6f"},
|
{file = "requests_toolbelt-0.9.1-py2.py3-none-any.whl", hash = "sha256:380606e1d10dc85c3bd47bf5a6095f815ec007be7a8b69c878507068df059e6f"},
|
||||||
]
|
]
|
||||||
|
"ruamel.yaml" = [
|
||||||
|
{file = "ruamel.yaml-0.16.12-py2.py3-none-any.whl", hash = "sha256:012b9470a0ea06e4e44e99e7920277edf6b46eee0232a04487ea73a7386340a5"},
|
||||||
|
{file = "ruamel.yaml-0.16.12.tar.gz", hash = "sha256:076cc0bc34f1966d920a49f18b52b6ad559fbe656a0748e3535cf7b3f29ebf9e"},
|
||||||
|
]
|
||||||
|
"ruamel.yaml.clib" = [
|
||||||
|
{file = "ruamel.yaml.clib-0.2.2-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:28116f204103cb3a108dfd37668f20abe6e3cafd0d3fd40dba126c732457b3cc"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.2-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:daf21aa33ee9b351f66deed30a3d450ab55c14242cfdfcd377798e2c0d25c9f1"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.2-cp27-cp27m-win32.whl", hash = "sha256:30dca9bbcbb1cc858717438218d11eafb78666759e5094dd767468c0d577a7e7"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.2-cp27-cp27m-win_amd64.whl", hash = "sha256:f6061a31880c1ed6b6ce341215336e2f3d0c1deccd84957b6fa8ca474b41e89f"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.2-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:73b3d43e04cc4b228fa6fa5d796409ece6fcb53a6c270eb2048109cbcbc3b9c2"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.2-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:53b9dd1abd70e257a6e32f934ebc482dac5edb8c93e23deb663eac724c30b026"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:839dd72545ef7ba78fd2aa1a5dd07b33696adf3e68fae7f31327161c1093001b"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.2-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:1236df55e0f73cd138c0eca074ee086136c3f16a97c2ac719032c050f7e0622f"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.2-cp35-cp35m-win32.whl", hash = "sha256:b1e981fe1aff1fd11627f531524826a4dcc1f26c726235a52fcb62ded27d150f"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.2-cp35-cp35m-win_amd64.whl", hash = "sha256:4e52c96ca66de04be42ea2278012a2342d89f5e82b4512fb6fb7134e377e2e62"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:a873e4d4954f865dcb60bdc4914af7eaae48fb56b60ed6daa1d6251c72f5337c"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:ab845f1f51f7eb750a78937be9f79baea4a42c7960f5a94dde34e69f3cce1988"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.2-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:2fd336a5c6415c82e2deb40d08c222087febe0aebe520f4d21910629018ab0f3"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.2-cp36-cp36m-win32.whl", hash = "sha256:e9f7d1d8c26a6a12c23421061f9022bb62704e38211fe375c645485f38df34a2"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.2-cp36-cp36m-win_amd64.whl", hash = "sha256:2602e91bd5c1b874d6f93d3086f9830f3e907c543c7672cf293a97c3fabdcd91"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:44c7b0498c39f27795224438f1a6be6c5352f82cb887bc33d962c3a3acc00df6"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:8e8fd0a22c9d92af3a34f91e8a2594eeb35cba90ab643c5e0e643567dc8be43e"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.2-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:75f0ee6839532e52a3a53f80ce64925ed4aed697dd3fa890c4c918f3304bd4f4"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.2-cp37-cp37m-win32.whl", hash = "sha256:464e66a04e740d754170be5e740657a3b3b6d2bcc567f0c3437879a6e6087ff6"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.2-cp37-cp37m-win_amd64.whl", hash = "sha256:52ae5739e4b5d6317b52f5b040b1b6639e8af68a5b8fd606a8b08658fbd0cab5"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4df5019e7783d14b79217ad9c56edf1ba7485d614ad5a385d1b3c768635c81c0"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:5254af7d8bdf4d5484c089f929cb7f5bafa59b4f01d4f48adda4be41e6d29f99"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.2-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:8be05be57dc5c7b4a0b24edcaa2f7275866d9c907725226cdde46da09367d923"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.2-cp38-cp38-win32.whl", hash = "sha256:74161d827407f4db9072011adcfb825b5258a5ccb3d2cd518dd6c9edea9e30f1"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.2-cp38-cp38-win_amd64.whl", hash = "sha256:058a1cc3df2a8aecc12f983a48bda99315cebf55a3b3a5463e37bb599b05727b"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c6ac7e45367b1317e56f1461719c853fd6825226f45b835df7436bb04031fd8a"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:b4b0d31f2052b3f9f9b5327024dc629a253a83d8649d4734ca7f35b60ec3e9e5"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.2-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:1f8c0a4577c0e6c99d208de5c4d3fd8aceed9574bb154d7a2b21c16bb924154c"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.2-cp39-cp39-win32.whl", hash = "sha256:46d6d20815064e8bb023ea8628cfb7402c0f0e83de2c2227a88097e239a7dffd"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:6c0a5dc52fc74eb87c67374a4e554d4761fd42a4d01390b7e868b30d21f4b8bb"},
|
||||||
|
{file = "ruamel.yaml.clib-0.2.2.tar.gz", hash = "sha256:2d24bd98af676f4990c4d715bcdc2a60b19c56a3fb3a763164d2d8ca0e806ba7"},
|
||||||
|
]
|
||||||
safety = [
|
safety = [
|
||||||
{file = "safety-1.9.0-py2.py3-none-any.whl", hash = "sha256:86c1c4a031fe35bd624fce143fbe642a0234d29f7cbf7a9aa269f244a955b087"},
|
{file = "safety-1.9.0-py2.py3-none-any.whl", hash = "sha256:86c1c4a031fe35bd624fce143fbe642a0234d29f7cbf7a9aa269f244a955b087"},
|
||||||
{file = "safety-1.9.0.tar.gz", hash = "sha256:23bf20690d4400edc795836b0c983c2b4cbbb922233108ff925b7dd7750f00c9"},
|
{file = "safety-1.9.0.tar.gz", hash = "sha256:23bf20690d4400edc795836b0c983c2b4cbbb922233108ff925b7dd7750f00c9"},
|
||||||
]
|
]
|
||||||
secretstorage = [
|
secretstorage = [
|
||||||
{file = "SecretStorage-3.1.2-py3-none-any.whl", hash = "sha256:b5ec909dde94d4ae2fa26af7c089036997030f0cf0a5cb372b4cccabd81c143b"},
|
{file = "SecretStorage-3.3.0-py3-none-any.whl", hash = "sha256:5c36f6537a523ec5f969ef9fad61c98eb9e017bc601d811e53aa25bece64892f"},
|
||||||
{file = "SecretStorage-3.1.2.tar.gz", hash = "sha256:15da8a989b65498e29be338b3b279965f1b8f09b9668bd8010da183024c8bff6"},
|
{file = "SecretStorage-3.3.0.tar.gz", hash = "sha256:30cfdef28829dad64d6ea1ed08f8eff6aa115a77068926bcc9f5225d5a3246aa"},
|
||||||
]
|
]
|
||||||
shellingham = [
|
shellingham = [
|
||||||
{file = "shellingham-1.3.2-py2.py3-none-any.whl", hash = "sha256:7f6206ae169dc1a03af8a138681b3f962ae61cc93ade84d0585cca3aaf770044"},
|
{file = "shellingham-1.3.2-py2.py3-none-any.whl", hash = "sha256:7f6206ae169dc1a03af8a138681b3f962ae61cc93ade84d0585cca3aaf770044"},
|
||||||
@@ -1590,8 +1693,8 @@ stevedore = [
|
|||||||
{file = "stevedore-3.2.2.tar.gz", hash = "sha256:f845868b3a3a77a2489d226568abe7328b5c2d4f6a011cc759dfa99144a521f0"},
|
{file = "stevedore-3.2.2.tar.gz", hash = "sha256:f845868b3a3a77a2489d226568abe7328b5c2d4f6a011cc759dfa99144a521f0"},
|
||||||
]
|
]
|
||||||
toml = [
|
toml = [
|
||||||
{file = "toml-0.10.1-py2.py3-none-any.whl", hash = "sha256:bda89d5935c2eac546d648028b9901107a595863cb36bae0c73ac804a9b4ce88"},
|
{file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
|
||||||
{file = "toml-0.10.1.tar.gz", hash = "sha256:926b612be1e5ce0634a2ca03470f95169cf16f939018233a670519cb4ac58b0f"},
|
{file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
|
||||||
]
|
]
|
||||||
tomlkit = [
|
tomlkit = [
|
||||||
{file = "tomlkit-0.7.0-py2.py3-none-any.whl", hash = "sha256:6babbd33b17d5c9691896b0e68159215a9387ebfa938aa3ac42f4a4beeb2b831"},
|
{file = "tomlkit-0.7.0-py2.py3-none-any.whl", hash = "sha256:6babbd33b17d5c9691896b0e68159215a9387ebfa938aa3ac42f4a4beeb2b831"},
|
||||||
@@ -1602,8 +1705,8 @@ tox = [
|
|||||||
{file = "tox-3.20.1.tar.gz", hash = "sha256:4321052bfe28f9d85082341ca8e233e3ea901fdd14dab8a5d3fbd810269fbaf6"},
|
{file = "tox-3.20.1.tar.gz", hash = "sha256:4321052bfe28f9d85082341ca8e233e3ea901fdd14dab8a5d3fbd810269fbaf6"},
|
||||||
]
|
]
|
||||||
traitlets = [
|
traitlets = [
|
||||||
{file = "traitlets-5.0.4-py3-none-any.whl", hash = "sha256:9664ec0c526e48e7b47b7d14cd6b252efa03e0129011de0a9c1d70315d4309c3"},
|
{file = "traitlets-5.0.5-py3-none-any.whl", hash = "sha256:69ff3f9d5351f31a7ad80443c2674b7099df13cc41fc5fa6e2f6d3b0330b0426"},
|
||||||
{file = "traitlets-5.0.4.tar.gz", hash = "sha256:86c9351f94f95de9db8a04ad8e892da299a088a64fd283f9f6f18770ae5eae1b"},
|
{file = "traitlets-5.0.5.tar.gz", hash = "sha256:178f4ce988f69189f7e523337a3e11d91c786ded9360174a3d9ca83e79bc5396"},
|
||||||
]
|
]
|
||||||
typed-ast = [
|
typed-ast = [
|
||||||
{file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3"},
|
{file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3"},
|
||||||
@@ -1634,12 +1737,12 @@ typing-extensions = [
|
|||||||
{file = "typing_extensions-3.7.4.3.tar.gz", hash = "sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c"},
|
{file = "typing_extensions-3.7.4.3.tar.gz", hash = "sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c"},
|
||||||
]
|
]
|
||||||
urllib3 = [
|
urllib3 = [
|
||||||
{file = "urllib3-1.25.10-py2.py3-none-any.whl", hash = "sha256:e7983572181f5e1522d9c98453462384ee92a0be7fac5f1413a1e35c56cc0461"},
|
{file = "urllib3-1.26.2-py2.py3-none-any.whl", hash = "sha256:d8ff90d979214d7b4f8ce956e80f4028fc6860e4431f731ea4a8c08f23f99473"},
|
||||||
{file = "urllib3-1.25.10.tar.gz", hash = "sha256:91056c15fa70756691db97756772bb1eb9678fa585d9184f24534b100dc60f4a"},
|
{file = "urllib3-1.26.2.tar.gz", hash = "sha256:19188f96923873c92ccb987120ec4acaa12f0461fa9ce5d3d0772bc965a39e08"},
|
||||||
]
|
]
|
||||||
virtualenv = [
|
virtualenv = [
|
||||||
{file = "virtualenv-20.0.33-py2.py3-none-any.whl", hash = "sha256:35ecdeb58cfc2147bb0706f7cdef69a8f34f1b81b6d49568174e277932908b8f"},
|
{file = "virtualenv-20.2.1-py2.py3-none-any.whl", hash = "sha256:07cff122e9d343140366055f31be4dcd61fd598c69d11cd33a9d9c8df4546dd7"},
|
||||||
{file = "virtualenv-20.0.33.tar.gz", hash = "sha256:a5e0d253fe138097c6559c906c528647254f437d1019af9d5a477b09bfa7300f"},
|
{file = "virtualenv-20.2.1.tar.gz", hash = "sha256:e0aac7525e880a429764cefd3aaaff54afb5d9f25c82627563603f5d7de5a6e5"},
|
||||||
]
|
]
|
||||||
wcwidth = [
|
wcwidth = [
|
||||||
{file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"},
|
{file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"},
|
||||||
@@ -1653,6 +1756,6 @@ wrapt = [
|
|||||||
{file = "wrapt-1.12.1.tar.gz", hash = "sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7"},
|
{file = "wrapt-1.12.1.tar.gz", hash = "sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7"},
|
||||||
]
|
]
|
||||||
zipp = [
|
zipp = [
|
||||||
{file = "zipp-3.3.0-py3-none-any.whl", hash = "sha256:eed8ec0b8d1416b2ca33516a37a08892442f3954dee131e92cfd92d8fe3e7066"},
|
{file = "zipp-3.4.0-py3-none-any.whl", hash = "sha256:102c24ef8f171fd729d46599845e95c7ab894a4cf45f5de11a44cc7444fb1108"},
|
||||||
{file = "zipp-3.3.0.tar.gz", hash = "sha256:64ad89efee774d1897a58607895d80789c59778ea02185dd846ac38394a8642b"},
|
{file = "zipp-3.4.0.tar.gz", hash = "sha256:ed5eee1974372595f9e416cc7bbeeb12335201d8081ca8a0743c954d4446e5cb"},
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,14 +1,17 @@
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "tox-poetry-installer"
|
name = "tox-poetry-installer"
|
||||||
version = "0.3.1"
|
version = "0.5.2"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
authors = ["Ethan Paul <24588726+enpaul@users.noreply.github.com>"]
|
authors = ["Ethan Paul <24588726+enpaul@users.noreply.github.com>"]
|
||||||
description = "Tox plugin to install Tox environment dependencies using the Poetry backend and lockfile"
|
description = "Tox plugin to install Tox environment dependencies using the Poetry backend and lockfile"
|
||||||
repository = "https://github.com/enpaul/tox-poetry-installer/"
|
repository = "https://github.com/enpaul/tox-poetry-installer/"
|
||||||
packages = [
|
packages = [
|
||||||
{include = "tox_poetry_installer.py"},
|
{include = "tox_poetry_installer"},
|
||||||
{include = "tests/*.py", format = "sdist"}
|
{include = "tests/*.py", format = "sdist"}
|
||||||
]
|
]
|
||||||
|
include = [
|
||||||
|
"tox_poetry_installer/py.typed"
|
||||||
|
]
|
||||||
keywords = ["tox", "poetry", "plugin"]
|
keywords = ["tox", "poetry", "plugin"]
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
classifiers = [
|
classifiers = [
|
||||||
@@ -22,6 +25,7 @@ classifiers = [
|
|||||||
"Programming Language :: Python :: 3.6",
|
"Programming Language :: Python :: 3.6",
|
||||||
"Programming Language :: Python :: 3.7",
|
"Programming Language :: Python :: 3.7",
|
||||||
"Programming Language :: Python :: 3.8",
|
"Programming Language :: Python :: 3.8",
|
||||||
|
"Programming Language :: Python :: 3.9",
|
||||||
"Programming Language :: Python :: Implementation :: CPython",
|
"Programming Language :: Python :: Implementation :: CPython",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -29,25 +33,27 @@ classifiers = [
|
|||||||
poetry_installer = "tox_poetry_installer"
|
poetry_installer = "tox_poetry_installer"
|
||||||
|
|
||||||
[tool.poetry.dependencies]
|
[tool.poetry.dependencies]
|
||||||
python = "^3.6"
|
python = "^3.6.1"
|
||||||
poetry = "^1.0.0"
|
poetry = "^1.0.0"
|
||||||
poetry-core = "^1.0.0"
|
poetry-core = "^1.0.0"
|
||||||
tox = "^2.3.0 || ^3.0.0"
|
tox = "^2.3.0 || ^3.0.0"
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
[tool.poetry.dev-dependencies]
|
||||||
bandit = "^1.6.2"
|
bandit = "^1.6.2"
|
||||||
black = {version = "^20.8b1", allow-prereleases = true}
|
black = { version = "^20.8b1", allow-prereleases = true }
|
||||||
ipython = {version = "^7.18.1", python = "^3.7"}
|
blacken-docs = "^1.8.0"
|
||||||
|
ipython = { version = "^7.18.1", python = "^3.7" }
|
||||||
mypy = "^0.782"
|
mypy = "^0.782"
|
||||||
pre-commit = {version = "^2.7.1", python = "^3.6.1"}
|
pre-commit = "^2.7.1"
|
||||||
|
pre-commit-hooks = "^3.3.0"
|
||||||
pylint = "^2.4.4"
|
pylint = "^2.4.4"
|
||||||
pytest = "^6.0.2"
|
pytest = "^6.0.2"
|
||||||
pytest-cov = "^2.10.1"
|
pytest-cov = "^2.10.1"
|
||||||
reorder-python-imports = {version = "^2.3.5", python = "^3.6.1"}
|
reorder-python-imports = "^2.3.5"
|
||||||
safety = "^1.9.0"
|
safety = "^1.9.0"
|
||||||
toml = "^0.10.1"
|
toml = "^0.10.1"
|
||||||
tox = "^3.20.0"
|
tox = "^3.20.0"
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["poetry>=1.0.0"]
|
requires = ["poetry-core>=1.0.0"]
|
||||||
build-backend = "poetry.masonry.api"
|
build-backend = "poetry.core.masonry.api"
|
||||||
|
|||||||
0
tests/__init__.py
Normal file
0
tests/__init__.py
Normal file
@@ -7,7 +7,7 @@ from pathlib import Path
|
|||||||
|
|
||||||
import toml
|
import toml
|
||||||
|
|
||||||
import tox_poetry_installer
|
from tox_poetry_installer import __about__
|
||||||
|
|
||||||
|
|
||||||
def test_metadata():
|
def test_metadata():
|
||||||
@@ -16,16 +16,14 @@ def test_metadata():
|
|||||||
with (Path(__file__).resolve().parent / ".." / "pyproject.toml").open() as infile:
|
with (Path(__file__).resolve().parent / ".." / "pyproject.toml").open() as infile:
|
||||||
pyproject = toml.load(infile, _dict=dict)
|
pyproject = toml.load(infile, _dict=dict)
|
||||||
|
|
||||||
assert pyproject["tool"]["poetry"]["name"] == tox_poetry_installer.__title__
|
assert pyproject["tool"]["poetry"]["name"] == __about__.__title__
|
||||||
assert pyproject["tool"]["poetry"]["version"] == tox_poetry_installer.__version__
|
assert pyproject["tool"]["poetry"]["version"] == __about__.__version__
|
||||||
assert pyproject["tool"]["poetry"]["license"] == tox_poetry_installer.__license__
|
assert pyproject["tool"]["poetry"]["license"] == __about__.__license__
|
||||||
assert (
|
assert pyproject["tool"]["poetry"]["description"] == __about__.__summary__
|
||||||
pyproject["tool"]["poetry"]["description"] == tox_poetry_installer.__summary__
|
assert pyproject["tool"]["poetry"]["repository"] == __about__.__url__
|
||||||
)
|
|
||||||
assert pyproject["tool"]["poetry"]["repository"] == tox_poetry_installer.__url__
|
|
||||||
assert (
|
assert (
|
||||||
all(
|
all(
|
||||||
item in tox_poetry_installer.__authors__
|
item in __about__.__authors__
|
||||||
for item in pyproject["tool"]["poetry"]["authors"]
|
for item in pyproject["tool"]["poetry"]["authors"]
|
||||||
)
|
)
|
||||||
is True
|
is True
|
||||||
@@ -33,7 +31,7 @@ def test_metadata():
|
|||||||
assert (
|
assert (
|
||||||
all(
|
all(
|
||||||
item in pyproject["tool"]["poetry"]["authors"]
|
item in pyproject["tool"]["poetry"]["authors"]
|
||||||
for item in tox_poetry_installer.__authors__
|
for item in __about__.__authors__
|
||||||
)
|
)
|
||||||
is True
|
is True
|
||||||
)
|
)
|
||||||
|
|||||||
58
tox.ini
58
tox.ini
@@ -1,66 +1,62 @@
|
|||||||
[tox]
|
[tox]
|
||||||
envlist = py36, py37, py38, static, static-tests, security
|
envlist = py36, py37, py38, py39, static, static-tests, security
|
||||||
isolated_build = true
|
isolated_build = true
|
||||||
|
skip_missing_interpreters = true
|
||||||
|
|
||||||
[testenv]
|
[testenv]
|
||||||
description = Run the tests
|
description = Run the tests
|
||||||
require_locked_deps = true
|
require_locked_deps = true
|
||||||
deps =
|
locked_deps =
|
||||||
pytest
|
pytest
|
||||||
pytest-cov
|
pytest-cov
|
||||||
toml
|
toml
|
||||||
commands =
|
commands =
|
||||||
pytest --cov tox_poetry_installer --cov-config {toxinidir}/.coveragerc tests/ --cov-report term-missing
|
pytest --cov {envsitepackagesdir}/tox_poetry_installer --cov-config {toxinidir}/.coveragerc --cov-report term-missing tests/
|
||||||
|
|
||||||
[testenv:static]
|
[testenv:static]
|
||||||
description = Static formatting and quality enforcement
|
description = Static formatting and quality enforcement
|
||||||
require_locked_deps = true
|
|
||||||
basepython = python3.8
|
basepython = python3.8
|
||||||
|
platform = linux
|
||||||
ignore_errors = true
|
ignore_errors = true
|
||||||
deps =
|
require_locked_deps = true
|
||||||
|
locked_deps =
|
||||||
|
pre-commit
|
||||||
|
pre-commit-hooks
|
||||||
|
black
|
||||||
|
blacken-docs
|
||||||
|
reorder-python-imports
|
||||||
pylint
|
pylint
|
||||||
mypy
|
mypy
|
||||||
black
|
|
||||||
reorder-python-imports
|
|
||||||
pre-commit
|
|
||||||
commands =
|
commands =
|
||||||
black {toxinidir}/tox_poetry_installer.py
|
|
||||||
reorder-python-imports {toxinidir}/tox_poetry_installer.py
|
|
||||||
pre-commit run --all-files
|
pre-commit run --all-files
|
||||||
pylint --rcfile {toxinidir}/.pylintrc {toxinidir}/tox_poetry_installer.py
|
pylint --rcfile {toxinidir}/.pylintrc {toxinidir}/tox_poetry_installer/
|
||||||
mypy --ignore-missing-imports --no-strict-optional {toxinidir}/tox_poetry_installer.py
|
mypy --ignore-missing-imports --no-strict-optional {toxinidir}/tox_poetry_installer/
|
||||||
|
|
||||||
[testenv:static-tests]
|
[testenv:static-tests]
|
||||||
description = Static formatting and quality enforcement for the tests
|
description = Static formatting and quality enforcement for the tests
|
||||||
require_locked_deps = true
|
|
||||||
basepython = python3.8
|
basepython = python3.8
|
||||||
|
platform = linux
|
||||||
ingore_errors = true
|
ingore_errors = true
|
||||||
deps =
|
require_locked_deps = true
|
||||||
|
locked_deps =
|
||||||
pylint
|
pylint
|
||||||
mypy
|
mypy
|
||||||
black
|
|
||||||
reorder-python-imports
|
|
||||||
allowlist_externals =
|
|
||||||
bash
|
|
||||||
commands =
|
commands =
|
||||||
black {toxinidir}/tests/
|
pylint --rcfile {toxinidir}/.pylintrc {toxinidir}/tests/
|
||||||
bash -c "reorder-python-imports {toxinidir}/tests/*.py --unclassifiable-application-module tox_poetry_installer"
|
mypy --ignore-missing-imports --no-strict-optional {toxinidir}/tests/
|
||||||
bash -c "pylint --rcfile {toxinidir}/.pylintrc {toxinidir}/tests/*.py"
|
|
||||||
bash -c "mypy --ignore-missing-imports --no-strict-optional {toxinidir}/tests/*.py"
|
|
||||||
|
|
||||||
[testenv:security]
|
[testenv:security]
|
||||||
description = Security checks
|
description = Security checks
|
||||||
require_locked_deps = true
|
|
||||||
basepython = python3.8
|
basepython = python3.8
|
||||||
ignore_errors = true
|
platform = linux
|
||||||
skip_install = true
|
ingore_errors = true
|
||||||
deps =
|
require_locked_deps = true
|
||||||
|
locked_deps =
|
||||||
bandit
|
bandit
|
||||||
safety
|
safety
|
||||||
poetry
|
poetry
|
||||||
allowlist_externals =
|
|
||||||
bash
|
|
||||||
commands =
|
commands =
|
||||||
bandit --quiet {toxinidir}/tox_poetry_installer.py
|
bandit --recursive --quiet {toxinidir}/tox_poetry_installer/
|
||||||
bash -c "bandit --quiet --skip B101 {toxinidir}/tests/*.py"
|
bandit --recursive --quiet --skip B101 {toxinidir}/tests/
|
||||||
bash -c "poetry export --format requirements.txt --without-hashes --dev | safety check --stdin --bare"
|
poetry export --format requirements.txt --output {envtmpdir}/requirements.txt --without-hashes --dev
|
||||||
|
safety check --bare --file {envtmpdir}/requirements.txt
|
||||||
|
|||||||
@@ -1,377 +0,0 @@
|
|||||||
"""Tox plugin for installing environments using Poetry
|
|
||||||
|
|
||||||
This plugin makes use of the ``tox_testenv_install_deps`` Tox plugin hook to augment the default
|
|
||||||
installation functionality to install dependencies from the Poetry lockfile for the project. It
|
|
||||||
does this by using ``poetry`` to read in the lockfile, identify necessary dependencies, and then
|
|
||||||
use Poetry's ``PipInstaller`` class to install those packages into the Tox environment.
|
|
||||||
|
|
||||||
Quick definition of terminology:
|
|
||||||
|
|
||||||
* "project package" - the package that Tox is testing, usually the one the current project is
|
|
||||||
is developing; definitionally, this is the package that is built by Tox in the ``.package`` env.
|
|
||||||
* "project package dependency" or "project dependency" - a dependency required by the project
|
|
||||||
package for installation; i.e. a package that would be installed when running
|
|
||||||
``pip install <project package>``.
|
|
||||||
* "environment dependency" - a dependency specified for a given testenv in the Tox configuration.
|
|
||||||
* "locked dependency" - a package that is present in the Poetry lockfile and will be installed
|
|
||||||
according to the metadata in the lockfile.
|
|
||||||
* "unlocked dependency" - a package that is either not present in the Poetry lockfile or is not
|
|
||||||
specified to be installed according to the metadata in the lockfile.
|
|
||||||
* "transiety dependency" - a package not explicitly specified for installation, but required by a
|
|
||||||
package that is explicitly specified.
|
|
||||||
"""
|
|
||||||
from pathlib import Path
|
|
||||||
from typing import Dict
|
|
||||||
from typing import List
|
|
||||||
from typing import NamedTuple
|
|
||||||
from typing import Sequence
|
|
||||||
from typing import Set
|
|
||||||
from typing import Tuple
|
|
||||||
|
|
||||||
from poetry.core.packages import Package as PoetryPackage
|
|
||||||
from poetry.factory import Factory as PoetryFactory
|
|
||||||
from poetry.installation.pip_installer import PipInstaller as PoetryPipInstaller
|
|
||||||
from poetry.io.null_io import NullIO as PoetryNullIO
|
|
||||||
from poetry.poetry import Poetry
|
|
||||||
from poetry.puzzle.provider import Provider as PoetryProvider
|
|
||||||
from poetry.utils.env import VirtualEnv as PoetryVirtualEnv
|
|
||||||
from tox import hookimpl
|
|
||||||
from tox import reporter
|
|
||||||
from tox.action import Action as ToxAction
|
|
||||||
from tox.config import DepConfig as ToxDepConfig
|
|
||||||
from tox.config import Parser as ToxParser
|
|
||||||
from tox.venv import VirtualEnv as ToxVirtualEnv
|
|
||||||
|
|
||||||
|
|
||||||
__title__ = "tox-poetry-installer"
|
|
||||||
__summary__ = "Tox plugin to install Tox environment dependencies using the Poetry backend and lockfile"
|
|
||||||
__version__ = "0.3.1"
|
|
||||||
__url__ = "https://github.com/enpaul/tox-poetry-installer/"
|
|
||||||
__license__ = "MIT"
|
|
||||||
__authors__ = ["Ethan Paul <24588726+enpaul@users.noreply.github.com>"]
|
|
||||||
|
|
||||||
|
|
||||||
# Valid PEP508 version delimiters. These are used to test whether a given string (specifically a
|
|
||||||
# dependency name) is just a package name or also includes a version identifier.
|
|
||||||
_PEP508_VERSION_DELIMITERS: Tuple[str, ...] = ("~=", "==", "!=", ">", "<")
|
|
||||||
|
|
||||||
# Prefix all reporter messages should include to indicate that they came from this module in the
|
|
||||||
# console output.
|
|
||||||
_REPORTER_PREFIX = f"[{__title__}]:"
|
|
||||||
|
|
||||||
# Suffix that indicates an env dependency should be treated as a locked dependency and thus be
|
|
||||||
# installed from the lockfile. Will be automatically stripped off of a dependency name during
|
|
||||||
# sorting so that the resulting string is just the valid package name. This becomes optional when
|
|
||||||
# the "require_locked_deps" option is true for an environment; in that case a bare dependency like
|
|
||||||
# 'foo' is treated the same as an explicitly locked dependency like 'foo@poetry'
|
|
||||||
_MAGIC_SUFFIX_MARKER = "@poetry"
|
|
||||||
|
|
||||||
|
|
||||||
# Map of package names to the package object
|
|
||||||
PackageMap = Dict[str, PoetryPackage]
|
|
||||||
|
|
||||||
|
|
||||||
class _SortedEnvDeps(NamedTuple):
|
|
||||||
unlocked_deps: List[ToxDepConfig]
|
|
||||||
locked_deps: List[ToxDepConfig]
|
|
||||||
|
|
||||||
|
|
||||||
class ToxPoetryInstallerException(Exception):
|
|
||||||
"""Error while installing locked dependencies to the test environment"""
|
|
||||||
|
|
||||||
|
|
||||||
class LockedDepVersionConflictError(ToxPoetryInstallerException):
|
|
||||||
"""Locked dependencies cannot specify an alternate version for installation"""
|
|
||||||
|
|
||||||
|
|
||||||
class LockedDepNotFoundError(ToxPoetryInstallerException):
|
|
||||||
"""Locked dependency was not found in the lockfile"""
|
|
||||||
|
|
||||||
|
|
||||||
class ExtraNotFoundError(ToxPoetryInstallerException):
|
|
||||||
"""Project package extra not defined in project's pyproject.toml"""
|
|
||||||
|
|
||||||
|
|
||||||
def _sort_env_deps(venv: ToxVirtualEnv) -> _SortedEnvDeps:
|
|
||||||
"""Sorts the environment dependencies by lock status
|
|
||||||
|
|
||||||
Lock status determines whether a given environment dependency will be installed from the
|
|
||||||
lockfile using the Poetry backend, or whether this plugin will skip it and allow it to be
|
|
||||||
installed using the default pip-based backend (an unlocked dependency).
|
|
||||||
|
|
||||||
.. note:: A locked dependency must follow a required format. To avoid reinventing the wheel
|
|
||||||
(no pun intended) this module does not have any infrastructure for parsing PEP-508
|
|
||||||
version specifiers, and so requires locked dependencies to be specified with no
|
|
||||||
version (the installed version being taken from the lockfile). If a dependency is
|
|
||||||
specified as locked and its name is also a PEP-508 string then an error will be
|
|
||||||
raised.
|
|
||||||
"""
|
|
||||||
|
|
||||||
reporter.verbosity1(
|
|
||||||
f"{_REPORTER_PREFIX} sorting {len(venv.envconfig.deps)} env dependencies by lock requirement"
|
|
||||||
)
|
|
||||||
unlocked_deps = []
|
|
||||||
locked_deps = []
|
|
||||||
|
|
||||||
for dep in venv.envconfig.deps:
|
|
||||||
if venv.envconfig.require_locked_deps:
|
|
||||||
reporter.verbosity1(
|
|
||||||
f"{_REPORTER_PREFIX} lock required for env, treating '{dep.name}' as locked env dependency"
|
|
||||||
)
|
|
||||||
dep.name = dep.name.replace(_MAGIC_SUFFIX_MARKER, "")
|
|
||||||
locked_deps.append(dep)
|
|
||||||
else:
|
|
||||||
if dep.name.endswith(_MAGIC_SUFFIX_MARKER):
|
|
||||||
reporter.verbosity1(
|
|
||||||
f"{_REPORTER_PREFIX} specification includes marker '{_MAGIC_SUFFIX_MARKER}', treating '{dep.name}' as locked env dependency"
|
|
||||||
)
|
|
||||||
dep.name = dep.name.replace(_MAGIC_SUFFIX_MARKER, "")
|
|
||||||
locked_deps.append(dep)
|
|
||||||
else:
|
|
||||||
reporter.verbosity1(
|
|
||||||
f"{_REPORTER_PREFIX} specification does not include marker '{_MAGIC_SUFFIX_MARKER}', treating '{dep.name}' as unlocked env dependency"
|
|
||||||
)
|
|
||||||
unlocked_deps.append(dep)
|
|
||||||
|
|
||||||
reporter.verbosity1(
|
|
||||||
f"{_REPORTER_PREFIX} identified {len(locked_deps)} locked env dependencies: {[item.name for item in locked_deps]}"
|
|
||||||
)
|
|
||||||
reporter.verbosity1(
|
|
||||||
f"{_REPORTER_PREFIX} identified {len(unlocked_deps)} unlocked env dependencies: {[item.name for item in unlocked_deps]}"
|
|
||||||
)
|
|
||||||
|
|
||||||
return _SortedEnvDeps(locked_deps=locked_deps, unlocked_deps=unlocked_deps)
|
|
||||||
|
|
||||||
|
|
||||||
def _install_to_venv(
|
|
||||||
poetry: Poetry, venv: ToxVirtualEnv, packages: Sequence[PoetryPackage]
|
|
||||||
):
|
|
||||||
"""Install a bunch of packages to a virtualenv
|
|
||||||
|
|
||||||
:param poetry: Poetry object the packages were sourced from
|
|
||||||
:param venv: Tox virtual environment to install the packages to
|
|
||||||
:param packages: List of packages to install to the virtual environment
|
|
||||||
"""
|
|
||||||
|
|
||||||
reporter.verbosity1(
|
|
||||||
f"{_REPORTER_PREFIX} Installing {len(packages)} packages to environment at {venv.envconfig.envdir}"
|
|
||||||
)
|
|
||||||
|
|
||||||
installer = PoetryPipInstaller(
|
|
||||||
env=PoetryVirtualEnv(path=Path(venv.envconfig.envdir)),
|
|
||||||
io=PoetryNullIO(),
|
|
||||||
pool=poetry.pool,
|
|
||||||
)
|
|
||||||
|
|
||||||
for dependency in packages:
|
|
||||||
reporter.verbosity1(f"{_REPORTER_PREFIX} installing {dependency}")
|
|
||||||
installer.install(dependency)
|
|
||||||
|
|
||||||
|
|
||||||
def _find_transients(packages: PackageMap, dependency_name: str) -> Set[PoetryPackage]:
|
|
||||||
"""Using a poetry object identify all dependencies of a specific dependency
|
|
||||||
|
|
||||||
:param poetry: Populated poetry object which can be used to build a populated locked
|
|
||||||
repository object.
|
|
||||||
:param dependency_name: Bare name (without version) of the dependency to fetch the transient
|
|
||||||
dependencies of.
|
|
||||||
:returns: List of packages that need to be installed for the requested dependency.
|
|
||||||
|
|
||||||
.. note:: The package corresponding to the dependency named by ``dependency_name`` is included
|
|
||||||
in the list of returned packages.
|
|
||||||
"""
|
|
||||||
|
|
||||||
try:
|
|
||||||
top_level = packages[dependency_name]
|
|
||||||
|
|
||||||
def find_deps_of_deps(name: str) -> List[PoetryPackage]:
|
|
||||||
if name in PoetryProvider.UNSAFE_PACKAGES:
|
|
||||||
reporter.warning(
|
|
||||||
f"{_REPORTER_PREFIX} installing package '{name}' using Poetry is not supported; skipping installation of package '{name}'"
|
|
||||||
)
|
|
||||||
return []
|
|
||||||
transients = [packages[name]]
|
|
||||||
for dep in packages[name].requires:
|
|
||||||
transients += find_deps_of_deps(dep.name)
|
|
||||||
return transients
|
|
||||||
|
|
||||||
return set(find_deps_of_deps(top_level.name))
|
|
||||||
|
|
||||||
except KeyError:
|
|
||||||
if any(
|
|
||||||
delimiter in dependency_name for delimiter in _PEP508_VERSION_DELIMITERS
|
|
||||||
):
|
|
||||||
raise LockedDepVersionConflictError(
|
|
||||||
f"Locked dependency '{dependency_name}' cannot include version specifier"
|
|
||||||
) from None
|
|
||||||
raise LockedDepNotFoundError(
|
|
||||||
f"No version of locked dependency '{dependency_name}' found in the project lockfile"
|
|
||||||
) from None
|
|
||||||
|
|
||||||
|
|
||||||
def _install_env_dependencies(
|
|
||||||
venv: ToxVirtualEnv, poetry: Poetry, packages: PackageMap
|
|
||||||
):
|
|
||||||
"""Install the packages for a specified testenv
|
|
||||||
|
|
||||||
Processes the tox environment config, identifies any locked environment dependencies, pulls
|
|
||||||
them from the lockfile, and installs them to the virtual environment.
|
|
||||||
|
|
||||||
:param venv: Tox virtual environment to install the packages to
|
|
||||||
:param poetry: Poetry object the packages were sourced from
|
|
||||||
:param packages: Mapping of package names to the corresponding package object
|
|
||||||
"""
|
|
||||||
env_deps = _sort_env_deps(venv)
|
|
||||||
|
|
||||||
dependencies: List[PoetryPackage] = []
|
|
||||||
for dep in env_deps.locked_deps:
|
|
||||||
try:
|
|
||||||
dependencies += _find_transients(packages, dep.name.lower())
|
|
||||||
except ToxPoetryInstallerException as err:
|
|
||||||
venv.status = "lockfile installation failed"
|
|
||||||
reporter.error(f"{_REPORTER_PREFIX} {err}")
|
|
||||||
raise err
|
|
||||||
|
|
||||||
reporter.verbosity1(
|
|
||||||
f"{_REPORTER_PREFIX} identified {len(dependencies)} total dependencies from {len(env_deps.locked_deps)} locked env dependencies"
|
|
||||||
)
|
|
||||||
|
|
||||||
reporter.verbosity1(
|
|
||||||
f"{_REPORTER_PREFIX} updating env config with {len(env_deps.unlocked_deps)} unlocked env dependencies for installation using the default backend"
|
|
||||||
)
|
|
||||||
venv.envconfig.deps = env_deps.unlocked_deps
|
|
||||||
|
|
||||||
reporter.verbosity0(
|
|
||||||
f"{_REPORTER_PREFIX} ({venv.name}) installing {len(dependencies)} env dependencies from lockfile"
|
|
||||||
)
|
|
||||||
_install_to_venv(poetry, venv, dependencies)
|
|
||||||
|
|
||||||
|
|
||||||
def _install_project_dependencies(
|
|
||||||
venv: ToxVirtualEnv, poetry: Poetry, packages: PackageMap
|
|
||||||
):
|
|
||||||
"""Install the dependencies of the project package
|
|
||||||
|
|
||||||
Install all primary dependencies of the project package.
|
|
||||||
|
|
||||||
:param venv: Tox virtual environment to install the packages to
|
|
||||||
:param poetry: Poetry object the packages were sourced from
|
|
||||||
:param packages: Mapping of package names to the corresponding package object
|
|
||||||
"""
|
|
||||||
reporter.verbosity1(
|
|
||||||
f"{_REPORTER_PREFIX} performing installation of project dependencies"
|
|
||||||
)
|
|
||||||
|
|
||||||
base_dependencies: List[PoetryPackage] = [
|
|
||||||
packages[item.name]
|
|
||||||
for item in poetry.package.requires
|
|
||||||
if not item.is_optional()
|
|
||||||
]
|
|
||||||
|
|
||||||
extra_dependencies: List[PoetryPackage] = []
|
|
||||||
for extra in venv.envconfig.extras:
|
|
||||||
try:
|
|
||||||
extra_dependencies += [
|
|
||||||
packages[item.name] for item in poetry.package.extras[extra]
|
|
||||||
]
|
|
||||||
except KeyError:
|
|
||||||
raise ExtraNotFoundError(
|
|
||||||
f"Environment '{venv.name}' specifies project extra '{extra}' which was not found in the lockfile"
|
|
||||||
) from None
|
|
||||||
|
|
||||||
dependencies: List[PoetryPackage] = []
|
|
||||||
for dep in base_dependencies + extra_dependencies:
|
|
||||||
try:
|
|
||||||
dependencies += _find_transients(packages, dep.name.lower())
|
|
||||||
except ToxPoetryInstallerException as err:
|
|
||||||
venv.status = "lockfile installation failed"
|
|
||||||
reporter.error(f"{_REPORTER_PREFIX} {err}")
|
|
||||||
raise err
|
|
||||||
|
|
||||||
reporter.verbosity1(
|
|
||||||
f"{_REPORTER_PREFIX} identified {len(dependencies)} total dependencies from {len(poetry.package.requires)} project dependencies"
|
|
||||||
)
|
|
||||||
|
|
||||||
reporter.verbosity0(
|
|
||||||
f"{_REPORTER_PREFIX} ({venv.name}) installing {len(dependencies)} project dependencies from lockfile"
|
|
||||||
)
|
|
||||||
_install_to_venv(poetry, venv, dependencies)
|
|
||||||
|
|
||||||
|
|
||||||
@hookimpl
|
|
||||||
def tox_addoption(parser: ToxParser):
|
|
||||||
"""Add required configuration options to the tox INI file
|
|
||||||
|
|
||||||
Adds the ``require_locked_deps`` configuration option to the venv to check whether all
|
|
||||||
dependencies should be treated as locked or not.
|
|
||||||
"""
|
|
||||||
|
|
||||||
parser.add_testenv_attribute(
|
|
||||||
name="require_locked_deps",
|
|
||||||
type="bool",
|
|
||||||
default=False,
|
|
||||||
help="Require all dependencies in the environment be installed using the Poetry lockfile",
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@hookimpl
|
|
||||||
def tox_testenv_install_deps(venv: ToxVirtualEnv, action: ToxAction):
|
|
||||||
"""Install the dependencies for the current environment
|
|
||||||
|
|
||||||
Loads the local Poetry environment and the corresponding lockfile then pulls the dependencies
|
|
||||||
specified by the Tox environment. Finally these dependencies are installed into the Tox
|
|
||||||
environment using the Poetry ``PipInstaller`` backend.
|
|
||||||
|
|
||||||
:param venv: Tox virtual environment object with configuration for the local Tox environment.
|
|
||||||
:param action: Tox action object
|
|
||||||
"""
|
|
||||||
|
|
||||||
if action.name == venv.envconfig.config.isolated_build_env:
|
|
||||||
# Skip running the plugin for the packaging environment. PEP-517 front ends can handle
|
|
||||||
# that better than we can, so let them do their thing. More to the point: if you're having
|
|
||||||
# problems in the packaging env that this plugin would solve, god help you.
|
|
||||||
reporter.verbosity1(
|
|
||||||
f"{_REPORTER_PREFIX} skipping isolated build env '{action.name}'"
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
try:
|
|
||||||
poetry = PoetryFactory().create_poetry(venv.envconfig.config.toxinidir)
|
|
||||||
except RuntimeError:
|
|
||||||
# Support running the plugin when the current tox project does not use Poetry for its
|
|
||||||
# environment/dependency management.
|
|
||||||
#
|
|
||||||
# ``RuntimeError`` is dangerous to blindly catch because it can be (and in Poetry's case,
|
|
||||||
# is) raised in many different places for different purposes.
|
|
||||||
reporter.verbosity1(
|
|
||||||
f"{_REPORTER_PREFIX} project does not use Poetry for env management, skipping installation of locked dependencies"
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
reporter.verbosity1(
|
|
||||||
f"{_REPORTER_PREFIX} loaded project pyproject.toml from {poetry.file}"
|
|
||||||
)
|
|
||||||
|
|
||||||
package_map: PackageMap = {
|
|
||||||
package.name: package
|
|
||||||
for package in poetry.locker.locked_repository(True).packages
|
|
||||||
}
|
|
||||||
|
|
||||||
# Handle the installation of any locked env dependencies from the lockfile
|
|
||||||
_install_env_dependencies(venv, poetry, package_map)
|
|
||||||
|
|
||||||
# Handle the installation of the package dependencies from the lockfile if the package is
|
|
||||||
# being installed to this venv; otherwise skip installing the package dependencies
|
|
||||||
if venv.envconfig.skip_install:
|
|
||||||
reporter.verbosity1(
|
|
||||||
f"{_REPORTER_PREFIX} env specifies 'skip_install = true', skipping installation of project package"
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
if venv.envconfig.config.skipsdist:
|
|
||||||
reporter.verbosity1(
|
|
||||||
f"{_REPORTER_PREFIX} config specifies 'skipsdist = true', skipping installation of project package"
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
_install_project_dependencies(venv, poetry, package_map)
|
|
||||||
7
tox_poetry_installer/__about__.py
Normal file
7
tox_poetry_installer/__about__.py
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# pylint: disable=missing-docstring
|
||||||
|
__title__ = "tox-poetry-installer"
|
||||||
|
__summary__ = "Tox plugin to install Tox environment dependencies using the Poetry backend and lockfile"
|
||||||
|
__version__ = "0.5.2"
|
||||||
|
__url__ = "https://github.com/enpaul/tox-poetry-installer/"
|
||||||
|
__license__ = "MIT"
|
||||||
|
__authors__ = ["Ethan Paul <24588726+enpaul@users.noreply.github.com>"]
|
||||||
3
tox_poetry_installer/__init__.py
Normal file
3
tox_poetry_installer/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# pylint: disable=missing-docstring
|
||||||
|
from tox_poetry_installer.hooks import tox_addoption
|
||||||
|
from tox_poetry_installer.hooks import tox_testenv_install_deps
|
||||||
19
tox_poetry_installer/constants.py
Normal file
19
tox_poetry_installer/constants.py
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
"""Static constants for reference
|
||||||
|
|
||||||
|
Rule of thumb: if it's an arbitrary value that will never be changed at runtime, it should go
|
||||||
|
in this module.
|
||||||
|
|
||||||
|
All constants should be type hinted.
|
||||||
|
"""
|
||||||
|
from typing import Tuple
|
||||||
|
|
||||||
|
from tox_poetry_installer import __about__
|
||||||
|
|
||||||
|
|
||||||
|
# Valid PEP508 version delimiters. These are used to test whether a given string (specifically a
|
||||||
|
# dependency name) is just a package name or also includes a version identifier.
|
||||||
|
PEP508_VERSION_DELIMITERS: Tuple[str, ...] = ("~=", "==", "!=", ">", "<")
|
||||||
|
|
||||||
|
# Prefix all reporter messages should include to indicate that they came from this module in the
|
||||||
|
# console output.
|
||||||
|
REPORTER_PREFIX = f"[{__about__.__title__}]:"
|
||||||
8
tox_poetry_installer/datatypes.py
Normal file
8
tox_poetry_installer/datatypes.py
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
"""Definitions for typehints/containers used by the plugin"""
|
||||||
|
from typing import Dict
|
||||||
|
|
||||||
|
from poetry.core.packages import Package as PoetryPackage
|
||||||
|
|
||||||
|
|
||||||
|
# Map of package names to the package object
|
||||||
|
PackageMap = Dict[str, PoetryPackage]
|
||||||
38
tox_poetry_installer/exceptions.py
Normal file
38
tox_poetry_installer/exceptions.py
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
"""Custom plugin exceptions
|
||||||
|
|
||||||
|
All exceptions should inherit from the common base exception :exc:`ToxPoetryInstallerException`.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
ToxPoetryInstallerException
|
||||||
|
+-- SkipEnvironment
|
||||||
|
+-- LockedDepVersionConflictError
|
||||||
|
+-- LockedDepNotFoundError
|
||||||
|
+-- ExtraNotFoundError
|
||||||
|
+-- LockedDepsRequiredError
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class ToxPoetryInstallerException(Exception):
|
||||||
|
"""Error while installing locked dependencies to the test environment"""
|
||||||
|
|
||||||
|
|
||||||
|
class SkipEnvironment(ToxPoetryInstallerException):
|
||||||
|
"""Current environment does not meet preconditions and should be skipped by the plugin"""
|
||||||
|
|
||||||
|
|
||||||
|
class LockedDepVersionConflictError(ToxPoetryInstallerException):
|
||||||
|
"""Locked dependencies cannot specify an alternate version for installation"""
|
||||||
|
|
||||||
|
|
||||||
|
class LockedDepNotFoundError(ToxPoetryInstallerException):
|
||||||
|
"""Locked dependency was not found in the lockfile"""
|
||||||
|
|
||||||
|
|
||||||
|
class ExtraNotFoundError(ToxPoetryInstallerException):
|
||||||
|
"""Project package extra not defined in project's pyproject.toml"""
|
||||||
|
|
||||||
|
|
||||||
|
class LockedDepsRequiredError(ToxPoetryInstallerException):
|
||||||
|
"""Environment cannot specify unlocked dependencies when locked dependencies are required"""
|
||||||
165
tox_poetry_installer/hooks.py
Normal file
165
tox_poetry_installer/hooks.py
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
"""Main hook definition module
|
||||||
|
|
||||||
|
All implementations of tox hooks are defined here, as well as any single-use helper functions
|
||||||
|
specifically related to implementing the hooks (to keep the size/readability of the hook functions
|
||||||
|
themselves manageable).
|
||||||
|
"""
|
||||||
|
from typing import List
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from poetry.core.packages import Package as PoetryPackage
|
||||||
|
from poetry.poetry import Poetry
|
||||||
|
from tox import hookimpl
|
||||||
|
from tox import reporter
|
||||||
|
from tox.action import Action as ToxAction
|
||||||
|
from tox.config import Parser as ToxParser
|
||||||
|
from tox.venv import VirtualEnv as ToxVirtualEnv
|
||||||
|
|
||||||
|
from tox_poetry_installer import constants
|
||||||
|
from tox_poetry_installer import exceptions
|
||||||
|
from tox_poetry_installer import utilities
|
||||||
|
from tox_poetry_installer.datatypes import PackageMap
|
||||||
|
|
||||||
|
|
||||||
|
@hookimpl
|
||||||
|
def tox_addoption(parser: ToxParser):
|
||||||
|
"""Add required configuration options to the tox INI file
|
||||||
|
|
||||||
|
Adds the ``require_locked_deps`` configuration option to the venv to check whether all
|
||||||
|
dependencies should be treated as locked or not.
|
||||||
|
"""
|
||||||
|
|
||||||
|
parser.add_testenv_attribute(
|
||||||
|
name="install_dev_deps",
|
||||||
|
type="bool",
|
||||||
|
default=False,
|
||||||
|
help="Automatically install all Poetry development dependencies to the environment",
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_testenv_attribute(
|
||||||
|
name="require_locked_deps",
|
||||||
|
type="bool",
|
||||||
|
default=False,
|
||||||
|
help="Require all dependencies in the environment be installed using the Poetry lockfile",
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_testenv_attribute(
|
||||||
|
name="locked_deps",
|
||||||
|
type="line-list",
|
||||||
|
help="List of locked dependencies to install to the environment using the Poetry lockfile",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@hookimpl
|
||||||
|
def tox_testenv_install_deps(venv: ToxVirtualEnv, action: ToxAction) -> Optional[bool]:
|
||||||
|
"""Install the dependencies for the current environment
|
||||||
|
|
||||||
|
Loads the local Poetry environment and the corresponding lockfile then pulls the dependencies
|
||||||
|
specified by the Tox environment. Finally these dependencies are installed into the Tox
|
||||||
|
environment using the Poetry ``PipInstaller`` backend.
|
||||||
|
|
||||||
|
:param venv: Tox virtual environment object with configuration for the local Tox environment.
|
||||||
|
:param action: Tox action object
|
||||||
|
"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
poetry = utilities.check_preconditions(venv, action)
|
||||||
|
except exceptions.SkipEnvironment as err:
|
||||||
|
reporter.verbosity1(str(err))
|
||||||
|
return None
|
||||||
|
|
||||||
|
reporter.verbosity1(
|
||||||
|
f"{constants.REPORTER_PREFIX} Loaded project pyproject.toml from {poetry.file}"
|
||||||
|
)
|
||||||
|
|
||||||
|
if venv.envconfig.require_locked_deps and venv.envconfig.deps:
|
||||||
|
raise exceptions.LockedDepsRequiredError(
|
||||||
|
f"Unlocked dependencies '{venv.envconfig.deps}' specified for environment '{venv.name}' which requires locked dependencies"
|
||||||
|
)
|
||||||
|
|
||||||
|
package_map: PackageMap = {
|
||||||
|
package.name: package
|
||||||
|
for package in poetry.locker.locked_repository(True).packages
|
||||||
|
}
|
||||||
|
|
||||||
|
if venv.envconfig.install_dev_deps:
|
||||||
|
dev_deps: List[PoetryPackage] = [
|
||||||
|
dep
|
||||||
|
for dep in package_map.values()
|
||||||
|
if dep not in poetry.locker.locked_repository(False).packages
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
dev_deps = []
|
||||||
|
|
||||||
|
reporter.verbosity1(
|
||||||
|
f"{constants.REPORTER_PREFIX} Identified {len(dev_deps)} development dependencies to install to env"
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
env_deps: List[PoetryPackage] = []
|
||||||
|
for dep in venv.envconfig.locked_deps:
|
||||||
|
env_deps += utilities.find_transients(package_map, dep.lower())
|
||||||
|
reporter.verbosity1(
|
||||||
|
f"{constants.REPORTER_PREFIX} Identified {len(env_deps)} environment dependencies to install to env"
|
||||||
|
)
|
||||||
|
|
||||||
|
if not venv.envconfig.skip_install and not venv.envconfig.config.skipsdist:
|
||||||
|
project_deps: List[PoetryPackage] = _find_project_dependencies(
|
||||||
|
venv, poetry, package_map
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
project_deps = []
|
||||||
|
reporter.verbosity1(
|
||||||
|
f"{constants.REPORTER_PREFIX} Skipping installation of project dependencies, env does not install project package"
|
||||||
|
)
|
||||||
|
reporter.verbosity1(
|
||||||
|
f"{constants.REPORTER_PREFIX} Identified {len(project_deps)} project dependencies to install to env"
|
||||||
|
)
|
||||||
|
except exceptions.ToxPoetryInstallerException as err:
|
||||||
|
venv.status = "lockfile installation failed"
|
||||||
|
reporter.error(f"{constants.REPORTER_PREFIX} {err}")
|
||||||
|
raise err
|
||||||
|
|
||||||
|
dependencies = list(set(dev_deps + env_deps + project_deps))
|
||||||
|
reporter.verbosity0(
|
||||||
|
f"{constants.REPORTER_PREFIX} Installing {len(dependencies)} dependencies to env '{action.name}'"
|
||||||
|
)
|
||||||
|
utilities.install_to_venv(poetry, venv, dependencies)
|
||||||
|
|
||||||
|
return venv.envconfig.require_locked_deps or None
|
||||||
|
|
||||||
|
|
||||||
|
def _find_project_dependencies(
|
||||||
|
venv: ToxVirtualEnv, poetry: Poetry, packages: PackageMap
|
||||||
|
) -> List[PoetryPackage]:
|
||||||
|
"""Install the dependencies of the project package
|
||||||
|
|
||||||
|
Install all primary dependencies of the project package.
|
||||||
|
|
||||||
|
:param venv: Tox virtual environment to install the packages to
|
||||||
|
:param poetry: Poetry object the packages were sourced from
|
||||||
|
:param packages: Mapping of package names to the corresponding package object
|
||||||
|
"""
|
||||||
|
|
||||||
|
base_dependencies: List[PoetryPackage] = [
|
||||||
|
packages[item.name]
|
||||||
|
for item in poetry.package.requires
|
||||||
|
if not item.is_optional()
|
||||||
|
]
|
||||||
|
|
||||||
|
extra_dependencies: List[PoetryPackage] = []
|
||||||
|
for extra in venv.envconfig.extras:
|
||||||
|
try:
|
||||||
|
extra_dependencies += [
|
||||||
|
packages[item.name] for item in poetry.package.extras[extra]
|
||||||
|
]
|
||||||
|
except KeyError:
|
||||||
|
raise exceptions.ExtraNotFoundError(
|
||||||
|
f"Environment '{venv.name}' specifies project extra '{extra}' which was not found in the lockfile"
|
||||||
|
) from None
|
||||||
|
|
||||||
|
dependencies: List[PoetryPackage] = []
|
||||||
|
for dep in base_dependencies + extra_dependencies:
|
||||||
|
dependencies += utilities.find_transients(packages, dep.name.lower())
|
||||||
|
|
||||||
|
return dependencies
|
||||||
0
tox_poetry_installer/py.typed
Normal file
0
tox_poetry_installer/py.typed
Normal file
137
tox_poetry_installer/utilities.py
Normal file
137
tox_poetry_installer/utilities.py
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
"""Helper utility functions, usually bridging Tox and Poetry functionality"""
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Sequence
|
||||||
|
from typing import Set
|
||||||
|
|
||||||
|
from poetry.core.packages import Package as PoetryPackage
|
||||||
|
from poetry.core.semver.version import Version
|
||||||
|
from poetry.factory import Factory as PoetryFactory
|
||||||
|
from poetry.installation.pip_installer import PipInstaller as PoetryPipInstaller
|
||||||
|
from poetry.io.null_io import NullIO as PoetryNullIO
|
||||||
|
from poetry.poetry import Poetry
|
||||||
|
from poetry.puzzle.provider import Provider as PoetryProvider
|
||||||
|
from poetry.utils.env import VirtualEnv as PoetryVirtualEnv
|
||||||
|
from tox import reporter
|
||||||
|
from tox.action import Action as ToxAction
|
||||||
|
from tox.venv import VirtualEnv as ToxVirtualEnv
|
||||||
|
|
||||||
|
from tox_poetry_installer import constants
|
||||||
|
from tox_poetry_installer import exceptions
|
||||||
|
from tox_poetry_installer.datatypes import PackageMap
|
||||||
|
|
||||||
|
|
||||||
|
def install_to_venv(
|
||||||
|
poetry: Poetry, venv: ToxVirtualEnv, packages: Sequence[PoetryPackage]
|
||||||
|
):
|
||||||
|
"""Install a bunch of packages to a virtualenv
|
||||||
|
|
||||||
|
:param poetry: Poetry object the packages were sourced from
|
||||||
|
:param venv: Tox virtual environment to install the packages to
|
||||||
|
:param packages: List of packages to install to the virtual environment
|
||||||
|
"""
|
||||||
|
|
||||||
|
reporter.verbosity1(
|
||||||
|
f"{constants.REPORTER_PREFIX} Installing {len(packages)} packages to environment at {venv.envconfig.envdir}"
|
||||||
|
)
|
||||||
|
|
||||||
|
installer = PoetryPipInstaller(
|
||||||
|
env=PoetryVirtualEnv(path=Path(venv.envconfig.envdir)),
|
||||||
|
io=PoetryNullIO(),
|
||||||
|
pool=poetry.pool,
|
||||||
|
)
|
||||||
|
|
||||||
|
for dependency in packages:
|
||||||
|
reporter.verbosity1(f"{constants.REPORTER_PREFIX} Installing {dependency}")
|
||||||
|
installer.install(dependency)
|
||||||
|
|
||||||
|
|
||||||
|
def find_transients(packages: PackageMap, dependency_name: str) -> Set[PoetryPackage]:
|
||||||
|
"""Using a poetry object identify all dependencies of a specific dependency
|
||||||
|
|
||||||
|
:param poetry: Populated poetry object which can be used to build a populated locked
|
||||||
|
repository object.
|
||||||
|
:param dependency_name: Bare name (without version) of the dependency to fetch the transient
|
||||||
|
dependencies of.
|
||||||
|
:returns: List of packages that need to be installed for the requested dependency.
|
||||||
|
|
||||||
|
.. note:: The package corresponding to the dependency named by ``dependency_name`` is included
|
||||||
|
in the list of returned packages.
|
||||||
|
"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
|
||||||
|
def find_deps_of_deps(name: str, searched: Set[str]) -> PackageMap:
|
||||||
|
package = packages[name]
|
||||||
|
local_version = Version(
|
||||||
|
major=sys.version_info.major,
|
||||||
|
minor=sys.version_info.minor,
|
||||||
|
patch=sys.version_info.micro,
|
||||||
|
)
|
||||||
|
transients: PackageMap = {}
|
||||||
|
searched.update([name])
|
||||||
|
|
||||||
|
if name in PoetryProvider.UNSAFE_PACKAGES:
|
||||||
|
reporter.warning(
|
||||||
|
f"{constants.REPORTER_PREFIX} Installing package '{name}' using Poetry is not supported; skipping installation of package '{name}'"
|
||||||
|
)
|
||||||
|
reporter.verbosity2(
|
||||||
|
f"{constants.REPORTER_PREFIX} Skip {package}: designated unsafe by Poetry"
|
||||||
|
)
|
||||||
|
elif not package.python_constraint.allows(local_version):
|
||||||
|
reporter.verbosity2(
|
||||||
|
f"{constants.REPORTER_PREFIX} Skip {package}: incompatible Python requirement '{package.python_constraint}' for current version '{local_version}'"
|
||||||
|
)
|
||||||
|
elif package.platform is not None and package.platform != sys.platform:
|
||||||
|
reporter.verbosity2(
|
||||||
|
f"{constants.REPORTER_PREFIX} Skip {package}: incompatible platform requirement '{package.platform}' for current platform '{sys.platform}'"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
reporter.verbosity2(f"{constants.REPORTER_PREFIX} Include {package}")
|
||||||
|
transients[name] = package
|
||||||
|
for dep in package.requires:
|
||||||
|
if dep.name not in searched:
|
||||||
|
transients.update(find_deps_of_deps(dep.name, searched))
|
||||||
|
|
||||||
|
return transients
|
||||||
|
|
||||||
|
searched: Set[str] = set()
|
||||||
|
transients: PackageMap = find_deps_of_deps(
|
||||||
|
packages[dependency_name].name, searched
|
||||||
|
)
|
||||||
|
|
||||||
|
return set(transients.values())
|
||||||
|
except KeyError:
|
||||||
|
if any(
|
||||||
|
delimiter in dependency_name
|
||||||
|
for delimiter in constants.PEP508_VERSION_DELIMITERS
|
||||||
|
):
|
||||||
|
raise exceptions.LockedDepVersionConflictError(
|
||||||
|
f"Locked dependency '{dependency_name}' cannot include version specifier"
|
||||||
|
) from None
|
||||||
|
raise exceptions.LockedDepNotFoundError(
|
||||||
|
f"No version of locked dependency '{dependency_name}' found in the project lockfile"
|
||||||
|
) from None
|
||||||
|
|
||||||
|
|
||||||
|
def check_preconditions(venv: ToxVirtualEnv, action: ToxAction) -> Poetry:
|
||||||
|
"""Check that the local project environment meets expectations"""
|
||||||
|
# Skip running the plugin for the packaging environment. PEP-517 front ends can handle
|
||||||
|
# that better than we can, so let them do their thing. More to the point: if you're having
|
||||||
|
# problems in the packaging env that this plugin would solve, god help you.
|
||||||
|
if action.name == venv.envconfig.config.isolated_build_env:
|
||||||
|
raise exceptions.SkipEnvironment(
|
||||||
|
f"Skipping isolated packaging build env '{action.name}'"
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
return PoetryFactory().create_poetry(venv.envconfig.config.toxinidir)
|
||||||
|
# Support running the plugin when the current tox project does not use Poetry for its
|
||||||
|
# environment/dependency management.
|
||||||
|
#
|
||||||
|
# ``RuntimeError`` is dangerous to blindly catch because it can be (and in Poetry's case,
|
||||||
|
# is) raised in many different places for different purposes.
|
||||||
|
except RuntimeError:
|
||||||
|
raise exceptions.SkipEnvironment(
|
||||||
|
"Project does not use Poetry for env management, skipping installation of locked dependencies"
|
||||||
|
) from None
|
||||||
Reference in New Issue
Block a user