From 2308dca183b8f7463464f983364d348ad2b4049a Mon Sep 17 00:00:00 2001 From: Claudio Jolowicz Date: Sat, 1 Aug 2020 18:00:50 +0200 Subject: [PATCH 01/17] Update template to 2020.7.15 --- .cookiecutter.json | 2 +- .dependabot/config.yml | 26 - .github/dependabot.yml | 18 + .github/workflows/constraints.txt | 7 +- .github/workflows/coverage.yml | 16 - .github/workflows/docs.yml | 18 - .github/workflows/release-drafter.yml | 12 - .github/workflows/release.yml | 88 +++- .github/workflows/test-pypi.yml | 26 - .github/workflows/tests.yml | 94 +++- .pre-commit-config.yaml | 64 ++- README.rst | 34 +- docs/reference.rst | 1 - docs/requirements.txt | 2 +- mypy.ini | 6 - noxfile.py | 100 +++- poetry.lock | 721 +++++++++++++++++++++----- pyproject.toml | 30 +- 18 files changed, 912 insertions(+), 353 deletions(-) delete mode 100644 .dependabot/config.yml create mode 100644 .github/dependabot.yml delete mode 100644 .github/workflows/coverage.yml delete mode 100644 .github/workflows/docs.yml delete mode 100644 .github/workflows/release-drafter.yml delete mode 100644 .github/workflows/test-pypi.yml diff --git a/.cookiecutter.json b/.cookiecutter.json index da8b3c17..ddac2641 100644 --- a/.cookiecutter.json +++ b/.cookiecutter.json @@ -1,5 +1,5 @@ { - "_template": "gh:cjolowicz/cookiecutter-hypermodern-python", + "_template": "https://github.com/cjolowicz/cookiecutter-hypermodern-python.git", "author": "Claudio Jolowicz", "email": "mail@claudiojolowicz.com", "friendly_name": "nox-poetry", diff --git a/.dependabot/config.yml b/.dependabot/config.yml deleted file mode 100644 index 837e3e88..00000000 --- a/.dependabot/config.yml +++ /dev/null @@ -1,26 +0,0 @@ -version: 1 -update_configs: - - package_manager: "python" - directory: "/" - update_schedule: "daily" - allowed_updates: - - match: - update_type: "all" - - package_manager: "python" - directory: "/docs" - update_schedule: "daily" - allowed_updates: - - match: - update_type: "all" - - package_manager: "python" - directory: "/.github/workflows" - update_schedule: "daily" - allowed_updates: - - match: - update_type: "all" - - package_manager: "github_actions" - directory: "/" - update_schedule: "daily" - allowed_updates: - - match: - update_type: "all" diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..a0a5c735 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,18 @@ +version: 2 +updates: + - package-ecosystem: github-actions + directory: "/" + schedule: + interval: daily + - package-ecosystem: pip + directory: "/.github/workflows" + schedule: + interval: daily + - package-ecosystem: pip + directory: "/docs" + schedule: + interval: daily + - package-ecosystem: pip + directory: "/" + schedule: + interval: daily diff --git a/.github/workflows/constraints.txt b/.github/workflows/constraints.txt index 179fdc79..80c9f8dc 100644 --- a/.github/workflows/constraints.txt +++ b/.github/workflows/constraints.txt @@ -1,3 +1,4 @@ -pip==20.1 -nox==2019.11.9 -poetry==1.0.5 +pip==20.1.1 +nox==2020.5.24 +poetry==1.0.9 +virtualenv==20.0.26 diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml deleted file mode 100644 index f2a12f67..00000000 --- a/.github/workflows/coverage.yml +++ /dev/null @@ -1,16 +0,0 @@ -name: Coverage -on: [push, pull_request] -jobs: - coverage: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2.1.0 - - uses: actions/setup-python@v2 - with: - python-version: "3.8" - - run: | - pip install --constraint=.github/workflows/constraints.txt pip - pip install --constraint=.github/workflows/constraints.txt nox poetry - - run: nox --force-color --session=tests-3.8 -- --cov --cov-report=xml - - if: always() - uses: codecov/codecov-action@v1.0.7 diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml deleted file mode 100644 index 20b97938..00000000 --- a/.github/workflows/docs.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: Build documentation -on: [push, pull_request] -jobs: - docs: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2.1.0 - - uses: actions/setup-python@v2 - with: - python-version: "3.8" - - run: | - pip install --constraint=.github/workflows/constraints.txt pip - pip install --constraint=.github/workflows/constraints.txt nox poetry - - run: nox --force-color --session=docs - - uses: actions/upload-artifact@v2 - with: - name: docs - path: docs/_build diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml deleted file mode 100644 index 668a88bd..00000000 --- a/.github/workflows/release-drafter.yml +++ /dev/null @@ -1,12 +0,0 @@ -name: Release Drafter -on: - push: - branches: - - master -jobs: - draft_release: - runs-on: ubuntu-latest - steps: - - uses: release-drafter/release-drafter@v5.8.0 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7059e656..182ef749 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,42 +1,78 @@ name: Release + on: - release: - types: [published] + push: + branches: + - master + jobs: release: + name: Release runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2.1.0 - - uses: actions/setup-python@v2 + - name: Check out the repository + uses: actions/checkout@v2.3.1 + with: + fetch-depth: 2 + + - name: Set up Python + uses: actions/setup-python@v2 with: python-version: "3.8" - - run: | + + - name: Upgrade pip + run: | pip install --constraint=.github/workflows/constraints.txt pip - pip install --constraint=.github/workflows/constraints.txt nox poetry - - name: Compute cache key prefix - if: matrix.os != 'windows-latest' - id: cache_key_prefix - shell: python + pip --version + + - name: Install Poetry run: | - import hashlib - import sys + pip install --constraint=.github/workflows/constraints.txt poetry + poetry --version - python = "py{}.{}".format(*sys.version_info[:2]) - payload = sys.version.encode() + sys.executable.encode() - digest = hashlib.sha256(payload).hexdigest() - result = "${{ runner.os }}-{}-{}-pre-commit".format(python, digest[:8]) + - name: Check if there is a parent commit + id: check-parent-commit + run: | + echo "::set-output name=sha::$(git rev-parse --verify --quiet HEAD^)" - print("::set-output name=result::{}".format(result)) - - uses: actions/cache@v1.2.0 - if: matrix.os != 'windows-latest' + - name: Detect and tag new version + id: check-version + if: steps.check-parent-commit.outputs.sha + uses: salsify/action-detect-and-tag-new-version@v2.0.1 with: - path: ~/.cache/pre-commit - key: ${{ steps.cache_key_prefix.outputs.result }}-${{ hashFiles('.pre-commit-config.yaml') }} - restore-keys: | - ${{ steps.cache_key_prefix.outputs.result }}- - - run: nox --force-color - - run: poetry build --ansi - - uses: pypa/gh-action-pypi-publish@v1.1.0 + version-command: | + bash -o pipefail -c "poetry version | awk '{ print \$2 }'" + + - name: Bump version for developmental release + if: "! steps.check-version.outputs.tag" + run: | + poetry version patch && + version=$(poetry version | awk '{ print $2 }') && + poetry version $version.dev.$(date +%s) + + - name: Build package + run: | + poetry build --ansi + + - name: Publish package on PyPI + if: steps.check-version.outputs.tag + uses: pypa/gh-action-pypi-publish@v1.3.1 with: user: __token__ password: ${{ secrets.PYPI_TOKEN }} + + - name: Publish package on TestPyPI + if: "! steps.check-version.outputs.tag" + uses: pypa/gh-action-pypi-publish@v1.3.1 + with: + user: __token__ + password: ${{ secrets.TEST_PYPI_TOKEN }} + repository_url: https://test.pypi.org/legacy/ + + - name: Publish the release notes + uses: release-drafter/release-drafter@v5.11.0 + with: + publish: ${{ steps.check-version.outputs.tag != '' }} + tag: ${{ steps.check-version.outputs.tag }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/test-pypi.yml b/.github/workflows/test-pypi.yml deleted file mode 100644 index fa40e7aa..00000000 --- a/.github/workflows/test-pypi.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: TestPyPI -on: - push: - branches: - - master -jobs: - test_pypi: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2.1.0 - - uses: actions/setup-python@v2 - with: - python-version: "3.8" - - run: | - pip install --constraint=.github/workflows/constraints.txt pip - pip install --constraint=.github/workflows/constraints.txt poetry - - run: >- - poetry version patch && - version=$(poetry version | awk '{print $2}') && - poetry version $version.dev.$(date +%s) - - run: poetry build --ansi - - uses: pypa/gh-action-pypi-publish@v1.1.0 - with: - user: __token__ - password: ${{ secrets.TEST_PYPI_TOKEN }} - repository_url: https://test.pypi.org/legacy/ diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index fb6ef0d5..a2c2994e 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,26 +1,60 @@ name: Tests -on: [push, pull_request] + +on: + - push + - pull_request + jobs: tests: + name: ${{ matrix.session }} ${{ matrix.python-version }} / ${{ matrix.os }} + runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: include: - - { python-version: 3.8, os: ubuntu-latest } - - { python-version: 3.8, os: windows-latest } - - { python-version: 3.8, os: macos-latest } - - { python-version: 3.7, os: ubuntu-latest } - - { python-version: 3.6, os: ubuntu-latest } - runs-on: ${{ matrix.os }} - name: Python ${{ matrix.python-version }} (${{ matrix.os }}) + - { python-version: 3.8, os: ubuntu-latest, session: "pre-commit" } + - { python-version: 3.8, os: ubuntu-latest, session: "safety" } + - { python-version: 3.8, os: ubuntu-latest, session: "mypy" } + - { python-version: 3.7, os: ubuntu-latest, session: "mypy" } + - { python-version: 3.6, os: ubuntu-latest, session: "mypy" } + - { python-version: 3.8, os: ubuntu-latest, session: "tests" } + - { python-version: 3.7, os: ubuntu-latest, session: "tests" } + - { python-version: 3.6, os: ubuntu-latest, session: "tests" } + - { python-version: 3.8, os: windows-latest, session: "tests" } + - { python-version: 3.8, os: macos-latest, session: "tests" } + - { python-version: 3.8, os: ubuntu-latest, session: "typeguard" } + - { python-version: 3.8, os: ubuntu-latest, session: "docs" } + + env: + NOXSESSION: ${{ matrix.session }} + steps: - - uses: actions/checkout@v2.1.0 - - uses: actions/setup-python@v2 + - name: Check out the repository + uses: actions/checkout@v2.3.1 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} - - name: Compute cache key prefix - if: matrix.os != 'windows-latest' - id: cache_key_prefix + + - name: Upgrade pip + run: | + pip install --constraint=.github/workflows/constraints.txt pip + pip --version + + - name: Install Poetry + run: | + pip install --constraint=.github/workflows/constraints.txt poetry + poetry --version + + - name: Install Nox + run: | + pip install --constraint=.github/workflows/constraints.txt nox + nox --version + + - name: Compute pre-commit cache key + if: matrix.session == 'pre-commit' + id: pre-commit-cache shell: python run: | import hashlib @@ -32,14 +66,32 @@ jobs: result = "${{ runner.os }}-{}-{}-pre-commit".format(python, digest[:8]) print("::set-output name=result::{}".format(result)) - - uses: actions/cache@v1.2.0 - if: matrix.os != 'windows-latest' + + - name: Restore pre-commit cache + uses: actions/cache@v2 + if: matrix.session == 'pre-commit' with: path: ~/.cache/pre-commit - key: ${{ steps.cache_key_prefix.outputs.result }}-${{ hashFiles('.pre-commit-config.yaml') }} + key: ${{ steps.pre-commit-cache.outputs.result }}-${{ hashFiles('.pre-commit-config.yaml') }} restore-keys: | - ${{ steps.cache_key_prefix.outputs.result }}- - - run: | - pip install --constraint=.github/workflows/constraints.txt pip - pip install --constraint=.github/workflows/constraints.txt nox poetry - - run: nox --force-color + ${{ steps.pre-commit-cache.outputs.result }}- + + - name: Run Nox + run: | + nox --force-color --python=${{ matrix.python-version }} + + - name: Upload documentation + if: matrix.session == 'docs' + uses: actions/upload-artifact@v2 + with: + name: docs + path: docs/_build + + - name: Create coverage report + if: always() && matrix.session == 'tests' + run: | + nox --force-color --session=coverage -- xml + + - name: Upload coverage report + if: always() && matrix.session == 'tests' + uses: codecov/codecov-action@v1.0.10 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 55433abf..76a22c8a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,33 +1,51 @@ repos: - - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v3.0.0 + - repo: local hooks: + - id: black + name: black + entry: black + language: system + types: [python] + require_serial: true + - id: check-added-large-files + name: Check for added large files + entry: check-added-large-files + language: system - id: check-toml + name: Check Toml + entry: check-toml + language: system + types: [toml] - id: check-yaml + name: Check Yaml + entry: check-yaml + language: system + types: [yaml] - id: end-of-file-fixer + name: Fix End of Files + entry: end-of-file-fixer + language: system + types: [text] + stages: [commit, push, manual] + - id: flake8 + name: flake8 + entry: flake8 + language: system + types: [python] + require_serial: true + - id: reorder-python-imports + name: Reorder python imports + entry: reorder-python-imports + language: system + types: [python] + args: [--application-directories=src] - id: trailing-whitespace - - id: check-added-large-files + name: Trim Trailing Whitespace + entry: trailing-whitespace-fixer + language: system + types: [text] + stages: [commit, push, manual] - repo: https://github.com/prettier/prettier rev: 2.0.5 hooks: - id: prettier - - repo: https://github.com/psf/black - rev: 19.10b0 - hooks: - - id: black - - repo: https://gitlab.com/pycqa/flake8 - rev: 3.8.1 - hooks: - - id: flake8 - additional_dependencies: - - flake8-bandit==2.1.2 - - flake8-bugbear==20.1.4 - - flake8-docstrings==1.5.0 - - flake8-rst-docstrings==0.0.13 - - pep8-naming==0.10.0 - - darglint==1.3.0 - - repo: https://github.com/asottile/reorder_python_imports - rev: v2.3.0 - hooks: - - id: reorder-python-imports - args: [--application-directories=src] diff --git a/README.rst b/README.rst index 8baa620f..ca864783 100644 --- a/README.rst +++ b/README.rst @@ -1,36 +1,36 @@ - nox-poetry ========== -|Tests| |Codecov| |PyPI| |Python Version| |Read the Docs| |License| |Black| |pre-commit| |Dependabot| +|PyPI| |Python Version| |License| + +|Read the Docs| |Tests| |Codecov| + +|pre-commit| |Black| -.. |Tests| image:: https://github.com/cjolowicz/nox-poetry/workflows/Tests/badge.svg - :target: https://github.com/cjolowicz/nox-poetry/actions?workflow=Tests - :alt: Tests -.. |Codecov| image:: https://codecov.io/gh/cjolowicz/nox-poetry/branch/master/graph/badge.svg - :target: https://codecov.io/gh/cjolowicz/nox-poetry - :alt: Codecov .. |PyPI| image:: https://img.shields.io/pypi/v/nox-poetry.svg :target: https://pypi.org/project/nox-poetry/ :alt: PyPI .. |Python Version| image:: https://img.shields.io/pypi/pyversions/nox-poetry :target: https://pypi.org/project/nox-poetry :alt: Python Version -.. |Read the Docs| image:: https://readthedocs.org/projects/nox-poetry/badge/ - :target: https://nox-poetry.readthedocs.io/ - :alt: Read the Docs .. |License| image:: https://img.shields.io/pypi/l/nox-poetry :target: https://opensource.org/licenses/MIT :alt: License -.. |Black| image:: https://img.shields.io/badge/code%20style-black-000000.svg - :target: https://github.com/psf/black - :alt: Black +.. |Read the Docs| image:: https://img.shields.io/readthedocs/nox-poetry/latest.svg?label=Read%20the%20Docs + :target: https://nox-poetry.readthedocs.io/ + :alt: Read the documentation at https://nox-poetry.readthedocs.io/ +.. |Tests| image:: https://github.com/cjolowicz/nox-poetry/workflows/Tests/badge.svg + :target: https://github.com/cjolowicz/nox-poetry/actions?workflow=Tests + :alt: Tests +.. |Codecov| image:: https://codecov.io/gh/cjolowicz/nox-poetry/branch/master/graph/badge.svg + :target: https://codecov.io/gh/cjolowicz/nox-poetry + :alt: Codecov .. |pre-commit| image:: https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white :target: https://github.com/pre-commit/pre-commit :alt: pre-commit -.. |Dependabot| image:: https://api.dependabot.com/badges/status?host=github&repo=cjolowicz/nox-poetry - :target: https://dependabot.com - :alt: Dependabot +.. |Black| image:: https://img.shields.io/badge/code%20style-black-000000.svg + :target: https://github.com/psf/black + :alt: Black Features diff --git a/docs/reference.rst b/docs/reference.rst index 2ca86995..11c4d362 100644 --- a/docs/reference.rst +++ b/docs/reference.rst @@ -1,4 +1,3 @@ - Reference ========= diff --git a/docs/requirements.txt b/docs/requirements.txt index 1c07e20b..96451c97 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1 +1 @@ -sphinx==3.0.3 +sphinx==3.1.2 diff --git a/mypy.ini b/mypy.ini index 37db7174..dfca56c1 100644 --- a/mypy.ini +++ b/mypy.ini @@ -19,14 +19,8 @@ warn_unreachable = True warn_unused_configs = True warn_unused_ignores = True -[mypy-noxfile] -disallow_untyped_decorators = False - [mypy-tests.*] disallow_untyped_decorators = False -[mypy-nox.*] -ignore_missing_imports = True - [mypy-pytest] ignore_missing_imports = True diff --git a/noxfile.py b/noxfile.py index b63e0a90..676b307c 100644 --- a/noxfile.py +++ b/noxfile.py @@ -1,8 +1,10 @@ """Nox sessions.""" import contextlib import shutil +import sys import tempfile from pathlib import Path +from textwrap import dedent from typing import cast from typing import Iterator @@ -12,8 +14,7 @@ package = "nox_poetry" python_versions = ["3.8", "3.7", "3.6"] -nox.options.sessions = "pre-commit", "safety", "mypy", "tests" -locations = "src", "tests", "noxfile.py", "docs/conf.py" +nox.options.sessions = "pre-commit", "safety", "mypy", "tests", "typeguard" class Poetry: @@ -110,12 +111,78 @@ def install(session: Session, *args: str) -> None: session.install(f"--constraint={requirements}", *args) +def activate_virtualenv_in_precommit_hooks(session: Session) -> None: + """Activate virtualenv in hooks installed by pre-commit. + + This function patches git hooks installed by pre-commit to activate the + session's virtual environment. This allows pre-commit to locate hooks in + that environment when invoked from git. + + Args: + session: The Session object. + """ + if session.bin is None: + return + + virtualenv = session.env.get("VIRTUAL_ENV") + if virtualenv is None: + return + + hookdir = Path(".git") / "hooks" + if not hookdir.is_dir(): + return + + for hook in hookdir.iterdir(): + if hook.name.endswith(".sample") or not hook.is_file(): + continue + + text = hook.read_text() + bindir = repr(session.bin)[1:-1] # strip quotes + if not ( + Path("A") == Path("a") and bindir.lower() in text.lower() or bindir in text + ): + continue + + lines = text.splitlines() + if not (lines[0].startswith("#!") and "python" in lines[0].lower()): + continue + + header = dedent( + f"""\ + import os + os.environ["VIRTUAL_ENV"] = {virtualenv!r} + os.environ["PATH"] = os.pathsep.join(( + {session.bin!r}, + os.environ.get("PATH", ""), + )) + """ + ) + + lines.insert(1, header) + hook.write_text("\n".join(lines)) + + @nox.session(name="pre-commit", python="3.8") def precommit(session: Session) -> None: """Lint using pre-commit.""" args = session.posargs or ["run", "--all-files", "--show-diff-on-failure"] - install(session, "pre-commit") + install( + session, + "black", + "darglint", + "flake8", + "flake8-bandit", + "flake8-bugbear", + "flake8-docstrings", + "flake8-rst-docstrings", + "pep8-naming", + "pre-commit", + "pre-commit-hooks", + "reorder-python-imports", + ) session.run("pre-commit", *args) + if args and args[0] == "install": + activate_virtualenv_in_precommit_hooks(session) @nox.session(python="3.8") @@ -130,19 +197,38 @@ def safety(session: Session) -> None: @nox.session(python=python_versions) def mypy(session: Session) -> None: """Type-check using mypy.""" - args = session.posargs or locations + args = session.posargs or ["src", "tests", "docs/conf.py"] install_package(session) install(session, "mypy") session.run("mypy", *args) + if not session.posargs: + session.run("mypy", f"--python-executable={sys.executable}", "noxfile.py") @nox.session(python=python_versions) def tests(session: Session) -> None: """Run the test suite.""" - args = session.posargs or ["--cov"] install_package(session) - install(session, "coverage[toml]", "pytest", "pytest-cov") - session.run("pytest", *args) + install(session, "coverage[toml]", "pytest") + try: + session.run("coverage", "run", "--parallel", "-m", "pytest", *session.posargs) + finally: + session.notify("coverage") + + +@nox.session +def coverage(session: Session) -> None: + """Produce the coverage report.""" + # Do not use session.posargs unless this is the only session. + has_args = session.posargs and len(session._runner.manifest) == 1 + args = session.posargs if has_args else ["report"] + + install(session, "coverage[toml]") + + if not has_args and any(Path().glob(".coverage.*")): + session.run("coverage", "combine") + + session.run("coverage", *args) @nox.session(python=python_versions) diff --git a/poetry.lock b/poetry.lock index 0818bb82..efd52014 100644 --- a/poetry.lock +++ b/poetry.lock @@ -22,6 +22,17 @@ optional = false python-versions = "*" version = "0.26.2" +[[package]] +category = "dev" +description = "Utilities for refactoring imports in python-like syntax." +name = "aspy.refactor-imports" +optional = false +python-versions = ">=3.6.1" +version = "2.1.1" + +[package.dependencies] +cached-property = "*" + [[package]] category = "dev" description = "Atomic file writes." @@ -56,13 +67,56 @@ version = "2.8.0" [package.dependencies] pytz = ">=2015.7" +[[package]] +category = "dev" +description = "Security oriented static analyser for python code." +name = "bandit" +optional = false +python-versions = "*" +version = "1.6.2" + +[package.dependencies] +GitPython = ">=1.0.1" +PyYAML = ">=3.13" +colorama = ">=0.3.9" +six = ">=1.10.0" +stevedore = ">=1.20.0" + +[[package]] +category = "dev" +description = "The uncompromising code formatter." +name = "black" +optional = false +python-versions = ">=3.6" +version = "19.10b0" + +[package.dependencies] +appdirs = "*" +attrs = ">=18.1.0" +click = ">=6.5" +pathspec = ">=0.6,<1" +regex = "*" +toml = ">=0.9.4" +typed-ast = ">=1.4.0" + +[package.extras] +d = ["aiohttp (>=3.3.2)", "aiohttp-cors"] + +[[package]] +category = "dev" +description = "A decorator for caching properties in classes." +name = "cached-property" +optional = false +python-versions = "*" +version = "1.5.1" + [[package]] category = "dev" description = "Python package for providing Mozilla's CA Bundle." name = "certifi" optional = false python-versions = "*" -version = "2020.4.5.1" +version = "2020.6.20" [[package]] category = "dev" @@ -91,7 +145,7 @@ version = "7.1.2" [[package]] category = "dev" description = "Cross-platform colored terminal text." -marker = "sys_platform == \"win32\"" +marker = "platform_system == \"Windows\" or sys_platform == \"win32\"" name = "colorama" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" @@ -103,7 +157,7 @@ description = "Code coverage measurement for Python" name = "coverage" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" -version = "5.1" +version = "5.2" [package.dependencies] [package.dependencies.toml] @@ -113,13 +167,21 @@ version = "*" [package.extras] toml = ["toml"] +[[package]] +category = "dev" +description = "A utility for ensuring Google-style docstrings stay up to date with the source code." +name = "darglint" +optional = false +python-versions = ">=3.5,<4.0" +version = "1.5.1" + [[package]] category = "dev" description = "Distribution utilities" name = "distlib" optional = false python-versions = "*" -version = "0.3.0" +version = "0.3.1" [[package]] category = "dev" @@ -153,13 +215,113 @@ optional = false python-versions = "*" version = "3.0.12" +[[package]] +category = "dev" +description = "the modular source code checker: pep8 pyflakes and co" +name = "flake8" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" +version = "3.8.3" + +[package.dependencies] +mccabe = ">=0.6.0,<0.7.0" +pycodestyle = ">=2.6.0a1,<2.7.0" +pyflakes = ">=2.2.0,<2.3.0" + +[package.dependencies.importlib-metadata] +python = "<3.8" +version = "*" + +[[package]] +category = "dev" +description = "Automated security testing with bandit and flake8." +name = "flake8-bandit" +optional = false +python-versions = "*" +version = "2.1.2" + +[package.dependencies] +bandit = "*" +flake8 = "*" +flake8-polyfill = "*" +pycodestyle = "*" + +[[package]] +category = "dev" +description = "A plugin for flake8 finding likely bugs and design problems in your program. Contains warnings that don't belong in pyflakes and pycodestyle." +name = "flake8-bugbear" +optional = false +python-versions = ">=3.6" +version = "20.1.4" + +[package.dependencies] +attrs = ">=19.2.0" +flake8 = ">=3.0.0" + +[[package]] +category = "dev" +description = "Extension for flake8 which uses pydocstyle to check docstrings" +name = "flake8-docstrings" +optional = false +python-versions = "*" +version = "1.5.0" + +[package.dependencies] +flake8 = ">=3" +pydocstyle = ">=2.1" + +[[package]] +category = "dev" +description = "Polyfill package for Flake8 plugins" +name = "flake8-polyfill" +optional = false +python-versions = "*" +version = "1.0.2" + +[package.dependencies] +flake8 = "*" + +[[package]] +category = "dev" +description = "Python docstring reStructuredText (RST) validator" +name = "flake8-rst-docstrings" +optional = false +python-versions = "*" +version = "0.0.13" + +[package.dependencies] +flake8 = ">=3.0.0" +restructuredtext_lint = "*" + +[[package]] +category = "dev" +description = "Git Object Database" +name = "gitdb" +optional = false +python-versions = ">=3.4" +version = "4.0.5" + +[package.dependencies] +smmap = ">=3.0.1,<4" + +[[package]] +category = "dev" +description = "Python Git Library" +name = "gitpython" +optional = false +python-versions = ">=3.4" +version = "3.1.3" + +[package.dependencies] +gitdb = ">=4.0.1,<5" + [[package]] category = "dev" description = "File identification library for Python" name = "identify" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" -version = "1.4.15" +version = "1.4.21" [package.extras] license = ["editdistance"] @@ -170,7 +332,7 @@ description = "Internationalized Domain Names in Applications (IDNA)" name = "idna" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "2.9" +version = "2.10" [[package]] category = "dev" @@ -187,14 +349,14 @@ marker = "python_version < \"3.8\"" name = "importlib-metadata" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" -version = "1.6.0" +version = "1.7.0" [package.dependencies] zipp = ">=0.5" [package.extras] docs = ["sphinx", "rst.linker"] -testing = ["packaging", "importlib-resources"] +testing = ["packaging", "pep517", "importlib-resources (>=1.3)"] [[package]] category = "dev" @@ -203,13 +365,9 @@ marker = "python_version < \"3.7\"" name = "importlib-resources" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" -version = "1.5.0" +version = "3.0.0" [package.dependencies] -[package.dependencies.importlib-metadata] -python = "<3.8" -version = "*" - [package.dependencies.zipp] python = "<3.8" version = ">=0.4" @@ -237,11 +395,14 @@ description = "Python LiveReload is an awesome tool for web developers" name = "livereload" optional = false python-versions = "*" -version = "2.6.1" +version = "2.6.2" [package.dependencies] six = "*" -tornado = "*" + +[package.dependencies.tornado] +python = ">=2.8" +version = "*" [[package]] category = "dev" @@ -251,13 +412,21 @@ optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" version = "1.1.1" +[[package]] +category = "dev" +description = "McCabe checker, plugin for flake8" +name = "mccabe" +optional = false +python-versions = "*" +version = "0.6.1" + [[package]] category = "dev" description = "More routines for operating on iterables, beyond itertools" name = "more-itertools" optional = false python-versions = ">=3.5" -version = "8.2.0" +version = "8.4.0" [[package]] category = "dev" @@ -265,7 +434,7 @@ description = "Optional static typing for Python" name = "mypy" optional = false python-versions = ">=3.5" -version = "0.770" +version = "0.782" [package.dependencies] mypy-extensions = ">=0.4.3,<0.5.0" @@ -289,7 +458,7 @@ description = "Node.js virtual environment builder" name = "nodeenv" optional = false python-versions = "*" -version = "1.3.5" +version = "1.4.0" [[package]] category = "dev" @@ -297,12 +466,20 @@ description = "Core utilities for Python packages" name = "packaging" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "20.3" +version = "20.4" [package.dependencies] pyparsing = ">=2.0.2" six = "*" +[[package]] +category = "dev" +description = "Utility library for gitignore style pattern matching of file paths." +name = "pathspec" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "0.8.0" + [[package]] category = "dev" description = "File system general utilities" @@ -311,6 +488,25 @@ optional = false python-versions = "*" version = "0.1.2" +[[package]] +category = "dev" +description = "Python Build Reasonableness" +name = "pbr" +optional = false +python-versions = "*" +version = "5.4.5" + +[[package]] +category = "dev" +description = "Check PEP-8 naming conventions, plugin for flake8" +name = "pep8-naming" +optional = false +python-versions = "*" +version = "0.11.1" + +[package.dependencies] +flake8-polyfill = ">=1.0.2,<2" + [[package]] category = "dev" description = "plugin and hook calling mechanisms for python" @@ -341,7 +537,7 @@ description = "A framework for managing and maintaining multi-language pre-commi name = "pre-commit" optional = false python-versions = ">=3.6.1" -version = "2.4.0" +version = "2.6.0" [package.dependencies] cfgv = ">=2.0.0" @@ -359,13 +555,52 @@ version = "*" python = "<3.7" version = "*" +[[package]] +category = "dev" +description = "Some out-of-the-box hooks for pre-commit." +name = "pre-commit-hooks" +optional = false +python-versions = ">=3.6.1" +version = "3.1.0" + +[package.dependencies] +"ruamel.yaml" = ">=0.15" +toml = "*" + [[package]] category = "dev" description = "library with cross-python path, ini-parsing, io, code, log facilities" name = "py" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "1.8.1" +version = "1.9.0" + +[[package]] +category = "dev" +description = "Python style guide checker" +name = "pycodestyle" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "2.6.0" + +[[package]] +category = "dev" +description = "Python docstring style checker" +name = "pydocstyle" +optional = false +python-versions = ">=3.5" +version = "5.0.2" + +[package.dependencies] +snowballstemmer = "*" + +[[package]] +category = "dev" +description = "passive checker of Python programs" +name = "pyflakes" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "2.2.0" [[package]] category = "dev" @@ -389,7 +624,7 @@ description = "pytest: simple powerful testing with Python" name = "pytest" optional = false python-versions = ">=3.5" -version = "5.4.2" +version = "5.4.3" [package.dependencies] atomicwrites = ">=1.0" @@ -409,21 +644,6 @@ version = ">=0.12" checkqa-mypy = ["mypy (v0.761)"] testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] -[[package]] -category = "dev" -description = "Pytest plugin for measuring coverage." -name = "pytest-cov" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "2.8.1" - -[package.dependencies] -coverage = ">=4.4" -pytest = ">=3.6" - -[package.extras] -testing = ["fields", "hunter", "process-tests (2.0.2)", "six", "virtualenv"] - [[package]] category = "dev" description = "World timezone definitions, modern and historical" @@ -440,13 +660,32 @@ optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" version = "5.3.1" +[[package]] +category = "dev" +description = "Alternative regular expression module, to replace re." +name = "regex" +optional = false +python-versions = "*" +version = "2020.6.8" + +[[package]] +category = "dev" +description = "Tool for reordering python imports" +name = "reorder-python-imports" +optional = false +python-versions = ">=3.6.1" +version = "2.3.1" + +[package.dependencies] +"aspy.refactor-imports" = ">=2.1.0" + [[package]] category = "dev" description = "Python HTTP for Humans." name = "requests" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -version = "2.23.0" +version = "2.24.0" [package.dependencies] certifi = ">=2017.4.17" @@ -458,6 +697,43 @@ urllib3 = ">=1.21.1,<1.25.0 || >1.25.0,<1.25.1 || >1.25.1,<1.26" security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)"] socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7)", "win-inet-pton"] +[[package]] +category = "dev" +description = "reStructuredText linter" +name = "restructuredtext-lint" +optional = false +python-versions = "*" +version = "1.3.1" + +[package.dependencies] +docutils = ">=0.11,<1.0" + +[[package]] +category = "dev" +description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order" +name = "ruamel.yaml" +optional = false +python-versions = "*" +version = "0.16.10" + +[package.dependencies] +[package.dependencies."ruamel.yaml.clib"] +python = "<3.9" +version = ">=0.1.2" + +[package.extras] +docs = ["ryd"] +jinja2 = ["ruamel.yaml.jinja2 (>=0.2)"] + +[[package]] +category = "dev" +description = "C version of reader, parser and emitter for ruamel.yaml derived from libyaml" +marker = "platform_python_implementation == \"CPython\" and python_version < \"3.9\"" +name = "ruamel.yaml.clib" +optional = false +python-versions = "*" +version = "0.2.0" + [[package]] category = "dev" description = "Checks installed dependencies for known vulnerabilities." @@ -479,7 +755,15 @@ description = "Python 2 and 3 compatibility utilities" name = "six" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -version = "1.14.0" +version = "1.15.0" + +[[package]] +category = "dev" +description = "A pure Python implementation of a sliding window memory map manager" +name = "smmap" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "3.0.4" [[package]] category = "dev" @@ -495,7 +779,7 @@ description = "Python documentation generator" name = "sphinx" optional = false python-versions = ">=3.5" -version = "3.0.3" +version = "3.1.2" [package.dependencies] Jinja2 = ">=2.3" @@ -518,7 +802,7 @@ sphinxcontrib-serializinghtml = "*" [package.extras] docs = ["sphinxcontrib-websupport"] -lint = ["flake8 (>=3.5.0)", "flake8-import-order", "mypy (>=0.770)", "docutils-stubs"] +lint = ["flake8 (>=3.5.0)", "flake8-import-order", "mypy (>=0.780)", "docutils-stubs"] test = ["pytest", "pytest-cov", "html5lib", "typed-ast", "cython"] [[package]] @@ -609,6 +893,17 @@ version = "1.1.4" lint = ["flake8", "mypy", "docutils-stubs"] test = ["pytest"] +[[package]] +category = "dev" +description = "Manage dynamic plugins for Python applications" +name = "stevedore" +optional = false +python-versions = ">=3.6" +version = "2.0.0" + +[package.dependencies] +pbr = ">=2.0.0,<2.1.0 || >2.1.0" + [[package]] category = "dev" description = "Python Library for Tom's Obvious, Minimal Language" @@ -638,12 +933,12 @@ category = "dev" description = "Run-time type checker for Python" name = "typeguard" optional = false -python-versions = ">=3.5.2" -version = "2.7.1" +python-versions = ">=3.5.3" +version = "2.9.1" [package.extras] doc = ["sphinx-rtd-theme", "sphinx-autodoc-typehints (>=1.2.0)"] -test = ["pytest", "pytest-cov", "typing-extensions"] +test = ["pytest", "typing-extensions"] [[package]] category = "dev" @@ -672,11 +967,11 @@ description = "Virtual Python Environment builder" name = "virtualenv" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" -version = "20.0.20" +version = "20.0.26" [package.dependencies] appdirs = ">=1.4.3,<2" -distlib = ">=0.3.0,<1" +distlib = ">=0.3.1,<1" filelock = ">=3.0.0,<4" six = ">=1.9.0,<2" @@ -686,11 +981,11 @@ version = ">=0.12,<2" [package.dependencies.importlib-resources] python = "<3.7" -version = ">=1.0,<2" +version = ">=1.0" [package.extras] docs = ["sphinx (>=3)", "sphinx-argparse (>=0.2.5)", "sphinx-rtd-theme (>=0.4.3)", "towncrier (>=19.9.0rc1)", "proselint (>=0.10.2)"] -testing = ["pytest (>=4)", "coverage (>=5)", "coverage-enable-subprocess (>=1)", "pytest-xdist (>=1.31.0)", "pytest-mock (>=2)", "pytest-env (>=0.6.2)", "pytest-randomly (>=1)", "pytest-timeout", "packaging (>=20.0)", "xonsh (>=0.9.16)"] +testing = ["pytest (>=4)", "coverage (>=5)", "coverage-enable-subprocess (>=1)", "pytest-xdist (>=1.31.0)", "pytest-mock (>=2)", "pytest-env (>=0.6.2)", "pytest-randomly (>=1)", "pytest-timeout (>=1)", "pytest-freezegun (>=0.4.1)", "flaky (>=3)", "packaging (>=20.0)", "xonsh (>=0.9.16)"] [[package]] category = "dev" @@ -698,7 +993,7 @@ description = "Filesystem events monitoring" name = "watchdog" optional = false python-versions = "*" -version = "0.10.2" +version = "0.10.3" [package.dependencies] pathtools = ">=0.1.1" @@ -708,11 +1003,11 @@ watchmedo = ["PyYAML (>=3.10)", "argh (>=0.24.1)"] [[package]] category = "dev" -description = "Measures number of Terminal column cells of wide-character codes" +description = "Measures the displayed width of unicode strings in a terminal" name = "wcwidth" optional = false python-versions = "*" -version = "0.1.9" +version = "0.2.5" [[package]] category = "dev" @@ -720,7 +1015,7 @@ description = "A rewrite of the builtin doctest module" name = "xdoctest" optional = false python-versions = "*" -version = "0.12.0" +version = "0.13.0" [package.dependencies] six = "*" @@ -744,7 +1039,7 @@ docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] testing = ["jaraco.itertools", "func-timeout"] [metadata] -content-hash = "22562d32f821aca447bcb38e0240f12ad840af068bbee3a03ab6f1e7d2dff591" +content-hash = "cfc67c767dd4aa60a61e0ec3fdd5d28ff8d94114b99bcc9f39ced91ba0ca32de" python-versions = "^3.6.1" [metadata.files] @@ -760,6 +1055,10 @@ argh = [ {file = "argh-0.26.2-py2.py3-none-any.whl", hash = "sha256:a9b3aaa1904eeb78e32394cd46c6f37ac0fb4af6dc488daa58971bdc7d7fcaf3"}, {file = "argh-0.26.2.tar.gz", hash = "sha256:e9535b8c84dc9571a48999094fda7f33e63c3f1b74f3e5f3ac0105a58405bb65"}, ] +"aspy.refactor-imports" = [ + {file = "aspy.refactor_imports-2.1.1-py2.py3-none-any.whl", hash = "sha256:9df76bf19ef81620068b785a386740ab3c8939fcbdcebf20c4a4e0057230d782"}, + {file = "aspy.refactor_imports-2.1.1.tar.gz", hash = "sha256:eec8d1a73bedf64ffb8b589ad919a030c1fb14acf7d1ce0ab192f6eedae895c5"}, +] atomicwrites = [ {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, @@ -772,9 +1071,21 @@ babel = [ {file = "Babel-2.8.0-py2.py3-none-any.whl", hash = "sha256:d670ea0b10f8b723672d3a6abeb87b565b244da220d76b4dba1b66269ec152d4"}, {file = "Babel-2.8.0.tar.gz", hash = "sha256:1aac2ae2d0d8ea368fa90906567f5c08463d98ade155c0c4bfedd6a0f7160e38"}, ] +bandit = [ + {file = "bandit-1.6.2-py2.py3-none-any.whl", hash = "sha256:336620e220cf2d3115877685e264477ff9d9abaeb0afe3dc7264f55fa17a3952"}, + {file = "bandit-1.6.2.tar.gz", hash = "sha256:41e75315853507aa145d62a78a2a6c5e3240fe14ee7c601459d0df9418196065"}, +] +black = [ + {file = "black-19.10b0-py36-none-any.whl", hash = "sha256:1b30e59be925fafc1ee4565e5e08abef6b03fe455102883820fe5ee2e4734e0b"}, + {file = "black-19.10b0.tar.gz", hash = "sha256:c2edb73a08e9e0e6f65a0e6af18b059b8b1cdd5bef997d7a0b181df93dc81539"}, +] +cached-property = [ + {file = "cached-property-1.5.1.tar.gz", hash = "sha256:9217a59f14a5682da7c4b8829deadbfc194ac22e9908ccf7c8820234e80a1504"}, + {file = "cached_property-1.5.1-py2.py3-none-any.whl", hash = "sha256:3a026f1a54135677e7da5ce819b0c690f156f37976f3e30c5430740725203d7f"}, +] certifi = [ - {file = "certifi-2020.4.5.1-py2.py3-none-any.whl", hash = "sha256:1d987a998c75633c40847cc966fcf5904906c920a7f17ef374f5aa4282abd304"}, - {file = "certifi-2020.4.5.1.tar.gz", hash = "sha256:51fcb31174be6e6664c5f69e3e1691a2d72a1a12e90f872cbdb1567eb47b6519"}, + {file = "certifi-2020.6.20-py2.py3-none-any.whl", hash = "sha256:8fc0819f1f30ba15bdb34cceffb9ef04d99f420f68eb75d901e9560b8749fc41"}, + {file = "certifi-2020.6.20.tar.gz", hash = "sha256:5930595817496dd21bb8dc35dad090f1c2cd0adfaf21204bf6732ca5d8ee34d3"}, ] cfgv = [ {file = "cfgv-3.1.0-py2.py3-none-any.whl", hash = "sha256:1ccf53320421aeeb915275a196e23b3b8ae87dea8ac6698b1638001d4a486d53"}, @@ -793,40 +1104,48 @@ colorama = [ {file = "colorama-0.4.3.tar.gz", hash = "sha256:e96da0d330793e2cb9485e9ddfd918d456036c7149416295932478192f4436a1"}, ] coverage = [ - {file = "coverage-5.1-cp27-cp27m-macosx_10_12_x86_64.whl", hash = "sha256:0cb4be7e784dcdc050fc58ef05b71aa8e89b7e6636b99967fadbdba694cf2b65"}, - {file = "coverage-5.1-cp27-cp27m-macosx_10_13_intel.whl", hash = "sha256:c317eaf5ff46a34305b202e73404f55f7389ef834b8dbf4da09b9b9b37f76dd2"}, - {file = "coverage-5.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:b83835506dfc185a319031cf853fa4bb1b3974b1f913f5bb1a0f3d98bdcded04"}, - {file = "coverage-5.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:5f2294dbf7875b991c381e3d5af2bcc3494d836affa52b809c91697449d0eda6"}, - {file = "coverage-5.1-cp27-cp27m-win32.whl", hash = "sha256:de807ae933cfb7f0c7d9d981a053772452217df2bf38e7e6267c9cbf9545a796"}, - {file = "coverage-5.1-cp27-cp27m-win_amd64.whl", hash = "sha256:bf9cb9a9fd8891e7efd2d44deb24b86d647394b9705b744ff6f8261e6f29a730"}, - {file = "coverage-5.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:acf3763ed01af8410fc36afea23707d4ea58ba7e86a8ee915dfb9ceff9ef69d0"}, - {file = "coverage-5.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:dec5202bfe6f672d4511086e125db035a52b00f1648d6407cc8e526912c0353a"}, - {file = "coverage-5.1-cp35-cp35m-macosx_10_12_x86_64.whl", hash = "sha256:7a5bdad4edec57b5fb8dae7d3ee58622d626fd3a0be0dfceda162a7035885ecf"}, - {file = "coverage-5.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:1601e480b9b99697a570cea7ef749e88123c04b92d84cedaa01e117436b4a0a9"}, - {file = "coverage-5.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:dbe8c6ae7534b5b024296464f387d57c13caa942f6d8e6e0346f27e509f0f768"}, - {file = "coverage-5.1-cp35-cp35m-win32.whl", hash = "sha256:a027ef0492ede1e03a8054e3c37b8def89a1e3c471482e9f046906ba4f2aafd2"}, - {file = "coverage-5.1-cp35-cp35m-win_amd64.whl", hash = "sha256:0e61d9803d5851849c24f78227939c701ced6704f337cad0a91e0972c51c1ee7"}, - {file = "coverage-5.1-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:2d27a3f742c98e5c6b461ee6ef7287400a1956c11421eb574d843d9ec1f772f0"}, - {file = "coverage-5.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:66460ab1599d3cf894bb6baee8c684788819b71a5dc1e8fa2ecc152e5d752019"}, - {file = "coverage-5.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:5c542d1e62eece33c306d66fe0a5c4f7f7b3c08fecc46ead86d7916684b36d6c"}, - {file = "coverage-5.1-cp36-cp36m-win32.whl", hash = "sha256:2742c7515b9eb368718cd091bad1a1b44135cc72468c731302b3d641895b83d1"}, - {file = "coverage-5.1-cp36-cp36m-win_amd64.whl", hash = "sha256:dead2ddede4c7ba6cb3a721870f5141c97dc7d85a079edb4bd8d88c3ad5b20c7"}, - {file = "coverage-5.1-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:01333e1bd22c59713ba8a79f088b3955946e293114479bbfc2e37d522be03355"}, - {file = "coverage-5.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:e1ea316102ea1e1770724db01998d1603ed921c54a86a2efcb03428d5417e489"}, - {file = "coverage-5.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:adeb4c5b608574a3d647011af36f7586811a2c1197c861aedb548dd2453b41cd"}, - {file = "coverage-5.1-cp37-cp37m-win32.whl", hash = "sha256:782caea581a6e9ff75eccda79287daefd1d2631cc09d642b6ee2d6da21fc0a4e"}, - {file = "coverage-5.1-cp37-cp37m-win_amd64.whl", hash = "sha256:00f1d23f4336efc3b311ed0d807feb45098fc86dee1ca13b3d6768cdab187c8a"}, - {file = "coverage-5.1-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:402e1744733df483b93abbf209283898e9f0d67470707e3c7516d84f48524f55"}, - {file = "coverage-5.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:a3f3654d5734a3ece152636aad89f58afc9213c6520062db3978239db122f03c"}, - {file = "coverage-5.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:6402bd2fdedabbdb63a316308142597534ea8e1895f4e7d8bf7476c5e8751fef"}, - {file = "coverage-5.1-cp38-cp38-win32.whl", hash = "sha256:8fa0cbc7ecad630e5b0f4f35b0f6ad419246b02bc750de7ac66db92667996d24"}, - {file = "coverage-5.1-cp38-cp38-win_amd64.whl", hash = "sha256:79a3cfd6346ce6c13145731d39db47b7a7b859c0272f02cdb89a3bdcbae233a0"}, - {file = "coverage-5.1-cp39-cp39-win32.whl", hash = "sha256:a82b92b04a23d3c8a581fc049228bafde988abacba397d57ce95fe95e0338ab4"}, - {file = "coverage-5.1-cp39-cp39-win_amd64.whl", hash = "sha256:bb28a7245de68bf29f6fb199545d072d1036a1917dca17a1e75bbb919e14ee8e"}, - {file = "coverage-5.1.tar.gz", hash = "sha256:f90bfc4ad18450c80b024036eaf91e4a246ae287701aaa88eaebebf150868052"}, + {file = "coverage-5.2-cp27-cp27m-macosx_10_13_intel.whl", hash = "sha256:d9ad0a988ae20face62520785ec3595a5e64f35a21762a57d115dae0b8fb894a"}, + {file = "coverage-5.2-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:4bb385a747e6ae8a65290b3df60d6c8a692a5599dc66c9fa3520e667886f2e10"}, + {file = "coverage-5.2-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:9702e2cb1c6dec01fb8e1a64c015817c0800a6eca287552c47a5ee0ebddccf62"}, + {file = "coverage-5.2-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:42fa45a29f1059eda4d3c7b509589cc0343cd6bbf083d6118216830cd1a51613"}, + {file = "coverage-5.2-cp27-cp27m-win32.whl", hash = "sha256:41d88736c42f4a22c494c32cc48a05828236e37c991bd9760f8923415e3169e4"}, + {file = "coverage-5.2-cp27-cp27m-win_amd64.whl", hash = "sha256:bbb387811f7a18bdc61a2ea3d102be0c7e239b0db9c83be7bfa50f095db5b92a"}, + {file = "coverage-5.2-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:3740b796015b889e46c260ff18b84683fa2e30f0f75a171fb10d2bf9fb91fc70"}, + {file = "coverage-5.2-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ebf2431b2d457ae5217f3a1179533c456f3272ded16f8ed0b32961a6d90e38ee"}, + {file = "coverage-5.2-cp35-cp35m-macosx_10_13_x86_64.whl", hash = "sha256:d54d7ea74cc00482a2410d63bf10aa34ebe1c49ac50779652106c867f9986d6b"}, + {file = "coverage-5.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:87bdc8135b8ee739840eee19b184804e5d57f518578ffc797f5afa2c3c297913"}, + {file = "coverage-5.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:ed9a21502e9223f563e071759f769c3d6a2e1ba5328c31e86830368e8d78bc9c"}, + {file = "coverage-5.2-cp35-cp35m-win32.whl", hash = "sha256:509294f3e76d3f26b35083973fbc952e01e1727656d979b11182f273f08aa80b"}, + {file = "coverage-5.2-cp35-cp35m-win_amd64.whl", hash = "sha256:ca63dae130a2e788f2b249200f01d7fa240f24da0596501d387a50e57aa7075e"}, + {file = "coverage-5.2-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:5c74c5b6045969b07c9fb36b665c9cac84d6c174a809fc1b21bdc06c7836d9a0"}, + {file = "coverage-5.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:c32aa13cc3fe86b0f744dfe35a7f879ee33ac0a560684fef0f3e1580352b818f"}, + {file = "coverage-5.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:1e58fca3d9ec1a423f1b7f2aa34af4f733cbfa9020c8fe39ca451b6071237405"}, + {file = "coverage-5.2-cp36-cp36m-win32.whl", hash = "sha256:3b2c34690f613525672697910894b60d15800ac7e779fbd0fccf532486c1ba40"}, + {file = "coverage-5.2-cp36-cp36m-win_amd64.whl", hash = "sha256:a4d511012beb967a39580ba7d2549edf1e6865a33e5fe51e4dce550522b3ac0e"}, + {file = "coverage-5.2-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:32ecee61a43be509b91a526819717d5e5650e009a8d5eda8631a59c721d5f3b6"}, + {file = "coverage-5.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:6f91b4492c5cde83bfe462f5b2b997cdf96a138f7c58b1140f05de5751623cf1"}, + {file = "coverage-5.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:bfcc811883699ed49afc58b1ed9f80428a18eb9166422bce3c31a53dba00fd1d"}, + {file = "coverage-5.2-cp37-cp37m-win32.whl", hash = "sha256:60a3d36297b65c7f78329b80120f72947140f45b5c7a017ea730f9112b40f2ec"}, + {file = "coverage-5.2-cp37-cp37m-win_amd64.whl", hash = "sha256:12eaccd86d9a373aea59869bc9cfa0ab6ba8b1477752110cb4c10d165474f703"}, + {file = "coverage-5.2-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:d82db1b9a92cb5c67661ca6616bdca6ff931deceebb98eecbd328812dab52032"}, + {file = "coverage-5.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:214eb2110217f2636a9329bc766507ab71a3a06a8ea30cdeebb47c24dce5972d"}, + {file = "coverage-5.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8a3decd12e7934d0254939e2bf434bf04a5890c5bf91a982685021786a08087e"}, + {file = "coverage-5.2-cp38-cp38-win32.whl", hash = "sha256:1dcebae667b73fd4aa69237e6afb39abc2f27520f2358590c1b13dd90e32abe7"}, + {file = "coverage-5.2-cp38-cp38-win_amd64.whl", hash = "sha256:f50632ef2d749f541ca8e6c07c9928a37f87505ce3a9f20c8446ad310f1aa87b"}, + {file = "coverage-5.2-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:7403675df5e27745571aba1c957c7da2dacb537c21e14007ec3a417bf31f7f3d"}, + {file = "coverage-5.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:0fc4e0d91350d6f43ef6a61f64a48e917637e1dcfcba4b4b7d543c628ef82c2d"}, + {file = "coverage-5.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:25fe74b5b2f1b4abb11e103bb7984daca8f8292683957d0738cd692f6a7cc64c"}, + {file = "coverage-5.2-cp39-cp39-win32.whl", hash = "sha256:d67599521dff98ec8c34cd9652cbcfe16ed076a2209625fca9dc7419b6370e5c"}, + {file = "coverage-5.2-cp39-cp39-win_amd64.whl", hash = "sha256:10f2a618a6e75adf64329f828a6a5b40244c1c50f5ef4ce4109e904e69c71bd2"}, + {file = "coverage-5.2.tar.gz", hash = "sha256:1874bdc943654ba46d28f179c1846f5710eda3aeb265ff029e0ac2b52daae404"}, +] +darglint = [ + {file = "darglint-1.5.1-py3-none-any.whl", hash = "sha256:b37be3bea80d25fa015c002ab63d4100a676441dbb75af7cd1df69b1b9324d5f"}, + {file = "darglint-1.5.1.tar.gz", hash = "sha256:cb845b4cd046c9073be1f24935b6609abdc521270669ed7370ca0cdb112a7e1c"}, ] distlib = [ - {file = "distlib-0.3.0.zip", hash = "sha256:2e166e231a26b36d6dfe35a48c4464346620f8645ed0ace01ee31822b288de21"}, + {file = "distlib-0.3.1-py2.py3-none-any.whl", hash = "sha256:8c09de2c67b3e7deef7184574fc060ab8a793e7adbb183d942c389c8b13c52fb"}, + {file = "distlib-0.3.1.zip", hash = "sha256:edf6116872c863e1aa9d5bb7cb5e05a022c519a4594dc703843343a9ddd9bff1"}, ] docutils = [ {file = "docutils-0.16-py2.py3-none-any.whl", hash = "sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af"}, @@ -840,33 +1159,62 @@ filelock = [ {file = "filelock-3.0.12-py3-none-any.whl", hash = "sha256:929b7d63ec5b7d6b71b0fa5ac14e030b3f70b75747cef1b10da9b879fef15836"}, {file = "filelock-3.0.12.tar.gz", hash = "sha256:18d82244ee114f543149c66a6e0c14e9c4f8a1044b5cdaadd0f82159d6a6ff59"}, ] +flake8 = [ + {file = "flake8-3.8.3-py2.py3-none-any.whl", hash = "sha256:15e351d19611c887e482fb960eae4d44845013cc142d42896e9862f775d8cf5c"}, + {file = "flake8-3.8.3.tar.gz", hash = "sha256:f04b9fcbac03b0a3e58c0ab3a0ecc462e023a9faf046d57794184028123aa208"}, +] +flake8-bandit = [ + {file = "flake8_bandit-2.1.2.tar.gz", hash = "sha256:687fc8da2e4a239b206af2e54a90093572a60d0954f3054e23690739b0b0de3b"}, +] +flake8-bugbear = [ + {file = "flake8-bugbear-20.1.4.tar.gz", hash = "sha256:bd02e4b009fb153fe6072c31c52aeab5b133d508095befb2ffcf3b41c4823162"}, + {file = "flake8_bugbear-20.1.4-py36.py37.py38-none-any.whl", hash = "sha256:a3ddc03ec28ba2296fc6f89444d1c946a6b76460f859795b35b77d4920a51b63"}, +] +flake8-docstrings = [ + {file = "flake8-docstrings-1.5.0.tar.gz", hash = "sha256:3d5a31c7ec6b7367ea6506a87ec293b94a0a46c0bce2bb4975b7f1d09b6f3717"}, + {file = "flake8_docstrings-1.5.0-py2.py3-none-any.whl", hash = "sha256:a256ba91bc52307bef1de59e2a009c3cf61c3d0952dbe035d6ff7208940c2edc"}, +] +flake8-polyfill = [ + {file = "flake8-polyfill-1.0.2.tar.gz", hash = "sha256:e44b087597f6da52ec6393a709e7108b2905317d0c0b744cdca6208e670d8eda"}, + {file = "flake8_polyfill-1.0.2-py2.py3-none-any.whl", hash = "sha256:12be6a34ee3ab795b19ca73505e7b55826d5f6ad7230d31b18e106400169b9e9"}, +] +flake8-rst-docstrings = [ + {file = "flake8-rst-docstrings-0.0.13.tar.gz", hash = "sha256:b1b619d81d879b874533973ac04ee5d823fdbe8c9f3701bfe802bb41813997b4"}, +] +gitdb = [ + {file = "gitdb-4.0.5-py3-none-any.whl", hash = "sha256:91f36bfb1ab7949b3b40e23736db18231bf7593edada2ba5c3a174a7b23657ac"}, + {file = "gitdb-4.0.5.tar.gz", hash = "sha256:c9e1f2d0db7ddb9a704c2a0217be31214e91a4fe1dea1efad19ae42ba0c285c9"}, +] +gitpython = [ + {file = "GitPython-3.1.3-py3-none-any.whl", hash = "sha256:ef1d60b01b5ce0040ad3ec20bc64f783362d41fa0822a2742d3586e1f49bb8ac"}, + {file = "GitPython-3.1.3.tar.gz", hash = "sha256:e107af4d873daed64648b4f4beb89f89f0cfbe3ef558fc7821ed2331c2f8da1a"}, +] identify = [ - {file = "identify-1.4.15-py2.py3-none-any.whl", hash = "sha256:88ed90632023e52a6495749c6732e61e08ec9f4f04e95484a5c37b9caf40283c"}, - {file = "identify-1.4.15.tar.gz", hash = "sha256:23c18d97bb50e05be1a54917ee45cc61d57cb96aedc06aabb2b02331edf0dbf0"}, + {file = "identify-1.4.21-py2.py3-none-any.whl", hash = "sha256:dac33eff90d57164e289fb20bf4e131baef080947ee9bf45efcd0da8d19064bf"}, + {file = "identify-1.4.21.tar.gz", hash = "sha256:c4d07f2b979e3931894170a9e0d4b8281e6905ea6d018c326f7ffefaf20db680"}, ] idna = [ - {file = "idna-2.9-py2.py3-none-any.whl", hash = "sha256:a068a21ceac8a4d63dbfd964670474107f541babbd2250d61922f029858365fa"}, - {file = "idna-2.9.tar.gz", hash = "sha256:7588d1c14ae4c77d74036e8c22ff447b26d0fde8f007354fd48a7814db15b7cb"}, + {file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"}, + {file = "idna-2.10.tar.gz", hash = "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6"}, ] imagesize = [ {file = "imagesize-1.2.0-py2.py3-none-any.whl", hash = "sha256:6965f19a6a2039c7d48bca7dba2473069ff854c36ae6f19d2cde309d998228a1"}, {file = "imagesize-1.2.0.tar.gz", hash = "sha256:b1f6b5a4eab1f73479a50fb79fcf729514a900c341d8503d62a62dbc4127a2b1"}, ] importlib-metadata = [ - {file = "importlib_metadata-1.6.0-py2.py3-none-any.whl", hash = "sha256:2a688cbaa90e0cc587f1df48bdc97a6eadccdcd9c35fb3f976a09e3b5016d90f"}, - {file = "importlib_metadata-1.6.0.tar.gz", hash = "sha256:34513a8a0c4962bc66d35b359558fd8a5e10cd472d37aec5f66858addef32c1e"}, + {file = "importlib_metadata-1.7.0-py2.py3-none-any.whl", hash = "sha256:dc15b2969b4ce36305c51eebe62d418ac7791e9a157911d58bfb1f9ccd8e2070"}, + {file = "importlib_metadata-1.7.0.tar.gz", hash = "sha256:90bb658cdbbf6d1735b6341ce708fc7024a3e14e99ffdc5783edea9f9b077f83"}, ] importlib-resources = [ - {file = "importlib_resources-1.5.0-py2.py3-none-any.whl", hash = "sha256:85dc0b9b325ff78c8bef2e4ff42616094e16b98ebd5e3b50fe7e2f0bbcdcde49"}, - {file = "importlib_resources-1.5.0.tar.gz", hash = "sha256:6f87df66833e1942667108628ec48900e02a4ab4ad850e25fbf07cb17cf734ca"}, + {file = "importlib_resources-3.0.0-py2.py3-none-any.whl", hash = "sha256:d028f66b66c0d5732dae86ba4276999855e162a749c92620a38c1d779ed138a7"}, + {file = "importlib_resources-3.0.0.tar.gz", hash = "sha256:19f745a6eca188b490b1428c8d1d4a0d2368759f32370ea8fb89cad2ab1106c3"}, ] jinja2 = [ {file = "Jinja2-2.11.2-py2.py3-none-any.whl", hash = "sha256:f0a4641d3cf955324a89c04f3d94663aa4d638abe8f733ecd3582848e1c37035"}, {file = "Jinja2-2.11.2.tar.gz", hash = "sha256:89aab215427ef59c34ad58735269eb58b1a5808103067f7bb9d5836c651b3bb0"}, ] livereload = [ - {file = "livereload-2.6.1-py2.py3-none-any.whl", hash = "sha256:78d55f2c268a8823ba499305dcac64e28ddeb9a92571e12d543cd304faf5817b"}, - {file = "livereload-2.6.1.tar.gz", hash = "sha256:89254f78d7529d7ea0a3417d224c34287ebfe266b05e67e51facaf82c27f0f66"}, + {file = "livereload-2.6.2.tar.gz", hash = "sha256:d1eddcb5c5eb8d2ca1fa1f750e580da624c0f7fcb734aa5780dc81b7dcbd89be"}, ] markupsafe = [ {file = "MarkupSafe-1.1.1-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161"}, @@ -903,40 +1251,56 @@ markupsafe = [ {file = "MarkupSafe-1.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be"}, {file = "MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b"}, ] +mccabe = [ + {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, + {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, +] more-itertools = [ - {file = "more-itertools-8.2.0.tar.gz", hash = "sha256:b1ddb932186d8a6ac451e1d95844b382f55e12686d51ca0c68b6f61f2ab7a507"}, - {file = "more_itertools-8.2.0-py3-none-any.whl", hash = "sha256:5dd8bcf33e5f9513ffa06d5ad33d78f31e1931ac9a18f33d37e77a180d393a7c"}, + {file = "more-itertools-8.4.0.tar.gz", hash = "sha256:68c70cc7167bdf5c7c9d8f6954a7837089c6a36bf565383919bb595efb8a17e5"}, + {file = "more_itertools-8.4.0-py3-none-any.whl", hash = "sha256:b78134b2063dd214000685165d81c154522c3ee0a1c0d4d113c80361c234c5a2"}, ] mypy = [ - {file = "mypy-0.770-cp35-cp35m-macosx_10_6_x86_64.whl", hash = "sha256:a34b577cdf6313bf24755f7a0e3f3c326d5c1f4fe7422d1d06498eb25ad0c600"}, - {file = "mypy-0.770-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:86c857510a9b7c3104cf4cde1568f4921762c8f9842e987bc03ed4f160925754"}, - {file = "mypy-0.770-cp35-cp35m-win_amd64.whl", hash = "sha256:a8ffcd53cb5dfc131850851cc09f1c44689c2812d0beb954d8138d4f5fc17f65"}, - {file = "mypy-0.770-cp36-cp36m-macosx_10_6_x86_64.whl", hash = "sha256:7687f6455ec3ed7649d1ae574136835a4272b65b3ddcf01ab8704ac65616c5ce"}, - {file = "mypy-0.770-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:3beff56b453b6ef94ecb2996bea101a08f1f8a9771d3cbf4988a61e4d9973761"}, - {file = "mypy-0.770-cp36-cp36m-win_amd64.whl", hash = "sha256:15b948e1302682e3682f11f50208b726a246ab4e6c1b39f9264a8796bb416aa2"}, - {file = "mypy-0.770-cp37-cp37m-macosx_10_6_x86_64.whl", hash = "sha256:b90928f2d9eb2f33162405f32dde9f6dcead63a0971ca8a1b50eb4ca3e35ceb8"}, - {file = "mypy-0.770-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:c56ffe22faa2e51054c5f7a3bc70a370939c2ed4de308c690e7949230c995913"}, - {file = "mypy-0.770-cp37-cp37m-win_amd64.whl", hash = "sha256:8dfb69fbf9f3aeed18afffb15e319ca7f8da9642336348ddd6cab2713ddcf8f9"}, - {file = "mypy-0.770-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:219a3116ecd015f8dca7b5d2c366c973509dfb9a8fc97ef044a36e3da66144a1"}, - {file = "mypy-0.770-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7ec45a70d40ede1ec7ad7f95b3c94c9cf4c186a32f6bacb1795b60abd2f9ef27"}, - {file = "mypy-0.770-cp38-cp38-win_amd64.whl", hash = "sha256:f91c7ae919bbc3f96cd5e5b2e786b2b108343d1d7972ea130f7de27fdd547cf3"}, - {file = "mypy-0.770-py3-none-any.whl", hash = "sha256:3b1fc683fb204c6b4403a1ef23f0b1fac8e4477091585e0c8c54cbdf7d7bb164"}, - {file = "mypy-0.770.tar.gz", hash = "sha256:8a627507ef9b307b46a1fea9513d5c98680ba09591253082b4c48697ba05a4ae"}, + {file = "mypy-0.782-cp35-cp35m-macosx_10_6_x86_64.whl", hash = "sha256:2c6cde8aa3426c1682d35190b59b71f661237d74b053822ea3d748e2c9578a7c"}, + {file = "mypy-0.782-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9c7a9a7ceb2871ba4bac1cf7217a7dd9ccd44c27c2950edbc6dc08530f32ad4e"}, + {file = "mypy-0.782-cp35-cp35m-win_amd64.whl", hash = "sha256:c05b9e4fb1d8a41d41dec8786c94f3b95d3c5f528298d769eb8e73d293abc48d"}, + {file = "mypy-0.782-cp36-cp36m-macosx_10_6_x86_64.whl", hash = "sha256:6731603dfe0ce4352c555c6284c6db0dc935b685e9ce2e4cf220abe1e14386fd"}, + {file = "mypy-0.782-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:f05644db6779387ccdb468cc47a44b4356fc2ffa9287135d05b70a98dc83b89a"}, + {file = "mypy-0.782-cp36-cp36m-win_amd64.whl", hash = "sha256:b7fbfabdbcc78c4f6fc4712544b9b0d6bf171069c6e0e3cb82440dd10ced3406"}, + {file = "mypy-0.782-cp37-cp37m-macosx_10_6_x86_64.whl", hash = "sha256:3fdda71c067d3ddfb21da4b80e2686b71e9e5c72cca65fa216d207a358827f86"}, + {file = "mypy-0.782-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:d7df6eddb6054d21ca4d3c6249cae5578cb4602951fd2b6ee2f5510ffb098707"}, + {file = "mypy-0.782-cp37-cp37m-win_amd64.whl", hash = "sha256:a4a2cbcfc4cbf45cd126f531dedda8485671545b43107ded25ce952aac6fb308"}, + {file = "mypy-0.782-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6bb93479caa6619d21d6e7160c552c1193f6952f0668cdda2f851156e85186fc"}, + {file = "mypy-0.782-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:81c7908b94239c4010e16642c9102bfc958ab14e36048fa77d0be3289dda76ea"}, + {file = "mypy-0.782-cp38-cp38-win_amd64.whl", hash = "sha256:5dd13ff1f2a97f94540fd37a49e5d255950ebcdf446fb597463a40d0df3fac8b"}, + {file = "mypy-0.782-py3-none-any.whl", hash = "sha256:e0b61738ab504e656d1fe4ff0c0601387a5489ca122d55390ade31f9ca0e252d"}, + {file = "mypy-0.782.tar.gz", hash = "sha256:eff7d4a85e9eea55afa34888dfeaccde99e7520b51f867ac28a48492c0b1130c"}, ] mypy-extensions = [ {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, ] nodeenv = [ - {file = "nodeenv-1.3.5-py2.py3-none-any.whl", hash = "sha256:5b2438f2e42af54ca968dd1b374d14a1194848955187b0e5e4be1f73813a5212"}, + {file = "nodeenv-1.4.0-py2.py3-none-any.whl", hash = "sha256:4b0b77afa3ba9b54f4b6396e60b0c83f59eaeb2d63dc3cc7a70f7f4af96c82bc"}, ] packaging = [ - {file = "packaging-20.3-py2.py3-none-any.whl", hash = "sha256:82f77b9bee21c1bafbf35a84905d604d5d1223801d639cf3ed140bd651c08752"}, - {file = "packaging-20.3.tar.gz", hash = "sha256:3c292b474fda1671ec57d46d739d072bfd495a4f51ad01a055121d81e952b7a3"}, + {file = "packaging-20.4-py2.py3-none-any.whl", hash = "sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181"}, + {file = "packaging-20.4.tar.gz", hash = "sha256:4357f74f47b9c12db93624a82154e9b120fa8293699949152b22065d556079f8"}, +] +pathspec = [ + {file = "pathspec-0.8.0-py2.py3-none-any.whl", hash = "sha256:7d91249d21749788d07a2d0f94147accd8f845507400749ea19c1ec9054a12b0"}, + {file = "pathspec-0.8.0.tar.gz", hash = "sha256:da45173eb3a6f2a5a487efba21f050af2b41948be6ab52b6a1e3ff22bb8b7061"}, ] pathtools = [ {file = "pathtools-0.1.2.tar.gz", hash = "sha256:7c35c5421a39bb82e58018febd90e3b6e5db34c5443aaaf742b3f33d4655f1c0"}, ] +pbr = [ + {file = "pbr-5.4.5-py2.py3-none-any.whl", hash = "sha256:579170e23f8e0c2f24b0de612f71f648eccb79fb1322c814ae6b3c07b5ba23e8"}, + {file = "pbr-5.4.5.tar.gz", hash = "sha256:07f558fece33b05caf857474a366dfcc00562bca13dd8b47b2b3e22d9f9bf55c"}, +] +pep8-naming = [ + {file = "pep8-naming-0.11.1.tar.gz", hash = "sha256:a1dd47dd243adfe8a83616e27cf03164960b507530f155db94e10b36a6cd6724"}, + {file = "pep8_naming-0.11.1-py2.py3-none-any.whl", hash = "sha256:f43bfe3eea7e0d73e8b5d07d6407ab47f2476ccaeff6937c84275cd30b016738"}, +] pluggy = [ {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, @@ -945,12 +1309,28 @@ port-for = [ {file = "port-for-0.3.1.tar.gz", hash = "sha256:b16a84bb29c2954db44c29be38b17c659c9c27e33918dec16b90d375cc596f1c"}, ] pre-commit = [ - {file = "pre_commit-2.4.0-py2.py3-none-any.whl", hash = "sha256:5559e09afcac7808933951ffaf4ff9aac524f31efbc3f24d021540b6c579813c"}, - {file = "pre_commit-2.4.0.tar.gz", hash = "sha256:703e2e34cbe0eedb0d319eff9f7b83e2022bb5a3ab5289a6a8841441076514d0"}, + {file = "pre_commit-2.6.0-py2.py3-none-any.whl", hash = "sha256:e8b1315c585052e729ab7e99dcca5698266bedce9067d21dc909c23e3ceed626"}, + {file = "pre_commit-2.6.0.tar.gz", hash = "sha256:1657663fdd63a321a4a739915d7d03baedd555b25054449090f97bb0cb30a915"}, +] +pre-commit-hooks = [ + {file = "pre_commit_hooks-3.1.0-py2.py3-none-any.whl", hash = "sha256:32e07d6bd511e26ac3d7b7aafdd2e49d0f1efdb7fc772156386004b9e6f66dbe"}, + {file = "pre_commit_hooks-3.1.0.tar.gz", hash = "sha256:78642bdda65d524a6c91faaf4b322f18fc561e4377e8651d8502c6073e4a19d9"}, ] py = [ - {file = "py-1.8.1-py2.py3-none-any.whl", hash = "sha256:c20fdd83a5dbc0af9efd622bee9a5564e278f6380fffcacc43ba6f43db2813b0"}, - {file = "py-1.8.1.tar.gz", hash = "sha256:5e27081401262157467ad6e7f851b7aa402c5852dbcb3dae06768434de5752aa"}, + {file = "py-1.9.0-py2.py3-none-any.whl", hash = "sha256:366389d1db726cd2fcfc79732e75410e5fe4d31db13692115529d34069a043c2"}, + {file = "py-1.9.0.tar.gz", hash = "sha256:9ca6883ce56b4e8da7e79ac18787889fa5206c79dcc67fb065376cd2fe03f342"}, +] +pycodestyle = [ + {file = "pycodestyle-2.6.0-py2.py3-none-any.whl", hash = "sha256:2295e7b2f6b5bd100585ebcb1f616591b652db8a741695b3d8f5d28bdc934367"}, + {file = "pycodestyle-2.6.0.tar.gz", hash = "sha256:c58a7d2815e0e8d7972bf1803331fb0152f867bd89adf8a01dfd55085434192e"}, +] +pydocstyle = [ + {file = "pydocstyle-5.0.2-py3-none-any.whl", hash = "sha256:da7831660b7355307b32778c4a0dbfb137d89254ef31a2b2978f50fc0b4d7586"}, + {file = "pydocstyle-5.0.2.tar.gz", hash = "sha256:f4f5d210610c2d153fae39093d44224c17429e2ad7da12a8b419aba5c2f614b5"}, +] +pyflakes = [ + {file = "pyflakes-2.2.0-py2.py3-none-any.whl", hash = "sha256:0d94e0e05a19e57a99444b6ddcf9a6eb2e5c68d3ca1e98e90707af8152c90a92"}, + {file = "pyflakes-2.2.0.tar.gz", hash = "sha256:35b2d75ee967ea93b55750aa9edbbf72813e06a66ba54438df2cfac9e3c27fc8"}, ] pygments = [ {file = "Pygments-2.6.1-py3-none-any.whl", hash = "sha256:ff7a40b4860b727ab48fad6360eb351cc1b33cbf9b15a0f689ca5353e9463324"}, @@ -961,12 +1341,8 @@ pyparsing = [ {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, ] pytest = [ - {file = "pytest-5.4.2-py3-none-any.whl", hash = "sha256:95c710d0a72d91c13fae35dce195633c929c3792f54125919847fdcdf7caa0d3"}, - {file = "pytest-5.4.2.tar.gz", hash = "sha256:eb2b5e935f6a019317e455b6da83dd8650ac9ffd2ee73a7b657a30873d67a698"}, -] -pytest-cov = [ - {file = "pytest-cov-2.8.1.tar.gz", hash = "sha256:cc6742d8bac45070217169f5f72ceee1e0e55b0221f54bcf24845972d3a47f2b"}, - {file = "pytest_cov-2.8.1-py2.py3-none-any.whl", hash = "sha256:cdbdef4f870408ebdbfeb44e63e07eb18bb4619fae852f6e760645fa36172626"}, + {file = "pytest-5.4.3-py3-none-any.whl", hash = "sha256:5c0db86b698e8f170ba4582a492248919255fcd4c79b1ee64ace34301fb589a1"}, + {file = "pytest-5.4.3.tar.gz", hash = "sha256:7979331bfcba207414f5e1263b5a0f8f521d0f457318836a7355531ed1a4c7d8"}, ] pytz = [ {file = "pytz-2020.1-py2.py3-none-any.whl", hash = "sha256:a494d53b6d39c3c6e44c3bec237336e14305e4f29bbf800b599253057fbb79ed"}, @@ -985,25 +1361,84 @@ pyyaml = [ {file = "PyYAML-5.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee"}, {file = "PyYAML-5.3.1.tar.gz", hash = "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d"}, ] +regex = [ + {file = "regex-2020.6.8-cp27-cp27m-win32.whl", hash = "sha256:fbff901c54c22425a5b809b914a3bfaf4b9570eee0e5ce8186ac71eb2025191c"}, + {file = "regex-2020.6.8-cp27-cp27m-win_amd64.whl", hash = "sha256:112e34adf95e45158c597feea65d06a8124898bdeac975c9087fe71b572bd938"}, + {file = "regex-2020.6.8-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:92d8a043a4241a710c1cf7593f5577fbb832cf6c3a00ff3fc1ff2052aff5dd89"}, + {file = "regex-2020.6.8-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:bae83f2a56ab30d5353b47f9b2a33e4aac4de9401fb582b55c42b132a8ac3868"}, + {file = "regex-2020.6.8-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:b2ba0f78b3ef375114856cbdaa30559914d081c416b431f2437f83ce4f8b7f2f"}, + {file = "regex-2020.6.8-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:95fa7726d073c87141f7bbfb04c284901f8328e2d430eeb71b8ffdd5742a5ded"}, + {file = "regex-2020.6.8-cp36-cp36m-win32.whl", hash = "sha256:e3cdc9423808f7e1bb9c2e0bdb1c9dc37b0607b30d646ff6faf0d4e41ee8fee3"}, + {file = "regex-2020.6.8-cp36-cp36m-win_amd64.whl", hash = "sha256:c78e66a922de1c95a208e4ec02e2e5cf0bb83a36ceececc10a72841e53fbf2bd"}, + {file = "regex-2020.6.8-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:08997a37b221a3e27d68ffb601e45abfb0093d39ee770e4257bd2f5115e8cb0a"}, + {file = "regex-2020.6.8-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:2f6f211633ee8d3f7706953e9d3edc7ce63a1d6aad0be5dcee1ece127eea13ae"}, + {file = "regex-2020.6.8-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:55b4c25cbb3b29f8d5e63aeed27b49fa0f8476b0d4e1b3171d85db891938cc3a"}, + {file = "regex-2020.6.8-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:89cda1a5d3e33ec9e231ece7307afc101b5217523d55ef4dc7fb2abd6de71ba3"}, + {file = "regex-2020.6.8-cp37-cp37m-win32.whl", hash = "sha256:690f858d9a94d903cf5cada62ce069b5d93b313d7d05456dbcd99420856562d9"}, + {file = "regex-2020.6.8-cp37-cp37m-win_amd64.whl", hash = "sha256:1700419d8a18c26ff396b3b06ace315b5f2a6e780dad387e4c48717a12a22c29"}, + {file = "regex-2020.6.8-cp38-cp38-manylinux1_i686.whl", hash = "sha256:654cb773b2792e50151f0e22be0f2b6e1c3a04c5328ff1d9d59c0398d37ef610"}, + {file = "regex-2020.6.8-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:52e1b4bef02f4040b2fd547357a170fc1146e60ab310cdbdd098db86e929b387"}, + {file = "regex-2020.6.8-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:cf59bbf282b627130f5ba68b7fa3abdb96372b24b66bdf72a4920e8153fc7910"}, + {file = "regex-2020.6.8-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:5aaa5928b039ae440d775acea11d01e42ff26e1561c0ffcd3d805750973c6baf"}, + {file = "regex-2020.6.8-cp38-cp38-win32.whl", hash = "sha256:97712e0d0af05febd8ab63d2ef0ab2d0cd9deddf4476f7aa153f76feef4b2754"}, + {file = "regex-2020.6.8-cp38-cp38-win_amd64.whl", hash = "sha256:6ad8663c17db4c5ef438141f99e291c4d4edfeaacc0ce28b5bba2b0bf273d9b5"}, + {file = "regex-2020.6.8.tar.gz", hash = "sha256:e9b64e609d37438f7d6e68c2546d2cb8062f3adb27e6336bc129b51be20773ac"}, +] +reorder-python-imports = [ + {file = "reorder_python_imports-2.3.1-py2.py3-none-any.whl", hash = "sha256:c0a9d60d84db9e6425d9379296d296cce78699967a6012972b8f4f074e22c3f5"}, + {file = "reorder_python_imports-2.3.1.tar.gz", hash = "sha256:e2a4712866aee291c1c019aa67f95a3be2fffa5ebd801cab5d98ab2b66cfd512"}, +] requests = [ - {file = "requests-2.23.0-py2.py3-none-any.whl", hash = "sha256:43999036bfa82904b6af1d99e4882b560e5e2c68e5c4b0aa03b655f3d7d73fee"}, - {file = "requests-2.23.0.tar.gz", hash = "sha256:b3f43d496c6daba4493e7c431722aeb7dbc6288f52a6e04e7b6023b0247817e6"}, + {file = "requests-2.24.0-py2.py3-none-any.whl", hash = "sha256:fe75cc94a9443b9246fc7049224f75604b113c36acb93f87b80ed42c44cbb898"}, + {file = "requests-2.24.0.tar.gz", hash = "sha256:b3559a131db72c33ee969480840fff4bb6dd111de7dd27c8ee1f820f4f00231b"}, +] +restructuredtext-lint = [ + {file = "restructuredtext_lint-1.3.1.tar.gz", hash = "sha256:470e53b64817211a42805c3a104d2216f6f5834b22fe7adb637d1de4d6501fb8"}, +] +"ruamel.yaml" = [ + {file = "ruamel.yaml-0.16.10-py2.py3-none-any.whl", hash = "sha256:0962fd7999e064c4865f96fb1e23079075f4a2a14849bcdc5cdba53a24f9759b"}, + {file = "ruamel.yaml-0.16.10.tar.gz", hash = "sha256:099c644a778bf72ffa00524f78dd0b6476bca94a1da344130f4bf3381ce5b954"}, +] +"ruamel.yaml.clib" = [ + {file = "ruamel.yaml.clib-0.2.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:9c6d040d0396c28d3eaaa6cb20152cb3b2f15adf35a0304f4f40a3cf9f1d2448"}, + {file = "ruamel.yaml.clib-0.2.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:4d55386129291b96483edcb93b381470f7cd69f97585829b048a3d758d31210a"}, + {file = "ruamel.yaml.clib-0.2.0-cp27-cp27m-win32.whl", hash = "sha256:8073c8b92b06b572e4057b583c3d01674ceaf32167801fe545a087d7a1e8bf52"}, + {file = "ruamel.yaml.clib-0.2.0-cp27-cp27m-win_amd64.whl", hash = "sha256:615b0396a7fad02d1f9a0dcf9f01202bf9caefee6265198f252c865f4227fcc6"}, + {file = "ruamel.yaml.clib-0.2.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:a0ff786d2a7dbe55f9544b3f6ebbcc495d7e730df92a08434604f6f470b899c5"}, + {file = "ruamel.yaml.clib-0.2.0-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:ea4362548ee0cbc266949d8a441238d9ad3600ca9910c3fe4e82ee3a50706973"}, + {file = "ruamel.yaml.clib-0.2.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:77556a7aa190be9a2bd83b7ee075d3df5f3c5016d395613671487e79b082d784"}, + {file = "ruamel.yaml.clib-0.2.0-cp35-cp35m-win32.whl", hash = "sha256:392b7c371312abf27fb549ec2d5e0092f7ef6e6c9f767bfb13e83cb903aca0fd"}, + {file = "ruamel.yaml.clib-0.2.0-cp35-cp35m-win_amd64.whl", hash = "sha256:ed5b3698a2bb241b7f5cbbe277eaa7fe48b07a58784fba4f75224fd066d253ad"}, + {file = "ruamel.yaml.clib-0.2.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:7aee724e1ff424757b5bd8f6c5bbdb033a570b2b4683b17ace4dbe61a99a657b"}, + {file = "ruamel.yaml.clib-0.2.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:d0d3ac228c9bbab08134b4004d748cf9f8743504875b3603b3afbb97e3472947"}, + {file = "ruamel.yaml.clib-0.2.0-cp36-cp36m-win32.whl", hash = "sha256:f9dcc1ae73f36e8059589b601e8e4776b9976effd76c21ad6a855a74318efd6e"}, + {file = "ruamel.yaml.clib-0.2.0-cp36-cp36m-win_amd64.whl", hash = "sha256:1e77424825caba5553bbade750cec2277ef130647d685c2b38f68bc03453bac6"}, + {file = "ruamel.yaml.clib-0.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d10e9dd744cf85c219bf747c75194b624cc7a94f0c80ead624b06bfa9f61d3bc"}, + {file = "ruamel.yaml.clib-0.2.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:550168c02d8de52ee58c3d8a8193d5a8a9491a5e7b2462d27ac5bf63717574c9"}, + {file = "ruamel.yaml.clib-0.2.0-cp37-cp37m-win32.whl", hash = "sha256:57933a6986a3036257ad7bf283529e7c19c2810ff24c86f4a0cfeb49d2099919"}, + {file = "ruamel.yaml.clib-0.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:b1b7fcee6aedcdc7e62c3a73f238b3d080c7ba6650cd808bce8d7761ec484070"}, + {file = "ruamel.yaml.clib-0.2.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:be018933c2f4ee7de55e7bd7d0d801b3dfb09d21dad0cce8a97995fd3e44be30"}, + {file = "ruamel.yaml.clib-0.2.0.tar.gz", hash = "sha256:b66832ea8077d9b3f6e311c4a53d06273db5dc2db6e8a908550f3c14d67e718c"}, ] safety = [ {file = "safety-1.9.0-py2.py3-none-any.whl", hash = "sha256:86c1c4a031fe35bd624fce143fbe642a0234d29f7cbf7a9aa269f244a955b087"}, {file = "safety-1.9.0.tar.gz", hash = "sha256:23bf20690d4400edc795836b0c983c2b4cbbb922233108ff925b7dd7750f00c9"}, ] six = [ - {file = "six-1.14.0-py2.py3-none-any.whl", hash = "sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c"}, - {file = "six-1.14.0.tar.gz", hash = "sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a"}, + {file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"}, + {file = "six-1.15.0.tar.gz", hash = "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259"}, +] +smmap = [ + {file = "smmap-3.0.4-py2.py3-none-any.whl", hash = "sha256:54c44c197c819d5ef1991799a7e30b662d1e520f2ac75c9efbeb54a742214cf4"}, + {file = "smmap-3.0.4.tar.gz", hash = "sha256:9c98bbd1f9786d22f14b3d4126894d56befb835ec90cef151af566c7e19b5d24"}, ] snowballstemmer = [ {file = "snowballstemmer-2.0.0-py2.py3-none-any.whl", hash = "sha256:209f257d7533fdb3cb73bdbd24f436239ca3b2fa67d56f6ff88e86be08cc5ef0"}, {file = "snowballstemmer-2.0.0.tar.gz", hash = "sha256:df3bac3df4c2c01363f3dd2cfa78cce2840a79b9f1c2d2de9ce8d31683992f52"}, ] sphinx = [ - {file = "Sphinx-3.0.3-py3-none-any.whl", hash = "sha256:f5505d74cf9592f3b997380f9bdb2d2d0320ed74dd69691e3ee0644b956b8d83"}, - {file = "Sphinx-3.0.3.tar.gz", hash = "sha256:62edfd92d955b868d6c124c0942eba966d54b5f3dcb4ded39e65f74abac3f572"}, + {file = "Sphinx-3.1.2-py3-none-any.whl", hash = "sha256:97dbf2e31fc5684bb805104b8ad34434ed70e6c588f6896991b2fdfd2bef8c00"}, + {file = "Sphinx-3.1.2.tar.gz", hash = "sha256:b9daeb9b39aa1ffefc2809b43604109825300300b987a24f45976c001ba1a8fd"}, ] sphinx-autobuild = [ {file = "sphinx-autobuild-0.7.1.tar.gz", hash = "sha256:66388f81884666e3821edbe05dd53a0cfb68093873d17320d0610de8db28c74e"}, @@ -1033,6 +1468,10 @@ sphinxcontrib-serializinghtml = [ {file = "sphinxcontrib-serializinghtml-1.1.4.tar.gz", hash = "sha256:eaa0eccc86e982a9b939b2b82d12cc5d013385ba5eadcc7e4fed23f4405f77bc"}, {file = "sphinxcontrib_serializinghtml-1.1.4-py2.py3-none-any.whl", hash = "sha256:f242a81d423f59617a8e5cf16f5d4d74e28ee9a66f9e5b637a18082991db5a9a"}, ] +stevedore = [ + {file = "stevedore-2.0.0-py3-none-any.whl", hash = "sha256:471c920412265cc809540ae6fb01f3f02aba89c79bbc7091372f4745a50f9691"}, + {file = "stevedore-2.0.0.tar.gz", hash = "sha256:001e90cd704be6470d46cc9076434e2d0d566c1379187e7013eb296d3a6032d9"}, +] toml = [ {file = "toml-0.10.1-py2.py3-none-any.whl", hash = "sha256:bda89d5935c2eac546d648028b9901107a595863cb36bae0c73ac804a9b4ce88"}, {file = "toml-0.10.1.tar.gz", hash = "sha256:926b612be1e5ce0634a2ca03470f95169cf16f939018233a670519cb4ac58b0f"}, @@ -1072,8 +1511,8 @@ typed-ast = [ {file = "typed_ast-1.4.1.tar.gz", hash = "sha256:8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b"}, ] typeguard = [ - {file = "typeguard-2.7.1-py3-none-any.whl", hash = "sha256:1d3710251d3d3d6c64e0c49f45edec2e88ddc386a51e89c3ec0703efeb8b3b81"}, - {file = "typeguard-2.7.1.tar.gz", hash = "sha256:2d545c71e9439c21bcd7c28f5f55b3606e6106f7031ab58375656a1aed483ef2"}, + {file = "typeguard-2.9.1-py3-none-any.whl", hash = "sha256:e258567e62d28f9a51d4f7c71f491154e9ef0889286ad2f37e3e22e4f668b21b"}, + {file = "typeguard-2.9.1.tar.gz", hash = "sha256:529ef3d88189cc457f4340388028412f71be8091c2c943465146d4170fb67288"}, ] typing-extensions = [ {file = "typing_extensions-3.7.4.2-py2-none-any.whl", hash = "sha256:f8d2bd89d25bc39dabe7d23df520442fa1d8969b82544370e03d88b5a591c392"}, @@ -1085,19 +1524,19 @@ urllib3 = [ {file = "urllib3-1.25.9.tar.gz", hash = "sha256:3018294ebefce6572a474f0604c2021e33b3fd8006ecd11d62107a5d2a963527"}, ] virtualenv = [ - {file = "virtualenv-20.0.20-py2.py3-none-any.whl", hash = "sha256:b4c14d4d73a0c23db267095383c4276ef60e161f94fde0427f2f21a0132dde74"}, - {file = "virtualenv-20.0.20.tar.gz", hash = "sha256:fd0e54dec8ac96c1c7c87daba85f0a59a7c37fe38748e154306ca21c73244637"}, + {file = "virtualenv-20.0.26-py2.py3-none-any.whl", hash = "sha256:c11a475400e98450403c0364eb3a2d25d42f71cf1493da64390487b666de4324"}, + {file = "virtualenv-20.0.26.tar.gz", hash = "sha256:e10cc66f40cbda459720dfe1d334c4dc15add0d80f09108224f171006a97a172"}, ] watchdog = [ - {file = "watchdog-0.10.2.tar.gz", hash = "sha256:c560efb643faed5ef28784b2245cf8874f939569717a4a12826a173ac644456b"}, + {file = "watchdog-0.10.3.tar.gz", hash = "sha256:4214e1379d128b0588021880ccaf40317ee156d4603ac388b9adcf29165e0c04"}, ] wcwidth = [ - {file = "wcwidth-0.1.9-py2.py3-none-any.whl", hash = "sha256:cafe2186b3c009a04067022ce1dcd79cb38d8d65ee4f4791b8888d6599d1bbe1"}, - {file = "wcwidth-0.1.9.tar.gz", hash = "sha256:ee73862862a156bf77ff92b09034fc4825dd3af9cf81bc5b360668d425f3c5f1"}, + {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"}, + {file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"}, ] xdoctest = [ - {file = "xdoctest-0.12.0-py2.py3-none-any.whl", hash = "sha256:82424d2cc4b6d6b96b7b7134c81e97a4594c536547c1954533128a6a26cf1cb2"}, - {file = "xdoctest-0.12.0.tar.gz", hash = "sha256:2d985d8d78d4444079d3b072965327ab06a5e6dcb4882f3561d7596eb4da6b13"}, + {file = "xdoctest-0.13.0-py2.py3-none-any.whl", hash = "sha256:de861fd5230a46bd26c054b4981169dd963f813768cb62b62e104e4d2644ac94"}, + {file = "xdoctest-0.13.0.tar.gz", hash = "sha256:4f113a430076561a9d7f31af65b5d5acda62ee06b05cb6894264cb9efb8196ac"}, ] zipp = [ {file = "zipp-3.1.0-py3-none-any.whl", hash = "sha256:aa36550ff0c0b7ef7fa639055d797116ee891440eac1a56f378e2d3179e0320b"}, diff --git a/pyproject.toml b/pyproject.toml index 216f1603..ab265637 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,6 +8,11 @@ readme = "README.rst" homepage = "https://github.com/cjolowicz/nox-poetry" repository = "https://github.com/cjolowicz/nox-poetry" documentation = "https://nox-poetry.readthedocs.io" +classifiers = [ + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", +] [tool.poetry.urls] Changelog = "https://github.com/cjolowicz/nox-poetry/releases" @@ -17,16 +22,25 @@ python = "^3.6.1" click = "^7.0" [tool.poetry.dev-dependencies] -pytest = "^5.4.2" -coverage = {extras = ["toml"], version = "^5.1"} -pytest-cov = "^2.8.1" +pytest = "^5.4.3" +coverage = {extras = ["toml"], version = "^5.2"} safety = "^1.9.0" -mypy = "^0.770" -typeguard = "^2.7.1" -xdoctest = "^0.12.0" -sphinx = "^3.0.3" +mypy = "^0.782" +typeguard = "^2.9.1" +xdoctest = "^0.13.0" +sphinx = "^3.1.2" sphinx-autobuild = "^0.7.1" -pre-commit = "^2.4.0" +pre-commit = "^2.6.0" +flake8 = "^3.8.3" +black = "^19.10b0" +flake8-bandit = "^2.1.2" +flake8-bugbear = "^20.1.4" +flake8-docstrings = "^1.5.0" +flake8-rst-docstrings = "^0.0.13" +pep8-naming = "^0.11.1" +darglint = "^1.5.1" +reorder-python-imports = "^2.3.1" +pre-commit-hooks = "^3.1.0" [tool.poetry.scripts] nox-poetry = "nox_poetry.__main__:main" From 2f7b780fff82f33d71279057947fe2244815321a Mon Sep 17 00:00:00 2001 From: Claudio Jolowicz Date: Wed, 20 May 2020 17:51:37 +0200 Subject: [PATCH 02/17] Remove command-line interface --- docs/reference.rst | 4 ++-- pyproject.toml | 3 --- src/nox_poetry/__main__.py | 12 ------------ tests/test_main.py | 17 ----------------- 4 files changed, 2 insertions(+), 34 deletions(-) delete mode 100644 src/nox_poetry/__main__.py delete mode 100644 tests/test_main.py diff --git a/docs/reference.rst b/docs/reference.rst index 11c4d362..794571b7 100644 --- a/docs/reference.rst +++ b/docs/reference.rst @@ -6,8 +6,8 @@ Reference :backlinks: none -nox_poetry.__main__ +nox_poetry.__init__ ------------------- -.. automodule:: nox_poetry.__main__ +.. automodule:: nox_poetry.__init__ :members: diff --git a/pyproject.toml b/pyproject.toml index ab265637..3b24ee8f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -42,9 +42,6 @@ darglint = "^1.5.1" reorder-python-imports = "^2.3.1" pre-commit-hooks = "^3.1.0" -[tool.poetry.scripts] -nox-poetry = "nox_poetry.__main__:main" - [tool.coverage.paths] source = ["src", "*/site-packages"] diff --git a/src/nox_poetry/__main__.py b/src/nox_poetry/__main__.py deleted file mode 100644 index 8c9ab71b..00000000 --- a/src/nox_poetry/__main__.py +++ /dev/null @@ -1,12 +0,0 @@ -"""Command-line interface.""" -import click - - -@click.command() -@click.version_option() -def main() -> None: - """nox-poetry.""" - - -if __name__ == "__main__": - main(prog_name="nox-poetry") # pragma: no cover diff --git a/tests/test_main.py b/tests/test_main.py deleted file mode 100644 index f56f2be2..00000000 --- a/tests/test_main.py +++ /dev/null @@ -1,17 +0,0 @@ -"""Test cases for the __main__ module.""" -import pytest -from click.testing import CliRunner - -from nox_poetry import __main__ - - -@pytest.fixture -def runner() -> CliRunner: - """Fixture for invoking command-line interfaces.""" - return CliRunner() - - -def test_main_succeeds(runner: CliRunner) -> None: - """It exits with a status code of zero.""" - result = runner.invoke(__main__.main) - assert result.exit_code == 0 From aeeda11b4ef075090af0c14c7b34f97200077a18 Mon Sep 17 00:00:00 2001 From: Claudio Jolowicz Date: Wed, 20 May 2020 17:54:02 +0200 Subject: [PATCH 03/17] Remove click from dependencies --- pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 3b24ee8f..b73391ec 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,7 +19,6 @@ Changelog = "https://github.com/cjolowicz/nox-poetry/releases" [tool.poetry.dependencies] python = "^3.6.1" -click = "^7.0" [tool.poetry.dev-dependencies] pytest = "^5.4.3" From 7acb798beca58c2e646c094f3b5c220272d00de9 Mon Sep 17 00:00:00 2001 From: Claudio Jolowicz Date: Sat, 1 Aug 2020 23:41:32 +0200 Subject: [PATCH 04/17] Update poetry.lock --- poetry.lock | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/poetry.lock b/poetry.lock index efd52014..7f724d18 100644 --- a/poetry.lock +++ b/poetry.lock @@ -135,7 +135,7 @@ python-versions = "*" version = "3.0.4" [[package]] -category = "main" +category = "dev" description = "Composable command line interface toolkit" name = "click" optional = false @@ -145,7 +145,7 @@ version = "7.1.2" [[package]] category = "dev" description = "Cross-platform colored terminal text." -marker = "platform_system == \"Windows\" or sys_platform == \"win32\"" +marker = "sys_platform == \"win32\" or platform_system == \"Windows\"" name = "colorama" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" @@ -1039,7 +1039,8 @@ docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] testing = ["jaraco.itertools", "func-timeout"] [metadata] -content-hash = "cfc67c767dd4aa60a61e0ec3fdd5d28ff8d94114b99bcc9f39ced91ba0ca32de" +content-hash = "0d41a1a996c60640d9435378d254d27f8b88b7769ceebabde9381e8dbd638d77" +lock-version = "1.0" python-versions = "^3.6.1" [metadata.files] @@ -1244,11 +1245,6 @@ markupsafe = [ {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6"}, {file = "MarkupSafe-1.1.1-cp37-cp37m-win32.whl", hash = "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2"}, {file = "MarkupSafe-1.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c"}, - {file = "MarkupSafe-1.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15"}, - {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2"}, - {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42"}, - {file = "MarkupSafe-1.1.1-cp38-cp38-win32.whl", hash = "sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b"}, - {file = "MarkupSafe-1.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be"}, {file = "MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b"}, ] mccabe = [ @@ -1333,7 +1329,7 @@ pyflakes = [ {file = "pyflakes-2.2.0.tar.gz", hash = "sha256:35b2d75ee967ea93b55750aa9edbbf72813e06a66ba54438df2cfac9e3c27fc8"}, ] pygments = [ - {file = "Pygments-2.6.1-py3-none-any.whl", hash = "sha256:ff7a40b4860b727ab48fad6360eb351cc1b33cbf9b15a0f689ca5353e9463324"}, + {file = "Pygments-2.6.1-py2.py3-none-any.whl", hash = "sha256:aa931c0bd5daa25c475afadb2147115134cfe501f0656828cbe7cb566c7123bc"}, {file = "Pygments-2.6.1.tar.gz", hash = "sha256:647344a061c249a3b74e230c739f434d7ea4d8b1d5f3721bc0f3558049b38f44"}, ] pyparsing = [ From 72e9537506485726c876c4681aa7a0bc24d7c956 Mon Sep 17 00:00:00 2001 From: Claudio Jolowicz Date: Thu, 21 May 2020 05:46:24 +0200 Subject: [PATCH 05/17] Add implementation --- src/nox_poetry/__init__.py | 97 +++++++++++++++++++++++++++++++++++++- 1 file changed, 96 insertions(+), 1 deletion(-) diff --git a/src/nox_poetry/__init__.py b/src/nox_poetry/__init__.py index 0f0596ca..59c861a2 100644 --- a/src/nox_poetry/__init__.py +++ b/src/nox_poetry/__init__.py @@ -1 +1,96 @@ -"""nox-poetry.""" +"""Using Poetry in Nox sessions.""" +import contextlib +import tempfile +from pathlib import Path +from typing import Iterator + +from nox.sessions import Session + + +class _Poetry: + """Helper class for invoking Poetry inside a Nox session. + + Attributes: + session: The Session object. + """ + + def __init__(self, session: Session) -> None: + """Constructor.""" + self.session = session + + def install(self, *args: str) -> None: + """Install the dependencies.""" + self.session.run("poetry", "install", *args, external=True) + + @contextlib.contextmanager + def export(self, *args: str) -> Iterator[Path]: + """Export the lock file to requirements format. + + Args: + args: Command-line arguments for ``poetry export``. + + Yields: + The path to the requirements file. + """ + with tempfile.TemporaryDirectory() as directory: + requirements = Path(directory) / "requirements.txt" + self.session.run( + "poetry", + "export", + *args, + "--format=requirements.txt", + f"--output={requirements}", + external=True, + ) + yield requirements + + def build(self, *args: str) -> str: + """Build the package. + + Args: + args: Command-line arguments for ``poetry build``. + + Returns: + The basename of the wheel built by Poetry. + """ + output = self.session.run( + "poetry", "build", *args, external=True, silent=True, stderr=None + ) + assert isinstance(output, str) # noqa: S101 + return output.split()[-1] + + +def install_package(session: Session) -> None: + """Build and install the package. + + Build a wheel from the package, and install it into the virtual environment + of the specified Nox session. + + The package requirements are installed using the versions specified in + Poetry's lock file. + + Args: + session: The Session object. + """ + poetry = _Poetry(session) + + poetry.install("--no-root") + wheel = poetry.build("--format=wheel") + + session.install("--no-deps", "--force-reinstall", f"dist/{wheel}") + + +def install(session: Session, *args: str) -> None: + """Install development dependencies into the session's virtual environment. + + This function is a wrapper for nox.sessions.Session.install. + + The packages must be managed as development dependencies in Poetry. + + Args: + session: The Session object. + args: Command-line arguments for ``pip install``. + """ + poetry = _Poetry(session) + with poetry.export("--dev") as requirements: + session.install(f"--constraint={requirements}", *args) From 66bee11d748b4c74f6c539edf112986a094e6426 Mon Sep 17 00:00:00 2001 From: Claudio Jolowicz Date: Thu, 21 May 2020 05:46:35 +0200 Subject: [PATCH 06/17] Use this project in its own noxfile.py --- noxfile.py | 106 ++++------------------------------------------------- 1 file changed, 7 insertions(+), 99 deletions(-) diff --git a/noxfile.py b/noxfile.py index 676b307c..ba239c1b 100644 --- a/noxfile.py +++ b/noxfile.py @@ -1,116 +1,24 @@ """Nox sessions.""" -import contextlib import shutil import sys -import tempfile from pathlib import Path from textwrap import dedent -from typing import cast -from typing import Iterator import nox from nox.sessions import Session +sys.path.insert(0, "src") + +from nox_poetry import _Poetry +from nox_poetry import install +from nox_poetry import install_package + package = "nox_poetry" python_versions = ["3.8", "3.7", "3.6"] nox.options.sessions = "pre-commit", "safety", "mypy", "tests", "typeguard" -class Poetry: - """Helper class for invoking Poetry inside a Nox session. - - Attributes: - session: The Session object. - """ - - def __init__(self, session: Session) -> None: - """Constructor.""" - self.session = session - - @contextlib.contextmanager - def export(self, *args: str) -> Iterator[Path]: - """Export the lock file to requirements format. - - Args: - args: Command-line arguments for ``poetry export``. - - Yields: - The path to the requirements file. - """ - with tempfile.TemporaryDirectory() as directory: - requirements = Path(directory) / "requirements.txt" - self.session.run( - "poetry", - "export", - *args, - "--format=requirements.txt", - f"--output={requirements}", - external=True, - ) - yield requirements - - def version(self) -> str: - """Retrieve the package version. - - Returns: - The package version. - """ - output = self.session.run( - "poetry", "version", external=True, silent=True, stderr=None - ) - return cast(str, output).split()[1] - - def build(self, *args: str) -> None: - """Build the package. - - Args: - args: Command-line arguments for ``poetry build``. - """ - self.session.run("poetry", "build", *args, external=True) - - -def install_package(session: Session) -> None: - """Build and install the package. - - Build a wheel from the package, and install it into the virtual environment - of the specified Nox session. - - The package requirements are installed using the versions specified in - Poetry's lock file. - - Args: - session: The Session object. - """ - poetry = Poetry(session) - - with poetry.export() as requirements: - session.install(f"--requirement={requirements}") - - poetry.build("--format=wheel") - - version = poetry.version() - session.install( - "--no-deps", "--force-reinstall", f"dist/{package}-{version}-py3-none-any.whl" - ) - - -def install(session: Session, *args: str) -> None: - """Install development dependencies into the session's virtual environment. - - This function is a wrapper for nox.sessions.Session.install. - - The packages must be managed as development dependencies in Poetry. - - Args: - session: The Session object. - args: Command-line arguments for ``pip install``. - """ - poetry = Poetry(session) - with poetry.export("--dev") as requirements: - session.install(f"--constraint={requirements}", *args) - - def activate_virtualenv_in_precommit_hooks(session: Session) -> None: """Activate virtualenv in hooks installed by pre-commit. @@ -188,7 +96,7 @@ def precommit(session: Session) -> None: @nox.session(python="3.8") def safety(session: Session) -> None: """Scan dependencies for insecure packages.""" - poetry = Poetry(session) + poetry = _Poetry(session) with poetry.export("--dev", "--without-hashes") as requirements: install(session, "safety") session.run("safety", "check", f"--file={requirements}", "--bare") From 1daf8e9db837834df98040405955b8f5cd6e43fe Mon Sep 17 00:00:00 2001 From: Claudio Jolowicz Date: Sat, 1 Aug 2020 23:46:48 +0200 Subject: [PATCH 07/17] Ignore E402 --- noxfile.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/noxfile.py b/noxfile.py index ba239c1b..9b8d0000 100644 --- a/noxfile.py +++ b/noxfile.py @@ -9,9 +9,9 @@ sys.path.insert(0, "src") -from nox_poetry import _Poetry -from nox_poetry import install -from nox_poetry import install_package +from nox_poetry import _Poetry # noqa: E402 +from nox_poetry import install # noqa: E402 +from nox_poetry import install_package # noqa: E402 package = "nox_poetry" From c628fc592acc7b4a632752b76f01ee36224cb483 Mon Sep 17 00:00:00 2001 From: Claudio Jolowicz Date: Sat, 1 Aug 2020 23:49:35 +0200 Subject: [PATCH 08/17] Add nox 2020.5.24 --- poetry.lock | 82 +++++++++++++++++++++++++++++++++++++++++++------- pyproject.toml | 1 + 2 files changed, 72 insertions(+), 11 deletions(-) diff --git a/poetry.lock b/poetry.lock index 7f724d18..9a2db849 100644 --- a/poetry.lock +++ b/poetry.lock @@ -7,13 +7,29 @@ python-versions = "*" version = "0.7.12" [[package]] -category = "dev" +category = "main" description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." name = "appdirs" optional = false python-versions = "*" version = "1.4.4" +[[package]] +category = "main" +description = "Bash tab completion for argparse" +name = "argcomplete" +optional = false +python-versions = "*" +version = "1.12.0" + +[package.dependencies] +[package.dependencies.importlib-metadata] +python = ">=3.6,<3.7" +version = ">=0.23,<2" + +[package.extras] +test = ["coverage", "flake8", "pexpect", "wheel"] + [[package]] category = "dev" description = "An unobtrusive argparse wrapper with natural syntax" @@ -143,7 +159,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" version = "7.1.2" [[package]] -category = "dev" +category = "main" description = "Cross-platform colored terminal text." marker = "sys_platform == \"win32\" or platform_system == \"Windows\"" name = "colorama" @@ -151,6 +167,17 @@ optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" version = "0.4.3" +[[package]] +category = "main" +description = "Log formatting with colors!" +name = "colorlog" +optional = false +python-versions = "*" +version = "4.2.1" + +[package.dependencies] +colorama = "*" + [[package]] category = "dev" description = "Code coverage measurement for Python" @@ -176,7 +203,7 @@ python-versions = ">=3.5,<4.0" version = "1.5.1" [[package]] -category = "dev" +category = "main" description = "Distribution utilities" name = "distlib" optional = false @@ -208,7 +235,7 @@ toml = "*" pipenv = ["pipenv"] [[package]] -category = "dev" +category = "main" description = "A platform independent file lock." name = "filelock" optional = false @@ -343,7 +370,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" version = "1.2.0" [[package]] -category = "dev" +category = "main" description = "Read metadata from Python packages" marker = "python_version < \"3.8\"" name = "importlib-metadata" @@ -359,7 +386,7 @@ docs = ["sphinx", "rst.linker"] testing = ["packaging", "pep517", "importlib-resources (>=1.3)"] [[package]] -category = "dev" +category = "main" description = "Read resources from Python packages" marker = "python_version < \"3.7\"" name = "importlib-resources" @@ -460,6 +487,27 @@ optional = false python-versions = "*" version = "1.4.0" +[[package]] +category = "main" +description = "Flexible test automation." +name = "nox" +optional = false +python-versions = ">=3.5" +version = "2020.5.24" + +[package.dependencies] +argcomplete = ">=1.9.4,<2.0" +colorlog = ">=2.6.1,<5.0.0" +py = ">=1.4.0,<2.0.0" +virtualenv = ">=14.0.0" + +[package.dependencies.importlib-metadata] +python = "<3.8" +version = "*" + +[package.extras] +tox_to_nox = ["jinja2", "tox"] + [[package]] category = "dev" description = "Core utilities for Python packages" @@ -568,7 +616,7 @@ version = "3.1.0" toml = "*" [[package]] -category = "dev" +category = "main" description = "library with cross-python path, ini-parsing, io, code, log facilities" name = "py" optional = false @@ -750,7 +798,7 @@ requests = "*" setuptools = "*" [[package]] -category = "dev" +category = "main" description = "Python 2 and 3 compatibility utilities" name = "six" optional = false @@ -962,7 +1010,7 @@ secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "pyOpenSSL (>=0 socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7,<2.0)"] [[package]] -category = "dev" +category = "main" description = "Virtual Python Environment builder" name = "virtualenv" optional = false @@ -1026,7 +1074,7 @@ optional = ["pygments", "colorama"] tests = ["pytest", "pytest-cov", "codecov", "scikit-build", "cmake", "ninja", "pybind11"] [[package]] -category = "dev" +category = "main" description = "Backport of pathlib-compatible object wrapper for zip files" marker = "python_version < \"3.8\"" name = "zipp" @@ -1039,7 +1087,7 @@ docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] testing = ["jaraco.itertools", "func-timeout"] [metadata] -content-hash = "0d41a1a996c60640d9435378d254d27f8b88b7769ceebabde9381e8dbd638d77" +content-hash = "2b609d88ef1aeee1d48d8f4d337013a72cfe3aaa7aab305858350082d53bf894" lock-version = "1.0" python-versions = "^3.6.1" @@ -1052,6 +1100,10 @@ appdirs = [ {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"}, {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, ] +argcomplete = [ + {file = "argcomplete-1.12.0-py2.py3-none-any.whl", hash = "sha256:91dc7f9c7f6281d5a0dce5e73d2e33283aaef083495c13974a7dd197a1cdc949"}, + {file = "argcomplete-1.12.0.tar.gz", hash = "sha256:2fbe5ed09fd2c1d727d4199feca96569a5b50d44c71b16da9c742201f7cc295c"}, +] argh = [ {file = "argh-0.26.2-py2.py3-none-any.whl", hash = "sha256:a9b3aaa1904eeb78e32394cd46c6f37ac0fb4af6dc488daa58971bdc7d7fcaf3"}, {file = "argh-0.26.2.tar.gz", hash = "sha256:e9535b8c84dc9571a48999094fda7f33e63c3f1b74f3e5f3ac0105a58405bb65"}, @@ -1104,6 +1156,10 @@ colorama = [ {file = "colorama-0.4.3-py2.py3-none-any.whl", hash = "sha256:7d73d2a99753107a36ac6b455ee49046802e59d9d076ef8e47b61499fa29afff"}, {file = "colorama-0.4.3.tar.gz", hash = "sha256:e96da0d330793e2cb9485e9ddfd918d456036c7149416295932478192f4436a1"}, ] +colorlog = [ + {file = "colorlog-4.2.1-py2.py3-none-any.whl", hash = "sha256:43597fd822ce705190fc997519342fdaaf44b9b47f896ece7aa153ed4b909c74"}, + {file = "colorlog-4.2.1.tar.gz", hash = "sha256:75e55822c3a3387d721579241e776de2cf089c9ef9528b1f09e8b04d403ad118"}, +] coverage = [ {file = "coverage-5.2-cp27-cp27m-macosx_10_13_intel.whl", hash = "sha256:d9ad0a988ae20face62520785ec3595a5e64f35a21762a57d115dae0b8fb894a"}, {file = "coverage-5.2-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:4bb385a747e6ae8a65290b3df60d6c8a692a5599dc66c9fa3520e667886f2e10"}, @@ -1278,6 +1334,10 @@ mypy-extensions = [ nodeenv = [ {file = "nodeenv-1.4.0-py2.py3-none-any.whl", hash = "sha256:4b0b77afa3ba9b54f4b6396e60b0c83f59eaeb2d63dc3cc7a70f7f4af96c82bc"}, ] +nox = [ + {file = "nox-2020.5.24-py3-none-any.whl", hash = "sha256:c4509621fead99473a1401870e680b0aadadce5c88440f0532863595176d64c1"}, + {file = "nox-2020.5.24.tar.gz", hash = "sha256:61a55705736a1a73efbd18d5b262a43d55a1176546e0eb28b29064cfcffe26c0"}, +] packaging = [ {file = "packaging-20.4-py2.py3-none-any.whl", hash = "sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181"}, {file = "packaging-20.4.tar.gz", hash = "sha256:4357f74f47b9c12db93624a82154e9b120fa8293699949152b22065d556079f8"}, diff --git a/pyproject.toml b/pyproject.toml index b73391ec..fe1e01a4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,6 +19,7 @@ Changelog = "https://github.com/cjolowicz/nox-poetry/releases" [tool.poetry.dependencies] python = "^3.6.1" +nox = "^2020.5.24" [tool.poetry.dev-dependencies] pytest = "^5.4.3" From 121752a10f956425eaf71e5e072d047cfe3a0e14 Mon Sep 17 00:00:00 2001 From: Claudio Jolowicz Date: Sat, 1 Aug 2020 23:52:49 +0200 Subject: [PATCH 09/17] Import nox_poetry from the Nox installation --- noxfile.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/noxfile.py b/noxfile.py index 9b8d0000..b696f4c5 100644 --- a/noxfile.py +++ b/noxfile.py @@ -7,11 +7,9 @@ import nox from nox.sessions import Session -sys.path.insert(0, "src") - -from nox_poetry import _Poetry # noqa: E402 -from nox_poetry import install # noqa: E402 -from nox_poetry import install_package # noqa: E402 +from nox_poetry import _Poetry +from nox_poetry import install +from nox_poetry import install_package package = "nox_poetry" From 5fd3b9080d8903180a59cbb0fb365d58a716b23b Mon Sep 17 00:00:00 2001 From: Claudio Jolowicz Date: Sat, 1 Aug 2020 23:55:33 +0200 Subject: [PATCH 10/17] Install nox-poetry in Tests workflow --- .github/workflows/tests.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index a2c2994e..41d3b01f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -52,6 +52,10 @@ jobs: pip install --constraint=.github/workflows/constraints.txt nox nox --version + - name: Install nox-poetry + run: | + pip install . + - name: Compute pre-commit cache key if: matrix.session == 'pre-commit' id: pre-commit-cache From de65743e5bf299c13d25f4d21ba1094adb75e163 Mon Sep 17 00:00:00 2001 From: Claudio Jolowicz Date: Sun, 2 Aug 2020 00:11:16 +0200 Subject: [PATCH 11/17] Add fake tests --- tests/test_nox_poetry.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 tests/test_nox_poetry.py diff --git a/tests/test_nox_poetry.py b/tests/test_nox_poetry.py new file mode 100644 index 00000000..eb647458 --- /dev/null +++ b/tests/test_nox_poetry.py @@ -0,0 +1,32 @@ +"""Tests.""" +from typing import Any +from typing import cast + +from nox.sessions import Session + +from nox_poetry import install +from nox_poetry import install_package + + +class FakeSession: + """Fake session.""" + + def run(self, *args: str, **kargs: Any) -> str: + """Run.""" + return "example.whl" + + def install(self, *args: str, **kargs: Any) -> None: + """Install.""" + pass + + +def test_install() -> None: + """It installs.""" + session = cast(Session, FakeSession()) + install(session, "pip") + + +def test_install_package() -> None: + """It installs.""" + session = cast(Session, FakeSession()) + install_package(session) From 34597da1ce6ef2639cfeed420a6da82f2f42aa56 Mon Sep 17 00:00:00 2001 From: Claudio Jolowicz Date: Fri, 25 Sep 2020 16:33:57 +0200 Subject: [PATCH 12/17] Update cookiecutter-hypermodern-python to 2020.9.15 --- .flake8 | 2 +- .github/workflows/constraints.txt | 8 +- .github/workflows/release.yml | 4 +- .github/workflows/tests.yml | 10 +- .pre-commit-config.yaml | 2 +- CONTRIBUTING.rst | 5 +- docs/requirements.txt | 2 +- mypy.ini | 6 +- noxfile.py | 47 ++++-- poetry.lock | 260 +++++++++++++----------------- pyproject.toml | 20 +-- src/nox_poetry/__init__.py | 73 +++++---- tests/test_nox_poetry.py | 4 + 13 files changed, 220 insertions(+), 223 deletions(-) diff --git a/.flake8 b/.flake8 index 8295d18d..9b47ccb6 100644 --- a/.flake8 +++ b/.flake8 @@ -1,6 +1,6 @@ [flake8] select = B,B9,C,D,DAR,E,F,N,RST,S,W -ignore = E203,E501,W503 +ignore = E203,E501,RST203,RST301,W503 max-line-length = 80 max-complexity = 10 docstring-convention = google diff --git a/.github/workflows/constraints.txt b/.github/workflows/constraints.txt index 80c9f8dc..ce409116 100644 --- a/.github/workflows/constraints.txt +++ b/.github/workflows/constraints.txt @@ -1,4 +1,4 @@ -pip==20.1.1 -nox==2020.5.24 -poetry==1.0.9 -virtualenv==20.0.26 +pip==20.2.3 +nox==2020.8.22 +poetry==1.0.10 +virtualenv==20.0.31 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 182ef749..bd64a241 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,12 +11,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out the repository - uses: actions/checkout@v2.3.1 + uses: actions/checkout@v2.3.2 with: fetch-depth: 2 - name: Set up Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v2.1.2 with: python-version: "3.8" diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 41d3b01f..3c83994d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -23,17 +23,17 @@ jobs: - { python-version: 3.8, os: windows-latest, session: "tests" } - { python-version: 3.8, os: macos-latest, session: "tests" } - { python-version: 3.8, os: ubuntu-latest, session: "typeguard" } - - { python-version: 3.8, os: ubuntu-latest, session: "docs" } + - { python-version: 3.8, os: ubuntu-latest, session: "docs-build" } env: NOXSESSION: ${{ matrix.session }} steps: - name: Check out the repository - uses: actions/checkout@v2.3.1 + uses: actions/checkout@v2.3.2 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v2.1.2 with: python-version: ${{ matrix.python-version }} @@ -85,7 +85,7 @@ jobs: nox --force-color --python=${{ matrix.python-version }} - name: Upload documentation - if: matrix.session == 'docs' + if: matrix.session == 'docs-build' uses: actions/upload-artifact@v2 with: name: docs @@ -98,4 +98,4 @@ jobs: - name: Upload coverage report if: always() && matrix.session == 'tests' - uses: codecov/codecov-action@v1.0.10 + uses: codecov/codecov-action@v1.0.13 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 76a22c8a..7081d5e6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -46,6 +46,6 @@ repos: types: [text] stages: [commit, push, manual] - repo: https://github.com/prettier/prettier - rev: 2.0.5 + rev: 2.1.1 hooks: - id: prettier diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index c591ffa1..91549456 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -107,16 +107,15 @@ Your pull request needs to meet the following guidelines for acceptance: Feel free to submit early, though—we can always iterate on this. -You can ensure that your changes adhere to the code style by reformatting with Black_: +To run linting and code formatting checks before commiting your change, you can install pre-commit as a Git hook by running the following command: .. code:: console - $ nox --session=black + $ nox --session=pre-commit -- install It is recommended to open an issue before starting work on anything. This will allow a chance to talk it over with the owners and validate your approach. .. _pull request: https://github.com/cjolowicz/nox-poetry/pulls -.. _Black: https://black.readthedocs.io/ .. github-only .. _Code of Conduct: CODE_OF_CONDUCT.rst diff --git a/docs/requirements.txt b/docs/requirements.txt index 96451c97..89eb0be0 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1 +1 @@ -sphinx==3.1.2 +sphinx==3.2.1 diff --git a/mypy.ini b/mypy.ini index dfca56c1..01202bca 100644 --- a/mypy.ini +++ b/mypy.ini @@ -19,8 +19,8 @@ warn_unreachable = True warn_unused_configs = True warn_unused_ignores = True -[mypy-tests.*] -disallow_untyped_decorators = False - [mypy-pytest] ignore_missing_imports = True + +[mypy-tests.*] +disallow_untyped_decorators = False diff --git a/noxfile.py b/noxfile.py index b696f4c5..a43acebc 100644 --- a/noxfile.py +++ b/noxfile.py @@ -7,14 +7,21 @@ import nox from nox.sessions import Session -from nox_poetry import _Poetry +from nox_poetry import export_requirements from nox_poetry import install from nox_poetry import install_package package = "nox_poetry" python_versions = ["3.8", "3.7", "3.6"] -nox.options.sessions = "pre-commit", "safety", "mypy", "tests", "typeguard" +nox.options.sessions = ( + "pre-commit", + "safety", + "mypy", + "tests", + "typeguard", + "docs-build", +) def activate_virtualenv_in_precommit_hooks(session: Session) -> None: @@ -94,10 +101,9 @@ def precommit(session: Session) -> None: @nox.session(python="3.8") def safety(session: Session) -> None: """Scan dependencies for insecure packages.""" - poetry = _Poetry(session) - with poetry.export("--dev", "--without-hashes") as requirements: - install(session, "safety") - session.run("safety", "check", f"--file={requirements}", "--bare") + install(session, "safety") + requirements = export_requirements(session, dev=True) + session.run("safety", "check", f"--file={requirements}", "--bare") @nox.session(python=python_versions) @@ -154,22 +160,29 @@ def xdoctest(session: Session) -> None: session.run("python", "-m", "xdoctest", package, *args) -@nox.session(python="3.8") -def docs(session: Session) -> None: +@nox.session(name="docs-build", python="3.8") +def docs_build(session: Session) -> None: """Build the documentation.""" args = session.posargs or ["docs", "docs/_build"] + install_package(session) + install(session, "sphinx") + + build_dir = Path("docs", "_build") + if build_dir.exists(): + shutil.rmtree(build_dir) - if session.interactive and not session.posargs: - args.insert(0, "--open-browser") + session.run("sphinx-build", *args) - builddir = Path("docs", "_build") - if builddir.exists(): - shutil.rmtree(builddir) +@nox.session(python="3.8") +def docs(session: Session) -> None: + """Build and serve the documentation with live reloading on file changes.""" + args = session.posargs or ["--open-browser", "docs", "docs/_build"] install_package(session) install(session, "sphinx", "sphinx-autobuild") - if session.interactive: - session.run("sphinx-autobuild", *args) - else: - session.run("sphinx-build", *args) + build_dir = Path("docs", "_build") + if build_dir.exists(): + shutil.rmtree(build_dir) + + session.run("sphinx-autobuild", *args) diff --git a/poetry.lock b/poetry.lock index 9a2db849..1803f730 100644 --- a/poetry.lock +++ b/poetry.lock @@ -30,14 +30,6 @@ version = ">=0.23,<2" [package.extras] test = ["coverage", "flake8", "pexpect", "wheel"] -[[package]] -category = "dev" -description = "An unobtrusive argparse wrapper with natural syntax" -name = "argh" -optional = false -python-versions = "*" -version = "0.26.2" - [[package]] category = "dev" description = "Utilities for refactoring imports in python-like syntax." @@ -104,18 +96,24 @@ description = "The uncompromising code formatter." name = "black" optional = false python-versions = ">=3.6" -version = "19.10b0" +version = "20.8b1" [package.dependencies] appdirs = "*" -attrs = ">=18.1.0" -click = ">=6.5" +click = ">=7.1.2" +mypy-extensions = ">=0.4.3" pathspec = ">=0.6,<1" -regex = "*" -toml = ">=0.9.4" +regex = ">=2020.1.8" +toml = ">=0.10.1" typed-ast = ">=1.4.0" +typing-extensions = ">=3.7.4" + +[package.dependencies.dataclasses] +python = "<3.7" +version = ">=0.6" [package.extras] +colorama = ["colorama (>=0.4.3)"] d = ["aiohttp (>=3.3.2)", "aiohttp-cors"] [[package]] @@ -184,7 +182,7 @@ description = "Code coverage measurement for Python" name = "coverage" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" -version = "5.2" +version = "5.3" [package.dependencies] [package.dependencies.toml] @@ -200,7 +198,16 @@ description = "A utility for ensuring Google-style docstrings stay up to date wi name = "darglint" optional = false python-versions = ">=3.5,<4.0" -version = "1.5.1" +version = "1.5.4" + +[[package]] +category = "dev" +description = "A backport of the dataclasses module for Python 3.6" +marker = "python_version < \"3.7\"" +name = "dataclasses" +optional = false +python-versions = "*" +version = "0.6" [[package]] category = "main" @@ -402,6 +409,14 @@ version = ">=0.4" [package.extras] docs = ["sphinx", "rst.linker", "jaraco.packaging"] +[[package]] +category = "dev" +description = "iniconfig: brain-dead simple config-ini parsing" +name = "iniconfig" +optional = false +python-versions = "*" +version = "1.0.1" + [[package]] category = "dev" description = "A very fast and expressive template engine." @@ -528,14 +543,6 @@ optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" version = "0.8.0" -[[package]] -category = "dev" -description = "File system general utilities" -name = "pathtools" -optional = false -python-versions = "*" -version = "0.1.2" - [[package]] category = "dev" description = "Python Build Reasonableness" @@ -571,21 +578,13 @@ version = ">=0.12" [package.extras] dev = ["pre-commit", "tox"] -[[package]] -category = "dev" -description = "Utility that helps with local TCP ports managment. It can find an unused TCP localhost port and remember the association." -name = "port-for" -optional = false -python-versions = "*" -version = "0.3.1" - [[package]] category = "dev" description = "A framework for managing and maintaining multi-language pre-commit hooks." name = "pre-commit" optional = false python-versions = ">=3.6.1" -version = "2.6.0" +version = "2.7.1" [package.dependencies] cfgv = ">=2.0.0" @@ -609,7 +608,7 @@ description = "Some out-of-the-box hooks for pre-commit." name = "pre-commit-hooks" optional = false python-versions = ">=3.6.1" -version = "3.1.0" +version = "3.2.0" [package.dependencies] "ruamel.yaml" = ">=0.15" @@ -672,24 +671,25 @@ description = "pytest: simple powerful testing with Python" name = "pytest" optional = false python-versions = ">=3.5" -version = "5.4.3" +version = "6.0.2" [package.dependencies] atomicwrites = ">=1.0" attrs = ">=17.4.0" colorama = "*" +iniconfig = "*" more-itertools = ">=4.0.0" packaging = "*" pluggy = ">=0.12,<1.0" -py = ">=1.5.0" -wcwidth = "*" +py = ">=1.8.2" +toml = "*" [package.dependencies.importlib-metadata] python = "<3.8" version = ">=0.12" [package.extras] -checkqa-mypy = ["mypy (v0.761)"] +checkqa_mypy = ["mypy (0.780)"] testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] [[package]] @@ -722,7 +722,7 @@ description = "Tool for reordering python imports" name = "reorder-python-imports" optional = false python-versions = ">=3.6.1" -version = "2.3.1" +version = "2.3.5" [package.dependencies] "aspy.refactor-imports" = ">=2.1.0" @@ -827,7 +827,7 @@ description = "Python documentation generator" name = "sphinx" optional = false python-versions = ">=3.5" -version = "3.1.2" +version = "3.2.1" [package.dependencies] Jinja2 = ">=2.3" @@ -855,20 +855,18 @@ test = ["pytest", "pytest-cov", "html5lib", "typed-ast", "cython"] [[package]] category = "dev" -description = "Watch a Sphinx directory and rebuild the documentation when a change is detected. Also includes a livereload enabled web server." +description = "Rebuild Sphinx documentation on changes, with live-reload in the browser." name = "sphinx-autobuild" optional = false -python-versions = "*" -version = "0.7.1" +python-versions = ">=3.6" +version = "2020.9.1" [package.dependencies] -PyYAML = ">=3.10" -argh = ">=0.24.1" -livereload = ">=2.3.0" -pathtools = ">=0.1.2" -port-for = "0.3.1" -tornado = ">=3.2" -watchdog = ">=0.7.1" +livereload = "*" +sphinx = "*" + +[package.extras] +test = ["pytest", "pytest-cov"] [[package]] category = "dev" @@ -963,6 +961,7 @@ version = "0.10.1" [[package]] category = "dev" description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." +marker = "python_version > \"2.7\"" name = "tornado" optional = false python-versions = ">= 3.5" @@ -1035,43 +1034,23 @@ version = ">=1.0" docs = ["sphinx (>=3)", "sphinx-argparse (>=0.2.5)", "sphinx-rtd-theme (>=0.4.3)", "towncrier (>=19.9.0rc1)", "proselint (>=0.10.2)"] testing = ["pytest (>=4)", "coverage (>=5)", "coverage-enable-subprocess (>=1)", "pytest-xdist (>=1.31.0)", "pytest-mock (>=2)", "pytest-env (>=0.6.2)", "pytest-randomly (>=1)", "pytest-timeout (>=1)", "pytest-freezegun (>=0.4.1)", "flaky (>=3)", "packaging (>=20.0)", "xonsh (>=0.9.16)"] -[[package]] -category = "dev" -description = "Filesystem events monitoring" -name = "watchdog" -optional = false -python-versions = "*" -version = "0.10.3" - -[package.dependencies] -pathtools = ">=0.1.1" - -[package.extras] -watchmedo = ["PyYAML (>=3.10)", "argh (>=0.24.1)"] - -[[package]] -category = "dev" -description = "Measures the displayed width of unicode strings in a terminal" -name = "wcwidth" -optional = false -python-versions = "*" -version = "0.2.5" - [[package]] category = "dev" description = "A rewrite of the builtin doctest module" name = "xdoctest" optional = false python-versions = "*" -version = "0.13.0" +version = "0.15.0" [package.dependencies] six = "*" [package.extras] -all = ["six", "pytest", "pytest-cov", "codecov", "scikit-build", "cmake", "ninja", "pybind11", "pygments", "colorama"] -optional = ["pygments", "colorama"] -tests = ["pytest", "pytest-cov", "codecov", "scikit-build", "cmake", "ninja", "pybind11"] +all = ["six", "pytest", "pytest-cov", "codecov", "scikit-build", "cmake", "ninja", "pybind11", "pygments", "colorama", "nbformat", "nbconvert", "jupyter-client", "ipython", "ipykernel"] +colors = ["pygments", "colorama"] +jupyter = ["nbformat", "nbconvert", "jupyter-client", "ipython", "ipykernel"] +optional = ["pygments", "colorama", "nbformat", "nbconvert", "jupyter-client", "ipython", "ipykernel"] +tests = ["pytest", "pytest-cov", "codecov", "scikit-build", "cmake", "ninja", "pybind11", "nbformat", "nbconvert", "jupyter-client", "ipython", "ipykernel"] [[package]] category = "main" @@ -1087,8 +1066,7 @@ docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] testing = ["jaraco.itertools", "func-timeout"] [metadata] -content-hash = "2b609d88ef1aeee1d48d8f4d337013a72cfe3aaa7aab305858350082d53bf894" -lock-version = "1.0" +content-hash = "e0b72bc6d25bfc48486aedfd8357e7a654a13ce2b563171a7a72e6a33e4965f2" python-versions = "^3.6.1" [metadata.files] @@ -1104,10 +1082,6 @@ argcomplete = [ {file = "argcomplete-1.12.0-py2.py3-none-any.whl", hash = "sha256:91dc7f9c7f6281d5a0dce5e73d2e33283aaef083495c13974a7dd197a1cdc949"}, {file = "argcomplete-1.12.0.tar.gz", hash = "sha256:2fbe5ed09fd2c1d727d4199feca96569a5b50d44c71b16da9c742201f7cc295c"}, ] -argh = [ - {file = "argh-0.26.2-py2.py3-none-any.whl", hash = "sha256:a9b3aaa1904eeb78e32394cd46c6f37ac0fb4af6dc488daa58971bdc7d7fcaf3"}, - {file = "argh-0.26.2.tar.gz", hash = "sha256:e9535b8c84dc9571a48999094fda7f33e63c3f1b74f3e5f3ac0105a58405bb65"}, -] "aspy.refactor-imports" = [ {file = "aspy.refactor_imports-2.1.1-py2.py3-none-any.whl", hash = "sha256:9df76bf19ef81620068b785a386740ab3c8939fcbdcebf20c4a4e0057230d782"}, {file = "aspy.refactor_imports-2.1.1.tar.gz", hash = "sha256:eec8d1a73bedf64ffb8b589ad919a030c1fb14acf7d1ce0ab192f6eedae895c5"}, @@ -1129,8 +1103,7 @@ bandit = [ {file = "bandit-1.6.2.tar.gz", hash = "sha256:41e75315853507aa145d62a78a2a6c5e3240fe14ee7c601459d0df9418196065"}, ] black = [ - {file = "black-19.10b0-py36-none-any.whl", hash = "sha256:1b30e59be925fafc1ee4565e5e08abef6b03fe455102883820fe5ee2e4734e0b"}, - {file = "black-19.10b0.tar.gz", hash = "sha256:c2edb73a08e9e0e6f65a0e6af18b059b8b1cdd5bef997d7a0b181df93dc81539"}, + {file = "black-20.8b1.tar.gz", hash = "sha256:1c02557aa099101b9d21496f8a914e9ed2222ef70336404eeeac8edba836fbea"}, ] cached-property = [ {file = "cached-property-1.5.1.tar.gz", hash = "sha256:9217a59f14a5682da7c4b8829deadbfc194ac22e9908ccf7c8820234e80a1504"}, @@ -1161,44 +1134,48 @@ colorlog = [ {file = "colorlog-4.2.1.tar.gz", hash = "sha256:75e55822c3a3387d721579241e776de2cf089c9ef9528b1f09e8b04d403ad118"}, ] coverage = [ - {file = "coverage-5.2-cp27-cp27m-macosx_10_13_intel.whl", hash = "sha256:d9ad0a988ae20face62520785ec3595a5e64f35a21762a57d115dae0b8fb894a"}, - {file = "coverage-5.2-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:4bb385a747e6ae8a65290b3df60d6c8a692a5599dc66c9fa3520e667886f2e10"}, - {file = "coverage-5.2-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:9702e2cb1c6dec01fb8e1a64c015817c0800a6eca287552c47a5ee0ebddccf62"}, - {file = "coverage-5.2-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:42fa45a29f1059eda4d3c7b509589cc0343cd6bbf083d6118216830cd1a51613"}, - {file = "coverage-5.2-cp27-cp27m-win32.whl", hash = "sha256:41d88736c42f4a22c494c32cc48a05828236e37c991bd9760f8923415e3169e4"}, - {file = "coverage-5.2-cp27-cp27m-win_amd64.whl", hash = "sha256:bbb387811f7a18bdc61a2ea3d102be0c7e239b0db9c83be7bfa50f095db5b92a"}, - {file = "coverage-5.2-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:3740b796015b889e46c260ff18b84683fa2e30f0f75a171fb10d2bf9fb91fc70"}, - {file = "coverage-5.2-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ebf2431b2d457ae5217f3a1179533c456f3272ded16f8ed0b32961a6d90e38ee"}, - {file = "coverage-5.2-cp35-cp35m-macosx_10_13_x86_64.whl", hash = "sha256:d54d7ea74cc00482a2410d63bf10aa34ebe1c49ac50779652106c867f9986d6b"}, - {file = "coverage-5.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:87bdc8135b8ee739840eee19b184804e5d57f518578ffc797f5afa2c3c297913"}, - {file = "coverage-5.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:ed9a21502e9223f563e071759f769c3d6a2e1ba5328c31e86830368e8d78bc9c"}, - {file = "coverage-5.2-cp35-cp35m-win32.whl", hash = "sha256:509294f3e76d3f26b35083973fbc952e01e1727656d979b11182f273f08aa80b"}, - {file = "coverage-5.2-cp35-cp35m-win_amd64.whl", hash = "sha256:ca63dae130a2e788f2b249200f01d7fa240f24da0596501d387a50e57aa7075e"}, - {file = "coverage-5.2-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:5c74c5b6045969b07c9fb36b665c9cac84d6c174a809fc1b21bdc06c7836d9a0"}, - {file = "coverage-5.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:c32aa13cc3fe86b0f744dfe35a7f879ee33ac0a560684fef0f3e1580352b818f"}, - {file = "coverage-5.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:1e58fca3d9ec1a423f1b7f2aa34af4f733cbfa9020c8fe39ca451b6071237405"}, - {file = "coverage-5.2-cp36-cp36m-win32.whl", hash = "sha256:3b2c34690f613525672697910894b60d15800ac7e779fbd0fccf532486c1ba40"}, - {file = "coverage-5.2-cp36-cp36m-win_amd64.whl", hash = "sha256:a4d511012beb967a39580ba7d2549edf1e6865a33e5fe51e4dce550522b3ac0e"}, - {file = "coverage-5.2-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:32ecee61a43be509b91a526819717d5e5650e009a8d5eda8631a59c721d5f3b6"}, - {file = "coverage-5.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:6f91b4492c5cde83bfe462f5b2b997cdf96a138f7c58b1140f05de5751623cf1"}, - {file = "coverage-5.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:bfcc811883699ed49afc58b1ed9f80428a18eb9166422bce3c31a53dba00fd1d"}, - {file = "coverage-5.2-cp37-cp37m-win32.whl", hash = "sha256:60a3d36297b65c7f78329b80120f72947140f45b5c7a017ea730f9112b40f2ec"}, - {file = "coverage-5.2-cp37-cp37m-win_amd64.whl", hash = "sha256:12eaccd86d9a373aea59869bc9cfa0ab6ba8b1477752110cb4c10d165474f703"}, - {file = "coverage-5.2-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:d82db1b9a92cb5c67661ca6616bdca6ff931deceebb98eecbd328812dab52032"}, - {file = "coverage-5.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:214eb2110217f2636a9329bc766507ab71a3a06a8ea30cdeebb47c24dce5972d"}, - {file = "coverage-5.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8a3decd12e7934d0254939e2bf434bf04a5890c5bf91a982685021786a08087e"}, - {file = "coverage-5.2-cp38-cp38-win32.whl", hash = "sha256:1dcebae667b73fd4aa69237e6afb39abc2f27520f2358590c1b13dd90e32abe7"}, - {file = "coverage-5.2-cp38-cp38-win_amd64.whl", hash = "sha256:f50632ef2d749f541ca8e6c07c9928a37f87505ce3a9f20c8446ad310f1aa87b"}, - {file = "coverage-5.2-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:7403675df5e27745571aba1c957c7da2dacb537c21e14007ec3a417bf31f7f3d"}, - {file = "coverage-5.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:0fc4e0d91350d6f43ef6a61f64a48e917637e1dcfcba4b4b7d543c628ef82c2d"}, - {file = "coverage-5.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:25fe74b5b2f1b4abb11e103bb7984daca8f8292683957d0738cd692f6a7cc64c"}, - {file = "coverage-5.2-cp39-cp39-win32.whl", hash = "sha256:d67599521dff98ec8c34cd9652cbcfe16ed076a2209625fca9dc7419b6370e5c"}, - {file = "coverage-5.2-cp39-cp39-win_amd64.whl", hash = "sha256:10f2a618a6e75adf64329f828a6a5b40244c1c50f5ef4ce4109e904e69c71bd2"}, - {file = "coverage-5.2.tar.gz", hash = "sha256:1874bdc943654ba46d28f179c1846f5710eda3aeb265ff029e0ac2b52daae404"}, + {file = "coverage-5.3-cp27-cp27m-macosx_10_13_intel.whl", hash = "sha256:bd3166bb3b111e76a4f8e2980fa1addf2920a4ca9b2b8ca36a3bc3dedc618270"}, + {file = "coverage-5.3-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:9342dd70a1e151684727c9c91ea003b2fb33523bf19385d4554f7897ca0141d4"}, + {file = "coverage-5.3-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:63808c30b41f3bbf65e29f7280bf793c79f54fb807057de7e5238ffc7cc4d7b9"}, + {file = "coverage-5.3-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:4d6a42744139a7fa5b46a264874a781e8694bb32f1d76d8137b68138686f1729"}, + {file = "coverage-5.3-cp27-cp27m-win32.whl", hash = "sha256:86e9f8cd4b0cdd57b4ae71a9c186717daa4c5a99f3238a8723f416256e0b064d"}, + {file = "coverage-5.3-cp27-cp27m-win_amd64.whl", hash = "sha256:7858847f2d84bf6e64c7f66498e851c54de8ea06a6f96a32a1d192d846734418"}, + {file = "coverage-5.3-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:530cc8aaf11cc2ac7430f3614b04645662ef20c348dce4167c22d99bec3480e9"}, + {file = "coverage-5.3-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:381ead10b9b9af5f64646cd27107fb27b614ee7040bb1226f9c07ba96625cbb5"}, + {file = "coverage-5.3-cp35-cp35m-macosx_10_13_x86_64.whl", hash = "sha256:71b69bd716698fa62cd97137d6f2fdf49f534decb23a2c6fc80813e8b7be6822"}, + {file = "coverage-5.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:1d44bb3a652fed01f1f2c10d5477956116e9b391320c94d36c6bf13b088a1097"}, + {file = "coverage-5.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:1c6703094c81fa55b816f5ae542c6ffc625fec769f22b053adb42ad712d086c9"}, + {file = "coverage-5.3-cp35-cp35m-win32.whl", hash = "sha256:cedb2f9e1f990918ea061f28a0f0077a07702e3819602d3507e2ff98c8d20636"}, + {file = "coverage-5.3-cp35-cp35m-win_amd64.whl", hash = "sha256:7f43286f13d91a34fadf61ae252a51a130223c52bfefb50310d5b2deb062cf0f"}, + {file = "coverage-5.3-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:c851b35fc078389bc16b915a0a7c1d5923e12e2c5aeec58c52f4aa8085ac8237"}, + {file = "coverage-5.3-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:aac1ba0a253e17889550ddb1b60a2063f7474155465577caa2a3b131224cfd54"}, + {file = "coverage-5.3-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:2b31f46bf7b31e6aa690d4c7a3d51bb262438c6dcb0d528adde446531d0d3bb7"}, + {file = "coverage-5.3-cp36-cp36m-win32.whl", hash = "sha256:c5f17ad25d2c1286436761b462e22b5020d83316f8e8fcb5deb2b3151f8f1d3a"}, + {file = "coverage-5.3-cp36-cp36m-win_amd64.whl", hash = "sha256:aef72eae10b5e3116bac6957de1df4d75909fc76d1499a53fb6387434b6bcd8d"}, + {file = "coverage-5.3-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:e8caf961e1b1a945db76f1b5fa9c91498d15f545ac0ababbe575cfab185d3bd8"}, + {file = "coverage-5.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:29a6272fec10623fcbe158fdf9abc7a5fa032048ac1d8631f14b50fbfc10d17f"}, + {file = "coverage-5.3-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:2d43af2be93ffbad25dd959899b5b809618a496926146ce98ee0b23683f8c51c"}, + {file = "coverage-5.3-cp37-cp37m-win32.whl", hash = "sha256:c3888a051226e676e383de03bf49eb633cd39fc829516e5334e69b8d81aae751"}, + {file = "coverage-5.3-cp37-cp37m-win_amd64.whl", hash = "sha256:9669179786254a2e7e57f0ecf224e978471491d660aaca833f845b72a2df3709"}, + {file = "coverage-5.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0203acd33d2298e19b57451ebb0bed0ab0c602e5cf5a818591b4918b1f97d516"}, + {file = "coverage-5.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:582ddfbe712025448206a5bc45855d16c2e491c2dd102ee9a2841418ac1c629f"}, + {file = "coverage-5.3-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:0f313707cdecd5cd3e217fc68c78a960b616604b559e9ea60cc16795c4304259"}, + {file = "coverage-5.3-cp38-cp38-win32.whl", hash = "sha256:78e93cc3571fd928a39c0b26767c986188a4118edc67bc0695bc7a284da22e82"}, + {file = "coverage-5.3-cp38-cp38-win_amd64.whl", hash = "sha256:8f264ba2701b8c9f815b272ad568d555ef98dfe1576802ab3149c3629a9f2221"}, + {file = "coverage-5.3-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:50691e744714856f03a86df3e2bff847c2acede4c191f9a1da38f088df342978"}, + {file = "coverage-5.3-cp39-cp39-manylinux1_i686.whl", hash = "sha256:9361de40701666b034c59ad9e317bae95c973b9ff92513dd0eced11c6adf2e21"}, + {file = "coverage-5.3-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:c1b78fb9700fc961f53386ad2fd86d87091e06ede5d118b8a50dea285a071c24"}, + {file = "coverage-5.3-cp39-cp39-win32.whl", hash = "sha256:cb7df71de0af56000115eafd000b867d1261f786b5eebd88a0ca6360cccfaca7"}, + {file = "coverage-5.3-cp39-cp39-win_amd64.whl", hash = "sha256:47a11bdbd8ada9b7ee628596f9d97fbd3851bd9999d398e9436bd67376dbece7"}, + {file = "coverage-5.3.tar.gz", hash = "sha256:280baa8ec489c4f542f8940f9c4c2181f0306a8ee1a54eceba071a449fb870a0"}, ] darglint = [ - {file = "darglint-1.5.1-py3-none-any.whl", hash = "sha256:b37be3bea80d25fa015c002ab63d4100a676441dbb75af7cd1df69b1b9324d5f"}, - {file = "darglint-1.5.1.tar.gz", hash = "sha256:cb845b4cd046c9073be1f24935b6609abdc521270669ed7370ca0cdb112a7e1c"}, + {file = "darglint-1.5.4-py3-none-any.whl", hash = "sha256:e58ff63f0f29a4dc8f9c1e102c7d00539290567d72feb74b7b9d5f8302992b8d"}, + {file = "darglint-1.5.4.tar.gz", hash = "sha256:7ebaafc8559d0db7735b6e15904ee5cca4be56fa85eac21c025c328278c6317a"}, +] +dataclasses = [ + {file = "dataclasses-0.6-py3-none-any.whl", hash = "sha256:454a69d788c7fda44efd71e259be79577822f5e3f53f029a22d08004e951dc9f"}, + {file = "dataclasses-0.6.tar.gz", hash = "sha256:6988bd2b895eef432d562370bb707d540f32f7360ab13da45340101bc2307d84"}, ] distlib = [ {file = "distlib-0.3.1-py2.py3-none-any.whl", hash = "sha256:8c09de2c67b3e7deef7184574fc060ab8a793e7adbb183d942c389c8b13c52fb"}, @@ -1266,6 +1243,10 @@ importlib-resources = [ {file = "importlib_resources-3.0.0-py2.py3-none-any.whl", hash = "sha256:d028f66b66c0d5732dae86ba4276999855e162a749c92620a38c1d779ed138a7"}, {file = "importlib_resources-3.0.0.tar.gz", hash = "sha256:19f745a6eca188b490b1428c8d1d4a0d2368759f32370ea8fb89cad2ab1106c3"}, ] +iniconfig = [ + {file = "iniconfig-1.0.1-py3-none-any.whl", hash = "sha256:80cf40c597eb564e86346103f609d74efce0f6b4d4f30ec8ce9e2c26411ba437"}, + {file = "iniconfig-1.0.1.tar.gz", hash = "sha256:e5f92f89355a67de0595932a6c6c02ab4afddc6fcdc0bfc5becd0d60884d3f69"}, +] jinja2 = [ {file = "Jinja2-2.11.2-py2.py3-none-any.whl", hash = "sha256:f0a4641d3cf955324a89c04f3d94663aa4d638abe8f733ecd3582848e1c37035"}, {file = "Jinja2-2.11.2.tar.gz", hash = "sha256:89aab215427ef59c34ad58735269eb58b1a5808103067f7bb9d5836c651b3bb0"}, @@ -1346,9 +1327,6 @@ pathspec = [ {file = "pathspec-0.8.0-py2.py3-none-any.whl", hash = "sha256:7d91249d21749788d07a2d0f94147accd8f845507400749ea19c1ec9054a12b0"}, {file = "pathspec-0.8.0.tar.gz", hash = "sha256:da45173eb3a6f2a5a487efba21f050af2b41948be6ab52b6a1e3ff22bb8b7061"}, ] -pathtools = [ - {file = "pathtools-0.1.2.tar.gz", hash = "sha256:7c35c5421a39bb82e58018febd90e3b6e5db34c5443aaaf742b3f33d4655f1c0"}, -] pbr = [ {file = "pbr-5.4.5-py2.py3-none-any.whl", hash = "sha256:579170e23f8e0c2f24b0de612f71f648eccb79fb1322c814ae6b3c07b5ba23e8"}, {file = "pbr-5.4.5.tar.gz", hash = "sha256:07f558fece33b05caf857474a366dfcc00562bca13dd8b47b2b3e22d9f9bf55c"}, @@ -1361,16 +1339,13 @@ pluggy = [ {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, ] -port-for = [ - {file = "port-for-0.3.1.tar.gz", hash = "sha256:b16a84bb29c2954db44c29be38b17c659c9c27e33918dec16b90d375cc596f1c"}, -] pre-commit = [ - {file = "pre_commit-2.6.0-py2.py3-none-any.whl", hash = "sha256:e8b1315c585052e729ab7e99dcca5698266bedce9067d21dc909c23e3ceed626"}, - {file = "pre_commit-2.6.0.tar.gz", hash = "sha256:1657663fdd63a321a4a739915d7d03baedd555b25054449090f97bb0cb30a915"}, + {file = "pre_commit-2.7.1-py2.py3-none-any.whl", hash = "sha256:810aef2a2ba4f31eed1941fc270e72696a1ad5590b9751839c90807d0fff6b9a"}, + {file = "pre_commit-2.7.1.tar.gz", hash = "sha256:c54fd3e574565fe128ecc5e7d2f91279772ddb03f8729645fa812fe809084a70"}, ] pre-commit-hooks = [ - {file = "pre_commit_hooks-3.1.0-py2.py3-none-any.whl", hash = "sha256:32e07d6bd511e26ac3d7b7aafdd2e49d0f1efdb7fc772156386004b9e6f66dbe"}, - {file = "pre_commit_hooks-3.1.0.tar.gz", hash = "sha256:78642bdda65d524a6c91faaf4b322f18fc561e4377e8651d8502c6073e4a19d9"}, + {file = "pre_commit_hooks-3.2.0-py2.py3-none-any.whl", hash = "sha256:8a174237326576c5f2279eba18ccbf2ca2a19fcaab8844db80f576c8fe76c2c2"}, + {file = "pre_commit_hooks-3.2.0.tar.gz", hash = "sha256:917bce8feb048f8271e3a4a900c6d780118d23e8ddf4557ddec9384c0d1dba79"}, ] py = [ {file = "py-1.9.0-py2.py3-none-any.whl", hash = "sha256:366389d1db726cd2fcfc79732e75410e5fe4d31db13692115529d34069a043c2"}, @@ -1397,8 +1372,8 @@ pyparsing = [ {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, ] pytest = [ - {file = "pytest-5.4.3-py3-none-any.whl", hash = "sha256:5c0db86b698e8f170ba4582a492248919255fcd4c79b1ee64ace34301fb589a1"}, - {file = "pytest-5.4.3.tar.gz", hash = "sha256:7979331bfcba207414f5e1263b5a0f8f521d0f457318836a7355531ed1a4c7d8"}, + {file = "pytest-6.0.2-py3-none-any.whl", hash = "sha256:0e37f61339c4578776e090c3b8f6b16ce4db333889d65d0efb305243ec544b40"}, + {file = "pytest-6.0.2.tar.gz", hash = "sha256:c8f57c2a30983f469bf03e68cdfa74dc474ce56b8f280ddcb080dfd91df01043"}, ] pytz = [ {file = "pytz-2020.1-py2.py3-none-any.whl", hash = "sha256:a494d53b6d39c3c6e44c3bec237336e14305e4f29bbf800b599253057fbb79ed"}, @@ -1441,8 +1416,8 @@ regex = [ {file = "regex-2020.6.8.tar.gz", hash = "sha256:e9b64e609d37438f7d6e68c2546d2cb8062f3adb27e6336bc129b51be20773ac"}, ] reorder-python-imports = [ - {file = "reorder_python_imports-2.3.1-py2.py3-none-any.whl", hash = "sha256:c0a9d60d84db9e6425d9379296d296cce78699967a6012972b8f4f074e22c3f5"}, - {file = "reorder_python_imports-2.3.1.tar.gz", hash = "sha256:e2a4712866aee291c1c019aa67f95a3be2fffa5ebd801cab5d98ab2b66cfd512"}, + {file = "reorder_python_imports-2.3.5-py2.py3-none-any.whl", hash = "sha256:6e8d3baba68c409ec87242757cf579a7ad2b133d1efed498be987b97ee385ac3"}, + {file = "reorder_python_imports-2.3.5.tar.gz", hash = "sha256:7c46593d39899e3fb249248b448bde93ee7417889904f015c0c5a738c23fd0e0"}, ] requests = [ {file = "requests-2.24.0-py2.py3-none-any.whl", hash = "sha256:fe75cc94a9443b9246fc7049224f75604b113c36acb93f87b80ed42c44cbb898"}, @@ -1493,12 +1468,12 @@ snowballstemmer = [ {file = "snowballstemmer-2.0.0.tar.gz", hash = "sha256:df3bac3df4c2c01363f3dd2cfa78cce2840a79b9f1c2d2de9ce8d31683992f52"}, ] sphinx = [ - {file = "Sphinx-3.1.2-py3-none-any.whl", hash = "sha256:97dbf2e31fc5684bb805104b8ad34434ed70e6c588f6896991b2fdfd2bef8c00"}, - {file = "Sphinx-3.1.2.tar.gz", hash = "sha256:b9daeb9b39aa1ffefc2809b43604109825300300b987a24f45976c001ba1a8fd"}, + {file = "Sphinx-3.2.1-py3-none-any.whl", hash = "sha256:ce6fd7ff5b215af39e2fcd44d4a321f6694b4530b6f2b2109b64d120773faea0"}, + {file = "Sphinx-3.2.1.tar.gz", hash = "sha256:321d6d9b16fa381a5306e5a0b76cd48ffbc588e6340059a729c6fdd66087e0e8"}, ] sphinx-autobuild = [ - {file = "sphinx-autobuild-0.7.1.tar.gz", hash = "sha256:66388f81884666e3821edbe05dd53a0cfb68093873d17320d0610de8db28c74e"}, - {file = "sphinx_autobuild-0.7.1-py2-none-any.whl", hash = "sha256:e60aea0789cab02fa32ee63c7acae5ef41c06f1434d9fd0a74250a61f5994692"}, + {file = "sphinx-autobuild-2020.9.1.tar.gz", hash = "sha256:4b184a7db893f2100bbd831991ae54ca89167a2b9ce68faea71eaa9e37716aed"}, + {file = "sphinx_autobuild-2020.9.1-py3-none-any.whl", hash = "sha256:df5c72cb8b8fc9b31279c4619780c4e95029be6de569ff60a8bb2e99d20f63dd"}, ] sphinxcontrib-applehelp = [ {file = "sphinxcontrib-applehelp-1.0.2.tar.gz", hash = "sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58"}, @@ -1583,16 +1558,9 @@ virtualenv = [ {file = "virtualenv-20.0.26-py2.py3-none-any.whl", hash = "sha256:c11a475400e98450403c0364eb3a2d25d42f71cf1493da64390487b666de4324"}, {file = "virtualenv-20.0.26.tar.gz", hash = "sha256:e10cc66f40cbda459720dfe1d334c4dc15add0d80f09108224f171006a97a172"}, ] -watchdog = [ - {file = "watchdog-0.10.3.tar.gz", hash = "sha256:4214e1379d128b0588021880ccaf40317ee156d4603ac388b9adcf29165e0c04"}, -] -wcwidth = [ - {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"}, - {file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"}, -] xdoctest = [ - {file = "xdoctest-0.13.0-py2.py3-none-any.whl", hash = "sha256:de861fd5230a46bd26c054b4981169dd963f813768cb62b62e104e4d2644ac94"}, - {file = "xdoctest-0.13.0.tar.gz", hash = "sha256:4f113a430076561a9d7f31af65b5d5acda62ee06b05cb6894264cb9efb8196ac"}, + {file = "xdoctest-0.15.0-py2.py3-none-any.whl", hash = "sha256:695ea04303a48cbb319709270d43f7bae7f3de3701aec73f09d90a216499992e"}, + {file = "xdoctest-0.15.0.tar.gz", hash = "sha256:7f0a184d403b69b166ebec1aadb13c98c96c59101e974ae2e4db4c3a803ec371"}, ] zipp = [ {file = "zipp-3.1.0-py3-none-any.whl", hash = "sha256:aa36550ff0c0b7ef7fa639055d797116ee891440eac1a56f378e2d3179e0320b"}, diff --git a/pyproject.toml b/pyproject.toml index fe1e01a4..1c75c904 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,25 +22,25 @@ python = "^3.6.1" nox = "^2020.5.24" [tool.poetry.dev-dependencies] -pytest = "^5.4.3" -coverage = {extras = ["toml"], version = "^5.2"} +pytest = "^6.0.2" +coverage = {extras = ["toml"], version = "^5.3"} safety = "^1.9.0" mypy = "^0.782" typeguard = "^2.9.1" -xdoctest = "^0.13.0" -sphinx = "^3.1.2" -sphinx-autobuild = "^0.7.1" -pre-commit = "^2.6.0" +xdoctest = "^0.15.0" +sphinx = "^3.2.1" +sphinx-autobuild = "^2020.9.1" +pre-commit = "^2.7.1" flake8 = "^3.8.3" -black = "^19.10b0" +black = "^20.8b1" flake8-bandit = "^2.1.2" flake8-bugbear = "^20.1.4" flake8-docstrings = "^1.5.0" flake8-rst-docstrings = "^0.0.13" pep8-naming = "^0.11.1" -darglint = "^1.5.1" -reorder-python-imports = "^2.3.1" -pre-commit-hooks = "^3.1.0" +darglint = "^1.5.4" +reorder-python-imports = "^2.3.5" +pre-commit-hooks = "^3.2.0" [tool.coverage.paths] source = ["src", "*/site-packages"] diff --git a/src/nox_poetry/__init__.py b/src/nox_poetry/__init__.py index 59c861a2..27bc4e49 100644 --- a/src/nox_poetry/__init__.py +++ b/src/nox_poetry/__init__.py @@ -1,8 +1,6 @@ """Using Poetry in Nox sessions.""" -import contextlib -import tempfile +import hashlib from pathlib import Path -from typing import Iterator from nox.sessions import Session @@ -15,34 +13,25 @@ class _Poetry: """ def __init__(self, session: Session) -> None: - """Constructor.""" + """Initialize.""" self.session = session - def install(self, *args: str) -> None: - """Install the dependencies.""" - self.session.run("poetry", "install", *args, external=True) - - @contextlib.contextmanager - def export(self, *args: str) -> Iterator[Path]: + def export(self, path: Path, *, dev: bool) -> None: """Export the lock file to requirements format. Args: - args: Command-line arguments for ``poetry export``. - - Yields: - The path to the requirements file. + path: The destination path. + dev: If True, include development dependencies. """ - with tempfile.TemporaryDirectory() as directory: - requirements = Path(directory) / "requirements.txt" - self.session.run( - "poetry", - "export", - *args, - "--format=requirements.txt", - f"--output={requirements}", - external=True, - ) - yield requirements + options = ["--dev"] if dev else [] + self.session.run( + "poetry", + "export", + "--format=requirements.txt", + f"--output={path}", + *options, + external=True, + ) def build(self, *args: str) -> str: """Build the package. @@ -60,6 +49,31 @@ def build(self, *args: str) -> str: return output.split()[-1] +def export_requirements(session: Session, *, dev: bool) -> Path: + """Export the lock file to requirements format. + + Args: + session: The Session object. + dev: If True, include development dependencies. + + Returns: + The path to the requirements file. + """ + tmpdir = Path(session.create_tmp()) + name = "dev-requirements.txt" if dev else "requirements.txt" + path = tmpdir / name + hashfile = tmpdir / f"{name}.hash" + + lockdata = Path("poetry.lock").read_bytes() + digest = hashlib.blake2b(lockdata).hexdigest() + + if not hashfile.is_file() or hashfile.read_text() != digest: + _Poetry(session).export(path, dev=dev) + hashfile.write_text(digest) + + return path + + def install_package(session: Session) -> None: """Build and install the package. @@ -73,10 +87,10 @@ def install_package(session: Session) -> None: session: The Session object. """ poetry = _Poetry(session) - - poetry.install("--no-root") wheel = poetry.build("--format=wheel") + requirements = export_requirements(session, dev=False) + session.install(f"--requirement={requirements}") session.install("--no-deps", "--force-reinstall", f"dist/{wheel}") @@ -91,6 +105,5 @@ def install(session: Session, *args: str) -> None: session: The Session object. args: Command-line arguments for ``pip install``. """ - poetry = _Poetry(session) - with poetry.export("--dev") as requirements: - session.install(f"--constraint={requirements}", *args) + requirements = export_requirements(session, dev=True) + session.install(f"--constraint={requirements}", *args) diff --git a/tests/test_nox_poetry.py b/tests/test_nox_poetry.py index eb647458..d9fb28f0 100644 --- a/tests/test_nox_poetry.py +++ b/tests/test_nox_poetry.py @@ -19,6 +19,10 @@ def install(self, *args: str, **kargs: Any) -> None: """Install.""" pass + def create_tmp(self, *args: str, **kargs: Any) -> None: + """Create temporary directory.""" + pass + def test_install() -> None: """It installs.""" From 9b6c11a2c670dafbafed0d9fe5746787e5ab56a8 Mon Sep 17 00:00:00 2001 From: Claudio Jolowicz Date: Fri, 25 Sep 2020 16:50:55 +0200 Subject: [PATCH 13/17] Update tests --- tests/test_nox_poetry.py | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/tests/test_nox_poetry.py b/tests/test_nox_poetry.py index d9fb28f0..404c8338 100644 --- a/tests/test_nox_poetry.py +++ b/tests/test_nox_poetry.py @@ -1,9 +1,12 @@ """Tests.""" +from pathlib import Path from typing import Any from typing import cast +import pytest from nox.sessions import Session +from nox_poetry import export_requirements from nox_poetry import install from nox_poetry import install_package @@ -11,6 +14,10 @@ class FakeSession: """Fake session.""" + def __init__(self, tmpdir: Path) -> None: + """Initialize.""" + self.tmpdir = tmpdir + def run(self, *args: str, **kargs: Any) -> str: """Run.""" return "example.whl" @@ -19,18 +26,29 @@ def install(self, *args: str, **kargs: Any) -> None: """Install.""" pass - def create_tmp(self, *args: str, **kargs: Any) -> None: + def create_tmp(self, *args: str, **kargs: Any) -> str: """Create temporary directory.""" - pass + return str(self.tmpdir) + +@pytest.fixture +def session(tmp_path: Path) -> Session: + """Return a fake Nox session.""" + session = FakeSession(tmp_path) + return cast(Session, session) -def test_install() -> None: - """It installs.""" - session = cast(Session, FakeSession()) + +def test_install(session: Session) -> None: + """It installs the dependencies.""" install(session, "pip") -def test_install_package() -> None: - """It installs.""" - session = cast(Session, FakeSession()) +def test_install_package(session: Session) -> None: + """It installs the package.""" install_package(session) + + +def test_export_requirements(session: Session) -> None: + """It exports the requirements.""" + export_requirements(session, dev=True).touch() + export_requirements(session, dev=True) From 53b7baeeab72bc8e9b57941098801ff526bf14ad Mon Sep 17 00:00:00 2001 From: Claudio Jolowicz Date: Fri, 25 Sep 2020 17:53:31 +0200 Subject: [PATCH 14/17] Use package instead of __init__ in API reference --- docs/reference.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/reference.rst b/docs/reference.rst index 794571b7..a4078e5b 100644 --- a/docs/reference.rst +++ b/docs/reference.rst @@ -6,8 +6,8 @@ Reference :backlinks: none -nox_poetry.__init__ -------------------- +nox_poetry +---------- -.. automodule:: nox_poetry.__init__ +.. automodule:: nox_poetry :members: From c89f6f4683df0f51abcfd0f485a3bc49683b419c Mon Sep 17 00:00:00 2001 From: Claudio Jolowicz Date: Fri, 25 Sep 2020 17:54:01 +0200 Subject: [PATCH 15/17] Do not run typeguard by default --- noxfile.py | 1 - 1 file changed, 1 deletion(-) diff --git a/noxfile.py b/noxfile.py index a43acebc..9d996de3 100644 --- a/noxfile.py +++ b/noxfile.py @@ -19,7 +19,6 @@ "safety", "mypy", "tests", - "typeguard", "docs-build", ) From 6812ace89970304941ce45324e56a705c5f8bc31 Mon Sep 17 00:00:00 2001 From: Claudio Jolowicz Date: Fri, 25 Sep 2020 17:56:53 +0200 Subject: [PATCH 16/17] Do not run typeguard in CI --- .github/workflows/tests.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 3c83994d..4f9448be 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -22,7 +22,6 @@ jobs: - { python-version: 3.6, os: ubuntu-latest, session: "tests" } - { python-version: 3.8, os: windows-latest, session: "tests" } - { python-version: 3.8, os: macos-latest, session: "tests" } - - { python-version: 3.8, os: ubuntu-latest, session: "typeguard" } - { python-version: 3.8, os: ubuntu-latest, session: "docs-build" } env: From 1db2324180bcfc9562b332f44ba94d7c9c5ba73c Mon Sep 17 00:00:00 2001 From: Claudio Jolowicz Date: Fri, 25 Sep 2020 18:43:43 +0200 Subject: [PATCH 17/17] Update README.rst --- README.rst | 139 +++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 124 insertions(+), 15 deletions(-) diff --git a/README.rst b/README.rst index ca864783..6196c9ef 100644 --- a/README.rst +++ b/README.rst @@ -33,32 +33,135 @@ nox-poetry :alt: Black -Features --------- +Helper functions for using Poetry_ inside Nox_ sessions -* TODO - -Requirements +Installation ------------ -* TODO +You can install ``nox-poetry`` via pip_ from the Python Package Index: +.. code:: console + + $ pip install nox-poetry -Installation ------------- -You can install *nox-poetry* via pip_ from PyPI_: +**Important:** +This package must be installed into the same environment that Nox is run from. +If you installed Nox using pipx_, +use the following command to install this package into the same environment: .. code:: console - $ pip install nox-poetry + $ pipx inject nox nox-poetry Usage ----- -* TODO +- Use ``nox_poetry.install_package(session)`` to install your own package. +- Use ``nox_poetry.install(session, *args)`` to install third-party packages. +- Packages installed like this must be declared as development dependencies using Poetry. + +For example, the following Nox session runs your test suite: + +.. code:: python + + # noxfile.py + import nox + from nox.sessions import Session + from nox_poetry import install, install_package + + @nox.session + def tests(session: Session) -> None: + """Run the test suite.""" + install_package(session) + install(session, "pytest") + session.run("pytest", *session.posargs) + + +Why? +---- + +Compare the session above to one written without this package: + +.. code:: python + + @nox.session + def tests(session: Session) -> None: + """Run the test suite.""" + session.install(".") + session.install("pytest") + session.run("pytest", *session.posargs) + +This session has several problems: + +- Poetry is installed as a build backend every time. +- Package dependencies are only constrained by the wheel metadata, not by the lock file (*pinned*). +- The ``pytest`` dependency is not constrained at all. + +You can solve these issues by declaring ``pytest`` as a development dependency, +and installing your package and its dependencies using ``poetry install``: + +.. code:: python + + @nox.session + def tests(session: Session) -> None: + """Run the test suite.""" + session.run("poetry", "install", external=True) + session.run("pytest", *session.posargs) + +Unfortunately, this approach creates problems of its own: + +- Checks run against an editable installation of your package, + i.e. your local copy of the code, instead of the installed wheel your users see. +- The package is installed, as well as all of its core and development dependencies. + This is wasteful when you only need to run ``black`` or ``flake8``. + It also goes against the idea of running checks in isolated environments. +- Poetry may decide to install packages into its own virtual environment instead of the one provided by Nox. + +``nox-poetry`` uses a third approach. +Third-party packages are installed by exporting the lock file in ``requirements.txt`` format, +and passing it as a `constraints file`_ to pip. +When installing your own package, Poetry is used to build a wheel, which is then installed by pip. +This approach has some advantages: + +- You can declare tools like ``pytest`` as development dependencies in Poetry. +- Dependencies are pinned by Poetry's lock file, making checks predictable and deterministic. +- You can run checks against an installed wheel, instead of your local copy of the code. +- Every tool can run in an isolated environment with minimal dependencies. +- No need to install your package with all its dependencies if all you need is some linter. + +For more details, take a look at `this article`__. + +__ https://cjolowicz.github.io/posts/hypermodern-python-03-linting/#managing-dependencies-in-nox-sessions-with-poetry + + +API +--- + +``nox_poetry.install(session, *args)``: + Install development dependencies into a Nox session using Poetry. + + The ``nox_poetry.install`` function + installs development dependencies into a Nox session, + using the versions specified in Poetry's lock file. + The function arguments are the same as those for `nox.sessions.Session.install`_: + The first argument is the ``Session`` object, + and the remaining arguments are command-line arguments for `pip install`_, + typically just the package or packages to be installed. + +``nox_poetry.install_package(session)``: + Install the package into a Nox session using Poetry. + + The ``nox_poetry.install_package`` function + installs your package into a Nox session, + including the core dependencies as specified in Poetry's lock file. + This is done by building a wheel from the package, + and installing it using pip_. + Dependencies are installed in the same way as in the ``nox_poetry.install`` function, + i.e. using a constraints file. + Its only argument is the ``Session`` object from Nox. Contributing @@ -71,8 +174,8 @@ To learn more, see the `Contributor Guide`_. License ------- -Distributed under the terms of the MIT_ license, -*nox-poetry* is free and open source software. +``nox-poetry`` is free and open source software, +distributed under the terms of the MIT_ license. Issues @@ -90,10 +193,16 @@ This project was generated from `@cjolowicz`_'s `Hypermodern Python Cookiecutter .. _@cjolowicz: https://github.com/cjolowicz .. _Cookiecutter: https://github.com/audreyr/cookiecutter -.. _MIT: http://opensource.org/licenses/MIT -.. _PyPI: https://pypi.org/ .. _Hypermodern Python Cookiecutter: https://github.com/cjolowicz/cookiecutter-hypermodern-python +.. _MIT: http://opensource.org/licenses/MIT +.. _Nox: https://nox.thea.codes/ +.. _Poetry: https://python-poetry.org/ +.. _constraints file: https://pip.pypa.io/en/stable/user_guide/#constraints-files .. _file an issue: https://github.com/cjolowicz/nox-poetry/issues +.. _nox.sessions.Session.install: https://nox.thea.codes/en/stable/config.html#nox.sessions.Session.install +.. _nox.sessions.Session.run: https://nox.thea.codes/en/stable/config.html#nox.sessions.Session.run +.. _pip install: https://pip.pypa.io/en/stable/reference/pip_install/ .. _pip: https://pip.pypa.io/ +.. _pipx: https://pipxproject.github.io/pipx/ .. github-only .. _Contributor Guide: CONTRIBUTING.rst