├── .editorconfig ├── .github ├── dependabot.yml └── workflows │ └── test.yml ├── .gitignore ├── .readthedocs.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── docs ├── Makefile ├── _static │ └── logo-black.png ├── _templates │ ├── badges.html │ ├── github.html │ └── moreinfo.html ├── api.rst ├── changelog.rst ├── conf.py └── index.rst ├── poetry.lock ├── pyproject.toml ├── setup.cfg ├── split_settings ├── __init__.py ├── py.typed └── tools.py └── tests ├── __init__.py ├── conftest.py ├── settings ├── __init__.py ├── basic │ └── fixture_to_include.py ├── merged │ ├── __init__.py │ └── components │ │ ├── __init__.py │ │ ├── apps_middleware.py │ │ ├── base.py │ │ ├── database.py │ │ ├── locale.py │ │ ├── logging.py │ │ ├── static.py │ │ ├── templates.py │ │ └── testing.py ├── recursion │ ├── __init__.py │ └── ok.py └── stacked │ ├── __init__.py │ ├── base.py │ └── db │ ├── __init__.py │ └── persistent.py ├── test_import.py ├── test_split_settings.py └── test_tools.py /.editorconfig: -------------------------------------------------------------------------------- 1 | # Check http://editorconfig.org for more information 2 | # This is the main config file for this project: 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | trim_trailing_whitespace = true 8 | end_of_line = lf 9 | indent_style = space 10 | insert_final_newline = true 11 | indent_size = 2 12 | 13 | [*.py] 14 | indent_size = 4 15 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: pip 4 | directory: "/" 5 | schedule: 6 | interval: weekly 7 | time: "02:00" 8 | open-pull-requests-limit: 10 9 | 10 | - package-ecosystem: pip 11 | directory: "/docs" 12 | schedule: 13 | interval: daily 14 | time: "02:00" 15 | open-pull-requests-limit: 10 16 | 17 | - package-ecosystem: github-actions 18 | directory: "/" 19 | schedule: 20 | interval: daily 21 | time: "02:00" 22 | open-pull-requests-limit: 10 23 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: test 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | workflow_dispatch: 9 | 10 | concurrency: 11 | group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} 12 | cancel-in-progress: true 13 | 14 | permissions: 15 | contents: read 16 | 17 | jobs: 18 | build: 19 | runs-on: ubuntu-latest 20 | strategy: 21 | fail-fast: false 22 | matrix: 23 | python-version: ['3.10', '3.11', '3.12'] 24 | django-version: 25 | - 'Django~=4.2.0' 26 | - 'Django~=5.0.0' 27 | include: 28 | - python-version: '3.9' 29 | django-version: 'Django~=4.1.0' 30 | - python-version: '3.12' 31 | django-version: 'Django~=4.1.0' 32 | 33 | steps: 34 | - uses: actions/checkout@v4 35 | - name: Set up Python ${{ matrix.python-version }} 36 | uses: actions/setup-python@v5 37 | with: 38 | python-version: ${{ matrix.python-version }} 39 | 40 | - name: Install poetry 41 | run: | 42 | curl -sSL "https://install.python-poetry.org" | python 43 | 44 | # Adding `poetry` to `$PATH`: 45 | echo "$HOME/.poetry/bin" >> $GITHUB_PATH 46 | 47 | - name: Install dependencies 48 | run: | 49 | poetry run pip install --upgrade pip setuptools 50 | poetry install 51 | 52 | poetry run pip install --upgrade "${{ matrix.django-version }}" 53 | 54 | - name: Run tests 55 | run: | 56 | poetry run flake8 . 57 | poetry run mypy split_settings 58 | poetry run pytest 59 | poetry run doc8 -q docs 60 | poetry check 61 | poetry run pip check 62 | 63 | - name: Upload coverage to Codecov 64 | uses: codecov/codecov-action@v5 65 | with: 66 | file: ./coverage.xml 67 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #### joe made this: https://goel.io/joe 2 | 3 | #####=== Python ===##### 4 | 5 | # Byte-compiled / optimized / DLL files 6 | __pycache__/ 7 | *.py[cod] 8 | .mypy_cache/ 9 | 10 | # C extensions 11 | *.so 12 | 13 | # Distribution / packaging 14 | .Python 15 | env/ 16 | build/ 17 | develop-eggs/ 18 | dist/ 19 | downloads/ 20 | eggs/ 21 | lib/ 22 | .eggs/ 23 | lib64/ 24 | parts/ 25 | sdist/ 26 | var/ 27 | *.egg-info/ 28 | .installed.cfg 29 | *.egg 30 | 31 | # PyInstaller 32 | # Usually these files are written by a python script from a template 33 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 34 | *.manifest 35 | *.spec 36 | 37 | # Installer logs 38 | pip-log.txt 39 | pip-delete-this-directory.txt 40 | 41 | # Unit test / coverage reports 42 | htmlcov/ 43 | .tox/ 44 | .coverage 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | 49 | # Translations 50 | *.mo 51 | *.pot 52 | 53 | # Django stuff: 54 | *.log 55 | 56 | # Sphinx documentation 57 | docs/_build/ 58 | 59 | # PyBuilder 60 | target/ 61 | 62 | #####=== OSX ===##### 63 | .DS_Store 64 | .AppleDouble 65 | .LSOverride 66 | 67 | # Icon must end with two \r 68 | Icon 69 | 70 | # Thumbnails 71 | ._* 72 | 73 | # Files that might appear on external disk 74 | .Spotlight-V100 75 | .Trashes 76 | 77 | # Directories potentially created on remote AFP share 78 | .AppleDB 79 | .AppleDesktop 80 | Network Trash Folder 81 | Temporary Items 82 | .apdisk 83 | 84 | #####=== Windows ===##### 85 | # Windows image file caches 86 | Thumbs.db 87 | ehthumbs.db 88 | 89 | # Folder config file 90 | Desktop.ini 91 | 92 | # Recycle Bin used on file shares 93 | $RECYCLE.BIN/ 94 | 95 | # Windows Installer files 96 | *.cab 97 | *.msi 98 | *.msm 99 | *.msp 100 | 101 | # Windows shortcuts 102 | *.lnk 103 | 104 | #####=== Custom ===##### 105 | # Temporary files: 106 | *~ 107 | 108 | # IDEs: 109 | .idea/ 110 | 111 | # Test database: 112 | *.db 113 | -------------------------------------------------------------------------------- /.readthedocs.yml: -------------------------------------------------------------------------------- 1 | # .readthedocs.yml 2 | version: 2 3 | 4 | # Set the version of Python and other tools you might need 5 | build: 6 | os: ubuntu-20.04 7 | tools: 8 | python: "3.9" 9 | jobs: 10 | pre_create_environment: 11 | - asdf plugin add poetry 12 | - asdf install poetry latest 13 | - asdf global poetry latest 14 | - poetry config virtualenvs.create false 15 | post_install: 16 | - . "$(pwd | rev | sed 's/stuokcehc/svne/' | rev)/bin/activate" && poetry install --only main --only docs 17 | 18 | # Build documentation in the docs/ directory with Sphinx 19 | sphinx: 20 | configuration: docs/conf.py 21 | fail_on_warning: true 22 | 23 | formats: all 24 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Version history 2 | 3 | We follow Semantic Version. 4 | 5 | 6 | ## 1.3.2 7 | 8 | ### Bugfixes 9 | 10 | - Do not fail on `include(optional(None))` 11 | 12 | 13 | ## 1.3.1 14 | 15 | ### Bugfixes 16 | 17 | - Fixes getting the last stack item performance #532 18 | 19 | 20 | ## 1.3.0 21 | 22 | ### Features 23 | 24 | - Drops `python3.8` support 25 | - Adds `python3.11` and `python3.12` support 26 | - Adds `django5.0` support 27 | - Uses `OSError` instead of `IOError` alias 28 | - Converts `include(*args, **kwargs)` to `include(*args, scope=...)`, 29 | because other kwargs were not supported anyway 30 | 31 | 32 | ## 1.2.0 33 | 34 | ### Features 35 | 36 | - Adds `python3.10` support 37 | - Drops `python3.6` support 38 | - Adds `django4.1` support 39 | 40 | 41 | ## 1.1.0 42 | 43 | ### Features 44 | 45 | - Adds `python3.9` support 46 | - Adds `django3.1` support 47 | 48 | ### Misc 49 | 50 | - Moves to Github Actions 51 | 52 | 53 | ## 1.0.1 54 | 55 | ### Bugfixes 56 | 57 | - Fixes that django's dev server was not catching split setting filechanges 58 | 59 | 60 | ## 1.0.0 61 | 62 | Breaking changes: 63 | 64 | - Drops `python2` support 65 | - Drops `django2.0` support 66 | 67 | Improvements: 68 | 69 | - Moves to `poetry` 70 | - Adds `mypy` support 71 | - Adds `wemake-python-styleguide` support 72 | - Adds extra CI checks: `safety`, `doc8` 73 | - Adds `py.typed` file to package type information 74 | 75 | 76 | ## 0.3.1 77 | 78 | Improvements: 79 | 80 | - Added support for django till to 2.2 version. 81 | 82 | 83 | ## 0.3.0 84 | 85 | Improvements: 86 | 87 | - Added `Django==2.0` 88 | - Removed old versions of `Django` from test matrix 89 | - Removed `python3.4` from test matrix 90 | - Documentation updates 91 | - Adds more `flake8` plugins to enforce strict style 92 | 93 | Bugs: 94 | 95 | - Fixes Windows problems via [#21](https://github.com/sobolevn/django-split-settings/pull/21) 96 | 97 | 98 | ## 0.2.5 99 | 100 | Improvements: 101 | 102 | - Added `python3.6` and `Django==1.11` 103 | - Fixed `tests/settings` structure with `basic/` folder 104 | - Added documentation, which is built with `Sphinx` 105 | - Updated `README.rst` with new logo 106 | - Updated `README.rst` with `docs` badge 107 | - Updated `CONTRIBUTING.rst` with new information 108 | 109 | Bugs: 110 | 111 | - Updated `README.rst` to be compatible with `PyPI` 112 | 113 | 114 | ## 0.2.4 115 | 116 | - Changed the default Django version in the requirements from `>= 1.5.1` to `>= 1.5` 117 | - Added `setup.cfg` to support `python setup.py test` command 118 | - Refactored how the tests work 119 | - Added `tests/conftest.py` file with the fixtures, used fixtures widely 120 | - Changed all test to be functions instead of classes 121 | - Added new classifiers 122 | - Added `pytest-env` to read env variables from `setup.cfg` 123 | - Removed `run_coveralls.py`, added `after_success` section in `.travis.yml` 124 | - Changed the `README.rst` to be shorter 125 | 126 | 127 | ## 0.2.3 128 | 129 | - Added `django@1.10` support 130 | - Now `include` function finds parent `globals()` scope automatically if not provided 131 | - Added protection against infinite recursion 132 | - Added tests for stackable settings definition. See `tests/settings/stacked/` 133 | - Added tests for the new functionality 134 | - Added tests for `django@1.10` in `tox` and `travis` 135 | - Removed `3.2` and `3.3` from `setup.py` since these versions were not tested anyway 136 | 137 | 138 | ## 0.2.2 139 | 140 | - Now supporting `unicode` filenames, fixes [#9](https://github.com/sobolevn/django-split-settings/issues/9) 141 | - Tests structure is changed 142 | - Removed example 143 | - Changed how `MANIFEST.in` is defined 144 | 145 | 146 | ## 0.2.1 147 | 148 | - Changed `optional` to be a function. 149 | - Added `test_tools.py`, achieved 100% in coverage. 150 | - Removed `setuptools-git` from `setup.py`, now `Manifest` is only way to provide `dist` sources. 151 | - Added `run_coveralls.py` to work on both `CI` and local tests. 152 | - Style fixes. 153 | 154 | 155 | ## 0.2.0 156 | 157 | - Now `tox` is used for testing. 158 | - Added `coverage` information and badge. 159 | - Removed `pep8` utility, now using `pylint`. 160 | 161 | 162 | ## 0.1.3 163 | 164 | - Python 3.5 support, Django 1.9 test-support, documentation updates. 165 | 166 | 167 | ## 0.1.2 168 | 169 | - Fixed Python 3 compatibility. Fixed [#7](https://github.com/sobolevn/django-split-settings/issues/7). 170 | 171 | 172 | ## 0.1.1 173 | 174 | - Fixed issue [#1](https://github.com/sobolevn/django-split-settings/issues/1): now works with Gunicorn, too 175 | 176 | 177 | ## 0.1.0 178 | 179 | - Initial version 180 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to contribute 2 | 3 | 4 | ## Dependencies 5 | 6 | We use [poetry](https://github.com/sdispater/poetry) to manage the dependencies. 7 | 8 | To install them you would need to run `install` command: 9 | 10 | ```bash 11 | poetry install 12 | ``` 13 | 14 | To activate your `virtualenv` run `poetry shell`. 15 | 16 | 17 | ## Tests 18 | 19 | We use `pytest` and `flake8` for quality control. 20 | We also use `wemake_python_styleguide` itself 21 | to develop `wemake_python_styleguide`. 22 | 23 | To run all tests: 24 | 25 | ```bash 26 | pytest 27 | ``` 28 | 29 | To run linting: 30 | 31 | ```bash 32 | flake8 . 33 | ``` 34 | 35 | These steps are mandatory during the CI. 36 | 37 | 38 | ## Type checks 39 | 40 | We use `mypy` to run type checks on our code. 41 | To use it: 42 | 43 | ```bash 44 | mypy django_split_settings 45 | ``` 46 | 47 | This step is mandatory during the CI. 48 | 49 | 50 | ## Submitting your code 51 | 52 | We use [trunk based](https://trunkbaseddevelopment.com/) 53 | development (we also sometimes call it `wemake-git-flow`). 54 | 55 | What the point of this method? 56 | 57 | 1. We use protected `master` branch, 58 | so the only way to push your code is via pull request 59 | 2. We use issue branches: to implement a new feature or to fix a bug 60 | create a new branch named `issue-$TASKNUMBER` 61 | 3. Then create a pull request to `master` branch 62 | 4. We use `git tag`s to make releases, so we can track what has changed 63 | since the latest release 64 | 65 | So, this way we achieve an easy and scalable development process 66 | which frees us from merging hell and long-living branches. 67 | 68 | In this method, the latest version of the app is always in the `master` branch. 69 | 70 | ### Before submitting 71 | 72 | Before submitting your code please do the following steps: 73 | 74 | 1. Run `pytest` to make sure everything was working before 75 | 2. Add any changes you want 76 | 3. Add tests for the new changes 77 | 4. Edit documentation if you have changed something significant 78 | 5. Update `CHANGELOG.md` with a quick summary of your changes 79 | 6. Run `pytest` again to make sure it is still working 80 | 7. Run `mypy` to ensure that types are correct 81 | 8. Run `flake8` to ensure that style is correct 82 | 83 | 84 | ## Other help 85 | 86 | You can contribute by spreading a word about this library. 87 | It would also be a huge contribution to write 88 | a short article on how you are using this project. 89 | You can also share your best practices with us. 90 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013, 2General Oy 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 14 | 3. Neither the name of django-split-settings nor the names of its contributors 15 | may be used to endorse or promote products derived from this software 16 | without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | django-split-settings logo 4 |

5 | 6 | --- 7 | 8 | [![wemake.services](https://img.shields.io/badge/%20-wemake.services-green.svg?label=%20&logo=data%3Aimage%2Fpng%3Bbase64%2CiVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC%2FxhBQAAAAFzUkdCAK7OHOkAAAAbUExURQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP%2F%2F%2F5TvxDIAAAAIdFJOUwAjRA8xXANAL%2Bv0SAAAADNJREFUGNNjYCAIOJjRBdBFWMkVQeGzcHAwksJnAPPZGOGAASzPzAEHEGVsLExQwE7YswCb7AFZSF3bbAAAAABJRU5ErkJggg%3D%3D)](https://wemake.services) 9 | [![test](https://github.com/wemake-services/django-split-settings/actions/workflows/test.yml/badge.svg?branch=master&event=push)](https://github.com/wemake-services/django-split-settings/actions/workflows/test.yml) 10 | [![codecov](https://codecov.io/gh/sobolevn/django-split-settings/branch/master/graph/badge.svg)](https://codecov.io/gh/sobolevn/django-split-settings) 11 | [![Docs](https://readthedocs.org/projects/django-split-settings/badge/?version=latest)](http://django-split-settings.readthedocs.io/en/latest/?badge=latest) 12 | [![Python Version](https://img.shields.io/pypi/pyversions/django-split-settings.svg)](https://pypi.org/project/django-split-settings/) 13 | [![wemake-python-styleguide](https://img.shields.io/badge/style-wemake-000000.svg)](https://github.com/wemake-services/wemake-python-styleguide) 14 | 15 | 16 | 17 | Organize Django settings into multiple files and directories. Easily 18 | override and modify settings. Use wildcards in settings file paths 19 | and mark settings files as optional. 20 | 21 | Read [this blog post](https://sobolevn.me/2017/04/managing-djangos-settings) 22 | for more information. 23 | Also, check this [example project](https://github.com/wemake-services/wemake-django-template). 24 | 25 | 26 | ## Requirements 27 | 28 | While this package will most likely work with the most versions of `django`, we [officially support](https://github.com/sobolevn/django-split-settings/blob/master/.github/workflows/test.yml): 29 | 30 | - 4.2 31 | - 5.0 32 | - 5.1 33 | 34 | This package has no dependencies itself. 35 | 36 | In case you need older `python` / `django` versions support, 37 | then consider using older versions of `django-split-settings`. 38 | 39 | 40 | ## Installation 41 | 42 | ```bash 43 | pip install django-split-settings 44 | ``` 45 | 46 | 47 | ## Usage 48 | 49 | Replace your existing `settings.py` with a list of components that 50 | make up your Django settings. Preferably create a settings package 51 | that contains all the files. 52 | 53 | Here's a minimal example: 54 | 55 | ```python 56 | from split_settings.tools import optional, include 57 | 58 | include( 59 | 'components/base.py', 60 | 'components/database.py', 61 | optional('local_settings.py') 62 | ) 63 | ``` 64 | 65 | In the example, the files `base.py` and `database.py` are included 66 | in that order from the subdirectory called `components/`. 67 | `local_settings.py` in the same directory is included if it exists. 68 | 69 | **Note:** The local context is passed on to each file, so each 70 | following file can access and modify the settings declared in the 71 | previous files. 72 | 73 | We also made an in-depth [tutorial](https://sobolevn.me/2017/04/managing-djangos-settings). 74 | 75 | 76 | ## Tips and tricks 77 | 78 | You can use wildcards in file paths: 79 | 80 | ```python 81 | include('components/my_app/*.py') 82 | ``` 83 | 84 | Note that files are included in the order that `glob` returns them, 85 | probably in the same order as what `ls -U` would list them. The 86 | files are NOT in alphabetical order. 87 | 88 | You can modify common settings in environment settings simply importing them 89 | 90 | ```python 91 | # local_settings.py 92 | from components.base import INSTALLED_APPS 93 | 94 | INSTALLED_APPS += ( 95 | 'raven.contrib.django.raven_compat', 96 | ) 97 | ``` 98 | 99 | 100 | ## Updating `BASE_DIR` 101 | 102 | The `django create-project` command will create a variable in your `settings.py` called `BASE_DIR`, which is often used to locate static files, media files, and templates. 103 | 104 | ```python 105 | # Created by django create-project 106 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 107 | STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles/") 108 | MEDIA_ROOT = os.path.join(BASE_DIR, "mediafiles/") 109 | ``` 110 | 111 | The expression for `BASE_DIR` means: get the path to the current file (`settings.py`), get the parent folder (whatever you named your project), get the parent folder (the root of the project). So `STATIC_ROOT` will then be evaluated to `/staticfiles` (with `/` meaning the root of your project/repo). 112 | 113 | With `django-split-settings` `settings` is now a module (instead of a file), so `os.path.dirname(os.path.dirname(os.path.abspath(__file__)))` will evaluate to `/whatever-you-named-your-project` as opposed to `/`. 114 | 115 | To fix this `BASE_DIR` needs to be set to the parent folder of `/whatever-you-named-your-project`: 116 | 117 | ```python 118 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) 119 | ``` 120 | 121 | ## Do you want to contribute? 122 | 123 | Read the [CONTRIBUTING.md](https://github.com/sobolevn/django-split-settings/blob/master/CONTRIBUTING.md) file. 124 | 125 | 126 | ## Version history 127 | 128 | See [CHANGELOG.md](https://github.com/sobolevn/django-split-settings/blob/master/CHANGELOG.md) file. 129 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | SPHINXPROJ = django_split_settings 8 | SOURCEDIR = . 9 | BUILDDIR = _build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -------------------------------------------------------------------------------- /docs/_static/logo-black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wemake-services/django-split-settings/0fdad90ca2c8283840ca61cab267a548c8aa2b8a/docs/_static/logo-black.png -------------------------------------------------------------------------------- /docs/_templates/badges.html: -------------------------------------------------------------------------------- 1 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/_templates/github.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /docs/_templates/moreinfo.html: -------------------------------------------------------------------------------- 1 |

2 | Links 3 |

4 | 18 | -------------------------------------------------------------------------------- /docs/api.rst: -------------------------------------------------------------------------------- 1 | API 2 | === 3 | 4 | .. automodule:: split_settings.tools 5 | :members: 6 | 7 | .. autoclass:: _Optional 8 | :members: 9 | -------------------------------------------------------------------------------- /docs/changelog.rst: -------------------------------------------------------------------------------- 1 | 2 | .. mdinclude:: ../CHANGELOG.md 3 | -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | # Configuration file for the Sphinx documentation builder. 2 | # 3 | # This file does only contain a selection of the most common options. For a 4 | # full list see the documentation: 5 | # http://www.sphinx-doc.org/en/master/config 6 | 7 | # -- Path setup -------------------------------------------------------------- 8 | 9 | # If extensions (or modules to document with autodoc) are in another directory, 10 | # add these directories to sys.path here. If the directory is relative to the 11 | # documentation root, use os.path.abspath to make it absolute, like shown here. 12 | 13 | import os 14 | import sys 15 | 16 | try: 17 | import tomllib 18 | except ImportError: 19 | import tomli as tomllib 20 | 21 | sys.path.insert(0, os.path.abspath('..')) 22 | 23 | 24 | # -- Project information ----------------------------------------------------- 25 | 26 | def _get_project_meta(): 27 | with open('../pyproject.toml', mode='rb') as pyproject: 28 | return tomllib.load(pyproject)['tool']['poetry'] 29 | 30 | 31 | pkg_meta = _get_project_meta() 32 | project = str(pkg_meta['name']) 33 | copyright = '2013, 2General Oy' # noqa: WPS125 34 | author = 'Nikita Sobolev' 35 | 36 | # The short X.Y version 37 | version = str(pkg_meta['version']) 38 | # The full version, including alpha/beta/rc tags 39 | release = version 40 | 41 | 42 | # -- General configuration --------------------------------------------------- 43 | 44 | needs_sphinx = '3.3' 45 | 46 | # Add any Sphinx extension module names here, as strings. They can be 47 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 48 | # ones. 49 | extensions = [ 50 | 'sphinx.ext.autodoc', 51 | 'sphinx.ext.doctest', 52 | 'sphinx.ext.todo', 53 | 'sphinx.ext.coverage', 54 | 'sphinx.ext.viewcode', 55 | 'sphinx.ext.autosummary', 56 | 'sphinx.ext.napoleon', 57 | 58 | # Used to include .md files: 59 | 'm2r2', 60 | 61 | # Used to insert typehints into the final docs: 62 | 'sphinx_autodoc_typehints', 63 | ] 64 | 65 | autoclass_content = 'class' 66 | autodoc_member_order = 'bysource' 67 | 68 | autodoc_member_order = 'bysource' 69 | autodoc_default_flags = {} 70 | 71 | # Add any paths that contain templates here, relative to this directory. 72 | templates_path = ['_templates'] 73 | 74 | # The suffix(es) of source filenames. 75 | # You can specify multiple suffix as a list of string: 76 | 77 | source_suffix = ['.rst', '.md'] 78 | 79 | # The master toctree document. 80 | master_doc = 'index' 81 | 82 | # The language for content autogenerated by Sphinx. Refer to documentation 83 | # for a list of supported languages. 84 | # 85 | # This is also used if you do content translation via gettext catalogs. 86 | # Usually you set "language" from the command line for these cases. 87 | language = 'en' 88 | 89 | # List of patterns, relative to source directory, that match files and 90 | # directories to ignore when looking for source files. 91 | # This pattern also affects html_static_path and html_extra_path . 92 | exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] 93 | 94 | # The name of the Pygments (syntax highlighting) style to use. 95 | pygments_style = 'sphinx' 96 | 97 | add_module_names = False 98 | 99 | autodoc_default_options = { 100 | 'show-inheritance': True, 101 | } 102 | 103 | 104 | # -- Options for HTML output ------------------------------------------------- 105 | 106 | # The theme to use for HTML and HTML Help pages. See the documentation for 107 | # a list of builtin themes. 108 | html_theme = 'alabaster' 109 | 110 | # Theme options are theme-specific and customize the look and feel of a theme 111 | # further. For a list of options available for each theme, see the 112 | # documentation. 113 | html_theme_options = { 114 | 'sidebar_collapse': False, 115 | 'show_powered_by': False, 116 | } 117 | 118 | # Add any paths that contain custom static files (such as style sheets) here, 119 | # relative to this directory. They are copied after the builtin static files, 120 | # so a file named "default.css" will overwrite the builtin "default.css". 121 | html_static_path = ['_static'] 122 | 123 | # Custom sidebar templates, must be a dictionary that maps document names 124 | # to template names. 125 | # 126 | # This is required for the alabaster theme 127 | # refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars 128 | html_sidebars = { 129 | '**': [ 130 | 'about.html', 131 | 'navigation.html', 132 | 'moreinfo.html', 133 | 'github.html', 134 | 'searchbox.html', 135 | ], 136 | } 137 | 138 | 139 | # -- Extension configuration ------------------------------------------------- 140 | 141 | napoleon_numpy_docstring = False 142 | 143 | # -- Options for todo extension ---------------------------------------------- 144 | 145 | # If true, `todo` and `todoList` produce output, else they produce nothing. 146 | todo_include_todos = True 147 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | .. mdinclude:: ../README.md 2 | 3 | API Reference 4 | ============= 5 | 6 | .. toctree:: 7 | :maxdepth: 2 8 | 9 | api 10 | changelog 11 | -------------------------------------------------------------------------------- /poetry.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Poetry 2.1.1 and should not be changed by hand. 2 | 3 | [[package]] 4 | name = "alabaster" 5 | version = "0.7.16" 6 | description = "A light, configurable Sphinx theme" 7 | optional = false 8 | python-versions = ">=3.9" 9 | groups = ["docs"] 10 | files = [ 11 | {file = "alabaster-0.7.16-py3-none-any.whl", hash = "sha256:b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92"}, 12 | {file = "alabaster-0.7.16.tar.gz", hash = "sha256:75a8b99c28a5dad50dd7f8ccdd447a121ddb3892da9e53d1ca5cca3106d58d65"}, 13 | ] 14 | 15 | [[package]] 16 | name = "asgiref" 17 | version = "3.8.1" 18 | description = "ASGI specs, helper code, and adapters" 19 | optional = false 20 | python-versions = ">=3.8" 21 | groups = ["dev"] 22 | files = [ 23 | {file = "asgiref-3.8.1-py3-none-any.whl", hash = "sha256:3e1e3ecc849832fe52ccf2cb6686b7a55f82bb1d6aee72a58826471390335e47"}, 24 | {file = "asgiref-3.8.1.tar.gz", hash = "sha256:c343bd80a0bec947a9860adb4c432ffa7db769836c64238fc34bdc3fec84d590"}, 25 | ] 26 | 27 | [package.dependencies] 28 | typing-extensions = {version = ">=4", markers = "python_version < \"3.11\""} 29 | 30 | [package.extras] 31 | tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"] 32 | 33 | [[package]] 34 | name = "astor" 35 | version = "0.8.1" 36 | description = "Read/rewrite/write Python ASTs" 37 | optional = false 38 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" 39 | groups = ["dev"] 40 | files = [ 41 | {file = "astor-0.8.1-py2.py3-none-any.whl", hash = "sha256:070a54e890cefb5b3739d19f30f5a5ec840ffc9c50ffa7d23cc9fc1a38ebbfc5"}, 42 | {file = "astor-0.8.1.tar.gz", hash = "sha256:6a6effda93f4e1ce9f618779b2dd1d9d84f1e32812c23a29b3fff6fd7f63fa5e"}, 43 | ] 44 | 45 | [[package]] 46 | name = "attrs" 47 | version = "23.2.0" 48 | description = "Classes Without Boilerplate" 49 | optional = false 50 | python-versions = ">=3.7" 51 | groups = ["dev"] 52 | files = [ 53 | {file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"}, 54 | {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"}, 55 | ] 56 | 57 | [package.extras] 58 | cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] 59 | dev = ["attrs[tests]", "pre-commit"] 60 | docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] 61 | tests = ["attrs[tests-no-zope]", "zope-interface"] 62 | tests-mypy = ["mypy (>=1.6) ; platform_python_implementation == \"CPython\" and python_version >= \"3.8\"", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.8\""] 63 | tests-no-zope = ["attrs[tests-mypy]", "cloudpickle ; platform_python_implementation == \"CPython\"", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"] 64 | 65 | [[package]] 66 | name = "autorepr" 67 | version = "0.3.0" 68 | description = "Makes civilized __repr__, __str__, and __unicode__ methods" 69 | optional = false 70 | python-versions = "*" 71 | groups = ["dev"] 72 | files = [ 73 | {file = "autorepr-0.3.0-py2-none-any.whl", hash = "sha256:c34567e4073630feb52d9c788fc198085e9e9de4817e3b93b7c4c534fc689f11"}, 74 | {file = "autorepr-0.3.0-py2.py3-none-any.whl", hash = "sha256:1d9010d14fb325d3961e3aa73692685563f97d6ba4a2f0f735329fb37422599c"}, 75 | {file = "autorepr-0.3.0.tar.gz", hash = "sha256:ef770b84793d5433e6bb893054973b8c7ce6b487274f9c3f734f678cae11e85e"}, 76 | ] 77 | 78 | [[package]] 79 | name = "babel" 80 | version = "2.15.0" 81 | description = "Internationalization utilities" 82 | optional = false 83 | python-versions = ">=3.8" 84 | groups = ["docs"] 85 | files = [ 86 | {file = "Babel-2.15.0-py3-none-any.whl", hash = "sha256:08706bdad8d0a3413266ab61bd6c34d0c28d6e1e7badf40a2cebe67644e2e1fb"}, 87 | {file = "babel-2.15.0.tar.gz", hash = "sha256:8daf0e265d05768bc6c7a314cf1321e9a123afc328cc635c18622a2f30a04413"}, 88 | ] 89 | 90 | [package.extras] 91 | dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] 92 | 93 | [[package]] 94 | name = "bandit" 95 | version = "1.7.9" 96 | description = "Security oriented static analyser for python code." 97 | optional = false 98 | python-versions = ">=3.8" 99 | groups = ["dev"] 100 | files = [ 101 | {file = "bandit-1.7.9-py3-none-any.whl", hash = "sha256:52077cb339000f337fb25f7e045995c4ad01511e716e5daac37014b9752de8ec"}, 102 | {file = "bandit-1.7.9.tar.gz", hash = "sha256:7c395a436743018f7be0a4cbb0a4ea9b902b6d87264ddecf8cfdc73b4f78ff61"}, 103 | ] 104 | 105 | [package.dependencies] 106 | colorama = {version = ">=0.3.9", markers = "platform_system == \"Windows\""} 107 | PyYAML = ">=5.3.1" 108 | rich = "*" 109 | stevedore = ">=1.20.0" 110 | 111 | [package.extras] 112 | baseline = ["GitPython (>=3.1.30)"] 113 | sarif = ["jschema-to-python (>=1.2.3)", "sarif-om (>=1.0.4)"] 114 | 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)"] 115 | toml = ["tomli (>=1.1.0) ; python_version < \"3.11\""] 116 | yaml = ["PyYAML"] 117 | 118 | [[package]] 119 | name = "cattrs" 120 | version = "23.2.3" 121 | description = "Composable complex class support for attrs and dataclasses." 122 | optional = false 123 | python-versions = ">=3.8" 124 | groups = ["dev"] 125 | files = [ 126 | {file = "cattrs-23.2.3-py3-none-any.whl", hash = "sha256:0341994d94971052e9ee70662542699a3162ea1e0c62f7ce1b4a57f563685108"}, 127 | {file = "cattrs-23.2.3.tar.gz", hash = "sha256:a934090d95abaa9e911dac357e3a8699e0b4b14f8529bcc7d2b1ad9d51672b9f"}, 128 | ] 129 | 130 | [package.dependencies] 131 | attrs = ">=23.1.0" 132 | exceptiongroup = {version = ">=1.1.1", markers = "python_version < \"3.11\""} 133 | typing-extensions = {version = ">=4.1.0,<4.6.3 || >4.6.3", markers = "python_version < \"3.11\""} 134 | 135 | [package.extras] 136 | bson = ["pymongo (>=4.4.0)"] 137 | cbor2 = ["cbor2 (>=5.4.6)"] 138 | msgpack = ["msgpack (>=1.0.5)"] 139 | orjson = ["orjson (>=3.9.2) ; implementation_name == \"cpython\""] 140 | pyyaml = ["pyyaml (>=6.0)"] 141 | tomlkit = ["tomlkit (>=0.11.8)"] 142 | ujson = ["ujson (>=5.7.0)"] 143 | 144 | [[package]] 145 | name = "certifi" 146 | version = "2024.7.4" 147 | description = "Python package for providing Mozilla's CA Bundle." 148 | optional = false 149 | python-versions = ">=3.6" 150 | groups = ["dev", "docs"] 151 | files = [ 152 | {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, 153 | {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, 154 | ] 155 | 156 | [[package]] 157 | name = "charset-normalizer" 158 | version = "3.3.2" 159 | description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." 160 | optional = false 161 | python-versions = ">=3.7.0" 162 | groups = ["dev", "docs"] 163 | files = [ 164 | {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, 165 | {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, 166 | {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, 167 | {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, 168 | {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, 169 | {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, 170 | {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, 171 | {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, 172 | {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, 173 | {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, 174 | {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, 175 | {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, 176 | {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, 177 | {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, 178 | {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, 179 | {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, 180 | {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, 181 | {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, 182 | {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, 183 | {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, 184 | {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, 185 | {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, 186 | {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, 187 | {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, 188 | {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, 189 | {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, 190 | {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, 191 | {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, 192 | {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, 193 | {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, 194 | {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, 195 | {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, 196 | {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, 197 | {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, 198 | {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, 199 | {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, 200 | {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, 201 | {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, 202 | {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, 203 | {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, 204 | {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, 205 | {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, 206 | {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, 207 | {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, 208 | {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, 209 | {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, 210 | {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, 211 | {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, 212 | {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, 213 | {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, 214 | {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, 215 | {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, 216 | {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, 217 | {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, 218 | {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, 219 | {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, 220 | {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, 221 | {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, 222 | {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, 223 | {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, 224 | {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, 225 | {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, 226 | {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, 227 | {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, 228 | {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, 229 | {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, 230 | {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, 231 | {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, 232 | {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, 233 | {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, 234 | {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, 235 | {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, 236 | {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, 237 | {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, 238 | {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, 239 | {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, 240 | {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, 241 | {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, 242 | {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, 243 | {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, 244 | {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, 245 | {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, 246 | {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, 247 | {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, 248 | {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, 249 | {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, 250 | {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, 251 | {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, 252 | {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, 253 | {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, 254 | ] 255 | 256 | [[package]] 257 | name = "click" 258 | version = "8.1.7" 259 | description = "Composable command line interface toolkit" 260 | optional = false 261 | python-versions = ">=3.7" 262 | groups = ["dev"] 263 | files = [ 264 | {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, 265 | {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, 266 | ] 267 | 268 | [package.dependencies] 269 | colorama = {version = "*", markers = "platform_system == \"Windows\""} 270 | 271 | [[package]] 272 | name = "colorama" 273 | version = "0.4.6" 274 | description = "Cross-platform colored terminal text." 275 | optional = false 276 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" 277 | groups = ["dev", "docs"] 278 | files = [ 279 | {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, 280 | {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, 281 | ] 282 | markers = {dev = "platform_system == \"Windows\" or sys_platform == \"win32\"", docs = "sys_platform == \"win32\""} 283 | 284 | [[package]] 285 | name = "configupdater" 286 | version = "3.2" 287 | description = "Parser like ConfigParser but for updating configuration files" 288 | optional = false 289 | python-versions = ">=3.6" 290 | groups = ["dev"] 291 | files = [ 292 | {file = "ConfigUpdater-3.2-py2.py3-none-any.whl", hash = "sha256:0f65a041627d7693840b4dd743581db4c441c97195298a29d075f91b79539df2"}, 293 | {file = "ConfigUpdater-3.2.tar.gz", hash = "sha256:9fdac53831c1b062929bf398b649b87ca30e7f1a735f3fbf482072804106306b"}, 294 | ] 295 | 296 | [package.extras] 297 | testing = ["flake8", "pytest", "pytest-cov", "pytest-randomly", "pytest-xdist", "sphinx"] 298 | 299 | [[package]] 300 | name = "coverage" 301 | version = "7.5.4" 302 | description = "Code coverage measurement for Python" 303 | optional = false 304 | python-versions = ">=3.8" 305 | groups = ["dev"] 306 | files = [ 307 | {file = "coverage-7.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6cfb5a4f556bb51aba274588200a46e4dd6b505fb1a5f8c5ae408222eb416f99"}, 308 | {file = "coverage-7.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2174e7c23e0a454ffe12267a10732c273243b4f2d50d07544a91198f05c48f47"}, 309 | {file = "coverage-7.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2214ee920787d85db1b6a0bd9da5f8503ccc8fcd5814d90796c2f2493a2f4d2e"}, 310 | {file = "coverage-7.5.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1137f46adb28e3813dec8c01fefadcb8c614f33576f672962e323b5128d9a68d"}, 311 | {file = "coverage-7.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b385d49609f8e9efc885790a5a0e89f2e3ae042cdf12958b6034cc442de428d3"}, 312 | {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b4a474f799456e0eb46d78ab07303286a84a3140e9700b9e154cfebc8f527016"}, 313 | {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5cd64adedf3be66f8ccee418473c2916492d53cbafbfcff851cbec5a8454b136"}, 314 | {file = "coverage-7.5.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e564c2cf45d2f44a9da56f4e3a26b2236504a496eb4cb0ca7221cd4cc7a9aca9"}, 315 | {file = "coverage-7.5.4-cp310-cp310-win32.whl", hash = "sha256:7076b4b3a5f6d2b5d7f1185fde25b1e54eb66e647a1dfef0e2c2bfaf9b4c88c8"}, 316 | {file = "coverage-7.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:018a12985185038a5b2bcafab04ab833a9a0f2c59995b3cec07e10074c78635f"}, 317 | {file = "coverage-7.5.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:db14f552ac38f10758ad14dd7b983dbab424e731588d300c7db25b6f89e335b5"}, 318 | {file = "coverage-7.5.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3257fdd8e574805f27bb5342b77bc65578e98cbc004a92232106344053f319ba"}, 319 | {file = "coverage-7.5.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a6612c99081d8d6134005b1354191e103ec9705d7ba2754e848211ac8cacc6b"}, 320 | {file = "coverage-7.5.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d45d3cbd94159c468b9b8c5a556e3f6b81a8d1af2a92b77320e887c3e7a5d080"}, 321 | {file = "coverage-7.5.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed550e7442f278af76d9d65af48069f1fb84c9f745ae249c1a183c1e9d1b025c"}, 322 | {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7a892be37ca35eb5019ec85402c3371b0f7cda5ab5056023a7f13da0961e60da"}, 323 | {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8192794d120167e2a64721d88dbd688584675e86e15d0569599257566dec9bf0"}, 324 | {file = "coverage-7.5.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:820bc841faa502e727a48311948e0461132a9c8baa42f6b2b84a29ced24cc078"}, 325 | {file = "coverage-7.5.4-cp311-cp311-win32.whl", hash = "sha256:6aae5cce399a0f065da65c7bb1e8abd5c7a3043da9dceb429ebe1b289bc07806"}, 326 | {file = "coverage-7.5.4-cp311-cp311-win_amd64.whl", hash = "sha256:d2e344d6adc8ef81c5a233d3a57b3c7d5181f40e79e05e1c143da143ccb6377d"}, 327 | {file = "coverage-7.5.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:54317c2b806354cbb2dc7ac27e2b93f97096912cc16b18289c5d4e44fc663233"}, 328 | {file = "coverage-7.5.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:042183de01f8b6d531e10c197f7f0315a61e8d805ab29c5f7b51a01d62782747"}, 329 | {file = "coverage-7.5.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6bb74ed465d5fb204b2ec41d79bcd28afccf817de721e8a807d5141c3426638"}, 330 | {file = "coverage-7.5.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3d45ff86efb129c599a3b287ae2e44c1e281ae0f9a9bad0edc202179bcc3a2e"}, 331 | {file = "coverage-7.5.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5013ed890dc917cef2c9f765c4c6a8ae9df983cd60dbb635df8ed9f4ebc9f555"}, 332 | {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1014fbf665fef86cdfd6cb5b7371496ce35e4d2a00cda501cf9f5b9e6fced69f"}, 333 | {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3684bc2ff328f935981847082ba4fdc950d58906a40eafa93510d1b54c08a66c"}, 334 | {file = "coverage-7.5.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:581ea96f92bf71a5ec0974001f900db495488434a6928a2ca7f01eee20c23805"}, 335 | {file = "coverage-7.5.4-cp312-cp312-win32.whl", hash = "sha256:73ca8fbc5bc622e54627314c1a6f1dfdd8db69788f3443e752c215f29fa87a0b"}, 336 | {file = "coverage-7.5.4-cp312-cp312-win_amd64.whl", hash = "sha256:cef4649ec906ea7ea5e9e796e68b987f83fa9a718514fe147f538cfeda76d7a7"}, 337 | {file = "coverage-7.5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cdd31315fc20868c194130de9ee6bfd99755cc9565edff98ecc12585b90be882"}, 338 | {file = "coverage-7.5.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:02ff6e898197cc1e9fa375581382b72498eb2e6d5fc0b53f03e496cfee3fac6d"}, 339 | {file = "coverage-7.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d05c16cf4b4c2fc880cb12ba4c9b526e9e5d5bb1d81313d4d732a5b9fe2b9d53"}, 340 | {file = "coverage-7.5.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5986ee7ea0795a4095ac4d113cbb3448601efca7f158ec7f7087a6c705304e4"}, 341 | {file = "coverage-7.5.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5df54843b88901fdc2f598ac06737f03d71168fd1175728054c8f5a2739ac3e4"}, 342 | {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:ab73b35e8d109bffbda9a3e91c64e29fe26e03e49addf5b43d85fc426dde11f9"}, 343 | {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:aea072a941b033813f5e4814541fc265a5c12ed9720daef11ca516aeacd3bd7f"}, 344 | {file = "coverage-7.5.4-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:16852febd96acd953b0d55fc842ce2dac1710f26729b31c80b940b9afcd9896f"}, 345 | {file = "coverage-7.5.4-cp38-cp38-win32.whl", hash = "sha256:8f894208794b164e6bd4bba61fc98bf6b06be4d390cf2daacfa6eca0a6d2bb4f"}, 346 | {file = "coverage-7.5.4-cp38-cp38-win_amd64.whl", hash = "sha256:e2afe743289273209c992075a5a4913e8d007d569a406ffed0bd080ea02b0633"}, 347 | {file = "coverage-7.5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b95c3a8cb0463ba9f77383d0fa8c9194cf91f64445a63fc26fb2327e1e1eb088"}, 348 | {file = "coverage-7.5.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3d7564cc09dd91b5a6001754a5b3c6ecc4aba6323baf33a12bd751036c998be4"}, 349 | {file = "coverage-7.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44da56a2589b684813f86d07597fdf8a9c6ce77f58976727329272f5a01f99f7"}, 350 | {file = "coverage-7.5.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e16f3d6b491c48c5ae726308e6ab1e18ee830b4cdd6913f2d7f77354b33f91c8"}, 351 | {file = "coverage-7.5.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbc5958cb471e5a5af41b0ddaea96a37e74ed289535e8deca404811f6cb0bc3d"}, 352 | {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a04e990a2a41740b02d6182b498ee9796cf60eefe40cf859b016650147908029"}, 353 | {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ddbd2f9713a79e8e7242d7c51f1929611e991d855f414ca9996c20e44a895f7c"}, 354 | {file = "coverage-7.5.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b1ccf5e728ccf83acd313c89f07c22d70d6c375a9c6f339233dcf792094bcbf7"}, 355 | {file = "coverage-7.5.4-cp39-cp39-win32.whl", hash = "sha256:56b4eafa21c6c175b3ede004ca12c653a88b6f922494b023aeb1e836df953ace"}, 356 | {file = "coverage-7.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:65e528e2e921ba8fd67d9055e6b9f9e34b21ebd6768ae1c1723f4ea6ace1234d"}, 357 | {file = "coverage-7.5.4-pp38.pp39.pp310-none-any.whl", hash = "sha256:79b356f3dd5b26f3ad23b35c75dbdaf1f9e2450b6bcefc6d0825ea0aa3f86ca5"}, 358 | {file = "coverage-7.5.4.tar.gz", hash = "sha256:a44963520b069e12789d0faea4e9fdb1e410cdc4aab89d94f7f55cbb7fef0353"}, 359 | ] 360 | 361 | [package.dependencies] 362 | tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} 363 | 364 | [package.extras] 365 | toml = ["tomli ; python_full_version <= \"3.11.0a6\""] 366 | 367 | [[package]] 368 | name = "darglint" 369 | version = "1.8.1" 370 | description = "A utility for ensuring Google-style docstrings stay up to date with the source code." 371 | optional = false 372 | python-versions = ">=3.6,<4.0" 373 | groups = ["dev"] 374 | files = [ 375 | {file = "darglint-1.8.1-py3-none-any.whl", hash = "sha256:5ae11c259c17b0701618a20c3da343a3eb98b3bc4b5a83d31cdd94f5ebdced8d"}, 376 | {file = "darglint-1.8.1.tar.gz", hash = "sha256:080d5106df149b199822e7ee7deb9c012b49891538f14a11be681044f0bb20da"}, 377 | ] 378 | 379 | [[package]] 380 | name = "dictdiffer" 381 | version = "0.9.0" 382 | description = "Dictdiffer is a library that helps you to diff and patch dictionaries." 383 | optional = false 384 | python-versions = "*" 385 | groups = ["dev"] 386 | files = [ 387 | {file = "dictdiffer-0.9.0-py2.py3-none-any.whl", hash = "sha256:442bfc693cfcadaf46674575d2eba1c53b42f5e404218ca2c2ff549f2df56595"}, 388 | {file = "dictdiffer-0.9.0.tar.gz", hash = "sha256:17bacf5fbfe613ccf1b6d512bd766e6b21fb798822a133aa86098b8ac9997578"}, 389 | ] 390 | 391 | [package.extras] 392 | all = ["Sphinx (>=3)", "check-manifest (>=0.42)", "mock (>=1.3.0)", "numpy (>=1.13.0) ; python_version < \"3.7\"", "numpy (>=1.15.0) ; python_version < \"3.8\"", "numpy (>=1.18.0) ; python_version < \"3.9\"", "numpy (>=1.20.0) ; python_version >= \"3.9\"", "pytest (==5.4.3) ; python_version <= \"3.5\"", "pytest (>=6) ; python_version > \"3.5\"", "pytest-cov (>=2.10.1)", "pytest-isort (>=1.2.0)", "pytest-pycodestyle (>=2) ; python_version <= \"3.5\"", "pytest-pycodestyle (>=2.2.0) ; python_version > \"3.5\"", "pytest-pydocstyle (>=2) ; python_version <= \"3.5\"", "pytest-pydocstyle (>=2.2.0) ; python_version > \"3.5\"", "sphinx (>=3)", "sphinx-rtd-theme (>=0.2)", "tox (>=3.7.0)"] 393 | docs = ["Sphinx (>=3)", "sphinx-rtd-theme (>=0.2)"] 394 | numpy = ["numpy (>=1.13.0) ; python_version < \"3.7\"", "numpy (>=1.15.0) ; python_version < \"3.8\"", "numpy (>=1.18.0) ; python_version < \"3.9\"", "numpy (>=1.20.0) ; python_version >= \"3.9\""] 395 | tests = ["check-manifest (>=0.42)", "mock (>=1.3.0)", "pytest (==5.4.3) ; python_version <= \"3.5\"", "pytest (>=6) ; python_version > \"3.5\"", "pytest-cov (>=2.10.1)", "pytest-isort (>=1.2.0)", "pytest-pycodestyle (>=2) ; python_version <= \"3.5\"", "pytest-pycodestyle (>=2.2.0) ; python_version > \"3.5\"", "pytest-pydocstyle (>=2) ; python_version <= \"3.5\"", "pytest-pydocstyle (>=2.2.0) ; python_version > \"3.5\"", "sphinx (>=3)", "tox (>=3.7.0)"] 396 | 397 | [[package]] 398 | name = "django" 399 | version = "4.2.13" 400 | description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design." 401 | optional = false 402 | python-versions = ">=3.8" 403 | groups = ["dev"] 404 | markers = "python_version < \"3.10\"" 405 | files = [ 406 | {file = "Django-4.2.13-py3-none-any.whl", hash = "sha256:a17fcba2aad3fc7d46fdb23215095dbbd64e6174bf4589171e732b18b07e426a"}, 407 | {file = "Django-4.2.13.tar.gz", hash = "sha256:837e3cf1f6c31347a1396a3f6b65688f2b4bb4a11c580dcb628b5afe527b68a5"}, 408 | ] 409 | 410 | [package.dependencies] 411 | asgiref = ">=3.6.0,<4" 412 | sqlparse = ">=0.3.1" 413 | tzdata = {version = "*", markers = "sys_platform == \"win32\""} 414 | 415 | [package.extras] 416 | argon2 = ["argon2-cffi (>=19.1.0)"] 417 | bcrypt = ["bcrypt"] 418 | 419 | [[package]] 420 | name = "django" 421 | version = "5.0.6" 422 | description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design." 423 | optional = false 424 | python-versions = ">=3.10" 425 | groups = ["dev"] 426 | markers = "python_version >= \"3.10\"" 427 | files = [ 428 | {file = "Django-5.0.6-py3-none-any.whl", hash = "sha256:8363ac062bb4ef7c3f12d078f6fa5d154031d129a15170a1066412af49d30905"}, 429 | {file = "Django-5.0.6.tar.gz", hash = "sha256:ff1b61005004e476e0aeea47c7f79b85864c70124030e95146315396f1e7951f"}, 430 | ] 431 | 432 | [package.dependencies] 433 | asgiref = ">=3.7.0,<4" 434 | sqlparse = ">=0.3.1" 435 | tzdata = {version = "*", markers = "sys_platform == \"win32\""} 436 | 437 | [package.extras] 438 | argon2 = ["argon2-cffi (>=19.1.0)"] 439 | bcrypt = ["bcrypt"] 440 | 441 | [[package]] 442 | name = "doc8" 443 | version = "1.1.2" 444 | description = "Style checker for Sphinx (or other) RST documentation" 445 | optional = false 446 | python-versions = ">=3.8" 447 | groups = ["dev"] 448 | files = [ 449 | {file = "doc8-1.1.2-py3-none-any.whl", hash = "sha256:e787b3076b391b8b49400da5d018bacafe592dfc0a04f35a9be22d0122b82b59"}, 450 | {file = "doc8-1.1.2.tar.gz", hash = "sha256:1225f30144e1cc97e388dbaf7fe3e996d2897473a53a6dae268ddde21c354b98"}, 451 | ] 452 | 453 | [package.dependencies] 454 | docutils = ">=0.19,<=0.21.2" 455 | Pygments = "*" 456 | restructuredtext-lint = ">=0.7" 457 | stevedore = "*" 458 | tomli = {version = "*", markers = "python_version < \"3.11\""} 459 | 460 | [[package]] 461 | name = "docutils" 462 | version = "0.20.1" 463 | description = "Docutils -- Python Documentation Utilities" 464 | optional = false 465 | python-versions = ">=3.7" 466 | groups = ["dev", "docs"] 467 | files = [ 468 | {file = "docutils-0.20.1-py3-none-any.whl", hash = "sha256:96f387a2c5562db4476f09f13bbab2192e764cac08ebbf3a34a95d9b1e4a59d6"}, 469 | {file = "docutils-0.20.1.tar.gz", hash = "sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b"}, 470 | ] 471 | 472 | [[package]] 473 | name = "dpath" 474 | version = "2.2.0" 475 | description = "Filesystem-like pathing and searching for dictionaries" 476 | optional = false 477 | python-versions = ">=3.7" 478 | groups = ["dev"] 479 | files = [ 480 | {file = "dpath-2.2.0-py3-none-any.whl", hash = "sha256:b330a375ded0a0d2ed404440f6c6a715deae5313af40bbb01c8a41d891900576"}, 481 | {file = "dpath-2.2.0.tar.gz", hash = "sha256:34f7e630dc55ea3f219e555726f5da4b4b25f2200319c8e6902c394258dd6a3e"}, 482 | ] 483 | 484 | [[package]] 485 | name = "eradicate" 486 | version = "2.3.0" 487 | description = "Removes commented-out code." 488 | optional = false 489 | python-versions = "*" 490 | groups = ["dev"] 491 | files = [ 492 | {file = "eradicate-2.3.0-py3-none-any.whl", hash = "sha256:2b29b3dd27171f209e4ddd8204b70c02f0682ae95eecb353f10e8d72b149c63e"}, 493 | {file = "eradicate-2.3.0.tar.gz", hash = "sha256:06df115be3b87d0fc1c483db22a2ebb12bcf40585722810d809cc770f5031c37"}, 494 | ] 495 | 496 | [[package]] 497 | name = "exceptiongroup" 498 | version = "1.2.1" 499 | description = "Backport of PEP 654 (exception groups)" 500 | optional = false 501 | python-versions = ">=3.7" 502 | groups = ["dev"] 503 | markers = "python_version < \"3.11\"" 504 | files = [ 505 | {file = "exceptiongroup-1.2.1-py3-none-any.whl", hash = "sha256:5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad"}, 506 | {file = "exceptiongroup-1.2.1.tar.gz", hash = "sha256:a4785e48b045528f5bfe627b6ad554ff32def154f42372786903b7abcfe1aa16"}, 507 | ] 508 | 509 | [package.extras] 510 | test = ["pytest (>=6)"] 511 | 512 | [[package]] 513 | name = "flake8" 514 | version = "7.1.0" 515 | description = "the modular source code checker: pep8 pyflakes and co" 516 | optional = false 517 | python-versions = ">=3.8.1" 518 | groups = ["dev"] 519 | files = [ 520 | {file = "flake8-7.1.0-py2.py3-none-any.whl", hash = "sha256:2e416edcc62471a64cea09353f4e7bdba32aeb079b6e360554c659a122b1bc6a"}, 521 | {file = "flake8-7.1.0.tar.gz", hash = "sha256:48a07b626b55236e0fb4784ee69a465fbf59d79eec1f5b4785c3d3bc57d17aa5"}, 522 | ] 523 | 524 | [package.dependencies] 525 | mccabe = ">=0.7.0,<0.8.0" 526 | pycodestyle = ">=2.12.0,<2.13.0" 527 | pyflakes = ">=3.2.0,<3.3.0" 528 | 529 | [[package]] 530 | name = "flake8-bandit" 531 | version = "4.1.1" 532 | description = "Automated security testing with bandit and flake8." 533 | optional = false 534 | python-versions = ">=3.6" 535 | groups = ["dev"] 536 | files = [ 537 | {file = "flake8_bandit-4.1.1-py3-none-any.whl", hash = "sha256:4c8a53eb48f23d4ef1e59293657181a3c989d0077c9952717e98a0eace43e06d"}, 538 | {file = "flake8_bandit-4.1.1.tar.gz", hash = "sha256:068e09287189cbfd7f986e92605adea2067630b75380c6b5733dab7d87f9a84e"}, 539 | ] 540 | 541 | [package.dependencies] 542 | bandit = ">=1.7.3" 543 | flake8 = ">=5.0.0" 544 | 545 | [[package]] 546 | name = "flake8-broken-line" 547 | version = "1.0.0" 548 | description = "Flake8 plugin to forbid backslashes for line breaks" 549 | optional = false 550 | python-versions = ">=3.8,<4.0" 551 | groups = ["dev"] 552 | files = [ 553 | {file = "flake8_broken_line-1.0.0-py3-none-any.whl", hash = "sha256:96c964336024a5030dc536a9f6fb02aa679e2d2a6b35b80a558b5136c35832a9"}, 554 | {file = "flake8_broken_line-1.0.0.tar.gz", hash = "sha256:e2c6a17f8d9a129e99c1320fce89b33843e2963871025c4c2bb7b8b8d8732a85"}, 555 | ] 556 | 557 | [package.dependencies] 558 | flake8 = ">5" 559 | 560 | [[package]] 561 | name = "flake8-bugbear" 562 | version = "24.4.26" 563 | description = "A plugin for flake8 finding likely bugs and design problems in your program. Contains warnings that don't belong in pyflakes and pycodestyle." 564 | optional = false 565 | python-versions = ">=3.8.1" 566 | groups = ["dev"] 567 | files = [ 568 | {file = "flake8_bugbear-24.4.26-py3-none-any.whl", hash = "sha256:cb430dd86bc821d79ccc0b030789a9c87a47a369667f12ba06e80f11305e8258"}, 569 | {file = "flake8_bugbear-24.4.26.tar.gz", hash = "sha256:ff8d4ba5719019ebf98e754624c30c05cef0dadcf18a65d91c7567300e52a130"}, 570 | ] 571 | 572 | [package.dependencies] 573 | attrs = ">=19.2.0" 574 | flake8 = ">=6.0.0" 575 | 576 | [package.extras] 577 | dev = ["coverage", "hypothesis", "hypothesmith (>=0.2)", "pre-commit", "pytest", "tox"] 578 | 579 | [[package]] 580 | name = "flake8-commas" 581 | version = "2.1.0" 582 | description = "Flake8 lint for trailing commas." 583 | optional = false 584 | python-versions = "*" 585 | groups = ["dev"] 586 | files = [ 587 | {file = "flake8-commas-2.1.0.tar.gz", hash = "sha256:940441ab8ee544df564ae3b3f49f20462d75d5c7cac2463e0b27436e2050f263"}, 588 | {file = "flake8_commas-2.1.0-py2.py3-none-any.whl", hash = "sha256:ebb96c31e01d0ef1d0685a21f3f0e2f8153a0381430e748bf0bbbb5d5b453d54"}, 589 | ] 590 | 591 | [package.dependencies] 592 | flake8 = ">=2" 593 | 594 | [[package]] 595 | name = "flake8-comprehensions" 596 | version = "3.15.0" 597 | description = "A flake8 plugin to help you write better list/set/dict comprehensions." 598 | optional = false 599 | python-versions = ">=3.8" 600 | groups = ["dev"] 601 | files = [ 602 | {file = "flake8_comprehensions-3.15.0-py3-none-any.whl", hash = "sha256:b7e027bbb52be2ceb779ee12484cdeef52b0ad3c1fcb8846292bdb86d3034681"}, 603 | {file = "flake8_comprehensions-3.15.0.tar.gz", hash = "sha256:923c22603e0310376a6b55b03efebdc09753c69f2d977755cba8bb73458a5d4d"}, 604 | ] 605 | 606 | [package.dependencies] 607 | flake8 = ">=3,<3.2 || >3.2" 608 | 609 | [[package]] 610 | name = "flake8-debugger" 611 | version = "4.1.2" 612 | description = "ipdb/pdb statement checker plugin for flake8" 613 | optional = false 614 | python-versions = ">=3.7" 615 | groups = ["dev"] 616 | files = [ 617 | {file = "flake8-debugger-4.1.2.tar.gz", hash = "sha256:52b002560941e36d9bf806fca2523dc7fb8560a295d5f1a6e15ac2ded7a73840"}, 618 | {file = "flake8_debugger-4.1.2-py3-none-any.whl", hash = "sha256:0a5e55aeddcc81da631ad9c8c366e7318998f83ff00985a49e6b3ecf61e571bf"}, 619 | ] 620 | 621 | [package.dependencies] 622 | flake8 = ">=3.0" 623 | pycodestyle = "*" 624 | 625 | [[package]] 626 | name = "flake8-docstrings" 627 | version = "1.7.0" 628 | description = "Extension for flake8 which uses pydocstyle to check docstrings" 629 | optional = false 630 | python-versions = ">=3.7" 631 | groups = ["dev"] 632 | files = [ 633 | {file = "flake8_docstrings-1.7.0-py2.py3-none-any.whl", hash = "sha256:51f2344026da083fc084166a9353f5082b01f72901df422f74b4d953ae88ac75"}, 634 | {file = "flake8_docstrings-1.7.0.tar.gz", hash = "sha256:4c8cc748dc16e6869728699e5d0d685da9a10b0ea718e090b1ba088e67a941af"}, 635 | ] 636 | 637 | [package.dependencies] 638 | flake8 = ">=3" 639 | pydocstyle = ">=2.1" 640 | 641 | [[package]] 642 | name = "flake8-eradicate" 643 | version = "1.5.0" 644 | description = "Flake8 plugin to find commented out code" 645 | optional = false 646 | python-versions = ">=3.8,<4.0" 647 | groups = ["dev"] 648 | files = [ 649 | {file = "flake8_eradicate-1.5.0-py3-none-any.whl", hash = "sha256:18acc922ad7de623f5247c7d5595da068525ec5437dd53b22ec2259b96ce9d22"}, 650 | {file = "flake8_eradicate-1.5.0.tar.gz", hash = "sha256:aee636cb9ecb5594a7cd92d67ad73eb69909e5cc7bd81710cf9d00970f3983a6"}, 651 | ] 652 | 653 | [package.dependencies] 654 | attrs = "*" 655 | eradicate = ">=2.0,<3.0" 656 | flake8 = ">5" 657 | 658 | [[package]] 659 | name = "flake8-isort" 660 | version = "6.1.1" 661 | description = "flake8 plugin that integrates isort" 662 | optional = false 663 | python-versions = ">=3.8" 664 | groups = ["dev"] 665 | files = [ 666 | {file = "flake8_isort-6.1.1-py3-none-any.whl", hash = "sha256:0fec4dc3a15aefbdbe4012e51d5531a2eb5fa8b981cdfbc882296a59b54ede12"}, 667 | {file = "flake8_isort-6.1.1.tar.gz", hash = "sha256:c1f82f3cf06a80c13e1d09bfae460e9666255d5c780b859f19f8318d420370b3"}, 668 | ] 669 | 670 | [package.dependencies] 671 | flake8 = "*" 672 | isort = ">=5.0.0,<6" 673 | 674 | [package.extras] 675 | test = ["pytest"] 676 | 677 | [[package]] 678 | name = "flake8-plugin-utils" 679 | version = "1.3.3" 680 | description = "The package provides base classes and utils for flake8 plugin writing" 681 | optional = false 682 | python-versions = ">=3.6,<4.0" 683 | groups = ["dev"] 684 | files = [ 685 | {file = "flake8-plugin-utils-1.3.3.tar.gz", hash = "sha256:39f6f338d038b301c6fd344b06f2e81e382b68fa03c0560dff0d9b1791a11a2c"}, 686 | {file = "flake8_plugin_utils-1.3.3-py3-none-any.whl", hash = "sha256:e4848c57d9d50f19100c2d75fa794b72df068666a9041b4b0409be923356a3ed"}, 687 | ] 688 | 689 | [[package]] 690 | name = "flake8-pytest-style" 691 | version = "2.1.0" 692 | description = "A flake8 plugin checking common style issues or inconsistencies with pytest-based tests." 693 | optional = false 694 | python-versions = ">=3.9" 695 | groups = ["dev"] 696 | files = [ 697 | {file = "flake8_pytest_style-2.1.0-py3-none-any.whl", hash = "sha256:a0d6dddcd533bfc13f19b8445907be0330c5e6ccf7090bcd9d5fa5a0b1b65e71"}, 698 | {file = "flake8_pytest_style-2.1.0.tar.gz", hash = "sha256:fee6befdb5915d600ef24e38d48a077d0dcffb032945ae0169486e7ff8a1079a"}, 699 | ] 700 | 701 | [package.dependencies] 702 | flake8-plugin-utils = ">=1.3.2,<2.0.0" 703 | 704 | [[package]] 705 | name = "flake8-quotes" 706 | version = "3.4.0" 707 | description = "Flake8 lint for quotes." 708 | optional = false 709 | python-versions = "*" 710 | groups = ["dev"] 711 | files = [ 712 | {file = "flake8-quotes-3.4.0.tar.gz", hash = "sha256:aad8492fb710a2d3eabe68c5f86a1428de650c8484127e14c43d0504ba30276c"}, 713 | ] 714 | 715 | [package.dependencies] 716 | flake8 = "*" 717 | setuptools = "*" 718 | 719 | [[package]] 720 | name = "flake8-rst-docstrings" 721 | version = "0.3.0" 722 | description = "Python docstring reStructuredText (RST) validator for flake8" 723 | optional = false 724 | python-versions = ">=3.7" 725 | groups = ["dev"] 726 | files = [ 727 | {file = "flake8-rst-docstrings-0.3.0.tar.gz", hash = "sha256:d1ce22b4bd37b73cd86b8d980e946ef198cfcc18ed82fedb674ceaa2f8d1afa4"}, 728 | {file = "flake8_rst_docstrings-0.3.0-py3-none-any.whl", hash = "sha256:f8c3c6892ff402292651c31983a38da082480ad3ba253743de52989bdc84ca1c"}, 729 | ] 730 | 731 | [package.dependencies] 732 | flake8 = ">=3" 733 | pygments = "*" 734 | restructuredtext-lint = "*" 735 | 736 | [package.extras] 737 | develop = ["build", "twine"] 738 | 739 | [[package]] 740 | name = "flake8-string-format" 741 | version = "0.3.0" 742 | description = "string format checker, plugin for flake8" 743 | optional = false 744 | python-versions = "*" 745 | groups = ["dev"] 746 | files = [ 747 | {file = "flake8-string-format-0.3.0.tar.gz", hash = "sha256:65f3da786a1461ef77fca3780b314edb2853c377f2e35069723348c8917deaa2"}, 748 | {file = "flake8_string_format-0.3.0-py2.py3-none-any.whl", hash = "sha256:812ff431f10576a74c89be4e85b8e075a705be39bc40c4b4278b5b13e2afa9af"}, 749 | ] 750 | 751 | [package.dependencies] 752 | flake8 = "*" 753 | 754 | [[package]] 755 | name = "flatten-dict" 756 | version = "0.4.2" 757 | description = "A flexible utility for flattening and unflattening dict-like objects in Python." 758 | optional = false 759 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" 760 | groups = ["dev"] 761 | files = [ 762 | {file = "flatten-dict-0.4.2.tar.gz", hash = "sha256:506a96b6e6f805b81ae46a0f9f31290beb5fa79ded9d80dbe1b7fa236ab43076"}, 763 | {file = "flatten_dict-0.4.2-py2.py3-none-any.whl", hash = "sha256:7e245b20c4c718981212210eec4284a330c9f713e632e98765560e05421e48ad"}, 764 | ] 765 | 766 | [package.dependencies] 767 | six = ">=1.12,<2.0" 768 | 769 | [[package]] 770 | name = "furl" 771 | version = "2.1.3" 772 | description = "URL manipulation made simple." 773 | optional = false 774 | python-versions = "*" 775 | groups = ["dev"] 776 | files = [ 777 | {file = "furl-2.1.3-py2.py3-none-any.whl", hash = "sha256:9ab425062c4217f9802508e45feb4a83e54324273ac4b202f1850363309666c0"}, 778 | {file = "furl-2.1.3.tar.gz", hash = "sha256:5a6188fe2666c484a12159c18be97a1977a71d632ef5bb867ef15f54af39cc4e"}, 779 | ] 780 | 781 | [package.dependencies] 782 | orderedmultidict = ">=1.0.1" 783 | six = ">=1.8.0" 784 | 785 | [[package]] 786 | name = "gitignore-parser" 787 | version = "0.1.11" 788 | description = "A spec-compliant gitignore parser for Python 3.5+" 789 | optional = false 790 | python-versions = "*" 791 | groups = ["dev"] 792 | files = [ 793 | {file = "gitignore_parser-0.1.11.tar.gz", hash = "sha256:fa10fde48b44888eeefac096f53bcdad9b87a4ffd7db788558dbdf71ff3bc9db"}, 794 | ] 795 | 796 | [[package]] 797 | name = "identify" 798 | version = "2.5.36" 799 | description = "File identification library for Python" 800 | optional = false 801 | python-versions = ">=3.8" 802 | groups = ["dev"] 803 | files = [ 804 | {file = "identify-2.5.36-py2.py3-none-any.whl", hash = "sha256:37d93f380f4de590500d9dba7db359d0d3da95ffe7f9de1753faa159e71e7dfa"}, 805 | {file = "identify-2.5.36.tar.gz", hash = "sha256:e5e00f54165f9047fbebeb4a560f9acfb8af4c88232be60a488e9b68d122745d"}, 806 | ] 807 | 808 | [package.extras] 809 | license = ["ukkonen"] 810 | 811 | [[package]] 812 | name = "idna" 813 | version = "3.7" 814 | description = "Internationalized Domain Names in Applications (IDNA)" 815 | optional = false 816 | python-versions = ">=3.5" 817 | groups = ["dev", "docs"] 818 | files = [ 819 | {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, 820 | {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, 821 | ] 822 | 823 | [[package]] 824 | name = "imagesize" 825 | version = "1.4.1" 826 | description = "Getting image size from png/jpeg/jpeg2000/gif file" 827 | optional = false 828 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 829 | groups = ["docs"] 830 | files = [ 831 | {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"}, 832 | {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"}, 833 | ] 834 | 835 | [[package]] 836 | name = "importlib-metadata" 837 | version = "8.0.0" 838 | description = "Read metadata from Python packages" 839 | optional = false 840 | python-versions = ">=3.8" 841 | groups = ["dev", "docs"] 842 | markers = "python_version < \"3.10\"" 843 | files = [ 844 | {file = "importlib_metadata-8.0.0-py3-none-any.whl", hash = "sha256:15584cf2b1bf449d98ff8a6ff1abef57bf20f3ac6454f431736cd3e660921b2f"}, 845 | {file = "importlib_metadata-8.0.0.tar.gz", hash = "sha256:188bd24e4c346d3f0a933f275c2fec67050326a856b9a359881d7c2a697e8812"}, 846 | ] 847 | 848 | [package.dependencies] 849 | zipp = ">=0.5" 850 | 851 | [package.extras] 852 | doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] 853 | perf = ["ipython"] 854 | test = ["flufl.flake8", "importlib-resources (>=1.3) ; python_version < \"3.9\"", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"] 855 | 856 | [[package]] 857 | name = "iniconfig" 858 | version = "2.0.0" 859 | description = "brain-dead simple config-ini parsing" 860 | optional = false 861 | python-versions = ">=3.7" 862 | groups = ["dev"] 863 | files = [ 864 | {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, 865 | {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, 866 | ] 867 | 868 | [[package]] 869 | name = "isort" 870 | version = "5.13.2" 871 | description = "A Python utility / library to sort Python imports." 872 | optional = false 873 | python-versions = ">=3.8.0" 874 | groups = ["dev"] 875 | files = [ 876 | {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"}, 877 | {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"}, 878 | ] 879 | 880 | [package.extras] 881 | colors = ["colorama (>=0.4.6)"] 882 | 883 | [[package]] 884 | name = "jinja2" 885 | version = "3.1.4" 886 | description = "A very fast and expressive template engine." 887 | optional = false 888 | python-versions = ">=3.7" 889 | groups = ["docs"] 890 | files = [ 891 | {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, 892 | {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, 893 | ] 894 | 895 | [package.dependencies] 896 | MarkupSafe = ">=2.0" 897 | 898 | [package.extras] 899 | i18n = ["Babel (>=2.7)"] 900 | 901 | [[package]] 902 | name = "jmespath" 903 | version = "1.0.1" 904 | description = "JSON Matching Expressions" 905 | optional = false 906 | python-versions = ">=3.7" 907 | groups = ["dev"] 908 | files = [ 909 | {file = "jmespath-1.0.1-py3-none-any.whl", hash = "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980"}, 910 | {file = "jmespath-1.0.1.tar.gz", hash = "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe"}, 911 | ] 912 | 913 | [[package]] 914 | name = "loguru" 915 | version = "0.7.2" 916 | description = "Python logging made (stupidly) simple" 917 | optional = false 918 | python-versions = ">=3.5" 919 | groups = ["dev"] 920 | files = [ 921 | {file = "loguru-0.7.2-py3-none-any.whl", hash = "sha256:003d71e3d3ed35f0f8984898359d65b79e5b21943f78af86aa5491210429b8eb"}, 922 | {file = "loguru-0.7.2.tar.gz", hash = "sha256:e671a53522515f34fd406340ee968cb9ecafbc4b36c679da03c18fd8d0bd51ac"}, 923 | ] 924 | 925 | [package.dependencies] 926 | colorama = {version = ">=0.3.4", markers = "sys_platform == \"win32\""} 927 | win32-setctime = {version = ">=1.0.0", markers = "sys_platform == \"win32\""} 928 | 929 | [package.extras] 930 | dev = ["Sphinx (==7.2.5) ; python_version >= \"3.9\"", "colorama (==0.4.5) ; python_version < \"3.8\"", "colorama (==0.4.6) ; python_version >= \"3.8\"", "exceptiongroup (==1.1.3) ; python_version >= \"3.7\" and python_version < \"3.11\"", "freezegun (==1.1.0) ; python_version < \"3.8\"", "freezegun (==1.2.2) ; python_version >= \"3.8\"", "mypy (==v0.910) ; python_version < \"3.6\"", "mypy (==v0.971) ; python_version == \"3.6\"", "mypy (==v1.4.1) ; python_version == \"3.7\"", "mypy (==v1.5.1) ; python_version >= \"3.8\"", "pre-commit (==3.4.0) ; python_version >= \"3.8\"", "pytest (==6.1.2) ; python_version < \"3.8\"", "pytest (==7.4.0) ; python_version >= \"3.8\"", "pytest-cov (==2.12.1) ; python_version < \"3.8\"", "pytest-cov (==4.1.0) ; python_version >= \"3.8\"", "pytest-mypy-plugins (==1.9.3) ; python_version >= \"3.6\" and python_version < \"3.8\"", "pytest-mypy-plugins (==3.0.0) ; python_version >= \"3.8\"", "sphinx-autobuild (==2021.3.14) ; python_version >= \"3.9\"", "sphinx-rtd-theme (==1.3.0) ; python_version >= \"3.9\"", "tox (==3.27.1) ; python_version < \"3.8\"", "tox (==4.11.0) ; python_version >= \"3.8\""] 931 | 932 | [[package]] 933 | name = "m2r2" 934 | version = "0.3.4" 935 | description = "Markdown and reStructuredText in a single file." 936 | optional = false 937 | python-versions = ">=3.7" 938 | groups = ["docs"] 939 | files = [ 940 | {file = "m2r2-0.3.4-py3-none-any.whl", hash = "sha256:1a445514af8a229496bfb1380c52da8dd38313e48600359ee92b2c9d2e4df34a"}, 941 | {file = "m2r2-0.3.4.tar.gz", hash = "sha256:e278f5f337e9aa7b2080fcc3e94b051bda9615b02e36c6fb3f23ff019872f043"}, 942 | ] 943 | 944 | [package.dependencies] 945 | docutils = ">=0.19" 946 | mistune = "0.8.4" 947 | 948 | [[package]] 949 | name = "markdown-it-py" 950 | version = "3.0.0" 951 | description = "Python port of markdown-it. Markdown parsing, done right!" 952 | optional = false 953 | python-versions = ">=3.8" 954 | groups = ["dev"] 955 | files = [ 956 | {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, 957 | {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, 958 | ] 959 | 960 | [package.dependencies] 961 | mdurl = ">=0.1,<1.0" 962 | 963 | [package.extras] 964 | benchmarking = ["psutil", "pytest", "pytest-benchmark"] 965 | code-style = ["pre-commit (>=3.0,<4.0)"] 966 | compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"] 967 | linkify = ["linkify-it-py (>=1,<3)"] 968 | plugins = ["mdit-py-plugins"] 969 | profiling = ["gprof2dot"] 970 | rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] 971 | testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] 972 | 973 | [[package]] 974 | name = "markupsafe" 975 | version = "2.1.5" 976 | description = "Safely add untrusted strings to HTML/XML markup." 977 | optional = false 978 | python-versions = ">=3.7" 979 | groups = ["docs"] 980 | files = [ 981 | {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, 982 | {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, 983 | {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, 984 | {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, 985 | {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, 986 | {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, 987 | {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, 988 | {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, 989 | {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, 990 | {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, 991 | {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, 992 | {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, 993 | {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, 994 | {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, 995 | {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, 996 | {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, 997 | {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, 998 | {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, 999 | {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, 1000 | {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, 1001 | {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, 1002 | {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, 1003 | {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, 1004 | {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, 1005 | {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, 1006 | {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, 1007 | {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, 1008 | {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, 1009 | {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, 1010 | {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, 1011 | {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, 1012 | {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, 1013 | {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, 1014 | {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, 1015 | {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, 1016 | {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, 1017 | {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, 1018 | {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, 1019 | {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, 1020 | {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, 1021 | {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, 1022 | {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, 1023 | {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, 1024 | {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, 1025 | {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, 1026 | {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, 1027 | {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, 1028 | {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, 1029 | {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, 1030 | {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, 1031 | {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, 1032 | {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, 1033 | {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, 1034 | {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, 1035 | {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, 1036 | {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, 1037 | {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, 1038 | {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, 1039 | {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, 1040 | {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, 1041 | ] 1042 | 1043 | [[package]] 1044 | name = "marshmallow" 1045 | version = "3.21.3" 1046 | description = "A lightweight library for converting complex datatypes to and from native Python datatypes." 1047 | optional = false 1048 | python-versions = ">=3.8" 1049 | groups = ["dev"] 1050 | files = [ 1051 | {file = "marshmallow-3.21.3-py3-none-any.whl", hash = "sha256:86ce7fb914aa865001a4b2092c4c2872d13bc347f3d42673272cabfdbad386f1"}, 1052 | {file = "marshmallow-3.21.3.tar.gz", hash = "sha256:4f57c5e050a54d66361e826f94fba213eb10b67b2fdb02c3e0343ce207ba1662"}, 1053 | ] 1054 | 1055 | [package.dependencies] 1056 | packaging = ">=17.0" 1057 | 1058 | [package.extras] 1059 | dev = ["marshmallow[tests]", "pre-commit (>=3.5,<4.0)", "tox"] 1060 | docs = ["alabaster (==0.7.16)", "autodocsumm (==0.2.12)", "sphinx (==7.3.7)", "sphinx-issues (==4.1.0)", "sphinx-version-warning (==1.1.2)"] 1061 | tests = ["pytest", "pytz", "simplejson"] 1062 | 1063 | [[package]] 1064 | name = "marshmallow-polyfield" 1065 | version = "5.11" 1066 | description = "An unofficial extension to Marshmallow to allow for polymorphic fields" 1067 | optional = false 1068 | python-versions = ">=3.5" 1069 | groups = ["dev"] 1070 | files = [ 1071 | {file = "marshmallow-polyfield-5.11.tar.gz", hash = "sha256:8075a9cc490da4af58b902b4a40a99882dd031adb7aaa96abd147a4fcd53415f"}, 1072 | ] 1073 | 1074 | [package.dependencies] 1075 | marshmallow = ">=3.0.0b10" 1076 | 1077 | [[package]] 1078 | name = "mccabe" 1079 | version = "0.7.0" 1080 | description = "McCabe checker, plugin for flake8" 1081 | optional = false 1082 | python-versions = ">=3.6" 1083 | groups = ["dev"] 1084 | files = [ 1085 | {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, 1086 | {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, 1087 | ] 1088 | 1089 | [[package]] 1090 | name = "mdurl" 1091 | version = "0.1.2" 1092 | description = "Markdown URL utilities" 1093 | optional = false 1094 | python-versions = ">=3.7" 1095 | groups = ["dev"] 1096 | files = [ 1097 | {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, 1098 | {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, 1099 | ] 1100 | 1101 | [[package]] 1102 | name = "mistune" 1103 | version = "0.8.4" 1104 | description = "The fastest markdown parser in pure Python" 1105 | optional = false 1106 | python-versions = "*" 1107 | groups = ["docs"] 1108 | files = [ 1109 | {file = "mistune-0.8.4-py2.py3-none-any.whl", hash = "sha256:88a1051873018da288eee8538d476dffe1262495144b33ecb586c4ab266bb8d4"}, 1110 | {file = "mistune-0.8.4.tar.gz", hash = "sha256:59a3429db53c50b5c6bcc8a07f8848cb00d7dc8bdb431a4ab41920d201d4756e"}, 1111 | ] 1112 | 1113 | [[package]] 1114 | name = "more-itertools" 1115 | version = "10.3.0" 1116 | description = "More routines for operating on iterables, beyond itertools" 1117 | optional = false 1118 | python-versions = ">=3.8" 1119 | groups = ["dev"] 1120 | files = [ 1121 | {file = "more-itertools-10.3.0.tar.gz", hash = "sha256:e5d93ef411224fbcef366a6e8ddc4c5781bc6359d43412a65dd5964e46111463"}, 1122 | {file = "more_itertools-10.3.0-py3-none-any.whl", hash = "sha256:ea6a02e24a9161e51faad17a8782b92a0df82c12c1c8886fec7f0c3fa1a1b320"}, 1123 | ] 1124 | 1125 | [[package]] 1126 | name = "mypy" 1127 | version = "1.15.0" 1128 | description = "Optional static typing for Python" 1129 | optional = false 1130 | python-versions = ">=3.9" 1131 | groups = ["dev"] 1132 | files = [ 1133 | {file = "mypy-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:979e4e1a006511dacf628e36fadfecbcc0160a8af6ca7dad2f5025529e082c13"}, 1134 | {file = "mypy-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c4bb0e1bd29f7d34efcccd71cf733580191e9a264a2202b0239da95984c5b559"}, 1135 | {file = "mypy-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:be68172e9fd9ad8fb876c6389f16d1c1b5f100ffa779f77b1fb2176fcc9ab95b"}, 1136 | {file = "mypy-1.15.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c7be1e46525adfa0d97681432ee9fcd61a3964c2446795714699a998d193f1a3"}, 1137 | {file = "mypy-1.15.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2e2c2e6d3593f6451b18588848e66260ff62ccca522dd231cd4dd59b0160668b"}, 1138 | {file = "mypy-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:6983aae8b2f653e098edb77f893f7b6aca69f6cffb19b2cc7443f23cce5f4828"}, 1139 | {file = "mypy-1.15.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2922d42e16d6de288022e5ca321cd0618b238cfc5570e0263e5ba0a77dbef56f"}, 1140 | {file = "mypy-1.15.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2ee2d57e01a7c35de00f4634ba1bbf015185b219e4dc5909e281016df43f5ee5"}, 1141 | {file = "mypy-1.15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:973500e0774b85d9689715feeffcc980193086551110fd678ebe1f4342fb7c5e"}, 1142 | {file = "mypy-1.15.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a95fb17c13e29d2d5195869262f8125dfdb5c134dc8d9a9d0aecf7525b10c2c"}, 1143 | {file = "mypy-1.15.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1905f494bfd7d85a23a88c5d97840888a7bd516545fc5aaedff0267e0bb54e2f"}, 1144 | {file = "mypy-1.15.0-cp311-cp311-win_amd64.whl", hash = "sha256:c9817fa23833ff189db061e6d2eff49b2f3b6ed9856b4a0a73046e41932d744f"}, 1145 | {file = "mypy-1.15.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:aea39e0583d05124836ea645f412e88a5c7d0fd77a6d694b60d9b6b2d9f184fd"}, 1146 | {file = "mypy-1.15.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2f2147ab812b75e5b5499b01ade1f4a81489a147c01585cda36019102538615f"}, 1147 | {file = "mypy-1.15.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ce436f4c6d218a070048ed6a44c0bbb10cd2cc5e272b29e7845f6a2f57ee4464"}, 1148 | {file = "mypy-1.15.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8023ff13985661b50a5928fc7a5ca15f3d1affb41e5f0a9952cb68ef090b31ee"}, 1149 | {file = "mypy-1.15.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1124a18bc11a6a62887e3e137f37f53fbae476dc36c185d549d4f837a2a6a14e"}, 1150 | {file = "mypy-1.15.0-cp312-cp312-win_amd64.whl", hash = "sha256:171a9ca9a40cd1843abeca0e405bc1940cd9b305eaeea2dda769ba096932bb22"}, 1151 | {file = "mypy-1.15.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:93faf3fdb04768d44bf28693293f3904bbb555d076b781ad2530214ee53e3445"}, 1152 | {file = "mypy-1.15.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:811aeccadfb730024c5d3e326b2fbe9249bb7413553f15499a4050f7c30e801d"}, 1153 | {file = "mypy-1.15.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:98b7b9b9aedb65fe628c62a6dc57f6d5088ef2dfca37903a7d9ee374d03acca5"}, 1154 | {file = "mypy-1.15.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c43a7682e24b4f576d93072216bf56eeff70d9140241f9edec0c104d0c515036"}, 1155 | {file = "mypy-1.15.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:baefc32840a9f00babd83251560e0ae1573e2f9d1b067719479bfb0e987c6357"}, 1156 | {file = "mypy-1.15.0-cp313-cp313-win_amd64.whl", hash = "sha256:b9378e2c00146c44793c98b8d5a61039a048e31f429fb0eb546d93f4b000bedf"}, 1157 | {file = "mypy-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e601a7fa172c2131bff456bb3ee08a88360760d0d2f8cbd7a75a65497e2df078"}, 1158 | {file = "mypy-1.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:712e962a6357634fef20412699a3655c610110e01cdaa6180acec7fc9f8513ba"}, 1159 | {file = "mypy-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f95579473af29ab73a10bada2f9722856792a36ec5af5399b653aa28360290a5"}, 1160 | {file = "mypy-1.15.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8f8722560a14cde92fdb1e31597760dc35f9f5524cce17836c0d22841830fd5b"}, 1161 | {file = "mypy-1.15.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1fbb8da62dc352133d7d7ca90ed2fb0e9d42bb1a32724c287d3c76c58cbaa9c2"}, 1162 | {file = "mypy-1.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:d10d994b41fb3497719bbf866f227b3489048ea4bbbb5015357db306249f7980"}, 1163 | {file = "mypy-1.15.0-py3-none-any.whl", hash = "sha256:5469affef548bd1895d86d3bf10ce2b44e33d86923c29e4d675b3e323437ea3e"}, 1164 | {file = "mypy-1.15.0.tar.gz", hash = "sha256:404534629d51d3efea5c800ee7c42b72a6554d6c400e6a79eafe15d11341fd43"}, 1165 | ] 1166 | 1167 | [package.dependencies] 1168 | mypy_extensions = ">=1.0.0" 1169 | tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} 1170 | typing_extensions = ">=4.6.0" 1171 | 1172 | [package.extras] 1173 | dmypy = ["psutil (>=4.0)"] 1174 | faster-cache = ["orjson"] 1175 | install-types = ["pip"] 1176 | mypyc = ["setuptools (>=50)"] 1177 | reports = ["lxml"] 1178 | 1179 | [[package]] 1180 | name = "mypy-extensions" 1181 | version = "1.0.0" 1182 | description = "Type system extensions for programs checked with the mypy type checker." 1183 | optional = false 1184 | python-versions = ">=3.5" 1185 | groups = ["dev"] 1186 | files = [ 1187 | {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, 1188 | {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, 1189 | ] 1190 | 1191 | [[package]] 1192 | name = "nitpick" 1193 | version = "0.35.0" 1194 | description = "Enforce the same settings across multiple language-independent projects" 1195 | optional = false 1196 | python-versions = ">=3.8,<4.0" 1197 | groups = ["dev"] 1198 | files = [ 1199 | {file = "nitpick-0.35.0-py3-none-any.whl", hash = "sha256:9911d32c2d488b41914aa1a6d230531fa92bbe3d6610e4a468a5cb5e30fab907"}, 1200 | {file = "nitpick-0.35.0.tar.gz", hash = "sha256:098167a4c65655aca52c0ea3876b1e71cf634a27d0e17b971bce9bfcc1f3febe"}, 1201 | ] 1202 | 1203 | [package.dependencies] 1204 | attrs = ">=20.1.0" 1205 | autorepr = "*" 1206 | click = "*" 1207 | ConfigUpdater = "*" 1208 | dictdiffer = "*" 1209 | dpath = "*" 1210 | flake8 = ">=3.0.0" 1211 | flatten-dict = "*" 1212 | furl = "*" 1213 | gitignore_parser = "*" 1214 | identify = "*" 1215 | jmespath = "*" 1216 | loguru = "*" 1217 | marshmallow = ">=3.0.0b10" 1218 | marshmallow-polyfield = ">=5.10,<6.0" 1219 | more-itertools = "*" 1220 | packaging = "*" 1221 | pluggy = "*" 1222 | python-slugify = "*" 1223 | requests = "*" 1224 | requests-cache = ">=1.0.0" 1225 | "ruamel.yaml" = "*" 1226 | sortedcontainers = "*" 1227 | StrEnum = "*" 1228 | toml = "*" 1229 | tomlkit = ">=0.8.0" 1230 | 1231 | [package.extras] 1232 | doc = ["sphinx", "sphinx-gitref", "sphinx_rtd_theme", "sphobjinv"] 1233 | lint = ["pylint"] 1234 | test = ["freezegun", "pytest", "pytest-cov", "pytest-datadir", "pytest-socket", "pytest-testmon", "pytest-watch", "responses", "testfixtures"] 1235 | 1236 | [[package]] 1237 | name = "orderedmultidict" 1238 | version = "1.0.1" 1239 | description = "Ordered Multivalue Dictionary" 1240 | optional = false 1241 | python-versions = "*" 1242 | groups = ["dev"] 1243 | files = [ 1244 | {file = "orderedmultidict-1.0.1-py2.py3-none-any.whl", hash = "sha256:43c839a17ee3cdd62234c47deca1a8508a3f2ca1d0678a3bf791c87cf84adbf3"}, 1245 | {file = "orderedmultidict-1.0.1.tar.gz", hash = "sha256:04070bbb5e87291cc9bfa51df413677faf2141c73c61d2a5f7b26bea3cd882ad"}, 1246 | ] 1247 | 1248 | [package.dependencies] 1249 | six = ">=1.8.0" 1250 | 1251 | [[package]] 1252 | name = "packaging" 1253 | version = "24.1" 1254 | description = "Core utilities for Python packages" 1255 | optional = false 1256 | python-versions = ">=3.8" 1257 | groups = ["dev", "docs"] 1258 | files = [ 1259 | {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, 1260 | {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, 1261 | ] 1262 | 1263 | [[package]] 1264 | name = "pbr" 1265 | version = "6.0.0" 1266 | description = "Python Build Reasonableness" 1267 | optional = false 1268 | python-versions = ">=2.6" 1269 | groups = ["dev"] 1270 | files = [ 1271 | {file = "pbr-6.0.0-py2.py3-none-any.whl", hash = "sha256:4a7317d5e3b17a3dccb6a8cfe67dab65b20551404c52c8ed41279fa4f0cb4cda"}, 1272 | {file = "pbr-6.0.0.tar.gz", hash = "sha256:d1377122a5a00e2f940ee482999518efe16d745d423a670c27773dfbc3c9a7d9"}, 1273 | ] 1274 | 1275 | [[package]] 1276 | name = "pep8-naming" 1277 | version = "0.13.3" 1278 | description = "Check PEP-8 naming conventions, plugin for flake8" 1279 | optional = false 1280 | python-versions = ">=3.7" 1281 | groups = ["dev"] 1282 | files = [ 1283 | {file = "pep8-naming-0.13.3.tar.gz", hash = "sha256:1705f046dfcd851378aac3be1cd1551c7c1e5ff363bacad707d43007877fa971"}, 1284 | {file = "pep8_naming-0.13.3-py3-none-any.whl", hash = "sha256:1a86b8c71a03337c97181917e2b472f0f5e4ccb06844a0d6f0a33522549e7a80"}, 1285 | ] 1286 | 1287 | [package.dependencies] 1288 | flake8 = ">=5.0.0" 1289 | 1290 | [[package]] 1291 | name = "platformdirs" 1292 | version = "4.2.2" 1293 | description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." 1294 | optional = false 1295 | python-versions = ">=3.8" 1296 | groups = ["dev"] 1297 | files = [ 1298 | {file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"}, 1299 | {file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"}, 1300 | ] 1301 | 1302 | [package.extras] 1303 | docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] 1304 | test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] 1305 | type = ["mypy (>=1.8)"] 1306 | 1307 | [[package]] 1308 | name = "pluggy" 1309 | version = "1.5.0" 1310 | description = "plugin and hook calling mechanisms for python" 1311 | optional = false 1312 | python-versions = ">=3.8" 1313 | groups = ["dev"] 1314 | files = [ 1315 | {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, 1316 | {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, 1317 | ] 1318 | 1319 | [package.extras] 1320 | dev = ["pre-commit", "tox"] 1321 | testing = ["pytest", "pytest-benchmark"] 1322 | 1323 | [[package]] 1324 | name = "pycodestyle" 1325 | version = "2.12.0" 1326 | description = "Python style guide checker" 1327 | optional = false 1328 | python-versions = ">=3.8" 1329 | groups = ["dev"] 1330 | files = [ 1331 | {file = "pycodestyle-2.12.0-py2.py3-none-any.whl", hash = "sha256:949a39f6b86c3e1515ba1787c2022131d165a8ad271b11370a8819aa070269e4"}, 1332 | {file = "pycodestyle-2.12.0.tar.gz", hash = "sha256:442f950141b4f43df752dd303511ffded3a04c2b6fb7f65980574f0c31e6e79c"}, 1333 | ] 1334 | 1335 | [[package]] 1336 | name = "pydocstyle" 1337 | version = "6.3.0" 1338 | description = "Python docstring style checker" 1339 | optional = false 1340 | python-versions = ">=3.6" 1341 | groups = ["dev"] 1342 | files = [ 1343 | {file = "pydocstyle-6.3.0-py3-none-any.whl", hash = "sha256:118762d452a49d6b05e194ef344a55822987a462831ade91ec5c06fd2169d019"}, 1344 | {file = "pydocstyle-6.3.0.tar.gz", hash = "sha256:7ce43f0c0ac87b07494eb9c0b462c0b73e6ff276807f204d6b53edc72b7e44e1"}, 1345 | ] 1346 | 1347 | [package.dependencies] 1348 | snowballstemmer = ">=2.2.0" 1349 | 1350 | [package.extras] 1351 | toml = ["tomli (>=1.2.3) ; python_version < \"3.11\""] 1352 | 1353 | [[package]] 1354 | name = "pyflakes" 1355 | version = "3.2.0" 1356 | description = "passive checker of Python programs" 1357 | optional = false 1358 | python-versions = ">=3.8" 1359 | groups = ["dev"] 1360 | files = [ 1361 | {file = "pyflakes-3.2.0-py2.py3-none-any.whl", hash = "sha256:84b5be138a2dfbb40689ca07e2152deb896a65c3a3e24c251c5c62489568074a"}, 1362 | {file = "pyflakes-3.2.0.tar.gz", hash = "sha256:1c61603ff154621fb2a9172037d84dca3500def8c8b630657d1701f026f8af3f"}, 1363 | ] 1364 | 1365 | [[package]] 1366 | name = "pygments" 1367 | version = "2.18.0" 1368 | description = "Pygments is a syntax highlighting package written in Python." 1369 | optional = false 1370 | python-versions = ">=3.8" 1371 | groups = ["dev", "docs"] 1372 | files = [ 1373 | {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"}, 1374 | {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"}, 1375 | ] 1376 | 1377 | [package.extras] 1378 | windows-terminal = ["colorama (>=0.4.6)"] 1379 | 1380 | [[package]] 1381 | name = "pytest" 1382 | version = "8.3.5" 1383 | description = "pytest: simple powerful testing with Python" 1384 | optional = false 1385 | python-versions = ">=3.8" 1386 | groups = ["dev"] 1387 | files = [ 1388 | {file = "pytest-8.3.5-py3-none-any.whl", hash = "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820"}, 1389 | {file = "pytest-8.3.5.tar.gz", hash = "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845"}, 1390 | ] 1391 | 1392 | [package.dependencies] 1393 | colorama = {version = "*", markers = "sys_platform == \"win32\""} 1394 | exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} 1395 | iniconfig = "*" 1396 | packaging = "*" 1397 | pluggy = ">=1.5,<2" 1398 | tomli = {version = ">=1", markers = "python_version < \"3.11\""} 1399 | 1400 | [package.extras] 1401 | dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] 1402 | 1403 | [[package]] 1404 | name = "pytest-cov" 1405 | version = "6.1.1" 1406 | description = "Pytest plugin for measuring coverage." 1407 | optional = false 1408 | python-versions = ">=3.9" 1409 | groups = ["dev"] 1410 | files = [ 1411 | {file = "pytest_cov-6.1.1-py3-none-any.whl", hash = "sha256:bddf29ed2d0ab6f4df17b4c55b0a657287db8684af9c42ea546b21b1041b3dde"}, 1412 | {file = "pytest_cov-6.1.1.tar.gz", hash = "sha256:46935f7aaefba760e716c2ebfbe1c216240b9592966e7da99ea8292d4d3e2a0a"}, 1413 | ] 1414 | 1415 | [package.dependencies] 1416 | coverage = {version = ">=7.5", extras = ["toml"]} 1417 | pytest = ">=4.6" 1418 | 1419 | [package.extras] 1420 | testing = ["fields", "hunter", "process-tests", "pytest-xdist", "virtualenv"] 1421 | 1422 | [[package]] 1423 | name = "pytest-randomly" 1424 | version = "3.16.0" 1425 | description = "Pytest plugin to randomly order tests and control random.seed." 1426 | optional = false 1427 | python-versions = ">=3.9" 1428 | groups = ["dev"] 1429 | files = [ 1430 | {file = "pytest_randomly-3.16.0-py3-none-any.whl", hash = "sha256:8633d332635a1a0983d3bba19342196807f6afb17c3eef78e02c2f85dade45d6"}, 1431 | {file = "pytest_randomly-3.16.0.tar.gz", hash = "sha256:11bf4d23a26484de7860d82f726c0629837cf4064b79157bd18ec9d41d7feb26"}, 1432 | ] 1433 | 1434 | [package.dependencies] 1435 | importlib-metadata = {version = ">=3.6", markers = "python_version < \"3.10\""} 1436 | pytest = "*" 1437 | 1438 | [[package]] 1439 | name = "python-slugify" 1440 | version = "8.0.4" 1441 | description = "A Python slugify application that also handles Unicode" 1442 | optional = false 1443 | python-versions = ">=3.7" 1444 | groups = ["dev"] 1445 | files = [ 1446 | {file = "python-slugify-8.0.4.tar.gz", hash = "sha256:59202371d1d05b54a9e7720c5e038f928f45daaffe41dd10822f3907b937c856"}, 1447 | {file = "python_slugify-8.0.4-py2.py3-none-any.whl", hash = "sha256:276540b79961052b66b7d116620b36518847f52d5fd9e3a70164fc8c50faa6b8"}, 1448 | ] 1449 | 1450 | [package.dependencies] 1451 | text-unidecode = ">=1.3" 1452 | 1453 | [package.extras] 1454 | unidecode = ["Unidecode (>=1.1.1)"] 1455 | 1456 | [[package]] 1457 | name = "pyyaml" 1458 | version = "6.0.1" 1459 | description = "YAML parser and emitter for Python" 1460 | optional = false 1461 | python-versions = ">=3.6" 1462 | groups = ["dev"] 1463 | files = [ 1464 | {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, 1465 | {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, 1466 | {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, 1467 | {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, 1468 | {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, 1469 | {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, 1470 | {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, 1471 | {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, 1472 | {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, 1473 | {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, 1474 | {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, 1475 | {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, 1476 | {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, 1477 | {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, 1478 | {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, 1479 | {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, 1480 | {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, 1481 | {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, 1482 | {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, 1483 | {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, 1484 | {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, 1485 | {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, 1486 | {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, 1487 | {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, 1488 | {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, 1489 | {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, 1490 | {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, 1491 | {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, 1492 | {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, 1493 | {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, 1494 | {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, 1495 | {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, 1496 | {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, 1497 | {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, 1498 | {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, 1499 | {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, 1500 | {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, 1501 | {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, 1502 | {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, 1503 | {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, 1504 | {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, 1505 | {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, 1506 | {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, 1507 | {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, 1508 | {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, 1509 | {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, 1510 | {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, 1511 | {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, 1512 | {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, 1513 | {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, 1514 | {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, 1515 | ] 1516 | 1517 | [[package]] 1518 | name = "requests" 1519 | version = "2.32.3" 1520 | description = "Python HTTP for Humans." 1521 | optional = false 1522 | python-versions = ">=3.8" 1523 | groups = ["dev", "docs"] 1524 | files = [ 1525 | {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, 1526 | {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, 1527 | ] 1528 | 1529 | [package.dependencies] 1530 | certifi = ">=2017.4.17" 1531 | charset-normalizer = ">=2,<4" 1532 | idna = ">=2.5,<4" 1533 | urllib3 = ">=1.21.1,<3" 1534 | 1535 | [package.extras] 1536 | socks = ["PySocks (>=1.5.6,!=1.5.7)"] 1537 | use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] 1538 | 1539 | [[package]] 1540 | name = "requests-cache" 1541 | version = "1.2.1" 1542 | description = "A persistent cache for python requests" 1543 | optional = false 1544 | python-versions = ">=3.8" 1545 | groups = ["dev"] 1546 | files = [ 1547 | {file = "requests_cache-1.2.1-py3-none-any.whl", hash = "sha256:1285151cddf5331067baa82598afe2d47c7495a1334bfe7a7d329b43e9fd3603"}, 1548 | {file = "requests_cache-1.2.1.tar.gz", hash = "sha256:68abc986fdc5b8d0911318fbb5f7c80eebcd4d01bfacc6685ecf8876052511d1"}, 1549 | ] 1550 | 1551 | [package.dependencies] 1552 | attrs = ">=21.2" 1553 | cattrs = ">=22.2" 1554 | platformdirs = ">=2.5" 1555 | requests = ">=2.22" 1556 | url-normalize = ">=1.4" 1557 | urllib3 = ">=1.25.5" 1558 | 1559 | [package.extras] 1560 | all = ["boto3 (>=1.15)", "botocore (>=1.18)", "itsdangerous (>=2.0)", "pymongo (>=3)", "pyyaml (>=6.0.1)", "redis (>=3)", "ujson (>=5.4)"] 1561 | bson = ["bson (>=0.5)"] 1562 | docs = ["furo (>=2023.3,<2024.0)", "linkify-it-py (>=2.0,<3.0)", "myst-parser (>=1.0,<2.0)", "sphinx (>=5.0.2,<6.0.0)", "sphinx-autodoc-typehints (>=1.19)", "sphinx-automodapi (>=0.14)", "sphinx-copybutton (>=0.5)", "sphinx-design (>=0.2)", "sphinx-notfound-page (>=0.8)", "sphinxcontrib-apidoc (>=0.3)", "sphinxext-opengraph (>=0.9)"] 1563 | dynamodb = ["boto3 (>=1.15)", "botocore (>=1.18)"] 1564 | json = ["ujson (>=5.4)"] 1565 | mongodb = ["pymongo (>=3)"] 1566 | redis = ["redis (>=3)"] 1567 | security = ["itsdangerous (>=2.0)"] 1568 | yaml = ["pyyaml (>=6.0.1)"] 1569 | 1570 | [[package]] 1571 | name = "restructuredtext-lint" 1572 | version = "1.4.0" 1573 | description = "reStructuredText linter" 1574 | optional = false 1575 | python-versions = "*" 1576 | groups = ["dev"] 1577 | files = [ 1578 | {file = "restructuredtext_lint-1.4.0.tar.gz", hash = "sha256:1b235c0c922341ab6c530390892eb9e92f90b9b75046063e047cacfb0f050c45"}, 1579 | ] 1580 | 1581 | [package.dependencies] 1582 | docutils = ">=0.11,<1.0" 1583 | 1584 | [[package]] 1585 | name = "rich" 1586 | version = "13.7.1" 1587 | description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" 1588 | optional = false 1589 | python-versions = ">=3.7.0" 1590 | groups = ["dev"] 1591 | files = [ 1592 | {file = "rich-13.7.1-py3-none-any.whl", hash = "sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222"}, 1593 | {file = "rich-13.7.1.tar.gz", hash = "sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432"}, 1594 | ] 1595 | 1596 | [package.dependencies] 1597 | markdown-it-py = ">=2.2.0" 1598 | pygments = ">=2.13.0,<3.0.0" 1599 | 1600 | [package.extras] 1601 | jupyter = ["ipywidgets (>=7.5.1,<9)"] 1602 | 1603 | [[package]] 1604 | name = "ruamel-yaml" 1605 | version = "0.18.6" 1606 | description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order" 1607 | optional = false 1608 | python-versions = ">=3.7" 1609 | groups = ["dev"] 1610 | files = [ 1611 | {file = "ruamel.yaml-0.18.6-py3-none-any.whl", hash = "sha256:57b53ba33def16c4f3d807c0ccbc00f8a6081827e81ba2491691b76882d0c636"}, 1612 | {file = "ruamel.yaml-0.18.6.tar.gz", hash = "sha256:8b27e6a217e786c6fbe5634d8f3f11bc63e0f80f6a5890f28863d9c45aac311b"}, 1613 | ] 1614 | 1615 | [package.dependencies] 1616 | "ruamel.yaml.clib" = {version = ">=0.2.7", markers = "platform_python_implementation == \"CPython\" and python_version < \"3.13\""} 1617 | 1618 | [package.extras] 1619 | docs = ["mercurial (>5.7)", "ryd"] 1620 | jinja2 = ["ruamel.yaml.jinja2 (>=0.2)"] 1621 | 1622 | [[package]] 1623 | name = "ruamel-yaml-clib" 1624 | version = "0.2.8" 1625 | description = "C version of reader, parser and emitter for ruamel.yaml derived from libyaml" 1626 | optional = false 1627 | python-versions = ">=3.6" 1628 | groups = ["dev"] 1629 | markers = "platform_python_implementation == \"CPython\" and python_version < \"3.13\"" 1630 | files = [ 1631 | {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b42169467c42b692c19cf539c38d4602069d8c1505e97b86387fcf7afb766e1d"}, 1632 | {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:07238db9cbdf8fc1e9de2489a4f68474e70dffcb32232db7c08fa61ca0c7c462"}, 1633 | {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:fff3573c2db359f091e1589c3d7c5fc2f86f5bdb6f24252c2d8e539d4e45f412"}, 1634 | {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_24_aarch64.whl", hash = "sha256:aa2267c6a303eb483de8d02db2871afb5c5fc15618d894300b88958f729ad74f"}, 1635 | {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:840f0c7f194986a63d2c2465ca63af8ccbbc90ab1c6001b1978f05119b5e7334"}, 1636 | {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:024cfe1fc7c7f4e1aff4a81e718109e13409767e4f871443cbff3dba3578203d"}, 1637 | {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-win32.whl", hash = "sha256:c69212f63169ec1cfc9bb44723bf2917cbbd8f6191a00ef3410f5a7fe300722d"}, 1638 | {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-win_amd64.whl", hash = "sha256:cabddb8d8ead485e255fe80429f833172b4cadf99274db39abc080e068cbcc31"}, 1639 | {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:bef08cd86169d9eafb3ccb0a39edb11d8e25f3dae2b28f5c52fd997521133069"}, 1640 | {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:b16420e621d26fdfa949a8b4b47ade8810c56002f5389970db4ddda51dbff248"}, 1641 | {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:25c515e350e5b739842fc3228d662413ef28f295791af5e5110b543cf0b57d9b"}, 1642 | {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_24_aarch64.whl", hash = "sha256:1707814f0d9791df063f8c19bb51b0d1278b8e9a2353abbb676c2f685dee6afe"}, 1643 | {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:46d378daaac94f454b3a0e3d8d78cafd78a026b1d71443f4966c696b48a6d899"}, 1644 | {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:09b055c05697b38ecacb7ac50bdab2240bfca1a0c4872b0fd309bb07dc9aa3a9"}, 1645 | {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-win32.whl", hash = "sha256:53a300ed9cea38cf5a2a9b069058137c2ca1ce658a874b79baceb8f892f915a7"}, 1646 | {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-win_amd64.whl", hash = "sha256:c2a72e9109ea74e511e29032f3b670835f8a59bbdc9ce692c5b4ed91ccf1eedb"}, 1647 | {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:ebc06178e8821efc9692ea7544aa5644217358490145629914d8020042c24aa1"}, 1648 | {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:edaef1c1200c4b4cb914583150dcaa3bc30e592e907c01117c08b13a07255ec2"}, 1649 | {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d176b57452ab5b7028ac47e7b3cf644bcfdc8cacfecf7e71759f7f51a59e5c92"}, 1650 | {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_24_aarch64.whl", hash = "sha256:1dc67314e7e1086c9fdf2680b7b6c2be1c0d8e3a8279f2e993ca2a7545fecf62"}, 1651 | {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3213ece08ea033eb159ac52ae052a4899b56ecc124bb80020d9bbceeb50258e9"}, 1652 | {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:aab7fd643f71d7946f2ee58cc88c9b7bfc97debd71dcc93e03e2d174628e7e2d"}, 1653 | {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-win32.whl", hash = "sha256:5c365d91c88390c8d0a8545df0b5857172824b1c604e867161e6b3d59a827eaa"}, 1654 | {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-win_amd64.whl", hash = "sha256:1758ce7d8e1a29d23de54a16ae867abd370f01b5a69e1a3ba75223eaa3ca1a1b"}, 1655 | {file = "ruamel.yaml.clib-0.2.8-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a5aa27bad2bb83670b71683aae140a1f52b0857a2deff56ad3f6c13a017a26ed"}, 1656 | {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c58ecd827313af6864893e7af0a3bb85fd529f862b6adbefe14643947cfe2942"}, 1657 | {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-macosx_12_0_arm64.whl", hash = "sha256:f481f16baec5290e45aebdc2a5168ebc6d35189ae6fea7a58787613a25f6e875"}, 1658 | {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-manylinux_2_24_aarch64.whl", hash = "sha256:77159f5d5b5c14f7c34073862a6b7d34944075d9f93e681638f6d753606c6ce6"}, 1659 | {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7f67a1ee819dc4562d444bbafb135832b0b909f81cc90f7aa00260968c9ca1b3"}, 1660 | {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:4ecbf9c3e19f9562c7fdd462e8d18dd902a47ca046a2e64dba80699f0b6c09b7"}, 1661 | {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:87ea5ff66d8064301a154b3933ae406b0863402a799b16e4a1d24d9fbbcbe0d3"}, 1662 | {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-win32.whl", hash = "sha256:75e1ed13e1f9de23c5607fe6bd1aeaae21e523b32d83bb33918245361e9cc51b"}, 1663 | {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-win_amd64.whl", hash = "sha256:3f215c5daf6a9d7bbed4a0a4f760f3113b10e82ff4c5c44bec20a68c8014f675"}, 1664 | {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1b617618914cb00bf5c34d4357c37aa15183fa229b24767259657746c9077615"}, 1665 | {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:a6a9ffd280b71ad062eae53ac1659ad86a17f59a0fdc7699fd9be40525153337"}, 1666 | {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-manylinux_2_24_aarch64.whl", hash = "sha256:305889baa4043a09e5b76f8e2a51d4ffba44259f6b4c72dec8ca56207d9c6fe1"}, 1667 | {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:700e4ebb569e59e16a976857c8798aee258dceac7c7d6b50cab63e080058df91"}, 1668 | {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:e2b4c44b60eadec492926a7270abb100ef9f72798e18743939bdbf037aab8c28"}, 1669 | {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e79e5db08739731b0ce4850bed599235d601701d5694c36570a99a0c5ca41a9d"}, 1670 | {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-win32.whl", hash = "sha256:955eae71ac26c1ab35924203fda6220f84dce57d6d7884f189743e2abe3a9fbe"}, 1671 | {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-win_amd64.whl", hash = "sha256:56f4252222c067b4ce51ae12cbac231bce32aee1d33fbfc9d17e5b8d6966c312"}, 1672 | {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:03d1162b6d1df1caa3a4bd27aa51ce17c9afc2046c31b0ad60a0a96ec22f8001"}, 1673 | {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:bba64af9fa9cebe325a62fa398760f5c7206b215201b0ec825005f1b18b9bccf"}, 1674 | {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-manylinux_2_24_aarch64.whl", hash = "sha256:a1a45e0bb052edf6a1d3a93baef85319733a888363938e1fc9924cb00c8df24c"}, 1675 | {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:da09ad1c359a728e112d60116f626cc9f29730ff3e0e7db72b9a2dbc2e4beed5"}, 1676 | {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:184565012b60405d93838167f425713180b949e9d8dd0bbc7b49f074407c5a8b"}, 1677 | {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a75879bacf2c987c003368cf14bed0ffe99e8e85acfa6c0bfffc21a090f16880"}, 1678 | {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-win32.whl", hash = "sha256:84b554931e932c46f94ab306913ad7e11bba988104c5cff26d90d03f68258cd5"}, 1679 | {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-win_amd64.whl", hash = "sha256:25ac8c08322002b06fa1d49d1646181f0b2c72f5cbc15a85e80b4c30a544bb15"}, 1680 | {file = "ruamel.yaml.clib-0.2.8.tar.gz", hash = "sha256:beb2e0404003de9a4cab9753a8805a8fe9320ee6673136ed7f04255fe60bb512"}, 1681 | ] 1682 | 1683 | [[package]] 1684 | name = "setuptools" 1685 | version = "70.2.0" 1686 | description = "Easily download, build, install, upgrade, and uninstall Python packages" 1687 | optional = false 1688 | python-versions = ">=3.8" 1689 | groups = ["dev"] 1690 | files = [ 1691 | {file = "setuptools-70.2.0-py3-none-any.whl", hash = "sha256:b8b8060bb426838fbe942479c90296ce976249451118ef566a5a0b7d8b78fb05"}, 1692 | {file = "setuptools-70.2.0.tar.gz", hash = "sha256:bd63e505105011b25c3c11f753f7e3b8465ea739efddaccef8f0efac2137bac1"}, 1693 | ] 1694 | 1695 | [package.extras] 1696 | doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] 1697 | test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21) ; python_version >= \"3.9\" and sys_platform != \"cygwin\"", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.10.0)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf ; sys_platform != \"cygwin\"", "pytest-ruff (>=0.3.2) ; sys_platform != \"cygwin\"", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] 1698 | 1699 | [[package]] 1700 | name = "six" 1701 | version = "1.16.0" 1702 | description = "Python 2 and 3 compatibility utilities" 1703 | optional = false 1704 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" 1705 | groups = ["dev"] 1706 | files = [ 1707 | {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, 1708 | {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, 1709 | ] 1710 | 1711 | [[package]] 1712 | name = "snowballstemmer" 1713 | version = "2.2.0" 1714 | description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." 1715 | optional = false 1716 | python-versions = "*" 1717 | groups = ["dev", "docs"] 1718 | files = [ 1719 | {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, 1720 | {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, 1721 | ] 1722 | 1723 | [[package]] 1724 | name = "sortedcontainers" 1725 | version = "2.4.0" 1726 | description = "Sorted Containers -- Sorted List, Sorted Dict, Sorted Set" 1727 | optional = false 1728 | python-versions = "*" 1729 | groups = ["dev"] 1730 | files = [ 1731 | {file = "sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0"}, 1732 | {file = "sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88"}, 1733 | ] 1734 | 1735 | [[package]] 1736 | name = "sphinx" 1737 | version = "7.4.7" 1738 | description = "Python documentation generator" 1739 | optional = false 1740 | python-versions = ">=3.9" 1741 | groups = ["docs"] 1742 | files = [ 1743 | {file = "sphinx-7.4.7-py3-none-any.whl", hash = "sha256:c2419e2135d11f1951cd994d6eb18a1835bd8fdd8429f9ca375dc1f3281bd239"}, 1744 | {file = "sphinx-7.4.7.tar.gz", hash = "sha256:242f92a7ea7e6c5b406fdc2615413890ba9f699114a9c09192d7dfead2ee9cfe"}, 1745 | ] 1746 | 1747 | [package.dependencies] 1748 | alabaster = ">=0.7.14,<0.8.0" 1749 | babel = ">=2.13" 1750 | colorama = {version = ">=0.4.6", markers = "sys_platform == \"win32\""} 1751 | docutils = ">=0.20,<0.22" 1752 | imagesize = ">=1.3" 1753 | importlib-metadata = {version = ">=6.0", markers = "python_version < \"3.10\""} 1754 | Jinja2 = ">=3.1" 1755 | packaging = ">=23.0" 1756 | Pygments = ">=2.17" 1757 | requests = ">=2.30.0" 1758 | snowballstemmer = ">=2.2" 1759 | sphinxcontrib-applehelp = "*" 1760 | sphinxcontrib-devhelp = "*" 1761 | sphinxcontrib-htmlhelp = ">=2.0.0" 1762 | sphinxcontrib-jsmath = "*" 1763 | sphinxcontrib-qthelp = "*" 1764 | sphinxcontrib-serializinghtml = ">=1.1.9" 1765 | tomli = {version = ">=2", markers = "python_version < \"3.11\""} 1766 | 1767 | [package.extras] 1768 | docs = ["sphinxcontrib-websupport"] 1769 | lint = ["flake8 (>=6.0)", "importlib-metadata (>=6.0)", "mypy (==1.10.1)", "pytest (>=6.0)", "ruff (==0.5.2)", "sphinx-lint (>=0.9)", "tomli (>=2)", "types-docutils (==0.21.0.20240711)", "types-requests (>=2.30.0)"] 1770 | test = ["cython (>=3.0)", "defusedxml (>=0.7.1)", "pytest (>=8.0)", "setuptools (>=70.0)", "typing_extensions (>=4.9)"] 1771 | 1772 | [[package]] 1773 | name = "sphinx-autodoc-typehints" 1774 | version = "2.3.0" 1775 | description = "Type hints (PEP 484) support for the Sphinx autodoc extension" 1776 | optional = false 1777 | python-versions = ">=3.9" 1778 | groups = ["docs"] 1779 | files = [ 1780 | {file = "sphinx_autodoc_typehints-2.3.0-py3-none-any.whl", hash = "sha256:3098e2c6d0ba99eacd013eb06861acc9b51c6e595be86ab05c08ee5506ac0c67"}, 1781 | {file = "sphinx_autodoc_typehints-2.3.0.tar.gz", hash = "sha256:535c78ed2d6a1bad393ba9f3dfa2602cf424e2631ee207263e07874c38fde084"}, 1782 | ] 1783 | 1784 | [package.dependencies] 1785 | sphinx = ">=7.3.5" 1786 | 1787 | [package.extras] 1788 | docs = ["furo (>=2024.1.29)"] 1789 | numpy = ["nptyping (>=2.5)"] 1790 | testing = ["covdefaults (>=2.3)", "coverage (>=7.4.4)", "defusedxml (>=0.7.1)", "diff-cover (>=9)", "pytest (>=8.1.1)", "pytest-cov (>=5)", "sphobjinv (>=2.3.1)", "typing-extensions (>=4.11)"] 1791 | 1792 | [[package]] 1793 | name = "sphinxcontrib-applehelp" 1794 | version = "1.0.8" 1795 | description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" 1796 | optional = false 1797 | python-versions = ">=3.9" 1798 | groups = ["docs"] 1799 | files = [ 1800 | {file = "sphinxcontrib_applehelp-1.0.8-py3-none-any.whl", hash = "sha256:cb61eb0ec1b61f349e5cc36b2028e9e7ca765be05e49641c97241274753067b4"}, 1801 | {file = "sphinxcontrib_applehelp-1.0.8.tar.gz", hash = "sha256:c40a4f96f3776c4393d933412053962fac2b84f4c99a7982ba42e09576a70619"}, 1802 | ] 1803 | 1804 | [package.extras] 1805 | lint = ["docutils-stubs", "flake8", "mypy"] 1806 | standalone = ["Sphinx (>=5)"] 1807 | test = ["pytest"] 1808 | 1809 | [[package]] 1810 | name = "sphinxcontrib-devhelp" 1811 | version = "1.0.6" 1812 | description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents" 1813 | optional = false 1814 | python-versions = ">=3.9" 1815 | groups = ["docs"] 1816 | files = [ 1817 | {file = "sphinxcontrib_devhelp-1.0.6-py3-none-any.whl", hash = "sha256:6485d09629944511c893fa11355bda18b742b83a2b181f9a009f7e500595c90f"}, 1818 | {file = "sphinxcontrib_devhelp-1.0.6.tar.gz", hash = "sha256:9893fd3f90506bc4b97bdb977ceb8fbd823989f4316b28c3841ec128544372d3"}, 1819 | ] 1820 | 1821 | [package.extras] 1822 | lint = ["docutils-stubs", "flake8", "mypy"] 1823 | standalone = ["Sphinx (>=5)"] 1824 | test = ["pytest"] 1825 | 1826 | [[package]] 1827 | name = "sphinxcontrib-htmlhelp" 1828 | version = "2.0.5" 1829 | description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" 1830 | optional = false 1831 | python-versions = ">=3.9" 1832 | groups = ["docs"] 1833 | files = [ 1834 | {file = "sphinxcontrib_htmlhelp-2.0.5-py3-none-any.whl", hash = "sha256:393f04f112b4d2f53d93448d4bce35842f62b307ccdc549ec1585e950bc35e04"}, 1835 | {file = "sphinxcontrib_htmlhelp-2.0.5.tar.gz", hash = "sha256:0dc87637d5de53dd5eec3a6a01753b1ccf99494bd756aafecd74b4fa9e729015"}, 1836 | ] 1837 | 1838 | [package.extras] 1839 | lint = ["docutils-stubs", "flake8", "mypy"] 1840 | standalone = ["Sphinx (>=5)"] 1841 | test = ["html5lib", "pytest"] 1842 | 1843 | [[package]] 1844 | name = "sphinxcontrib-jsmath" 1845 | version = "1.0.1" 1846 | description = "A sphinx extension which renders display math in HTML via JavaScript" 1847 | optional = false 1848 | python-versions = ">=3.5" 1849 | groups = ["docs"] 1850 | files = [ 1851 | {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"}, 1852 | {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"}, 1853 | ] 1854 | 1855 | [package.extras] 1856 | test = ["flake8", "mypy", "pytest"] 1857 | 1858 | [[package]] 1859 | name = "sphinxcontrib-qthelp" 1860 | version = "1.0.7" 1861 | description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents" 1862 | optional = false 1863 | python-versions = ">=3.9" 1864 | groups = ["docs"] 1865 | files = [ 1866 | {file = "sphinxcontrib_qthelp-1.0.7-py3-none-any.whl", hash = "sha256:e2ae3b5c492d58fcbd73281fbd27e34b8393ec34a073c792642cd8e529288182"}, 1867 | {file = "sphinxcontrib_qthelp-1.0.7.tar.gz", hash = "sha256:053dedc38823a80a7209a80860b16b722e9e0209e32fea98c90e4e6624588ed6"}, 1868 | ] 1869 | 1870 | [package.extras] 1871 | lint = ["docutils-stubs", "flake8", "mypy"] 1872 | standalone = ["Sphinx (>=5)"] 1873 | test = ["pytest"] 1874 | 1875 | [[package]] 1876 | name = "sphinxcontrib-serializinghtml" 1877 | version = "1.1.10" 1878 | description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)" 1879 | optional = false 1880 | python-versions = ">=3.9" 1881 | groups = ["docs"] 1882 | files = [ 1883 | {file = "sphinxcontrib_serializinghtml-1.1.10-py3-none-any.whl", hash = "sha256:326369b8df80a7d2d8d7f99aa5ac577f51ea51556ed974e7716cfd4fca3f6cb7"}, 1884 | {file = "sphinxcontrib_serializinghtml-1.1.10.tar.gz", hash = "sha256:93f3f5dc458b91b192fe10c397e324f262cf163d79f3282c158e8436a2c4511f"}, 1885 | ] 1886 | 1887 | [package.extras] 1888 | lint = ["docutils-stubs", "flake8", "mypy"] 1889 | standalone = ["Sphinx (>=5)"] 1890 | test = ["pytest"] 1891 | 1892 | [[package]] 1893 | name = "sqlparse" 1894 | version = "0.5.0" 1895 | description = "A non-validating SQL parser." 1896 | optional = false 1897 | python-versions = ">=3.8" 1898 | groups = ["dev"] 1899 | files = [ 1900 | {file = "sqlparse-0.5.0-py3-none-any.whl", hash = "sha256:c204494cd97479d0e39f28c93d46c0b2d5959c7b9ab904762ea6c7af211c8663"}, 1901 | {file = "sqlparse-0.5.0.tar.gz", hash = "sha256:714d0a4932c059d16189f58ef5411ec2287a4360f17cdd0edd2d09d4c5087c93"}, 1902 | ] 1903 | 1904 | [package.extras] 1905 | dev = ["build", "hatch"] 1906 | doc = ["sphinx"] 1907 | 1908 | [[package]] 1909 | name = "stevedore" 1910 | version = "5.2.0" 1911 | description = "Manage dynamic plugins for Python applications" 1912 | optional = false 1913 | python-versions = ">=3.8" 1914 | groups = ["dev"] 1915 | files = [ 1916 | {file = "stevedore-5.2.0-py3-none-any.whl", hash = "sha256:1c15d95766ca0569cad14cb6272d4d31dae66b011a929d7c18219c176ea1b5c9"}, 1917 | {file = "stevedore-5.2.0.tar.gz", hash = "sha256:46b93ca40e1114cea93d738a6c1e365396981bb6bb78c27045b7587c9473544d"}, 1918 | ] 1919 | 1920 | [package.dependencies] 1921 | pbr = ">=2.0.0,<2.1.0 || >2.1.0" 1922 | 1923 | [[package]] 1924 | name = "strenum" 1925 | version = "0.4.15" 1926 | description = "An Enum that inherits from str." 1927 | optional = false 1928 | python-versions = "*" 1929 | groups = ["dev"] 1930 | files = [ 1931 | {file = "StrEnum-0.4.15-py3-none-any.whl", hash = "sha256:a30cda4af7cc6b5bf52c8055bc4bf4b2b6b14a93b574626da33df53cf7740659"}, 1932 | {file = "StrEnum-0.4.15.tar.gz", hash = "sha256:878fb5ab705442070e4dd1929bb5e2249511c0bcf2b0eeacf3bcd80875c82eff"}, 1933 | ] 1934 | 1935 | [package.extras] 1936 | docs = ["myst-parser[linkify]", "sphinx", "sphinx-rtd-theme"] 1937 | release = ["twine"] 1938 | test = ["pylint", "pytest", "pytest-black", "pytest-cov", "pytest-pylint"] 1939 | 1940 | [[package]] 1941 | name = "text-unidecode" 1942 | version = "1.3" 1943 | description = "The most basic Text::Unidecode port" 1944 | optional = false 1945 | python-versions = "*" 1946 | groups = ["dev"] 1947 | files = [ 1948 | {file = "text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93"}, 1949 | {file = "text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8"}, 1950 | ] 1951 | 1952 | [[package]] 1953 | name = "toml" 1954 | version = "0.10.2" 1955 | description = "Python Library for Tom's Obvious, Minimal Language" 1956 | optional = false 1957 | python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" 1958 | groups = ["dev"] 1959 | files = [ 1960 | {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, 1961 | {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, 1962 | ] 1963 | 1964 | [[package]] 1965 | name = "tomli" 1966 | version = "2.2.1" 1967 | description = "A lil' TOML parser" 1968 | optional = false 1969 | python-versions = ">=3.8" 1970 | groups = ["dev", "docs"] 1971 | files = [ 1972 | {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, 1973 | {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, 1974 | {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"}, 1975 | {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"}, 1976 | {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"}, 1977 | {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"}, 1978 | {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"}, 1979 | {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"}, 1980 | {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"}, 1981 | {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"}, 1982 | {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"}, 1983 | {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"}, 1984 | {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"}, 1985 | {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"}, 1986 | {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"}, 1987 | {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"}, 1988 | {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"}, 1989 | {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"}, 1990 | {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"}, 1991 | {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"}, 1992 | {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"}, 1993 | {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"}, 1994 | {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"}, 1995 | {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"}, 1996 | {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"}, 1997 | {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"}, 1998 | {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"}, 1999 | {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"}, 2000 | {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"}, 2001 | {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"}, 2002 | {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, 2003 | {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, 2004 | ] 2005 | 2006 | [[package]] 2007 | name = "tomlkit" 2008 | version = "0.12.5" 2009 | description = "Style preserving TOML library" 2010 | optional = false 2011 | python-versions = ">=3.7" 2012 | groups = ["dev"] 2013 | files = [ 2014 | {file = "tomlkit-0.12.5-py3-none-any.whl", hash = "sha256:af914f5a9c59ed9d0762c7b64d3b5d5df007448eb9cd2edc8a46b1eafead172f"}, 2015 | {file = "tomlkit-0.12.5.tar.gz", hash = "sha256:eef34fba39834d4d6b73c9ba7f3e4d1c417a4e56f89a7e96e090dd0d24b8fb3c"}, 2016 | ] 2017 | 2018 | [[package]] 2019 | name = "typing-extensions" 2020 | version = "4.12.2" 2021 | description = "Backported and Experimental Type Hints for Python 3.8+" 2022 | optional = false 2023 | python-versions = ">=3.8" 2024 | groups = ["dev"] 2025 | files = [ 2026 | {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, 2027 | {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, 2028 | ] 2029 | 2030 | [[package]] 2031 | name = "tzdata" 2032 | version = "2024.1" 2033 | description = "Provider of IANA time zone data" 2034 | optional = false 2035 | python-versions = ">=2" 2036 | groups = ["dev"] 2037 | markers = "sys_platform == \"win32\"" 2038 | files = [ 2039 | {file = "tzdata-2024.1-py2.py3-none-any.whl", hash = "sha256:9068bc196136463f5245e51efda838afa15aaeca9903f49050dfa2679db4d252"}, 2040 | {file = "tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd"}, 2041 | ] 2042 | 2043 | [[package]] 2044 | name = "url-normalize" 2045 | version = "1.4.3" 2046 | description = "URL normalization for Python" 2047 | optional = false 2048 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" 2049 | groups = ["dev"] 2050 | files = [ 2051 | {file = "url-normalize-1.4.3.tar.gz", hash = "sha256:d23d3a070ac52a67b83a1c59a0e68f8608d1cd538783b401bc9de2c0fac999b2"}, 2052 | {file = "url_normalize-1.4.3-py2.py3-none-any.whl", hash = "sha256:ec3c301f04e5bb676d333a7fa162fa977ad2ca04b7e652bfc9fac4e405728eed"}, 2053 | ] 2054 | 2055 | [package.dependencies] 2056 | six = "*" 2057 | 2058 | [[package]] 2059 | name = "urllib3" 2060 | version = "2.2.2" 2061 | description = "HTTP library with thread-safe connection pooling, file post, and more." 2062 | optional = false 2063 | python-versions = ">=3.8" 2064 | groups = ["dev", "docs"] 2065 | files = [ 2066 | {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"}, 2067 | {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"}, 2068 | ] 2069 | 2070 | [package.extras] 2071 | brotli = ["brotli (>=1.0.9) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\""] 2072 | h2 = ["h2 (>=4,<5)"] 2073 | socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] 2074 | zstd = ["zstandard (>=0.18.0)"] 2075 | 2076 | [[package]] 2077 | name = "wemake-python-styleguide" 2078 | version = "0.19.2" 2079 | description = "The strictest and most opinionated python linter ever" 2080 | optional = false 2081 | python-versions = "<4.0,>=3.9" 2082 | groups = ["dev"] 2083 | files = [ 2084 | {file = "wemake_python_styleguide-0.19.2-py3-none-any.whl", hash = "sha256:d53205dbb629755026d853d15fb3ca03ebb2717c97de4198b5676b9bdc0663bd"}, 2085 | {file = "wemake_python_styleguide-0.19.2.tar.gz", hash = "sha256:850fe70e6d525fd37ac51778e552a121a489f1bd057184de96ffd74a09aef414"}, 2086 | ] 2087 | 2088 | [package.dependencies] 2089 | astor = ">=0.8,<0.9" 2090 | attrs = "*" 2091 | darglint = ">=1.2,<2.0" 2092 | flake8 = ">=7.0,<8.0" 2093 | flake8-bandit = ">=4.1,<5.0" 2094 | flake8-broken-line = ">=1.0,<2.0" 2095 | flake8-bugbear = ">=24.2,<25.0" 2096 | flake8-commas = ">=2.0,<3.0" 2097 | flake8-comprehensions = ">=3.1,<4.0" 2098 | flake8-debugger = ">=4.0,<5.0" 2099 | flake8-docstrings = ">=1.3,<2.0" 2100 | flake8-eradicate = ">=1.5,<2.0" 2101 | flake8-isort = ">=6.0,<7.0" 2102 | flake8-quotes = ">=3.0,<4.0" 2103 | flake8-rst-docstrings = ">=0.3,<0.4" 2104 | flake8-string-format = ">=0.3,<0.4" 2105 | pep8-naming = ">=0.13,<0.14" 2106 | pygments = ">=2.4,<3.0" 2107 | setuptools = "*" 2108 | typing_extensions = ">=4.0,<5.0" 2109 | 2110 | [[package]] 2111 | name = "win32-setctime" 2112 | version = "1.1.0" 2113 | description = "A small Python utility to set file creation time on Windows" 2114 | optional = false 2115 | python-versions = ">=3.5" 2116 | groups = ["dev"] 2117 | markers = "sys_platform == \"win32\"" 2118 | files = [ 2119 | {file = "win32_setctime-1.1.0-py3-none-any.whl", hash = "sha256:231db239e959c2fe7eb1d7dc129f11172354f98361c4fa2d6d2d7e278baa8aad"}, 2120 | {file = "win32_setctime-1.1.0.tar.gz", hash = "sha256:15cf5750465118d6929ae4de4eb46e8edae9a5634350c01ba582df868e932cb2"}, 2121 | ] 2122 | 2123 | [package.extras] 2124 | dev = ["black (>=19.3b0) ; python_version >= \"3.6\"", "pytest (>=4.6.2)"] 2125 | 2126 | [[package]] 2127 | name = "zipp" 2128 | version = "3.19.2" 2129 | description = "Backport of pathlib-compatible object wrapper for zip files" 2130 | optional = false 2131 | python-versions = ">=3.8" 2132 | groups = ["dev", "docs"] 2133 | markers = "python_version < \"3.10\"" 2134 | files = [ 2135 | {file = "zipp-3.19.2-py3-none-any.whl", hash = "sha256:f091755f667055f2d02b32c53771a7a6c8b47e1fdbc4b72a8b9072b3eef8015c"}, 2136 | {file = "zipp-3.19.2.tar.gz", hash = "sha256:bf1dcf6450f873a13e952a29504887c89e6de7506209e5b1bcc3460135d4de19"}, 2137 | ] 2138 | 2139 | [package.extras] 2140 | doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] 2141 | test = ["big-O", "importlib-resources ; python_version < \"3.9\"", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy", "pytest-ruff (>=0.2.1)"] 2142 | 2143 | [metadata] 2144 | lock-version = "2.1" 2145 | python-versions = "^3.9" 2146 | content-hash = "9e299c52303cdce11bf8b9f2905dc44f78d8c033e1a740f81f00a7be373b9092" 2147 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "django-split-settings" 3 | version = "1.3.2" 4 | description = "Organize Django settings into multiple files and directories. Easily override and modify settings. Use wildcards and optional settings files." 5 | authors = [ 6 | "sobolevn ", 7 | "Visa Kopu", 8 | "Antti Kaihola", 9 | ] 10 | license = "BSD-2-Clause" 11 | packages = [ 12 | { include = "split_settings" } 13 | ] 14 | 15 | readme = "README.md" 16 | 17 | repository = "https://github.com/sobolevn/django-split-settings" 18 | homepage = "https://django-split-settings.readthedocs.io" 19 | 20 | keywords = [ 21 | "django", 22 | "settings", 23 | "configuration", 24 | "config", 25 | ] 26 | 27 | classifiers = [ 28 | "Development Status :: 5 - Production/Stable", 29 | "Environment :: Web Environment", 30 | "Framework :: Django", 31 | "Framework :: Django :: 3.2", 32 | "Framework :: Django :: 4.0", 33 | "Framework :: Django :: 4.1", 34 | "Framework :: Django :: 4.2", 35 | "Framework :: Django :: 5.0", 36 | "Intended Audience :: Developers", 37 | "License :: OSI Approved :: BSD License", 38 | "Operating System :: OS Independent", 39 | "Topic :: Software Development :: Libraries :: Python Modules", 40 | "Topic :: Internet :: WWW/HTTP", 41 | "Topic :: Internet :: WWW/HTTP :: Dynamic Content", 42 | ] 43 | 44 | [project.urls] 45 | "Funding" = "https://github.com/sponsors/wemake-services" 46 | 47 | [tool.poetry.dependencies] 48 | python = "^3.9" 49 | 50 | [tool.poetry.group.dev.dependencies] 51 | django = [ 52 | { version = "^4.2", python = "<3.10" }, 53 | { version = "^5.0", python = ">=3.10" }, 54 | ] 55 | 56 | mypy = "^1.10" 57 | wemake-python-styleguide = "^0.19" 58 | flake8-pytest-style = "^2.0" 59 | nitpick = "^0.35" 60 | 61 | doc8 = "^1.1" 62 | 63 | pytest = "^8.1" 64 | pytest-cov = ">=5,<7" 65 | pytest-randomly = "^3.12" 66 | 67 | [tool.poetry.group.docs] 68 | optional = true 69 | 70 | [tool.poetry.group.docs.dependencies] 71 | sphinx = "^7.3" 72 | sphinx-autodoc-typehints = "^2.2" 73 | m2r2 = "^0.3" 74 | tomli = "^2.0" 75 | 76 | 77 | [build-system] 78 | requires = ["poetry-core>=1.9.0"] 79 | build-backend = "poetry.masonry.api" 80 | 81 | 82 | [tool.nitpick] 83 | style = "https://raw.githubusercontent.com/wemake-services/wemake-python-styleguide/0.19.2/styles/nitpick-style-wemake.toml" 84 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | # All configuration for plugins and other utils is defined here. 2 | # Read more about `setup.cfg`: 3 | # https://docs.python.org/3/distutils/configfile.html 4 | 5 | [flake8] 6 | # Base flake8 configuration: 7 | # https://flake8.pycqa.org/en/latest/user/configuration.html 8 | format = wemake 9 | show-source = true 10 | doctests = true 11 | 12 | # darglint configuration: 13 | # https://github.com/terrencepreilly/darglint 14 | strictness = long 15 | docstring-style = numpy 16 | 17 | # Plugins: 18 | max-complexity = 6 19 | max-line-length = 80 20 | 21 | # Excluding some directories: 22 | exclude = 23 | .git 24 | __pycache__ 25 | .venv 26 | .eggs 27 | *.egg 28 | 29 | # Exclude some pydoctest checks globally: 30 | ignore = D100, D104, D401, W504, RST210, RST213, RST299, RST303, RST304, DAR103, DAR203 31 | 32 | per-file-ignores = 33 | # Our module is complex, there's nothing we can do: 34 | split_settings/tools.py: WPS232 35 | # Tests contain examples with logic in init files: 36 | tests/*/__init__.py: WPS412 37 | # There are multiple fixtures, `assert`s, and subprocesses in tests: 38 | tests/*.py: S101, S105, S404, S603, S607 39 | 40 | 41 | [isort] 42 | # isort configuration: 43 | # https://github.com/timothycrosley/isort/wiki/isort-Settings 44 | profile = wemake 45 | 46 | 47 | [tool:pytest] 48 | # py.test options: 49 | norecursedirs = *.egg .eggs dist build docs .tox .git __pycache__ 50 | 51 | addopts = 52 | --strict-markers 53 | --strict-config 54 | --cov=split_settings 55 | --cov-branch 56 | --cov-report=term-missing:skip-covered 57 | --cov-report=html 58 | --cov-report=xml 59 | --cov-fail-under=100 60 | 61 | 62 | [mypy] 63 | # The mypy configurations: http://bit.ly/2zEl9WI 64 | enable_error_code = 65 | truthy-bool, 66 | truthy-iterable, 67 | redundant-expr, 68 | unused-awaitable, 69 | ignore-without-code, 70 | possibly-undefined, 71 | redundant-self, 72 | 73 | ignore_missing_imports = true 74 | strict = true 75 | warn_unreachable = true 76 | 77 | [mypy-tests.*] 78 | disable_error_code = no-untyped-def 79 | 80 | 81 | [doc8] 82 | ignore-path = docs/_build 83 | max-line-length = 80 84 | sphinx = True 85 | -------------------------------------------------------------------------------- /split_settings/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Organize Django settings into multiple files and directories. 3 | 4 | Easily override and modify settings. Use wildcards and optional 5 | settings files. 6 | """ 7 | -------------------------------------------------------------------------------- /split_settings/py.typed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wemake-services/django-split-settings/0fdad90ca2c8283840ca61cab267a548c8aa2b8a/split_settings/py.typed -------------------------------------------------------------------------------- /split_settings/tools.py: -------------------------------------------------------------------------------- 1 | """ 2 | Organize Django settings into multiple files and directories. 3 | 4 | Easily override and modify settings. Use wildcards and optional 5 | settings files. 6 | """ 7 | 8 | from __future__ import annotations 9 | 10 | import glob 11 | import os 12 | import sys 13 | import typing 14 | from importlib.util import module_from_spec, spec_from_file_location 15 | 16 | __all__ = ('optional', 'include') # noqa: WPS410 17 | 18 | #: Special magic attribute that is sometimes set by `uwsgi` / `gunicorn`. 19 | _INCLUDED_FILE = '__included_file__' 20 | 21 | 22 | def optional(filename: typing.Optional[str]) -> str: 23 | """ 24 | This function is used for compatibility reasons. 25 | 26 | It masks the old `optional` class with the name error. 27 | Now `invalid-name` is removed from `pylint`. 28 | 29 | Args: 30 | filename: the filename to be optional. 31 | 32 | Returns: 33 | New instance of :class:`_Optional`. 34 | 35 | """ 36 | return _Optional(filename or '') 37 | 38 | 39 | class _Optional(str): # noqa: WPS600 40 | """ 41 | Wrap a file path with this class to mark it as optional. 42 | 43 | Optional paths don't raise an :class:`OSError` if file is not found. 44 | """ 45 | 46 | 47 | def include( # noqa: WPS210, WPS231, C901 48 | *args: str, 49 | scope: dict[str, typing.Any] | None = None, 50 | ) -> None: 51 | """ 52 | Used for including Django project settings from multiple files. 53 | 54 | Args: 55 | *args: File paths (``glob`` - compatible wildcards can be used). 56 | scope: Settings context (``globals()`` or ``None``). 57 | 58 | Raises: 59 | OSError: if a required settings file is not found. 60 | 61 | Usage example: 62 | 63 | .. code:: python 64 | 65 | from split_settings.tools import optional, include 66 | 67 | include( 68 | 'components/base.py', 69 | 'components/database.py', 70 | optional('local_settings.py'), 71 | 72 | scope=globals(), # optional scope 73 | ) 74 | 75 | """ 76 | # we are getting globals() from previous frame 77 | # globals - it is caller's globals() 78 | scope = scope or sys._getframe(1).f_globals # noqa: WPS437 79 | 80 | scope.setdefault('__included_files__', []) 81 | included_files = scope.get('__included_files__', []) 82 | 83 | including_file = scope.get( 84 | _INCLUDED_FILE, 85 | scope['__file__'].rstrip('c'), 86 | ) 87 | conf_path = os.path.dirname(including_file) 88 | 89 | for conf_file in args: 90 | if isinstance(conf_file, _Optional) and not conf_file: 91 | continue # skip empty optional values 92 | 93 | saved_included_file = scope.get(_INCLUDED_FILE) 94 | pattern = os.path.join(conf_path, conf_file) 95 | 96 | # find files per pattern, raise an error if not found 97 | # (unless file is optional) 98 | files_to_include = glob.glob(pattern) 99 | if not files_to_include and not isinstance(conf_file, _Optional): 100 | raise OSError('No such file: {0}'.format(pattern)) 101 | 102 | for included_file in files_to_include: 103 | included_file = os.path.abspath(included_file) # noqa: WPS440 104 | if included_file in included_files: 105 | continue 106 | 107 | included_files.append(included_file) 108 | 109 | scope[_INCLUDED_FILE] = included_file 110 | with open(included_file, 'rb') as to_compile: 111 | compiled_code = compile( # noqa: WPS421 112 | to_compile.read(), included_file, 'exec', 113 | ) 114 | exec(compiled_code, scope) # noqa: S102, WPS421 115 | 116 | # Adds dummy modules to sys.modules to make runserver autoreload 117 | # work with settings components: 118 | rel_path = os.path.relpath(included_file) 119 | module_name = '_split_settings.{0}'.format( 120 | rel_path[:rel_path.rfind('.')].replace('/', '.'), 121 | ) 122 | 123 | spec = spec_from_file_location(module_name, included_file) 124 | # This is only needed for mypy: 125 | assert spec is not None # noqa: S101 126 | module = module_from_spec(spec) 127 | sys.modules[module_name] = module 128 | if saved_included_file: 129 | scope[_INCLUDED_FILE] = saved_included_file 130 | elif _INCLUDED_FILE in scope: 131 | scope.pop(_INCLUDED_FILE) 132 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wemake-services/django-split-settings/0fdad90ca2c8283840ca61cab267a548c8aa2b8a/tests/__init__.py -------------------------------------------------------------------------------- /tests/conftest.py: -------------------------------------------------------------------------------- 1 | """This file contains different utils and fixtures.""" 2 | 3 | import os 4 | 5 | import pytest 6 | 7 | 8 | class Scope(dict): # noqa: WPS600 9 | """This class emulates `globals()`, but does not share state in tests.""" 10 | 11 | def __init__(self, *args, **kwargs): 12 | """Adding `__file__` to make things work in `tools.py`.""" 13 | super().__init__(*args, **kwargs) 14 | self['__file__'] = __file__ 15 | 16 | 17 | # Different util functions: 18 | 19 | @pytest.fixture 20 | def scope(): 21 | """This fixture just returns the new instance of the test Scope class.""" 22 | return Scope() 23 | 24 | 25 | @pytest.fixture 26 | def fixture_file(): 27 | """This fixture return a path to the test fixture file.""" 28 | return os.path.join( 29 | 'settings', 30 | 'basic', 31 | 'fixture_to_include.py', 32 | ) 33 | 34 | 35 | # Settings files: 36 | 37 | @pytest.fixture 38 | def merged(): 39 | """This fixture returns basic merged settings example.""" 40 | from tests.settings import merged as _merged # noqa: WPS433 41 | return _merged 42 | 43 | 44 | @pytest.fixture 45 | def stacked(): 46 | """This fixture returns stacked settings example.""" 47 | from tests.settings import stacked as _stacked # noqa: WPS433 48 | return _stacked 49 | 50 | 51 | @pytest.fixture 52 | def recursion(): 53 | """This fixture returns recursion settings example.""" 54 | from tests.settings import recursion as _recursion # noqa: WPS433 55 | return _recursion 56 | -------------------------------------------------------------------------------- /tests/settings/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wemake-services/django-split-settings/0fdad90ca2c8283840ca61cab267a548c8aa2b8a/tests/settings/__init__.py -------------------------------------------------------------------------------- /tests/settings/basic/fixture_to_include.py: -------------------------------------------------------------------------------- 1 | """This file only serves as a test fixture to be included.""" 2 | 3 | FIXTURE_VALUE = __file__ 4 | -------------------------------------------------------------------------------- /tests/settings/merged/__init__.py: -------------------------------------------------------------------------------- 1 | from split_settings.tools import include, optional 2 | 3 | include( 4 | # Components: 5 | 'components/base.py', 6 | 'components/locale.py', 7 | 'components/apps_middleware.py', 8 | 'components/static.py', 9 | 'components/templates.py', 10 | 'components/database.py', 11 | 'components/logging.py', 12 | 13 | # Override settings for testing: 14 | optional('components/testing.py'), 15 | 16 | # Missing file: 17 | optional('components/missing_file.py'), 18 | 19 | # Scope: 20 | scope=globals(), # noqa: WPS421 21 | ) 22 | -------------------------------------------------------------------------------- /tests/settings/merged/components/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wemake-services/django-split-settings/0fdad90ca2c8283840ca61cab267a548c8aa2b8a/tests/settings/merged/components/__init__.py -------------------------------------------------------------------------------- /tests/settings/merged/components/apps_middleware.py: -------------------------------------------------------------------------------- 1 | MIDDLEWARE_CLASSES = ( 2 | 'django.middleware.common.CommonMiddleware', 3 | 'django.contrib.sessions.middleware.SessionMiddleware', 4 | 'django.middleware.csrf.CsrfViewMiddleware', 5 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 6 | 'django.contrib.messages.middleware.MessageMiddleware', 7 | # Uncomment the next line for simple clickjacking protection: 8 | # 'django.middleware.clickjacking.XFrameOptionsMiddleware', 9 | ) 10 | 11 | INSTALLED_APPS = ( 12 | 'django.contrib.auth', 13 | 'django.contrib.contenttypes', 14 | 'django.contrib.sessions', 15 | 'django.contrib.sites', 16 | 'django.contrib.messages', 17 | 'django.contrib.staticfiles', 18 | # Uncomment the next line to enable the admin: 19 | # 'django.contrib.admin', 20 | # Uncomment the next line to enable admin documentation: 21 | # 'django.contrib.admindocs', 22 | ) 23 | -------------------------------------------------------------------------------- /tests/settings/merged/components/base.py: -------------------------------------------------------------------------------- 1 | # Django settings for example project. 2 | 3 | DEBUG = True 4 | TEMPLATE_DEBUG = DEBUG 5 | 6 | ADMINS = () 7 | 8 | MANAGERS = ADMINS 9 | 10 | # Hosts/domain names that are valid for this site; required if DEBUG is False 11 | # See https://docs.djangoproject.com/en/1.5/ref/settings/#allowed-hosts 12 | ALLOWED_HOSTS = () 13 | 14 | SITE_ID = 1 15 | 16 | # Make this unique, and don't share it with anybody. 17 | SECRET_KEY = 'a2j43z$c+s#v@9^7$zlqjty)s--v655_8*lkkvuz7&d-6(9d=v' 18 | 19 | ROOT_URLCONF = 'example.urls' 20 | 21 | # Python dotted path to the WSGI application used by Django's runserver. 22 | WSGI_APPLICATION = 'example.wsgi.application' 23 | -------------------------------------------------------------------------------- /tests/settings/merged/components/database.py: -------------------------------------------------------------------------------- 1 | DATABASES = { # noqa: WPS407 2 | 'default': { 3 | 'ENGINE': 'django.db.backends.sqlite3', 4 | 'NAME': 'test.db', 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /tests/settings/merged/components/locale.py: -------------------------------------------------------------------------------- 1 | # Local time zone for this installation. Choices can be found here: 2 | # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name 3 | # although not all choices may be available on all operating systems. 4 | # In a Windows environment this must be set to your system time zone. 5 | TIME_ZONE = 'America/Chicago' 6 | 7 | # Language code for this installation. All choices can be found here: 8 | # http://www.i18nguy.com/unicode/language-identifiers.html 9 | LANGUAGE_CODE = 'en-us' 10 | 11 | # If you set this to False, Django will make some optimizations so as not 12 | # to load the internationalization machinery. 13 | USE_I18N = True 14 | 15 | # If you set this to False, Django will not use timezone-aware datetimes. 16 | USE_TZ = True 17 | -------------------------------------------------------------------------------- /tests/settings/merged/components/logging.py: -------------------------------------------------------------------------------- 1 | LOGGING = { # noqa: WPS407 2 | 'version': 1, 3 | 'disable_existing_loggers': False, 4 | 'filters': { 5 | 'require_debug_false': { 6 | '()': 'django.utils.log.RequireDebugFalse', 7 | }, 8 | }, 9 | 'handlers': { 10 | 'mail_admins': { 11 | 'level': 'ERROR', 12 | 'filters': ['require_debug_false'], 13 | 'class': 'django.utils.log.AdminEmailHandler', 14 | }, 15 | }, 16 | 'loggers': { 17 | 'django.request': { 18 | 'handlers': ['mail_admins'], 19 | 'level': 'ERROR', 20 | 'propagate': True, 21 | }, 22 | }, 23 | } 24 | -------------------------------------------------------------------------------- /tests/settings/merged/components/static.py: -------------------------------------------------------------------------------- 1 | MEDIA_ROOT = '' 2 | 3 | MEDIA_URL = '' 4 | 5 | STATIC_ROOT = '' 6 | 7 | STATIC_URL = '/static/' 8 | 9 | STATICFILES_DIRS = () 10 | 11 | STATICFILES_FINDERS = ( 12 | 'django.contrib.staticfiles.finders.FileSystemFinder', 13 | 'django.contrib.staticfiles.finders.AppDirectoriesFinder', 14 | ) 15 | -------------------------------------------------------------------------------- /tests/settings/merged/components/templates.py: -------------------------------------------------------------------------------- 1 | # List of callables that know how to import templates from various sources. 2 | 3 | TEMPLATE_LOADERS = ( 4 | 'django.template.loaders.filesystem.Loader', 5 | 'django.template.loaders.app_directories.Loader', 6 | ) 7 | 8 | TEMPLATE_DIRS = ( 9 | # Put strings here, like 10 | # "/home/html/django_templates" or "C:/www/django/templates". 11 | # Always use forward slashes, even on Windows. 12 | # Don't forget to use absolute paths, not relative paths. 13 | ) 14 | -------------------------------------------------------------------------------- /tests/settings/merged/components/testing.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | # This settings will override settings in static.py 4 | STATIC_ROOT = 'test_folder' 5 | 6 | 7 | class TestingConfiguration: 8 | """Test class.""" 9 | 10 | def __init__(self, testing_dir): 11 | """Public constructor.""" 12 | self.test_path = os.path.join(testing_dir, STATIC_ROOT) 13 | 14 | def get_path(self): 15 | """Returns path.""" 16 | return self.test_path 17 | -------------------------------------------------------------------------------- /tests/settings/recursion/__init__.py: -------------------------------------------------------------------------------- 1 | from split_settings.tools import include 2 | 3 | # Includes all python files without scope: 4 | include('*.py') 5 | -------------------------------------------------------------------------------- /tests/settings/recursion/ok.py: -------------------------------------------------------------------------------- 1 | RECURSION_OK = True 2 | -------------------------------------------------------------------------------- /tests/settings/stacked/__init__.py: -------------------------------------------------------------------------------- 1 | from split_settings.tools import include 2 | 3 | include('base.py') 4 | -------------------------------------------------------------------------------- /tests/settings/stacked/base.py: -------------------------------------------------------------------------------- 1 | from split_settings.tools import include 2 | 3 | STACKED_BASE_LOADED = True 4 | 5 | include('db/*.py') 6 | -------------------------------------------------------------------------------- /tests/settings/stacked/db/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wemake-services/django-split-settings/0fdad90ca2c8283840ca61cab267a548c8aa2b8a/tests/settings/stacked/db/__init__.py -------------------------------------------------------------------------------- /tests/settings/stacked/db/persistent.py: -------------------------------------------------------------------------------- 1 | if STACKED_BASE_LOADED: # noqa: F821 2 | STACKED_DB_PERSISTENT = True 3 | -------------------------------------------------------------------------------- /tests/test_import.py: -------------------------------------------------------------------------------- 1 | from split_settings.tools import __all__ 2 | 3 | 4 | def test_wildcard_import(): 5 | """Imports all from all modules.""" 6 | assert 'optional' in __all__ 7 | assert 'include' in __all__ 8 | 9 | 10 | def test_class_import(merged): 11 | """This test case covers #7 issue.""" 12 | from tests.settings.merged.components import testing # noqa: WPS433 13 | 14 | path = testing.TestingConfiguration('').get_path() 15 | assert merged.STATIC_ROOT == path 16 | -------------------------------------------------------------------------------- /tests/test_split_settings.py: -------------------------------------------------------------------------------- 1 | 2 | def test_merge(merged): 3 | """Test that all values from settings are present.""" 4 | assert merged.SECRET_KEY 5 | assert merged.STATIC_ROOT 6 | 7 | 8 | def test_override(merged, monkeypatch): 9 | """This setting must be overridden in the testing.py.""" 10 | monkeypatch.setenv('DJANGO_SETTINGS_MODULE', 'tests.settings.merged') 11 | 12 | from django.conf import settings # noqa: WPS433 13 | 14 | assert merged.STATIC_ROOT == settings.STATIC_ROOT 15 | 16 | 17 | def test_recursion_inclusion(recursion): 18 | """ 19 | Tests `include` function for inclusion files only once. 20 | 21 | It protects of infinite recursion. 22 | """ 23 | assert recursion.RECURSION_OK 24 | 25 | 26 | def test_stacked_settings(stacked): 27 | """ 28 | Tests `include` function for inclusion files only once. 29 | 30 | It protects of infinite recursion. 31 | """ 32 | assert stacked.STACKED_BASE_LOADED 33 | assert stacked.STACKED_DB_PERSISTENT 34 | -------------------------------------------------------------------------------- /tests/test_tools.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | import pytest 4 | 5 | from split_settings.tools import include, optional 6 | 7 | _FIXTURE_VALUE = 'FIXTURE_VALUE' 8 | 9 | 10 | def test_missing_file_error(scope): 11 | """This test covers the OSError, when file does not exist.""" 12 | with pytest.raises(OSError, match='does-not-exist.py'): 13 | include('does-not-exist.py', scope=scope) 14 | 15 | 16 | def test_keys_count(scope, fixture_file): 17 | """Scope must contain all base python attrs and a custom value.""" 18 | include(fixture_file, scope=scope) 19 | 20 | # Keys: 21 | # 'FIXTURE_VALUE', '__file__', '__doc__', 22 | # '__builtins__', '__included_files__' 23 | assert len(scope.keys()) == 5 24 | 25 | 26 | def test_included_file_scope(scope, fixture_file): 27 | """Test emulates gunicorn behavior with `__included_file__` value.""" 28 | base = os.path.dirname(__file__) 29 | saved_file = os.path.join(base, 'basic') 30 | scope['__included_file__'] = saved_file 31 | 32 | include(fixture_file, scope=scope) 33 | 34 | assert _FIXTURE_VALUE in scope 35 | assert scope['__included_file__'] == saved_file 36 | 37 | 38 | def test_empty_included_file(scope, fixture_file): 39 | """Test when there's no `__included_file__`.""" 40 | include(fixture_file, scope=scope) 41 | 42 | assert _FIXTURE_VALUE in scope 43 | assert '__included_file__' not in scope 44 | 45 | 46 | def test_unicode_passed(scope, fixture_file): 47 | """Tests the `unicode` filename in `python2`.""" 48 | include(fixture_file, scope=scope) 49 | assert _FIXTURE_VALUE in scope 50 | 51 | 52 | def test_caller_scope_automatically(fixture_file): 53 | """ 54 | Tests `include` function for automatic `globals()` extraction. 55 | 56 | Now you can omit positional argument `scope`. 57 | """ 58 | include(fixture_file) 59 | 60 | assert _FIXTURE_VALUE in globals() # noqa: WPS421 61 | 62 | 63 | def test_optional_none(fixture_file): 64 | """ 65 | Tests that calling optional on `None` and including the result is fine. 66 | 67 | Previously it used to raise an error. 68 | """ 69 | include(optional(None)) # should not fail 70 | --------------------------------------------------------------------------------