├── .darglint ├── .flake8 ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── dependabot.yml ├── labels.yml ├── release-drafter.yml └── workflows │ ├── constraints.txt │ ├── dependabot-auto-merge.yml │ ├── issues.yml │ ├── labeler.yml │ ├── pre-release.yml │ ├── release-please.yml │ ├── release.yml │ └── tests.yml ├── .gitignore ├── .pre-commit-config.yaml ├── .prettierignore ├── .readthedocs.yml ├── CHANGELOG.md ├── CODE_OF_CONDUCT.rst ├── CONTRIBUTING.rst ├── LICENSE.rst ├── README.rst ├── codecov.yml ├── docs ├── codeofconduct.rst ├── conf.py ├── contributing.rst ├── index.rst ├── license.rst ├── reference.rst ├── requirements.txt └── usage.rst ├── noxfile.py ├── poetry.lock ├── pyproject.toml ├── src └── pydantic_pynamodb │ ├── __init__.py │ └── py.typed └── tests ├── __init__.py └── test_model.py /.darglint: -------------------------------------------------------------------------------- 1 | [darglint] 2 | strictness = long 3 | -------------------------------------------------------------------------------- /.flake8: -------------------------------------------------------------------------------- 1 | 2 | [flake8] 3 | # Eventually would add D and DAR 4 | select = B,B9,C,E,F,N,RST,S,W 5 | ignore = E203,E501,RST201,RST203,RST301,W503,B902,N805,DAR402 6 | max-line-length = 119 7 | max-complexity = 10 8 | docstring-convention = google 9 | per-file-ignores = tests/*:S101 10 | rst-roles = class,const,func,meth,mod,ref 11 | rst-directives = deprecated 12 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "" 5 | labels: "" 6 | assignees: "" 7 | --- 8 | 9 | **Describe the bug** 10 | A clear and concise description of what the bug is. 11 | 12 | **To Reproduce** 13 | Steps to reproduce the behavior: 14 | 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | 28 | - OS: [e.g. iOS] 29 | - Browser [e.g. chrome, safari] 30 | - Version [e.g. 22] 31 | 32 | **Smartphone (please complete the following information):** 33 | 34 | - Device: [e.g. iPhone6] 35 | - OS: [e.g. iOS8.1] 36 | - Browser [e.g. stock browser, safari] 37 | - Version [e.g. 22] 38 | 39 | **Additional context** 40 | Add any other context about the problem here. 41 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: "" 5 | labels: "" 6 | assignees: "" 7 | --- 8 | 9 | **Is your feature request related to a problem? Please describe.** 10 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 11 | 12 | **Describe the solution you'd like** 13 | A clear and concise description of what you want to happen. 14 | 15 | **Describe alternatives you've considered** 16 | A clear and concise description of any alternative solutions or features you've considered. 17 | 18 | **Additional context** 19 | Add any other context or screenshots about the feature request here. 20 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: github-actions 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | commit-message: 8 | prefix: ci 9 | - package-ecosystem: pip 10 | directory: "/.github/workflows" 11 | schedule: 12 | interval: daily 13 | commit-message: 14 | prefix: ci 15 | - package-ecosystem: pip 16 | directory: "/docs" 17 | schedule: 18 | interval: daily 19 | commit-message: 20 | prefix: docs 21 | - package-ecosystem: pip 22 | directory: "/" 23 | schedule: 24 | interval: daily 25 | commit-message: 26 | prefix: deps 27 | 28 | -------------------------------------------------------------------------------- /.github/labels.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Labels names are important as they are used by Release Drafter to decide 3 | # regarding where to record them in changelog or if to skip them. 4 | # 5 | # The repository labels will be automatically configured using this file and 6 | # the GitHub Action https://github.com/marketplace/actions/github-labeler. 7 | - name: breaking 8 | description: Breaking Changes 9 | color: bfd4f2 10 | - name: bug 11 | description: Something isn't working 12 | color: d73a4a 13 | - name: build 14 | description: Build System and Dependencies 15 | color: bfdadc 16 | - name: ci 17 | description: Continuous Integration 18 | color: 4a97d6 19 | - name: dependencies 20 | description: Pull requests that update a dependency file 21 | color: 0366d6 22 | - name: documentation 23 | description: Improvements or additions to documentation 24 | color: 0075ca 25 | - name: duplicate 26 | description: This issue or pull request already exists 27 | color: cfd3d7 28 | - name: enhancement 29 | description: New feature or request 30 | color: a2eeef 31 | - name: github_actions 32 | description: Pull requests that update Github_actions code 33 | color: "000000" 34 | - name: good first issue 35 | description: Good for newcomers 36 | color: 7057ff 37 | - name: help wanted 38 | description: Extra attention is needed 39 | color: 008672 40 | - name: invalid 41 | description: This doesn't seem right 42 | color: e4e669 43 | - name: performance 44 | description: Performance 45 | color: "016175" 46 | - name: python 47 | description: Pull requests that update Python code 48 | color: 2b67c6 49 | - name: question 50 | description: Further information is requested 51 | color: d876e3 52 | - name: refactoring 53 | description: Refactoring 54 | color: ef67c4 55 | - name: removal 56 | description: Removals and Deprecations 57 | color: 9ae7ea 58 | - name: style 59 | description: Style 60 | color: c120e5 61 | - name: testing 62 | description: Testing 63 | color: b1fc6f 64 | - name: wontfix 65 | description: This will not be worked on 66 | color: ffffff 67 | -------------------------------------------------------------------------------- /.github/release-drafter.yml: -------------------------------------------------------------------------------- 1 | categories: 2 | - title: ":boom: Breaking Changes" 3 | label: "breaking" 4 | - title: ":rocket: Features" 5 | label: "enhancement" 6 | - title: ":fire: Removals and Deprecations" 7 | label: "removal" 8 | - title: ":beetle: Fixes" 9 | label: "bug" 10 | - title: ":racehorse: Performance" 11 | label: "performance" 12 | - title: ":rotating_light: Testing" 13 | label: "testing" 14 | - title: ":construction_worker: Continuous Integration" 15 | label: "ci" 16 | - title: ":books: Documentation" 17 | label: "documentation" 18 | - title: ":hammer: Refactoring" 19 | label: "refactoring" 20 | - title: ":lipstick: Style" 21 | label: "style" 22 | - title: ":package: Dependencies" 23 | labels: 24 | - "dependencies" 25 | - "build" 26 | template: | 27 | ## Changes 28 | 29 | $CHANGES 30 | -------------------------------------------------------------------------------- /.github/workflows/constraints.txt: -------------------------------------------------------------------------------- 1 | pip==23.1.2 2 | nox==2023.4.22 3 | nox-poetry==1.0.3 4 | poetry==1.4.2 5 | virtualenv==20.21.0 6 | -------------------------------------------------------------------------------- /.github/workflows/dependabot-auto-merge.yml: -------------------------------------------------------------------------------- 1 | name: Auto Merge Dependabot 2 | 3 | on: 4 | pull_request: 5 | 6 | jobs: 7 | auto-merge: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v3 11 | - uses: ahmadnassri/action-dependabot-auto-merge@v2 12 | with: 13 | target: minor 14 | github-token: ${{ secrets.THIS_PAT }} 15 | -------------------------------------------------------------------------------- /.github/workflows/issues.yml: -------------------------------------------------------------------------------- 1 | name: Issues to Discord 2 | on: 3 | issues: 4 | types: 5 | - opened 6 | - reopened 7 | - deleted 8 | - closed 9 | jobs: 10 | issue-to-discord: 11 | name: issue-to-discord 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: Post to discord 15 | uses: Ilshidur/action-discord@0.3.2 16 | env: 17 | DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK_ISSUES }} 18 | ACTION: ${{ github.event.action }} 19 | REPO: ${{ github.repository }} 20 | ISSUE_URL: ${{ github.event.issue.html_url }} 21 | ISSUE_USER: ${{ github.event.issue.user.login }} 22 | with: 23 | args: "{{ REPO }} had an issue {{ ACTION }} by {{ ISSUE_USER }} at {{ ISSUE_URL }}." 24 | -------------------------------------------------------------------------------- /.github/workflows/labeler.yml: -------------------------------------------------------------------------------- 1 | name: Labeler 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | labeler: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Check out the repository 13 | uses: actions/checkout@v3.0.2 14 | 15 | - name: Run Labeler 16 | uses: crazy-max/ghaction-github-labeler@v4.0.0 17 | with: 18 | skip-delete: true 19 | -------------------------------------------------------------------------------- /.github/workflows/pre-release.yml: -------------------------------------------------------------------------------- 1 | name: Pre-release to pypi 2 | 3 | on: 4 | release: 5 | types: [prereleased] 6 | 7 | jobs: 8 | release: 9 | name: Release 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Check out the repository 13 | uses: actions/checkout@v3.0.2 14 | with: 15 | fetch-depth: 2 16 | 17 | - name: Set up Python 18 | uses: actions/setup-python@v4.2.0 19 | with: 20 | python-version: "3.10" 21 | 22 | - name: Upgrade pip 23 | run: | 24 | pip install --constraint=.github/workflows/constraints.txt pip 25 | pip --version 26 | 27 | - name: Install Poetry 28 | run: | 29 | pip install --constraint=.github/workflows/constraints.txt poetry poetry-dynamic-versioning 30 | poetry --version 31 | 32 | - name: Build package 33 | run: | 34 | poetry build --ansi 35 | 36 | - name: Publish package on TestPyPI 37 | uses: pypa/gh-action-pypi-publish@v1.5.0 38 | with: 39 | user: __token__ 40 | password: ${{ secrets.TEST_PYPI_TOKEN }} 41 | repository_url: https://test.pypi.org/legacy/ 42 | -------------------------------------------------------------------------------- /.github/workflows/release-please.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - main 5 | name: release-please 6 | jobs: 7 | release-please: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: google-github-actions/release-please-action@v3 11 | with: 12 | token: ${{ secrets.THIS_PAT }} 13 | release-type: python 14 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release to pypi 2 | 3 | on: 4 | release: 5 | types: [released] 6 | 7 | jobs: 8 | release: 9 | name: Release 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Check out the repository 13 | uses: actions/checkout@v3.0.2 14 | with: 15 | fetch-depth: 2 16 | - name: Set up Python 17 | uses: actions/setup-python@v4.2.0 18 | with: 19 | python-version: "3.10" 20 | 21 | - name: Upgrade pip 22 | run: | 23 | pip install --constraint=.github/workflows/constraints.txt pip 24 | pip --version 25 | 26 | - name: Install Poetry 27 | run: | 28 | pip install --constraint=.github/workflows/constraints.txt poetry poetry-dynamic-versioning 29 | poetry --version 30 | 31 | - name: Build package 32 | run: | 33 | poetry build --ansi 34 | 35 | - name: Publish package on PyPI 36 | uses: pypa/gh-action-pypi-publish@v1.5.0 37 | with: 38 | user: __token__ 39 | password: ${{ secrets.PYPI_TOKEN }} 40 | -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | 3 | on: 4 | - push 5 | 6 | jobs: 7 | tests: 8 | name: ${{ matrix.session }} ${{ matrix.python }} / ${{ matrix.os }} 9 | runs-on: ${{ matrix.os }} 10 | strategy: 11 | fail-fast: false 12 | matrix: 13 | include: 14 | - { python: "3.10", os: "ubuntu-latest", session: "pre-commit" } 15 | - { python: "3.10", os: "ubuntu-latest", session: "safety" } 16 | # - { python: "3.10", os: "ubuntu-latest", session: "mypy" } 17 | # - { python: "3.9", os: "ubuntu-latest", session: "mypy" } 18 | # - { python: "3.8", os: "ubuntu-latest", session: "mypy" } 19 | # - { python: "3.7", os: "ubuntu-latest", session: "mypy" } 20 | - { python: "3.10", os: "ubuntu-latest", session: "tests" } 21 | - { python: "3.11", os: "ubuntu-latest", session: "tests" } 22 | - { python: "3.9", os: "ubuntu-latest", session: "tests" } 23 | - { python: "3.8", os: "ubuntu-latest", session: "tests" } 24 | - { python: "3.7", os: "ubuntu-latest", session: "tests" } 25 | # - { python: "3.10", os: "windows-latest", session: "tests" } 26 | # - { python: "3.10", os: "macos-latest", session: "tests" } 27 | # - { python: "3.10", os: "ubuntu-latest", session: "typeguard" } 28 | - { python: "3.10", os: "ubuntu-latest", session: "xdoctest" } 29 | - { python: "3.10", os: "ubuntu-latest", session: "docs-build" } 30 | 31 | env: 32 | NOXSESSION: ${{ matrix.session }} 33 | FORCE_COLOR: "1" 34 | PRE_COMMIT_COLOR: "always" 35 | 36 | steps: 37 | - name: Check out the repository 38 | uses: actions/checkout@v3.0.2 39 | 40 | - name: Set up Python ${{ matrix.python }} 41 | uses: actions/setup-python@v4.1.0 42 | with: 43 | python-version: ${{ matrix.python }} 44 | 45 | - name: Upgrade pip 46 | run: | 47 | pip install --constraint=.github/workflows/constraints.txt pip 48 | pip --version 49 | 50 | - name: Upgrade pip in virtual environments 51 | shell: python 52 | run: | 53 | import os 54 | import pip 55 | 56 | with open(os.environ["GITHUB_ENV"], mode="a") as io: 57 | print(f"VIRTUALENV_PIP={pip.__version__}", file=io) 58 | 59 | - name: Install Poetry 60 | run: | 61 | pipx install --pip-args=--constraint=.github/workflows/constraints.txt poetry 62 | poetry --version 63 | 64 | - name: Install Nox 65 | run: | 66 | pipx install --pip-args=--constraint=.github/workflows/constraints.txt nox 67 | pipx inject --pip-args=--constraint=.github/workflows/constraints.txt nox nox-poetry 68 | nox --version 69 | 70 | - name: Compute pre-commit cache key 71 | if: matrix.session == 'pre-commit' 72 | id: pre-commit-cache 73 | shell: python 74 | run: | 75 | import hashlib 76 | import sys 77 | import os 78 | 79 | python = "py{}.{}".format(*sys.version_info[:2]) 80 | payload = sys.version.encode() + sys.executable.encode() 81 | digest = hashlib.sha256(payload).hexdigest() 82 | result = "${{ runner.os }}-{}-{}-pre-commit".format(python, digest[:8]) 83 | 84 | with open(os.environ['GITHUB_OUTPUT'], 'a') as fh: 85 | fh.write(f"result={result}\n") 86 | 87 | - name: Restore pre-commit cache 88 | uses: actions/cache@v3.0.5 89 | if: matrix.session == 'pre-commit' 90 | with: 91 | path: ~/.cache/pre-commit 92 | key: ${{ steps.pre-commit-cache.outputs.result }}-${{ hashFiles('.pre-commit-config.yaml') }} 93 | restore-keys: | 94 | ${{ steps.pre-commit-cache.outputs.result }}- 95 | 96 | - name: Run Nox 97 | run: | 98 | nox --force-color --python=${{ matrix.python }} 99 | 100 | - name: Upload coverage data 101 | if: always() && matrix.session == 'tests' 102 | uses: "actions/upload-artifact@v3.1.0" 103 | with: 104 | name: coverage-data 105 | path: ".coverage.*" 106 | 107 | - name: Upload documentation 108 | if: matrix.session == 'docs-build' 109 | uses: actions/upload-artifact@v3.1.0 110 | with: 111 | name: docs 112 | path: docs/_build 113 | 114 | coverage: 115 | runs-on: ubuntu-latest 116 | needs: tests 117 | steps: 118 | - name: Check out the repository 119 | uses: actions/checkout@v3.0.2 120 | 121 | - name: Set up Python 122 | uses: actions/setup-python@v4.2.0 123 | with: 124 | python-version: "3.10" 125 | 126 | - name: Upgrade pip 127 | run: | 128 | pip install --constraint=.github/workflows/constraints.txt pip 129 | pip --version 130 | 131 | - name: Install Poetry 132 | run: | 133 | pipx install --pip-args=--constraint=.github/workflows/constraints.txt poetry 134 | poetry --version 135 | 136 | - name: Install Nox 137 | run: | 138 | pipx install --pip-args=--constraint=.github/workflows/constraints.txt nox 139 | pipx inject --pip-args=--constraint=.github/workflows/constraints.txt nox nox-poetry 140 | nox --version 141 | 142 | - name: Download coverage data 143 | uses: actions/download-artifact@v3.0.0 144 | with: 145 | name: coverage-data 146 | 147 | - name: Upload coverage report 148 | uses: codecov/codecov-action@v3.1.0 149 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ 130 | 131 | .vscode 132 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: local 3 | hooks: 4 | - id: black 5 | name: black 6 | entry: black 7 | language: system 8 | types: [python] 9 | require_serial: true 10 | - id: check-added-large-files 11 | name: Check for added large files 12 | entry: check-added-large-files 13 | language: system 14 | - id: check-toml 15 | name: Check Toml 16 | entry: check-toml 17 | language: system 18 | types: [toml] 19 | - id: check-yaml 20 | name: Check Yaml 21 | entry: check-yaml 22 | language: system 23 | types: [yaml] 24 | - id: end-of-file-fixer 25 | name: Fix End of Files 26 | entry: end-of-file-fixer 27 | language: system 28 | types: [text] 29 | stages: [commit, push, manual] 30 | - id: flake8 31 | name: flake8 32 | entry: flake8 33 | language: system 34 | types: [python] 35 | exclude: "^(test/*|examples/*|noxfile.py)" 36 | require_serial: true 37 | args: ["--config=.flake8"] 38 | - id: pyupgrade 39 | name: pyupgrade 40 | description: Automatically upgrade syntax for newer versions. 41 | entry: pyupgrade 42 | language: system 43 | types: [python] 44 | args: [--py37-plus] 45 | - id: reorder-python-imports 46 | name: Reorder python imports 47 | entry: reorder-python-imports 48 | language: system 49 | types: [python] 50 | args: [--application-directories=src] 51 | - id: trailing-whitespace 52 | name: Trim Trailing Whitespace 53 | entry: trailing-whitespace-fixer 54 | language: system 55 | types: [text] 56 | stages: [commit, push, manual] 57 | - repo: https://github.com/pre-commit/mirrors-prettier 58 | rev: v2.7.1 59 | hooks: 60 | - id: prettier 61 | - repo: https://github.com/rhysd/actionlint 62 | rev: v1.6.15 63 | hooks: 64 | - id: actionlint-docker 65 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | .github/* 2 | CHANGELOG.md 3 | -------------------------------------------------------------------------------- /.readthedocs.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | build: 3 | os: ubuntu-20.04 4 | tools: 5 | python: "3.10" 6 | sphinx: 7 | configuration: docs/conf.py 8 | formats: all 9 | python: 10 | install: 11 | - requirements: docs/requirements.txt 12 | - path: . 13 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [0.1.0](https://github.com/andrewthetechie/pydantic-pynamodb/compare/v0.0.8...v0.1.0) (2023-02-16) 4 | 5 | 6 | ### Features 7 | 8 | * py3.11 support ([#388](https://github.com/andrewthetechie/pydantic-pynamodb/issues/388)) ([c1e7080](https://github.com/andrewthetechie/pydantic-pynamodb/commit/c1e7080869bd9d9dc478f353075ac46eead3c763)) 9 | 10 | ## [0.0.8](https://github.com/andrewthetechie/pydantic-pynamodb/compare/v0.0.7...v0.0.8) (2022-09-13) 11 | 12 | 13 | ### Bug Fixes 14 | 15 | * trigger release with updated dependencies ([e153e3c](https://github.com/andrewthetechie/pydantic-pynamodb/commit/e153e3c6cd762885f5ec80a3b66ae1d6b7ebf12f)) 16 | 17 | ## [0.0.7](https://github.com/andrewthetechie/pydantic-pynamodb/compare/v0.0.6...v0.0.7) (2022-09-13) 18 | 19 | 20 | ### Bug Fixes 21 | 22 | * trigger release with updated dependencies ([253b09b](https://github.com/andrewthetechie/pydantic-pynamodb/commit/253b09bba20efc77d5521742c91da9e8ac717ad1)) 23 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.rst: -------------------------------------------------------------------------------- 1 | Contributor Covenant Code of Conduct 2 | ==================================== 3 | 4 | Our Pledge 5 | ---------- 6 | 7 | We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. 8 | 9 | We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. 10 | 11 | 12 | Our Standards 13 | ------------- 14 | 15 | Examples of behavior that contributes to a positive environment for our community include: 16 | 17 | - Demonstrating empathy and kindness toward other people 18 | - Being respectful of differing opinions, viewpoints, and experiences 19 | - Giving and gracefully accepting constructive feedback 20 | - Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience 21 | - Focusing on what is best not just for us as individuals, but for the overall community 22 | 23 | Examples of unacceptable behavior include: 24 | 25 | - The use of sexualized language or imagery, and sexual attention or 26 | advances of any kind 27 | - Trolling, insulting or derogatory comments, and personal or political attacks 28 | - Public or private harassment 29 | - Publishing others' private information, such as a physical or email 30 | address, without their explicit permission 31 | - Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | Enforcement Responsibilities 35 | ---------------------------- 36 | 37 | Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful. 38 | 39 | Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate. 40 | 41 | 42 | Scope 43 | ----- 44 | 45 | This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. 46 | 47 | 48 | Enforcement 49 | ----------- 50 | 51 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at andrew.the.techie@gmail.com. All complaints will be reviewed and investigated promptly and fairly. 52 | 53 | All community leaders are obligated to respect the privacy and security of the reporter of any incident. 54 | 55 | 56 | Enforcement Guidelines 57 | ---------------------- 58 | 59 | Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct: 60 | 61 | 62 | 1. Correction 63 | ~~~~~~~~~~~~~ 64 | 65 | **Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community. 66 | 67 | **Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested. 68 | 69 | 70 | 2. Warning 71 | ~~~~~~~~~~ 72 | 73 | **Community Impact**: A violation through a single incident or series of actions. 74 | 75 | **Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban. 76 | 77 | 78 | 3. Temporary Ban 79 | ~~~~~~~~~~~~~~~~ 80 | 81 | **Community Impact**: A serious violation of community standards, including sustained inappropriate behavior. 82 | 83 | **Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. 84 | 85 | 86 | 4. Permanent Ban 87 | ~~~~~~~~~~~~~~~~ 88 | 89 | **Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. 90 | 91 | **Consequence**: A permanent ban from any sort of public interaction within the community. 92 | 93 | 94 | Attribution 95 | ----------- 96 | 97 | This Code of Conduct is adapted from the `Contributor Covenant `__, version 2.0, 98 | available at https://www.contributor-covenant.org/version/2/0/code_of_conduct/. 99 | 100 | Community Impact Guidelines were inspired by `Mozilla’s code of conduct enforcement ladder `__. 101 | 102 | .. _homepage: https://www.contributor-covenant.org 103 | 104 | For answers to common questions about this code of conduct, see the FAQ at 105 | https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations. 106 | -------------------------------------------------------------------------------- /CONTRIBUTING.rst: -------------------------------------------------------------------------------- 1 | Contributor Guide 2 | ================= 3 | 4 | Thank you for your interest in improving this project. 5 | This project is open-source under the `MIT license`_ and 6 | welcomes contributions in the form of bug reports, feature requests, and pull requests. 7 | 8 | Here is a list of important resources for contributors: 9 | 10 | - `Source Code`_ 11 | - `Documentation`_ 12 | - `Issue Tracker`_ 13 | - `Code of Conduct`_ 14 | 15 | .. _MIT license: https://opensource.org/licenses/MIT 16 | .. _Source Code: https://github.com/andrewthetechie/pydantic-pynamodb 17 | .. _Documentation: https://pydantic-pynamodb.readthedocs.io/ 18 | .. _Issue Tracker: https://github.com/andrewthetechie/pydantic-pynamodb/issues 19 | 20 | How to report a bug 21 | ------------------- 22 | 23 | Report bugs on the `Issue Tracker`_. 24 | 25 | When filing an issue, make sure to answer these questions: 26 | 27 | - Which operating system and Python version are you using? 28 | - Which version of this project are you using? 29 | - What did you do? 30 | - What did you expect to see? 31 | - What did you see instead? 32 | 33 | The best way to get your bug fixed is to provide a test case, 34 | and/or steps to reproduce the issue. 35 | 36 | 37 | How to request a feature 38 | ------------------------ 39 | 40 | Request features on the `Issue Tracker`_. 41 | 42 | 43 | How to set up your development environment 44 | ------------------------------------------ 45 | 46 | You need Python 3.7+ and the following tools: 47 | 48 | - Poetry_ 49 | - Nox_ 50 | - nox-poetry_ 51 | 52 | Install the package with development requirements: 53 | 54 | .. code:: console 55 | 56 | $ poetry install 57 | 58 | You can now run an interactive Python session, 59 | or the command-line interface: 60 | 61 | .. code:: console 62 | 63 | $ poetry run python 64 | $ poetry run pydantic-pynamodb 65 | 66 | .. _Poetry: https://python-poetry.org/ 67 | .. _Nox: https://nox.thea.codes/ 68 | .. _nox-poetry: https://nox-poetry.readthedocs.io/ 69 | 70 | 71 | How to test the project 72 | ----------------------- 73 | 74 | Run the full test suite: 75 | 76 | .. code:: console 77 | 78 | $ nox 79 | 80 | List the available Nox sessions: 81 | 82 | .. code:: console 83 | 84 | $ nox --list-sessions 85 | 86 | You can also run a specific Nox session. 87 | For example, invoke the unit test suite like this: 88 | 89 | .. code:: console 90 | 91 | $ nox --session=tests 92 | 93 | Unit tests are located in the ``tests`` directory, 94 | and are written using the pytest_ testing framework. 95 | 96 | .. _pytest: https://pytest.readthedocs.io/ 97 | 98 | 99 | How to submit changes 100 | --------------------- 101 | 102 | Open a `pull request`_ to submit changes to this project. 103 | 104 | Your pull request needs to meet the following guidelines for acceptance: 105 | 106 | - The Nox test suite must pass without errors and warnings. 107 | - Include unit tests. This project maintains 100% code coverage. 108 | - If your changes add functionality, update the documentation accordingly. 109 | 110 | Feel free to submit early, though—we can always iterate on this. 111 | 112 | To run linting and code formatting checks before committing your change, you can install pre-commit as a Git hook by running the following command: 113 | 114 | .. code:: console 115 | 116 | $ nox --session=pre-commit -- install 117 | 118 | It is recommended to open an issue before starting work on anything. 119 | This will allow a chance to talk it over with the owners and validate your approach. 120 | 121 | .. _pull request: https://github.com/andrewthetechie/pydantic-pynamodb/pulls 122 | .. github-only 123 | .. _Code of Conduct: CODE_OF_CONDUCT.rst 124 | -------------------------------------------------------------------------------- /LICENSE.rst: -------------------------------------------------------------------------------- 1 | MIT License 2 | =========== 3 | 4 | Copyright © 2022 Andrew Herrington 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | **The software is provided "as is", without warranty of any kind, express or 17 | implied, including but not limited to the warranties of merchantability, 18 | fitness for a particular purpose and noninfringement. In no event shall the 19 | authors or copyright holders be liable for any claim, damages or other 20 | liability, whether in an action of contract, tort or otherwise, arising from, 21 | out of or in connection with the software or the use or other dealings in the 22 | software.** 23 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | Pydantic Pynamodb 2 | ================= 3 | 4 | |PyPI| |Status| |Python Version| |License| 5 | 6 | |Read the Docs| |Tests| |Codecov| 7 | 8 | |pre-commit| |Black| 9 | 10 | .. |PyPI| image:: https://img.shields.io/pypi/v/pydantic-pynamodb.svg 11 | :target: https://pypi.org/project/pydantic-pynamodb/ 12 | :alt: PyPI 13 | .. |Status| image:: https://img.shields.io/pypi/status/pydantic-pynamodb.svg 14 | :target: https://pypi.org/project/pydantic-pynamodb/ 15 | :alt: Status 16 | .. |Python Version| image:: https://img.shields.io/pypi/pyversions/pydantic-pynamodb 17 | :target: https://pypi.org/project/pydantic-pynamodb 18 | :alt: Python Version 19 | .. |License| image:: https://img.shields.io/pypi/l/pydantic-pynamodb 20 | :target: https://opensource.org/licenses/MIT 21 | :alt: License 22 | .. |Read the Docs| image:: https://img.shields.io/readthedocs/pydantic-pynamodb/latest.svg?label=Read%20the%20Docs 23 | :target: https://pydantic-pynamodb.readthedocs.io/ 24 | :alt: Read the documentation at https://pydantic-pynamodb.readthedocs.io/ 25 | .. |Tests| image:: https://github.com/andrewthetechie/pydantic-pynamodb/workflows/Tests/badge.svg 26 | :target: https://github.com/andrewthetechie/pydantic-pynamodb/actions?workflow=Tests 27 | :alt: Tests 28 | .. |Codecov| image:: https://codecov.io/gh/andrewthetechie/pydantic-pynamodb/branch/main/graph/badge.svg 29 | :target: https://app.codecov.io/gh/andrewthetechie/pydantic-pynamodb 30 | :alt: Codecov 31 | .. |pre-commit| image:: https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white 32 | :target: https://github.com/pre-commit/pre-commit 33 | :alt: pre-commit 34 | .. |Black| image:: https://img.shields.io/badge/code%20style-black-000000.svg 35 | :target: https://github.com/psf/black 36 | :alt: Black 37 | 38 | Wrap pynamo models in pydantic schemas to make them easy to work with in FastAPI. 39 | 40 | Features 41 | -------- 42 | 43 | * TODO 44 | 45 | 46 | Requirements 47 | ------------ 48 | 49 | * pydantic 50 | * pynamodb 51 | 52 | 53 | Installation 54 | ------------ 55 | 56 | You can install *Pydantic Pynamodb* via pip_ from PyPI_: 57 | 58 | .. code:: console 59 | 60 | $ pip install pydantic-pynamodb 61 | 62 | 63 | Usage 64 | ----- 65 | 66 | Please see the `Command-line Reference `_ for details. 67 | 68 | 69 | Contributing 70 | ------------ 71 | 72 | Contributions are very welcome. 73 | To learn more, see the `Contributor Guide`_. 74 | 75 | 76 | License 77 | ------- 78 | 79 | Distributed under the terms of the `MIT license`_, 80 | *Pydantic Pynamodb* is free and open source software. 81 | 82 | 83 | Issues 84 | ------ 85 | 86 | If you encounter any problems, 87 | please `file an issue`_ along with a detailed description. 88 | 89 | 90 | Credits 91 | ------- 92 | 93 | This project was generated from `@cjolowicz`_'s `Hypermodern Python Cookiecutter`_ template. 94 | 95 | .. _@cjolowicz: https://github.com/cjolowicz 96 | .. _Cookiecutter: https://github.com/audreyr/cookiecutter 97 | .. _MIT license: https://opensource.org/licenses/MIT 98 | .. _PyPI: https://pypi.org/ 99 | .. _Hypermodern Python Cookiecutter: https://github.com/cjolowicz/cookiecutter-hypermodern-python 100 | .. _file an issue: https://github.com/andrewthetechie/pydantic-pynamodb/issues 101 | .. _pip: https://pip.pypa.io/ 102 | .. github-only 103 | .. _Contributor Guide: https://pydantic-pynamodb.readthedocs.io/en/latest/contributing.html 104 | .. _Usage: https://pydantic-pynamodb.readthedocs.io/en/latest/usage.html 105 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | comment: true 2 | coverage: 3 | status: 4 | project: 5 | default: 6 | target: "45" 7 | patch: 8 | default: 9 | target: "45" 10 | -------------------------------------------------------------------------------- /docs/codeofconduct.rst: -------------------------------------------------------------------------------- 1 | .. include:: ../CODE_OF_CONDUCT.rst 2 | -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | """Sphinx configuration.""" 2 | project = "Pydantic Pynamodb" 3 | author = "Andrew Herrington" 4 | copyright = "2022, Andrew Herrington" 5 | extensions = ["sphinx.ext.autodoc", "sphinx.ext.napoleon"] 6 | autodoc_typehints = "description" 7 | html_theme = "furo" 8 | -------------------------------------------------------------------------------- /docs/contributing.rst: -------------------------------------------------------------------------------- 1 | .. include:: ../CONTRIBUTING.rst 2 | :end-before: github-only 3 | 4 | .. _Code of Conduct: codeofconduct.html 5 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | .. include:: ../README.rst 2 | :end-before: github-only 3 | 4 | .. _Contributor Guide: contributing.html 5 | .. _Usage: usage.html 6 | 7 | .. toctree:: 8 | :hidden: 9 | :maxdepth: 1 10 | 11 | usage 12 | reference 13 | contributing 14 | Code of Conduct 15 | License 16 | Changelog 17 | -------------------------------------------------------------------------------- /docs/license.rst: -------------------------------------------------------------------------------- 1 | .. include:: ../LICENSE.rst 2 | -------------------------------------------------------------------------------- /docs/reference.rst: -------------------------------------------------------------------------------- 1 | Reference 2 | ========= 3 | 4 | 5 | pydantic_pynamodb 6 | ----------------- 7 | 8 | .. automodule:: pydantic_pynamodb 9 | :members: 10 | -------------------------------------------------------------------------------- /docs/requirements.txt: -------------------------------------------------------------------------------- 1 | furo==2023.5.20 2 | sphinx==7.0.1 3 | -------------------------------------------------------------------------------- /docs/usage.rst: -------------------------------------------------------------------------------- 1 | Usage 2 | ===== 3 | 4 | .. click:: pydantic_pynamodb.__main__:main 5 | :prog: pydantic-pynamodb 6 | :nested: full 7 | -------------------------------------------------------------------------------- /noxfile.py: -------------------------------------------------------------------------------- 1 | """Nox sessions.""" 2 | import os 3 | import shlex 4 | import shutil 5 | import sys 6 | from pathlib import Path 7 | from textwrap import dedent 8 | 9 | import nox 10 | 11 | 12 | try: 13 | from nox_poetry import Session 14 | from nox_poetry import session 15 | except ImportError: 16 | message = f"""\ 17 | Nox failed to import the 'nox-poetry' package. 18 | 19 | Please install it using the following command: 20 | 21 | {sys.executable} -m pip install nox-poetry""" 22 | raise SystemExit(dedent(message)) from None 23 | 24 | 25 | package = "pydantic_pynamodb" 26 | python_versions = ["3.10", "3.11", "3.9", "3.8", "3.7"] 27 | nox.needs_version = ">= 2021.6.6" 28 | nox.options.sessions = ( 29 | "pre-commit", 30 | "bandit", 31 | "safety", 32 | # "mypy", 33 | "tests", 34 | # "typeguard", 35 | "xdoctest", 36 | "docs-build", 37 | ) 38 | mypy_type_packages = ("types-croniter", "types-pytz") 39 | test_requirements = ( 40 | "coverage[toml]", 41 | "pytest", 42 | "pygments", 43 | "isort", 44 | "pytest-asyncio", 45 | "pytest-lazy-fixture", 46 | ) 47 | 48 | 49 | def activate_virtualenv_in_precommit_hooks(session: Session) -> None: 50 | """Activate virtualenv in hooks installed by pre-commit. 51 | 52 | This function patches git hooks installed by pre-commit to activate the 53 | session's virtual environment. This allows pre-commit to locate hooks in 54 | that environment when invoked from git. 55 | 56 | Args: 57 | session: The Session object. 58 | """ 59 | assert session.bin is not None # noqa: S101 60 | 61 | # Only patch hooks containing a reference to this session's bindir. Support 62 | # quoting rules for Python and bash, but strip the outermost quotes so we 63 | # can detect paths within the bindir, like /python. 64 | bindirs = [ 65 | bindir[1:-1] if bindir[0] in "'\"" else bindir 66 | for bindir in (repr(session.bin), shlex.quote(session.bin)) 67 | ] 68 | 69 | virtualenv = session.env.get("VIRTUAL_ENV") 70 | if virtualenv is None: 71 | return 72 | 73 | headers = { 74 | # pre-commit < 2.16.0 75 | "python": f"""\ 76 | import os 77 | os.environ["VIRTUAL_ENV"] = {virtualenv!r} 78 | os.environ["PATH"] = os.pathsep.join(( 79 | {session.bin!r}, 80 | os.environ.get("PATH", ""), 81 | )) 82 | """, 83 | # pre-commit >= 2.16.0 84 | "bash": f"""\ 85 | VIRTUAL_ENV={shlex.quote(virtualenv)} 86 | PATH={shlex.quote(session.bin)}"{os.pathsep}$PATH" 87 | """, 88 | } 89 | 90 | hookdir = Path(".git") / "hooks" 91 | if not hookdir.is_dir(): 92 | return 93 | 94 | for hook in hookdir.iterdir(): 95 | if hook.name.endswith(".sample") or not hook.is_file(): 96 | continue 97 | 98 | if not hook.read_bytes().startswith(b"#!"): 99 | continue 100 | 101 | text = hook.read_text() 102 | 103 | if not any( 104 | Path("A") == Path("a") and bindir.lower() in text.lower() or bindir in text 105 | for bindir in bindirs 106 | ): 107 | continue 108 | 109 | lines = text.splitlines() 110 | 111 | for executable, header in headers.items(): 112 | if executable in lines[0].lower(): 113 | lines.insert(1, dedent(header)) 114 | hook.write_text("\n".join(lines)) 115 | break 116 | 117 | 118 | @session(name="pre-commit", python=python_versions[0]) 119 | def precommit(session: Session) -> None: 120 | """Lint using pre-commit.""" 121 | args = session.posargs or ["run", "--all-files", "--show-diff-on-failure"] 122 | session.install( 123 | "black", 124 | "darglint", 125 | "flake8", 126 | "flake8-bandit", 127 | "flake8-bugbear", 128 | "flake8-docstrings", 129 | "flake8-rst-docstrings", 130 | "pep8-naming", 131 | "pre-commit", 132 | "pre-commit-hooks", 133 | "pyupgrade", 134 | "reorder-python-imports", 135 | "isort", 136 | ) 137 | session.run("pre-commit", *args) 138 | if args and args[0] == "install": 139 | activate_virtualenv_in_precommit_hooks(session) 140 | 141 | 142 | @session(python=python_versions[0]) 143 | def safety(session: Session) -> None: 144 | """Scan dependencies for insecure packages.""" 145 | requirements = session.poetry.export_requirements() 146 | session.install("safety") 147 | session.run("safety", "check", "--full-report", f"--file={requirements}") 148 | 149 | 150 | @session(python=python_versions) 151 | def mypy(session: Session) -> None: 152 | """Type-check using mypy.""" 153 | args = session.posargs or ["src"] 154 | session.install(".") 155 | session.install("mypy", "pytest") 156 | session.install(*mypy_type_packages) 157 | session.run("mypy", *args) 158 | 159 | 160 | @session(python=python_versions[0]) 161 | def bandit(session: Session) -> None: 162 | """Run bandit security tests""" 163 | args = session.posargs or ["-r", "./src"] 164 | session.run("bandit", *args) 165 | 166 | 167 | @session(python=python_versions) 168 | def tests(session: Session) -> None: 169 | """Run the test suite.""" 170 | session.install(".") 171 | session.install(*test_requirements) 172 | try: 173 | session.run("coverage", "run", "--parallel", "-m", "pytest", *session.posargs) 174 | finally: 175 | if session.interactive: 176 | session.notify("coverage", posargs=[]) 177 | 178 | 179 | @session(python=python_versions[0]) 180 | def coverage(session: Session) -> None: 181 | """Produce the coverage report.""" 182 | args = session.posargs or ["report"] 183 | 184 | session.install("coverage[toml]") 185 | 186 | if not session.posargs and any(Path().glob(".coverage.*")): 187 | session.run("coverage", "combine") 188 | 189 | session.run("coverage", *args) 190 | 191 | 192 | @session(python=python_versions) 193 | def typeguard(session: Session) -> None: 194 | """Runtime type checking using Typeguard.""" 195 | session.install(".") 196 | session.install("pytest", "typeguard", "pygments") 197 | session.run("pytest", f"--typeguard-packages={package}", *session.posargs) 198 | 199 | 200 | @session(python=python_versions) 201 | def xdoctest(session: Session) -> None: 202 | """Run examples with xdoctest.""" 203 | if session.posargs: 204 | args = [package, *session.posargs] 205 | else: 206 | args = [f"--modname={package}", "--command=all"] 207 | if "FORCE_COLOR" in os.environ: 208 | args.append("--colored=1") 209 | 210 | session.install(".") 211 | session.install("xdoctest[colors]") 212 | session.run("python", "-m", "xdoctest", *args) 213 | 214 | 215 | @session(name="docs-build", python=python_versions[0]) 216 | def docs_build(session: Session) -> None: 217 | """Build the documentation.""" 218 | args = session.posargs or ["docs", "docs/_build"] 219 | if not session.posargs and "FORCE_COLOR" in os.environ: 220 | args.insert(0, "--color") 221 | 222 | session.install(".") 223 | session.install("sphinx", "sphinx-click", "furo") 224 | 225 | build_dir = Path("docs", "_build") 226 | if build_dir.exists(): 227 | shutil.rmtree(build_dir) 228 | 229 | session.run("sphinx-build", *args) 230 | 231 | 232 | @session(python=python_versions[0]) 233 | def docs(session: Session) -> None: 234 | """Build and serve the documentation with live reloading on file changes.""" 235 | args = session.posargs or ["--open-browser", "docs", "docs/_build"] 236 | session.install(".") 237 | session.install("sphinx", "sphinx-autobuild", "sphinx-click", "furo") 238 | 239 | build_dir = Path("docs", "_build") 240 | if build_dir.exists(): 241 | shutil.rmtree(build_dir) 242 | 243 | session.run("sphinx-autobuild", *args) 244 | -------------------------------------------------------------------------------- /poetry.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. 2 | 3 | [[package]] 4 | name = "alabaster" 5 | version = "0.7.13" 6 | description = "A configurable sidebar-enabled Sphinx theme" 7 | optional = false 8 | python-versions = ">=3.6" 9 | files = [ 10 | {file = "alabaster-0.7.13-py3-none-any.whl", hash = "sha256:1ee19aca801bbabb5ba3f5f258e4422dfa86f82f3e9cefb0859b283cdd7f62a3"}, 11 | {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"}, 12 | ] 13 | 14 | [[package]] 15 | name = "attrs" 16 | version = "22.2.0" 17 | description = "Classes Without Boilerplate" 18 | optional = false 19 | python-versions = ">=3.6" 20 | files = [ 21 | {file = "attrs-22.2.0-py3-none-any.whl", hash = "sha256:29e95c7f6778868dbd49170f98f8818f78f3dc5e0e37c0b1f474e3561b240836"}, 22 | {file = "attrs-22.2.0.tar.gz", hash = "sha256:c9227bfc2f01993c03f68db37d1d15c9690188323c067c641f1a35ca58185f99"}, 23 | ] 24 | 25 | [package.extras] 26 | cov = ["attrs[tests]", "coverage-enable-subprocess", "coverage[toml] (>=5.3)"] 27 | dev = ["attrs[docs,tests]"] 28 | docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope.interface"] 29 | tests = ["attrs[tests-no-zope]", "zope.interface"] 30 | tests-no-zope = ["cloudpickle", "cloudpickle", "hypothesis", "hypothesis", "mypy (>=0.971,<0.990)", "mypy (>=0.971,<0.990)", "pympler", "pympler", "pytest (>=4.3.0)", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-mypy-plugins", "pytest-xdist[psutil]", "pytest-xdist[psutil]"] 31 | 32 | [[package]] 33 | name = "babel" 34 | version = "2.11.0" 35 | description = "Internationalization utilities" 36 | optional = false 37 | python-versions = ">=3.6" 38 | files = [ 39 | {file = "Babel-2.11.0-py3-none-any.whl", hash = "sha256:1ad3eca1c885218f6dce2ab67291178944f810a10a9b5f3cb8382a5a232b64fe"}, 40 | {file = "Babel-2.11.0.tar.gz", hash = "sha256:5ef4b3226b0180dedded4229651c8b0e1a3a6a2837d45a073272f313e4cf97f6"}, 41 | ] 42 | 43 | [package.dependencies] 44 | pytz = ">=2015.7" 45 | 46 | [[package]] 47 | name = "bandit" 48 | version = "1.7.4" 49 | description = "Security oriented static analyser for python code." 50 | optional = false 51 | python-versions = ">=3.7" 52 | files = [ 53 | {file = "bandit-1.7.4-py3-none-any.whl", hash = "sha256:412d3f259dab4077d0e7f0c11f50f650cc7d10db905d98f6520a95a18049658a"}, 54 | {file = "bandit-1.7.4.tar.gz", hash = "sha256:2d63a8c573417bae338962d4b9b06fbc6080f74ecd955a092849e1e65c717bd2"}, 55 | ] 56 | 57 | [package.dependencies] 58 | colorama = {version = ">=0.3.9", markers = "platform_system == \"Windows\""} 59 | GitPython = ">=1.0.1" 60 | PyYAML = ">=5.3.1" 61 | stevedore = ">=1.20.0" 62 | 63 | [package.extras] 64 | test = ["beautifulsoup4 (>=4.8.0)", "coverage (>=4.5.4)", "fixtures (>=3.0.0)", "flake8 (>=4.0.0)", "pylint (==1.9.4)", "stestr (>=2.5.0)", "testscenarios (>=0.5.0)", "testtools (>=2.3.0)", "toml"] 65 | toml = ["toml"] 66 | yaml = ["PyYAML"] 67 | 68 | [[package]] 69 | name = "beautifulsoup4" 70 | version = "4.11.2" 71 | description = "Screen-scraping library" 72 | optional = false 73 | python-versions = ">=3.6.0" 74 | files = [ 75 | {file = "beautifulsoup4-4.11.2-py3-none-any.whl", hash = "sha256:0e79446b10b3ecb499c1556f7e228a53e64a2bfcebd455f370d8927cb5b59e39"}, 76 | {file = "beautifulsoup4-4.11.2.tar.gz", hash = "sha256:bc4bdda6717de5a2987436fb8d72f45dc90dd856bdfd512a1314ce90349a0106"}, 77 | ] 78 | 79 | [package.dependencies] 80 | soupsieve = ">1.2" 81 | 82 | [package.extras] 83 | html5lib = ["html5lib"] 84 | lxml = ["lxml"] 85 | 86 | [[package]] 87 | name = "black" 88 | version = "23.3.0" 89 | description = "The uncompromising code formatter." 90 | optional = false 91 | python-versions = ">=3.7" 92 | files = [ 93 | {file = "black-23.3.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:0945e13506be58bf7db93ee5853243eb368ace1c08a24c65ce108986eac65915"}, 94 | {file = "black-23.3.0-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:67de8d0c209eb5b330cce2469503de11bca4085880d62f1628bd9972cc3366b9"}, 95 | {file = "black-23.3.0-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:7c3eb7cea23904399866c55826b31c1f55bbcd3890ce22ff70466b907b6775c2"}, 96 | {file = "black-23.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32daa9783106c28815d05b724238e30718f34155653d4d6e125dc7daec8e260c"}, 97 | {file = "black-23.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:35d1381d7a22cc5b2be2f72c7dfdae4072a3336060635718cc7e1ede24221d6c"}, 98 | {file = "black-23.3.0-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:a8a968125d0a6a404842fa1bf0b349a568634f856aa08ffaff40ae0dfa52e7c6"}, 99 | {file = "black-23.3.0-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:c7ab5790333c448903c4b721b59c0d80b11fe5e9803d8703e84dcb8da56fec1b"}, 100 | {file = "black-23.3.0-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:a6f6886c9869d4daae2d1715ce34a19bbc4b95006d20ed785ca00fa03cba312d"}, 101 | {file = "black-23.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f3c333ea1dd6771b2d3777482429864f8e258899f6ff05826c3a4fcc5ce3f70"}, 102 | {file = "black-23.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:11c410f71b876f961d1de77b9699ad19f939094c3a677323f43d7a29855fe326"}, 103 | {file = "black-23.3.0-cp37-cp37m-macosx_10_16_x86_64.whl", hash = "sha256:1d06691f1eb8de91cd1b322f21e3bfc9efe0c7ca1f0e1eb1db44ea367dff656b"}, 104 | {file = "black-23.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50cb33cac881766a5cd9913e10ff75b1e8eb71babf4c7104f2e9c52da1fb7de2"}, 105 | {file = "black-23.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:e114420bf26b90d4b9daa597351337762b63039752bdf72bf361364c1aa05925"}, 106 | {file = "black-23.3.0-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:48f9d345675bb7fbc3dd85821b12487e1b9a75242028adad0333ce36ed2a6d27"}, 107 | {file = "black-23.3.0-cp38-cp38-macosx_10_16_universal2.whl", hash = "sha256:714290490c18fb0126baa0fca0a54ee795f7502b44177e1ce7624ba1c00f2331"}, 108 | {file = "black-23.3.0-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:064101748afa12ad2291c2b91c960be28b817c0c7eaa35bec09cc63aa56493c5"}, 109 | {file = "black-23.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:562bd3a70495facf56814293149e51aa1be9931567474993c7942ff7d3533961"}, 110 | {file = "black-23.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:e198cf27888ad6f4ff331ca1c48ffc038848ea9f031a3b40ba36aced7e22f2c8"}, 111 | {file = "black-23.3.0-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:3238f2aacf827d18d26db07524e44741233ae09a584273aa059066d644ca7b30"}, 112 | {file = "black-23.3.0-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:f0bd2f4a58d6666500542b26354978218a9babcdc972722f4bf90779524515f3"}, 113 | {file = "black-23.3.0-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:92c543f6854c28a3c7f39f4d9b7694f9a6eb9d3c5e2ece488c327b6e7ea9b266"}, 114 | {file = "black-23.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a150542a204124ed00683f0db1f5cf1c2aaaa9cc3495b7a3b5976fb136090ab"}, 115 | {file = "black-23.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:6b39abdfb402002b8a7d030ccc85cf5afff64ee90fa4c5aebc531e3ad0175ddb"}, 116 | {file = "black-23.3.0-py3-none-any.whl", hash = "sha256:ec751418022185b0c1bb7d7736e6933d40bbb14c14a0abcf9123d1b159f98dd4"}, 117 | {file = "black-23.3.0.tar.gz", hash = "sha256:1c7b8d606e728a41ea1ccbd7264677e494e87cf630e399262ced92d4a8dac940"}, 118 | ] 119 | 120 | [package.dependencies] 121 | click = ">=8.0.0" 122 | mypy-extensions = ">=0.4.3" 123 | packaging = ">=22.0" 124 | pathspec = ">=0.9.0" 125 | platformdirs = ">=2" 126 | tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} 127 | typed-ast = {version = ">=1.4.2", markers = "python_version < \"3.8\" and implementation_name == \"cpython\""} 128 | typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""} 129 | 130 | [package.extras] 131 | colorama = ["colorama (>=0.4.3)"] 132 | d = ["aiohttp (>=3.7.4)"] 133 | jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] 134 | uvloop = ["uvloop (>=0.15.2)"] 135 | 136 | [[package]] 137 | name = "botocore" 138 | version = "1.29.80" 139 | description = "Low-level, data-driven core of boto 3." 140 | optional = false 141 | python-versions = ">= 3.7" 142 | files = [ 143 | {file = "botocore-1.29.80-py3-none-any.whl", hash = "sha256:9a301cb4de8ec6efe4e4b6ebb29b4301decd5b00c1a7f9187652002efb520ad0"}, 144 | {file = "botocore-1.29.80.tar.gz", hash = "sha256:19d4cadc79f75b31ffa78b5e750833d53e0edfe414d308b6788382ad32d23e12"}, 145 | ] 146 | 147 | [package.dependencies] 148 | jmespath = ">=0.7.1,<2.0.0" 149 | python-dateutil = ">=2.1,<3.0.0" 150 | urllib3 = ">=1.25.4,<1.27" 151 | 152 | [package.extras] 153 | crt = ["awscrt (==0.16.9)"] 154 | 155 | [[package]] 156 | name = "certifi" 157 | version = "2022.12.7" 158 | description = "Python package for providing Mozilla's CA Bundle." 159 | optional = false 160 | python-versions = ">=3.6" 161 | files = [ 162 | {file = "certifi-2022.12.7-py3-none-any.whl", hash = "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18"}, 163 | {file = "certifi-2022.12.7.tar.gz", hash = "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3"}, 164 | ] 165 | 166 | [[package]] 167 | name = "cfgv" 168 | version = "3.3.1" 169 | description = "Validate configuration and produce human readable error messages." 170 | optional = false 171 | python-versions = ">=3.6.1" 172 | files = [ 173 | {file = "cfgv-3.3.1-py2.py3-none-any.whl", hash = "sha256:c6a0883f3917a037485059700b9e75da2464e6c27051014ad85ba6aaa5884426"}, 174 | {file = "cfgv-3.3.1.tar.gz", hash = "sha256:f5a830efb9ce7a445376bb66ec94c638a9787422f96264c98edc6bdeed8ab736"}, 175 | ] 176 | 177 | [[package]] 178 | name = "charset-normalizer" 179 | version = "3.0.1" 180 | description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." 181 | optional = false 182 | python-versions = "*" 183 | files = [ 184 | {file = "charset-normalizer-3.0.1.tar.gz", hash = "sha256:ebea339af930f8ca5d7a699b921106c6e29c617fe9606fa7baa043c1cdae326f"}, 185 | {file = "charset_normalizer-3.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:88600c72ef7587fe1708fd242b385b6ed4b8904976d5da0893e31df8b3480cb6"}, 186 | {file = "charset_normalizer-3.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c75ffc45f25324e68ab238cb4b5c0a38cd1c3d7f1fb1f72b5541de469e2247db"}, 187 | {file = "charset_normalizer-3.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:db72b07027db150f468fbada4d85b3b2729a3db39178abf5c543b784c1254539"}, 188 | {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62595ab75873d50d57323a91dd03e6966eb79c41fa834b7a1661ed043b2d404d"}, 189 | {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ff6f3db31555657f3163b15a6b7c6938d08df7adbfc9dd13d9d19edad678f1e8"}, 190 | {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:772b87914ff1152b92a197ef4ea40efe27a378606c39446ded52c8f80f79702e"}, 191 | {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70990b9c51340e4044cfc394a81f614f3f90d41397104d226f21e66de668730d"}, 192 | {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:292d5e8ba896bbfd6334b096e34bffb56161c81408d6d036a7dfa6929cff8783"}, 193 | {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:2edb64ee7bf1ed524a1da60cdcd2e1f6e2b4f66ef7c077680739f1641f62f555"}, 194 | {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:31a9ddf4718d10ae04d9b18801bd776693487cbb57d74cc3458a7673f6f34639"}, 195 | {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:44ba614de5361b3e5278e1241fda3dc1838deed864b50a10d7ce92983797fa76"}, 196 | {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:12db3b2c533c23ab812c2b25934f60383361f8a376ae272665f8e48b88e8e1c6"}, 197 | {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c512accbd6ff0270939b9ac214b84fb5ada5f0409c44298361b2f5e13f9aed9e"}, 198 | {file = "charset_normalizer-3.0.1-cp310-cp310-win32.whl", hash = "sha256:502218f52498a36d6bf5ea77081844017bf7982cdbe521ad85e64cabee1b608b"}, 199 | {file = "charset_normalizer-3.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:601f36512f9e28f029d9481bdaf8e89e5148ac5d89cffd3b05cd533eeb423b59"}, 200 | {file = "charset_normalizer-3.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0298eafff88c99982a4cf66ba2efa1128e4ddaca0b05eec4c456bbc7db691d8d"}, 201 | {file = "charset_normalizer-3.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a8d0fc946c784ff7f7c3742310cc8a57c5c6dc31631269876a88b809dbeff3d3"}, 202 | {file = "charset_normalizer-3.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:87701167f2a5c930b403e9756fab1d31d4d4da52856143b609e30a1ce7160f3c"}, 203 | {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14e76c0f23218b8f46c4d87018ca2e441535aed3632ca134b10239dfb6dadd6b"}, 204 | {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0c0a590235ccd933d9892c627dec5bc7511ce6ad6c1011fdf5b11363022746c1"}, 205 | {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8c7fe7afa480e3e82eed58e0ca89f751cd14d767638e2550c77a92a9e749c317"}, 206 | {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79909e27e8e4fcc9db4addea88aa63f6423ebb171db091fb4373e3312cb6d603"}, 207 | {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ac7b6a045b814cf0c47f3623d21ebd88b3e8cf216a14790b455ea7ff0135d18"}, 208 | {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:72966d1b297c741541ca8cf1223ff262a6febe52481af742036a0b296e35fa5a"}, 209 | {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:f9d0c5c045a3ca9bedfc35dca8526798eb91a07aa7a2c0fee134c6c6f321cbd7"}, 210 | {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:5995f0164fa7df59db4746112fec3f49c461dd6b31b841873443bdb077c13cfc"}, 211 | {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4a8fcf28c05c1f6d7e177a9a46a1c52798bfe2ad80681d275b10dcf317deaf0b"}, 212 | {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:761e8904c07ad053d285670f36dd94e1b6ab7f16ce62b9805c475b7aa1cffde6"}, 213 | {file = "charset_normalizer-3.0.1-cp311-cp311-win32.whl", hash = "sha256:71140351489970dfe5e60fc621ada3e0f41104a5eddaca47a7acb3c1b851d6d3"}, 214 | {file = "charset_normalizer-3.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:9ab77acb98eba3fd2a85cd160851816bfce6871d944d885febf012713f06659c"}, 215 | {file = "charset_normalizer-3.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:84c3990934bae40ea69a82034912ffe5a62c60bbf6ec5bc9691419641d7d5c9a"}, 216 | {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74292fc76c905c0ef095fe11e188a32ebd03bc38f3f3e9bcb85e4e6db177b7ea"}, 217 | {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c95a03c79bbe30eec3ec2b7f076074f4281526724c8685a42872974ef4d36b72"}, 218 | {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f4c39b0e3eac288fedc2b43055cfc2ca7a60362d0e5e87a637beac5d801ef478"}, 219 | {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df2c707231459e8a4028eabcd3cfc827befd635b3ef72eada84ab13b52e1574d"}, 220 | {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93ad6d87ac18e2a90b0fe89df7c65263b9a99a0eb98f0a3d2e079f12a0735837"}, 221 | {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:59e5686dd847347e55dffcc191a96622f016bc0ad89105e24c14e0d6305acbc6"}, 222 | {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:cd6056167405314a4dc3c173943f11249fa0f1b204f8b51ed4bde1a9cd1834dc"}, 223 | {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:083c8d17153ecb403e5e1eb76a7ef4babfc2c48d58899c98fcaa04833e7a2f9a"}, 224 | {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:f5057856d21e7586765171eac8b9fc3f7d44ef39425f85dbcccb13b3ebea806c"}, 225 | {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:7eb33a30d75562222b64f569c642ff3dc6689e09adda43a082208397f016c39a"}, 226 | {file = "charset_normalizer-3.0.1-cp36-cp36m-win32.whl", hash = "sha256:95dea361dd73757c6f1c0a1480ac499952c16ac83f7f5f4f84f0658a01b8ef41"}, 227 | {file = "charset_normalizer-3.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:eaa379fcd227ca235d04152ca6704c7cb55564116f8bc52545ff357628e10602"}, 228 | {file = "charset_normalizer-3.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3e45867f1f2ab0711d60c6c71746ac53537f1684baa699f4f668d4c6f6ce8e14"}, 229 | {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cadaeaba78750d58d3cc6ac4d1fd867da6fc73c88156b7a3212a3cd4819d679d"}, 230 | {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:911d8a40b2bef5b8bbae2e36a0b103f142ac53557ab421dc16ac4aafee6f53dc"}, 231 | {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:503e65837c71b875ecdd733877d852adbc465bd82c768a067badd953bf1bc5a3"}, 232 | {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a60332922359f920193b1d4826953c507a877b523b2395ad7bc716ddd386d866"}, 233 | {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:16a8663d6e281208d78806dbe14ee9903715361cf81f6d4309944e4d1e59ac5b"}, 234 | {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:a16418ecf1329f71df119e8a65f3aa68004a3f9383821edcb20f0702934d8087"}, 235 | {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:9d9153257a3f70d5f69edf2325357251ed20f772b12e593f3b3377b5f78e7ef8"}, 236 | {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:02a51034802cbf38db3f89c66fb5d2ec57e6fe7ef2f4a44d070a593c3688667b"}, 237 | {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:2e396d70bc4ef5325b72b593a72c8979999aa52fb8bcf03f701c1b03e1166918"}, 238 | {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:11b53acf2411c3b09e6af37e4b9005cba376c872503c8f28218c7243582df45d"}, 239 | {file = "charset_normalizer-3.0.1-cp37-cp37m-win32.whl", hash = "sha256:0bf2dae5291758b6f84cf923bfaa285632816007db0330002fa1de38bfcb7154"}, 240 | {file = "charset_normalizer-3.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:2c03cc56021a4bd59be889c2b9257dae13bf55041a3372d3295416f86b295fb5"}, 241 | {file = "charset_normalizer-3.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:024e606be3ed92216e2b6952ed859d86b4cfa52cd5bc5f050e7dc28f9b43ec42"}, 242 | {file = "charset_normalizer-3.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4b0d02d7102dd0f997580b51edc4cebcf2ab6397a7edf89f1c73b586c614272c"}, 243 | {file = "charset_normalizer-3.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:358a7c4cb8ba9b46c453b1dd8d9e431452d5249072e4f56cfda3149f6ab1405e"}, 244 | {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81d6741ab457d14fdedc215516665050f3822d3e56508921cc7239f8c8e66a58"}, 245 | {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8b8af03d2e37866d023ad0ddea594edefc31e827fee64f8de5611a1dbc373174"}, 246 | {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9cf4e8ad252f7c38dd1f676b46514f92dc0ebeb0db5552f5f403509705e24753"}, 247 | {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e696f0dd336161fca9adbb846875d40752e6eba585843c768935ba5c9960722b"}, 248 | {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c22d3fe05ce11d3671297dc8973267daa0f938b93ec716e12e0f6dee81591dc1"}, 249 | {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:109487860ef6a328f3eec66f2bf78b0b72400280d8f8ea05f69c51644ba6521a"}, 250 | {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:37f8febc8ec50c14f3ec9637505f28e58d4f66752207ea177c1d67df25da5aed"}, 251 | {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:f97e83fa6c25693c7a35de154681fcc257c1c41b38beb0304b9c4d2d9e164479"}, 252 | {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a152f5f33d64a6be73f1d30c9cc82dfc73cec6477ec268e7c6e4c7d23c2d2291"}, 253 | {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:39049da0ffb96c8cbb65cbf5c5f3ca3168990adf3551bd1dee10c48fce8ae820"}, 254 | {file = "charset_normalizer-3.0.1-cp38-cp38-win32.whl", hash = "sha256:4457ea6774b5611f4bed5eaa5df55f70abde42364d498c5134b7ef4c6958e20e"}, 255 | {file = "charset_normalizer-3.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:e62164b50f84e20601c1ff8eb55620d2ad25fb81b59e3cd776a1902527a788af"}, 256 | {file = "charset_normalizer-3.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8eade758719add78ec36dc13201483f8e9b5d940329285edcd5f70c0a9edbd7f"}, 257 | {file = "charset_normalizer-3.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8499ca8f4502af841f68135133d8258f7b32a53a1d594aa98cc52013fff55678"}, 258 | {file = "charset_normalizer-3.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3fc1c4a2ffd64890aebdb3f97e1278b0cc72579a08ca4de8cd2c04799a3a22be"}, 259 | {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00d3ffdaafe92a5dc603cb9bd5111aaa36dfa187c8285c543be562e61b755f6b"}, 260 | {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c2ac1b08635a8cd4e0cbeaf6f5e922085908d48eb05d44c5ae9eabab148512ca"}, 261 | {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f6f45710b4459401609ebebdbcfb34515da4fc2aa886f95107f556ac69a9147e"}, 262 | {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ae1de54a77dc0d6d5fcf623290af4266412a7c4be0b1ff7444394f03f5c54e3"}, 263 | {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b590df687e3c5ee0deef9fc8c547d81986d9a1b56073d82de008744452d6541"}, 264 | {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab5de034a886f616a5668aa5d098af2b5385ed70142090e2a31bcbd0af0fdb3d"}, 265 | {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9cb3032517f1627cc012dbc80a8ec976ae76d93ea2b5feaa9d2a5b8882597579"}, 266 | {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:608862a7bf6957f2333fc54ab4399e405baad0163dc9f8d99cb236816db169d4"}, 267 | {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0f438ae3532723fb6ead77e7c604be7c8374094ef4ee2c5e03a3a17f1fca256c"}, 268 | {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:356541bf4381fa35856dafa6a965916e54bed415ad8a24ee6de6e37deccf2786"}, 269 | {file = "charset_normalizer-3.0.1-cp39-cp39-win32.whl", hash = "sha256:39cf9ed17fe3b1bc81f33c9ceb6ce67683ee7526e65fde1447c772afc54a1bb8"}, 270 | {file = "charset_normalizer-3.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:0a11e971ed097d24c534c037d298ad32c6ce81a45736d31e0ff0ad37ab437d59"}, 271 | {file = "charset_normalizer-3.0.1-py3-none-any.whl", hash = "sha256:7e189e2e1d3ed2f4aebabd2d5b0f931e883676e51c7624826e0a4e5fe8a0bf24"}, 272 | ] 273 | 274 | [[package]] 275 | name = "click" 276 | version = "8.1.3" 277 | description = "Composable command line interface toolkit" 278 | optional = false 279 | python-versions = ">=3.7" 280 | files = [ 281 | {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, 282 | {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, 283 | ] 284 | 285 | [package.dependencies] 286 | colorama = {version = "*", markers = "platform_system == \"Windows\""} 287 | importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} 288 | 289 | [[package]] 290 | name = "colorama" 291 | version = "0.4.6" 292 | description = "Cross-platform colored terminal text." 293 | optional = false 294 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" 295 | files = [ 296 | {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, 297 | {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, 298 | ] 299 | 300 | [[package]] 301 | name = "coverage" 302 | version = "7.2.7" 303 | description = "Code coverage measurement for Python" 304 | optional = false 305 | python-versions = ">=3.7" 306 | files = [ 307 | {file = "coverage-7.2.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d39b5b4f2a66ccae8b7263ac3c8170994b65266797fb96cbbfd3fb5b23921db8"}, 308 | {file = "coverage-7.2.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6d040ef7c9859bb11dfeb056ff5b3872436e3b5e401817d87a31e1750b9ae2fb"}, 309 | {file = "coverage-7.2.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba90a9563ba44a72fda2e85302c3abc71c5589cea608ca16c22b9804262aaeb6"}, 310 | {file = "coverage-7.2.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7d9405291c6928619403db1d10bd07888888ec1abcbd9748fdaa971d7d661b2"}, 311 | {file = "coverage-7.2.7-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31563e97dae5598556600466ad9beea39fb04e0229e61c12eaa206e0aa202063"}, 312 | {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ebba1cd308ef115925421d3e6a586e655ca5a77b5bf41e02eb0e4562a111f2d1"}, 313 | {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:cb017fd1b2603ef59e374ba2063f593abe0fc45f2ad9abdde5b4d83bd922a353"}, 314 | {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62a5c7dad11015c66fbb9d881bc4caa5b12f16292f857842d9d1871595f4495"}, 315 | {file = "coverage-7.2.7-cp310-cp310-win32.whl", hash = "sha256:ee57190f24fba796e36bb6d3aa8a8783c643d8fa9760c89f7a98ab5455fbf818"}, 316 | {file = "coverage-7.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:f75f7168ab25dd93110c8a8117a22450c19976afbc44234cbf71481094c1b850"}, 317 | {file = "coverage-7.2.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:06a9a2be0b5b576c3f18f1a241f0473575c4a26021b52b2a85263a00f034d51f"}, 318 | {file = "coverage-7.2.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5baa06420f837184130752b7c5ea0808762083bf3487b5038d68b012e5937dbe"}, 319 | {file = "coverage-7.2.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdec9e8cbf13a5bf63290fc6013d216a4c7232efb51548594ca3631a7f13c3a3"}, 320 | {file = "coverage-7.2.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:52edc1a60c0d34afa421c9c37078817b2e67a392cab17d97283b64c5833f427f"}, 321 | {file = "coverage-7.2.7-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63426706118b7f5cf6bb6c895dc215d8a418d5952544042c8a2d9fe87fcf09cb"}, 322 | {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:afb17f84d56068a7c29f5fa37bfd38d5aba69e3304af08ee94da8ed5b0865833"}, 323 | {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:48c19d2159d433ccc99e729ceae7d5293fbffa0bdb94952d3579983d1c8c9d97"}, 324 | {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0e1f928eaf5469c11e886fe0885ad2bf1ec606434e79842a879277895a50942a"}, 325 | {file = "coverage-7.2.7-cp311-cp311-win32.whl", hash = "sha256:33d6d3ea29d5b3a1a632b3c4e4f4ecae24ef170b0b9ee493883f2df10039959a"}, 326 | {file = "coverage-7.2.7-cp311-cp311-win_amd64.whl", hash = "sha256:5b7540161790b2f28143191f5f8ec02fb132660ff175b7747b95dcb77ac26562"}, 327 | {file = "coverage-7.2.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f2f67fe12b22cd130d34d0ef79206061bfb5eda52feb6ce0dba0644e20a03cf4"}, 328 | {file = "coverage-7.2.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a342242fe22407f3c17f4b499276a02b01e80f861f1682ad1d95b04018e0c0d4"}, 329 | {file = "coverage-7.2.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:171717c7cb6b453aebac9a2ef603699da237f341b38eebfee9be75d27dc38e01"}, 330 | {file = "coverage-7.2.7-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49969a9f7ffa086d973d91cec8d2e31080436ef0fb4a359cae927e742abfaaa6"}, 331 | {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b46517c02ccd08092f4fa99f24c3b83d8f92f739b4657b0f146246a0ca6a831d"}, 332 | {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:a3d33a6b3eae87ceaefa91ffdc130b5e8536182cd6dfdbfc1aa56b46ff8c86de"}, 333 | {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:976b9c42fb2a43ebf304fa7d4a310e5f16cc99992f33eced91ef6f908bd8f33d"}, 334 | {file = "coverage-7.2.7-cp312-cp312-win32.whl", hash = "sha256:8de8bb0e5ad103888d65abef8bca41ab93721647590a3f740100cd65c3b00511"}, 335 | {file = "coverage-7.2.7-cp312-cp312-win_amd64.whl", hash = "sha256:9e31cb64d7de6b6f09702bb27c02d1904b3aebfca610c12772452c4e6c21a0d3"}, 336 | {file = "coverage-7.2.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:58c2ccc2f00ecb51253cbe5d8d7122a34590fac9646a960d1430d5b15321d95f"}, 337 | {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d22656368f0e6189e24722214ed8d66b8022db19d182927b9a248a2a8a2f67eb"}, 338 | {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a895fcc7b15c3fc72beb43cdcbdf0ddb7d2ebc959edac9cef390b0d14f39f8a9"}, 339 | {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e84606b74eb7de6ff581a7915e2dab7a28a0517fbe1c9239eb227e1354064dcd"}, 340 | {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0a5f9e1dbd7fbe30196578ca36f3fba75376fb99888c395c5880b355e2875f8a"}, 341 | {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:419bfd2caae268623dd469eff96d510a920c90928b60f2073d79f8fe2bbc5959"}, 342 | {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2aee274c46590717f38ae5e4650988d1af340fe06167546cc32fe2f58ed05b02"}, 343 | {file = "coverage-7.2.7-cp37-cp37m-win32.whl", hash = "sha256:61b9a528fb348373c433e8966535074b802c7a5d7f23c4f421e6c6e2f1697a6f"}, 344 | {file = "coverage-7.2.7-cp37-cp37m-win_amd64.whl", hash = "sha256:b1c546aca0ca4d028901d825015dc8e4d56aac4b541877690eb76490f1dc8ed0"}, 345 | {file = "coverage-7.2.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:54b896376ab563bd38453cecb813c295cf347cf5906e8b41d340b0321a5433e5"}, 346 | {file = "coverage-7.2.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3d376df58cc111dc8e21e3b6e24606b5bb5dee6024f46a5abca99124b2229ef5"}, 347 | {file = "coverage-7.2.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e330fc79bd7207e46c7d7fd2bb4af2963f5f635703925543a70b99574b0fea9"}, 348 | {file = "coverage-7.2.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e9d683426464e4a252bf70c3498756055016f99ddaec3774bf368e76bbe02b6"}, 349 | {file = "coverage-7.2.7-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d13c64ee2d33eccf7437961b6ea7ad8673e2be040b4f7fd4fd4d4d28d9ccb1e"}, 350 | {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b7aa5f8a41217360e600da646004f878250a0d6738bcdc11a0a39928d7dc2050"}, 351 | {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8fa03bce9bfbeeef9f3b160a8bed39a221d82308b4152b27d82d8daa7041fee5"}, 352 | {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:245167dd26180ab4c91d5e1496a30be4cd721a5cf2abf52974f965f10f11419f"}, 353 | {file = "coverage-7.2.7-cp38-cp38-win32.whl", hash = "sha256:d2c2db7fd82e9b72937969bceac4d6ca89660db0a0967614ce2481e81a0b771e"}, 354 | {file = "coverage-7.2.7-cp38-cp38-win_amd64.whl", hash = "sha256:2e07b54284e381531c87f785f613b833569c14ecacdcb85d56b25c4622c16c3c"}, 355 | {file = "coverage-7.2.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:537891ae8ce59ef63d0123f7ac9e2ae0fc8b72c7ccbe5296fec45fd68967b6c9"}, 356 | {file = "coverage-7.2.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:06fb182e69f33f6cd1d39a6c597294cff3143554b64b9825d1dc69d18cc2fff2"}, 357 | {file = "coverage-7.2.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:201e7389591af40950a6480bd9edfa8ed04346ff80002cec1a66cac4549c1ad7"}, 358 | {file = "coverage-7.2.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f6951407391b639504e3b3be51b7ba5f3528adbf1a8ac3302b687ecababf929e"}, 359 | {file = "coverage-7.2.7-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f48351d66575f535669306aa7d6d6f71bc43372473b54a832222803eb956fd1"}, 360 | {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b29019c76039dc3c0fd815c41392a044ce555d9bcdd38b0fb60fb4cd8e475ba9"}, 361 | {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:81c13a1fc7468c40f13420732805a4c38a105d89848b7c10af65a90beff25250"}, 362 | {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:975d70ab7e3c80a3fe86001d8751f6778905ec723f5b110aed1e450da9d4b7f2"}, 363 | {file = "coverage-7.2.7-cp39-cp39-win32.whl", hash = "sha256:7ee7d9d4822c8acc74a5e26c50604dff824710bc8de424904c0982e25c39c6cb"}, 364 | {file = "coverage-7.2.7-cp39-cp39-win_amd64.whl", hash = "sha256:eb393e5ebc85245347950143969b241d08b52b88a3dc39479822e073a1a8eb27"}, 365 | {file = "coverage-7.2.7-pp37.pp38.pp39-none-any.whl", hash = "sha256:b7b4c971f05e6ae490fef852c218b0e79d4e52f79ef0c8475566584a8fb3e01d"}, 366 | {file = "coverage-7.2.7.tar.gz", hash = "sha256:924d94291ca674905fe9481f12294eb11f2d3d3fd1adb20314ba89e94f44ed59"}, 367 | ] 368 | 369 | [package.dependencies] 370 | tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} 371 | 372 | [package.extras] 373 | toml = ["tomli"] 374 | 375 | [[package]] 376 | name = "darglint" 377 | version = "1.8.1" 378 | description = "A utility for ensuring Google-style docstrings stay up to date with the source code." 379 | optional = false 380 | python-versions = ">=3.6,<4.0" 381 | files = [ 382 | {file = "darglint-1.8.1-py3-none-any.whl", hash = "sha256:5ae11c259c17b0701618a20c3da343a3eb98b3bc4b5a83d31cdd94f5ebdced8d"}, 383 | {file = "darglint-1.8.1.tar.gz", hash = "sha256:080d5106df149b199822e7ee7deb9c012b49891538f14a11be681044f0bb20da"}, 384 | ] 385 | 386 | [[package]] 387 | name = "distlib" 388 | version = "0.3.6" 389 | description = "Distribution utilities" 390 | optional = false 391 | python-versions = "*" 392 | files = [ 393 | {file = "distlib-0.3.6-py2.py3-none-any.whl", hash = "sha256:f35c4b692542ca110de7ef0bea44d73981caeb34ca0b9b6b2e6d7790dda8f80e"}, 394 | {file = "distlib-0.3.6.tar.gz", hash = "sha256:14bad2d9b04d3a36127ac97f30b12a19268f211063d8f8ee4f47108896e11b46"}, 395 | ] 396 | 397 | [[package]] 398 | name = "docutils" 399 | version = "0.17.1" 400 | description = "Docutils -- Python Documentation Utilities" 401 | optional = false 402 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" 403 | files = [ 404 | {file = "docutils-0.17.1-py2.py3-none-any.whl", hash = "sha256:cf316c8370a737a022b72b56874f6602acf974a37a9fba42ec2876387549fc61"}, 405 | {file = "docutils-0.17.1.tar.gz", hash = "sha256:686577d2e4c32380bb50cbb22f575ed742d58168cee37e99117a854bcd88f125"}, 406 | ] 407 | 408 | [[package]] 409 | name = "dparse" 410 | version = "0.6.2" 411 | description = "A parser for Python dependency files" 412 | optional = false 413 | python-versions = ">=3.5" 414 | files = [ 415 | {file = "dparse-0.6.2-py3-none-any.whl", hash = "sha256:8097076f1dd26c377f30d4745e6ec18fef42f3bf493933b842ac5bafad8c345f"}, 416 | {file = "dparse-0.6.2.tar.gz", hash = "sha256:d45255bda21f998bc7ddf2afd5e62505ba6134756ba2d42a84c56b0826614dfe"}, 417 | ] 418 | 419 | [package.dependencies] 420 | packaging = "*" 421 | toml = "*" 422 | 423 | [package.extras] 424 | conda = ["pyyaml"] 425 | pipenv = ["pipenv"] 426 | 427 | [[package]] 428 | name = "exceptiongroup" 429 | version = "1.1.0" 430 | description = "Backport of PEP 654 (exception groups)" 431 | optional = false 432 | python-versions = ">=3.7" 433 | files = [ 434 | {file = "exceptiongroup-1.1.0-py3-none-any.whl", hash = "sha256:327cbda3da756e2de031a3107b81ab7b3770a602c4d16ca618298c526f4bec1e"}, 435 | {file = "exceptiongroup-1.1.0.tar.gz", hash = "sha256:bcb67d800a4497e1b404c2dd44fca47d3b7a5e5433dbab67f96c1a685cdfdf23"}, 436 | ] 437 | 438 | [package.extras] 439 | test = ["pytest (>=6)"] 440 | 441 | [[package]] 442 | name = "filelock" 443 | version = "3.9.0" 444 | description = "A platform independent file lock." 445 | optional = false 446 | python-versions = ">=3.7" 447 | files = [ 448 | {file = "filelock-3.9.0-py3-none-any.whl", hash = "sha256:f58d535af89bb9ad5cd4df046f741f8553a418c01a7856bf0d173bbc9f6bd16d"}, 449 | {file = "filelock-3.9.0.tar.gz", hash = "sha256:7b319f24340b51f55a2bf7a12ac0755a9b03e718311dac567a0f4f7fabd2f5de"}, 450 | ] 451 | 452 | [package.extras] 453 | docs = ["furo (>=2022.12.7)", "sphinx (>=5.3)", "sphinx-autodoc-typehints (>=1.19.5)"] 454 | testing = ["covdefaults (>=2.2.2)", "coverage (>=7.0.1)", "pytest (>=7.2)", "pytest-cov (>=4)", "pytest-timeout (>=2.1)"] 455 | 456 | [[package]] 457 | name = "flake8" 458 | version = "5.0.4" 459 | description = "the modular source code checker: pep8 pyflakes and co" 460 | optional = false 461 | python-versions = ">=3.6.1" 462 | files = [ 463 | {file = "flake8-5.0.4-py2.py3-none-any.whl", hash = "sha256:7a1cf6b73744f5806ab95e526f6f0d8c01c66d7bbe349562d22dfca20610b248"}, 464 | {file = "flake8-5.0.4.tar.gz", hash = "sha256:6fbe320aad8d6b95cec8b8e47bc933004678dc63095be98528b7bdd2a9f510db"}, 465 | ] 466 | 467 | [package.dependencies] 468 | importlib-metadata = {version = ">=1.1.0,<4.3", markers = "python_version < \"3.8\""} 469 | mccabe = ">=0.7.0,<0.8.0" 470 | pycodestyle = ">=2.9.0,<2.10.0" 471 | pyflakes = ">=2.5.0,<2.6.0" 472 | 473 | [[package]] 474 | name = "flake8-bandit" 475 | version = "4.1.1" 476 | description = "Automated security testing with bandit and flake8." 477 | optional = false 478 | python-versions = ">=3.6" 479 | files = [ 480 | {file = "flake8_bandit-4.1.1-py3-none-any.whl", hash = "sha256:4c8a53eb48f23d4ef1e59293657181a3c989d0077c9952717e98a0eace43e06d"}, 481 | {file = "flake8_bandit-4.1.1.tar.gz", hash = "sha256:068e09287189cbfd7f986e92605adea2067630b75380c6b5733dab7d87f9a84e"}, 482 | ] 483 | 484 | [package.dependencies] 485 | bandit = ">=1.7.3" 486 | flake8 = ">=5.0.0" 487 | 488 | [[package]] 489 | name = "flake8-bugbear" 490 | version = "23.3.12" 491 | description = "A plugin for flake8 finding likely bugs and design problems in your program. Contains warnings that don't belong in pyflakes and pycodestyle." 492 | optional = false 493 | python-versions = ">=3.7" 494 | files = [ 495 | {file = "flake8-bugbear-23.3.12.tar.gz", hash = "sha256:e3e7f74c8a49ad3794a7183353026dabd68c74030d5f46571f84c1fb0eb79363"}, 496 | {file = "flake8_bugbear-23.3.12-py3-none-any.whl", hash = "sha256:beb5c7efcd7ccc2039ef66a77bb8db925e7be3531ff1cb4d0b7030d0e2113d72"}, 497 | ] 498 | 499 | [package.dependencies] 500 | attrs = ">=19.2.0" 501 | flake8 = ">=3.0.0" 502 | 503 | [package.extras] 504 | dev = ["coverage", "hypothesis", "hypothesmith (>=0.2)", "pre-commit", "pytest", "tox"] 505 | 506 | [[package]] 507 | name = "flake8-docstrings" 508 | version = "1.7.0" 509 | description = "Extension for flake8 which uses pydocstyle to check docstrings" 510 | optional = false 511 | python-versions = ">=3.7" 512 | files = [ 513 | {file = "flake8_docstrings-1.7.0-py2.py3-none-any.whl", hash = "sha256:51f2344026da083fc084166a9353f5082b01f72901df422f74b4d953ae88ac75"}, 514 | {file = "flake8_docstrings-1.7.0.tar.gz", hash = "sha256:4c8cc748dc16e6869728699e5d0d685da9a10b0ea718e090b1ba088e67a941af"}, 515 | ] 516 | 517 | [package.dependencies] 518 | flake8 = ">=3" 519 | pydocstyle = ">=2.1" 520 | 521 | [[package]] 522 | name = "flake8-rst-docstrings" 523 | version = "0.3.0" 524 | description = "Python docstring reStructuredText (RST) validator for flake8" 525 | optional = false 526 | python-versions = ">=3.7" 527 | files = [ 528 | {file = "flake8-rst-docstrings-0.3.0.tar.gz", hash = "sha256:d1ce22b4bd37b73cd86b8d980e946ef198cfcc18ed82fedb674ceaa2f8d1afa4"}, 529 | {file = "flake8_rst_docstrings-0.3.0-py3-none-any.whl", hash = "sha256:f8c3c6892ff402292651c31983a38da082480ad3ba253743de52989bdc84ca1c"}, 530 | ] 531 | 532 | [package.dependencies] 533 | flake8 = ">=3" 534 | pygments = "*" 535 | restructuredtext-lint = "*" 536 | 537 | [package.extras] 538 | develop = ["build", "twine"] 539 | 540 | [[package]] 541 | name = "furo" 542 | version = "2022.9.29" 543 | description = "A clean customisable Sphinx documentation theme." 544 | optional = false 545 | python-versions = ">=3.7" 546 | files = [ 547 | {file = "furo-2022.9.29-py3-none-any.whl", hash = "sha256:559ee17999c0f52728481dcf6b1b0cf8c9743e68c5e3a18cb45a7992747869a9"}, 548 | {file = "furo-2022.9.29.tar.gz", hash = "sha256:d4238145629c623609c2deb5384f8d036e2a1ee2a101d64b67b4348112470dbd"}, 549 | ] 550 | 551 | [package.dependencies] 552 | beautifulsoup4 = "*" 553 | pygments = ">=2.7" 554 | sphinx = ">=4.0,<6.0" 555 | sphinx-basic-ng = "*" 556 | 557 | [[package]] 558 | name = "gitdb" 559 | version = "4.0.10" 560 | description = "Git Object Database" 561 | optional = false 562 | python-versions = ">=3.7" 563 | files = [ 564 | {file = "gitdb-4.0.10-py3-none-any.whl", hash = "sha256:c286cf298426064079ed96a9e4a9d39e7f3e9bf15ba60701e95f5492f28415c7"}, 565 | {file = "gitdb-4.0.10.tar.gz", hash = "sha256:6eb990b69df4e15bad899ea868dc46572c3f75339735663b81de79b06f17eb9a"}, 566 | ] 567 | 568 | [package.dependencies] 569 | smmap = ">=3.0.1,<6" 570 | 571 | [[package]] 572 | name = "gitpython" 573 | version = "3.1.31" 574 | description = "GitPython is a Python library used to interact with Git repositories" 575 | optional = false 576 | python-versions = ">=3.7" 577 | files = [ 578 | {file = "GitPython-3.1.31-py3-none-any.whl", hash = "sha256:f04893614f6aa713a60cbbe1e6a97403ef633103cdd0ef5eb6efe0deb98dbe8d"}, 579 | {file = "GitPython-3.1.31.tar.gz", hash = "sha256:8ce3bcf69adfdf7c7d503e78fd3b1c492af782d58893b650adb2ac8912ddd573"}, 580 | ] 581 | 582 | [package.dependencies] 583 | gitdb = ">=4.0.1,<5" 584 | typing-extensions = {version = ">=3.7.4.3", markers = "python_version < \"3.8\""} 585 | 586 | [[package]] 587 | name = "identify" 588 | version = "2.5.18" 589 | description = "File identification library for Python" 590 | optional = false 591 | python-versions = ">=3.7" 592 | files = [ 593 | {file = "identify-2.5.18-py2.py3-none-any.whl", hash = "sha256:93aac7ecf2f6abf879b8f29a8002d3c6de7086b8c28d88e1ad15045a15ab63f9"}, 594 | {file = "identify-2.5.18.tar.gz", hash = "sha256:89e144fa560cc4cffb6ef2ab5e9fb18ed9f9b3cb054384bab4b95c12f6c309fe"}, 595 | ] 596 | 597 | [package.extras] 598 | license = ["ukkonen"] 599 | 600 | [[package]] 601 | name = "idna" 602 | version = "3.4" 603 | description = "Internationalized Domain Names in Applications (IDNA)" 604 | optional = false 605 | python-versions = ">=3.5" 606 | files = [ 607 | {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, 608 | {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, 609 | ] 610 | 611 | [[package]] 612 | name = "imagesize" 613 | version = "1.4.1" 614 | description = "Getting image size from png/jpeg/jpeg2000/gif file" 615 | optional = false 616 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 617 | files = [ 618 | {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"}, 619 | {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"}, 620 | ] 621 | 622 | [[package]] 623 | name = "importlib-metadata" 624 | version = "4.2.0" 625 | description = "Read metadata from Python packages" 626 | optional = false 627 | python-versions = ">=3.6" 628 | files = [ 629 | {file = "importlib_metadata-4.2.0-py3-none-any.whl", hash = "sha256:057e92c15bc8d9e8109738a48db0ccb31b4d9d5cfbee5a8670879a30be66304b"}, 630 | {file = "importlib_metadata-4.2.0.tar.gz", hash = "sha256:b7e52a1f8dec14a75ea73e0891f3060099ca1d8e6a462a4dff11c3e119ea1b31"}, 631 | ] 632 | 633 | [package.dependencies] 634 | typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} 635 | zipp = ">=0.5" 636 | 637 | [package.extras] 638 | docs = ["jaraco.packaging (>=8.2)", "rst.linker (>=1.9)", "sphinx"] 639 | testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pep517", "pyfakefs", "pytest (>=4.6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.0.1)", "pytest-flake8", "pytest-mypy"] 640 | 641 | [[package]] 642 | name = "iniconfig" 643 | version = "2.0.0" 644 | description = "brain-dead simple config-ini parsing" 645 | optional = false 646 | python-versions = ">=3.7" 647 | files = [ 648 | {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, 649 | {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, 650 | ] 651 | 652 | [[package]] 653 | name = "isort" 654 | version = "5.11.5" 655 | description = "A Python utility / library to sort Python imports." 656 | optional = false 657 | python-versions = ">=3.7.0" 658 | files = [ 659 | {file = "isort-5.11.5-py3-none-any.whl", hash = "sha256:ba1d72fb2595a01c7895a5128f9585a5cc4b6d395f1c8d514989b9a7eb2a8746"}, 660 | {file = "isort-5.11.5.tar.gz", hash = "sha256:6be1f76a507cb2ecf16c7cf14a37e41609ca082330be4e3436a18ef74add55db"}, 661 | ] 662 | 663 | [package.extras] 664 | colors = ["colorama (>=0.4.3,<0.5.0)"] 665 | pipfile-deprecated-finder = ["pip-shims (>=0.5.2)", "pipreqs", "requirementslib"] 666 | plugins = ["setuptools"] 667 | requirements-deprecated-finder = ["pip-api", "pipreqs"] 668 | 669 | [[package]] 670 | name = "jinja2" 671 | version = "3.1.2" 672 | description = "A very fast and expressive template engine." 673 | optional = false 674 | python-versions = ">=3.7" 675 | files = [ 676 | {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, 677 | {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, 678 | ] 679 | 680 | [package.dependencies] 681 | MarkupSafe = ">=2.0" 682 | 683 | [package.extras] 684 | i18n = ["Babel (>=2.7)"] 685 | 686 | [[package]] 687 | name = "jmespath" 688 | version = "1.0.1" 689 | description = "JSON Matching Expressions" 690 | optional = false 691 | python-versions = ">=3.7" 692 | files = [ 693 | {file = "jmespath-1.0.1-py3-none-any.whl", hash = "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980"}, 694 | {file = "jmespath-1.0.1.tar.gz", hash = "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe"}, 695 | ] 696 | 697 | [[package]] 698 | name = "livereload" 699 | version = "2.6.3" 700 | description = "Python LiveReload is an awesome tool for web developers" 701 | optional = false 702 | python-versions = "*" 703 | files = [ 704 | {file = "livereload-2.6.3-py2.py3-none-any.whl", hash = "sha256:ad4ac6f53b2d62bb6ce1a5e6e96f1f00976a32348afedcb4b6d68df2a1d346e4"}, 705 | {file = "livereload-2.6.3.tar.gz", hash = "sha256:776f2f865e59fde56490a56bcc6773b6917366bce0c267c60ee8aaf1a0959869"}, 706 | ] 707 | 708 | [package.dependencies] 709 | six = "*" 710 | tornado = {version = "*", markers = "python_version > \"2.7\""} 711 | 712 | [[package]] 713 | name = "markupsafe" 714 | version = "2.1.2" 715 | description = "Safely add untrusted strings to HTML/XML markup." 716 | optional = false 717 | python-versions = ">=3.7" 718 | files = [ 719 | {file = "MarkupSafe-2.1.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:665a36ae6f8f20a4676b53224e33d456a6f5a72657d9c83c2aa00765072f31f7"}, 720 | {file = "MarkupSafe-2.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:340bea174e9761308703ae988e982005aedf427de816d1afe98147668cc03036"}, 721 | {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22152d00bf4a9c7c83960521fc558f55a1adbc0631fbb00a9471e097b19d72e1"}, 722 | {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28057e985dace2f478e042eaa15606c7efccb700797660629da387eb289b9323"}, 723 | {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca244fa73f50a800cf8c3ebf7fd93149ec37f5cb9596aa8873ae2c1d23498601"}, 724 | {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d9d971ec1e79906046aa3ca266de79eac42f1dbf3612a05dc9368125952bd1a1"}, 725 | {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7e007132af78ea9df29495dbf7b5824cb71648d7133cf7848a2a5dd00d36f9ff"}, 726 | {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7313ce6a199651c4ed9d7e4cfb4aa56fe923b1adf9af3b420ee14e6d9a73df65"}, 727 | {file = "MarkupSafe-2.1.2-cp310-cp310-win32.whl", hash = "sha256:c4a549890a45f57f1ebf99c067a4ad0cb423a05544accaf2b065246827ed9603"}, 728 | {file = "MarkupSafe-2.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:835fb5e38fd89328e9c81067fd642b3593c33e1e17e2fdbf77f5676abb14a156"}, 729 | {file = "MarkupSafe-2.1.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2ec4f2d48ae59bbb9d1f9d7efb9236ab81429a764dedca114f5fdabbc3788013"}, 730 | {file = "MarkupSafe-2.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608e7073dfa9e38a85d38474c082d4281f4ce276ac0010224eaba11e929dd53a"}, 731 | {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65608c35bfb8a76763f37036547f7adfd09270fbdbf96608be2bead319728fcd"}, 732 | {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2bfb563d0211ce16b63c7cb9395d2c682a23187f54c3d79bfec33e6705473c6"}, 733 | {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da25303d91526aac3672ee6d49a2f3db2d9502a4a60b55519feb1a4c7714e07d"}, 734 | {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9cad97ab29dfc3f0249b483412c85c8ef4766d96cdf9dcf5a1e3caa3f3661cf1"}, 735 | {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:085fd3201e7b12809f9e6e9bc1e5c96a368c8523fad5afb02afe3c051ae4afcc"}, 736 | {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1bea30e9bf331f3fef67e0a3877b2288593c98a21ccb2cf29b74c581a4eb3af0"}, 737 | {file = "MarkupSafe-2.1.2-cp311-cp311-win32.whl", hash = "sha256:7df70907e00c970c60b9ef2938d894a9381f38e6b9db73c5be35e59d92e06625"}, 738 | {file = "MarkupSafe-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:e55e40ff0cc8cc5c07996915ad367fa47da6b3fc091fdadca7f5403239c5fec3"}, 739 | {file = "MarkupSafe-2.1.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a6e40afa7f45939ca356f348c8e23048e02cb109ced1eb8420961b2f40fb373a"}, 740 | {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf877ab4ed6e302ec1d04952ca358b381a882fbd9d1b07cccbfd61783561f98a"}, 741 | {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63ba06c9941e46fa389d389644e2d8225e0e3e5ebcc4ff1ea8506dce646f8c8a"}, 742 | {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f1cd098434e83e656abf198f103a8207a8187c0fc110306691a2e94a78d0abb2"}, 743 | {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:55f44b440d491028addb3b88f72207d71eeebfb7b5dbf0643f7c023ae1fba619"}, 744 | {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a6f2fcca746e8d5910e18782f976489939d54a91f9411c32051b4aab2bd7c513"}, 745 | {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0b462104ba25f1ac006fdab8b6a01ebbfbce9ed37fd37fd4acd70c67c973e460"}, 746 | {file = "MarkupSafe-2.1.2-cp37-cp37m-win32.whl", hash = "sha256:7668b52e102d0ed87cb082380a7e2e1e78737ddecdde129acadb0eccc5423859"}, 747 | {file = "MarkupSafe-2.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6d6607f98fcf17e534162f0709aaad3ab7a96032723d8ac8750ffe17ae5a0666"}, 748 | {file = "MarkupSafe-2.1.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a806db027852538d2ad7555b203300173dd1b77ba116de92da9afbc3a3be3eed"}, 749 | {file = "MarkupSafe-2.1.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a4abaec6ca3ad8660690236d11bfe28dfd707778e2442b45addd2f086d6ef094"}, 750 | {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f03a532d7dee1bed20bc4884194a16160a2de9ffc6354b3878ec9682bb623c54"}, 751 | {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4cf06cdc1dda95223e9d2d3c58d3b178aa5dacb35ee7e3bbac10e4e1faacb419"}, 752 | {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22731d79ed2eb25059ae3df1dfc9cb1546691cc41f4e3130fe6bfbc3ecbbecfa"}, 753 | {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f8ffb705ffcf5ddd0e80b65ddf7bed7ee4f5a441ea7d3419e861a12eaf41af58"}, 754 | {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8db032bf0ce9022a8e41a22598eefc802314e81b879ae093f36ce9ddf39ab1ba"}, 755 | {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2298c859cfc5463f1b64bd55cb3e602528db6fa0f3cfd568d3605c50678f8f03"}, 756 | {file = "MarkupSafe-2.1.2-cp38-cp38-win32.whl", hash = "sha256:50c42830a633fa0cf9e7d27664637532791bfc31c731a87b202d2d8ac40c3ea2"}, 757 | {file = "MarkupSafe-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:bb06feb762bade6bf3c8b844462274db0c76acc95c52abe8dbed28ae3d44a147"}, 758 | {file = "MarkupSafe-2.1.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:99625a92da8229df6d44335e6fcc558a5037dd0a760e11d84be2260e6f37002f"}, 759 | {file = "MarkupSafe-2.1.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8bca7e26c1dd751236cfb0c6c72d4ad61d986e9a41bbf76cb445f69488b2a2bd"}, 760 | {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40627dcf047dadb22cd25ea7ecfe9cbf3bbbad0482ee5920b582f3809c97654f"}, 761 | {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40dfd3fefbef579ee058f139733ac336312663c6706d1163b82b3003fb1925c4"}, 762 | {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:090376d812fb6ac5f171e5938e82e7f2d7adc2b629101cec0db8b267815c85e2"}, 763 | {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2e7821bffe00aa6bd07a23913b7f4e01328c3d5cc0b40b36c0bd81d362faeb65"}, 764 | {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c0a33bc9f02c2b17c3ea382f91b4db0e6cde90b63b296422a939886a7a80de1c"}, 765 | {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b8526c6d437855442cdd3d87eede9c425c4445ea011ca38d937db299382e6fa3"}, 766 | {file = "MarkupSafe-2.1.2-cp39-cp39-win32.whl", hash = "sha256:137678c63c977754abe9086a3ec011e8fd985ab90631145dfb9294ad09c102a7"}, 767 | {file = "MarkupSafe-2.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:0576fe974b40a400449768941d5d0858cc624e3249dfd1e0c33674e5c7ca7aed"}, 768 | {file = "MarkupSafe-2.1.2.tar.gz", hash = "sha256:abcabc8c2b26036d62d4c746381a6f7cf60aafcc653198ad678306986b09450d"}, 769 | ] 770 | 771 | [[package]] 772 | name = "mccabe" 773 | version = "0.7.0" 774 | description = "McCabe checker, plugin for flake8" 775 | optional = false 776 | python-versions = ">=3.6" 777 | files = [ 778 | {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, 779 | {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, 780 | ] 781 | 782 | [[package]] 783 | name = "mypy" 784 | version = "1.4.1" 785 | description = "Optional static typing for Python" 786 | optional = false 787 | python-versions = ">=3.7" 788 | files = [ 789 | {file = "mypy-1.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:566e72b0cd6598503e48ea610e0052d1b8168e60a46e0bfd34b3acf2d57f96a8"}, 790 | {file = "mypy-1.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ca637024ca67ab24a7fd6f65d280572c3794665eaf5edcc7e90a866544076878"}, 791 | {file = "mypy-1.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dde1d180cd84f0624c5dcaaa89c89775550a675aff96b5848de78fb11adabcd"}, 792 | {file = "mypy-1.4.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8c4d8e89aa7de683e2056a581ce63c46a0c41e31bd2b6d34144e2c80f5ea53dc"}, 793 | {file = "mypy-1.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:bfdca17c36ae01a21274a3c387a63aa1aafe72bff976522886869ef131b937f1"}, 794 | {file = "mypy-1.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7549fbf655e5825d787bbc9ecf6028731973f78088fbca3a1f4145c39ef09462"}, 795 | {file = "mypy-1.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:98324ec3ecf12296e6422939e54763faedbfcc502ea4a4c38502082711867258"}, 796 | {file = "mypy-1.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:141dedfdbfe8a04142881ff30ce6e6653c9685b354876b12e4fe6c78598b45e2"}, 797 | {file = "mypy-1.4.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8207b7105829eca6f3d774f64a904190bb2231de91b8b186d21ffd98005f14a7"}, 798 | {file = "mypy-1.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:16f0db5b641ba159eff72cff08edc3875f2b62b2fa2bc24f68c1e7a4e8232d01"}, 799 | {file = "mypy-1.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:470c969bb3f9a9efcedbadcd19a74ffb34a25f8e6b0e02dae7c0e71f8372f97b"}, 800 | {file = "mypy-1.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5952d2d18b79f7dc25e62e014fe5a23eb1a3d2bc66318df8988a01b1a037c5b"}, 801 | {file = "mypy-1.4.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:190b6bab0302cec4e9e6767d3eb66085aef2a1cc98fe04936d8a42ed2ba77bb7"}, 802 | {file = "mypy-1.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9d40652cc4fe33871ad3338581dca3297ff5f2213d0df345bcfbde5162abf0c9"}, 803 | {file = "mypy-1.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:01fd2e9f85622d981fd9063bfaef1aed6e336eaacca00892cd2d82801ab7c042"}, 804 | {file = "mypy-1.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2460a58faeea905aeb1b9b36f5065f2dc9a9c6e4c992a6499a2360c6c74ceca3"}, 805 | {file = "mypy-1.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2746d69a8196698146a3dbe29104f9eb6a2a4d8a27878d92169a6c0b74435b6"}, 806 | {file = "mypy-1.4.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ae704dcfaa180ff7c4cfbad23e74321a2b774f92ca77fd94ce1049175a21c97f"}, 807 | {file = "mypy-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:43d24f6437925ce50139a310a64b2ab048cb2d3694c84c71c3f2a1626d8101dc"}, 808 | {file = "mypy-1.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c482e1246726616088532b5e964e39765b6d1520791348e6c9dc3af25b233828"}, 809 | {file = "mypy-1.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:43b592511672017f5b1a483527fd2684347fdffc041c9ef53428c8dc530f79a3"}, 810 | {file = "mypy-1.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:34a9239d5b3502c17f07fd7c0b2ae6b7dd7d7f6af35fbb5072c6208e76295816"}, 811 | {file = "mypy-1.4.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5703097c4936bbb9e9bce41478c8d08edd2865e177dc4c52be759f81ee4dd26c"}, 812 | {file = "mypy-1.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:e02d700ec8d9b1859790c0475df4e4092c7bf3272a4fd2c9f33d87fac4427b8f"}, 813 | {file = "mypy-1.4.1-py3-none-any.whl", hash = "sha256:45d32cec14e7b97af848bddd97d85ea4f0db4d5a149ed9676caa4eb2f7402bb4"}, 814 | {file = "mypy-1.4.1.tar.gz", hash = "sha256:9bbcd9ab8ea1f2e1c8031c21445b511442cc45c89951e49bbf852cbb70755b1b"}, 815 | ] 816 | 817 | [package.dependencies] 818 | mypy-extensions = ">=1.0.0" 819 | tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} 820 | typed-ast = {version = ">=1.4.0,<2", markers = "python_version < \"3.8\""} 821 | typing-extensions = ">=4.1.0" 822 | 823 | [package.extras] 824 | dmypy = ["psutil (>=4.0)"] 825 | install-types = ["pip"] 826 | python2 = ["typed-ast (>=1.4.0,<2)"] 827 | reports = ["lxml"] 828 | 829 | [[package]] 830 | name = "mypy-extensions" 831 | version = "1.0.0" 832 | description = "Type system extensions for programs checked with the mypy type checker." 833 | optional = false 834 | python-versions = ">=3.5" 835 | files = [ 836 | {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, 837 | {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, 838 | ] 839 | 840 | [[package]] 841 | name = "nodeenv" 842 | version = "1.7.0" 843 | description = "Node.js virtual environment builder" 844 | optional = false 845 | python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" 846 | files = [ 847 | {file = "nodeenv-1.7.0-py2.py3-none-any.whl", hash = "sha256:27083a7b96a25f2f5e1d8cb4b6317ee8aeda3bdd121394e5ac54e498028a042e"}, 848 | {file = "nodeenv-1.7.0.tar.gz", hash = "sha256:e0e7f7dfb85fc5394c6fe1e8fa98131a2473e04311a45afb6508f7cf1836fa2b"}, 849 | ] 850 | 851 | [package.dependencies] 852 | setuptools = "*" 853 | 854 | [[package]] 855 | name = "packaging" 856 | version = "23.0" 857 | description = "Core utilities for Python packages" 858 | optional = false 859 | python-versions = ">=3.7" 860 | files = [ 861 | {file = "packaging-23.0-py3-none-any.whl", hash = "sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2"}, 862 | {file = "packaging-23.0.tar.gz", hash = "sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97"}, 863 | ] 864 | 865 | [[package]] 866 | name = "pathspec" 867 | version = "0.11.0" 868 | description = "Utility library for gitignore style pattern matching of file paths." 869 | optional = false 870 | python-versions = ">=3.7" 871 | files = [ 872 | {file = "pathspec-0.11.0-py3-none-any.whl", hash = "sha256:3a66eb970cbac598f9e5ccb5b2cf58930cd8e3ed86d393d541eaf2d8b1705229"}, 873 | {file = "pathspec-0.11.0.tar.gz", hash = "sha256:64d338d4e0914e91c1792321e6907b5a593f1ab1851de7fc269557a21b30ebbc"}, 874 | ] 875 | 876 | [[package]] 877 | name = "pbr" 878 | version = "5.11.1" 879 | description = "Python Build Reasonableness" 880 | optional = false 881 | python-versions = ">=2.6" 882 | files = [ 883 | {file = "pbr-5.11.1-py2.py3-none-any.whl", hash = "sha256:567f09558bae2b3ab53cb3c1e2e33e726ff3338e7bae3db5dc954b3a44eef12b"}, 884 | {file = "pbr-5.11.1.tar.gz", hash = "sha256:aefc51675b0b533d56bb5fd1c8c6c0522fe31896679882e1c4c63d5e4a0fccb3"}, 885 | ] 886 | 887 | [[package]] 888 | name = "pep8-naming" 889 | version = "0.13.3" 890 | description = "Check PEP-8 naming conventions, plugin for flake8" 891 | optional = false 892 | python-versions = ">=3.7" 893 | files = [ 894 | {file = "pep8-naming-0.13.3.tar.gz", hash = "sha256:1705f046dfcd851378aac3be1cd1551c7c1e5ff363bacad707d43007877fa971"}, 895 | {file = "pep8_naming-0.13.3-py3-none-any.whl", hash = "sha256:1a86b8c71a03337c97181917e2b472f0f5e4ccb06844a0d6f0a33522549e7a80"}, 896 | ] 897 | 898 | [package.dependencies] 899 | flake8 = ">=5.0.0" 900 | 901 | [[package]] 902 | name = "platformdirs" 903 | version = "2.6.2" 904 | description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." 905 | optional = false 906 | python-versions = ">=3.7" 907 | files = [ 908 | {file = "platformdirs-2.6.2-py3-none-any.whl", hash = "sha256:83c8f6d04389165de7c9b6f0c682439697887bca0aa2f1c87ef1826be3584490"}, 909 | {file = "platformdirs-2.6.2.tar.gz", hash = "sha256:e1fea1fe471b9ff8332e229df3cb7de4f53eeea4998d3b6bfff542115e998bd2"}, 910 | ] 911 | 912 | [package.dependencies] 913 | typing-extensions = {version = ">=4.4", markers = "python_version < \"3.8\""} 914 | 915 | [package.extras] 916 | docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=5.3)", "sphinx-autodoc-typehints (>=1.19.5)"] 917 | test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest (>=7.2)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] 918 | 919 | [[package]] 920 | name = "pluggy" 921 | version = "1.0.0" 922 | description = "plugin and hook calling mechanisms for python" 923 | optional = false 924 | python-versions = ">=3.6" 925 | files = [ 926 | {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, 927 | {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, 928 | ] 929 | 930 | [package.dependencies] 931 | importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} 932 | 933 | [package.extras] 934 | dev = ["pre-commit", "tox"] 935 | testing = ["pytest", "pytest-benchmark"] 936 | 937 | [[package]] 938 | name = "pre-commit" 939 | version = "2.21.0" 940 | description = "A framework for managing and maintaining multi-language pre-commit hooks." 941 | optional = false 942 | python-versions = ">=3.7" 943 | files = [ 944 | {file = "pre_commit-2.21.0-py2.py3-none-any.whl", hash = "sha256:e2f91727039fc39a92f58a588a25b87f936de6567eed4f0e673e0507edc75bad"}, 945 | {file = "pre_commit-2.21.0.tar.gz", hash = "sha256:31ef31af7e474a8d8995027fefdfcf509b5c913ff31f2015b4ec4beb26a6f658"}, 946 | ] 947 | 948 | [package.dependencies] 949 | cfgv = ">=2.0.0" 950 | identify = ">=1.0.0" 951 | importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} 952 | nodeenv = ">=0.11.1" 953 | pyyaml = ">=5.1" 954 | virtualenv = ">=20.10.0" 955 | 956 | [[package]] 957 | name = "pre-commit-hooks" 958 | version = "4.4.0" 959 | description = "Some out-of-the-box hooks for pre-commit." 960 | optional = false 961 | python-versions = ">=3.7" 962 | files = [ 963 | {file = "pre_commit_hooks-4.4.0-py2.py3-none-any.whl", hash = "sha256:fc8837335476221ccccda3d176ed6ae29fe58753ce7e8b7863f5d0f987328fc6"}, 964 | {file = "pre_commit_hooks-4.4.0.tar.gz", hash = "sha256:7011eed8e1a25cde94693da009cba76392194cecc2f3f06c51a44ea6ad6c2af9"}, 965 | ] 966 | 967 | [package.dependencies] 968 | "ruamel.yaml" = ">=0.15" 969 | tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} 970 | 971 | [[package]] 972 | name = "pycodestyle" 973 | version = "2.9.1" 974 | description = "Python style guide checker" 975 | optional = false 976 | python-versions = ">=3.6" 977 | files = [ 978 | {file = "pycodestyle-2.9.1-py2.py3-none-any.whl", hash = "sha256:d1735fc58b418fd7c5f658d28d943854f8a849b01a5d0a1e6f3f3fdd0166804b"}, 979 | {file = "pycodestyle-2.9.1.tar.gz", hash = "sha256:2c9607871d58c76354b697b42f5d57e1ada7d261c261efac224b664affdc5785"}, 980 | ] 981 | 982 | [[package]] 983 | name = "pydantic" 984 | version = "1.10.9" 985 | description = "Data validation and settings management using python type hints" 986 | optional = false 987 | python-versions = ">=3.7" 988 | files = [ 989 | {file = "pydantic-1.10.9-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e692dec4a40bfb40ca530e07805b1208c1de071a18d26af4a2a0d79015b352ca"}, 990 | {file = "pydantic-1.10.9-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3c52eb595db83e189419bf337b59154bdcca642ee4b2a09e5d7797e41ace783f"}, 991 | {file = "pydantic-1.10.9-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:939328fd539b8d0edf244327398a667b6b140afd3bf7e347cf9813c736211896"}, 992 | {file = "pydantic-1.10.9-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b48d3d634bca23b172f47f2335c617d3fcb4b3ba18481c96b7943a4c634f5c8d"}, 993 | {file = "pydantic-1.10.9-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:f0b7628fb8efe60fe66fd4adadd7ad2304014770cdc1f4934db41fe46cc8825f"}, 994 | {file = "pydantic-1.10.9-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e1aa5c2410769ca28aa9a7841b80d9d9a1c5f223928ca8bec7e7c9a34d26b1d4"}, 995 | {file = "pydantic-1.10.9-cp310-cp310-win_amd64.whl", hash = "sha256:eec39224b2b2e861259d6f3c8b6290d4e0fbdce147adb797484a42278a1a486f"}, 996 | {file = "pydantic-1.10.9-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d111a21bbbfd85c17248130deac02bbd9b5e20b303338e0dbe0faa78330e37e0"}, 997 | {file = "pydantic-1.10.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2e9aec8627a1a6823fc62fb96480abe3eb10168fd0d859ee3d3b395105ae19a7"}, 998 | {file = "pydantic-1.10.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07293ab08e7b4d3c9d7de4949a0ea571f11e4557d19ea24dd3ae0c524c0c334d"}, 999 | {file = "pydantic-1.10.9-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ee829b86ce984261d99ff2fd6e88f2230068d96c2a582f29583ed602ef3fc2c"}, 1000 | {file = "pydantic-1.10.9-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4b466a23009ff5cdd7076eb56aca537c745ca491293cc38e72bf1e0e00de5b91"}, 1001 | {file = "pydantic-1.10.9-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7847ca62e581e6088d9000f3c497267868ca2fa89432714e21a4fb33a04d52e8"}, 1002 | {file = "pydantic-1.10.9-cp311-cp311-win_amd64.whl", hash = "sha256:7845b31959468bc5b78d7b95ec52fe5be32b55d0d09983a877cca6aedc51068f"}, 1003 | {file = "pydantic-1.10.9-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:517a681919bf880ce1dac7e5bc0c3af1e58ba118fd774da2ffcd93c5f96eaece"}, 1004 | {file = "pydantic-1.10.9-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67195274fd27780f15c4c372f4ba9a5c02dad6d50647b917b6a92bf00b3d301a"}, 1005 | {file = "pydantic-1.10.9-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2196c06484da2b3fded1ab6dbe182bdabeb09f6318b7fdc412609ee2b564c49a"}, 1006 | {file = "pydantic-1.10.9-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:6257bb45ad78abacda13f15bde5886efd6bf549dd71085e64b8dcf9919c38b60"}, 1007 | {file = "pydantic-1.10.9-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:3283b574b01e8dbc982080d8287c968489d25329a463b29a90d4157de4f2baaf"}, 1008 | {file = "pydantic-1.10.9-cp37-cp37m-win_amd64.whl", hash = "sha256:5f8bbaf4013b9a50e8100333cc4e3fa2f81214033e05ac5aa44fa24a98670a29"}, 1009 | {file = "pydantic-1.10.9-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b9cd67fb763248cbe38f0593cd8611bfe4b8ad82acb3bdf2b0898c23415a1f82"}, 1010 | {file = "pydantic-1.10.9-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f50e1764ce9353be67267e7fd0da08349397c7db17a562ad036aa7c8f4adfdb6"}, 1011 | {file = "pydantic-1.10.9-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:73ef93e5e1d3c8e83f1ff2e7fdd026d9e063c7e089394869a6e2985696693766"}, 1012 | {file = "pydantic-1.10.9-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:128d9453d92e6e81e881dd7e2484e08d8b164da5507f62d06ceecf84bf2e21d3"}, 1013 | {file = "pydantic-1.10.9-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ad428e92ab68798d9326bb3e5515bc927444a3d71a93b4a2ca02a8a5d795c572"}, 1014 | {file = "pydantic-1.10.9-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fab81a92f42d6d525dd47ced310b0c3e10c416bbfae5d59523e63ea22f82b31e"}, 1015 | {file = "pydantic-1.10.9-cp38-cp38-win_amd64.whl", hash = "sha256:963671eda0b6ba6926d8fc759e3e10335e1dc1b71ff2a43ed2efd6996634dafb"}, 1016 | {file = "pydantic-1.10.9-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:970b1bdc6243ef663ba5c7e36ac9ab1f2bfecb8ad297c9824b542d41a750b298"}, 1017 | {file = "pydantic-1.10.9-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7e1d5290044f620f80cf1c969c542a5468f3656de47b41aa78100c5baa2b8276"}, 1018 | {file = "pydantic-1.10.9-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83fcff3c7df7adff880622a98022626f4f6dbce6639a88a15a3ce0f96466cb60"}, 1019 | {file = "pydantic-1.10.9-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0da48717dc9495d3a8f215e0d012599db6b8092db02acac5e0d58a65248ec5bc"}, 1020 | {file = "pydantic-1.10.9-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:0a2aabdc73c2a5960e87c3ffebca6ccde88665616d1fd6d3db3178ef427b267a"}, 1021 | {file = "pydantic-1.10.9-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9863b9420d99dfa9c064042304868e8ba08e89081428a1c471858aa2af6f57c4"}, 1022 | {file = "pydantic-1.10.9-cp39-cp39-win_amd64.whl", hash = "sha256:e7c9900b43ac14110efa977be3da28931ffc74c27e96ee89fbcaaf0b0fe338e1"}, 1023 | {file = "pydantic-1.10.9-py3-none-any.whl", hash = "sha256:6cafde02f6699ce4ff643417d1a9223716ec25e228ddc3b436fe7e2d25a1f305"}, 1024 | {file = "pydantic-1.10.9.tar.gz", hash = "sha256:95c70da2cd3b6ddf3b9645ecaa8d98f3d80c606624b6d245558d202cd23ea3be"}, 1025 | ] 1026 | 1027 | [package.dependencies] 1028 | typing-extensions = ">=4.2.0" 1029 | 1030 | [package.extras] 1031 | dotenv = ["python-dotenv (>=0.10.4)"] 1032 | email = ["email-validator (>=1.0.3)"] 1033 | 1034 | [[package]] 1035 | name = "pydocstyle" 1036 | version = "6.3.0" 1037 | description = "Python docstring style checker" 1038 | optional = false 1039 | python-versions = ">=3.6" 1040 | files = [ 1041 | {file = "pydocstyle-6.3.0-py3-none-any.whl", hash = "sha256:118762d452a49d6b05e194ef344a55822987a462831ade91ec5c06fd2169d019"}, 1042 | {file = "pydocstyle-6.3.0.tar.gz", hash = "sha256:7ce43f0c0ac87b07494eb9c0b462c0b73e6ff276807f204d6b53edc72b7e44e1"}, 1043 | ] 1044 | 1045 | [package.dependencies] 1046 | importlib-metadata = {version = ">=2.0.0,<5.0.0", markers = "python_version < \"3.8\""} 1047 | snowballstemmer = ">=2.2.0" 1048 | 1049 | [package.extras] 1050 | toml = ["tomli (>=1.2.3)"] 1051 | 1052 | [[package]] 1053 | name = "pyflakes" 1054 | version = "2.5.0" 1055 | description = "passive checker of Python programs" 1056 | optional = false 1057 | python-versions = ">=3.6" 1058 | files = [ 1059 | {file = "pyflakes-2.5.0-py2.py3-none-any.whl", hash = "sha256:4579f67d887f804e67edb544428f264b7b24f435b263c4614f384135cea553d2"}, 1060 | {file = "pyflakes-2.5.0.tar.gz", hash = "sha256:491feb020dca48ccc562a8c0cbe8df07ee13078df59813b83959cbdada312ea3"}, 1061 | ] 1062 | 1063 | [[package]] 1064 | name = "pygments" 1065 | version = "2.15.1" 1066 | description = "Pygments is a syntax highlighting package written in Python." 1067 | optional = false 1068 | python-versions = ">=3.7" 1069 | files = [ 1070 | {file = "Pygments-2.15.1-py3-none-any.whl", hash = "sha256:db2db3deb4b4179f399a09054b023b6a586b76499d36965813c71aa8ed7b5fd1"}, 1071 | {file = "Pygments-2.15.1.tar.gz", hash = "sha256:8ace4d3c1dd481894b2005f560ead0f9f19ee64fe983366be1a21e171d12775c"}, 1072 | ] 1073 | 1074 | [package.extras] 1075 | plugins = ["importlib-metadata"] 1076 | 1077 | [[package]] 1078 | name = "pynamodb" 1079 | version = "5.5.0" 1080 | description = "A Pythonic Interface to DynamoDB" 1081 | optional = false 1082 | python-versions = ">=3.6" 1083 | files = [ 1084 | {file = "pynamodb-5.5.0-py3-none-any.whl", hash = "sha256:a44fb486fc3e66a25b58d921e07f016f62416e323b381b96c1b725105868dacf"}, 1085 | {file = "pynamodb-5.5.0.tar.gz", hash = "sha256:82f77bb0c21a12756e6781df735ca841f543337847d8522a4ab8db6df7bbfc9f"}, 1086 | ] 1087 | 1088 | [package.dependencies] 1089 | botocore = ">=1.12.54" 1090 | typing-extensions = {version = ">=3.7", markers = "python_version < \"3.8\""} 1091 | 1092 | [package.extras] 1093 | signals = ["blinker (>=1.3,<2.0)"] 1094 | 1095 | [[package]] 1096 | name = "pytest" 1097 | version = "7.4.0" 1098 | description = "pytest: simple powerful testing with Python" 1099 | optional = false 1100 | python-versions = ">=3.7" 1101 | files = [ 1102 | {file = "pytest-7.4.0-py3-none-any.whl", hash = "sha256:78bf16451a2eb8c7a2ea98e32dc119fd2aa758f1d5d66dbf0a59d69a3969df32"}, 1103 | {file = "pytest-7.4.0.tar.gz", hash = "sha256:b4bf8c45bd59934ed84001ad51e11b4ee40d40a1229d2c79f9c592b0a3f6bd8a"}, 1104 | ] 1105 | 1106 | [package.dependencies] 1107 | colorama = {version = "*", markers = "sys_platform == \"win32\""} 1108 | exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} 1109 | importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} 1110 | iniconfig = "*" 1111 | packaging = "*" 1112 | pluggy = ">=0.12,<2.0" 1113 | tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} 1114 | 1115 | [package.extras] 1116 | testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] 1117 | 1118 | [[package]] 1119 | name = "python-dateutil" 1120 | version = "2.8.2" 1121 | description = "Extensions to the standard Python datetime module" 1122 | optional = false 1123 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" 1124 | files = [ 1125 | {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, 1126 | {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, 1127 | ] 1128 | 1129 | [package.dependencies] 1130 | six = ">=1.5" 1131 | 1132 | [[package]] 1133 | name = "pytz" 1134 | version = "2022.7.1" 1135 | description = "World timezone definitions, modern and historical" 1136 | optional = false 1137 | python-versions = "*" 1138 | files = [ 1139 | {file = "pytz-2022.7.1-py2.py3-none-any.whl", hash = "sha256:78f4f37d8198e0627c5f1143240bb0206b8691d8d7ac6d78fee88b78733f8c4a"}, 1140 | {file = "pytz-2022.7.1.tar.gz", hash = "sha256:01a0681c4b9684a28304615eba55d1ab31ae00bf68ec157ec3708a8182dbbcd0"}, 1141 | ] 1142 | 1143 | [[package]] 1144 | name = "pyupgrade" 1145 | version = "3.3.2" 1146 | description = "A tool to automatically upgrade syntax for newer versions." 1147 | optional = false 1148 | python-versions = ">=3.7" 1149 | files = [ 1150 | {file = "pyupgrade-3.3.2-py2.py3-none-any.whl", hash = "sha256:c05b82c911934b3a638b29f48f48dc6e0ef6c57c55ec36f2b41ae9dbf6711b4b"}, 1151 | {file = "pyupgrade-3.3.2.tar.gz", hash = "sha256:bcfed63d38811809f179fd269dec246680b0aaa5bbe662b535826e5fa2275219"}, 1152 | ] 1153 | 1154 | [package.dependencies] 1155 | tokenize-rt = ">=3.2.0" 1156 | 1157 | [[package]] 1158 | name = "pyyaml" 1159 | version = "6.0" 1160 | description = "YAML parser and emitter for Python" 1161 | optional = false 1162 | python-versions = ">=3.6" 1163 | files = [ 1164 | {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, 1165 | {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"}, 1166 | {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"}, 1167 | {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"}, 1168 | {file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"}, 1169 | {file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"}, 1170 | {file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"}, 1171 | {file = "PyYAML-6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358"}, 1172 | {file = "PyYAML-6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1"}, 1173 | {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d"}, 1174 | {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f"}, 1175 | {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782"}, 1176 | {file = "PyYAML-6.0-cp311-cp311-win32.whl", hash = "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7"}, 1177 | {file = "PyYAML-6.0-cp311-cp311-win_amd64.whl", hash = "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf"}, 1178 | {file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"}, 1179 | {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"}, 1180 | {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"}, 1181 | {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"}, 1182 | {file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"}, 1183 | {file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"}, 1184 | {file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"}, 1185 | {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"}, 1186 | {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"}, 1187 | {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"}, 1188 | {file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"}, 1189 | {file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"}, 1190 | {file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"}, 1191 | {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"}, 1192 | {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"}, 1193 | {file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"}, 1194 | {file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"}, 1195 | {file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"}, 1196 | {file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"}, 1197 | {file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"}, 1198 | {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"}, 1199 | {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"}, 1200 | {file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"}, 1201 | {file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"}, 1202 | {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"}, 1203 | {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, 1204 | ] 1205 | 1206 | [[package]] 1207 | name = "requests" 1208 | version = "2.31.0" 1209 | description = "Python HTTP for Humans." 1210 | optional = false 1211 | python-versions = ">=3.7" 1212 | files = [ 1213 | {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, 1214 | {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, 1215 | ] 1216 | 1217 | [package.dependencies] 1218 | certifi = ">=2017.4.17" 1219 | charset-normalizer = ">=2,<4" 1220 | idna = ">=2.5,<4" 1221 | urllib3 = ">=1.21.1,<3" 1222 | 1223 | [package.extras] 1224 | socks = ["PySocks (>=1.5.6,!=1.5.7)"] 1225 | use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] 1226 | 1227 | [[package]] 1228 | name = "restructuredtext-lint" 1229 | version = "1.4.0" 1230 | description = "reStructuredText linter" 1231 | optional = false 1232 | python-versions = "*" 1233 | files = [ 1234 | {file = "restructuredtext_lint-1.4.0.tar.gz", hash = "sha256:1b235c0c922341ab6c530390892eb9e92f90b9b75046063e047cacfb0f050c45"}, 1235 | ] 1236 | 1237 | [package.dependencies] 1238 | docutils = ">=0.11,<1.0" 1239 | 1240 | [[package]] 1241 | name = "ruamel-yaml" 1242 | version = "0.17.21" 1243 | description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order" 1244 | optional = false 1245 | python-versions = ">=3" 1246 | files = [ 1247 | {file = "ruamel.yaml-0.17.21-py3-none-any.whl", hash = "sha256:742b35d3d665023981bd6d16b3d24248ce5df75fdb4e2924e93a05c1f8b61ca7"}, 1248 | {file = "ruamel.yaml-0.17.21.tar.gz", hash = "sha256:8b7ce697a2f212752a35c1ac414471dc16c424c9573be4926b56ff3f5d23b7af"}, 1249 | ] 1250 | 1251 | [package.dependencies] 1252 | "ruamel.yaml.clib" = {version = ">=0.2.6", markers = "platform_python_implementation == \"CPython\" and python_version < \"3.11\""} 1253 | 1254 | [package.extras] 1255 | docs = ["ryd"] 1256 | jinja2 = ["ruamel.yaml.jinja2 (>=0.2)"] 1257 | 1258 | [[package]] 1259 | name = "ruamel-yaml-clib" 1260 | version = "0.2.7" 1261 | description = "C version of reader, parser and emitter for ruamel.yaml derived from libyaml" 1262 | optional = false 1263 | python-versions = ">=3.5" 1264 | files = [ 1265 | {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d5859983f26d8cd7bb5c287ef452e8aacc86501487634573d260968f753e1d71"}, 1266 | {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:debc87a9516b237d0466a711b18b6ebeb17ba9f391eb7f91c649c5c4ec5006c7"}, 1267 | {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:df5828871e6648db72d1c19b4bd24819b80a755c4541d3409f0f7acd0f335c80"}, 1268 | {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:efa08d63ef03d079dcae1dfe334f6c8847ba8b645d08df286358b1f5293d24ab"}, 1269 | {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-win32.whl", hash = "sha256:763d65baa3b952479c4e972669f679fe490eee058d5aa85da483ebae2009d231"}, 1270 | {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:d000f258cf42fec2b1bbf2863c61d7b8918d31ffee905da62dede869254d3b8a"}, 1271 | {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:045e0626baf1c52e5527bd5db361bc83180faaba2ff586e763d3d5982a876a9e"}, 1272 | {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:1a6391a7cabb7641c32517539ca42cf84b87b667bad38b78d4d42dd23e957c81"}, 1273 | {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:9c7617df90c1365638916b98cdd9be833d31d337dbcd722485597b43c4a215bf"}, 1274 | {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:41d0f1fa4c6830176eef5b276af04c89320ea616655d01327d5ce65e50575c94"}, 1275 | {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-win32.whl", hash = "sha256:f6d3d39611ac2e4f62c3128a9eed45f19a6608670c5a2f4f07f24e8de3441d38"}, 1276 | {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-win_amd64.whl", hash = "sha256:da538167284de58a52109a9b89b8f6a53ff8437dd6dc26d33b57bf6699153122"}, 1277 | {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:4b3a93bb9bc662fc1f99c5c3ea8e623d8b23ad22f861eb6fce9377ac07ad6072"}, 1278 | {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-macosx_12_0_arm64.whl", hash = "sha256:a234a20ae07e8469da311e182e70ef6b199d0fbeb6c6cc2901204dd87fb867e8"}, 1279 | {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:15910ef4f3e537eea7fe45f8a5d19997479940d9196f357152a09031c5be59f3"}, 1280 | {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:370445fd795706fd291ab00c9df38a0caed0f17a6fb46b0f607668ecb16ce763"}, 1281 | {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-win32.whl", hash = "sha256:ecdf1a604009bd35c674b9225a8fa609e0282d9b896c03dd441a91e5f53b534e"}, 1282 | {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-win_amd64.whl", hash = "sha256:f34019dced51047d6f70cb9383b2ae2853b7fc4dce65129a5acd49f4f9256646"}, 1283 | {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2aa261c29a5545adfef9296b7e33941f46aa5bbd21164228e833412af4c9c75f"}, 1284 | {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-macosx_12_0_arm64.whl", hash = "sha256:f01da5790e95815eb5a8a138508c01c758e5f5bc0ce4286c4f7028b8dd7ac3d0"}, 1285 | {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:40d030e2329ce5286d6b231b8726959ebbe0404c92f0a578c0e2482182e38282"}, 1286 | {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:c3ca1fbba4ae962521e5eb66d72998b51f0f4d0f608d3c0347a48e1af262efa7"}, 1287 | {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-win32.whl", hash = "sha256:7bdb4c06b063f6fd55e472e201317a3bb6cdeeee5d5a38512ea5c01e1acbdd93"}, 1288 | {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-win_amd64.whl", hash = "sha256:be2a7ad8fd8f7442b24323d24ba0b56c51219513cfa45b9ada3b87b76c374d4b"}, 1289 | {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:91a789b4aa0097b78c93e3dc4b40040ba55bef518f84a40d4442f713b4094acb"}, 1290 | {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:99e77daab5d13a48a4054803d052ff40780278240a902b880dd37a51ba01a307"}, 1291 | {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:3243f48ecd450eddadc2d11b5feb08aca941b5cd98c9b1db14b2fd128be8c697"}, 1292 | {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:8831a2cedcd0f0927f788c5bdf6567d9dc9cc235646a434986a852af1cb54b4b"}, 1293 | {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-win32.whl", hash = "sha256:3110a99e0f94a4a3470ff67fc20d3f96c25b13d24c6980ff841e82bafe827cac"}, 1294 | {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-win_amd64.whl", hash = "sha256:92460ce908546ab69770b2e576e4f99fbb4ce6ab4b245345a3869a0a0410488f"}, 1295 | {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5bc0667c1eb8f83a3752b71b9c4ba55ef7c7058ae57022dd9b29065186a113d9"}, 1296 | {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:4a4d8d417868d68b979076a9be6a38c676eca060785abaa6709c7b31593c35d1"}, 1297 | {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:bf9a6bc4a0221538b1a7de3ed7bca4c93c02346853f44e1cd764be0023cd3640"}, 1298 | {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:a7b301ff08055d73223058b5c46c55638917f04d21577c95e00e0c4d79201a6b"}, 1299 | {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-win32.whl", hash = "sha256:d5e51e2901ec2366b79f16c2299a03e74ba4531ddcfacc1416639c557aef0ad8"}, 1300 | {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-win_amd64.whl", hash = "sha256:184faeaec61dbaa3cace407cffc5819f7b977e75360e8d5ca19461cd851a5fc5"}, 1301 | {file = "ruamel.yaml.clib-0.2.7.tar.gz", hash = "sha256:1f08fd5a2bea9c4180db71678e850b995d2a5f4537be0e94557668cf0f5f9497"}, 1302 | ] 1303 | 1304 | [[package]] 1305 | name = "safety" 1306 | version = "2.3.4" 1307 | description = "Checks installed dependencies for known vulnerabilities and licenses." 1308 | optional = false 1309 | python-versions = "*" 1310 | files = [ 1311 | {file = "safety-2.3.4-py3-none-any.whl", hash = "sha256:6224dcd9b20986a2b2c5e7acfdfba6bca42bb11b2783b24ed04f32317e5167ea"}, 1312 | {file = "safety-2.3.4.tar.gz", hash = "sha256:b9e74e794e82f54d11f4091c5d820c4d2d81de9f953bf0b4f33ac8bc402ae72c"}, 1313 | ] 1314 | 1315 | [package.dependencies] 1316 | Click = ">=8.0.2" 1317 | dparse = ">=0.6.2" 1318 | packaging = ">=21.0" 1319 | requests = "*" 1320 | "ruamel.yaml" = ">=0.17.21" 1321 | setuptools = ">=19.3" 1322 | 1323 | [package.extras] 1324 | github = ["jinja2 (>=3.1.0)", "pygithub (>=1.43.3)"] 1325 | gitlab = ["python-gitlab (>=1.3.0)"] 1326 | 1327 | [[package]] 1328 | name = "setuptools" 1329 | version = "67.4.0" 1330 | description = "Easily download, build, install, upgrade, and uninstall Python packages" 1331 | optional = false 1332 | python-versions = ">=3.7" 1333 | files = [ 1334 | {file = "setuptools-67.4.0-py3-none-any.whl", hash = "sha256:f106dee1b506dee5102cc3f3e9e68137bbad6d47b616be7991714b0c62204251"}, 1335 | {file = "setuptools-67.4.0.tar.gz", hash = "sha256:e5fd0a713141a4a105412233c63dc4e17ba0090c8e8334594ac790ec97792330"}, 1336 | ] 1337 | 1338 | [package.extras] 1339 | docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] 1340 | testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] 1341 | testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] 1342 | 1343 | [[package]] 1344 | name = "six" 1345 | version = "1.16.0" 1346 | description = "Python 2 and 3 compatibility utilities" 1347 | optional = false 1348 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" 1349 | files = [ 1350 | {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, 1351 | {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, 1352 | ] 1353 | 1354 | [[package]] 1355 | name = "smmap" 1356 | version = "5.0.0" 1357 | description = "A pure Python implementation of a sliding window memory map manager" 1358 | optional = false 1359 | python-versions = ">=3.6" 1360 | files = [ 1361 | {file = "smmap-5.0.0-py3-none-any.whl", hash = "sha256:2aba19d6a040e78d8b09de5c57e96207b09ed71d8e55ce0959eeee6c8e190d94"}, 1362 | {file = "smmap-5.0.0.tar.gz", hash = "sha256:c840e62059cd3be204b0c9c9f74be2c09d5648eddd4580d9314c3ecde0b30936"}, 1363 | ] 1364 | 1365 | [[package]] 1366 | name = "snowballstemmer" 1367 | version = "2.2.0" 1368 | description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." 1369 | optional = false 1370 | python-versions = "*" 1371 | files = [ 1372 | {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, 1373 | {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, 1374 | ] 1375 | 1376 | [[package]] 1377 | name = "soupsieve" 1378 | version = "2.4" 1379 | description = "A modern CSS selector implementation for Beautiful Soup." 1380 | optional = false 1381 | python-versions = ">=3.7" 1382 | files = [ 1383 | {file = "soupsieve-2.4-py3-none-any.whl", hash = "sha256:49e5368c2cda80ee7e84da9dbe3e110b70a4575f196efb74e51b94549d921955"}, 1384 | {file = "soupsieve-2.4.tar.gz", hash = "sha256:e28dba9ca6c7c00173e34e4ba57448f0688bb681b7c5e8bf4971daafc093d69a"}, 1385 | ] 1386 | 1387 | [[package]] 1388 | name = "sphinx" 1389 | version = "4.3.2" 1390 | description = "Python documentation generator" 1391 | optional = false 1392 | python-versions = ">=3.6" 1393 | files = [ 1394 | {file = "Sphinx-4.3.2-py3-none-any.whl", hash = "sha256:6a11ea5dd0bdb197f9c2abc2e0ce73e01340464feaece525e64036546d24c851"}, 1395 | {file = "Sphinx-4.3.2.tar.gz", hash = "sha256:0a8836751a68306b3fe97ecbe44db786f8479c3bf4b80e3a7f5c838657b4698c"}, 1396 | ] 1397 | 1398 | [package.dependencies] 1399 | alabaster = ">=0.7,<0.8" 1400 | babel = ">=1.3" 1401 | colorama = {version = ">=0.3.5", markers = "sys_platform == \"win32\""} 1402 | docutils = ">=0.14,<0.18" 1403 | imagesize = "*" 1404 | Jinja2 = ">=2.3" 1405 | packaging = "*" 1406 | Pygments = ">=2.0" 1407 | requests = ">=2.5.0" 1408 | setuptools = "*" 1409 | snowballstemmer = ">=1.1" 1410 | sphinxcontrib-applehelp = "*" 1411 | sphinxcontrib-devhelp = "*" 1412 | sphinxcontrib-htmlhelp = ">=2.0.0" 1413 | sphinxcontrib-jsmath = "*" 1414 | sphinxcontrib-qthelp = "*" 1415 | sphinxcontrib-serializinghtml = ">=1.1.5" 1416 | 1417 | [package.extras] 1418 | docs = ["sphinxcontrib-websupport"] 1419 | lint = ["docutils-stubs", "flake8 (>=3.5.0)", "isort", "mypy (>=0.920)", "types-pkg-resources", "types-requests", "types-typed-ast"] 1420 | test = ["cython", "html5lib", "pytest", "pytest-cov", "typed-ast"] 1421 | 1422 | [[package]] 1423 | name = "sphinx-autobuild" 1424 | version = "2021.3.14" 1425 | description = "Rebuild Sphinx documentation on changes, with live-reload in the browser." 1426 | optional = false 1427 | python-versions = ">=3.6" 1428 | files = [ 1429 | {file = "sphinx-autobuild-2021.3.14.tar.gz", hash = "sha256:de1ca3b66e271d2b5b5140c35034c89e47f263f2cd5db302c9217065f7443f05"}, 1430 | {file = "sphinx_autobuild-2021.3.14-py3-none-any.whl", hash = "sha256:8fe8cbfdb75db04475232f05187c776f46f6e9e04cacf1e49ce81bdac649ccac"}, 1431 | ] 1432 | 1433 | [package.dependencies] 1434 | colorama = "*" 1435 | livereload = "*" 1436 | sphinx = "*" 1437 | 1438 | [package.extras] 1439 | test = ["pytest", "pytest-cov"] 1440 | 1441 | [[package]] 1442 | name = "sphinx-basic-ng" 1443 | version = "1.0.0b1" 1444 | description = "A modern skeleton for Sphinx themes." 1445 | optional = false 1446 | python-versions = ">=3.7" 1447 | files = [ 1448 | {file = "sphinx_basic_ng-1.0.0b1-py3-none-any.whl", hash = "sha256:ade597a3029c7865b24ad0eda88318766bcc2f9f4cef60df7e28126fde94db2a"}, 1449 | {file = "sphinx_basic_ng-1.0.0b1.tar.gz", hash = "sha256:89374bd3ccd9452a301786781e28c8718e99960f2d4f411845ea75fc7bb5a9b0"}, 1450 | ] 1451 | 1452 | [package.dependencies] 1453 | sphinx = ">=4.0" 1454 | 1455 | [package.extras] 1456 | docs = ["furo", "ipython", "myst-parser", "sphinx-copybutton", "sphinx-inline-tabs"] 1457 | 1458 | [[package]] 1459 | name = "sphinx-click" 1460 | version = "4.4.0" 1461 | description = "Sphinx extension that automatically documents click applications" 1462 | optional = false 1463 | python-versions = ">=3.7" 1464 | files = [ 1465 | {file = "sphinx-click-4.4.0.tar.gz", hash = "sha256:cc67692bd28f482c7f01531c61b64e9d2f069bfcf3d24cbbb51d4a84a749fa48"}, 1466 | {file = "sphinx_click-4.4.0-py3-none-any.whl", hash = "sha256:2821c10a68fc9ee6ce7c92fad26540d8d8c8f45e6d7258f0e4fb7529ae8fab49"}, 1467 | ] 1468 | 1469 | [package.dependencies] 1470 | click = ">=7.0" 1471 | docutils = "*" 1472 | sphinx = ">=2.0" 1473 | 1474 | [[package]] 1475 | name = "sphinxcontrib-applehelp" 1476 | version = "1.0.2" 1477 | description = "sphinxcontrib-applehelp is a sphinx extension which outputs Apple help books" 1478 | optional = false 1479 | python-versions = ">=3.5" 1480 | files = [ 1481 | {file = "sphinxcontrib-applehelp-1.0.2.tar.gz", hash = "sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58"}, 1482 | {file = "sphinxcontrib_applehelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a"}, 1483 | ] 1484 | 1485 | [package.extras] 1486 | lint = ["docutils-stubs", "flake8", "mypy"] 1487 | test = ["pytest"] 1488 | 1489 | [[package]] 1490 | name = "sphinxcontrib-devhelp" 1491 | version = "1.0.2" 1492 | description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document." 1493 | optional = false 1494 | python-versions = ">=3.5" 1495 | files = [ 1496 | {file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"}, 1497 | {file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"}, 1498 | ] 1499 | 1500 | [package.extras] 1501 | lint = ["docutils-stubs", "flake8", "mypy"] 1502 | test = ["pytest"] 1503 | 1504 | [[package]] 1505 | name = "sphinxcontrib-htmlhelp" 1506 | version = "2.0.0" 1507 | description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" 1508 | optional = false 1509 | python-versions = ">=3.6" 1510 | files = [ 1511 | {file = "sphinxcontrib-htmlhelp-2.0.0.tar.gz", hash = "sha256:f5f8bb2d0d629f398bf47d0d69c07bc13b65f75a81ad9e2f71a63d4b7a2f6db2"}, 1512 | {file = "sphinxcontrib_htmlhelp-2.0.0-py2.py3-none-any.whl", hash = "sha256:d412243dfb797ae3ec2b59eca0e52dac12e75a241bf0e4eb861e450d06c6ed07"}, 1513 | ] 1514 | 1515 | [package.extras] 1516 | lint = ["docutils-stubs", "flake8", "mypy"] 1517 | test = ["html5lib", "pytest"] 1518 | 1519 | [[package]] 1520 | name = "sphinxcontrib-jsmath" 1521 | version = "1.0.1" 1522 | description = "A sphinx extension which renders display math in HTML via JavaScript" 1523 | optional = false 1524 | python-versions = ">=3.5" 1525 | files = [ 1526 | {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"}, 1527 | {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"}, 1528 | ] 1529 | 1530 | [package.extras] 1531 | test = ["flake8", "mypy", "pytest"] 1532 | 1533 | [[package]] 1534 | name = "sphinxcontrib-qthelp" 1535 | version = "1.0.3" 1536 | description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document." 1537 | optional = false 1538 | python-versions = ">=3.5" 1539 | files = [ 1540 | {file = "sphinxcontrib-qthelp-1.0.3.tar.gz", hash = "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72"}, 1541 | {file = "sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"}, 1542 | ] 1543 | 1544 | [package.extras] 1545 | lint = ["docutils-stubs", "flake8", "mypy"] 1546 | test = ["pytest"] 1547 | 1548 | [[package]] 1549 | name = "sphinxcontrib-serializinghtml" 1550 | version = "1.1.5" 1551 | description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)." 1552 | optional = false 1553 | python-versions = ">=3.5" 1554 | files = [ 1555 | {file = "sphinxcontrib-serializinghtml-1.1.5.tar.gz", hash = "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"}, 1556 | {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"}, 1557 | ] 1558 | 1559 | [package.extras] 1560 | lint = ["docutils-stubs", "flake8", "mypy"] 1561 | test = ["pytest"] 1562 | 1563 | [[package]] 1564 | name = "stevedore" 1565 | version = "3.5.2" 1566 | description = "Manage dynamic plugins for Python applications" 1567 | optional = false 1568 | python-versions = ">=3.6" 1569 | files = [ 1570 | {file = "stevedore-3.5.2-py3-none-any.whl", hash = "sha256:fa2630e3d0ad3e22d4914aff2501445815b9a4467a6edc49387c667a38faf5bf"}, 1571 | {file = "stevedore-3.5.2.tar.gz", hash = "sha256:cf99f41fc0d5a4f185ca4d3d42b03be9011b0a1ec1a4ea1a282be1b4b306dcc2"}, 1572 | ] 1573 | 1574 | [package.dependencies] 1575 | importlib-metadata = {version = ">=1.7.0", markers = "python_version < \"3.8\""} 1576 | pbr = ">=2.0.0,<2.1.0 || >2.1.0" 1577 | 1578 | [[package]] 1579 | name = "tokenize-rt" 1580 | version = "5.0.0" 1581 | description = "A wrapper around the stdlib `tokenize` which roundtrips." 1582 | optional = false 1583 | python-versions = ">=3.7" 1584 | files = [ 1585 | {file = "tokenize_rt-5.0.0-py2.py3-none-any.whl", hash = "sha256:c67772c662c6b3dc65edf66808577968fb10badfc2042e3027196bed4daf9e5a"}, 1586 | {file = "tokenize_rt-5.0.0.tar.gz", hash = "sha256:3160bc0c3e8491312d0485171dea861fc160a240f5f5766b72a1165408d10740"}, 1587 | ] 1588 | 1589 | [[package]] 1590 | name = "toml" 1591 | version = "0.10.2" 1592 | description = "Python Library for Tom's Obvious, Minimal Language" 1593 | optional = false 1594 | python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" 1595 | files = [ 1596 | {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, 1597 | {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, 1598 | ] 1599 | 1600 | [[package]] 1601 | name = "tomli" 1602 | version = "2.0.1" 1603 | description = "A lil' TOML parser" 1604 | optional = false 1605 | python-versions = ">=3.7" 1606 | files = [ 1607 | {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, 1608 | {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, 1609 | ] 1610 | 1611 | [[package]] 1612 | name = "tornado" 1613 | version = "6.2" 1614 | description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." 1615 | optional = false 1616 | python-versions = ">= 3.7" 1617 | files = [ 1618 | {file = "tornado-6.2-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:20f638fd8cc85f3cbae3c732326e96addff0a15e22d80f049e00121651e82e72"}, 1619 | {file = "tornado-6.2-cp37-abi3-macosx_10_9_x86_64.whl", hash = "sha256:87dcafae3e884462f90c90ecc200defe5e580a7fbbb4365eda7c7c1eb809ebc9"}, 1620 | {file = "tornado-6.2-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba09ef14ca9893954244fd872798b4ccb2367c165946ce2dd7376aebdde8e3ac"}, 1621 | {file = "tornado-6.2-cp37-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b8150f721c101abdef99073bf66d3903e292d851bee51910839831caba341a75"}, 1622 | {file = "tornado-6.2-cp37-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3a2f5999215a3a06a4fc218026cd84c61b8b2b40ac5296a6db1f1451ef04c1e"}, 1623 | {file = "tornado-6.2-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:5f8c52d219d4995388119af7ccaa0bcec289535747620116a58d830e7c25d8a8"}, 1624 | {file = "tornado-6.2-cp37-abi3-musllinux_1_1_i686.whl", hash = "sha256:6fdfabffd8dfcb6cf887428849d30cf19a3ea34c2c248461e1f7d718ad30b66b"}, 1625 | {file = "tornado-6.2-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:1d54d13ab8414ed44de07efecb97d4ef7c39f7438cf5e976ccd356bebb1b5fca"}, 1626 | {file = "tornado-6.2-cp37-abi3-win32.whl", hash = "sha256:5c87076709343557ef8032934ce5f637dbb552efa7b21d08e89ae7619ed0eb23"}, 1627 | {file = "tornado-6.2-cp37-abi3-win_amd64.whl", hash = "sha256:e5f923aa6a47e133d1cf87d60700889d7eae68988704e20c75fb2d65677a8e4b"}, 1628 | {file = "tornado-6.2.tar.gz", hash = "sha256:9b630419bde84ec666bfd7ea0a4cb2a8a651c2d5cccdbdd1972a0c859dfc3c13"}, 1629 | ] 1630 | 1631 | [[package]] 1632 | name = "typed-ast" 1633 | version = "1.5.4" 1634 | description = "a fork of Python 2 and 3 ast modules with type comment support" 1635 | optional = false 1636 | python-versions = ">=3.6" 1637 | files = [ 1638 | {file = "typed_ast-1.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:669dd0c4167f6f2cd9f57041e03c3c2ebf9063d0757dc89f79ba1daa2bfca9d4"}, 1639 | {file = "typed_ast-1.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:211260621ab1cd7324e0798d6be953d00b74e0428382991adfddb352252f1d62"}, 1640 | {file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:267e3f78697a6c00c689c03db4876dd1efdfea2f251a5ad6555e82a26847b4ac"}, 1641 | {file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c542eeda69212fa10a7ada75e668876fdec5f856cd3d06829e6aa64ad17c8dfe"}, 1642 | {file = "typed_ast-1.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:a9916d2bb8865f973824fb47436fa45e1ebf2efd920f2b9f99342cb7fab93f72"}, 1643 | {file = "typed_ast-1.5.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:79b1e0869db7c830ba6a981d58711c88b6677506e648496b1f64ac7d15633aec"}, 1644 | {file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a94d55d142c9265f4ea46fab70977a1944ecae359ae867397757d836ea5a3f47"}, 1645 | {file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:183afdf0ec5b1b211724dfef3d2cad2d767cbefac291f24d69b00546c1837fb6"}, 1646 | {file = "typed_ast-1.5.4-cp36-cp36m-win_amd64.whl", hash = "sha256:639c5f0b21776605dd6c9dbe592d5228f021404dafd377e2b7ac046b0349b1a1"}, 1647 | {file = "typed_ast-1.5.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:cf4afcfac006ece570e32d6fa90ab74a17245b83dfd6655a6f68568098345ff6"}, 1648 | {file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed855bbe3eb3715fca349c80174cfcfd699c2f9de574d40527b8429acae23a66"}, 1649 | {file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6778e1b2f81dfc7bc58e4b259363b83d2e509a65198e85d5700dfae4c6c8ff1c"}, 1650 | {file = "typed_ast-1.5.4-cp37-cp37m-win_amd64.whl", hash = "sha256:0261195c2062caf107831e92a76764c81227dae162c4f75192c0d489faf751a2"}, 1651 | {file = "typed_ast-1.5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2efae9db7a8c05ad5547d522e7dbe62c83d838d3906a3716d1478b6c1d61388d"}, 1652 | {file = "typed_ast-1.5.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7d5d014b7daa8b0bf2eaef684295acae12b036d79f54178b92a2b6a56f92278f"}, 1653 | {file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:370788a63915e82fd6f212865a596a0fefcbb7d408bbbb13dea723d971ed8bdc"}, 1654 | {file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4e964b4ff86550a7a7d56345c7864b18f403f5bd7380edf44a3c1fb4ee7ac6c6"}, 1655 | {file = "typed_ast-1.5.4-cp38-cp38-win_amd64.whl", hash = "sha256:683407d92dc953c8a7347119596f0b0e6c55eb98ebebd9b23437501b28dcbb8e"}, 1656 | {file = "typed_ast-1.5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4879da6c9b73443f97e731b617184a596ac1235fe91f98d279a7af36c796da35"}, 1657 | {file = "typed_ast-1.5.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3e123d878ba170397916557d31c8f589951e353cc95fb7f24f6bb69adc1a8a97"}, 1658 | {file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebd9d7f80ccf7a82ac5f88c521115cc55d84e35bf8b446fcd7836eb6b98929a3"}, 1659 | {file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98f80dee3c03455e92796b58b98ff6ca0b2a6f652120c263efdba4d6c5e58f72"}, 1660 | {file = "typed_ast-1.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:0fdbcf2fef0ca421a3f5912555804296f0b0960f0418c440f5d6d3abb549f3e1"}, 1661 | {file = "typed_ast-1.5.4.tar.gz", hash = "sha256:39e21ceb7388e4bb37f4c679d72707ed46c2fbf2a5609b8b8ebc4b067d977df2"}, 1662 | ] 1663 | 1664 | [[package]] 1665 | name = "typeguard" 1666 | version = "2.13.3" 1667 | description = "Run-time type checker for Python" 1668 | optional = false 1669 | python-versions = ">=3.5.3" 1670 | files = [ 1671 | {file = "typeguard-2.13.3-py3-none-any.whl", hash = "sha256:5e3e3be01e887e7eafae5af63d1f36c849aaa94e3a0112097312aabfa16284f1"}, 1672 | {file = "typeguard-2.13.3.tar.gz", hash = "sha256:00edaa8da3a133674796cf5ea87d9f4b4c367d77476e185e80251cc13dfbb8c4"}, 1673 | ] 1674 | 1675 | [package.extras] 1676 | doc = ["sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] 1677 | test = ["mypy", "pytest", "typing-extensions"] 1678 | 1679 | [[package]] 1680 | name = "typing-extensions" 1681 | version = "4.5.0" 1682 | description = "Backported and Experimental Type Hints for Python 3.7+" 1683 | optional = false 1684 | python-versions = ">=3.7" 1685 | files = [ 1686 | {file = "typing_extensions-4.5.0-py3-none-any.whl", hash = "sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4"}, 1687 | {file = "typing_extensions-4.5.0.tar.gz", hash = "sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb"}, 1688 | ] 1689 | 1690 | [[package]] 1691 | name = "urllib3" 1692 | version = "1.26.14" 1693 | description = "HTTP library with thread-safe connection pooling, file post, and more." 1694 | optional = false 1695 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" 1696 | files = [ 1697 | {file = "urllib3-1.26.14-py2.py3-none-any.whl", hash = "sha256:75edcdc2f7d85b137124a6c3c9fc3933cdeaa12ecb9a6a959f22797a0feca7e1"}, 1698 | {file = "urllib3-1.26.14.tar.gz", hash = "sha256:076907bf8fd355cde77728471316625a4d2f7e713c125f51953bb5b3eecf4f72"}, 1699 | ] 1700 | 1701 | [package.extras] 1702 | brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] 1703 | secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] 1704 | socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] 1705 | 1706 | [[package]] 1707 | name = "virtualenv" 1708 | version = "20.16.2" 1709 | description = "Virtual Python Environment builder" 1710 | optional = false 1711 | python-versions = ">=3.6" 1712 | files = [ 1713 | {file = "virtualenv-20.16.2-py2.py3-none-any.whl", hash = "sha256:635b272a8e2f77cb051946f46c60a54ace3cb5e25568228bd6b57fc70eca9ff3"}, 1714 | {file = "virtualenv-20.16.2.tar.gz", hash = "sha256:0ef5be6d07181946891f5abc8047fda8bc2f0b4b9bf222c64e6e8963baee76db"}, 1715 | ] 1716 | 1717 | [package.dependencies] 1718 | distlib = ">=0.3.1,<1" 1719 | filelock = ">=3.2,<4" 1720 | importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} 1721 | platformdirs = ">=2,<3" 1722 | 1723 | [package.extras] 1724 | docs = ["proselint (>=0.10.2)", "sphinx (>=3)", "sphinx-argparse (>=0.2.5)", "sphinx-rtd-theme (>=0.4.3)", "towncrier (>=21.3)"] 1725 | testing = ["coverage (>=4)", "coverage-enable-subprocess (>=1)", "flaky (>=3)", "packaging (>=20.0)", "pytest (>=4)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.1)", "pytest-mock (>=2)", "pytest-randomly (>=1)", "pytest-timeout (>=1)"] 1726 | 1727 | [[package]] 1728 | name = "xdoctest" 1729 | version = "1.1.1" 1730 | description = "A rewrite of the builtin doctest module" 1731 | optional = false 1732 | python-versions = ">=3.6" 1733 | files = [ 1734 | {file = "xdoctest-1.1.1-py3-none-any.whl", hash = "sha256:d59d4ed91cb92e4430ef0ad1b134a2bef02adff7d2fb9c9f057547bee44081a2"}, 1735 | {file = "xdoctest-1.1.1.tar.gz", hash = "sha256:2eac8131bdcdf2781b4e5a62d6de87f044b730cc8db8af142a51bb29c245e779"}, 1736 | ] 1737 | 1738 | [package.dependencies] 1739 | colorama = {version = "*", optional = true, markers = "platform_system == \"Windows\" and extra == \"colors\""} 1740 | Pygments = {version = "*", optional = true, markers = "python_version >= \"3.5.0\" and extra == \"colors\""} 1741 | six = "*" 1742 | 1743 | [package.extras] 1744 | all = ["IPython", "IPython", "Pygments", "Pygments", "attrs", "codecov", "colorama", "debugpy", "debugpy", "debugpy", "debugpy", "debugpy", "ipykernel", "ipykernel", "ipython-genutils", "jedi", "jinja2", "jupyter-client", "jupyter-client", "jupyter-core", "nbconvert", "pyflakes", "pytest", "pytest", "pytest", "pytest-cov", "six", "tomli", "typing"] 1745 | all-strict = ["IPython (==7.10.0)", "IPython (==7.23.1)", "Pygments (==2.0.0)", "Pygments (==2.4.1)", "attrs (==19.2.0)", "codecov (==2.0.15)", "colorama (==0.4.1)", "debugpy (==1.0.0)", "debugpy (==1.0.0)", "debugpy (==1.0.0)", "debugpy (==1.3.0)", "debugpy (==1.6.0)", "ipykernel (==5.2.0)", "ipykernel (==6.0.0)", "ipython-genutils (==0.2.0)", "jedi (==0.16)", "jinja2 (==3.0.0)", "jupyter-client (==6.1.5)", "jupyter-client (==7.0.0)", "jupyter-core (==4.7.0)", "nbconvert (==6.0.0)", "pyflakes (==2.2.0)", "pytest (==4.6.0)", "pytest (==4.6.0)", "pytest (==6.2.5)", "pytest-cov (==3.0.0)", "six (==1.11.0)", "tomli (==0.2.0)", "typing (==3.7.4)"] 1746 | colors = ["Pygments", "Pygments", "colorama"] 1747 | jupyter = ["IPython", "IPython", "attrs", "debugpy", "debugpy", "debugpy", "debugpy", "debugpy", "ipykernel", "ipykernel", "ipython-genutils", "jedi", "jinja2", "jupyter-client", "jupyter-client", "jupyter-core", "nbconvert"] 1748 | optional = ["IPython", "IPython", "Pygments", "Pygments", "attrs", "colorama", "debugpy", "debugpy", "debugpy", "debugpy", "debugpy", "ipykernel", "ipykernel", "ipython-genutils", "jedi", "jinja2", "jupyter-client", "jupyter-client", "jupyter-core", "nbconvert", "pyflakes", "tomli"] 1749 | optional-strict = ["IPython (==7.10.0)", "IPython (==7.23.1)", "Pygments (==2.0.0)", "Pygments (==2.4.1)", "attrs (==19.2.0)", "colorama (==0.4.1)", "debugpy (==1.0.0)", "debugpy (==1.0.0)", "debugpy (==1.0.0)", "debugpy (==1.3.0)", "debugpy (==1.6.0)", "ipykernel (==5.2.0)", "ipykernel (==6.0.0)", "ipython-genutils (==0.2.0)", "jedi (==0.16)", "jinja2 (==3.0.0)", "jupyter-client (==6.1.5)", "jupyter-client (==7.0.0)", "jupyter-core (==4.7.0)", "nbconvert (==6.0.0)", "pyflakes (==2.2.0)", "tomli (==0.2.0)"] 1750 | runtime-strict = ["six (==1.11.0)"] 1751 | tests = ["codecov", "pytest", "pytest", "pytest", "pytest-cov", "typing"] 1752 | tests-binary = ["cmake", "cmake", "ninja", "ninja", "pybind11", "pybind11", "scikit-build", "scikit-build"] 1753 | tests-binary-strict = ["cmake (==3.21.2)", "cmake (==3.25.0)", "ninja (==1.10.2)", "ninja (==1.11.1)", "pybind11 (==2.10.3)", "pybind11 (==2.7.1)", "scikit-build (==0.11.1)", "scikit-build (==0.16.1)"] 1754 | tests-strict = ["codecov (==2.0.15)", "pytest (==4.6.0)", "pytest (==4.6.0)", "pytest (==6.2.5)", "pytest-cov (==3.0.0)", "typing (==3.7.4)"] 1755 | 1756 | [[package]] 1757 | name = "zipp" 1758 | version = "3.15.0" 1759 | description = "Backport of pathlib-compatible object wrapper for zip files" 1760 | optional = false 1761 | python-versions = ">=3.7" 1762 | files = [ 1763 | {file = "zipp-3.15.0-py3-none-any.whl", hash = "sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556"}, 1764 | {file = "zipp-3.15.0.tar.gz", hash = "sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b"}, 1765 | ] 1766 | 1767 | [package.extras] 1768 | docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] 1769 | testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] 1770 | 1771 | [metadata] 1772 | lock-version = "2.0" 1773 | python-versions = ">=3.7,<4.0" 1774 | content-hash = "4a6bc14eb2dafb148d6e8786a7b98379b26663504401b97af7a9e156c0d7202b" 1775 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "pydantic-pynamodb" 3 | version = "0.1.0" 4 | description = "Pydantic Pynamodb" 5 | authors = ["Andrew Herrington "] 6 | license = "MIT" 7 | readme = "README.rst" 8 | homepage = "https://github.com/andrewthetechie/pydantic-pynamodb" 9 | repository = "https://github.com/andrewthetechie/pydantic-pynamodb" 10 | documentation = "https://pydantic-pynamodb.readthedocs.io" 11 | classifiers = [ 12 | "Development Status :: 3 - Alpha", 13 | ] 14 | 15 | [tool.poetry.urls] 16 | Changelog = "https://github.com/andrewthetechie/pydantic-pynamodb/releases" 17 | 18 | [tool.poetry.dependencies] 19 | python = ">=3.7,<4.0" 20 | pydantic = "^1.9.0" 21 | pynamodb = "^5.2.0" 22 | 23 | [tool.poetry.dev-dependencies] 24 | Pygments = ">=2.10.0" 25 | black = ">=21.10b0" 26 | coverage = {extras = ["toml"], version = ">=6.2"} 27 | darglint = ">=1.8.1" 28 | flake8 = ">=4.0.1" 29 | flake8-bandit = ">=2.1.2" 30 | flake8-bugbear = ">=21.9.2" 31 | flake8-docstrings = ">=1.6.0" 32 | flake8-rst-docstrings = ">=0.2.5" 33 | furo = ">=2021.11.12" 34 | isort = ">=5.10.1" 35 | mypy = ">=0.930" 36 | pep8-naming = ">=0.12.1" 37 | pre-commit = ">=2.16.0" 38 | pre-commit-hooks = ">=4.1.0" 39 | pytest = ">=6.2.5" 40 | pyupgrade = ">=2.29.1" 41 | safety = ">=1.10.3" 42 | sphinx = ">=4.3.2" 43 | sphinx-autobuild = ">=2021.3.14" 44 | sphinx-click = ">=3.0.2" 45 | typeguard = ">=2.13.3" 46 | xdoctest = {extras = ["colors"], version = ">=0.15.10"} 47 | 48 | [tool.coverage.paths] 49 | source = ["src", "*/site-packages"] 50 | tests = ["tests", "*/tests"] 51 | 52 | [tool.coverage.run] 53 | branch = true 54 | source = ["pydantic_pynamodb", "tests"] 55 | 56 | [tool.coverage.report] 57 | show_missing = true 58 | fail_under = 25 59 | 60 | [tool.isort] 61 | profile = "black" 62 | force_single_line = true 63 | lines_after_imports = 2 64 | 65 | [tool.mypy] 66 | strict = true 67 | warn_unreachable = true 68 | pretty = true 69 | show_column_numbers = true 70 | show_error_codes = true 71 | show_error_context = true 72 | 73 | [build-system] 74 | requires = ["poetry-core>=1.0.0", "poetry-dynamic-versioning"] 75 | build-backend = "poetry.core.masonry.api" 76 | 77 | [tool.poetry-dynamic-versioning] 78 | enable = true 79 | vcs = "git" 80 | dirty = true 81 | 82 | [tool.poetry-dynamic-versioning.substitution] 83 | files = ["src/pydantic_pynamodb/__init__.py"] 84 | -------------------------------------------------------------------------------- /src/pydantic_pynamodb/__init__.py: -------------------------------------------------------------------------------- 1 | """Pydantic Pynamodb.""" 2 | # set by poetry-dynamic-versioning 3 | __version__ = "0.1.0" # noqa: E402 4 | 5 | from collections import namedtuple 6 | from typing import AbstractSet 7 | from typing import Any 8 | from typing import Callable 9 | from typing import Dict 10 | from typing import Iterable 11 | from typing import List 12 | from typing import Mapping 13 | from typing import Optional 14 | from typing import Sequence 15 | from typing import Tuple 16 | from typing import Type 17 | from typing import TypeVar 18 | from typing import Union 19 | from typing import cast 20 | 21 | from pydantic import BaseModel as PydanticSchema 22 | from pynamodb.exceptions import GetError 23 | from pynamodb.expressions.condition import Condition 24 | from pynamodb.expressions.update import Action 25 | from pynamodb.models import Model as PydnamoModel 26 | from pynamodb.settings import OperationSettings 27 | 28 | 29 | _T = TypeVar("_T", bound="PydanticPynamoDB") 30 | _TM = TypeVar("_TM", bound="PydanticPynamoDB.Model") 31 | _KeyType = Any 32 | 33 | DynamoKeyVal = namedtuple("DynamoKeyVal", ("key", "val")) 34 | 35 | __all__ = ["PydanticPynamoDB"] 36 | 37 | 38 | class PydanticPynamoDB(PydanticSchema): 39 | """This is a pydantic schema wrapped around a PynamoDB model. 40 | 41 | The idea is that you interact with the pydantic object and use the 42 | class methods on the PydanticPydnamo to do database operations. 43 | 44 | Special "config variables" as part of the object: 45 | * _hash_key: Str or Callable. This is the key of the object to use as the dynamo hash key 46 | * _range_key: Optional Str or Callable. This is the key of the object to use as the dynamo range key. 47 | Callable Signature callable(PydanticPynamoDB) -> str 48 | * _key_remap : Dict[str, Str or Callable] This is a dictionary of keys to remap to the dynamo object. 49 | If you pass a string, the remap is a direct rename 50 | (i.e. name: thingName would map the value name to thingName in the dynamo object) 51 | Callable Signature callable(str, Any, PydanticPynamoDB) -> Tuple[str, Any] 52 | Take in key name, value, and the PydanticPynamoDB object. Return the new key name, and the new value. 53 | * _ create_if_not_exist: bool - Default false. If true, will create the object in dynamodb if it doesn't already exist 54 | * _auto_sync: bool - Default false. If true, will update dynamodb each time one of the pydantic attributes is updated. 55 | """ 56 | 57 | _dynamo_obj: Optional[PydnamoModel] = None 58 | _hash_key: Union[str, Callable[[str, str, _T], Tuple[str, Any]]] 59 | _range_key: Optional[Union[str, Callable[[str, str, _T], Tuple[str, Any]]]] 60 | _key_remap: Dict[str, Union[str, Callable[[str, str, _T], Tuple[str, Any]]]] = {} 61 | _computed_keys: Dict[str, Callable[[str, str, _T], Tuple[str, Any]]] = {} 62 | _auto_sync: bool = False 63 | 64 | class Model(PydnamoModel): 65 | pass 66 | 67 | class Config: 68 | allow_population_by_field_name = True 69 | allow_population_by_alias = True 70 | orm_mode = True 71 | underscore_attrs_are_private = True 72 | extra = "ignore" 73 | 74 | @property 75 | def dynamo_obj(self) -> PydnamoModel: 76 | if self._dynamo_obj is None: 77 | try: 78 | if self.range_key is not None: 79 | self._dynamo_obj = self.Model.get( 80 | self.hash_key.val, self.range_key.val 81 | ) 82 | else: 83 | self._dynamo_obj = self.Model.get(self.hash_key.val) 84 | except Exception as exc: 85 | if isinstance(exc, PydnamoModel.DoesNotExist) or isinstance( 86 | exc, GetError 87 | ): 88 | self._dynamo_obj = self.Model(**self.dict(remap_to_dynamo=True)) 89 | if self._auto_sync: 90 | self._dynamo_obj.save() 91 | else: 92 | raise exc 93 | cast(self._dynamo_obj, self.Model) 94 | return self._dynamo_obj 95 | 96 | @property 97 | def hash_key(self) -> DynamoKeyVal: 98 | """This object's hash key from dynamodb. 99 | 100 | Returns: 101 | str -- this object's hash key from dynamodb. 102 | """ 103 | if isinstance(self._hash_key, Callable): 104 | key, val = self._hash_key("hash_key", "", self) 105 | else: 106 | key = self._hash_key 107 | val = getattr(self, self._hash_key) 108 | return DynamoKeyVal(key, val) 109 | 110 | @property 111 | def range_key(self) -> Optional[DynamoKeyVal]: 112 | """This object's range key, if any, from dynamodb. 113 | 114 | Returns: 115 | Optional[str] -- this object's range key, if any, from dynamodb 116 | """ 117 | if self._range_key is None: 118 | return None 119 | 120 | if isinstance(self._range_key, Callable): 121 | key, val = self._range_key(value="", database=self) 122 | else: 123 | key = self._range_key 124 | val = getattr(self, self._range_key) 125 | return DynamoKeyVal(key, val) 126 | 127 | def __repr__(self) -> str: 128 | if self._range_key is not None: 129 | msg = f"{self.Model.Meta.table_name}<{self.hash_key.val}, {self.range_key.val}>" 130 | else: 131 | msg = f"{self.Model.Meta.table_name}<{self.hash_key.val}>" 132 | 133 | return msg 134 | 135 | def dict( 136 | self, 137 | *, 138 | include: Union[ 139 | AbstractSet[Union[int, str]], Mapping[Union[int, str], Any] 140 | ] = None, 141 | exclude: Union[ 142 | AbstractSet[Union[int, str]], Mapping[Union[int, str], Any] 143 | ] = None, 144 | by_alias: bool = False, 145 | skip_defaults: bool = None, 146 | exclude_unset: bool = False, 147 | exclude_defaults: bool = False, 148 | exclude_none: bool = False, 149 | remap_to_dynamo: bool = False, 150 | ) -> Dict[str, Any]: 151 | """ 152 | Generate a dictionary representation of the model, optionally specifying which fields to include or exclude. 153 | 154 | """ 155 | this_dict = super().dict( 156 | include=include, 157 | exclude=exclude, 158 | by_alias=by_alias, 159 | skip_defaults=skip_defaults, 160 | exclude_unset=exclude_unset, 161 | exclude_defaults=exclude_defaults, 162 | exclude_none=exclude_none, 163 | ) 164 | keys = this_dict.keys() 165 | if remap_to_dynamo: 166 | for key, transform in self._key_remap.items(): 167 | if key in keys: 168 | if isinstance(transform, Callable): 169 | this_dict[key] = transform(key, this_dict[key], self) 170 | else: 171 | this_dict[transform] = this_dict[key] 172 | del this_dict[key] 173 | for key, compute_function in self._computed_keys.items(): 174 | computed_key, computed_value = compute_function( 175 | key, this_dict[key], self 176 | ) 177 | this_dict[computed_key] = computed_value 178 | return this_dict 179 | 180 | def __setattr__(self, name: str, value: Any): 181 | super().__setattr__(name, value) 182 | original_name = name 183 | original_value = value 184 | if name in ( 185 | "_dynamo_obj", 186 | "_hash_key", 187 | "_range_key", 188 | "_key_remap", 189 | "_auto_sync", 190 | ): 191 | return 192 | if name in self._key_remap.keys(): 193 | if isinstance(self._key_remap[name], Callable): 194 | name, value = self._key_remap[name](name, value, self) 195 | else: 196 | name = self._key_remap[name] 197 | setattr(self.dynamo_obj, name, value) 198 | if original_name in self._computed_keys.keys(): 199 | computed_key, computed_value = self._computed_keys[original_name]( 200 | original_name, original_value, self 201 | ) 202 | setattr(self.dynamo_obj, computed_key, computed_value) 203 | 204 | if self._auto_sync: 205 | self.dynamo_obj.save() 206 | 207 | @classmethod 208 | def from_dynamo(cls, dynamo_obj: _TM) -> Type[_T]: 209 | """Creates a PydanticPynamoDB object from a pydnamodb object. 210 | 211 | Uses pydantic from_orm mode. 212 | 213 | Arguments: 214 | cls {Type[} -- [description] 215 | dynamo_obj {_TM} -- [description] 216 | 217 | Returns: 218 | Type[_T] -- [description] 219 | """ 220 | pydantic_obj = cls.from_orm(dynamo_obj) 221 | pydantic_obj._dynamo_obj = dynamo_obj 222 | return pydantic_obj 223 | 224 | @classmethod 225 | def get( 226 | cls, 227 | hash_key: _KeyType, 228 | range_key: Optional[_KeyType] = None, 229 | consistent_read: bool = False, 230 | attributes_to_get: Optional[Sequence[str]] = None, 231 | settings: OperationSettings = OperationSettings.default, 232 | ) -> _T: 233 | """Returns a single object using the provided keys. 234 | 235 | 236 | Arguments: 237 | hash_key {_KeyType} -- The hash key of the desired item 238 | 239 | Keyword Arguments: 240 | range_key {Optional[_KeyType]} -- The range key of the desired item, only used when appropriate (default: {None}) 241 | consistent_read {bool} -- [description] (default: {False}) 242 | attributes_to_get {Optional[Sequence[Text]]} -- [description] (default: {None}) 243 | settings {OperationSettings} -- [description] (default: {OperationSettings.default}) 244 | 245 | Raises: 246 | PydanticPydnamo.Model.DoesNotExist: if the object to does not exist 247 | 248 | Returns: 249 | _T -- A PydanticPydnamo object 250 | """ 251 | dynamo_obj = cls.Model.get( 252 | hash_key, range_key, consistent_read, attributes_to_get, settings 253 | ) 254 | pydantic_obj = cls.from_dynamo(dynamo_obj) 255 | pydantic_obj._dynamo_obj = dynamo_obj 256 | return pydantic_obj 257 | 258 | @classmethod 259 | def query( 260 | cls: Type[_T], 261 | hash_key: _KeyType, 262 | range_key_condition: Optional[Condition] = None, 263 | filter_condition: Optional[Condition] = None, 264 | consistent_read: bool = False, 265 | index_name: Optional[str] = None, 266 | scan_index_forward: Optional[bool] = None, 267 | limit: Optional[int] = None, 268 | last_evaluated_key: Optional[Dict[str, Dict[str, Any]]] = None, 269 | attributes_to_get: Optional[Iterable[str]] = None, 270 | page_size: Optional[int] = None, 271 | rate_limit: Optional[float] = None, 272 | settings: OperationSettings = OperationSettings.default, 273 | ) -> List[Optional[_T]]: 274 | """ 275 | Provides a high level query API. 276 | 277 | :param hash_key: The hash key to query 278 | :param range_key_condition: Condition for range key 279 | :param filter_condition: Condition used to restrict the query results 280 | :param consistent_read: If True, a consistent read is performed 281 | :param index_name: If set, then this index is used 282 | :param limit: Used to limit the number of results returned 283 | :param scan_index_forward: If set, then used to specify the same parameter to the DynamoDB API. 284 | Controls descending or ascending results 285 | :param last_evaluated_key: If set, provides the starting point for query. 286 | :param attributes_to_get: If set, only returns these elements 287 | :param page_size: Page size of the query to DynamoDB 288 | :param rate_limit: If set then consumed capacity will be limited to this amount per second 289 | """ 290 | return [ 291 | cls.from_dynamo(dynamodb) 292 | for dynamodb in cls.Model.query( 293 | hash_key, 294 | range_key_condition, 295 | filter_condition, 296 | consistent_read, 297 | index_name, 298 | scan_index_forward, 299 | limit, 300 | last_evaluated_key, 301 | attributes_to_get, 302 | page_size, 303 | rate_limit, 304 | settings, 305 | ) 306 | ] 307 | 308 | @classmethod 309 | def query_page( 310 | cls: Type[_T], 311 | hash_key: _KeyType, 312 | range_key_condition: Optional[Condition] = None, 313 | filter_condition: Optional[Condition] = None, 314 | consistent_read: bool = False, 315 | index_name: Optional[str] = None, 316 | scan_index_forward: Optional[bool] = None, 317 | limit: Optional[int] = None, 318 | last_evaluated_key: Optional[Dict[str, Dict[str, Any]]] = None, 319 | attributes_to_get: Optional[Iterable[str]] = None, 320 | page_size: Optional[int] = None, 321 | rate_limit: Optional[float] = None, 322 | settings: OperationSettings = OperationSettings.default, 323 | ) -> tuple[List[Optional[_T]], Optional[Dict[str, Any]]]: 324 | """ 325 | Provides a high level query API, and return last_evaluated_key for pagination 326 | 327 | :param hash_key: The hash key to query 328 | :param range_key_condition: Condition for range key 329 | :param filter_condition: Condition used to restrict the query results 330 | :param consistent_read: If True, a consistent read is performed 331 | :param index_name: If set, then this index is used 332 | :param limit: Used to limit the number of results returned 333 | :param scan_index_forward: If set, then used to specify the same parameter to the DynamoDB API. 334 | Controls descending or ascending results 335 | :param last_evaluated_key: If set, provides the starting point for query. 336 | :param attributes_to_get: If set, only returns these elements 337 | :param page_size: Page size of the query to DynamoDB 338 | :param rate_limit: If set then consumed capacity will be limited to this amount per second 339 | """ 340 | query_iterator = cls.Model.query( 341 | hash_key, 342 | range_key_condition, 343 | filter_condition, 344 | consistent_read, 345 | index_name, 346 | scan_index_forward, 347 | limit, 348 | last_evaluated_key, 349 | attributes_to_get, 350 | page_size, 351 | rate_limit, 352 | settings, 353 | ) 354 | return [ 355 | cls.from_dynamo(dynamodb) for dynamodb in query_iterator 356 | ], query_iterator.last_evaluated_key 357 | 358 | @classmethod 359 | def scan( 360 | cls: Type[_T], 361 | filter_condition: Optional[Condition] = None, 362 | segment: Optional[int] = None, 363 | total_segments: Optional[int] = None, 364 | limit: Optional[int] = None, 365 | last_evaluated_key: Optional[Dict[str, Dict[str, Any]]] = None, 366 | page_size: Optional[int] = None, 367 | consistent_read: Optional[bool] = None, 368 | index_name: Optional[str] = None, 369 | rate_limit: Optional[float] = None, 370 | attributes_to_get: Optional[Sequence[str]] = None, 371 | settings: OperationSettings = OperationSettings.default, 372 | ) -> List[Optional[_T]]: 373 | """ 374 | Iterates through all items in the table 375 | 376 | :param filter_condition: Condition used to restrict the scan results 377 | :param segment: If set, then scans the segment 378 | :param total_segments: If set, then specifies total segments 379 | :param limit: Used to limit the number of results returned 380 | :param last_evaluated_key: If set, provides the starting point for scan. 381 | :param page_size: Page size of the scan to DynamoDB 382 | :param consistent_read: If True, a consistent read is performed 383 | :param index_name: If set, then this index is used 384 | :param rate_limit: If set then consumed capacity will be limited to this amount per second 385 | :param attributes_to_get: If set, specifies the properties to include in the projection expression 386 | """ 387 | return [ 388 | cls.from_dynamo(dynamodb) 389 | for dynamodb in cls.Model.scan( 390 | filter_condition, 391 | segment, 392 | total_segments, 393 | limit, 394 | last_evaluated_key, 395 | page_size, 396 | consistent_read, 397 | index_name, 398 | rate_limit, 399 | attributes_to_get, 400 | settings, 401 | ) 402 | ] 403 | 404 | @classmethod 405 | def scan_page( 406 | cls: Type[_T], 407 | filter_condition: Optional[Condition] = None, 408 | segment: Optional[int] = None, 409 | total_segments: Optional[int] = None, 410 | limit: Optional[int] = None, 411 | last_evaluated_key: Optional[Dict[str, Dict[str, Any]]] = None, 412 | page_size: Optional[int] = None, 413 | consistent_read: Optional[bool] = None, 414 | index_name: Optional[str] = None, 415 | rate_limit: Optional[float] = None, 416 | attributes_to_get: Optional[Sequence[str]] = None, 417 | settings: OperationSettings = OperationSettings.default, 418 | ) -> tuple[List[Optional[_T]], Optional[Dict[str, Any]]]: 419 | """ 420 | Iterates through all items in the table, and return last_evaluated_key for pagination 421 | 422 | :param filter_condition: Condition used to restrict the scan results 423 | :param segment: If set, then scans the segment 424 | :param total_segments: If set, then specifies total segments 425 | :param limit: Used to limit the number of results returned 426 | :param last_evaluated_key: If set, provides the starting point for scan. 427 | :param page_size: Page size of the scan to DynamoDB 428 | :param consistent_read: If True, a consistent read is performed 429 | :param index_name: If set, then this index is used 430 | :param rate_limit: If set then consumed capacity will be limited to this amount per second 431 | :param attributes_to_get: If set, specifies the properties to include in the projection expression 432 | """ 433 | query_iterator = cls.Model.scan( 434 | filter_condition, 435 | segment, 436 | total_segments, 437 | limit, 438 | last_evaluated_key, 439 | page_size, 440 | consistent_read, 441 | index_name, 442 | rate_limit, 443 | attributes_to_get, 444 | settings, 445 | ) 446 | return [ 447 | cls.from_dynamo(dynamodb) for dynamodb in query_iterator 448 | ], query_iterator.last_evaluated_key 449 | 450 | @classmethod 451 | def update_ttl(cls, ignore_update_ttl_errors: bool) -> None: 452 | """ 453 | Attempt to update the TTL on the table. 454 | Certain implementations (eg: dynalite) do not support updating TTLs and will fail. 455 | """ 456 | cls.Model.update_ttl(ignore_update_ttl_errors) 457 | 458 | @classmethod 459 | def count( 460 | cls: Type[_T], 461 | hash_key: Optional[_KeyType] = None, 462 | range_key_condition: Optional[Condition] = None, 463 | filter_condition: Optional[Condition] = None, 464 | consistent_read: bool = False, 465 | index_name: Optional[str] = None, 466 | limit: Optional[int] = None, 467 | rate_limit: Optional[float] = None, 468 | settings: OperationSettings = OperationSettings.default, 469 | ) -> int: 470 | """ 471 | Provides a filtered count 472 | :param hash_key: The hash key to query. Can be None. 473 | :param range_key_condition: Condition for range key 474 | :param filter_condition: Condition used to restrict the query results 475 | :param consistent_read: If True, a consistent read is performed 476 | :param index_name: If set, then this index is used 477 | :param rate_limit: If set then consumed capacity will be limited to this amount per second 478 | """ 479 | return cls.Model.count( 480 | hash_key, 481 | range_key_condition, 482 | filter_condition, 483 | consistent_read, 484 | index_name, 485 | limit, 486 | rate_limit, 487 | settings, 488 | ) 489 | 490 | @classmethod 491 | def exists(cls: Type[_T]) -> bool: 492 | """ 493 | Returns True if this table exists, False otherwise 494 | """ 495 | return cls.Model.exists() 496 | 497 | def save( 498 | self, 499 | condition: Optional[Condition] = None, 500 | settings: OperationSettings = OperationSettings.default, 501 | ) -> Dict[str, Any]: 502 | """ 503 | Save this object to dynamodb. 504 | """ 505 | return self.dynamo_obj.save(condition, settings) 506 | 507 | def refresh( 508 | self, 509 | consistent_read: bool = False, 510 | settings: OperationSettings = OperationSettings.default, 511 | ) -> None: 512 | """ 513 | Retrieves this object's data from dynamodb and syncs this local object. 514 | 515 | :param consistent_read: If True, then a consistent read is performed. 516 | :param settings: per-operation settings 517 | :raises ModelInstance.DoesNotExist: if the object to be updated does not exist 518 | """ 519 | self.dynamo_obj.refresh(consistent_read, settings) 520 | # use from_orm to run any remapping from dynamo -> pydantic 521 | pydantic_obj = self.__class__.from_dynamo(self.dynamo_obj) 522 | # Update our pydantic object with values from the new pydantic object 523 | self.__dict__.update(pydantic_obj.dict()) 524 | del pydantic_obj 525 | 526 | def delete( 527 | self, 528 | condition: Optional[Condition] = None, 529 | settings: OperationSettings = OperationSettings.default, 530 | ) -> Any: 531 | """ 532 | Deletes this object from dynamodb 533 | :raises pynamodb.exceptions.DeleteError: If the record can not be deleted 534 | """ 535 | return self.dynamo_obj.delete(condition, settings) 536 | 537 | def update( 538 | self, 539 | actions: List[Action], 540 | condition: Optional[Condition] = None, 541 | settings: OperationSettings = OperationSettings.default, 542 | ) -> Any: 543 | """ 544 | Updates an item using the UpdateItem operation. 545 | :param actions: a list of Action updates to apply 546 | :param condition: an optional Condition on which to update 547 | :param settings: per-operation settings 548 | :raises ModelInstance.DoesNotExist: if the object to be updated does not exist 549 | :raises pynamodb.exceptions.UpdateError: if the `condition` is not met 550 | """ 551 | return self.dynamo_obj.update(actions, condition, settings) 552 | -------------------------------------------------------------------------------- /src/pydantic_pynamodb/py.typed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrewthetechie/pydantic-pynamodb/e7d9aca0dc9fdde4b2e69426fbd3467cb1ce69b3/src/pydantic_pynamodb/py.typed -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- 1 | """Test suite for the pydantic_pynamodb package.""" 2 | -------------------------------------------------------------------------------- /tests/test_model.py: -------------------------------------------------------------------------------- 1 | from pydantic_pynamodb import PydanticPynamoDB 2 | 3 | 4 | def test(): 5 | assert True 6 | --------------------------------------------------------------------------------