pax_global_header00006660000000000000000000000064146242511470014520gustar00rootroot0000000000000052 comment=cdc987d4b12680fc6469825089d567ec5841f997 validators-0.28.3/000077500000000000000000000000001462425114700137625ustar00rootroot00000000000000validators-0.28.3/.github/000077500000000000000000000000001462425114700153225ustar00rootroot00000000000000validators-0.28.3/.github/workflows/000077500000000000000000000000001462425114700173575ustar00rootroot00000000000000validators-0.28.3/.github/workflows/docs.yaml.bkp000066400000000000000000000025001462425114700217430ustar00rootroot00000000000000# Documentation name: docs on: workflow_dispatch: push: branches: ["master"] jobs: build: runs-on: ubuntu-latest permissions: contents: read env: BUILD_PATH: . PIP_DISABLE_PIP_VERSION_CHECK: 1 steps: # checkout repository - name: Checkout repository uses: actions/checkout@v4 # set up specific python version - name: Set up Python v3.12 uses: actions/setup-python@v5 with: python-version: "3.12" # building - name: Install 'documentation' dependencies run: | pip install . pip install -r package/requirements.mkdocs.txt - name: Build documentation run: python package/export doc # set up Pages - name: Set up Pages uses: actions/configure-pages@v4 # upload static page - name: Upload artifact uses: actions/upload-pages-artifact@v3 with: path: ${{ env.BUILD_PATH }}/site deploy: needs: build runs-on: ubuntu-latest permissions: pages: write id-token: write environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} # deploy documentation name: Deploy steps: - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v4 validators-0.28.3/.github/workflows/package.yaml.bkp000066400000000000000000000027231462425114700224150ustar00rootroot00000000000000# Publish to PyPI name: package on: workflow_dispatch: # uncomment the following lines to enable workflow on package release # release: # types: [published] jobs: build: runs-on: ubuntu-latest permissions: contents: read env: BUILD_PATH: . PIP_DISABLE_PIP_VERSION_CHECK: 1 steps: # checkout repository - name: Checkout repository uses: actions/checkout@v4 # set up specific python version - name: Set up Python v3.8 uses: actions/setup-python@v5 with: python-version: "3.8" # install dependencies - name: Install dependencies run: | python -m venv .venv ./.venv/bin/python -m pip install --upgrade pip ./.venv/bin/pip install . ./.venv/bin/pip install -r package/requirements.sphinx.txt ./.venv/bin/pip install build # build package - name: Build package run: | . ./.venv/bin/activate python package/export pkg deactivate # upload package as artifact - name: Upload artifact uses: actions/upload-pages-artifact@v3 with: path: ${{ env.BUILD_PATH }}/dist publish: needs: build runs-on: ubuntu-latest permissions: id-token: write steps: # publish package - name: Publish to PyPI uses: pypa/gh-action-pypi-publish@release/v1 with: password: ${{ secrets.PYPI_API_TOKEN }} validators-0.28.3/.github/workflows/pycqa.yaml000066400000000000000000000027321462425114700213640ustar00rootroot00000000000000# Python Code Quality Analysis name: pycqa on: workflow_dispatch: push: branches: [master] pull_request: branches: [master] jobs: tooling: runs-on: ubuntu-latest env: PIP_DISABLE_PIP_VERSION_CHECK: 1 steps: # checkout repository - name: Checkout repository uses: actions/checkout@v4 # set up specific python version - name: Set up Python v3.8 uses: actions/setup-python@v5 with: python-version: "3.8" # tooling - name: Install 'tooling' dependencies run: | pip install . pip install -r package/requirements.tooling.txt - name: Tooling run: | black . ruff check . pyright . testing: strategy: fail-fast: true matrix: os: [ubuntu-latest, macos-latest, windows-latest] python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] runs-on: ${{ matrix.os }} steps: # checkout repository again! # ref: https://github.com/actions/checkout/issues/19 - name: Checkout repository uses: actions/checkout@v4 # set up specific python version - name: Set up Python v${{ matrix.python-version }} uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} cache: "pip" # testing - name: Install 'testing' dependencies run: pip install pytest - name: Testing run: pytest . validators-0.28.3/.github/workflows/sast.yaml000066400000000000000000000041421462425114700212160ustar00rootroot00000000000000# Static Application Security Testing name: sast on: workflow_dispatch: push: branches: ["master"] pull_request: branches: ["master"] schedule: - cron: "00 00 * * 0" jobs: sast: permissions: contents: read # for actions/checkout to fetch code security-events: write # for github/codeql-action/upload-sarif to upload SARIF results actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Bandit uses: mdegis/bandit-action@85fcc340c3b0bf5d86029abb49b9aac916d807b2 with: # exit with 0, even with results found # exit_zero: true # optional, default is DEFAULT # Github token of the repository (automatically created by Github) GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information. # File or directory to run bandit on path: ./src/validators # optional, default is . # Report only issues of a given severity level or higher. Can be LOW, MEDIUM or HIGH. Default is UNDEFINED (everything) # level: # optional, default is UNDEFINED # Report only issues of a given confidence level or higher. Can be LOW, MEDIUM or HIGH. Default is UNDEFINED (everything) # confidence: # optional, default is UNDEFINED # comma-separated list of paths (glob patterns supported) to exclude from scan (note that these are in addition to the excluded paths provided in the config file) (default: .svn,CVS,.bzr,.hg,.git,__pycache__,.tox,.eggs,*.egg) excluded_paths: .github,.pytest_cache,.venv,.vscode,site,tests # optional, default is DEFAULT # comma-separated list of test IDs to skip # skips: # optional, default is DEFAULT # path to a .bandit file that supplies command line arguments # ini_path: # optional, default is DEFAULT # https://github.com/marketplace/actions/bandit-scan is ISC licensed, by abirismyname # https://pypi.org/project/bandit/ is Apache v2.0 licensed, by PyCQA validators-0.28.3/.gitignore000066400000000000000000000062211462425114700157530ustar00rootroot00000000000000# Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # C extensions *.so # Distribution / packaging .Python build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ wheels/ share/python-wheels/ *.egg-info/ .installed.cfg *.egg MANIFEST # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .nox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *.cover *.py,cover .hypothesis/ .pytest_cache/ cover/ # Translations *.mo *.pot # Django stuff: *.log local_settings.py db.sqlite3 db.sqlite3-journal # Flask stuff: instance/ .webassets-cache # Scrapy stuff: .scrapy # Sphinx documentation docs/_build/ docs/*.1 # PyBuilder .pybuilder/ target/ # Jupyter Notebook .ipynb_checkpoints # IPython profile_default/ ipython_config.py # pyenv # For a library or package, you might want to ignore these files since the code is # intended to run in multiple environments; otherwise, check them in: # .python-version # pipenv # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. # However, in case of collaboration, if having platform-specific dependencies or dependencies # having no cross-platform support, pipenv may install dependencies that don't work, or not # install all needed dependencies. #Pipfile.lock # poetry # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. # This is especially recommended for binary packages to ensure reproducibility, and is more # commonly ignored for libraries. # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control #poetry.lock # pdm # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. #pdm.lock # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it # in version control. # https://pdm.fming.dev/#use-with-ide .pdm.toml .pdm-python .pdm-build/ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm __pypackages__/ # Celery stuff celerybeat-schedule celerybeat.pid # SageMath parsed files *.sage.py # Environments .env .venv env/ venv/ ENV/ env.bak/ venv.bak/ .venv.dev/ # Spyder project settings .spyderproject .spyproject # Rope project settings .ropeproject # mkdocs documentation site/ # mypy .mypy_cache/ .dmypy.json dmypy.json # Pyre type checker .pyre/ # pytype static type analyzer .pytype/ # Cython debug symbols cython_debug/ # PyCharm # JetBrains specific template is maintained in a separate JetBrains.gitignore that can # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore # and can be added to the global gitignore or merged into this file. For a more nuclear # option (not recommended) you can uncomment the following to ignore the entire idea folder. #.idea/ # VSCode .vscode/ # asdf .tool-versions # rtx/mise .rtx.toml .mise.toml # ruff .ruff_cache validators-0.28.3/CHANGES.md000066400000000000000000000555151462425114700153670ustar00rootroot00000000000000# Changelog ## 0.28.3 (2024-05-25) _**Breaking**_ > No breaking changes were introduced in this version. _**Features**_ > No features were introduced in this version. _**Maintenance**_ - hotfix: ensure `_tld.txt` is in `sdist` and `bdist` by @yozachar in [#379](https://github.com/python-validators/validators/pull/379) **Full Changelog**: [`0.28.2...0.28.3`](https://github.com/python-validators/validators/compare/0.28.2...0.28.3) ## 0.28.2 (2024-05-24) _**Breaking**_ > No breaking changes were introduced in this version. _**Features**_ > No features were introduced in this version. _**Maintenance**_ - fix: corrects a few typo by @yozachar in [#371](https://github.com/python-validators/validators/pull/371) - build(deps): bump jinja2 from 3.1.3 to 3.1.4 in /package by @dependabot in [#372](https://github.com/python-validators/validators/pull/372) - fix(ip_address): properly handle private is false by @grleblanc in [#374](https://github.com/python-validators/validators/pull/374) - chore(url): allow symbols and pictographs in url by @prousso in [#375](https://github.com/python-validators/validators/pull/375) - build(deps): bump requests from 2.31.0 to 2.32.0 in /package by @dependabot in [#376](https://github.com/python-validators/validators/pull/376) - chore: fix typo; update dev deps; bump version by @yozachar in [#377](https://github.com/python-validators/validators/pull/377) **Full Changelog**: [`0.28.1...0.28.2`](https://github.com/python-validators/validators/compare/0.28.1...0.28.2) ## 0.28.1 (2024-04-19) _**Breaking**_ > No breaking changes were introduced in this version. _**Features**_ > No features were introduced in this version. _**Maintenance**_ - fix: reduce memory footprint when loading TLDs by @yozachar in [#362](https://github.com/python-validators/validators/pull/362) - build(deps): bump idna from 3.6 to 3.7 in /package by @dependabot in [#365](https://github.com/python-validators/validators/pull/365) - fix: rfc cases in the `domain` validator by @yozachar in [#367](https://github.com/python-validators/validators/pull/367) - chore: documentation maintenance by @yozachar in [#368](https://github.com/python-validators/validators/pull/368) - chore: update contribution guidelines by @yozachar in [#369](https://github.com/python-validators/validators/pull/369) - chore: updated dev dependencies; bump version by @yozachar in [#370](https://github.com/python-validators/validators/pull/370) **Full Changelog**: [`0.28.0...0.28.1`](https://github.com/python-validators/validators/compare/0.28.0...0.28.1) ## 0.28.0 (2024-04-04) _**Breaking**_ ⚠️ - patch: moves `country_code` module to `country` module by @yozachar in [#357](https://github.com/python-validators/validators/pull/357) _**Features**_ - feat: adds indian aadhar and pan validator by @yozachar in [#358](https://github.com/python-validators/validators/pull/358) - feat: adds `finance` validator by @yozachar in [#359](https://github.com/python-validators/validators/pull/359) - feat: adds `consider_tld` parameter to `domain`, `hostname` and `url` modules by @yozachar in [#360](https://github.com/python-validators/validators/pull/360) _**Maintenance**_ - maint: updated dev dependencies, doc links; bump version by @yozachar in [#361](https://github.com/python-validators/validators/pull/361) **Full Changelog**: [`0.27.0...0.28.0`](https://github.com/python-validators/validators/compare/0.27.0...0.28.0) --- ## 0.27.0 (2024-04-03) _**Breaking**_ ⚠️ - patch: moves `base58` and `base64` into `encoding` by @yozachar in [#354](https://github.com/python-validators/validators/pull/354) _**Features**_ - feat: lays foundation for URI validation by @yozachar in [#353](https://github.com/python-validators/validators/pull/353) - feat: adds `private` parameter to `ip_address`, `hostname` & `url` by @yozachar in [#356](https://github.com/python-validators/validators/pull/356) _**Maintenance**_ - patch: adds `encoding` tests and docs by @yozachar in [#355](https://github.com/python-validators/validators/pull/355) **Full Changelog**: [`0.26.0...0.27.0`](https://github.com/python-validators/validators/compare/0.26.0...0.27.0) --- ## 0.26.0 (2024-04-02) _**Breaking**_ > No breaking changes were introduced in this version. _**Features**_ - feat: adds `base58` and `base64` validators by @yozachar in [#351](https://github.com/python-validators/validators/pull/351) _**Maintenance**_ - fix: regex ignore-case uses only `a-z` by @yozachar in [#349](https://github.com/python-validators/validators/pull/349) - patch: supported extended latin in username by @yozachar in [#350](https://github.com/python-validators/validators/pull/350) **Full Changelog**: [`0.25.0...0.26.0`](https://github.com/python-validators/validators/compare/0.25.0...0.26.0) --- ## 0.25.0 (2024-04-02) _**Breaking**_ > No breaking changes were introduced in this version. _**Features**_ - feat: adds basic `cron` validator by @yozachar in [#348](https://github.com/python-validators/validators/pull/348) _**Maintenance**_ - maint: adds quick start docs by @yozachar in [#344](https://github.com/python-validators/validators/pull/344) - fix: `domain` validation is now more consistent across rfcs by @yozachar in [#347](https://github.com/python-validators/validators/pull/347) **Full Changelog**: [`0.24.2...0.25.0`](https://github.com/python-validators/validators/compare/0.24.2...0.25.0) --- ## 0.24.0 (2024-03-24) _**Breaking**_ > No breaking changes were introduced in this version. _**Features**_ - feat: conditionally raises `ValidationError`; bump version by @yozachar in [#343](https://github.com/python-validators/validators/pull/343) _**Maintenance**_ - patch: `domain` & `url` modules by @yozachar in [#339](https://github.com/python-validators/validators/pull/339) - fix: domain name not confirming to rfc_2782 by @yozachar in [#341](https://github.com/python-validators/validators/pull/341) - maint: update dev dependencies; adds favicon to docs by @yozachar in [#342](https://github.com/python-validators/validators/pull/342) **Full Changelog**: [`0.23.2...0.24.0`](https://github.com/python-validators/validators/compare/0.23.2...0.24.0) --- ## 0.23.2 (2024-03-20) _**Breaking**_ > No breaking changes were introduced in this version. _**Features**_ > No features were introduced in this version. _**Maintenance**_ - maint: rectifies changelog by @yozachar in [#336](ttps://github.com/python-validators/validators/pull/336) - fix: packaging as well as `rST` & `md` document generation by @yozachar in [#337](ttps://github.com/python-validators/validators/pull/337) **Full Changelog**: [`0.23.1...0.23.2`](https://github.com/python-validators/validators/compare/0.23.1...0.23.2) ## 0.23.1 (2024-03-19) _**Breaking**_ > No breaking changes were introduced in this version. _**Features**_ > No features were introduced in this version. _**Maintenance**_ - maint: fix `between` & `length` validators by @yozachar in [#334](https://github.com/python-validators/validators/pull/334) - fix: manual nav reference for mkdocs; bumps version by @yozachar in [#335](https://github.com/python-validators/validators/pull/335) **Full Changelog**: [`0.23.0...0.23.1`](https://github.com/python-validators/validators/compare/0.23.0...0.23.1) ## 0.23.0 (2024-03-19) _**Breaking**_ > No breaking changes were introduced in this version. _**Features**_ - feat: add french i18n validation by @imperosol in [#308](https://github.com/python-validators/validators/pull/308) _**Maintenance**_ - fix: Valid URLs failing validation - query and fragment parts by @danherbriley in [#297](https://github.com/python-validators/validators/pull/297) - fix: bug in `between` module by @yozachar in [#301](https://github.com/python-validators/validators/pull/301) - chore: update dependencies, improve packaging by @yozachar in [#304](https://github.com/python-validators/validators/pull/304) - Fix fragment check by @darkdragon-001 in [#305](https://github.com/python-validators/validators/pull/305) - build(deps): bump urllib3 from 2.0.6 to 2.0.7 in /package by @dependabot in [#310](https://github.com/python-validators/validators/pull/310) - fix: allow pct-encoded entities in fragments by @conitrade-as in [#317](https://github.com/python-validators/validators/pull/317) - chore: update dev dependencies by @yozachar in [#318](https://github.com/python-validators/validators/pull/318) - build(deps): bump gitpython from 3.1.37 to 3.1.41 in /package by @dependabot in [#321](https://github.com/python-validators/validators/pull/321) - build(deps): bump jinja2 from 3.1.2 to 3.1.3 in /package by @dependabot in [#322](https://github.com/python-validators/validators/pull/322) - chore: monthly updates for Jan'24 by @yozachar in [#324](https://github.com/python-validators/validators/pull/324) - maint: adds versiond docs; update copyright year by @yozachar in [#329](https://github.com/python-validators/validators/pull/329) - chore: update dev dependencies by @yozachar in [#330](https://github.com/python-validators/validators/pull/330) - build(deps): bump gitpython from 3.1.37 to 3.1.41 in /package by @dependabot in [#331](https://github.com/python-validators/validators/pull/331) - build(deps): bump jinja2 from 3.1.2 to 3.1.3 in /package by @dependabot in [#332](https://github.com/python-validators/validators/pull/332) - build(deps): bump urllib3 from 2.0.6 to 2.0.7 in /package by @dependabot in [#319](https://github.com/python-validators/validators/pull/319) **Full Changelog**: [`0.22.0...0.23.0`](https://github.com/python-validators/validators/compare/0.22.0...0.23.0) --- ## 0.22.0 (2023-09-02) _**Breaking**_ ⚠️ - A new keyword parameter `host_bit = True`, is added to `validators.ipv4` and `validators.ipv6`. _**Features**_ > No features were introduced in this version. _**Maintenance**_ - fix: url validator considers urls with /#/ as valid by @adrienthiery in [#289](https://github.com/python-validators/validators/pull/289) - Add note about ValidationFailure to ValidationError in changes.md by @tswfi in [#291](https://github.com/python-validators/validators/pull/291) - fix: simple hostname validation regex by @yozachar in [#294](https://github.com/python-validators/validators/pull/294) - fix: strict CIDR IP validation; bump version by @yozachar in [#295](https://github.com/python-validators/validators/pull/295) **Full Changelog**: [`0.21.2...0.22.0`](https://github.com/python-validators/validators/compare/0.21.2...0.22.0) --- ## 0.21.2 (2023-08-07) _**Breaking**_ ⚠️ - `ValidationFailure` is renamed to `ValidationError` in [`yozachar@12ae1f5`](https://github.com/yozachar/pyvalidators/commit/12ae1f5850555d11e1f1a2c03f597fd10610215a) _**Features**_ - Added Country Code Validation by @aviiciii in [#280](https://github.com/python-validators/validators/pull/280) - add validator ETH addresses (ERC20) by @msamsami in [#276](https://github.com/python-validators/validators/pull/276) _**Maintenance**_ - feat: refactoring; updates; fixes; bump version by @yozachar in [#283](https://github.com/python-validators/validators/pull/283)(ref: ) - build(deps): bump pymdown-extensions from 9.11 to 10.0 by @dependabot in [#273](https://github.com/python-validators/validators/pull/273) - build(deps): bump requests from 2.28.2 to 2.31.0 by @dependabot in [#275](https://github.com/python-validators/validators/pull/275) - build(deps-dev): bump certifi from 2022.12.7 to 2023.7.22 by @dependabot in [#281](https://github.com/python-validators/validators/pull/281) **Full Changelog**: [`0.21.1...0.21.2`](https://github.com/python-validators/validators/compare/0.21.1...0.21.2) ## 0.21.1 (2023-04-10) _**Breaking**_ > No breaking changes were introduced in this version. _**Features**_ > No features were introduced in this version. _**Maintenance**_ - fix: `source .venv/bin/activate` before build by @yozachar in [#260](https://github.com/python-validators/validators/pull/260) - fix: id-token write permission at job level by @yozachar in [#261](https://github.com/python-validators/validators/pull/261) - feat: docs can be built with both sphinx & mkdocs by @yozachar in [#262](https://github.com/python-validators/validators/pull/262) - fix: improves build process by @yozachar in [#263](https://github.com/python-validators/validators/pull/263) - fix: removes 64-char limit for url path & query by @yozachar in [#264](https://github.com/python-validators/validators/pull/264) **Full Changelog**: [`0.21.0...0.21.1`](https://github.com/python-validators/validators/compare/0.21.0...0.21.1) ## 0.21.0 (2023-03-25) _**Breaking**_ ⚠️ - Drops support for all Python versions below `v3.8`. - Makes API's primary parameter, `positional`, and the remaining, `keyword-only`. - Keyword-only parameters like `max` and `min`, has been renamed to `max_val` and `min_val` respectively. - `domain` API now accepts two new keyword-only arguments: `rfc_1034: bool = False` and `rfc_2782: bool = False`. - `extremes.py` renamed to `_extremes.py` and is no longer exposed. - `truthy` was discarded in favour of simple `bool()` function. - `ipv4_cidr()` and `ipv6_cidr()` has been dropped in favour of `cidr: bool = True` and `cidr: bool = True` keyword-only parameters. - `email()` API now accepts the following keyword-only arguments: - `simple_host: bool = False`, - `ipv6_address: bool = False`, - `ipv4_address: bool = False`, - `rfc_1034: bool = False` and - `rfc_2782: bool = False`. - `whitelist=None` has been removed from `email()`. - `url()` has been refactored, it accepts the following keyword-only arguments: - `skip_ipv6_addr: bool = False`, - `skip_ipv4_addr: bool = False`, - `may_have_port: bool = True`, - `simple_host: bool = False`, - `rfc_1034: bool = False` and - `rfc_2782: bool = False`. - `public=False` keyword argument has been removed from `url()`. - Exposes `i18n` functions directly via `__init__.py`. - `@validator` decorator catches `Exception`. _**Features**_ - Adds `hostname` validator. _**Maintenance**_ - feat: add build for pypi workflow by @yozachar in [#255](https://github.com/python-validators/validators/pull/255) - feat: @validator now catches `Exception` by @yozachar in [#254](https://github.com/python-validators/validators/pull/254) - maint: improves `i18n` package by @yozachar in [#252](https://github.com/python-validators/validators/pull/252) - maint: misc changes to dev and ci by @yozachar in [#251](https://github.com/python-validators/validators/pull/251) - maint: misc fixes and improvements by @yozachar in [#249](https://github.com/python-validators/validators/pull/249) - maint: improves state of package development by @yozachar in [#248](https://github.com/python-validators/validators/pull/248) - fix: generate dynamic reference docs by @yozachar in [#247](https://github.com/python-validators/validators/pull/247) - maint: moving docs from `.rst` to `.md` by @yozachar in [#246](https://github.com/python-validators/validators/pull/246) - maint: improves `url` module by @yozachar in [#245](https://github.com/python-validators/validators/pull/245) - maint: improve `domain`, `email` & `hostname` by @yozachar in [#244](https://github.com/python-validators/validators/pull/244) - maint: simplified `hostname` module by @yozachar in [#242](https://github.com/python-validators/validators/pull/242) - maint: update `email` module by @yozachar in [#241](https://github.com/python-validators/validators/pull/241) - feat: adds `hostname` validator by @yozachar in [#240](https://github.com/python-validators/validators/pull/240) - maint: improves `ip_address` module by @yozachar in [#239](https://github.com/python-validators/validators/pull/239) - fix: misc fixes, use bandit by @yozachar in [#238](https://github.com/python-validators/validators/pull/238) - Create SECURITY.md by @yozachar in [#237](https://github.com/python-validators/validators/pull/237) - maint: improves `mac_address`, `slug` and `uuid` by @yozachar in [#236](https://github.com/python-validators/validators/pull/236) - maint: improve `hashes` and `iban` modules by @yozachar in [#235](https://github.com/python-validators/validators/pull/235) - feat: auto docs using mkdocstrings by @yozachar in [#234](https://github.com/python-validators/validators/pull/234) - maint: improves `email` module by @yozachar in [#233](https://github.com/python-validators/validators/pull/233) - maint: minor improvements by @yozachar in [#232](https://github.com/python-validators/validators/pull/232) - maint: improves `domain` module by @yozachar in [#231](https://github.com/python-validators/validators/pull/231) - maint: reformats `card` module, fix typo by @yozachar in [#230](https://github.com/python-validators/validators/pull/230) - feat: formats google pydoc style for mkdocstring by @yozachar in [#229](https://github.com/python-validators/validators/pull/229) - maint: refresh `btc_address` module by @yozachar in [#228](https://github.com/python-validators/validators/pull/228) - maint: improve type annotations by @yozachar in [#227](https://github.com/python-validators/validators/pull/227) - maint: improves `between` and `length` modules by @yozachar in [#225](https://github.com/python-validators/validators/pull/225) - maint: follows google's python style guide for docstrings by @yozachar in [#224](https://github.com/python-validators/validators/pull/224) - feat: type hints in utils.py, gh-actions by @yozachar in [#223](https://github.com/python-validators/validators/pull/223) - feat: add pyproject.toml, README.md, upd gitignore by @yozachar in [#221](https://github.com/python-validators/validators/pull/221) - remove Travis CI settings by @ktdreyer in [#196](https://github.com/python-validators/validators/pull/196) **Full Changelog**: [`0.20.0...0.21.0`](https://github.com/python-validators/validators/compare/0.20.0...0.21.0) --- ## 0.20.0 (2022-06-05) - Added ipv4 digit lenghts validation (#191, pull request courtesy of Norbiox) - Fixes error with international URLs that have more than 2 hyphens (#184, pull request courtesy of automationator) ## 0.19.0 (2022-05-04) - Dropped py34 support - Improve IPv6 validation (#201, pull request courtesy of SimonIT) ## 0.18.2 (2020-12-18) - Implement actual validation for old style BTC addresses including checksumming (#182, pull request courtesy of tpatja) - Use a regex to guesstimate validity of new segwit BTC addresses (#182, pull request courtesy of tpatja) ## 0.18.1 (2020-09-03) - Made uuid validator accept UUID objects (#174, pull request courtesy of Letsch22) ## 0.18.0 (2020-08-19) - Added bitcoin address validator (#166, pull request courtesy of daveusa31) ## 0.17.1 (2020-08-03) - Fixed python_requires using twine ## 0.17.0 (2020-08-02) - Added python_requires='>=3.4' to setup.py (#163, pull request courtesy of vphilippon) - Fixed URL validator ip_last_octet regex (#145, pull request courtesy of ghost) ## 0.16.0 (2020-07-16) - Added support for emojis and more IDNA URLs (#161, pull request courtesy of automationator) ## 0.15.0 (2020-05-07) - Added bank card validators (#157, pull request courtesy of TimonPeng) ## 0.14.3 (2020-04-02) - Handle None values gracefully in domain validator (#144, pull request courtesy reahaas) - Local part of the email address should be less or equal than 64 bytes (#147, pull request courtesy mondeja) - Removed py27 support - Removed pypy2 support ## 0.14.2 (2020-01-24) - Made domain validation case-insensitive (#136, pull request courtesy ehmkah) ## 0.14.1 (2019-12-04) - Updated domain validator regex to not allow numeric only TLDs (#133, pull request courtesy jmeridth) - Allow for idna encoded domains (#133, pull request courtesy jmeridth) ## 0.14.0 (2019-08-21) - Added new validators `ipv4_cidr`, `ipv6_cidr` (#117, pull request courtesy woodruffw) ## 0.13.0 (2019-05-20) - Added new validator: `es_doi`, `es_nif`, `es_cif`, `es_nie` (#121, pull request courtesy kingbuzzman) ## 0.12.6 (2019-05-08) - Fixed domain validator for single character domains (#118, pull request courtesy kingbuzzman) ## 0.12.5 (2019-04-15) - Fixed py37 support (#113, pull request courtesy agiletechnologist) ## 0.12.4 (2019-01-02) - Use inspect.getfullargspec() in py3 (#110, pull request courtesy riconnon) ## 0.12.3 (2018-11-13) - Added `allow_temporal_ssn` parameter to fi_ssn validator (#97, pull request courtesy quantus) - Remove py33 support ## 0.12.2 (2018-06-03) - Fixed IPv4 formatted IP address returning True on ipv6 (#85, pull request courtesy johndlong) - Fixed IPv6 address parsing (#83, pull request courtesy JulianKahnert) - Fixed domain validator for international domains and certain edge cases (#76, pull request courtesy Ni-Knight) ## 0.12.1 (2018-01-30) - Fixed IDNA encoded TLDs in domain validator (#75, pull request courtesy piewpiew) - Fixed URL validator for URLs with invalid characters in userinfo part (#69, pull request courtesy timb07) ## 0.12.0 (2017-06-03) - Added hash validators for md5, sha1, sha224, sha256 and sha512 - Made ipv6 validator support IPv4-mapped IPv6 addresses ## 0.11.3 (2017-03-27) - Fixed URL validator for URLs containing localhost (#51, pull request courtesy vladimirdotk) ## 0.11.2 (2017-01-08) - Fixed URL validator for urls with query parameters but without path (#44, pull request courtesy zjjw) ## 0.11.1 (2016-11-19) - Fixed pyp2rpm build problem (#37, pull request courtesy BOPOHA) ## 0.11.0 (2016-08-30) - Fixed public url validation (#29) - Made URL validator case insensitive (#27) - Drop Python 2.6 support ## 0.10.3 (2016-06-13) - Added `public` parameter to url validator (#26, pull request courtesy Iconceicao) ## 0.10.2 (2016-06-11) - Fixed various URL validation issues ## 0.10.1 (2016-04-09) - Fixed domain name validation for numeric domain names (#21, pull request courtesy shaunpud) - Fixed IBAN validation for Norwegian and Belgian IBANs (#17, pull request courtesy mboelens91) ## 0.10.0 (2016-01-09) - Added support for internationalized domain names (IDN) in `domain` validator ## 0.9.0 (2015-10-10) - Added new validator: `domain` - Added flake8 and isort checks in travis config ## 0.8.0 (2015-06-24) - Added new validator: `iban` ## 0.7.0 (2014-09-07) - Fixed errors in code examples. - Fixed `TypeError` when using `between` validator with `datetime` objects like in the code example. - Changed validators to always return `True` instead of a truthy object when the validation succeeds. - Fixed `truthy` validator to work like it's name suggests. Previously it worked like `falsy`. ## 0.6.0 (2014-06-25) - Added new validator: `slug` ## 0.5.0 (2013-10-31) - Renamed `finnish_business_id` to `fi_business_id` - Added new validator: `fi_ssn` ## 0.4.0 (2013-10-29) - Added new validator: `finnish_business_id` ## 0.3.0 (2013-10-27) - `number_range` -> `between` ## 0.2.0 (2013-10-22) - Various new validators: `ipv4`, `ipv6`, `length`, `number_range`, `mac_address`, `url`, `uuid` ## 0.1.0 (2013-10-18) - Initial public release validators-0.28.3/CONTRIBUTING.md000066400000000000000000000101311462425114700162070ustar00rootroot00000000000000# How to contribute to `validators` Hi, to start, you need the following installed on your system. 1. [Git](https://git-scm.com) 2. [Python](https://www.python.org) v3.8 or later 3. [PDM](https://pdm-project.org) for easy dependency management 4. (Optional/Recommended) NodeJS for type checking 5. (Optional/Recommended) [mise](https://github.com/jdx/mise) to manage multiple versions of Python & NodeJS. First [fork this repository](https://github.com/python-validators/validators/fork). Uncheck "fork only `master`", because for versioned docs you'll need `gh-pages` too. Clone it to your system. Install development dependencies. ```sh # clone repository $ git clone "https://github.com/YOUR-USERNAME/validators.git" # change directory $ cd validators # install development dependencies $ pdm install ``` Activate the virtual environment and run `tox` to verify test cases. ```sh # activate virtual environment $ . ./.venv/bin/activate # replace `/bin/` with `/Scripts/` if you're on Windows. # run tox for linting, type checking, formatting etc. $ tox ``` Create a git branch and make changes to the source code. If needed, test your changes by running `pytest`. Execute `tox` to format, lint and type-check your code before committing. Commit, push and create a pull request. If you're in doubt, feel free to start a discussion [here](https://github.com/python-validators/validators/discussions). ## Documentation > Documentation is extracted from the source code. Please follow [Google's Python Doc Style](https://google.github.io/styleguide/pyguide.html). If you're adding/removing a module, you must update the `nav` key in `mkdocs.yml`. Then export documentation as follows: ```sh $ . ./.venv/bin/activate # generate documentation $ python package/export TYPE # where TYPE is any of `doc`, `man` or `web`. # doc - generates docs found here: https://yozachar.github.io/pyvalidators # man - generates sphinx based manpages # web - generates sphinx based web docs ``` You can preview the generated documentation: ```sh $ . ./.venv/bin/activate # To preview mkdocs $ mkdocs serve # To preview man pages $ man docs/_build/man/validators.1 # To preview sphinx webpages $ python -m http.server -d docs/_build/web ``` ## Versioning, Packaging & Releasing (for collaborators) > You must be familiar with [semantic versioning](https://semver.org) and [Python packaging](https://packaging.python.org). 1. Take a look at the [`CHANGES.md`](CHANGES.md). They are generated with [GitHub's releaser](https://github.com/python-validators/validators/releases/new), and then modified. 2. Update the changelog. Version number must be updated in both [`SECURITY.md`](SECURITY.md) and [`src/validators/__init__.py`](src/validators/__init__.py). 3. The final merge commit on the upstream (i.e. this repo) is tagged. ```sh # syncing with upstream $ git pull upstream master $ git push # tagging that final merge commit before release $ GIT_COMMITTER_DATE=$(git log -n1 --pretty=%aD) git tag -a -m "vMAJOR.MINOR.PATCH" vMAJOR.MINOR.PATCH # pushing tag to remote $ git push --tag $ git push upstream --tag ``` 4. To prevew versioned docs, run `mike serve` (`mike` is already a dev dependency). 5. To update it, checkout to the tag you want to include in the versioned documentation `git checkout TAG_NAME`. 6. Then run `mike deploy -p -u VERSION stable` OR run `mike deploy -p -u dev master`, 7. Which will deploy docs in the CURRENT commit as the `latest` documentation, onto `gh-pages` branch. 8. Run `./package/roll.sh` (or `./package/roll.ps1`) to generate both `sdist` and `bdist`. 9. Install [`twine`](https://pypi.org/project/twine) using [`pipx`](https://pipx.pypa.io) to upload package to PyPI. ```sh # publishing $ twine check dist/* $ twine upload dist/* ``` 10. Create a GitHub release with the contents from the [changelog](CHANGES.md). Upload the wheel from `dist/` along with the shasum file generated with: ```sh # generate sha256sum $ sha256sum dist/validators-VERSION-py3-none-any.whl > dist/validators-VERSION-py3-none-any.whl.sha256 ``` Thanks for taking interest in this library! validators-0.28.3/LICENSE.txt000066400000000000000000000021031462425114700156010ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) 2013 - 2024 Konsta Vesterinen Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. validators-0.28.3/MANIFEST.in000066400000000000000000000006371462425114700155260ustar00rootroot00000000000000# MANIFEST.in stays as long as pyproject.toml does not officially support it # https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ # include include CHANGES.md include mkdocs.yaml # global-include # recursive-include recursive-include tests * recursive-include docs * # graft # exclude # global-exclude # recursive-exclude # prune prune docs/_build prune **/__pycache__ validators-0.28.3/README.md000066400000000000000000000044051462425114700152440ustar00rootroot00000000000000# validators - Python Data Validation for Humans™ [![PyCQA][pycqa-badge]][pycqa-link] [![SAST][sast-badge]][sast-link] [![Docs][docs-badge]][docs-link] [![Version][vs-badge]][vs-link] [![Downloads][dw-badge]][dw-link] Python has all kinds of data validation tools, but every one of them seems to require defining a schema or form. I wanted to create a simple validation library where validating a simple value does not require defining a form or a schema. ```python >>> import validators >>> >>> validators.email('someone@example.com') True ``` ## Resources - [Documentation](https://yozachar.github.io/pyvalidators) - [Bugtracker](https://github.com/python-validators/validators/issues) - [Security](https://github.com/python-validators/validators/blob/master/SECURITY.md) - [Code](https://github.com/python-validators/validators/) [sast-badge]: https://github.com/python-validators/validators/actions/workflows/sast.yaml/badge.svg [sast-link]: https://github.com/python-validators/validators/actions/workflows/sast.yaml [pycqa-badge]: https://github.com/python-validators/validators/actions/workflows/pycqa.yaml/badge.svg [pycqa-link]: https://github.com/python-validators/validators/actions/workflows/pycqa.yaml [docs-badge]: https://github.com/yozachar/pyvalidators/actions/workflows/pages/pages-build-deployment/badge.svg [docs-link]: https://github.com/yozachar/pyvalidators/actions/workflows/pages/pages-build-deployment [vs-badge]: https://img.shields.io/pypi/v/validators?logo=pypi&logoColor=white&label=version&color=blue [vs-link]: https://pypi.python.org/pypi/validators/ [dw-badge]: https://img.shields.io/pypi/dm/validators?logo=pypi&logoColor=white&color=blue [dw-link]: https://pypi.python.org/pypi/validators/ validators-0.28.3/SECURITY.md000066400000000000000000000013421462425114700155530ustar00rootroot00000000000000# Security Policy ## Supported Versions | Version | Supported | | ---------- | ------------------ | | `>=0.28.3` | :white_check_mark: | ## Reporting a Vulnerability Please read [CVD](https://resources.sei.cmu.edu/asset_files/SpecialReport/2017_003_001_503340.pdf) before reporting vulnerabilities. - We do our best to write safe code. - [@kvesteri](https://github.com/kvesteri) is the author of `validators`. - You can raise security concerns [here](https://github.com/python-validators/validators/discussions/categories/security). - None of us can promise any response time-frame, but we'll try. That said, use the package at your own risk. The source code is open, we encourage you to read. _Spammers will be banned._ validators-0.28.3/docs/000077500000000000000000000000001462425114700147125ustar00rootroot00000000000000validators-0.28.3/docs/Makefile000066400000000000000000000011721462425114700163530ustar00rootroot00000000000000# Minimal makefile for Sphinx documentation # # You can set these variables from the command line, and also # from the environment for the first two. SPHINXOPTS ?= SPHINXBUILD ?= sphinx-build SOURCEDIR = . BUILDDIR = _build # Put it first so that "make" without argument is like "make help". help: @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) .PHONY: help Makefile # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) validators-0.28.3/docs/api/000077500000000000000000000000001462425114700154635ustar00rootroot00000000000000validators-0.28.3/docs/api/between.md000066400000000000000000000000521462425114700174330ustar00rootroot00000000000000# between ::: validators.between.between validators-0.28.3/docs/api/between.rst000066400000000000000000000001121462425114700176400ustar00rootroot00000000000000between ------- .. module:: validators.between .. autofunction:: between validators-0.28.3/docs/api/btc_address.md000066400000000000000000000000661462425114700202640ustar00rootroot00000000000000# btc_address ::: validators.btc_address.btc_address validators-0.28.3/docs/api/btc_address.rst000066400000000000000000000001321462425114700204660ustar00rootroot00000000000000btc_address ----------- .. module:: validators.btc_address .. autofunction:: btc_address validators-0.28.3/docs/api/card.md000066400000000000000000000003461462425114700167210ustar00rootroot00000000000000# card ::: validators.card.amex ::: validators.card.card_number ::: validators.card.diners ::: validators.card.discover ::: validators.card.jcb ::: validators.card.mastercard ::: validators.card.unionpay ::: validators.card.visa validators-0.28.3/docs/api/card.rst000066400000000000000000000003651462425114700171320ustar00rootroot00000000000000card ---- .. module:: validators.card .. autofunction:: amex .. autofunction:: card_number .. autofunction:: diners .. autofunction:: discover .. autofunction:: jcb .. autofunction:: mastercard .. autofunction:: unionpay .. autofunction:: visa validators-0.28.3/docs/api/country.md000066400000000000000000000001631462425114700175100ustar00rootroot00000000000000# country ::: validators.country.calling_code ::: validators.country.country_code ::: validators.country.currency validators-0.28.3/docs/api/country.rst000066400000000000000000000002111462425114700177120ustar00rootroot00000000000000country ------- .. module:: validators.country .. autofunction:: calling_code .. autofunction:: country_code .. autofunction:: currency validators-0.28.3/docs/api/cron.md000066400000000000000000000000411462425114700167410ustar00rootroot00000000000000# cron ::: validators.cron.cron validators-0.28.3/docs/api/cron.rst000066400000000000000000000000761462425114700171610ustar00rootroot00000000000000cron ---- .. module:: validators.cron .. autofunction:: cron validators-0.28.3/docs/api/domain.md000066400000000000000000000000471462425114700172550ustar00rootroot00000000000000# domain ::: validators.domain.domain validators-0.28.3/docs/api/domain.rst000066400000000000000000000001061462425114700174610ustar00rootroot00000000000000domain ------ .. module:: validators.domain .. autofunction:: domain validators-0.28.3/docs/api/email.md000066400000000000000000000000441462425114700170720ustar00rootroot00000000000000# email ::: validators.email.email validators-0.28.3/docs/api/email.rst000066400000000000000000000001021462425114700172750ustar00rootroot00000000000000email ----- .. module:: validators.email .. autofunction:: email validators-0.28.3/docs/api/encoding.md000066400000000000000000000001121462425114700175650ustar00rootroot00000000000000# encoding ::: validators.encoding.base58 ::: validators.encoding.base64 validators-0.28.3/docs/api/encoding.rst000066400000000000000000000001451462425114700200030ustar00rootroot00000000000000encoding -------- .. module:: validators.encoding .. autofunction:: base58 .. autofunction:: base64 validators-0.28.3/docs/api/finance.md000066400000000000000000000001411462425114700174040ustar00rootroot00000000000000# finance ::: validators.finance.cusip ::: validators.finance.isin ::: validators.finance.sedol validators-0.28.3/docs/api/finance.rst000066400000000000000000000001671462425114700176240ustar00rootroot00000000000000finance ------- .. module:: validators.finance .. autofunction:: cusip .. autofunction:: isin .. autofunction:: sedol validators-0.28.3/docs/api/hashes.md000066400000000000000000000002261462425114700172600ustar00rootroot00000000000000# hashes ::: validators.hashes.md5 ::: validators.hashes.sha1 ::: validators.hashes.sha224 ::: validators.hashes.sha256 ::: validators.hashes.sha512 validators-0.28.3/docs/api/hashes.rst000066400000000000000000000002451462425114700174710ustar00rootroot00000000000000hashes ------ .. module:: validators.hashes .. autofunction:: md5 .. autofunction:: sha1 .. autofunction:: sha224 .. autofunction:: sha256 .. autofunction:: sha512 validators-0.28.3/docs/api/hostname.md000066400000000000000000000000551462425114700176230ustar00rootroot00000000000000# hostname ::: validators.hostname.hostname validators-0.28.3/docs/api/hostname.rst000066400000000000000000000001161462425114700200310ustar00rootroot00000000000000hostname -------- .. module:: validators.hostname .. autofunction:: hostname validators-0.28.3/docs/api/i18n.md000066400000000000000000000004521462425114700165650ustar00rootroot00000000000000# i18n ::: validators.i18n.es_cif ::: validators.i18n.es_doi ::: validators.i18n.es_nie ::: validators.i18n.es_nif ::: validators.i18n.fi_business_id ::: validators.i18n.fi_ssn ::: validators.i18n.fr_department ::: validators.i18n.fr_ssn ::: validators.i18n.ind_aadhar ::: validators.i18n.ind_pan validators-0.28.3/docs/api/i18n.rst000066400000000000000000000004651462425114700170010ustar00rootroot00000000000000i18n ---- .. module:: validators.i18n .. autofunction:: es_cif .. autofunction:: es_doi .. autofunction:: es_nie .. autofunction:: es_nif .. autofunction:: fi_business_id .. autofunction:: fi_ssn .. autofunction:: fr_department .. autofunction:: fr_ssn .. autofunction:: ind_aadhar .. autofunction:: ind_pan validators-0.28.3/docs/api/iban.md000066400000000000000000000000411462425114700167110ustar00rootroot00000000000000# iban ::: validators.iban.iban validators-0.28.3/docs/api/iban.rst000066400000000000000000000000761462425114700171310ustar00rootroot00000000000000iban ---- .. module:: validators.iban .. autofunction:: iban validators-0.28.3/docs/api/ip_address.md000066400000000000000000000001141462425114700201160ustar00rootroot00000000000000# ip_address ::: validators.ip_address.ipv4 ::: validators.ip_address.ipv6 validators-0.28.3/docs/api/ip_address.rst000066400000000000000000000001471462425114700203340ustar00rootroot00000000000000ip_address ---------- .. module:: validators.ip_address .. autofunction:: ipv4 .. autofunction:: ipv6 validators-0.28.3/docs/api/length.md000066400000000000000000000000471462425114700172670ustar00rootroot00000000000000# length ::: validators.length.length validators-0.28.3/docs/api/length.rst000066400000000000000000000001061462425114700174730ustar00rootroot00000000000000length ------ .. module:: validators.length .. autofunction:: length validators-0.28.3/docs/api/mac_address.md000066400000000000000000000000661462425114700202540ustar00rootroot00000000000000# mac_address ::: validators.mac_address.mac_address validators-0.28.3/docs/api/mac_address.rst000066400000000000000000000001321462425114700204560ustar00rootroot00000000000000mac_address ----------- .. module:: validators.mac_address .. autofunction:: mac_address validators-0.28.3/docs/api/slug.md000066400000000000000000000000411462425114700167520ustar00rootroot00000000000000# slug ::: validators.slug.slug validators-0.28.3/docs/api/slug.rst000066400000000000000000000000761462425114700171720ustar00rootroot00000000000000slug ---- .. module:: validators.slug .. autofunction:: slug validators-0.28.3/docs/api/url.md000066400000000000000000000000361462425114700166060ustar00rootroot00000000000000# url ::: validators.url.url validators-0.28.3/docs/api/url.rst000066400000000000000000000000721462425114700170160ustar00rootroot00000000000000url --- .. module:: validators.url .. autofunction:: url validators-0.28.3/docs/api/utils.md000066400000000000000000000001151462425114700171420ustar00rootroot00000000000000# utils ::: validators.utils.ValidationError ::: validators.utils.validator validators-0.28.3/docs/api/utils.rst000066400000000000000000000001501462425114700173510ustar00rootroot00000000000000utils ----- .. module:: validators.utils .. autofunction:: ValidationError .. autofunction:: validator validators-0.28.3/docs/api/uuid.md000066400000000000000000000000411462425114700167460ustar00rootroot00000000000000# uuid ::: validators.uuid.uuid validators-0.28.3/docs/api/uuid.rst000066400000000000000000000000761462425114700171660ustar00rootroot00000000000000uuid ---- .. module:: validators.uuid .. autofunction:: uuid validators-0.28.3/docs/assets/000077500000000000000000000000001462425114700162145ustar00rootroot00000000000000validators-0.28.3/docs/assets/icons/000077500000000000000000000000001462425114700173275ustar00rootroot00000000000000validators-0.28.3/docs/assets/icons/favicon.svg000066400000000000000000000014221462425114700214740ustar00rootroot00000000000000 validators-0.28.3/docs/conf.py000066400000000000000000000033741462425114700162200ustar00rootroot00000000000000"""Configuration file for the Sphinx documentation builder. For the full list of built-in configuration values, see the documentation: https://www.sphinx-doc.org/en/master/usage/configuration.html """ # standard from datetime import datetime from importlib.metadata import metadata # -- Project information ---------------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information _metadata = metadata("validators") _author_name = _metadata["author-email"].split(" <")[0] # _author_email = _metadata["author-email"].split(" <")[1].rstrip(">") project: str = _metadata["name"] author: str = _author_name project_copyright = f"2013 - {datetime.now().year}, {_author_name}" version: str = _metadata["version"] release = version # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration extensions = [ "sphinx.ext.autodoc", "sphinx.ext.napoleon", "myst_parser", ] exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", "**/*.md", "*.md"] # -- Options for HTML output ------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output html_theme = "furo" html_favicon = "./assets/icons/favicon.svg" # -- Options for manpage generation ------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-man_pages man_pages = [("index", project, _metadata["summary"], [author], 1)] # -- Options for docstring parsing ------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/extensions/napoleon.html napoleon_numpy_docstring = False validators-0.28.3/docs/index.md000066400000000000000000000044051462425114700163460ustar00rootroot00000000000000# validators - Python Data Validation for Humans™ [![PyCQA][pycqa-badge]][pycqa-link] [![SAST][sast-badge]][sast-link] [![Docs][docs-badge]][docs-link] [![Version][vs-badge]][vs-link] [![Downloads][dw-badge]][dw-link] Python has all kinds of data validation tools, but every one of them seems to require defining a schema or form. I wanted to create a simple validation library where validating a simple value does not require defining a form or a schema. ```python >>> import validators >>> >>> validators.email('someone@example.com') True ``` ## Resources - [Documentation](https://yozachar.github.io/pyvalidators) - [Bugtracker](https://github.com/python-validators/validators/issues) - [Security](https://github.com/python-validators/validators/blob/master/SECURITY.md) - [Code](https://github.com/python-validators/validators/) [sast-badge]: https://github.com/python-validators/validators/actions/workflows/sast.yaml/badge.svg [sast-link]: https://github.com/python-validators/validators/actions/workflows/sast.yaml [pycqa-badge]: https://github.com/python-validators/validators/actions/workflows/pycqa.yaml/badge.svg [pycqa-link]: https://github.com/python-validators/validators/actions/workflows/pycqa.yaml [docs-badge]: https://github.com/yozachar/pyvalidators/actions/workflows/pages/pages-build-deployment/badge.svg [docs-link]: https://github.com/yozachar/pyvalidators/actions/workflows/pages/pages-build-deployment [vs-badge]: https://img.shields.io/pypi/v/validators?logo=pypi&logoColor=white&label=version&color=blue [vs-link]: https://pypi.python.org/pypi/validators/ [dw-badge]: https://img.shields.io/pypi/dm/validators?logo=pypi&logoColor=white&color=blue [dw-link]: https://pypi.python.org/pypi/validators/ validators-0.28.3/docs/index.rst000066400000000000000000000047761462425114700165710ustar00rootroot00000000000000validators - Python Data Validation for Humans™ =============================================== |PyCQA| |SAST| |Docs| |Version| |Downloads| .. raw:: html Python has all kinds of data validation tools, but every one of them seems to require defining a schema or form. I wanted to create a simple validation library where validating a simple value does not require defining a form or a schema. .. code:: python >>> import validators >>> >>> validators.email('someone@example.com') True Resources --------- .. raw:: html .. raw:: html - `Documentation `__ - `Bugtracker `__ - `Security `__ - `Code `__ .. raw:: html .. raw:: html .. raw:: html .. |PyCQA| image:: https://github.com/python-validators/validators/actions/workflows/pycqa.yaml/badge.svg :target: https://github.com/python-validators/validators/actions/workflows/pycqa.yaml .. |SAST| image:: https://github.com/python-validators/validators/actions/workflows/sast.yaml/badge.svg :target: https://github.com/python-validators/validators/actions/workflows/sast.yaml .. |Docs| image:: https://github.com/yozachar/pyvalidators/actions/workflows/pages/pages-build-deployment/badge.svg :target: https://github.com/yozachar/pyvalidators/actions/workflows/pages/pages-build-deployment .. |Version| image:: https://img.shields.io/pypi/v/validators?logo=pypi&logoColor=white&label=version&color=blue :target: https://pypi.python.org/pypi/validators/ .. |Downloads| image:: https://img.shields.io/pypi/dm/validators?logo=pypi&logoColor=white&color=blue :target: https://pypi.python.org/pypi/validators/ .. toctree:: :hidden: :maxdepth: 2 :caption: Quick Start: :glob: install_and_use .. toctree:: :hidden: :maxdepth: 2 :caption: API Reference: :glob: api/* validators-0.28.3/docs/install_and_use.md000066400000000000000000000024421462425114700204020ustar00rootroot00000000000000# Install and Use ## Installation Execute the following command: ```text pip install validators ``` > It's preferable to use `pip` within a virtual environment. ## Usage ```python import validators print(validators.email('someone@example.com')) ``` ### To raise validation error 1. Either set the environment variable `RAISE_VALIDATION_ERROR` to `True` ```console $ export RAISE_VALIDATION_ERROR=True $ python -c "from validators import url; print(url('https//bad_url'))" Traceback (most recent call last): File "", line 1, in File "/path/to/lib/validators/utils.py", line 87, in wrapper raise ValidationError(func, _func_args_as_dict(func, *args, **kwargs)) validators.utils.ValidationError: ValidationError(func=url, args={'value': 'https//bad_url'}) ``` 2. Or pass `r_ve=True` to each caller function: ```console $ python -c "from validators.card import visa; print(visa('bad_visa_number', r_ve=True))" Traceback (most recent call last): File "", line 1, in File "/path/to/lib/validators/utils.py", line 87, in wrapper raise ValidationError(func, _func_args_as_dict(func, *args, **kwargs)) validators.utils.ValidationError: ValidationError(func=visa, args={'value': 'bad_visa_number'}) ``` validators-0.28.3/docs/install_and_use.rst000066400000000000000000000026141462425114700206130ustar00rootroot00000000000000Install and Use =============== Installation ------------ Execute the following command: .. code:: text pip install validators .. It's preferable to use ``pip`` within a virtual environment. Usage ----- .. code:: python import validators print(validators.email('someone@example.com')) To raise validation error ~~~~~~~~~~~~~~~~~~~~~~~~~ 1. Either set the environment variable ``RAISE_VALIDATION_ERROR`` to ``True`` .. code:: console $ export RAISE_VALIDATION_ERROR=True $ python -c "from validators import url; print(url('https//bad_url'))" Traceback (most recent call last): File "", line 1, in File "/path/to/lib/validators/utils.py", line 87, in wrapper raise ValidationError(func, _func_args_as_dict(func, *args, **kwargs)) validators.utils.ValidationError: ValidationError(func=url, args={'value': 'https//bad_url'}) 2. Or pass ``r_ve=True`` to each caller function: .. code:: console $ python -c "from validators.card import visa; print(visa('bad_visa_number', r_ve=True))" Traceback (most recent call last): File "", line 1, in File "/path/to/lib/validators/utils.py", line 87, in wrapper raise ValidationError(func, _func_args_as_dict(func, *args, **kwargs)) validators.utils.ValidationError: ValidationError(func=visa, args={'value': 'bad_visa_number'}) validators-0.28.3/docs/make.bat000066400000000000000000000014401462425114700163160ustar00rootroot00000000000000@ECHO OFF pushd %~dp0 REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=sphinx-build ) set SOURCEDIR=. set BUILDDIR=_build %SPHINXBUILD% >NUL 2>NUL if errorlevel 9009 ( echo. echo.The 'sphinx-build' command was not found. Make sure you have Sphinx echo.installed, then set the SPHINXBUILD environment variable to point echo.to the full path of the 'sphinx-build' executable. Alternatively you echo.may add the Sphinx directory to PATH. echo. echo.If you don't have Sphinx installed, grab it from echo.https://www.sphinx-doc.org/ exit /b 1 ) if "%1" == "" goto help %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% goto end :help %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% :end popd validators-0.28.3/mkdocs.yaml000066400000000000000000000041331462425114700161270ustar00rootroot00000000000000site_name: "validators" site_description: "Automatic documentation from sources, for MkDocs." site_url: "https://yozachar.github.io/pyvalidators/" repo_url: "https://github.com/python-validators/validators/" edit_uri: "edit/master/docs/" repo_name: "validators/validators" site_dir: "site" watch: [README.md, src/validators/] theme: name: material icon: logo: material/marker-check favicon: assets/icons/favicon.svg font: text: Inter code: "Fira Code" features: - content.code.copy palette: - media: "(prefers-color-scheme: light)" scheme: default primary: white accent: teal toggle: icon: material/toggle-switch name: Switch to dark mode - media: "(prefers-color-scheme: dark)" scheme: slate primary: black accent: teal toggle: icon: material/toggle-switch-off-outline name: Switch to light mode markdown_extensions: - toc: permalink: true - pymdownx.superfences - pymdownx.highlight: use_pygments: true - pymdownx.inlinehilite plugins: - search - mkdocstrings: handlers: python: options: show_root_heading: true import: - https://docs.python-requests.org/en/master/objects.inv - git-revision-date-localized - mike extra: social: - icon: fontawesome/brands/github link: https://github.com/python-validators - icon: fontawesome/brands/python link: https://pypi.org/project/validators version: provider: mike default: stable copyright: Copyright © 2013 - 2024 Konsta Vesterinen nav: - Home: index.md - Install and Use: install_and_use.md - API: - api/between.md - api/btc_address.md - api/card.md - api/country.md - api/cron.md - api/domain.md - api/email.md - api/encoding.md - api/finance.md - api/hashes.md - api/hostname.md - api/i18n.md - api/iban.md - api/ip_address.md - api/length.md - api/mac_address.md - api/slug.md - api/url.md - api/utils.md - api/uuid.md validators-0.28.3/package/000077500000000000000000000000001462425114700153555ustar00rootroot00000000000000validators-0.28.3/package/export/000077500000000000000000000000001462425114700166765ustar00rootroot00000000000000validators-0.28.3/package/export/__init__.py000066400000000000000000000000161462425114700210040ustar00rootroot00000000000000"""Export.""" validators-0.28.3/package/export/__main__.py000066400000000000000000000137101462425114700207720ustar00rootroot00000000000000"""Generate docs.""" # standard from ast import ImportFrom, parse from os import getenv from os.path import getsize from pathlib import Path from shutil import copy from subprocess import Popen # nosec def _write_ref_content(source: Path, module_name: str, func_name: str): """Write content.""" with open(source, "at") as ref: ref.write( ( (f"# {module_name}\n\n" if getsize(source) == 0 else "") + f"::: validators.{module_name}.{func_name}\n" ) if f"{source}".endswith(".md") else ( ( f"{module_name}\n{len(module_name) * '-'}\n\n" + f".. module:: validators.{module_name}\n" if getsize(source) == 0 else "" ) + f".. autofunction:: {func_name}\n" ) ) def _parse_package(source: Path): """Parse validators package.""" v_ast = parse(source.read_text(), source) for namespace in (node for node in v_ast.body if isinstance(node, ImportFrom)): if not namespace.module: continue yield (namespace.module, namespace.names) def _gen_md_docs(source: Path, refs_path: Path): """Generate Markdown docs.""" # remove existing markdown files for md_files in (source / "docs/api").glob("*.md"): md_files.unlink() # generate md reference documentation for module_name, aliases in _parse_package(source / "src/validators/__init__.py"): for alias in aliases: _write_ref_content(refs_path / f"{module_name}.md", module_name, alias.name) # build mkdocs as subprocess mkdocs_build = Popen(("mkdocs", "build")) # nosec mkdocs_build.communicate() return mkdocs_build.returncode def _gen_rst_docs(source: Path, refs_path: Path, only_web: bool = False, only_man: bool = False): """Generate reStructuredText docs.""" # external from pypandoc import convert_file # type: ignore # remove existing rST files for rst_files in (source / "docs/api").glob("*.rst"): rst_files.unlink() with open(source / "docs/index.rst", "wt") as idx_f: idx_f.write( convert_file(source_file=source / "docs/index.md", format="md", to="rst").replace( "\r\n", "\n" # remove carriage return in windows ) + "\n\n.. toctree::" + "\n :hidden:" + "\n :maxdepth: 2" + "\n :caption: Quick Start:" + "\n :glob:\n" + "\n install_and_use" + "\n\n.. toctree::" + "\n :hidden:" + "\n :maxdepth: 2" + "\n :caption: API Reference:" + "\n :glob:\n" + "\n api/*\n" ) with open(source / "docs/install_and_use.rst", "wt") as iau_f: iau_f.write( convert_file(source_file=source / "docs/install_and_use.md", format="md", to="rst") .replace("\r\n", "\n") # remove carriage return in windows .replace("’", "'") ) # generate rST reference documentation for module_name, aliases in _parse_package(source / "src/validators/__init__.py"): for alias in aliases: _write_ref_content(refs_path / f"{module_name}.rst", module_name, alias.name) exit_code = 0 if not only_man: # build sphinx web pages as subprocess web_build = Popen(("sphinx-build", "docs", "docs/_build/web"), shell=False) # nosec web_build.communicate() exit_code = web_build.returncode print("Run `python -m http.server -d docs/_build/web` to preview.") if not only_web: # build sphinx man pages as subprocess man_build = Popen( # nosec ("sphinx-build", "-b", "man", "docs", "docs/_build/man"), shell=False ) man_build.communicate() copy(source / "docs/_build/man/validators.1", source / "docs/validators.1") print(f"Man page copied to: {source / 'docs/validators.1'}") exit_code = man_build.returncode if exit_code == 0 else exit_code return exit_code def _generate_documentation( source: Path, only_md: bool = False, only_rst_web: bool = False, only_rst_man: bool = False, ): """Generate documentation.""" if only_md is only_rst_web is only_rst_man is True: return if only_md is only_rst_web is only_rst_man is False: return # copy readme as docs index file copy(source / "README.md", source / "docs/index.md") # clean destination refs_path = source / "docs/api" # if refs_path.is_dir(): # rmtree(refs_path) refs_path.mkdir(exist_ok=True) exit_code = 0 if (only_rst_web or only_rst_man) else _gen_md_docs(source, refs_path) if not only_md: exit_code = ( _gen_rst_docs(source, refs_path, only_rst_web, only_rst_man) if exit_code == 0 else exit_code ) return exit_code def package(source: Path): """Package the source code.""" _generate_documentation(source, only_rst_man=True) if getenv("CI", "false") == "true": process = Popen(("./.venv/bin/python", "-m", "build"), shell=False) # nosec else: process = Popen(("pdm", "build"), shell=False) # nosec process.communicate() return process.returncode if __name__ == "__main__": project_root = Path(__file__).parent.parent.parent exit_code = 0 # standard from sys import argv if len(argv) != 2: print("Expected one of these augments: `pkg` `doc` `man` or `web`") quit(1) if argv[1] == "pkg": exit_code = package(project_root) elif argv[1] == "doc": exit_code = _generate_documentation(project_root, only_md=True) elif argv[1] == "man": exit_code = _generate_documentation(project_root, only_rst_man=True) elif argv[1] == "web": exit_code = _generate_documentation(project_root, only_rst_web=True) quit(exit_code) # TODO: Address all '# nosec' validators-0.28.3/package/requirements.mkdocs.txt000066400000000000000000000757431462425114700221400ustar00rootroot00000000000000# This file is @generated by PDM. # Please do not edit it manually. astunparse==1.6.3; python_version < "3.9" \ --hash=sha256:5ad93a8456f0d084c3456d059fd9a92cce667963232cbf763eac3bc5b7940872 \ --hash=sha256:c2652417f2c8b5bb325c885ae329bdf3f86424075c4fd1a128674bc6fba4b8e8 babel==2.15.0 \ --hash=sha256:08706bdad8d0a3413266ab61bd6c34d0c28d6e1e7badf40a2cebe67644e2e1fb \ --hash=sha256:8daf0e265d05768bc6c7a314cf1321e9a123afc328cc635c18622a2f30a04413 certifi==2024.2.2 \ --hash=sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f \ --hash=sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1 charset-normalizer==3.3.2 \ --hash=sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027 \ --hash=sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087 \ --hash=sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8 \ --hash=sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09 \ --hash=sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185 \ --hash=sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574 \ --hash=sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e \ --hash=sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519 \ --hash=sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898 \ --hash=sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269 \ --hash=sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3 \ --hash=sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f \ --hash=sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8 \ --hash=sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a \ --hash=sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73 \ --hash=sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc \ --hash=sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2 \ --hash=sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc \ --hash=sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce \ --hash=sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d \ --hash=sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e \ --hash=sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6 \ --hash=sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269 \ --hash=sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96 \ --hash=sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d \ --hash=sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a \ --hash=sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4 \ --hash=sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77 \ --hash=sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d \ --hash=sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0 \ --hash=sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed \ --hash=sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068 \ --hash=sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac \ --hash=sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25 \ --hash=sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8 \ --hash=sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab \ --hash=sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26 \ --hash=sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2 \ --hash=sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db \ --hash=sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f \ --hash=sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5 \ --hash=sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d \ --hash=sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa \ --hash=sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a \ --hash=sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03 \ --hash=sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b \ --hash=sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04 \ --hash=sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001 \ --hash=sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458 \ --hash=sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389 \ --hash=sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99 \ --hash=sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537 \ --hash=sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238 \ --hash=sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f \ --hash=sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d \ --hash=sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796 \ --hash=sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a \ --hash=sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143 \ --hash=sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c \ --hash=sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4 \ --hash=sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6 \ --hash=sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c \ --hash=sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7 \ --hash=sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b \ --hash=sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae \ --hash=sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12 \ --hash=sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c \ --hash=sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae \ --hash=sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8 \ --hash=sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887 \ --hash=sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b \ --hash=sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4 \ --hash=sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f \ --hash=sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5 \ --hash=sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33 \ --hash=sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519 \ --hash=sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561 click==8.1.7 \ --hash=sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28 \ --hash=sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de colorama==0.4.6 \ --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 ghp-import==2.1.0 \ --hash=sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619 \ --hash=sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343 gitdb==4.0.11 \ --hash=sha256:81a3407ddd2ee8df444cbacea00e2d038e40150acfa3001696fe0dcf1d3adfa4 \ --hash=sha256:bf5421126136d6d0af55bc1e7c1af1c397a34f5b7bd79e776cd3e89785c2b04b gitpython==3.1.43 \ --hash=sha256:35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c \ --hash=sha256:eec7ec56b92aad751f9912a73404bc02ba212a23adb2c7098ee668417051a1ff griffe==0.45.2 \ --hash=sha256:297ec8530d0c68e5b98ff86fb588ebc3aa3559bb5dc21f3caea8d9542a350133 \ --hash=sha256:83ce7dcaafd8cb7f43cbf1a455155015a1eb624b1ffd93249e5e1c4a22b2fdb2 idna==3.7 \ --hash=sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc \ --hash=sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0 importlib-metadata==7.1.0 \ --hash=sha256:30962b96c0c223483ed6cc7280e7f0199feb01a0e40cfae4d4450fc6fab1f570 \ --hash=sha256:b78938b926ee8d5f020fc4772d487045805a55ddbad2ecf21c6d60938dc7fcd2 importlib-resources==6.4.0 \ --hash=sha256:50d10f043df931902d4194ea07ec57960f66a80449ff867bfe782b4c486ba78c \ --hash=sha256:cdb2b453b8046ca4e3798eb1d84f3cce1446a0e8e7b5ef4efb600f19fc398145 jinja2==3.1.4 \ --hash=sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369 \ --hash=sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d markdown==3.6 \ --hash=sha256:48f276f4d8cfb8ce6527c8f79e2ee29708508bf4d40aa410fbc3b4ee832c850f \ --hash=sha256:ed4f41f6daecbeeb96e576ce414c41d2d876daa9a16cb35fa8ed8c2ddfad0224 markupsafe==2.1.5 \ --hash=sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf \ --hash=sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff \ --hash=sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f \ --hash=sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3 \ --hash=sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532 \ --hash=sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f \ --hash=sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617 \ --hash=sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4 \ --hash=sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906 \ --hash=sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f \ --hash=sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4 \ --hash=sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8 \ --hash=sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465 \ --hash=sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6 \ --hash=sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169 \ --hash=sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad \ --hash=sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2 \ --hash=sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0 \ --hash=sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029 \ --hash=sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f \ --hash=sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a \ --hash=sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced \ --hash=sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5 \ --hash=sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c \ --hash=sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf \ --hash=sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb \ --hash=sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad \ --hash=sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3 \ --hash=sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1 \ --hash=sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46 \ --hash=sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc \ --hash=sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee \ --hash=sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900 \ --hash=sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5 \ --hash=sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea \ --hash=sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f \ --hash=sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5 \ --hash=sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e \ --hash=sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a \ --hash=sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a \ --hash=sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b \ --hash=sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4 \ --hash=sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff \ --hash=sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2 \ --hash=sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46 \ --hash=sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b \ --hash=sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5 \ --hash=sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5 \ --hash=sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab \ --hash=sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd \ --hash=sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68 mergedeep==1.3.4 \ --hash=sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8 \ --hash=sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307 mike==2.1.1 \ --hash=sha256:0b1d01a397a423284593eeb1b5f3194e37169488f929b860c9bfe95c0d5efb79 \ --hash=sha256:f39ed39f3737da83ad0adc33e9f885092ed27f8c9e7ff0523add0480352a2c22 mkdocs==1.6.0 \ --hash=sha256:1eb5cb7676b7d89323e62b56235010216319217d4af5ddc543a91beb8d125ea7 \ --hash=sha256:a73f735824ef83a4f3bcb7a231dcab23f5a838f88b7efc54a0eef5fbdbc3c512 mkdocs-autorefs==1.0.1 \ --hash=sha256:aacdfae1ab197780fb7a2dac92ad8a3d8f7ca8049a9cbe56a4218cd52e8da570 \ --hash=sha256:f684edf847eced40b570b57846b15f0bf57fb93ac2c510450775dcf16accb971 mkdocs-get-deps==0.2.0 \ --hash=sha256:162b3d129c7fad9b19abfdcb9c1458a651628e4b1dea628ac68790fb3061c60c \ --hash=sha256:2bf11d0b133e77a0dd036abeeb06dec8775e46efa526dc70667d8863eefc6134 mkdocs-git-revision-date-localized-plugin==1.2.5 \ --hash=sha256:0c439816d9d0dba48e027d9d074b2b9f1d7cd179f74ba46b51e4da7bb3dc4b9b \ --hash=sha256:d796a18b07cfcdb154c133e3ec099d2bb5f38389e4fd54d3eb516a8a736815b8 mkdocs-material==9.5.24 \ --hash=sha256:02d5aaba0ee755e707c3ef6e748f9acb7b3011187c0ea766db31af8905078a34 \ --hash=sha256:e12cd75954c535b61e716f359cf2a5056bf4514889d17161fdebd5df4b0153c6 mkdocs-material-extensions==1.3.1 \ --hash=sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443 \ --hash=sha256:adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31 mkdocstrings==0.25.1 \ --hash=sha256:c3a2515f31577f311a9ee58d089e4c51fc6046dbd9e9b4c3de4c3194667fe9bf \ --hash=sha256:da01fcc2670ad61888e8fe5b60afe9fee5781017d67431996832d63e887c2e51 mkdocstrings-python==1.10.3 \ --hash=sha256:11ff6d21d3818fb03af82c3ea6225b1534837e17f790aa5f09626524171f949b \ --hash=sha256:321cf9c732907ab2b1fedaafa28765eaa089d89320f35f7206d00ea266889d03 packaging==24.0 \ --hash=sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5 \ --hash=sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9 paginate==0.5.6 \ --hash=sha256:5e6007b6a9398177a7e1648d04fdd9f8c9766a1a945bceac82f1929e8c78af2d pathspec==0.12.1 \ --hash=sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08 \ --hash=sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712 platformdirs==4.2.2 \ --hash=sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee \ --hash=sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3 pygments==2.18.0 \ --hash=sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199 \ --hash=sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a pymdown-extensions==10.8.1 \ --hash=sha256:3ab1db5c9e21728dabf75192d71471f8e50f216627e9a1fa9535ecb0231b9940 \ --hash=sha256:f938326115884f48c6059c67377c46cf631c733ef3629b6eed1349989d1b30cb pyparsing==3.1.2 \ --hash=sha256:a1bac0ce561155ecc3ed78ca94d3c9378656ad4c94c1270de543f621420f94ad \ --hash=sha256:f9db75911801ed778fe61bb643079ff86601aca99fcae6345aa67292038fb742 python-dateutil==2.9.0.post0 \ --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \ --hash=sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 pytz==2024.1 \ --hash=sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812 \ --hash=sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319 pyyaml==6.0.1 \ --hash=sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5 \ --hash=sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc \ --hash=sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df \ --hash=sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741 \ --hash=sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206 \ --hash=sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595 \ --hash=sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62 \ --hash=sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696 \ --hash=sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290 \ --hash=sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9 \ --hash=sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d \ --hash=sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6 \ --hash=sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486 \ --hash=sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6 \ --hash=sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007 \ --hash=sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938 \ --hash=sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0 \ --hash=sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735 \ --hash=sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d \ --hash=sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28 \ --hash=sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4 \ --hash=sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8 \ --hash=sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef \ --hash=sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5 \ --hash=sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0 \ --hash=sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515 \ --hash=sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c \ --hash=sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924 \ --hash=sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34 \ --hash=sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43 \ --hash=sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859 \ --hash=sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673 \ --hash=sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54 \ --hash=sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a \ --hash=sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b \ --hash=sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab \ --hash=sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c \ --hash=sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d \ --hash=sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f pyyaml-env-tag==0.1 \ --hash=sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb \ --hash=sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069 regex==2024.5.15 \ --hash=sha256:0721931ad5fe0dda45d07f9820b90b2148ccdd8e45bb9e9b42a146cb4f695649 \ --hash=sha256:10002e86e6068d9e1c91eae8295ef690f02f913c57db120b58fdd35a6bb1af35 \ --hash=sha256:10e4ce0dca9ae7a66e6089bb29355d4432caed736acae36fef0fdd7879f0b0cb \ --hash=sha256:119af6e56dce35e8dfb5222573b50c89e5508d94d55713c75126b753f834de68 \ --hash=sha256:1337b7dbef9b2f71121cdbf1e97e40de33ff114801263b275aafd75303bd62b5 \ --hash=sha256:13cdaf31bed30a1e1c2453ef6015aa0983e1366fad2667657dbcac7b02f67133 \ --hash=sha256:1595f2d10dff3d805e054ebdc41c124753631b6a471b976963c7b28543cf13b0 \ --hash=sha256:16093f563098448ff6b1fa68170e4acbef94e6b6a4e25e10eae8598bb1694b5d \ --hash=sha256:1878b8301ed011704aea4c806a3cadbd76f84dece1ec09cc9e4dc934cfa5d4da \ --hash=sha256:19068a6a79cf99a19ccefa44610491e9ca02c2be3305c7760d3831d38a467a6f \ --hash=sha256:19dfb1c504781a136a80ecd1fff9f16dddf5bb43cec6871778c8a907a085bb3d \ --hash=sha256:1b5269484f6126eee5e687785e83c6b60aad7663dafe842b34691157e5083e53 \ --hash=sha256:1c1c174d6ec38d6c8a7504087358ce9213d4332f6293a94fbf5249992ba54efa \ --hash=sha256:2431b9e263af1953c55abbd3e2efca67ca80a3de8a0437cb58e2421f8184717a \ --hash=sha256:287eb7f54fc81546346207c533ad3c2c51a8d61075127d7f6d79aaf96cdee890 \ --hash=sha256:2b4c884767504c0e2401babe8b5b7aea9148680d2e157fa28f01529d1f7fcf67 \ --hash=sha256:35cb514e137cb3488bce23352af3e12fb0dbedd1ee6e60da053c69fb1b29cc6c \ --hash=sha256:391d7f7f1e409d192dba8bcd42d3e4cf9e598f3979cdaed6ab11288da88cb9f2 \ --hash=sha256:3ad070b823ca5890cab606c940522d05d3d22395d432f4aaaf9d5b1653e47ced \ --hash=sha256:3cd7874d57f13bf70078f1ff02b8b0aa48d5b9ed25fc48547516c6aba36f5741 \ --hash=sha256:3e507ff1e74373c4d3038195fdd2af30d297b4f0950eeda6f515ae3d84a1770f \ --hash=sha256:455705d34b4154a80ead722f4f185b04c4237e8e8e33f265cd0798d0e44825fa \ --hash=sha256:4a605586358893b483976cffc1723fb0f83e526e8f14c6e6614e75919d9862cf \ --hash=sha256:4babf07ad476aaf7830d77000874d7611704a7fcf68c9c2ad151f5d94ae4bfc4 \ --hash=sha256:4eee78a04e6c67e8391edd4dad3279828dd66ac4b79570ec998e2155d2e59fd5 \ --hash=sha256:5397de3219a8b08ae9540c48f602996aa6b0b65d5a61683e233af8605c42b0f2 \ --hash=sha256:5b5467acbfc153847d5adb21e21e29847bcb5870e65c94c9206d20eb4e99a384 \ --hash=sha256:5eaa7ddaf517aa095fa8da0b5015c44d03da83f5bd49c87961e3c997daed0de7 \ --hash=sha256:632b01153e5248c134007209b5c6348a544ce96c46005d8456de1d552455b014 \ --hash=sha256:64c65783e96e563103d641760664125e91bd85d8e49566ee560ded4da0d3e704 \ --hash=sha256:64f18a9a3513a99c4bef0e3efd4c4a5b11228b48aa80743be822b71e132ae4f5 \ --hash=sha256:673b5a6da4557b975c6c90198588181029c60793835ce02f497ea817ff647cb2 \ --hash=sha256:68811ab14087b2f6e0fc0c2bae9ad689ea3584cad6917fc57be6a48bbd012c49 \ --hash=sha256:6e8d717bca3a6e2064fc3a08df5cbe366369f4b052dcd21b7416e6d71620dca1 \ --hash=sha256:71a455a3c584a88f654b64feccc1e25876066c4f5ef26cd6dd711308aa538694 \ --hash=sha256:72d7a99cd6b8f958e85fc6ca5b37c4303294954eac1376535b03c2a43eb72629 \ --hash=sha256:7b59138b219ffa8979013be7bc85bb60c6f7b7575df3d56dc1e403a438c7a3f6 \ --hash=sha256:7dbe2467273b875ea2de38ded4eba86cbcbc9a1a6d0aa11dcf7bd2e67859c435 \ --hash=sha256:833616ddc75ad595dee848ad984d067f2f31be645d603e4d158bba656bbf516c \ --hash=sha256:87e2a9c29e672fc65523fb47a90d429b70ef72b901b4e4b1bd42387caf0d6835 \ --hash=sha256:8fe45aa3f4aa57faabbc9cb46a93363edd6197cbc43523daea044e9ff2fea83e \ --hash=sha256:9e717956dcfd656f5055cc70996ee2cc82ac5149517fc8e1b60261b907740201 \ --hash=sha256:9efa1a32ad3a3ea112224897cdaeb6aa00381627f567179c0314f7b65d354c62 \ --hash=sha256:9ff11639a8d98969c863d4617595eb5425fd12f7c5ef6621a4b74b71ed8726d5 \ --hash=sha256:a094801d379ab20c2135529948cb84d417a2169b9bdceda2a36f5f10977ebc16 \ --hash=sha256:a0981022dccabca811e8171f913de05720590c915b033b7e601f35ce4ea7019f \ --hash=sha256:a0bd000c6e266927cb7a1bc39d55be95c4b4f65c5be53e659537537e019232b1 \ --hash=sha256:a32b96f15c8ab2e7d27655969a23895eb799de3665fa94349f3b2fbfd547236f \ --hash=sha256:a81e3cfbae20378d75185171587cbf756015ccb14840702944f014e0d93ea09f \ --hash=sha256:ac394ff680fc46b97487941f5e6ae49a9f30ea41c6c6804832063f14b2a5a145 \ --hash=sha256:ada150c5adfa8fbcbf321c30c751dc67d2f12f15bd183ffe4ec7cde351d945b3 \ --hash=sha256:b2b6f1b3bb6f640c1a92be3bbfbcb18657b125b99ecf141fb3310b5282c7d4ed \ --hash=sha256:b802512f3e1f480f41ab5f2cfc0e2f761f08a1f41092d6718868082fc0d27143 \ --hash=sha256:ba68168daedb2c0bab7fd7e00ced5ba90aebf91024dea3c88ad5063c2a562cca \ --hash=sha256:bfc4f82cabe54f1e7f206fd3d30fda143f84a63fe7d64a81558d6e5f2e5aaba9 \ --hash=sha256:c0c18345010870e58238790a6779a1219b4d97bd2e77e1140e8ee5d14df071aa \ --hash=sha256:c3bea0ba8b73b71b37ac833a7f3fd53825924165da6a924aec78c13032f20850 \ --hash=sha256:c486b4106066d502495b3025a0a7251bf37ea9540433940a23419461ab9f2a80 \ --hash=sha256:c49e15eac7c149f3670b3e27f1f28a2c1ddeccd3a2812cba953e01be2ab9b5fe \ --hash=sha256:c6a2b494a76983df8e3d3feea9b9ffdd558b247e60b92f877f93a1ff43d26656 \ --hash=sha256:cab12877a9bdafde5500206d1020a584355a97884dfd388af3699e9137bf7388 \ --hash=sha256:cac27dcaa821ca271855a32188aa61d12decb6fe45ffe3e722401fe61e323cd1 \ --hash=sha256:cdd09d47c0b2efee9378679f8510ee6955d329424c659ab3c5e3a6edea696294 \ --hash=sha256:cf2430df4148b08fb4324b848672514b1385ae3807651f3567871f130a728cc3 \ --hash=sha256:d0a3d8d6acf0c78a1fff0e210d224b821081330b8524e3e2bc5a68ef6ab5803d \ --hash=sha256:d0c0c0003c10f54a591d220997dd27d953cd9ccc1a7294b40a4be5312be8797b \ --hash=sha256:d1f059a4d795e646e1c37665b9d06062c62d0e8cc3c511fe01315973a6542e40 \ --hash=sha256:d347a741ea871c2e278fde6c48f85136c96b8659b632fb57a7d1ce1872547600 \ --hash=sha256:d3ee02d9e5f482cc8309134a91eeaacbdd2261ba111b0fef3748eeb4913e6a2c \ --hash=sha256:d99ceffa25ac45d150e30bd9ed14ec6039f2aad0ffa6bb87a5936f5782fc1569 \ --hash=sha256:e38a7d4e8f633a33b4c7350fbd8bad3b70bf81439ac67ac38916c4a86b465456 \ --hash=sha256:e4682f5ba31f475d58884045c1a97a860a007d44938c4c0895f41d64481edbc9 \ --hash=sha256:e5bb9425fe881d578aeca0b2b4b3d314ec88738706f66f219c194d67179337cb \ --hash=sha256:e64198f6b856d48192bf921421fdd8ad8eb35e179086e99e99f711957ffedd6e \ --hash=sha256:e6662686aeb633ad65be2a42b4cb00178b3fbf7b91878f9446075c404ada552f \ --hash=sha256:ec54d5afa89c19c6dd8541a133be51ee1017a38b412b1321ccb8d6ddbeb4cf7d \ --hash=sha256:f5b1dff3ad008dccf18e652283f5e5339d70bf8ba7c98bf848ac33db10f7bc7a \ --hash=sha256:f8ec0c2fea1e886a19c3bee0cd19d862b3aa75dcdfb42ebe8ed30708df64687a \ --hash=sha256:f9ebd0a36102fcad2f03696e8af4ae682793a5d30b46c647eaf280d6cfb32796 requests==2.32.2 \ --hash=sha256:dd951ff5ecf3e3b3aa26b40703ba77495dab41da839ae72ef3c8e5d8e2433289 \ --hash=sha256:fc06670dd0ed212426dfeb94fc1b983d917c4f9847c863f313c9dfaaffb7c23c six==1.16.0 \ --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \ --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254 smmap==5.0.1 \ --hash=sha256:dceeb6c0028fdb6734471eb07c0cd2aae706ccaecab45965ee83f11c8d3b1f62 \ --hash=sha256:e6d8668fa5f93e706934a62d7b4db19c8d9eb8cf2adbb75ef1b675aa332b69da typing-extensions==4.12.0; python_version < "3.11" \ --hash=sha256:8cbcdc8606ebcb0d95453ad7dc5065e6237b6aa230a31e81d0f440c30fed5fd8 \ --hash=sha256:b349c66bea9016ac22978d800cfff206d5f9816951f12a7d0ec5578b0a819594 urllib3==2.2.1 \ --hash=sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d \ --hash=sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19 verspec==0.1.0 \ --hash=sha256:741877d5633cc9464c45a469ae2a31e801e6dbbaa85b9675d481cda100f11c31 \ --hash=sha256:c4504ca697b2056cdb4bfa7121461f5a0e81809255b41c03dda4ba823637c01e watchdog==4.0.1 \ --hash=sha256:0144c0ea9997b92615af1d94afc0c217e07ce2c14912c7b1a5731776329fcfc7 \ --hash=sha256:03e70d2df2258fb6cb0e95bbdbe06c16e608af94a3ffbd2b90c3f1e83eb10767 \ --hash=sha256:093b23e6906a8b97051191a4a0c73a77ecc958121d42346274c6af6520dec175 \ --hash=sha256:123587af84260c991dc5f62a6e7ef3d1c57dfddc99faacee508c71d287248459 \ --hash=sha256:17e32f147d8bf9657e0922c0940bcde863b894cd871dbb694beb6704cfbd2fb5 \ --hash=sha256:206afc3d964f9a233e6ad34618ec60b9837d0582b500b63687e34011e15bb429 \ --hash=sha256:4107ac5ab936a63952dea2a46a734a23230aa2f6f9db1291bf171dac3ebd53c6 \ --hash=sha256:4513ec234c68b14d4161440e07f995f231be21a09329051e67a2118a7a612d2d \ --hash=sha256:611be3904f9843f0529c35a3ff3fd617449463cb4b73b1633950b3d97fa4bfb7 \ --hash=sha256:62c613ad689ddcb11707f030e722fa929f322ef7e4f18f5335d2b73c61a85c28 \ --hash=sha256:667f3c579e813fcbad1b784db7a1aaa96524bed53437e119f6a2f5de4db04235 \ --hash=sha256:6e8c70d2cd745daec2a08734d9f63092b793ad97612470a0ee4cbb8f5f705c57 \ --hash=sha256:7577b3c43e5909623149f76b099ac49a1a01ca4e167d1785c76eb52fa585745a \ --hash=sha256:998d2be6976a0ee3a81fb8e2777900c28641fb5bfbd0c84717d89bca0addcdc5 \ --hash=sha256:a3c2c317a8fb53e5b3d25790553796105501a235343f5d2bf23bb8649c2c8709 \ --hash=sha256:ab998f567ebdf6b1da7dc1e5accfaa7c6992244629c0fdaef062f43249bd8dee \ --hash=sha256:ac7041b385f04c047fcc2951dc001671dee1b7e0615cde772e84b01fbf68ee84 \ --hash=sha256:bca36be5707e81b9e6ce3208d92d95540d4ca244c006b61511753583c81c70dd \ --hash=sha256:c9904904b6564d4ee8a1ed820db76185a3c96e05560c776c79a6ce5ab71888ba \ --hash=sha256:cad0bbd66cd59fc474b4a4376bc5ac3fc698723510cbb64091c2a793b18654db \ --hash=sha256:d10a681c9a1d5a77e75c48a3b8e1a9f2ae2928eda463e8d33660437705659682 \ --hash=sha256:d4925e4bf7b9bddd1c3de13c9b8a2cdb89a468f640e66fbfabaf735bd85b3e35 \ --hash=sha256:d7b9f5f3299e8dd230880b6c55504a1f69cf1e4316275d1b215ebdd8187ec88d \ --hash=sha256:da2dfdaa8006eb6a71051795856bedd97e5b03e57da96f98e375682c48850645 \ --hash=sha256:dddba7ca1c807045323b6af4ff80f5ddc4d654c8bce8317dde1bd96b128ed253 \ --hash=sha256:e7921319fe4430b11278d924ef66d4daa469fafb1da679a2e48c935fa27af193 \ --hash=sha256:e93f451f2dfa433d97765ca2634628b789b49ba8b504fdde5837cdcf25fdb53b \ --hash=sha256:eebaacf674fa25511e8867028d281e602ee6500045b57f43b08778082f7f8b44 \ --hash=sha256:ef0107bbb6a55f5be727cfc2ef945d5676b97bffb8425650dadbb184be9f9a2b \ --hash=sha256:f0de0f284248ab40188f23380b03b59126d1479cd59940f2a34f8852db710625 \ --hash=sha256:f27279d060e2ab24c0aa98363ff906d2386aa6c4dc2f1a374655d4e02a6c5e5e \ --hash=sha256:f8affdf3c0f0466e69f5b3917cdd042f89c8c63aebdb9f7c078996f607cdb0f5 wheel==0.43.0; python_version < "3.9" \ --hash=sha256:465ef92c69fa5c5da2d1cf8ac40559a8c940886afcef87dcf14b9470862f1d85 \ --hash=sha256:55c570405f142630c6b9f72fe09d9b67cf1477fcf543ae5b8dcb1f5b7377da81 zipp==3.18.2 \ --hash=sha256:6278d9ddbcfb1f1089a88fde84481528b07b0e10474e09dcfe53dad4069fa059 \ --hash=sha256:dce197b859eb796242b0622af1b8beb0a722d52aa2f57133ead08edd5bf5374e validators-0.28.3/package/requirements.sphinx.txt000066400000000000000000000505311462425114700221550ustar00rootroot00000000000000# This file is @generated by PDM. # Please do not edit it manually. alabaster==0.7.13 \ --hash=sha256:1ee19aca801bbabb5ba3f5f258e4422dfa86f82f3e9cefb0859b283cdd7f62a3 \ --hash=sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2 babel==2.15.0 \ --hash=sha256:08706bdad8d0a3413266ab61bd6c34d0c28d6e1e7badf40a2cebe67644e2e1fb \ --hash=sha256:8daf0e265d05768bc6c7a314cf1321e9a123afc328cc635c18622a2f30a04413 beautifulsoup4==4.12.3 \ --hash=sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051 \ --hash=sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed certifi==2024.2.2 \ --hash=sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f \ --hash=sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1 charset-normalizer==3.3.2 \ --hash=sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027 \ --hash=sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087 \ --hash=sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8 \ --hash=sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09 \ --hash=sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185 \ --hash=sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574 \ --hash=sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e \ --hash=sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519 \ --hash=sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898 \ --hash=sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269 \ --hash=sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3 \ --hash=sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f \ --hash=sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8 \ --hash=sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a \ --hash=sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73 \ --hash=sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc \ --hash=sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2 \ --hash=sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc \ --hash=sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce \ --hash=sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d \ --hash=sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e \ --hash=sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6 \ --hash=sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269 \ --hash=sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96 \ --hash=sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d \ --hash=sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a \ --hash=sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4 \ --hash=sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77 \ --hash=sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d \ --hash=sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0 \ --hash=sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed \ --hash=sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068 \ --hash=sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac \ --hash=sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25 \ --hash=sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8 \ --hash=sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab \ --hash=sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26 \ --hash=sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2 \ --hash=sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db \ --hash=sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f \ --hash=sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5 \ --hash=sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d \ --hash=sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa \ --hash=sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a \ --hash=sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03 \ --hash=sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b \ --hash=sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04 \ --hash=sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001 \ --hash=sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458 \ --hash=sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389 \ --hash=sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99 \ --hash=sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537 \ --hash=sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238 \ --hash=sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f \ --hash=sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d \ --hash=sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796 \ --hash=sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a \ --hash=sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143 \ --hash=sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c \ --hash=sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4 \ --hash=sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6 \ --hash=sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c \ --hash=sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7 \ --hash=sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b \ --hash=sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae \ --hash=sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12 \ --hash=sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c \ --hash=sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae \ --hash=sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8 \ --hash=sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887 \ --hash=sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b \ --hash=sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4 \ --hash=sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f \ --hash=sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5 \ --hash=sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33 \ --hash=sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519 \ --hash=sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561 colorama==0.4.6 \ --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 docutils==0.20.1 \ --hash=sha256:96f387a2c5562db4476f09f13bbab2192e764cac08ebbf3a34a95d9b1e4a59d6 \ --hash=sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b furo==2024.5.6 \ --hash=sha256:490a00d08c0a37ecc90de03ae9227e8eb5d6f7f750edf9807f398a2bdf2358de \ --hash=sha256:81f205a6605ebccbb883350432b4831c0196dd3d1bc92f61e1f459045b3d2b0b idna==3.7 \ --hash=sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc \ --hash=sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0 imagesize==1.4.1 \ --hash=sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b \ --hash=sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a importlib-metadata==7.1.0 \ --hash=sha256:30962b96c0c223483ed6cc7280e7f0199feb01a0e40cfae4d4450fc6fab1f570 \ --hash=sha256:b78938b926ee8d5f020fc4772d487045805a55ddbad2ecf21c6d60938dc7fcd2 jinja2==3.1.4 \ --hash=sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369 \ --hash=sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d markdown-it-py==3.0.0 \ --hash=sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1 \ --hash=sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb markupsafe==2.1.5 \ --hash=sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf \ --hash=sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff \ --hash=sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f \ --hash=sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3 \ --hash=sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532 \ --hash=sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f \ --hash=sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617 \ --hash=sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4 \ --hash=sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906 \ --hash=sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f \ --hash=sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4 \ --hash=sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8 \ --hash=sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465 \ --hash=sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6 \ --hash=sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169 \ --hash=sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad \ --hash=sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2 \ --hash=sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0 \ --hash=sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029 \ --hash=sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f \ --hash=sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a \ --hash=sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced \ --hash=sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5 \ --hash=sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c \ --hash=sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf \ --hash=sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb \ --hash=sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad \ --hash=sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3 \ --hash=sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1 \ --hash=sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46 \ --hash=sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc \ --hash=sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee \ --hash=sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900 \ --hash=sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5 \ --hash=sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea \ --hash=sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f \ --hash=sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5 \ --hash=sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e \ --hash=sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a \ --hash=sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a \ --hash=sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b \ --hash=sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4 \ --hash=sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff \ --hash=sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2 \ --hash=sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46 \ --hash=sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b \ --hash=sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5 \ --hash=sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5 \ --hash=sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab \ --hash=sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd \ --hash=sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68 mdit-py-plugins==0.4.1 \ --hash=sha256:1020dfe4e6bfc2c79fb49ae4e3f5b297f5ccd20f010187acc52af2921e27dc6a \ --hash=sha256:834b8ac23d1cd60cec703646ffd22ae97b7955a6d596eb1d304be1e251ae499c mdurl==0.1.2 \ --hash=sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 \ --hash=sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba myst-parser==3.0.1 \ --hash=sha256:6457aaa33a5d474aca678b8ead9b3dc298e89c68e67012e73146ea6fd54babf1 \ --hash=sha256:88f0cb406cb363b077d176b51c476f62d60604d68a8dcdf4832e080441301a87 packaging==24.0 \ --hash=sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5 \ --hash=sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9 pygments==2.18.0 \ --hash=sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199 \ --hash=sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a pypandoc-binary==1.13 \ --hash=sha256:11a2497320eb3dccb74de3c67b6df3e5d3f66cdc2a36a67e9a871708f7e48412 \ --hash=sha256:21ef0345726d36fc45a50211320614daf2caede684b0d0963ce8738292809746 \ --hash=sha256:2915f52e4632bd2d0a8fcd2f7e7dfc2ea19b4e1a280fcbc2ddcd142713c4ff12 \ --hash=sha256:3881aa7c84faec2007c0ae4466d3a1cfc93171206b8540f2defa8ea971bf6fd6 \ --hash=sha256:67c0c7af811bcf3cd4f3221be756a4975ec35b2d7df89d8de4313a8caa2cd54f \ --hash=sha256:9455fdd9521cbf4b56d79a56b806afa94c8c22f3c8ef878536e58d941a70f6d6 \ --hash=sha256:946666388eb79b307d7f497b3b33045ef807750f8e5ef3440e0ba3bbab698044 pytz==2024.1 \ --hash=sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812 \ --hash=sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319 pyyaml==6.0.1 \ --hash=sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5 \ --hash=sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc \ --hash=sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df \ --hash=sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741 \ --hash=sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206 \ --hash=sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595 \ --hash=sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62 \ --hash=sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696 \ --hash=sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290 \ --hash=sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9 \ --hash=sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d \ --hash=sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6 \ --hash=sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486 \ --hash=sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6 \ --hash=sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007 \ --hash=sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938 \ --hash=sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0 \ --hash=sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735 \ --hash=sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d \ --hash=sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28 \ --hash=sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4 \ --hash=sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8 \ --hash=sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef \ --hash=sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5 \ --hash=sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0 \ --hash=sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515 \ --hash=sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c \ --hash=sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924 \ --hash=sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34 \ --hash=sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43 \ --hash=sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859 \ --hash=sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673 \ --hash=sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54 \ --hash=sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a \ --hash=sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b \ --hash=sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab \ --hash=sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c \ --hash=sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d \ --hash=sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f requests==2.32.2 \ --hash=sha256:dd951ff5ecf3e3b3aa26b40703ba77495dab41da839ae72ef3c8e5d8e2433289 \ --hash=sha256:fc06670dd0ed212426dfeb94fc1b983d917c4f9847c863f313c9dfaaffb7c23c snowballstemmer==2.2.0 \ --hash=sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1 \ --hash=sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a soupsieve==2.5 \ --hash=sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690 \ --hash=sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7 sphinx==7.1.2 \ --hash=sha256:780f4d32f1d7d1126576e0e5ecc19dc32ab76cd24e950228dcf7b1f6d3d9e22f \ --hash=sha256:d170a81825b2fcacb6dfd5a0d7f578a053e45d3f2b153fecc948c37344eb4cbe sphinx-basic-ng==1.0.0b2 \ --hash=sha256:9ec55a47c90c8c002b5960c57492ec3021f5193cb26cebc2dc4ea226848651c9 \ --hash=sha256:eb09aedbabfb650607e9b4b68c9d240b90b1e1be221d6ad71d61c52e29f7932b sphinxcontrib-applehelp==1.0.4 \ --hash=sha256:29d341f67fb0f6f586b23ad80e072c8e6ad0b48417db2bde114a4c9746feb228 \ --hash=sha256:828f867945bbe39817c210a1abfd1bc4895c8b73fcaade56d45357a348a07d7e sphinxcontrib-devhelp==1.0.2 \ --hash=sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e \ --hash=sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4 sphinxcontrib-htmlhelp==2.0.1 \ --hash=sha256:0cbdd302815330058422b98a113195c9249825d681e18f11e8b1f78a2f11efff \ --hash=sha256:c38cb46dccf316c79de6e5515e1770414b797162b23cd3d06e67020e1d2a6903 sphinxcontrib-jsmath==1.0.1 \ --hash=sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178 \ --hash=sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8 sphinxcontrib-qthelp==1.0.3 \ --hash=sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72 \ --hash=sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6 sphinxcontrib-serializinghtml==1.1.5 \ --hash=sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd \ --hash=sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952 urllib3==2.2.1 \ --hash=sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d \ --hash=sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19 zipp==3.18.2 \ --hash=sha256:6278d9ddbcfb1f1089a88fde84481528b07b0e10474e09dcfe53dad4069fa059 \ --hash=sha256:dce197b859eb796242b0622af1b8beb0a722d52aa2f57133ead08edd5bf5374e validators-0.28.3/package/requirements.tooling.txt000066400000000000000000000154021462425114700223150ustar00rootroot00000000000000# This file is @generated by PDM. # Please do not edit it manually. black==24.4.2 \ --hash=sha256:257d724c2c9b1660f353b36c802ccece186a30accc7742c176d29c146df6e474 \ --hash=sha256:37aae07b029fa0174d39daf02748b379399b909652a806e5708199bd93899da1 \ --hash=sha256:415e686e87dbbe6f4cd5ef0fbf764af7b89f9057b97c908742b6008cc554b9c0 \ --hash=sha256:48a85f2cb5e6799a9ef05347b476cce6c182d6c71ee36925a6c194d074336ef8 \ --hash=sha256:7768a0dbf16a39aa5e9a3ded568bb545c8c2727396d063bbaf847df05b08cd96 \ --hash=sha256:7e122b1c4fb252fd85df3ca93578732b4749d9be076593076ef4d07a0233c3e1 \ --hash=sha256:88c57dc656038f1ab9f92b3eb5335ee9b021412feaa46330d5eba4e51fe49b04 \ --hash=sha256:8e537d281831ad0e71007dcdcbe50a71470b978c453fa41ce77186bbe0ed6021 \ --hash=sha256:98e123f1d5cfd42f886624d84464f7756f60ff6eab89ae845210631714f6db94 \ --hash=sha256:accf49e151c8ed2c0cdc528691838afd217c50412534e876a19270fea1e28e2d \ --hash=sha256:b1530ae42e9d6d5b670a34db49a94115a64596bc77710b1d05e9801e62ca0a7c \ --hash=sha256:b9176b9832e84308818a99a561e90aa479e73c523b3f77afd07913380ae2eab7 \ --hash=sha256:bdde6f877a18f24844e381d45e9947a49e97933573ac9d4345399be37621e26c \ --hash=sha256:be8bef99eb46d5021bf053114442914baeb3649a89dc5f3a555c88737e5e98fc \ --hash=sha256:bf10f7310db693bb62692609b397e8d67257c55f949abde4c67f9cc574492cc7 \ --hash=sha256:c872b53057f000085da66a19c55d68f6f8ddcac2642392ad3a355878406fbd4d \ --hash=sha256:d36ed1124bb81b32f8614555b34cc4259c3fbc7eec17870e8ff8ded335b58d8c \ --hash=sha256:da33a1a5e49c4122ccdfd56cd021ff1ebc4a1ec4e2d01594fef9b6f267a9e741 \ --hash=sha256:dd1b5a14e417189db4c7b64a6540f31730713d173f0b63e55fabd52d61d8fdce \ --hash=sha256:e151054aa00bad1f4e1f04919542885f89f5f7d086b8a59e5000e6c616896ffb \ --hash=sha256:eaea3008c281f1038edb473c1aa8ed8143a5535ff18f978a318f10302b254063 \ --hash=sha256:ef703f83fc32e131e9bcc0a5094cfe85599e7109f896fe8bc96cc402f3eb4b6e click==8.1.7 \ --hash=sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28 \ --hash=sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de colorama==0.4.6 \ --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 exceptiongroup==1.2.1; python_version < "3.11" \ --hash=sha256:5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad \ --hash=sha256:a4785e48b045528f5bfe627b6ad554ff32def154f42372786903b7abcfe1aa16 iniconfig==2.0.0 \ --hash=sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3 \ --hash=sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374 mypy-extensions==1.0.0 \ --hash=sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d \ --hash=sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782 nodeenv==1.8.0 \ --hash=sha256:d51e0c37e64fbf47d017feac3145cdbb58836d7eee8c6f6d3b6880c5456227d2 \ --hash=sha256:df865724bb3c3adc86b3876fa209771517b0cfe596beff01a92700e0e8be4cec packaging==24.0 \ --hash=sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5 \ --hash=sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9 pathspec==0.12.1 \ --hash=sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08 \ --hash=sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712 platformdirs==4.2.2 \ --hash=sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee \ --hash=sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3 pluggy==1.5.0 \ --hash=sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1 \ --hash=sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669 pypandoc-binary==1.13 \ --hash=sha256:11a2497320eb3dccb74de3c67b6df3e5d3f66cdc2a36a67e9a871708f7e48412 \ --hash=sha256:21ef0345726d36fc45a50211320614daf2caede684b0d0963ce8738292809746 \ --hash=sha256:2915f52e4632bd2d0a8fcd2f7e7dfc2ea19b4e1a280fcbc2ddcd142713c4ff12 \ --hash=sha256:3881aa7c84faec2007c0ae4466d3a1cfc93171206b8540f2defa8ea971bf6fd6 \ --hash=sha256:67c0c7af811bcf3cd4f3221be756a4975ec35b2d7df89d8de4313a8caa2cd54f \ --hash=sha256:9455fdd9521cbf4b56d79a56b806afa94c8c22f3c8ef878536e58d941a70f6d6 \ --hash=sha256:946666388eb79b307d7f497b3b33045ef807750f8e5ef3440e0ba3bbab698044 pyright==1.1.364 \ --hash=sha256:612a2106a4078ec57efc22b5620729e9bdf4a3c17caba013b534bd33f7d08e5a \ --hash=sha256:865f1e02873c5dc7427c95acf53659a118574010e6fb364e27e47ec5c46a9f26 pytest==8.2.1 \ --hash=sha256:5046e5b46d8e4cac199c373041f26be56fdb81eb4e67dc11d4e10811fc3408fd \ --hash=sha256:faccc5d332b8c3719f40283d0d44aa5cf101cec36f88cde9ed8f2bc0538612b1 ruff==0.4.5 \ --hash=sha256:1169e47e9c4136c997f08f9857ae889d614c5035d87d38fda9b44b4338909cdf \ --hash=sha256:25f483ad9d50b00e7fd577f6d0305aa18494c6af139bce7319c68a17180087f4 \ --hash=sha256:286eabd47e7d4d521d199cab84deca135557e6d1e0f0d01c29e757c3cb151b54 \ --hash=sha256:441dab55c568e38d02bbda68a926a3d0b54f5510095c9de7f95e47a39e0168aa \ --hash=sha256:63fde3bf6f3ad4e990357af1d30e8ba2730860a954ea9282c95fc0846f5f64af \ --hash=sha256:6e1b139b45e2911419044237d90b60e472f57285950e1492c757dfc88259bb06 \ --hash=sha256:755ac9ac2598a941512fc36a9070a13c88d72ff874a9781493eb237ab02d75df \ --hash=sha256:75a426506a183d9201e7e5664de3f6b414ad3850d7625764106f7b6d0486f0a1 \ --hash=sha256:78e3ba4620dee27f76bbcad97067766026c918ba0f2d035c2fc25cbdd04d9c97 \ --hash=sha256:84dd157474e16e3a82745d2afa1016c17d27cb5d52b12e3d45d418bcc6d49264 \ --hash=sha256:8f58e615dec58b1a6b291769b559e12fdffb53cc4187160a2fc83250eaf54e96 \ --hash=sha256:9d15de3425f53161b3f5a5658d4522e4eee5ea002bf2ac7aa380743dd9ad5fba \ --hash=sha256:a6f29a8221d2e3d85ff0c7b4371c0e37b39c87732c969b4d90f3dad2e721c5b1 \ --hash=sha256:aed8166c18b1a169a5d3ec28a49b43340949e400665555b51ee06f22813ef062 \ --hash=sha256:b0b03c619d2b4350b4a27e34fd2ac64d0dabe1afbf43de57d0f9d8a05ecffa45 \ --hash=sha256:d6ef817124d72b54cc923f3444828ba24fa45c3164bc9e8f1813db2f3d3a8a11 \ --hash=sha256:f4b02a65985be2b34b170025a8b92449088ce61e33e69956ce4d316c0fe7cce0 setuptools==70.0.0 \ --hash=sha256:54faa7f2e8d2d11bcd2c07bed282eef1046b5c080d1c32add737d7b5817b1ad4 \ --hash=sha256:f211a66637b8fa059bb28183da127d4e86396c991a942b028c6650d4319c3fd0 tomli==2.0.1; python_version < "3.11" \ --hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \ --hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f typing-extensions==4.12.0; python_version < "3.11" \ --hash=sha256:8cbcdc8606ebcb0d95453ad7dc5065e6237b6aa230a31e81d0f440c30fed5fd8 \ --hash=sha256:b349c66bea9016ac22978d800cfff206d5f9816951f12a7d0ec5578b0a819594 validators-0.28.3/package/roll.ps1000077500000000000000000000026041462425114700167570ustar00rootroot00000000000000#!/bin/pwsh $ErrorActionPreference = "Stop" # Check if CI environment variable is set to "false" if ($null -eq $env:CI || "false" -eq $env:CI) { # tooling pdm export --group tooling -f requirements -o package/requirements.tooling.txt # mkdocs pdm export --group docs-online -f requirements -o package/requirements.mkdocs.txt # sphinx pdm export --group docs-offline -f requirements -o package/requirements.sphinx.txt # create environment variable $env:CI = "true"; } # Cleanup directories $venv_dir = "./.venv.dev" $directories = @($venv_dir, "./build", "./dist") foreach ($dir in $directories) { if (Test-Path $dir -PathType Container) { Remove-Item $dir -Recurse -Force } } # Create venv python -m venv $venv_dir $bin_path = "Scripts" if ($IsLinux || $IsMacOS) { $bin_path = "bin" } # Upgrade pip & $venv_dir\$bin_path\python -m pip install --upgrade pip # Install the current package & $venv_dir\$bin_path\pip install . # Install sphinx requirements & $venv_dir\$bin_path\pip install -r package/requirements.sphinx.txt # Install build tool & $venv_dir\$bin_path\pip install build # Activate virtual environment . $venv_dir\$bin_path\Activate.ps1 # Run export script python package/export pkg # Deactivate virtual environment deactivate # delete environment variable $env:CI = ""; validators-0.28.3/package/roll.sh000077500000000000000000000023171462425114700166670ustar00rootroot00000000000000#!/bin/bash set -e # Check if CI environment variable is set to "false" # or set to empty string or not set at all. # Using the wrong way see: https://stackoverflow.com/a/13864829 if [ -z "$CI" ] || [ "$CI" = "false" ]; then # tooling pdm export --group tooling -f requirements -o package/requirements.tooling.txt # mkdocs pdm export --group docs-online -f requirements -o package/requirements.mkdocs.txt # sphinx pdm export --group docs-offline -f requirements -o package/requirements.sphinx.txt export CI=true fi # Cleanup directories venv_dir="./.venv.dev" directories=("$venv_dir" "./build" "./dist") for dir in "${directories[@]}"; do if [ -d "$dir" ]; then rm -rf "$dir" fi done # Create venv python -m venv $venv_dir # Upgrade pip $venv_dir/bin/python -m pip install --upgrade pip # Install the current package $venv_dir/bin/pip install . # Install sphinx requirements $venv_dir/bin/pip install -r package/requirements.sphinx.txt # Install build tool $venv_dir/bin/pip install build # Activate virtual environment . $venv_dir/bin/activate # Run export script python package/export pkg # Deactivate virtual environment deactivate # delete environment variable unset CI validators-0.28.3/pdm.lock000066400000000000000000002720711462425114700154250ustar00rootroot00000000000000# This file is @generated by PDM. # It is not intended for manual editing. [metadata] groups = ["default", "package", "docs-online", "tooling", "runner", "sast", "docs-offline"] strategy = ["cross_platform", "inherit_metadata"] lock_version = "4.4.1" content_hash = "sha256:5b8fd4acbb36295cb541cd2fb6952362eed3451f427007bc26a47c53c8f874c2" [[package]] name = "alabaster" version = "0.7.13" requires_python = ">=3.6" summary = "A configurable sidebar-enabled Sphinx theme" groups = ["docs-offline"] files = [ {file = "alabaster-0.7.13-py3-none-any.whl", hash = "sha256:1ee19aca801bbabb5ba3f5f258e4422dfa86f82f3e9cefb0859b283cdd7f62a3"}, {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"}, ] [[package]] name = "astunparse" version = "1.6.3" summary = "An AST unparser for Python" groups = ["docs-online"] marker = "python_version < \"3.9\"" dependencies = [ "six<2.0,>=1.6.1", "wheel<1.0,>=0.23.0", ] files = [ {file = "astunparse-1.6.3-py2.py3-none-any.whl", hash = "sha256:c2652417f2c8b5bb325c885ae329bdf3f86424075c4fd1a128674bc6fba4b8e8"}, {file = "astunparse-1.6.3.tar.gz", hash = "sha256:5ad93a8456f0d084c3456d059fd9a92cce667963232cbf763eac3bc5b7940872"}, ] [[package]] name = "babel" version = "2.15.0" requires_python = ">=3.8" summary = "Internationalization utilities" groups = ["docs-offline", "docs-online"] dependencies = [ "pytz>=2015.7; python_version < \"3.9\"", ] files = [ {file = "Babel-2.15.0-py3-none-any.whl", hash = "sha256:08706bdad8d0a3413266ab61bd6c34d0c28d6e1e7badf40a2cebe67644e2e1fb"}, {file = "babel-2.15.0.tar.gz", hash = "sha256:8daf0e265d05768bc6c7a314cf1321e9a123afc328cc635c18622a2f30a04413"}, ] [[package]] name = "bandit" version = "1.7.8" requires_python = ">=3.8" summary = "Security oriented static analyser for python code." groups = ["sast"] dependencies = [ "PyYAML>=5.3.1", "colorama>=0.3.9; platform_system == \"Windows\"", "rich", "stevedore>=1.20.0", ] files = [ {file = "bandit-1.7.8-py3-none-any.whl", hash = "sha256:509f7af645bc0cd8fd4587abc1a038fc795636671ee8204d502b933aee44f381"}, {file = "bandit-1.7.8.tar.gz", hash = "sha256:36de50f720856ab24a24dbaa5fee2c66050ed97c1477e0a1159deab1775eab6b"}, ] [[package]] name = "bandit" version = "1.7.8" extras = ["toml"] requires_python = ">=3.8" summary = "Security oriented static analyser for python code." groups = ["sast"] dependencies = [ "bandit==1.7.8", "tomli>=1.1.0; python_version < \"3.11\"", ] files = [ {file = "bandit-1.7.8-py3-none-any.whl", hash = "sha256:509f7af645bc0cd8fd4587abc1a038fc795636671ee8204d502b933aee44f381"}, {file = "bandit-1.7.8.tar.gz", hash = "sha256:36de50f720856ab24a24dbaa5fee2c66050ed97c1477e0a1159deab1775eab6b"}, ] [[package]] name = "beautifulsoup4" version = "4.12.3" requires_python = ">=3.6.0" summary = "Screen-scraping library" groups = ["docs-offline"] dependencies = [ "soupsieve>1.2", ] files = [ {file = "beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed"}, {file = "beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051"}, ] [[package]] name = "black" version = "24.4.2" requires_python = ">=3.8" summary = "The uncompromising code formatter." groups = ["tooling"] dependencies = [ "click>=8.0.0", "mypy-extensions>=0.4.3", "packaging>=22.0", "pathspec>=0.9.0", "platformdirs>=2", "tomli>=1.1.0; python_version < \"3.11\"", "typing-extensions>=4.0.1; python_version < \"3.11\"", ] files = [ {file = "black-24.4.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dd1b5a14e417189db4c7b64a6540f31730713d173f0b63e55fabd52d61d8fdce"}, {file = "black-24.4.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e537d281831ad0e71007dcdcbe50a71470b978c453fa41ce77186bbe0ed6021"}, {file = "black-24.4.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eaea3008c281f1038edb473c1aa8ed8143a5535ff18f978a318f10302b254063"}, {file = "black-24.4.2-cp310-cp310-win_amd64.whl", hash = "sha256:7768a0dbf16a39aa5e9a3ded568bb545c8c2727396d063bbaf847df05b08cd96"}, {file = "black-24.4.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:257d724c2c9b1660f353b36c802ccece186a30accc7742c176d29c146df6e474"}, {file = "black-24.4.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bdde6f877a18f24844e381d45e9947a49e97933573ac9d4345399be37621e26c"}, {file = "black-24.4.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e151054aa00bad1f4e1f04919542885f89f5f7d086b8a59e5000e6c616896ffb"}, {file = "black-24.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:7e122b1c4fb252fd85df3ca93578732b4749d9be076593076ef4d07a0233c3e1"}, {file = "black-24.4.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:accf49e151c8ed2c0cdc528691838afd217c50412534e876a19270fea1e28e2d"}, {file = "black-24.4.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:88c57dc656038f1ab9f92b3eb5335ee9b021412feaa46330d5eba4e51fe49b04"}, {file = "black-24.4.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:be8bef99eb46d5021bf053114442914baeb3649a89dc5f3a555c88737e5e98fc"}, {file = "black-24.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:415e686e87dbbe6f4cd5ef0fbf764af7b89f9057b97c908742b6008cc554b9c0"}, {file = "black-24.4.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bf10f7310db693bb62692609b397e8d67257c55f949abde4c67f9cc574492cc7"}, {file = "black-24.4.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:98e123f1d5cfd42f886624d84464f7756f60ff6eab89ae845210631714f6db94"}, {file = "black-24.4.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48a85f2cb5e6799a9ef05347b476cce6c182d6c71ee36925a6c194d074336ef8"}, {file = "black-24.4.2-cp38-cp38-win_amd64.whl", hash = "sha256:b1530ae42e9d6d5b670a34db49a94115a64596bc77710b1d05e9801e62ca0a7c"}, {file = "black-24.4.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:37aae07b029fa0174d39daf02748b379399b909652a806e5708199bd93899da1"}, {file = "black-24.4.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:da33a1a5e49c4122ccdfd56cd021ff1ebc4a1ec4e2d01594fef9b6f267a9e741"}, {file = "black-24.4.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef703f83fc32e131e9bcc0a5094cfe85599e7109f896fe8bc96cc402f3eb4b6e"}, {file = "black-24.4.2-cp39-cp39-win_amd64.whl", hash = "sha256:b9176b9832e84308818a99a561e90aa479e73c523b3f77afd07913380ae2eab7"}, {file = "black-24.4.2-py3-none-any.whl", hash = "sha256:d36ed1124bb81b32f8614555b34cc4259c3fbc7eec17870e8ff8ded335b58d8c"}, {file = "black-24.4.2.tar.gz", hash = "sha256:c872b53057f000085da66a19c55d68f6f8ddcac2642392ad3a355878406fbd4d"}, ] [[package]] name = "build" version = "1.2.1" requires_python = ">=3.8" summary = "A simple, correct Python build frontend" groups = ["package"] dependencies = [ "colorama; os_name == \"nt\"", "importlib-metadata>=4.6; python_full_version < \"3.10.2\"", "packaging>=19.1", "pyproject-hooks", "tomli>=1.1.0; python_version < \"3.11\"", ] files = [ {file = "build-1.2.1-py3-none-any.whl", hash = "sha256:75e10f767a433d9a86e50d83f418e83efc18ede923ee5ff7df93b6cb0306c5d4"}, {file = "build-1.2.1.tar.gz", hash = "sha256:526263f4870c26f26c433545579475377b2b7588b6f1eac76a001e873ae3e19d"}, ] [[package]] name = "cachetools" version = "5.3.3" requires_python = ">=3.7" summary = "Extensible memoizing collections and decorators" groups = ["runner"] files = [ {file = "cachetools-5.3.3-py3-none-any.whl", hash = "sha256:0abad1021d3f8325b2fc1d2e9c8b9c9d57b04c3932657a72465447332c24d945"}, {file = "cachetools-5.3.3.tar.gz", hash = "sha256:ba29e2dfa0b8b556606f097407ed1aa62080ee108ab0dc5ec9d6a723a007d105"}, ] [[package]] name = "certifi" version = "2024.2.2" requires_python = ">=3.6" summary = "Python package for providing Mozilla's CA Bundle." groups = ["docs-offline", "docs-online"] files = [ {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"}, {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, ] [[package]] name = "chardet" version = "5.2.0" requires_python = ">=3.7" summary = "Universal encoding detector for Python 3" groups = ["runner"] files = [ {file = "chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970"}, {file = "chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7"}, ] [[package]] name = "charset-normalizer" version = "3.3.2" requires_python = ">=3.7.0" summary = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." groups = ["docs-offline", "docs-online"] files = [ {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, ] [[package]] name = "click" version = "8.1.7" requires_python = ">=3.7" summary = "Composable command line interface toolkit" groups = ["docs-online", "tooling"] dependencies = [ "colorama; platform_system == \"Windows\"", ] files = [ {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, ] [[package]] name = "colorama" version = "0.4.6" requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" summary = "Cross-platform colored terminal text." groups = ["docs-offline", "docs-online", "package", "runner", "sast", "tooling"] files = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] [[package]] name = "distlib" version = "0.3.8" summary = "Distribution utilities" groups = ["runner"] files = [ {file = "distlib-0.3.8-py2.py3-none-any.whl", hash = "sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784"}, {file = "distlib-0.3.8.tar.gz", hash = "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64"}, ] [[package]] name = "docutils" version = "0.20.1" requires_python = ">=3.7" summary = "Docutils -- Python Documentation Utilities" groups = ["docs-offline"] files = [ {file = "docutils-0.20.1-py3-none-any.whl", hash = "sha256:96f387a2c5562db4476f09f13bbab2192e764cac08ebbf3a34a95d9b1e4a59d6"}, {file = "docutils-0.20.1.tar.gz", hash = "sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b"}, ] [[package]] name = "exceptiongroup" version = "1.2.1" requires_python = ">=3.7" summary = "Backport of PEP 654 (exception groups)" groups = ["tooling"] marker = "python_version < \"3.11\"" files = [ {file = "exceptiongroup-1.2.1-py3-none-any.whl", hash = "sha256:5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad"}, {file = "exceptiongroup-1.2.1.tar.gz", hash = "sha256:a4785e48b045528f5bfe627b6ad554ff32def154f42372786903b7abcfe1aa16"}, ] [[package]] name = "filelock" version = "3.14.0" requires_python = ">=3.8" summary = "A platform independent file lock." groups = ["runner"] files = [ {file = "filelock-3.14.0-py3-none-any.whl", hash = "sha256:43339835842f110ca7ae60f1e1c160714c5a6afd15a2873419ab185334975c0f"}, {file = "filelock-3.14.0.tar.gz", hash = "sha256:6ea72da3be9b8c82afd3edcf99f2fffbb5076335a5ae4d03248bb5b6c3eae78a"}, ] [[package]] name = "furo" version = "2024.5.6" requires_python = ">=3.8" summary = "A clean customisable Sphinx documentation theme." groups = ["docs-offline"] dependencies = [ "beautifulsoup4", "pygments>=2.7", "sphinx-basic-ng>=1.0.0.beta2", "sphinx<8.0,>=6.0", ] files = [ {file = "furo-2024.5.6-py3-none-any.whl", hash = "sha256:490a00d08c0a37ecc90de03ae9227e8eb5d6f7f750edf9807f398a2bdf2358de"}, {file = "furo-2024.5.6.tar.gz", hash = "sha256:81f205a6605ebccbb883350432b4831c0196dd3d1bc92f61e1f459045b3d2b0b"}, ] [[package]] name = "ghp-import" version = "2.1.0" summary = "Copy your docs directly to the gh-pages branch." groups = ["docs-online"] dependencies = [ "python-dateutil>=2.8.1", ] files = [ {file = "ghp-import-2.1.0.tar.gz", hash = "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343"}, {file = "ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619"}, ] [[package]] name = "gitdb" version = "4.0.11" requires_python = ">=3.7" summary = "Git Object Database" groups = ["docs-online"] dependencies = [ "smmap<6,>=3.0.1", ] files = [ {file = "gitdb-4.0.11-py3-none-any.whl", hash = "sha256:81a3407ddd2ee8df444cbacea00e2d038e40150acfa3001696fe0dcf1d3adfa4"}, {file = "gitdb-4.0.11.tar.gz", hash = "sha256:bf5421126136d6d0af55bc1e7c1af1c397a34f5b7bd79e776cd3e89785c2b04b"}, ] [[package]] name = "gitpython" version = "3.1.43" requires_python = ">=3.7" summary = "GitPython is a Python library used to interact with Git repositories" groups = ["docs-online"] dependencies = [ "gitdb<5,>=4.0.1", ] files = [ {file = "GitPython-3.1.43-py3-none-any.whl", hash = "sha256:eec7ec56b92aad751f9912a73404bc02ba212a23adb2c7098ee668417051a1ff"}, {file = "GitPython-3.1.43.tar.gz", hash = "sha256:35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c"}, ] [[package]] name = "griffe" version = "0.45.2" requires_python = ">=3.8" summary = "Signatures for entire Python programs. Extract the structure, the frame, the skeleton of your project, to generate API documentation or find breaking changes in your API." groups = ["docs-online"] dependencies = [ "astunparse>=1.6; python_version < \"3.9\"", "colorama>=0.4", ] files = [ {file = "griffe-0.45.2-py3-none-any.whl", hash = "sha256:297ec8530d0c68e5b98ff86fb588ebc3aa3559bb5dc21f3caea8d9542a350133"}, {file = "griffe-0.45.2.tar.gz", hash = "sha256:83ce7dcaafd8cb7f43cbf1a455155015a1eb624b1ffd93249e5e1c4a22b2fdb2"}, ] [[package]] name = "idna" version = "3.7" requires_python = ">=3.5" summary = "Internationalized Domain Names in Applications (IDNA)" groups = ["docs-offline", "docs-online"] files = [ {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, ] [[package]] name = "imagesize" version = "1.4.1" requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" summary = "Getting image size from png/jpeg/jpeg2000/gif file" groups = ["docs-offline"] files = [ {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"}, {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"}, ] [[package]] name = "importlib-metadata" version = "7.1.0" requires_python = ">=3.8" summary = "Read metadata from Python packages" groups = ["docs-offline", "docs-online", "package"] dependencies = [ "zipp>=0.5", ] files = [ {file = "importlib_metadata-7.1.0-py3-none-any.whl", hash = "sha256:30962b96c0c223483ed6cc7280e7f0199feb01a0e40cfae4d4450fc6fab1f570"}, {file = "importlib_metadata-7.1.0.tar.gz", hash = "sha256:b78938b926ee8d5f020fc4772d487045805a55ddbad2ecf21c6d60938dc7fcd2"}, ] [[package]] name = "importlib-resources" version = "6.4.0" requires_python = ">=3.8" summary = "Read resources from Python packages" groups = ["docs-online"] dependencies = [ "zipp>=3.1.0; python_version < \"3.10\"", ] files = [ {file = "importlib_resources-6.4.0-py3-none-any.whl", hash = "sha256:50d10f043df931902d4194ea07ec57960f66a80449ff867bfe782b4c486ba78c"}, {file = "importlib_resources-6.4.0.tar.gz", hash = "sha256:cdb2b453b8046ca4e3798eb1d84f3cce1446a0e8e7b5ef4efb600f19fc398145"}, ] [[package]] name = "iniconfig" version = "2.0.0" requires_python = ">=3.7" summary = "brain-dead simple config-ini parsing" groups = ["tooling"] files = [ {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, ] [[package]] name = "jinja2" version = "3.1.4" requires_python = ">=3.7" summary = "A very fast and expressive template engine." groups = ["docs-offline", "docs-online"] dependencies = [ "MarkupSafe>=2.0", ] files = [ {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, ] [[package]] name = "markdown" version = "3.6" requires_python = ">=3.8" summary = "Python implementation of John Gruber's Markdown." groups = ["docs-online"] dependencies = [ "importlib-metadata>=4.4; python_version < \"3.10\"", ] files = [ {file = "Markdown-3.6-py3-none-any.whl", hash = "sha256:48f276f4d8cfb8ce6527c8f79e2ee29708508bf4d40aa410fbc3b4ee832c850f"}, {file = "Markdown-3.6.tar.gz", hash = "sha256:ed4f41f6daecbeeb96e576ce414c41d2d876daa9a16cb35fa8ed8c2ddfad0224"}, ] [[package]] name = "markdown-it-py" version = "3.0.0" requires_python = ">=3.8" summary = "Python port of markdown-it. Markdown parsing, done right!" groups = ["docs-offline", "sast"] dependencies = [ "mdurl~=0.1", ] files = [ {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, ] [[package]] name = "markupsafe" version = "2.1.5" requires_python = ">=3.7" summary = "Safely add untrusted strings to HTML/XML markup." groups = ["docs-offline", "docs-online"] files = [ {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, ] [[package]] name = "mdit-py-plugins" version = "0.4.1" requires_python = ">=3.8" summary = "Collection of plugins for markdown-it-py" groups = ["docs-offline"] dependencies = [ "markdown-it-py<4.0.0,>=1.0.0", ] files = [ {file = "mdit_py_plugins-0.4.1-py3-none-any.whl", hash = "sha256:1020dfe4e6bfc2c79fb49ae4e3f5b297f5ccd20f010187acc52af2921e27dc6a"}, {file = "mdit_py_plugins-0.4.1.tar.gz", hash = "sha256:834b8ac23d1cd60cec703646ffd22ae97b7955a6d596eb1d304be1e251ae499c"}, ] [[package]] name = "mdurl" version = "0.1.2" requires_python = ">=3.7" summary = "Markdown URL utilities" groups = ["docs-offline", "sast"] files = [ {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, ] [[package]] name = "mergedeep" version = "1.3.4" requires_python = ">=3.6" summary = "A deep merge function for 🐍." groups = ["docs-online"] files = [ {file = "mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307"}, {file = "mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8"}, ] [[package]] name = "mike" version = "2.1.1" summary = "Manage multiple versions of your MkDocs-powered documentation" groups = ["docs-online"] dependencies = [ "importlib-metadata", "importlib-resources", "jinja2>=2.7", "mkdocs>=1.0", "pyparsing>=3.0", "pyyaml-env-tag", "pyyaml>=5.1", "verspec", ] files = [ {file = "mike-2.1.1-py3-none-any.whl", hash = "sha256:0b1d01a397a423284593eeb1b5f3194e37169488f929b860c9bfe95c0d5efb79"}, {file = "mike-2.1.1.tar.gz", hash = "sha256:f39ed39f3737da83ad0adc33e9f885092ed27f8c9e7ff0523add0480352a2c22"}, ] [[package]] name = "mkdocs" version = "1.6.0" requires_python = ">=3.8" summary = "Project documentation with Markdown." groups = ["docs-online"] dependencies = [ "click>=7.0", "colorama>=0.4; platform_system == \"Windows\"", "ghp-import>=1.0", "importlib-metadata>=4.4; python_version < \"3.10\"", "jinja2>=2.11.1", "markdown>=3.3.6", "markupsafe>=2.0.1", "mergedeep>=1.3.4", "mkdocs-get-deps>=0.2.0", "packaging>=20.5", "pathspec>=0.11.1", "pyyaml-env-tag>=0.1", "pyyaml>=5.1", "watchdog>=2.0", ] files = [ {file = "mkdocs-1.6.0-py3-none-any.whl", hash = "sha256:1eb5cb7676b7d89323e62b56235010216319217d4af5ddc543a91beb8d125ea7"}, {file = "mkdocs-1.6.0.tar.gz", hash = "sha256:a73f735824ef83a4f3bcb7a231dcab23f5a838f88b7efc54a0eef5fbdbc3c512"}, ] [[package]] name = "mkdocs-autorefs" version = "1.0.1" requires_python = ">=3.8" summary = "Automatically link across pages in MkDocs." groups = ["docs-online"] dependencies = [ "Markdown>=3.3", "markupsafe>=2.0.1", "mkdocs>=1.1", ] files = [ {file = "mkdocs_autorefs-1.0.1-py3-none-any.whl", hash = "sha256:aacdfae1ab197780fb7a2dac92ad8a3d8f7ca8049a9cbe56a4218cd52e8da570"}, {file = "mkdocs_autorefs-1.0.1.tar.gz", hash = "sha256:f684edf847eced40b570b57846b15f0bf57fb93ac2c510450775dcf16accb971"}, ] [[package]] name = "mkdocs-get-deps" version = "0.2.0" requires_python = ">=3.8" summary = "MkDocs extension that lists all dependencies according to a mkdocs.yml file" groups = ["docs-online"] dependencies = [ "importlib-metadata>=4.3; python_version < \"3.10\"", "mergedeep>=1.3.4", "platformdirs>=2.2.0", "pyyaml>=5.1", ] files = [ {file = "mkdocs_get_deps-0.2.0-py3-none-any.whl", hash = "sha256:2bf11d0b133e77a0dd036abeeb06dec8775e46efa526dc70667d8863eefc6134"}, {file = "mkdocs_get_deps-0.2.0.tar.gz", hash = "sha256:162b3d129c7fad9b19abfdcb9c1458a651628e4b1dea628ac68790fb3061c60c"}, ] [[package]] name = "mkdocs-git-revision-date-localized-plugin" version = "1.2.5" requires_python = ">=3.8" summary = "Mkdocs plugin that enables displaying the localized date of the last git modification of a markdown file." groups = ["docs-online"] dependencies = [ "GitPython", "babel>=2.7.0", "mkdocs>=1.0", "pytz", ] files = [ {file = "mkdocs_git_revision_date_localized_plugin-1.2.5-py3-none-any.whl", hash = "sha256:d796a18b07cfcdb154c133e3ec099d2bb5f38389e4fd54d3eb516a8a736815b8"}, {file = "mkdocs_git_revision_date_localized_plugin-1.2.5.tar.gz", hash = "sha256:0c439816d9d0dba48e027d9d074b2b9f1d7cd179f74ba46b51e4da7bb3dc4b9b"}, ] [[package]] name = "mkdocs-material" version = "9.5.24" requires_python = ">=3.8" summary = "Documentation that simply works" groups = ["docs-online"] dependencies = [ "babel~=2.10", "colorama~=0.4", "jinja2~=3.0", "markdown~=3.2", "mkdocs-material-extensions~=1.3", "mkdocs~=1.6", "paginate~=0.5", "pygments~=2.16", "pymdown-extensions~=10.2", "regex>=2022.4", "requests~=2.26", ] files = [ {file = "mkdocs_material-9.5.24-py3-none-any.whl", hash = "sha256:e12cd75954c535b61e716f359cf2a5056bf4514889d17161fdebd5df4b0153c6"}, {file = "mkdocs_material-9.5.24.tar.gz", hash = "sha256:02d5aaba0ee755e707c3ef6e748f9acb7b3011187c0ea766db31af8905078a34"}, ] [[package]] name = "mkdocs-material-extensions" version = "1.3.1" requires_python = ">=3.8" summary = "Extension pack for Python Markdown and MkDocs Material." groups = ["docs-online"] files = [ {file = "mkdocs_material_extensions-1.3.1-py3-none-any.whl", hash = "sha256:adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31"}, {file = "mkdocs_material_extensions-1.3.1.tar.gz", hash = "sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443"}, ] [[package]] name = "mkdocstrings" version = "0.25.1" requires_python = ">=3.8" summary = "Automatic documentation from sources, for MkDocs." groups = ["docs-online"] dependencies = [ "Jinja2>=2.11.1", "Markdown>=3.3", "MarkupSafe>=1.1", "click>=7.0", "importlib-metadata>=4.6; python_version < \"3.10\"", "mkdocs-autorefs>=0.3.1", "mkdocs>=1.4", "platformdirs>=2.2.0", "pymdown-extensions>=6.3", "typing-extensions>=4.1; python_version < \"3.10\"", ] files = [ {file = "mkdocstrings-0.25.1-py3-none-any.whl", hash = "sha256:da01fcc2670ad61888e8fe5b60afe9fee5781017d67431996832d63e887c2e51"}, {file = "mkdocstrings-0.25.1.tar.gz", hash = "sha256:c3a2515f31577f311a9ee58d089e4c51fc6046dbd9e9b4c3de4c3194667fe9bf"}, ] [[package]] name = "mkdocstrings-python" version = "1.10.3" requires_python = ">=3.8" summary = "A Python handler for mkdocstrings." groups = ["docs-online"] dependencies = [ "griffe>=0.44", "mkdocstrings>=0.25", ] files = [ {file = "mkdocstrings_python-1.10.3-py3-none-any.whl", hash = "sha256:11ff6d21d3818fb03af82c3ea6225b1534837e17f790aa5f09626524171f949b"}, {file = "mkdocstrings_python-1.10.3.tar.gz", hash = "sha256:321cf9c732907ab2b1fedaafa28765eaa089d89320f35f7206d00ea266889d03"}, ] [[package]] name = "mkdocstrings" version = "0.25.1" extras = ["python"] requires_python = ">=3.8" summary = "Automatic documentation from sources, for MkDocs." groups = ["docs-online"] dependencies = [ "mkdocstrings-python>=0.5.2", "mkdocstrings==0.25.1", ] files = [ {file = "mkdocstrings-0.25.1-py3-none-any.whl", hash = "sha256:da01fcc2670ad61888e8fe5b60afe9fee5781017d67431996832d63e887c2e51"}, {file = "mkdocstrings-0.25.1.tar.gz", hash = "sha256:c3a2515f31577f311a9ee58d089e4c51fc6046dbd9e9b4c3de4c3194667fe9bf"}, ] [[package]] name = "mypy-extensions" version = "1.0.0" requires_python = ">=3.5" summary = "Type system extensions for programs checked with the mypy type checker." groups = ["tooling"] files = [ {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, ] [[package]] name = "myst-parser" version = "3.0.1" requires_python = ">=3.8" summary = "An extended [CommonMark](https://spec.commonmark.org/) compliant parser," groups = ["docs-offline"] dependencies = [ "docutils<0.22,>=0.18", "jinja2", "markdown-it-py~=3.0", "mdit-py-plugins~=0.4", "pyyaml", "sphinx<8,>=6", ] files = [ {file = "myst_parser-3.0.1-py3-none-any.whl", hash = "sha256:6457aaa33a5d474aca678b8ead9b3dc298e89c68e67012e73146ea6fd54babf1"}, {file = "myst_parser-3.0.1.tar.gz", hash = "sha256:88f0cb406cb363b077d176b51c476f62d60604d68a8dcdf4832e080441301a87"}, ] [[package]] name = "nodeenv" version = "1.8.0" requires_python = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" summary = "Node.js virtual environment builder" groups = ["tooling"] dependencies = [ "setuptools", ] files = [ {file = "nodeenv-1.8.0-py2.py3-none-any.whl", hash = "sha256:df865724bb3c3adc86b3876fa209771517b0cfe596beff01a92700e0e8be4cec"}, {file = "nodeenv-1.8.0.tar.gz", hash = "sha256:d51e0c37e64fbf47d017feac3145cdbb58836d7eee8c6f6d3b6880c5456227d2"}, ] [[package]] name = "packaging" version = "24.0" requires_python = ">=3.7" summary = "Core utilities for Python packages" groups = ["docs-offline", "docs-online", "package", "runner", "tooling"] files = [ {file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"}, {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, ] [[package]] name = "paginate" version = "0.5.6" summary = "Divides large result sets into pages for easier browsing" groups = ["docs-online"] files = [ {file = "paginate-0.5.6.tar.gz", hash = "sha256:5e6007b6a9398177a7e1648d04fdd9f8c9766a1a945bceac82f1929e8c78af2d"}, ] [[package]] name = "pathspec" version = "0.12.1" requires_python = ">=3.8" summary = "Utility library for gitignore style pattern matching of file paths." groups = ["docs-online", "tooling"] files = [ {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, ] [[package]] name = "pbr" version = "6.0.0" requires_python = ">=2.6" summary = "Python Build Reasonableness" groups = ["sast"] files = [ {file = "pbr-6.0.0-py2.py3-none-any.whl", hash = "sha256:4a7317d5e3b17a3dccb6a8cfe67dab65b20551404c52c8ed41279fa4f0cb4cda"}, {file = "pbr-6.0.0.tar.gz", hash = "sha256:d1377122a5a00e2f940ee482999518efe16d745d423a670c27773dfbc3c9a7d9"}, ] [[package]] name = "platformdirs" version = "4.2.2" requires_python = ">=3.8" summary = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." groups = ["docs-online", "runner", "tooling"] files = [ {file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"}, {file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"}, ] [[package]] name = "pluggy" version = "1.5.0" requires_python = ">=3.8" summary = "plugin and hook calling mechanisms for python" groups = ["runner", "tooling"] files = [ {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, ] [[package]] name = "pygments" version = "2.18.0" requires_python = ">=3.8" summary = "Pygments is a syntax highlighting package written in Python." groups = ["docs-offline", "docs-online", "sast"] files = [ {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"}, {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"}, ] [[package]] name = "pymdown-extensions" version = "10.8.1" requires_python = ">=3.8" summary = "Extension pack for Python Markdown." groups = ["docs-online"] dependencies = [ "markdown>=3.6", "pyyaml", ] files = [ {file = "pymdown_extensions-10.8.1-py3-none-any.whl", hash = "sha256:f938326115884f48c6059c67377c46cf631c733ef3629b6eed1349989d1b30cb"}, {file = "pymdown_extensions-10.8.1.tar.gz", hash = "sha256:3ab1db5c9e21728dabf75192d71471f8e50f216627e9a1fa9535ecb0231b9940"}, ] [[package]] name = "pypandoc-binary" version = "1.13" requires_python = ">=3.6" summary = "Thin wrapper for pandoc." groups = ["docs-offline", "tooling"] files = [ {file = "pypandoc_binary-1.13-py3-none-macosx_10_9_x86_64.whl", hash = "sha256:946666388eb79b307d7f497b3b33045ef807750f8e5ef3440e0ba3bbab698044"}, {file = "pypandoc_binary-1.13-py3-none-macosx_11_0_arm64.whl", hash = "sha256:21ef0345726d36fc45a50211320614daf2caede684b0d0963ce8738292809746"}, {file = "pypandoc_binary-1.13-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67c0c7af811bcf3cd4f3221be756a4975ec35b2d7df89d8de4313a8caa2cd54f"}, {file = "pypandoc_binary-1.13-py3-none-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9455fdd9521cbf4b56d79a56b806afa94c8c22f3c8ef878536e58d941a70f6d6"}, {file = "pypandoc_binary-1.13-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:2915f52e4632bd2d0a8fcd2f7e7dfc2ea19b4e1a280fcbc2ddcd142713c4ff12"}, {file = "pypandoc_binary-1.13-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:11a2497320eb3dccb74de3c67b6df3e5d3f66cdc2a36a67e9a871708f7e48412"}, {file = "pypandoc_binary-1.13-py3-none-win_amd64.whl", hash = "sha256:3881aa7c84faec2007c0ae4466d3a1cfc93171206b8540f2defa8ea971bf6fd6"}, ] [[package]] name = "pyparsing" version = "3.1.2" requires_python = ">=3.6.8" summary = "pyparsing module - Classes and methods to define and execute parsing grammars" groups = ["docs-online"] files = [ {file = "pyparsing-3.1.2-py3-none-any.whl", hash = "sha256:f9db75911801ed778fe61bb643079ff86601aca99fcae6345aa67292038fb742"}, {file = "pyparsing-3.1.2.tar.gz", hash = "sha256:a1bac0ce561155ecc3ed78ca94d3c9378656ad4c94c1270de543f621420f94ad"}, ] [[package]] name = "pyproject-api" version = "1.6.1" requires_python = ">=3.8" summary = "API to interact with the python pyproject.toml based projects" groups = ["runner"] dependencies = [ "packaging>=23.1", "tomli>=2.0.1; python_version < \"3.11\"", ] files = [ {file = "pyproject_api-1.6.1-py3-none-any.whl", hash = "sha256:4c0116d60476b0786c88692cf4e325a9814965e2469c5998b830bba16b183675"}, {file = "pyproject_api-1.6.1.tar.gz", hash = "sha256:1817dc018adc0d1ff9ca1ed8c60e1623d5aaca40814b953af14a9cf9a5cae538"}, ] [[package]] name = "pyproject-hooks" version = "1.1.0" requires_python = ">=3.7" summary = "Wrappers to call pyproject.toml-based build backend hooks." groups = ["package"] files = [ {file = "pyproject_hooks-1.1.0-py3-none-any.whl", hash = "sha256:7ceeefe9aec63a1064c18d939bdc3adf2d8aa1988a510afec15151578b232aa2"}, {file = "pyproject_hooks-1.1.0.tar.gz", hash = "sha256:4b37730834edbd6bd37f26ece6b44802fb1c1ee2ece0e54ddff8bfc06db86965"}, ] [[package]] name = "pyright" version = "1.1.364" requires_python = ">=3.7" summary = "Command line wrapper for pyright" groups = ["tooling"] dependencies = [ "nodeenv>=1.6.0", ] files = [ {file = "pyright-1.1.364-py3-none-any.whl", hash = "sha256:865f1e02873c5dc7427c95acf53659a118574010e6fb364e27e47ec5c46a9f26"}, {file = "pyright-1.1.364.tar.gz", hash = "sha256:612a2106a4078ec57efc22b5620729e9bdf4a3c17caba013b534bd33f7d08e5a"}, ] [[package]] name = "pytest" version = "8.2.1" requires_python = ">=3.8" summary = "pytest: simple powerful testing with Python" groups = ["tooling"] dependencies = [ "colorama; sys_platform == \"win32\"", "exceptiongroup>=1.0.0rc8; python_version < \"3.11\"", "iniconfig", "packaging", "pluggy<2.0,>=1.5", "tomli>=1; python_version < \"3.11\"", ] files = [ {file = "pytest-8.2.1-py3-none-any.whl", hash = "sha256:faccc5d332b8c3719f40283d0d44aa5cf101cec36f88cde9ed8f2bc0538612b1"}, {file = "pytest-8.2.1.tar.gz", hash = "sha256:5046e5b46d8e4cac199c373041f26be56fdb81eb4e67dc11d4e10811fc3408fd"}, ] [[package]] name = "python-dateutil" version = "2.9.0.post0" requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" summary = "Extensions to the standard Python datetime module" groups = ["docs-online"] dependencies = [ "six>=1.5", ] files = [ {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, ] [[package]] name = "pytz" version = "2024.1" summary = "World timezone definitions, modern and historical" groups = ["docs-offline", "docs-online"] files = [ {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, ] [[package]] name = "pyyaml" version = "6.0.1" requires_python = ">=3.6" summary = "YAML parser and emitter for Python" groups = ["docs-offline", "docs-online", "sast"] files = [ {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, ] [[package]] name = "pyyaml-env-tag" version = "0.1" requires_python = ">=3.6" summary = "A custom YAML tag for referencing environment variables in YAML files. " groups = ["docs-online"] dependencies = [ "pyyaml", ] files = [ {file = "pyyaml_env_tag-0.1-py3-none-any.whl", hash = "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069"}, {file = "pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb"}, ] [[package]] name = "regex" version = "2024.5.15" requires_python = ">=3.8" summary = "Alternative regular expression module, to replace re." groups = ["docs-online"] files = [ {file = "regex-2024.5.15-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a81e3cfbae20378d75185171587cbf756015ccb14840702944f014e0d93ea09f"}, {file = "regex-2024.5.15-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7b59138b219ffa8979013be7bc85bb60c6f7b7575df3d56dc1e403a438c7a3f6"}, {file = "regex-2024.5.15-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a0bd000c6e266927cb7a1bc39d55be95c4b4f65c5be53e659537537e019232b1"}, {file = "regex-2024.5.15-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5eaa7ddaf517aa095fa8da0b5015c44d03da83f5bd49c87961e3c997daed0de7"}, {file = "regex-2024.5.15-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba68168daedb2c0bab7fd7e00ced5ba90aebf91024dea3c88ad5063c2a562cca"}, {file = "regex-2024.5.15-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6e8d717bca3a6e2064fc3a08df5cbe366369f4b052dcd21b7416e6d71620dca1"}, {file = "regex-2024.5.15-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1337b7dbef9b2f71121cdbf1e97e40de33ff114801263b275aafd75303bd62b5"}, {file = "regex-2024.5.15-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f9ebd0a36102fcad2f03696e8af4ae682793a5d30b46c647eaf280d6cfb32796"}, {file = "regex-2024.5.15-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9efa1a32ad3a3ea112224897cdaeb6aa00381627f567179c0314f7b65d354c62"}, {file = "regex-2024.5.15-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:1595f2d10dff3d805e054ebdc41c124753631b6a471b976963c7b28543cf13b0"}, {file = "regex-2024.5.15-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b802512f3e1f480f41ab5f2cfc0e2f761f08a1f41092d6718868082fc0d27143"}, {file = "regex-2024.5.15-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:a0981022dccabca811e8171f913de05720590c915b033b7e601f35ce4ea7019f"}, {file = "regex-2024.5.15-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:19068a6a79cf99a19ccefa44610491e9ca02c2be3305c7760d3831d38a467a6f"}, {file = "regex-2024.5.15-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:1b5269484f6126eee5e687785e83c6b60aad7663dafe842b34691157e5083e53"}, {file = "regex-2024.5.15-cp310-cp310-win32.whl", hash = "sha256:ada150c5adfa8fbcbf321c30c751dc67d2f12f15bd183ffe4ec7cde351d945b3"}, {file = "regex-2024.5.15-cp310-cp310-win_amd64.whl", hash = "sha256:ac394ff680fc46b97487941f5e6ae49a9f30ea41c6c6804832063f14b2a5a145"}, {file = "regex-2024.5.15-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f5b1dff3ad008dccf18e652283f5e5339d70bf8ba7c98bf848ac33db10f7bc7a"}, {file = "regex-2024.5.15-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c6a2b494a76983df8e3d3feea9b9ffdd558b247e60b92f877f93a1ff43d26656"}, {file = "regex-2024.5.15-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a32b96f15c8ab2e7d27655969a23895eb799de3665fa94349f3b2fbfd547236f"}, {file = "regex-2024.5.15-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:10002e86e6068d9e1c91eae8295ef690f02f913c57db120b58fdd35a6bb1af35"}, {file = "regex-2024.5.15-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ec54d5afa89c19c6dd8541a133be51ee1017a38b412b1321ccb8d6ddbeb4cf7d"}, {file = "regex-2024.5.15-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:10e4ce0dca9ae7a66e6089bb29355d4432caed736acae36fef0fdd7879f0b0cb"}, {file = "regex-2024.5.15-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e507ff1e74373c4d3038195fdd2af30d297b4f0950eeda6f515ae3d84a1770f"}, {file = "regex-2024.5.15-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d1f059a4d795e646e1c37665b9d06062c62d0e8cc3c511fe01315973a6542e40"}, {file = "regex-2024.5.15-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0721931ad5fe0dda45d07f9820b90b2148ccdd8e45bb9e9b42a146cb4f695649"}, {file = "regex-2024.5.15-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:833616ddc75ad595dee848ad984d067f2f31be645d603e4d158bba656bbf516c"}, {file = "regex-2024.5.15-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:287eb7f54fc81546346207c533ad3c2c51a8d61075127d7f6d79aaf96cdee890"}, {file = "regex-2024.5.15-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:19dfb1c504781a136a80ecd1fff9f16dddf5bb43cec6871778c8a907a085bb3d"}, {file = "regex-2024.5.15-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:119af6e56dce35e8dfb5222573b50c89e5508d94d55713c75126b753f834de68"}, {file = "regex-2024.5.15-cp311-cp311-win32.whl", hash = "sha256:1c1c174d6ec38d6c8a7504087358ce9213d4332f6293a94fbf5249992ba54efa"}, {file = "regex-2024.5.15-cp311-cp311-win_amd64.whl", hash = "sha256:9e717956dcfd656f5055cc70996ee2cc82ac5149517fc8e1b60261b907740201"}, {file = "regex-2024.5.15-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:632b01153e5248c134007209b5c6348a544ce96c46005d8456de1d552455b014"}, {file = "regex-2024.5.15-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e64198f6b856d48192bf921421fdd8ad8eb35e179086e99e99f711957ffedd6e"}, {file = "regex-2024.5.15-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:68811ab14087b2f6e0fc0c2bae9ad689ea3584cad6917fc57be6a48bbd012c49"}, {file = "regex-2024.5.15-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8ec0c2fea1e886a19c3bee0cd19d862b3aa75dcdfb42ebe8ed30708df64687a"}, {file = "regex-2024.5.15-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d0c0c0003c10f54a591d220997dd27d953cd9ccc1a7294b40a4be5312be8797b"}, {file = "regex-2024.5.15-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2431b9e263af1953c55abbd3e2efca67ca80a3de8a0437cb58e2421f8184717a"}, {file = "regex-2024.5.15-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a605586358893b483976cffc1723fb0f83e526e8f14c6e6614e75919d9862cf"}, {file = "regex-2024.5.15-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:391d7f7f1e409d192dba8bcd42d3e4cf9e598f3979cdaed6ab11288da88cb9f2"}, {file = "regex-2024.5.15-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9ff11639a8d98969c863d4617595eb5425fd12f7c5ef6621a4b74b71ed8726d5"}, {file = "regex-2024.5.15-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4eee78a04e6c67e8391edd4dad3279828dd66ac4b79570ec998e2155d2e59fd5"}, {file = "regex-2024.5.15-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:8fe45aa3f4aa57faabbc9cb46a93363edd6197cbc43523daea044e9ff2fea83e"}, {file = "regex-2024.5.15-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:d0a3d8d6acf0c78a1fff0e210d224b821081330b8524e3e2bc5a68ef6ab5803d"}, {file = "regex-2024.5.15-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c486b4106066d502495b3025a0a7251bf37ea9540433940a23419461ab9f2a80"}, {file = "regex-2024.5.15-cp312-cp312-win32.whl", hash = "sha256:c49e15eac7c149f3670b3e27f1f28a2c1ddeccd3a2812cba953e01be2ab9b5fe"}, {file = "regex-2024.5.15-cp312-cp312-win_amd64.whl", hash = "sha256:673b5a6da4557b975c6c90198588181029c60793835ce02f497ea817ff647cb2"}, {file = "regex-2024.5.15-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:87e2a9c29e672fc65523fb47a90d429b70ef72b901b4e4b1bd42387caf0d6835"}, {file = "regex-2024.5.15-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c3bea0ba8b73b71b37ac833a7f3fd53825924165da6a924aec78c13032f20850"}, {file = "regex-2024.5.15-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bfc4f82cabe54f1e7f206fd3d30fda143f84a63fe7d64a81558d6e5f2e5aaba9"}, {file = "regex-2024.5.15-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5bb9425fe881d578aeca0b2b4b3d314ec88738706f66f219c194d67179337cb"}, {file = "regex-2024.5.15-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:64c65783e96e563103d641760664125e91bd85d8e49566ee560ded4da0d3e704"}, {file = "regex-2024.5.15-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cf2430df4148b08fb4324b848672514b1385ae3807651f3567871f130a728cc3"}, {file = "regex-2024.5.15-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5397de3219a8b08ae9540c48f602996aa6b0b65d5a61683e233af8605c42b0f2"}, {file = "regex-2024.5.15-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:455705d34b4154a80ead722f4f185b04c4237e8e8e33f265cd0798d0e44825fa"}, {file = "regex-2024.5.15-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b2b6f1b3bb6f640c1a92be3bbfbcb18657b125b99ecf141fb3310b5282c7d4ed"}, {file = "regex-2024.5.15-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:3ad070b823ca5890cab606c940522d05d3d22395d432f4aaaf9d5b1653e47ced"}, {file = "regex-2024.5.15-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:5b5467acbfc153847d5adb21e21e29847bcb5870e65c94c9206d20eb4e99a384"}, {file = "regex-2024.5.15-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:e6662686aeb633ad65be2a42b4cb00178b3fbf7b91878f9446075c404ada552f"}, {file = "regex-2024.5.15-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:2b4c884767504c0e2401babe8b5b7aea9148680d2e157fa28f01529d1f7fcf67"}, {file = "regex-2024.5.15-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:3cd7874d57f13bf70078f1ff02b8b0aa48d5b9ed25fc48547516c6aba36f5741"}, {file = "regex-2024.5.15-cp38-cp38-win32.whl", hash = "sha256:e4682f5ba31f475d58884045c1a97a860a007d44938c4c0895f41d64481edbc9"}, {file = "regex-2024.5.15-cp38-cp38-win_amd64.whl", hash = "sha256:d99ceffa25ac45d150e30bd9ed14ec6039f2aad0ffa6bb87a5936f5782fc1569"}, {file = "regex-2024.5.15-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:13cdaf31bed30a1e1c2453ef6015aa0983e1366fad2667657dbcac7b02f67133"}, {file = "regex-2024.5.15-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cac27dcaa821ca271855a32188aa61d12decb6fe45ffe3e722401fe61e323cd1"}, {file = "regex-2024.5.15-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7dbe2467273b875ea2de38ded4eba86cbcbc9a1a6d0aa11dcf7bd2e67859c435"}, {file = "regex-2024.5.15-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:64f18a9a3513a99c4bef0e3efd4c4a5b11228b48aa80743be822b71e132ae4f5"}, {file = "regex-2024.5.15-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d347a741ea871c2e278fde6c48f85136c96b8659b632fb57a7d1ce1872547600"}, {file = "regex-2024.5.15-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1878b8301ed011704aea4c806a3cadbd76f84dece1ec09cc9e4dc934cfa5d4da"}, {file = "regex-2024.5.15-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4babf07ad476aaf7830d77000874d7611704a7fcf68c9c2ad151f5d94ae4bfc4"}, {file = "regex-2024.5.15-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:35cb514e137cb3488bce23352af3e12fb0dbedd1ee6e60da053c69fb1b29cc6c"}, {file = "regex-2024.5.15-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cdd09d47c0b2efee9378679f8510ee6955d329424c659ab3c5e3a6edea696294"}, {file = "regex-2024.5.15-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:72d7a99cd6b8f958e85fc6ca5b37c4303294954eac1376535b03c2a43eb72629"}, {file = "regex-2024.5.15-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:a094801d379ab20c2135529948cb84d417a2169b9bdceda2a36f5f10977ebc16"}, {file = "regex-2024.5.15-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:c0c18345010870e58238790a6779a1219b4d97bd2e77e1140e8ee5d14df071aa"}, {file = "regex-2024.5.15-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:16093f563098448ff6b1fa68170e4acbef94e6b6a4e25e10eae8598bb1694b5d"}, {file = "regex-2024.5.15-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:e38a7d4e8f633a33b4c7350fbd8bad3b70bf81439ac67ac38916c4a86b465456"}, {file = "regex-2024.5.15-cp39-cp39-win32.whl", hash = "sha256:71a455a3c584a88f654b64feccc1e25876066c4f5ef26cd6dd711308aa538694"}, {file = "regex-2024.5.15-cp39-cp39-win_amd64.whl", hash = "sha256:cab12877a9bdafde5500206d1020a584355a97884dfd388af3699e9137bf7388"}, {file = "regex-2024.5.15.tar.gz", hash = "sha256:d3ee02d9e5f482cc8309134a91eeaacbdd2261ba111b0fef3748eeb4913e6a2c"}, ] [[package]] name = "requests" version = "2.32.2" requires_python = ">=3.8" summary = "Python HTTP for Humans." groups = ["docs-offline", "docs-online"] dependencies = [ "certifi>=2017.4.17", "charset-normalizer<4,>=2", "idna<4,>=2.5", "urllib3<3,>=1.21.1", ] files = [ {file = "requests-2.32.2-py3-none-any.whl", hash = "sha256:fc06670dd0ed212426dfeb94fc1b983d917c4f9847c863f313c9dfaaffb7c23c"}, {file = "requests-2.32.2.tar.gz", hash = "sha256:dd951ff5ecf3e3b3aa26b40703ba77495dab41da839ae72ef3c8e5d8e2433289"}, ] [[package]] name = "rich" version = "13.7.1" requires_python = ">=3.7.0" summary = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" groups = ["sast"] dependencies = [ "markdown-it-py>=2.2.0", "pygments<3.0.0,>=2.13.0", "typing-extensions<5.0,>=4.0.0; python_version < \"3.9\"", ] files = [ {file = "rich-13.7.1-py3-none-any.whl", hash = "sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222"}, {file = "rich-13.7.1.tar.gz", hash = "sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432"}, ] [[package]] name = "ruff" version = "0.4.5" requires_python = ">=3.7" summary = "An extremely fast Python linter and code formatter, written in Rust." groups = ["tooling"] files = [ {file = "ruff-0.4.5-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:8f58e615dec58b1a6b291769b559e12fdffb53cc4187160a2fc83250eaf54e96"}, {file = "ruff-0.4.5-py3-none-macosx_11_0_arm64.whl", hash = "sha256:84dd157474e16e3a82745d2afa1016c17d27cb5d52b12e3d45d418bcc6d49264"}, {file = "ruff-0.4.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25f483ad9d50b00e7fd577f6d0305aa18494c6af139bce7319c68a17180087f4"}, {file = "ruff-0.4.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63fde3bf6f3ad4e990357af1d30e8ba2730860a954ea9282c95fc0846f5f64af"}, {file = "ruff-0.4.5-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78e3ba4620dee27f76bbcad97067766026c918ba0f2d035c2fc25cbdd04d9c97"}, {file = "ruff-0.4.5-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:441dab55c568e38d02bbda68a926a3d0b54f5510095c9de7f95e47a39e0168aa"}, {file = "ruff-0.4.5-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1169e47e9c4136c997f08f9857ae889d614c5035d87d38fda9b44b4338909cdf"}, {file = "ruff-0.4.5-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:755ac9ac2598a941512fc36a9070a13c88d72ff874a9781493eb237ab02d75df"}, {file = "ruff-0.4.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f4b02a65985be2b34b170025a8b92449088ce61e33e69956ce4d316c0fe7cce0"}, {file = "ruff-0.4.5-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:75a426506a183d9201e7e5664de3f6b414ad3850d7625764106f7b6d0486f0a1"}, {file = "ruff-0.4.5-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:6e1b139b45e2911419044237d90b60e472f57285950e1492c757dfc88259bb06"}, {file = "ruff-0.4.5-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a6f29a8221d2e3d85ff0c7b4371c0e37b39c87732c969b4d90f3dad2e721c5b1"}, {file = "ruff-0.4.5-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:d6ef817124d72b54cc923f3444828ba24fa45c3164bc9e8f1813db2f3d3a8a11"}, {file = "ruff-0.4.5-py3-none-win32.whl", hash = "sha256:aed8166c18b1a169a5d3ec28a49b43340949e400665555b51ee06f22813ef062"}, {file = "ruff-0.4.5-py3-none-win_amd64.whl", hash = "sha256:b0b03c619d2b4350b4a27e34fd2ac64d0dabe1afbf43de57d0f9d8a05ecffa45"}, {file = "ruff-0.4.5-py3-none-win_arm64.whl", hash = "sha256:9d15de3425f53161b3f5a5658d4522e4eee5ea002bf2ac7aa380743dd9ad5fba"}, {file = "ruff-0.4.5.tar.gz", hash = "sha256:286eabd47e7d4d521d199cab84deca135557e6d1e0f0d01c29e757c3cb151b54"}, ] [[package]] name = "setuptools" version = "70.0.0" requires_python = ">=3.8" summary = "Easily download, build, install, upgrade, and uninstall Python packages" groups = ["tooling"] files = [ {file = "setuptools-70.0.0-py3-none-any.whl", hash = "sha256:54faa7f2e8d2d11bcd2c07bed282eef1046b5c080d1c32add737d7b5817b1ad4"}, {file = "setuptools-70.0.0.tar.gz", hash = "sha256:f211a66637b8fa059bb28183da127d4e86396c991a942b028c6650d4319c3fd0"}, ] [[package]] name = "six" version = "1.16.0" requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" summary = "Python 2 and 3 compatibility utilities" groups = ["docs-online"] files = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] [[package]] name = "smmap" version = "5.0.1" requires_python = ">=3.7" summary = "A pure Python implementation of a sliding window memory map manager" groups = ["docs-online"] files = [ {file = "smmap-5.0.1-py3-none-any.whl", hash = "sha256:e6d8668fa5f93e706934a62d7b4db19c8d9eb8cf2adbb75ef1b675aa332b69da"}, {file = "smmap-5.0.1.tar.gz", hash = "sha256:dceeb6c0028fdb6734471eb07c0cd2aae706ccaecab45965ee83f11c8d3b1f62"}, ] [[package]] name = "snowballstemmer" version = "2.2.0" summary = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." groups = ["docs-offline"] files = [ {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, ] [[package]] name = "soupsieve" version = "2.5" requires_python = ">=3.8" summary = "A modern CSS selector implementation for Beautiful Soup." groups = ["docs-offline"] files = [ {file = "soupsieve-2.5-py3-none-any.whl", hash = "sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7"}, {file = "soupsieve-2.5.tar.gz", hash = "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690"}, ] [[package]] name = "sphinx" version = "7.1.2" requires_python = ">=3.8" summary = "Python documentation generator" groups = ["docs-offline"] dependencies = [ "Jinja2>=3.0", "Pygments>=2.13", "alabaster<0.8,>=0.7", "babel>=2.9", "colorama>=0.4.5; sys_platform == \"win32\"", "docutils<0.21,>=0.18.1", "imagesize>=1.3", "importlib-metadata>=4.8; python_version < \"3.10\"", "packaging>=21.0", "requests>=2.25.0", "snowballstemmer>=2.0", "sphinxcontrib-applehelp", "sphinxcontrib-devhelp", "sphinxcontrib-htmlhelp>=2.0.0", "sphinxcontrib-jsmath", "sphinxcontrib-qthelp", "sphinxcontrib-serializinghtml>=1.1.5", ] files = [ {file = "sphinx-7.1.2-py3-none-any.whl", hash = "sha256:d170a81825b2fcacb6dfd5a0d7f578a053e45d3f2b153fecc948c37344eb4cbe"}, {file = "sphinx-7.1.2.tar.gz", hash = "sha256:780f4d32f1d7d1126576e0e5ecc19dc32ab76cd24e950228dcf7b1f6d3d9e22f"}, ] [[package]] name = "sphinx-basic-ng" version = "1.0.0b2" requires_python = ">=3.7" summary = "A modern skeleton for Sphinx themes." groups = ["docs-offline"] dependencies = [ "sphinx>=4.0", ] files = [ {file = "sphinx_basic_ng-1.0.0b2-py3-none-any.whl", hash = "sha256:eb09aedbabfb650607e9b4b68c9d240b90b1e1be221d6ad71d61c52e29f7932b"}, {file = "sphinx_basic_ng-1.0.0b2.tar.gz", hash = "sha256:9ec55a47c90c8c002b5960c57492ec3021f5193cb26cebc2dc4ea226848651c9"}, ] [[package]] name = "sphinxcontrib-applehelp" version = "1.0.4" requires_python = ">=3.8" summary = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" groups = ["docs-offline"] files = [ {file = "sphinxcontrib-applehelp-1.0.4.tar.gz", hash = "sha256:828f867945bbe39817c210a1abfd1bc4895c8b73fcaade56d45357a348a07d7e"}, {file = "sphinxcontrib_applehelp-1.0.4-py3-none-any.whl", hash = "sha256:29d341f67fb0f6f586b23ad80e072c8e6ad0b48417db2bde114a4c9746feb228"}, ] [[package]] name = "sphinxcontrib-devhelp" version = "1.0.2" requires_python = ">=3.5" summary = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document." groups = ["docs-offline"] files = [ {file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"}, {file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"}, ] [[package]] name = "sphinxcontrib-htmlhelp" version = "2.0.1" requires_python = ">=3.8" summary = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" groups = ["docs-offline"] files = [ {file = "sphinxcontrib-htmlhelp-2.0.1.tar.gz", hash = "sha256:0cbdd302815330058422b98a113195c9249825d681e18f11e8b1f78a2f11efff"}, {file = "sphinxcontrib_htmlhelp-2.0.1-py3-none-any.whl", hash = "sha256:c38cb46dccf316c79de6e5515e1770414b797162b23cd3d06e67020e1d2a6903"}, ] [[package]] name = "sphinxcontrib-jsmath" version = "1.0.1" requires_python = ">=3.5" summary = "A sphinx extension which renders display math in HTML via JavaScript" groups = ["docs-offline"] files = [ {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"}, {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"}, ] [[package]] name = "sphinxcontrib-qthelp" version = "1.0.3" requires_python = ">=3.5" summary = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document." groups = ["docs-offline"] files = [ {file = "sphinxcontrib-qthelp-1.0.3.tar.gz", hash = "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72"}, {file = "sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"}, ] [[package]] name = "sphinxcontrib-serializinghtml" version = "1.1.5" requires_python = ">=3.5" summary = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)." groups = ["docs-offline"] files = [ {file = "sphinxcontrib-serializinghtml-1.1.5.tar.gz", hash = "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"}, {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"}, ] [[package]] name = "stevedore" version = "5.2.0" requires_python = ">=3.8" summary = "Manage dynamic plugins for Python applications" groups = ["sast"] dependencies = [ "pbr!=2.1.0,>=2.0.0", ] files = [ {file = "stevedore-5.2.0-py3-none-any.whl", hash = "sha256:1c15d95766ca0569cad14cb6272d4d31dae66b011a929d7c18219c176ea1b5c9"}, {file = "stevedore-5.2.0.tar.gz", hash = "sha256:46b93ca40e1114cea93d738a6c1e365396981bb6bb78c27045b7587c9473544d"}, ] [[package]] name = "tomli" version = "2.0.1" requires_python = ">=3.7" summary = "A lil' TOML parser" groups = ["package", "runner", "sast", "tooling"] marker = "python_version < \"3.11\"" files = [ {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] [[package]] name = "tox" version = "4.15.0" requires_python = ">=3.8" summary = "tox is a generic virtualenv management and test command line tool" groups = ["runner"] dependencies = [ "cachetools>=5.3.2", "chardet>=5.2", "colorama>=0.4.6", "filelock>=3.13.1", "packaging>=23.2", "platformdirs>=4.1", "pluggy>=1.3", "pyproject-api>=1.6.1", "tomli>=2.0.1; python_version < \"3.11\"", "virtualenv>=20.25", ] files = [ {file = "tox-4.15.0-py3-none-any.whl", hash = "sha256:300055f335d855b2ab1b12c5802de7f62a36d4fd53f30bd2835f6a201dda46ea"}, {file = "tox-4.15.0.tar.gz", hash = "sha256:7a0beeef166fbe566f54f795b4906c31b428eddafc0102ac00d20998dd1933f6"}, ] [[package]] name = "typing-extensions" version = "4.12.0" requires_python = ">=3.8" summary = "Backported and Experimental Type Hints for Python 3.8+" groups = ["docs-online", "sast", "tooling"] marker = "python_version < \"3.11\"" files = [ {file = "typing_extensions-4.12.0-py3-none-any.whl", hash = "sha256:b349c66bea9016ac22978d800cfff206d5f9816951f12a7d0ec5578b0a819594"}, {file = "typing_extensions-4.12.0.tar.gz", hash = "sha256:8cbcdc8606ebcb0d95453ad7dc5065e6237b6aa230a31e81d0f440c30fed5fd8"}, ] [[package]] name = "urllib3" version = "2.2.1" requires_python = ">=3.8" summary = "HTTP library with thread-safe connection pooling, file post, and more." groups = ["docs-offline", "docs-online"] files = [ {file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"}, {file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"}, ] [[package]] name = "verspec" version = "0.1.0" summary = "Flexible version handling" groups = ["docs-online"] files = [ {file = "verspec-0.1.0-py3-none-any.whl", hash = "sha256:741877d5633cc9464c45a469ae2a31e801e6dbbaa85b9675d481cda100f11c31"}, {file = "verspec-0.1.0.tar.gz", hash = "sha256:c4504ca697b2056cdb4bfa7121461f5a0e81809255b41c03dda4ba823637c01e"}, ] [[package]] name = "virtualenv" version = "20.26.2" requires_python = ">=3.7" summary = "Virtual Python Environment builder" groups = ["runner"] dependencies = [ "distlib<1,>=0.3.7", "filelock<4,>=3.12.2", "platformdirs<5,>=3.9.1", ] files = [ {file = "virtualenv-20.26.2-py3-none-any.whl", hash = "sha256:a624db5e94f01ad993d476b9ee5346fdf7b9de43ccaee0e0197012dc838a0e9b"}, {file = "virtualenv-20.26.2.tar.gz", hash = "sha256:82bf0f4eebbb78d36ddaee0283d43fe5736b53880b8a8cdcd37390a07ac3741c"}, ] [[package]] name = "watchdog" version = "4.0.1" requires_python = ">=3.8" summary = "Filesystem events monitoring" groups = ["docs-online"] files = [ {file = "watchdog-4.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:da2dfdaa8006eb6a71051795856bedd97e5b03e57da96f98e375682c48850645"}, {file = "watchdog-4.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e93f451f2dfa433d97765ca2634628b789b49ba8b504fdde5837cdcf25fdb53b"}, {file = "watchdog-4.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ef0107bbb6a55f5be727cfc2ef945d5676b97bffb8425650dadbb184be9f9a2b"}, {file = "watchdog-4.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:17e32f147d8bf9657e0922c0940bcde863b894cd871dbb694beb6704cfbd2fb5"}, {file = "watchdog-4.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:03e70d2df2258fb6cb0e95bbdbe06c16e608af94a3ffbd2b90c3f1e83eb10767"}, {file = "watchdog-4.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:123587af84260c991dc5f62a6e7ef3d1c57dfddc99faacee508c71d287248459"}, {file = "watchdog-4.0.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:093b23e6906a8b97051191a4a0c73a77ecc958121d42346274c6af6520dec175"}, {file = "watchdog-4.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:611be3904f9843f0529c35a3ff3fd617449463cb4b73b1633950b3d97fa4bfb7"}, {file = "watchdog-4.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:62c613ad689ddcb11707f030e722fa929f322ef7e4f18f5335d2b73c61a85c28"}, {file = "watchdog-4.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:d4925e4bf7b9bddd1c3de13c9b8a2cdb89a468f640e66fbfabaf735bd85b3e35"}, {file = "watchdog-4.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cad0bbd66cd59fc474b4a4376bc5ac3fc698723510cbb64091c2a793b18654db"}, {file = "watchdog-4.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a3c2c317a8fb53e5b3d25790553796105501a235343f5d2bf23bb8649c2c8709"}, {file = "watchdog-4.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c9904904b6564d4ee8a1ed820db76185a3c96e05560c776c79a6ce5ab71888ba"}, {file = "watchdog-4.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:667f3c579e813fcbad1b784db7a1aaa96524bed53437e119f6a2f5de4db04235"}, {file = "watchdog-4.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d10a681c9a1d5a77e75c48a3b8e1a9f2ae2928eda463e8d33660437705659682"}, {file = "watchdog-4.0.1-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0144c0ea9997b92615af1d94afc0c217e07ce2c14912c7b1a5731776329fcfc7"}, {file = "watchdog-4.0.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:998d2be6976a0ee3a81fb8e2777900c28641fb5bfbd0c84717d89bca0addcdc5"}, {file = "watchdog-4.0.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e7921319fe4430b11278d924ef66d4daa469fafb1da679a2e48c935fa27af193"}, {file = "watchdog-4.0.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:f0de0f284248ab40188f23380b03b59126d1479cd59940f2a34f8852db710625"}, {file = "watchdog-4.0.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:bca36be5707e81b9e6ce3208d92d95540d4ca244c006b61511753583c81c70dd"}, {file = "watchdog-4.0.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:ab998f567ebdf6b1da7dc1e5accfaa7c6992244629c0fdaef062f43249bd8dee"}, {file = "watchdog-4.0.1-py3-none-manylinux2014_aarch64.whl", hash = "sha256:dddba7ca1c807045323b6af4ff80f5ddc4d654c8bce8317dde1bd96b128ed253"}, {file = "watchdog-4.0.1-py3-none-manylinux2014_armv7l.whl", hash = "sha256:4513ec234c68b14d4161440e07f995f231be21a09329051e67a2118a7a612d2d"}, {file = "watchdog-4.0.1-py3-none-manylinux2014_i686.whl", hash = "sha256:4107ac5ab936a63952dea2a46a734a23230aa2f6f9db1291bf171dac3ebd53c6"}, {file = "watchdog-4.0.1-py3-none-manylinux2014_ppc64.whl", hash = "sha256:6e8c70d2cd745daec2a08734d9f63092b793ad97612470a0ee4cbb8f5f705c57"}, {file = "watchdog-4.0.1-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:f27279d060e2ab24c0aa98363ff906d2386aa6c4dc2f1a374655d4e02a6c5e5e"}, {file = "watchdog-4.0.1-py3-none-manylinux2014_s390x.whl", hash = "sha256:f8affdf3c0f0466e69f5b3917cdd042f89c8c63aebdb9f7c078996f607cdb0f5"}, {file = "watchdog-4.0.1-py3-none-manylinux2014_x86_64.whl", hash = "sha256:ac7041b385f04c047fcc2951dc001671dee1b7e0615cde772e84b01fbf68ee84"}, {file = "watchdog-4.0.1-py3-none-win32.whl", hash = "sha256:206afc3d964f9a233e6ad34618ec60b9837d0582b500b63687e34011e15bb429"}, {file = "watchdog-4.0.1-py3-none-win_amd64.whl", hash = "sha256:7577b3c43e5909623149f76b099ac49a1a01ca4e167d1785c76eb52fa585745a"}, {file = "watchdog-4.0.1-py3-none-win_ia64.whl", hash = "sha256:d7b9f5f3299e8dd230880b6c55504a1f69cf1e4316275d1b215ebdd8187ec88d"}, {file = "watchdog-4.0.1.tar.gz", hash = "sha256:eebaacf674fa25511e8867028d281e602ee6500045b57f43b08778082f7f8b44"}, ] [[package]] name = "wheel" version = "0.43.0" requires_python = ">=3.8" summary = "A built-package format for Python" groups = ["docs-online"] marker = "python_version < \"3.9\"" files = [ {file = "wheel-0.43.0-py3-none-any.whl", hash = "sha256:55c570405f142630c6b9f72fe09d9b67cf1477fcf543ae5b8dcb1f5b7377da81"}, {file = "wheel-0.43.0.tar.gz", hash = "sha256:465ef92c69fa5c5da2d1cf8ac40559a8c940886afcef87dcf14b9470862f1d85"}, ] [[package]] name = "zipp" version = "3.18.2" requires_python = ">=3.8" summary = "Backport of pathlib-compatible object wrapper for zip files" groups = ["docs-offline", "docs-online", "package"] files = [ {file = "zipp-3.18.2-py3-none-any.whl", hash = "sha256:dce197b859eb796242b0622af1b8beb0a722d52aa2f57133ead08edd5bf5374e"}, {file = "zipp-3.18.2.tar.gz", hash = "sha256:6278d9ddbcfb1f1089a88fde84481528b07b0e10474e09dcfe53dad4069fa059"}, ] validators-0.28.3/pyproject.toml000066400000000000000000000101701462425114700166750ustar00rootroot00000000000000#################### # Build System # #################### [build-system] requires = ["setuptools"] build-backend = "setuptools.build_meta" #################### # Metadata # #################### [project] name = "validators" description = "Python Data Validation for Humans™" authors = [{ name = "Konsta Vesterinen", email = "konsta@fastmonkeys.com" }] license = { text = "MIT" } readme = "README.md" keywords = ["validation", "validator", "python-validator"] classifiers = [ "Development Status :: 4 - Beta", "Environment :: Web Environment", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: Implementation :: CPython", "Topic :: Software Development :: Libraries :: Python Modules", ] requires-python = ">=3.8" dynamic = ["version"] dependencies = [] [project.urls] Homepage = "https://python-validators.github.io/validators" Documentation = "https://yozachar.github.io/pyvalidators" Repository = "https://github.com/python-validators/validators" Changelog = "https://github.com/python-validators/validators/blob/master/CHANGES.md" ########################### # Optional Dependencies # ########################### # [project.optional-dependencies] ############################## # Development Dependencies # ############################## [tool.pdm.dev-dependencies] docs-offline = [ "myst-parser>=3.0.1", "pypandoc-binary>=1.13", "sphinx>=7.1.2", "furo>=2024.5.6", ] docs-online = [ "mkdocs>=1.6.0", "mkdocs-git-revision-date-localized-plugin>=1.2.5", "mkdocs-material>=9.5.24", "mkdocstrings[python]>=0.25.1", "mike>=2.1.1", ] package = ["build>=1.2.1"] runner = ["tox>=4.15.0"] sast = ["bandit[toml]>=1.7.8"] tooling = [ "black>=24.4.2", "ruff>=0.4.5", "pyright>=1.1.364", "pytest>=8.2.1", "pypandoc-binary>=1.13", # helps with type checking ] #################### # Configurations # #################### [tool.setuptools.packages.find] where = ["src"] include = ["validators*"] namespaces = false [tool.setuptools.package-data] validators = ["py.typed", "_tld.txt"] [tool.setuptools.dynamic] version = { attr = "validators.__version__" } [tool.bandit] exclude_dirs = [ ".github", ".pytest_cache", ".tox", ".venv", ".venv.dev", ".vscode", "site", "tests", ] [tool.black] line-length = 100 target-version = ["py38", "py39", "py310", "py311", "py312"] [tool.pyright] extraPaths = ["src"] exclude = [ "**/__pycache__/", ".pytest_cache/", ".tox/", ".venv/", ".venv.dev/", "site/", ] pythonVersion = "3.8" pythonPlatform = "All" typeCheckingMode = "strict" [tool.pytest.ini_options] pythonpath = ["src"] [tool.ruff] lint.select = [ # Pyflakes "F", # pycodestyle "W", "E", # mccabe # C90 # isort "I", # pep8-naming "N", # pydocstyle "D", ] line-length = 100 target-version = "py38" extend-exclude = ["**/__pycache__", ".pytest_cache", "site"] [tool.ruff.lint.isort] # case-sensitive = true combine-as-imports = true force-sort-within-sections = true force-wrap-aliases = true known-local-folder = ["src"] relative-imports-order = "closest-to-furthest" [tool.ruff.lint.pydocstyle] convention = "google" [tool.tox] legacy_tox_ini = """ [tox] requires = tox>=4 env_list = lint, type, format, sast, py{38,39,310,311,312} [testenv:lint] description = ruff linter deps = ruff commands = ruff check . [testenv:type] description = pyright type checker deps = pyright pypandoc-binary pytest commands = pyright . [testenv:format] description = code formatter deps = black commands = black . [testenv:sast] deps = bandit[toml] commands = bandit -c pyproject.toml -r . [testenv] description = unit tests deps = pytest commands = pytest . """ validators-0.28.3/src/000077500000000000000000000000001462425114700145515ustar00rootroot00000000000000validators-0.28.3/src/validators/000077500000000000000000000000001462425114700167215ustar00rootroot00000000000000validators-0.28.3/src/validators/__init__.py000066400000000000000000000035611462425114700210370ustar00rootroot00000000000000"""Validate Anything!""" # local from .between import between from .btc_address import btc_address from .card import amex, card_number, diners, discover, jcb, mastercard, unionpay, visa from .country import calling_code, country_code, currency from .cron import cron from .domain import domain from .email import email from .encoding import base58, base64 from .finance import cusip, isin, sedol from .hashes import md5, sha1, sha224, sha256, sha512 from .hostname import hostname from .i18n import ( es_cif, es_doi, es_nie, es_nif, fi_business_id, fi_ssn, fr_department, fr_ssn, ind_aadhar, ind_pan, ) from .iban import iban from .ip_address import ipv4, ipv6 from .length import length from .mac_address import mac_address from .slug import slug from .url import url from .utils import ValidationError, validator from .uuid import uuid # from .crypto_addresses import eth_address __all__ = ( # ... "between", # crypto_addresses "btc_address", # cards "amex", "card_number", "diners", "discover", "jcb", "mastercard", "visa", "unionpay", # country "calling_code", "country_code", "currency", # ... "cron", # ... "domain", # ... "email", # encodings "base58", "base64", # finance "cusip", "isin", "sedol", # hashes "md5", "sha1", "sha224", "sha256", "sha512", # ... "hostname", # i18n "es_cif", "es_doi", "es_nie", "es_nif", "fi_business_id", "fi_ssn", "fr_department", "fr_ssn", "ind_aadhar", "ind_pan", # ... "iban", # ip_addresses "ipv4", "ipv6", # ... "length", # ... "mac_address", # ... "slug", # ... "url", # ... "uuid", # utils "ValidationError", "validator", ) __version__ = "0.28.3" validators-0.28.3/src/validators/_extremes.py000066400000000000000000000020161462425114700212650ustar00rootroot00000000000000"""Extremes.""" # standard from functools import total_ordering from typing import Any @total_ordering class AbsMax: """An object that is greater than any other object (except itself). Inspired by https://pypi.python.org/pypi/Extremes. Examples: >>> from sys import maxint >>> AbsMax > AbsMin # Output: True >>> AbsMax > maxint # Output: True >>> AbsMax > 99999999999999999 # Output: True """ def __ge__(self, other: Any): """GreaterThanOrEqual.""" return other is not AbsMax @total_ordering class AbsMin: """An object that is less than any other object (except itself). Inspired by https://pypi.python.org/pypi/Extremes. Examples: >>> from sys import maxint >>> AbsMin < -maxint # Output: True >>> AbsMin < None # Output: True >>> AbsMin < '' # Output: True """ def __le__(self, other: Any): """LessThanOrEqual.""" return other is not AbsMin validators-0.28.3/src/validators/_tld.txt000066400000000000000000000226331462425114700204120ustar00rootroot00000000000000# Version 2024052400, Last Updated Fri May 24 07:07:01 2024 UTC AAA AARP ABB ABBOTT ABBVIE ABC ABLE ABOGADO ABUDHABI AC ACADEMY ACCENTURE ACCOUNTANT ACCOUNTANTS ACO ACTOR AD ADS ADULT AE AEG AERO AETNA AF AFL AFRICA AG AGAKHAN AGENCY AI AIG AIRBUS AIRFORCE AIRTEL AKDN AL ALIBABA ALIPAY ALLFINANZ ALLSTATE ALLY ALSACE ALSTOM AM AMAZON AMERICANEXPRESS AMERICANFAMILY AMEX AMFAM AMICA AMSTERDAM ANALYTICS ANDROID ANQUAN ANZ AO AOL APARTMENTS APP APPLE AQ AQUARELLE AR ARAB ARAMCO ARCHI ARMY ARPA ART ARTE AS ASDA ASIA ASSOCIATES AT ATHLETA ATTORNEY AU AUCTION AUDI AUDIBLE AUDIO AUSPOST AUTHOR AUTO AUTOS AW AWS AX AXA AZ AZURE BA BABY BAIDU BANAMEX BAND BANK BAR BARCELONA BARCLAYCARD BARCLAYS BAREFOOT BARGAINS BASEBALL BASKETBALL BAUHAUS BAYERN BB BBC BBT BBVA BCG BCN BD BE BEATS BEAUTY BEER BENTLEY BERLIN BEST BESTBUY BET BF BG BH BHARTI BI BIBLE BID BIKE BING BINGO BIO BIZ BJ BLACK BLACKFRIDAY BLOCKBUSTER BLOG BLOOMBERG BLUE BM BMS BMW BN BNPPARIBAS BO BOATS BOEHRINGER BOFA BOM BOND BOO BOOK BOOKING BOSCH BOSTIK BOSTON BOT BOUTIQUE BOX BR BRADESCO BRIDGESTONE BROADWAY BROKER BROTHER BRUSSELS BS BT BUILD BUILDERS BUSINESS BUY BUZZ BV BW BY BZ BZH CA CAB CAFE CAL CALL CALVINKLEIN CAM CAMERA CAMP CANON CAPETOWN CAPITAL CAPITALONE CAR CARAVAN CARDS CARE CAREER CAREERS CARS CASA CASE CASH CASINO CAT CATERING CATHOLIC CBA CBN CBRE CC CD CENTER CEO CERN CF CFA CFD CG CH CHANEL CHANNEL CHARITY CHASE CHAT CHEAP CHINTAI CHRISTMAS CHROME CHURCH CI CIPRIANI CIRCLE CISCO CITADEL CITI CITIC CITY CK CL CLAIMS CLEANING CLICK CLINIC CLINIQUE CLOTHING CLOUD CLUB CLUBMED CM CN CO COACH CODES COFFEE COLLEGE COLOGNE COM COMMBANK COMMUNITY COMPANY COMPARE COMPUTER COMSEC CONDOS CONSTRUCTION CONSULTING CONTACT CONTRACTORS COOKING COOL COOP CORSICA COUNTRY COUPON COUPONS COURSES CPA CR CREDIT CREDITCARD CREDITUNION CRICKET CROWN CRS CRUISE CRUISES CU CUISINELLA CV CW CX CY CYMRU CYOU CZ DABUR DAD DANCE DATA DATE DATING DATSUN DAY DCLK DDS DE DEAL DEALER DEALS DEGREE DELIVERY DELL DELOITTE DELTA DEMOCRAT DENTAL DENTIST DESI DESIGN DEV DHL DIAMONDS DIET DIGITAL DIRECT DIRECTORY DISCOUNT DISCOVER DISH DIY DJ DK DM DNP DO DOCS DOCTOR DOG DOMAINS DOT DOWNLOAD DRIVE DTV DUBAI DUNLOP DUPONT DURBAN DVAG DVR DZ EARTH EAT EC ECO EDEKA EDU EDUCATION EE EG EMAIL EMERCK ENERGY ENGINEER ENGINEERING ENTERPRISES EPSON EQUIPMENT ER ERICSSON ERNI ES ESQ ESTATE ET EU EUROVISION EUS EVENTS EXCHANGE EXPERT EXPOSED EXPRESS EXTRASPACE FAGE FAIL FAIRWINDS FAITH FAMILY FAN FANS FARM FARMERS FASHION FAST FEDEX FEEDBACK FERRARI FERRERO FI FIDELITY FIDO FILM FINAL FINANCE FINANCIAL FIRE FIRESTONE FIRMDALE FISH FISHING FIT FITNESS FJ FK FLICKR FLIGHTS FLIR FLORIST FLOWERS FLY FM FO FOO FOOD FOOTBALL FORD FOREX FORSALE FORUM FOUNDATION FOX FR FREE FRESENIUS FRL FROGANS FRONTIER FTR FUJITSU FUN FUND FURNITURE FUTBOL FYI GA GAL GALLERY GALLO GALLUP GAME GAMES GAP GARDEN GAY GB GBIZ GD GDN GE GEA GENT GENTING GEORGE GF GG GGEE GH GI GIFT GIFTS GIVES GIVING GL GLASS GLE GLOBAL GLOBO GM GMAIL GMBH GMO GMX GN GODADDY GOLD GOLDPOINT GOLF GOO GOODYEAR GOOG GOOGLE GOP GOT GOV GP GQ GR GRAINGER GRAPHICS GRATIS GREEN GRIPE GROCERY GROUP GS GT GU GUCCI GUGE GUIDE GUITARS GURU GW GY HAIR HAMBURG HANGOUT HAUS HBO HDFC HDFCBANK HEALTH HEALTHCARE HELP HELSINKI HERE HERMES HIPHOP HISAMITSU HITACHI HIV HK HKT HM HN HOCKEY HOLDINGS HOLIDAY HOMEDEPOT HOMEGOODS HOMES HOMESENSE HONDA HORSE HOSPITAL HOST HOSTING HOT HOTELS HOTMAIL HOUSE HOW HR HSBC HT HU HUGHES HYATT HYUNDAI IBM ICBC ICE ICU ID IE IEEE IFM IKANO IL IM IMAMAT IMDB IMMO IMMOBILIEN IN INC INDUSTRIES INFINITI INFO ING INK INSTITUTE INSURANCE INSURE INT INTERNATIONAL INTUIT INVESTMENTS IO IPIRANGA IQ IR IRISH IS ISMAILI IST ISTANBUL IT ITAU ITV JAGUAR JAVA JCB JE JEEP JETZT JEWELRY JIO JLL JM JMP JNJ JO JOBS JOBURG JOT JOY JP JPMORGAN JPRS JUEGOS JUNIPER KAUFEN KDDI KE KERRYHOTELS KERRYLOGISTICS KERRYPROPERTIES KFH KG KH KI KIA KIDS KIM KINDLE KITCHEN KIWI KM KN KOELN KOMATSU KOSHER KP KPMG KPN KR KRD KRED KUOKGROUP KW KY KYOTO KZ LA LACAIXA LAMBORGHINI LAMER LANCASTER LAND LANDROVER LANXESS LASALLE LAT LATINO LATROBE LAW LAWYER LB LC LDS LEASE LECLERC LEFRAK LEGAL LEGO LEXUS LGBT LI LIDL LIFE LIFEINSURANCE LIFESTYLE LIGHTING LIKE LILLY LIMITED LIMO LINCOLN LINK LIPSY LIVE LIVING LK LLC LLP LOAN LOANS LOCKER LOCUS LOL LONDON LOTTE LOTTO LOVE LPL LPLFINANCIAL LR LS LT LTD LTDA LU LUNDBECK LUXE LUXURY LV LY MA MADRID MAIF MAISON MAKEUP MAN MANAGEMENT MANGO MAP MARKET MARKETING MARKETS MARRIOTT MARSHALLS MATTEL MBA MC MCKINSEY MD ME MED MEDIA MEET MELBOURNE MEME MEMORIAL MEN MENU MERCKMSD MG MH MIAMI MICROSOFT MIL MINI MINT MIT MITSUBISHI MK ML MLB MLS MM MMA MN MO MOBI MOBILE MODA MOE MOI MOM MONASH MONEY MONSTER MORMON MORTGAGE MOSCOW MOTO MOTORCYCLES MOV MOVIE MP MQ MR MS MSD MT MTN MTR MU MUSEUM MUSIC MV MW MX MY MZ NA NAB NAGOYA NAME NATURA NAVY NBA NC NE NEC NET NETBANK NETFLIX NETWORK NEUSTAR NEW NEWS NEXT NEXTDIRECT NEXUS NF NFL NG NGO NHK NI NICO NIKE NIKON NINJA NISSAN NISSAY NL NO NOKIA NORTON NOW NOWRUZ NOWTV NP NR NRA NRW NTT NU NYC NZ OBI OBSERVER OFFICE OKINAWA OLAYAN OLAYANGROUP OLLO OM OMEGA ONE ONG ONL ONLINE OOO OPEN ORACLE ORANGE ORG ORGANIC ORIGINS OSAKA OTSUKA OTT OVH PA PAGE PANASONIC PARIS PARS PARTNERS PARTS PARTY PAY PCCW PE PET PF PFIZER PG PH PHARMACY PHD PHILIPS PHONE PHOTO PHOTOGRAPHY PHOTOS PHYSIO PICS PICTET PICTURES PID PIN PING PINK PIONEER PIZZA PK PL PLACE PLAY PLAYSTATION PLUMBING PLUS PM PN PNC POHL POKER POLITIE PORN POST PR PRAMERICA PRAXI PRESS PRIME PRO PROD PRODUCTIONS PROF PROGRESSIVE PROMO PROPERTIES PROPERTY PROTECTION PRU PRUDENTIAL PS PT PUB PW PWC PY QA QPON QUEBEC QUEST RACING RADIO RE READ REALESTATE REALTOR REALTY RECIPES RED REDSTONE REDUMBRELLA REHAB REISE REISEN REIT RELIANCE REN RENT RENTALS REPAIR REPORT REPUBLICAN REST RESTAURANT REVIEW REVIEWS REXROTH RICH RICHARDLI RICOH RIL RIO RIP RO ROCKS RODEO ROGERS ROOM RS RSVP RU RUGBY RUHR RUN RW RWE RYUKYU SA SAARLAND SAFE SAFETY SAKURA SALE SALON SAMSCLUB SAMSUNG SANDVIK SANDVIKCOROMANT SANOFI SAP SARL SAS SAVE SAXO SB SBI SBS SC SCB SCHAEFFLER SCHMIDT SCHOLARSHIPS SCHOOL SCHULE SCHWARZ SCIENCE SCOT SD SE SEARCH SEAT SECURE SECURITY SEEK SELECT SENER SERVICES SEVEN SEW SEX SEXY SFR SG SH SHANGRILA SHARP SHAW SHELL SHIA SHIKSHA SHOES SHOP SHOPPING SHOUJI SHOW SI SILK SINA SINGLES SITE SJ SK SKI SKIN SKY SKYPE SL SLING SM SMART SMILE SN SNCF SO SOCCER SOCIAL SOFTBANK SOFTWARE SOHU SOLAR SOLUTIONS SONG SONY SOY SPA SPACE SPORT SPOT SR SRL SS ST STADA STAPLES STAR STATEBANK STATEFARM STC STCGROUP STOCKHOLM STORAGE STORE STREAM STUDIO STUDY STYLE SU SUCKS SUPPLIES SUPPLY SUPPORT SURF SURGERY SUZUKI SV SWATCH SWISS SX SY SYDNEY SYSTEMS SZ TAB TAIPEI TALK TAOBAO TARGET TATAMOTORS TATAR TATTOO TAX TAXI TC TCI TD TDK TEAM TECH TECHNOLOGY TEL TEMASEK TENNIS TEVA TF TG TH THD THEATER THEATRE TIAA TICKETS TIENDA TIPS TIRES TIROL TJ TJMAXX TJX TK TKMAXX TL TM TMALL TN TO TODAY TOKYO TOOLS TOP TORAY TOSHIBA TOTAL TOURS TOWN TOYOTA TOYS TR TRADE TRADING TRAINING TRAVEL TRAVELERS TRAVELERSINSURANCE TRUST TRV TT TUBE TUI TUNES TUSHU TV TVS TW TZ UA UBANK UBS UG UK UNICOM UNIVERSITY UNO UOL UPS US UY UZ VA VACATIONS VANA VANGUARD VC VE VEGAS VENTURES VERISIGN VERSICHERUNG VET VG VI VIAJES VIDEO VIG VIKING VILLAS VIN VIP VIRGIN VISA VISION VIVA VIVO VLAANDEREN VN VODKA VOLVO VOTE VOTING VOTO VOYAGE VU WALES WALMART WALTER WANG WANGGOU WATCH WATCHES WEATHER WEATHERCHANNEL WEBCAM WEBER WEBSITE WED WEDDING WEIBO WEIR WF WHOSWHO WIEN WIKI WILLIAMHILL WIN WINDOWS WINE WINNERS WME WOLTERSKLUWER WOODSIDE WORK WORKS WORLD WOW WS WTC WTF XBOX XEROX XIHUAN XIN XN--11B4C3D XN--1CK2E1B XN--1QQW23A XN--2SCRJ9C XN--30RR7Y XN--3BST00M XN--3DS443G XN--3E0B707E XN--3HCRJ9C XN--3PXU8K XN--42C2D9A XN--45BR5CYL XN--45BRJ9C XN--45Q11C XN--4DBRK0CE XN--4GBRIM XN--54B7FTA0CC XN--55QW42G XN--55QX5D XN--5SU34J936BGSG XN--5TZM5G XN--6FRZ82G XN--6QQ986B3XL XN--80ADXHKS XN--80AO21A XN--80AQECDR1A XN--80ASEHDB XN--80ASWG XN--8Y0A063A XN--90A3AC XN--90AE XN--90AIS XN--9DBQ2A XN--9ET52U XN--9KRT00A XN--B4W605FERD XN--BCK1B9A5DRE4C XN--C1AVG XN--C2BR7G XN--CCK2B3B XN--CCKWCXETD XN--CG4BKI XN--CLCHC0EA0B2G2A9GCD XN--CZR694B XN--CZRS0T XN--CZRU2D XN--D1ACJ3B XN--D1ALF XN--E1A4C XN--ECKVDTC9D XN--EFVY88H XN--FCT429K XN--FHBEI XN--FIQ228C5HS XN--FIQ64B XN--FIQS8S XN--FIQZ9S XN--FJQ720A XN--FLW351E XN--FPCRJ9C3D XN--FZC2C9E2C XN--FZYS8D69UVGM XN--G2XX48C XN--GCKR3F0F XN--GECRJ9C XN--GK3AT1E XN--H2BREG3EVE XN--H2BRJ9C XN--H2BRJ9C8C XN--HXT814E XN--I1B6B1A6A2E XN--IMR513N XN--IO0A7I XN--J1AEF XN--J1AMH XN--J6W193G XN--JLQ480N2RG XN--JVR189M XN--KCRX77D1X4A XN--KPRW13D XN--KPRY57D XN--KPUT3I XN--L1ACC XN--LGBBAT1AD8J XN--MGB9AWBF XN--MGBA3A3EJT XN--MGBA3A4F16A XN--MGBA7C0BBN0A XN--MGBAAM7A8H XN--MGBAB2BD XN--MGBAH1A3HJKRD XN--MGBAI9AZGQP6J XN--MGBAYH7GPA XN--MGBBH1A XN--MGBBH1A71E XN--MGBC0A9AZCG XN--MGBCA7DZDO XN--MGBCPQ6GPA1A XN--MGBERP4A5D4AR XN--MGBGU82A XN--MGBI4ECEXP XN--MGBPL2FH XN--MGBT3DHD XN--MGBTX2B XN--MGBX4CD0AB XN--MIX891F XN--MK1BU44C XN--MXTQ1M XN--NGBC5AZD XN--NGBE9E0A XN--NGBRX XN--NODE XN--NQV7F XN--NQV7FS00EMA XN--NYQY26A XN--O3CW4H XN--OGBPF8FL XN--OTU796D XN--P1ACF XN--P1AI XN--PGBS0DH XN--PSSY2U XN--Q7CE6A XN--Q9JYB4C XN--QCKA1PMC XN--QXA6A XN--QXAM XN--RHQV96G XN--ROVU88B XN--RVC1E0AM3E XN--S9BRJ9C XN--SES554G XN--T60B56A XN--TCKWE XN--TIQ49XQYJ XN--UNUP4Y XN--VERMGENSBERATER-CTB XN--VERMGENSBERATUNG-PWB XN--VHQUV XN--VUQ861B XN--W4R85EL8FHU5DNRA XN--W4RS40L XN--WGBH1C XN--WGBL6A XN--XHQ521B XN--XKC2AL3HYE2A XN--XKC2DL3A5EE0H XN--Y9A3AQ XN--YFRO4I67O XN--YGBI2AMMX XN--ZFR164B XXX XYZ YACHTS YAHOO YAMAXUN YANDEX YE YODOBASHI YOGA YOKOHAMA YOU YOUTUBE YT YUN ZA ZAPPOS ZARA ZERO ZIP ZM ZONE ZUERICH ZW validators-0.28.3/src/validators/between.py000066400000000000000000000046141462425114700207310ustar00rootroot00000000000000"""Between.""" # standard from datetime import datetime from typing import TypeVar, Union # local from ._extremes import AbsMax, AbsMin from .utils import validator PossibleValueTypes = TypeVar("PossibleValueTypes", int, float, str, datetime, None) @validator def between( value: PossibleValueTypes, /, *, min_val: Union[PossibleValueTypes, AbsMin, None] = None, max_val: Union[PossibleValueTypes, AbsMax, None] = None, ): """Validate that a number is between minimum and/or maximum value. This will work with any comparable type, such as floats, decimals and dates not just integers. This validator is originally based on [WTForms-NumberRange-Validator][1]. [1]: https://github.com/wtforms/wtforms/blob/master/src/wtforms/validators.py#L166-L220 Examples: >>> from datetime import datetime >>> between(5, min_val=2) # Output: True >>> between(13.2, min_val=13, max_val=14) # Output: True >>> between(500, max_val=400) # Output: ValidationError(func=between, args=...) >>> between( ... datetime(2000, 11, 11), ... min_val=datetime(1999, 11, 11) ... ) # Output: True Args: value: Value which is to be compared. min_val: The minimum required value of the number. If not provided, minimum value will not be checked. max_val: The maximum value of the number. If not provided, maximum value will not be checked. Returns: (Literal[True]): If `value` is in between the given conditions. (ValidationError): If `value` is not in between the given conditions. Raises: (ValueError): If `min_val` is greater than `max_val`. (TypeError): If there's a type mismatch during comparison. Note: - `PossibleValueTypes` = `TypeVar("PossibleValueTypes", int, float, str, datetime)` - If neither `min_val` nor `max_val` is provided, result will always be `True`. """ if value is None: return False if max_val is None: max_val = AbsMax() if min_val is None: min_val = AbsMin() try: if min_val > max_val: raise ValueError("`min_val` cannot be greater than `max_val`") except TypeError as err: raise TypeError("Comparison type mismatch") from err return min_val <= value <= max_val validators-0.28.3/src/validators/btc_address.py000066400000000000000000000031671462425114700215570ustar00rootroot00000000000000"""BTC Address.""" # standard from hashlib import sha256 import re # local from .utils import validator def _decode_base58(addr: str): """Decode base58.""" alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" return sum((58**enm) * alphabet.index(idx) for enm, idx in enumerate(addr[::-1])) def _validate_old_btc_address(addr: str): """Validate P2PKH and P2SH type address.""" if len(addr) not in range(25, 35): return False decoded_bytes = _decode_base58(addr).to_bytes(25, "big") header, checksum = decoded_bytes[:-4], decoded_bytes[-4:] return checksum == sha256(sha256(header).digest()).digest()[:4] @validator def btc_address(value: str, /): """Return whether or not given value is a valid bitcoin address. Full validation is implemented for P2PKH and P2SH addresses. For segwit addresses a regexp is used to provide a reasonable estimate on whether the address is valid. Examples: >>> btc_address('3Cwgr2g7vsi1bXDUkpEnVoRLA9w4FZfC69') # Output: True >>> btc_address('1BvBMsEYstWetqTFn5Au4m4GFg7xJaNVN2') # Output: ValidationError(func=btc_address, args=...) Args: value: Bitcoin address string to validate. Returns: (Literal[True]): If `value` is a valid bitcoin address. (ValidationError): If `value` is an invalid bitcoin address. """ if not value: return False return ( # segwit pattern re.compile(r"^(bc|tc)[0-3][02-9ac-hj-np-z]{14,74}$").match(value) if value[:2] in ("bc", "tb") else _validate_old_btc_address(value) ) validators-0.28.3/src/validators/card.py000066400000000000000000000132061462425114700202060ustar00rootroot00000000000000"""Card.""" # standard import re # local from .utils import validator @validator def card_number(value: str, /): """Return whether or not given value is a valid generic card number. This validator is based on [Luhn's algorithm][1]. [1]: https://github.com/mmcloughlin/luhn Examples: >>> card_number('4242424242424242') # Output: True >>> card_number('4242424242424241') # Output: ValidationError(func=card_number, args={'value': '4242424242424241'}) Args: value: Generic card number string to validate Returns: (Literal[True]): If `value` is a valid generic card number. (ValidationError): If `value` is an invalid generic card number. """ if not value: return False try: digits = list(map(int, value)) odd_sum = sum(digits[-1::-2]) even_sum = sum(sum(divmod(2 * d, 10)) for d in digits[-2::-2]) return (odd_sum + even_sum) % 10 == 0 except ValueError: return False @validator def visa(value: str, /): """Return whether or not given value is a valid Visa card number. Examples: >>> visa('4242424242424242') # Output: True >>> visa('2223003122003222') # Output: ValidationError(func=visa, args={'value': '2223003122003222'}) Args: value: Visa card number string to validate Returns: (Literal[True]): If `value` is a valid Visa card number. (ValidationError): If `value` is an invalid Visa card number. """ pattern = re.compile(r"^4") return card_number(value) and len(value) == 16 and pattern.match(value) @validator def mastercard(value: str, /): """Return whether or not given value is a valid Mastercard card number. Examples: >>> mastercard('5555555555554444') # Output: True >>> mastercard('4242424242424242') # Output: ValidationError(func=mastercard, args={'value': '4242424242424242'}) Args: value: Mastercard card number string to validate Returns: (Literal[True]): If `value` is a valid Mastercard card number. (ValidationError): If `value` is an invalid Mastercard card number. """ pattern = re.compile(r"^(51|52|53|54|55|22|23|24|25|26|27)") return card_number(value) and len(value) == 16 and pattern.match(value) @validator def amex(value: str, /): """Return whether or not given value is a valid American Express card number. Examples: >>> amex('378282246310005') # Output: True >>> amex('4242424242424242') # Output: ValidationError(func=amex, args={'value': '4242424242424242'}) Args: value: American Express card number string to validate Returns: (Literal[True]): If `value` is a valid American Express card number. (ValidationError): If `value` is an invalid American Express card number. """ pattern = re.compile(r"^(34|37)") return card_number(value) and len(value) == 15 and pattern.match(value) @validator def unionpay(value: str, /): """Return whether or not given value is a valid UnionPay card number. Examples: >>> unionpay('6200000000000005') # Output: True >>> unionpay('4242424242424242') # Output: ValidationError(func=unionpay, args={'value': '4242424242424242'}) Args: value: UnionPay card number string to validate Returns: (Literal[True]): If `value` is a valid UnionPay card number. (ValidationError): If `value` is an invalid UnionPay card number. """ pattern = re.compile(r"^62") return card_number(value) and len(value) == 16 and pattern.match(value) @validator def diners(value: str, /): """Return whether or not given value is a valid Diners Club card number. Examples: >>> diners('3056930009020004') # Output: True >>> diners('4242424242424242') # Output: ValidationError(func=diners, args={'value': '4242424242424242'}) Args: value: Diners Club card number string to validate Returns: (Literal[True]): If `value` is a valid Diners Club card number. (ValidationError): If `value` is an invalid Diners Club card number. """ pattern = re.compile(r"^(30|36|38|39)") return card_number(value) and len(value) in {14, 16} and pattern.match(value) @validator def jcb(value: str, /): """Return whether or not given value is a valid JCB card number. Examples: >>> jcb('3566002020360505') # Output: True >>> jcb('4242424242424242') # Output: ValidationError(func=jcb, args={'value': '4242424242424242'}) Args: value: JCB card number string to validate Returns: (Literal[True]): If `value` is a valid JCB card number. (ValidationError): If `value` is an invalid JCB card number. """ pattern = re.compile(r"^35") return card_number(value) and len(value) == 16 and pattern.match(value) @validator def discover(value: str, /): """Return whether or not given value is a valid Discover card number. Examples: >>> discover('6011111111111117') # Output: True >>> discover('4242424242424242') # Output: ValidationError(func=discover, args={'value': '4242424242424242'}) Args: value: Discover card number string to validate Returns: (Literal[True]): If `value` is a valid Discover card number. (ValidationError): If `value` is an invalid Discover card number. """ pattern = re.compile(r"^(60|64|65)") return card_number(value) and len(value) == 16 and pattern.match(value) validators-0.28.3/src/validators/country.py000066400000000000000000000351071462425114700210040ustar00rootroot00000000000000"""Country.""" # local from validators.utils import validator # fmt: off _alpha3_to_alpha2 = { # A "ABW": "AW", "AFG": "AF", "AGO": "AO", "AIA": "AI", "ALB": "AL", "AND": "AD", "ANT": "AN", "ARE": "AE", "ARG": "AR", "ARM": "AM", "ASM": "AS", "ATA": "AQ", "ATF": "TF", "ATG": "AG", "AUS": "AU", "AUT": "AT", "AZE": "AZ", # B "BDI": "BI", "BEL": "BE", "BEN": "BJ", "BFA": "BF", "BGD": "BD", "BGR": "BG", "BHR": "BH", "BHS": "BS", "BIH": "BA", "BLR": "BY", "BLZ": "BZ", "BMU": "BM", "BOL": "BO", "BRA": "BR", "BRB": "BB", "BRN": "BN", "BTN": "BT", "BVT": "BV", "BWA": "BW", # C "CAF": "CF", "CAN": "CA", "CCK": "CC", "CHE": "CH", "CHL": "CL", "CHN": "CN", "CMR": "CM", "COD": "CD", "COG": "CG", "COK": "CK", "COL": "CO", "COM": "KM", "CPV": "CV", "CRI": "CR", "CUB": "CU", "CXR": "CX", "CYM": "KY", "CYP": "CY", "CZE": "CZ", # D "DEU": "DE", "DJI": "DJ", "DMA": "DM", "DNK": "DK", "DOM": "DO", "DZA": "DZ", # E "ECU": "EC", "EGY": "EG", "ERI": "ER", "ESH": "EH", "ESP": "ES", "EST": "EE", "ETH": "ET", # F "FIN": "FI", "FJI": "FJ", "FLK": "FK", "FRA": "FR", "FRO": "FO", "FSM": "FM", # G "GAB": "GA", "GBR": "GB", "GEO": "GE", "GGY": "GG", "GHA": "GH", "GIB": "GI", "GIN": "GN", "GLP": "GP", "GMB": "GM", "GNB": "GW", "GNQ": "GQ", "GRC": "GR", "GRD": "GD", "GRL": "GL", "GTM": "GT", "GUF": "GF", "GUM": "GU", "GUY": "GY", # H "HKG": "HK", "HMD": "HM", "HND": "HN", "HRV": "HR", "HTI": "HT", "HUN": "HU", # I "IDN": "ID", "IMN": "IM", "IND": "IN", "IOT": "IO", "IRL": "IE", "IRN": "IR", "IRQ": "IQ", "ISL": "IS", "ISR": "IL", "ITA": "IT", # J "JAM": "JM", "JEY": "JE", "JOR": "JO", "JPN": "JP", # K "KAZ": "KZ", "KEN": "KE", "KGZ": "KG", "KHM": "KH", "KIR": "KI", "KNA": "KN", "KOR": "KR", "KWT": "KW", # L "LAO": "LA", "LBN": "LB", "LBR": "LR", "LBY": "LY", "LCA": "LC", "LIE": "LI", "LKA": "LK", "LSO": "LS", "LTU": "LT", "LUX": "LU", "LVA": "LV", # M "MAC": "MO", "MAR": "MA", "MCO": "MC", "MDA": "MD", "MDG": "MG", "MDV": "MV", "MEX": "MX", "MHL": "MH", "MKD": "MK", "MLI": "ML", "MLT": "MT", "MMR": "MM", "MNE": "ME", "MNG": "MN", "MNP": "MP", "MOZ": "MZ", "MRT": "MR", "MSR": "MS", "MTQ": "MQ", "MUS": "MU", "MWI": "MW", "MYS": "MY", "MYT": "YT", # N "NAM": "NA", "NCL": "NC", "NER": "NE", "NFK": "NF", "NGA": "NG", "NIC": "NI", "NIU": "NU", "NLD": "NL", "NOR": "NO", "NPL": "NP", "NRU": "NR", "NZL": "NZ", # O "OMN": "OM", # P "PAK": "PK", "PAN": "PA", "PCN": "PN", "PER": "PE", "PHL": "PH", "PLW": "PW", "PNG": "PG", "POL": "PL", "PRI": "PR", "PRK": "KP", "PRT": "PT", "PRY": "PY", "PSE": "PS", "PYF": "PF", # Q "QAT": "QA", # R "REU": "RE", "ROU": "RO", "RUS": "RU", "RWA": "RW", # S "SAU": "SA", "SDN": "SD", "SEN": "SN", "SGP": "SG", "SGS": "GS", "SHN": "SH", "SJM": "SJ", "SLB": "SB", "SLE": "SL", "SLV": "SV", "SMR": "SM", "SOM": "SO", "SPM": "PM", "SRB": "RS", "STP": "ST", "SUR": "SR", "SVK": "SK", "SVN": "SI", "SWE": "SE", "SWZ": "SZ", "SYC": "SC", "SYR": "SY", # T "TCA": "TC", "TCD": "TD", "TGO": "TG", "THA": "TH", "TJK": "TJ", "TKL": "TK", "TKM": "TM", "TLS": "TL", "TON": "TO", "TTO": "TT", "TUN": "TN", "TUR": "TR", "TUV": "TV", "TWN": "TW", "TZA": "TZ", # U "UGA": "UG", "UKR": "UA", "UMI": "UM", "URY": "UY", "USA": "US", "UZB": "UZ", # V "VAT": "VA", "VCT": "VC", "VEN": "VE", "VGB": "VG", "VIR": "VI", "VNM": "VN", "VUT": "VU", # W "WLF": "WF", "WSM": "WS", # Y "YEM": "YE", # Z "ZAF": "ZA", "ZMB": "ZM", "ZWE": "ZW", } _calling_codes = { # A "ABW": "+297", "AFG": "+93", "AGO": "+244", "AIA": "+1-264", "ALB": "+355", "AND": "+376", "ANT": "+599", "ARE": "+971", "ARG": "+54", "ARM": "+374", "ASM": "+1-684", "ATA": "+672", "ATG": "+1-268", "AUS": "+61", "AUT": "+43", "AZE": "+994", # B "BDI": "+257", "BEL": "+32", "BEN": "+229", "BFA": "+226", "BGD": "+880", "BGR": "+359", "BHR": "+973", "BHS": "+1-242", "BIH": "+387", "BLR": "+375", "BLZ": "+501", "BMU": "+1-441", "BOL": "+591", "BRA": "+55", "BRB": "+1-246", "BRN": "+673", "BTN": "+975", "BWA": "+267", # C "CAF": "+236", "CAN": "+1", "CCK": "+61", "CHE": "+41", "CHL": "+56", "CHN": "+86", "CMR": "+237", "COD": "+243", "COG": "+242", "COK": "+682", "COL": "+57", "COM": "+269", "CPV": "+238", "CRI": "+506", "CUB": "+53", "CXR": "+61", "CYM": "+1-345", "CYP": "+357", "CZE": "+420", # D "DEU": "+49", "DJI": "+253", "DMA": "+1-767", "DNK": "+45", "DOM": "+1-809", "DZA": "+213", # E "ECU": "+593", "EGY": "+20", "ERI": "+291", "ESH": "+212", "ESP": "+34", "EST": "+372", "ETH": "+251", # F "FIN": "+358", "FJI": "+679", "FLK": "+500", "FRA": "+33", "FRO": "+298", "FSM": "+691", # G "GAB": "+241", "GBR": "+44", "GEO": "+995", "GGY": "+44-1481", "GHA": "+233", "GIB": "+350", "GIN": "+224", "GLP": "+590", "GMB": "+220", "GNB": "+245", "GNQ": "+240", "GRC": "+30", "GRD": "+1-473", "GRL": "+299", "GTM": "+502", "GUF": "+594", "GUM": "+1-671", "GUY": "+592", # H "HKG": "+852", "HMD": "+672", "HND": "+504", "HRV": "+385", "HTI": "+509", "HUN": "+36", # I "IDN": "+62", "IMN": "+44-1624", "IND": "+91", "IOT": "+246", "IRL": "+353", "IRN": "+98", "IRQ": "+964", "ISL": "+354", "ISR": "+972", "ITA": "+39", # J "JAM": "+1-876", "JEY": "+44-1534", "JOR": "+962", "JPN": "+81", # K "KAZ": "+7", "KEN": "+254", "KGZ": "+996", "KHM": "+855", "KIR": "+686", "KNA": "+1-869", "KOR": "+82", "KWT": "+965", # L "LAO": "+856", "LBN": "+961", "LBR": "+231", "LBY": "+218", "LCA": "+1-758", "LIE": "+423", "LKA": "+94", "LSO": "+266", "LTU": "+370", "LUX": "+352", "LVA": "+371", # M "MAC": "+853", "MAR": "+212", "MCO": "+377", "MDA": "+373", "MDG": "+261", "MDV": "+960", "MEX": "+52", "MHL": "+692", "MKD": "+389", "MLI": "+223", "MLT": "+356", "MMR": "+95", "MNE": "+382", "MNG": "+976", "MNP": "+1-670", "MOZ": "+258", "MRT": "+222", "MSR": "+1-664", "MTQ": "+596", "MUS": "+230", "MWI": "+265", "MYS": "+60", "MYT": "+262", # N "NAM": "+264", "NCL": "+687", "NER": "+227", "NFK": "+672", "NGA": "+234", "NIC": "+505", "NIU": "+683", "NLD": "+31", "NOR": "+47", "NPL": "+977", "NRU": "+674", "NZL": "+64", # O "OMN": "+968", # P "PAK": "+92", "PAN": "+507", "PCN": "+64", "PER": "+51", "PHL": "+63", "PLW": "+680", "PNG": "+675", "POL": "+48", "PRI": "+1-787", "PRK": "+850", "PRT": "+351", "PRY": "+595", "PSE": "+970", "PYF": "+689", # Q "QAT": "+974", # R "REU": "+262", "ROU": "+40", "RUS": "+7", "RWA": "+250", # S "SAU": "+966", "SDN": "+249", "SEN": "+221", "SGP": "+65", "SHN": "+290", "SJM": "+47", "SLB": "+677", "SLE": "+232", "SLV": "+503", "SMR": "+378", "SOM": "+252", "SPM": "+508", "SRB": "+381", "STP": "+239", "SUR": "+597", "SVK": "+421", "SVN": "+386", "SWE": "+46", "SWZ": "+268", "SYC": "+248", "SYR": "+963", # T "TCA": "+1-649", "TCD": "+235", "TGO": "+228", "THA": "+66", "TJK": "+992", "TKL": "+690", "TKM": "+993", "TLS": "+670", "TON": "+676", "TTO": "+1-868", "TUN": "+216", "TUR": "+90", "TUV": "+688", "TWN": "+886", "TZA": "+255", # U "UGA": "+256", "UKR": "+380", "UMI": "+1", "URY": "+598", "USA": "+1", "UZB": "+998", # V "VAT": "+379", "VCT": "+1-784", "VEN": "+58", "VGB": "+1-284", "VIR": "+1-340", "VNM": "+84", "VUT": "+678", # W "WLF": "+681", "WSM": "+685", # Y "YEM": "+967", # Z "ZAF": "+27", "ZMB": "+260", "ZWE": "+263" } _numeric = { "004", "008", "010", "012", "016", "020", "024", "028", "031", "032", "036", "040", "044", "048", "050", "051", "052", "056", "060", "064", "068", "070", "072", "074", "076", "084", "086", "090", "092", "096", "100", "104", "108", "112", "116", "120", "124", "132", "136", "140", "144", "148", "152", "156", "158", "162", "166", "170", "174", "175", "178", "180", "184", "188", "191", "192", "196", "203", "204", "208", "212", "214", "218", "222", "226", "231", "232", "233", "234", "238", "239", "242", "246", "248", "250", "254", "258", "260", "262", "266", "268", "270", "275", "276", "288", "292", "296", "300", "304", "308", "312", "316", "320", "324", "328", "332", "334", "340", "344", "348", "352", "356", "360", "364", "368", "372", "376", "380", "384", "388", "392", "398", "400", "404", "408", "410", "414", "417", "418", "422", "426", "428", "430", "434", "438", "440", "442", "446", "450", "454", "458", "462", "466", "470", "474", "478", "480", "484", "492", "496", "498", "499", "500", "504", "508", "512", "516", "520", "524", "528", "531", "533", "534", "535", "540", "548", "554", "558", "562", "566", "570", "574", "578", "580", "581", "583", "584", "585", "586", "591", "598", "600", "604", "608", "612", "616", "620", "624", "626", "630", "634", "638", "642", "643", "646", "652", "654", "659", "660", "662", "663", "666", "670", "674", "678", "682", "686", "688", "690", "694", "702", "703", "704", "705", "706", "710", "716", "724", "728", "729", "732", "740", "744", "748", "752", "756", "760", "762", "764", "768", "772", "776", "780", "784", "788", "792", "795", "796", "798", "800", "804", "807", "818", "826", "831", "832", "833", "834", "840", "850", "854", "858", "860", "862", "876", "882", "887", "894", } _currency_iso4217 = { # https://en.wikipedia.org/wiki/ISO_4217 "AED", "AFN", "ALL", "AMD", "ANG", "AOA", "ARS", "AUD", "AWG", "AZN", "BAM", "BBD", "BDT", "BGN", "BHD", "BIF", "BMD", "BND", "BOB", "BOV", "BRL", "BSD", "BTN", "BWP", "BYN", "BZD", "CAD", "CDF", "CHE", "CHF", "CHW", "CKD", "CLF", "CLP", "CNY", "COP", "CRC", "CUC", "CUP", "CVE", "CZK", "DJF", "DKK", "DOP", "DZD", "EGP", "ERN", "ETB", "EUR", "FJD", "FKP", "GBP", "GEL", "GHS", "GIP", "GMD", "GNF", "GTQ", "GYD", "HKD", "HNL", "HRK", "HTG", "HUF", "IDR", "IEP", "ILS", "INR", "IQD", "IRR", "ISK", "JMD", "JOD", "JPY", "KES", "KGS", "KHR", "KID", "KMF", "KPW", "KRW", "KWD", "KYD", "KZT", "LAK", "LBP", "LKR", "LRD", "LSL", "LYD", "MAD", "MDL", "MGA", "MKD", "MMK", "MNT", "MOP", "MRU", "MUR", "MVR", "MWK", "MXN", "MYR", "MZN", "NAD", "NGN", "NIO", "NOK", "NPR", "NZD", "OMR", "PAB", "PEN", "PGK", "PHP", "PKR", "PLN", "PYG", "QAR", "RON", "RSD", "RUB", "RWF", "SAR", "SBD", "SCR", "SDG", "SEK", "SGD", "SHP", "SLL", "SOS", "SRD", "SSP", "STN", "SVC", "SYP", "SZL", "THB", "TJS", "TMT", "TND", "TOP", "TRY", "TTD", "TWD", "TZS", "UAH", "UGX", "USD", "UYU", "UZS", "VED", "VES", "VND", "VUV", "WST", "XAF", "XCD", "XDR", "XOF", "XPF", "YER", "ZAR", "ZMW", "ZWL" } _currency_symbols = { # https://en.wikipedia.org/wiki/Currency_sign_(generic) "؋", "฿", "₵", "₡", "¢", "$", "₫", "֏", "€", "ƒ", "₣", "₲", "₴", "₭", "₾", "£", "₺", "₼", "₦", "₱", "元", "圆", "圓", "﷼", "៛", "₽", "₹", "रू", "රු", "૱", "௹", "꠸", "Rs", "₪", "⃀" "৳", "₸", "₮", "₩", "¥", "円", "₿", "¤" } # fmt: on def _get_code_type(format_type: str): """Returns the type of country code.""" if format_type.isdecimal(): return "numeric" if format_type.isalpha(): if len(format_type) == 2: return "alpha2" if len(format_type) == 3: return "alpha3" return "invalid" @validator def calling_code(value: str, /): """Validates given calling code. This performs country's calling code validation. Examples: >>> calling_code('+91') # Output: True >>> calling_code('-31') # Output: ValidationError(func=calling_code, args={'value': '-31'}) Args: value: Country's calling code string to validate. Returns: (Literal[True]): If `value` is a valid calling code. (ValidationError): If `value` is an invalid calling code. """ if not value: return False return value in set(_calling_codes.values()) @validator def country_code(value: str, /, *, iso_format: str = "auto", ignore_case: bool = False): """Validates given country code. This performs a case-sensitive [ISO 3166][1] country code validation. [1]: https://www.iso.org/iso-3166-country-codes.html Examples: >>> country_code('GB', iso_format='alpha3') # Output: False >>> country_code('USA') # Output: True >>> country_code('840', iso_format='numeric') # Output: True >>> country_code('iN', iso_format='alpha2') # Output: False >>> country_code('ZWE', iso_format='alpha3') # Output: True Args: value: Country code string to validate. iso_format: ISO format to be used. Available options are: `auto`, `alpha2`, `alpha3` and `numeric`. ignore_case: Enable/Disable case-sensitive matching. Returns: (Literal[True]): If `value` is a valid country code. (ValidationError): If `value` is an invalid country code. """ if not value: return False if not (1 < len(value) < 4): return False if iso_format == "auto" and (iso_format := _get_code_type(value)) == "invalid": return False if iso_format == "alpha2": return ( value.upper() in set(_alpha3_to_alpha2.values()) if ignore_case else value in set(_alpha3_to_alpha2.values()) ) if iso_format == "alpha3": return value.upper() in _alpha3_to_alpha2 if ignore_case else value in _alpha3_to_alpha2 return value in _numeric if iso_format == "numeric" else False @validator def currency(value: str, /, *, skip_symbols: bool = True, ignore_case: bool = False): """Validates given currency code. This performs [ISO 4217][1] currency code/symbol validation. [1]: https://www.iso.org/iso-4217-currency-codes.html Examples: >>> currency('USD') # Output: True >>> currency('ZWX') # Output: ValidationError(func=currency, args={'value': 'ZWX'}) Args: value: Currency code/symbol string to validate. skip_symbols: Skip currency symbol validation. ignore_case: Enable/Disable case-sensitive matching. Returns: (Literal[True]): If `value` is a valid currency code. (ValidationError): If `value` is an invalid currency code. """ if not value: return False if not skip_symbols and value in _currency_symbols: return True if len(value) != 3: return False return value.upper() in _currency_iso4217 if ignore_case else value in _currency_iso4217 validators-0.28.3/src/validators/cron.py000066400000000000000000000043511462425114700202370ustar00rootroot00000000000000"""Cron.""" # local from .utils import validator def _validate_cron_component(component: str, min_val: int, max_val: int): if component == "*": return True if component.isdecimal(): return min_val <= int(component) <= max_val if "/" in component: parts = component.split("/") if len(parts) != 2 or not parts[1].isdecimal() or int(parts[1]) < 1: return False if parts[0] == "*": return True return parts[0].isdecimal() and min_val <= int(parts[0]) <= max_val if "-" in component: parts = component.split("-") if len(parts) != 2 or not parts[0].isdecimal() or not parts[1].isdecimal(): return False start, end = int(parts[0]), int(parts[1]) return min_val <= start <= max_val and min_val <= end <= max_val and start <= end if "," in component: for item in component.split(","): if not _validate_cron_component(item, min_val, max_val): return False return True # return all( # _validate_cron_component(item, min_val, max_val) for item in component.split(",") # ) # throws type error. why? return False @validator def cron(value: str, /): """Return whether or not given value is a valid cron string. Examples: >>> cron('*/5 * * * *') # Output: True >>> cron('30-20 * * * *') # Output: ValidationError(func=cron, ...) Args: value: Cron string to validate. Returns: (Literal[True]): If `value` is a valid cron string. (ValidationError): If `value` is an invalid cron string. """ if not value: return False try: minutes, hours, days, months, weekdays = value.strip().split() except ValueError as err: raise ValueError("Badly formatted cron string") from err if not _validate_cron_component(minutes, 0, 59): return False if not _validate_cron_component(hours, 0, 23): return False if not _validate_cron_component(days, 1, 31): return False if not _validate_cron_component(months, 1, 12): return False if not _validate_cron_component(weekdays, 0, 6): return False return True validators-0.28.3/src/validators/domain.py000066400000000000000000000047341462425114700205520ustar00rootroot00000000000000"""Domain.""" # standard from pathlib import Path import re # local from .utils import validator def _iana_tld(): """Load IANA TLDs as a Generator.""" # source: https://data.iana.org/TLD/tlds-alpha-by-domain.txt with Path(__file__).parent.joinpath("_tld.txt").open() as tld_f: _ = next(tld_f) # ignore the first line for line in tld_f: yield line.strip() @validator def domain( value: str, /, *, consider_tld: bool = False, rfc_1034: bool = False, rfc_2782: bool = False ): """Return whether or not given value is a valid domain. Examples: >>> domain('example.com') # Output: True >>> domain('example.com/') # Output: ValidationError(func=domain, ...) >>> # Supports IDN domains as well:: >>> domain('xn----gtbspbbmkef.xn--p1ai') # Output: True Args: value: Domain string to validate. consider_tld: Restrict domain to TLDs allowed by IANA. rfc_1034: Allows optional trailing dot in the domain name. Ref: [RFC 1034](https://www.rfc-editor.org/rfc/rfc1034). rfc_2782: Domain name is of type service record. Allows optional underscores in the domain name. Ref: [RFC 2782](https://www.rfc-editor.org/rfc/rfc2782). Returns: (Literal[True]): If `value` is a valid domain name. (ValidationError): If `value` is an invalid domain name. Raises: (UnicodeError): If `value` cannot be encoded into `idna` or decoded into `utf-8`. """ if not value: return False if consider_tld and value.rstrip(".").rsplit(".", 1)[-1].upper() not in _iana_tld(): return False try: service_record = r"_" if rfc_2782 else "" trailing_dot = r"\.?$" if rfc_1034 else r"$" return not re.search(r"\s|__+", value) and re.match( # First character of the domain rf"^(?:[a-z0-9{service_record}]" # Sub-domain + rf"(?:[a-z0-9-{service_record}]{{0,61}}" # Hostname + rf"[a-z0-9{service_record}])?\.)" # First 61 characters of the gTLD + r"+[a-z0-9][a-z0-9-_]{0,61}" # Last character of the gTLD + rf"[a-z]{trailing_dot}", value.encode("idna").decode("utf-8"), re.IGNORECASE, ) except UnicodeError as err: raise UnicodeError(f"Unable to encode/decode {value}") from err validators-0.28.3/src/validators/email.py000066400000000000000000000053441462425114700203700ustar00rootroot00000000000000"""eMail.""" # standard import re # local from .hostname import hostname from .utils import validator @validator def email( value: str, /, *, ipv6_address: bool = False, ipv4_address: bool = False, simple_host: bool = False, rfc_1034: bool = False, rfc_2782: bool = False, ): """Validate an email address. This was inspired from [Django's email validator][1]. Also ref: [RFC 1034][2], [RFC 5321][3] and [RFC 5322][4]. [1]: https://github.com/django/django/blob/main/django/core/validators.py#L174 [2]: https://www.rfc-editor.org/rfc/rfc1034 [3]: https://www.rfc-editor.org/rfc/rfc5321 [4]: https://www.rfc-editor.org/rfc/rfc5322 Examples: >>> email('someone@example.com') # Output: True >>> email('bogus@@') # Output: ValidationError(email=email, args={'value': 'bogus@@'}) Args: value: eMail string to validate. ipv6_address: When the domain part is an IPv6 address. ipv4_address: When the domain part is an IPv4 address. simple_host: When the domain part is a simple hostname. rfc_1034: Allow trailing dot in domain name. Ref: [RFC 1034](https://www.rfc-editor.org/rfc/rfc1034). rfc_2782: Domain name is of type service record. Ref: [RFC 2782](https://www.rfc-editor.org/rfc/rfc2782). Returns: (Literal[True]): If `value` is a valid eMail. (ValidationError): If `value` is an invalid eMail. """ if not value or value.count("@") != 1: return False username_part, domain_part = value.rsplit("@", 1) if len(username_part) > 64 or len(domain_part) > 253: # ref: RFC 1034 and 5231 return False if ipv6_address or ipv4_address: if domain_part.startswith("[") and domain_part.endswith("]"): # ref: RFC 5321 domain_part = domain_part.lstrip("[").rstrip("]") else: return False return ( bool( hostname( domain_part, skip_ipv6_addr=not ipv6_address, skip_ipv4_addr=not ipv4_address, may_have_port=False, maybe_simple=simple_host, rfc_1034=rfc_1034, rfc_2782=rfc_2782, ) ) if re.match( # extended latin r"(^[\u0100-\u017F\u0180-\u024F]" # dot-atom + r"|[-!#$%&'*+/=?^_`{}|~0-9a-z]+(\.[-!#$%&'*+/=?^_`{}|~0-9a-z]+)*$" # quoted-string + r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\011.])*"$)', username_part, re.IGNORECASE, ) else False ) validators-0.28.3/src/validators/encoding.py000066400000000000000000000025311462425114700210620ustar00rootroot00000000000000"""Encoding.""" # standard import re # local from .utils import validator @validator def base58(value: str, /): """Return whether or not given value is a valid base58 encoding. Examples: >>> base58('14pq6y9H2DLGahPsM4s7ugsNSD2uxpHsJx') # Output: True >>> base58('cUSECm5YzcXJwP') # Output: ValidationError(func=base58, args={'value': 'cUSECm5YzcXJwP'}) Args: value: base58 string to validate. Returns: (Literal[True]): If `value` is a valid base58 encoding. (ValidationError): If `value` is an invalid base58 encoding. """ return re.match(r"^[1-9A-HJ-NP-Za-km-z]+$", value) if value else False @validator def base64(value: str, /): """Return whether or not given value is a valid base64 encoding. Examples: >>> base64('Y2hhcmFjdGVyIHNldA==') # Output: True >>> base64('cUSECm5YzcXJwP') # Output: ValidationError(func=base64, args={'value': 'cUSECm5YzcXJwP'}) Args: value: base64 string to validate. Returns: (Literal[True]): If `value` is a valid base64 encoding. (ValidationError): If `value` is an invalid base64 encoding. """ return ( re.match(r"^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$", value) if value else False ) validators-0.28.3/src/validators/finance.py000066400000000000000000000063431462425114700207040ustar00rootroot00000000000000"""Finance.""" from .utils import validator def _cusip_checksum(cusip: str): check, val = 0, None for idx in range(9): c = cusip[idx] if c >= "0" and c <= "9": val = ord(c) - ord("0") elif c >= "A" and c <= "Z": val = 10 + ord(c) - ord("A") elif c >= "a" and c <= "z": val = 10 + ord(c) - ord("a") elif c == "*": val = 36 elif c == "@": val = 37 elif c == "#": val = 38 else: return False if idx & 1: val += val check = check + (val // 10) + (val % 10) return (check % 10) == 0 def _isin_checksum(value: str): check, val = 0, None for idx in range(12): c = value[idx] if c >= "0" and c <= "9" and idx > 1: val = ord(c) - ord("0") elif c >= "A" and c <= "Z": val = 10 + ord(c) - ord("A") elif c >= "a" and c <= "z": val = 10 + ord(c) - ord("a") else: return False if idx & 1: val += val return (check % 10) == 0 @validator def cusip(value: str): """Return whether or not given value is a valid CUSIP. Checks if the value is a valid [CUSIP][1]. [1]: https://en.wikipedia.org/wiki/CUSIP Examples: >>> cusip('037833DP2') True >>> cusip('037833DP3') ValidationFailure(func=cusip, ...) Args: value: CUSIP string to validate. Returns: (Literal[True]): If `value` is a valid CUSIP string. (ValidationError): If `value` is an invalid CUSIP string. """ return len(value) == 9 and _cusip_checksum(value) @validator def isin(value: str): """Return whether or not given value is a valid ISIN. Checks if the value is a valid [ISIN][1]. [1]: https://en.wikipedia.org/wiki/International_Securities_Identification_Number Examples: >>> isin('037833DP2') True >>> isin('037833DP3') ValidationFailure(func=isin, ...) Args: value: ISIN string to validate. Returns: (Literal[True]): If `value` is a valid ISIN string. (ValidationError): If `value` is an invalid ISIN string. """ return len(value) == 12 and _isin_checksum(value) @validator def sedol(value: str): """Return whether or not given value is a valid SEDOL. Checks if the value is a valid [SEDOL][1]. [1]: https://en.wikipedia.org/wiki/SEDOL Examples: >>> sedol('2936921') True >>> sedol('29A6922') ValidationFailure(func=sedol, ...) Args: value: SEDOL string to validate. Returns: (Literal[True]): If `value` is a valid SEDOL string. (ValidationError): If `value` is an invalid SEDOL string. """ if len(value) != 7: return False weights = [1, 3, 1, 7, 3, 9, 1] check = 0 for idx in range(7): c = value[idx] if c in "AEIOU": return False val = None if c >= "0" and c <= "9": val = ord(c) - ord("0") elif c >= "A" and c <= "Z": val = 10 + ord(c) - ord("A") else: return False check += val * weights[idx] return (check % 10) == 0 validators-0.28.3/src/validators/hashes.py000066400000000000000000000063271462425114700205560ustar00rootroot00000000000000"""Hashes.""" # standard import re # local from .utils import validator @validator def md5(value: str, /): """Return whether or not given value is a valid MD5 hash. Examples: >>> md5('d41d8cd98f00b204e9800998ecf8427e') # Output: True >>> md5('900zz11') # Output: ValidationError(func=md5, args={'value': '900zz11'}) Args: value: MD5 string to validate. Returns: (Literal[True]): If `value` is a valid MD5 hash. (ValidationError): If `value` is an invalid MD5 hash. """ return re.match(r"^[0-9a-f]{32}$", value, re.IGNORECASE) if value else False @validator def sha1(value: str, /): """Return whether or not given value is a valid SHA1 hash. Examples: >>> sha1('da39a3ee5e6b4b0d3255bfef95601890afd80709') # Output: True >>> sha1('900zz11') # Output: ValidationError(func=sha1, args={'value': '900zz11'}) Args: value: SHA1 string to validate. Returns: (Literal[True]): If `value` is a valid SHA1 hash. (ValidationError): If `value` is an invalid SHA1 hash. """ return re.match(r"^[0-9a-f]{40}$", value, re.IGNORECASE) if value else False @validator def sha224(value: str, /): """Return whether or not given value is a valid SHA224 hash. Examples: >>> sha224('d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f') # Output: True >>> sha224('900zz11') # Output: ValidationError(func=sha224, args={'value': '900zz11'}) Args: value: SHA224 string to validate. Returns: (Literal[True]): If `value` is a valid SHA224 hash. (ValidationError): If `value` is an invalid SHA224 hash. """ return re.match(r"^[0-9a-f]{56}$", value, re.IGNORECASE) if value else False @validator def sha256(value: str, /): """Return whether or not given value is a valid SHA256 hash. Examples: >>> sha256( ... 'e3b0c44298fc1c149afbf4c8996fb924' ... '27ae41e4649b934ca495991b7852b855' ... ) # Output: True >>> sha256('900zz11') # Output: ValidationError(func=sha256, args={'value': '900zz11'}) Args: value: SHA256 string to validate. Returns: (Literal[True]): If `value` is a valid SHA256 hash. (ValidationError): If `value` is an invalid SHA256 hash. """ return re.match(r"^[0-9a-f]{64}$", value, re.IGNORECASE) if value else False @validator def sha512(value: str, /): """Return whether or not given value is a valid SHA512 hash. Examples: >>> sha512( ... 'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce' ... '9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af9' ... '27da3e' ... ) # Output: True >>> sha512('900zz11') # Output: ValidationError(func=sha512, args={'value': '900zz11'}) Args: value: SHA512 string to validate. Returns: (Literal[True]): If `value` is a valid SHA512 hash. (ValidationError): If `value` is an invalid SHA512 hash. """ return re.match(r"^[0-9a-f]{128}$", value, re.IGNORECASE) if value else False validators-0.28.3/src/validators/hostname.py000066400000000000000000000100571462425114700211140ustar00rootroot00000000000000"""Hostname.""" # standard from functools import lru_cache import re from typing import Optional from .domain import domain # local from .ip_address import ipv4, ipv6 from .utils import validator @lru_cache def _port_regex(): """Port validation regex.""" return re.compile( r"^\:(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|" + r"6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{0,3})$", ) @lru_cache def _simple_hostname_regex(): """Simple hostname validation regex.""" # {0,59} because two characters are already matched at # the beginning and at the end, making the range {1, 61} return re.compile(r"^(?!-)[a-z0-9](?:[a-z0-9-]{0,59}[a-z0-9])?(?>> hostname("ubuntu-pc:443") # Output: True >>> hostname("this-pc") # Output: True >>> hostname("xn----gtbspbbmkef.xn--p1ai:65535") # Output: True >>> hostname("_example.com") # Output: True >>> hostname("123.5.77.88:31000") # Output: True >>> hostname("12.12.12.12") # Output: True >>> hostname("[::1]:22") # Output: True >>> hostname("dead:beef:0:0:0:0000:42:1") # Output: True >>> hostname("[0:0:0:0:0:ffff:1.2.3.4]:-65538") # Output: ValidationError(func=hostname, ...) >>> hostname("[0:&:b:c:@:e:f::]:9999") # Output: ValidationError(func=hostname, ...) Args: value: Hostname string to validate. skip_ipv6_addr: When hostname string cannot be an IPv6 address. skip_ipv4_addr: When hostname string cannot be an IPv4 address. may_have_port: Hostname string may contain port number. maybe_simple: Hostname string maybe only hyphens and alpha-numerals. consider_tld: Restrict domain to TLDs allowed by IANA. private: Embedded IP address is public if `False`, private/local if `True`. rfc_1034: Allow trailing dot in domain/host name. Ref: [RFC 1034](https://www.rfc-editor.org/rfc/rfc1034). rfc_2782: Domain/Host name is of type service record. Ref: [RFC 2782](https://www.rfc-editor.org/rfc/rfc2782). Returns: (Literal[True]): If `value` is a valid hostname. (ValidationError): If `value` is an invalid hostname. """ if not value: return False if may_have_port and (host_seg := _port_validator(value)): return ( (_simple_hostname_regex().match(host_seg) if maybe_simple else False) or domain(host_seg, consider_tld=consider_tld, rfc_1034=rfc_1034, rfc_2782=rfc_2782) or (False if skip_ipv4_addr else ipv4(host_seg, cidr=False, private=private)) or (False if skip_ipv6_addr else ipv6(host_seg, cidr=False)) ) return ( (_simple_hostname_regex().match(value) if maybe_simple else False) or domain(value, consider_tld=consider_tld, rfc_1034=rfc_1034, rfc_2782=rfc_2782) or (False if skip_ipv4_addr else ipv4(value, cidr=False, private=private)) or (False if skip_ipv6_addr else ipv6(value, cidr=False)) ) validators-0.28.3/src/validators/i18n/000077500000000000000000000000001462425114700175005ustar00rootroot00000000000000validators-0.28.3/src/validators/i18n/__init__.py000066400000000000000000000005451462425114700216150ustar00rootroot00000000000000"""i18n.""" # local from .es import es_cif, es_doi, es_nie, es_nif from .fi import fi_business_id, fi_ssn from .fr import fr_department, fr_ssn from .ind import ind_aadhar, ind_pan __all__ = ( "fi_business_id", "fi_ssn", "es_cif", "es_doi", "es_nie", "es_nif", "fr_department", "fr_ssn", "ind_aadhar", "ind_pan", ) validators-0.28.3/src/validators/i18n/es.py000066400000000000000000000122751462425114700204700ustar00rootroot00000000000000"""Spain.""" # standard from typing import Dict, Set # local from validators.utils import validator def _nif_nie_validation(value: str, number_by_letter: Dict[str, str], special_cases: Set[str]): """Validate if the doi is a NIF or a NIE.""" if value in special_cases or len(value) != 9: return False value = value.upper() table = "TRWAGMYFPDXBNJZSQVHLCKE" # If it is not a DNI, convert the first # letter to the corresponding digit numbers = number_by_letter.get(value[0], value[0]) + value[1:8] # doi[8] is control return numbers.isdigit() and value[8] == table[int(numbers) % 23] @validator def es_cif(value: str, /): """Validate a Spanish CIF. Each company in Spain prior to 2008 had a distinct CIF and has been discontinued. For more information see [wikipedia.org/cif][1]. The new replacement is to use NIF for absolutely everything. The issue is that there are "types" of NIFs now: company, person [citizen or resident] all distinguished by the first character of the DOI. For this reason we will continue to call CIFs NIFs, that are used for companies. This validator is based on [generadordni.es][2]. [1]: https://es.wikipedia.org/wiki/C%C3%B3digo_de_identificaci%C3%B3n_fiscal [2]: https://generadordni.es/ Examples: >>> es_cif('B25162520') # Output: True >>> es_cif('B25162529') # Output: ValidationError(func=es_cif, args=...) Args: value: DOI string which is to be validated. Returns: (Literal[True]): If `value` is a valid DOI string. (ValidationError): If `value` is an invalid DOI string. """ if not value or len(value) != 9: return False value = value.upper() table = "JABCDEFGHI" first_chr = value[0] doi_body = value[1:8] control = value[8] if not doi_body.isdigit(): return False res = ( 10 - sum( # Multiply each positionally even doi # digit by 2 and sum it all together sum(map(int, str(int(char) * 2))) if index % 2 == 0 else int(char) for index, char in enumerate(doi_body) ) % 10 ) % 10 if first_chr in "ABEH": # Number type return str(res) == control if first_chr in "PSQW": # Letter type return table[res] == control return control in {str(res), table[res]} if first_chr in "CDFGJNRUV" else False @validator def es_nif(value: str, /): """Validate a Spanish NIF. Each entity, be it person or company in Spain has a distinct NIF. Since we've designated CIF to be a company NIF, this NIF is only for person. For more information see [wikipedia.org/nif][1]. This validator is based on [generadordni.es][2]. [1]: https://es.wikipedia.org/wiki/N%C3%BAmero_de_identificaci%C3%B3n_fiscal [2]: https://generadordni.es/ Examples: >>> es_nif('26643189N') # Output: True >>> es_nif('26643189X') # Output: ValidationError(func=es_nif, args=...) Args: value: DOI string which is to be validated. Returns: (Literal[True]): If `value` is a valid DOI string. (ValidationError): If `value` is an invalid DOI string. """ number_by_letter = {"L": "0", "M": "0", "K": "0"} special_cases = {"X0000000T", "00000000T", "00000001R"} return _nif_nie_validation(value, number_by_letter, special_cases) @validator def es_nie(value: str, /): """Validate a Spanish NIE. The NIE is a tax identification number in Spain, known in Spanish as the NIE, or more formally the Número de identidad de extranjero. For more information see [wikipedia.org/nie][1]. This validator is based on [generadordni.es][2]. [1]: https://es.wikipedia.org/wiki/N%C3%BAmero_de_identidad_de_extranjero [2]: https://generadordni.es/ Examples: >>> es_nie('X0095892M') # Output: True >>> es_nie('X0095892X') # Output: ValidationError(func=es_nie, args=...) Args: value: DOI string which is to be validated. Returns: (Literal[True]): If `value` is a valid DOI string. (ValidationError): If `value` is an invalid DOI string. """ number_by_letter = {"X": "0", "Y": "1", "Z": "2"} # NIE must must start with X Y or Z if value and value[0] in number_by_letter: return _nif_nie_validation(value, number_by_letter, {"X0000000T"}) return False @validator def es_doi(value: str, /): """Validate a Spanish DOI. A DOI in spain is all NIF / CIF / NIE / DNI -- a digital ID. For more information see [wikipedia.org/doi][1]. This validator is based on [generadordni.es][2]. [1]: https://es.wikipedia.org/wiki/Identificador_de_objeto_digital [2]: https://generadordni.es/ Examples: >>> es_doi('X0095892M') # Output: True >>> es_doi('X0095892X') # Output: ValidationError(func=es_doi, args=...) Args: value: DOI string which is to be validated. Returns: (Literal[True]): If `value` is a valid DOI string. (ValidationError): If `value` is an invalid DOI string. """ return es_nie(value) or es_nif(value) or es_cif(value) validators-0.28.3/src/validators/i18n/fi.py000066400000000000000000000056311462425114700204550ustar00rootroot00000000000000"""Finland.""" # standard from functools import lru_cache import re # local from validators.utils import validator @lru_cache def _business_id_pattern(): """Business ID Pattern.""" return re.compile(r"^[0-9]{7}-[0-9]$") @lru_cache def _ssn_pattern(ssn_check_marks: str): """SSN Pattern.""" return re.compile( r"""^ (?P(0[1-9]|[1-2]\d|3[01]) (0[1-9]|1[012]) (\d{{2}})) [ABCDEFYXWVU+-] (?P(\d{{3}})) (?P[{check_marks}])$""".format( check_marks=ssn_check_marks ), re.VERBOSE, ) @validator def fi_business_id(value: str, /): """Validate a Finnish Business ID. Each company in Finland has a distinct business id. For more information see [Finnish Trade Register][1] [1]: http://en.wikipedia.org/wiki/Finnish_Trade_Register Examples: >>> fi_business_id('0112038-9') # Fast Monkeys Ltd # Output: True >>> fi_business_id('1234567-8') # Bogus ID # Output: ValidationError(func=fi_business_id, ...) Args: value: Business ID string to be validated. Returns: (Literal[True]): If `value` is a valid finnish business id. (ValidationError): If `value` is an invalid finnish business id. """ if not value: return False if not re.match(_business_id_pattern(), value): return False factors = [7, 9, 10, 5, 8, 4, 2] numbers = map(int, value[:7]) checksum = int(value[8]) modulo = sum(f * n for f, n in zip(factors, numbers)) % 11 return (11 - modulo == checksum) or (modulo == checksum == 0) @validator def fi_ssn(value: str, /, *, allow_temporal_ssn: bool = True): """Validate a Finnish Social Security Number. This validator is based on [django-localflavor-fi][1]. [1]: https://github.com/django/django-localflavor-fi/ Examples: >>> fi_ssn('010101-0101') # Output: True >>> fi_ssn('101010-0102') # Output: ValidationError(func=fi_ssn, args=...) Args: value: Social Security Number to be validated. allow_temporal_ssn: Whether to accept temporal SSN numbers. Temporal SSN numbers are the ones where the serial is in the range [900-999]. By default temporal SSN numbers are valid. Returns: (Literal[True]): If `value` is a valid finnish SSN. (ValidationError): If `value` is an invalid finnish SSN. """ if not value: return False ssn_check_marks = "0123456789ABCDEFHJKLMNPRSTUVWXY" if not (result := re.match(_ssn_pattern(ssn_check_marks), value)): return False gd = result.groupdict() checksum = int(gd["date"] + gd["serial"]) return ( int(gd["serial"]) >= 2 and (allow_temporal_ssn or int(gd["serial"]) <= 899) and ssn_check_marks[checksum % len(ssn_check_marks)] == gd["checksum"] ) validators-0.28.3/src/validators/i18n/fr.py000066400000000000000000000075151462425114700204710ustar00rootroot00000000000000"""France.""" # standard from functools import lru_cache import re import typing # local from validators.utils import validator @lru_cache def _ssn_pattern(): """SSN Pattern.""" return re.compile( r"^([1,2])" # gender (1=M, 2=F) r"\s(\d{2})" # year of birth r"\s(0[1-9]|1[0-2])" # month of birth r"\s(\d{2,3}|2[A,B])" # department of birth r"\s(\d{2,3})" # town of birth r"\s(\d{3})" # registration number r"(?:\s(\d{2}))?$", # control key (may or may not be provided) re.VERBOSE, ) @validator def fr_department(value: typing.Union[str, int]): """Validate a french department number. Examples: >>> fr_department(20) # can be an integer # Output: True >>> fr_department("20") # Output: True >>> fr_department("971") # Guadeloupe # Output: True >>> fr_department("00") # Output: ValidationError(func=fr_department, args=...) >>> fr_department('2A') # Corsica # Output: True >>> fr_department('2B') # Output: True >>> fr_department('2C') # Output: ValidationError(func=fr_department, args=...) Args: value: French department number to validate. Returns: (Literal[True]): If `value` is a valid french department number. (ValidationError): If `value` is an invalid french department number. """ if not value: return False if isinstance(value, str): if value in ("2A", "2B"): # Corsica return True try: value = int(value) except ValueError: return False return 1 <= value <= 19 or 21 <= value <= 95 or 971 <= value <= 976 # Overseas departments @validator def fr_ssn(value: str): """Validate a french Social Security Number. Each french citizen has a distinct Social Security Number. For more information see [French Social Security Number][1] (sadly unavailable in english). [1]: https://fr.wikipedia.org/wiki/Num%C3%A9ro_de_s%C3%A9curit%C3%A9_sociale_en_France Examples: >>> fr_ssn('1 84 12 76 451 089 46') # Output: True >>> fr_ssn('1 84 12 76 451 089') # control key is optional # Output: True >>> fr_ssn('3 84 12 76 451 089 46') # wrong gender number # Output: ValidationError(func=fr_ssn, args=...) >>> fr_ssn('1 84 12 76 451 089 47') # wrong control key # Output: ValidationError(func=fr_ssn, args=...) Args: value: French Social Security Number string to validate. Returns: (Literal[True]): If `value` is a valid french Social Security Number. (ValidationError): If `value` is an invalid french Social Security Number. """ if not value: return False matched = re.match(_ssn_pattern(), value) if not matched: return False groups = list(matched.groups()) control_key = groups[-1] department = groups[3] if department != "99" and not fr_department(department): # 99 stands for foreign born people return False if control_key is None: # no control key provided, no additional check needed return True if len(department) == len(groups[4]): # if the department number is 3 digits long (overseas departments), # the town number must be 2 digits long # and vice versa return False if department in ("2A", "2B"): # Corsica's department numbers are not in the same range as the others # thus 2A and 2B are replaced by 19 and 18 respectively to compute the control key groups[3] = "19" if department == "2A" else "18" # the control key is valid if it is equal to 97 - (the first 13 digits modulo 97) digits = int("".join(groups[:-1])) return int(control_key) == (97 - (digits % 97)) validators-0.28.3/src/validators/i18n/ind.py000066400000000000000000000021711462425114700206250ustar00rootroot00000000000000"""India.""" # standard import re # local from validators.utils import validator @validator def ind_aadhar(value: str): """Validate an indian aadhar card number. Examples: >>> ind_aadhar('3675 9834 6015') True >>> ind_aadhar('3675 ABVC 2133') ValidationFailure(func=aadhar, args={'value': '3675 ABVC 2133'}) Args: value: Aadhar card number string to validate. Returns: (Literal[True]): If `value` is a valid aadhar card number. (ValidationError): If `value` is an invalid aadhar card number. """ return re.match(r"^[2-9]{1}\d{3}\s\d{4}\s\d{4}$", value) @validator def ind_pan(value: str): """Validate a pan card number. Examples: >>> ind_pan('ABCDE9999K') True >>> ind_pan('ABC5d7896B') ValidationFailure(func=pan, args={'value': 'ABC5d7896B'}) Args: value: PAN card number string to validate. Returns: (Literal[True]): If `value` is a valid PAN card number. (ValidationError): If `value` is an invalid PAN card number. """ return re.match(r"[A-Z]{5}\d{4}[A-Z]{1}", value) validators-0.28.3/src/validators/iban.py000066400000000000000000000020671462425114700202110ustar00rootroot00000000000000"""IBAN.""" # standard import re # local from .utils import validator def _char_value(char: str): """A=10, B=11, ..., Z=35.""" return char if char.isdigit() else str(10 + ord(char) - ord("A")) def _mod_check(value: str): """Check if the value string passes the mod97-test.""" # move country code and check numbers to end rearranged = value[4:] + value[:4] return int("".join(_char_value(char) for char in rearranged)) % 97 == 1 @validator def iban(value: str, /): """Return whether or not given value is a valid IBAN code. Examples: >>> iban('DE29100500001061045672') # Output: True >>> iban('123456') # Output: ValidationError(func=iban, ...) Args: value: IBAN string to validate. Returns: (Literal[True]): If `value` is a valid IBAN code. (ValidationError): If `value` is an invalid IBAN code. """ return ( (re.match(r"^[a-z]{2}[0-9]{2}[a-z0-9]{11,30}$", value, re.IGNORECASE) and _mod_check(value)) if value else False ) validators-0.28.3/src/validators/ip_address.py000066400000000000000000000105361462425114700214150ustar00rootroot00000000000000"""IP Address.""" # standard from ipaddress import ( AddressValueError, IPv4Address, IPv4Network, IPv6Address, IPv6Network, NetmaskValueError, ) import re from typing import Optional # local from .utils import validator def _check_private_ip(value: str, is_private: Optional[bool]): if is_private is None: return True if ( any( value.startswith(l_bit) for l_bit in { "10.", # private "192.168.", # private "169.254.", # link-local "127.", # localhost "0.0.0.0", # loopback #nosec } ) or re.match(r"^172\.(?:1[6-9]|2\d|3[0-1])\.", value) # private or re.match(r"^(?:22[4-9]|23[0-9]|24[0-9]|25[0-5])\.", value) # broadcast ): return is_private return not is_private @validator def ipv4( value: str, /, *, cidr: bool = True, strict: bool = False, private: Optional[bool] = None, host_bit: bool = True, ): """Returns whether a given value is a valid IPv4 address. From Python version 3.9.5 leading zeros are no longer tolerated and are treated as an error. The initial version of ipv4 validator was inspired from [WTForms IPAddress validator][1]. [1]: https://github.com/wtforms/wtforms/blob/master/src/wtforms/validators.py Examples: >>> ipv4('123.0.0.7') # Output: True >>> ipv4('1.1.1.1/8') # Output: True >>> ipv4('900.80.70.11') # Output: ValidationError(func=ipv4, args={'value': '900.80.70.11'}) Args: value: IP address string to validate. cidr: IP address string may contain CIDR notation. strict: IP address string is strictly in CIDR notation. private: IP address is public if `False`, private/local/loopback/broadcast if `True`. host_bit: If `False` and host bits (along with network bits) _are_ set in the supplied address, this function raises a validation error. ref [IPv4Network][2]. [2]: https://docs.python.org/3/library/ipaddress.html#ipaddress.IPv4Network Returns: (Literal[True]): If `value` is a valid IPv4 address. (ValidationError): If `value` is an invalid IPv4 address. """ if not value: return False try: if cidr: if strict and value.count("/") != 1: raise ValueError("IPv4 address was expected in CIDR notation") return IPv4Network(value, strict=not host_bit) and _check_private_ip(value, private) return IPv4Address(value) and _check_private_ip(value, private) except (ValueError, AddressValueError, NetmaskValueError): return False @validator def ipv6(value: str, /, *, cidr: bool = True, strict: bool = False, host_bit: bool = True): """Returns if a given value is a valid IPv6 address. Including IPv4-mapped IPv6 addresses. The initial version of ipv6 validator was inspired from [WTForms IPAddress validator][1]. [1]: https://github.com/wtforms/wtforms/blob/master/src/wtforms/validators.py Examples: >>> ipv6('::ffff:192.0.2.128') # Output: True >>> ipv6('::1/128') # Output: True >>> ipv6('abc.0.0.1') # Output: ValidationError(func=ipv6, args={'value': 'abc.0.0.1'}) Args: value: IP address string to validate. cidr: IP address string may contain CIDR annotation. strict: IP address string is strictly in CIDR notation. host_bit: If `False` and host bits (along with network bits) _are_ set in the supplied address, this function raises a validation error. ref [IPv6Network][2]. [2]: https://docs.python.org/3/library/ipaddress.html#ipaddress.IPv6Network Returns: (Literal[True]): If `value` is a valid IPv6 address. (ValidationError): If `value` is an invalid IPv6 address. """ if not value: return False try: if cidr: if strict and value.count("/") != 1: raise ValueError("IPv6 address was expected in CIDR notation") return IPv6Network(value, strict=not host_bit) return IPv6Address(value) except (ValueError, AddressValueError, NetmaskValueError): return False validators-0.28.3/src/validators/length.py000066400000000000000000000027151462425114700205610ustar00rootroot00000000000000"""Length.""" # standard from typing import Union # local from .between import between from .utils import validator @validator def length(value: str, /, *, min_val: Union[int, None] = None, max_val: Union[int, None] = None): """Return whether or not the length of given string is within a specified range. Examples: >>> length('something', min_val=2) # Output: True >>> length('something', min_val=9, max_val=9) # Output: True >>> length('something', max_val=5) # Output: ValidationError(func=length, ...) Args: value: The string to validate. min_val: The minimum required length of the string. If not provided, minimum length will not be checked. max_val: The maximum length of the string. If not provided, maximum length will not be checked. Returns: (Literal[True]): If `len(value)` is in between the given conditions. (ValidationError): If `len(value)` is not in between the given conditions. Raises: (ValueError): If either `min_val` or `max_val` is negative. """ if min_val is not None and min_val < 0: raise ValueError("Length cannot be negative. `min_val` is less than zero.") if max_val is not None and max_val < 0: raise ValueError("Length cannot be negative. `max_val` is less than zero.") return bool(between(len(value), min_val=min_val, max_val=max_val)) validators-0.28.3/src/validators/mac_address.py000066400000000000000000000015411462425114700215410ustar00rootroot00000000000000"""MAC Address.""" # standard import re # local from .utils import validator @validator def mac_address(value: str, /): """Return whether or not given value is a valid MAC address. This validator is based on [WTForms MacAddress validator][1]. [1]: https://github.com/wtforms/wtforms/blob/master/src/wtforms/validators.py#L482 Examples: >>> mac_address('01:23:45:67:ab:CD') # Output: True >>> mac_address('00:00:00:00:00') # Output: ValidationError(func=mac_address, args={'value': '00:00:00:00:00'}) Args: value: MAC address string to validate. Returns: (Literal[True]): If `value` is a valid MAC address. (ValidationError): If `value` is an invalid MAC address. """ return re.match(r"^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$", value) if value else False validators-0.28.3/src/validators/py.typed000066400000000000000000000000001462425114700204060ustar00rootroot00000000000000validators-0.28.3/src/validators/slug.py000066400000000000000000000013561462425114700202520ustar00rootroot00000000000000"""Slug.""" # standard import re # local from .utils import validator @validator def slug(value: str, /): """Validate whether or not given value is valid slug. Valid slug can contain only lowercase alphanumeric characters and hyphens. It starts and ends with these lowercase alphanumeric characters. Examples: >>> slug('my-slug-2134') # Output: True >>> slug('my.slug') # Output: ValidationError(func=slug, args={'value': 'my.slug'}) Args: value: Slug string to validate. Returns: (Literal[True]): If `value` is a valid slug. (ValidationError): If `value` is an invalid slug. """ return re.match(r"^[a-z0-9]+(?:-[a-z0-9]+)*$", value) if value else False validators-0.28.3/src/validators/uri.py000066400000000000000000000034341462425114700200760ustar00rootroot00000000000000"""URI.""" # Read: https://stackoverflow.com/questions/176264 # https://www.rfc-editor.org/rfc/rfc3986#section-3 # local from .email import email from .url import url from .utils import validator def _file_url(value: str): if not value.startswith("file:///"): return False return True def _ipfs_url(value: str): if not value.startswith("ipfs://"): return False return True @validator def uri(value: str, /): """Return whether or not given value is a valid URI. Examples: >>> uri('mailto:example@domain.com') # Output: True >>> uri('file:path.txt') # Output: ValidationError(func=uri, ...) Args: value: URI to validate. Returns: (Literal[True]): If `value` is a valid URI. (ValidationError): If `value` is an invalid URI. """ if not value: return False # TODO: work on various validations # url if any( # fmt: off value.startswith(item) for item in { "ftp", "ftps", "git", "http", "https", "irc", "rtmp", "rtmps", "rtsp", "sftp", "ssh", "telnet", } # fmt: on ): return url(value) # email if value.startswith("mailto:"): return email(value.lstrip("mailto:")) # file if value.startswith("file:"): return _file_url(value) # ipfs if value.startswith("ipfs:"): return _ipfs_url(value) # magnet if value.startswith("magnet:?"): return True # telephone if value.startswith("tel:"): return True # data if value.startswith("data:"): return True # urn if value.startswith("urn:"): return True # urc if value.startswith("urc:"): return True return False validators-0.28.3/src/validators/url.py000066400000000000000000000164601462425114700201040ustar00rootroot00000000000000"""URL.""" # standard from functools import lru_cache import re from typing import Optional from urllib.parse import parse_qs, unquote, urlsplit # local from .hostname import hostname from .utils import validator @lru_cache def _username_regex(): return re.compile( # extended latin r"(^[\u0100-\u017F\u0180-\u024F]" # dot-atom + r"|[-!#$%&'*+/=?^_`{}|~0-9a-z]+(\.[-!#$%&'*+/=?^_`{}|~0-9a-z]+)*$" # non-quoted-string + r"|^([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\011.])*$)", re.IGNORECASE, ) @lru_cache def _path_regex(): return re.compile( # allowed symbols r"^[\/a-z0-9\-\.\_\~\!\$\&\'\(\)\*\+\,\;\=\:\@\%" # symbols / pictographs + r"\U0001F300-\U0001F5FF" # emoticons / emoji + r"\U0001F600-\U0001F64F" # multilingual unicode ranges + r"\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+$", re.IGNORECASE, ) def _validate_scheme(value: str): """Validate scheme.""" # More schemes will be considered later. return ( value # fmt: off in { "ftp", "ftps", "git", "http", "https", "irc", "rtmp", "rtmps", "rtsp", "sftp", "ssh", "telnet", } # fmt: on if value else False ) def _confirm_ipv6_skip(value: str, skip_ipv6_addr: bool): """Confirm skip IPv6 check.""" return skip_ipv6_addr or value.count(":") < 2 or not value.startswith("[") def _validate_auth_segment(value: str): """Validate authentication segment.""" if not value: return True if (colon_count := value.count(":")) > 1: # everything before @ is then considered as a username # this is a bad practice, but syntactically valid URL return _username_regex().match(unquote(value)) if colon_count < 1: return _username_regex().match(value) username, password = value.rsplit(":", 1) return _username_regex().match(username) and all( char_to_avoid not in password for char_to_avoid in ("/", "?", "#", "@") ) def _validate_netloc( value: str, skip_ipv6_addr: bool, skip_ipv4_addr: bool, may_have_port: bool, simple_host: bool, consider_tld: bool, private: Optional[bool], rfc_1034: bool, rfc_2782: bool, ): """Validate netloc.""" if not value or value.count("@") > 1: return False if value.count("@") < 1: return hostname( ( value if _confirm_ipv6_skip(value, skip_ipv6_addr) or "]:" in value else value.lstrip("[").replace("]", "", 1) ), skip_ipv6_addr=_confirm_ipv6_skip(value, skip_ipv6_addr), skip_ipv4_addr=skip_ipv4_addr, may_have_port=may_have_port, maybe_simple=simple_host, consider_tld=consider_tld, private=private, rfc_1034=rfc_1034, rfc_2782=rfc_2782, ) basic_auth, host = value.rsplit("@", 1) return hostname( ( host if _confirm_ipv6_skip(host, skip_ipv6_addr) or "]:" in value else host.lstrip("[").replace("]", "", 1) ), skip_ipv6_addr=_confirm_ipv6_skip(host, skip_ipv6_addr), skip_ipv4_addr=skip_ipv4_addr, may_have_port=may_have_port, maybe_simple=simple_host, consider_tld=consider_tld, private=private, rfc_1034=rfc_1034, rfc_2782=rfc_2782, ) and _validate_auth_segment(basic_auth) def _validate_optionals(path: str, query: str, fragment: str, strict_query: bool): """Validate path query and fragments.""" optional_segments = True if path: optional_segments &= bool(_path_regex().match(path)) try: if ( query # ref: https://github.com/python/cpython/issues/117109 and parse_qs(query, strict_parsing=strict_query, separator="&") and parse_qs(query, strict_parsing=strict_query, separator=";") ): optional_segments &= True except TypeError: # for Python < v3.9.2 (official v3.10) if query and parse_qs(query, strict_parsing=strict_query): optional_segments &= True if fragment: # See RFC3986 Section 3.5 Fragment for allowed characters optional_segments &= bool( re.fullmatch(r"[0-9a-z?/:@\-._~%!$&'()*+,;=]*", fragment, re.IGNORECASE) ) return optional_segments @validator def url( value: str, /, *, skip_ipv6_addr: bool = False, skip_ipv4_addr: bool = False, may_have_port: bool = True, simple_host: bool = False, strict_query: bool = True, consider_tld: bool = False, private: Optional[bool] = None, # only for ip-addresses rfc_1034: bool = False, rfc_2782: bool = False, ): r"""Return whether or not given value is a valid URL. This validator was originally inspired from [URL validator of dperini][1]. The following diagram is from [urlly][2]:: foo://admin:hunter1@example.com:8042/over/there?name=ferret#nose \_/ \___/ \_____/ \_________/ \__/\_________/ \_________/ \__/ | | | | | | | | scheme username password hostname port path query fragment [1]: https://gist.github.com/dperini/729294 [2]: https://github.com/treeform/urlly Examples: >>> url('http://duck.com') # Output: True >>> url('ftp://foobar.dk') # Output: True >>> url('http://10.0.0.1') # Output: True >>> url('http://example.com/">user@example.com') # Output: ValidationError(func=url, ...) Args: value: URL string to validate. skip_ipv6_addr: When URL string cannot contain an IPv6 address. skip_ipv4_addr: When URL string cannot contain an IPv4 address. may_have_port: URL string may contain port number. simple_host: URL string maybe only hyphens and alpha-numerals. strict_query: Fail validation on query string parsing error. consider_tld: Restrict domain to TLDs allowed by IANA. private: Embedded IP address is public if `False`, private/local if `True`. rfc_1034: Allow trailing dot in domain/host name. Ref: [RFC 1034](https://www.rfc-editor.org/rfc/rfc1034). rfc_2782: Domain/Host name is of type service record. Ref: [RFC 2782](https://www.rfc-editor.org/rfc/rfc2782). Returns: (Literal[True]): If `value` is a valid url. (ValidationError): If `value` is an invalid url. """ if not value or re.search(r"\s", value): # url must not contain any white # spaces, they must be encoded return False try: scheme, netloc, path, query, fragment = urlsplit(value) except ValueError: return False return ( _validate_scheme(scheme) and _validate_netloc( netloc, skip_ipv6_addr, skip_ipv4_addr, may_have_port, simple_host, consider_tld, private, rfc_1034, rfc_2782, ) and _validate_optionals(path, query, fragment, strict_query) ) validators-0.28.3/src/validators/utils.py000066400000000000000000000061511462425114700204360ustar00rootroot00000000000000"""Utils.""" # standard from functools import wraps from inspect import getfullargspec from itertools import chain from os import environ from typing import Any, Callable, Dict class ValidationError(Exception): """Exception class when validation failure occurs.""" def __init__(self, function: Callable[..., Any], arg_dict: Dict[str, Any], message: str = ""): """Initialize Validation Failure.""" if message: self.reason = message self.func = function self.__dict__.update(arg_dict) def __repr__(self): """Repr Validation Failure.""" return ( f"ValidationError(func={self.func.__name__}, " + f"args={({k: v for (k, v) in self.__dict__.items() if k != 'func'})})" ) def __str__(self): """Str Validation Failure.""" return repr(self) def __bool__(self): """Bool Validation Failure.""" return False def _func_args_as_dict(func: Callable[..., Any], *args: Any, **kwargs: Any): """Return function's positional and key value arguments as an ordered dictionary.""" return dict( list(zip(dict.fromkeys(chain(getfullargspec(func)[0], kwargs.keys())), args)) + list(kwargs.items()) ) def validator(func: Callable[..., Any]): """A decorator that makes given function validator. Whenever the given `func` returns `False` this decorator returns `ValidationError` object. Examples: >>> @validator ... def even(value): ... return not (value % 2) >>> even(4) # Output: True >>> even(5) # Output: ValidationError(func=even, args={'value': 5}) Args: func: Function which is to be decorated. Returns: (Callable[..., ValidationError | Literal[True]]): A decorator which returns either `ValidationError` or `Literal[True]`. Raises: (ValidationError): If `r_ve` or `RAISE_VALIDATION_ERROR` is `True` """ @wraps(func) def wrapper(*args: Any, **kwargs: Any): raise_validation_error = False if "r_ve" in kwargs: raise_validation_error = True del kwargs["r_ve"] if environ.get("RAISE_VALIDATION_ERROR", "False") == "True": raise_validation_error = True try: if raise_validation_error: if func(*args, **kwargs): return True else: raise ValidationError(func, _func_args_as_dict(func, *args, **kwargs)) else: return ( True if func(*args, **kwargs) else ValidationError(func, _func_args_as_dict(func, *args, **kwargs)) ) except (ValueError, TypeError, UnicodeError) as exp: if raise_validation_error: raise ValidationError( func, _func_args_as_dict(func, *args, **kwargs), str(exp) ) from exp else: return ValidationError(func, _func_args_as_dict(func, *args, **kwargs), str(exp)) return wrapper validators-0.28.3/src/validators/uuid.py000066400000000000000000000020501462425114700202360ustar00rootroot00000000000000"""UUID.""" # standard import re from typing import Union from uuid import UUID # local from .utils import validator @validator def uuid(value: Union[str, UUID], /): """Return whether or not given value is a valid UUID-v4 string. This validator is based on [WTForms UUID validator][1]. [1]: https://github.com/wtforms/wtforms/blob/master/src/wtforms/validators.py#L539 Examples: >>> uuid('2bc1c94f-0deb-43e9-92a1-4775189ec9f8') # Output: True >>> uuid('2bc1c94f 0deb-43e9-92a1-4775189ec9f8') # Output: ValidationError(func=uuid, ...) Args: value: UUID string or object to validate. Returns: (Literal[True]): If `value` is a valid UUID. (ValidationError): If `value` is an invalid UUID. """ if not value: return False if isinstance(value, UUID): return True try: return UUID(value) or re.match( r"^[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}$", value ) except ValueError: return False validators-0.28.3/tests/000077500000000000000000000000001462425114700151245ustar00rootroot00000000000000validators-0.28.3/tests/i18n/000077500000000000000000000000001462425114700157035ustar00rootroot00000000000000validators-0.28.3/tests/i18n/test_es.py000066400000000000000000000052551462425114700177320ustar00rootroot00000000000000"""Test i18n/es.""" # external import pytest # local from validators import ValidationError, es_cif, es_doi, es_nie, es_nif @pytest.mark.parametrize( ("value",), [ ("B25162520",), ("U4839822F",), ("B96817697",), ("P7067074J",), ("Q7899705C",), ("C75098681",), ("G76061860",), ("C71345375",), ("G20558169",), ("U5021960I",), ], ) def test_returns_true_on_valid_cif(value: str): """Test returns true on valid cif.""" assert es_cif(value) @pytest.mark.parametrize( ("value",), [ ("12345",), ("ABCDEFGHI",), ("Z5021960I",), ], ) def test_returns_false_on_invalid_cif(value: str): """Test returns false on invalid cif.""" result = es_cif(value) assert isinstance(result, ValidationError) @pytest.mark.parametrize( ("value",), [ ("X0095892M",), ("X8868108K",), ("X2911154K",), ("Y2584969J",), ("X7536157T",), ("Y5840388N",), ("Z2915723H",), ("Y4002236C",), ("X7750702R",), ("Y0408759V",), ], ) def test_returns_true_on_valid_nie(value: str): """Test returns true on valid nie.""" assert es_nie(value) @pytest.mark.parametrize( ("value",), [ ("K0000023T",), ("L0000024R",), ("M0000025W",), ("00000026A",), ("00000027G",), ("00000028M",), ("00000029Y",), ("00000030F",), ("00000031P",), ("00000032D",), ("00000033X",), ("00000034B",), ("00000035N",), ("00000036J",), ("00000037Z",), ("00000038S",), ("00000039Q",), ("00000040V",), ("00000041H",), ("00000042L",), ("00000043C",), ("00000044K",), ("00000045E",), ], ) def test_returns_true_on_valid_nif(value: str): """Test returns true on valid nif.""" assert es_nif(value) @pytest.mark.parametrize( ("value",), [ ("12345",), ("X0000000T",), ("00000000T",), ("00000001R",), ], ) def test_returns_false_on_invalid_nif(value: str): """Test returns false on invalid nif.""" result = es_nif(value) assert isinstance(result, ValidationError) @pytest.mark.parametrize( ("value",), [ # CIFs ("B25162520",), ("U4839822F",), ("B96817697",), # NIEs ("X0095892M",), ("X8868108K",), ("X2911154K",), # NIFs ("26643189N",), ("07060225F",), ("49166693F",), ], ) def test_returns_true_on_valid_doi(value: str): """Test returns true on valid doi.""" assert es_doi(value) validators-0.28.3/tests/i18n/test_fi.py000066400000000000000000000040041462425114700177100ustar00rootroot00000000000000"""Test i18n/es.""" # external import pytest # local from validators import ValidationError from validators.i18n.fi import fi_business_id, fi_ssn @pytest.mark.parametrize( ("value",), [ ("2336509-6",), # Supercell ("0112038-9",), # Fast Monkeys ("2417581-7",), # Nokia ], ) def test_returns_true_on_valid_business_id(value: str): """Test returns true on valid business id.""" assert fi_business_id(value) @pytest.mark.parametrize( ("value",), [ (None,), ("",), ("1233312312",), ("1333333-8",), ("1231233-9",), ], ) def test_returns_failed_validation_on_invalid_business_id(value: str): """Test returns failed validation on invalid business id.""" assert isinstance(fi_business_id(value), ValidationError) @pytest.mark.parametrize( ("value",), [ ("010190-002R",), ("010101-0101",), ("010101+0101",), ("010101A0101",), ("010190-900P",), ("020516C903K",), ("010594Y9032",), ], ) def test_returns_true_on_valid_ssn(value: str): """Test returns true on valid ssn.""" assert fi_ssn(value) @pytest.mark.parametrize( ("value",), [ (None,), ("",), ("010190-001P",), # Too low serial ("010190-000N",), # Too low serial ("000190-0023",), # Invalid day ("010090-002X",), # Invalid month ("010190-002r",), # Invalid checksum ("101010-0102",), ("10a010-0101",), ("101010-0\xe401",), ("101010b0101",), ("0205169C03K",), ("0105949Y032",), ], ) def test_returns_failed_validation_on_invalid_ssn(value: str): """Test returns failed validation on invalid_ssn.""" assert isinstance(fi_ssn(value), ValidationError) def test_returns_failed_validation_on_temporal_ssn_when_not_allowed(): """Test returns failed validation on temporal-ssn when not allowed.""" assert isinstance(fi_ssn("010190-900P", allow_temporal_ssn=False), ValidationError) validators-0.28.3/tests/i18n/test_fr.py000066400000000000000000000040521462425114700177240ustar00rootroot00000000000000"""Test French validators.""" # standard from typing import Union # external import pytest # local from validators import ValidationError from validators.i18n.fr import fr_department, fr_ssn @pytest.mark.parametrize( ("value",), [ ("1 84 12 76 451 089 46",), ("1 84 12 76 451 089",), # control key is optional ("2 99 05 75 202 818 97",), ("2 99 05 75 202 817 01",), ("2 99 05 2A 202 817 58",), ("2 99 05 2B 202 817 85",), ("2 99 05 971 12 817 70",), ], ) def test_returns_true_on_valid_ssn(value: str): """Test returns true on valid ssn.""" assert fr_ssn(value) @pytest.mark.parametrize( ("value",), [ (None,), ("",), ("3 84 12 76 451 089 46",), # wrong gender number ("1 84 12 76 451 089 47",), # wrong control key ("1 84 00 76 451 089",), # invalid month ("1 84 13 76 451 089",), # invalid month ("1 84 12 00 451 089",), # invalid department ("1 84 12 2C 451 089",), ("1 84 12 98 451 089",), # invalid department # ("1 84 12 971 451 089",), # ? ], ) def test_returns_failed_validation_on_invalid_ssn(value: str): """Test returns failed validation on invalid_ssn.""" assert isinstance(fr_ssn(value), ValidationError) @pytest.mark.parametrize( ("value",), [ ("01",), ("2A",), # Corsica ("2B",), (14,), ("95",), ("971",), (971,), ], ) def test_returns_true_on_valid_department(value: Union[str, int]): """Test returns true on valid department.""" assert fr_department(value) @pytest.mark.parametrize( ("value",), [ (None,), ("",), ("00",), (0,), ("2C",), ("97",), ("978",), ("98",), ("96",), ("20",), (20,), ], ) def test_returns_failed_validation_on_invalid_department(value: Union[str, int]): """Test returns failed validation on invalid department.""" assert isinstance(fr_department(value), ValidationError) validators-0.28.3/tests/i18n/test_ind.py000066400000000000000000000021121462425114700200620ustar00rootroot00000000000000"""Test Indian validators.""" # external import pytest # local from validators import ValidationError from validators.i18n import ind_aadhar, ind_pan @pytest.mark.parametrize("value", ["3675 9834 6012", "5046 3182 4299"]) def test_returns_true_on_valid_ind_aadhar(value: str): """Test returns true on valid ind aadhar.""" assert ind_aadhar(value) @pytest.mark.parametrize("value", ["3675 9834 6012 8", "417598346012", "3675 98AF 60#2"]) def test_returns_failed_validation_on_invalid_ind_aadhar(value: str): """Test returns failed validation on invalid ind aadhar.""" assert isinstance(ind_aadhar(value), ValidationError) @pytest.mark.parametrize("value", ["ABCDE9999K", "AAAPL1234C"]) def test_returns_true_on_valid_ind_pan(value: str): """Test returns true on valid ind pan.""" assert ind_pan(value) @pytest.mark.parametrize("value", ["ABC5d7896B", "417598346012", "AaaPL1234C"]) def test_returns_failed_validation_on_invalid_ind_pan(value: str): """Test returns failed validation on invalid ind pan.""" assert isinstance(ind_pan(value), ValidationError) validators-0.28.3/tests/test__extremes.py000066400000000000000000000024671462425114700205410ustar00rootroot00000000000000"""Test Extremes.""" # standard from typing import Any # external import pytest # local from validators._extremes import AbsMax, AbsMin abs_max = AbsMax() abs_min = AbsMin() @pytest.mark.parametrize( ("value",), [(None,), ("",), (12,), (abs_min,)], ) def test_abs_max_is_greater_than_every_other_value(value: Any): """Test if AbsMax is greater than every other value.""" assert value < abs_max assert abs_max > value def test_abs_max_is_not_greater_than_itself(): """Test if AbsMax is not greater than itself.""" assert not (abs_max > abs_max) def test_other_comparison_methods_for_abs_max(): """Test other comparison methods for AbsMax.""" assert abs_max <= abs_max assert abs_max == abs_max assert abs_max == abs_max @pytest.mark.parametrize( ("value",), [(None,), ("",), (12,), (abs_max,)], ) def test_abs_min_is_smaller_than_every_other_value(value: Any): """Test if AbsMin is less than every other value.""" assert value > abs_min def test_abs_min_is_not_greater_than_itself(): """Test if AbsMin is not less than itself.""" assert not (abs_min < abs_min) def test_other_comparison_methods_for_abs_min(): """Test other comparison methods for AbsMin.""" assert abs_min <= abs_min assert abs_min == abs_min assert abs_min == abs_min validators-0.28.3/tests/test_between.py000066400000000000000000000021221462425114700201630ustar00rootroot00000000000000"""Test Between.""" # standard from datetime import datetime from typing import TypeVar # external import pytest # local from validators import ValidationError, between T = TypeVar("T", int, float, str, datetime) @pytest.mark.parametrize( ("value", "min_val", "max_val"), [(12, 11, 13), (12, None, 14), (12, 11, None), (12, 12, 12), (0, 0, 0), (0, -1, 3)], ) def test_returns_true_on_valid_range(value: T, min_val: T, max_val: T): """Test returns true on valid range.""" assert between(value, min_val=min_val, max_val=max_val) @pytest.mark.parametrize( ("value", "min_val", "max_val"), [ (None, 13, 14), (12, 13, 14), (12, None, 11), (12, 13, None), (12, "13.5", datetime(1970, 1, 1)), ("12", 20.5, "None"), (datetime(1970, 1, 1), 20, "string"), (30, 40, "string"), ], ) def test_returns_failed_validation_on_invalid_range(value: T, min_val: T, max_val: T): """Test returns failed validation on invalid range.""" assert isinstance(between(value, min_val=min_val, max_val=max_val), ValidationError) validators-0.28.3/tests/test_btc_address.py000066400000000000000000000021551462425114700210150ustar00rootroot00000000000000"""Test BTC address.""" # external import pytest # local from validators import ValidationError, btc_address @pytest.mark.parametrize( "value", [ # P2PKH (Pay-to-PubkeyHash) type "1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2", # P2SH (Pay to script hash) type "3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy", # Bech32/segwit type "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq", "bc1qc7slrfxkknqcq2jevvvkdgvrt8080852dfjewde450xdlk4ugp7szw5tk9", ], ) def test_returns_true_on_valid_btc_address(value: str): """Test returns true on valid btc address.""" assert btc_address(value) @pytest.mark.parametrize( "value", [ "ff3Cwgr2g7vsi1bXDUkpEnVoRLA9w4FZfC69", "b3Cgwgr2g7vsi1bXyjyDUkphEnVoRLA9w4FZfC69", # incorrect header "1BvBMsEYstWetqTFn5Au4m4GFg7xJaNVN2", # incorrect checksum "3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLz", ], ) def test_returns_failed_validation_on_invalid_btc_address(value: str): """Test returns failed validation on invalid btc address.""" assert isinstance(btc_address(value), ValidationError) validators-0.28.3/tests/test_card.py000066400000000000000000000104231462425114700174460ustar00rootroot00000000000000"""Test Card.""" # external import pytest # local from validators import ( ValidationError, amex, card_number, diners, discover, jcb, mastercard, unionpay, visa, ) visa_cards = ["4242424242424242", "4000002760003184"] mastercard_cards = ["5555555555554444", "2223003122003222"] amex_cards = ["378282246310005", "371449635398431"] unionpay_cards = ["6200000000000005"] diners_cards = ["3056930009020004", "36227206271667"] jcb_cards = ["3566002020360505"] discover_cards = ["6011111111111117", "6011000990139424"] @pytest.mark.parametrize( "value", visa_cards + mastercard_cards + amex_cards + unionpay_cards + diners_cards + jcb_cards + discover_cards, ) def test_returns_true_on_valid_card_number(value: str): """Test returns true on valid card number.""" assert card_number(value) @pytest.mark.parametrize("value", ["4242424242424240", "4000002760003180", "400000276000318X"]) def test_returns_failed_on_valid_card_number(value: str): """Test returns failed on valid card number.""" assert isinstance(card_number(value), ValidationError) @pytest.mark.parametrize("value", visa_cards) def test_returns_true_on_valid_visa(value: str): """Test returns true on valid visa.""" assert visa(value) @pytest.mark.parametrize( "value", mastercard_cards + amex_cards + unionpay_cards + diners_cards + jcb_cards + discover_cards, ) def test_returns_failed_on_valid_visa(value: str): """Test returns failed on valid visa.""" assert isinstance(visa(value), ValidationError) @pytest.mark.parametrize("value", mastercard_cards) def test_returns_true_on_valid_mastercard(value: str): """Test returns true on valid mastercard.""" assert mastercard(value) @pytest.mark.parametrize( "value", visa_cards + amex_cards + unionpay_cards + diners_cards + jcb_cards + discover_cards, ) def test_returns_failed_on_valid_mastercard(value: str): """Test returns failed on valid mastercard.""" assert isinstance(mastercard(value), ValidationError) @pytest.mark.parametrize("value", amex_cards) def test_returns_true_on_valid_amex(value: str): """Test returns true on valid amex.""" assert amex(value) @pytest.mark.parametrize( "value", visa_cards + mastercard_cards + unionpay_cards + diners_cards + jcb_cards + discover_cards, ) def test_returns_failed_on_valid_amex(value: str): """Test returns failed on valid amex.""" assert isinstance(amex(value), ValidationError) @pytest.mark.parametrize("value", unionpay_cards) def test_returns_true_on_valid_unionpay(value: str): """Test returns true on valid unionpay.""" assert unionpay(value) @pytest.mark.parametrize( "value", visa_cards + mastercard_cards + amex_cards + diners_cards + jcb_cards + discover_cards, ) def test_returns_failed_on_valid_unionpay(value: str): """Test returns failed on valid unionpay.""" assert isinstance(unionpay(value), ValidationError) @pytest.mark.parametrize("value", diners_cards) def test_returns_true_on_valid_diners(value: str): """Test returns true on valid diners.""" assert diners(value) @pytest.mark.parametrize( "value", visa_cards + mastercard_cards + amex_cards + unionpay_cards + jcb_cards + discover_cards, ) def test_returns_failed_on_valid_diners(value: str): """Test returns failed on valid diners.""" assert isinstance(diners(value), ValidationError) @pytest.mark.parametrize("value", jcb_cards) def test_returns_true_on_valid_jcb(value: str): """Test returns true on valid jcb.""" assert jcb(value) @pytest.mark.parametrize( "value", visa_cards + mastercard_cards + amex_cards + unionpay_cards + diners_cards + discover_cards, ) def test_returns_failed_on_valid_jcb(value: str): """Test returns failed on valid jcb.""" assert isinstance(jcb(value), ValidationError) @pytest.mark.parametrize("value", discover_cards) def test_returns_true_on_valid_discover(value: str): """Test returns true on valid discover.""" assert discover(value) @pytest.mark.parametrize( "value", visa_cards + mastercard_cards + amex_cards + unionpay_cards + diners_cards + jcb_cards, ) def test_returns_failed_on_valid_discover(value: str): """Test returns failed on valid discover.""" assert isinstance(discover(value), ValidationError) validators-0.28.3/tests/test_country.py000066400000000000000000000044241462425114700202440ustar00rootroot00000000000000"""Test Country.""" # external import pytest # local from validators import ValidationError, calling_code, country_code, currency @pytest.mark.parametrize(("value"), ["+1", "+371"]) def test_returns_true_on_valid_calling_code(value: str): """Test returns true on valid calling code.""" assert calling_code(value) @pytest.mark.parametrize(("value"), ["+19", "+37", "-9"]) def test_returns_failed_validation_invalid_calling_code(value: str): """Test returns failed validation invalid calling code.""" assert isinstance(calling_code(value), ValidationError) @pytest.mark.parametrize( ("value", "iso_format"), [ ("ISR", "auto"), ("US", "alpha2"), ("USA", "alpha3"), ("840", "numeric"), ], ) def test_returns_true_on_valid_country_code(value: str, iso_format: str): """Test returns true on valid country code.""" assert country_code(value, iso_format=iso_format) @pytest.mark.parametrize( ("value", "iso_format"), [ (None, "auto"), ("", "auto"), ("123456", "auto"), ("XY", "alpha2"), ("PPP", "alpha3"), ("123", "numeric"), ("us", "auto"), ("uSa", "auto"), ("US ", "auto"), ("U.S", "auto"), ("1ND", "unknown"), ("ISR", None), ], ) def test_returns_failed_validation_on_invalid_country_code(value: str, iso_format: str): """Test returns failed validation on invalid country code.""" assert isinstance(country_code(value, iso_format=iso_format), ValidationError) @pytest.mark.parametrize( ("value", "skip_symbols", "ignore_case"), [("$", False, False), ("uSd", True, True)] ) def test_returns_true_on_valid_currency(value: str, skip_symbols: bool, ignore_case: bool): """Test returns true on valid currency.""" assert currency(value, skip_symbols=skip_symbols, ignore_case=ignore_case) @pytest.mark.parametrize( ("value", "skip_symbols", "ignore_case"), [("$", True, False), ("uSd", True, False), ("Bucks", True, True)], ) def test_returns_failed_validation_invalid_currency( value: str, skip_symbols: bool, ignore_case: bool ): """Test returns failed validation invalid currency.""" assert isinstance( currency(value, skip_symbols=skip_symbols, ignore_case=ignore_case), ValidationError ) validators-0.28.3/tests/test_cron.py000066400000000000000000000022601462425114700174760ustar00rootroot00000000000000"""Test Cron.""" # external import pytest # local from validators import ValidationError, cron @pytest.mark.parametrize( "value", [ "* * * * *", "*/5 * * * *", "0 0 * * *", "30 3 * * 1-5", "15 5 * * 1,3,5", "0 12 1 */2 *", "0 */3 * * *", "0 0 1 1 *", "0 12 * 1-6 1-5", "0 3-6 * * *", "*/15 0,6,12,18 * * *", "0 12 * * 0", "*/61 * * * *", # "5-10/2 * * * *", # this is valid, but not supported yet ], ) def test_returns_true_on_valid_cron(value: str): """Test returns true on valid cron string.""" assert cron(value) @pytest.mark.parametrize( "value", [ "* * * * * *", "* * * *", "*/5 25 * * *", "*/5 * *-1 * *", "32-30 * * * *", "0 12 32 * *", "0 12 * * 8", "0 */0 * * *", "30-20 * * * *", "10-* * * * *", "*/15 0,6,12,24 * * *", "& * * & * *", "* - * * - *", ], ) def test_returns_failed_validation_on_invalid_cron(value: str): """Test returns failed validation on invalid cron string.""" assert isinstance(cron(value), ValidationError) validators-0.28.3/tests/test_domain.py000066400000000000000000000075231462425114700200130ustar00rootroot00000000000000"""Test Domain.""" # external import pytest # local from validators import ValidationError, domain @pytest.mark.parametrize( ("value", "rfc_1034", "rfc_2782"), [ ("example.com", False, False), ("exa_mple.com", False, True), ("xn----gtbspbbmkef.xn--p1ai", False, False), ("underscore_subdomain.example.com", False, True), ("something.versicherung", False, False), ("someThing.versicherung.", True, False), ("11.com", False, False), ("3.cn.", True, False), ("_example.com", False, True), ("example_.com", False, True), ("_exa_mple_.com", False, True), ("a.cn", False, False), ("sub1.sub2.sample.co.uk", False, False), ("somerandomexample.xn--fiqs8s", False, False), ("kräuter.com.", True, False), ("über.com", False, False), ], ) def test_returns_true_on_valid_domain(value: str, rfc_1034: bool, rfc_2782: bool): """Test returns true on valid domain.""" assert domain(value, rfc_1034=rfc_1034, rfc_2782=rfc_2782) @pytest.mark.parametrize( ("value", "consider_tld", "rfc_1034", "rfc_2782"), [ ("example.com", True, False, False), ("exa_mple.com", True, False, True), ("xn----gtbspbbmkef.xn--p1ai", True, False, False), ("underscore_subdomain.example.com", True, False, True), ("someThing.versicherung.", True, True, False), ("11.com", True, False, False), ("3.cn.", True, True, False), ("_example.com", True, False, True), ("example_.com", True, False, True), ("somerandomexample.xn--fiqs8s", True, False, False), ], ) def test_returns_true_on_valid_top_level_domain( value: str, consider_tld: bool, rfc_1034: bool, rfc_2782: bool ): """Test returns true on valid top level domain.""" assert domain(value, consider_tld=consider_tld, rfc_1034=rfc_1034, rfc_2782=rfc_2782) @pytest.mark.parametrize( ("value", "rfc_1034", "rfc_2782"), [ ("example.com/.", True, False), ("example.com:4444", False, False), ("example.-com", False, False), ("example.", False, False), ("-example.com", False, False), ("example-.com.", True, False), ("_example.com", False, False), ("_example._com", False, False), ("example_.com", False, False), ("example", False, False), ("example.com!", True, False), ("example?.com", True, False), ("__exa__mple__.com", False, True), ("a......b.com", False, False), ("a.123", False, False), ("123.123", False, False), ("123.123.123.", True, False), ("123.123.123.123", False, False), ], ) def test_returns_failed_validation_on_invalid_domain(value: str, rfc_1034: bool, rfc_2782: bool): """Test returns failed validation on invalid domain.""" assert isinstance(domain(value, rfc_1034=rfc_1034, rfc_2782=rfc_2782), ValidationError) @pytest.mark.parametrize( ("value", "consider_tld", "rfc_1034", "rfc_2782"), [ ("example.266", True, False, False), ("exa_mple.org_", True, False, True), ("xn----gtbspbbmkef.xn-p1ai", True, False, False), ("underscore_subdomain.example.flat", True, False, True), ("someThing.versicherung.reddit.", True, True, False), ("11.twitter", True, False, False), ("3.cnx.", True, True, False), ("_example.#13", True, False, True), ("example_.fo-ul", True, False, True), ("somerandomexample.xn-n-fiqs8s", True, False, False), ], ) def test_returns_failed_validation_invalid_top_level_domain( value: str, consider_tld: bool, rfc_1034: bool, rfc_2782: bool ): """Test returns failed validation invalid top level domain.""" assert isinstance( domain(value, consider_tld=consider_tld, rfc_1034=rfc_1034, rfc_2782=rfc_2782), ValidationError, ) validators-0.28.3/tests/test_email.py000066400000000000000000000027651462425114700176360ustar00rootroot00000000000000"""Test eMail.""" # external import pytest # local from validators import ValidationError, email @pytest.mark.parametrize( ("value",), [ ("email@here.com",), ("weirder-email@here.and.there.com",), ("email@127.local.home.arpa",), ("example@valid-----hyphens.com",), ("example@valid-with-hyphens.com",), ("test@domain.with.idn.tld.उदाहरण.परीक्षा",), ("email@localhost.in",), ("Łókaść@email.com",), ("łemłail@here.com",), ("email@localdomain.org",), ('"\\\011"@here.com',), ], ) def test_returns_true_on_valid_email(value: str): """Test returns true on valid email.""" assert email(value) @pytest.mark.parametrize( ("value",), [ (None,), ("",), ("abc",), ("abc@",), ("abc@bar",), ("a @x.cz",), ("abc@.com",), ("something@@somewhere.com",), ("email@127.0.0.1",), ("example@invalid-.com",), ("example@-invalid.com",), ("example@inv-.alid-.com",), ("example@inv-.-alid.com",), ("john56789.john56789.john56789.john56789.john56789.john56789.john5@example.com",), ('"test@test"@example.com',), # Quoted-string format (CR not allowed) ('"\\\012"@here.com',), ], ) def test_returns_failed_validation_on_invalid_email(value: str): """Test returns failed validation on invalid email.""" assert isinstance(email(value), ValidationError) validators-0.28.3/tests/test_encoding.py000066400000000000000000000025641462425114700203320ustar00rootroot00000000000000"""Test Encodings.""" # external import pytest # local from validators import ValidationError, base58, base64 # ==> base58 <== # @pytest.mark.parametrize( "value", [ "cUSECaVvAiV3srWbFRvVPzm5YzcXJwPSwZfE7veYPHoXmR9h6YMQ", "18KToMF5ckjXBYt2HAj77qsG3GPeej3PZn", "n4FFXRNNEW1aA2WPscSuzHTCjzjs4TVE2Z", "38XzQ9dPGb1uqbZsjPtUajp7omy8aefjqj", ], ) def test_returns_true_on_valid_base58(value: str): """Test returns true on valid base58.""" assert base58(value) @pytest.mark.parametrize( "value", ["ThisIsAReallyLongStringThatIsDefinitelyNotBase58Encoded", "abcABC!@#", "InvalidBase58!"], ) def test_returns_failed_validation_on_invalid_base58(value: str): """Test returns failed validation on invalid base58.""" assert isinstance(base58(value), ValidationError) # ==> base64 <== # @pytest.mark.parametrize( "value", ["SGVsbG8gV29ybGQ=", "U29tZSBkYXRhIHN0cmluZw==", "YW55IGNhcm5hbCBwbGVhcw=="], ) def test_returns_true_on_valid_base64(value: str): """Test returns true on valid base64.""" assert base64(value) @pytest.mark.parametrize( "value", ["SGVsbG8gV29ybGQ", "U29tZSBkYXRhIHN0cmluZw", "YW55IGNhcm5hbCBwbGVhc"], ) def test_returns_failed_validation_on_invalid_base64(value: str): """Test returns failed validation on invalid base64.""" assert isinstance(base64(value), ValidationError) validators-0.28.3/tests/test_finance.py000066400000000000000000000030001462425114700201310ustar00rootroot00000000000000"""Test Finance.""" # external import pytest # local from validators import ValidationError, cusip, isin, sedol # ==> CUSIP <== # @pytest.mark.parametrize("value", ["912796X38", "912796X20", "912796x20"]) def test_returns_true_on_valid_cusip(value: str): """Test returns true on valid cusip.""" assert cusip(value) @pytest.mark.parametrize("value", ["912796T67", "912796T68", "XCVF", "00^^^1234"]) def test_returns_failed_validation_on_invalid_cusip(value: str): """Test returns failed validation on invalid cusip.""" assert isinstance(cusip(value), ValidationError) # ==> ISIN <== # @pytest.mark.parametrize("value", ["US0004026250", "JP000K0VF054", "US0378331005"]) def test_returns_true_on_valid_isin(value: str): """Test returns true on valid isin.""" assert isin(value) @pytest.mark.parametrize("value", ["010378331005" "XCVF", "00^^^1234", "A000009"]) def test_returns_failed_validation_on_invalid_isin(value: str): """Test returns failed validation on invalid isin.""" assert isinstance(isin(value), ValidationError) # ==> SEDOL <== # @pytest.mark.parametrize("value", ["0263494", "0540528", "B000009"]) def test_returns_true_on_valid_sedol(value: str): """Test returns true on valid sedol.""" assert sedol(value) @pytest.mark.parametrize("value", ["0540526", "XCVF", "00^^^1234", "A000009"]) def test_returns_failed_validation_on_invalid_sedol(value: str): """Test returns failed validation on invalid sedol.""" assert isinstance(sedol(value), ValidationError) validators-0.28.3/tests/test_hashes.py000066400000000000000000000127521462425114700200170ustar00rootroot00000000000000"""Test Hashes.""" # external import pytest # local from validators import ValidationError, base58, base64, md5, sha1, sha224, sha256, sha512 # ==> base58 <== # @pytest.mark.parametrize( "value", [ "cUSECaVvAiV3srWbFRvVPzm5YzcXJwPSwZfE7veYPHoXmR9h6YMQ", "18KToMF5ckjXBYt2HAj77qsG3GPeej3PZn", "n4FFXRNNEW1aA2WPscSuzHTCjzjs4TVE2Z", "38XzQ9dPGb1uqbZsjPtUajp7omy8aefjqj", ], ) def test_returns_true_on_valid_base58(value: str): """Test returns true on valid base58.""" assert base58(value) @pytest.mark.parametrize( "value", ["ThisIsAReallyLongStringThatIsDefinitelyNotBase58Encoded", "abcABC!@#", "InvalidBase58!"], ) def test_returns_failed_validation_on_invalid_base58(value: str): """Test returns failed validation on invalid base58.""" assert isinstance(base58(value), ValidationError) # ==> base64 <== # @pytest.mark.parametrize( "value", ["SGVsbG8gV29ybGQ=", "U29tZSBkYXRhIHN0cmluZw==", "YW55IGNhcm5hbCBwbGVhcw=="], ) def test_returns_true_on_valid_base64(value: str): """Test returns true on valid base64.""" assert base64(value) @pytest.mark.parametrize( "value", ["SGVsbG8gV29ybGQ", "U29tZSBkYXRhIHN0cmluZw", "YW55IGNhcm5hbCBwbGVhc"], ) def test_returns_failed_validation_on_invalid_base64(value: str): """Test returns failed validation on invalid base64.""" assert isinstance(base64(value), ValidationError) # ==> md5 <== # @pytest.mark.parametrize( "value", ["d41d8cd98f00b204e9800998ecf8427e", "D41D8CD98F00B204E9800998ECF8427E"] ) def test_returns_true_on_valid_md5(value: str): """Test returns true on valid md5.""" assert md5(value) @pytest.mark.parametrize( "value", [ "z41d8cd98f00b204e9800998ecf8427e", "z8cd98f00b204e9800998ecf8427e", "z4aaaa1d8cd98f00b204e9800998ecf8427e", ], ) def test_returns_failed_validation_on_invalid_md5(value: str): """Test returns failed validation on invalid md5.""" assert isinstance(md5(value), ValidationError) # ==> sha1 <== # @pytest.mark.parametrize( "value", ["da39a3ee5e6b4b0d3255bfef95601890afd80709", "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709"], ) def test_returns_true_on_valid_sha1(value: str): """Test returns true on valid sha1.""" assert sha1(value) @pytest.mark.parametrize( "value", [ "za39a3ee5e6b4b0d3255bfef95601890afd80709", "da39e5e6b4b0d3255bfef95601890afd80709", "daaaa39a3ee5e6b4b0d3255bfef95601890afd80709", ], ) def test_returns_failed_validation_on_invalid_sha1(value: str): """Test returns failed validation on invalid sha1.""" assert isinstance(sha1(value), ValidationError) # ==> sha224 <== # @pytest.mark.parametrize( "value", [ "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", "D14A028C2A3A2BC9476102BB288234C415A2B01F828EA62AC5B3E42F", ], ) def test_returns_true_on_valid_sha224(value: str): """Test returns true on valid sha224.""" assert sha224(value) @pytest.mark.parametrize( "value", [ "z14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", "d028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", "daaa14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", ], ) def test_returns_failed_validation_on_invalid_sha224(value: str): """Test returns failed validation on invalid sha224.""" assert isinstance(sha224(value), ValidationError) # ==> sha256 <== # @pytest.mark.parametrize( "value", [ "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855", ], ) def test_returns_true_on_valid_sha256(value: str): """Test returns true on valid sha256.""" assert sha256(value) @pytest.mark.parametrize( "value", [ "z3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "ec44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "eaaaa3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", ], ) def test_returns_failed_validation_on_invalid_sha256(value: str): """Test returns failed validation on invalid sha256.""" assert isinstance(sha256(value), ValidationError) # ==> sha256 <== # @pytest.mark.parametrize( "value", [ ( "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d" "13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e" ), ( "CF83E1357EEFB8BDF1542850D66D8007D620E4050B5715DC83F4A921D36CE9CE47D0D" "13C5D85F2B0FF8318D2877EEC2F63B931BD47417A81A538327AF927DA3E" ), ], ) def test_returns_true_on_valid_sha512(value: str): """Test returns true on valid sha512.""" assert sha512(value) @pytest.mark.parametrize( "value", [ ( "zf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d" "13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e" ), ( "cf8357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c" "5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e" ), ( "cf8aaaa3e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce4" "7d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e" ), ], ) def test_returns_failed_validation_on_invalid_sha512(value: str): """Test returns failed validation on invalid sha512.""" assert isinstance(sha512(value), ValidationError) validators-0.28.3/tests/test_hostname.py000066400000000000000000000047421462425114700203620ustar00rootroot00000000000000"""Test Hostname.""" # external import pytest # local from validators import ValidationError, hostname @pytest.mark.parametrize( ("value", "rfc_1034", "rfc_2782"), [ # simple hostname w/ optional ports ("ubuntu-pc:443", False, False), ("this-pc", False, False), ("lab-01a-notebook:404", False, False), ("4-oh-4", False, False), # hostname w/ optional ports ("example.com:4444", False, False), ("kräuter.com.", True, False), ("xn----gtbspbbmkef.xn--p1ai:65535", False, False), ("_example.com", False, True), # ipv4 addr w/ optional ports ("123.123.123.123:9090", False, False), ("127.0.0.1:43512", False, False), ("123.5.77.88:31000", False, False), ("12.12.12.12:5353", False, False), # ipv6 addr w/ optional ports ("[::1]:22", False, False), ("[dead:beef:0:0:0:0000:42:1]:5731", False, False), ("[0:0:0:0:0:ffff:1.2.3.4]:80", False, False), ("[0:a:b:c:d:e:f::]:53", False, False), ], ) def test_returns_true_on_valid_hostname(value: str, rfc_1034: bool, rfc_2782: bool): """Test returns true on valid hostname.""" assert hostname(value, rfc_1034=rfc_1034, rfc_2782=rfc_2782) @pytest.mark.parametrize( ("value", "rfc_1034", "rfc_2782"), [ # bad (simple hostname w/ optional ports) ("ubuntu-pc:443080", False, False), ("this-pc-is-sh*t", False, False), ("lab-01a-note._com_.com:404", False, False), ("4-oh-4:@.com", False, False), # bad (hostname w/ optional ports) ("example.com:-4444", False, False), ("xn----gtbspbbmkef.xn--p1ai:65538", False, False), ("_example.com:0", False, True), ("kräuter.com.:81_00", True, False), # bad (ipv4 addr w/ optional ports) ("123.123.123.123:99999", False, False), ("127.0.0.1:", False, False), ("123.5.-12.88:8080", False, False), ("12.12.12.12:$#", False, False), # bad (ipv6 addr w/ optional ports) ("[::1]:[22]", False, False), ("[dead:beef:0:-:0:-:42:1]:5731", False, False), ("[0:0:0:0:0:ffff:1.2.3.4]:-65538", False, False), ("[0:&:b:c:@:e:f:::9999", False, False), ], ) def test_returns_failed_validation_on_invalid_hostname(value: str, rfc_1034: bool, rfc_2782: bool): """Test returns failed validation on invalid hostname.""" assert isinstance(hostname(value, rfc_1034=rfc_1034, rfc_2782=rfc_2782), ValidationError) validators-0.28.3/tests/test_iban.py000066400000000000000000000010501462425114700174420ustar00rootroot00000000000000"""Test IBAN.""" # external import pytest # local from validators import ValidationError, iban @pytest.mark.parametrize("value", ["GB82WEST12345698765432", "NO9386011117947"]) def test_returns_true_on_valid_iban(value: str): """Test returns true on valid iban.""" assert iban(value) @pytest.mark.parametrize("value", ["GB81WEST12345698765432", "NO9186011117947"]) def test_returns_failed_validation_on_invalid_iban(value: str): """Test returns failed validation on invalid iban.""" assert isinstance(iban(value), ValidationError) validators-0.28.3/tests/test_ip_address.py000066400000000000000000000135541462425114700206620ustar00rootroot00000000000000"""Test IP Address.""" # external import pytest # local from validators import ValidationError, ipv4, ipv6 @pytest.mark.parametrize( ("address",), [ ("127.0.0.1",), ("123.5.77.88",), ("12.12.12.12",), ], ) def test_returns_true_on_valid_ipv4_address(address: str): """Test returns true on valid ipv4 address.""" assert ipv4(address) assert not ipv6(address) @pytest.mark.parametrize( ("address", "cidr", "strict", "host_bit"), [ ("127.0.0.1/0", True, True, True), ("123.5.77.88", True, False, True), ("12.12.12.0/24", True, True, False), ], ) def test_returns_true_on_valid_ipv4_cidr_address( address: str, cidr: bool, strict: bool, host_bit: bool ): """Test returns true on valid ipv4 CIDR address.""" assert ipv4(address, cidr=cidr, strict=strict, host_bit=host_bit) assert not ipv6(address, cidr=cidr, strict=strict, host_bit=host_bit) @pytest.mark.parametrize( ("address",), [ # leading zeroes error-out from Python 3.9.5 # ("100.100.033.033",), ("900.200.100.75",), ("0127.0.0.1",), ("abc.0.0.1",), ], ) def test_returns_failed_validation_on_invalid_ipv4_address(address: str): """Test returns failed validation on invalid ipv4 address.""" assert isinstance(ipv4(address), ValidationError) @pytest.mark.parametrize( ("address", "cidr", "strict", "host_bit"), [ ("1.1.1.1/1", False, True, True), ("1.1.1.1/33", True, False, True), ("1.1.1.1/24", True, True, False), ("1.1.1.1/-1", True, True, True), ], ) def test_returns_failed_validation_on_invalid_ipv4_cidr_address( address: str, cidr: bool, strict: bool, host_bit: bool ): """Test returns failed validation on invalid ipv4 CIDR address.""" assert isinstance(ipv4(address, cidr=cidr, strict=strict, host_bit=host_bit), ValidationError) @pytest.mark.parametrize( ("address",), [ ("::",), ("::1",), ("1::",), ("dead:beef:0:0:0:0000:42:1",), ("abcd:ef::42:1",), ("0:0:0:0:0:ffff:1.2.3.4",), ("::192.168.30.2",), ("0000:0000:0000:0000:0000::",), ("0:a:b:c:d:e:f::",), ], ) def test_returns_true_on_valid_ipv6_address(address: str): """Test returns true on valid ipv6 address.""" assert ipv6(address) assert not ipv4(address) @pytest.mark.parametrize( ("address", "cidr", "strict", "host_bit"), [ ("::1/128", True, True, True), ("::1/0", True, True, True), ("dead:beef:0:0:0:0:42:1/8", True, True, True), ("abcd:ef::42:1/32", True, True, True), ("0:0:0:0:0:ffff:1.2.3.4/16", True, True, True), ("2001:0db8:85a3:0000:0000:8a2e:0370:7334/64", True, True, True), ("::192.168.30.2/128", True, True, True), ], ) def test_returns_true_on_valid_ipv6_cidr_address( address: str, cidr: bool, strict: bool, host_bit: bool ): """Test returns true on valid ipv6 CIDR address.""" assert ipv6(address, cidr=cidr, strict=strict, host_bit=host_bit) assert not ipv4(address, cidr=cidr, strict=strict, host_bit=host_bit) @pytest.mark.parametrize( ("address",), [ ("abc.0.0.1",), ("abcd:1234::123::1",), ("1:2:3:4:5:6:7:8:9",), ("1:2:3:4:5:6:7:8::",), ("1:2:3:4:5:6:7::8:9",), ("abcd::1ffff",), ("1111:",), (":8888",), (":1.2.3.4",), ("18:05",), (":",), (":1:2:",), (":1:2::",), ("::1:2::",), ("8::1:2::9",), ("02001:0000:1234:0000:0000:C1C0:ABCD:0876",), ], ) def test_returns_failed_validation_on_invalid_ipv6_address(address: str): """Test returns failed validation on invalid ipv6 address.""" assert isinstance(ipv6(address), ValidationError) @pytest.mark.parametrize( ("address", "cidr", "strict", "host_bit"), [ ("::1/128", False, True, True), ("::1/129", True, False, True), ("dead:beef:0:0:0:0:42:1/8", True, True, False), ("::1/-130", True, True, True), ], ) def test_returns_failed_validation_on_invalid_ipv6_cidr_address( address: str, cidr: bool, strict: bool, host_bit: bool ): """Test returns failed validation on invalid ipv6 CIDR address.""" assert isinstance(ipv6(address, cidr=cidr, strict=strict, host_bit=host_bit), ValidationError) @pytest.mark.parametrize( ("address", "private"), [ ("10.1.1.1", True), ("192.168.1.1", True), ("169.254.1.1", True), ("127.0.0.1", True), ("0.0.0.0", True), ], ) def test_returns_true_on_valid_private_ipv4_address(address: str, private: bool): """Test returns true on private ipv4 address.""" assert ipv4(address, private=private) @pytest.mark.parametrize( ("address", "private"), [ ("1.1.1.1", True), ("192.169.1.1", True), ("7.53.12.1", True), ], ) def test_returns_failed_validation_on_invalid_private_ipv4_address(address: str, private: bool): """Test returns failed validation on invalid private ipv4 address.""" assert isinstance(ipv4(address, private=private), ValidationError) @pytest.mark.parametrize( ("address", "private"), [ ("1.1.1.1", False), ("192.169.1.1", False), ("7.53.12.1", False), ], ) def test_returns_true_on_valid_public_ipv4_address(address: str, private: bool): """Test returns true on valid public ipv4 address.""" assert ipv4(address, private=private) @pytest.mark.parametrize( ("address", "private"), [ ("10.1.1.1", False), ("192.168.1.1", False), ("169.254.1.1", False), ("127.0.0.1", False), ("0.0.0.0", False), ], ) def test_returns_failed_validation_on_invalid_public_ipv4_address(address: str, private: bool): """Test returns failed validation on private ipv4 address.""" assert isinstance(ipv4(address, private=private), ValidationError) validators-0.28.3/tests/test_length.py000066400000000000000000000015251462425114700200210ustar00rootroot00000000000000"""Test Length.""" # external import pytest # local from validators import ValidationError, length @pytest.mark.parametrize( ("value", "min_val", "max_val"), [("password", 2, None), ("password", None, None), ("password", 0, 10), ("password", 8, 8)], ) def test_returns_true_on_valid_length(value: str, min_val: int, max_val: int): """Test returns true on valid length.""" assert length(value, min_val=min_val, max_val=max_val) @pytest.mark.parametrize( ("value", "min_val", "max_val"), [("something", 14, 12), ("something", -10, -20), ("something", 0, -2), ("something", 13, 14)], ) def test_returns_failed_validation_on_invalid_range(value: str, min_val: int, max_val: int): """Test returns failed validation on invalid range.""" assert isinstance(length(value, min_val=min_val, max_val=max_val), ValidationError) validators-0.28.3/tests/test_mac_address.py000066400000000000000000000014641462425114700210070ustar00rootroot00000000000000"""MAC Address.""" # external import pytest # local from validators import ValidationError, mac_address @pytest.mark.parametrize( ("address",), [ ("01:23:45:67:ab:CD",), ("01-23-45-67-ab-CD",), ("01:2F:45:37:ab:CD",), ("A1-2F-4E-68-ab-CD",), ], ) def test_returns_true_on_valid_mac_address(address: str): """Test returns true on valid mac address.""" assert mac_address(address) @pytest.mark.parametrize( ("address",), [ ("00-00:-00-00-00",), ("01:23:45:67:89:",), ("01:23-45:67-89:gh",), ("123:23:45:67:89:00",), ], ) def test_returns_failed_validation_on_invalid_mac_address(address: str): """Test returns failed validation on invalid mac address.""" assert isinstance(mac_address(address), ValidationError) validators-0.28.3/tests/test_slug.py000066400000000000000000000012501462425114700175050ustar00rootroot00000000000000"""Test Slug.""" # external import pytest # local from validators import ValidationError, slug @pytest.mark.parametrize( "value", [ "123-asd-7sda", "123-k-123", "dac-12sa-459", "dac-12sa7-ad31as", ], ) def test_returns_true_on_valid_slug(value: str): """Test returns true on valid slug.""" assert slug(value) @pytest.mark.parametrize( "value", [ "some.slug&", "1231321%", " 21312", "-47q-p--123", ], ) def test_returns_failed_validation_on_invalid_slug(value: str): """Test returns failed validation on invalid slug.""" assert isinstance(slug(value), ValidationError) validators-0.28.3/tests/test_url.py000066400000000000000000000203541462425114700173430ustar00rootroot00000000000000"""Test URL.""" # standard from typing import Optional # external import pytest # local from validators import ValidationError, url @pytest.mark.parametrize( "value", [ "http://foobar.dk", "http://foobar.museum/foobar", "http://fo.com", "http://FOO.com", "http://foo.com/blah_blah", "http://foo.com/blah_blah/", "http://foo.com/blah_blah_(wikipedia)", "http://foo.com/blah_blah_(wikipedia)_(again)", "http://www.example.com/wpstyle/?p=364", "https://www.example.com?bar=baz", "http://✪df.ws/123", "http://userid:password@example.com:8080", "http://userid:password@example.com:8080/", "http://userid@example.com", "http://userid@example.com/", "http://userid@example.com:8080", "http://userid@example.com:8080/", "http://userid:password@example.com", "http://userid:password@example.com/", "http://142.42.1.1/", "http://142.42.1.1:8080/", "http://➡.ws/䨹", "http://⌘.ws", "http://⌘.ws/", "http://foo.com/blah_(wikipedia)#cite-1", "http://foo.com/blah_(wikipedia)_blah#cite-1", "http://foo.com/unicode_(✪)_in_parens", "http://foo.com/(something)?after=parens", "http://☺.damowmow.com/", "http://code.google.com/events/#&product=browser", "http://j.mp", "ftp://foo.bar/baz", "http://foo.bar/?q=Test%20URL-encoded%20stuff", "http://مثال.إختبار", "http://例子.测试", "http://उदाहरण.परीक्षा", "http://www.😉.com", "http://😉.com/😁", "http://উদাহরণ.বাংলা", "http://xn--d5b6ci4b4b3a.xn--54b7fta0cc", "http://дом-м.рф/1/asdf", "http://xn----gtbybh.xn--p1ai/1/asdf", "http://1337.net", "http://a.b-c.de", "http://a.b--c.de/", "http://0.0.0.0", "http://224.1.1.1", "http://223.255.255.254", "http://10.1.1.0", "http://10.1.1.1", "http://10.1.1.254", "http://10.1.1.255", "http://127.0.0.1:8080", "http://127.0.10.150", "http://47.96.118.255:2333/", "http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html", "http://[1080:0:0:0:8:800:200C:417A]/index.html", "http://[3ffe:2a00:100:7031::1]", "http://[1080::8:800:200C:417A]/foo", "http://[::192.9.5.5]/ipng", "http://[::FFFF:129.144.52.38]:80/index.html", "http://[2010:836B:4179::836B:4179]", "http://foo.bar", "http://foo.bar/📍", "http://google.com:9/test", "http://5.196.190.0/", "http://username:password@example.com:4010/", "http://username:password@112.168.10.10:4010/", "http://base-test-site.local", "http://президент.рф/", "http://10.24.90.255:83/", "https://travel-usa.com/wisconsin/旅行/", "http://:::::::::::::@exmp.com", "http://-.~_!$&'()*+,;=:%40:80%2f::::::@example.com", "https://exchange.jetswap.finance/#/swap", "https://www.foo.com/bar#/baz/test", "https://matrix.to/#/!BSqRHgvCtIsGittkBG:talk.puri.sm/$1551464398" + "853539kMJNP:matrix.org?via=talk.puri.sm&via=matrix.org&via=disroot.org", "https://example.org/path#2022%201040%20(Cornelius%20Morgan%20G).pdf", # when simple_host=True # "http://localhost", # "http://localhost:8000", # "http://pc:8081/", # "http://3628126748", # "http://foobar", # when strict_query=False # "https://www.example.com/foo/?bar=baz&inga=42&quux", # "https://foo.bar.net/baz.php?-/inga/test-lenient-query/", # "https://foo.com/img/bar/baz.jpg?-62169987208", # "https://example.com/foo/?bar#!baz/inga/8SA-M3as7A8", ], ) def test_returns_true_on_valid_url(value: str): """Test returns true on valid url.""" assert url(value) @pytest.mark.parametrize( "value, private", [ ("http://username:password@10.0.10.1/", True), ("http://username:password@192.168.10.10:4010/", True), ("http://127.0.0.1", True), ], ) def test_returns_true_on_valid_private_url(value: str, private: Optional[bool]): """Test returns true on valid private url.""" assert url(value, private=private) @pytest.mark.parametrize( "value", [ "foobar.dk", "http://127.0.0/asdf", "http://foobar.d", "http://foobar.12", "htp://foobar.com", "http://foobar..com", "http://fo..com", "http://", "http://.", "http://..", "http://../", "http://?", "http://??", "http://??/", "http://#", "http://##", "http://##/", "http://foo.bar?q=Spaces should be encoded", "//", "//a", "///a", "///", "http:///a", "foo.com", "rdar://1234", "h://test", "http:// shouldfail.com", ":// should fail", "http://foo.bar/foo(bar)baz quux", "http://-error-.invalid/", "http://www.\uFFFD.ch", "http://-a.b.co", "http://a.b-.co", "http://1.1.1.1.1", "http://123.123.123", "http://.www.foo.bar/", "http://www.foo.bar./", "http://.www.foo.bar./", "http://127.12.0.260", 'http://example.com/">user@example.com', "http://[2010:836B:4179::836B:4179", "http://2010:836B:4179::836B:4179", "http://2010:836B:4179::836B:4179:80/index.html", "https://example.org?q=search');alert(document.domain);", "https://www.example.com/foo/?bar=baz&inga=42&quux", "https://foo.com/img/bar/baz.jpg?-62169987208", "https://foo.bar.net/baz.php?-/inga/test-lenient-query/", "https://example.com/foo/?bar#!baz/inga/8SA-M3as7A8", "http://0.00.00.00.00.00.00.00.00.00.00.00.00.00.00." + "00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00." + "00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00." + "00.00.00.00.00.00.00.00.00.00.00.00.00.", # ReDoS "http://172.20.201.135-10.10.10.1656172.20.11.80-10." + "10.10.1746172.16.9.13-192.168.17.68610.10.10.226-192." + "168.17.64610.10.10.226-192.168.17.63610.10.10.226-192." + "168.17.62610.10.10.226-192.168.17.61610.10.10.226-192." + "168.17.60610.10.10.226-192.168.17.59610.10.10.226-192." + "168.17.58610.10.10.226-192.168.17.57610.10.10.226-192." + "168.17.56610.10.10.226-192.168.17.55610.10.10.226-192." + "168.17.54610.10.10.226-192.168.17.53610.10.10.226-192." + "168.17.52610.10.10.226-192.168.17.51610.10.10.195-10." + "10.10.2610.10.10.194-192.168.17.685172.20.11.52-10.10." + "10.195510.10.10.226-192.168.17.50510.10.10.186-172.20." + "11.1510.10.10.165-198.41.0.54192.168.84.1-192.168.17." + "684192.168.222.1-192.168.17.684172.20.11.52-10.10.10." + "174410.10.10.232-172.20.201.198410.10.10.228-172.20.201." + "1983192.168.17.135-10.10.10.1423192.168.17.135-10.10.10." + "122310.10.10.224-172.20.201.198310.10.10.195-172.20.11." + "1310.10.10.160-172.20.201.198310.10.10.142-192.168.17." + "1352192.168.22.207-10.10.10.2242192.168.17.66-10.10.10." + "1122192.168.17.135-10.10.10.1122192.168.17.129-10.10.10." + "1122172.20.201.198-10.10.10.2282172.20.201.198-10.10.10." + "2242172.20.201.1-10.10.10.1652172.20.11.2-10.10.10.1412172." + "16.8.229-12.162.170.196210.10.10.212-192.168.22.133", # ReDoS ], ) def test_returns_failed_validation_on_invalid_url(value: str): """Test returns failed validation on invalid url.""" assert isinstance(url(value), ValidationError) @pytest.mark.parametrize( "value, private", [ ("http://username:password@192.168.10.10:4010", False), ("http://username:password@127.0.0.1:8080", False), ("http://10.0.10.1", False), ("http://255.255.255.255", False), ], ) def test_returns_failed_validation_on_invalid_private_url(value: str, private: Optional[bool]): """Test returns failed validation on invalid private url.""" assert isinstance(url(value, private=private), ValidationError) validators-0.28.3/tests/test_uuid.py000066400000000000000000000016511462425114700175060ustar00rootroot00000000000000"""Test UUIDs.""" # standard from typing import Union from uuid import UUID, uuid4 # external import pytest # local from validators import ValidationError, uuid @pytest.mark.parametrize( ("value",), [ (uuid4(),), ("2bc1c94f-0deb-43e9-92a1-4775189ec9f8",), (uuid4(),), ("888256d7c49341f19fa33f29d3f820d7",), ], ) def test_returns_true_on_valid_uuid(value: Union[str, UUID]): """Test returns true on valid uuid.""" assert uuid(value) @pytest.mark.parametrize( ("value",), [ ("2bc1c94f-deb-43e9-92a1-4775189ec9f8",), ("2bc1c94f-0deb-43e9-92a1-4775189ec9f",), ("gbc1c94f-0deb-43e9-92a1-4775189ec9f8",), ("2bc1c94f 0deb-43e9-92a1-4775189ec9f8",), ], ) def test_returns_failed_validation_on_invalid_uuid(value: Union[str, UUID]): """Test returns failed validation on invalid uuid.""" assert isinstance(uuid(value), ValidationError) validators-0.28.3/tests/test_validation_failure.py000066400000000000000000000016431462425114700224020ustar00rootroot00000000000000"""Test validation Failure.""" # local from validators import between failed_obj_repr = "ValidationError(func=between" class TestValidationError: """Test validation Failure.""" def setup_method(self): """Setup Method.""" self.is_in_between = between(3, min_val=4, max_val=5) def test_boolean_coerce(self): """Test Boolean.""" assert not bool(self.is_in_between) assert not self.is_in_between def test_repr(self): """Test Repr.""" assert failed_obj_repr in repr(self.is_in_between) def test_string(self): """Test Repr.""" assert failed_obj_repr in str(self.is_in_between) def test_arguments_as_properties(self): """Test argument properties.""" assert self.is_in_between.__dict__["value"] == 3 assert self.is_in_between.__dict__["min_val"] == 4 assert self.is_in_between.__dict__["max_val"] == 5