pax_global_header00006660000000000000000000000064150160320040014501gustar00rootroot0000000000000052 comment=7332abb2337527c6d259b9b07bde17012da020a7 pydantic-extra-types-2.10.5/000077500000000000000000000000001501603200400156645ustar00rootroot00000000000000pydantic-extra-types-2.10.5/.github/000077500000000000000000000000001501603200400172245ustar00rootroot00000000000000pydantic-extra-types-2.10.5/.github/dependabot.yml000066400000000000000000000005761501603200400220640ustar00rootroot00000000000000version: 2 updates: # GitHub Actions - package-ecosystem: "github-actions" directory: "/" schedule: interval: "monthly" commit-message: prefix: ⬆ # Python - package-ecosystem: "uv" directory: "/" schedule: interval: "monthly" groups: python-packages: patterns: - "*" commit-message: prefix: ⬆ pydantic-extra-types-2.10.5/.github/workflows/000077500000000000000000000000001501603200400212615ustar00rootroot00000000000000pydantic-extra-types-2.10.5/.github/workflows/ci.yml000066400000000000000000000055161501603200400224060ustar00rootroot00000000000000name: CI on: push: branches: - main tags: - '**' pull_request: {} env: COLUMNS: 150 jobs: lint: runs-on: ubuntu-latest strategy: fail-fast: false steps: - uses: actions/checkout@v4 - uses: astral-sh/setup-uv@v6 with: enable-cache: true - name: Install dependencies run: uv sync --python 3.12 --group lint --all-extras - uses: pre-commit/action@v3.0.1 with: extra_args: --all-files --verbose env: SKIP: no-commit-to-branch test: name: test py${{ matrix.python-version }} runs-on: ubuntu-latest strategy: fail-fast: false matrix: python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13'] env: UV_PYTHON: ${{ matrix.python-version }} steps: - uses: actions/checkout@v4 - uses: astral-sh/setup-uv@v6 with: enable-cache: true - name: Install dependencies run: uv sync --extra all - name: Make coverage directory run: mkdir coverage - run: uv run --frozen coverage run -m pytest env: COVERAGE_FILE: coverage/.coverage.${{ runner.os }}-py${{ matrix.python-version }} - name: store coverage files uses: actions/upload-artifact@v4 with: name: coverage-${{ matrix.python-version }} path: coverage include-hidden-files: true coverage: runs-on: ubuntu-latest needs: [test] steps: - uses: actions/checkout@v4 - uses: astral-sh/setup-uv@v6 with: enable-cache: true - name: get coverage files uses: actions/download-artifact@v4 with: merge-multiple: true path: coverage - run: uv run --frozen coverage combine coverage - run: uv run --frozen coverage report --fail-under 85 # https://github.com/marketplace/actions/alls-green#why used for branch protection checks check: if: always() needs: [lint, test, coverage] runs-on: ubuntu-latest steps: - name: Decide whether the needed jobs succeeded or failed uses: re-actors/alls-green@release/v1 with: jobs: ${{ toJSON(needs) }} release: needs: [check] if: "success() && startsWith(github.ref, 'refs/tags/')" runs-on: ubuntu-latest environment: release permissions: id-token: write steps: - uses: actions/checkout@v4 - uses: astral-sh/setup-uv@v6 with: enable-cache: true - name: check GITHUB_REF matches package version uses: samuelcolvin/check-python-version@v4.1 with: version_file_path: pydantic_extra_types/__init__.py - run: uv build - name: Publish to PyPI uses: pypa/gh-action-pypi-publish@release/v1 with: skip-existing: true pydantic-extra-types-2.10.5/.gitignore000066400000000000000000000004011501603200400176470ustar00rootroot00000000000000.idea/ env/ venv/ .venv/ env3*/ Pipfile *.py[cod] *.egg-info/ .python-version /build/ dist/ .cache/ .mypy_cache/ test.py .coverage /htmlcov/ /site/ /site.zip .pytest_cache/ .vscode/ _build/ .auto-format /sandbox/ /.ghtopdep_cache/ /worktrees/ /.ruff_cache/ pydantic-extra-types-2.10.5/.pre-commit-config.yaml000066400000000000000000000013221501603200400221430ustar00rootroot00000000000000repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v5.0.0 hooks: - id: no-commit-to-branch # prevent direct commits to the `main` branch - id: check-yaml - id: check-toml - id: end-of-file-fixer - id: trailing-whitespace - repo: local hooks: - id: format name: Format entry: make args: [format] language: system types: [python] pass_filenames: false - id: lint name: Lint entry: make args: [lint] types: [python] language: system pass_filenames: false - id: Typecheck name: Typecheck entry: make args: [typecheck] types: [python] language: system pass_filenames: false pydantic-extra-types-2.10.5/HISTORY.md000066400000000000000000000360331501603200400173540ustar00rootroot00000000000000# CHANGELOG ## Latest Changes ## 2.10.2 * Add back Python 3.8 support by @Viicos in https://github.com/pydantic/pydantic-extra-types/pull/249 * ⬆ Bump astral-sh/setup-uv from 4 to 5 by @dependabot in https://github.com/pydantic/pydantic-extra-types/pull/282 * Preserve months when using the Pendulum Duration type by @gareththackeray in https://github.com/pydantic/pydantic-extra-types/pull/283 * ✨ Add type checking support and improve type hints across the codebase by @yezz123 in https://github.com/pydantic/pydantic-extra-types/pull/285 * πŸ“ Add additional installation information to README by @oakhan3 in https://github.com/pydantic/pydantic-extra-types/pull/233 ## 2.10.1 * Allow build with python-ulid 3.0.0 by @sunpoet in https://github.com/pydantic/pydantic-extra-types/pull/225 * πŸ”¨ added automatic syntax-upgrade hook ~ pyupgrade by @janas-adam in https://github.com/pydantic/pydantic-extra-types/pull/229 * :fire: Revert adding pyupgrade as a hook in pre-commit by @yezz123 in https://github.com/pydantic/pydantic-extra-types/pull/230 * isolate url in Currency by @edasubert in https://github.com/pydantic/pydantic-extra-types/pull/235 * lower case currency is valid by @edasubert in https://github.com/pydantic/pydantic-extra-types/pull/236 * Update SemanticVersion by @viccie30 in https://github.com/pydantic/pydantic-extra-types/pull/237 * Epoch - unix timestamp by @commonism in https://github.com/pydantic/pydantic-extra-types/pull/240 * :recycle: Migrate Pydantic Extra Types to use uv by @yezz123 in https://github.com/pydantic/pydantic-extra-types/pull/241 * ⬆ Bump astral-sh/setup-uv from 3 to 4 by @dependabot in https://github.com/pydantic/pydantic-extra-types/pull/245 * ⬆ Bump pre-commit/action from 3.0.0 to 3.0.1 by @dependabot in https://github.com/pydantic/pydantic-extra-types/pull/244 * πŸ”– Release version 2.10.1 by @yezz123 in https://github.com/pydantic/pydantic-extra-types/pull/246 * Fix check python version for release by @hramezani in https://github.com/pydantic/pydantic-extra-types/pull/247 ## 2.10.0 ### Types * Add semantic version type by @jbkroner in https://github.com/pydantic/pydantic-extra-types/pull/199 * feat: add S3Path by @lucianosrp in https://github.com/pydantic/pydantic-extra-types/pull/206 ### Refactor * feature: Improve phone number validator by @mZbZ in https://github.com/pydantic/pydantic-extra-types/pull/202 * Feature: Add phone number validator by @mZbZ in https://github.com/pydantic/pydantic-extra-types/pull/203 * Domain name string type by @matter1-git in https://github.com/pydantic/pydantic-extra-types/pull/212 * Adjust test_json_schema() for Pydantic 2.9 by @musicinmybrain in https://github.com/pydantic/pydantic-extra-types/pull/215 * Allow python-ulid 3.0 by @musicinmybrain in https://github.com/pydantic/pydantic-extra-types/pull/222 ### Dependencies * ⬆ Bump the python-packages group with 5 updates by @dependabot in https://github.com/pydantic/pydantic-extra-types/pull/201 * ✨ deprecate `semver` in favor of `semantic_version` by @07pepa in https://github.com/pydantic/pydantic-extra-types/pull/209 * πŸ”– Release version 2.10.0 by @yezz123 in https://github.com/pydantic/pydantic-extra-types/pull/224 ## 2.9.0 ### Types * Add Semantic version type. PR [#195](https://github.com/pydantic/pydantic-extra-types/pull/195) by [@nikstuckenbrock](https://github.com/nikstuckenbrock) * Add timezone name validation. PR [#193](https://github.com/pydantic/pydantic-extra-types/pull/193) by [@07pepa](https://github.com/07pepa) ### Refactor * Replace try-except block by if-else statement. PR [#192](https://github.com/pydantic/pydantic-extra-types/pull/192) by [@maxsos](https://github.com/maxsos) ### Dependencies * ⬆ Bump the python-packages group with 4 updates. PR [#194](https://github.com/pydantic/pydantic-extra-types/pull/194) by @dependabot ## 2.8.2 * πŸ› Preserve timezone information when validating Pendulum DateTimes. [#189](https://github.com/pydantic/pydantic-extra-types/pull/189) by [@chrisguidry ](https://github.com/chrisguidry) ## 2.8.1 ### Bug Fixes * πŸ› Fix Pendulum date time object to have correct typing. [#184](https://github.com/pydantic/pydantic-extra-types/pull/184) by [@07pepa](https://github.com/07pepa) ### Types * ✨ Add parsing of pendulum_dt from unix time and non-strict parsing. [#185](https://github.com/pydantic/pydantic-extra-types/pull/185) by [@07pepa](https://github.com/07pepa) ## 2.8.0 ### Refactor * ♻️ refactor some functions & minor changes. [#180](https://github.com/pydantic/pydantic-extra-types/pull/180) by [@yezz123](https://github.com/yezz123) ### Internal * Allow requiring extra dependencies. [#178](https://github.com/pydantic/pydantic-extra-types/pull/178) by [@yezz123](https://github.com/yezz123) ### Types * Add ISO 15924 and tests. [#174](https://github.com/pydantic/pydantic-extra-types/pull/174) by [@07pepa](https://github.com/07pepa) * add native datetime to pendulum_dt.py. [#176](https://github.com/pydantic/pydantic-extra-types/pull/176) by [@07pepa](https://github.com/07pepa) * add hash and eq to phone_numbers. [#177](https://github.com/pydantic/pydantic-extra-types/pull/177) by [@07pepa](https://github.com/07pepa) ### Dependencies * ⬆ Bump the python-packages group with 5 updates. PR [#179](https://github.com/pydantic/pydantic-extra-types/pull/179) by @dependabot * ⬆ Bump the python-packages group with 4 updates. PR [#171](https://github.com/pydantic/pydantic-extra-types/pull/171) by @dependabot ## 2.7.0 * πŸ”₯ Remove latest-changes workflow. PR [#165](https://github.com/pydantic/pydantic-extra-types/pull/165) by [yezz123](https://github.com/yezz123) * πŸ”¨ Add latest-changes workflow to generate Changes. PR [#164](https://github.com/pydantic/pydantic-extra-types/pull/164) by [yezz123](https://github.com/yezz123) * Added LanguageAlpha2 and LanguageName types. PR [#153](https://github.com/pydantic/pydantic-extra-types/pull/153) by [odelmarcelle](https://github.com/odelmarcelle) * Added support for pendulum Dates. PR [#154](https://github.com/pydantic/pydantic-extra-types/pull/154) by [Woody1193](https://github.com/Woody1193) * Add support for pendulum Duration. PR [#162](https://github.com/pydantic/pydantic-extra-types/pull/162) by [tempookian](https://github.com/tempookian) ### Dependencies * ⬆ Bump the python-packages group with 1 update. PR [#150](https://github.com/pydantic/pydantic-extra-types/pull/150) by [dependabot](https://github.com/dependabot) * ⬆ Bump the python-packages group with 6 updates. PR [#160](https://github.com/pydantic/pydantic-extra-types/pull/160) by [dependabot](https://github.com/dependabot) ## 2.6.0 * Allow python-ulid 2.x on Python 3.9 and later. PR [#131](https://github.com/pydantic/pydantic-extra-types/pull/131) by [@musicinmybrain](https://github.com/musicinmybrain) * Do not pin the ”major” version of pycountry. PR [#132](https://github.com/pydantic/pydantic-extra-types/pull/132) by [@musicinmybrain](https://github.com/musicinmybrain) * πŸ€– Create dependabot.yml for updating GitHub action. PR [#134](https://github.com/pydantic/pydantic-extra-types/pull/134) by [@yezz123](https://github.com/yezz123) * Refactor Documentation for ISBN and MAC address modules. PR [#124](https://github.com/pydantic/pydantic-extra-types/pull/124) by [@yezz123](https://github.com/yezz123) * Add language code definitions and test. PR [#141](https://github.com/pydantic/pydantic-extra-types/pull/141) by [@07pepa](https://github.com/07pepa) * Create a `changelog` to match release notes. PR [#142](https://github.com/pydantic/pydantic-extra-types/pull/142) by [@yezz123](https://github.com/yezz123) * Add currency code ISO 4217 and its subset that includes only currencies. PR [#143](https://github.com/pydantic/pydantic-extra-types/pull/143) by [@07pepa](https://github.com/07pepa) * πŸ”¨ Update code formatting and linting configurations. PR [#144](https://github.com/pydantic/pydantic-extra-types/pull/144) by [@yezz123](https://github.com/yezz123) * πŸ‘· Add Python checking for dependencies. PR [#145](https://github.com/pydantic/pydantic-extra-types/pull/145) by [@yezz123](https://github.com/yezz123) * πŸ› Fix single quote issue. PR [#148](https://github.com/pydantic/pydantic-extra-types/pull/148) by [@yezz123](https://github.com/yezz123) ## 2.5.0 * Add Pendulum DT support. PR [#110](https://github.com/pydantic/pydantic-extra-types/pull/110) by [@theunkn0wn1](https://github.com/theunkn0wn1) ## 2.4.1 * Fix refs blocking docs build. PR [#125](https://github.com/pydantic/pydantic-extra-types/pull/125) by [@sydney-runkle](https://github.com/sydney-runkle) ## 2.4.0 * Add: New type ISBN. PR [#116](https://github.com/pydantic/pydantic-extra-types/pull/116) by [lucasmucidas](https://github.com/lucasmucidas) * Fix validate_digits actually allowing non-digit characters. PR [#120](https://github.com/pydantic/pydantic-extra-types/pull/120) by [romaincaillon](https://github.com/romaincaillon) * Refactor the `validate_brand` method & add new types. PR [#56](https://github.com/pydantic/pydantic-extra-types/pull/56) by [yezz123](https://github.com/yezz123) * Drop Python 3.7 & support 3.12. PR [#122](https://github.com/pydantic/pydantic-extra-types/pull/122) by [yezz123](https://github.com/yezz123) ## 2.3.0 * Upgrade pydantic version to >=2.5.2. PR [#113](https://github.com/pydantic/pydantic-extra-types/pull/113) by [hramezani](https://github.com/hramezani) ## 2.2.0 * Add `long` and `short` format to `as_hex`. PR [#93](https://github.com/pydantic/pydantic-extra-types/pull/93) by [DJRHails](https://github.com/DJRHails) * Refactor documentation. PR [#98](https://github.com/pydantic/pydantic-extra-types/pull/98) by [Kludex](https://github.com/Kludex) * Add `ULID` type. PR [#73](https://github.com/pydantic/pydantic-extra-types/pull/73) by [JeanArhancet](https://github.com/JeanArhancet) * Add `__get_pydantic_json_schema__` method with `format='tel'`. PR [#106](https://github.com/pydantic/pydantic-extra-types/pull/106) by [hasansezertasan](https://github.com/hasansezertasan) ## 2.1.0 * Add `MacAddress` type. PR [#71](https://github.com/pydantic/pydantic-extra-types/pull/71) by [JeanArhancet](https://github.com/JeanArhancet) * Fix usage of `MAC address`. PR [#72](https://github.com/pydantic/pydantic-extra-types/pull/72) by [yezz123](https://github.com/yezz123) * Add docstrings for payment cards. PR [#77](https://github.com/pydantic/pydantic-extra-types/pull/77) by [tpdorsey](https://github.com/tpdorsey) * Fix MAC address validation. PR [#79](https://github.com/pydantic/pydantic-extra-types/pull/79) by [JeanArhancet](https://github.com/JeanArhancet) * Remove work in progress part from README.md. PR [#81](https://github.com/pydantic/pydantic-extra-types/pull/81) by [hramezani](https://github.com/hramezani) * Add `Latitude`, `Longitude`, and `Coordinate`. PR [#76](https://github.com/pydantic/pydantic-extra-types/pull/76) by [JeanArhancet](https://github.com/JeanArhancet) * Refactor: use stdlib and remove useless code. PR [#86](https://github.com/pydantic/pydantic-extra-types/pull/86) by [eumiro](https://github.com/eumiro) * Make Latitude and Longitude evaluated. PR [#90](https://github.com/pydantic/pydantic-extra-types/pull/90) by [Kludex](https://github.com/Kludex) ## 2.0.0 * Migrate `Color` & `Payment Card`. PR [#2](https://github.com/pydantic/pydantic-extra-types/pull/2) by [yezz123](https://github.com/yezz123) * Add `pydantic` to classifiers. PR [#13](https://github.com/pydantic/pydantic-extra-types/pull/13) by [yezz123](https://github.com/yezz123) * Remove dependencies caching. PR [#16](https://github.com/pydantic/pydantic-extra-types/pull/16) by [yezz123](https://github.com/yezz123) * Deprecate `__modify_schema__` method. PR [#20](https://github.com/pydantic/pydantic-extra-types/pull/20) by [yezz123](https://github.com/yezz123) * Fix Color JSON schema generation. PR [#21](https://github.com/pydantic/pydantic-extra-types/pull/21) by [dmontagu](https://github.com/dmontagu) * Fix issues of `pydantic_core.core_schema` has no attribute `xxx`. PR [#23](https://github.com/pydantic/pydantic-extra-types/pull/23) by [yezz123](https://github.com/yezz123) * Fix Failed tests for `color` type. PR [#26](https://github.com/pydantic/pydantic-extra-types/pull/26) by [yezz123](https://github.com/yezz123) * Created Country type. PR [#14](https://github.com/pydantic/pydantic-extra-types/pull/14) by [HomiGrotas](https://github.com/HomiGrotas) * Add phone number types. PR [#25](https://github.com/pydantic/pydantic-extra-types/pull/25) by [JamesHutchison](https://github.com/JamesHutchison) * Make `phonenumbers` a requirement. PR [#29](https://github.com/pydantic/pydantic-extra-types/pull/29) by [yezz123](https://github.com/yezz123) * Add ABARouting number type. PR [#30](https://github.com/pydantic/pydantic-extra-types/pull/30) by [RevinderDev](https://github.com/RevinderDev) * Add missing countries. PR [#32](https://github.com/pydantic/pydantic-extra-types/pull/32) by [EssaAlshammri](https://github.com/EssaAlshammri) * Resolve `pydantic-core` dependency conflict. PR [#45](https://github.com/pydantic/pydantic-extra-types/pull/45) by [hirotasoshu](https://github.com/hirotasoshu) * Add `MIR` card brand. PR [#46](https://github.com/pydantic/pydantic-extra-types/pull/46) by [hirotasoshu](https://github.com/hirotasoshu) * Fix dependencies version. PR [#48](https://github.com/pydantic/pydantic-extra-types/pull/48) by [yezz123](https://github.com/yezz123) * Add documentation for `Color` and `PaymentCardNumber`. PR [#50](https://github.com/pydantic/pydantic-extra-types/pull/50) by [Kludex](https://github.com/Kludex) * Add hooky. PR [#51](https://github.com/pydantic/pydantic-extra-types/pull/51) by [Kludex](https://github.com/Kludex) * Simplify project structure. PR [#52](https://github.com/pydantic/pydantic-extra-types/pull/52) by [Kludex](https://github.com/Kludex) * Add coverage check on the pipeline. PR [#53](https://github.com/pydantic/pydantic-extra-types/pull/53) by [Kludex](https://github.com/Kludex) * Refactor country type using `pycountry`. PR [#54](https://github.com/pydantic/pydantic-extra-types/pull/54) by [yezz123](https://github.com/yezz123) * Add 100% coverage. PR [#57](https://github.com/pydantic/pydantic-extra-types/pull/57) by [Kludex](https://github.com/Kludex) * Add support for transparent Color. PR [#59](https://github.com/pydantic/pydantic-extra-types/pull/59) by [CollinHeist](https://github.com/CollinHeist) * Add documentation for `PhoneNumber` and `ABARoutingNumber`. PR [#60](https://github.com/pydantic/pydantic-extra-types/pull/60) by [Kludex](https://github.com/Kludex) * Refactor README. PR [#61](https://github.com/pydantic/pydantic-extra-types/pull/61) by [Kludex](https://github.com/Kludex) * Rename `routing_number.md` to `routing_numbers.md`. PR [#62](https://github.com/pydantic/pydantic-extra-types/pull/62) by [Kludex](https://github.com/Kludex) * Fix code in `payment` documentation. PR [#63](https://github.com/pydantic/pydantic-extra-types/pull/63) by [yezz123](https://github.com/yezz123) * Uprev pydantic to b3. PR [#69](https://github.com/pydantic/pydantic-extra-types/pull/69) by [samuelcolvin](https://github.com/samuelcolvin) * Prepare for release 2.0.0. PR [#70](https://github.com/pydantic/pydantic-extra-types/pull/70) by [hramezani](https://github.com/hramezani) pydantic-extra-types-2.10.5/LICENSE000066400000000000000000000021171501603200400166720ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) 2023 Samuel Colvin and other contributors 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. pydantic-extra-types-2.10.5/Makefile000066400000000000000000000030411501603200400173220ustar00rootroot00000000000000.DEFAULT_GOAL := all sources = pydantic_extra_types tests .PHONY: .uv # Check that uv is installed .uv: @uv --version || echo 'Please install uv: https://docs.astral.sh/uv/getting-started/installation/' .PHONY: install ## Install the package, dependencies, and pre-commit for local development install: .uv uv sync --frozen --all-groups --all-extras uv pip install pre-commit uv run pre-commit install --install-hooks .PHONY: rebuild-lockfiles ## Rebuild lockfiles from scratch, updating all dependencies rebuild-lockfiles: .uv uv lock --upgrade .PHONY: format # Format the code format: uv run ruff format uv run ruff check --fix --fix-only .PHONY: lint # Lint the code lint: uv run ruff format --check uv run ruff check .PHONY: typecheck # Typecheck the code typecheck: uv run mypy pydantic_extra_types .PHONY: test test: uv run pytest .PHONY: test-all-python # Run tests on Python 3.9 to 3.13 test-all-python: UV_PROJECT_ENVIRONMENT=.venv39 uv run --python 3.9 coverage run -p -m pytest UV_PROJECT_ENVIRONMENT=.venv310 uv run --python 3.10 coverage run -p -m pytest UV_PROJECT_ENVIRONMENT=.venv311 uv run --python 3.11 coverage run -p -m pytest UV_PROJECT_ENVIRONMENT=.venv312 uv run --python 3.12 coverage run -p -m pytest UV_PROJECT_ENVIRONMENT=.venv313 uv run --python 3.13 coverage run -p -m pytest @uv run coverage combine @uv run coverage report .PHONY: testcov # Run tests and collect coverage data testcov: uv run coverage run -m pytest @uv run coverage report @uv run coverage html .PHONY: all all: format lint testcov pydantic-extra-types-2.10.5/README.md000066400000000000000000000021541501603200400171450ustar00rootroot00000000000000# Pydantic Extra Types [![CI](https://github.com/pydantic/pydantic-extra-types/workflows/CI/badge.svg?event=push)](https://github.com/pydantic/pydantic-extra-types/actions?query=event%3Apush+branch%3Amain+workflow%3ACI) [![Coverage](https://codecov.io/gh/pydantic/pydantic-extra-types/branch/main/graph/badge.svg)](https://codecov.io/gh/pydantic/pydantic-extra-types) [![pypi](https://img.shields.io/pypi/v/pydantic-extra-types.svg)](https://pypi.python.org/pypi/pydantic-extra-types) [![license](https://img.shields.io/github/license/pydantic/pydantic-extra-types.svg)](https://github.com/pydantic/pydantic-extra-types/blob/main/LICENSE) A place for pydantic types that probably shouldn't exist in the main pydantic lib. See [pydantic/pydantic#5012](https://github.com/pydantic/pydantic/issues/5012) for more info. ## Installation Install this library with the desired extras dependencies as listed in [project.optional-dependencies](./pyproject.toml). For example, if pendulum support was desired: ```shell # via uv $ uv add "pydantic-extra-types[pendulum]" # via pip $ pip install -U "pydantic-extra-types[pendulum]" ``` pydantic-extra-types-2.10.5/pydantic_extra_types/000077500000000000000000000000001501603200400221265ustar00rootroot00000000000000pydantic-extra-types-2.10.5/pydantic_extra_types/__init__.py000066400000000000000000000000271501603200400242360ustar00rootroot00000000000000__version__ = '2.10.5' pydantic-extra-types-2.10.5/pydantic_extra_types/color.py000066400000000000000000000505771501603200400236340ustar00rootroot00000000000000"""Color definitions are used as per the CSS3 [CSS Color Module Level 3](http://www.w3.org/TR/css3-color/#svg-color) specification. A few colors have multiple names referring to the sames colors, eg. `grey` and `gray` or `aqua` and `cyan`. In these cases the _last_ color when sorted alphabetically takes preferences, eg. `Color((0, 255, 255)).as_named() == 'cyan'` because "cyan" comes after "aqua". """ from __future__ import annotations import math import re from colorsys import hls_to_rgb, rgb_to_hls from typing import Any, Callable, Literal, Tuple, Union, cast from pydantic import GetJsonSchemaHandler from pydantic._internal import _repr from pydantic.json_schema import JsonSchemaValue from pydantic_core import CoreSchema, PydanticCustomError, core_schema ColorTuple = Union[Tuple[int, int, int], Tuple[int, int, int, float]] ColorType = Union[ColorTuple, str, 'Color'] HslColorTuple = Union[Tuple[float, float, float], Tuple[float, float, float, float]] class RGBA: """Internal use only as a representation of a color.""" __slots__ = 'r', 'g', 'b', 'alpha', '_tuple' def __init__(self, r: float, g: float, b: float, alpha: float | None): self.r = r self.g = g self.b = b self.alpha = alpha self._tuple: tuple[float, float, float, float | None] = (r, g, b, alpha) def __getitem__(self, item: Any) -> Any: return self._tuple[item] # these are not compiled here to avoid import slowdown, they'll be compiled the first time they're used, then cached _r_255 = r'(\d{1,3}(?:\.\d+)?)' _r_comma = r'\s*,\s*' _r_alpha = r'(\d(?:\.\d+)?|\.\d+|\d{1,2}%)' _r_h = r'(-?\d+(?:\.\d+)?|-?\.\d+)(deg|rad|turn)?' _r_sl = r'(\d{1,3}(?:\.\d+)?)%' r_hex_short = r'\s*(?:#|0x)?([0-9a-f])([0-9a-f])([0-9a-f])([0-9a-f])?\s*' r_hex_long = r'\s*(?:#|0x)?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})?\s*' # CSS3 RGB examples: rgb(0, 0, 0), rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 50%) r_rgb = rf'\s*rgba?\(\s*{_r_255}{_r_comma}{_r_255}{_r_comma}{_r_255}(?:{_r_comma}{_r_alpha})?\s*\)\s*' # CSS3 HSL examples: hsl(270, 60%, 50%), hsla(270, 60%, 50%, 0.5), hsla(270, 60%, 50%, 50%) r_hsl = rf'\s*hsla?\(\s*{_r_h}{_r_comma}{_r_sl}{_r_comma}{_r_sl}(?:{_r_comma}{_r_alpha})?\s*\)\s*' # CSS4 RGB examples: rgb(0 0 0), rgb(0 0 0 / 0.5), rgb(0 0 0 / 50%), rgba(0 0 0 / 50%) r_rgb_v4_style = rf'\s*rgba?\(\s*{_r_255}\s+{_r_255}\s+{_r_255}(?:\s*/\s*{_r_alpha})?\s*\)\s*' # CSS4 HSL examples: hsl(270 60% 50%), hsl(270 60% 50% / 0.5), hsl(270 60% 50% / 50%), hsla(270 60% 50% / 50%) r_hsl_v4_style = rf'\s*hsla?\(\s*{_r_h}\s+{_r_sl}\s+{_r_sl}(?:\s*/\s*{_r_alpha})?\s*\)\s*' # colors where the two hex characters are the same, if all colors match this the short version of hex colors can be used repeat_colors = {int(c * 2, 16) for c in '0123456789abcdef'} rads = 2 * math.pi class Color(_repr.Representation): """Represents a color.""" __slots__ = '_original', '_rgba' def __init__(self, value: ColorType) -> None: self._rgba: RGBA self._original: ColorType if isinstance(value, (tuple, list)): self._rgba = parse_tuple(value) elif isinstance(value, str): self._rgba = parse_str(value) elif isinstance(value, Color): self._rgba = value._rgba value = value._original else: raise PydanticCustomError( 'color_error', 'value is not a valid color: value must be a tuple, list or string', ) # if we've got here value must be a valid color self._original = value @classmethod def __get_pydantic_json_schema__( cls, core_schema: core_schema.CoreSchema, handler: GetJsonSchemaHandler ) -> JsonSchemaValue: field_schema: dict[str, Any] = {} field_schema.update(type='string', format='color') return field_schema def original(self) -> ColorType: """Original value passed to `Color`.""" return self._original def as_named(self, *, fallback: bool = False) -> str: """Returns the name of the color if it can be found in `COLORS_BY_VALUE` dictionary, otherwise returns the hexadecimal representation of the color or raises `ValueError`. Args: fallback: If True, falls back to returning the hexadecimal representation of the color instead of raising a ValueError when no named color is found. Returns: The name of the color, or the hexadecimal representation of the color. Raises: ValueError: When no named color is found and fallback is `False`. """ if self._rgba.alpha is not None: return self.as_hex() rgb = cast('tuple[int, int, int]', self.as_rgb_tuple()) if rgb in COLORS_BY_VALUE: return COLORS_BY_VALUE[rgb] else: if fallback: return self.as_hex() else: raise ValueError('no named color found, use fallback=True, as_hex() or as_rgb()') def as_hex(self, format: Literal['short', 'long'] = 'short') -> str: """Returns the hexadecimal representation of the color. Hex string representing the color can be 3, 4, 6, or 8 characters depending on whether the string a "short" representation of the color is possible and whether there's an alpha channel. Returns: The hexadecimal representation of the color. """ values = [float_to_255(c) for c in self._rgba[:3]] if self._rgba.alpha is not None: values.append(float_to_255(self._rgba.alpha)) as_hex = ''.join(f'{v:02x}' for v in values) if format == 'short' and all(c in repeat_colors for c in values): as_hex = ''.join(as_hex[c] for c in range(0, len(as_hex), 2)) return f'#{as_hex}' def as_rgb(self) -> str: """Color as an `rgb(, , )` or `rgba(, , , )` string.""" if self._rgba.alpha is None: return f'rgb({float_to_255(self._rgba.r)}, {float_to_255(self._rgba.g)}, {float_to_255(self._rgba.b)})' else: return ( f'rgba({float_to_255(self._rgba.r)}, {float_to_255(self._rgba.g)}, {float_to_255(self._rgba.b)}, ' f'{round(self._alpha_float(), 2)})' ) def as_rgb_tuple(self, *, alpha: bool | None = None) -> ColorTuple: """Returns the color as an RGB or RGBA tuple. Args: alpha: Whether to include the alpha channel. There are three options for this input: - `None` (default): Include alpha only if it's set. (e.g. not `None`) - `True`: Always include alpha. - `False`: Always omit alpha. Returns: A tuple that contains the values of the red, green, and blue channels in the range 0 to 255. If alpha is included, it is in the range 0 to 1. """ r, g, b = (float_to_255(c) for c in self._rgba[:3]) if alpha is None and self._rgba.alpha is None or alpha is not None and not alpha: return r, g, b else: return r, g, b, self._alpha_float() def as_hsl(self) -> str: """Color as an `hsl(, , )` or `hsl(, , , )` string.""" if self._rgba.alpha is None: h, s, li = self.as_hsl_tuple(alpha=False) # type: ignore return f'hsl({h * 360:0.0f}, {s:0.0%}, {li:0.0%})' else: h, s, li, a = self.as_hsl_tuple(alpha=True) # type: ignore return f'hsl({h * 360:0.0f}, {s:0.0%}, {li:0.0%}, {round(a, 2)})' def as_hsl_tuple(self, *, alpha: bool | None = None) -> HslColorTuple: """Returns the color as an HSL or HSLA tuple. Args: alpha: Whether to include the alpha channel. - `None` (default): Include the alpha channel only if it's set (e.g. not `None`). - `True`: Always include alpha. - `False`: Always omit alpha. Returns: The color as a tuple of hue, saturation, lightness, and alpha (if included). All elements are in the range 0 to 1. Note: This is HSL as used in HTML and most other places, not HLS as used in Python's `colorsys`. """ h, l, s = rgb_to_hls(self._rgba.r, self._rgba.g, self._rgba.b) if alpha is None: if self._rgba.alpha is None: return h, s, l else: return h, s, l, self._alpha_float() return (h, s, l, self._alpha_float()) if alpha else (h, s, l) def _alpha_float(self) -> float: return 1 if self._rgba.alpha is None else self._rgba.alpha @classmethod def __get_pydantic_core_schema__( cls, source: type[Any], handler: Callable[[Any], CoreSchema] ) -> core_schema.CoreSchema: return core_schema.with_info_plain_validator_function( cls._validate, serialization=core_schema.to_string_ser_schema() ) @classmethod def _validate(cls, __input_value: Any, _: Any) -> Color: return cls(__input_value) def __str__(self) -> str: return self.as_named(fallback=True) def __repr_args__(self) -> _repr.ReprArgs: return [(None, self.as_named(fallback=True))] + [('rgb', self.as_rgb_tuple())] def __eq__(self, other: Any) -> bool: return isinstance(other, Color) and self.as_rgb_tuple() == other.as_rgb_tuple() def __hash__(self) -> int: return hash(self.as_rgb_tuple()) def parse_tuple(value: tuple[Any, ...]) -> RGBA: """Parse a tuple or list to get RGBA values. Args: value: A tuple or list. Returns: An `RGBA` tuple parsed from the input tuple. Raises: PydanticCustomError: If tuple is not valid. """ if len(value) == 3: r, g, b = (parse_color_value(v) for v in value) return RGBA(r, g, b, None) elif len(value) == 4: r, g, b = (parse_color_value(v) for v in value[:3]) return RGBA(r, g, b, parse_float_alpha(value[3])) else: raise PydanticCustomError('color_error', 'value is not a valid color: tuples must have length 3 or 4') def parse_str(value: str) -> RGBA: """Parse a string representing a color to an RGBA tuple. Possible formats for the input string include: * named color, see `COLORS_BY_NAME` * hex short eg. `fff` (prefix can be `#`, `0x` or nothing) * hex long eg. `ffffff` (prefix can be `#`, `0x` or nothing) * `rgb(, , )` * `rgba(, , , )` * `transparent` Args: value: A string representing a color. Returns: An `RGBA` tuple parsed from the input string. Raises: ValueError: If the input string cannot be parsed to an RGBA tuple. """ value_lower = value.lower() if value_lower in COLORS_BY_NAME: r, g, b = COLORS_BY_NAME[value_lower] return ints_to_rgba(r, g, b, None) m = re.fullmatch(r_hex_short, value_lower) if m: *rgb, a = m.groups() r, g, b = (int(v * 2, 16) for v in rgb) alpha = int(a * 2, 16) / 255 if a else None return ints_to_rgba(r, g, b, alpha) m = re.fullmatch(r_hex_long, value_lower) if m: *rgb, a = m.groups() r, g, b = (int(v, 16) for v in rgb) alpha = int(a, 16) / 255 if a else None return ints_to_rgba(r, g, b, alpha) m = re.fullmatch(r_rgb, value_lower) or re.fullmatch(r_rgb_v4_style, value_lower) if m: return ints_to_rgba(*m.groups()) # type: ignore m = re.fullmatch(r_hsl, value_lower) or re.fullmatch(r_hsl_v4_style, value_lower) if m: return parse_hsl(*m.groups()) # type: ignore if value_lower == 'transparent': return RGBA(0, 0, 0, 0) raise PydanticCustomError( 'color_error', 'value is not a valid color: string not recognised as a valid color', ) def ints_to_rgba( r: int | str, g: int | str, b: int | str, alpha: float | None = None, ) -> RGBA: """Converts integer or string values for RGB color and an optional alpha value to an `RGBA` object. Args: r: An integer or string representing the red color value. g: An integer or string representing the green color value. b: An integer or string representing the blue color value. alpha: A float representing the alpha value. Defaults to None. Returns: An instance of the `RGBA` class with the corresponding color and alpha values. """ return RGBA( parse_color_value(r), parse_color_value(g), parse_color_value(b), parse_float_alpha(alpha), ) def parse_color_value(value: int | str, max_val: int = 255) -> float: """Parse the color value provided and return a number between 0 and 1. Args: value: An integer or string color value. max_val: Maximum range value. Defaults to 255. Raises: PydanticCustomError: If the value is not a valid color. Returns: A number between 0 and 1. """ try: color = float(value) except (ValueError, TypeError) as e: raise PydanticCustomError( 'color_error', 'value is not a valid color: color values must be a valid number', ) from e if 0 <= color <= max_val: return color / max_val else: raise PydanticCustomError( 'color_error', 'value is not a valid color: color values must be in the range 0 to {max_val}', {'max_val': max_val}, ) def parse_float_alpha(value: None | str | float | int) -> float | None: """Parse an alpha value checking it's a valid float in the range 0 to 1. Args: value: The input value to parse. Returns: The parsed value as a float, or `None` if the value was None or equal 1. Raises: PydanticCustomError: If the input value cannot be successfully parsed as a float in the expected range. """ if value is None: return None try: if isinstance(value, str) and value.endswith('%'): alpha = float(value[:-1]) / 100 else: alpha = float(value) except ValueError as e: raise PydanticCustomError( 'color_error', 'value is not a valid color: alpha values must be a valid float', ) from e if math.isclose(alpha, 1): return None elif 0 <= alpha <= 1: return alpha else: raise PydanticCustomError( 'color_error', 'value is not a valid color: alpha values must be in the range 0 to 1', ) def parse_hsl(h: str, h_units: str, sat: str, light: str, alpha: float | None = None) -> RGBA: """Parse raw hue, saturation, lightness, and alpha values and convert to RGBA. Args: h: The hue value. h_units: The unit for hue value. sat: The saturation value. light: The lightness value. alpha: Alpha value. Returns: An instance of `RGBA`. """ s_value, l_value = parse_color_value(sat, 100), parse_color_value(light, 100) h_value = float(h) if h_units in {None, 'deg'}: h_value = h_value % 360 / 360 elif h_units == 'rad': h_value = h_value % rads / rads else: # turns h_value %= 1 r, g, b = hls_to_rgb(h_value, l_value, s_value) return RGBA(r, g, b, parse_float_alpha(alpha)) def float_to_255(c: float) -> int: """Converts a float value between 0 and 1 (inclusive) to an integer between 0 and 255 (inclusive). Args: c: The float value to be converted. Must be between 0 and 1 (inclusive). Returns: The integer equivalent of the given float value rounded to the nearest whole number. """ return round(c * 255) COLORS_BY_NAME = { 'aliceblue': (240, 248, 255), 'antiquewhite': (250, 235, 215), 'aqua': (0, 255, 255), 'aquamarine': (127, 255, 212), 'azure': (240, 255, 255), 'beige': (245, 245, 220), 'bisque': (255, 228, 196), 'black': (0, 0, 0), 'blanchedalmond': (255, 235, 205), 'blue': (0, 0, 255), 'blueviolet': (138, 43, 226), 'brown': (165, 42, 42), 'burlywood': (222, 184, 135), 'cadetblue': (95, 158, 160), 'chartreuse': (127, 255, 0), 'chocolate': (210, 105, 30), 'coral': (255, 127, 80), 'cornflowerblue': (100, 149, 237), 'cornsilk': (255, 248, 220), 'crimson': (220, 20, 60), 'cyan': (0, 255, 255), 'darkblue': (0, 0, 139), 'darkcyan': (0, 139, 139), 'darkgoldenrod': (184, 134, 11), 'darkgray': (169, 169, 169), 'darkgreen': (0, 100, 0), 'darkgrey': (169, 169, 169), 'darkkhaki': (189, 183, 107), 'darkmagenta': (139, 0, 139), 'darkolivegreen': (85, 107, 47), 'darkorange': (255, 140, 0), 'darkorchid': (153, 50, 204), 'darkred': (139, 0, 0), 'darksalmon': (233, 150, 122), 'darkseagreen': (143, 188, 143), 'darkslateblue': (72, 61, 139), 'darkslategray': (47, 79, 79), 'darkslategrey': (47, 79, 79), 'darkturquoise': (0, 206, 209), 'darkviolet': (148, 0, 211), 'deeppink': (255, 20, 147), 'deepskyblue': (0, 191, 255), 'dimgray': (105, 105, 105), 'dimgrey': (105, 105, 105), 'dodgerblue': (30, 144, 255), 'firebrick': (178, 34, 34), 'floralwhite': (255, 250, 240), 'forestgreen': (34, 139, 34), 'fuchsia': (255, 0, 255), 'gainsboro': (220, 220, 220), 'ghostwhite': (248, 248, 255), 'gold': (255, 215, 0), 'goldenrod': (218, 165, 32), 'gray': (128, 128, 128), 'green': (0, 128, 0), 'greenyellow': (173, 255, 47), 'grey': (128, 128, 128), 'honeydew': (240, 255, 240), 'hotpink': (255, 105, 180), 'indianred': (205, 92, 92), 'indigo': (75, 0, 130), 'ivory': (255, 255, 240), 'khaki': (240, 230, 140), 'lavender': (230, 230, 250), 'lavenderblush': (255, 240, 245), 'lawngreen': (124, 252, 0), 'lemonchiffon': (255, 250, 205), 'lightblue': (173, 216, 230), 'lightcoral': (240, 128, 128), 'lightcyan': (224, 255, 255), 'lightgoldenrodyellow': (250, 250, 210), 'lightgray': (211, 211, 211), 'lightgreen': (144, 238, 144), 'lightgrey': (211, 211, 211), 'lightpink': (255, 182, 193), 'lightsalmon': (255, 160, 122), 'lightseagreen': (32, 178, 170), 'lightskyblue': (135, 206, 250), 'lightslategray': (119, 136, 153), 'lightslategrey': (119, 136, 153), 'lightsteelblue': (176, 196, 222), 'lightyellow': (255, 255, 224), 'lime': (0, 255, 0), 'limegreen': (50, 205, 50), 'linen': (250, 240, 230), 'magenta': (255, 0, 255), 'maroon': (128, 0, 0), 'mediumaquamarine': (102, 205, 170), 'mediumblue': (0, 0, 205), 'mediumorchid': (186, 85, 211), 'mediumpurple': (147, 112, 219), 'mediumseagreen': (60, 179, 113), 'mediumslateblue': (123, 104, 238), 'mediumspringgreen': (0, 250, 154), 'mediumturquoise': (72, 209, 204), 'mediumvioletred': (199, 21, 133), 'midnightblue': (25, 25, 112), 'mintcream': (245, 255, 250), 'mistyrose': (255, 228, 225), 'moccasin': (255, 228, 181), 'navajowhite': (255, 222, 173), 'navy': (0, 0, 128), 'oldlace': (253, 245, 230), 'olive': (128, 128, 0), 'olivedrab': (107, 142, 35), 'orange': (255, 165, 0), 'orangered': (255, 69, 0), 'orchid': (218, 112, 214), 'palegoldenrod': (238, 232, 170), 'palegreen': (152, 251, 152), 'paleturquoise': (175, 238, 238), 'palevioletred': (219, 112, 147), 'papayawhip': (255, 239, 213), 'peachpuff': (255, 218, 185), 'peru': (205, 133, 63), 'pink': (255, 192, 203), 'plum': (221, 160, 221), 'powderblue': (176, 224, 230), 'purple': (128, 0, 128), 'red': (255, 0, 0), 'rosybrown': (188, 143, 143), 'royalblue': (65, 105, 225), 'saddlebrown': (139, 69, 19), 'salmon': (250, 128, 114), 'sandybrown': (244, 164, 96), 'seagreen': (46, 139, 87), 'seashell': (255, 245, 238), 'sienna': (160, 82, 45), 'silver': (192, 192, 192), 'skyblue': (135, 206, 235), 'slateblue': (106, 90, 205), 'slategray': (112, 128, 144), 'slategrey': (112, 128, 144), 'snow': (255, 250, 250), 'springgreen': (0, 255, 127), 'steelblue': (70, 130, 180), 'tan': (210, 180, 140), 'teal': (0, 128, 128), 'thistle': (216, 191, 216), 'tomato': (255, 99, 71), 'turquoise': (64, 224, 208), 'violet': (238, 130, 238), 'wheat': (245, 222, 179), 'white': (255, 255, 255), 'whitesmoke': (245, 245, 245), 'yellow': (255, 255, 0), 'yellowgreen': (154, 205, 50), } COLORS_BY_VALUE = {v: k for k, v in COLORS_BY_NAME.items()} pydantic-extra-types-2.10.5/pydantic_extra_types/coordinate.py000066400000000000000000000133271501603200400246350ustar00rootroot00000000000000"""The `pydantic_extra_types.coordinate` module provides the [`Latitude`][pydantic_extra_types.coordinate.Latitude], [`Longitude`][pydantic_extra_types.coordinate.Longitude], and [`Coordinate`][pydantic_extra_types.coordinate.Coordinate] data types. """ from __future__ import annotations from dataclasses import dataclass from decimal import Decimal from typing import Any, ClassVar, Tuple, Union from pydantic import GetCoreSchemaHandler from pydantic._internal import _repr from pydantic_core import ArgsKwargs, PydanticCustomError, core_schema LatitudeType = Union[float, Decimal] LongitudeType = Union[float, Decimal] CoordinateType = Tuple[LatitudeType, LongitudeType] class Latitude(float): """Latitude value should be between -90 and 90, inclusive. Supports both float and Decimal types. ```py from decimal import Decimal from pydantic import BaseModel from pydantic_extra_types.coordinate import Latitude class Location(BaseModel): latitude: Latitude # Using float location1 = Location(latitude=41.40338) # Using Decimal location2 = Location(latitude=Decimal('41.40338')) ``` """ min: ClassVar[float] = -90.00 max: ClassVar[float] = 90.00 @classmethod def __get_pydantic_core_schema__(cls, source: type[Any], handler: GetCoreSchemaHandler) -> core_schema.CoreSchema: return core_schema.union_schema( [ core_schema.float_schema(ge=cls.min, le=cls.max), core_schema.decimal_schema(ge=Decimal(cls.min), le=Decimal(cls.max)), ] ) class Longitude(float): """Longitude value should be between -180 and 180, inclusive. Supports both float and Decimal types. ```py from decimal import Decimal from pydantic import BaseModel from pydantic_extra_types.coordinate import Longitude class Location(BaseModel): longitude: Longitude # Using float location1 = Location(longitude=2.17403) # Using Decimal location2 = Location(longitude=Decimal('2.17403')) ``` """ min: ClassVar[float] = -180.00 max: ClassVar[float] = 180.00 @classmethod def __get_pydantic_core_schema__(cls, source: type[Any], handler: GetCoreSchemaHandler) -> core_schema.CoreSchema: return core_schema.union_schema( [ core_schema.float_schema(ge=cls.min, le=cls.max), core_schema.decimal_schema(ge=Decimal(cls.min), le=Decimal(cls.max)), ] ) @dataclass class Coordinate(_repr.Representation): """Coordinate parses Latitude and Longitude. You can use the `Coordinate` data type for storing coordinates. Coordinates can be defined using one of the following formats: 1. Tuple: `(Latitude, Longitude)`. For example: `(41.40338, 2.17403)` or `(Decimal('41.40338'), Decimal('2.17403'))`. 2. `Coordinate` instance: `Coordinate(latitude=Latitude, longitude=Longitude)`. ```py from decimal import Decimal from pydantic import BaseModel from pydantic_extra_types.coordinate import Coordinate class Location(BaseModel): coordinate: Coordinate # Using float values location1 = Location(coordinate=(41.40338, 2.17403)) # > coordinate=Coordinate(latitude=41.40338, longitude=2.17403) # Using Decimal values location2 = Location(coordinate=(Decimal('41.40338'), Decimal('2.17403'))) # > coordinate=Coordinate(latitude=41.40338, longitude=2.17403) ``` """ _NULL_ISLAND: ClassVar[Tuple[float, float]] = (0.0, 0.0) latitude: Latitude longitude: Longitude @classmethod def __get_pydantic_core_schema__(cls, source: type[Any], handler: GetCoreSchemaHandler) -> core_schema.CoreSchema: schema_chain = [ core_schema.no_info_wrap_validator_function(cls._parse_str, core_schema.str_schema()), core_schema.no_info_wrap_validator_function( cls._parse_tuple, handler.generate_schema(CoordinateType), ), handler(source), ] chain_length = len(schema_chain) chain_schemas = [core_schema.chain_schema(schema_chain[x:]) for x in range(chain_length - 1, -1, -1)] return core_schema.no_info_wrap_validator_function( cls._parse_args, core_schema.union_schema(chain_schemas), # type: ignore[arg-type] ) @classmethod def _parse_args(cls, value: Any, handler: core_schema.ValidatorFunctionWrapHandler) -> Any: if isinstance(value, ArgsKwargs) and not value.kwargs: n_args = len(value.args) if n_args == 0: value = cls._NULL_ISLAND elif n_args == 1: value = value.args[0] return handler(value) @classmethod def _parse_str(cls, value: Any, handler: core_schema.ValidatorFunctionWrapHandler) -> Any: if not isinstance(value, str): return value try: value = tuple(float(x) for x in value.split(',')) except ValueError as e: raise PydanticCustomError( 'coordinate_error', 'value is not a valid coordinate: string is not recognized as a valid coordinate', ) from e return ArgsKwargs(args=value) @classmethod def _parse_tuple(cls, value: Any, handler: core_schema.ValidatorFunctionWrapHandler) -> Any: return ArgsKwargs(args=handler(value)) if isinstance(value, tuple) else value def __str__(self) -> str: return f'{self.latitude},{self.longitude}' def __eq__(self, other: Any) -> bool: return isinstance(other, Coordinate) and self.latitude == other.latitude and self.longitude == other.longitude def __hash__(self) -> int: return hash((self.latitude, self.longitude)) pydantic-extra-types-2.10.5/pydantic_extra_types/country.py000066400000000000000000000214631501603200400242110ustar00rootroot00000000000000"""Country definitions that are based on the [ISO 3166](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes).""" from __future__ import annotations from dataclasses import dataclass from functools import lru_cache from typing import Any from pydantic import GetCoreSchemaHandler, GetJsonSchemaHandler from pydantic_core import PydanticCustomError, core_schema try: import pycountry except ModuleNotFoundError as e: # pragma: no cover raise RuntimeError( 'The `country` module requires "pycountry" to be installed. You can install it with "pip install pycountry".' ) from e @dataclass class CountryInfo: alpha2: str alpha3: str numeric_code: str short_name: str @lru_cache def _countries() -> list[CountryInfo]: return [ CountryInfo( alpha2=country.alpha_2, alpha3=country.alpha_3, numeric_code=country.numeric, short_name=country.name, ) for country in pycountry.countries ] @lru_cache def _index_by_alpha2() -> dict[str, CountryInfo]: return {country.alpha2: country for country in _countries()} @lru_cache def _index_by_alpha3() -> dict[str, CountryInfo]: return {country.alpha3: country for country in _countries()} @lru_cache def _index_by_numeric_code() -> dict[str, CountryInfo]: return {country.numeric_code: country for country in _countries()} @lru_cache def _index_by_short_name() -> dict[str, CountryInfo]: return {country.short_name: country for country in _countries()} class CountryAlpha2(str): """CountryAlpha2 parses country codes in the [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format. ```py from pydantic import BaseModel from pydantic_extra_types.country import CountryAlpha2 class Product(BaseModel): made_in: CountryAlpha2 product = Product(made_in='ES') print(product) # > made_in='ES' ``` """ @classmethod def _validate(cls, __input_value: str, _: core_schema.ValidationInfo) -> CountryAlpha2: if __input_value not in _index_by_alpha2(): raise PydanticCustomError('country_alpha2', 'Invalid country alpha2 code') return cls(__input_value) @classmethod def __get_pydantic_core_schema__( cls, source: type[Any], handler: GetCoreSchemaHandler ) -> core_schema.AfterValidatorFunctionSchema: return core_schema.with_info_after_validator_function( cls._validate, core_schema.str_schema(to_upper=True), ) @classmethod def __get_pydantic_json_schema__( cls, schema: core_schema.CoreSchema, handler: GetJsonSchemaHandler ) -> dict[str, Any]: json_schema = handler(schema) json_schema.update({'pattern': r'^\w{2}$'}) return json_schema @property def alpha3(self) -> str: """The country code in the [ISO 3166-1 alpha-3](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3) format.""" return _index_by_alpha2()[self].alpha3 @property def numeric_code(self) -> str: """The country code in the [ISO 3166-1 numeric](https://en.wikipedia.org/wiki/ISO_3166-1_numeric) format.""" return _index_by_alpha2()[self].numeric_code @property def short_name(self) -> str: """The country short name.""" return _index_by_alpha2()[self].short_name class CountryAlpha3(str): """CountryAlpha3 parses country codes in the [ISO 3166-1 alpha-3](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3) format. ```py from pydantic import BaseModel from pydantic_extra_types.country import CountryAlpha3 class Product(BaseModel): made_in: CountryAlpha3 product = Product(made_in='USA') print(product) # > made_in='USA' ``` """ @classmethod def _validate(cls, __input_value: str, _: core_schema.ValidationInfo) -> CountryAlpha3: if __input_value not in _index_by_alpha3(): raise PydanticCustomError('country_alpha3', 'Invalid country alpha3 code') return cls(__input_value) @classmethod def __get_pydantic_core_schema__( cls, source: type[Any], handler: GetCoreSchemaHandler ) -> core_schema.AfterValidatorFunctionSchema: return core_schema.with_info_after_validator_function( cls._validate, core_schema.str_schema(to_upper=True), serialization=core_schema.to_string_ser_schema(), ) @classmethod def __get_pydantic_json_schema__( cls, schema: core_schema.CoreSchema, handler: GetJsonSchemaHandler ) -> dict[str, Any]: json_schema = handler(schema) json_schema.update({'pattern': r'^\w{3}$'}) return json_schema @property def alpha2(self) -> str: """The country code in the [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format.""" return _index_by_alpha3()[self].alpha2 @property def numeric_code(self) -> str: """The country code in the [ISO 3166-1 numeric](https://en.wikipedia.org/wiki/ISO_3166-1_numeric) format.""" return _index_by_alpha3()[self].numeric_code @property def short_name(self) -> str: """The country short name.""" return _index_by_alpha3()[self].short_name class CountryNumericCode(str): """CountryNumericCode parses country codes in the [ISO 3166-1 numeric](https://en.wikipedia.org/wiki/ISO_3166-1_numeric) format. ```py from pydantic import BaseModel from pydantic_extra_types.country import CountryNumericCode class Product(BaseModel): made_in: CountryNumericCode product = Product(made_in='840') print(product) # > made_in='840' ``` """ @classmethod def _validate(cls, __input_value: str, _: core_schema.ValidationInfo) -> CountryNumericCode: if __input_value not in _index_by_numeric_code(): raise PydanticCustomError('country_numeric_code', 'Invalid country numeric code') return cls(__input_value) @classmethod def __get_pydantic_core_schema__( cls, source: type[Any], handler: GetCoreSchemaHandler ) -> core_schema.AfterValidatorFunctionSchema: return core_schema.with_info_after_validator_function( cls._validate, core_schema.str_schema(to_upper=True), serialization=core_schema.to_string_ser_schema(), ) @classmethod def __get_pydantic_json_schema__( cls, schema: core_schema.CoreSchema, handler: GetJsonSchemaHandler ) -> dict[str, Any]: json_schema = handler(schema) json_schema.update({'pattern': r'^[0-9]{3}$'}) return json_schema @property def alpha2(self) -> str: """The country code in the [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format.""" return _index_by_numeric_code()[self].alpha2 @property def alpha3(self) -> str: """The country code in the [ISO 3166-1 alpha-3](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3) format.""" return _index_by_numeric_code()[self].alpha3 @property def short_name(self) -> str: """The country short name.""" return _index_by_numeric_code()[self].short_name class CountryShortName(str): """CountryShortName parses country codes in the short name format. ```py from pydantic import BaseModel from pydantic_extra_types.country import CountryShortName class Product(BaseModel): made_in: CountryShortName product = Product(made_in='United States') print(product) # > made_in='United States' ``` """ @classmethod def _validate(cls, __input_value: str, _: core_schema.ValidationInfo) -> CountryShortName: if __input_value not in _index_by_short_name(): raise PydanticCustomError('country_short_name', 'Invalid country short name') return cls(__input_value) @classmethod def __get_pydantic_core_schema__( cls, source: type[Any], handler: GetCoreSchemaHandler ) -> core_schema.AfterValidatorFunctionSchema: return core_schema.with_info_after_validator_function( cls._validate, core_schema.str_schema(), serialization=core_schema.to_string_ser_schema(), ) @property def alpha2(self) -> str: """The country code in the [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format.""" return _index_by_short_name()[self].alpha2 @property def alpha3(self) -> str: """The country code in the [ISO 3166-1 alpha-3](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3) format.""" return _index_by_short_name()[self].alpha3 @property def numeric_code(self) -> str: """The country code in the [ISO 3166-1 numeric](https://en.wikipedia.org/wiki/ISO_3166-1_numeric) format.""" return _index_by_short_name()[self].numeric_code pydantic-extra-types-2.10.5/pydantic_extra_types/currency_code.py000066400000000000000000000141121501603200400253230ustar00rootroot00000000000000"""Currency definitions that are based on the [ISO4217](https://en.wikipedia.org/wiki/ISO_4217).""" from __future__ import annotations from typing import Any from pydantic import GetCoreSchemaHandler, GetJsonSchemaHandler from pydantic_core import PydanticCustomError, core_schema try: import pycountry except ModuleNotFoundError as e: # pragma: no cover raise RuntimeError( 'The `currency_code` module requires "pycountry" to be installed. You can install it with "pip install ' 'pycountry".' ) from e # List of codes that should not be usually used within regular transactions _CODES_FOR_BONDS_METAL_TESTING = { 'XTS', # testing 'XAU', # gold 'XAG', # silver 'XPD', # palladium 'XPT', # platinum 'XBA', # Bond Markets Unit European Composite Unit (EURCO) 'XBB', # Bond Markets Unit European Monetary Unit (E.M.U.-6) 'XBC', # Bond Markets Unit European Unit of Account 9 (E.U.A.-9) 'XBD', # Bond Markets Unit European Unit of Account 17 (E.U.A.-17) 'XXX', # no currency 'XDR', # SDR (Special Drawing Right) } class ISO4217(str): """ISO4217 parses Currency in the [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) format. ```py from pydantic import BaseModel from pydantic_extra_types.currency_code import ISO4217 class Currency(BaseModel): alpha_3: ISO4217 currency = Currency(alpha_3='AED') print(currency) # > alpha_3='AED' ``` """ allowed_countries_list = [country.alpha_3 for country in pycountry.currencies] allowed_currencies = set(allowed_countries_list) @classmethod def _validate(cls, currency_code: str, _: core_schema.ValidationInfo) -> str: """Validate a ISO 4217 language code from the provided str value. Args: currency_code: The str value to be validated. _: The Pydantic ValidationInfo. Returns: The validated ISO 4217 currency code. Raises: PydanticCustomError: If the ISO 4217 currency code is not valid. """ currency_code = currency_code.upper() if currency_code not in cls.allowed_currencies: raise PydanticCustomError( 'ISO4217', 'Invalid ISO 4217 currency code. See https://en.wikipedia.org/wiki/ISO_4217' ) return currency_code @classmethod def __get_pydantic_core_schema__(cls, _: type[Any], __: GetCoreSchemaHandler) -> core_schema.CoreSchema: return core_schema.with_info_after_validator_function( cls._validate, core_schema.str_schema(min_length=3, max_length=3), ) @classmethod def __get_pydantic_json_schema__( cls, schema: core_schema.CoreSchema, handler: GetJsonSchemaHandler ) -> dict[str, Any]: json_schema = handler(schema) json_schema.update({'enum': cls.allowed_countries_list}) return json_schema class Currency(str): """Currency parses currency subset of the [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) format. It excludes bonds testing codes and precious metals. ```py from pydantic import BaseModel from pydantic_extra_types.currency_code import Currency class currency(BaseModel): alpha_3: Currency cur = currency(alpha_3='AED') print(cur) # > alpha_3='AED' ``` """ allowed_countries_list = list( filter(lambda x: x not in _CODES_FOR_BONDS_METAL_TESTING, ISO4217.allowed_countries_list) ) allowed_currencies = set(allowed_countries_list) @classmethod def _validate(cls, currency_symbol: str, _: core_schema.ValidationInfo) -> str: """Validate a subset of the [ISO4217](https://en.wikipedia.org/wiki/ISO_4217) format. It excludes bonds testing codes and precious metals. Args: currency_symbol: The str value to be validated. _: The Pydantic ValidationInfo. Returns: The validated ISO 4217 currency code. Raises: PydanticCustomError: If the ISO 4217 currency code is not valid or is bond, precious metal or testing code. """ currency_symbol = currency_symbol.upper() if currency_symbol not in cls.allowed_currencies: raise PydanticCustomError( 'InvalidCurrency', 'Invalid currency code.' ' See https://en.wikipedia.org/wiki/ISO_4217 . ' 'Bonds, testing and precious metals codes are not allowed.', ) return currency_symbol @classmethod def __get_pydantic_core_schema__(cls, _: type[Any], __: GetCoreSchemaHandler) -> core_schema.CoreSchema: """Return a Pydantic CoreSchema with the currency subset of the [ISO4217](https://en.wikipedia.org/wiki/ISO_4217) format. It excludes bonds testing codes and precious metals. Args: _: The source type. __: The handler to get the CoreSchema. Returns: A Pydantic CoreSchema with the subset of the currency subset of the [ISO4217](https://en.wikipedia.org/wiki/ISO_4217) format. It excludes bonds testing codes and precious metals. """ return core_schema.with_info_after_validator_function( cls._validate, core_schema.str_schema(min_length=3, max_length=3), ) @classmethod def __get_pydantic_json_schema__( cls, schema: core_schema.CoreSchema, handler: GetJsonSchemaHandler ) -> dict[str, Any]: """Return a Pydantic JSON Schema with subset of the [ISO4217](https://en.wikipedia.org/wiki/ISO_4217) format. Excluding bonds testing codes and precious metals. Args: schema: The Pydantic CoreSchema. handler: The handler to get the JSON Schema. Returns: A Pydantic JSON Schema with the subset of the ISO4217 currency code validation. without bonds testing codes and precious metals. """ json_schema = handler(schema) json_schema.update({'enum': cls.allowed_countries_list}) return json_schema pydantic-extra-types-2.10.5/pydantic_extra_types/domain.py000066400000000000000000000036121501603200400237510ustar00rootroot00000000000000"""The `domain_str` module provides the `DomainStr` data type. This class depends on the `pydantic` package and implements custom validation for domain string format. """ from __future__ import annotations import re from typing import Any from pydantic import GetCoreSchemaHandler from pydantic_core import PydanticCustomError, core_schema class DomainStr(str): """A string subclass with custom validation for domain string format.""" _domain_re_pattern = r'(?=^.{1,253}$)(^((?!-)[a-zA-Z0-9-]{1,63}(? str: """Validate a domain name from the provided value. Args: __input_value: The value to be validated. _: The source type to be converted. Returns: str: The parsed domain name. """ return cls._validate(__input_value) @classmethod def _validate(cls, v: Any) -> DomainStr: if not isinstance(v, str): raise PydanticCustomError('domain_type', 'Value must be a string') v = v.strip().lower() if len(v) < 1 or len(v) > 253: raise PydanticCustomError('domain_length', 'Domain must be between 1 and 253 characters') if not re.match(cls._domain_re_pattern, v): raise PydanticCustomError('domain_format', 'Invalid domain format') return cls(v) @classmethod def __get_pydantic_core_schema__(cls, source_type: Any, handler: GetCoreSchemaHandler) -> core_schema.CoreSchema: return core_schema.with_info_before_validator_function( cls.validate, core_schema.str_schema(), ) @classmethod def __get_pydantic_json_schema__( cls, schema: core_schema.CoreSchema, handler: GetCoreSchemaHandler ) -> dict[str, Any]: # Cast the return value to dict[str, Any] return dict(handler(schema)) pydantic-extra-types-2.10.5/pydantic_extra_types/epoch.py000066400000000000000000000052261501603200400236030ustar00rootroot00000000000000from __future__ import annotations import datetime from typing import Any, Callable import pydantic_core.core_schema from pydantic import GetJsonSchemaHandler from pydantic.json_schema import JsonSchemaValue from pydantic_core import CoreSchema, core_schema EPOCH = datetime.datetime(1970, 1, 1, tzinfo=datetime.timezone.utc) class _Base(datetime.datetime): TYPE: str = '' SCHEMA: pydantic_core.core_schema.CoreSchema @classmethod def __get_pydantic_json_schema__( cls, core_schema: core_schema.CoreSchema, handler: GetJsonSchemaHandler ) -> JsonSchemaValue: field_schema: dict[str, Any] = {} field_schema.update(type=cls.TYPE, format='date-time') return field_schema @classmethod def __get_pydantic_core_schema__( cls, source: type[Any], handler: Callable[[Any], CoreSchema] ) -> core_schema.CoreSchema: return core_schema.with_info_after_validator_function( cls._validate, cls.SCHEMA, serialization=core_schema.wrap_serializer_function_ser_schema(cls._f, return_schema=cls.SCHEMA), ) @classmethod def _validate(cls, __input_value: Any, _: Any) -> datetime.datetime: return EPOCH + datetime.timedelta(seconds=__input_value) @classmethod def _f(cls, value: Any, serializer: Callable[[Any], Any]) -> Any: # pragma: no cover raise NotImplementedError(cls) class Number(_Base): """epoch.Number parses unix timestamp as float and converts it to datetime. ```py from pydantic import BaseModel from pydantic_extra_types import epoch class LogEntry(BaseModel): timestamp: epoch.Number logentry = LogEntry(timestamp=1.1) print(logentry) # > timestamp=datetime.datetime(1970, 1, 1, 0, 0, 1, 100000, tzinfo=datetime.timezone.utc) ``` """ TYPE = 'number' SCHEMA = core_schema.float_schema() @classmethod def _f(cls, value: Any, serializer: Callable[[float], float]) -> float: ts = value.timestamp() return serializer(ts) class Integer(_Base): """epoch.Integer parses unix timestamp as integer and converts it to datetime. ``` ```py from pydantic import BaseModel from pydantic_extra_types import epoch class LogEntry(BaseModel): timestamp: epoch.Integer logentry = LogEntry(timestamp=1) print(logentry) #> timestamp=datetime.datetime(1970, 1, 1, 0, 0, 1, tzinfo=datetime.timezone.utc) ``` """ TYPE = 'integer' SCHEMA = core_schema.int_schema() @classmethod def _f(cls, value: Any, serializer: Callable[[int], int]) -> int: ts = value.timestamp() return serializer(int(ts)) pydantic-extra-types-2.10.5/pydantic_extra_types/isbn.py000066400000000000000000000115041501603200400234340ustar00rootroot00000000000000"""The `pydantic_extra_types.isbn` module provides functionality to recieve and validate ISBN. ISBN (International Standard Book Number) is a numeric commercial book identifier which is intended to be unique. This module provides a ISBN type for Pydantic models. """ from __future__ import annotations import itertools as it from typing import Any from pydantic import GetCoreSchemaHandler from pydantic_core import PydanticCustomError, core_schema def isbn10_digit_calc(isbn: str) -> str: """Calc a ISBN-10 last digit from the provided str value. More information of validation algorithm on [Wikipedia](https://en.wikipedia.org/wiki/ISBN#Check_digits) Args: isbn: The str value representing the ISBN in 10 digits. Returns: The calculated last digit of the ISBN-10 value. """ total = sum(int(digit) * (10 - idx) for idx, digit in enumerate(isbn[:9])) diff = (11 - total) % 11 valid_check_digit = 'X' if diff == 10 else str(diff) return valid_check_digit def isbn13_digit_calc(isbn: str) -> str: """Calc a ISBN-13 last digit from the provided str value. More information of validation algorithm on [Wikipedia](https://en.wikipedia.org/wiki/ISBN#Check_digits) Args: isbn: The str value representing the ISBN in 13 digits. Returns: The calculated last digit of the ISBN-13 value. """ total = sum(int(digit) * factor for digit, factor in zip(isbn[:12], it.cycle((1, 3)))) check_digit = (10 - total) % 10 return str(check_digit) class ISBN(str): """Represents a ISBN and provides methods for conversion, validation, and serialization. ```py from pydantic import BaseModel from pydantic_extra_types.isbn import ISBN class Book(BaseModel): isbn: ISBN book = Book(isbn='8537809667') print(book) # > isbn='9788537809662' ``` """ @classmethod def __get_pydantic_core_schema__(cls, source: type[Any], handler: GetCoreSchemaHandler) -> core_schema.CoreSchema: """Return a Pydantic CoreSchema with the ISBN validation. Args: source: The source type to be converted. handler: The handler to get the CoreSchema. Returns: A Pydantic CoreSchema with the ISBN validation. """ return core_schema.with_info_before_validator_function( cls._validate, core_schema.str_schema(), ) @classmethod def _validate(cls, __input_value: str, _: Any) -> str: """Validate a ISBN from the provided str value. Args: __input_value: The str value to be validated. _: The source type to be converted. Returns: The validated ISBN. Raises: PydanticCustomError: If the ISBN is not valid. """ cls.validate_isbn_format(__input_value) return cls.convert_isbn10_to_isbn13(__input_value) @staticmethod def validate_isbn_format(value: str) -> None: """Validate a ISBN format from the provided str value. Args: value: The str value representing the ISBN in 10 or 13 digits. Raises: PydanticCustomError: If the ISBN is not valid. """ isbn_length = len(value) if isbn_length not in (10, 13): raise PydanticCustomError('isbn_length', f'Length for ISBN must be 10 or 13 digits, not {isbn_length}') if isbn_length == 10: if not value[:-1].isdigit() or ((value[-1] != 'X') and (not value[-1].isdigit())): raise PydanticCustomError('isbn10_invalid_characters', 'First 9 digits of ISBN-10 must be integers') if isbn10_digit_calc(value) != value[-1]: raise PydanticCustomError('isbn_invalid_digit_check_isbn10', 'Provided digit is invalid for given ISBN') if isbn_length == 13: if not value.isdigit(): raise PydanticCustomError('isbn13_invalid_characters', 'All digits of ISBN-13 must be integers') if value[:3] not in ('978', '979'): raise PydanticCustomError( 'isbn_invalid_early_characters', 'The first 3 digits of ISBN-13 must be 978 or 979' ) if isbn13_digit_calc(value) != value[-1]: raise PydanticCustomError('isbn_invalid_digit_check_isbn13', 'Provided digit is invalid for given ISBN') @staticmethod def convert_isbn10_to_isbn13(value: str) -> str: """Convert an ISBN-10 to ISBN-13. Args: value: The ISBN-10 value to be converted. Returns: The converted ISBN or the original value if no conversion is necessary. """ if len(value) == 10: base_isbn = f'978{value[:-1]}' isbn13_digit = isbn13_digit_calc(base_isbn) return ISBN(f'{base_isbn}{isbn13_digit}') return ISBN(value) pydantic-extra-types-2.10.5/pydantic_extra_types/language_code.py000066400000000000000000000277611501603200400252720ustar00rootroot00000000000000"""Language definitions that are based on the [ISO 639-3](https://en.wikipedia.org/wiki/ISO_639-3) & [ISO 639-5](https://en.wikipedia.org/wiki/ISO_639-5).""" from __future__ import annotations from dataclasses import dataclass from functools import lru_cache from typing import Any, Union from pydantic import GetCoreSchemaHandler, GetJsonSchemaHandler from pydantic_core import PydanticCustomError, core_schema try: import pycountry except ModuleNotFoundError as e: # pragma: no cover raise RuntimeError( 'The `language_code` module requires "pycountry" to be installed.' ' You can install it with "pip install pycountry".' ) from e @dataclass class LanguageInfo: """LanguageInfo is a dataclass that contains the language information. Args: alpha2: The language code in the [ISO 639-1 alpha-2](https://en.wikipedia.org/wiki/ISO_639-1) format. alpha3: The language code in the [ISO 639-3 alpha-3](https://en.wikipedia.org/wiki/ISO_639-3) format. name: The language name. """ alpha2: Union[str, None] alpha3: str name: str @lru_cache def _languages() -> list[LanguageInfo]: """Return a list of LanguageInfo objects containing the language information. Returns: A list of LanguageInfo objects containing the language information. """ return [ LanguageInfo( alpha2=getattr(language, 'alpha_2', None), alpha3=language.alpha_3, name=language.name, ) for language in pycountry.languages ] @lru_cache def _index_by_alpha2() -> dict[str, LanguageInfo]: """Return a dictionary with the language code in the [ISO 639-1 alpha-2](https://en.wikipedia.org/wiki/ISO_639-1) format as the key and the LanguageInfo object as the value.""" return {language.alpha2: language for language in _languages() if language.alpha2 is not None} @lru_cache def _index_by_alpha3() -> dict[str, LanguageInfo]: """Return a dictionary with the language code in the [ISO 639-3 alpha-3](https://en.wikipedia.org/wiki/ISO_639-3) format as the key and the LanguageInfo object as the value.""" return {language.alpha3: language for language in _languages()} @lru_cache def _index_by_name() -> dict[str, LanguageInfo]: """Return a dictionary with the language name as the key and the LanguageInfo object as the value.""" return {language.name: language for language in _languages()} class LanguageAlpha2(str): """LanguageAlpha2 parses languages codes in the [ISO 639-1 alpha-2](https://en.wikipedia.org/wiki/ISO_639-1) format. ```py from pydantic import BaseModel from pydantic_extra_types.language_code import LanguageAlpha2 class Movie(BaseModel): audio_lang: LanguageAlpha2 subtitles_lang: LanguageAlpha2 movie = Movie(audio_lang='de', subtitles_lang='fr') print(movie) # > audio_lang='de' subtitles_lang='fr' ``` """ @classmethod def _validate(cls, __input_value: str, _: core_schema.ValidationInfo) -> LanguageAlpha2: """Validate a language code in the ISO 639-1 alpha-2 format from the provided str value. Args: __input_value: The str value to be validated. _: The Pydantic ValidationInfo. Returns: The validated language code in the ISO 639-1 alpha-2 format. """ if __input_value not in _index_by_alpha2(): raise PydanticCustomError('language_alpha2', 'Invalid language alpha2 code') return cls(__input_value) @classmethod def __get_pydantic_core_schema__( cls, source: type[Any], handler: GetCoreSchemaHandler ) -> core_schema.AfterValidatorFunctionSchema: """Return a Pydantic CoreSchema with the language code in the ISO 639-1 alpha-2 format validation. Args: source: The source type. handler: The handler to get the CoreSchema. Returns: A Pydantic CoreSchema with the language code in the ISO 639-1 alpha-2 format validation. """ return core_schema.with_info_after_validator_function( cls._validate, core_schema.str_schema(to_lower=True), ) @classmethod def __get_pydantic_json_schema__( cls, schema: core_schema.CoreSchema, handler: GetJsonSchemaHandler ) -> dict[str, Any]: """Return a Pydantic JSON Schema with the language code in the ISO 639-1 alpha-2 format validation. Args: schema: The Pydantic CoreSchema. handler: The handler to get the JSON Schema. Returns: A Pydantic JSON Schema with the language code in the ISO 639-1 alpha-2 format validation. """ json_schema = handler(schema) json_schema.update({'pattern': r'^\w{2}$'}) return json_schema @property def alpha3(self) -> str: """The language code in the [ISO 639-3 alpha-3](https://en.wikipedia.org/wiki/ISO_639-3) format.""" return _index_by_alpha2()[self].alpha3 @property def name(self) -> str: """The language name.""" return _index_by_alpha2()[self].name class LanguageName(str): """LanguageName parses languages names listed in the [ISO 639-3 standard](https://en.wikipedia.org/wiki/ISO_639-3) format. ```py from pydantic import BaseModel from pydantic_extra_types.language_code import LanguageName class Movie(BaseModel): audio_lang: LanguageName subtitles_lang: LanguageName movie = Movie(audio_lang='Dutch', subtitles_lang='Mandarin Chinese') print(movie) # > audio_lang='Dutch' subtitles_lang='Mandarin Chinese' ``` """ @classmethod def _validate(cls, __input_value: str, _: core_schema.ValidationInfo) -> LanguageName: """Validate a language name from the provided str value. Args: __input_value: The str value to be validated. _: The Pydantic ValidationInfo. Returns: The validated language name. """ if __input_value not in _index_by_name(): raise PydanticCustomError('language_name', 'Invalid language name') return cls(__input_value) @classmethod def __get_pydantic_core_schema__( cls, source: type[Any], handler: GetCoreSchemaHandler ) -> core_schema.AfterValidatorFunctionSchema: """Return a Pydantic CoreSchema with the language name validation. Args: source: The source type. handler: The handler to get the CoreSchema. Returns: A Pydantic CoreSchema with the language name validation. """ return core_schema.with_info_after_validator_function( cls._validate, core_schema.str_schema(), serialization=core_schema.to_string_ser_schema(), ) @property def alpha2(self) -> Union[str, None]: """The language code in the [ISO 639-1 alpha-2](https://en.wikipedia.org/wiki/ISO_639-1) format. Does not exist for all languages.""" return _index_by_name()[self].alpha2 @property def alpha3(self) -> str: """The language code in the [ISO 639-3 alpha-3](https://en.wikipedia.org/wiki/ISO_639-3) format.""" return _index_by_name()[self].alpha3 class ISO639_3(str): """ISO639_3 parses Language in the [ISO 639-3 alpha-3](https://en.wikipedia.org/wiki/ISO_639-3_alpha-3) format. ```py from pydantic import BaseModel from pydantic_extra_types.language_code import ISO639_3 class Language(BaseModel): alpha_3: ISO639_3 lang = Language(alpha_3='ssr') print(lang) # > alpha_3='ssr' ``` """ allowed_values_list = [lang.alpha_3 for lang in pycountry.languages] allowed_values = set(allowed_values_list) @classmethod def _validate(cls, __input_value: str, _: core_schema.ValidationInfo) -> ISO639_3: """Validate a ISO 639-3 language code from the provided str value. Args: __input_value: The str value to be validated. _: The Pydantic ValidationInfo. Returns: The validated ISO 639-3 language code. Raises: PydanticCustomError: If the ISO 639-3 language code is not valid. """ if __input_value not in cls.allowed_values: raise PydanticCustomError( 'ISO649_3', 'Invalid ISO 639-3 language code. See https://en.wikipedia.org/wiki/ISO_639-3' ) return cls(__input_value) @classmethod def __get_pydantic_core_schema__( cls, _: type[Any], __: GetCoreSchemaHandler ) -> core_schema.AfterValidatorFunctionSchema: """Return a Pydantic CoreSchema with the ISO 639-3 language code validation. Args: _: The source type. __: The handler to get the CoreSchema. Returns: A Pydantic CoreSchema with the ISO 639-3 language code validation. """ return core_schema.with_info_after_validator_function( cls._validate, core_schema.str_schema(min_length=3, max_length=3), ) @classmethod def __get_pydantic_json_schema__( cls, schema: core_schema.CoreSchema, handler: GetJsonSchemaHandler ) -> dict[str, Any]: """Return a Pydantic JSON Schema with the ISO 639-3 language code validation. Args: schema: The Pydantic CoreSchema. handler: The handler to get the JSON Schema. Returns: A Pydantic JSON Schema with the ISO 639-3 language code validation. """ json_schema = handler(schema) json_schema.update({'enum': cls.allowed_values_list}) return json_schema class ISO639_5(str): """ISO639_5 parses Language in the [ISO 639-5 alpha-3](https://en.wikipedia.org/wiki/ISO_639-5_alpha-3) format. ```py from pydantic import BaseModel from pydantic_extra_types.language_code import ISO639_5 class Language(BaseModel): alpha_3: ISO639_5 lang = Language(alpha_3='gem') print(lang) # > alpha_3='gem' ``` """ allowed_values_list = [lang.alpha_3 for lang in pycountry.language_families] allowed_values_list.sort() allowed_values = set(allowed_values_list) @classmethod def _validate(cls, __input_value: str, _: core_schema.ValidationInfo) -> ISO639_5: """Validate a ISO 639-5 language code from the provided str value. Args: __input_value: The str value to be validated. _: The Pydantic ValidationInfo. Returns: The validated ISO 639-3 language code. Raises: PydanticCustomError: If the ISO 639-5 language code is not valid. """ if __input_value not in cls.allowed_values: raise PydanticCustomError( 'ISO649_5', 'Invalid ISO 639-5 language code. See https://en.wikipedia.org/wiki/ISO_639-5' ) return cls(__input_value) @classmethod def __get_pydantic_core_schema__( cls, _: type[Any], __: GetCoreSchemaHandler ) -> core_schema.AfterValidatorFunctionSchema: """Return a Pydantic CoreSchema with the ISO 639-5 language code validation. Args: _: The source type. __: The handler to get the CoreSchema. Returns: A Pydantic CoreSchema with the ISO 639-5 language code validation. """ return core_schema.with_info_after_validator_function( cls._validate, core_schema.str_schema(min_length=3, max_length=3), ) @classmethod def __get_pydantic_json_schema__( cls, schema: core_schema.CoreSchema, handler: GetJsonSchemaHandler ) -> dict[str, Any]: """Return a Pydantic JSON Schema with the ISO 639-5 language code validation. Args: schema: The Pydantic CoreSchema. handler: The handler to get the JSON Schema. Returns: A Pydantic JSON Schema with the ISO 639-5 language code validation. """ json_schema = handler(schema) json_schema.update({'enum': cls.allowed_values_list}) return json_schema pydantic-extra-types-2.10.5/pydantic_extra_types/mac_address.py000066400000000000000000000067401501603200400247540ustar00rootroot00000000000000"""The MAC address module provides functionality to parse and validate MAC addresses in different formats, such as IEEE 802 MAC-48, EUI-48, EUI-64, or a 20-octet format. """ from __future__ import annotations from typing import Any from pydantic import GetCoreSchemaHandler from pydantic_core import PydanticCustomError, core_schema class MacAddress(str): """Represents a MAC address and provides methods for conversion, validation, and serialization. ```py from pydantic import BaseModel from pydantic_extra_types.mac_address import MacAddress class Network(BaseModel): mac_address: MacAddress network = Network(mac_address='00:00:5e:00:53:01') print(network) # > mac_address='00:00:5e:00:53:01' ``` """ @classmethod def __get_pydantic_core_schema__(cls, source: type[Any], handler: GetCoreSchemaHandler) -> core_schema.CoreSchema: """Return a Pydantic CoreSchema with the MAC address validation. Args: source: The source type to be converted. handler: The handler to get the CoreSchema. Returns: A Pydantic CoreSchema with the MAC address validation. """ return core_schema.with_info_before_validator_function( cls._validate, core_schema.str_schema(), ) @classmethod def _validate(cls, __input_value: str, _: Any) -> str: """Validate a MAC Address from the provided str value. Args: __input_value: The str value to be validated. _: The source type to be converted. Returns: str: The parsed MAC address. """ return cls.validate_mac_address(__input_value.encode()) @staticmethod def validate_mac_address(value: bytes) -> str: """Validate a MAC Address from the provided byte value.""" string = value.decode() if len(string) < 14: raise PydanticCustomError( 'mac_address_len', 'Length for a {mac_address} MAC address must be {required_length}', {'mac_address': string, 'required_length': 14}, ) for sep, partbytes in ((':', 2), ('-', 2), ('.', 4)): if sep in string: parts = string.split(sep) if any(len(part) != partbytes for part in parts): raise PydanticCustomError( 'mac_address_format', f'Must have the format xx{sep}xx{sep}xx{sep}xx{sep}xx{sep}xx', ) if len(parts) * partbytes // 2 not in (6, 8, 20): raise PydanticCustomError( 'mac_address_format', 'Length for a {mac_address} MAC address must be {required_length}', {'mac_address': string, 'required_length': (6, 8, 20)}, ) mac_address = [] for part in parts: for idx in range(0, partbytes, 2): try: byte_value = int(part[idx : idx + 2], 16) except ValueError as exc: raise PydanticCustomError('mac_address_format', 'Unrecognized format') from exc else: mac_address.append(byte_value) return ':'.join(f'{b:02x}' for b in mac_address) else: raise PydanticCustomError('mac_address_format', 'Unrecognized format') pydantic-extra-types-2.10.5/pydantic_extra_types/mongo_object_id.py000066400000000000000000000043421501603200400256240ustar00rootroot00000000000000""" Validation for MongoDB ObjectId fields. Ref: https://github.com/pydantic/pydantic-extra-types/issues/133 """ from typing import Any from pydantic import GetCoreSchemaHandler from pydantic_core import core_schema try: from bson import ObjectId except ModuleNotFoundError as e: # pragma: no cover raise RuntimeError( 'The `mongo_object_id` module requires "pymongo" to be installed. You can install it with "pip install ' 'pymongo".' ) from e class MongoObjectId(str): """MongoObjectId parses and validates MongoDB bson.ObjectId. ```py from pydantic import BaseModel from pydantic_extra_types.mongo_object_id import MongoObjectId class MongoDocument(BaseModel): id: MongoObjectId doc = MongoDocument(id='5f9f2f4b9d3c5a7b4c7e6c1d') print(doc) # > id='5f9f2f4b9d3c5a7b4c7e6c1d' ``` Raises: PydanticCustomError: If the provided value is not a valid MongoDB ObjectId. """ OBJECT_ID_LENGTH = 24 @classmethod def __get_pydantic_core_schema__(cls, _: Any, __: GetCoreSchemaHandler) -> core_schema.CoreSchema: return core_schema.json_or_python_schema( json_schema=core_schema.str_schema(min_length=cls.OBJECT_ID_LENGTH, max_length=cls.OBJECT_ID_LENGTH), python_schema=core_schema.union_schema( [ core_schema.is_instance_schema(ObjectId), core_schema.chain_schema( [ core_schema.str_schema(min_length=cls.OBJECT_ID_LENGTH, max_length=cls.OBJECT_ID_LENGTH), core_schema.no_info_plain_validator_function(cls.validate), ] ), ] ), serialization=core_schema.plain_serializer_function_ser_schema(lambda x: str(x), when_used='json'), ) @classmethod def validate(cls, value: str) -> ObjectId: """Validate the MongoObjectId str is a valid ObjectId instance.""" if not ObjectId.is_valid(value): raise ValueError( f"Invalid ObjectId {value} has to be 24 characters long and in the format '5f9f2f4b9d3c5a7b4c7e6c1d'." ) return ObjectId(value) pydantic-extra-types-2.10.5/pydantic_extra_types/path.py000066400000000000000000000040141501603200400234330ustar00rootroot00000000000000from __future__ import annotations import typing from dataclasses import dataclass from pathlib import Path import pydantic from pydantic.types import PathType from pydantic_core import core_schema from typing_extensions import Annotated ExistingPath = typing.Union[pydantic.FilePath, pydantic.DirectoryPath] @dataclass class ResolvedPathType(PathType): """A custom PathType that resolves the path to its absolute form. Args: path_type (typing.Literal['file', 'dir', 'new']): The type of path to resolve. Can be 'file', 'dir' or 'new'. Returns: Resolved path as a pathlib.Path object. Example: ```python from pydantic import BaseModel from pydantic_extra_types.path import ResolvedFilePath, ResolvedDirectoryPath, ResolvedNewPath class MyModel(BaseModel): file_path: ResolvedFilePath dir_path: ResolvedDirectoryPath new_path: ResolvedNewPath model = MyModel(file_path='~/myfile.txt', dir_path='~/mydir', new_path='~/newfile.txt') print(model.file_path) # > file_path=PosixPath('/home/user/myfile.txt') dir_path=PosixPath('/home/user/mydir') new_path=PosixPath('/home/user/newfile.txt')""" @staticmethod def validate_file(path: Path, _: core_schema.ValidationInfo) -> Path: return PathType.validate_file(path.expanduser().resolve(), _) @staticmethod def validate_directory(path: Path, _: core_schema.ValidationInfo) -> Path: return PathType.validate_directory(path.expanduser().resolve(), _) @staticmethod def validate_new(path: Path, _: core_schema.ValidationInfo) -> Path: return PathType.validate_new(path.expanduser().resolve(), _) def __hash__(self) -> int: return hash(type(self.path_type)) ResolvedFilePath = Annotated[Path, ResolvedPathType('file')] ResolvedDirectoryPath = Annotated[Path, ResolvedPathType('dir')] ResolvedNewPath = Annotated[Path, ResolvedPathType('new')] ResolvedExistingPath = typing.Union[ResolvedFilePath, ResolvedDirectoryPath] pydantic-extra-types-2.10.5/pydantic_extra_types/payment.py000066400000000000000000000152201501603200400241550ustar00rootroot00000000000000"""The `pydantic_extra_types.payment` module provides the [`PaymentCardNumber`][pydantic_extra_types.payment.PaymentCardNumber] data type. """ from __future__ import annotations from enum import Enum from typing import Any, ClassVar from pydantic import GetCoreSchemaHandler from pydantic_core import PydanticCustomError, core_schema class PaymentCardBrand(str, Enum): """Payment card brands supported by the [`PaymentCardNumber`][pydantic_extra_types.payment.PaymentCardNumber].""" amex = 'American Express' mastercard = 'Mastercard' visa = 'Visa' mir = 'Mir' maestro = 'Maestro' discover = 'Discover' verve = 'Verve' dankort = 'Dankort' troy = 'Troy' unionpay = 'UnionPay' jcb = 'JCB' other = 'other' def __str__(self) -> str: return self.value class PaymentCardNumber(str): """A [payment card number](https://en.wikipedia.org/wiki/Payment_card_number).""" strip_whitespace: ClassVar[bool] = True """Whether to strip whitespace from the input value.""" min_length: ClassVar[int] = 12 """The minimum length of the card number.""" max_length: ClassVar[int] = 19 """The maximum length of the card number.""" bin: str """The first 6 digits of the card number.""" last4: str """The last 4 digits of the card number.""" brand: PaymentCardBrand """The brand of the card.""" def __init__(self, card_number: str): self.validate_digits(card_number) card_number = self.validate_luhn_check_digit(card_number) self.bin = card_number[:6] self.last4 = card_number[-4:] self.brand = self.validate_brand(card_number) @classmethod def __get_pydantic_core_schema__(cls, source: type[Any], handler: GetCoreSchemaHandler) -> core_schema.CoreSchema: return core_schema.with_info_after_validator_function( cls.validate, core_schema.str_schema( min_length=cls.min_length, max_length=cls.max_length, strip_whitespace=cls.strip_whitespace ), ) @classmethod def validate(cls, __input_value: str, _: core_schema.ValidationInfo) -> PaymentCardNumber: """Validate the `PaymentCardNumber` instance. Args: __input_value: The input value to validate. _: The validation info. Returns: The validated `PaymentCardNumber` instance. """ return cls(__input_value) @property def masked(self) -> str: """The masked card number.""" num_masked = len(self) - 10 # len(bin) + len(last4) == 10 return f'{self.bin}{"*" * num_masked}{self.last4}' @classmethod def validate_digits(cls, card_number: str) -> None: """Validate that the card number is all digits. Args: card_number: The card number to validate. Raises: PydanticCustomError: If the card number is not all digits. """ if not card_number or not all('0' <= c <= '9' for c in card_number): raise PydanticCustomError('payment_card_number_digits', 'Card number is not all digits') @classmethod def validate_luhn_check_digit(cls, card_number: str) -> str: """Validate the payment card number. Based on the [Luhn algorithm](https://en.wikipedia.org/wiki/Luhn_algorithm). Args: card_number: The card number to validate. Returns: The validated card number. Raises: PydanticCustomError: If the card number is not valid. """ sum_ = int(card_number[-1]) length = len(card_number) parity = length % 2 for i in range(length - 1): digit = int(card_number[i]) if i % 2 == parity: digit *= 2 if digit > 9: digit -= 9 sum_ += digit valid = sum_ % 10 == 0 if not valid: raise PydanticCustomError('payment_card_number_luhn', 'Card number is not luhn valid') return card_number @staticmethod def validate_brand(card_number: str) -> PaymentCardBrand: """Validate length based on [BIN](https://en.wikipedia.org/wiki/Payment_card_number#Issuer_identification_number_(IIN)) for major brands. Args: card_number: The card number to validate. Returns: The validated card brand. Raises: PydanticCustomError: If the card number is not valid. """ brand = PaymentCardBrand.other if card_number[0] == '4': brand = PaymentCardBrand.visa required_length = [13, 16, 19] elif 51 <= int(card_number[:2]) <= 55: brand = PaymentCardBrand.mastercard required_length = [16] elif card_number[:2] in {'34', '37'}: brand = PaymentCardBrand.amex required_length = [15] elif 2200 <= int(card_number[:4]) <= 2204: brand = PaymentCardBrand.mir required_length = list(range(16, 20)) elif card_number[:4] in {'5018', '5020', '5038', '5893', '6304', '6759', '6761', '6762', '6763'} or card_number[ :6 ] in ( '676770', '676774', ): brand = PaymentCardBrand.maestro required_length = list(range(12, 20)) elif card_number.startswith('65') or 644 <= int(card_number[:3]) <= 649 or card_number.startswith('6011'): brand = PaymentCardBrand.discover required_length = list(range(16, 20)) elif ( 506099 <= int(card_number[:6]) <= 506198 or 650002 <= int(card_number[:6]) <= 650027 or 507865 <= int(card_number[:6]) <= 507964 ): brand = PaymentCardBrand.verve required_length = [16, 18, 19] elif card_number[:4] in {'5019', '4571'}: brand = PaymentCardBrand.dankort required_length = [16] elif card_number.startswith('9792'): brand = PaymentCardBrand.troy required_length = [16] elif card_number[:2] in {'62', '81'}: brand = PaymentCardBrand.unionpay required_length = [16, 19] elif 3528 <= int(card_number[:4]) <= 3589: brand = PaymentCardBrand.jcb required_length = [16, 19] valid = len(card_number) in required_length if brand != PaymentCardBrand.other else True if not valid: raise PydanticCustomError( 'payment_card_number_brand', f'Length for a {brand} card must be {" or ".join(map(str, required_length))}', {'brand': brand, 'required_length': required_length}, ) return brand pydantic-extra-types-2.10.5/pydantic_extra_types/pendulum_dt.py000066400000000000000000000246771501603200400250400ustar00rootroot00000000000000"""Native Pendulum DateTime object implementation. This is a copy of the Pendulum DateTime object, but with a Pydantic CoreSchema implementation. This allows Pydantic to validate the DateTime object. """ from __future__ import annotations try: from pendulum import Date as _Date from pendulum import DateTime as _DateTime from pendulum import Duration as _Duration from pendulum import parse except ModuleNotFoundError as e: # pragma: no cover raise RuntimeError( 'The `pendulum_dt` module requires "pendulum" to be installed. You can install it with "pip install pendulum".' ) from e from datetime import date, datetime, timedelta from typing import Any from pydantic import GetCoreSchemaHandler from pydantic_core import PydanticCustomError, core_schema class DateTimeSettings(type): def __new__(cls, name, bases, dct, **kwargs): # type: ignore[no-untyped-def] dct['strict'] = kwargs.pop('strict', True) return super().__new__(cls, name, bases, dct) def __init__(cls, name, bases, dct, **kwargs): # type: ignore[no-untyped-def] super().__init__(name, bases, dct) cls.strict = kwargs.get('strict', True) class DateTime(_DateTime, metaclass=DateTimeSettings): """A `pendulum.DateTime` object. At runtime, this type decomposes into pendulum.DateTime automatically. This type exists because Pydantic throws a fit on unknown types. ```python from pydantic import BaseModel from pydantic_extra_types.pendulum_dt import DateTime class test_model(BaseModel): dt: DateTime print(test_model(dt='2021-01-01T00:00:00+00:00')) # > test_model(dt=DateTime(2021, 1, 1, 0, 0, 0, tzinfo=FixedTimezone(0, name="+00:00"))) ``` """ __slots__: list[str] = [] @classmethod def __get_pydantic_core_schema__(cls, source: type[Any], handler: GetCoreSchemaHandler) -> core_schema.CoreSchema: """Return a Pydantic CoreSchema with the Datetime validation Args: source: The source type to be converted. handler: The handler to get the CoreSchema. Returns: A Pydantic CoreSchema with the Datetime validation. """ return core_schema.no_info_wrap_validator_function(cls._validate, core_schema.datetime_schema()) @classmethod def _validate(cls, value: Any, handler: core_schema.ValidatorFunctionWrapHandler) -> DateTime: """Validate the datetime object and return it. Args: value: The value to validate. handler: The handler to get the CoreSchema. Returns: The validated value or raises a PydanticCustomError. """ # if we are passed an existing instance, pass it straight through. if isinstance(value, (_DateTime, datetime)): return DateTime.instance(value) try: # probably the best way to have feature parity with # https://docs.pydantic.dev/latest/api/standard_library_types/#datetimedatetime value = handler(value) return DateTime.instance(value) except ValueError: try: value = parse(value, strict=cls.strict) if isinstance(value, _DateTime): return DateTime.instance(value) raise ValueError(f'value is not a valid datetime it is a {type(value)}') except ValueError: raise except Exception as exc: raise PydanticCustomError('value_error', 'value is not a valid datetime') from exc class Date(_Date): """A `pendulum.Date` object. At runtime, this type decomposes into pendulum.Date automatically. This type exists because Pydantic throws a fit on unknown types. ```python from pydantic import BaseModel from pydantic_extra_types.pendulum_dt import Date class test_model(BaseModel): dt: Date print(test_model(dt='2021-01-01')) # > test_model(dt=Date(2021, 1, 1)) ``` """ __slots__: list[str] = [] @classmethod def __get_pydantic_core_schema__(cls, source: type[Any], handler: GetCoreSchemaHandler) -> core_schema.CoreSchema: """Return a Pydantic CoreSchema with the Date validation Args: source: The source type to be converted. handler: The handler to get the CoreSchema. Returns: A Pydantic CoreSchema with the Date validation. """ return core_schema.no_info_wrap_validator_function(cls._validate, core_schema.date_schema()) @classmethod def _validate(cls, value: Any, handler: core_schema.ValidatorFunctionWrapHandler) -> Date: """Validate the date object and return it. Args: value: The value to validate. handler: The handler to get the CoreSchema. Returns: The validated value or raises a PydanticCustomError. """ # if we are passed an existing instance, pass it straight through. if isinstance(value, (_Date, date)): return Date(value.year, value.month, value.day) # otherwise, parse it. try: parsed = parse(value) if isinstance(parsed, (_DateTime, _Date)): return Date(parsed.year, parsed.month, parsed.day) raise ValueError('value is not a valid date it is a {type(parsed)}') except Exception as exc: raise PydanticCustomError('value_error', 'value is not a valid date') from exc class Duration(_Duration): """A `pendulum.Duration` object. At runtime, this type decomposes into pendulum.Duration automatically. This type exists because Pydantic throws a fit on unknown types. ```python from pydantic import BaseModel from pydantic_extra_types.pendulum_dt import Duration class test_model(BaseModel): delta_t: Duration print(test_model(delta_t='P1DT25H')) # > test_model(delta_t=Duration(days=2, hours=1)) ``` """ __slots__: list[str] = [] @classmethod def __get_pydantic_core_schema__(cls, source: type[Any], handler: GetCoreSchemaHandler) -> core_schema.CoreSchema: """Return a Pydantic CoreSchema with the Duration validation Args: source: The source type to be converted. handler: The handler to get the CoreSchema. Returns: A Pydantic CoreSchema with the Duration validation. """ return core_schema.no_info_wrap_validator_function( cls._validate, core_schema.timedelta_schema(), serialization=core_schema.plain_serializer_function_ser_schema( lambda instance: instance.to_iso8601_string(), when_used='json-unless-none' ), ) def to_iso8601_string(self) -> str: """ Convert a Duration object to an ISO 8601 string. In addition to the standard ISO 8601 format, this method also supports the representation of fractions of a second and negative durations. Args: duration (Duration): The Duration object. Returns: str: The ISO 8601 string representation of the duration. """ # Extracting components from the Duration object years = self.years months = self.months days = self._days hours = self.hours minutes = self.minutes seconds = self.remaining_seconds milliseconds = self.microseconds // 1000 microseconds = self.microseconds % 1000 # Constructing the ISO 8601 duration string iso_duration = 'P' if years or months or days: if years: iso_duration += f'{years}Y' if months: iso_duration += f'{months}M' if days: iso_duration += f'{days}D' if hours or minutes or seconds or milliseconds or microseconds: iso_duration += 'T' if hours: iso_duration += f'{hours}H' if minutes: iso_duration += f'{minutes}M' if seconds or milliseconds or microseconds: iso_duration += f'{seconds}' if milliseconds or microseconds: iso_duration += f'.{milliseconds:03d}' if microseconds: iso_duration += f'{microseconds:03d}' iso_duration += 'S' # Prefix with '-' if the duration is negative if self.total_seconds() < 0: iso_duration = '-' + iso_duration if iso_duration == 'P': iso_duration = 'P0D' return iso_duration @classmethod def _validate(cls, value: Any, handler: core_schema.ValidatorFunctionWrapHandler) -> Duration: """Validate the Duration object and return it. Args: value: The value to validate. handler: The handler to get the CoreSchema. Returns: The validated value or raises a PydanticCustomError. """ if isinstance(value, _Duration): return Duration( years=value.years, months=value.months, weeks=value.weeks, days=value.remaining_days, hours=value.hours, minutes=value.minutes, seconds=value.remaining_seconds, microseconds=value.microseconds, ) if isinstance(value, timedelta): return Duration( days=value.days, seconds=value.seconds, microseconds=value.microseconds, ) assert isinstance(value, str) try: # https://github.com/python-pendulum/pendulum/issues/532 if value.startswith('-'): parsed = parse(value.lstrip('-'), exact=True) else: parsed = parse(value, exact=True) if not isinstance(parsed, _Duration): raise ValueError(f'value is not a valid duration it is a {type(parsed)}') if value.startswith('-'): parsed = -parsed return Duration( years=parsed.years, months=parsed.months, weeks=parsed.weeks, days=parsed.remaining_days, hours=parsed.hours, minutes=parsed.minutes, seconds=parsed.remaining_seconds, microseconds=parsed.microseconds, ) except Exception as exc: raise PydanticCustomError('value_error', 'value is not a valid duration') from exc pydantic-extra-types-2.10.5/pydantic_extra_types/phone_numbers.py000066400000000000000000000164111501603200400253470ustar00rootroot00000000000000"""The `pydantic_extra_types.phone_numbers` module provides the [`PhoneNumber`][pydantic_extra_types.phone_numbers.PhoneNumber] data type. This class depends on the [phonenumbers] package, which is a Python port of Google's [libphonenumber]. """ from __future__ import annotations from collections.abc import Sequence from dataclasses import dataclass from functools import partial from typing import Any, ClassVar from pydantic import GetCoreSchemaHandler, GetJsonSchemaHandler from pydantic_core import PydanticCustomError, core_schema try: import phonenumbers from phonenumbers import PhoneNumber as BasePhoneNumber from phonenumbers.phonenumberutil import NumberParseException except ModuleNotFoundError as e: # pragma: no cover raise RuntimeError( '`PhoneNumber` requires "phonenumbers" to be installed. You can install it with "pip install phonenumbers"' ) from e class PhoneNumber(str): """A wrapper around [phonenumbers](https://pypi.org/project/phonenumbers/) package, which is a Python port of Google's [libphonenumber](https://github.com/google/libphonenumber/). """ supported_regions: list[str] = [] """The supported regions. If empty, all regions are supported.""" default_region_code: ClassVar[str | None] = None """The default region code to use when parsing phone numbers without an international prefix.""" phone_format: str = 'RFC3966' """The format of the phone number.""" @classmethod def __get_pydantic_json_schema__( cls, schema: core_schema.CoreSchema, handler: GetJsonSchemaHandler ) -> dict[str, Any]: json_schema = handler(schema) json_schema.update({'format': 'phone'}) return json_schema @classmethod def __get_pydantic_core_schema__(cls, source: type[Any], handler: GetCoreSchemaHandler) -> core_schema.CoreSchema: return core_schema.with_info_after_validator_function( cls._validate, core_schema.str_schema(), ) @classmethod def _validate(cls, phone_number: str, _: core_schema.ValidationInfo) -> str: try: parsed_number = phonenumbers.parse(phone_number, cls.default_region_code) except phonenumbers.phonenumberutil.NumberParseException as exc: raise PydanticCustomError('value_error', 'value is not a valid phone number') from exc if not phonenumbers.is_valid_number(parsed_number): raise PydanticCustomError('value_error', 'value is not a valid phone number') if cls.supported_regions and not any( phonenumbers.is_valid_number_for_region(parsed_number, region_code=region) for region in cls.supported_regions ): raise PydanticCustomError('value_error', 'value is not from a supported region') return phonenumbers.format_number(parsed_number, getattr(phonenumbers.PhoneNumberFormat, cls.phone_format)) def __eq__(self, other: Any) -> bool: return super().__eq__(other) def __hash__(self) -> int: return super().__hash__() @dataclass(frozen=True) class PhoneNumberValidator: """A pydantic before validator for phone numbers using the [phonenumbers](https://pypi.org/project/phonenumbers/) package, a Python port of Google's [libphonenumber](https://github.com/google/libphonenumber/). Intended to be used to create custom pydantic data types using the `typing.Annotated` type construct. Args: default_region (str | None): The default region code to use when parsing phone numbers without an international prefix. If `None` (default), the region must be supplied in the phone number as an international prefix. number_format (str): The format of the phone number to return. See `phonenumbers.PhoneNumberFormat` for valid values. supported_regions (list[str]): The supported regions. If empty, all regions are supported (default). Returns: The formatted phone number. Example: MyNumberType = Annotated[ Union[str, phonenumbers.PhoneNumber], PhoneNumberValidator() ] USNumberType = Annotated[ Union[str, phonenumbers.PhoneNumber], PhoneNumberValidator(supported_regions=['US'], default_region='US') ] class SomeModel(BaseModel): phone_number: MyNumberType us_number: USNumberType """ default_region: str | None = None number_format: str = 'RFC3966' supported_regions: Sequence[str] | None = None def __post_init__(self) -> None: if self.default_region and self.default_region not in phonenumbers.SUPPORTED_REGIONS: raise ValueError(f'Invalid default region code: {self.default_region}') if self.number_format not in ( number_format for number_format in dir(phonenumbers.PhoneNumberFormat) if not number_format.startswith('_') and number_format.isupper() ): raise ValueError(f'Invalid number format: {self.number_format}') if self.supported_regions: for supported_region in self.supported_regions: if supported_region not in phonenumbers.SUPPORTED_REGIONS: raise ValueError(f'Invalid supported region code: {supported_region}') @staticmethod def _parse( region: str | None, number_format: str, supported_regions: Sequence[str] | None, phone_number: Any, ) -> str: if not phone_number: raise PydanticCustomError('value_error', 'value is not a valid phone number') if not isinstance(phone_number, (str, BasePhoneNumber)): raise PydanticCustomError('value_error', 'value is not a valid phone number') parsed_number = None if isinstance(phone_number, BasePhoneNumber): parsed_number = phone_number else: try: parsed_number = phonenumbers.parse(phone_number, region=region) except NumberParseException as exc: raise PydanticCustomError('value_error', 'value is not a valid phone number') from exc if not phonenumbers.is_valid_number(parsed_number): raise PydanticCustomError('value_error', 'value is not a valid phone number') if supported_regions and not any( phonenumbers.is_valid_number_for_region(parsed_number, region_code=region) for region in supported_regions ): raise PydanticCustomError('value_error', 'value is not from a supported region') return phonenumbers.format_number(parsed_number, getattr(phonenumbers.PhoneNumberFormat, number_format)) def __get_pydantic_core_schema__(self, source: type[Any], handler: GetCoreSchemaHandler) -> core_schema.CoreSchema: return core_schema.no_info_before_validator_function( partial( self._parse, self.default_region, self.number_format, self.supported_regions, ), core_schema.str_schema(), ) def __get_pydantic_json_schema__( self, schema: core_schema.CoreSchema, handler: GetJsonSchemaHandler ) -> dict[str, Any]: json_schema = handler(schema) json_schema.update({'format': 'phone'}) return json_schema def __hash__(self) -> int: return super().__hash__() pydantic-extra-types-2.10.5/pydantic_extra_types/py.typed000066400000000000000000000000001501603200400236130ustar00rootroot00000000000000pydantic-extra-types-2.10.5/pydantic_extra_types/routing_number.py000066400000000000000000000060051501603200400255400ustar00rootroot00000000000000"""The `pydantic_extra_types.routing_number` module provides the [`ABARoutingNumber`][pydantic_extra_types.routing_number.ABARoutingNumber] data type. """ from __future__ import annotations import itertools as it from typing import Any, ClassVar from pydantic import GetCoreSchemaHandler from pydantic_core import PydanticCustomError, core_schema class ABARoutingNumber(str): """The `ABARoutingNumber` data type is a string of 9 digits representing an ABA routing transit number. The algorithm used to validate the routing number is described in the [ABA routing transit number](https://en.wikipedia.org/wiki/ABA_routing_transit_number#Check_digit) Wikipedia article. ```py from pydantic import BaseModel from pydantic_extra_types.routing_number import ABARoutingNumber class BankAccount(BaseModel): routing_number: ABARoutingNumber account = BankAccount(routing_number='122105155') print(account) # > routing_number='122105155' ``` """ strip_whitespace: ClassVar[bool] = True min_length: ClassVar[int] = 9 max_length: ClassVar[int] = 9 def __init__(self, routing_number: str): self._validate_digits(routing_number) self._routing_number = self._validate_routing_number(routing_number) @classmethod def __get_pydantic_core_schema__( cls, source: type[Any], handler: GetCoreSchemaHandler ) -> core_schema.AfterValidatorFunctionSchema: return core_schema.with_info_after_validator_function( cls._validate, core_schema.str_schema( min_length=cls.min_length, max_length=cls.max_length, strip_whitespace=cls.strip_whitespace, strict=False, ), ) @classmethod def _validate(cls, __input_value: str, _: core_schema.ValidationInfo) -> ABARoutingNumber: return cls(__input_value) @classmethod def _validate_digits(cls, routing_number: str) -> None: """Check that the routing number is all digits. Args: routing_number: The routing number to validate. Raises: PydanticCustomError: If the routing number is not all digits. """ if not routing_number.isdigit(): raise PydanticCustomError('aba_routing_number', 'routing number is not all digits') @classmethod def _validate_routing_number(cls, routing_number: str) -> str: """Check [digit algorithm](https://en.wikipedia.org/wiki/ABA_routing_transit_number#Check_digit) for [ABA routing transit number](https://www.routingnumber.com/). Args: routing_number: The routing number to validate. Raises: PydanticCustomError: If the routing number is incorrect. """ checksum = sum(int(digit) * factor for digit, factor in zip(routing_number, it.cycle((3, 7, 1)))) if checksum % 10: raise PydanticCustomError('aba_routing_number', 'Incorrect ABA routing transit number') return routing_number pydantic-extra-types-2.10.5/pydantic_extra_types/s3.py000066400000000000000000000037661501603200400230410ustar00rootroot00000000000000"""The `pydantic_extra_types.s3` module provides the [`S3Path`][pydantic_extra_types.s3.S3Path] data type. A simpleAWS S3 URLs parser. It also provides the `Bucket`, `Key` component. """ from __future__ import annotations import re from typing import Any, ClassVar from pydantic import GetCoreSchemaHandler from pydantic_core import core_schema class S3Path(str): """An object representing a valid S3 path. This type also allows you to access the `bucket` and `key` component of the S3 path. It also contains the `last_key` which represents the last part of the path (tipically a file). ```python from pydantic import BaseModel from pydantic_extra_types.s3 import S3Path class TestModel(BaseModel): path: S3Path p = 's3://my-data-bucket/2023/08/29/sales-report.csv' model = TestModel(path=p) model # > TestModel(path=S3Path('s3://my-data-bucket/2023/08/29/sales-report.csv')) model.path.bucket # > 'my-data-bucket' ``` """ patt: ClassVar[str] = r'^s3://([^/]+)/(.*?([^/]+)/?)$' def __init__(self, value: str) -> None: self.value = value groups: tuple[str, str, str] = re.match(self.patt, self.value).groups() # type: ignore self.bucket: str = groups[0] self.key: str = groups[1] self.last_key: str = groups[2] def __str__(self) -> str: # pragma: no cover return self.value def __repr__(self) -> str: # pragma: no cover return f'{self.__class__.__name__}({self.value!r})' @classmethod def _validate(cls, __input_value: str, _: core_schema.ValidationInfo) -> S3Path: return cls(__input_value) @classmethod def __get_pydantic_core_schema__(cls, source: type[Any], handler: GetCoreSchemaHandler) -> core_schema.CoreSchema: _, _ = source, handler return core_schema.with_info_after_validator_function( cls._validate, core_schema.str_schema(pattern=cls.patt), field_name=cls.__class__.__name__, ) pydantic-extra-types-2.10.5/pydantic_extra_types/script_code.py000066400000000000000000000056311501603200400250030ustar00rootroot00000000000000"""script definitions that are based on the [ISO 15924](https://en.wikipedia.org/wiki/ISO_15924)""" from __future__ import annotations from typing import Any from pydantic import GetCoreSchemaHandler, GetJsonSchemaHandler from pydantic_core import PydanticCustomError, core_schema try: import pycountry except ModuleNotFoundError as e: # pragma: no cover raise RuntimeError( 'The `script_code` module requires "pycountry" to be installed.' ' You can install it with "pip install pycountry".' ) from e class ISO_15924(str): """ISO_15924 parses script in the [ISO 15924](https://en.wikipedia.org/wiki/ISO_15924) format. ```py from pydantic import BaseModel from pydantic_extra_types.language_code import ISO_15924 class Script(BaseModel): alpha_4: ISO_15924 script = Script(alpha_4='Java') print(lang) # > script='Java' ``` """ allowed_values_list = [script.alpha_4 for script in pycountry.scripts] allowed_values = set(allowed_values_list) @classmethod def _validate(cls, __input_value: str, _: core_schema.ValidationInfo) -> ISO_15924: """Validate a ISO 15924 language code from the provided str value. Args: __input_value: The str value to be validated. _: The Pydantic ValidationInfo. Returns: The validated ISO 15924 script code. Raises: PydanticCustomError: If the ISO 15924 script code is not valid. """ if __input_value not in cls.allowed_values: raise PydanticCustomError( 'ISO_15924', 'Invalid ISO 15924 script code. See https://en.wikipedia.org/wiki/ISO_15924' ) return cls(__input_value) @classmethod def __get_pydantic_core_schema__( cls, _: type[Any], __: GetCoreSchemaHandler ) -> core_schema.AfterValidatorFunctionSchema: """Return a Pydantic CoreSchema with the ISO 639-3 language code validation. Args: _: The source type. __: The handler to get the CoreSchema. Returns: A Pydantic CoreSchema with the ISO 639-3 language code validation. """ return core_schema.with_info_after_validator_function( cls._validate, core_schema.str_schema(min_length=4, max_length=4), ) @classmethod def __get_pydantic_json_schema__( cls, schema: core_schema.CoreSchema, handler: GetJsonSchemaHandler ) -> dict[str, Any]: """Return a Pydantic JSON Schema with the ISO 639-3 language code validation. Args: schema: The Pydantic CoreSchema. handler: The handler to get the JSON Schema. Returns: A Pydantic JSON Schema with the ISO 639-3 language code validation. """ json_schema = handler(schema) json_schema.update({'enum': cls.allowed_values_list}) return json_schema pydantic-extra-types-2.10.5/pydantic_extra_types/semantic_version.py000066400000000000000000000041541501603200400260540ustar00rootroot00000000000000"""SemanticVersion definition that is based on the Semantiv Versioning Specification [semver](https://semver.org/).""" from typing import Any, Callable from pydantic import GetJsonSchemaHandler from pydantic.json_schema import JsonSchemaValue from pydantic_core import core_schema try: import semver except ModuleNotFoundError as e: # pragma: no cover raise RuntimeError( 'The `semantic_version` module requires "semver" to be installed. You can install it with "pip install semver".' ) from e class SemanticVersion(semver.Version): """Semantic version based on the official [semver thread](https://python-semver.readthedocs.io/en/latest/advanced/combine-pydantic-and-semver.html).""" @classmethod def __get_pydantic_core_schema__( cls, _source_type: Any, _handler: Callable[[Any], core_schema.CoreSchema], ) -> core_schema.CoreSchema: def validate_from_str(value: str) -> SemanticVersion: return cls.parse(value) from_str_schema = core_schema.chain_schema( [ core_schema.str_schema(), core_schema.no_info_plain_validator_function(validate_from_str), ] ) return core_schema.json_or_python_schema( json_schema=from_str_schema, python_schema=core_schema.union_schema( [ core_schema.is_instance_schema(semver.Version), from_str_schema, ] ), serialization=core_schema.to_string_ser_schema(), ) @classmethod def __get_pydantic_json_schema__( cls, _core_schema: core_schema.CoreSchema, handler: GetJsonSchemaHandler ) -> JsonSchemaValue: return handler( core_schema.str_schema( pattern=r'^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$' ) ) @classmethod def validate_from_str(cls, value: str) -> 'SemanticVersion': return cls.parse(value) pydantic-extra-types-2.10.5/pydantic_extra_types/semver.py000066400000000000000000000042551501603200400240070ustar00rootroot00000000000000"""The _VersionPydanticAnnotation class provides functionality to parse and validate Semantic Versioning (SemVer) strings. This class depends on the [semver](https://python-semver.readthedocs.io/en/latest/index.html) package. """ import warnings from typing import Any, Callable from pydantic import GetJsonSchemaHandler from pydantic.json_schema import JsonSchemaValue from pydantic_core import core_schema from semver import Version from typing_extensions import Annotated warnings.warn( 'Use from pydantic_extra_types.semver import SemanticVersion instead. Will be removed in 3.0.0.', DeprecationWarning ) class _VersionPydanticAnnotation(Version): """Represents a Semantic Versioning (SemVer). Wraps the `version` type from `semver`. Example: ```python from pydantic import BaseModel from pydantic_extra_types.semver import _VersionPydanticAnnotation class appVersion(BaseModel): version: _VersionPydanticAnnotation app_version = appVersion(version='1.2.3') print(app_version.version) # > 1.2.3 ``` """ @classmethod def __get_pydantic_core_schema__( cls, _source_type: Any, _handler: Callable[[Any], core_schema.CoreSchema], ) -> core_schema.CoreSchema: def validate_from_str(value: str) -> Version: return Version.parse(value) from_str_schema = core_schema.chain_schema( [ core_schema.str_schema(), core_schema.no_info_plain_validator_function(validate_from_str), ] ) return core_schema.json_or_python_schema( json_schema=from_str_schema, python_schema=core_schema.union_schema( [ core_schema.is_instance_schema(Version), from_str_schema, ] ), serialization=core_schema.to_string_ser_schema(), ) @classmethod def __get_pydantic_json_schema__( cls, _core_schema: core_schema.CoreSchema, handler: GetJsonSchemaHandler ) -> JsonSchemaValue: return handler(core_schema.str_schema()) ManifestVersion = Annotated[Version, _VersionPydanticAnnotation] pydantic-extra-types-2.10.5/pydantic_extra_types/timezone_name.py000066400000000000000000000137371501603200400253450ustar00rootroot00000000000000"""Time zone name validation and serialization module.""" from __future__ import annotations import importlib import sys import warnings from typing import Any, Callable, cast from pydantic import GetCoreSchemaHandler, GetJsonSchemaHandler from pydantic_core import PydanticCustomError, core_schema def _is_available(name: str) -> bool: """Check if a module is available for import.""" try: importlib.import_module(name) return True except ModuleNotFoundError: # pragma: no cover return False def _tz_provider_from_zone_info() -> set[str]: # pragma: no cover """Get timezones from the zoneinfo module.""" from zoneinfo import available_timezones return set(available_timezones()) def _tz_provider_from_pytz() -> set[str]: # pragma: no cover """Get timezones from the pytz module.""" from pytz import all_timezones return set(all_timezones) def _warn_about_pytz_usage() -> None: """Warn about using pytz with Python 3.9 or later.""" warnings.warn( # pragma: no cover 'Projects using Python 3.9 or later should be using the support now included as part of the standard library. ' 'Please consider switching to the standard library (zoneinfo) module.' ) def get_timezones() -> set[str]: """Determine the timezone provider and return available timezones.""" if _is_available('zoneinfo'): # pragma: no cover timezones = _tz_provider_from_zone_info() if len(timezones) == 0: # pragma: no cover raise ImportError('No timezone provider found. Please install tzdata with "pip install tzdata"') return timezones elif _is_available('pytz'): # pragma: no cover return _tz_provider_from_pytz() else: # pragma: no cover if sys.version_info[:2] == (3, 8): raise ImportError('No pytz module found. Please install it with "pip install pytz"') raise ImportError('No timezone provider found. Please install tzdata with "pip install tzdata"') class TimeZoneNameSettings(type): def __new__(cls, name: str, bases: tuple[type, ...], dct: dict[str, Any], **kwargs: Any) -> type[TimeZoneName]: dct['strict'] = kwargs.pop('strict', True) return cast('type[TimeZoneName]', super().__new__(cls, name, bases, dct)) def __init__(cls, name: str, bases: tuple[type, ...], dct: dict[str, Any], **kwargs: Any) -> None: super().__init__(name, bases, dct) cls.strict = kwargs.get('strict', True) def timezone_name_settings(**kwargs: Any) -> Callable[[type[TimeZoneName]], type[TimeZoneName]]: def wrapper(cls: type[TimeZoneName]) -> type[TimeZoneName]: cls.strict = kwargs.get('strict', True) return cls return wrapper @timezone_name_settings(strict=True) class TimeZoneName(str): """TimeZoneName is a custom string subclass for validating and serializing timezone names. The TimeZoneName class uses the IANA Time Zone Database for validation. It supports both strict and non-strict modes for timezone name validation. ## Examples: Some examples of using the TimeZoneName class: ### Normal usage: ```python from pydantic_extra_types.timezone_name import TimeZoneName from pydantic import BaseModel class Location(BaseModel): city: str timezone: TimeZoneName loc = Location(city="New York", timezone="America/New_York") print(loc.timezone) >> America/New_York ``` ### Non-strict mode: ```python from pydantic_extra_types.timezone_name import TimeZoneName, timezone_name_settings @timezone_name_settings(strict=False) class TZNonStrict(TimeZoneName): pass tz = TZNonStrict("america/new_york") print(tz) >> america/new_york ``` """ __slots__: list[str] = [] allowed_values: set[str] = set(get_timezones()) allowed_values_list: list[str] = sorted(allowed_values) allowed_values_upper_to_correct: dict[str, str] = {val.upper(): val for val in allowed_values} strict: bool @classmethod def _validate(cls, __input_value: str, _: core_schema.ValidationInfo) -> TimeZoneName: """Validate a time zone name from the provided str value. Args: __input_value: The str value to be validated. _: The Pydantic ValidationInfo. Returns: The validated time zone name. Raises: PydanticCustomError: If the timezone name is not valid. """ if __input_value not in cls.allowed_values: # be fast for the most common case if not cls.strict: upper_value = __input_value.strip().upper() if upper_value in cls.allowed_values_upper_to_correct: return cls(cls.allowed_values_upper_to_correct[upper_value]) raise PydanticCustomError('TimeZoneName', 'Invalid timezone name.') return cls(__input_value) @classmethod def __get_pydantic_core_schema__( cls, _: type[Any], __: GetCoreSchemaHandler ) -> core_schema.AfterValidatorFunctionSchema: """Return a Pydantic CoreSchema with the timezone name validation. Args: _: The source type. __: The handler to get the CoreSchema. Returns: A Pydantic CoreSchema with the timezone name validation. """ return core_schema.with_info_after_validator_function( cls._validate, core_schema.str_schema(min_length=1), ) @classmethod def __get_pydantic_json_schema__( cls, schema: core_schema.CoreSchema, handler: GetJsonSchemaHandler ) -> dict[str, Any]: """Return a Pydantic JSON Schema with the timezone name validation. Args: schema: The Pydantic CoreSchema. handler: The handler to get the JSON Schema. Returns: A Pydantic JSON Schema with the timezone name validation. """ json_schema = handler(schema) json_schema.update({'enum': cls.allowed_values_list}) return json_schema pydantic-extra-types-2.10.5/pydantic_extra_types/ulid.py000066400000000000000000000045621501603200400234440ustar00rootroot00000000000000"""The `pydantic_extra_types.ULID` module provides the [`ULID`] data type. This class depends on the [python-ulid] package, which is a validate by the [ULID-spec](https://github.com/ulid/spec#implementations-in-other-languages). """ from __future__ import annotations import uuid from dataclasses import dataclass from typing import Any, Union from pydantic import GetCoreSchemaHandler from pydantic._internal import _repr from pydantic_core import PydanticCustomError, core_schema try: from ulid import ULID as _ULID except ModuleNotFoundError as e: # pragma: no cover raise RuntimeError( 'The `ulid` module requires "python-ulid" to be installed. You can install it with "pip install python-ulid".' ) from e UlidType = Union[str, bytes, int] @dataclass class ULID(_repr.Representation): """A wrapper around [python-ulid](https://pypi.org/project/python-ulid/) package, which is a validate by the [ULID-spec](https://github.com/ulid/spec#implementations-in-other-languages). """ ulid: _ULID @classmethod def __get_pydantic_core_schema__(cls, source: type[Any], handler: GetCoreSchemaHandler) -> core_schema.CoreSchema: return core_schema.no_info_wrap_validator_function( cls._validate_ulid, core_schema.union_schema( [ core_schema.is_instance_schema(_ULID), core_schema.int_schema(), core_schema.bytes_schema(), core_schema.str_schema(), core_schema.uuid_schema(), ] ), ) @classmethod def _validate_ulid(cls, value: Any, handler: core_schema.ValidatorFunctionWrapHandler) -> Any: ulid: _ULID if isinstance(value, bool): raise PydanticCustomError('ulid_format', 'Unrecognized format') try: if isinstance(value, int): ulid = _ULID.from_int(value) elif isinstance(value, str): ulid = _ULID.from_str(value) elif isinstance(value, uuid.UUID): ulid = _ULID.from_uuid(value) elif isinstance(value, _ULID): ulid = value else: ulid = _ULID.from_bytes(value) except ValueError as e: raise PydanticCustomError('ulid_format', 'Unrecognized format') from e return handler(ulid) pydantic-extra-types-2.10.5/pyproject.toml000066400000000000000000000103731501603200400206040ustar00rootroot00000000000000[build-system] requires = ['hatchling'] build-backend = 'hatchling.build' [tool.hatch.version] path = 'pydantic_extra_types/__init__.py' [project] name = 'pydantic-extra-types' description = 'Extra Pydantic types.' authors = [ { name = 'Samuel Colvin', email = 's@muelcolvin.com' }, { name = 'Yasser Tahiri', email = 'hello@yezz.me' }, ] license = 'MIT' readme = 'README.md' classifiers = [ 'Development Status :: 5 - Production/Stable', 'Programming Language :: Python', 'Programming Language :: Python :: 3', '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 :: 3.13', 'Intended Audience :: Developers', 'Intended Audience :: Information Technology', 'Intended Audience :: System Administrators', 'License :: OSI Approved :: MIT License', 'Operating System :: Unix', 'Operating System :: POSIX :: Linux', 'Environment :: Console', 'Environment :: MacOS X', 'Framework :: Pydantic', 'Framework :: Pydantic :: 2', 'Topic :: Software Development :: Libraries :: Python Modules', 'Topic :: Internet', ] requires-python = '>=3.8' dependencies = ['pydantic>=2.5.2','typing-extensions'] dynamic = ['version'] [project.optional-dependencies] all = [ 'phonenumbers>=8,<10', 'pycountry>=23', 'semver>=3.0.2', 'python-ulid>=1,<2; python_version<"3.9"', 'python-ulid>=1,<4; python_version>="3.9"', 'pendulum>=3.0.0,<4.0.0', 'pymongo>=4.0.0,<5.0.0', 'pytz>=2024.1', 'semver~=3.0.2', 'tzdata>=2024.1', ] phonenumbers = ['phonenumbers>=8,<10'] pycountry = ['pycountry>=23'] semver = ['semver>=3.0.2'] python_ulid = [ 'python-ulid>=1,<2; python_version<"3.9"', 'python-ulid>=1,<4; python_version>="3.9"', ] pendulum = ['pendulum>=3.0.0,<4.0.0'] [dependency-groups] dev = [ "coverage[toml]>=7.6.1", "pytest-pretty>=1.2.0", "dirty-equals>=0.7.1", "pytest>=8.3.2", ] lint = [ "ruff>=0.7.4", "mypy>=0.910", "annotated-types>=0.7.0", "types-pytz>=2024.1.0.20240417", ] extra = [ { include-group = 'dev' }, { include-group = 'lint' }, ] [project.urls] Homepage = 'https://github.com/pydantic/pydantic-extra-types' Source = 'https://github.com/pydantic/pydantic-extra-types' Changelog = 'https://github.com/pydantic/pydantic-extra-types/releases' Documentation = 'https://docs.pydantic.dev/latest/' [tool.ruff.lint.pyupgrade] keep-runtime-typing = true [tool.ruff] line-length = 120 target-version = 'py38' [tool.ruff.lint] extend-select = [ "Q", "RUF100", "C90", "UP", "I", ] flake8-quotes = { inline-quotes = 'single', multiline-quotes = 'double' } isort = {known-first-party = ['pydantic_extra_types', 'tests'] } mccabe = { max-complexity = 14 } pydocstyle = { convention = 'google' } [tool.ruff.format] docstring-code-format = true quote-style = "single" [tool.ruff.lint.per-file-ignores] 'pydantic_extra_types/color.py' = ['E741'] [tool.coverage.run] source = ['pydantic_extra_types'] branch = true context = '${CONTEXT}' [tool.coverage.paths] source = [ 'pydantic_extra_types/', '/Users/runner/work/pydantic-extra-types/pydantic-extra-types/pydantic_extra_types/', 'D:\a\pydantic-extra-types\pydantic-extra-types\pydantic_extra_types', ] [tool.coverage.report] precision = 2 fail_under = 100 show_missing = true skip_covered = true exclude_lines = [ 'pragma: no cover', 'raise NotImplementedError', 'if TYPE_CHECKING:', '@overload', ] [tool.mypy] strict = true plugins = 'pydantic.mypy' [tool.pytest.ini_options] filterwarnings = [ 'error', # This ignore will be removed when pycountry will drop py36 & support py311 'ignore:::pkg_resources', # This ignore will be removed when pendulum fixes https://github.com/sdispater/pendulum/issues/834 'ignore:datetime.datetime.utcfromtimestamp.*:DeprecationWarning', ' ignore:Use from pydantic_extra_types.semver import SemanticVersion instead. Will be removed in 3.0.0.:DeprecationWarning' ] # configuring https://github.com/pydantic/hooky [tool.hooky] reviewers = ['yezz123', 'Kludex'] require_change_file = false pydantic-extra-types-2.10.5/tests/000077500000000000000000000000001501603200400170265ustar00rootroot00000000000000pydantic-extra-types-2.10.5/tests/__init__.py000066400000000000000000000000001501603200400211250ustar00rootroot00000000000000pydantic-extra-types-2.10.5/tests/test_coordinate.py000066400000000000000000000236461501603200400226010ustar00rootroot00000000000000from decimal import Decimal from re import Pattern from typing import Any, Optional, Union import pytest from pydantic import BaseModel, ValidationError from pydantic_core._pydantic_core import ArgsKwargs from pydantic_extra_types.coordinate import Coordinate, Latitude, Longitude class Coord(BaseModel): coord: Coordinate class Lat(BaseModel): lat: Latitude class Lng(BaseModel): lng: Longitude @pytest.mark.parametrize( 'coord, result, error', [ # Valid coordinates ((20.0, 10.0), (20.0, 10.0), None), ((-90.0, 0.0), (-90.0, 0.0), None), (('20.0', 10.0), (20.0, 10.0), None), ((20.0, '10.0'), (20.0, 10.0), None), ((45.678, -123.456), (45.678, -123.456), None), (('45.678, -123.456'), (45.678, -123.456), None), (Coordinate(20.0, 10.0), (20.0, 10.0), None), (Coordinate(latitude=0, longitude=0), (0, 0), None), (ArgsKwargs(args=()), (0, 0), None), (ArgsKwargs(args=(1, 0.0)), (1.0, 0), None), # Decimal test cases ((Decimal('20.0'), Decimal('10.0')), (Decimal('20.0'), Decimal('10.0')), None), ((Decimal('-90.0'), Decimal('0.0')), (Decimal('-90.0'), Decimal('0.0')), None), ((Decimal('45.678'), Decimal('-123.456')), (Decimal('45.678'), Decimal('-123.456')), None), (Coordinate(Decimal('20.0'), Decimal('10.0')), (Decimal('20.0'), Decimal('10.0')), None), (Coordinate(latitude=Decimal('0'), longitude=Decimal('0')), (Decimal('0'), Decimal('0')), None), (ArgsKwargs(args=(Decimal('1'), Decimal('0.0'))), (Decimal('1.0'), Decimal('0.0')), None), # Invalid coordinates ((), None, 'Field required'), # Empty tuple ((10.0,), None, 'Field required'), # Tuple with only one value (('ten, '), None, 'string is not recognized as a valid coordinate'), ((20.0, 10.0, 30.0), None, 'Tuple should have at most 2 items'), # Tuple with more than 2 values (ArgsKwargs(args=(1.0,)), None, 'Input should be a dictionary or an instance of Coordinate'), ( '20.0, 10.0, 30.0', None, 'Input should be a dictionary or an instance of Coordinate ', ), # Str with more than 2 values ('20.0, 10.0, 30.0', None, 'Unexpected positional argument'), # Str with more than 2 values (2, None, 'Input should be a dictionary or an instance of Coordinate'), # Wrong type ], ) def test_format_for_coordinate( coord: (Any, Any), result: (Union[float, Decimal], Union[float, Decimal]), error: Optional[Pattern] ): if error is None: _coord: Coordinate = Coord(coord=coord).coord assert _coord.latitude == result[0] assert _coord.longitude == result[1] else: with pytest.raises(ValidationError, match=error): Coord(coord=coord).coord @pytest.mark.parametrize( 'coord, error', [ # Valid coordinates ((-90.0, 0.0), None), ((50.0, 180.0), None), # Invalid coordinates ((-91.0, 0.0), 'Input should be greater than or equal to -90'), ((50.0, 181.0), 'Input should be less than or equal to 180'), # Valid Decimal coordinates ((Decimal('-90.0'), Decimal('0.0')), None), ((Decimal('50.0'), Decimal('180.0')), None), ((Decimal('-89.999999'), Decimal('179.999999')), None), ((Decimal('0.0'), Decimal('0.0')), None), # Invalid Decimal coordinates ((Decimal('-90.1'), Decimal('0.0')), 'Input should be greater than or equal to -90'), ((Decimal('50.0'), Decimal('180.1')), 'Input should be less than or equal to 180'), ((Decimal('90.1'), Decimal('0.0')), 'Input should be less than or equal to 90'), ((Decimal('0.0'), Decimal('-180.1')), 'Input should be greater than or equal to -180'), ], ) def test_limit_for_coordinate(coord: (Any, Any), error: Optional[Pattern]): if error is None: _coord: Coordinate = Coord(coord=coord).coord assert _coord.latitude == coord[0] assert _coord.longitude == coord[1] else: with pytest.raises(ValidationError, match=error): Coord(coord=coord).coord @pytest.mark.parametrize( 'latitude, valid', [ # Valid latitude (20.0, True), (3.0000000000000000000000, True), (90.0, True), ('90.0', True), (-90.0, True), ('-90.0', True), (Decimal('90.0'), True), (Decimal('-90.0'), True), # Unvalid latitude (91.0, False), (-91.0, False), (Decimal('91.0'), False), (Decimal('-91.0'), False), ], ) def test_format_latitude(latitude: float, valid: bool): if valid: _lat = Lat(lat=latitude).lat assert _lat == float(latitude) else: with pytest.raises(ValidationError, match='2 validation errors for Lat'): Lat(lat=latitude) @pytest.mark.parametrize( 'longitude, valid', [ # Valid latitude (20.0, True), (3.0000000000000000000000, True), (90.0, True), ('90.0', True), (-90.0, True), ('-90.0', True), (91.0, True), (-91.0, True), (180.0, True), (-180.0, True), (Decimal('180.0'), True), (Decimal('-180.0'), True), # Unvalid latitude (181.0, False), (-181.0, False), (Decimal('181.0'), False), (Decimal('-181.0'), False), ], ) def test_format_longitude(longitude: float, valid: bool): if valid: _lng = Lng(lng=longitude).lng assert _lng == float(longitude) else: with pytest.raises(ValidationError, match='2 validation errors for Lng'): Lng(lng=longitude) def test_str_repr(): # Float tests assert str(Coord(coord=(20.0, 10.0)).coord) == '20.0,10.0' assert str(Coord(coord=('20.0, 10.0')).coord) == '20.0,10.0' assert repr(Coord(coord=(20.0, 10.0)).coord) == 'Coordinate(latitude=20.0, longitude=10.0)' # Decimal tests assert str(Coord(coord=(Decimal('20.0'), Decimal('10.0'))).coord) == '20.0,10.0' assert str(Coord(coord=(Decimal('20.000'), Decimal('10.000'))).coord) == '20.000,10.000' assert ( repr(Coord(coord=(Decimal('20.0'), Decimal('10.0'))).coord) == "Coordinate(latitude=Decimal('20.0'), longitude=Decimal('10.0'))" ) def test_eq(): # Float tests assert Coord(coord=(20.0, 10.0)).coord != Coord(coord='20.0,11.0').coord assert Coord(coord=('20.0, 10.0')).coord != Coord(coord='20.0,11.0').coord assert Coord(coord=('20.0, 10.0')).coord != Coord(coord='20.0,11.0').coord assert Coord(coord=(20.0, 10.0)).coord == Coord(coord='20.0,10.0').coord # Decimal tests assert Coord(coord=(Decimal('20.0'), Decimal('10.0'))).coord == Coord(coord='20.0,10.0').coord assert Coord(coord=(Decimal('20.0'), Decimal('10.0'))).coord == Coord(coord=(20.0, 10.0)).coord assert ( Coord(coord=(Decimal('20.0'), Decimal('10.0'))).coord != Coord(coord=(Decimal('20.0'), Decimal('11.0'))).coord ) assert ( Coord(coord=(Decimal('20.000'), Decimal('10.000'))).coord == Coord(coord=(Decimal('20.0'), Decimal('10.0'))).coord ) def test_hashable(): # Float tests assert hash(Coord(coord=(20.0, 10.0)).coord) == hash(Coord(coord=(20.0, 10.0)).coord) assert hash(Coord(coord=(20.0, 11.0)).coord) != hash(Coord(coord=(20.0, 10.0)).coord) # Decimal tests assert hash(Coord(coord=(Decimal('20.0'), Decimal('10.0'))).coord) == hash( Coord(coord=(Decimal('20.0'), Decimal('10.0'))).coord ) assert hash(Coord(coord=(Decimal('20.0'), Decimal('10.0'))).coord) == hash(Coord(coord=(20.0, 10.0)).coord) assert hash(Coord(coord=(Decimal('20.0'), Decimal('11.0'))).coord) != hash( Coord(coord=(Decimal('20.0'), Decimal('10.0'))).coord ) assert hash(Coord(coord=(Decimal('20.000'), Decimal('10.000'))).coord) == hash( Coord(coord=(Decimal('20.0'), Decimal('10.0'))).coord ) def test_json_schema(): class Model(BaseModel): value: Coordinate assert Model.model_json_schema(mode='validation')['$defs']['Coordinate'] == { 'properties': { 'latitude': { 'anyOf': [{'maximum': 90.0, 'minimum': -90.0, 'type': 'number'}, {'type': 'string'}], 'title': 'Latitude', }, 'longitude': { 'anyOf': [{'maximum': 180.0, 'minimum': -180.0, 'type': 'number'}, {'type': 'string'}], 'title': 'Longitude', }, }, 'required': ['latitude', 'longitude'], 'title': 'Coordinate', 'type': 'object', } assert Model.model_json_schema(mode='validation')['properties']['value'] == { 'anyOf': [ {'$ref': '#/$defs/Coordinate'}, { 'maxItems': 2, 'minItems': 2, 'prefixItems': [ {'anyOf': [{'type': 'number'}, {'type': 'string'}]}, {'anyOf': [{'type': 'number'}, {'type': 'string'}]}, ], 'type': 'array', }, {'type': 'string'}, ], 'title': 'Value', } assert Model.model_json_schema(mode='serialization') == { '$defs': { 'Coordinate': { 'properties': { 'latitude': { 'anyOf': [{'maximum': 90.0, 'minimum': -90.0, 'type': 'number'}, {'type': 'string'}], 'title': 'Latitude', }, 'longitude': { 'anyOf': [{'maximum': 180.0, 'minimum': -180.0, 'type': 'number'}, {'type': 'string'}], 'title': 'Longitude', }, }, 'required': ['latitude', 'longitude'], 'title': 'Coordinate', 'type': 'object', } }, 'properties': {'value': {'$ref': '#/$defs/Coordinate', 'title': 'Value'}}, 'required': ['value'], 'title': 'Model', 'type': 'object', } pydantic-extra-types-2.10.5/tests/test_country_code.py000066400000000000000000000074631501603200400231460ustar00rootroot00000000000000from string import printable import pytest from pydantic import BaseModel, ValidationError from pydantic_extra_types.country import ( CountryAlpha2, CountryAlpha3, CountryInfo, CountryNumericCode, CountryShortName, _index_by_alpha2, _index_by_alpha3, _index_by_numeric_code, _index_by_short_name, ) PARAMS_AMOUNT = 20 @pytest.fixture(scope='module', name='ProductAlpha2') def product_alpha2_fixture(): class Product(BaseModel): made_in: CountryAlpha2 return Product @pytest.fixture(scope='module', name='ProductAlpha3') def product_alpha3_fixture(): class Product(BaseModel): made_in: CountryAlpha3 return Product @pytest.fixture(scope='module', name='ProductShortName') def product_short_name_fixture(): class Product(BaseModel): made_in: CountryShortName return Product @pytest.fixture(scope='module', name='ProductNumericCode') def product_numeric_code_fixture(): class Product(BaseModel): made_in: CountryNumericCode return Product @pytest.mark.parametrize('alpha2, country_data', list(_index_by_alpha2().items())[:PARAMS_AMOUNT]) def test_valid_alpha2(alpha2: str, country_data: CountryInfo, ProductAlpha2): banana = ProductAlpha2(made_in=alpha2) assert banana.made_in == country_data.alpha2 assert banana.made_in.alpha3 == country_data.alpha3 assert banana.made_in.numeric_code == country_data.numeric_code assert banana.made_in.short_name == country_data.short_name @pytest.mark.parametrize('alpha2', list(printable)) def test_invalid_alpha2(alpha2: str, ProductAlpha2): with pytest.raises(ValidationError, match='Invalid country alpha2 code'): ProductAlpha2(made_in=alpha2) @pytest.mark.parametrize('alpha3, country_data', list(_index_by_alpha3().items())[:PARAMS_AMOUNT]) def test_valid_alpha3(alpha3: str, country_data: CountryInfo, ProductAlpha3): banana = ProductAlpha3(made_in=alpha3) assert banana.made_in == country_data.alpha3 assert banana.made_in.alpha2 == country_data.alpha2 assert banana.made_in.numeric_code == country_data.numeric_code assert banana.made_in.short_name == country_data.short_name @pytest.mark.parametrize('alpha3', list(printable)) def test_invalid_alpha3(alpha3: str, ProductAlpha3): with pytest.raises(ValidationError, match='Invalid country alpha3 code'): ProductAlpha3(made_in=alpha3) @pytest.mark.parametrize('short_name, country_data', list(_index_by_short_name().items())[:PARAMS_AMOUNT]) def test_valid_short_name(short_name: str, country_data: CountryInfo, ProductShortName): banana = ProductShortName(made_in=short_name) assert banana.made_in == country_data.short_name assert banana.made_in.alpha2 == country_data.alpha2 assert banana.made_in.alpha3 == country_data.alpha3 assert banana.made_in.numeric_code == country_data.numeric_code @pytest.mark.parametrize('short_name', list(printable)) def test_invalid_short_name(short_name: str, ProductShortName): with pytest.raises(ValidationError, match='Invalid country short name'): ProductShortName(made_in=short_name) @pytest.mark.parametrize('numeric_code, country_data', list(_index_by_numeric_code().items())[:PARAMS_AMOUNT]) def test_valid_numeric_code(numeric_code: str, country_data: CountryInfo, ProductNumericCode): banana = ProductNumericCode(made_in=numeric_code) assert banana.made_in == country_data.numeric_code assert banana.made_in.alpha2 == country_data.alpha2 assert banana.made_in.alpha3 == country_data.alpha3 assert banana.made_in.short_name == country_data.short_name @pytest.mark.parametrize('numeric_code', list(printable)) def test_invalid_numeric_code(numeric_code: str, ProductNumericCode): with pytest.raises(ValidationError, match='Invalid country numeric code'): ProductNumericCode(made_in=numeric_code) pydantic-extra-types-2.10.5/tests/test_currency_code.py000066400000000000000000000047021501603200400232660ustar00rootroot00000000000000import re import pycountry import pytest from pydantic import BaseModel, ValidationError from pydantic_extra_types import currency_code class ISO4217CheckingModel(BaseModel): currency: currency_code.ISO4217 class CurrencyCheckingModel(BaseModel): currency: currency_code.Currency forbidden_currencies = sorted(currency_code._CODES_FOR_BONDS_METAL_TESTING) @pytest.mark.parametrize('currency', map(lambda code: code.alpha_3, pycountry.currencies)) def test_ISO4217_code_ok(currency: str): model = ISO4217CheckingModel(currency=currency) assert model.currency == currency assert model.model_dump() == {'currency': currency} # test serialization @pytest.mark.parametrize('currency', ['USD', 'usd', 'UsD']) def test_ISO4217_code_ok_lower_case(currency: str): model = ISO4217CheckingModel(currency=currency) assert model.currency == currency.upper() @pytest.mark.parametrize( 'currency', filter( lambda code: code not in currency_code._CODES_FOR_BONDS_METAL_TESTING, map(lambda code: code.alpha_3, pycountry.currencies), ), ) def test_everyday_code_ok(currency: str): model = CurrencyCheckingModel(currency=currency) assert model.currency == currency assert model.model_dump() == {'currency': currency} # test serialization @pytest.mark.parametrize('currency', ['USD', 'usd', 'UsD']) def test_everyday_code_ok_lower_case(currency: str): model = CurrencyCheckingModel(currency=currency) assert model.currency == currency.upper() def test_ISO4217_fails(): with pytest.raises( ValidationError, match=re.escape( '1 validation error for ISO4217CheckingModel\ncurrency\n ' 'Invalid ISO 4217 currency code. See https://en.wikipedia.org/wiki/ISO_4217 ' "[type=ISO4217, input_value='OMG', input_type=str]" ), ): ISO4217CheckingModel(currency='OMG') @pytest.mark.parametrize('forbidden_currency', forbidden_currencies) def test_forbidden_everyday(forbidden_currency): with pytest.raises( ValidationError, match=re.escape( '1 validation error for CurrencyCheckingModel\ncurrency\n ' 'Invalid currency code. See https://en.wikipedia.org/wiki/ISO_4217 . ' 'Bonds, testing and precious metals codes are not allowed. ' f"[type=InvalidCurrency, input_value='{forbidden_currency}', input_type=str]" ), ): CurrencyCheckingModel(currency=forbidden_currency) pydantic-extra-types-2.10.5/tests/test_domain.py000066400000000000000000000045361501603200400217160ustar00rootroot00000000000000from typing import Any import pytest from pydantic import BaseModel, ValidationError from pydantic_extra_types.domain import DomainStr class MyModel(BaseModel): domain: DomainStr valid_domains = [ 'example.com', 'sub.example.com', 'sub-domain.example-site.co.uk', 'a.com', 'x.com', '1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.com', # Multiple subdomains ] invalid_domains = [ '', # Empty string 'example', # Missing TLD '.com', # Missing domain name 'example.', # Trailing dot 'exam ple.com', # Space in domain 'exa_mple.com', # Underscore in domain 'example.com.', # Trailing dot '192.168.1.23', # Ip address '192.168.1.0/23', # CIDR ] very_long_domains = [ 'a' * 249 + '.com', # Just under the limit 'a' * 250 + '.com', # At the limit 'a' * 251 + '.com', # Just over the limit 'sub1.sub2.sub3.sub4.sub5.sub6.sub7.sub8.sub9.sub10.sub11.sub12.sub13.sub14.sub15.sub16.sub17.sub18.sub19.sub20.sub21.sub22.sub23.sub24.sub25.sub26.sub27.sub28.sub29.sub30.sub31.sub32.sub33.extremely-long-domain-name-example-to-test-the-253-character-limit.com', ] invalid_domain_types = [1, 2, 1.1, 2.1, False, [], {}, None] @pytest.mark.parametrize('domain', valid_domains) def test_valid_domains(domain: str): try: MyModel.model_validate({'domain': domain}) assert len(domain) < 254 and len(domain) > 0 except ValidationError: assert len(domain) > 254 or len(domain) == 0 @pytest.mark.parametrize('domain', invalid_domains) def test_invalid_domains(domain: str): try: MyModel.model_validate({'domain': domain}) raise Exception( f"This test case has only samples that should raise a ValidationError. This domain '{domain}' did not raise such an exception." ) except ValidationError: # An error is expected on this test pass @pytest.mark.parametrize('domain', very_long_domains) def test_very_long_domains(domain: str): try: MyModel.model_validate({'domain': domain}) assert len(domain) < 254 and len(domain) > 0 except ValidationError: # An error is expected on this test pass @pytest.mark.parametrize('domain', invalid_domain_types) def test_invalid_domain_types(domain: Any): with pytest.raises(ValidationError, match='Value must be a string'): MyModel(domain=domain) pydantic-extra-types-2.10.5/tests/test_epoch.py000066400000000000000000000017251501603200400215420ustar00rootroot00000000000000import datetime import pytest from pydantic_extra_types import epoch @pytest.mark.parametrize('type_,cls_', [(int, epoch.Integer), (float, epoch.Number)], ids=['integer', 'number']) def test_type(type_, cls_): from pydantic import BaseModel class A(BaseModel): epoch: cls_ now = datetime.datetime.now(tz=datetime.timezone.utc) ts = type_(now.timestamp()) a = A.model_validate({'epoch': ts}) v = a.model_dump() assert v['epoch'] == ts b = A.model_construct(epoch=now) v = b.model_dump() assert v['epoch'] == ts c = A.model_validate(dict(epoch=ts)) v = c.model_dump() assert v['epoch'] == ts @pytest.mark.parametrize('cls_', [(epoch.Integer), (epoch.Number)], ids=['integer', 'number']) def test_schema(cls_): from pydantic import BaseModel class A(BaseModel): dt: cls_ v = A.model_json_schema() assert (dt := v['properties']['dt'])['type'] == cls_.TYPE and dt['format'] == 'date-time' pydantic-extra-types-2.10.5/tests/test_isbn.py000066400000000000000000000150061501603200400213740ustar00rootroot00000000000000from typing import Any import pytest from pydantic import BaseModel, ValidationError from pydantic_extra_types.isbn import ISBN class Book(BaseModel): isbn: ISBN isbn_length_test_cases = [ # Valid ISBNs ('8537809667', '9788537809662', True), # ISBN-10 as input ('9788537809662', '9788537809662', True), # ISBN-13 as input ('080442957X', '9780804429573', True), # ISBN-10 ending in "X" as input ('9788584390670', '9788584390670', True), # ISBN-13 Starting with 978 ('9790306406156', '9790306406156', True), # ISBN-13 starting with 979 # Invalid ISBNs ('97885843906701', None, False), # Length: 14 (Higher) ('978858439067', None, False), # Length: 12 (In Between) ('97885843906', None, False), # Length: 11 (In Between) ('978858439', None, False), # Length: 9 (Lower) ('', None, False), # Length: 0 (Lower) ] @pytest.mark.parametrize('input_isbn, output_isbn, valid', isbn_length_test_cases) def test_isbn_length(input_isbn: Any, output_isbn: str, valid: bool) -> None: if valid: assert Book(isbn=ISBN(input_isbn)).isbn == output_isbn else: with pytest.raises(ValidationError, match='isbn_length'): Book(isbn=ISBN(input_isbn)) isbn10_digits_test_cases = [ # Valid ISBNs ('8537809667', '9788537809662', True), # ISBN-10 as input ('080442957X', '9780804429573', True), # ISBN-10 ending in "X" as input # Invalid ISBNs ('@80442957X', None, False), # Non Integer in [0] position ('8@37809667', None, False), # Non Integer in [1] position ('85@7809667', None, False), # Non Integer in [2] position ('853@809667', None, False), # Non Integer in [3] position ('8537@09667', None, False), # Non Integer in [4] position ('85378@9667', None, False), # Non Integer in [5] position ('853780@667', None, False), # Non Integer in [6] position ('8537809@67', None, False), # Non Integer in [7] position ('85378096@7', None, False), # Non Integer in [8] position ('853780966@', None, False), # Non Integer or X in [9] position ] @pytest.mark.parametrize('input_isbn, output_isbn, valid', isbn10_digits_test_cases) def test_isbn10_digits(input_isbn: Any, output_isbn: str, valid: bool) -> None: if valid: assert Book(isbn=ISBN(input_isbn)).isbn == output_isbn else: with pytest.raises(ValidationError, match='isbn10_invalid_characters'): Book(isbn=ISBN(input_isbn)) isbn13_digits_test_cases = [ # Valid ISBNs ('9788537809662', '9788537809662', True), # ISBN-13 as input ('9780306406157', '9780306406157', True), # ISBN-13 as input ('9788584390670', '9788584390670', True), # ISBN-13 Starting with 978 ('9790306406156', '9790306406156', True), # ISBN-13 starting with 979 # Invalid ISBNs ('@788537809662', None, False), # Non Integer in [0] position ('9@88537809662', None, False), # Non Integer in [1] position ('97@8537809662', None, False), # Non Integer in [2] position ('978@537809662', None, False), # Non Integer in [3] position ('9788@37809662', None, False), # Non Integer in [4] position ('97885@7809662', None, False), # Non Integer in [5] position ('978853@809662', None, False), # Non Integer in [6] position ('9788537@09662', None, False), # Non Integer in [7] position ('97885378@9662', None, False), # Non Integer in [8] position ('978853780@662', None, False), # Non Integer in [9] position ('9788537809@62', None, False), # Non Integer in [10] position ('97885378096@2', None, False), # Non Integer in [11] position ('978853780966@', None, False), # Non Integer in [12] position ] @pytest.mark.parametrize('input_isbn, output_isbn, valid', isbn13_digits_test_cases) def test_isbn13_digits(input_isbn: Any, output_isbn: str, valid: bool) -> None: if valid: assert Book(isbn=ISBN(input_isbn)).isbn == output_isbn else: with pytest.raises(ValidationError, match='isbn13_invalid_characters'): Book(isbn=ISBN(input_isbn)) isbn13_early_digits_test_cases = [ # Valid ISBNs ('9780306406157', '9780306406157', True), # ISBN-13 as input ('9788584390670', '9788584390670', True), # ISBN-13 Starting with 978 ('9790306406156', '9790306406156', True), # ISBN-13 starting with 979 # Invalid ISBNs ('1788584390670', None, False), # Does not start with 978 or 979 ('9288584390670', None, False), # Does not start with 978 or 979 ('9738584390670', None, False), # Does not start with 978 or 979 ] @pytest.mark.parametrize('input_isbn, output_isbn, valid', isbn13_early_digits_test_cases) def test_isbn13_early_digits(input_isbn: Any, output_isbn: str, valid: bool) -> None: if valid: assert Book(isbn=ISBN(input_isbn)).isbn == output_isbn else: with pytest.raises(ValidationError, match='isbn_invalid_early_characters'): Book(isbn=ISBN(input_isbn)) isbn_last_digit_test_cases = [ # Valid ISBNs ('8537809667', '9788537809662', True), # ISBN-10 as input ('9788537809662', '9788537809662', True), # ISBN-13 as input ('080442957X', '9780804429573', True), # ISBN-10 ending in "X" as input ('9788584390670', '9788584390670', True), # ISBN-13 Starting with 978 ('9790306406156', '9790306406156', True), # ISBN-13 starting with 979 ('8306018060', '9788306018066', True), # ISBN-10 as input # Invalid ISBNs ('8537809663', None, False), # ISBN-10 as input with wrong last digit ('9788537809661', None, False), # ISBN-13 as input with wrong last digit ('080442953X', None, False), # ISBN-10 ending in "X" as input with wrong last digit ('9788584390671', None, False), # ISBN-13 Starting with 978 with wrong last digit ('9790306406155', None, False), # ISBN-13 starting with 979 with wrong last digit ] @pytest.mark.parametrize('input_isbn, output_isbn, valid', isbn_last_digit_test_cases) def test_isbn_last_digit(input_isbn: Any, output_isbn: str, valid: bool) -> None: if valid: assert Book(isbn=ISBN(input_isbn)).isbn == output_isbn else: with pytest.raises(ValidationError, match='isbn_invalid_digit_check_isbn'): Book(isbn=ISBN(input_isbn)) isbn_conversion_test_cases = [ # Valid ISBNs ('8537809667', '9788537809662'), ('080442957X', '9780804429573'), ('9788584390670', '9788584390670'), ('9790306406156', '9790306406156'), ] @pytest.mark.parametrize('input_isbn, output_isbn', isbn_conversion_test_cases) def test_isbn_conversion(input_isbn: Any, output_isbn: str) -> None: assert Book(isbn=ISBN(input_isbn)).isbn == output_isbn pydantic-extra-types-2.10.5/tests/test_json_schema.py000066400000000000000000000402251501603200400227330ustar00rootroot00000000000000from typing import Any, Dict, Union import pycountry import pytest from pydantic import BaseModel from typing_extensions import Annotated import pydantic_extra_types from pydantic_extra_types import epoch from pydantic_extra_types.color import Color from pydantic_extra_types.coordinate import Coordinate, Latitude, Longitude from pydantic_extra_types.country import CountryAlpha2, CountryAlpha3, CountryNumericCode, CountryShortName from pydantic_extra_types.currency_code import ISO4217, Currency from pydantic_extra_types.domain import DomainStr from pydantic_extra_types.isbn import ISBN from pydantic_extra_types.language_code import ISO639_3, ISO639_5, LanguageAlpha2, LanguageName from pydantic_extra_types.mac_address import MacAddress from pydantic_extra_types.mongo_object_id import MongoObjectId from pydantic_extra_types.payment import PaymentCardNumber from pydantic_extra_types.pendulum_dt import DateTime from pydantic_extra_types.phone_numbers import PhoneNumber, PhoneNumberValidator from pydantic_extra_types.s3 import S3Path from pydantic_extra_types.script_code import ISO_15924 from pydantic_extra_types.semantic_version import SemanticVersion from pydantic_extra_types.semver import _VersionPydanticAnnotation from pydantic_extra_types.timezone_name import TimeZoneName from pydantic_extra_types.ulid import ULID languages = [lang.alpha_3 for lang in pycountry.languages] language_families = [lang.alpha_3 for lang in pycountry.language_families] languages.sort() language_families.sort() currencies = [currency.alpha_3 for currency in pycountry.currencies] currencies.sort() everyday_currencies = [ currency.alpha_3 for currency in pycountry.currencies if currency.alpha_3 not in pydantic_extra_types.currency_code._CODES_FOR_BONDS_METAL_TESTING ] scripts = [script.alpha_4 for script in pycountry.scripts] timezone_names = TimeZoneName.allowed_values_list everyday_currencies.sort() AnyNumberRFC3966 = Annotated[Union[str, PhoneNumber], PhoneNumberValidator()] USNumberE164 = Annotated[ Union[str, PhoneNumber], PhoneNumberValidator( supported_regions=['US'], default_region='US', number_format='E164', ), ] @pytest.mark.parametrize( 'cls,expected', [ ( Color, { 'properties': {'x': {'format': 'color', 'title': 'X', 'type': 'string'}}, 'required': ['x'], 'title': 'Model', 'type': 'object', }, ), ( PaymentCardNumber, { 'properties': { 'x': { 'maxLength': 19, 'minLength': 12, 'title': 'X', 'type': 'string', } }, 'required': ['x'], 'title': 'Model', 'type': 'object', }, ), ( CountryAlpha2, { 'properties': {'x': {'pattern': '^\\w{2}$', 'title': 'X', 'type': 'string'}}, 'required': ['x'], 'title': 'Model', 'type': 'object', }, ), ( CountryAlpha3, { 'properties': {'x': {'pattern': '^\\w{3}$', 'title': 'X', 'type': 'string'}}, 'required': ['x'], 'title': 'Model', 'type': 'object', }, ), ( CountryNumericCode, { 'properties': {'x': {'pattern': '^[0-9]{3}$', 'title': 'X', 'type': 'string'}}, 'required': ['x'], 'title': 'Model', 'type': 'object', }, ), ( CountryShortName, { 'properties': {'x': {'title': 'X', 'type': 'string'}}, 'required': ['x'], 'title': 'Model', 'type': 'object', }, ), ( MacAddress, { 'properties': { 'x': { 'title': 'X', 'type': 'string', } }, 'required': ['x'], 'title': 'Model', 'type': 'object', }, ), ( Latitude, { 'properties': { 'x': { 'anyOf': [ {'maximum': 90.0, 'minimum': -90.0, 'type': 'number'}, {'type': 'string'}, ], 'title': 'X', } }, 'required': ['x'], 'title': 'Model', 'type': 'object', }, ), ( Longitude, { 'properties': { 'x': { 'anyOf': [ {'maximum': 180.0, 'minimum': -180.0, 'type': 'number'}, {'type': 'string'}, ], 'title': 'X', } }, 'required': ['x'], 'title': 'Model', 'type': 'object', }, ), ( Coordinate, { '$defs': { 'Coordinate': { 'properties': { 'latitude': { 'anyOf': [ {'maximum': 90.0, 'minimum': -90.0, 'type': 'number'}, {'type': 'string'}, ], 'title': 'Latitude', }, 'longitude': { 'anyOf': [ {'maximum': 180.0, 'minimum': -180.0, 'type': 'number'}, {'type': 'string'}, ], 'title': 'Longitude', }, }, 'required': ['latitude', 'longitude'], 'title': 'Coordinate', 'type': 'object', } }, 'properties': { 'x': { 'anyOf': [ {'$ref': '#/$defs/Coordinate'}, { 'maxItems': 2, 'minItems': 2, 'prefixItems': [ {'anyOf': [{'type': 'number'}, {'type': 'string'}]}, {'anyOf': [{'type': 'number'}, {'type': 'string'}]}, ], 'type': 'array', }, {'type': 'string'}, ], 'title': 'X', }, }, 'required': ['x'], 'title': 'Model', 'type': 'object', }, ), ( ULID, { 'properties': { 'x': { 'anyOf': [ {'type': 'integer'}, {'format': 'binary', 'type': 'string'}, {'type': 'string'}, {'format': 'uuid', 'type': 'string'}, ], 'title': 'X', } }, 'required': ['x'], 'title': 'Model', 'type': 'object', }, ), ( ISBN, { 'properties': { 'x': { 'title': 'X', 'type': 'string', } }, 'required': ['x'], 'title': 'Model', 'type': 'object', }, ), ( DateTime, { 'properties': {'x': {'format': 'date-time', 'title': 'X', 'type': 'string'}}, 'required': ['x'], 'title': 'Model', 'type': 'object', }, ), ( LanguageAlpha2, { 'properties': {'x': {'pattern': '^\\w{2}$', 'title': 'X', 'type': 'string'}}, 'required': ['x'], 'title': 'Model', 'type': 'object', }, ), ( LanguageName, { 'properties': {'x': {'title': 'X', 'type': 'string'}}, 'required': ['x'], 'title': 'Model', 'type': 'object', }, ), ( ISO639_3, { 'properties': { 'x': { 'title': 'X', 'type': 'string', 'enum': languages, 'maxLength': 3, 'minLength': 3, } }, 'required': ['x'], 'title': 'Model', 'type': 'object', }, ), ( ISO639_5, { 'properties': { 'x': { 'title': 'X', 'type': 'string', 'enum': language_families, 'maxLength': 3, 'minLength': 3, } }, 'required': ['x'], 'title': 'Model', 'type': 'object', }, ), ( ISO4217, { 'properties': { 'x': { 'title': 'X', 'type': 'string', 'enum': currencies, 'maxLength': 3, 'minLength': 3, } }, 'required': ['x'], 'title': 'Model', 'type': 'object', }, ), ( Currency, { 'properties': { 'x': { 'title': 'X', 'type': 'string', 'enum': everyday_currencies, 'maxLength': 3, 'minLength': 3, } }, 'required': ['x'], 'title': 'Model', 'type': 'object', }, ), ( ISO_15924, { 'properties': { 'x': { 'title': 'X', 'type': 'string', 'enum': scripts, 'maxLength': 4, 'minLength': 4, } }, 'required': ['x'], 'title': 'Model', 'type': 'object', }, ), ( SemanticVersion, { 'properties': { 'x': { 'title': 'X', 'type': 'string', 'pattern': r'^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$', } }, 'required': ['x'], 'title': 'Model', 'type': 'object', }, ), ( TimeZoneName, { 'properties': { 'x': { 'title': 'X', 'type': 'string', 'enum': timezone_names, 'minLength': 1, } }, 'required': ['x'], 'title': 'Model', 'type': 'object', }, ), ( _VersionPydanticAnnotation, { 'properties': {'x': {'title': 'X', 'type': 'string'}}, 'required': ['x'], 'title': 'Model', 'type': 'object', }, ), ( PhoneNumber, { 'title': 'Model', 'type': 'object', 'properties': { 'x': { 'title': 'X', 'type': 'string', 'format': 'phone', } }, 'required': ['x'], }, ), ( AnyNumberRFC3966, { 'title': 'Model', 'type': 'object', 'properties': { 'x': { 'title': 'X', 'type': 'string', 'format': 'phone', } }, 'required': ['x'], }, ), ( USNumberE164, { 'title': 'Model', 'type': 'object', 'properties': { 'x': { 'title': 'X', 'type': 'string', 'format': 'phone', } }, 'required': ['x'], }, ), ( S3Path, { 'title': 'Model', 'type': 'object', 'properties': { 'x': { 'pattern': '^s3://([^/]+)/(.*?([^/]+)/?)$', 'title': 'X', 'type': 'string', }, }, 'required': [ 'x', ], }, ), ( DomainStr, { 'title': 'Model', 'type': 'object', 'properties': { 'x': { 'title': 'X', 'type': 'string', }, }, 'required': [ 'x', ], }, ), ( epoch.Integer, { 'title': 'Model', 'type': 'object', 'properties': { 'x': { 'title': 'X', 'type': 'integer', 'format': 'date-time', }, }, 'required': [ 'x', ], }, ), ( epoch.Number, { 'title': 'Model', 'type': 'object', 'properties': { 'x': { 'title': 'X', 'type': 'number', 'format': 'date-time', }, }, 'required': [ 'x', ], }, ), ( MongoObjectId, { 'title': 'Model', 'type': 'object', 'properties': { 'x': { 'maxLength': MongoObjectId.OBJECT_ID_LENGTH, 'minLength': MongoObjectId.OBJECT_ID_LENGTH, 'title': 'X', 'type': 'string', }, }, 'required': ['x'], }, ), ], ) def test_json_schema(cls: Any, expected: Dict[str, Any]) -> None: """Test the model_json_schema implementation for all extra types.""" class Model(BaseModel): x: cls assert Model.model_json_schema() == expected pydantic-extra-types-2.10.5/tests/test_language_codes.py000066400000000000000000000066241501603200400234070ustar00rootroot00000000000000import re from string import printable import pycountry import pytest from pydantic import BaseModel, ValidationError from pydantic_extra_types import language_code from pydantic_extra_types.language_code import ( LanguageAlpha2, LanguageInfo, LanguageName, _index_by_alpha2, _index_by_alpha3, _index_by_name, ) PARAMS_AMOUNT = 20 @pytest.fixture(scope='module', name='MovieAlpha2') def movie_alpha2_fixture(): class Movie(BaseModel): audio_lang: LanguageAlpha2 return Movie @pytest.fixture(scope='module', name='MovieName') def movie_name_fixture(): class Movie(BaseModel): audio_lang: LanguageName return Movie class ISO3CheckingModel(BaseModel): lang: language_code.ISO639_3 class ISO5CheckingModel(BaseModel): lang: language_code.ISO639_5 @pytest.mark.parametrize('alpha2, language_data', list(_index_by_alpha2().items())) def test_valid_alpha2(alpha2: str, language_data: LanguageInfo, MovieAlpha2): the_godfather = MovieAlpha2(audio_lang=alpha2) assert the_godfather.audio_lang == language_data.alpha2 assert the_godfather.audio_lang.alpha3 == language_data.alpha3 assert the_godfather.audio_lang.name == language_data.name @pytest.mark.parametrize('alpha2', list(printable) + list(_index_by_alpha3().keys())[:PARAMS_AMOUNT]) def test_invalid_alpha2(alpha2: str, MovieAlpha2): with pytest.raises(ValidationError, match='Invalid language alpha2 code'): MovieAlpha2(audio_lang=alpha2) @pytest.mark.parametrize('name, language_data', list(_index_by_name().items())[:PARAMS_AMOUNT]) def test_valid_name(name: str, language_data: LanguageInfo, MovieName): the_godfather = MovieName(audio_lang=name) assert the_godfather.audio_lang == language_data.name assert the_godfather.audio_lang.alpha2 == language_data.alpha2 assert the_godfather.audio_lang.alpha3 == language_data.alpha3 @pytest.mark.parametrize('name', set(printable) - {'E', 'U'}) # E and U are valid language codes def test_invalid_name(name: str, MovieName): with pytest.raises(ValidationError, match='Invalid language name'): MovieName(audio_lang=name) @pytest.mark.parametrize('lang', map(lambda lang: lang.alpha_3, pycountry.languages)) def test_iso_ISO639_3_code_ok(lang: str): model = ISO3CheckingModel(lang=lang) assert model.lang == lang assert model.model_dump() == {'lang': lang} # test serialization @pytest.mark.parametrize('lang', map(lambda lang: lang.alpha_3, pycountry.language_families)) def test_iso_639_5_code_ok(lang: str): model = ISO5CheckingModel(lang=lang) assert model.lang == lang assert model.model_dump() == {'lang': lang} # test serialization def test_iso3_language_fail(): with pytest.raises( ValidationError, match=re.escape( '1 validation error for ISO3CheckingModel\nlang\n ' 'Invalid ISO 639-3 language code. ' "See https://en.wikipedia.org/wiki/ISO_639-3 [type=ISO649_3, input_value='LOL', input_type=str]" ), ): ISO3CheckingModel(lang='LOL') def test_iso5_language_fail(): with pytest.raises( ValidationError, match=re.escape( '1 validation error for ISO5CheckingModel\nlang\n ' 'Invalid ISO 639-5 language code. ' "See https://en.wikipedia.org/wiki/ISO_639-5 [type=ISO649_5, input_value='LOL', input_type=str]" ), ): ISO5CheckingModel(lang='LOL') pydantic-extra-types-2.10.5/tests/test_mac_address.py000066400000000000000000000124201501603200400227030ustar00rootroot00000000000000from typing import Any import pytest from pydantic import BaseModel, ValidationError from pydantic_extra_types.mac_address import MacAddress class Network(BaseModel): mac_address: MacAddress @pytest.mark.parametrize( 'mac_address, result, valid', [ # Valid MAC addresses ('00:00:5e:00:53:01', '00:00:5e:00:53:01', True), ('02:00:5e:10:00:00:00:01', '02:00:5e:10:00:00:00:01', True), ( '00:00:00:00:fe:80:00:00:00:00:00:00:02:00:5e:10:00:00:00:01', '00:00:00:00:fe:80:00:00:00:00:00:00:02:00:5e:10:00:00:00:01', True, ), ('00-00-5e-00-53-01', '00:00:5e:00:53:01', True), ('02-00-5e-10-00-00-00-01', '02:00:5e:10:00:00:00:01', True), ( '00-00-00-00-fe-80-00-00-00-00-00-00-02-00-5e-10-00-00-00-01', '00:00:00:00:fe:80:00:00:00:00:00:00:02:00:5e:10:00:00:00:01', True, ), ('0000.5e00.5301', '00:00:5e:00:53:01', True), ('0200.5e10.0000.0001', '02:00:5e:10:00:00:00:01', True), ( '0000.0000.fe80.0000.0000.0000.0200.5e10.0000.0001', '00:00:00:00:fe:80:00:00:00:00:00:00:02:00:5e:10:00:00:00:01', True, ), # Invalid MAC addresses ('0200.5e10.0000.001', None, False), ('00-00-5e-00-53-0', None, False), ('00:00:5e:00:53:1', None, False), ('02:00:5e:10:00:00:00:1', None, False), ('00:00:00:00:fe:80:00:00:00:00:00:00:02:00:5e:10:00:00:00:1', None, False), ('0200.5e10.0000.001', None, False), # Invalid length ('00-00-5e-00-53-0', None, False), # Missing character ('00:00:5e:00:53:1', None, False), # Missing leading zero ('00:00:5g:00:53:01', None, False), # Invalid hex digit 'g' ('00.00.5e.0.3.01.0.0.5e.0.53.01', None, False), ('00-00-5e-00-53-01:', None, False), # Extra separator at the end ('00000.5e000.5301', None, False), ('000.5e0.530001', None, False), ('0000.5e#0./301', None, False), (b'12.!4.5!.7/.#G.AB......', None, False), ('12.!4.5!.7/.#G.AB', None, False), ('00-00-5e-00-53-01-', None, False), # Extra separator at the end ('00.00.5e.00.53.01.', None, False), # Extra separator at the end ('00:00:5e:00:53:', None, False), # Incomplete MAC address (float(12345678910111213), None, False), ], ) def test_format_for_mac_address(mac_address: Any, result: str, valid: bool): if valid: assert Network(mac_address=MacAddress(mac_address)).mac_address == result else: with pytest.raises(ValidationError, match='format'): Network(mac_address=MacAddress(mac_address)) @pytest.mark.parametrize( 'mac_address, result, valid', [ # Valid MAC addresses ('00:00:5e:00:53:01', '00:00:5e:00:53:01', True), ('02:00:5e:10:00:00:00:01', '02:00:5e:10:00:00:00:01', True), ( '00:00:00:00:fe:80:00:00:00:00:00:00:02:00:5e:10:00:00:00:01', '00:00:00:00:fe:80:00:00:00:00:00:00:02:00:5e:10:00:00:00:01', True, ), ('00-00-5e-00-53-01', '00:00:5e:00:53:01', True), ('02-00-5e-10-00-00-00-01', '02:00:5e:10:00:00:00:01', True), ( '00-00-00-00-fe-80-00-00-00-00-00-00-02-00-5e-10-00-00-00-01', '00:00:00:00:fe:80:00:00:00:00:00:00:02:00:5e:10:00:00:00:01', True, ), ('0000.5e00.5301', '00:00:5e:00:53:01', True), ('0200.5e10.0000.0001', '02:00:5e:10:00:00:00:01', True), ( '0000.0000.fe80.0000.0000.0000.0200.5e10.0000.0001', '00:00:00:00:fe:80:00:00:00:00:00:00:02:00:5e:10:00:00:00:01', True, ), # Invalid MAC addresses ('0', None, False), ('00:00:00', None, False), ('00-00-5e-00-53-01-01', None, False), ('0000.0000.fe80.0000.0000.0000.0200.5e10.0000.0001.0000.0001', None, False), ], ) def test_length_for_mac_address(mac_address: str, result: str, valid: bool): if valid: assert Network(mac_address=MacAddress(mac_address)).mac_address == result else: with pytest.raises(ValueError, match='Length'): Network(mac_address=MacAddress(mac_address)) @pytest.mark.parametrize( 'mac_address, valid', [ # Valid MAC addresses ('00:00:5e:00:53:01', True), (MacAddress('00:00:5e:00:53:01'), True), # Invalid MAC addresses (0, False), (['00:00:00'], False), ], ) def test_type_for_mac_address(mac_address: Any, valid: bool): if valid: Network(mac_address=MacAddress(mac_address)) else: with pytest.raises(ValidationError, match='MAC address must be 14'): Network(mac_address=MacAddress(mac_address)) def test_model_validation(): class Model(BaseModel): mac_address: MacAddress assert Model(mac_address='00:00:5e:00:53:01').mac_address == '00:00:5e:00:53:01' with pytest.raises(ValidationError) as exc_info: Model(mac_address='1234') assert exc_info.value.errors() == [ { 'ctx': {'mac_address': '1234', 'required_length': 14}, 'input': '1234', 'loc': ('mac_address',), 'msg': 'Length for a 1234 MAC address must be 14', 'type': 'mac_address_len', } ] pydantic-extra-types-2.10.5/tests/test_mongo_object_id.py000066400000000000000000000046271501603200400235710ustar00rootroot00000000000000"""Tests for the mongo_object_id module.""" import pytest from pydantic import BaseModel, GetCoreSchemaHandler, ValidationError from pydantic.json_schema import JsonSchemaMode from pydantic_extra_types.mongo_object_id import MongoObjectId class MongoDocument(BaseModel): object_id: MongoObjectId @pytest.mark.parametrize( 'object_id, result, valid', [ # Valid ObjectId for str format ('611827f2878b88b49ebb69fc', '611827f2878b88b49ebb69fc', True), ('611827f2878b88b49ebb69fd', '611827f2878b88b49ebb69fd', True), # Invalid ObjectId for str format ('611827f2878b88b49ebb69f', None, False), # Invalid ObjectId (short length) ('611827f2878b88b49ebb69fca', None, False), # Invalid ObjectId (long length) # Valid ObjectId for bytes format ], ) def test_format_for_object_id(object_id: str, result: str, valid: bool) -> None: """Test the MongoObjectId validation.""" if valid: assert str(MongoDocument(object_id=object_id).object_id) == result else: with pytest.raises(ValidationError): MongoDocument(object_id=object_id) with pytest.raises( ValueError, match=f"Invalid ObjectId {object_id} has to be 24 characters long and in the format '5f9f2f4b9d3c5a7b4c7e6c1d'.", ): MongoObjectId.validate(object_id) @pytest.mark.parametrize( 'schema_mode', [ 'validation', 'serialization', ], ) def test_json_schema(schema_mode: JsonSchemaMode) -> None: """Test the MongoObjectId model_json_schema implementation.""" expected_json_schema = { 'properties': { 'object_id': { 'maxLength': MongoObjectId.OBJECT_ID_LENGTH, 'minLength': MongoObjectId.OBJECT_ID_LENGTH, 'title': 'Object Id', 'type': 'string', } }, 'required': ['object_id'], 'title': 'MongoDocument', 'type': 'object', } assert MongoDocument.model_json_schema(mode=schema_mode) == expected_json_schema def test_get_pydantic_core_schema() -> None: """Test the __get_pydantic_core_schema__ method override.""" schema = MongoObjectId.__get_pydantic_core_schema__(MongoObjectId, GetCoreSchemaHandler()) assert isinstance(schema, dict) assert 'json_schema' in schema assert 'python_schema' in schema assert schema['json_schema']['type'] == 'str' pydantic-extra-types-2.10.5/tests/test_path.py000066400000000000000000000074151501603200400214020ustar00rootroot00000000000000import os import pathlib import pytest from pydantic import BaseModel from pydantic_extra_types.path import ( ExistingPath, ResolvedDirectoryPath, ResolvedExistingPath, ResolvedFilePath, ResolvedNewPath, ) class File(BaseModel): file: ResolvedFilePath class Directory(BaseModel): directory: ResolvedDirectoryPath class NewPath(BaseModel): new_path: ResolvedNewPath class Existing(BaseModel): existing: ExistingPath class ResolvedExisting(BaseModel): resolved_existing: ResolvedExistingPath @pytest.fixture def absolute_file_path(tmp_path: pathlib.Path) -> pathlib.Path: directory = tmp_path / 'test-relative' directory.mkdir() file_path = directory / 'test-relative.txt' file_path.touch() return file_path @pytest.fixture def relative_file_path(absolute_file_path: pathlib.Path) -> pathlib.Path: return pathlib.Path(os.path.relpath(absolute_file_path, os.getcwd())) @pytest.fixture def absolute_directory_path(tmp_path: pathlib.Path) -> pathlib.Path: directory = tmp_path / 'test-relative' directory.mkdir() return directory @pytest.fixture def relative_directory_path(absolute_directory_path: pathlib.Path) -> pathlib.Path: return pathlib.Path(os.path.relpath(absolute_directory_path, os.getcwd())) @pytest.fixture def absolute_new_path(tmp_path: pathlib.Path) -> pathlib.Path: return tmp_path / 'test-relative' @pytest.fixture def relative_new_path(absolute_new_path: pathlib.Path) -> pathlib.Path: return pathlib.Path(os.path.relpath(absolute_new_path, os.getcwd())) def test_relative_file(absolute_file_path: pathlib.Path, relative_file_path: pathlib.Path): file = File(file=relative_file_path) assert file.file == absolute_file_path def test_absolute_file(absolute_file_path: pathlib.Path): file = File(file=absolute_file_path) assert file.file == absolute_file_path def test_relative_directory(absolute_directory_path: pathlib.Path, relative_directory_path: pathlib.Path): directory = Directory(directory=relative_directory_path) assert directory.directory == absolute_directory_path def test_absolute_directory(absolute_directory_path: pathlib.Path): directory = Directory(directory=absolute_directory_path) assert directory.directory == absolute_directory_path def test_relative_new_path(absolute_new_path: pathlib.Path, relative_new_path: pathlib.Path): new_path = NewPath(new_path=relative_new_path) assert new_path.new_path == absolute_new_path def test_absolute_new_path(absolute_new_path: pathlib.Path): new_path = NewPath(new_path=absolute_new_path) assert new_path.new_path == absolute_new_path @pytest.mark.parametrize( ('pass_fixture', 'expect_fixture'), ( ('relative_file_path', 'relative_file_path'), ('absolute_file_path', 'absolute_file_path'), ('relative_directory_path', 'relative_directory_path'), ('absolute_directory_path', 'absolute_directory_path'), ), ) def test_existing_path(request: pytest.FixtureRequest, pass_fixture: str, expect_fixture: str): existing = Existing(existing=request.getfixturevalue(pass_fixture)) assert existing.existing == request.getfixturevalue(expect_fixture) @pytest.mark.parametrize( ('pass_fixture', 'expect_fixture'), ( ('relative_file_path', 'absolute_file_path'), ('absolute_file_path', 'absolute_file_path'), ('relative_directory_path', 'absolute_directory_path'), ('absolute_directory_path', 'absolute_directory_path'), ), ) def test_resolved_existing_path(request: pytest.FixtureRequest, pass_fixture: str, expect_fixture: str): resolved_existing = ResolvedExisting(resolved_existing=request.getfixturevalue(pass_fixture)) assert resolved_existing.resolved_existing == request.getfixturevalue(expect_fixture) pydantic-extra-types-2.10.5/tests/test_pendulum_dt.py000066400000000000000000000314661501603200400227710ustar00rootroot00000000000000from datetime import date, datetime, timedelta from datetime import timezone as tz import pendulum import pytest from pydantic import BaseModel, TypeAdapter, ValidationError from pydantic_extra_types.pendulum_dt import Date, DateTime, Duration UTC = tz.utc DtTypeAdapter = TypeAdapter(datetime) class DtModel(BaseModel): dt: DateTime class DateTimeNonStrict(DateTime, strict=False): pass class DtModelNotStrict(BaseModel): dt: DateTimeNonStrict class DateModel(BaseModel): d: Date class DurationModel(BaseModel): delta_t: Duration @pytest.mark.parametrize( 'instance', [ pendulum.now(), datetime.now(), datetime.now(UTC), ], ) def test_existing_instance(instance): """Verifies that constructing a model with an existing pendulum dt doesn't throw.""" model = DtModel(dt=instance) if isinstance(instance, datetime): assert model.dt == pendulum.instance(instance) if instance.tzinfo is None and isinstance(instance, datetime): instance = model.dt.replace(tzinfo=UTC) # pendulum defaults to UTC dt = model.dt else: assert model.dt == instance dt = model.dt assert dt.day == instance.day assert dt.month == instance.month assert dt.year == instance.year assert dt.hour == instance.hour assert dt.minute == instance.minute assert dt.second == instance.second assert dt.microsecond == instance.microsecond assert isinstance(dt, pendulum.DateTime) assert type(dt) is DateTime if dt.tzinfo != instance.tzinfo: assert dt.tzinfo.utcoffset(dt) == instance.tzinfo.utcoffset(instance) @pytest.mark.parametrize( 'instance', [ pendulum.today(), date.today(), ], ) def test_pendulum_date_existing_instance(instance): """Verifies that constructing a model with an existing pendulum date doesn't throw.""" model = DateModel(d=instance) if isinstance(instance, datetime): assert model.d == pendulum.instance(instance).date() else: assert model.d == instance d = model.d assert d.day == instance.day assert d.month == instance.month assert d.year == instance.year assert isinstance(d, pendulum.Date) assert type(d) is Date @pytest.mark.parametrize( 'instance', [ pendulum.duration(days=42, hours=13, minutes=37), pendulum.duration(days=-42, hours=13, minutes=37), pendulum.duration(weeks=97), pendulum.duration(days=463), pendulum.duration(milliseconds=90122), pendulum.duration(microseconds=90122), pendulum.duration( years=2, months=3, weeks=19, days=1, hours=25, seconds=732, milliseconds=123, microseconds=1324, ), timedelta(days=42, hours=13, minutes=37), timedelta(days=-42, hours=13, minutes=37), timedelta( weeks=19, days=1, hours=25, seconds=732, milliseconds=123, microseconds=1324, ), ], ) def test_duration_timedelta__existing_instance(instance): """Verifies that constructing a model with an existing pendulum duration doesn't throw.""" model = DurationModel(delta_t=instance) assert model.delta_t.total_seconds() == instance.total_seconds() assert isinstance(model.delta_t, pendulum.Duration) assert model.delta_t @pytest.mark.parametrize( 'dt', [ pendulum.now().to_iso8601_string(), pendulum.now().to_w3c_string(), ], ) def test_pendulum_dt_from_serialized(dt): """Verifies that building an instance from serialized, well-formed strings decode properly.""" dt_actual = pendulum.parse(dt) model = DtModel(dt=dt) assert model.dt == dt_actual assert type(model.dt) is DateTime assert isinstance(model.dt, pendulum.DateTime) @pytest.mark.parametrize( 'dt', [ pendulum.now().to_iso8601_string(), pendulum.now().to_w3c_string(), ], ) def test_pendulum_dt_from_serialized_preserves_timezones(dt): """Verifies that building an instance from serialized, well-formed strings decode properly and preserves the timezone information across all of the Pendulum DateTime properties. Regression test for pydantic/pydantic-extra-types#188. """ dt_actual = pendulum.parse(dt) model = DtModel(dt=dt) assert model.dt == dt_actual assert type(model.dt) is DateTime assert isinstance(model.dt, pendulum.DateTime) assert model.dt.tzinfo is not None assert model.dt.tzinfo.utcoffset(model.dt) == dt_actual.tzinfo.utcoffset(dt_actual) assert model.dt.tz is not None assert model.dt.tz.utcoffset(model.dt) == dt_actual.tz.utcoffset(dt_actual) assert model.dt.timezone is not None assert model.dt.timezone.utcoffset(model.dt) == dt_actual.timezone.utcoffset(dt_actual) @pytest.mark.parametrize( 'dt', [ pendulum.now().to_iso8601_string(), pendulum.now().to_w3c_string(), 'Sat Oct 11 17:13:46 UTC 2003', # date util parsing pendulum.now().to_iso8601_string()[:5], # actualy valid or pendulum.parse(dt, strict=False) would fail here ], ) def test_pendulum_dt_not_strict_from_serialized(dt): """Verifies that building an instance from serialized, well-formed strings decode properly.""" dt_actual = pendulum.parse(dt, strict=False) model = DtModelNotStrict(dt=dt) assert model.dt == dt_actual assert type(model.dt) is DateTime assert isinstance(model.dt, pendulum.DateTime) @pytest.mark.parametrize( 'dt', [ pendulum.now().to_iso8601_string(), pendulum.now().to_w3c_string(), 1718096578, 1718096578.5, -5, -5.5, float('-0'), '1718096578', '1718096578.5', '-5', '-5.5', '-0', '-0.0', '+0.0', '+1718096578.5', float('-2e10') - 1.0, float('2e10') + 1.0, -2e10 - 1, 2e10 + 1, ], ) def test_pendulum_dt_from_str_unix_timestamp(dt): """Verifies that building an instance from serialized, well-formed strings decode properly.""" dt_actual = pendulum.instance(DtTypeAdapter.validate_python(dt)) model = DtModel(dt=dt) assert model.dt == dt_actual assert type(model.dt) is DateTime assert isinstance(model.dt, pendulum.DateTime) @pytest.mark.parametrize( 'dt', [ 1718096578, 1718096578.5, -5, -5.5, float('-0'), '1718096578', '1718096578.5', '-5', '-5.5', '-0', '-0.0', '+0.0', '+1718096578.5', float('-2e10') - 1.0, float('2e10') + 1.0, -2e10 - 1, 2e10 + 1, ], ) def test_pendulum_dt_from_str_unix_timestamp_is_utc(dt): """Verifies that without timezone information, it is coerced to UTC. As in pendulum""" model = DtModel(dt=dt) assert model.dt.tzinfo.tzname(model.dt) == 'UTC' @pytest.mark.parametrize( 'd', [ pendulum.now().date().isoformat(), pendulum.now().to_w3c_string(), pendulum.now().to_iso8601_string(), ], ) def test_pendulum_date_from_serialized(d): """Verifies that building an instance from serialized, well-formed strings decode properly.""" date_actual = pendulum.parse(d).date() model = DateModel(d=d) assert model.d == date_actual assert type(model.d) is Date assert isinstance(model.d, pendulum.Date) @pytest.mark.parametrize( 'delta_t_str', [ 'P3.14D', 'PT404H', 'P1DT25H', 'P2W', 'P10Y10M10D', ], ) def test_pendulum_duration_from_serialized(delta_t_str): """Verifies that building an instance from serialized, well-formed strings decode properly.""" true_delta_t = pendulum.parse(delta_t_str) model = DurationModel(delta_t=delta_t_str) assert model.delta_t == true_delta_t assert type(model.delta_t) is Duration assert isinstance(model.delta_t, pendulum.Duration) @pytest.mark.parametrize( 'duration', [ Duration(months=1), Duration(weeks=1), Duration(milliseconds=1), Duration(microseconds=1), Duration(days=1), Duration(hours=1), Duration(minutes=1), Duration(seconds=1), Duration(months=2, days=5), Duration(weeks=3, hours=12), Duration(days=10, minutes=30), Duration(weeks=1, days=2, hours=3), Duration(seconds=30, milliseconds=500), ], ) def test_pendulum_duration_serialization_roundtrip(duration): adapter = TypeAdapter(Duration) python_serialized = adapter.dump_python(duration) json_serialized = adapter.dump_json(duration) deserialized = TypeAdapter.validate_json(adapter, json_serialized) assert deserialized == python_serialized == duration assert deserialized.years == python_serialized.years == duration.years assert deserialized.months == python_serialized.months == duration.months def get_invalid_dt_common(): return [ None, 'malformed', 'P10Y10M10D', float('inf'), float('-inf'), 'inf', '-inf', 'INF', '-INF', '+inf', 'Infinity', '+Infinity', '-Infinity', 'INFINITY', '+INFINITY', '-INFINITY', 'infinity', '+infinity', '-infinity', float('nan'), 'nan', 'NaN', 'NAN', '+nan', '-nan', ] dt_strict = get_invalid_dt_common() dt_strict.append(pendulum.now().to_iso8601_string()[:5]) @pytest.mark.parametrize( 'dt', dt_strict, ) def test_pendulum_dt_malformed(dt): """Verifies that the instance fails to validate if malformed dt is passed.""" with pytest.raises(ValidationError): DtModel(dt=dt) @pytest.mark.parametrize('dt', get_invalid_dt_common()) def test_pendulum_dt_non_strict_malformed(dt): """Verifies that the instance fails to validate if malformed dt are passed.""" with pytest.raises(ValidationError): DtModelNotStrict(dt=dt) @pytest.mark.parametrize( 'invalid_value', [None, 'malformed', pendulum.today().to_iso8601_string()[:5], 'P10Y10M10D'], ) def test_pendulum_date_malformed(invalid_value): """Verifies that the instance fails to validate if malformed date are passed.""" with pytest.raises(ValidationError): DateModel(d=invalid_value) @pytest.mark.parametrize( 'delta_t', [ None, 'malformed', pendulum.today().to_iso8601_string()[:5], 42, '12m', '2021-01-01T12:00:00', ], ) def test_pendulum_duration_malformed(delta_t): """Verifies that the instance fails to validate if malformed durations are passed.""" with pytest.raises(ValidationError): DurationModel(delta_t=delta_t) @pytest.mark.parametrize( 'input_type, value, is_instance', [ (Date, '2021-01-01', pendulum.Date), (Date, date(2021, 1, 1), pendulum.Date), (Date, pendulum.date(2021, 1, 1), pendulum.Date), (DateTime, '2021-01-01T12:00:00', pendulum.DateTime), (DateTime, datetime(2021, 1, 1, 12, 0, 0), pendulum.DateTime), (DateTime, pendulum.datetime(2021, 1, 1, 12, 0, 0), pendulum.DateTime), (Duration, 'P1DT25H', pendulum.Duration), (Duration, timedelta(days=1, hours=25), pendulum.Duration), (Duration, pendulum.duration(days=1, hours=25), pendulum.Duration), ], ) def test_date_type_adapter(input_type: type, value, is_instance: type): validated = TypeAdapter(input_type).validate_python(value) assert type(validated) is input_type assert isinstance(validated, input_type) assert isinstance(validated, is_instance) def test_pendulum_duration_months_are_preserved(): m = DurationModel(delta_t=pendulum.Duration(months=1)) assert m.delta_t.months == 1 @pytest.mark.parametrize( 'zero_duration', [ Duration(), Duration(years=0, months=0, days=0, hours=0, minutes=0, seconds=0), Duration(0), pendulum.duration(), ], ) def test_zero_duration_serialization_and_validation(zero_duration): """Zero durations should serialize as 'P0D' and round-trip without error.""" model = DurationModel(delta_t=zero_duration) json_dump = model.model_dump_json() assert json_dump == '{"delta_t":"P0D"}' loaded = DurationModel.model_validate_json(json_dump) assert loaded.delta_t == zero_duration assert isinstance(loaded.delta_t, Duration) def test_zero_duration_from_string(): """'P0D' string should be accepted and produce a zero Duration.""" model = DurationModel(delta_t='P0D') assert model.delta_t == Duration() assert isinstance(model.delta_t, Duration) def test_invalid_zero_duration_string(): """'P' is not a valid ISO 8601 duration and should raise a validation error.""" with pytest.raises(ValidationError): DurationModel(delta_t='P') pydantic-extra-types-2.10.5/tests/test_phone_numbers.py000066400000000000000000000045471501603200400233150ustar00rootroot00000000000000from typing import Any import pytest from pydantic import BaseModel, ValidationError from pydantic_extra_types.phone_numbers import PhoneNumber class Something(BaseModel): phone_number: PhoneNumber # Note: the 555 area code will result in an invalid phone number def test_valid_phone_number() -> None: Something(phone_number='+1 901 555 1212') def test_when_extension_provided() -> None: Something(phone_number='+1 901 555 1212 ext 12533') @pytest.mark.parametrize('invalid_number', ['', '123', 12, None, object(), '55 121']) def test_invalid_phone_number(invalid_number: Any) -> None: with pytest.raises(ValidationError): Something(phone_number=invalid_number) def test_formats_phone_number() -> None: result = Something(phone_number='+1 901 555 1212 ext 12533') assert result.phone_number == 'tel:+1-901-555-1212;ext=12533' def test_supported_regions() -> None: assert PhoneNumber.supported_regions == [] PhoneNumber.supported_regions = ['US'] assert Something(phone_number='+1 901 555 1212') with pytest.raises(ValidationError, match='value is not from a supported region'): Something(phone_number='+44 20 7946 0958') USPhoneNumber = PhoneNumber() USPhoneNumber.supported_regions = ['US'] assert USPhoneNumber.supported_regions == ['US'] assert Something(phone_number='+1 901 555 1212') with pytest.raises(ValidationError, match='value is not from a supported region'): Something(phone_number='+44 20 7946 0958') def test_parse_error() -> None: with pytest.raises(ValidationError, match='value is not a valid phone number'): Something(phone_number='555 1212') def test_parsed_but_not_a_valid_number() -> None: with pytest.raises(ValidationError, match='value is not a valid phone number'): Something(phone_number='+1 555-1212') def test_hashes() -> None: assert hash(PhoneNumber('555-1212')) == hash(PhoneNumber('555-1212')) assert hash(PhoneNumber('555-1212')) == hash('555-1212') assert hash(PhoneNumber('555-1212')) != hash('555-1213') assert hash(PhoneNumber('555-1212')) != hash(PhoneNumber('555-1213')) def test_eq() -> None: assert PhoneNumber('555-1212') == PhoneNumber('555-1212') assert PhoneNumber('555-1212') == '555-1212' assert PhoneNumber('555-1212') != '555-1213' assert PhoneNumber('555-1212') != PhoneNumber('555-1213') pydantic-extra-types-2.10.5/tests/test_phone_numbers_validator.py000066400000000000000000000071531501603200400253560ustar00rootroot00000000000000from typing import Any, Optional, Union import phonenumbers import pytest from phonenumbers import PhoneNumber from pydantic import BaseModel, TypeAdapter, ValidationError from typing_extensions import Annotated from pydantic_extra_types.phone_numbers import PhoneNumberValidator Number = Annotated[Union[str, PhoneNumber], PhoneNumberValidator()] NANumber = Annotated[ Union[str, PhoneNumber], PhoneNumberValidator( supported_regions=['US', 'CA'], default_region='US', ), ] UKNumber = Annotated[ Union[str, PhoneNumber], PhoneNumberValidator( supported_regions=['GB'], default_region='GB', number_format='E164', ), ] number_adapter = TypeAdapter(Number) class Numbers(BaseModel): phone_number: Optional[Number] = None na_number: Optional[NANumber] = None uk_number: Optional[UKNumber] = None def test_validator_constructor() -> None: PhoneNumberValidator() PhoneNumberValidator(supported_regions=['US', 'CA'], default_region='US') PhoneNumberValidator(supported_regions=['GB'], default_region='GB', number_format='E164') with pytest.raises(ValueError, match='Invalid default region code: XX'): PhoneNumberValidator(default_region='XX') with pytest.raises(ValueError, match='Invalid number format: XX'): PhoneNumberValidator(number_format='XX') with pytest.raises(ValueError, match='Invalid supported region code: XX'): PhoneNumberValidator(supported_regions=['XX']) # Note: the 555 area code will result in an invalid phone number def test_valid_phone_number() -> None: Numbers(phone_number='+1 901 555 1212') def test_when_extension_provided() -> None: Numbers(phone_number='+1 901 555 1212 ext 12533') def test_when_phonenumber_instance() -> None: phone_number = phonenumbers.parse('+1 901 555 1212', region='US') numbers = Numbers(phone_number=phone_number) assert numbers.phone_number == 'tel:+1-901-555-1212' # Additional validation is still performed on the instance with pytest.raises(ValidationError, match='value is not from a supported region'): Numbers(uk_number=phone_number) @pytest.mark.parametrize('invalid_number', ['', '123', 12, object(), '55 121']) def test_invalid_phone_number(invalid_number: Any) -> None: # Use a TypeAdapter to test the validation logic for None otherwise # optional fields will not attempt to validate with pytest.raises(ValidationError, match='value is not a valid phone number'): number_adapter.validate_python(invalid_number) def test_formats_phone_number() -> None: result = Numbers(phone_number='+1 901 555 1212 ext 12533', uk_number='+44 20 7946 0958') assert result.phone_number == 'tel:+1-901-555-1212;ext=12533' assert result.uk_number == '+442079460958' def test_default_region() -> None: result = Numbers(na_number='901 555 1212') assert result.na_number == 'tel:+1-901-555-1212' with pytest.raises(ValidationError, match='value is not a valid phone number'): Numbers(phone_number='901 555 1212') def test_supported_regions() -> None: assert Numbers(na_number='+1 901 555 1212') assert Numbers(uk_number='+44 20 7946 0958') with pytest.raises(ValidationError, match='value is not from a supported region'): Numbers(na_number='+44 20 7946 0958') def test_parse_error() -> None: with pytest.raises(ValidationError, match='value is not a valid phone number'): Numbers(phone_number='555 1212') def test_parsed_but_not_a_valid_number() -> None: with pytest.raises(ValidationError, match='value is not a valid phone number'): Numbers(phone_number='+1 555-1212') pydantic-extra-types-2.10.5/tests/test_routing_number.py000066400000000000000000000030641501603200400235010ustar00rootroot00000000000000from typing import Any import pytest from pydantic import BaseModel, ValidationError from pydantic_extra_types.routing_number import ABARoutingNumber class Model(BaseModel): routing_number: ABARoutingNumber @pytest.mark.parametrize('routing_number', [12, None, object(), 123456789]) def test_invalid_routing_number_string(routing_number: Any) -> None: with pytest.raises(ValidationError) as validation_error: Model(routing_number=routing_number) assert validation_error.match('Input should be a valid string') @pytest.mark.parametrize('routing_number', ['', '123', '1234567890']) def test_invalid_routing_number_length(routing_number: Any) -> None: with pytest.raises(ValidationError) as validation_error: Model(routing_number=routing_number) assert validation_error.match(r'String should have at (most|least) 9 characters') @pytest.mark.parametrize('routing_number', ['122105154', '122235822', '123103723', '074900781']) def test_invalid_routing_number(routing_number: Any) -> None: with pytest.raises(ValidationError) as validation_error: Model(routing_number=routing_number) assert validation_error.match('Incorrect ABA routing transit number') @pytest.mark.parametrize('routing_number', ['122105155', '122235821', '123103729', '074900783']) def test_valid_routing_number(routing_number: str) -> None: Model(routing_number=routing_number) def test_raises_error_when_not_a_string() -> None: with pytest.raises(ValidationError, match='routing number is not all digits'): Model(routing_number='A12210515') pydantic-extra-types-2.10.5/tests/test_s3.py000066400000000000000000000117641501603200400207750ustar00rootroot00000000000000import pytest from pydantic import BaseModel, ValidationError from pydantic_extra_types.s3 import S3Path class S3Check(BaseModel): path: S3Path @pytest.mark.parametrize( 'raw,bucket,key,last_key', [ ( 's3://my-data-bucket/2023/08/29/sales-report.csv', 'my-data-bucket', '2023/08/29/sales-report.csv', 'sales-report.csv', ), ( 's3://logs-bucket/app-logs/production/2024/07/01/application-log.txt', 'logs-bucket', 'app-logs/production/2024/07/01/application-log.txt', 'application-log.txt', ), ( 's3://backup-storage/user_data/john_doe/photos/photo-2024-08-15.jpg', 'backup-storage', 'user_data/john_doe/photos/photo-2024-08-15.jpg', 'photo-2024-08-15.jpg', ), ( 's3://analytics-bucket/weekly-reports/Q3/2023/week-35-summary.pdf', 'analytics-bucket', 'weekly-reports/Q3/2023/week-35-summary.pdf', 'week-35-summary.pdf', ), ( 's3://project-data/docs/presentations/quarterly_review.pptx', 'project-data', 'docs/presentations/quarterly_review.pptx', 'quarterly_review.pptx', ), ( 's3://my-music-archive/genres/rock/2024/favorite-songs.mp3', 'my-music-archive', 'genres/rock/2024/favorite-songs.mp3', 'favorite-songs.mp3', ), ( 's3://video-uploads/movies/2024/03/action/thriller/movie-trailer.mp4', 'video-uploads', 'movies/2024/03/action/thriller/movie-trailer.mp4', 'movie-trailer.mp4', ), ( 's3://company-files/legal/contracts/contract-2023-09-01.pdf', 'company-files', 'legal/contracts/contract-2023-09-01.pdf', 'contract-2023-09-01.pdf', ), ( 's3://dev-environment/source-code/release_v1.0.2.zip', 'dev-environment', 'source-code/release_v1.0.2.zip', 'release_v1.0.2.zip', ), ( 's3://public-bucket/open-data/geojson/maps/city_boundaries.geojson', 'public-bucket', 'open-data/geojson/maps/city_boundaries.geojson', 'city_boundaries.geojson', ), ( 's3://image-storage/2024/portfolio/shoots/wedding/couple_photo_12.jpg', 'image-storage', '2024/portfolio/shoots/wedding/couple_photo_12.jpg', 'couple_photo_12.jpg', ), ( 's3://finance-data/reports/2024/Q2/income_statement.xlsx', 'finance-data', 'reports/2024/Q2/income_statement.xlsx', 'income_statement.xlsx', ), ( 's3://training-data/nlp/corpora/english/2023/text_corpus.txt', 'training-data', 'nlp/corpora/english/2023/text_corpus.txt', 'text_corpus.txt', ), ( 's3://ecommerce-backup/2024/transactions/august/orders_2024_08_28.csv', 'ecommerce-backup', '2024/transactions/august/orders_2024_08_28.csv', 'orders_2024_08_28.csv', ), ( 's3://gaming-assets/3d_models/characters/hero/model_v5.obj', 'gaming-assets', '3d_models/characters/hero/model_v5.obj', 'model_v5.obj', ), ( 's3://iot-sensor-data/2024/temperature_sensors/sensor_42_readings.csv', 'iot-sensor-data', '2024/temperature_sensors/sensor_42_readings.csv', 'sensor_42_readings.csv', ), ( 's3://user-uploads/avatars/user123/avatar_2024_08_29.png', 'user-uploads', 'avatars/user123/avatar_2024_08_29.png', 'avatar_2024_08_29.png', ), ( 's3://media-library/podcasts/2023/episode_45.mp3', 'media-library', 'podcasts/2023/episode_45.mp3', 'episode_45.mp3', ), ( 's3://logs-bucket/security/firewall-logs/2024/08/failed_attempts.log', 'logs-bucket', 'security/firewall-logs/2024/08/failed_attempts.log', 'failed_attempts.log', ), ( 's3://data-warehouse/financials/quarterly/2024/Q1/profit_loss.csv', 'data-warehouse', 'financials/quarterly/2024/Q1/profit_loss.csv', 'profit_loss.csv', ), ( 's3://data-warehouse/financials/quarterly/2024/Q1', 'data-warehouse', 'financials/quarterly/2024/Q1', 'Q1', ), ], ) def test_s3(raw: str, bucket: str, key: str, last_key: str): model = S3Check(path=raw) assert model.path == S3Path(raw) assert model.path.bucket == bucket assert model.path.key == key assert model.path.last_key == last_key def test_wrong_s3(): with pytest.raises(ValidationError): S3Check(path='s3/ok') pydantic-extra-types-2.10.5/tests/test_scripts.py000066400000000000000000000031221501603200400221240ustar00rootroot00000000000000import re import pycountry import pytest from pydantic import BaseModel, ValidationError from pydantic_extra_types.script_code import ISO_15924 class ScriptCheck(BaseModel): script: ISO_15924 @pytest.mark.parametrize('script', map(lambda lang: lang.alpha_4, pycountry.scripts)) def test_ISO_15924_code_ok(script: str): model = ScriptCheck(script=script) assert model.script == script assert str(model.script) == script assert model.model_dump() == {'script': script} # test serialization def test_ISO_15924_code_fail_not_enought_letters(): with pytest.raises( ValidationError, match=re.escape( '1 validation error for ScriptCheck\nscript\n ' "String should have at least 4 characters [type=string_too_short, input_value='X', input_type=str]\n" ), ): ScriptCheck(script='X') def test_ISO_15924_code_fail_too_much_letters(): with pytest.raises( ValidationError, match=re.escape( '1 validation error for ScriptCheck\nscript\n ' "String should have at most 4 characters [type=string_too_long, input_value='Klingon', input_type=str]" ), ): ScriptCheck(script='Klingon') def test_ISO_15924_code_fail_not_existing(): with pytest.raises( ValidationError, match=re.escape( '1 validation error for ScriptCheck\nscript\n ' 'Invalid ISO 15924 script code. See https://en.wikipedia.org/wiki/ISO_15924 ' "[type=ISO_15924, input_value='Klin', input_type=str]" ), ): ScriptCheck(script='Klin') pydantic-extra-types-2.10.5/tests/test_semantic_version.py000066400000000000000000000057261501603200400240210ustar00rootroot00000000000000import pytest import semver from pydantic import BaseModel, ValidationError from pydantic_extra_types.semantic_version import SemanticVersion @pytest.fixture(scope='module', name='SemanticVersionObject') def application_object_fixture(): class Application(BaseModel): version: SemanticVersion return Application @pytest.mark.parametrize( 'constructor', [str, semver.Version.parse, SemanticVersion.parse], ids=['str', 'semver.Version', 'SemanticVersion'] ) @pytest.mark.parametrize( 'version', [ '0.0.4', '1.2.3', '10.20.30', '1.1.2-prerelease+meta', '1.1.2+meta', '1.1.2+meta-valid', '1.0.0-alpha', '1.0.0-beta', '1.0.0-alpha.beta', '1.0.0-alpha.beta.1', '1.0.0-alpha.1', '1.0.0-alpha0.valid', '1.0.0-alpha.0valid', '1.0.0-alpha-a.b-c-somethinglong+build.1-aef.1-its-okay', '1.0.0-rc.1+build.1', '2.0.0-rc.1+build.123', '1.2.3-beta', '10.2.3-DEV-SNAPSHOT', '1.2.3-SNAPSHOT-123', '1.0.0', '2.0.0', '1.1.7', '2.0.0+build.1848', '2.0.1-alpha.1227', '1.0.0-alpha+beta', '1.2.3----RC-SNAPSHOT.12.9.1--.12+788', '1.2.3----R-S.12.9.1--.12+meta', '1.2.3----RC-SNAPSHOT.12.9.1--.12', '1.0.0+0.build.1-rc.10000aaa-kk-0.1', '99999999999999999999999.999999999999999999.99999999999999999', '1.0.0-0A.is.legal', ], ) def test_valid_semantic_version(SemanticVersionObject, constructor, version): application = SemanticVersionObject(version=constructor(version)) assert application.version assert application.model_dump() == {'version': version} @pytest.mark.parametrize( 'invalid_version', [ '', '1', '1.2', '1.2.3-0123', '1.2.3-0123.0123', '1.1.2+.123', '+invalid', '-invalid', '-invalid+invalid', '-invalid.01', 'alpha', 'alpha.beta', 'alpha.beta.1', 'alpha.1', 'alpha+beta', 'alpha_beta', 'alpha.', 'alpha..', 'beta', '1.0.0-alpha_beta', '-alpha.', '1.0.0-alpha..', '1.0.0-alpha..1', '1.0.0-alpha...1', '1.0.0-alpha....1', '1.0.0-alpha.....1', '1.0.0-alpha......1', '1.0.0-alpha.......1', '01.1.1', '1.01.1', '1.1.01', '1.2', '1.2.3.DEV', '1.2-SNAPSHOT', '1.2.31.2.3----RC-SNAPSHOT.12.09.1--..12+788', '1.2-RC-SNAPSHOT', '-1.0.3-gamma+b7718', '+justmeta', '9.8.7+meta+meta', '9.8.7-whatever+meta+meta', '99999999999999999999999.999999999999999999.99999999999999999----RC-SNAPSHOT.12.09.1--------------------------------..12', ], ) def test_invalid_semantic_version(SemanticVersionObject, invalid_version): with pytest.raises(ValidationError): SemanticVersionObject(version=invalid_version) pydantic-extra-types-2.10.5/tests/test_semver.py000066400000000000000000000007661501603200400217510ustar00rootroot00000000000000import pytest from pydantic import BaseModel from pydantic_extra_types.semver import _VersionPydanticAnnotation class SomethingWithAVersion(BaseModel): version: _VersionPydanticAnnotation def test_valid_semver() -> None: SomethingWithAVersion(version='1.2.3') def test_valid_semver_with_prerelease() -> None: SomethingWithAVersion(version='1.2.3-alpha.1') def test_invalid_semver() -> None: with pytest.raises(ValueError): SomethingWithAVersion(version='jim.was.here') pydantic-extra-types-2.10.5/tests/test_timezone_names.py000066400000000000000000000144421501603200400234610ustar00rootroot00000000000000import re import pytest import pytz from pydantic import BaseModel, ValidationError from pydantic_core import PydanticCustomError from pydantic_extra_types.timezone_name import TimeZoneName, TimeZoneNameSettings, timezone_name_settings has_zone_info = True try: from zoneinfo import available_timezones except ImportError: has_zone_info = False pytz_zones_bad = [(zone.lower(), zone) for zone in pytz.all_timezones] pytz_zones_bad.extend([(f' {zone}', zone) for zone in pytz.all_timezones_set]) class TZNameCheck(BaseModel): timezone_name: TimeZoneName @timezone_name_settings(strict=False) class TZNonStrict(TimeZoneName): pass class NonStrictTzName(BaseModel): timezone_name: TZNonStrict @pytest.mark.parametrize('zone', pytz.all_timezones) def test_all_timezones_non_strict_pytz(zone): assert TZNameCheck(timezone_name=zone).timezone_name == zone assert NonStrictTzName(timezone_name=zone).timezone_name == zone @pytest.mark.parametrize('zone', pytz_zones_bad) def test_all_timezones_pytz_lower(zone): assert NonStrictTzName(timezone_name=zone[0]).timezone_name == zone[1] def test_fail_non_existing_timezone(): with pytest.raises( ValidationError, match=re.escape( '1 validation error for TZNameCheck\n' 'timezone_name\n ' 'Invalid timezone name. ' "[type=TimeZoneName, input_value='mars', input_type=str]" ), ): TZNameCheck(timezone_name='mars') with pytest.raises( ValidationError, match=re.escape( '1 validation error for NonStrictTzName\n' 'timezone_name\n ' 'Invalid timezone name. ' "[type=TimeZoneName, input_value='mars', input_type=str]" ), ): NonStrictTzName(timezone_name='mars') if has_zone_info: zones = list(available_timezones()) zones.sort() zones_bad = [(zone.lower(), zone) for zone in zones] @pytest.mark.parametrize('zone', zones) def test_all_timezones_zone_info(zone): assert TZNameCheck(timezone_name=zone).timezone_name == zone assert NonStrictTzName(timezone_name=zone).timezone_name == zone @pytest.mark.parametrize('zone', zones_bad) def test_all_timezones_zone_info_NonStrict(zone): assert NonStrictTzName(timezone_name=zone[0]).timezone_name == zone[1] def test_timezone_name_settings_metaclass(): class TestStrictTZ(TimeZoneName, strict=True, metaclass=TimeZoneNameSettings): pass class TestNonStrictTZ(TimeZoneName, strict=False, metaclass=TimeZoneNameSettings): pass assert TestStrictTZ.strict is True assert TestNonStrictTZ.strict is False # Test default value class TestDefaultStrictTZ(TimeZoneName, metaclass=TimeZoneNameSettings): pass assert TestDefaultStrictTZ.strict is True def test_timezone_name_validation(): valid_tz = 'America/New_York' invalid_tz = 'Invalid/Timezone' assert TimeZoneName._validate(valid_tz, None) == valid_tz with pytest.raises(PydanticCustomError): TimeZoneName._validate(invalid_tz, None) assert TZNonStrict._validate(valid_tz.lower(), None) == valid_tz assert TZNonStrict._validate(f' {valid_tz} ', None) == valid_tz with pytest.raises(PydanticCustomError): TZNonStrict._validate(invalid_tz, None) def test_timezone_name_pydantic_core_schema(): schema = TimeZoneName.__get_pydantic_core_schema__(TimeZoneName, None) assert isinstance(schema, dict) assert schema['type'] == 'function-after' assert 'function' in schema assert 'schema' in schema assert schema['schema']['type'] == 'str' assert schema['schema']['min_length'] == 1 def test_timezone_name_pydantic_json_schema(): core_schema = TimeZoneName.__get_pydantic_core_schema__(TimeZoneName, None) class MockJsonSchemaHandler: def __call__(self, schema): return {'type': 'string'} handler = MockJsonSchemaHandler() json_schema = TimeZoneName.__get_pydantic_json_schema__(core_schema, handler) assert 'enum' in json_schema assert isinstance(json_schema['enum'], list) assert len(json_schema['enum']) > 0 def test_timezone_name_repr(): tz = TimeZoneName('America/New_York') assert repr(tz) == "'America/New_York'" assert str(tz) == 'America/New_York' def test_timezone_name_allowed_values(): assert isinstance(TimeZoneName.allowed_values, set) assert len(TimeZoneName.allowed_values) > 0 assert all(isinstance(tz, str) for tz in TimeZoneName.allowed_values) assert isinstance(TimeZoneName.allowed_values_list, list) assert len(TimeZoneName.allowed_values_list) > 0 assert all(isinstance(tz, str) for tz in TimeZoneName.allowed_values_list) assert isinstance(TimeZoneName.allowed_values_upper_to_correct, dict) assert len(TimeZoneName.allowed_values_upper_to_correct) > 0 assert all( isinstance(k, str) and isinstance(v, str) for k, v in TimeZoneName.allowed_values_upper_to_correct.items() ) def test_timezone_name_inheritance(): class CustomTZ(TimeZoneName, metaclass=TimeZoneNameSettings): pass assert issubclass(CustomTZ, TimeZoneName) assert issubclass(CustomTZ, str) assert isinstance(CustomTZ('America/New_York'), (CustomTZ, TimeZoneName, str)) def test_timezone_name_string_operations(): tz = TimeZoneName('America/New_York') assert tz.upper() == 'AMERICA/NEW_YORK' assert tz.lower() == 'america/new_york' assert tz.strip() == 'America/New_York' assert f'{tz} Time' == 'America/New_York Time' assert tz.startswith('America') assert tz.endswith('York') def test_timezone_name_comparison(): tz1 = TimeZoneName('America/New_York') tz2 = TimeZoneName('Europe/London') tz3 = TimeZoneName('America/New_York') assert tz1 == tz3 assert tz1 != tz2 assert tz1 < tz2 # Alphabetical comparison assert tz2 > tz1 assert tz1 <= tz3 assert tz1 >= tz3 def test_timezone_name_hash(): tz1 = TimeZoneName('America/New_York') tz2 = TimeZoneName('America/New_York') tz3 = TimeZoneName('Europe/London') assert hash(tz1) == hash(tz2) assert hash(tz1) != hash(tz3) tz_set = {tz1, tz2, tz3} assert len(tz_set) == 2 def test_timezone_name_slots(): tz = TimeZoneName('America/New_York') with pytest.raises(AttributeError): tz.new_attribute = 'test' pydantic-extra-types-2.10.5/tests/test_types_color.py000066400000000000000000000174711501603200400230130ustar00rootroot00000000000000from datetime import datetime import pytest from pydantic import BaseModel, ValidationError from pydantic_core import PydanticCustomError from pydantic_extra_types.color import Color @pytest.mark.parametrize( 'raw_color, as_tuple', [ # named colors ('aliceblue', (240, 248, 255)), ('Antiquewhite', (250, 235, 215)), ('transparent', (0, 0, 0, 0)), ('#000000', (0, 0, 0)), ('#DAB', (221, 170, 187)), ('#dab', (221, 170, 187)), ('#000', (0, 0, 0)), ('0x797979', (121, 121, 121)), ('0x777', (119, 119, 119)), ('0x777777', (119, 119, 119)), ('0x777777cc', (119, 119, 119, 0.8)), ('777', (119, 119, 119)), ('777c', (119, 119, 119, 0.8)), (' 777', (119, 119, 119)), ('777 ', (119, 119, 119)), (' 777 ', (119, 119, 119)), ((0, 0, 128), (0, 0, 128)), ([0, 0, 128], (0, 0, 128)), ((0, 0, 205, 1.0), (0, 0, 205)), ((0, 0, 205, 0.5), (0, 0, 205, 0.5)), ('rgb(0, 0, 205)', (0, 0, 205)), ('rgb(0, 0, 205.2)', (0, 0, 205)), ('rgb(0, 0.2, 205)', (0, 0, 205)), ('rgba(0, 0, 128, 0.6)', (0, 0, 128, 0.6)), ('rgba(0, 0, 128, .6)', (0, 0, 128, 0.6)), ('rgba(0, 0, 128, 60%)', (0, 0, 128, 0.6)), (' rgba(0, 0, 128,0.6) ', (0, 0, 128, 0.6)), ('rgba(00,0,128,0.6 )', (0, 0, 128, 0.6)), ('rgba(0, 0, 128, 0)', (0, 0, 128, 0)), ('rgba(0, 0, 128, 1)', (0, 0, 128)), ('rgb(0 0.2 205)', (0, 0, 205)), ('rgb(0 0.2 205 / 0.6)', (0, 0, 205, 0.6)), ('rgb(0 0.2 205 / 60%)', (0, 0, 205, 0.6)), ('rgba(0 0 128)', (0, 0, 128)), ('rgba(0 0 128 / 0.6)', (0, 0, 128, 0.6)), ('rgba(0 0 128 / 60%)', (0, 0, 128, 0.6)), ('hsl(270, 60%, 70%)', (178, 133, 224)), ('hsl(180, 100%, 50%)', (0, 255, 255)), ('hsl(630, 60%, 70%)', (178, 133, 224)), ('hsl(270deg, 60%, 70%)', (178, 133, 224)), ('hsl(.75turn, 60%, 70%)', (178, 133, 224)), ('hsl(-.25turn, 60%, 70%)', (178, 133, 224)), ('hsl(-0.25turn, 60%, 70%)', (178, 133, 224)), ('hsl(4.71238rad, 60%, 70%)', (178, 133, 224)), ('hsl(10.9955rad, 60%, 70%)', (178, 133, 224)), ('hsl(270, 60%, 50%, .15)', (127, 51, 204, 0.15)), ('hsl(270.00deg, 60%, 50%, 15%)', (127, 51, 204, 0.15)), ('hsl(630 60% 70%)', (178, 133, 224)), ('hsl(270 60% 50% / .15)', (127, 51, 204, 0.15)), ('hsla(630, 60%, 70%)', (178, 133, 224)), ('hsla(630 60% 70%)', (178, 133, 224)), ('hsla(270 60% 50% / .15)', (127, 51, 204, 0.15)), ], ) def test_color_success(raw_color, as_tuple): c = Color(raw_color) assert c.as_rgb_tuple() == as_tuple assert c.original() == raw_color @pytest.mark.parametrize( 'color', [ # named colors 'nosuchname', 'chucknorris', # hex '#0000000', 'x000', # rgb/rgba tuples (256, 256, 256), (128, 128, 128, 0.5, 128), (0, 0, 'x'), (0, 0, 0, 1.5), (0, 0, 0, 'x'), (0, 0, 1280), (0, 0, 1205, 0.1), (0, 0, 1128, 0.5), (0, 0, 1128, -0.5), (0, 0, 1128, 1.5), ({}, 0, 0), # rgb/rgba strings 'rgb(0, 0, 1205)', 'rgb(0, 0, 1128)', 'rgb(0, 0, 200 / 0.2)', 'rgb(72 122 18, 0.3)', 'rgba(0, 0, 11205, 0.1)', 'rgba(0, 0, 128, 11.5)', 'rgba(0, 0, 128 / 11.5)', 'rgba(72 122 18 0.3)', # hsl/hsla strings 'hsl(180, 101%, 50%)', 'hsl(72 122 18 / 0.3)', 'hsl(630 60% 70%, 0.3)', 'hsla(72 122 18 / 0.3)', # neither a tuple, not a string datetime(2017, 10, 5, 19, 47, 7), object, range(10), ], ) def test_color_fail(color): with pytest.raises(PydanticCustomError) as exc_info: Color(color) assert exc_info.value.type == 'color_error' def test_model_validation(): class Model(BaseModel): color: Color assert Model(color='red').color.as_hex() == '#f00' assert Model(color=Color('red')).color.as_hex() == '#f00' with pytest.raises(ValidationError) as exc_info: Model(color='snot') # insert_assert(exc_info.value.errors()) assert exc_info.value.errors() == [ { 'type': 'color_error', 'loc': ('color',), 'msg': 'value is not a valid color: string not recognised as a valid color', 'input': 'snot', } ] def test_as_rgb(): assert Color('bad').as_rgb() == 'rgb(187, 170, 221)' assert Color((1, 2, 3, 0.123456)).as_rgb() == 'rgba(1, 2, 3, 0.12)' assert Color((1, 2, 3, 0.1)).as_rgb() == 'rgba(1, 2, 3, 0.1)' def test_as_rgb_tuple(): assert Color((1, 2, 3)).as_rgb_tuple(alpha=None) == (1, 2, 3) assert Color((1, 2, 3, 1)).as_rgb_tuple(alpha=None) == (1, 2, 3) assert Color((1, 2, 3, 0.3)).as_rgb_tuple(alpha=None) == (1, 2, 3, 0.3) assert Color((1, 2, 3, 0.3)).as_rgb_tuple(alpha=None) == (1, 2, 3, 0.3) assert Color((1, 2, 3)).as_rgb_tuple(alpha=False) == (1, 2, 3) assert Color((1, 2, 3, 0.3)).as_rgb_tuple(alpha=False) == (1, 2, 3) assert Color((1, 2, 3)).as_rgb_tuple(alpha=True) == (1, 2, 3, 1) assert Color((1, 2, 3, 0.3)).as_rgb_tuple(alpha=True) == (1, 2, 3, 0.3) def test_as_hsl(): assert Color('bad').as_hsl() == 'hsl(260, 43%, 77%)' assert Color((1, 2, 3, 0.123456)).as_hsl() == 'hsl(210, 50%, 1%, 0.12)' assert Color('hsl(260, 43%, 77%)').as_hsl() == 'hsl(260, 43%, 77%)' def test_as_hsl_tuple(): c = Color('016997') h, s, l_, a = c.as_hsl_tuple(alpha=True) assert h == pytest.approx(0.551, rel=0.01) assert s == pytest.approx(0.986, rel=0.01) assert l_ == pytest.approx(0.298, rel=0.01) assert a == 1 assert c.as_hsl_tuple(alpha=False) == c.as_hsl_tuple(alpha=None) == (h, s, l_) c = Color((3, 40, 50, 0.5)) hsla = c.as_hsl_tuple(alpha=None) assert len(hsla) == 4 assert hsla[3] == 0.5 def test_as_hex(): assert Color((1, 2, 3)).as_hex() == '#010203' assert Color((119, 119, 119)).as_hex() == '#777' assert Color((119, 0, 238)).as_hex() == '#70e' assert Color('B0B').as_hex() == '#b0b' assert Color((1, 2, 3, 0.123456)).as_hex() == '#0102031f' assert Color((1, 2, 3, 0.1)).as_hex() == '#0102031a' def test_as_hex_long(): assert Color((1, 2, 3)).as_hex(format='long') == '#010203' assert Color((119, 119, 119)).as_hex(format='long') == '#777777' assert Color((119, 0, 238)).as_hex(format='long') == '#7700ee' assert Color('B0B').as_hex(format='long') == '#bb00bb' assert Color('#0102031a').as_hex(format='long') == '#0102031a' def test_as_named(): assert Color((0, 255, 255)).as_named() == 'cyan' assert Color('#808000').as_named() == 'olive' assert Color('hsl(180, 100%, 50%)').as_named() == 'cyan' assert Color((240, 248, 255)).as_named() == 'aliceblue' with pytest.raises(ValueError) as exc_info: Color((1, 2, 3)).as_named() assert exc_info.value.args[0] == 'no named color found, use fallback=True, as_hex() or as_rgb()' assert Color((1, 2, 3)).as_named(fallback=True) == '#010203' assert Color((1, 2, 3, 0.1)).as_named(fallback=True) == '#0102031a' def test_str_repr(): assert str(Color('red')) == 'red' assert repr(Color('red')) == "Color('red', rgb=(255, 0, 0))" assert str(Color((1, 2, 3))) == '#010203' assert repr(Color((1, 2, 3))) == "Color('#010203', rgb=(1, 2, 3))" def test_eq(): assert Color('red') == Color('red') assert Color('red') != Color('blue') assert Color('red') != 'red' assert Color('red') == Color((255, 0, 0)) assert Color('red') != Color((0, 0, 255)) def test_color_hashable(): assert hash(Color('red')) != hash(Color('blue')) assert hash(Color('red')) == hash(Color((255, 0, 0))) assert hash(Color('red')) != hash(Color((255, 0, 0, 0.5))) pydantic-extra-types-2.10.5/tests/test_types_payment.py000066400000000000000000000154161501603200400233470ustar00rootroot00000000000000from collections import namedtuple from typing import Any import pytest from pydantic import BaseModel, ValidationError from pydantic_core._pydantic_core import PydanticCustomError from pydantic_extra_types.payment import PaymentCardBrand, PaymentCardNumber VALID_AMEX = '370000000000002' VALID_MC = '5100000000000003' VALID_VISA_13 = '4050000000001' VALID_VISA_16 = '4050000000000001' VALID_VISA_19 = '4050000000000000001' VALID_MIR_16 = '2200000000000004' VALID_MIR_17 = '22000000000000004' VALID_MIR_18 = '220000000000000004' VALID_MIR_19 = '2200000000000000004' VALID_DISCOVER = '6011000000000004' VALID_VERVE_16 = '5061000000000001' VALID_VERVE_18 = '506100000000000001' VALID_VERVE_19 = '5061000000000000001' VALID_DANKORT = '5019000000000000' VALID_UNIONPAY_16 = '6200000000000001' VALID_UNIONPAY_19 = '8100000000000000001' VALID_JCB_16 = '3528000000000001' VALID_JCB_19 = '3528000000000000001' VALID_MAESTRO = '6759649826438453' VALID_TROY = '9792000000000001' VALID_OTHER = '2000000000000000008' LUHN_INVALID = '4000000000000000' LEN_INVALID = '40000000000000006' # Mock PaymentCardNumber PCN = namedtuple('PaymentCardNumber', ['card_number', 'brand']) PCN.__len__ = lambda v: len(v.card_number) @pytest.fixture(scope='session', name='PaymentCard') def payment_card_model_fixture(): class PaymentCard(BaseModel): card_number: PaymentCardNumber return PaymentCard def test_validate_digits(): digits = '12345' assert PaymentCardNumber.validate_digits(digits) is None with pytest.raises(PydanticCustomError, match='Card number is not all digits'): PaymentCardNumber.validate_digits('hello') with pytest.raises(PydanticCustomError, match='Card number is not all digits'): PaymentCardNumber.validate_digits('Β²') @pytest.mark.parametrize( 'card_number, valid', [ ('0', True), ('00', True), ('18', True), ('0000000000000000', True), ('4242424242424240', False), ('4242424242424241', False), ('4242424242424242', True), ('4242424242424243', False), ('4242424242424244', False), ('4242424242424245', False), ('4242424242424246', False), ('4242424242424247', False), ('4242424242424248', False), ('4242424242424249', False), ('42424242424242426', True), ('424242424242424267', True), ('4242424242424242675', True), ('5164581347216566', True), ('4345351087414150', True), ('343728738009846', True), ('5164581347216567', False), ('4345351087414151', False), ('343728738009847', False), ('000000018', True), ('99999999999999999999', True), ('99999999999999999999999999999999999999999999999999999999999999999997', True), ], ) def test_validate_luhn_check_digit(card_number: str, valid: bool): if valid: assert PaymentCardNumber.validate_luhn_check_digit(card_number) == card_number else: with pytest.raises(PydanticCustomError, match='Card number is not luhn valid'): PaymentCardNumber.validate_luhn_check_digit(card_number) @pytest.mark.parametrize( 'card_number, brand, valid', [ (VALID_VISA_13, PaymentCardBrand.visa, True), (VALID_VISA_16, PaymentCardBrand.visa, True), (VALID_VISA_19, PaymentCardBrand.visa, True), (VALID_MC, PaymentCardBrand.mastercard, True), (VALID_AMEX, PaymentCardBrand.amex, True), (VALID_MIR_16, PaymentCardBrand.mir, True), (VALID_MIR_17, PaymentCardBrand.mir, True), (VALID_MIR_18, PaymentCardBrand.mir, True), (VALID_MIR_19, PaymentCardBrand.mir, True), (VALID_DISCOVER, PaymentCardBrand.discover, True), (VALID_VERVE_16, PaymentCardBrand.verve, True), (VALID_VERVE_18, PaymentCardBrand.verve, True), (VALID_VERVE_19, PaymentCardBrand.verve, True), (VALID_DANKORT, PaymentCardBrand.dankort, True), (VALID_UNIONPAY_16, PaymentCardBrand.unionpay, True), (VALID_UNIONPAY_19, PaymentCardBrand.unionpay, True), (VALID_JCB_16, PaymentCardBrand.jcb, True), (VALID_JCB_19, PaymentCardBrand.jcb, True), (LEN_INVALID, PaymentCardBrand.visa, False), (VALID_MAESTRO, PaymentCardBrand.maestro, True), (VALID_TROY, PaymentCardBrand.troy, True), (VALID_OTHER, PaymentCardBrand.other, True), ], ) def test_length_for_brand(card_number: str, brand: PaymentCardBrand, valid: bool): # pcn = PCN(card_number, brand) if valid: assert PaymentCardNumber.validate_brand(card_number) == brand else: with pytest.raises(PydanticCustomError) as exc_info: PaymentCardNumber.validate_brand(card_number) assert exc_info.value.type == 'payment_card_number_brand' @pytest.mark.parametrize( 'card_number, brand', [ (VALID_AMEX, PaymentCardBrand.amex), (VALID_MC, PaymentCardBrand.mastercard), (VALID_VISA_16, PaymentCardBrand.visa), (VALID_MIR_16, PaymentCardBrand.mir), (VALID_DISCOVER, PaymentCardBrand.discover), (VALID_VERVE_16, PaymentCardBrand.verve), (VALID_DANKORT, PaymentCardBrand.dankort), (VALID_UNIONPAY_16, PaymentCardBrand.unionpay), (VALID_JCB_16, PaymentCardBrand.jcb), (VALID_OTHER, PaymentCardBrand.other), (VALID_MAESTRO, PaymentCardBrand.maestro), (VALID_TROY, PaymentCardBrand.troy), ], ) def test_get_brand(card_number: str, brand: PaymentCardBrand): assert PaymentCardNumber.validate_brand(card_number) == brand def test_valid(PaymentCard): card = PaymentCard(card_number=VALID_VISA_16) assert str(card.card_number) == VALID_VISA_16 assert card.card_number.masked == '405000******0001' @pytest.mark.parametrize( 'card_number, error_message', [ (None, 'type=string_type'), ('1' * 11, 'type=string_too_short,'), ('1' * 20, 'type=string_too_long,'), ('h' * 16, 'type=payment_card_number_digits'), (LUHN_INVALID, 'type=payment_card_number_luhn,'), (LEN_INVALID, 'type=payment_card_number_brand,'), ], ) def test_error_types(card_number: Any, error_message: str, PaymentCard): with pytest.raises(ValidationError, match=error_message): PaymentCard(card_number=card_number) def test_payment_card_brand(): b = PaymentCardBrand.visa assert str(b) == 'Visa' assert b is PaymentCardBrand.visa assert b == PaymentCardBrand.visa assert b in {PaymentCardBrand.visa, PaymentCardBrand.mastercard} b = 'Visa' assert b is not PaymentCardBrand.visa assert b == PaymentCardBrand.visa assert b in {PaymentCardBrand.visa, PaymentCardBrand.mastercard} b = PaymentCardBrand.amex assert b is not PaymentCardBrand.visa assert b != PaymentCardBrand.visa assert b not in {PaymentCardBrand.visa, PaymentCardBrand.mastercard} pydantic-extra-types-2.10.5/tests/test_ulid.py000066400000000000000000000070721501603200400214020ustar00rootroot00000000000000import uuid from datetime import datetime, timezone from typing import Any import pytest from pydantic import BaseModel, ValidationError from pydantic_extra_types.ulid import ULID try: from ulid import ULID as _ULID except ModuleNotFoundError: # pragma: no cover raise RuntimeError( 'The `ulid` module requires "python-ulid" to be installed. You can install it with "pip install python-ulid".' ) class Something(BaseModel): ulid: ULID @pytest.mark.parametrize( 'ulid, result, valid', [ # Valid ULID for str format ('01BTGNYV6HRNK8K8VKZASZCFPE', '01BTGNYV6HRNK8K8VKZASZCFPE', True), ('01BTGNYV6HRNK8K8VKZASZCFPF', '01BTGNYV6HRNK8K8VKZASZCFPF', True), # Invalid ULID for str format ('01BTGNYV6HRNK8K8VKZASZCFP', None, False), # Invalid ULID (short length) ('01BTGNYV6HRNK8K8VKZASZCFPEA', None, False), # Invalid ULID (long length) # Valid ULID for UUID format (uuid.UUID('0196FEB3-9C99-8D8C-B3F3-4301C5E9DCE1'), '01JVZB774SHP6B7WT3072YKQ71', True), (uuid.UUID('0196FEB3-CD14-4B50-0015-C1E09BF7B221'), '01JVZB7K8M9D8005E1W2DZFCH1', True), # Valid ULID for _ULID format (_ULID.from_str('01BTGNYV6HRNK8K8VKZASZCFPE'), '01BTGNYV6HRNK8K8VKZASZCFPE', True), (_ULID.from_str('01BTGNYV6HRNK8K8VKZASZCFPF'), '01BTGNYV6HRNK8K8VKZASZCFPF', True), # Invalid _ULID for bytes format (b'\x01\xba\x1e\xb2\x8a\x9f\xfay\x10\xd5\xa5k\xc8', None, False), # Invalid ULID (short length) (b'\x01\xba\x1e\xb2\x8a\x9f\xfay\x10\xd5\xa5k\xc8\xb6\x00', None, False), # Invalid ULID (long length) # Valid ULID for int format (109667145845879622871206540411193812282, '2JG4FVY7N8XS4GFVHPXGJZ8S9T', True), (109667145845879622871206540411193812283, '2JG4FVY7N8XS4GFVHPXGJZ8S9V', True), (109667145845879622871206540411193812284, '2JG4FVY7N8XS4GFVHPXGJZ8S9W', True), # Invalid ULID for bool format (True, None, False), (False, None, False), ], ) def test_format_for_ulid(ulid: Any, result: Any, valid: bool): if valid: assert str(Something(ulid=ulid).ulid) == result else: with pytest.raises(ValidationError, match='format'): Something(ulid=ulid) def test_property_for_ulid(): ulid = Something(ulid='01BTGNYV6HRNK8K8VKZASZCFPE').ulid assert ulid.hex == '015ea15f6cd1c56689a373fab3f63ece' assert ulid == '01BTGNYV6HRNK8K8VKZASZCFPE' assert ulid.datetime == datetime(2017, 9, 20, 22, 18, 59, 153000, tzinfo=timezone.utc) assert ulid.timestamp == 1505945939.153 def test_json_schema(): assert Something.model_json_schema(mode='validation') == { 'properties': { 'ulid': { 'anyOf': [ {'type': 'integer'}, {'format': 'binary', 'type': 'string'}, {'type': 'string'}, {'format': 'uuid', 'type': 'string'}, ], 'title': 'Ulid', } }, 'required': ['ulid'], 'title': 'Something', 'type': 'object', } assert Something.model_json_schema(mode='serialization') == { 'properties': { 'ulid': { 'anyOf': [ {'type': 'integer'}, {'format': 'binary', 'type': 'string'}, {'type': 'string'}, {'format': 'uuid', 'type': 'string'}, ], 'title': 'Ulid', } }, 'required': ['ulid'], 'title': 'Something', 'type': 'object', } pydantic-extra-types-2.10.5/uv.lock000066400000000000000000010640741501603200400172040ustar00rootroot00000000000000version = 1 revision = 2 requires-python = ">=3.8" resolution-markers = [ "python_full_version >= '3.9'", "python_full_version < '3.9'", ] [[package]] name = "annotated-types" version = "0.7.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions", marker = "python_full_version < '3.9'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, ] [[package]] name = "backports-zoneinfo" version = "0.2.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/ad/85/475e514c3140937cf435954f78dedea1861aeab7662d11de232bdaa90655/backports.zoneinfo-0.2.1.tar.gz", hash = "sha256:fadbfe37f74051d024037f223b8e001611eac868b5c5b06144ef4d8b799862f2", size = 74098, upload-time = "2020-06-23T13:51:22.041Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/4a/6d/eca004eeadcbf8bd64cc96feb9e355536147f0577420b44d80c7cac70767/backports.zoneinfo-0.2.1-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:8961c0f32cd0336fb8e8ead11a1f8cd99ec07145ec2931122faaac1c8f7fd987", size = 35816, upload-time = "2020-06-23T13:51:21.244Z" }, { url = "https://files.pythonhosted.org/packages/c1/8f/9b1b920a6a95652463143943fa3b8c000cb0b932ab463764a6f2a2416560/backports.zoneinfo-0.2.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:e81b76cace8eda1fca50e345242ba977f9be6ae3945af8d46326d776b4cf78d1", size = 72147, upload-time = "2020-06-23T13:51:17.562Z" }, { url = "https://files.pythonhosted.org/packages/1a/ab/3e941e3fcf1b7d3ab3d0233194d99d6a0ed6b24f8f956fc81e47edc8c079/backports.zoneinfo-0.2.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7b0a64cda4145548fed9efc10322770f929b944ce5cee6c0dfe0c87bf4c0c8c9", size = 74033, upload-time = "2020-06-23T13:51:14.592Z" }, { url = "https://files.pythonhosted.org/packages/c0/34/5fdb0a3a28841d215c255be8fc60b8666257bb6632193c86fd04b63d4a31/backports.zoneinfo-0.2.1-cp38-cp38-win32.whl", hash = "sha256:1b13e654a55cd45672cb54ed12148cd33628f672548f373963b0bff67b217328", size = 36803, upload-time = "2020-06-23T13:51:07.517Z" }, { url = "https://files.pythonhosted.org/packages/78/cc/e27fd6493bbce8dbea7e6c1bc861fe3d3bc22c4f7c81f4c3befb8ff5bfaf/backports.zoneinfo-0.2.1-cp38-cp38-win_amd64.whl", hash = "sha256:4a0f800587060bf8880f954dbef70de6c11bbe59c673c3d818921f042f9954a6", size = 38967, upload-time = "2020-06-23T13:51:13.735Z" }, ] [[package]] name = "colorama" version = "0.4.6" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, ] [[package]] name = "coverage" version = "7.6.1" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version < '3.9'", ] sdist = { url = "https://files.pythonhosted.org/packages/f7/08/7e37f82e4d1aead42a7443ff06a1e406aabf7302c4f00a546e4b320b994c/coverage-7.6.1.tar.gz", hash = "sha256:953510dfb7b12ab69d20135a0662397f077c59b1e6379a768e97c59d852ee51d", size = 798791, upload-time = "2024-08-04T19:45:30.9Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/7e/61/eb7ce5ed62bacf21beca4937a90fe32545c91a3c8a42a30c6616d48fc70d/coverage-7.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b06079abebbc0e89e6163b8e8f0e16270124c154dc6e4a47b413dd538859af16", size = 206690, upload-time = "2024-08-04T19:43:07.695Z" }, { url = "https://files.pythonhosted.org/packages/7d/73/041928e434442bd3afde5584bdc3f932fb4562b1597629f537387cec6f3d/coverage-7.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cf4b19715bccd7ee27b6b120e7e9dd56037b9c0681dcc1adc9ba9db3d417fa36", size = 207127, upload-time = "2024-08-04T19:43:10.15Z" }, { url = "https://files.pythonhosted.org/packages/c7/c8/6ca52b5147828e45ad0242388477fdb90df2c6cbb9a441701a12b3c71bc8/coverage-7.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61c0abb4c85b095a784ef23fdd4aede7a2628478e7baba7c5e3deba61070a02", size = 235654, upload-time = "2024-08-04T19:43:12.405Z" }, { url = "https://files.pythonhosted.org/packages/d5/da/9ac2b62557f4340270942011d6efeab9833648380109e897d48ab7c1035d/coverage-7.6.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd21f6ae3f08b41004dfb433fa895d858f3f5979e7762d052b12aef444e29afc", size = 233598, upload-time = "2024-08-04T19:43:14.078Z" }, { url = "https://files.pythonhosted.org/packages/53/23/9e2c114d0178abc42b6d8d5281f651a8e6519abfa0ef460a00a91f80879d/coverage-7.6.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f59d57baca39b32db42b83b2a7ba6f47ad9c394ec2076b084c3f029b7afca23", size = 234732, upload-time = "2024-08-04T19:43:16.632Z" }, { url = "https://files.pythonhosted.org/packages/0f/7e/a0230756fb133343a52716e8b855045f13342b70e48e8ad41d8a0d60ab98/coverage-7.6.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a1ac0ae2b8bd743b88ed0502544847c3053d7171a3cff9228af618a068ed9c34", size = 233816, upload-time = "2024-08-04T19:43:19.049Z" }, { url = "https://files.pythonhosted.org/packages/28/7c/3753c8b40d232b1e5eeaed798c875537cf3cb183fb5041017c1fdb7ec14e/coverage-7.6.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e6a08c0be454c3b3beb105c0596ebdc2371fab6bb90c0c0297f4e58fd7e1012c", size = 232325, upload-time = "2024-08-04T19:43:21.246Z" }, { url = "https://files.pythonhosted.org/packages/57/e3/818a2b2af5b7573b4b82cf3e9f137ab158c90ea750a8f053716a32f20f06/coverage-7.6.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f5796e664fe802da4f57a168c85359a8fbf3eab5e55cd4e4569fbacecc903959", size = 233418, upload-time = "2024-08-04T19:43:22.945Z" }, { url = "https://files.pythonhosted.org/packages/c8/fb/4532b0b0cefb3f06d201648715e03b0feb822907edab3935112b61b885e2/coverage-7.6.1-cp310-cp310-win32.whl", hash = "sha256:7bb65125fcbef8d989fa1dd0e8a060999497629ca5b0efbca209588a73356232", size = 209343, upload-time = "2024-08-04T19:43:25.121Z" }, { url = "https://files.pythonhosted.org/packages/5a/25/af337cc7421eca1c187cc9c315f0a755d48e755d2853715bfe8c418a45fa/coverage-7.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:3115a95daa9bdba70aea750db7b96b37259a81a709223c8448fa97727d546fe0", size = 210136, upload-time = "2024-08-04T19:43:26.851Z" }, { url = "https://files.pythonhosted.org/packages/ad/5f/67af7d60d7e8ce61a4e2ddcd1bd5fb787180c8d0ae0fbd073f903b3dd95d/coverage-7.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7dea0889685db8550f839fa202744652e87c60015029ce3f60e006f8c4462c93", size = 206796, upload-time = "2024-08-04T19:43:29.115Z" }, { url = "https://files.pythonhosted.org/packages/e1/0e/e52332389e057daa2e03be1fbfef25bb4d626b37d12ed42ae6281d0a274c/coverage-7.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed37bd3c3b063412f7620464a9ac1314d33100329f39799255fb8d3027da50d3", size = 207244, upload-time = "2024-08-04T19:43:31.285Z" }, { url = "https://files.pythonhosted.org/packages/aa/cd/766b45fb6e090f20f8927d9c7cb34237d41c73a939358bc881883fd3a40d/coverage-7.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d85f5e9a5f8b73e2350097c3756ef7e785f55bd71205defa0bfdaf96c31616ff", size = 239279, upload-time = "2024-08-04T19:43:33.581Z" }, { url = "https://files.pythonhosted.org/packages/70/6c/a9ccd6fe50ddaf13442a1e2dd519ca805cbe0f1fcd377fba6d8339b98ccb/coverage-7.6.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bc572be474cafb617672c43fe989d6e48d3c83af02ce8de73fff1c6bb3c198d", size = 236859, upload-time = "2024-08-04T19:43:35.301Z" }, { url = "https://files.pythonhosted.org/packages/14/6f/8351b465febb4dbc1ca9929505202db909c5a635c6fdf33e089bbc3d7d85/coverage-7.6.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c0420b573964c760df9e9e86d1a9a622d0d27f417e1a949a8a66dd7bcee7bc6", size = 238549, upload-time = "2024-08-04T19:43:37.578Z" }, { url = "https://files.pythonhosted.org/packages/68/3c/289b81fa18ad72138e6d78c4c11a82b5378a312c0e467e2f6b495c260907/coverage-7.6.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1f4aa8219db826ce6be7099d559f8ec311549bfc4046f7f9fe9b5cea5c581c56", size = 237477, upload-time = "2024-08-04T19:43:39.92Z" }, { url = "https://files.pythonhosted.org/packages/ed/1c/aa1efa6459d822bd72c4abc0b9418cf268de3f60eeccd65dc4988553bd8d/coverage-7.6.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:fc5a77d0c516700ebad189b587de289a20a78324bc54baee03dd486f0855d234", size = 236134, upload-time = "2024-08-04T19:43:41.453Z" }, { url = "https://files.pythonhosted.org/packages/fb/c8/521c698f2d2796565fe9c789c2ee1ccdae610b3aa20b9b2ef980cc253640/coverage-7.6.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b48f312cca9621272ae49008c7f613337c53fadca647d6384cc129d2996d1133", size = 236910, upload-time = "2024-08-04T19:43:43.037Z" }, { url = "https://files.pythonhosted.org/packages/7d/30/033e663399ff17dca90d793ee8a2ea2890e7fdf085da58d82468b4220bf7/coverage-7.6.1-cp311-cp311-win32.whl", hash = "sha256:1125ca0e5fd475cbbba3bb67ae20bd2c23a98fac4e32412883f9bcbaa81c314c", size = 209348, upload-time = "2024-08-04T19:43:44.787Z" }, { url = "https://files.pythonhosted.org/packages/20/05/0d1ccbb52727ccdadaa3ff37e4d2dc1cd4d47f0c3df9eb58d9ec8508ca88/coverage-7.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:8ae539519c4c040c5ffd0632784e21b2f03fc1340752af711f33e5be83a9d6c6", size = 210230, upload-time = "2024-08-04T19:43:46.707Z" }, { url = "https://files.pythonhosted.org/packages/7e/d4/300fc921dff243cd518c7db3a4c614b7e4b2431b0d1145c1e274fd99bd70/coverage-7.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:95cae0efeb032af8458fc27d191f85d1717b1d4e49f7cb226cf526ff28179778", size = 206983, upload-time = "2024-08-04T19:43:49.082Z" }, { url = "https://files.pythonhosted.org/packages/e1/ab/6bf00de5327ecb8db205f9ae596885417a31535eeda6e7b99463108782e1/coverage-7.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5621a9175cf9d0b0c84c2ef2b12e9f5f5071357c4d2ea6ca1cf01814f45d2391", size = 207221, upload-time = "2024-08-04T19:43:52.15Z" }, { url = "https://files.pythonhosted.org/packages/92/8f/2ead05e735022d1a7f3a0a683ac7f737de14850395a826192f0288703472/coverage-7.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:260933720fdcd75340e7dbe9060655aff3af1f0c5d20f46b57f262ab6c86a5e8", size = 240342, upload-time = "2024-08-04T19:43:53.746Z" }, { url = "https://files.pythonhosted.org/packages/0f/ef/94043e478201ffa85b8ae2d2c79b4081e5a1b73438aafafccf3e9bafb6b5/coverage-7.6.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07e2ca0ad381b91350c0ed49d52699b625aab2b44b65e1b4e02fa9df0e92ad2d", size = 237371, upload-time = "2024-08-04T19:43:55.993Z" }, { url = "https://files.pythonhosted.org/packages/1f/0f/c890339dd605f3ebc269543247bdd43b703cce6825b5ed42ff5f2d6122c7/coverage-7.6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c44fee9975f04b33331cb8eb272827111efc8930cfd582e0320613263ca849ca", size = 239455, upload-time = "2024-08-04T19:43:57.618Z" }, { url = "https://files.pythonhosted.org/packages/d1/04/7fd7b39ec7372a04efb0f70c70e35857a99b6a9188b5205efb4c77d6a57a/coverage-7.6.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:877abb17e6339d96bf08e7a622d05095e72b71f8afd8a9fefc82cf30ed944163", size = 238924, upload-time = "2024-08-04T19:44:00.012Z" }, { url = "https://files.pythonhosted.org/packages/ed/bf/73ce346a9d32a09cf369f14d2a06651329c984e106f5992c89579d25b27e/coverage-7.6.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3e0cadcf6733c09154b461f1ca72d5416635e5e4ec4e536192180d34ec160f8a", size = 237252, upload-time = "2024-08-04T19:44:01.713Z" }, { url = "https://files.pythonhosted.org/packages/86/74/1dc7a20969725e917b1e07fe71a955eb34bc606b938316bcc799f228374b/coverage-7.6.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c3c02d12f837d9683e5ab2f3d9844dc57655b92c74e286c262e0fc54213c216d", size = 238897, upload-time = "2024-08-04T19:44:03.898Z" }, { url = "https://files.pythonhosted.org/packages/b6/e9/d9cc3deceb361c491b81005c668578b0dfa51eed02cd081620e9a62f24ec/coverage-7.6.1-cp312-cp312-win32.whl", hash = "sha256:e05882b70b87a18d937ca6768ff33cc3f72847cbc4de4491c8e73880766718e5", size = 209606, upload-time = "2024-08-04T19:44:05.532Z" }, { url = "https://files.pythonhosted.org/packages/47/c8/5a2e41922ea6740f77d555c4d47544acd7dc3f251fe14199c09c0f5958d3/coverage-7.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:b5d7b556859dd85f3a541db6a4e0167b86e7273e1cdc973e5b175166bb634fdb", size = 210373, upload-time = "2024-08-04T19:44:07.079Z" }, { url = "https://files.pythonhosted.org/packages/8c/f9/9aa4dfb751cb01c949c990d136a0f92027fbcc5781c6e921df1cb1563f20/coverage-7.6.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a4acd025ecc06185ba2b801f2de85546e0b8ac787cf9d3b06e7e2a69f925b106", size = 207007, upload-time = "2024-08-04T19:44:09.453Z" }, { url = "https://files.pythonhosted.org/packages/b9/67/e1413d5a8591622a46dd04ff80873b04c849268831ed5c304c16433e7e30/coverage-7.6.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a6d3adcf24b624a7b778533480e32434a39ad8fa30c315208f6d3e5542aeb6e9", size = 207269, upload-time = "2024-08-04T19:44:11.045Z" }, { url = "https://files.pythonhosted.org/packages/14/5b/9dec847b305e44a5634d0fb8498d135ab1d88330482b74065fcec0622224/coverage-7.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0c212c49b6c10e6951362f7c6df3329f04c2b1c28499563d4035d964ab8e08c", size = 239886, upload-time = "2024-08-04T19:44:12.83Z" }, { url = "https://files.pythonhosted.org/packages/7b/b7/35760a67c168e29f454928f51f970342d23cf75a2bb0323e0f07334c85f3/coverage-7.6.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e81d7a3e58882450ec4186ca59a3f20a5d4440f25b1cff6f0902ad890e6748a", size = 237037, upload-time = "2024-08-04T19:44:15.393Z" }, { url = "https://files.pythonhosted.org/packages/f7/95/d2fd31f1d638df806cae59d7daea5abf2b15b5234016a5ebb502c2f3f7ee/coverage-7.6.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78b260de9790fd81e69401c2dc8b17da47c8038176a79092a89cb2b7d945d060", size = 239038, upload-time = "2024-08-04T19:44:17.466Z" }, { url = "https://files.pythonhosted.org/packages/6e/bd/110689ff5752b67924efd5e2aedf5190cbbe245fc81b8dec1abaffba619d/coverage-7.6.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a78d169acd38300060b28d600344a803628c3fd585c912cacc9ea8790fe96862", size = 238690, upload-time = "2024-08-04T19:44:19.336Z" }, { url = "https://files.pythonhosted.org/packages/d3/a8/08d7b38e6ff8df52331c83130d0ab92d9c9a8b5462f9e99c9f051a4ae206/coverage-7.6.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2c09f4ce52cb99dd7505cd0fc8e0e37c77b87f46bc9c1eb03fe3bc9991085388", size = 236765, upload-time = "2024-08-04T19:44:20.994Z" }, { url = "https://files.pythonhosted.org/packages/d6/6a/9cf96839d3147d55ae713eb2d877f4d777e7dc5ba2bce227167d0118dfe8/coverage-7.6.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6878ef48d4227aace338d88c48738a4258213cd7b74fd9a3d4d7582bb1d8a155", size = 238611, upload-time = "2024-08-04T19:44:22.616Z" }, { url = "https://files.pythonhosted.org/packages/74/e4/7ff20d6a0b59eeaab40b3140a71e38cf52547ba21dbcf1d79c5a32bba61b/coverage-7.6.1-cp313-cp313-win32.whl", hash = "sha256:44df346d5215a8c0e360307d46ffaabe0f5d3502c8a1cefd700b34baf31d411a", size = 209671, upload-time = "2024-08-04T19:44:24.418Z" }, { url = "https://files.pythonhosted.org/packages/35/59/1812f08a85b57c9fdb6d0b383d779e47b6f643bc278ed682859512517e83/coverage-7.6.1-cp313-cp313-win_amd64.whl", hash = "sha256:8284cf8c0dd272a247bc154eb6c95548722dce90d098c17a883ed36e67cdb129", size = 210368, upload-time = "2024-08-04T19:44:26.276Z" }, { url = "https://files.pythonhosted.org/packages/9c/15/08913be1c59d7562a3e39fce20661a98c0a3f59d5754312899acc6cb8a2d/coverage-7.6.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:d3296782ca4eab572a1a4eca686d8bfb00226300dcefdf43faa25b5242ab8a3e", size = 207758, upload-time = "2024-08-04T19:44:29.028Z" }, { url = "https://files.pythonhosted.org/packages/c4/ae/b5d58dff26cade02ada6ca612a76447acd69dccdbb3a478e9e088eb3d4b9/coverage-7.6.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:502753043567491d3ff6d08629270127e0c31d4184c4c8d98f92c26f65019962", size = 208035, upload-time = "2024-08-04T19:44:30.673Z" }, { url = "https://files.pythonhosted.org/packages/b8/d7/62095e355ec0613b08dfb19206ce3033a0eedb6f4a67af5ed267a8800642/coverage-7.6.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a89ecca80709d4076b95f89f308544ec8f7b4727e8a547913a35f16717856cb", size = 250839, upload-time = "2024-08-04T19:44:32.412Z" }, { url = "https://files.pythonhosted.org/packages/7c/1e/c2967cb7991b112ba3766df0d9c21de46b476d103e32bb401b1b2adf3380/coverage-7.6.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a318d68e92e80af8b00fa99609796fdbcdfef3629c77c6283566c6f02c6d6704", size = 246569, upload-time = "2024-08-04T19:44:34.547Z" }, { url = "https://files.pythonhosted.org/packages/8b/61/a7a6a55dd266007ed3b1df7a3386a0d760d014542d72f7c2c6938483b7bd/coverage-7.6.1-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13b0a73a0896988f053e4fbb7de6d93388e6dd292b0d87ee51d106f2c11b465b", size = 248927, upload-time = "2024-08-04T19:44:36.313Z" }, { url = "https://files.pythonhosted.org/packages/c8/fa/13a6f56d72b429f56ef612eb3bc5ce1b75b7ee12864b3bd12526ab794847/coverage-7.6.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4421712dbfc5562150f7554f13dde997a2e932a6b5f352edcce948a815efee6f", size = 248401, upload-time = "2024-08-04T19:44:38.155Z" }, { url = "https://files.pythonhosted.org/packages/75/06/0429c652aa0fb761fc60e8c6b291338c9173c6aa0f4e40e1902345b42830/coverage-7.6.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:166811d20dfea725e2e4baa71fffd6c968a958577848d2131f39b60043400223", size = 246301, upload-time = "2024-08-04T19:44:39.883Z" }, { url = "https://files.pythonhosted.org/packages/52/76/1766bb8b803a88f93c3a2d07e30ffa359467810e5cbc68e375ebe6906efb/coverage-7.6.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:225667980479a17db1048cb2bf8bfb39b8e5be8f164b8f6628b64f78a72cf9d3", size = 247598, upload-time = "2024-08-04T19:44:41.59Z" }, { url = "https://files.pythonhosted.org/packages/66/8b/f54f8db2ae17188be9566e8166ac6df105c1c611e25da755738025708d54/coverage-7.6.1-cp313-cp313t-win32.whl", hash = "sha256:170d444ab405852903b7d04ea9ae9b98f98ab6d7e63e1115e82620807519797f", size = 210307, upload-time = "2024-08-04T19:44:43.301Z" }, { url = "https://files.pythonhosted.org/packages/9f/b0/e0dca6da9170aefc07515cce067b97178cefafb512d00a87a1c717d2efd5/coverage-7.6.1-cp313-cp313t-win_amd64.whl", hash = "sha256:b9f222de8cded79c49bf184bdbc06630d4c58eec9459b939b4a690c82ed05657", size = 211453, upload-time = "2024-08-04T19:44:45.677Z" }, { url = "https://files.pythonhosted.org/packages/81/d0/d9e3d554e38beea5a2e22178ddb16587dbcbe9a1ef3211f55733924bf7fa/coverage-7.6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6db04803b6c7291985a761004e9060b2bca08da6d04f26a7f2294b8623a0c1a0", size = 206674, upload-time = "2024-08-04T19:44:47.694Z" }, { url = "https://files.pythonhosted.org/packages/38/ea/cab2dc248d9f45b2b7f9f1f596a4d75a435cb364437c61b51d2eb33ceb0e/coverage-7.6.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f1adfc8ac319e1a348af294106bc6a8458a0f1633cc62a1446aebc30c5fa186a", size = 207101, upload-time = "2024-08-04T19:44:49.32Z" }, { url = "https://files.pythonhosted.org/packages/ca/6f/f82f9a500c7c5722368978a5390c418d2a4d083ef955309a8748ecaa8920/coverage-7.6.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a95324a9de9650a729239daea117df21f4b9868ce32e63f8b650ebe6cef5595b", size = 236554, upload-time = "2024-08-04T19:44:51.631Z" }, { url = "https://files.pythonhosted.org/packages/a6/94/d3055aa33d4e7e733d8fa309d9adf147b4b06a82c1346366fc15a2b1d5fa/coverage-7.6.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b43c03669dc4618ec25270b06ecd3ee4fa94c7f9b3c14bae6571ca00ef98b0d3", size = 234440, upload-time = "2024-08-04T19:44:53.464Z" }, { url = "https://files.pythonhosted.org/packages/e4/6e/885bcd787d9dd674de4a7d8ec83faf729534c63d05d51d45d4fa168f7102/coverage-7.6.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8929543a7192c13d177b770008bc4e8119f2e1f881d563fc6b6305d2d0ebe9de", size = 235889, upload-time = "2024-08-04T19:44:55.165Z" }, { url = "https://files.pythonhosted.org/packages/f4/63/df50120a7744492710854860783d6819ff23e482dee15462c9a833cc428a/coverage-7.6.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a09ece4a69cf399510c8ab25e0950d9cf2b42f7b3cb0374f95d2e2ff594478a6", size = 235142, upload-time = "2024-08-04T19:44:57.269Z" }, { url = "https://files.pythonhosted.org/packages/3a/5d/9d0acfcded2b3e9ce1c7923ca52ccc00c78a74e112fc2aee661125b7843b/coverage-7.6.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:9054a0754de38d9dbd01a46621636689124d666bad1936d76c0341f7d71bf569", size = 233805, upload-time = "2024-08-04T19:44:59.033Z" }, { url = "https://files.pythonhosted.org/packages/c4/56/50abf070cb3cd9b1dd32f2c88f083aab561ecbffbcd783275cb51c17f11d/coverage-7.6.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0dbde0f4aa9a16fa4d754356a8f2e36296ff4d83994b2c9d8398aa32f222f989", size = 234655, upload-time = "2024-08-04T19:45:01.398Z" }, { url = "https://files.pythonhosted.org/packages/25/ee/b4c246048b8485f85a2426ef4abab88e48c6e80c74e964bea5cd4cd4b115/coverage-7.6.1-cp38-cp38-win32.whl", hash = "sha256:da511e6ad4f7323ee5702e6633085fb76c2f893aaf8ce4c51a0ba4fc07580ea7", size = 209296, upload-time = "2024-08-04T19:45:03.819Z" }, { url = "https://files.pythonhosted.org/packages/5c/1c/96cf86b70b69ea2b12924cdf7cabb8ad10e6130eab8d767a1099fbd2a44f/coverage-7.6.1-cp38-cp38-win_amd64.whl", hash = "sha256:3f1156e3e8f2872197af3840d8ad307a9dd18e615dc64d9ee41696f287c57ad8", size = 210137, upload-time = "2024-08-04T19:45:06.25Z" }, { url = "https://files.pythonhosted.org/packages/19/d3/d54c5aa83268779d54c86deb39c1c4566e5d45c155369ca152765f8db413/coverage-7.6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:abd5fd0db5f4dc9289408aaf34908072f805ff7792632250dcb36dc591d24255", size = 206688, upload-time = "2024-08-04T19:45:08.358Z" }, { url = "https://files.pythonhosted.org/packages/a5/fe/137d5dca72e4a258b1bc17bb04f2e0196898fe495843402ce826a7419fe3/coverage-7.6.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:547f45fa1a93154bd82050a7f3cddbc1a7a4dd2a9bf5cb7d06f4ae29fe94eaf8", size = 207120, upload-time = "2024-08-04T19:45:11.526Z" }, { url = "https://files.pythonhosted.org/packages/78/5b/a0a796983f3201ff5485323b225d7c8b74ce30c11f456017e23d8e8d1945/coverage-7.6.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:645786266c8f18a931b65bfcefdbf6952dd0dea98feee39bd188607a9d307ed2", size = 235249, upload-time = "2024-08-04T19:45:13.202Z" }, { url = "https://files.pythonhosted.org/packages/4e/e1/76089d6a5ef9d68f018f65411fcdaaeb0141b504587b901d74e8587606ad/coverage-7.6.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e0b2df163b8ed01d515807af24f63de04bebcecbd6c3bfeff88385789fdf75a", size = 233237, upload-time = "2024-08-04T19:45:14.961Z" }, { url = "https://files.pythonhosted.org/packages/9a/6f/eef79b779a540326fee9520e5542a8b428cc3bfa8b7c8f1022c1ee4fc66c/coverage-7.6.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:609b06f178fe8e9f89ef676532760ec0b4deea15e9969bf754b37f7c40326dbc", size = 234311, upload-time = "2024-08-04T19:45:16.924Z" }, { url = "https://files.pythonhosted.org/packages/75/e1/656d65fb126c29a494ef964005702b012f3498db1a30dd562958e85a4049/coverage-7.6.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:702855feff378050ae4f741045e19a32d57d19f3e0676d589df0575008ea5004", size = 233453, upload-time = "2024-08-04T19:45:18.672Z" }, { url = "https://files.pythonhosted.org/packages/68/6a/45f108f137941a4a1238c85f28fd9d048cc46b5466d6b8dda3aba1bb9d4f/coverage-7.6.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:2bdb062ea438f22d99cba0d7829c2ef0af1d768d1e4a4f528087224c90b132cb", size = 231958, upload-time = "2024-08-04T19:45:20.63Z" }, { url = "https://files.pythonhosted.org/packages/9b/e7/47b809099168b8b8c72ae311efc3e88c8d8a1162b3ba4b8da3cfcdb85743/coverage-7.6.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9c56863d44bd1c4fe2abb8a4d6f5371d197f1ac0ebdee542f07f35895fc07f36", size = 232938, upload-time = "2024-08-04T19:45:23.062Z" }, { url = "https://files.pythonhosted.org/packages/52/80/052222ba7058071f905435bad0ba392cc12006380731c37afaf3fe749b88/coverage-7.6.1-cp39-cp39-win32.whl", hash = "sha256:6e2cd258d7d927d09493c8df1ce9174ad01b381d4729a9d8d4e38670ca24774c", size = 209352, upload-time = "2024-08-04T19:45:25.042Z" }, { url = "https://files.pythonhosted.org/packages/b8/d8/1b92e0b3adcf384e98770a00ca095da1b5f7b483e6563ae4eb5e935d24a1/coverage-7.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:06a737c882bd26d0d6ee7269b20b12f14a8704807a01056c80bb881a4b2ce6ca", size = 210153, upload-time = "2024-08-04T19:45:27.079Z" }, { url = "https://files.pythonhosted.org/packages/a5/2b/0354ed096bca64dc8e32a7cbcae28b34cb5ad0b1fe2125d6d99583313ac0/coverage-7.6.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:e9a6e0eb86070e8ccaedfbd9d38fec54864f3125ab95419970575b42af7541df", size = 198926, upload-time = "2024-08-04T19:45:28.875Z" }, ] [package.optional-dependencies] toml = [ { name = "tomli", marker = "python_full_version < '3.9'" }, ] [[package]] name = "coverage" version = "7.8.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.9'", ] sdist = { url = "https://files.pythonhosted.org/packages/19/4f/2251e65033ed2ce1e68f00f91a0294e0f80c80ae8c3ebbe2f12828c4cd53/coverage-7.8.0.tar.gz", hash = "sha256:7a3d62b3b03b4b6fd41a085f3574874cf946cb4604d2b4d3e8dca8cd570ca501", size = 811872, upload-time = "2025-03-30T20:36:45.376Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/78/01/1c5e6ee4ebaaa5e079db933a9a45f61172048c7efa06648445821a201084/coverage-7.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2931f66991175369859b5fd58529cd4b73582461877ecfd859b6549869287ffe", size = 211379, upload-time = "2025-03-30T20:34:53.904Z" }, { url = "https://files.pythonhosted.org/packages/e9/16/a463389f5ff916963471f7c13585e5f38c6814607306b3cb4d6b4cf13384/coverage-7.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:52a523153c568d2c0ef8826f6cc23031dc86cffb8c6aeab92c4ff776e7951b28", size = 211814, upload-time = "2025-03-30T20:34:56.959Z" }, { url = "https://files.pythonhosted.org/packages/b8/b1/77062b0393f54d79064dfb72d2da402657d7c569cfbc724d56ac0f9c67ed/coverage-7.8.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c8a5c139aae4c35cbd7cadca1df02ea8cf28a911534fc1b0456acb0b14234f3", size = 240937, upload-time = "2025-03-30T20:34:58.751Z" }, { url = "https://files.pythonhosted.org/packages/d7/54/c7b00a23150083c124e908c352db03bcd33375494a4beb0c6d79b35448b9/coverage-7.8.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5a26c0c795c3e0b63ec7da6efded5f0bc856d7c0b24b2ac84b4d1d7bc578d676", size = 238849, upload-time = "2025-03-30T20:35:00.521Z" }, { url = "https://files.pythonhosted.org/packages/f7/ec/a6b7cfebd34e7b49f844788fda94713035372b5200c23088e3bbafb30970/coverage-7.8.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:821f7bcbaa84318287115d54becb1915eece6918136c6f91045bb84e2f88739d", size = 239986, upload-time = "2025-03-30T20:35:02.307Z" }, { url = "https://files.pythonhosted.org/packages/21/8c/c965ecef8af54e6d9b11bfbba85d4f6a319399f5f724798498387f3209eb/coverage-7.8.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a321c61477ff8ee705b8a5fed370b5710c56b3a52d17b983d9215861e37b642a", size = 239896, upload-time = "2025-03-30T20:35:04.141Z" }, { url = "https://files.pythonhosted.org/packages/40/83/070550273fb4c480efa8381735969cb403fa8fd1626d74865bfaf9e4d903/coverage-7.8.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:ed2144b8a78f9d94d9515963ed273d620e07846acd5d4b0a642d4849e8d91a0c", size = 238613, upload-time = "2025-03-30T20:35:05.889Z" }, { url = "https://files.pythonhosted.org/packages/07/76/fbb2540495b01d996d38e9f8897b861afed356be01160ab4e25471f4fed1/coverage-7.8.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:042e7841a26498fff7a37d6fda770d17519982f5b7d8bf5278d140b67b61095f", size = 238909, upload-time = "2025-03-30T20:35:07.76Z" }, { url = "https://files.pythonhosted.org/packages/a3/7e/76d604db640b7d4a86e5dd730b73e96e12a8185f22b5d0799025121f4dcb/coverage-7.8.0-cp310-cp310-win32.whl", hash = "sha256:f9983d01d7705b2d1f7a95e10bbe4091fabc03a46881a256c2787637b087003f", size = 213948, upload-time = "2025-03-30T20:35:09.144Z" }, { url = "https://files.pythonhosted.org/packages/5c/a7/f8ce4aafb4a12ab475b56c76a71a40f427740cf496c14e943ade72e25023/coverage-7.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:5a570cd9bd20b85d1a0d7b009aaf6c110b52b5755c17be6962f8ccd65d1dbd23", size = 214844, upload-time = "2025-03-30T20:35:10.734Z" }, { url = "https://files.pythonhosted.org/packages/2b/77/074d201adb8383addae5784cb8e2dac60bb62bfdf28b2b10f3a3af2fda47/coverage-7.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e7ac22a0bb2c7c49f441f7a6d46c9c80d96e56f5a8bc6972529ed43c8b694e27", size = 211493, upload-time = "2025-03-30T20:35:12.286Z" }, { url = "https://files.pythonhosted.org/packages/a9/89/7a8efe585750fe59b48d09f871f0e0c028a7b10722b2172dfe021fa2fdd4/coverage-7.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bf13d564d310c156d1c8e53877baf2993fb3073b2fc9f69790ca6a732eb4bfea", size = 211921, upload-time = "2025-03-30T20:35:14.18Z" }, { url = "https://files.pythonhosted.org/packages/e9/ef/96a90c31d08a3f40c49dbe897df4f1fd51fb6583821a1a1c5ee30cc8f680/coverage-7.8.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5761c70c017c1b0d21b0815a920ffb94a670c8d5d409d9b38857874c21f70d7", size = 244556, upload-time = "2025-03-30T20:35:15.616Z" }, { url = "https://files.pythonhosted.org/packages/89/97/dcd5c2ce72cee9d7b0ee8c89162c24972fb987a111b92d1a3d1d19100c61/coverage-7.8.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ff52d790c7e1628241ffbcaeb33e07d14b007b6eb00a19320c7b8a7024c040", size = 242245, upload-time = "2025-03-30T20:35:18.648Z" }, { url = "https://files.pythonhosted.org/packages/b2/7b/b63cbb44096141ed435843bbb251558c8e05cc835c8da31ca6ffb26d44c0/coverage-7.8.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d39fc4817fd67b3915256af5dda75fd4ee10621a3d484524487e33416c6f3543", size = 244032, upload-time = "2025-03-30T20:35:20.131Z" }, { url = "https://files.pythonhosted.org/packages/97/e3/7fa8c2c00a1ef530c2a42fa5df25a6971391f92739d83d67a4ee6dcf7a02/coverage-7.8.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b44674870709017e4b4036e3d0d6c17f06a0e6d4436422e0ad29b882c40697d2", size = 243679, upload-time = "2025-03-30T20:35:21.636Z" }, { url = "https://files.pythonhosted.org/packages/4f/b3/e0a59d8df9150c8a0c0841d55d6568f0a9195692136c44f3d21f1842c8f6/coverage-7.8.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8f99eb72bf27cbb167b636eb1726f590c00e1ad375002230607a844d9e9a2318", size = 241852, upload-time = "2025-03-30T20:35:23.525Z" }, { url = "https://files.pythonhosted.org/packages/9b/82/db347ccd57bcef150c173df2ade97976a8367a3be7160e303e43dd0c795f/coverage-7.8.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b571bf5341ba8c6bc02e0baeaf3b061ab993bf372d982ae509807e7f112554e9", size = 242389, upload-time = "2025-03-30T20:35:25.09Z" }, { url = "https://files.pythonhosted.org/packages/21/f6/3f7d7879ceb03923195d9ff294456241ed05815281f5254bc16ef71d6a20/coverage-7.8.0-cp311-cp311-win32.whl", hash = "sha256:e75a2ad7b647fd8046d58c3132d7eaf31b12d8a53c0e4b21fa9c4d23d6ee6d3c", size = 213997, upload-time = "2025-03-30T20:35:26.914Z" }, { url = "https://files.pythonhosted.org/packages/28/87/021189643e18ecf045dbe1e2071b2747901f229df302de01c998eeadf146/coverage-7.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:3043ba1c88b2139126fc72cb48574b90e2e0546d4c78b5299317f61b7f718b78", size = 214911, upload-time = "2025-03-30T20:35:28.498Z" }, { url = "https://files.pythonhosted.org/packages/aa/12/4792669473297f7973518bec373a955e267deb4339286f882439b8535b39/coverage-7.8.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:bbb5cc845a0292e0c520656d19d7ce40e18d0e19b22cb3e0409135a575bf79fc", size = 211684, upload-time = "2025-03-30T20:35:29.959Z" }, { url = "https://files.pythonhosted.org/packages/be/e1/2a4ec273894000ebedd789e8f2fc3813fcaf486074f87fd1c5b2cb1c0a2b/coverage-7.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4dfd9a93db9e78666d178d4f08a5408aa3f2474ad4d0e0378ed5f2ef71640cb6", size = 211935, upload-time = "2025-03-30T20:35:31.912Z" }, { url = "https://files.pythonhosted.org/packages/f8/3a/7b14f6e4372786709a361729164125f6b7caf4024ce02e596c4a69bccb89/coverage-7.8.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f017a61399f13aa6d1039f75cd467be388d157cd81f1a119b9d9a68ba6f2830d", size = 245994, upload-time = "2025-03-30T20:35:33.455Z" }, { url = "https://files.pythonhosted.org/packages/54/80/039cc7f1f81dcbd01ea796d36d3797e60c106077e31fd1f526b85337d6a1/coverage-7.8.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0915742f4c82208ebf47a2b154a5334155ed9ef9fe6190674b8a46c2fb89cb05", size = 242885, upload-time = "2025-03-30T20:35:35.354Z" }, { url = "https://files.pythonhosted.org/packages/10/e0/dc8355f992b6cc2f9dcd5ef6242b62a3f73264893bc09fbb08bfcab18eb4/coverage-7.8.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a40fcf208e021eb14b0fac6bdb045c0e0cab53105f93ba0d03fd934c956143a", size = 245142, upload-time = "2025-03-30T20:35:37.121Z" }, { url = "https://files.pythonhosted.org/packages/43/1b/33e313b22cf50f652becb94c6e7dae25d8f02e52e44db37a82de9ac357e8/coverage-7.8.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a1f406a8e0995d654b2ad87c62caf6befa767885301f3b8f6f73e6f3c31ec3a6", size = 244906, upload-time = "2025-03-30T20:35:39.07Z" }, { url = "https://files.pythonhosted.org/packages/05/08/c0a8048e942e7f918764ccc99503e2bccffba1c42568693ce6955860365e/coverage-7.8.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:77af0f6447a582fdc7de5e06fa3757a3ef87769fbb0fdbdeba78c23049140a47", size = 243124, upload-time = "2025-03-30T20:35:40.598Z" }, { url = "https://files.pythonhosted.org/packages/5b/62/ea625b30623083c2aad645c9a6288ad9fc83d570f9adb913a2abdba562dd/coverage-7.8.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f2d32f95922927186c6dbc8bc60df0d186b6edb828d299ab10898ef3f40052fe", size = 244317, upload-time = "2025-03-30T20:35:42.204Z" }, { url = "https://files.pythonhosted.org/packages/62/cb/3871f13ee1130a6c8f020e2f71d9ed269e1e2124aa3374d2180ee451cee9/coverage-7.8.0-cp312-cp312-win32.whl", hash = "sha256:769773614e676f9d8e8a0980dd7740f09a6ea386d0f383db6821df07d0f08545", size = 214170, upload-time = "2025-03-30T20:35:44.216Z" }, { url = "https://files.pythonhosted.org/packages/88/26/69fe1193ab0bfa1eb7a7c0149a066123611baba029ebb448500abd8143f9/coverage-7.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:e5d2b9be5b0693cf21eb4ce0ec8d211efb43966f6657807f6859aab3814f946b", size = 214969, upload-time = "2025-03-30T20:35:45.797Z" }, { url = "https://files.pythonhosted.org/packages/f3/21/87e9b97b568e223f3438d93072479c2f36cc9b3f6b9f7094b9d50232acc0/coverage-7.8.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5ac46d0c2dd5820ce93943a501ac5f6548ea81594777ca585bf002aa8854cacd", size = 211708, upload-time = "2025-03-30T20:35:47.417Z" }, { url = "https://files.pythonhosted.org/packages/75/be/882d08b28a0d19c9c4c2e8a1c6ebe1f79c9c839eb46d4fca3bd3b34562b9/coverage-7.8.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:771eb7587a0563ca5bb6f622b9ed7f9d07bd08900f7589b4febff05f469bea00", size = 211981, upload-time = "2025-03-30T20:35:49.002Z" }, { url = "https://files.pythonhosted.org/packages/7a/1d/ce99612ebd58082fbe3f8c66f6d8d5694976c76a0d474503fa70633ec77f/coverage-7.8.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42421e04069fb2cbcbca5a696c4050b84a43b05392679d4068acbe65449b5c64", size = 245495, upload-time = "2025-03-30T20:35:51.073Z" }, { url = "https://files.pythonhosted.org/packages/dc/8d/6115abe97df98db6b2bd76aae395fcc941d039a7acd25f741312ced9a78f/coverage-7.8.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:554fec1199d93ab30adaa751db68acec2b41c5602ac944bb19187cb9a41a8067", size = 242538, upload-time = "2025-03-30T20:35:52.941Z" }, { url = "https://files.pythonhosted.org/packages/cb/74/2f8cc196643b15bc096d60e073691dadb3dca48418f08bc78dd6e899383e/coverage-7.8.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5aaeb00761f985007b38cf463b1d160a14a22c34eb3f6a39d9ad6fc27cb73008", size = 244561, upload-time = "2025-03-30T20:35:54.658Z" }, { url = "https://files.pythonhosted.org/packages/22/70/c10c77cd77970ac965734fe3419f2c98665f6e982744a9bfb0e749d298f4/coverage-7.8.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:581a40c7b94921fffd6457ffe532259813fc68eb2bdda60fa8cc343414ce3733", size = 244633, upload-time = "2025-03-30T20:35:56.221Z" }, { url = "https://files.pythonhosted.org/packages/38/5a/4f7569d946a07c952688debee18c2bb9ab24f88027e3d71fd25dbc2f9dca/coverage-7.8.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f319bae0321bc838e205bf9e5bc28f0a3165f30c203b610f17ab5552cff90323", size = 242712, upload-time = "2025-03-30T20:35:57.801Z" }, { url = "https://files.pythonhosted.org/packages/bb/a1/03a43b33f50475a632a91ea8c127f7e35e53786dbe6781c25f19fd5a65f8/coverage-7.8.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:04bfec25a8ef1c5f41f5e7e5c842f6b615599ca8ba8391ec33a9290d9d2db3a3", size = 244000, upload-time = "2025-03-30T20:35:59.378Z" }, { url = "https://files.pythonhosted.org/packages/6a/89/ab6c43b1788a3128e4d1b7b54214548dcad75a621f9d277b14d16a80d8a1/coverage-7.8.0-cp313-cp313-win32.whl", hash = "sha256:dd19608788b50eed889e13a5d71d832edc34fc9dfce606f66e8f9f917eef910d", size = 214195, upload-time = "2025-03-30T20:36:01.005Z" }, { url = "https://files.pythonhosted.org/packages/12/12/6bf5f9a8b063d116bac536a7fb594fc35cb04981654cccb4bbfea5dcdfa0/coverage-7.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:a9abbccd778d98e9c7e85038e35e91e67f5b520776781d9a1e2ee9d400869487", size = 214998, upload-time = "2025-03-30T20:36:03.006Z" }, { url = "https://files.pythonhosted.org/packages/2a/e6/1e9df74ef7a1c983a9c7443dac8aac37a46f1939ae3499424622e72a6f78/coverage-7.8.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:18c5ae6d061ad5b3e7eef4363fb27a0576012a7447af48be6c75b88494c6cf25", size = 212541, upload-time = "2025-03-30T20:36:04.638Z" }, { url = "https://files.pythonhosted.org/packages/04/51/c32174edb7ee49744e2e81c4b1414ac9df3dacfcb5b5f273b7f285ad43f6/coverage-7.8.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:95aa6ae391a22bbbce1b77ddac846c98c5473de0372ba5c463480043a07bff42", size = 212767, upload-time = "2025-03-30T20:36:06.503Z" }, { url = "https://files.pythonhosted.org/packages/e9/8f/f454cbdb5212f13f29d4a7983db69169f1937e869a5142bce983ded52162/coverage-7.8.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e013b07ba1c748dacc2a80e69a46286ff145935f260eb8c72df7185bf048f502", size = 256997, upload-time = "2025-03-30T20:36:08.137Z" }, { url = "https://files.pythonhosted.org/packages/e6/74/2bf9e78b321216d6ee90a81e5c22f912fc428442c830c4077b4a071db66f/coverage-7.8.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d766a4f0e5aa1ba056ec3496243150698dc0481902e2b8559314368717be82b1", size = 252708, upload-time = "2025-03-30T20:36:09.781Z" }, { url = "https://files.pythonhosted.org/packages/92/4d/50d7eb1e9a6062bee6e2f92e78b0998848a972e9afad349b6cdde6fa9e32/coverage-7.8.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad80e6b4a0c3cb6f10f29ae4c60e991f424e6b14219d46f1e7d442b938ee68a4", size = 255046, upload-time = "2025-03-30T20:36:11.409Z" }, { url = "https://files.pythonhosted.org/packages/40/9e/71fb4e7402a07c4198ab44fc564d09d7d0ffca46a9fb7b0a7b929e7641bd/coverage-7.8.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b87eb6fc9e1bb8f98892a2458781348fa37e6925f35bb6ceb9d4afd54ba36c73", size = 256139, upload-time = "2025-03-30T20:36:13.86Z" }, { url = "https://files.pythonhosted.org/packages/49/1a/78d37f7a42b5beff027e807c2843185961fdae7fe23aad5a4837c93f9d25/coverage-7.8.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:d1ba00ae33be84066cfbe7361d4e04dec78445b2b88bdb734d0d1cbab916025a", size = 254307, upload-time = "2025-03-30T20:36:16.074Z" }, { url = "https://files.pythonhosted.org/packages/58/e9/8fb8e0ff6bef5e170ee19d59ca694f9001b2ec085dc99b4f65c128bb3f9a/coverage-7.8.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f3c38e4e5ccbdc9198aecc766cedbb134b2d89bf64533973678dfcf07effd883", size = 255116, upload-time = "2025-03-30T20:36:18.033Z" }, { url = "https://files.pythonhosted.org/packages/56/b0/d968ecdbe6fe0a863de7169bbe9e8a476868959f3af24981f6a10d2b6924/coverage-7.8.0-cp313-cp313t-win32.whl", hash = "sha256:379fe315e206b14e21db5240f89dc0774bdd3e25c3c58c2c733c99eca96f1ada", size = 214909, upload-time = "2025-03-30T20:36:19.644Z" }, { url = "https://files.pythonhosted.org/packages/87/e9/d6b7ef9fecf42dfb418d93544af47c940aa83056c49e6021a564aafbc91f/coverage-7.8.0-cp313-cp313t-win_amd64.whl", hash = "sha256:2e4b6b87bb0c846a9315e3ab4be2d52fac905100565f4b92f02c445c8799e257", size = 216068, upload-time = "2025-03-30T20:36:21.282Z" }, { url = "https://files.pythonhosted.org/packages/60/0c/5da94be095239814bf2730a28cffbc48d6df4304e044f80d39e1ae581997/coverage-7.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fa260de59dfb143af06dcf30c2be0b200bed2a73737a8a59248fcb9fa601ef0f", size = 211377, upload-time = "2025-03-30T20:36:23.298Z" }, { url = "https://files.pythonhosted.org/packages/d5/cb/b9e93ebf193a0bb89dbcd4f73d7b0e6ecb7c1b6c016671950e25f041835e/coverage-7.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:96121edfa4c2dfdda409877ea8608dd01de816a4dc4a0523356067b305e4e17a", size = 211803, upload-time = "2025-03-30T20:36:25.74Z" }, { url = "https://files.pythonhosted.org/packages/78/1a/cdbfe9e1bb14d3afcaf6bb6e1b9ba76c72666e329cd06865bbd241efd652/coverage-7.8.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b8af63b9afa1031c0ef05b217faa598f3069148eeee6bb24b79da9012423b82", size = 240561, upload-time = "2025-03-30T20:36:27.548Z" }, { url = "https://files.pythonhosted.org/packages/59/04/57f1223f26ac018d7ce791bfa65b0c29282de3e041c1cd3ed430cfeac5a5/coverage-7.8.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:89b1f4af0d4afe495cd4787a68e00f30f1d15939f550e869de90a86efa7e0814", size = 238488, upload-time = "2025-03-30T20:36:29.175Z" }, { url = "https://files.pythonhosted.org/packages/b7/b1/0f25516ae2a35e265868670384feebe64e7857d9cffeeb3887b0197e2ba2/coverage-7.8.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94ec0be97723ae72d63d3aa41961a0b9a6f5a53ff599813c324548d18e3b9e8c", size = 239589, upload-time = "2025-03-30T20:36:30.876Z" }, { url = "https://files.pythonhosted.org/packages/e0/a4/99d88baac0d1d5a46ceef2dd687aac08fffa8795e4c3e71b6f6c78e14482/coverage-7.8.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:8a1d96e780bdb2d0cbb297325711701f7c0b6f89199a57f2049e90064c29f6bd", size = 239366, upload-time = "2025-03-30T20:36:32.563Z" }, { url = "https://files.pythonhosted.org/packages/ea/9e/1db89e135feb827a868ed15f8fc857160757f9cab140ffee21342c783ceb/coverage-7.8.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:f1d8a2a57b47142b10374902777e798784abf400a004b14f1b0b9eaf1e528ba4", size = 237591, upload-time = "2025-03-30T20:36:34.721Z" }, { url = "https://files.pythonhosted.org/packages/1b/6d/ac4d6fdfd0e201bc82d1b08adfacb1e34b40d21a22cdd62cfaf3c1828566/coverage-7.8.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:cf60dd2696b457b710dd40bf17ad269d5f5457b96442f7f85722bdb16fa6c899", size = 238572, upload-time = "2025-03-30T20:36:36.805Z" }, { url = "https://files.pythonhosted.org/packages/25/5e/917cbe617c230f7f1745b6a13e780a3a1cd1cf328dbcd0fd8d7ec52858cd/coverage-7.8.0-cp39-cp39-win32.whl", hash = "sha256:be945402e03de47ba1872cd5236395e0f4ad635526185a930735f66710e1bd3f", size = 213966, upload-time = "2025-03-30T20:36:38.551Z" }, { url = "https://files.pythonhosted.org/packages/bd/93/72b434fe550135869f9ea88dd36068af19afce666db576e059e75177e813/coverage-7.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:90e7fbc6216ecaffa5a880cdc9c77b7418c1dcb166166b78dbc630d07f278cc3", size = 214852, upload-time = "2025-03-30T20:36:40.209Z" }, { url = "https://files.pythonhosted.org/packages/c4/f1/1da77bb4c920aa30e82fa9b6ea065da3467977c2e5e032e38e66f1c57ffd/coverage-7.8.0-pp39.pp310.pp311-none-any.whl", hash = "sha256:b8194fb8e50d556d5849753de991d390c5a1edeeba50f68e3a9253fbd8bf8ccd", size = 203443, upload-time = "2025-03-30T20:36:41.959Z" }, { url = "https://files.pythonhosted.org/packages/59/f1/4da7717f0063a222db253e7121bd6a56f6fb1ba439dcc36659088793347c/coverage-7.8.0-py3-none-any.whl", hash = "sha256:dbf364b4c5e7bae9250528167dfe40219b62e2d573c854d74be213e1e52069f7", size = 203435, upload-time = "2025-03-30T20:36:43.61Z" }, ] [package.optional-dependencies] toml = [ { name = "tomli", marker = "python_full_version >= '3.9' and python_full_version <= '3.11'" }, ] [[package]] name = "dirty-equals" version = "0.9.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytz", marker = "python_full_version < '3.9'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/b0/99/133892f401ced5a27e641a473c547d5fbdb39af8f85dac8a9d633ea3e7a7/dirty_equals-0.9.0.tar.gz", hash = "sha256:17f515970b04ed7900b733c95fd8091f4f85e52f1fb5f268757f25c858eb1f7b", size = 50412, upload-time = "2025-01-11T23:23:40.491Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/77/0c/03cc99bf3b6328604b10829de3460f2b2ad3373200c45665c38508e550c6/dirty_equals-0.9.0-py3-none-any.whl", hash = "sha256:ff4d027f5cfa1b69573af00f7ba9043ea652dbdce3fe5cbe828e478c7346db9c", size = 28226, upload-time = "2025-01-11T23:23:37.489Z" }, ] [[package]] name = "dnspython" version = "2.6.1" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version < '3.9'", ] sdist = { url = "https://files.pythonhosted.org/packages/37/7d/c871f55054e403fdfd6b8f65fd6d1c4e147ed100d3e9f9ba1fe695403939/dnspython-2.6.1.tar.gz", hash = "sha256:e8f0f9c23a7b7cb99ded64e6c3a6f3e701d78f50c55e002b839dea7225cff7cc", size = 332727, upload-time = "2024-02-18T18:48:48.952Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/87/a1/8c5287991ddb8d3e4662f71356d9656d91ab3a36618c3dd11b280df0d255/dnspython-2.6.1-py3-none-any.whl", hash = "sha256:5ef3b9680161f6fa89daf8ad451b5f1a33b18ae8a1c6778cdf4b43f08c0a6e50", size = 307696, upload-time = "2024-02-18T18:48:46.786Z" }, ] [[package]] name = "dnspython" version = "2.7.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.9'", ] sdist = { url = "https://files.pythonhosted.org/packages/b5/4a/263763cb2ba3816dd94b08ad3a33d5fdae34ecb856678773cc40a3605829/dnspython-2.7.0.tar.gz", hash = "sha256:ce9c432eda0dc91cf618a5cedf1a4e142651196bbcd2c80e89ed5a907e5cfaf1", size = 345197, upload-time = "2024-10-05T20:14:59.362Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/68/1b/e0a87d256e40e8c888847551b20a017a6b98139178505dc7ffb96f04e954/dnspython-2.7.0-py3-none-any.whl", hash = "sha256:b4c34b7d10b51bcc3a5071e7b8dee77939f1e878477eeecc965e9835f63c6c86", size = 313632, upload-time = "2024-10-05T20:14:57.687Z" }, ] [[package]] name = "exceptiongroup" version = "1.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88", size = 29749, upload-time = "2025-05-10T17:42:51.123Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/36/f4/c6e662dade71f56cd2f3735141b265c3c79293c109549c1e6933b0651ffc/exceptiongroup-1.3.0-py3-none-any.whl", hash = "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10", size = 16674, upload-time = "2025-05-10T17:42:49.33Z" }, ] [[package]] name = "importlib-resources" version = "6.4.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "zipp", marker = "python_full_version < '3.9'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/98/be/f3e8c6081b684f176b761e6a2fef02a0be939740ed6f54109a2951d806f3/importlib_resources-6.4.5.tar.gz", hash = "sha256:980862a1d16c9e147a59603677fa2aa5fd82b87f223b6cb870695bcfce830065", size = 43372, upload-time = "2024-09-09T17:03:14.677Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/e1/6a/4604f9ae2fa62ef47b9de2fa5ad599589d28c9fd1d335f32759813dfa91e/importlib_resources-6.4.5-py3-none-any.whl", hash = "sha256:ac29d5f956f01d5e4bb63102a5a19957f1b9175e45649977264a1416783bb717", size = 36115, upload-time = "2024-09-09T17:03:13.39Z" }, ] [[package]] name = "iniconfig" version = "2.1.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size = 4793, upload-time = "2025-03-19T20:09:59.721Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050, upload-time = "2025-03-19T20:10:01.071Z" }, ] [[package]] name = "markdown-it-py" version = "3.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mdurl" }, ] sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596, upload-time = "2023-06-03T06:41:14.443Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528, upload-time = "2023-06-03T06:41:11.019Z" }, ] [[package]] name = "mdurl" version = "0.1.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, ] [[package]] name = "mypy" version = "1.14.1" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version < '3.9'", ] dependencies = [ { name = "mypy-extensions", marker = "python_full_version < '3.9'" }, { name = "tomli", marker = "python_full_version < '3.9'" }, { name = "typing-extensions", marker = "python_full_version < '3.9'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/b9/eb/2c92d8ea1e684440f54fa49ac5d9a5f19967b7b472a281f419e69a8d228e/mypy-1.14.1.tar.gz", hash = "sha256:7ec88144fe9b510e8475ec2f5f251992690fcf89ccb4500b214b4226abcd32d6", size = 3216051, upload-time = "2024-12-30T16:39:07.335Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/9b/7a/87ae2adb31d68402da6da1e5f30c07ea6063e9f09b5e7cfc9dfa44075e74/mypy-1.14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:52686e37cf13d559f668aa398dd7ddf1f92c5d613e4f8cb262be2fb4fedb0fcb", size = 11211002, upload-time = "2024-12-30T16:37:22.435Z" }, { url = "https://files.pythonhosted.org/packages/e1/23/eada4c38608b444618a132be0d199b280049ded278b24cbb9d3fc59658e4/mypy-1.14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1fb545ca340537d4b45d3eecdb3def05e913299ca72c290326be19b3804b39c0", size = 10358400, upload-time = "2024-12-30T16:37:53.526Z" }, { url = "https://files.pythonhosted.org/packages/43/c9/d6785c6f66241c62fd2992b05057f404237deaad1566545e9f144ced07f5/mypy-1.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:90716d8b2d1f4cd503309788e51366f07c56635a3309b0f6a32547eaaa36a64d", size = 12095172, upload-time = "2024-12-30T16:37:50.332Z" }, { url = "https://files.pythonhosted.org/packages/c3/62/daa7e787770c83c52ce2aaf1a111eae5893de9e004743f51bfcad9e487ec/mypy-1.14.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2ae753f5c9fef278bcf12e1a564351764f2a6da579d4a81347e1d5a15819997b", size = 12828732, upload-time = "2024-12-30T16:37:29.96Z" }, { url = "https://files.pythonhosted.org/packages/1b/a2/5fb18318a3637f29f16f4e41340b795da14f4751ef4f51c99ff39ab62e52/mypy-1.14.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e0fe0f5feaafcb04505bcf439e991c6d8f1bf8b15f12b05feeed96e9e7bf1427", size = 13012197, upload-time = "2024-12-30T16:38:05.037Z" }, { url = "https://files.pythonhosted.org/packages/28/99/e153ce39105d164b5f02c06c35c7ba958aaff50a2babba7d080988b03fe7/mypy-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:7d54bd85b925e501c555a3227f3ec0cfc54ee8b6930bd6141ec872d1c572f81f", size = 9780836, upload-time = "2024-12-30T16:37:19.726Z" }, { url = "https://files.pythonhosted.org/packages/da/11/a9422850fd506edbcdc7f6090682ecceaf1f87b9dd847f9df79942da8506/mypy-1.14.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f995e511de847791c3b11ed90084a7a0aafdc074ab88c5a9711622fe4751138c", size = 11120432, upload-time = "2024-12-30T16:37:11.533Z" }, { url = "https://files.pythonhosted.org/packages/b6/9e/47e450fd39078d9c02d620545b2cb37993a8a8bdf7db3652ace2f80521ca/mypy-1.14.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d64169ec3b8461311f8ce2fd2eb5d33e2d0f2c7b49116259c51d0d96edee48d1", size = 10279515, upload-time = "2024-12-30T16:37:40.724Z" }, { url = "https://files.pythonhosted.org/packages/01/b5/6c8d33bd0f851a7692a8bfe4ee75eb82b6983a3cf39e5e32a5d2a723f0c1/mypy-1.14.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ba24549de7b89b6381b91fbc068d798192b1b5201987070319889e93038967a8", size = 12025791, upload-time = "2024-12-30T16:36:58.73Z" }, { url = "https://files.pythonhosted.org/packages/f0/4c/e10e2c46ea37cab5c471d0ddaaa9a434dc1d28650078ac1b56c2d7b9b2e4/mypy-1.14.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:183cf0a45457d28ff9d758730cd0210419ac27d4d3f285beda038c9083363b1f", size = 12749203, upload-time = "2024-12-30T16:37:03.741Z" }, { url = "https://files.pythonhosted.org/packages/88/55/beacb0c69beab2153a0f57671ec07861d27d735a0faff135a494cd4f5020/mypy-1.14.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f2a0ecc86378f45347f586e4163d1769dd81c5a223d577fe351f26b179e148b1", size = 12885900, upload-time = "2024-12-30T16:37:57.948Z" }, { url = "https://files.pythonhosted.org/packages/a2/75/8c93ff7f315c4d086a2dfcde02f713004357d70a163eddb6c56a6a5eff40/mypy-1.14.1-cp311-cp311-win_amd64.whl", hash = "sha256:ad3301ebebec9e8ee7135d8e3109ca76c23752bac1e717bc84cd3836b4bf3eae", size = 9777869, upload-time = "2024-12-30T16:37:33.428Z" }, { url = "https://files.pythonhosted.org/packages/43/1b/b38c079609bb4627905b74fc6a49849835acf68547ac33d8ceb707de5f52/mypy-1.14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:30ff5ef8519bbc2e18b3b54521ec319513a26f1bba19a7582e7b1f58a6e69f14", size = 11266668, upload-time = "2024-12-30T16:38:02.211Z" }, { url = "https://files.pythonhosted.org/packages/6b/75/2ed0d2964c1ffc9971c729f7a544e9cd34b2cdabbe2d11afd148d7838aa2/mypy-1.14.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cb9f255c18052343c70234907e2e532bc7e55a62565d64536dbc7706a20b78b9", size = 10254060, upload-time = "2024-12-30T16:37:46.131Z" }, { url = "https://files.pythonhosted.org/packages/a1/5f/7b8051552d4da3c51bbe8fcafffd76a6823779101a2b198d80886cd8f08e/mypy-1.14.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8b4e3413e0bddea671012b063e27591b953d653209e7a4fa5e48759cda77ca11", size = 11933167, upload-time = "2024-12-30T16:37:43.534Z" }, { url = "https://files.pythonhosted.org/packages/04/90/f53971d3ac39d8b68bbaab9a4c6c58c8caa4d5fd3d587d16f5927eeeabe1/mypy-1.14.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:553c293b1fbdebb6c3c4030589dab9fafb6dfa768995a453d8a5d3b23784af2e", size = 12864341, upload-time = "2024-12-30T16:37:36.249Z" }, { url = "https://files.pythonhosted.org/packages/03/d2/8bc0aeaaf2e88c977db41583559319f1821c069e943ada2701e86d0430b7/mypy-1.14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fad79bfe3b65fe6a1efaed97b445c3d37f7be9fdc348bdb2d7cac75579607c89", size = 12972991, upload-time = "2024-12-30T16:37:06.743Z" }, { url = "https://files.pythonhosted.org/packages/6f/17/07815114b903b49b0f2cf7499f1c130e5aa459411596668267535fe9243c/mypy-1.14.1-cp312-cp312-win_amd64.whl", hash = "sha256:8fa2220e54d2946e94ab6dbb3ba0a992795bd68b16dc852db33028df2b00191b", size = 9879016, upload-time = "2024-12-30T16:37:15.02Z" }, { url = "https://files.pythonhosted.org/packages/9e/15/bb6a686901f59222275ab228453de741185f9d54fecbaacec041679496c6/mypy-1.14.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:92c3ed5afb06c3a8e188cb5da4984cab9ec9a77ba956ee419c68a388b4595255", size = 11252097, upload-time = "2024-12-30T16:37:25.144Z" }, { url = "https://files.pythonhosted.org/packages/f8/b3/8b0f74dfd072c802b7fa368829defdf3ee1566ba74c32a2cb2403f68024c/mypy-1.14.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:dbec574648b3e25f43d23577309b16534431db4ddc09fda50841f1e34e64ed34", size = 10239728, upload-time = "2024-12-30T16:38:08.634Z" }, { url = "https://files.pythonhosted.org/packages/c5/9b/4fd95ab20c52bb5b8c03cc49169be5905d931de17edfe4d9d2986800b52e/mypy-1.14.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8c6d94b16d62eb3e947281aa7347d78236688e21081f11de976376cf010eb31a", size = 11924965, upload-time = "2024-12-30T16:38:12.132Z" }, { url = "https://files.pythonhosted.org/packages/56/9d/4a236b9c57f5d8f08ed346914b3f091a62dd7e19336b2b2a0d85485f82ff/mypy-1.14.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d4b19b03fdf54f3c5b2fa474c56b4c13c9dbfb9a2db4370ede7ec11a2c5927d9", size = 12867660, upload-time = "2024-12-30T16:38:17.342Z" }, { url = "https://files.pythonhosted.org/packages/40/88/a61a5497e2f68d9027de2bb139c7bb9abaeb1be1584649fa9d807f80a338/mypy-1.14.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0c911fde686394753fff899c409fd4e16e9b294c24bfd5e1ea4675deae1ac6fd", size = 12969198, upload-time = "2024-12-30T16:38:32.839Z" }, { url = "https://files.pythonhosted.org/packages/54/da/3d6fc5d92d324701b0c23fb413c853892bfe0e1dbe06c9138037d459756b/mypy-1.14.1-cp313-cp313-win_amd64.whl", hash = "sha256:8b21525cb51671219f5307be85f7e646a153e5acc656e5cebf64bfa076c50107", size = 9885276, upload-time = "2024-12-30T16:38:20.828Z" }, { url = "https://files.pythonhosted.org/packages/39/02/1817328c1372be57c16148ce7d2bfcfa4a796bedaed897381b1aad9b267c/mypy-1.14.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7084fb8f1128c76cd9cf68fe5971b37072598e7c31b2f9f95586b65c741a9d31", size = 11143050, upload-time = "2024-12-30T16:38:29.743Z" }, { url = "https://files.pythonhosted.org/packages/b9/07/99db9a95ece5e58eee1dd87ca456a7e7b5ced6798fd78182c59c35a7587b/mypy-1.14.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8f845a00b4f420f693f870eaee5f3e2692fa84cc8514496114649cfa8fd5e2c6", size = 10321087, upload-time = "2024-12-30T16:38:14.739Z" }, { url = "https://files.pythonhosted.org/packages/9a/eb/85ea6086227b84bce79b3baf7f465b4732e0785830726ce4a51528173b71/mypy-1.14.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:44bf464499f0e3a2d14d58b54674dee25c031703b2ffc35064bd0df2e0fac319", size = 12066766, upload-time = "2024-12-30T16:38:47.038Z" }, { url = "https://files.pythonhosted.org/packages/4b/bb/f01bebf76811475d66359c259eabe40766d2f8ac8b8250d4e224bb6df379/mypy-1.14.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c99f27732c0b7dc847adb21c9d47ce57eb48fa33a17bc6d7d5c5e9f9e7ae5bac", size = 12787111, upload-time = "2024-12-30T16:39:02.444Z" }, { url = "https://files.pythonhosted.org/packages/2f/c9/84837ff891edcb6dcc3c27d85ea52aab0c4a34740ff5f0ccc0eb87c56139/mypy-1.14.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:bce23c7377b43602baa0bd22ea3265c49b9ff0b76eb315d6c34721af4cdf1d9b", size = 12974331, upload-time = "2024-12-30T16:38:23.849Z" }, { url = "https://files.pythonhosted.org/packages/84/5f/901e18464e6a13f8949b4909535be3fa7f823291b8ab4e4b36cfe57d6769/mypy-1.14.1-cp38-cp38-win_amd64.whl", hash = "sha256:8edc07eeade7ebc771ff9cf6b211b9a7d93687ff892150cb5692e4f4272b0837", size = 9763210, upload-time = "2024-12-30T16:38:36.299Z" }, { url = "https://files.pythonhosted.org/packages/ca/1f/186d133ae2514633f8558e78cd658070ba686c0e9275c5a5c24a1e1f0d67/mypy-1.14.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3888a1816d69f7ab92092f785a462944b3ca16d7c470d564165fe703b0970c35", size = 11200493, upload-time = "2024-12-30T16:38:26.935Z" }, { url = "https://files.pythonhosted.org/packages/af/fc/4842485d034e38a4646cccd1369f6b1ccd7bc86989c52770d75d719a9941/mypy-1.14.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:46c756a444117c43ee984bd055db99e498bc613a70bbbc120272bd13ca579fbc", size = 10357702, upload-time = "2024-12-30T16:38:50.623Z" }, { url = "https://files.pythonhosted.org/packages/b4/e6/457b83f2d701e23869cfec013a48a12638f75b9d37612a9ddf99072c1051/mypy-1.14.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:27fc248022907e72abfd8e22ab1f10e903915ff69961174784a3900a8cba9ad9", size = 12091104, upload-time = "2024-12-30T16:38:53.735Z" }, { url = "https://files.pythonhosted.org/packages/f1/bf/76a569158db678fee59f4fd30b8e7a0d75bcbaeef49edd882a0d63af6d66/mypy-1.14.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:499d6a72fb7e5de92218db961f1a66d5f11783f9ae549d214617edab5d4dbdbb", size = 12830167, upload-time = "2024-12-30T16:38:56.437Z" }, { url = "https://files.pythonhosted.org/packages/43/bc/0bc6b694b3103de9fed61867f1c8bd33336b913d16831431e7cb48ef1c92/mypy-1.14.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:57961db9795eb566dc1d1b4e9139ebc4c6b0cb6e7254ecde69d1552bf7613f60", size = 13013834, upload-time = "2024-12-30T16:38:59.204Z" }, { url = "https://files.pythonhosted.org/packages/b0/79/5f5ec47849b6df1e6943d5fd8e6632fbfc04b4fd4acfa5a5a9535d11b4e2/mypy-1.14.1-cp39-cp39-win_amd64.whl", hash = "sha256:07ba89fdcc9451f2ebb02853deb6aaaa3d2239a236669a63ab3801bbf923ef5c", size = 9781231, upload-time = "2024-12-30T16:39:05.124Z" }, { url = "https://files.pythonhosted.org/packages/a0/b5/32dd67b69a16d088e533962e5044e51004176a9952419de0370cdaead0f8/mypy-1.14.1-py3-none-any.whl", hash = "sha256:b66a60cc4073aeb8ae00057f9c1f64d49e90f918fbcef9a977eb121da8b8f1d1", size = 2752905, upload-time = "2024-12-30T16:38:42.021Z" }, ] [[package]] name = "mypy" version = "1.15.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.9'", ] dependencies = [ { name = "mypy-extensions", marker = "python_full_version >= '3.9'" }, { name = "tomli", marker = "python_full_version >= '3.9' and python_full_version < '3.11'" }, { name = "typing-extensions", marker = "python_full_version >= '3.9'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ce/43/d5e49a86afa64bd3839ea0d5b9c7103487007d728e1293f52525d6d5486a/mypy-1.15.0.tar.gz", hash = "sha256:404534629d51d3efea5c800ee7c42b72a6554d6c400e6a79eafe15d11341fd43", size = 3239717, upload-time = "2025-02-05T03:50:34.655Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/68/f8/65a7ce8d0e09b6329ad0c8d40330d100ea343bd4dd04c4f8ae26462d0a17/mypy-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:979e4e1a006511dacf628e36fadfecbcc0160a8af6ca7dad2f5025529e082c13", size = 10738433, upload-time = "2025-02-05T03:49:29.145Z" }, { url = "https://files.pythonhosted.org/packages/b4/95/9c0ecb8eacfe048583706249439ff52105b3f552ea9c4024166c03224270/mypy-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c4bb0e1bd29f7d34efcccd71cf733580191e9a264a2202b0239da95984c5b559", size = 9861472, upload-time = "2025-02-05T03:49:16.986Z" }, { url = "https://files.pythonhosted.org/packages/84/09/9ec95e982e282e20c0d5407bc65031dfd0f0f8ecc66b69538296e06fcbee/mypy-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:be68172e9fd9ad8fb876c6389f16d1c1b5f100ffa779f77b1fb2176fcc9ab95b", size = 11611424, upload-time = "2025-02-05T03:49:46.908Z" }, { url = "https://files.pythonhosted.org/packages/78/13/f7d14e55865036a1e6a0a69580c240f43bc1f37407fe9235c0d4ef25ffb0/mypy-1.15.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c7be1e46525adfa0d97681432ee9fcd61a3964c2446795714699a998d193f1a3", size = 12365450, upload-time = "2025-02-05T03:50:05.89Z" }, { url = "https://files.pythonhosted.org/packages/48/e1/301a73852d40c241e915ac6d7bcd7fedd47d519246db2d7b86b9d7e7a0cb/mypy-1.15.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2e2c2e6d3593f6451b18588848e66260ff62ccca522dd231cd4dd59b0160668b", size = 12551765, upload-time = "2025-02-05T03:49:33.56Z" }, { url = "https://files.pythonhosted.org/packages/77/ba/c37bc323ae5fe7f3f15a28e06ab012cd0b7552886118943e90b15af31195/mypy-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:6983aae8b2f653e098edb77f893f7b6aca69f6cffb19b2cc7443f23cce5f4828", size = 9274701, upload-time = "2025-02-05T03:49:38.981Z" }, { url = "https://files.pythonhosted.org/packages/03/bc/f6339726c627bd7ca1ce0fa56c9ae2d0144604a319e0e339bdadafbbb599/mypy-1.15.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2922d42e16d6de288022e5ca321cd0618b238cfc5570e0263e5ba0a77dbef56f", size = 10662338, upload-time = "2025-02-05T03:50:17.287Z" }, { url = "https://files.pythonhosted.org/packages/e2/90/8dcf506ca1a09b0d17555cc00cd69aee402c203911410136cd716559efe7/mypy-1.15.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2ee2d57e01a7c35de00f4634ba1bbf015185b219e4dc5909e281016df43f5ee5", size = 9787540, upload-time = "2025-02-05T03:49:51.21Z" }, { url = "https://files.pythonhosted.org/packages/05/05/a10f9479681e5da09ef2f9426f650d7b550d4bafbef683b69aad1ba87457/mypy-1.15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:973500e0774b85d9689715feeffcc980193086551110fd678ebe1f4342fb7c5e", size = 11538051, upload-time = "2025-02-05T03:50:20.885Z" }, { url = "https://files.pythonhosted.org/packages/e9/9a/1f7d18b30edd57441a6411fcbc0c6869448d1a4bacbaee60656ac0fc29c8/mypy-1.15.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a95fb17c13e29d2d5195869262f8125dfdb5c134dc8d9a9d0aecf7525b10c2c", size = 12286751, upload-time = "2025-02-05T03:49:42.408Z" }, { url = "https://files.pythonhosted.org/packages/72/af/19ff499b6f1dafcaf56f9881f7a965ac2f474f69f6f618b5175b044299f5/mypy-1.15.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1905f494bfd7d85a23a88c5d97840888a7bd516545fc5aaedff0267e0bb54e2f", size = 12421783, upload-time = "2025-02-05T03:49:07.707Z" }, { url = "https://files.pythonhosted.org/packages/96/39/11b57431a1f686c1aed54bf794870efe0f6aeca11aca281a0bd87a5ad42c/mypy-1.15.0-cp311-cp311-win_amd64.whl", hash = "sha256:c9817fa23833ff189db061e6d2eff49b2f3b6ed9856b4a0a73046e41932d744f", size = 9265618, upload-time = "2025-02-05T03:49:54.581Z" }, { url = "https://files.pythonhosted.org/packages/98/3a/03c74331c5eb8bd025734e04c9840532226775c47a2c39b56a0c8d4f128d/mypy-1.15.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:aea39e0583d05124836ea645f412e88a5c7d0fd77a6d694b60d9b6b2d9f184fd", size = 10793981, upload-time = "2025-02-05T03:50:28.25Z" }, { url = "https://files.pythonhosted.org/packages/f0/1a/41759b18f2cfd568848a37c89030aeb03534411eef981df621d8fad08a1d/mypy-1.15.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2f2147ab812b75e5b5499b01ade1f4a81489a147c01585cda36019102538615f", size = 9749175, upload-time = "2025-02-05T03:50:13.411Z" }, { url = "https://files.pythonhosted.org/packages/12/7e/873481abf1ef112c582db832740f4c11b2bfa510e829d6da29b0ab8c3f9c/mypy-1.15.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ce436f4c6d218a070048ed6a44c0bbb10cd2cc5e272b29e7845f6a2f57ee4464", size = 11455675, upload-time = "2025-02-05T03:50:31.421Z" }, { url = "https://files.pythonhosted.org/packages/b3/d0/92ae4cde706923a2d3f2d6c39629134063ff64b9dedca9c1388363da072d/mypy-1.15.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8023ff13985661b50a5928fc7a5ca15f3d1affb41e5f0a9952cb68ef090b31ee", size = 12410020, upload-time = "2025-02-05T03:48:48.705Z" }, { url = "https://files.pythonhosted.org/packages/46/8b/df49974b337cce35f828ba6fda228152d6db45fed4c86ba56ffe442434fd/mypy-1.15.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1124a18bc11a6a62887e3e137f37f53fbae476dc36c185d549d4f837a2a6a14e", size = 12498582, upload-time = "2025-02-05T03:49:03.628Z" }, { url = "https://files.pythonhosted.org/packages/13/50/da5203fcf6c53044a0b699939f31075c45ae8a4cadf538a9069b165c1050/mypy-1.15.0-cp312-cp312-win_amd64.whl", hash = "sha256:171a9ca9a40cd1843abeca0e405bc1940cd9b305eaeea2dda769ba096932bb22", size = 9366614, upload-time = "2025-02-05T03:50:00.313Z" }, { url = "https://files.pythonhosted.org/packages/6a/9b/fd2e05d6ffff24d912f150b87db9e364fa8282045c875654ce7e32fffa66/mypy-1.15.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:93faf3fdb04768d44bf28693293f3904bbb555d076b781ad2530214ee53e3445", size = 10788592, upload-time = "2025-02-05T03:48:55.789Z" }, { url = "https://files.pythonhosted.org/packages/74/37/b246d711c28a03ead1fd906bbc7106659aed7c089d55fe40dd58db812628/mypy-1.15.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:811aeccadfb730024c5d3e326b2fbe9249bb7413553f15499a4050f7c30e801d", size = 9753611, upload-time = "2025-02-05T03:48:44.581Z" }, { url = "https://files.pythonhosted.org/packages/a6/ac/395808a92e10cfdac8003c3de9a2ab6dc7cde6c0d2a4df3df1b815ffd067/mypy-1.15.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:98b7b9b9aedb65fe628c62a6dc57f6d5088ef2dfca37903a7d9ee374d03acca5", size = 11438443, upload-time = "2025-02-05T03:49:25.514Z" }, { url = "https://files.pythonhosted.org/packages/d2/8b/801aa06445d2de3895f59e476f38f3f8d610ef5d6908245f07d002676cbf/mypy-1.15.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c43a7682e24b4f576d93072216bf56eeff70d9140241f9edec0c104d0c515036", size = 12402541, upload-time = "2025-02-05T03:49:57.623Z" }, { url = "https://files.pythonhosted.org/packages/c7/67/5a4268782eb77344cc613a4cf23540928e41f018a9a1ec4c6882baf20ab8/mypy-1.15.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:baefc32840a9f00babd83251560e0ae1573e2f9d1b067719479bfb0e987c6357", size = 12494348, upload-time = "2025-02-05T03:48:52.361Z" }, { url = "https://files.pythonhosted.org/packages/83/3e/57bb447f7bbbfaabf1712d96f9df142624a386d98fb026a761532526057e/mypy-1.15.0-cp313-cp313-win_amd64.whl", hash = "sha256:b9378e2c00146c44793c98b8d5a61039a048e31f429fb0eb546d93f4b000bedf", size = 9373648, upload-time = "2025-02-05T03:49:11.395Z" }, { url = "https://files.pythonhosted.org/packages/5a/fa/79cf41a55b682794abe71372151dbbf856e3008f6767057229e6649d294a/mypy-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e601a7fa172c2131bff456bb3ee08a88360760d0d2f8cbd7a75a65497e2df078", size = 10737129, upload-time = "2025-02-05T03:50:24.509Z" }, { url = "https://files.pythonhosted.org/packages/d3/33/dd8feb2597d648de29e3da0a8bf4e1afbda472964d2a4a0052203a6f3594/mypy-1.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:712e962a6357634fef20412699a3655c610110e01cdaa6180acec7fc9f8513ba", size = 9856335, upload-time = "2025-02-05T03:49:36.398Z" }, { url = "https://files.pythonhosted.org/packages/e4/b5/74508959c1b06b96674b364ffeb7ae5802646b32929b7701fc6b18447592/mypy-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f95579473af29ab73a10bada2f9722856792a36ec5af5399b653aa28360290a5", size = 11611935, upload-time = "2025-02-05T03:49:14.154Z" }, { url = "https://files.pythonhosted.org/packages/6c/53/da61b9d9973efcd6507183fdad96606996191657fe79701b2c818714d573/mypy-1.15.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8f8722560a14cde92fdb1e31597760dc35f9f5524cce17836c0d22841830fd5b", size = 12365827, upload-time = "2025-02-05T03:48:59.458Z" }, { url = "https://files.pythonhosted.org/packages/c1/72/965bd9ee89540c79a25778cc080c7e6ef40aa1eeac4d52cec7eae6eb5228/mypy-1.15.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1fbb8da62dc352133d7d7ca90ed2fb0e9d42bb1a32724c287d3c76c58cbaa9c2", size = 12541924, upload-time = "2025-02-05T03:50:03.12Z" }, { url = "https://files.pythonhosted.org/packages/46/d0/f41645c2eb263e6c77ada7d76f894c580c9ddb20d77f0c24d34273a4dab2/mypy-1.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:d10d994b41fb3497719bbf866f227b3489048ea4bbbb5015357db306249f7980", size = 9271176, upload-time = "2025-02-05T03:50:10.86Z" }, { url = "https://files.pythonhosted.org/packages/09/4e/a7d65c7322c510de2c409ff3828b03354a7c43f5a8ed458a7a131b41c7b9/mypy-1.15.0-py3-none-any.whl", hash = "sha256:5469affef548bd1895d86d3bf10ce2b44e33d86923c29e4d675b3e323437ea3e", size = 2221777, upload-time = "2025-02-05T03:50:08.348Z" }, ] [[package]] name = "mypy-extensions" version = "1.1.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/a2/6e/371856a3fb9d31ca8dac321cda606860fa4548858c0cc45d9d1d4ca2628b/mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558", size = 6343, upload-time = "2025-04-22T14:54:24.164Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" }, ] [[package]] name = "packaging" version = "25.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, ] [[package]] name = "pendulum" version = "3.0.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version < '3.9'", ] dependencies = [ { name = "backports-zoneinfo", marker = "python_full_version < '3.9'" }, { name = "importlib-resources", marker = "python_full_version < '3.9'" }, { name = "python-dateutil", marker = "python_full_version < '3.9'" }, { name = "time-machine", marker = "python_full_version < '3.9' and implementation_name != 'pypy'" }, { name = "tzdata", marker = "python_full_version < '3.9'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/b8/fe/27c7438c6ac8b8f8bef3c6e571855602ee784b85d072efddfff0ceb1cd77/pendulum-3.0.0.tar.gz", hash = "sha256:5d034998dea404ec31fae27af6b22cff1708f830a1ed7353be4d1019bb9f584e", size = 84524, upload-time = "2023-12-16T21:27:19.742Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/bf/2f/2f4719366d16f1e444b4e400d3de5021bc4b09965f97e45c81e08348cbdf/pendulum-3.0.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2cf9e53ef11668e07f73190c805dbdf07a1939c3298b78d5a9203a86775d1bfd", size = 362284, upload-time = "2023-12-16T21:23:53.124Z" }, { url = "https://files.pythonhosted.org/packages/30/ff/70a8f47e622e641de15b7ed8a8b66c3aa895fabc182a7d520a0c33ec850e/pendulum-3.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fb551b9b5e6059377889d2d878d940fd0bbb80ae4810543db18e6f77b02c5ef6", size = 352957, upload-time = "2023-12-16T21:23:55.553Z" }, { url = "https://files.pythonhosted.org/packages/f4/cd/4e2fb7d071e81a9b07719203fd1d329febaded59981b8709663341f758f4/pendulum-3.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c58227ac260d5b01fc1025176d7b31858c9f62595737f350d22124a9a3ad82d", size = 335784, upload-time = "2023-12-16T21:23:58.514Z" }, { url = "https://files.pythonhosted.org/packages/0f/e5/9fc684c59b6f3425cf597d9489c24c47dc96d391be9eb8c9a3c543cd7646/pendulum-3.0.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:60fb6f415fea93a11c52578eaa10594568a6716602be8430b167eb0d730f3332", size = 362215, upload-time = "2023-12-16T21:24:00.367Z" }, { url = "https://files.pythonhosted.org/packages/5a/ba/4dbb1ae42775010249ba29d01829353a9b59d9c3caf97df14d548a3b7d4c/pendulum-3.0.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b69f6b4dbcb86f2c2fe696ba991e67347bcf87fe601362a1aba6431454b46bde", size = 448632, upload-time = "2023-12-16T21:24:02.845Z" }, { url = "https://files.pythonhosted.org/packages/10/a9/0932bd7cd677bee8bdc9cb898448e47ada0f74e41f434f4ff687d03a3ea9/pendulum-3.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:138afa9c373ee450ede206db5a5e9004fd3011b3c6bbe1e57015395cd076a09f", size = 384881, upload-time = "2023-12-16T21:24:04.997Z" }, { url = "https://files.pythonhosted.org/packages/31/a9/8c9887ce8bfb8ab0db068ac2f1fe679b713f728c116bd136301c303893cd/pendulum-3.0.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:83d9031f39c6da9677164241fd0d37fbfc9dc8ade7043b5d6d62f56e81af8ad2", size = 559554, upload-time = "2023-12-16T21:24:07.941Z" }, { url = "https://files.pythonhosted.org/packages/f4/7e/70596b098b97799c78e3fc2f89394decca6f5443cac28c54082daf2d48eb/pendulum-3.0.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0c2308af4033fa534f089595bcd40a95a39988ce4059ccd3dc6acb9ef14ca44a", size = 558246, upload-time = "2023-12-16T21:24:11.53Z" }, { url = "https://files.pythonhosted.org/packages/67/5e/e646afbd1632bfbacdae79289d7d5879efdeeb5f5e58327bc5c698731107/pendulum-3.0.0-cp310-none-win_amd64.whl", hash = "sha256:9a59637cdb8462bdf2dbcb9d389518c0263799189d773ad5c11db6b13064fa79", size = 293456, upload-time = "2023-12-16T21:24:13.652Z" }, { url = "https://files.pythonhosted.org/packages/7b/f0/d60be6058657bf71281eeaa12bee85e87bac18acf6dbb7b5197bb8416537/pendulum-3.0.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:3725245c0352c95d6ca297193192020d1b0c0f83d5ee6bb09964edc2b5a2d508", size = 362283, upload-time = "2023-12-16T21:24:16.393Z" }, { url = "https://files.pythonhosted.org/packages/68/e5/0f9d8351242ddb119a40b41c0cf1d0c74cc243829eea6811f753a8ecf15f/pendulum-3.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6c035f03a3e565ed132927e2c1b691de0dbf4eb53b02a5a3c5a97e1a64e17bec", size = 352957, upload-time = "2023-12-16T21:24:20.091Z" }, { url = "https://files.pythonhosted.org/packages/30/43/70d0a08e5d6ca434ba139d19ec2a4847b0a3e461fbb82e680a9b6a4237ef/pendulum-3.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:597e66e63cbd68dd6d58ac46cb7a92363d2088d37ccde2dae4332ef23e95cd00", size = 335784, upload-time = "2023-12-16T21:24:22.12Z" }, { url = "https://files.pythonhosted.org/packages/fc/a3/7d4c0b3f57bf7b543da9088a78a6bd6c786808ca4098bd5db649fdf9f6a2/pendulum-3.0.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99a0f8172e19f3f0c0e4ace0ad1595134d5243cf75985dc2233e8f9e8de263ca", size = 362217, upload-time = "2023-12-16T21:24:25.239Z" }, { url = "https://files.pythonhosted.org/packages/8b/03/8c451d569e7f4d9898f155e793f46970eed256c5ae353ecb355584890d8a/pendulum-3.0.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:77d8839e20f54706aed425bec82a83b4aec74db07f26acd039905d1237a5e1d4", size = 448630, upload-time = "2023-12-16T21:24:27.584Z" }, { url = "https://files.pythonhosted.org/packages/84/3a/5e36479e199a034adcf6a1a95c691f0a2781ea55b9ac3bcb887e2f97d82b/pendulum-3.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afde30e8146292b059020fbc8b6f8fd4a60ae7c5e6f0afef937bbb24880bdf01", size = 384882, upload-time = "2023-12-16T21:24:29.569Z" }, { url = "https://files.pythonhosted.org/packages/4c/25/beff911dda686e0cf169bc3dbe5d10416b376a6dde94eb1bf04aa4035409/pendulum-3.0.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:660434a6fcf6303c4efd36713ca9212c753140107ee169a3fc6c49c4711c2a05", size = 559556, upload-time = "2023-12-16T21:24:32.11Z" }, { url = "https://files.pythonhosted.org/packages/e9/e8/f2aaa470adb6c720645f9f9ef30d5b223407ee327e12c6127eccf4218cb8/pendulum-3.0.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dee9e5a48c6999dc1106eb7eea3e3a50e98a50651b72c08a87ee2154e544b33e", size = 558249, upload-time = "2023-12-16T21:24:34.865Z" }, { url = "https://files.pythonhosted.org/packages/60/19/c13307ea8504d2c02c63c9dffdae1cefbd068b636ec7b18ccf2ec064d246/pendulum-3.0.0-cp311-none-win_amd64.whl", hash = "sha256:d4cdecde90aec2d67cebe4042fd2a87a4441cc02152ed7ed8fb3ebb110b94ec4", size = 293463, upload-time = "2023-12-16T21:24:37.718Z" }, { url = "https://files.pythonhosted.org/packages/6b/36/252d48610295c11c0f18e791dcc133d38c545b0bd19a5c3981652a9acb3c/pendulum-3.0.0-cp311-none-win_arm64.whl", hash = "sha256:773c3bc4ddda2dda9f1b9d51fe06762f9200f3293d75c4660c19b2614b991d83", size = 288057, upload-time = "2023-12-16T21:24:39.792Z" }, { url = "https://files.pythonhosted.org/packages/1e/37/17c8f0e7481a32f21b9002dd68912a8813f2c1d77b984e00af56eb9ae31b/pendulum-3.0.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:409e64e41418c49f973d43a28afe5df1df4f1dd87c41c7c90f1a63f61ae0f1f7", size = 362284, upload-time = "2023-12-16T21:24:42.056Z" }, { url = "https://files.pythonhosted.org/packages/12/e6/08f462f6ea87e2159f19b43ff88231d26e02bda31c10bcb29290a617ace4/pendulum-3.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a38ad2121c5ec7c4c190c7334e789c3b4624798859156b138fcc4d92295835dc", size = 352964, upload-time = "2023-12-16T21:24:44.306Z" }, { url = "https://files.pythonhosted.org/packages/47/29/b6877f6b53b91356c2c56d19ddab17b165ca994ad1e57b32c089e79f3fb5/pendulum-3.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fde4d0b2024b9785f66b7f30ed59281bd60d63d9213cda0eb0910ead777f6d37", size = 335848, upload-time = "2023-12-16T21:24:46.345Z" }, { url = "https://files.pythonhosted.org/packages/2b/77/62ca666f30b2558342deadda26290a575459a7b59248ea1e978b84175227/pendulum-3.0.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4b2c5675769fb6d4c11238132962939b960fcb365436b6d623c5864287faa319", size = 362215, upload-time = "2023-12-16T21:24:49.303Z" }, { url = "https://files.pythonhosted.org/packages/e0/29/ce37593f5ea51862c60dadf4e863d604f954478b3abbcc60a14dc05e242c/pendulum-3.0.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8af95e03e066826f0f4c65811cbee1b3123d4a45a1c3a2b4fc23c4b0dff893b5", size = 448673, upload-time = "2023-12-16T21:24:52.931Z" }, { url = "https://files.pythonhosted.org/packages/72/6a/68a8c7b8f1977d89aabfd0e2becb0921e5515dfb365097e98a522334a151/pendulum-3.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2165a8f33cb15e06c67070b8afc87a62b85c5a273e3aaa6bc9d15c93a4920d6f", size = 384891, upload-time = "2023-12-16T21:24:56.754Z" }, { url = "https://files.pythonhosted.org/packages/30/e6/edd699300f47a3c53c0d8ed26e905b9a31057c3646211e58cc540716a440/pendulum-3.0.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ad5e65b874b5e56bd942546ea7ba9dd1d6a25121db1c517700f1c9de91b28518", size = 559558, upload-time = "2023-12-16T21:24:59.132Z" }, { url = "https://files.pythonhosted.org/packages/d4/97/95a44aa5e1763d3a966551ed0e12f56508d8dfcc60e1f0395909b6a08626/pendulum-3.0.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:17fe4b2c844bbf5f0ece69cfd959fa02957c61317b2161763950d88fed8e13b9", size = 558240, upload-time = "2023-12-16T21:25:01.844Z" }, { url = "https://files.pythonhosted.org/packages/9a/91/fcd992eb36b77ab43f2cf44307b72c01a6fbb27f55c1bb2d4af30e9a6cb7/pendulum-3.0.0-cp312-none-win_amd64.whl", hash = "sha256:78f8f4e7efe5066aca24a7a57511b9c2119f5c2b5eb81c46ff9222ce11e0a7a5", size = 293456, upload-time = "2023-12-16T21:25:04.039Z" }, { url = "https://files.pythonhosted.org/packages/3b/60/ba8aa296ca6d76603d58146b4a222cd99e7da33831158b8c00240a896a56/pendulum-3.0.0-cp312-none-win_arm64.whl", hash = "sha256:28f49d8d1e32aae9c284a90b6bb3873eee15ec6e1d9042edd611b22a94ac462f", size = 288054, upload-time = "2023-12-16T21:25:05.935Z" }, { url = "https://files.pythonhosted.org/packages/9e/76/65e2e5c8fc7443c13cb50e87c52ab177a2660bd1f978b87de6962b309e07/pendulum-3.0.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:6a881d9c2a7f85bc9adafcfe671df5207f51f5715ae61f5d838b77a1356e8b7b", size = 362597, upload-time = "2023-12-16T21:25:30.611Z" }, { url = "https://files.pythonhosted.org/packages/61/8d/d922528d8a5ec22e1247773a66467eb971a20194d9aa7740c3449f61094a/pendulum-3.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d7762d2076b9b1cb718a6631ad6c16c23fc3fac76cbb8c454e81e80be98daa34", size = 353380, upload-time = "2023-12-16T21:25:33.094Z" }, { url = "https://files.pythonhosted.org/packages/ee/45/a3657c80bc86c31817dbe1646ef9a170aa2c5a5b1f55ff15ec82557f9509/pendulum-3.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e8e36a8130819d97a479a0e7bf379b66b3b1b520e5dc46bd7eb14634338df8c", size = 336154, upload-time = "2023-12-16T21:25:34.988Z" }, { url = "https://files.pythonhosted.org/packages/f0/7e/0b4d36b0210261b6c709640a6dd67dd9c720c3a5c3d8041d6d05f568ba2b/pendulum-3.0.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7dc843253ac373358ffc0711960e2dd5b94ab67530a3e204d85c6e8cb2c5fa10", size = 362743, upload-time = "2023-12-16T21:25:38.331Z" }, { url = "https://files.pythonhosted.org/packages/67/b7/b31a9b353b63d131bddceb2fa3477fd1c6bd322793d91f7f0c7607f91c94/pendulum-3.0.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0a78ad3635d609ceb1e97d6aedef6a6a6f93433ddb2312888e668365908c7120", size = 448992, upload-time = "2023-12-16T21:25:40.437Z" }, { url = "https://files.pythonhosted.org/packages/3b/e0/8d31270e49e85b28bc035c1d6c418b5842d2f63dcbbc32c8043be5fc1e16/pendulum-3.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b30a137e9e0d1f751e60e67d11fc67781a572db76b2296f7b4d44554761049d6", size = 385164, upload-time = "2023-12-16T21:25:42.907Z" }, { url = "https://files.pythonhosted.org/packages/7f/a2/4959088e14ef065f9c3700d3cb202b3aec0fc130f0b661d92c1465cb5a51/pendulum-3.0.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:c95984037987f4a457bb760455d9ca80467be792236b69d0084f228a8ada0162", size = 559786, upload-time = "2023-12-16T21:25:45.34Z" }, { url = "https://files.pythonhosted.org/packages/bb/7f/93b13e1d98e654cf13c885546337e6b487c9c1b41de384fd05b21272c851/pendulum-3.0.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d29c6e578fe0f893766c0d286adbf0b3c726a4e2341eba0917ec79c50274ec16", size = 558443, upload-time = "2023-12-16T21:25:47.587Z" }, { url = "https://files.pythonhosted.org/packages/fa/9a/9c96f12c48d5e9e6056358907d691fd35f3f47a468185762b340721fa690/pendulum-3.0.0-cp38-none-win_amd64.whl", hash = "sha256:deaba8e16dbfcb3d7a6b5fabdd5a38b7c982809567479987b9c89572df62e027", size = 293520, upload-time = "2023-12-16T21:25:49.613Z" }, { url = "https://files.pythonhosted.org/packages/b3/05/49db61d1d0a951526575d36cd571ce389f9c08b7625579e28a0ada5ed842/pendulum-3.0.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:b11aceea5b20b4b5382962b321dbc354af0defe35daa84e9ff3aae3c230df694", size = 362545, upload-time = "2023-12-16T21:25:51.566Z" }, { url = "https://files.pythonhosted.org/packages/52/e7/783425867db5df0a9661c2e91d1bd052a0636aee65634e9d758e7b53527e/pendulum-3.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a90d4d504e82ad236afac9adca4d6a19e4865f717034fc69bafb112c320dcc8f", size = 353300, upload-time = "2023-12-16T21:25:54.037Z" }, { url = "https://files.pythonhosted.org/packages/2a/75/15411992749dd450bb365ae6cc0173480a1411b80cc0a9fdc7d548d254ce/pendulum-3.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:825799c6b66e3734227756fa746cc34b3549c48693325b8b9f823cb7d21b19ac", size = 336118, upload-time = "2023-12-16T21:25:57.124Z" }, { url = "https://files.pythonhosted.org/packages/bf/64/14f8cc3147c8ee8339ca37058259134c38092829f85076aa14b5437bf546/pendulum-3.0.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad769e98dc07972e24afe0cff8d365cb6f0ebc7e65620aa1976fcfbcadc4c6f3", size = 362600, upload-time = "2023-12-16T21:25:59.162Z" }, { url = "https://files.pythonhosted.org/packages/bc/c9/d7d20ffa63b0d154f59536dcd2c6361afebc6e44a76ca34131d492624299/pendulum-3.0.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a6fc26907eb5fb8cc6188cc620bc2075a6c534d981a2f045daa5f79dfe50d512", size = 449101, upload-time = "2023-12-16T21:26:01.481Z" }, { url = "https://files.pythonhosted.org/packages/22/aa/2d6846d7f382262d894902d3cf8ee66b02aee3bab2910db0004ca0f9ef18/pendulum-3.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c717eab1b6d898c00a3e0fa7781d615b5c5136bbd40abe82be100bb06df7a56", size = 385208, upload-time = "2023-12-16T21:26:04.187Z" }, { url = "https://files.pythonhosted.org/packages/89/1c/ad9726d5e1d85c5ba24f9021baf5f6f39ef18e94fa851a7c9231adca9e75/pendulum-3.0.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3ddd1d66d1a714ce43acfe337190be055cdc221d911fc886d5a3aae28e14b76d", size = 559851, upload-time = "2023-12-16T21:26:07.429Z" }, { url = "https://files.pythonhosted.org/packages/b6/1c/e13764e578f646a1b50faad8045bb05a755e5a913854c89a0e7dd4caaa19/pendulum-3.0.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:822172853d7a9cf6da95d7b66a16c7160cb99ae6df55d44373888181d7a06edc", size = 558520, upload-time = "2023-12-16T21:26:10.716Z" }, { url = "https://files.pythonhosted.org/packages/4e/4f/6c8569ba60b933c726f6c0051519167d9f9167e49d03c6074b57bb4c204a/pendulum-3.0.0-cp39-none-win_amd64.whl", hash = "sha256:840de1b49cf1ec54c225a2a6f4f0784d50bd47f68e41dc005b7f67c7d5b5f3ae", size = 293746, upload-time = "2023-12-16T21:26:13.666Z" }, { url = "https://files.pythonhosted.org/packages/0f/7f/24d8c167937d663a9cf6d5fc5e87a87bfa320c3f002d4fbbc7bd5ff3b6f8/pendulum-3.0.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3b1f74d1e6ffe5d01d6023870e2ce5c2191486928823196f8575dcc786e107b1", size = 362388, upload-time = "2023-12-16T21:26:15.849Z" }, { url = "https://files.pythonhosted.org/packages/55/e1/33775ee68f8bbb0da967dfd818706ee69e0a054f663ee6111d5c7639f67a/pendulum-3.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:729e9f93756a2cdfa77d0fc82068346e9731c7e884097160603872686e570f07", size = 353062, upload-time = "2023-12-16T21:26:17.876Z" }, { url = "https://files.pythonhosted.org/packages/3e/1b/c3e399148c0d69c2c84c2eda45cd3580990b13f36d0c96516591bf4def56/pendulum-3.0.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e586acc0b450cd21cbf0db6bae386237011b75260a3adceddc4be15334689a9a", size = 335871, upload-time = "2023-12-16T21:26:20.284Z" }, { url = "https://files.pythonhosted.org/packages/32/6b/23dde8bd3fb78f693b81bd8fc67769b2a461918d51ed6ddf486a1a97e199/pendulum-3.0.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22e7944ffc1f0099a79ff468ee9630c73f8c7835cd76fdb57ef7320e6a409df4", size = 384859, upload-time = "2023-12-16T21:26:23.622Z" }, { url = "https://files.pythonhosted.org/packages/1d/1b/a3e0387f586d6121a15e6d02f7ae8cc3cd1ebb136fd243c1c191136ed518/pendulum-3.0.0-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:fa30af36bd8e50686846bdace37cf6707bdd044e5cb6e1109acbad3277232e04", size = 559441, upload-time = "2023-12-16T21:26:26.838Z" }, { url = "https://files.pythonhosted.org/packages/d7/23/91dea81265d5d11af0cd5053ca76730cc2c5ac14085c9a923d448e74c67f/pendulum-3.0.0-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:440215347b11914ae707981b9a57ab9c7b6983ab0babde07063c6ee75c0dc6e7", size = 558189, upload-time = "2023-12-16T21:26:29.408Z" }, { url = "https://files.pythonhosted.org/packages/7a/8a/166625d30f927e800e99f3f6556d8b3f4ad952c62d6a774844d73542b84b/pendulum-3.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:314c4038dc5e6a52991570f50edb2f08c339debdf8cea68ac355b32c4174e820", size = 293657, upload-time = "2023-12-16T21:26:32.171Z" }, { url = "https://files.pythonhosted.org/packages/c9/ff/83ce5b98c29d86d6afb951f9b73f0a1e4248fd74ea0f9104e3814d0fa479/pendulum-3.0.0-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:1c134ba2f0571d0b68b83f6972e2307a55a5a849e7dac8505c715c531d2a8795", size = 362442, upload-time = "2023-12-16T21:26:46.259Z" }, { url = "https://files.pythonhosted.org/packages/b3/c5/464ec6a334102bbcd4428d13ead2180e87b56da27a782a2ba2c15376120d/pendulum-3.0.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:385680812e7e18af200bb9b4a49777418c32422d05ad5a8eb85144c4a285907b", size = 353100, upload-time = "2023-12-16T21:26:48.128Z" }, { url = "https://files.pythonhosted.org/packages/9b/5a/4fb3a04cab1bf1c304c2d00d7d0f063e09776ac58a9a9c341a77e097ae08/pendulum-3.0.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9eec91cd87c59fb32ec49eb722f375bd58f4be790cae11c1b70fac3ee4f00da0", size = 335919, upload-time = "2023-12-16T21:26:50.575Z" }, { url = "https://files.pythonhosted.org/packages/7b/a9/752c29e4ae27aa2e51940861a8c803e0966d16b5cca65229ef106426059b/pendulum-3.0.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4386bffeca23c4b69ad50a36211f75b35a4deb6210bdca112ac3043deb7e494a", size = 384928, upload-time = "2023-12-16T21:26:53.255Z" }, { url = "https://files.pythonhosted.org/packages/12/23/2816c02e5b3ce4006c186353a859ba2f7834e7ffc8ab61c95d71dfd10a91/pendulum-3.0.0-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:dfbcf1661d7146d7698da4b86e7f04814221081e9fe154183e34f4c5f5fa3bf8", size = 559525, upload-time = "2023-12-16T21:26:55.905Z" }, { url = "https://files.pythonhosted.org/packages/b2/73/0b740805f94e7fa0915d7ae00d51a3676ca4c10401aa43ca611778075b4d/pendulum-3.0.0-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:04a1094a5aa1daa34a6b57c865b25f691848c61583fb22722a4df5699f6bf74c", size = 558323, upload-time = "2023-12-16T21:26:58.743Z" }, { url = "https://files.pythonhosted.org/packages/d0/b0/73581fe1755213a5a33b9f91c72a4d0705bbe3e7f19413b0af4878c73d70/pendulum-3.0.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5b0ec85b9045bd49dd3a3493a5e7ddfd31c36a2a60da387c419fa04abcaecb23", size = 293471, upload-time = "2023-12-16T21:27:00.649Z" }, { url = "https://files.pythonhosted.org/packages/ac/1c/69adbf18071d9c5571bed60aa881d76380d5121a7adc8c765375def08506/pendulum-3.0.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:0a15b90129765b705eb2039062a6daf4d22c4e28d1a54fa260892e8c3ae6e157", size = 362376, upload-time = "2023-12-16T21:27:02.635Z" }, { url = "https://files.pythonhosted.org/packages/a7/18/2c0d556f1a6832fa4c5c1d466ec179087d250e654f6fa8c5723f6377c7d8/pendulum-3.0.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:bb8f6d7acd67a67d6fedd361ad2958ff0539445ef51cbe8cd288db4306503cd0", size = 353041, upload-time = "2023-12-16T21:27:05.295Z" }, { url = "https://files.pythonhosted.org/packages/02/a6/951ff1930b796b272c9a372f0307c9e7f6b3ef9267972f404ee16bf32fd2/pendulum-3.0.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fd69b15374bef7e4b4440612915315cc42e8575fcda2a3d7586a0d88192d0c88", size = 335877, upload-time = "2023-12-16T21:27:07.447Z" }, { url = "https://files.pythonhosted.org/packages/76/b3/2bb091f05d1e94bc20549c2318d65606f704fb881728cc2f6bf146037443/pendulum-3.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc00f8110db6898360c53c812872662e077eaf9c75515d53ecc65d886eec209a", size = 384858, upload-time = "2023-12-16T21:27:09.819Z" }, { url = "https://files.pythonhosted.org/packages/dc/51/b49eed0f7c23e7fb1a6affc482f6cc6fbf0bb76a2156c792a97646cd513e/pendulum-3.0.0-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:83a44e8b40655d0ba565a5c3d1365d27e3e6778ae2a05b69124db9e471255c4a", size = 559448, upload-time = "2023-12-16T21:27:12.177Z" }, { url = "https://files.pythonhosted.org/packages/80/24/65427759911ec8823e728a40fa86fa8e70f275d0eb036c14c631366f1213/pendulum-3.0.0-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:1a3604e9fbc06b788041b2a8b78f75c243021e0f512447806a6d37ee5214905d", size = 558185, upload-time = "2023-12-16T21:27:15.158Z" }, { url = "https://files.pythonhosted.org/packages/5a/8b/f3ac476c70a39818a56dd24144cc2bee276e7a5fe3d254ba5238769224c8/pendulum-3.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:92c307ae7accebd06cbae4729f0ba9fa724df5f7d91a0964b1b972a22baa482b", size = 293645, upload-time = "2023-12-16T21:27:17.677Z" }, ] [[package]] name = "pendulum" version = "3.1.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.9'", ] dependencies = [ { name = "python-dateutil", marker = "python_full_version >= '3.9'" }, { name = "tzdata", marker = "python_full_version >= '3.9'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/23/7c/009c12b86c7cc6c403aec80f8a4308598dfc5995e5c523a5491faaa3952e/pendulum-3.1.0.tar.gz", hash = "sha256:66f96303560f41d097bee7d2dc98ffca716fbb3a832c4b3062034c2d45865015", size = 85930, upload-time = "2025-04-19T14:30:01.675Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/b4/d8/398cd27903a6899d0ae47b896d88e0b15849fc334931a6732e7ce3be9a45/pendulum-3.1.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:aa545a59e6517cf43597455a6fb44daa4a6e08473d67a7ad34e4fa951efb9620", size = 338637, upload-time = "2025-04-19T14:00:56.429Z" }, { url = "https://files.pythonhosted.org/packages/aa/9d/a125554919c6db14e189393254c7781ee98ed5a121b6c05652d353b03c12/pendulum-3.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:299df2da6c490ede86bb8d58c65e33d7a2a42479d21475a54b467b03ccb88531", size = 326003, upload-time = "2025-04-19T14:00:58.192Z" }, { url = "https://files.pythonhosted.org/packages/53/9f/43a5a902f904e06252c259c2f6cf2dceafbb25aef158df08f79c0089dfd7/pendulum-3.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dbaa66e3ab179a2746eec67462f852a5d555bd709c25030aef38477468dd008e", size = 344335, upload-time = "2025-04-19T14:00:59.985Z" }, { url = "https://files.pythonhosted.org/packages/ca/24/00fcd6abd1f7623d2bbcca048b45f01aa8bb6b647e0477c3a8ea6094335c/pendulum-3.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c3907ab3744c32e339c358d88ec80cd35fa2d4b25c77a3c67e6b39e99b7090c5", size = 382169, upload-time = "2025-04-19T14:01:01.411Z" }, { url = "https://files.pythonhosted.org/packages/32/bc/20a87f24c26c6c4daf3c69311208b28130b4d19c006da16efc0e55715963/pendulum-3.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8244958c5bc4ed1c47ee84b098ddd95287a3fc59e569ca6e2b664c6396138ec4", size = 436675, upload-time = "2025-04-19T14:01:03.068Z" }, { url = "https://files.pythonhosted.org/packages/1d/eb/3b1818a796408a250b8e6cfaa5372b991c0cbec768e02e0f9a226755383d/pendulum-3.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca5722b3993b85ff7dfced48d86b318f863c359877b6badf1a3601e35199ef8f", size = 353728, upload-time = "2025-04-19T14:01:04.483Z" }, { url = "https://files.pythonhosted.org/packages/36/23/755ef61f863b2777925171a59509540205b561a9e07ee7de0b5be9226bea/pendulum-3.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:5b77a3dc010eea1a4916ef3771163d808bfc3e02b894c37df311287f18e5b764", size = 524465, upload-time = "2025-04-19T14:01:05.865Z" }, { url = "https://files.pythonhosted.org/packages/07/1f/a3e5f08890d13d93eee725778bfeaa233db5c55463e526857dffbc1a47e4/pendulum-3.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2d6e1eff4a15fdb8fb3867c5469e691c2465eef002a6a541c47b48a390ff4cf4", size = 525690, upload-time = "2025-04-19T14:01:07.707Z" }, { url = "https://files.pythonhosted.org/packages/43/c5/bf8ce472b81e8f5f074e8ba39899d288acce417c2c4a9ec7486d56970e28/pendulum-3.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:73de43ec85b46ac75db848c8e2f3f5d086e90b11cd9c7f029e14c8d748d920e2", size = 260356, upload-time = "2025-04-19T14:01:09.339Z" }, { url = "https://files.pythonhosted.org/packages/5e/6e/d28d3c22e6708b819a94c05bd05a3dfaed5c685379e8b6dc4b34b473b942/pendulum-3.1.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:61a03d14f8c64d13b2f7d5859e4b4053c4a7d3b02339f6c71f3e4606bfd67423", size = 338596, upload-time = "2025-04-19T14:01:11.306Z" }, { url = "https://files.pythonhosted.org/packages/e1/e6/43324d58021d463c2eeb6146b169d2c935f2f840f9e45ac2d500453d954c/pendulum-3.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e674ed2d158afa5c361e60f1f67872dc55b492a10cacdaa7fcd7b7da5f158f24", size = 325854, upload-time = "2025-04-19T14:01:13.156Z" }, { url = "https://files.pythonhosted.org/packages/b0/a7/d2ae79b960bfdea94dab67e2f118697b08bc9e98eb6bd8d32c4d99240da3/pendulum-3.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7c75377eb16e58bbe7e03ea89eeea49be6fc5de0934a4aef0e263f8b4fa71bc2", size = 344334, upload-time = "2025-04-19T14:01:15.151Z" }, { url = "https://files.pythonhosted.org/packages/96/94/941f071212e23c29aae7def891fb636930c648386e059ce09ea0dcd43933/pendulum-3.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:656b8b0ce070f0f2e5e2668247d3c783c55336534aa1f13bd0969535878955e1", size = 382259, upload-time = "2025-04-19T14:01:16.924Z" }, { url = "https://files.pythonhosted.org/packages/51/ad/a78a701656aec00d16fee636704445c23ca11617a0bfe7c3848d1caa5157/pendulum-3.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48962903e6c1afe1f13548cb6252666056086c107d59e3d64795c58c9298bc2e", size = 436361, upload-time = "2025-04-19T14:01:18.796Z" }, { url = "https://files.pythonhosted.org/packages/da/93/83f59ccbf4435c29dca8c63a6560fcbe4783079a468a5f91d9f886fd21f0/pendulum-3.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d364ec3f8e65010fefd4b0aaf7be5eb97e5df761b107a06f5e743b7c3f52c311", size = 353653, upload-time = "2025-04-19T14:01:20.159Z" }, { url = "https://files.pythonhosted.org/packages/6f/0f/42d6644ec6339b41066f594e52d286162aecd2e9735aaf994d7e00c9e09d/pendulum-3.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:dd52caffc2afb86612ec43bbeb226f204ea12ebff9f3d12f900a7d3097210fcc", size = 524567, upload-time = "2025-04-19T14:01:21.457Z" }, { url = "https://files.pythonhosted.org/packages/de/45/d84d909202755ab9d3379e5481fdf70f53344ebefbd68d6f5803ddde98a6/pendulum-3.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d439fccaa35c91f686bd59d30604dab01e8b5c1d0dd66e81648c432fd3f8a539", size = 525571, upload-time = "2025-04-19T14:01:23.329Z" }, { url = "https://files.pythonhosted.org/packages/0d/e0/4de160773ce3c2f7843c310db19dd919a0cd02cc1c0384866f63b18a6251/pendulum-3.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:43288773a86d9c5c0ddb645f88f615ff6bd12fd1410b34323662beccb18f3b49", size = 260259, upload-time = "2025-04-19T14:01:24.689Z" }, { url = "https://files.pythonhosted.org/packages/c1/7f/ffa278f78112c6c6e5130a702042f52aab5c649ae2edf814df07810bbba5/pendulum-3.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:569ea5072ae0f11d625e03b36d865f8037b76e838a3b621f6967314193896a11", size = 253899, upload-time = "2025-04-19T14:01:26.442Z" }, { url = "https://files.pythonhosted.org/packages/7a/d7/b1bfe15a742f2c2713acb1fdc7dc3594ff46ef9418ac6a96fcb12a6ba60b/pendulum-3.1.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:4dfd53e7583ccae138be86d6c0a0b324c7547df2afcec1876943c4d481cf9608", size = 336209, upload-time = "2025-04-19T14:01:27.815Z" }, { url = "https://files.pythonhosted.org/packages/eb/87/0392da0c603c828b926d9f7097fbdddaafc01388cb8a00888635d04758c3/pendulum-3.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6a6e06a28f3a7d696546347805536f6f38be458cb79de4f80754430696bea9e6", size = 323130, upload-time = "2025-04-19T14:01:29.336Z" }, { url = "https://files.pythonhosted.org/packages/c0/61/95f1eec25796be6dddf71440ee16ec1fd0c573fc61a73bd1ef6daacd529a/pendulum-3.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7e68d6a51880708084afd8958af42dc8c5e819a70a6c6ae903b1c4bfc61e0f25", size = 341509, upload-time = "2025-04-19T14:01:31.1Z" }, { url = "https://files.pythonhosted.org/packages/b5/7b/eb0f5e6aa87d5e1b467a1611009dbdc92f0f72425ebf07669bfadd8885a6/pendulum-3.1.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9e3f1e5da39a7ea7119efda1dd96b529748c1566f8a983412d0908455d606942", size = 378674, upload-time = "2025-04-19T14:01:32.974Z" }, { url = "https://files.pythonhosted.org/packages/29/68/5a4c1b5de3e54e16cab21d2ec88f9cd3f18599e96cc90a441c0b0ab6b03f/pendulum-3.1.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9af1e5eeddb4ebbe1b1c9afb9fd8077d73416ade42dd61264b3f3b87742e0bb", size = 436133, upload-time = "2025-04-19T14:01:34.349Z" }, { url = "https://files.pythonhosted.org/packages/87/5d/f7a1d693e5c0f789185117d5c1d5bee104f5b0d9fbf061d715fb61c840a8/pendulum-3.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20f74aa8029a42e327bfc150472e0e4d2358fa5d795f70460160ba81b94b6945", size = 351232, upload-time = "2025-04-19T14:01:35.669Z" }, { url = "https://files.pythonhosted.org/packages/30/77/c97617eb31f1d0554edb073201a294019b9e0a9bd2f73c68e6d8d048cd6b/pendulum-3.1.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:cf6229e5ee70c2660148523f46c472e677654d0097bec010d6730f08312a4931", size = 521562, upload-time = "2025-04-19T14:01:37.05Z" }, { url = "https://files.pythonhosted.org/packages/76/22/0d0ef3393303877e757b848ecef8a9a8c7627e17e7590af82d14633b2cd1/pendulum-3.1.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:350cabb23bf1aec7c7694b915d3030bff53a2ad4aeabc8c8c0d807c8194113d6", size = 523221, upload-time = "2025-04-19T14:01:38.444Z" }, { url = "https://files.pythonhosted.org/packages/99/f3/aefb579aa3cebd6f2866b205fc7a60d33e9a696e9e629024752107dc3cf5/pendulum-3.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:42959341e843077c41d47420f28c3631de054abd64da83f9b956519b5c7a06a7", size = 260502, upload-time = "2025-04-19T14:01:39.814Z" }, { url = "https://files.pythonhosted.org/packages/02/74/4332b5d6e34c63d4df8e8eab2249e74c05513b1477757463f7fdca99e9be/pendulum-3.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:006758e2125da2e624493324dfd5d7d1b02b0c44bc39358e18bf0f66d0767f5f", size = 253089, upload-time = "2025-04-19T14:01:41.171Z" }, { url = "https://files.pythonhosted.org/packages/8e/1f/af928ba4aa403dac9569f787adcf024005e7654433d71f7a84e608716837/pendulum-3.1.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:28658b0baf4b30eb31d096a375983cfed033e60c0a7bbe94fa23f06cd779b50b", size = 336209, upload-time = "2025-04-19T14:01:42.775Z" }, { url = "https://files.pythonhosted.org/packages/b6/16/b010643007ba964c397da7fa622924423883c1bbff1a53f9d1022cd7f024/pendulum-3.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b114dcb99ce511cb8f5495c7b6f0056b2c3dba444ef1ea6e48030d7371bd531a", size = 323132, upload-time = "2025-04-19T14:01:44.577Z" }, { url = "https://files.pythonhosted.org/packages/64/19/c3c47aeecb5d9bceb0e89faafd800d39809b696c5b7bba8ec8370ad5052c/pendulum-3.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2404a6a54c80252ea393291f0b7f35525a61abae3d795407f34e118a8f133a18", size = 341509, upload-time = "2025-04-19T14:01:46.084Z" }, { url = "https://files.pythonhosted.org/packages/38/cf/c06921ff6b860ff7e62e70b8e5d4dc70e36f5abb66d168bd64d51760bc4e/pendulum-3.1.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d06999790d9ee9962a1627e469f98568bf7ad1085553fa3c30ed08b3944a14d7", size = 378674, upload-time = "2025-04-19T14:01:47.727Z" }, { url = "https://files.pythonhosted.org/packages/62/0b/a43953b9eba11e82612b033ac5133f716f1b76b6108a65da6f408b3cc016/pendulum-3.1.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:94751c52f6b7c306734d1044c2c6067a474237e1e5afa2f665d1fbcbbbcf24b3", size = 436133, upload-time = "2025-04-19T14:01:49.126Z" }, { url = "https://files.pythonhosted.org/packages/eb/a0/ec3d70b3b96e23ae1d039f132af35e17704c22a8250d1887aaefea4d78a6/pendulum-3.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5553ac27be05e997ec26d7f004cf72788f4ce11fe60bb80dda604a64055b29d0", size = 351232, upload-time = "2025-04-19T14:01:50.575Z" }, { url = "https://files.pythonhosted.org/packages/f4/97/aba23f1716b82f6951ba2b1c9178a2d107d1e66c102762a9bf19988547ea/pendulum-3.1.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:f8dee234ca6142bf0514368d01a72945a44685aaa2fc4c14c98d09da9437b620", size = 521563, upload-time = "2025-04-19T14:01:51.9Z" }, { url = "https://files.pythonhosted.org/packages/01/33/2c0d5216cc53d16db0c4b3d510f141ee0a540937f8675948541190fbd48b/pendulum-3.1.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:7378084fe54faab4ee481897a00b710876f2e901ded6221671e827a253e643f2", size = 523221, upload-time = "2025-04-19T14:01:53.275Z" }, { url = "https://files.pythonhosted.org/packages/51/89/8de955c339c31aeae77fd86d3225509b998c81875e9dba28cb88b8cbf4b3/pendulum-3.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:8539db7ae2c8da430ac2515079e288948c8ebf7eb1edd3e8281b5cdf433040d6", size = 260501, upload-time = "2025-04-19T14:01:54.749Z" }, { url = "https://files.pythonhosted.org/packages/15/c3/226a3837363e94f8722461848feec18bfdd7d5172564d53aa3c3397ff01e/pendulum-3.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:1ce26a608e1f7387cd393fba2a129507c4900958d4f47b90757ec17656856571", size = 253087, upload-time = "2025-04-19T14:01:55.998Z" }, { url = "https://files.pythonhosted.org/packages/c9/eb/e128af9e1a216c17b932f8c7f1f927f97cd8fd71d6e60148e1c69ad2bcf4/pendulum-3.1.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:2504df1a7ff8e0827781a601ff399bfcad23e7b7943f87ef33db02c11131f5e8", size = 339467, upload-time = "2025-04-19T14:01:57.346Z" }, { url = "https://files.pythonhosted.org/packages/2f/c3/a7f515c6dbe89f2d92216ccd9a2e31dd657767d7f64177da1579092a41e3/pendulum-3.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4041a7156695499b6676ed092f27e17760db2341bf350f6c5ea9137dd2cfd3f6", size = 326898, upload-time = "2025-04-19T14:01:58.789Z" }, { url = "https://files.pythonhosted.org/packages/15/da/80774350340e9d06789460b6e8def2d497cffe09334a8911be8d226caec5/pendulum-3.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87b277e9177651d6af8500b95f0af1e3c1769064f2353c06f638d3c1e065063e", size = 344866, upload-time = "2025-04-19T14:02:00.688Z" }, { url = "https://files.pythonhosted.org/packages/55/cf/771d1fee8d14abefbccbed99622c6f26e33b839b8964a18188b4f9159bf1/pendulum-3.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:784cf82b676118816fb81ea6bcbdf8f3b0c49aa74fcb895647ef7f8046093471", size = 382902, upload-time = "2025-04-19T14:02:02.077Z" }, { url = "https://files.pythonhosted.org/packages/bd/95/0660ae5dbe9212c99fbccb27ca64361018600aa954fab95641653a39ce36/pendulum-3.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9e44277a391fa5ad2e9ce02b1b24fd9489cb2a371ae2459eddb238301d31204d", size = 437782, upload-time = "2025-04-19T14:02:03.984Z" }, { url = "https://files.pythonhosted.org/packages/04/1f/007dff40bb0325ae91eba3d4d6ce911945d808f87d3cebaa4556ca07f35d/pendulum-3.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a7d0bca8cca92d60734b64fa4fa58b17b8ec1f55112bf77d00ee65248d19177", size = 354462, upload-time = "2025-04-19T14:02:05.831Z" }, { url = "https://files.pythonhosted.org/packages/e6/cc/8d2ed88beab1622623e321bd1f754eee174bb97e6ffcd34ceb9cce87a4ea/pendulum-3.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bfac5e02faee02c180444e722c298690688ec1c3dfa1aab65fb4e0e3825d84ed", size = 525009, upload-time = "2025-04-19T14:02:07.231Z" }, { url = "https://files.pythonhosted.org/packages/44/c0/a503df53796b0dc1dae7d50573d936f86f8f482cf4acd9adbbd2a30ef817/pendulum-3.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:e0da70941b062220e734c2c510ad30daa60aca1a37e893f1baa0da065ffa4c72", size = 526351, upload-time = "2025-04-19T14:02:08.619Z" }, { url = "https://files.pythonhosted.org/packages/c6/bc/1fbc57b2e482a0ee3b5a0759c4b3b5127f0401cdce4afef111a3b6179d8d/pendulum-3.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:300a237fb81028edb9604d4d1bb205b80515fd22ab9c1a4c55014d07869122f8", size = 260813, upload-time = "2025-04-19T14:02:10.677Z" }, { url = "https://files.pythonhosted.org/packages/66/10/3258c084653606d2be2c7168998eda4a57cf1559cecb43cf1100000fda5f/pendulum-3.1.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:d2cac744940299d8da41a3ed941aa1e02b5abbc9ae2c525f3aa2ae30c28a86b5", size = 339442, upload-time = "2025-04-19T14:02:12.512Z" }, { url = "https://files.pythonhosted.org/packages/98/d5/98a1a10cd1cfb3390fbf070864e9a10de8e70a9d4509832132f4d900d655/pendulum-3.1.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:ffb39c3f3906a9c9a108fa98e5556f18b52d2c6451984bbfe2f14436ec4fc9d4", size = 326609, upload-time = "2025-04-19T14:02:13.838Z" }, { url = "https://files.pythonhosted.org/packages/0a/2e/448abdebc11b9c54e190d273cb084162643199fc184cb1bb6bff7900e67f/pendulum-3.1.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebe18b1c2eb364064cc4a68a65900f1465cac47d0891dab82341766bcc05b40c", size = 344777, upload-time = "2025-04-19T14:02:15.512Z" }, { url = "https://files.pythonhosted.org/packages/ed/91/ee857bbd51168bf08b89c3a4705c920725eee0f830ccc513b8370f6ce71d/pendulum-3.1.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9e9b28a35cec9fcd90f224b4878456129a057dbd694fc8266a9393834804995", size = 354404, upload-time = "2025-04-19T14:02:16.91Z" }, { url = "https://files.pythonhosted.org/packages/bc/d4/e63a57df65e2b2d10f3aa917a4069be9abf5ac7d56d11336e0510742d8a6/pendulum-3.1.0-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:a3be19b73a9c6a866724419295482f817727e635ccc82f07ae6f818943a1ee96", size = 524948, upload-time = "2025-04-19T14:02:18.808Z" }, { url = "https://files.pythonhosted.org/packages/93/87/04e74600c5a5674e5f341b8888b530a9de9b84b31889f80fac3bee3e9e87/pendulum-3.1.0-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:24a53b523819bda4c70245687a589b5ea88711f7caac4be5f276d843fe63076b", size = 526340, upload-time = "2025-04-19T14:02:20.242Z" }, { url = "https://files.pythonhosted.org/packages/48/27/d3577a5f6f7d1fbf1138d87ce21ebab363c78642513b991d1c424d658d09/pendulum-3.1.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:bd701789414fbd0be3c75f46803f31e91140c23821e4bcb0fa2bddcdd051c425", size = 261089, upload-time = "2025-04-19T14:02:21.631Z" }, { url = "https://files.pythonhosted.org/packages/53/8f/6620b0df6acdd8c020ec4f5907e3deb8c6d46970568299b66eed9b5f53b4/pendulum-3.1.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:0803639fc98e03f74d0b83955a2800bcee1c99b0700638aae9ab7ceb1a7dcca3", size = 340056, upload-time = "2025-04-19T14:02:23.041Z" }, { url = "https://files.pythonhosted.org/packages/dd/90/957491643cff9d97764e443bd0ef7c5c549e733e306159d6ca8ab4034fb5/pendulum-3.1.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:4cceff50503ef9cb021e53a238f867c9843b4dd55859582d682f3c9e52460699", size = 327095, upload-time = "2025-04-19T14:02:24.866Z" }, { url = "https://files.pythonhosted.org/packages/fe/f2/550855e0285671278f763963b2470f437d340759aaef927fedb204e58fb0/pendulum-3.1.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c2cf8adcf3030eef78c3cd82afd9948cd1a4ae1a9450e9ac128b9e744c42825f", size = 345131, upload-time = "2025-04-19T14:02:26.332Z" }, { url = "https://files.pythonhosted.org/packages/b4/8f/938b83fe3e1450f4b04d1f96e8b2c288e07ad6b942260fef24cfd98cc3d0/pendulum-3.1.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5bce0f71c10e983e1c39e1eb37b9a5f5c2aa0c15a36edaaa0a844fb1fbc7bbb", size = 354886, upload-time = "2025-04-19T14:02:28.205Z" }, { url = "https://files.pythonhosted.org/packages/d9/aa/0e3c231a7e35b362226204d7276a47c0e225aa59b30c7c9cd2a8e2660967/pendulum-3.1.0-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:c1354be2df38f031ac6a985949b6541be7d39dd7e44c8804f4bc9a39dea9f3bb", size = 525344, upload-time = "2025-04-19T14:02:30.116Z" }, { url = "https://files.pythonhosted.org/packages/0b/c7/d3654a790129684d0e8dc04707cb6d75633d7b102a962c6dc0f862c64c25/pendulum-3.1.0-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e4cbd933a40c915ed5c41b083115cca15c7afa8179363b2a61db167c64fa0670", size = 526685, upload-time = "2025-04-19T14:02:31.523Z" }, { url = "https://files.pythonhosted.org/packages/50/d9/4a166256386b7973e36ff44135e8d009f4afb25d6c72df5380ccfd6fbb89/pendulum-3.1.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:3363a470b5d67dbf8d9fd1bf77dcdbf720788bc3be4a10bdcd28ae5d7dbd26c4", size = 261170, upload-time = "2025-04-19T14:02:33.099Z" }, { url = "https://files.pythonhosted.org/packages/6e/23/e98758924d1b3aac11a626268eabf7f3cf177e7837c28d47bf84c64532d0/pendulum-3.1.0-py3-none-any.whl", hash = "sha256:f9178c2a8e291758ade1e8dd6371b1d26d08371b4c7730a6e9a3ef8b16ebae0f", size = 111799, upload-time = "2025-04-19T14:02:34.739Z" }, ] [[package]] name = "phonenumbers" version = "9.0.5" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/49/3f/3c0ae68353f4cd58ef2d683c2d3f343e1804118c27216495f80c7e4eb6b3/phonenumbers-9.0.5.tar.gz", hash = "sha256:70fde168a92dd9c73f57872359515181d6cde6bb8e7ec5660e94c4ca45692c50", size = 2296916, upload-time = "2025-05-08T06:00:01.782Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/43/b2/1fba8f2aa0a54450a53e88f59e39d58a611438919e3a7623641558bc77f9/phonenumbers-9.0.5-py2.py3-none-any.whl", hash = "sha256:7acef19817868a6f9cbc0d628dc5ad447b3768137e3d53c70dd6827a1ac040ba", size = 2582730, upload-time = "2025-05-08T05:59:57.903Z" }, ] [[package]] name = "pluggy" version = "1.5.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955, upload-time = "2024-04-20T21:34:42.531Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556, upload-time = "2024-04-20T21:34:40.434Z" }, ] [[package]] name = "pycountry" version = "24.6.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "importlib-resources", marker = "python_full_version < '3.9'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/76/57/c389fa68c50590881a75b7883eeb3dc15e9e73a0fdc001cdd45c13290c92/pycountry-24.6.1.tar.gz", hash = "sha256:b61b3faccea67f87d10c1f2b0fc0be714409e8fcdcc1315613174f6466c10221", size = 6043910, upload-time = "2024-06-01T04:12:15.05Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/b1/ec/1fb891d8a2660716aadb2143235481d15ed1cbfe3ad669194690b0604492/pycountry-24.6.1-py3-none-any.whl", hash = "sha256:f1a4fb391cd7214f8eefd39556d740adcc233c778a27f8942c8dca351d6ce06f", size = 6335189, upload-time = "2024-06-01T04:11:49.711Z" }, ] [[package]] name = "pydantic" version = "2.10.6" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version < '3.9'", ] dependencies = [ { name = "annotated-types", marker = "python_full_version < '3.9'" }, { name = "pydantic-core", version = "2.27.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9'" }, { name = "typing-extensions", marker = "python_full_version < '3.9'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/b7/ae/d5220c5c52b158b1de7ca89fc5edb72f304a70a4c540c84c8844bf4008de/pydantic-2.10.6.tar.gz", hash = "sha256:ca5daa827cce33de7a42be142548b0096bf05a7e7b365aebfa5f8eeec7128236", size = 761681, upload-time = "2025-01-24T01:42:12.693Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/f4/3c/8cc1cc84deffa6e25d2d0c688ebb80635dfdbf1dbea3e30c541c8cf4d860/pydantic-2.10.6-py3-none-any.whl", hash = "sha256:427d664bf0b8a2b34ff5dd0f5a18df00591adcee7198fbd71981054cef37b584", size = 431696, upload-time = "2025-01-24T01:42:10.371Z" }, ] [[package]] name = "pydantic" version = "2.11.4" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.9'", ] dependencies = [ { name = "annotated-types", marker = "python_full_version >= '3.9'" }, { name = "pydantic-core", version = "2.33.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9'" }, { name = "typing-extensions", marker = "python_full_version >= '3.9'" }, { name = "typing-inspection", marker = "python_full_version >= '3.9'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/77/ab/5250d56ad03884ab5efd07f734203943c8a8ab40d551e208af81d0257bf2/pydantic-2.11.4.tar.gz", hash = "sha256:32738d19d63a226a52eed76645a98ee07c1f410ee41d93b4afbfa85ed8111c2d", size = 786540, upload-time = "2025-04-29T20:38:55.02Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/e7/12/46b65f3534d099349e38ef6ec98b1a5a81f42536d17e0ba382c28c67ba67/pydantic-2.11.4-py3-none-any.whl", hash = "sha256:d9615eaa9ac5a063471da949c8fc16376a84afb5024688b3ff885693506764eb", size = 443900, upload-time = "2025-04-29T20:38:52.724Z" }, ] [[package]] name = "pydantic-core" version = "2.27.2" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version < '3.9'", ] dependencies = [ { name = "typing-extensions", marker = "python_full_version < '3.9'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/fc/01/f3e5ac5e7c25833db5eb555f7b7ab24cd6f8c322d3a3ad2d67a952dc0abc/pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39", size = 413443, upload-time = "2024-12-18T11:31:54.917Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/3a/bc/fed5f74b5d802cf9a03e83f60f18864e90e3aed7223adaca5ffb7a8d8d64/pydantic_core-2.27.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2d367ca20b2f14095a8f4fa1210f5a7b78b8a20009ecced6b12818f455b1e9fa", size = 1895938, upload-time = "2024-12-18T11:27:14.406Z" }, { url = "https://files.pythonhosted.org/packages/71/2a/185aff24ce844e39abb8dd680f4e959f0006944f4a8a0ea372d9f9ae2e53/pydantic_core-2.27.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:491a2b73db93fab69731eaee494f320faa4e093dbed776be1a829c2eb222c34c", size = 1815684, upload-time = "2024-12-18T11:27:16.489Z" }, { url = "https://files.pythonhosted.org/packages/c3/43/fafabd3d94d159d4f1ed62e383e264f146a17dd4d48453319fd782e7979e/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7969e133a6f183be60e9f6f56bfae753585680f3b7307a8e555a948d443cc05a", size = 1829169, upload-time = "2024-12-18T11:27:22.16Z" }, { url = "https://files.pythonhosted.org/packages/a2/d1/f2dfe1a2a637ce6800b799aa086d079998959f6f1215eb4497966efd2274/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3de9961f2a346257caf0aa508a4da705467f53778e9ef6fe744c038119737ef5", size = 1867227, upload-time = "2024-12-18T11:27:25.097Z" }, { url = "https://files.pythonhosted.org/packages/7d/39/e06fcbcc1c785daa3160ccf6c1c38fea31f5754b756e34b65f74e99780b5/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2bb4d3e5873c37bb3dd58714d4cd0b0e6238cebc4177ac8fe878f8b3aa8e74c", size = 2037695, upload-time = "2024-12-18T11:27:28.656Z" }, { url = "https://files.pythonhosted.org/packages/7a/67/61291ee98e07f0650eb756d44998214231f50751ba7e13f4f325d95249ab/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:280d219beebb0752699480fe8f1dc61ab6615c2046d76b7ab7ee38858de0a4e7", size = 2741662, upload-time = "2024-12-18T11:27:30.798Z" }, { url = "https://files.pythonhosted.org/packages/32/90/3b15e31b88ca39e9e626630b4c4a1f5a0dfd09076366f4219429e6786076/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47956ae78b6422cbd46f772f1746799cbb862de838fd8d1fbd34a82e05b0983a", size = 1993370, upload-time = "2024-12-18T11:27:33.692Z" }, { url = "https://files.pythonhosted.org/packages/ff/83/c06d333ee3a67e2e13e07794995c1535565132940715931c1c43bfc85b11/pydantic_core-2.27.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:14d4a5c49d2f009d62a2a7140d3064f686d17a5d1a268bc641954ba181880236", size = 1996813, upload-time = "2024-12-18T11:27:37.111Z" }, { url = "https://files.pythonhosted.org/packages/7c/f7/89be1c8deb6e22618a74f0ca0d933fdcb8baa254753b26b25ad3acff8f74/pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:337b443af21d488716f8d0b6164de833e788aa6bd7e3a39c005febc1284f4962", size = 2005287, upload-time = "2024-12-18T11:27:40.566Z" }, { url = "https://files.pythonhosted.org/packages/b7/7d/8eb3e23206c00ef7feee17b83a4ffa0a623eb1a9d382e56e4aa46fd15ff2/pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:03d0f86ea3184a12f41a2d23f7ccb79cdb5a18e06993f8a45baa8dfec746f0e9", size = 2128414, upload-time = "2024-12-18T11:27:43.757Z" }, { url = "https://files.pythonhosted.org/packages/4e/99/fe80f3ff8dd71a3ea15763878d464476e6cb0a2db95ff1c5c554133b6b83/pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7041c36f5680c6e0f08d922aed302e98b3745d97fe1589db0a3eebf6624523af", size = 2155301, upload-time = "2024-12-18T11:27:47.36Z" }, { url = "https://files.pythonhosted.org/packages/2b/a3/e50460b9a5789ca1451b70d4f52546fa9e2b420ba3bfa6100105c0559238/pydantic_core-2.27.2-cp310-cp310-win32.whl", hash = "sha256:50a68f3e3819077be2c98110c1f9dcb3817e93f267ba80a2c05bb4f8799e2ff4", size = 1816685, upload-time = "2024-12-18T11:27:50.508Z" }, { url = "https://files.pythonhosted.org/packages/57/4c/a8838731cb0f2c2a39d3535376466de6049034d7b239c0202a64aaa05533/pydantic_core-2.27.2-cp310-cp310-win_amd64.whl", hash = "sha256:e0fd26b16394ead34a424eecf8a31a1f5137094cabe84a1bcb10fa6ba39d3d31", size = 1982876, upload-time = "2024-12-18T11:27:53.54Z" }, { url = "https://files.pythonhosted.org/packages/c2/89/f3450af9d09d44eea1f2c369f49e8f181d742f28220f88cc4dfaae91ea6e/pydantic_core-2.27.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8e10c99ef58cfdf2a66fc15d66b16c4a04f62bca39db589ae8cba08bc55331bc", size = 1893421, upload-time = "2024-12-18T11:27:55.409Z" }, { url = "https://files.pythonhosted.org/packages/9e/e3/71fe85af2021f3f386da42d291412e5baf6ce7716bd7101ea49c810eda90/pydantic_core-2.27.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:26f32e0adf166a84d0cb63be85c562ca8a6fa8de28e5f0d92250c6b7e9e2aff7", size = 1814998, upload-time = "2024-12-18T11:27:57.252Z" }, { url = "https://files.pythonhosted.org/packages/a6/3c/724039e0d848fd69dbf5806894e26479577316c6f0f112bacaf67aa889ac/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c19d1ea0673cd13cc2f872f6c9ab42acc4e4f492a7ca9d3795ce2b112dd7e15", size = 1826167, upload-time = "2024-12-18T11:27:59.146Z" }, { url = "https://files.pythonhosted.org/packages/2b/5b/1b29e8c1fb5f3199a9a57c1452004ff39f494bbe9bdbe9a81e18172e40d3/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e68c4446fe0810e959cdff46ab0a41ce2f2c86d227d96dc3847af0ba7def306", size = 1865071, upload-time = "2024-12-18T11:28:02.625Z" }, { url = "https://files.pythonhosted.org/packages/89/6c/3985203863d76bb7d7266e36970d7e3b6385148c18a68cc8915fd8c84d57/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9640b0059ff4f14d1f37321b94061c6db164fbe49b334b31643e0528d100d99", size = 2036244, upload-time = "2024-12-18T11:28:04.442Z" }, { url = "https://files.pythonhosted.org/packages/0e/41/f15316858a246b5d723f7d7f599f79e37493b2e84bfc789e58d88c209f8a/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40d02e7d45c9f8af700f3452f329ead92da4c5f4317ca9b896de7ce7199ea459", size = 2737470, upload-time = "2024-12-18T11:28:07.679Z" }, { url = "https://files.pythonhosted.org/packages/a8/7c/b860618c25678bbd6d1d99dbdfdf0510ccb50790099b963ff78a124b754f/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c1fd185014191700554795c99b347d64f2bb637966c4cfc16998a0ca700d048", size = 1992291, upload-time = "2024-12-18T11:28:10.297Z" }, { url = "https://files.pythonhosted.org/packages/bf/73/42c3742a391eccbeab39f15213ecda3104ae8682ba3c0c28069fbcb8c10d/pydantic_core-2.27.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d81d2068e1c1228a565af076598f9e7451712700b673de8f502f0334f281387d", size = 1994613, upload-time = "2024-12-18T11:28:13.362Z" }, { url = "https://files.pythonhosted.org/packages/94/7a/941e89096d1175d56f59340f3a8ebaf20762fef222c298ea96d36a6328c5/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a4207639fb02ec2dbb76227d7c751a20b1a6b4bc52850568e52260cae64ca3b", size = 2002355, upload-time = "2024-12-18T11:28:16.587Z" }, { url = "https://files.pythonhosted.org/packages/6e/95/2359937a73d49e336a5a19848713555605d4d8d6940c3ec6c6c0ca4dcf25/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:3de3ce3c9ddc8bbd88f6e0e304dea0e66d843ec9de1b0042b0911c1663ffd474", size = 2126661, upload-time = "2024-12-18T11:28:18.407Z" }, { url = "https://files.pythonhosted.org/packages/2b/4c/ca02b7bdb6012a1adef21a50625b14f43ed4d11f1fc237f9d7490aa5078c/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:30c5f68ded0c36466acede341551106821043e9afaad516adfb6e8fa80a4e6a6", size = 2153261, upload-time = "2024-12-18T11:28:21.471Z" }, { url = "https://files.pythonhosted.org/packages/72/9d/a241db83f973049a1092a079272ffe2e3e82e98561ef6214ab53fe53b1c7/pydantic_core-2.27.2-cp311-cp311-win32.whl", hash = "sha256:c70c26d2c99f78b125a3459f8afe1aed4d9687c24fd677c6a4436bc042e50d6c", size = 1812361, upload-time = "2024-12-18T11:28:23.53Z" }, { url = "https://files.pythonhosted.org/packages/e8/ef/013f07248041b74abd48a385e2110aa3a9bbfef0fbd97d4e6d07d2f5b89a/pydantic_core-2.27.2-cp311-cp311-win_amd64.whl", hash = "sha256:08e125dbdc505fa69ca7d9c499639ab6407cfa909214d500897d02afb816e7cc", size = 1982484, upload-time = "2024-12-18T11:28:25.391Z" }, { url = "https://files.pythonhosted.org/packages/10/1c/16b3a3e3398fd29dca77cea0a1d998d6bde3902fa2706985191e2313cc76/pydantic_core-2.27.2-cp311-cp311-win_arm64.whl", hash = "sha256:26f0d68d4b235a2bae0c3fc585c585b4ecc51382db0e3ba402a22cbc440915e4", size = 1867102, upload-time = "2024-12-18T11:28:28.593Z" }, { url = "https://files.pythonhosted.org/packages/d6/74/51c8a5482ca447871c93e142d9d4a92ead74de6c8dc5e66733e22c9bba89/pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0", size = 1893127, upload-time = "2024-12-18T11:28:30.346Z" }, { url = "https://files.pythonhosted.org/packages/d3/f3/c97e80721735868313c58b89d2de85fa80fe8dfeeed84dc51598b92a135e/pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef", size = 1811340, upload-time = "2024-12-18T11:28:32.521Z" }, { url = "https://files.pythonhosted.org/packages/9e/91/840ec1375e686dbae1bd80a9e46c26a1e0083e1186abc610efa3d9a36180/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7", size = 1822900, upload-time = "2024-12-18T11:28:34.507Z" }, { url = "https://files.pythonhosted.org/packages/f6/31/4240bc96025035500c18adc149aa6ffdf1a0062a4b525c932065ceb4d868/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934", size = 1869177, upload-time = "2024-12-18T11:28:36.488Z" }, { url = "https://files.pythonhosted.org/packages/fa/20/02fbaadb7808be578317015c462655c317a77a7c8f0ef274bc016a784c54/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6", size = 2038046, upload-time = "2024-12-18T11:28:39.409Z" }, { url = "https://files.pythonhosted.org/packages/06/86/7f306b904e6c9eccf0668248b3f272090e49c275bc488a7b88b0823444a4/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c", size = 2685386, upload-time = "2024-12-18T11:28:41.221Z" }, { url = "https://files.pythonhosted.org/packages/8d/f0/49129b27c43396581a635d8710dae54a791b17dfc50c70164866bbf865e3/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2", size = 1997060, upload-time = "2024-12-18T11:28:44.709Z" }, { url = "https://files.pythonhosted.org/packages/0d/0f/943b4af7cd416c477fd40b187036c4f89b416a33d3cc0ab7b82708a667aa/pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4", size = 2004870, upload-time = "2024-12-18T11:28:46.839Z" }, { url = "https://files.pythonhosted.org/packages/35/40/aea70b5b1a63911c53a4c8117c0a828d6790483f858041f47bab0b779f44/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3", size = 1999822, upload-time = "2024-12-18T11:28:48.896Z" }, { url = "https://files.pythonhosted.org/packages/f2/b3/807b94fd337d58effc5498fd1a7a4d9d59af4133e83e32ae39a96fddec9d/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4", size = 2130364, upload-time = "2024-12-18T11:28:50.755Z" }, { url = "https://files.pythonhosted.org/packages/fc/df/791c827cd4ee6efd59248dca9369fb35e80a9484462c33c6649a8d02b565/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57", size = 2158303, upload-time = "2024-12-18T11:28:54.122Z" }, { url = "https://files.pythonhosted.org/packages/9b/67/4e197c300976af185b7cef4c02203e175fb127e414125916bf1128b639a9/pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc", size = 1834064, upload-time = "2024-12-18T11:28:56.074Z" }, { url = "https://files.pythonhosted.org/packages/1f/ea/cd7209a889163b8dcca139fe32b9687dd05249161a3edda62860430457a5/pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9", size = 1989046, upload-time = "2024-12-18T11:28:58.107Z" }, { url = "https://files.pythonhosted.org/packages/bc/49/c54baab2f4658c26ac633d798dab66b4c3a9bbf47cff5284e9c182f4137a/pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b", size = 1885092, upload-time = "2024-12-18T11:29:01.335Z" }, { url = "https://files.pythonhosted.org/packages/41/b1/9bc383f48f8002f99104e3acff6cba1231b29ef76cfa45d1506a5cad1f84/pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b", size = 1892709, upload-time = "2024-12-18T11:29:03.193Z" }, { url = "https://files.pythonhosted.org/packages/10/6c/e62b8657b834f3eb2961b49ec8e301eb99946245e70bf42c8817350cbefc/pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154", size = 1811273, upload-time = "2024-12-18T11:29:05.306Z" }, { url = "https://files.pythonhosted.org/packages/ba/15/52cfe49c8c986e081b863b102d6b859d9defc63446b642ccbbb3742bf371/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9", size = 1823027, upload-time = "2024-12-18T11:29:07.294Z" }, { url = "https://files.pythonhosted.org/packages/b1/1c/b6f402cfc18ec0024120602bdbcebc7bdd5b856528c013bd4d13865ca473/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9", size = 1868888, upload-time = "2024-12-18T11:29:09.249Z" }, { url = "https://files.pythonhosted.org/packages/bd/7b/8cb75b66ac37bc2975a3b7de99f3c6f355fcc4d89820b61dffa8f1e81677/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1", size = 2037738, upload-time = "2024-12-18T11:29:11.23Z" }, { url = "https://files.pythonhosted.org/packages/c8/f1/786d8fe78970a06f61df22cba58e365ce304bf9b9f46cc71c8c424e0c334/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a", size = 2685138, upload-time = "2024-12-18T11:29:16.396Z" }, { url = "https://files.pythonhosted.org/packages/a6/74/d12b2cd841d8724dc8ffb13fc5cef86566a53ed358103150209ecd5d1999/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e", size = 1997025, upload-time = "2024-12-18T11:29:20.25Z" }, { url = "https://files.pythonhosted.org/packages/a0/6e/940bcd631bc4d9a06c9539b51f070b66e8f370ed0933f392db6ff350d873/pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4", size = 2004633, upload-time = "2024-12-18T11:29:23.877Z" }, { url = "https://files.pythonhosted.org/packages/50/cc/a46b34f1708d82498c227d5d80ce615b2dd502ddcfd8376fc14a36655af1/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27", size = 1999404, upload-time = "2024-12-18T11:29:25.872Z" }, { url = "https://files.pythonhosted.org/packages/ca/2d/c365cfa930ed23bc58c41463bae347d1005537dc8db79e998af8ba28d35e/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee", size = 2130130, upload-time = "2024-12-18T11:29:29.252Z" }, { url = "https://files.pythonhosted.org/packages/f4/d7/eb64d015c350b7cdb371145b54d96c919d4db516817f31cd1c650cae3b21/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1", size = 2157946, upload-time = "2024-12-18T11:29:31.338Z" }, { url = "https://files.pythonhosted.org/packages/a4/99/bddde3ddde76c03b65dfd5a66ab436c4e58ffc42927d4ff1198ffbf96f5f/pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130", size = 1834387, upload-time = "2024-12-18T11:29:33.481Z" }, { url = "https://files.pythonhosted.org/packages/71/47/82b5e846e01b26ac6f1893d3c5f9f3a2eb6ba79be26eef0b759b4fe72946/pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee", size = 1990453, upload-time = "2024-12-18T11:29:35.533Z" }, { url = "https://files.pythonhosted.org/packages/51/b2/b2b50d5ecf21acf870190ae5d093602d95f66c9c31f9d5de6062eb329ad1/pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b", size = 1885186, upload-time = "2024-12-18T11:29:37.649Z" }, { url = "https://files.pythonhosted.org/packages/43/53/13e9917fc69c0a4aea06fd63ed6a8d6cda9cf140ca9584d49c1650b0ef5e/pydantic_core-2.27.2-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d3e8d504bdd3f10835468f29008d72fc8359d95c9c415ce6e767203db6127506", size = 1899595, upload-time = "2024-12-18T11:29:40.887Z" }, { url = "https://files.pythonhosted.org/packages/f4/20/26c549249769ed84877f862f7bb93f89a6ee08b4bee1ed8781616b7fbb5e/pydantic_core-2.27.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:521eb9b7f036c9b6187f0b47318ab0d7ca14bd87f776240b90b21c1f4f149320", size = 1775010, upload-time = "2024-12-18T11:29:44.823Z" }, { url = "https://files.pythonhosted.org/packages/35/eb/8234e05452d92d2b102ffa1b56d801c3567e628fdc63f02080fdfc68fd5e/pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85210c4d99a0114f5a9481b44560d7d1e35e32cc5634c656bc48e590b669b145", size = 1830727, upload-time = "2024-12-18T11:29:46.904Z" }, { url = "https://files.pythonhosted.org/packages/8f/df/59f915c8b929d5f61e5a46accf748a87110ba145156f9326d1a7d28912b2/pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d716e2e30c6f140d7560ef1538953a5cd1a87264c737643d481f2779fc247fe1", size = 1868393, upload-time = "2024-12-18T11:29:49.098Z" }, { url = "https://files.pythonhosted.org/packages/d5/52/81cf4071dca654d485c277c581db368b0c95b2b883f4d7b736ab54f72ddf/pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f66d89ba397d92f840f8654756196d93804278457b5fbede59598a1f9f90b228", size = 2040300, upload-time = "2024-12-18T11:29:51.43Z" }, { url = "https://files.pythonhosted.org/packages/9c/00/05197ce1614f5c08d7a06e1d39d5d8e704dc81971b2719af134b844e2eaf/pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:669e193c1c576a58f132e3158f9dfa9662969edb1a250c54d8fa52590045f046", size = 2738785, upload-time = "2024-12-18T11:29:55.001Z" }, { url = "https://files.pythonhosted.org/packages/f7/a3/5f19bc495793546825ab160e530330c2afcee2281c02b5ffafd0b32ac05e/pydantic_core-2.27.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdbe7629b996647b99c01b37f11170a57ae675375b14b8c13b8518b8320ced5", size = 1996493, upload-time = "2024-12-18T11:29:57.13Z" }, { url = "https://files.pythonhosted.org/packages/ed/e8/e0102c2ec153dc3eed88aea03990e1b06cfbca532916b8a48173245afe60/pydantic_core-2.27.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d262606bf386a5ba0b0af3b97f37c83d7011439e3dc1a9298f21efb292e42f1a", size = 1998544, upload-time = "2024-12-18T11:30:00.681Z" }, { url = "https://files.pythonhosted.org/packages/fb/a3/4be70845b555bd80aaee9f9812a7cf3df81550bce6dadb3cfee9c5d8421d/pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:cabb9bcb7e0d97f74df8646f34fc76fbf793b7f6dc2438517d7a9e50eee4f14d", size = 2007449, upload-time = "2024-12-18T11:30:02.985Z" }, { url = "https://files.pythonhosted.org/packages/e3/9f/b779ed2480ba355c054e6d7ea77792467631d674b13d8257085a4bc7dcda/pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:d2d63f1215638d28221f664596b1ccb3944f6e25dd18cd3b86b0a4c408d5ebb9", size = 2129460, upload-time = "2024-12-18T11:30:06.55Z" }, { url = "https://files.pythonhosted.org/packages/a0/f0/a6ab0681f6e95260c7fbf552874af7302f2ea37b459f9b7f00698f875492/pydantic_core-2.27.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bca101c00bff0adb45a833f8451b9105d9df18accb8743b08107d7ada14bd7da", size = 2159609, upload-time = "2024-12-18T11:30:09.428Z" }, { url = "https://files.pythonhosted.org/packages/8a/2b/e1059506795104349712fbca647b18b3f4a7fd541c099e6259717441e1e0/pydantic_core-2.27.2-cp38-cp38-win32.whl", hash = "sha256:f6f8e111843bbb0dee4cb6594cdc73e79b3329b526037ec242a3e49012495b3b", size = 1819886, upload-time = "2024-12-18T11:30:11.777Z" }, { url = "https://files.pythonhosted.org/packages/aa/6d/df49c17f024dfc58db0bacc7b03610058018dd2ea2eaf748ccbada4c3d06/pydantic_core-2.27.2-cp38-cp38-win_amd64.whl", hash = "sha256:fd1aea04935a508f62e0d0ef1f5ae968774a32afc306fb8545e06f5ff5cdf3ad", size = 1980773, upload-time = "2024-12-18T11:30:14.828Z" }, { url = "https://files.pythonhosted.org/packages/27/97/3aef1ddb65c5ccd6eda9050036c956ff6ecbfe66cb7eb40f280f121a5bb0/pydantic_core-2.27.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:c10eb4f1659290b523af58fa7cffb452a61ad6ae5613404519aee4bfbf1df993", size = 1896475, upload-time = "2024-12-18T11:30:18.316Z" }, { url = "https://files.pythonhosted.org/packages/ad/d3/5668da70e373c9904ed2f372cb52c0b996426f302e0dee2e65634c92007d/pydantic_core-2.27.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ef592d4bad47296fb11f96cd7dc898b92e795032b4894dfb4076cfccd43a9308", size = 1772279, upload-time = "2024-12-18T11:30:20.547Z" }, { url = "https://files.pythonhosted.org/packages/8a/9e/e44b8cb0edf04a2f0a1f6425a65ee089c1d6f9c4c2dcab0209127b6fdfc2/pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c61709a844acc6bf0b7dce7daae75195a10aac96a596ea1b776996414791ede4", size = 1829112, upload-time = "2024-12-18T11:30:23.255Z" }, { url = "https://files.pythonhosted.org/packages/1c/90/1160d7ac700102effe11616e8119e268770f2a2aa5afb935f3ee6832987d/pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c5f762659e47fdb7b16956c71598292f60a03aa92f8b6351504359dbdba6cf", size = 1866780, upload-time = "2024-12-18T11:30:25.742Z" }, { url = "https://files.pythonhosted.org/packages/ee/33/13983426df09a36d22c15980008f8d9c77674fc319351813b5a2739b70f3/pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c9775e339e42e79ec99c441d9730fccf07414af63eac2f0e48e08fd38a64d76", size = 2037943, upload-time = "2024-12-18T11:30:28.036Z" }, { url = "https://files.pythonhosted.org/packages/01/d7/ced164e376f6747e9158c89988c293cd524ab8d215ae4e185e9929655d5c/pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57762139821c31847cfb2df63c12f725788bd9f04bc2fb392790959b8f70f118", size = 2740492, upload-time = "2024-12-18T11:30:30.412Z" }, { url = "https://files.pythonhosted.org/packages/8b/1f/3dc6e769d5b7461040778816aab2b00422427bcaa4b56cc89e9c653b2605/pydantic_core-2.27.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d1e85068e818c73e048fe28cfc769040bb1f475524f4745a5dc621f75ac7630", size = 1995714, upload-time = "2024-12-18T11:30:34.358Z" }, { url = "https://files.pythonhosted.org/packages/07/d7/a0bd09bc39283530b3f7c27033a814ef254ba3bd0b5cfd040b7abf1fe5da/pydantic_core-2.27.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:097830ed52fd9e427942ff3b9bc17fab52913b2f50f2880dc4a5611446606a54", size = 1997163, upload-time = "2024-12-18T11:30:37.979Z" }, { url = "https://files.pythonhosted.org/packages/2d/bb/2db4ad1762e1c5699d9b857eeb41959191980de6feb054e70f93085e1bcd/pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:044a50963a614ecfae59bb1eaf7ea7efc4bc62f49ed594e18fa1e5d953c40e9f", size = 2005217, upload-time = "2024-12-18T11:30:40.367Z" }, { url = "https://files.pythonhosted.org/packages/53/5f/23a5a3e7b8403f8dd8fc8a6f8b49f6b55c7d715b77dcf1f8ae919eeb5628/pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:4e0b4220ba5b40d727c7f879eac379b822eee5d8fff418e9d3381ee45b3b0362", size = 2127899, upload-time = "2024-12-18T11:30:42.737Z" }, { url = "https://files.pythonhosted.org/packages/c2/ae/aa38bb8dd3d89c2f1d8362dd890ee8f3b967330821d03bbe08fa01ce3766/pydantic_core-2.27.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5e4f4bb20d75e9325cc9696c6802657b58bc1dbbe3022f32cc2b2b632c3fbb96", size = 2155726, upload-time = "2024-12-18T11:30:45.279Z" }, { url = "https://files.pythonhosted.org/packages/98/61/4f784608cc9e98f70839187117ce840480f768fed5d386f924074bf6213c/pydantic_core-2.27.2-cp39-cp39-win32.whl", hash = "sha256:cca63613e90d001b9f2f9a9ceb276c308bfa2a43fafb75c8031c4f66039e8c6e", size = 1817219, upload-time = "2024-12-18T11:30:47.718Z" }, { url = "https://files.pythonhosted.org/packages/57/82/bb16a68e4a1a858bb3768c2c8f1ff8d8978014e16598f001ea29a25bf1d1/pydantic_core-2.27.2-cp39-cp39-win_amd64.whl", hash = "sha256:77d1bca19b0f7021b3a982e6f903dcd5b2b06076def36a652e3907f596e29f67", size = 1985382, upload-time = "2024-12-18T11:30:51.871Z" }, { url = "https://files.pythonhosted.org/packages/46/72/af70981a341500419e67d5cb45abe552a7c74b66326ac8877588488da1ac/pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2bf14caea37e91198329b828eae1618c068dfb8ef17bb33287a7ad4b61ac314e", size = 1891159, upload-time = "2024-12-18T11:30:54.382Z" }, { url = "https://files.pythonhosted.org/packages/ad/3d/c5913cccdef93e0a6a95c2d057d2c2cba347815c845cda79ddd3c0f5e17d/pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0cb791f5b45307caae8810c2023a184c74605ec3bcbb67d13846c28ff731ff8", size = 1768331, upload-time = "2024-12-18T11:30:58.178Z" }, { url = "https://files.pythonhosted.org/packages/f6/f0/a3ae8fbee269e4934f14e2e0e00928f9346c5943174f2811193113e58252/pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:688d3fd9fcb71f41c4c015c023d12a79d1c4c0732ec9eb35d96e3388a120dcf3", size = 1822467, upload-time = "2024-12-18T11:31:00.6Z" }, { url = "https://files.pythonhosted.org/packages/d7/7a/7bbf241a04e9f9ea24cd5874354a83526d639b02674648af3f350554276c/pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d591580c34f4d731592f0e9fe40f9cc1b430d297eecc70b962e93c5c668f15f", size = 1979797, upload-time = "2024-12-18T11:31:07.243Z" }, { url = "https://files.pythonhosted.org/packages/4f/5f/4784c6107731f89e0005a92ecb8a2efeafdb55eb992b8e9d0a2be5199335/pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:82f986faf4e644ffc189a7f1aafc86e46ef70372bb153e7001e8afccc6e54133", size = 1987839, upload-time = "2024-12-18T11:31:09.775Z" }, { url = "https://files.pythonhosted.org/packages/6d/a7/61246562b651dff00de86a5f01b6e4befb518df314c54dec187a78d81c84/pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:bec317a27290e2537f922639cafd54990551725fc844249e64c523301d0822fc", size = 1998861, upload-time = "2024-12-18T11:31:13.469Z" }, { url = "https://files.pythonhosted.org/packages/86/aa/837821ecf0c022bbb74ca132e117c358321e72e7f9702d1b6a03758545e2/pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:0296abcb83a797db256b773f45773da397da75a08f5fcaef41f2044adec05f50", size = 2116582, upload-time = "2024-12-18T11:31:17.423Z" }, { url = "https://files.pythonhosted.org/packages/81/b0/5e74656e95623cbaa0a6278d16cf15e10a51f6002e3ec126541e95c29ea3/pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0d75070718e369e452075a6017fbf187f788e17ed67a3abd47fa934d001863d9", size = 2151985, upload-time = "2024-12-18T11:31:19.901Z" }, { url = "https://files.pythonhosted.org/packages/63/37/3e32eeb2a451fddaa3898e2163746b0cffbbdbb4740d38372db0490d67f3/pydantic_core-2.27.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7e17b560be3c98a8e3aa66ce828bdebb9e9ac6ad5466fba92eb74c4c95cb1151", size = 2004715, upload-time = "2024-12-18T11:31:22.821Z" }, { url = "https://files.pythonhosted.org/packages/29/0e/dcaea00c9dbd0348b723cae82b0e0c122e0fa2b43fa933e1622fd237a3ee/pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c33939a82924da9ed65dab5a65d427205a73181d8098e79b6b426bdf8ad4e656", size = 1891733, upload-time = "2024-12-18T11:31:26.876Z" }, { url = "https://files.pythonhosted.org/packages/86/d3/e797bba8860ce650272bda6383a9d8cad1d1c9a75a640c9d0e848076f85e/pydantic_core-2.27.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:00bad2484fa6bda1e216e7345a798bd37c68fb2d97558edd584942aa41b7d278", size = 1768375, upload-time = "2024-12-18T11:31:29.276Z" }, { url = "https://files.pythonhosted.org/packages/41/f7/f847b15fb14978ca2b30262548f5fc4872b2724e90f116393eb69008299d/pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c817e2b40aba42bac6f457498dacabc568c3b7a986fc9ba7c8d9d260b71485fb", size = 1822307, upload-time = "2024-12-18T11:31:33.123Z" }, { url = "https://files.pythonhosted.org/packages/9c/63/ed80ec8255b587b2f108e514dc03eed1546cd00f0af281e699797f373f38/pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:251136cdad0cb722e93732cb45ca5299fb56e1344a833640bf93b2803f8d1bfd", size = 1979971, upload-time = "2024-12-18T11:31:35.755Z" }, { url = "https://files.pythonhosted.org/packages/a9/6d/6d18308a45454a0de0e975d70171cadaf454bc7a0bf86b9c7688e313f0bb/pydantic_core-2.27.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d2088237af596f0a524d3afc39ab3b036e8adb054ee57cbb1dcf8e09da5b29cc", size = 1987616, upload-time = "2024-12-18T11:31:38.534Z" }, { url = "https://files.pythonhosted.org/packages/82/8a/05f8780f2c1081b800a7ca54c1971e291c2d07d1a50fb23c7e4aef4ed403/pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d4041c0b966a84b4ae7a09832eb691a35aec90910cd2dbe7a208de59be77965b", size = 1998943, upload-time = "2024-12-18T11:31:41.853Z" }, { url = "https://files.pythonhosted.org/packages/5e/3e/fe5b6613d9e4c0038434396b46c5303f5ade871166900b357ada4766c5b7/pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:8083d4e875ebe0b864ffef72a4304827015cff328a1be6e22cc850753bfb122b", size = 2116654, upload-time = "2024-12-18T11:31:44.756Z" }, { url = "https://files.pythonhosted.org/packages/db/ad/28869f58938fad8cc84739c4e592989730bfb69b7c90a8fff138dff18e1e/pydantic_core-2.27.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f141ee28a0ad2123b6611b6ceff018039df17f32ada8b534e6aa039545a3efb2", size = 2152292, upload-time = "2024-12-18T11:31:48.613Z" }, { url = "https://files.pythonhosted.org/packages/a1/0c/c5c5cd3689c32ed1fe8c5d234b079c12c281c051759770c05b8bed6412b5/pydantic_core-2.27.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7d0c8399fcc1848491f00e0314bd59fb34a9c008761bcb422a057670c3f65e35", size = 2004961, upload-time = "2024-12-18T11:31:52.446Z" }, ] [[package]] name = "pydantic-core" version = "2.33.2" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.9'", ] dependencies = [ { name = "typing-extensions", marker = "python_full_version >= '3.9'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ad/88/5f2260bdfae97aabf98f1778d43f69574390ad787afb646292a638c923d4/pydantic_core-2.33.2.tar.gz", hash = "sha256:7cb8bc3605c29176e1b105350d2e6474142d7c1bd1d9327c4a9bdb46bf827acc", size = 435195, upload-time = "2025-04-23T18:33:52.104Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/e5/92/b31726561b5dae176c2d2c2dc43a9c5bfba5d32f96f8b4c0a600dd492447/pydantic_core-2.33.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2b3d326aaef0c0399d9afffeb6367d5e26ddc24d351dbc9c636840ac355dc5d8", size = 2028817, upload-time = "2025-04-23T18:30:43.919Z" }, { url = "https://files.pythonhosted.org/packages/a3/44/3f0b95fafdaca04a483c4e685fe437c6891001bf3ce8b2fded82b9ea3aa1/pydantic_core-2.33.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e5b2671f05ba48b94cb90ce55d8bdcaaedb8ba00cc5359f6810fc918713983d", size = 1861357, upload-time = "2025-04-23T18:30:46.372Z" }, { url = "https://files.pythonhosted.org/packages/30/97/e8f13b55766234caae05372826e8e4b3b96e7b248be3157f53237682e43c/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0069c9acc3f3981b9ff4cdfaf088e98d83440a4c7ea1bc07460af3d4dc22e72d", size = 1898011, upload-time = "2025-04-23T18:30:47.591Z" }, { url = "https://files.pythonhosted.org/packages/9b/a3/99c48cf7bafc991cc3ee66fd544c0aae8dc907b752f1dad2d79b1b5a471f/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d53b22f2032c42eaaf025f7c40c2e3b94568ae077a606f006d206a463bc69572", size = 1982730, upload-time = "2025-04-23T18:30:49.328Z" }, { url = "https://files.pythonhosted.org/packages/de/8e/a5b882ec4307010a840fb8b58bd9bf65d1840c92eae7534c7441709bf54b/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0405262705a123b7ce9f0b92f123334d67b70fd1f20a9372b907ce1080c7ba02", size = 2136178, upload-time = "2025-04-23T18:30:50.907Z" }, { url = "https://files.pythonhosted.org/packages/e4/bb/71e35fc3ed05af6834e890edb75968e2802fe98778971ab5cba20a162315/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4b25d91e288e2c4e0662b8038a28c6a07eaac3e196cfc4ff69de4ea3db992a1b", size = 2736462, upload-time = "2025-04-23T18:30:52.083Z" }, { url = "https://files.pythonhosted.org/packages/31/0d/c8f7593e6bc7066289bbc366f2235701dcbebcd1ff0ef8e64f6f239fb47d/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bdfe4b3789761f3bcb4b1ddf33355a71079858958e3a552f16d5af19768fef2", size = 2005652, upload-time = "2025-04-23T18:30:53.389Z" }, { url = "https://files.pythonhosted.org/packages/d2/7a/996d8bd75f3eda405e3dd219ff5ff0a283cd8e34add39d8ef9157e722867/pydantic_core-2.33.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:efec8db3266b76ef9607c2c4c419bdb06bf335ae433b80816089ea7585816f6a", size = 2113306, upload-time = "2025-04-23T18:30:54.661Z" }, { url = "https://files.pythonhosted.org/packages/ff/84/daf2a6fb2db40ffda6578a7e8c5a6e9c8affb251a05c233ae37098118788/pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:031c57d67ca86902726e0fae2214ce6770bbe2f710dc33063187a68744a5ecac", size = 2073720, upload-time = "2025-04-23T18:30:56.11Z" }, { url = "https://files.pythonhosted.org/packages/77/fb/2258da019f4825128445ae79456a5499c032b55849dbd5bed78c95ccf163/pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:f8de619080e944347f5f20de29a975c2d815d9ddd8be9b9b7268e2e3ef68605a", size = 2244915, upload-time = "2025-04-23T18:30:57.501Z" }, { url = "https://files.pythonhosted.org/packages/d8/7a/925ff73756031289468326e355b6fa8316960d0d65f8b5d6b3a3e7866de7/pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:73662edf539e72a9440129f231ed3757faab89630d291b784ca99237fb94db2b", size = 2241884, upload-time = "2025-04-23T18:30:58.867Z" }, { url = "https://files.pythonhosted.org/packages/0b/b0/249ee6d2646f1cdadcb813805fe76265745c4010cf20a8eba7b0e639d9b2/pydantic_core-2.33.2-cp310-cp310-win32.whl", hash = "sha256:0a39979dcbb70998b0e505fb1556a1d550a0781463ce84ebf915ba293ccb7e22", size = 1910496, upload-time = "2025-04-23T18:31:00.078Z" }, { url = "https://files.pythonhosted.org/packages/66/ff/172ba8f12a42d4b552917aa65d1f2328990d3ccfc01d5b7c943ec084299f/pydantic_core-2.33.2-cp310-cp310-win_amd64.whl", hash = "sha256:b0379a2b24882fef529ec3b4987cb5d003b9cda32256024e6fe1586ac45fc640", size = 1955019, upload-time = "2025-04-23T18:31:01.335Z" }, { url = "https://files.pythonhosted.org/packages/3f/8d/71db63483d518cbbf290261a1fc2839d17ff89fce7089e08cad07ccfce67/pydantic_core-2.33.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:4c5b0a576fb381edd6d27f0a85915c6daf2f8138dc5c267a57c08a62900758c7", size = 2028584, upload-time = "2025-04-23T18:31:03.106Z" }, { url = "https://files.pythonhosted.org/packages/24/2f/3cfa7244ae292dd850989f328722d2aef313f74ffc471184dc509e1e4e5a/pydantic_core-2.33.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e799c050df38a639db758c617ec771fd8fb7a5f8eaaa4b27b101f266b216a246", size = 1855071, upload-time = "2025-04-23T18:31:04.621Z" }, { url = "https://files.pythonhosted.org/packages/b3/d3/4ae42d33f5e3f50dd467761304be2fa0a9417fbf09735bc2cce003480f2a/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc46a01bf8d62f227d5ecee74178ffc448ff4e5197c756331f71efcc66dc980f", size = 1897823, upload-time = "2025-04-23T18:31:06.377Z" }, { url = "https://files.pythonhosted.org/packages/f4/f3/aa5976e8352b7695ff808599794b1fba2a9ae2ee954a3426855935799488/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a144d4f717285c6d9234a66778059f33a89096dfb9b39117663fd8413d582dcc", size = 1983792, upload-time = "2025-04-23T18:31:07.93Z" }, { url = "https://files.pythonhosted.org/packages/d5/7a/cda9b5a23c552037717f2b2a5257e9b2bfe45e687386df9591eff7b46d28/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73cf6373c21bc80b2e0dc88444f41ae60b2f070ed02095754eb5a01df12256de", size = 2136338, upload-time = "2025-04-23T18:31:09.283Z" }, { url = "https://files.pythonhosted.org/packages/2b/9f/b8f9ec8dd1417eb9da784e91e1667d58a2a4a7b7b34cf4af765ef663a7e5/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3dc625f4aa79713512d1976fe9f0bc99f706a9dee21dfd1810b4bbbf228d0e8a", size = 2730998, upload-time = "2025-04-23T18:31:11.7Z" }, { url = "https://files.pythonhosted.org/packages/47/bc/cd720e078576bdb8255d5032c5d63ee5c0bf4b7173dd955185a1d658c456/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b21b5549499972441da4758d662aeea93f1923f953e9cbaff14b8b9565aef", size = 2003200, upload-time = "2025-04-23T18:31:13.536Z" }, { url = "https://files.pythonhosted.org/packages/ca/22/3602b895ee2cd29d11a2b349372446ae9727c32e78a94b3d588a40fdf187/pydantic_core-2.33.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bdc25f3681f7b78572699569514036afe3c243bc3059d3942624e936ec93450e", size = 2113890, upload-time = "2025-04-23T18:31:15.011Z" }, { url = "https://files.pythonhosted.org/packages/ff/e6/e3c5908c03cf00d629eb38393a98fccc38ee0ce8ecce32f69fc7d7b558a7/pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fe5b32187cbc0c862ee201ad66c30cf218e5ed468ec8dc1cf49dec66e160cc4d", size = 2073359, upload-time = "2025-04-23T18:31:16.393Z" }, { url = "https://files.pythonhosted.org/packages/12/e7/6a36a07c59ebefc8777d1ffdaf5ae71b06b21952582e4b07eba88a421c79/pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:bc7aee6f634a6f4a95676fcb5d6559a2c2a390330098dba5e5a5f28a2e4ada30", size = 2245883, upload-time = "2025-04-23T18:31:17.892Z" }, { url = "https://files.pythonhosted.org/packages/16/3f/59b3187aaa6cc0c1e6616e8045b284de2b6a87b027cce2ffcea073adf1d2/pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:235f45e5dbcccf6bd99f9f472858849f73d11120d76ea8707115415f8e5ebebf", size = 2241074, upload-time = "2025-04-23T18:31:19.205Z" }, { url = "https://files.pythonhosted.org/packages/e0/ed/55532bb88f674d5d8f67ab121a2a13c385df382de2a1677f30ad385f7438/pydantic_core-2.33.2-cp311-cp311-win32.whl", hash = "sha256:6368900c2d3ef09b69cb0b913f9f8263b03786e5b2a387706c5afb66800efd51", size = 1910538, upload-time = "2025-04-23T18:31:20.541Z" }, { url = "https://files.pythonhosted.org/packages/fe/1b/25b7cccd4519c0b23c2dd636ad39d381abf113085ce4f7bec2b0dc755eb1/pydantic_core-2.33.2-cp311-cp311-win_amd64.whl", hash = "sha256:1e063337ef9e9820c77acc768546325ebe04ee38b08703244c1309cccc4f1bab", size = 1952909, upload-time = "2025-04-23T18:31:22.371Z" }, { url = "https://files.pythonhosted.org/packages/49/a9/d809358e49126438055884c4366a1f6227f0f84f635a9014e2deb9b9de54/pydantic_core-2.33.2-cp311-cp311-win_arm64.whl", hash = "sha256:6b99022f1d19bc32a4c2a0d544fc9a76e3be90f0b3f4af413f87d38749300e65", size = 1897786, upload-time = "2025-04-23T18:31:24.161Z" }, { url = "https://files.pythonhosted.org/packages/18/8a/2b41c97f554ec8c71f2a8a5f85cb56a8b0956addfe8b0efb5b3d77e8bdc3/pydantic_core-2.33.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a7ec89dc587667f22b6a0b6579c249fca9026ce7c333fc142ba42411fa243cdc", size = 2009000, upload-time = "2025-04-23T18:31:25.863Z" }, { url = "https://files.pythonhosted.org/packages/a1/02/6224312aacb3c8ecbaa959897af57181fb6cf3a3d7917fd44d0f2917e6f2/pydantic_core-2.33.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3c6db6e52c6d70aa0d00d45cdb9b40f0433b96380071ea80b09277dba021ddf7", size = 1847996, upload-time = "2025-04-23T18:31:27.341Z" }, { url = "https://files.pythonhosted.org/packages/d6/46/6dcdf084a523dbe0a0be59d054734b86a981726f221f4562aed313dbcb49/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e61206137cbc65e6d5256e1166f88331d3b6238e082d9f74613b9b765fb9025", size = 1880957, upload-time = "2025-04-23T18:31:28.956Z" }, { url = "https://files.pythonhosted.org/packages/ec/6b/1ec2c03837ac00886ba8160ce041ce4e325b41d06a034adbef11339ae422/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eb8c529b2819c37140eb51b914153063d27ed88e3bdc31b71198a198e921e011", size = 1964199, upload-time = "2025-04-23T18:31:31.025Z" }, { url = "https://files.pythonhosted.org/packages/2d/1d/6bf34d6adb9debd9136bd197ca72642203ce9aaaa85cfcbfcf20f9696e83/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c52b02ad8b4e2cf14ca7b3d918f3eb0ee91e63b3167c32591e57c4317e134f8f", size = 2120296, upload-time = "2025-04-23T18:31:32.514Z" }, { url = "https://files.pythonhosted.org/packages/e0/94/2bd0aaf5a591e974b32a9f7123f16637776c304471a0ab33cf263cf5591a/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:96081f1605125ba0855dfda83f6f3df5ec90c61195421ba72223de35ccfb2f88", size = 2676109, upload-time = "2025-04-23T18:31:33.958Z" }, { url = "https://files.pythonhosted.org/packages/f9/41/4b043778cf9c4285d59742281a769eac371b9e47e35f98ad321349cc5d61/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f57a69461af2a5fa6e6bbd7a5f60d3b7e6cebb687f55106933188e79ad155c1", size = 2002028, upload-time = "2025-04-23T18:31:39.095Z" }, { url = "https://files.pythonhosted.org/packages/cb/d5/7bb781bf2748ce3d03af04d5c969fa1308880e1dca35a9bd94e1a96a922e/pydantic_core-2.33.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:572c7e6c8bb4774d2ac88929e3d1f12bc45714ae5ee6d9a788a9fb35e60bb04b", size = 2100044, upload-time = "2025-04-23T18:31:41.034Z" }, { url = "https://files.pythonhosted.org/packages/fe/36/def5e53e1eb0ad896785702a5bbfd25eed546cdcf4087ad285021a90ed53/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:db4b41f9bd95fbe5acd76d89920336ba96f03e149097365afe1cb092fceb89a1", size = 2058881, upload-time = "2025-04-23T18:31:42.757Z" }, { url = "https://files.pythonhosted.org/packages/01/6c/57f8d70b2ee57fc3dc8b9610315949837fa8c11d86927b9bb044f8705419/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:fa854f5cf7e33842a892e5c73f45327760bc7bc516339fda888c75ae60edaeb6", size = 2227034, upload-time = "2025-04-23T18:31:44.304Z" }, { url = "https://files.pythonhosted.org/packages/27/b9/9c17f0396a82b3d5cbea4c24d742083422639e7bb1d5bf600e12cb176a13/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5f483cfb75ff703095c59e365360cb73e00185e01aaea067cd19acffd2ab20ea", size = 2234187, upload-time = "2025-04-23T18:31:45.891Z" }, { url = "https://files.pythonhosted.org/packages/b0/6a/adf5734ffd52bf86d865093ad70b2ce543415e0e356f6cacabbc0d9ad910/pydantic_core-2.33.2-cp312-cp312-win32.whl", hash = "sha256:9cb1da0f5a471435a7bc7e439b8a728e8b61e59784b2af70d7c169f8dd8ae290", size = 1892628, upload-time = "2025-04-23T18:31:47.819Z" }, { url = "https://files.pythonhosted.org/packages/43/e4/5479fecb3606c1368d496a825d8411e126133c41224c1e7238be58b87d7e/pydantic_core-2.33.2-cp312-cp312-win_amd64.whl", hash = "sha256:f941635f2a3d96b2973e867144fde513665c87f13fe0e193c158ac51bfaaa7b2", size = 1955866, upload-time = "2025-04-23T18:31:49.635Z" }, { url = "https://files.pythonhosted.org/packages/0d/24/8b11e8b3e2be9dd82df4b11408a67c61bb4dc4f8e11b5b0fc888b38118b5/pydantic_core-2.33.2-cp312-cp312-win_arm64.whl", hash = "sha256:cca3868ddfaccfbc4bfb1d608e2ccaaebe0ae628e1416aeb9c4d88c001bb45ab", size = 1888894, upload-time = "2025-04-23T18:31:51.609Z" }, { url = "https://files.pythonhosted.org/packages/46/8c/99040727b41f56616573a28771b1bfa08a3d3fe74d3d513f01251f79f172/pydantic_core-2.33.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:1082dd3e2d7109ad8b7da48e1d4710c8d06c253cbc4a27c1cff4fbcaa97a9e3f", size = 2015688, upload-time = "2025-04-23T18:31:53.175Z" }, { url = "https://files.pythonhosted.org/packages/3a/cc/5999d1eb705a6cefc31f0b4a90e9f7fc400539b1a1030529700cc1b51838/pydantic_core-2.33.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f517ca031dfc037a9c07e748cefd8d96235088b83b4f4ba8939105d20fa1dcd6", size = 1844808, upload-time = "2025-04-23T18:31:54.79Z" }, { url = "https://files.pythonhosted.org/packages/6f/5e/a0a7b8885c98889a18b6e376f344da1ef323d270b44edf8174d6bce4d622/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a9f2c9dd19656823cb8250b0724ee9c60a82f3cdf68a080979d13092a3b0fef", size = 1885580, upload-time = "2025-04-23T18:31:57.393Z" }, { url = "https://files.pythonhosted.org/packages/3b/2a/953581f343c7d11a304581156618c3f592435523dd9d79865903272c256a/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2b0a451c263b01acebe51895bfb0e1cc842a5c666efe06cdf13846c7418caa9a", size = 1973859, upload-time = "2025-04-23T18:31:59.065Z" }, { url = "https://files.pythonhosted.org/packages/e6/55/f1a813904771c03a3f97f676c62cca0c0a4138654107c1b61f19c644868b/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ea40a64d23faa25e62a70ad163571c0b342b8bf66d5fa612ac0dec4f069d916", size = 2120810, upload-time = "2025-04-23T18:32:00.78Z" }, { url = "https://files.pythonhosted.org/packages/aa/c3/053389835a996e18853ba107a63caae0b9deb4a276c6b472931ea9ae6e48/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fb2d542b4d66f9470e8065c5469ec676978d625a8b7a363f07d9a501a9cb36a", size = 2676498, upload-time = "2025-04-23T18:32:02.418Z" }, { url = "https://files.pythonhosted.org/packages/eb/3c/f4abd740877a35abade05e437245b192f9d0ffb48bbbbd708df33d3cda37/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdac5d6ffa1b5a83bca06ffe7583f5576555e6c8b3a91fbd25ea7780f825f7d", size = 2000611, upload-time = "2025-04-23T18:32:04.152Z" }, { url = "https://files.pythonhosted.org/packages/59/a7/63ef2fed1837d1121a894d0ce88439fe3e3b3e48c7543b2a4479eb99c2bd/pydantic_core-2.33.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:04a1a413977ab517154eebb2d326da71638271477d6ad87a769102f7c2488c56", size = 2107924, upload-time = "2025-04-23T18:32:06.129Z" }, { url = "https://files.pythonhosted.org/packages/04/8f/2551964ef045669801675f1cfc3b0d74147f4901c3ffa42be2ddb1f0efc4/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c8e7af2f4e0194c22b5b37205bfb293d166a7344a5b0d0eaccebc376546d77d5", size = 2063196, upload-time = "2025-04-23T18:32:08.178Z" }, { url = "https://files.pythonhosted.org/packages/26/bd/d9602777e77fc6dbb0c7db9ad356e9a985825547dce5ad1d30ee04903918/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:5c92edd15cd58b3c2d34873597a1e20f13094f59cf88068adb18947df5455b4e", size = 2236389, upload-time = "2025-04-23T18:32:10.242Z" }, { url = "https://files.pythonhosted.org/packages/42/db/0e950daa7e2230423ab342ae918a794964b053bec24ba8af013fc7c94846/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:65132b7b4a1c0beded5e057324b7e16e10910c106d43675d9bd87d4f38dde162", size = 2239223, upload-time = "2025-04-23T18:32:12.382Z" }, { url = "https://files.pythonhosted.org/packages/58/4d/4f937099c545a8a17eb52cb67fe0447fd9a373b348ccfa9a87f141eeb00f/pydantic_core-2.33.2-cp313-cp313-win32.whl", hash = "sha256:52fb90784e0a242bb96ec53f42196a17278855b0f31ac7c3cc6f5c1ec4811849", size = 1900473, upload-time = "2025-04-23T18:32:14.034Z" }, { url = "https://files.pythonhosted.org/packages/a0/75/4a0a9bac998d78d889def5e4ef2b065acba8cae8c93696906c3a91f310ca/pydantic_core-2.33.2-cp313-cp313-win_amd64.whl", hash = "sha256:c083a3bdd5a93dfe480f1125926afcdbf2917ae714bdb80b36d34318b2bec5d9", size = 1955269, upload-time = "2025-04-23T18:32:15.783Z" }, { url = "https://files.pythonhosted.org/packages/f9/86/1beda0576969592f1497b4ce8e7bc8cbdf614c352426271b1b10d5f0aa64/pydantic_core-2.33.2-cp313-cp313-win_arm64.whl", hash = "sha256:e80b087132752f6b3d714f041ccf74403799d3b23a72722ea2e6ba2e892555b9", size = 1893921, upload-time = "2025-04-23T18:32:18.473Z" }, { url = "https://files.pythonhosted.org/packages/a4/7d/e09391c2eebeab681df2b74bfe6c43422fffede8dc74187b2b0bf6fd7571/pydantic_core-2.33.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61c18fba8e5e9db3ab908620af374db0ac1baa69f0f32df4f61ae23f15e586ac", size = 1806162, upload-time = "2025-04-23T18:32:20.188Z" }, { url = "https://files.pythonhosted.org/packages/f1/3d/847b6b1fed9f8ed3bb95a9ad04fbd0b212e832d4f0f50ff4d9ee5a9f15cf/pydantic_core-2.33.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95237e53bb015f67b63c91af7518a62a8660376a6a0db19b89acc77a4d6199f5", size = 1981560, upload-time = "2025-04-23T18:32:22.354Z" }, { url = "https://files.pythonhosted.org/packages/6f/9a/e73262f6c6656262b5fdd723ad90f518f579b7bc8622e43a942eec53c938/pydantic_core-2.33.2-cp313-cp313t-win_amd64.whl", hash = "sha256:c2fc0a768ef76c15ab9238afa6da7f69895bb5d1ee83aeea2e3509af4472d0b9", size = 1935777, upload-time = "2025-04-23T18:32:25.088Z" }, { url = "https://files.pythonhosted.org/packages/53/ea/bbe9095cdd771987d13c82d104a9c8559ae9aec1e29f139e286fd2e9256e/pydantic_core-2.33.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a2b911a5b90e0374d03813674bf0a5fbbb7741570dcd4b4e85a2e48d17def29d", size = 2028677, upload-time = "2025-04-23T18:32:27.227Z" }, { url = "https://files.pythonhosted.org/packages/49/1d/4ac5ed228078737d457a609013e8f7edc64adc37b91d619ea965758369e5/pydantic_core-2.33.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6fa6dfc3e4d1f734a34710f391ae822e0a8eb8559a85c6979e14e65ee6ba2954", size = 1864735, upload-time = "2025-04-23T18:32:29.019Z" }, { url = "https://files.pythonhosted.org/packages/23/9a/2e70d6388d7cda488ae38f57bc2f7b03ee442fbcf0d75d848304ac7e405b/pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c54c939ee22dc8e2d545da79fc5381f1c020d6d3141d3bd747eab59164dc89fb", size = 1898467, upload-time = "2025-04-23T18:32:31.119Z" }, { url = "https://files.pythonhosted.org/packages/ff/2e/1568934feb43370c1ffb78a77f0baaa5a8b6897513e7a91051af707ffdc4/pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53a57d2ed685940a504248187d5685e49eb5eef0f696853647bf37c418c538f7", size = 1983041, upload-time = "2025-04-23T18:32:33.655Z" }, { url = "https://files.pythonhosted.org/packages/01/1a/1a1118f38ab64eac2f6269eb8c120ab915be30e387bb561e3af904b12499/pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09fb9dd6571aacd023fe6aaca316bd01cf60ab27240d7eb39ebd66a3a15293b4", size = 2136503, upload-time = "2025-04-23T18:32:35.519Z" }, { url = "https://files.pythonhosted.org/packages/5c/da/44754d1d7ae0f22d6d3ce6c6b1486fc07ac2c524ed8f6eca636e2e1ee49b/pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0e6116757f7959a712db11f3e9c0a99ade00a5bbedae83cb801985aa154f071b", size = 2736079, upload-time = "2025-04-23T18:32:37.659Z" }, { url = "https://files.pythonhosted.org/packages/4d/98/f43cd89172220ec5aa86654967b22d862146bc4d736b1350b4c41e7c9c03/pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d55ab81c57b8ff8548c3e4947f119551253f4e3787a7bbc0b6b3ca47498a9d3", size = 2006508, upload-time = "2025-04-23T18:32:39.637Z" }, { url = "https://files.pythonhosted.org/packages/2b/cc/f77e8e242171d2158309f830f7d5d07e0531b756106f36bc18712dc439df/pydantic_core-2.33.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c20c462aa4434b33a2661701b861604913f912254e441ab8d78d30485736115a", size = 2113693, upload-time = "2025-04-23T18:32:41.818Z" }, { url = "https://files.pythonhosted.org/packages/54/7a/7be6a7bd43e0a47c147ba7fbf124fe8aaf1200bc587da925509641113b2d/pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:44857c3227d3fb5e753d5fe4a3420d6376fa594b07b621e220cd93703fe21782", size = 2074224, upload-time = "2025-04-23T18:32:44.033Z" }, { url = "https://files.pythonhosted.org/packages/2a/07/31cf8fadffbb03be1cb520850e00a8490c0927ec456e8293cafda0726184/pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:eb9b459ca4df0e5c87deb59d37377461a538852765293f9e6ee834f0435a93b9", size = 2245403, upload-time = "2025-04-23T18:32:45.836Z" }, { url = "https://files.pythonhosted.org/packages/b6/8d/bbaf4c6721b668d44f01861f297eb01c9b35f612f6b8e14173cb204e6240/pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9fcd347d2cc5c23b06de6d3b7b8275be558a0c90549495c699e379a80bf8379e", size = 2242331, upload-time = "2025-04-23T18:32:47.618Z" }, { url = "https://files.pythonhosted.org/packages/bb/93/3cc157026bca8f5006250e74515119fcaa6d6858aceee8f67ab6dc548c16/pydantic_core-2.33.2-cp39-cp39-win32.whl", hash = "sha256:83aa99b1285bc8f038941ddf598501a86f1536789740991d7d8756e34f1e74d9", size = 1910571, upload-time = "2025-04-23T18:32:49.401Z" }, { url = "https://files.pythonhosted.org/packages/5b/90/7edc3b2a0d9f0dda8806c04e511a67b0b7a41d2187e2003673a996fb4310/pydantic_core-2.33.2-cp39-cp39-win_amd64.whl", hash = "sha256:f481959862f57f29601ccced557cc2e817bce7533ab8e01a797a48b49c9692b3", size = 1956504, upload-time = "2025-04-23T18:32:51.287Z" }, { url = "https://files.pythonhosted.org/packages/30/68/373d55e58b7e83ce371691f6eaa7175e3a24b956c44628eb25d7da007917/pydantic_core-2.33.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5c4aa4e82353f65e548c476b37e64189783aa5384903bfea4f41580f255fddfa", size = 2023982, upload-time = "2025-04-23T18:32:53.14Z" }, { url = "https://files.pythonhosted.org/packages/a4/16/145f54ac08c96a63d8ed6442f9dec17b2773d19920b627b18d4f10a061ea/pydantic_core-2.33.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d946c8bf0d5c24bf4fe333af284c59a19358aa3ec18cb3dc4370080da1e8ad29", size = 1858412, upload-time = "2025-04-23T18:32:55.52Z" }, { url = "https://files.pythonhosted.org/packages/41/b1/c6dc6c3e2de4516c0bb2c46f6a373b91b5660312342a0cf5826e38ad82fa/pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87b31b6846e361ef83fedb187bb5b4372d0da3f7e28d85415efa92d6125d6e6d", size = 1892749, upload-time = "2025-04-23T18:32:57.546Z" }, { url = "https://files.pythonhosted.org/packages/12/73/8cd57e20afba760b21b742106f9dbdfa6697f1570b189c7457a1af4cd8a0/pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa9d91b338f2df0508606f7009fde642391425189bba6d8c653afd80fd6bb64e", size = 2067527, upload-time = "2025-04-23T18:32:59.771Z" }, { url = "https://files.pythonhosted.org/packages/e3/d5/0bb5d988cc019b3cba4a78f2d4b3854427fc47ee8ec8e9eaabf787da239c/pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2058a32994f1fde4ca0480ab9d1e75a0e8c87c22b53a3ae66554f9af78f2fe8c", size = 2108225, upload-time = "2025-04-23T18:33:04.51Z" }, { url = "https://files.pythonhosted.org/packages/f1/c5/00c02d1571913d496aabf146106ad8239dc132485ee22efe08085084ff7c/pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:0e03262ab796d986f978f79c943fc5f620381be7287148b8010b4097f79a39ec", size = 2069490, upload-time = "2025-04-23T18:33:06.391Z" }, { url = "https://files.pythonhosted.org/packages/22/a8/dccc38768274d3ed3a59b5d06f59ccb845778687652daa71df0cab4040d7/pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:1a8695a8d00c73e50bff9dfda4d540b7dee29ff9b8053e38380426a85ef10052", size = 2237525, upload-time = "2025-04-23T18:33:08.44Z" }, { url = "https://files.pythonhosted.org/packages/d4/e7/4f98c0b125dda7cf7ccd14ba936218397b44f50a56dd8c16a3091df116c3/pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:fa754d1850735a0b0e03bcffd9d4b4343eb417e47196e4485d9cca326073a42c", size = 2238446, upload-time = "2025-04-23T18:33:10.313Z" }, { url = "https://files.pythonhosted.org/packages/ce/91/2ec36480fdb0b783cd9ef6795753c1dea13882f2e68e73bce76ae8c21e6a/pydantic_core-2.33.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a11c8d26a50bfab49002947d3d237abe4d9e4b5bdc8846a63537b6488e197808", size = 2066678, upload-time = "2025-04-23T18:33:12.224Z" }, { url = "https://files.pythonhosted.org/packages/7b/27/d4ae6487d73948d6f20dddcd94be4ea43e74349b56eba82e9bdee2d7494c/pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:dd14041875d09cc0f9308e37a6f8b65f5585cf2598a53aa0123df8b129d481f8", size = 2025200, upload-time = "2025-04-23T18:33:14.199Z" }, { url = "https://files.pythonhosted.org/packages/f1/b8/b3cb95375f05d33801024079b9392a5ab45267a63400bf1866e7ce0f0de4/pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d87c561733f66531dced0da6e864f44ebf89a8fba55f31407b00c2f7f9449593", size = 1859123, upload-time = "2025-04-23T18:33:16.555Z" }, { url = "https://files.pythonhosted.org/packages/05/bc/0d0b5adeda59a261cd30a1235a445bf55c7e46ae44aea28f7bd6ed46e091/pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f82865531efd18d6e07a04a17331af02cb7a651583c418df8266f17a63c6612", size = 1892852, upload-time = "2025-04-23T18:33:18.513Z" }, { url = "https://files.pythonhosted.org/packages/3e/11/d37bdebbda2e449cb3f519f6ce950927b56d62f0b84fd9cb9e372a26a3d5/pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bfb5112df54209d820d7bf9317c7a6c9025ea52e49f46b6a2060104bba37de7", size = 2067484, upload-time = "2025-04-23T18:33:20.475Z" }, { url = "https://files.pythonhosted.org/packages/8c/55/1f95f0a05ce72ecb02a8a8a1c3be0579bbc29b1d5ab68f1378b7bebc5057/pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:64632ff9d614e5eecfb495796ad51b0ed98c453e447a76bcbeeb69615079fc7e", size = 2108896, upload-time = "2025-04-23T18:33:22.501Z" }, { url = "https://files.pythonhosted.org/packages/53/89/2b2de6c81fa131f423246a9109d7b2a375e83968ad0800d6e57d0574629b/pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:f889f7a40498cc077332c7ab6b4608d296d852182211787d4f3ee377aaae66e8", size = 2069475, upload-time = "2025-04-23T18:33:24.528Z" }, { url = "https://files.pythonhosted.org/packages/b8/e9/1f7efbe20d0b2b10f6718944b5d8ece9152390904f29a78e68d4e7961159/pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:de4b83bb311557e439b9e186f733f6c645b9417c84e2eb8203f3f820a4b988bf", size = 2239013, upload-time = "2025-04-23T18:33:26.621Z" }, { url = "https://files.pythonhosted.org/packages/3c/b2/5309c905a93811524a49b4e031e9851a6b00ff0fb668794472ea7746b448/pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:82f68293f055f51b51ea42fafc74b6aad03e70e191799430b90c13d643059ebb", size = 2238715, upload-time = "2025-04-23T18:33:28.656Z" }, { url = "https://files.pythonhosted.org/packages/32/56/8a7ca5d2cd2cda1d245d34b1c9a942920a718082ae8e54e5f3e5a58b7add/pydantic_core-2.33.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:329467cecfb529c925cf2bbd4d60d2c509bc2fb52a20c1045bf09bb70971a9c1", size = 2066757, upload-time = "2025-04-23T18:33:30.645Z" }, { url = "https://files.pythonhosted.org/packages/08/98/dbf3fdfabaf81cda5622154fda78ea9965ac467e3239078e0dcd6df159e7/pydantic_core-2.33.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:87acbfcf8e90ca885206e98359d7dca4bcbb35abdc0ff66672a293e1d7a19101", size = 2024034, upload-time = "2025-04-23T18:33:32.843Z" }, { url = "https://files.pythonhosted.org/packages/8d/99/7810aa9256e7f2ccd492590f86b79d370df1e9292f1f80b000b6a75bd2fb/pydantic_core-2.33.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:7f92c15cd1e97d4b12acd1cc9004fa092578acfa57b67ad5e43a197175d01a64", size = 1858578, upload-time = "2025-04-23T18:33:34.912Z" }, { url = "https://files.pythonhosted.org/packages/d8/60/bc06fa9027c7006cc6dd21e48dbf39076dc39d9abbaf718a1604973a9670/pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3f26877a748dc4251cfcfda9dfb5f13fcb034f5308388066bcfe9031b63ae7d", size = 1892858, upload-time = "2025-04-23T18:33:36.933Z" }, { url = "https://files.pythonhosted.org/packages/f2/40/9d03997d9518816c68b4dfccb88969756b9146031b61cd37f781c74c9b6a/pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dac89aea9af8cd672fa7b510e7b8c33b0bba9a43186680550ccf23020f32d535", size = 2068498, upload-time = "2025-04-23T18:33:38.997Z" }, { url = "https://files.pythonhosted.org/packages/d8/62/d490198d05d2d86672dc269f52579cad7261ced64c2df213d5c16e0aecb1/pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:970919794d126ba8645f3837ab6046fb4e72bbc057b3709144066204c19a455d", size = 2108428, upload-time = "2025-04-23T18:33:41.18Z" }, { url = "https://files.pythonhosted.org/packages/9a/ec/4cd215534fd10b8549015f12ea650a1a973da20ce46430b68fc3185573e8/pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:3eb3fe62804e8f859c49ed20a8451342de53ed764150cb14ca71357c765dc2a6", size = 2069854, upload-time = "2025-04-23T18:33:43.446Z" }, { url = "https://files.pythonhosted.org/packages/1a/1a/abbd63d47e1d9b0d632fee6bb15785d0889c8a6e0a6c3b5a8e28ac1ec5d2/pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:3abcd9392a36025e3bd55f9bd38d908bd17962cc49bc6da8e7e96285336e2bca", size = 2237859, upload-time = "2025-04-23T18:33:45.56Z" }, { url = "https://files.pythonhosted.org/packages/80/1c/fa883643429908b1c90598fd2642af8839efd1d835b65af1f75fba4d94fe/pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:3a1c81334778f9e3af2f8aeb7a960736e5cab1dfebfb26aabca09afd2906c039", size = 2239059, upload-time = "2025-04-23T18:33:47.735Z" }, { url = "https://files.pythonhosted.org/packages/d4/29/3cade8a924a61f60ccfa10842f75eb12787e1440e2b8660ceffeb26685e7/pydantic_core-2.33.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2807668ba86cb38c6817ad9bc66215ab8584d1d304030ce4f0887336f28a5e27", size = 2066661, upload-time = "2025-04-23T18:33:49.995Z" }, ] [[package]] name = "pydantic-extra-types" source = { editable = "." } dependencies = [ { name = "pydantic", version = "2.10.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9'" }, { name = "pydantic", version = "2.11.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9'" }, { name = "typing-extensions" }, ] [package.optional-dependencies] all = [ { name = "pendulum", version = "3.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9'" }, { name = "pendulum", version = "3.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9'" }, { name = "phonenumbers" }, { name = "pycountry" }, { name = "pymongo", version = "4.10.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9'" }, { name = "pymongo", version = "4.13.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9'" }, { name = "python-ulid", version = "1.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9'" }, { name = "python-ulid", version = "3.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9'" }, { name = "pytz" }, { name = "semver" }, { name = "tzdata" }, ] pendulum = [ { name = "pendulum", version = "3.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9'" }, { name = "pendulum", version = "3.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9'" }, ] phonenumbers = [ { name = "phonenumbers" }, ] pycountry = [ { name = "pycountry" }, ] python-ulid = [ { name = "python-ulid", version = "1.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9'" }, { name = "python-ulid", version = "3.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9'" }, ] semver = [ { name = "semver" }, ] [package.dev-dependencies] dev = [ { name = "coverage", version = "7.6.1", source = { registry = "https://pypi.org/simple" }, extra = ["toml"], marker = "python_full_version < '3.9'" }, { name = "coverage", version = "7.8.0", source = { registry = "https://pypi.org/simple" }, extra = ["toml"], marker = "python_full_version >= '3.9'" }, { name = "dirty-equals" }, { name = "pytest" }, { name = "pytest-pretty" }, ] extra = [ { name = "annotated-types" }, { name = "coverage", version = "7.6.1", source = { registry = "https://pypi.org/simple" }, extra = ["toml"], marker = "python_full_version < '3.9'" }, { name = "coverage", version = "7.8.0", source = { registry = "https://pypi.org/simple" }, extra = ["toml"], marker = "python_full_version >= '3.9'" }, { name = "dirty-equals" }, { name = "mypy", version = "1.14.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9'" }, { name = "mypy", version = "1.15.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9'" }, { name = "pytest" }, { name = "pytest-pretty" }, { name = "ruff" }, { name = "types-pytz", version = "2024.2.0.20241221", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9'" }, { name = "types-pytz", version = "2025.2.0.20250326", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9'" }, ] lint = [ { name = "annotated-types" }, { name = "mypy", version = "1.14.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9'" }, { name = "mypy", version = "1.15.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9'" }, { name = "ruff" }, { name = "types-pytz", version = "2024.2.0.20241221", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9'" }, { name = "types-pytz", version = "2025.2.0.20250326", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9'" }, ] [package.metadata] requires-dist = [ { name = "pendulum", marker = "extra == 'all'", specifier = ">=3.0.0,<4.0.0" }, { name = "pendulum", marker = "extra == 'pendulum'", specifier = ">=3.0.0,<4.0.0" }, { name = "phonenumbers", marker = "extra == 'all'", specifier = ">=8,<10" }, { name = "phonenumbers", marker = "extra == 'phonenumbers'", specifier = ">=8,<10" }, { name = "pycountry", marker = "extra == 'all'", specifier = ">=23" }, { name = "pycountry", marker = "extra == 'pycountry'", specifier = ">=23" }, { name = "pydantic", specifier = ">=2.5.2" }, { name = "pymongo", marker = "extra == 'all'", specifier = ">=4.0.0,<5.0.0" }, { name = "python-ulid", marker = "python_full_version >= '3.9' and extra == 'all'", specifier = ">=1,<4" }, { name = "python-ulid", marker = "python_full_version >= '3.9' and extra == 'python-ulid'", specifier = ">=1,<4" }, { name = "python-ulid", marker = "python_full_version < '3.9' and extra == 'all'", specifier = ">=1,<2" }, { name = "python-ulid", marker = "python_full_version < '3.9' and extra == 'python-ulid'", specifier = ">=1,<2" }, { name = "pytz", marker = "extra == 'all'", specifier = ">=2024.1" }, { name = "semver", marker = "extra == 'all'", specifier = "~=3.0.2" }, { name = "semver", marker = "extra == 'all'", specifier = ">=3.0.2" }, { name = "semver", marker = "extra == 'semver'", specifier = ">=3.0.2" }, { name = "typing-extensions" }, { name = "tzdata", marker = "extra == 'all'", specifier = ">=2024.1" }, ] provides-extras = ["all", "pendulum", "phonenumbers", "pycountry", "python-ulid", "semver"] [package.metadata.requires-dev] dev = [ { name = "coverage", extras = ["toml"], specifier = ">=7.6.1" }, { name = "dirty-equals", specifier = ">=0.7.1" }, { name = "pytest", specifier = ">=8.3.2" }, { name = "pytest-pretty", specifier = ">=1.2.0" }, ] extra = [ { name = "annotated-types", specifier = ">=0.7.0" }, { name = "coverage", extras = ["toml"], specifier = ">=7.6.1" }, { name = "dirty-equals", specifier = ">=0.7.1" }, { name = "mypy", specifier = ">=0.910" }, { name = "pytest", specifier = ">=8.3.2" }, { name = "pytest-pretty", specifier = ">=1.2.0" }, { name = "ruff", specifier = ">=0.7.4" }, { name = "types-pytz", specifier = ">=2024.1.0.20240417" }, ] lint = [ { name = "annotated-types", specifier = ">=0.7.0" }, { name = "mypy", specifier = ">=0.910" }, { name = "ruff", specifier = ">=0.7.4" }, { name = "types-pytz", specifier = ">=2024.1.0.20240417" }, ] [[package]] name = "pygments" version = "2.19.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/7c/2d/c3338d48ea6cc0feb8446d8e6937e1408088a72a39937982cc6111d17f84/pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", size = 4968581, upload-time = "2025-01-06T17:26:30.443Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c", size = 1225293, upload-time = "2025-01-06T17:26:25.553Z" }, ] [[package]] name = "pymongo" version = "4.10.1" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version < '3.9'", ] dependencies = [ { name = "dnspython", version = "2.6.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/1a/35/b62a3139f908c68b69aac6a6a3f8cc146869de0a7929b994600e2c587c77/pymongo-4.10.1.tar.gz", hash = "sha256:a9de02be53b6bb98efe0b9eda84ffa1ec027fcb23a2de62c4f941d9a2f2f3330", size = 1903902, upload-time = "2024-10-01T23:07:58.525Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/c1/ca/f56b1dd84541de658d246f86828be27e32285f2151fab97efbce1db3ed57/pymongo-4.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e699aa68c4a7dea2ab5a27067f7d3e08555f8d2c0dc6a0c8c60cfd9ff2e6a4b1", size = 835459, upload-time = "2024-10-01T23:06:19.654Z" }, { url = "https://files.pythonhosted.org/packages/97/01/fe4ee34b33c6863be6a09d1e805ceb1122d9cd5d4a5d1664e360b91adf7e/pymongo-4.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:70645abc714f06b4ad6b72d5bf73792eaad14e3a2cfe29c62a9c81ada69d9e4b", size = 835716, upload-time = "2024-10-01T23:06:22.252Z" }, { url = "https://files.pythonhosted.org/packages/46/ff/9eb21c1d5861729ae1c91669b02f5bfbd23221ba9809fb97fade761f3f3b/pymongo-4.10.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ae2fd94c9fe048c94838badcc6e992d033cb9473eb31e5710b3707cba5e8aee2", size = 1407173, upload-time = "2024-10-01T23:06:24.204Z" }, { url = "https://files.pythonhosted.org/packages/e5/d9/8cf042449d6804e00e38d3bb138b0e9acb8a8e0c9dd9dd989ffffd481c3b/pymongo-4.10.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ded27a4a5374dae03a92e084a60cdbcecd595306555bda553b833baf3fc4868", size = 1456455, upload-time = "2024-10-01T23:06:26.125Z" }, { url = "https://files.pythonhosted.org/packages/37/9a/da0d121f98c1413853e1172e2095fe77c1629c83a1db107d45a37ca935c2/pymongo-4.10.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1ecc2455e3974a6c429687b395a0bc59636f2d6aedf5785098cf4e1f180f1c71", size = 1433360, upload-time = "2024-10-01T23:06:27.898Z" }, { url = "https://files.pythonhosted.org/packages/7d/6d/50480f0452e2fb59256d9d641d192366c0079920c36851b818ebeff0cec9/pymongo-4.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a920fee41f7d0259f5f72c1f1eb331bc26ffbdc952846f9bd8c3b119013bb52c", size = 1410758, upload-time = "2024-10-01T23:06:29.546Z" }, { url = "https://files.pythonhosted.org/packages/cd/8f/b83b9910c54f63bfff34305074e79cd08cf5e12dda22d1a2b4ad009b32b3/pymongo-4.10.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e0a15665b2d6cf364f4cd114d62452ce01d71abfbd9c564ba8c74dcd7bbd6822", size = 1380257, upload-time = "2024-10-01T23:06:30.895Z" }, { url = "https://files.pythonhosted.org/packages/ed/e3/8f381b576e5f912cf0fe34218c6b0ef23d7afdef13fed592900fb52f0ed4/pymongo-4.10.1-cp310-cp310-win32.whl", hash = "sha256:29e1c323c28a4584b7095378ff046815e39ff82cdb8dc4cc6dfe3acf6f9ad1f8", size = 812324, upload-time = "2024-10-01T23:06:32.717Z" }, { url = "https://files.pythonhosted.org/packages/ab/14/1cae5359e2c4677856527a2965c999c23f596cced4b7828d880cb8fc0f54/pymongo-4.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:88dc4aa45f8744ccfb45164aedb9a4179c93567bbd98a33109d7dc400b00eb08", size = 826774, upload-time = "2024-10-01T23:06:34.386Z" }, { url = "https://files.pythonhosted.org/packages/e4/a3/d6403ec53fa2fe922b4a5c86388ea5fada01dd51d803e17bb2a7c9cda839/pymongo-4.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:57ee6becae534e6d47848c97f6a6dff69e3cce7c70648d6049bd586764febe59", size = 889238, upload-time = "2024-10-01T23:06:36.03Z" }, { url = "https://files.pythonhosted.org/packages/29/a2/9643450424bcf241e80bb713497ec2e3273c183d548b4eca357f75d71885/pymongo-4.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6f437a612f4d4f7aca1812311b1e84477145e950fdafe3285b687ab8c52541f3", size = 889504, upload-time = "2024-10-01T23:06:37.328Z" }, { url = "https://files.pythonhosted.org/packages/ec/40/4759984f34415509e9111be8ee863034611affdc1e0b41016c9d53b2f1b3/pymongo-4.10.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a970fd3117ab40a4001c3dad333bbf3c43687d90f35287a6237149b5ccae61d", size = 1649069, upload-time = "2024-10-01T23:06:38.553Z" }, { url = "https://files.pythonhosted.org/packages/56/0f/b6e917478a3ada81e768475516cd544982cc42cbb7d3be325182768139e1/pymongo-4.10.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7c4d0e7cd08ef9f8fbf2d15ba281ed55604368a32752e476250724c3ce36c72e", size = 1714927, upload-time = "2024-10-01T23:06:40.292Z" }, { url = "https://files.pythonhosted.org/packages/56/c5/4237d94dfa19ebdf9a92b1071e2139c91f48908c5782e592c571c33b67ab/pymongo-4.10.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ca6f700cff6833de4872a4e738f43123db34400173558b558ae079b5535857a4", size = 1683454, upload-time = "2024-10-01T23:06:42.257Z" }, { url = "https://files.pythonhosted.org/packages/9a/16/dbffca9d4ad66f2a325c280f1177912fa23235987f7b9033e283da889b7a/pymongo-4.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cec237c305fcbeef75c0bcbe9d223d1e22a6e3ba1b53b2f0b79d3d29c742b45b", size = 1653840, upload-time = "2024-10-01T23:06:43.991Z" }, { url = "https://files.pythonhosted.org/packages/2b/4d/21df934ef5cf8f0e587bac922a129e13d4c0346c54e9bf2371b90dd31112/pymongo-4.10.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3337804ea0394a06e916add4e5fac1c89902f1b6f33936074a12505cab4ff05", size = 1613233, upload-time = "2024-10-01T23:06:46.113Z" }, { url = "https://files.pythonhosted.org/packages/24/07/dd9c3db30e754680606295d5574521956898005db0629411a89163cc6eee/pymongo-4.10.1-cp311-cp311-win32.whl", hash = "sha256:778ac646ce6ac1e469664062dfe9ae1f5c9961f7790682809f5ec3b8fda29d65", size = 857331, upload-time = "2024-10-01T23:06:47.812Z" }, { url = "https://files.pythonhosted.org/packages/02/68/b71c4106d03eef2482eade440c6f5737c2a4a42f6155726009f80ea38d06/pymongo-4.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:9df4ab5594fdd208dcba81be815fa8a8a5d8dedaf3b346cbf8b61c7296246a7a", size = 876473, upload-time = "2024-10-01T23:06:49.201Z" }, { url = "https://files.pythonhosted.org/packages/10/d1/60ad99fe3f64d45e6c71ac0e3078e88d9b64112b1bae571fc3707344d6d1/pymongo-4.10.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fbedc4617faa0edf423621bb0b3b8707836687161210d470e69a4184be9ca011", size = 943356, upload-time = "2024-10-01T23:06:50.9Z" }, { url = "https://files.pythonhosted.org/packages/ca/9b/21d4c6b4ee9c1fa9691c68dc2a52565e0acb644b9e95148569b4736a4ebd/pymongo-4.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7bd26b2aec8ceeb95a5d948d5cc0f62b0eb6d66f3f4230705c1e3d3d2c04ec76", size = 943142, upload-time = "2024-10-01T23:06:52.146Z" }, { url = "https://files.pythonhosted.org/packages/07/af/691b7454e219a8eb2d1641aecedd607e3a94b93650c2011ad8a8fd74ef9f/pymongo-4.10.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb104c3c2a78d9d85571c8ac90ec4f95bca9b297c6eee5ada71fabf1129e1674", size = 1909129, upload-time = "2024-10-01T23:06:53.551Z" }, { url = "https://files.pythonhosted.org/packages/0c/74/fd75d5ad4181d6e71ce0fca32404fb71b5046ac84d9a1a2f0862262dd032/pymongo-4.10.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4924355245a9c79f77b5cda2db36e0f75ece5faf9f84d16014c0a297f6d66786", size = 1987763, upload-time = "2024-10-01T23:06:55.304Z" }, { url = "https://files.pythonhosted.org/packages/8a/56/6d3d0ef63c6d8cb98c7c653a3a2e617675f77a95f3853851d17a7664876a/pymongo-4.10.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:11280809e5dacaef4971113f0b4ff4696ee94cfdb720019ff4fa4f9635138252", size = 1950821, upload-time = "2024-10-01T23:06:57.541Z" }, { url = "https://files.pythonhosted.org/packages/70/ed/1603fa0c0e51444752c3fa91f16c3a97e6d92eb9fe5e553dae4f18df16f6/pymongo-4.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5d55f2a82e5eb23795f724991cac2bffbb1c0f219c0ba3bf73a835f97f1bb2e", size = 1912247, upload-time = "2024-10-01T23:06:59.023Z" }, { url = "https://files.pythonhosted.org/packages/c1/66/e98b2308971d45667cb8179d4d66deca47336c90663a7e0527589f1038b7/pymongo-4.10.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e974ab16a60be71a8dfad4e5afccf8dd05d41c758060f5d5bda9a758605d9a5d", size = 1862230, upload-time = "2024-10-01T23:07:01.407Z" }, { url = "https://files.pythonhosted.org/packages/6c/80/ba9b7ed212a5f8cf8ad7037ed5bbebc1c587fc09242108f153776e4a338b/pymongo-4.10.1-cp312-cp312-win32.whl", hash = "sha256:544890085d9641f271d4f7a47684450ed4a7344d6b72d5968bfae32203b1bb7c", size = 903045, upload-time = "2024-10-01T23:07:02.973Z" }, { url = "https://files.pythonhosted.org/packages/76/8b/5afce891d78159912c43726fab32641e3f9718f14be40f978c148ea8db48/pymongo-4.10.1-cp312-cp312-win_amd64.whl", hash = "sha256:dcc07b1277e8b4bf4d7382ca133850e323b7ab048b8353af496d050671c7ac52", size = 926686, upload-time = "2024-10-01T23:07:04.403Z" }, { url = "https://files.pythonhosted.org/packages/83/76/df0fd0622a85b652ad0f91ec8a0ebfd0cb86af6caec8999a22a1f7481203/pymongo-4.10.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:90bc6912948dfc8c363f4ead54d54a02a15a7fee6cfafb36dc450fc8962d2cb7", size = 996981, upload-time = "2024-10-01T23:07:06.001Z" }, { url = "https://files.pythonhosted.org/packages/4c/39/fa50531de8d1d8af8c253caeed20c18ccbf1de5d970119c4a42c89f2bd09/pymongo-4.10.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:594dd721b81f301f33e843453638e02d92f63c198358e5a0fa8b8d0b1218dabc", size = 996769, upload-time = "2024-10-01T23:07:07.855Z" }, { url = "https://files.pythonhosted.org/packages/bf/50/6936612c1b2e32d95c30e860552d3bc9e55cfa79a4f73b73225fa05a028c/pymongo-4.10.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0783e0c8e95397c84e9cf8ab092ab1e5dd7c769aec0ef3a5838ae7173b98dea0", size = 2169159, upload-time = "2024-10-01T23:07:09.963Z" }, { url = "https://files.pythonhosted.org/packages/78/8c/45cb23096e66c7b1da62bb8d9c7ac2280e7c1071e13841e7fb71bd44fd9f/pymongo-4.10.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6fb6a72e88df46d1c1040fd32cd2d2c5e58722e5d3e31060a0393f04ad3283de", size = 2260569, upload-time = "2024-10-01T23:07:11.856Z" }, { url = "https://files.pythonhosted.org/packages/29/b6/e5ec697087e527a6a15c5f8daa5bcbd641edb8813487345aaf963d3537dc/pymongo-4.10.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2e3a593333e20c87415420a4fb76c00b7aae49b6361d2e2205b6fece0563bf40", size = 2218142, upload-time = "2024-10-01T23:07:13.61Z" }, { url = "https://files.pythonhosted.org/packages/ad/8a/c0b45bee0f0c57732c5c36da5122c1796efd5a62d585fbc504e2f1401244/pymongo-4.10.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72e2ace7456167c71cfeca7dcb47bd5dceda7db2231265b80fc625c5e8073186", size = 2170623, upload-time = "2024-10-01T23:07:15.319Z" }, { url = "https://files.pythonhosted.org/packages/3b/26/6c0a5360a571df24c9bfbd51b1dae279f4f0c511bdbc0906f6df6d1543fa/pymongo-4.10.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ad05eb9c97e4f589ed9e74a00fcaac0d443ccd14f38d1258eb4c39a35dd722b", size = 2111112, upload-time = "2024-10-01T23:07:16.859Z" }, { url = "https://files.pythonhosted.org/packages/38/bc/5b91b728e1cf505d931f04e24cbac71ae519523785570ed046cdc31e6efc/pymongo-4.10.1-cp313-cp313-win32.whl", hash = "sha256:ee4c86d8e6872a61f7888fc96577b0ea165eb3bdb0d841962b444fa36001e2bb", size = 948727, upload-time = "2024-10-01T23:07:18.275Z" }, { url = "https://files.pythonhosted.org/packages/0d/2a/7c24a6144eaa06d18ed52822ea2b0f119fd9267cd1abbb75dae4d89a3803/pymongo-4.10.1-cp313-cp313-win_amd64.whl", hash = "sha256:45ee87a4e12337353242bc758accc7fb47a2f2d9ecc0382a61e64c8f01e86708", size = 976873, upload-time = "2024-10-01T23:07:19.721Z" }, { url = "https://files.pythonhosted.org/packages/31/22/0580e055aa609ae61c5c054afc746968be771d75d42b6a43f3979fa1c20e/pymongo-4.10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:442ca247f53ad24870a01e80a71cd81b3f2318655fd9d66748ee2bd1b1569d9e", size = 727824, upload-time = "2024-10-01T23:07:21.15Z" }, { url = "https://files.pythonhosted.org/packages/82/9f/62599a11b2371ea176ddc4444fe9cef7bb1b8d8c2ba3ec2fce03a63f6b37/pymongo-4.10.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:23e1d62df5592518204943b507be7b457fb8a4ad95a349440406fd42db5d0923", size = 728136, upload-time = "2024-10-01T23:07:22.995Z" }, { url = "https://files.pythonhosted.org/packages/7f/87/ea553a6b3e2607d409ffcb8958153e84370f1cd54e1f2191b16dcc28b408/pymongo-4.10.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6131bc6568b26e7495a9f3ef2b1700566b76bbecd919f4472bfe90038a61f425", size = 928973, upload-time = "2024-10-01T23:07:24.577Z" }, { url = "https://files.pythonhosted.org/packages/6e/be/f7d3df1415af12200b63b3cfebd2d156ea3215f3ce054bf3f73d81e0be73/pymongo-4.10.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fdeba88c540c9ed0338c0b2062d9f81af42b18d6646b3e6dda05cf6edd46ada9", size = 945186, upload-time = "2024-10-01T23:07:26.005Z" }, { url = "https://files.pythonhosted.org/packages/f6/0c/8b3981432b8d635763aef504475c1f1ec51447889fd13ac30676cecf1229/pymongo-4.10.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15a624d752dd3c89d10deb0ef6431559b6d074703cab90a70bb849ece02adc6b", size = 938573, upload-time = "2024-10-01T23:07:27.486Z" }, { url = "https://files.pythonhosted.org/packages/5f/54/7da021c70dbac3e993aee5544398f6c1ec58d0aaaf6f91de555e4b6a6e29/pymongo-4.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba164e73fdade9b4614a2497321c5b7512ddf749ed508950bdecc28d8d76a2d9", size = 930164, upload-time = "2024-10-01T23:07:29.073Z" }, { url = "https://files.pythonhosted.org/packages/bb/f1/848132a5db3f5fba1928018d53d990f4ba81db9126129f2e5a99d9da8d55/pymongo-4.10.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9235fa319993405ae5505bf1333366388add2e06848db7b3deee8f990b69808e", size = 919676, upload-time = "2024-10-01T23:07:30.841Z" }, { url = "https://files.pythonhosted.org/packages/ad/31/9b5a831f7bd96e932c0b6e234a154896fe0373c19ba32054e959ae258b57/pymongo-4.10.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e4a65567bd17d19f03157c7ec992c6530eafd8191a4e5ede25566792c4fe3fa2", size = 920828, upload-time = "2024-10-01T23:07:32.388Z" }, { url = "https://files.pythonhosted.org/packages/65/5b/d134139e96fa085ebc7545a7bfb335606e7ee3ae403c170a3fe64ba7b854/pymongo-4.10.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:f1945d48fb9b8a87d515da07f37e5b2c35b364a435f534c122e92747881f4a7c", size = 928386, upload-time = "2024-10-01T23:07:33.982Z" }, { url = "https://files.pythonhosted.org/packages/9e/35/b932c0db60508971701ef42c47ab6db3e60497f0821da4f340ecff9eebf0/pymongo-4.10.1-cp38-cp38-win32.whl", hash = "sha256:345f8d340802ebce509f49d5833cc913da40c82f2e0daf9f60149cacc9ca680f", size = 722400, upload-time = "2024-10-01T23:07:35.537Z" }, { url = "https://files.pythonhosted.org/packages/38/52/a58196a45232e9046c8b13f4fa3d89cca0e462b5c6d28969759226f781ee/pymongo-4.10.1-cp38-cp38-win_amd64.whl", hash = "sha256:3a70d5efdc0387ac8cd50f9a5f379648ecfc322d14ec9e1ba8ec957e5d08c372", size = 727386, upload-time = "2024-10-01T23:07:37.295Z" }, { url = "https://files.pythonhosted.org/packages/39/69/a13a61fd9a19e659cb43cb98240a75dab2f8e7b60bee568c309a123f8edc/pymongo-4.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:15b1492cc5c7cd260229590be7218261e81684b8da6d6de2660cf743445500ce", size = 781650, upload-time = "2024-10-01T23:07:39.173Z" }, { url = "https://files.pythonhosted.org/packages/14/13/a5a3da69ee146bac81baacc7b27995849bfbb89eaabfb3d19824c7056fb4/pymongo-4.10.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:95207503c41b97e7ecc7e596d84a61f441b4935f11aa8332828a754e7ada8c82", size = 781929, upload-time = "2024-10-01T23:07:40.666Z" }, { url = "https://files.pythonhosted.org/packages/b0/65/118bc20fc66451ae4b8ceafbd9aab1168bb13cf4e5699b81807bb911a443/pymongo-4.10.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb99f003c720c6d83be02c8f1a7787c22384a8ca9a4181e406174db47a048619", size = 1167200, upload-time = "2024-10-01T23:07:42.37Z" }, { url = "https://files.pythonhosted.org/packages/d1/4a/19c3d45659835f814efef8b250456923899cc7542c52f8beb1a6a164106f/pymongo-4.10.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f2bc1ee4b1ca2c4e7e6b7a5e892126335ec8d9215bcd3ac2fe075870fefc3358", size = 1200021, upload-time = "2024-10-01T23:07:44.061Z" }, { url = "https://files.pythonhosted.org/packages/1c/03/69cee6f23463251a8f6de6670fb665e2531cc0df500d61150e57d1aedf70/pymongo-4.10.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:93a0833c10a967effcd823b4e7445ec491f0bf6da5de0ca33629c0528f42b748", size = 1185518, upload-time = "2024-10-01T23:07:45.613Z" }, { url = "https://files.pythonhosted.org/packages/00/58/01d8b3b374e45931581364752bf7a4693e9c7422704f81e6e91ffa42c38d/pymongo-4.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f56707497323150bd2ed5d63067f4ffce940d0549d4ea2dfae180deec7f9363", size = 1169799, upload-time = "2024-10-01T23:07:47.656Z" }, { url = "https://files.pythonhosted.org/packages/be/6f/9aa0ba2f4cfa4c30c962bd1f5a38b2eb95b23e3965918d211da82ebaacf6/pymongo-4.10.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:409ab7d6c4223e5c85881697f365239dd3ed1b58f28e4124b846d9d488c86880", size = 1149344, upload-time = "2024-10-01T23:07:49.945Z" }, { url = "https://files.pythonhosted.org/packages/fc/af/40f0112605f75f5ae5da554b2f779a83c40ecf2298c57e120e6d7bfcff65/pymongo-4.10.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dac78a650dc0637d610905fd06b5fa6419ae9028cf4d04d6a2657bc18a66bbce", size = 1134277, upload-time = "2024-10-01T23:07:51.544Z" }, { url = "https://files.pythonhosted.org/packages/a1/92/9a4afaf02d4d633c3211b7535e6bfbb2527524ca8ac8039b8d7eb3c765eb/pymongo-4.10.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1ec3fa88b541e0481aff3c35194c9fac96e4d57ec5d1c122376000eb28c01431", size = 1167588, upload-time = "2024-10-01T23:07:53.31Z" }, { url = "https://files.pythonhosted.org/packages/29/de/3c23e7739b0d0dafa4d802e9773011cf54e305c7cb788a52d50c3ef585d2/pymongo-4.10.1-cp39-cp39-win32.whl", hash = "sha256:e0e961923a7b8a1c801c43552dcb8153e45afa41749d9efbd3a6d33f45489f7a", size = 767325, upload-time = "2024-10-01T23:07:54.92Z" }, { url = "https://files.pythonhosted.org/packages/36/d4/49198168f296838c49d732743ae073f9ca9e8f65f15f5209637456892968/pymongo-4.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:dabe8bf1ad644e6b93f3acf90ff18536d94538ca4d27e583c6db49889e98e48f", size = 777078, upload-time = "2024-10-01T23:07:56.542Z" }, ] [[package]] name = "pymongo" version = "4.13.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.9'", ] dependencies = [ { name = "dnspython", version = "2.7.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/74/0c/1fb60383ab4b20566407b87f1a95b7f5cda83e8d5594da6fc84e2a543405/pymongo-4.13.0.tar.gz", hash = "sha256:92a06e3709e3c7e50820d352d3d4e60015406bcba69808937dac2a6d22226fde", size = 2166443, upload-time = "2025-05-14T19:11:08.649Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/4f/82/b19f8f3d1b78e432e1e2a6a2da4dd7bbf5535bce704c69ab14ea598e1af5/pymongo-4.13.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:fe497c885b08600a022646f00f4d3303697c5289990acec250e2be2e1699ca23", size = 802525, upload-time = "2025-05-14T19:09:19.767Z" }, { url = "https://files.pythonhosted.org/packages/f7/d6/1a95ce6af3eb8398d8cadaf9b1429acb1c51ad62c7ec1be77606649f7543/pymongo-4.13.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2d377bb0811e0a9676bacb21a4f87ef307f2e9a40a625660c113a9c0ae897e8c", size = 802817, upload-time = "2025-05-14T19:09:21.573Z" }, { url = "https://files.pythonhosted.org/packages/d0/bb/4b2f2013127ff36b6f7f567f714f3d4452dce4559abe236ea98d0626e9e6/pymongo-4.13.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bac84ee40032bec4c089e92970893157fcd0ef40b81157404ceb4c1dac8ba72", size = 1180183, upload-time = "2025-05-14T19:09:23.63Z" }, { url = "https://files.pythonhosted.org/packages/b9/32/f15f0b509797307905deadc7227aa83d824f4a2b419461534e8c25ef0149/pymongo-4.13.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ea47a64ed9918be0fa8a4a11146a80f546c09e0d65fd08e90a5c00366a59bdb0", size = 1214410, upload-time = "2025-05-14T19:09:25.63Z" }, { url = "https://files.pythonhosted.org/packages/7e/07/45a34e640cb863ddc514ee06845ea2c33312750eba6bbd6e5ab763eabf46/pymongo-4.13.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8e90195cb5aee24a67a29adde54c1dae4d9744e17e4585bea3a83bfff96db46c", size = 1197340, upload-time = "2025-05-14T19:09:27.667Z" }, { url = "https://files.pythonhosted.org/packages/70/59/ccab966891d536ff3efa36a111d424850efc96364412a117fda2acca9d17/pymongo-4.13.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4a7855933011026898ea0d4532fbd83cef63a76205c823a4ef5557d970df1f1", size = 1183356, upload-time = "2025-05-14T19:09:29.218Z" }, { url = "https://files.pythonhosted.org/packages/3c/c7/fe84905f49cca6500dab25554f914dfb0ef95e77faa0cd87e4c5e1a81cbb/pymongo-4.13.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f39791a88cd5ec1760f65e878af419747c6f94ce74f9293735cbba6025ff4d0d", size = 1162513, upload-time = "2025-05-14T19:09:31.738Z" }, { url = "https://files.pythonhosted.org/packages/87/aa/2752c1cdf67812703812199d4bbad2632ed801aa4736ebada43947dbf3ae/pymongo-4.13.0-cp310-cp310-win32.whl", hash = "sha256:209efd3b62cdbebd3cc7a76d5e37414ad08c9bfe8b28ae73695ade065d5b1277", size = 788539, upload-time = "2025-05-14T19:09:33.823Z" }, { url = "https://files.pythonhosted.org/packages/6b/ab/cc9ff174b4e60c02482685cdf7b76cfbe47640a46e2c026b987d8baded4f/pymongo-4.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:51081910a91e3451db74b7265ee290c72220412aa8897d6dfe28f6e5d80b685b", size = 797871, upload-time = "2025-05-14T19:09:35.3Z" }, { url = "https://files.pythonhosted.org/packages/27/21/422381c97454a56021c50f776847c1db6082f84a0944dda3823ef76b4860/pymongo-4.13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:46c8bce9af98556110a950939f3eaa3f7648308d60df65feb783c780f8b9bfa9", size = 856909, upload-time = "2025-05-14T19:09:37.257Z" }, { url = "https://files.pythonhosted.org/packages/c3/e6/b34ab65ad524bc34dc3aa634d3dc411f65c495842ebb25b2d8593fc4bbed/pymongo-4.13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dc9e412911f210d9b0eca42d25c22d3725809dda03dedbaf6f9ffa192d461905", size = 857202, upload-time = "2025-05-14T19:09:38.862Z" }, { url = "https://files.pythonhosted.org/packages/ff/62/17d3f8ff1d2ff67d3ed2985fdf616520362cfe4ae3802df0e9601d5686c9/pymongo-4.13.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9288188101506a9d1aa3f70f65b7f5f499f8f7d5c23ec86a47551d756e32059", size = 1426272, upload-time = "2025-05-14T19:09:41.103Z" }, { url = "https://files.pythonhosted.org/packages/51/e2/22582d886d5a382fb605b3025047d75ec38f497cddefe86e29fca39c4363/pymongo-4.13.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5303e2074b85234e337ebe622d353ce38a35696cd47a7d970f84b545288aee01", size = 1477235, upload-time = "2025-05-14T19:09:43.099Z" }, { url = "https://files.pythonhosted.org/packages/bd/e3/10bce21b8c0bf954c144638619099012a3e247c7d009df044f450fbaf340/pymongo-4.13.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d842e11eb94f7074314ff1d97a05790539a1d74c3048ce50ea9f0da1f4f96b0a", size = 1451677, upload-time = "2025-05-14T19:09:45.417Z" }, { url = "https://files.pythonhosted.org/packages/30/10/4c54a4adf90a04e6147260e16f9cfeab11cb661d71ddd12a98449a279977/pymongo-4.13.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b63d9d8be87f4be11972c5a63d815974c298ada59a2e1d56ef5b6984d81c544a", size = 1430799, upload-time = "2025-05-14T19:09:47.516Z" }, { url = "https://files.pythonhosted.org/packages/86/52/99620c5e106663a3679541b2316e0631b39cb49a6be14291597b28a8b428/pymongo-4.13.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7d740560710be0c514bc9d26f5dcbb3c85dbb6b450c4c3246d8136ca84055bd", size = 1399450, upload-time = "2025-05-14T19:09:49.095Z" }, { url = "https://files.pythonhosted.org/packages/f1/23/73d0379e46f98eed5339b6d44527e366b553c39327c69ba543f7beafb237/pymongo-4.13.0-cp311-cp311-win32.whl", hash = "sha256:936f7be9ed6919e3be7369b858d1c58ebaa4f3ef231cf4860779b8ba3b4fcd11", size = 834134, upload-time = "2025-05-14T19:09:50.682Z" }, { url = "https://files.pythonhosted.org/packages/45/bd/d6286b923e852dc080330182a8b57023555870d875b7523454ad1bdd1579/pymongo-4.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:6a8f060f8ad139d1d45f75ef7aa0084bd7f714fc666f98ef00009efc7db34acd", size = 848068, upload-time = "2025-05-14T19:09:52.778Z" }, { url = "https://files.pythonhosted.org/packages/42/5e/db6871892ec41860339e94e20fabce664b64c193636dc69b572503382f12/pymongo-4.13.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:007450b8c8d17b4e5b779ab6e1938983309eac26b5b8f0863c48effa4b151b07", size = 911769, upload-time = "2025-05-14T19:09:54.483Z" }, { url = "https://files.pythonhosted.org/packages/86/8b/6960dc8baf2b6e1b809513160913e90234160c5df2dc1f2baf1cf1d25ac9/pymongo-4.13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:899a5ea9cd32b1b0880015fdceaa36a41140a8c2ce8621626c52f7023724aed6", size = 911464, upload-time = "2025-05-14T19:09:56.253Z" }, { url = "https://files.pythonhosted.org/packages/41/fb/d682bf1c4cb656f47616796f707a1316862f71b3c1899cb6b6806803dff6/pymongo-4.13.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0b26cd4e090161927b7a81741a3627a41b74265dfb41c6957bfb474504b4b42", size = 1690111, upload-time = "2025-05-14T19:09:58.331Z" }, { url = "https://files.pythonhosted.org/packages/03/d4/0047767ee5b6c66e4b5b67a5d85de14da9910ee8f7d8159e7c1d5d627358/pymongo-4.13.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b54e19e0f6c8a7ad0c5074a8cbefb29c12267c784ceb9a1577a62bbc43150161", size = 1754348, upload-time = "2025-05-14T19:10:00.088Z" }, { url = "https://files.pythonhosted.org/packages/7c/ea/e64f2501eaca552b0f303c2eb828c69963c8bf1a663111686a900502792d/pymongo-4.13.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6208b83e7d566935218c0837f3b74c7d2dda83804d5d843ce21a55f22255ab74", size = 1723390, upload-time = "2025-05-14T19:10:02.28Z" }, { url = "https://files.pythonhosted.org/packages/d1/5c/fad80bc263281c8b819ce29ed1d88c2023c5576ecc608d15ca1628078e29/pymongo-4.13.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f33b8c1405d05517dce06756f2800b37dd098216cae5903cd80ad4f0a9dad08", size = 1693367, upload-time = "2025-05-14T19:10:04.405Z" }, { url = "https://files.pythonhosted.org/packages/c1/3d/4ff09614c996f8574d36008763b9fc01532ec7e954b5edde9254455b279b/pymongo-4.13.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02f0e1af87280697a1a8304238b863d4eee98c8b97f554ee456c3041c0f3a021", size = 1652496, upload-time = "2025-05-14T19:10:06.528Z" }, { url = "https://files.pythonhosted.org/packages/f2/2f/c4e54ac337e0ad3d91aae7de59849aaed28de6340112da2e2427f5e0c689/pymongo-4.13.0-cp312-cp312-win32.whl", hash = "sha256:5dea2f6b44697eda38a11ef754d2adfff5373c51b1ffda00b9fedc5facbd605f", size = 880497, upload-time = "2025-05-14T19:10:08.626Z" }, { url = "https://files.pythonhosted.org/packages/6a/43/6595a52fe144bb0dae4d592e49c6c909f98033c4fa2eaa544b13e22ac6e8/pymongo-4.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:c03e02129ad202d8e146480b398c4a3ea18266ee0754b6a4805de6baf4a6a8c7", size = 898742, upload-time = "2025-05-14T19:10:10.214Z" }, { url = "https://files.pythonhosted.org/packages/5a/dc/9afa6091bce4adad7cad736dcdc35c139a9b551fc61032ef20c7ba17eae5/pymongo-4.13.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:92f5e75ae265e798be1a8a40a29e2ab934e156f3827ca0e1c47e69d43f4dcb31", size = 965996, upload-time = "2025-05-14T19:10:12.319Z" }, { url = "https://files.pythonhosted.org/packages/36/69/e4242abffc0ee1501bb426d8a540e712e4f917491735f18622838b17f5a1/pymongo-4.13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3d631d879e934b46222f5092d8951cbb9fe83542649697c8d342ea7b5479f118", size = 965702, upload-time = "2025-05-14T19:10:14.051Z" }, { url = "https://files.pythonhosted.org/packages/fc/3e/0732876b48b1285bada803f4b0d7da5b720cf8f778d2117bbed9e04473a3/pymongo-4.13.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be048fb78e165243272a8cdbeb40d53eace82424b95417ab3ab6ec8e9b00c59b", size = 1953825, upload-time = "2025-05-14T19:10:16.214Z" }, { url = "https://files.pythonhosted.org/packages/dc/3b/6713fed92cab64508a1fb8359397c0720202e5f36d7faf4ed71b05875180/pymongo-4.13.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d81d159bd23d8ac53a6e819cccee991cb9350ab2541dfaa25aeb2f712d23b0a5", size = 2031179, upload-time = "2025-05-14T19:10:18.307Z" }, { url = "https://files.pythonhosted.org/packages/89/2b/1aad904563c312a0dc2ff752acf0f11194f836304d6e15d05dff3a33df08/pymongo-4.13.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8af08ba2886f08d334bc7e5d5c662c60ea2f16e813a2c35106f399463fa11087", size = 1995093, upload-time = "2025-05-14T19:10:20.089Z" }, { url = "https://files.pythonhosted.org/packages/4c/cc/33786f4ce9a46c776f0d32601b353f8c42b552ea9ff8060c290c912b661e/pymongo-4.13.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b91f59137e46cd3ff17d5684a18e8006d65d0ee62eb1068b512262d1c2c5ae8", size = 1955820, upload-time = "2025-05-14T19:10:21.788Z" }, { url = "https://files.pythonhosted.org/packages/2d/dd/9a2a87bd4aab12a2281ac20d179912eed824cc6f67df49edd87fa4879b3e/pymongo-4.13.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:61733c8f1ded90ab671a08033ee99b837073c73e505b3b3b633a55a0326e77f4", size = 1905394, upload-time = "2025-05-14T19:10:23.684Z" }, { url = "https://files.pythonhosted.org/packages/04/be/0a70db5e4c4e1c162207e31eaa3debf98476e0265b154f6d2252f85969b0/pymongo-4.13.0-cp313-cp313-win32.whl", hash = "sha256:d10d3967e87c21869f084af5716d02626a17f6f9ccc9379fcbece5821c2a9fb4", size = 926840, upload-time = "2025-05-14T19:10:25.505Z" }, { url = "https://files.pythonhosted.org/packages/dd/a6/fb104175a7f15dd69691c8c32bd4b99c4338ec89fe094b6895c940cf2afb/pymongo-4.13.0-cp313-cp313-win_amd64.whl", hash = "sha256:a9fe172e93551ddfdb94b9ad34dccebc4b7b680dc1d131bc6bd661c4a5b2945c", size = 949383, upload-time = "2025-05-14T19:10:27.234Z" }, { url = "https://files.pythonhosted.org/packages/62/3f/c89a6121b0143fde431f04c267a0d49159b499f518630a43aa6288709749/pymongo-4.13.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:5adc1349fd5c94d5dfbcbd1ad9858d1df61945a07f5905dcf17bb62eb4c81f93", size = 1022500, upload-time = "2025-05-14T19:10:29.002Z" }, { url = "https://files.pythonhosted.org/packages/4b/89/8fc36b83768b44805dd3a1caf755f019b110d2111671950b39c8c7781cd9/pymongo-4.13.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:8e11ea726ff8ddc8c8393895cd7e93a57e2558c27273d3712797895c53d25692", size = 1022503, upload-time = "2025-05-14T19:10:30.757Z" }, { url = "https://files.pythonhosted.org/packages/67/dc/f216cf6218f8ceb4025fd10e3de486553bd5373c3b71a45fef3483b745bb/pymongo-4.13.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c02160ab3a67eca393a2a2bb83dccddf4db2196d0d7c6a980a55157e4bdadc06", size = 2282184, upload-time = "2025-05-14T19:10:32.699Z" }, { url = "https://files.pythonhosted.org/packages/56/32/08a9045dbcd76a25d36a0bd42c635b56d9aed47126bcca0e630a63e08444/pymongo-4.13.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fca24e4df05501420b2ce2207c03f21fcbdfac1e3f41e312e61b8f416c5b4963", size = 2369224, upload-time = "2025-05-14T19:10:34.942Z" }, { url = "https://files.pythonhosted.org/packages/16/63/7991853fa6cf5e52222f8f480081840fb452d78c1dcd6803cabe2d3557a6/pymongo-4.13.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:50c503b7e809e54740704ec4c87a0f2ccdb910c3b1d36c07dbd2029b6eaa6a50", size = 2328611, upload-time = "2025-05-14T19:10:36.791Z" }, { url = "https://files.pythonhosted.org/packages/e9/0f/11beecc8d48c7549db3f13f2101fd1c06ccb668697d33a6a5a05bb955574/pymongo-4.13.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66800de4f4487e7c437991b44bc1e717aadaf06e67451a760efe5cd81ce86575", size = 2279806, upload-time = "2025-05-14T19:10:38.652Z" }, { url = "https://files.pythonhosted.org/packages/17/a7/0358efc8dba796545e9bd4642d1337a9b67b60928c583799fb0726594855/pymongo-4.13.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82c36928c1c26580ce4f2497a6875968636e87c77108ff253d76b1355181a405", size = 2219131, upload-time = "2025-05-14T19:10:40.444Z" }, { url = "https://files.pythonhosted.org/packages/58/d5/373cd1cd21eff769e22e4e0924dcbfd770dfa1298566d51a7097857267fc/pymongo-4.13.0-cp313-cp313t-win32.whl", hash = "sha256:1397eac713b84946210ab556666cfdd787eee824e910fbbe661d147e110ec516", size = 975711, upload-time = "2025-05-14T19:10:42.213Z" }, { url = "https://files.pythonhosted.org/packages/b0/39/1e204091bdf264a0d9eccc21f7da099903a7a30045f055a91178686c0259/pymongo-4.13.0-cp313-cp313t-win_amd64.whl", hash = "sha256:99a52cfbf31579cc63c926048cd0ada6f96c98c1c4c211356193e07418e6207c", size = 1004287, upload-time = "2025-05-14T19:10:45.468Z" }, { url = "https://files.pythonhosted.org/packages/84/e2/6b2bced59dba2e9108263821f6141d7742e8e9ef84c1e1b15dff6ee223bc/pymongo-4.13.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:267eff6a66da5cf5255b3bcd257984619e9c4d41a53578d4e1d827553a51cf40", size = 748144, upload-time = "2025-05-14T19:10:47.223Z" }, { url = "https://files.pythonhosted.org/packages/84/a8/90aa028f3d2b8f498fac1768257d9493c7a986b936fe3d5b9dfd1616b9e0/pymongo-4.13.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:81b46d9bc62128c3d968336f8635bcfce33d8e9e1fc6be6ebdfb98effaccb9c7", size = 748431, upload-time = "2025-05-14T19:10:48.947Z" }, { url = "https://files.pythonhosted.org/packages/92/dc/a643356995ac036f86f35e0e43cb1412e4f5b3128ae2398b208a9e8ef108/pymongo-4.13.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd0c9322fdf1b9e8a5c99ca337bd9a99d972ba57c976e77b5017366ba26725e1", size = 936094, upload-time = "2025-05-14T19:10:50.853Z" }, { url = "https://files.pythonhosted.org/packages/7e/27/96e5dcfac38a9ebadb9c3b740f6660e6ed9372ccb5b62ab5efda35aeb299/pymongo-4.13.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d4b4942e5566a134fe34c03d7182a0b346e4a478defe625dc430dd5a178ad96e", size = 953437, upload-time = "2025-05-14T19:10:52.689Z" }, { url = "https://files.pythonhosted.org/packages/f9/c5/a576862c4355cf350b8a66f0a079ed5858d52e123b93e71a9ec5f52f2ab5/pymongo-4.13.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cef461fae88ac51cd6b3f81adf58171113c58c0e77c82c751b3bdcef516cfeb1", size = 945102, upload-time = "2025-05-14T19:10:54.641Z" }, { url = "https://files.pythonhosted.org/packages/77/11/e7a104523f40739809560675cfdd753a8524c53aeb9583c2a20481e7f068/pymongo-4.13.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb780d9d284ffdf7922edd4a6d7ba08e54a6680f85f64f91fa9cc2617dd488b7", size = 937994, upload-time = "2025-05-14T19:10:56.438Z" }, { url = "https://files.pythonhosted.org/packages/c0/e6/6d23ee9aebccd85878f1f2851cf89e9c4090dd544dd2bb2fbc93d1131105/pymongo-4.13.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b2afe49109b4d498d8e55ac9692915f2a3fce0bd31646bb7ed41f9ab3546ca19", size = 927655, upload-time = "2025-05-14T19:10:58.755Z" }, { url = "https://files.pythonhosted.org/packages/42/b4/9a33412c98774f9c79157acffe50786a9aa4781dca5b70b779eaa3d75cc5/pymongo-4.13.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d9a1d7d49d0d364520894116133d017b6e0e2d5131eb31c8553552fa77a65085", size = 910905, upload-time = "2025-05-14T19:11:00.593Z" }, { url = "https://files.pythonhosted.org/packages/ac/45/0bc5ebe2e573d5945f15806b95bda4f1e816b64a7b9feefb555c342c10db/pymongo-4.13.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:d684d9b385d97ab821d2ae74628c81a8bd12a4e5004a3ded0ec8c20381d62d0e", size = 937307, upload-time = "2025-05-14T19:11:02.636Z" }, { url = "https://files.pythonhosted.org/packages/5a/2c/7bbbb4c8aa758f2c86005146f5ebd0c5ffeaf420f6f7f21e526c03efd4d1/pymongo-4.13.0-cp39-cp39-win32.whl", hash = "sha256:bd23119f9d0358aa1f78174d2eda88ca5c882a722e25ca31197402278acddc6e", size = 742944, upload-time = "2025-05-14T19:11:04.46Z" }, { url = "https://files.pythonhosted.org/packages/81/d3/372eecea4ac8629a215e9f2e387d6d73e4a7698a4fcfaeb478f843c217fb/pymongo-4.13.0-cp39-cp39-win_amd64.whl", hash = "sha256:e7d349066f4c229d638a30f1f53ec3a4aaf4a4fc568491bdf77e7415a96003fb", size = 747675, upload-time = "2025-05-14T19:11:06.839Z" }, ] [[package]] name = "pytest" version = "8.3.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, { name = "iniconfig" }, { name = "packaging" }, { name = "pluggy" }, { name = "tomli", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ae/3c/c9d525a414d506893f0cd8a8d0de7706446213181570cdbd766691164e40/pytest-8.3.5.tar.gz", hash = "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845", size = 1450891, upload-time = "2025-03-02T12:54:54.503Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/30/3d/64ad57c803f1fa1e963a7946b6e0fea4a70df53c1a7fed304586539c2bac/pytest-8.3.5-py3-none-any.whl", hash = "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820", size = 343634, upload-time = "2025-03-02T12:54:52.069Z" }, ] [[package]] name = "pytest-pretty" version = "1.2.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest" }, { name = "rich" }, ] sdist = { url = "https://files.pythonhosted.org/packages/a5/18/30ad0408295f3157f7a4913f0eaa51a0a377ebad0ffa51ff239e833c6c72/pytest_pretty-1.2.0.tar.gz", hash = "sha256:105a355f128e392860ad2c478ae173ff96d2f03044692f9818ff3d49205d3a60", size = 6542, upload-time = "2023-04-05T17:11:50.917Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/bf/fe/d44d391312c1b8abee2af58ee70fabb1c00b6577ac4e0bdf25b70c1caffb/pytest_pretty-1.2.0-py3-none-any.whl", hash = "sha256:6f79122bf53864ae2951b6c9e94d7a06a87ef753476acd4588aeac018f062036", size = 6180, upload-time = "2023-04-05T17:11:49.801Z" }, ] [[package]] name = "python-dateutil" version = "2.9.0.post0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "six" }, ] sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, ] [[package]] name = "python-ulid" version = "1.1.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version < '3.9'", ] sdist = { url = "https://files.pythonhosted.org/packages/e8/8b/0580d8ee0a73a3f3869488856737c429cbaa08b63c3506275f383c4771a8/python-ulid-1.1.0.tar.gz", hash = "sha256:5fb5e4a91db8ca93e8938a613360b3def299b60d41f847279a8c39c9b2e9c65e", size = 19992, upload-time = "2022-03-10T15:11:41.968Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/89/8e/c30b08ee9b8dc9b4a10e782c2a7fd5de55388201ddebfe0f7ab99dfbb349/python_ulid-1.1.0-py3-none-any.whl", hash = "sha256:88c952f6be133dbede19c907d72d26717d2691ec8421512b573144794d891e24", size = 9360, upload-time = "2022-03-10T15:11:40.405Z" }, ] [[package]] name = "python-ulid" version = "3.0.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.9'", ] sdist = { url = "https://files.pythonhosted.org/packages/9a/db/e5e67aeca9c2420cb91f94007f30693cc3628ae9783a565fd33ffb3fbfdd/python_ulid-3.0.0.tar.gz", hash = "sha256:e50296a47dc8209d28629a22fc81ca26c00982c78934bd7766377ba37ea49a9f", size = 28822, upload-time = "2024-10-11T15:31:55.475Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/63/4e/cc2ba2c0df2589f35a4db8473b8c2ba9bbfc4acdec4a94f1c78934d2350f/python_ulid-3.0.0-py3-none-any.whl", hash = "sha256:e4c4942ff50dbd79167ad01ac725ec58f924b4018025ce22c858bfcff99a5e31", size = 11194, upload-time = "2024-10-11T15:31:54.368Z" }, ] [[package]] name = "pytz" version = "2025.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/f8/bf/abbd3cdfb8fbc7fb3d4d38d320f2441b1e7cbe29be4f23797b4a2b5d8aac/pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3", size = 320884, upload-time = "2025-03-25T02:25:00.538Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00", size = 509225, upload-time = "2025-03-25T02:24:58.468Z" }, ] [[package]] name = "rich" version = "14.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markdown-it-py" }, { name = "pygments" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/a1/53/830aa4c3066a8ab0ae9a9955976fb770fe9c6102117c8ec4ab3ea62d89e8/rich-14.0.0.tar.gz", hash = "sha256:82f1bc23a6a21ebca4ae0c45af9bdbc492ed20231dcb63f297d6d1021a9d5725", size = 224078, upload-time = "2025-03-30T14:15:14.23Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/0d/9b/63f4c7ebc259242c89b3acafdb37b41d1185c07ff0011164674e9076b491/rich-14.0.0-py3-none-any.whl", hash = "sha256:1c9491e1951aac09caffd42f448ee3d04e58923ffe14993f6e83068dc395d7e0", size = 243229, upload-time = "2025-03-30T14:15:12.283Z" }, ] [[package]] name = "ruff" version = "0.11.9" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/f5/e7/e55dda1c92cdcf34b677ebef17486669800de01e887b7831a1b8fdf5cb08/ruff-0.11.9.tar.gz", hash = "sha256:ebd58d4f67a00afb3a30bf7d383e52d0e036e6195143c6db7019604a05335517", size = 4132134, upload-time = "2025-05-09T16:19:41.511Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/fb/71/75dfb7194fe6502708e547941d41162574d1f579c4676a8eb645bf1a6842/ruff-0.11.9-py3-none-linux_armv6l.whl", hash = "sha256:a31a1d143a5e6f499d1fb480f8e1e780b4dfdd580f86e05e87b835d22c5c6f8c", size = 10335453, upload-time = "2025-05-09T16:18:58.2Z" }, { url = "https://files.pythonhosted.org/packages/74/fc/ad80c869b1732f53c4232bbf341f33c5075b2c0fb3e488983eb55964076a/ruff-0.11.9-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:66bc18ca783b97186a1f3100e91e492615767ae0a3be584e1266aa9051990722", size = 11072566, upload-time = "2025-05-09T16:19:01.432Z" }, { url = "https://files.pythonhosted.org/packages/87/0d/0ccececef8a0671dae155cbf7a1f90ea2dd1dba61405da60228bbe731d35/ruff-0.11.9-py3-none-macosx_11_0_arm64.whl", hash = "sha256:bd576cd06962825de8aece49f28707662ada6a1ff2db848d1348e12c580acbf1", size = 10435020, upload-time = "2025-05-09T16:19:03.897Z" }, { url = "https://files.pythonhosted.org/packages/52/01/e249e1da6ad722278094e183cbf22379a9bbe5f21a3e46cef24ccab76e22/ruff-0.11.9-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b1d18b4be8182cc6fddf859ce432cc9631556e9f371ada52f3eaefc10d878de", size = 10593935, upload-time = "2025-05-09T16:19:06.455Z" }, { url = "https://files.pythonhosted.org/packages/ed/9a/40cf91f61e3003fe7bd43f1761882740e954506c5a0f9097b1cff861f04c/ruff-0.11.9-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0f3f46f759ac623e94824b1e5a687a0df5cd7f5b00718ff9c24f0a894a683be7", size = 10172971, upload-time = "2025-05-09T16:19:10.261Z" }, { url = "https://files.pythonhosted.org/packages/61/12/d395203de1e8717d7a2071b5a340422726d4736f44daf2290aad1085075f/ruff-0.11.9-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f34847eea11932d97b521450cf3e1d17863cfa5a94f21a056b93fb86f3f3dba2", size = 11748631, upload-time = "2025-05-09T16:19:12.307Z" }, { url = "https://files.pythonhosted.org/packages/66/d6/ef4d5eba77677eab511644c37c55a3bb8dcac1cdeb331123fe342c9a16c9/ruff-0.11.9-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:f33b15e00435773df97cddcd263578aa83af996b913721d86f47f4e0ee0ff271", size = 12409236, upload-time = "2025-05-09T16:19:15.006Z" }, { url = "https://files.pythonhosted.org/packages/c5/8f/5a2c5fc6124dd925a5faf90e1089ee9036462118b619068e5b65f8ea03df/ruff-0.11.9-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7b27613a683b086f2aca8996f63cb3dd7bc49e6eccf590563221f7b43ded3f65", size = 11881436, upload-time = "2025-05-09T16:19:17.063Z" }, { url = "https://files.pythonhosted.org/packages/39/d1/9683f469ae0b99b95ef99a56cfe8c8373c14eba26bd5c622150959ce9f64/ruff-0.11.9-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9e0d88756e63e8302e630cee3ce2ffb77859797cc84a830a24473939e6da3ca6", size = 13982759, upload-time = "2025-05-09T16:19:19.693Z" }, { url = "https://files.pythonhosted.org/packages/4e/0b/c53a664f06e0faab596397867c6320c3816df479e888fe3af63bc3f89699/ruff-0.11.9-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:537c82c9829d7811e3aa680205f94c81a2958a122ac391c0eb60336ace741a70", size = 11541985, upload-time = "2025-05-09T16:19:21.831Z" }, { url = "https://files.pythonhosted.org/packages/23/a0/156c4d7e685f6526a636a60986ee4a3c09c8c4e2a49b9a08c9913f46c139/ruff-0.11.9-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:440ac6a7029f3dee7d46ab7de6f54b19e34c2b090bb4f2480d0a2d635228f381", size = 10465775, upload-time = "2025-05-09T16:19:24.401Z" }, { url = "https://files.pythonhosted.org/packages/43/d5/88b9a6534d9d4952c355e38eabc343df812f168a2c811dbce7d681aeb404/ruff-0.11.9-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:71c539bac63d0788a30227ed4d43b81353c89437d355fdc52e0cda4ce5651787", size = 10170957, upload-time = "2025-05-09T16:19:27.08Z" }, { url = "https://files.pythonhosted.org/packages/f0/b8/2bd533bdaf469dc84b45815ab806784d561fab104d993a54e1852596d581/ruff-0.11.9-py3-none-musllinux_1_2_i686.whl", hash = "sha256:c67117bc82457e4501473c5f5217d49d9222a360794bfb63968e09e70f340abd", size = 11143307, upload-time = "2025-05-09T16:19:29.462Z" }, { url = "https://files.pythonhosted.org/packages/2f/d9/43cfba291788459b9bfd4e09a0479aa94d05ab5021d381a502d61a807ec1/ruff-0.11.9-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e4b78454f97aa454586e8a5557facb40d683e74246c97372af3c2d76901d697b", size = 11603026, upload-time = "2025-05-09T16:19:31.569Z" }, { url = "https://files.pythonhosted.org/packages/22/e6/7ed70048e89b01d728ccc950557a17ecf8df4127b08a56944b9d0bae61bc/ruff-0.11.9-py3-none-win32.whl", hash = "sha256:7fe1bc950e7d7b42caaee2a8a3bc27410547cc032c9558ee2e0f6d3b209e845a", size = 10548627, upload-time = "2025-05-09T16:19:33.657Z" }, { url = "https://files.pythonhosted.org/packages/90/36/1da5d566271682ed10f436f732e5f75f926c17255c9c75cefb77d4bf8f10/ruff-0.11.9-py3-none-win_amd64.whl", hash = "sha256:52edaa4a6d70f8180343a5b7f030c7edd36ad180c9f4d224959c2d689962d964", size = 11634340, upload-time = "2025-05-09T16:19:35.815Z" }, { url = "https://files.pythonhosted.org/packages/40/f7/70aad26e5877c8f7ee5b161c4c9fa0100e63fc4c944dc6d97b9c7e871417/ruff-0.11.9-py3-none-win_arm64.whl", hash = "sha256:bcf42689c22f2e240f496d0c183ef2c6f7b35e809f12c1db58f75d9aa8d630ca", size = 10741080, upload-time = "2025-05-09T16:19:39.605Z" }, ] [[package]] name = "semver" version = "3.0.4" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/72/d1/d3159231aec234a59dd7d601e9dd9fe96f3afff15efd33c1070019b26132/semver-3.0.4.tar.gz", hash = "sha256:afc7d8c584a5ed0a11033af086e8af226a9c0b206f313e0301f8dd7b6b589602", size = 269730, upload-time = "2025-01-24T13:19:27.617Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/a6/24/4d91e05817e92e3a61c8a21e08fd0f390f5301f1c448b137c57c4bc6e543/semver-3.0.4-py3-none-any.whl", hash = "sha256:9c824d87ba7f7ab4a1890799cec8596f15c1241cb473404ea1cb0c55e4b04746", size = 17912, upload-time = "2025-01-24T13:19:24.949Z" }, ] [[package]] name = "six" version = "1.17.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, ] [[package]] name = "time-machine" version = "2.15.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "python-dateutil", marker = "python_full_version < '3.9'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/b2/e8/82d358c4d53555f031c2343d1c235b56b9f3b0a60ac3adc555778fe87506/time_machine-2.15.0.tar.gz", hash = "sha256:ebd2e63baa117ded04b978813fcd1279d3fc6be2149c9cac75c716b6f1db774c", size = 25067, upload-time = "2024-08-06T11:12:18.578Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/67/47/35413db37da55865fdbf60649bcb948cc2559f420ef4e91e77e4e24c71b8/time_machine-2.15.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:892d016789b59950989b2db188dcd46cf16d34e8daf2343e33b679b0c5fd1001", size = 20779, upload-time = "2024-08-06T13:42:39.043Z" }, { url = "https://files.pythonhosted.org/packages/e0/c3/fda6d2336737d0331eb55357db1dc916af14c4fda77c69ad8b3733b003c4/time_machine-2.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4428bdae507996aa3fdeb4727bca09e26306fa64a502e7335207252684516cbf", size = 17040, upload-time = "2024-08-06T13:42:40.273Z" }, { url = "https://files.pythonhosted.org/packages/36/e1/71200f24d668e5183e875a08ba5e557b6107c1b7d57fa6d54ac24ad10234/time_machine-2.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0302568338c8bd333ed0698231dbb781b70ead1a5579b4ac734b9bf88313229f", size = 34811, upload-time = "2024-08-06T13:42:43.632Z" }, { url = "https://files.pythonhosted.org/packages/9e/2f/4b9289ea07978ad5c3469c872c7eeadf5f5b3a1dcebe2fb274c2486fc220/time_machine-2.15.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18fc4740073e67071472c48355775ec6d1b93af5c675524b7de2474e0dcd8741", size = 32820, upload-time = "2024-08-06T13:42:41.347Z" }, { url = "https://files.pythonhosted.org/packages/5f/9e/9f838c91d2248d716281af60dfea4131438c6ad6d7405ebc6e47f8c25c3b/time_machine-2.15.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:768d33b484a35da93731cc99bdc926b539240a78673216cdc6306833d9072350", size = 34635, upload-time = "2024-08-06T13:42:42.427Z" }, { url = "https://files.pythonhosted.org/packages/f3/10/1048b5ba6de55779563f005de5fbfb764727bf9678ad7701cea480b3816c/time_machine-2.15.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:73a8c8160d2a170dadcad5b82fb5ee53236a19cec0996651cf4d21da0a2574d5", size = 34326, upload-time = "2024-08-06T13:42:45.683Z" }, { url = "https://files.pythonhosted.org/packages/13/82/6b4df8e5abf754b0ccceeb59fa32486d28c65f67d4ada37ff8b1e9f52006/time_machine-2.15.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:09fd839a321a92aa8183206c383b9725eaf4e0a28a70e4cb87db292b352eeefb", size = 32639, upload-time = "2024-08-06T13:42:46.902Z" }, { url = "https://files.pythonhosted.org/packages/cf/07/95e380c46136252401d97f613782a10061b3c11b61edaeb78e83aedc1a88/time_machine-2.15.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:838a6d117739f1ae6ecc45ec630fa694f41a85c0d07b1f3b1db2a6cc52c1808b", size = 34021, upload-time = "2024-08-06T13:42:48.294Z" }, { url = "https://files.pythonhosted.org/packages/b6/0c/6595fa82bd70bc7e8065bfc6534e51a27c18978f7c158d6392c979cace2c/time_machine-2.15.0-cp310-cp310-win32.whl", hash = "sha256:d24d2ec74923b49bce7618e3e7762baa6be74e624d9829d5632321de102bf386", size = 19413, upload-time = "2024-08-06T13:42:49.579Z" }, { url = "https://files.pythonhosted.org/packages/2f/3d/cb3c1cecfeb4b6423302ee1b2863617390500f67526f0fc1fb5641db05f6/time_machine-2.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:95c8e7036cf442480d0bf6f5fde371e1eb6dbbf5391d7bdb8db73bd8a732b538", size = 20280, upload-time = "2024-08-06T13:42:52.548Z" }, { url = "https://files.pythonhosted.org/packages/22/aa/96aaac88738369fba43d5cb076bb09290b1a2cbd84210bcc0a9a519c7970/time_machine-2.15.0-cp310-cp310-win_arm64.whl", hash = "sha256:660810cd27a8a94cb5e845e8f28a95e70b01ff0c45466d394c4a0cba5a0ae279", size = 18392, upload-time = "2024-08-06T13:42:53.945Z" }, { url = "https://files.pythonhosted.org/packages/ce/54/829ab196c3306eb4cee95e3c8e7d004e15877b36479de5d2ecc72fc1d3d4/time_machine-2.15.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:674097dd54a0bbd555e7927092c74428c4c07268ad52bca38cfccc3214707e50", size = 20448, upload-time = "2024-08-06T13:42:58.809Z" }, { url = "https://files.pythonhosted.org/packages/e1/48/a06f8c7db768db501a60210a48f3d37b7b3d65ca85aa8dc08147eb204b4a/time_machine-2.15.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4e83fd6112808d1d14d1a57397c6fa3bd71bb2f3b8800036e12366e3680819b9", size = 16897, upload-time = "2024-08-06T13:43:00.751Z" }, { url = "https://files.pythonhosted.org/packages/e7/f8/73265927e3da54a417536dc3d8c9aad806b62b8133099a7ee12661aba1a3/time_machine-2.15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b095a1de40ca1afaeae8df3f45e26b645094a1912e6e6871e725fcf06ecdb74a", size = 32789, upload-time = "2024-08-06T13:43:06.312Z" }, { url = "https://files.pythonhosted.org/packages/8a/a4/bcf8ad40a4c6973a67aba5df7ed704dc34256835fb074cfb4d4caa0f93a5/time_machine-2.15.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4601fe7a6b74c6fd9207e614d9db2a20dd4befd4d314677a0feac13a67189707", size = 30911, upload-time = "2024-08-06T13:43:02.579Z" }, { url = "https://files.pythonhosted.org/packages/13/87/a6de1b187f5468781e0e722c877323625227151cc8ffff363a7391b01149/time_machine-2.15.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:245ef73f9927b7d4909d554a6a0284dbc5dee9730adea599e430b37c9e9fa203", size = 32644, upload-time = "2024-08-06T13:43:04.457Z" }, { url = "https://files.pythonhosted.org/packages/33/1f/7378d5a032467891a1005e546532223b97c53440c6359b1133696a5cb1ef/time_machine-2.15.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:704abc7f3403584cca9c01c5809812e0bd70632ea4251389fae4f45e11aad94f", size = 32472, upload-time = "2024-08-06T13:43:07.699Z" }, { url = "https://files.pythonhosted.org/packages/68/14/2fab61ad2c9a831925bce3d5e341fa2108ba062c2de0c190569e1ee6a1c9/time_machine-2.15.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:6425001e50a0c82108caed438233066cea04d42a8fc9c49bfcf081a5b96e5b4e", size = 30882, upload-time = "2024-08-06T13:43:08.83Z" }, { url = "https://files.pythonhosted.org/packages/8a/01/f5146b9956b548072000a87f3eb8dbb2591ada1516a5d889aa12b373948f/time_machine-2.15.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5d4073b754f90b19f28d036ec5143d3fca3a75e4d4241d78790a6178b00bb373", size = 32176, upload-time = "2024-08-06T13:43:10.689Z" }, { url = "https://files.pythonhosted.org/packages/ca/09/8a8488e6d3faf3cb68d078f27ca94aa3ba1bc08d5f804265c590208a70f5/time_machine-2.15.0-cp311-cp311-win32.whl", hash = "sha256:8817b0f7d7830215261b18db83c9c3ef1da6bb64da5c292d7c70b9a46e5a6745", size = 19305, upload-time = "2024-08-06T13:43:12.568Z" }, { url = "https://files.pythonhosted.org/packages/75/33/d8411b197a08eedb3ce086022cdf4faf1f15738607a2d943fd5286f57fdd/time_machine-2.15.0-cp311-cp311-win_amd64.whl", hash = "sha256:ddad27a62df2ea47b7b483009fbfcf167a71d702cbd8e2eefd9ddc1c93146658", size = 20210, upload-time = "2024-08-06T13:43:13.731Z" }, { url = "https://files.pythonhosted.org/packages/8c/f5/e9b5d7be612403e570a42af5c2823506877e726f77f2d6ff272d72d0aed3/time_machine-2.15.0-cp311-cp311-win_arm64.whl", hash = "sha256:6f021aa2dbd8fbfe54d3fa2258518129108b7496922b3bcff2cf5991078eec67", size = 18278, upload-time = "2024-08-06T13:43:17.612Z" }, { url = "https://files.pythonhosted.org/packages/49/47/46bf332f4ecd7f35e197131b9c23daa39423cf71b814e36e9d5df3cf2380/time_machine-2.15.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:a22f47c34ee1fcf7d93a8c5c93135499aac879d9d5d8f820bd28571a30fdabcd", size = 20436, upload-time = "2024-08-06T15:42:15.185Z" }, { url = "https://files.pythonhosted.org/packages/f1/36/9990f16868ffdefe6b5aecfdfbcb11718230e414ca61a887fbee884f70e5/time_machine-2.15.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b684f8ecdeacd6baabc17b15ac1b054ca62029193e6c5367ef00b3516671de80", size = 16926, upload-time = "2024-08-06T15:42:17.284Z" }, { url = "https://files.pythonhosted.org/packages/ca/2d/007955a0899cd079a400bc204c03edc76274de2471d94ca235ff587a6eba/time_machine-2.15.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5f7add997684bc6141e1c80f6ba0c38ffe316ba277a4074e61b1b7b4f5a172bf", size = 17157, upload-time = "2024-08-06T11:12:16.25Z" }, { url = "https://files.pythonhosted.org/packages/7a/e2/66d26450f9bfd1b019abdefbf0c62e760efc8992c7bf88d6c18f7ea6b94a/time_machine-2.15.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:31af56399bf7c9ef76a3f7b6d9471dffa8f06ee373c194a374b69523f9061de9", size = 34005, upload-time = "2024-08-06T15:42:22.266Z" }, { url = "https://files.pythonhosted.org/packages/46/2c/dc2c42200aee6b47a55274d984736f7507ecfbfd0345114ec511ec444bef/time_machine-2.15.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f5b94cba3edfc54bcb3ab5be616a2f50fa48be438e5af970824efdf882d1bc31", size = 31926, upload-time = "2024-08-06T15:42:19.044Z" }, { url = "https://files.pythonhosted.org/packages/87/59/10d8faecbd233b0da831eb9973c3e650c83fb3d443edb607b6b26c9688ac/time_machine-2.15.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3862dda89bdb05f9d521b08fdcb24b19a7dd9f559ae324f4301ba7a07b6eea64", size = 33685, upload-time = "2024-08-06T15:42:20.565Z" }, { url = "https://files.pythonhosted.org/packages/2e/a4/702ad9e328cbc7b3f1833dee4886d0994e52bc2d9640effa64bccc7740fa/time_machine-2.15.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e1790481a6b9ce38888f22ce30710244067898c3ac4805a0e061e381f3db3506", size = 33609, upload-time = "2024-08-06T15:42:23.817Z" }, { url = "https://files.pythonhosted.org/packages/a0/9d/6009d28ad395a45b5bb91af31616494b4e61d6d9df252d0e5933cd3aa8f1/time_machine-2.15.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a731c03bc00552ee6cc685a59616d36003124e7e04c6ddf65c2c47f1c3d85480", size = 31737, upload-time = "2024-08-06T15:42:25.175Z" }, { url = "https://files.pythonhosted.org/packages/36/22/b55df08cf48d46af93ee2f4310dd88c8519bc5f98afd24af57a81a5d5272/time_machine-2.15.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e6776840aea3ff5ab6924b50117957da62db51b109b3b491c0d5817a804b1a8e", size = 33253, upload-time = "2024-08-06T15:42:26.511Z" }, { url = "https://files.pythonhosted.org/packages/52/d7/bb5e92f0b0268cd13baad874d82b0e964a847cf52740464abeec48dc1642/time_machine-2.15.0-cp312-cp312-win32.whl", hash = "sha256:9479530e3fce65f6149058071fa4df8150025f15b43b103445f619842981a87c", size = 19369, upload-time = "2024-08-06T15:42:27.682Z" }, { url = "https://files.pythonhosted.org/packages/f4/33/276537ba292fc7ee67e6aef7566b2a6b313dbc4d479e5e80eed43094ef48/time_machine-2.15.0-cp312-cp312-win_amd64.whl", hash = "sha256:b5f3ab4185c1f72010846ca9fccb08349e23a2b52982a18d9870e848ce9f1c86", size = 20219, upload-time = "2024-08-06T15:42:29.475Z" }, { url = "https://files.pythonhosted.org/packages/e0/0e/e8b75032248f59a2bc5c125d3a41242b1e577caa07585c42b22373d6466d/time_machine-2.15.0-cp312-cp312-win_arm64.whl", hash = "sha256:c0473dfa8f17c6a9a250b2bd6a5b62af3aa7d22518f701649115f1085d5e35ab", size = 18297, upload-time = "2024-08-06T15:42:31.116Z" }, { url = "https://files.pythonhosted.org/packages/7c/a1/ebe212530628aa29a86a771ca77cb2d1ead667382cfa89a3fb849e3f0108/time_machine-2.15.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:f50f10058b884d45cd8a50423bf561b1f9f9df7058abeb8b318700c8bcf4bb54", size = 20492, upload-time = "2024-08-06T13:43:20.546Z" }, { url = "https://files.pythonhosted.org/packages/29/0d/2a19951729e50d8809e161e533585c0be5ae39c0cf40140877353847b9b5/time_machine-2.15.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:df6f618b98f0848fd8d07039541e10f23db679d8283f8719e870a98e1ef8e639", size = 16961, upload-time = "2024-08-06T13:43:23.227Z" }, { url = "https://files.pythonhosted.org/packages/85/eb/33cf2173758b128f55c880c492e17b70f6c325e7bee879f9b0171cfe02a0/time_machine-2.15.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52468a0784544eba708c0ae6bc5e8c5dcfd685495a60f7f74028662c984bd9cd", size = 34051, upload-time = "2024-08-06T13:43:26.529Z" }, { url = "https://files.pythonhosted.org/packages/e1/23/da9a7935a7be952ab6163caf976b6bad049f6e117f3a396ecc381b077cb6/time_machine-2.15.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c08800c28160f4d32ca510128b4e201a43c813e7a2dd53178fa79ebe050eba13", size = 31966, upload-time = "2024-08-06T13:43:24.344Z" }, { url = "https://files.pythonhosted.org/packages/0b/0d/a8e3cbd91ffa98b0fa50b6e29d03151f37aa04cca4dd658e33cdf2b4731e/time_machine-2.15.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65d395211736d9844537a530287a7c64b9fda1d353e899a0e1723986a0859154", size = 33727, upload-time = "2024-08-06T13:43:25.407Z" }, { url = "https://files.pythonhosted.org/packages/07/53/c084031980706517cfbae9f462e455d61c7cbf9b66a8a83bcc5b79d00836/time_machine-2.15.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3b177d334a35bf2ce103bfe4e0e416e4ee824dd33386ea73fa7491c17cc61897", size = 33690, upload-time = "2024-08-06T13:43:28.145Z" }, { url = "https://files.pythonhosted.org/packages/a0/30/5c87e8709ba00c893faf8a9bddf06abf317fdc6103fe78bdf99c53ab444f/time_machine-2.15.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:9a6a9342fae113b12aab42c790880c549d9ba695b8deff27ee08096eedd67569", size = 31809, upload-time = "2024-08-06T13:43:29.645Z" }, { url = "https://files.pythonhosted.org/packages/04/7b/92ac7c556cd123bf8b23dbae3cf4a273c276110b87d0c4b5600c2cec8e70/time_machine-2.15.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bcbb25029ee8756f10c6473cea5ef21707a1d9a8752cdf29fad3a5f34aa4a313", size = 33325, upload-time = "2024-08-06T13:43:30.832Z" }, { url = "https://files.pythonhosted.org/packages/e9/71/36c74bab3d4e4385d31610b367da1535a36d17358df058e0920a7510e17c/time_machine-2.15.0-cp313-cp313-win32.whl", hash = "sha256:29b988b1f09f2a083b12b6b054787b799ae91ee15bb0e9de3e48f880e4d68674", size = 19397, upload-time = "2024-08-06T13:43:31.996Z" }, { url = "https://files.pythonhosted.org/packages/a4/69/ea5976c43a673894f2fa85a05b28a610b474472f393e59722a6946f7070b/time_machine-2.15.0-cp313-cp313-win_amd64.whl", hash = "sha256:d828721dcbcb94b904a6b25df67c2513ecd24cd9e36694f38b9f0fa71c7c6103", size = 20242, upload-time = "2024-08-06T13:43:33.11Z" }, { url = "https://files.pythonhosted.org/packages/cc/c8/26367d0b8dfaf7445576fe0051bff61b8f5be752e7bf3e8807ed7fa3a343/time_machine-2.15.0-cp313-cp313-win_arm64.whl", hash = "sha256:008bd668d933b1a029c81805bcdc0132390c2545b103cf8e6709e3adbc37989d", size = 18337, upload-time = "2024-08-06T13:43:34.227Z" }, { url = "https://files.pythonhosted.org/packages/97/54/eeac8568cad4f3eb255cc78f1fa2c36147afd3fcba770283bf2b2a188b33/time_machine-2.15.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e99689f6c6b9ca6e2fc7a75d140e38c5a7985dab61fe1f4e506268f7e9844e05", size = 20674, upload-time = "2024-08-06T13:42:05.072Z" }, { url = "https://files.pythonhosted.org/packages/5c/82/488341de4c03c0856aaf5db74f2a8fe18dcc7657401334c54c4aa6cb0fc6/time_machine-2.15.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:671e88a6209a1cf415dc0f8c67d2b2d3b55b436cc63801a518f9800ebd752959", size = 16990, upload-time = "2024-08-06T13:42:07.508Z" }, { url = "https://files.pythonhosted.org/packages/9c/cc/0ca559e71be4eb05917d02364f4d356351b31dd0d6ff3c4c86fa4de0a03e/time_machine-2.15.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b2d28daf4cabc698aafb12135525d87dc1f2f893cbd29a8a6fe0d8d36d1342c", size = 35501, upload-time = "2024-08-06T13:42:12.348Z" }, { url = "https://files.pythonhosted.org/packages/92/a0/14905a5feecc6d2e87ebe6dd2b044358422836ed173071cdc1245aa5ec88/time_machine-2.15.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4cd9f057457d12604be18b623bcd5ae7d0b917ad66cb510ee1135d5f123666e2", size = 33430, upload-time = "2024-08-06T13:42:09.625Z" }, { url = "https://files.pythonhosted.org/packages/19/a4/282b65b4d835dfd7b863777cc4206bec375285bda884dc22bd1264716f6a/time_machine-2.15.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97dc6793e512a62ba9eab250134a2e67372c16ae9948e73d27c2ef355356e2e1", size = 35366, upload-time = "2024-08-06T13:42:10.957Z" }, { url = "https://files.pythonhosted.org/packages/93/8e/f7db3f641f1ff86b98594c9cf8d71c8d292cc2bde06c1369ce4745494cc5/time_machine-2.15.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:0630a32e9ebcf2fac3704365b31e271fef6eabd6fedfa404cd8dbd244f7fc84d", size = 34373, upload-time = "2024-08-06T13:42:13.419Z" }, { url = "https://files.pythonhosted.org/packages/3d/9f/8c8ac57ccb29e692e0940e58515a9afb844d2d11b7f057a0fe153bfe4877/time_machine-2.15.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:617c9a92d8d8f60d5ef39e76596620503752a09f834a218e5b83be352fdd6c91", size = 32667, upload-time = "2024-08-06T13:42:15.293Z" }, { url = "https://files.pythonhosted.org/packages/ec/e7/f0c6f9507b0bbfdec54d256b6efc9417ae1a01ce6320c2a42235b807cf86/time_machine-2.15.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:3f7eadd820e792de33a9ec91f8178a2b9088e4e8b9a166953419ddc4ec5f7cfe", size = 34070, upload-time = "2024-08-06T13:42:17.147Z" }, { url = "https://files.pythonhosted.org/packages/20/82/ac2d8343db8dade1372457d7a5694f069882d9eac110ddce2643ef0501aa/time_machine-2.15.0-cp38-cp38-win32.whl", hash = "sha256:b7b647684eb2e1fd1e5e6b101249d5fe9d6117c117b5e336ad8dd75af48d2d1f", size = 19396, upload-time = "2024-08-06T13:42:18.256Z" }, { url = "https://files.pythonhosted.org/packages/3a/12/ac7bb1e932536fce359e021a62c2a5a30c4e470293d6f8b2fb47077562dc/time_machine-2.15.0-cp38-cp38-win_amd64.whl", hash = "sha256:b48abd7745caec1a78a16a048966cde14ff6ccb04d471a7201532648d3f77d14", size = 20266, upload-time = "2024-08-06T13:42:20.304Z" }, { url = "https://files.pythonhosted.org/packages/ec/bf/d9689e1fa669e575c3ed57bf4f9205a9b5fbe703dc7ef89ba5ce9aa39a38/time_machine-2.15.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8c2b1c91b437133c672e374857eccb1dd2c2d9f8477ae3b35138382d5ef19846", size = 20775, upload-time = "2024-08-06T13:42:22.424Z" }, { url = "https://files.pythonhosted.org/packages/d8/4b/4314a7882b470c52cd527601107b1163e19d37fb1eb31eea0f8d73d0b178/time_machine-2.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:79bf1ef6850182e09d86e61fa31717da56014a3b2234afb025fca1f2a43ac07b", size = 17037, upload-time = "2024-08-06T13:42:23.539Z" }, { url = "https://files.pythonhosted.org/packages/f1/b8/adf2f8b8e10f6f5e498b0cddd103f6520144af53fb27b5a01eca50812a92/time_machine-2.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:658ea8477fa020f08435fb7277635eb0b50cd5206b9d4cbe10e9a5466b01f855", size = 34511, upload-time = "2024-08-06T13:42:28.63Z" }, { url = "https://files.pythonhosted.org/packages/e3/86/fda41a9e8115fd377f2d4d15c91a414f75cb8f2cd7f8bde974855a0f381f/time_machine-2.15.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c947135750d20f35acac290c34f1acf5771fc166a3fbc0e3816a97c756aaa5f5", size = 32533, upload-time = "2024-08-06T13:42:25.709Z" }, { url = "https://files.pythonhosted.org/packages/cb/7e/1e2e69fee659f00715f12392cabea1920245504862eab2caac6e3f30de5b/time_machine-2.15.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1dee3a0dd1866988c49a5d00564404db9bcdf49ca92f9c4e8b6c99609d64e698", size = 34348, upload-time = "2024-08-06T13:42:27.478Z" }, { url = "https://files.pythonhosted.org/packages/41/da/8db2df73ebe9f23af25b05f1720b108a145805a8c83d5ff8248e2d3cbcfa/time_machine-2.15.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:c596920d6017702a36e3a43fd8110a84e87d6229f30b84bd5640cbae9b5145da", size = 34081, upload-time = "2024-08-06T13:42:29.742Z" }, { url = "https://files.pythonhosted.org/packages/a7/c7/9202404f8885257c09c98d3e5186b989b6b482a2983dc24c81bd0333e668/time_machine-2.15.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:014589d0edd4aa14f8d63985745565e8cbbe48461d6c004a96000b47f6b44e78", size = 32357, upload-time = "2024-08-06T13:42:30.884Z" }, { url = "https://files.pythonhosted.org/packages/4d/79/482a69c31259c3c2efcd9e73ea4a0a4d315103836c1667875612288bca28/time_machine-2.15.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5ff655716cd13a242eef8cf5d368074e8b396ff86508a5933e7cff4f2b3eb3c2", size = 33742, upload-time = "2024-08-06T13:42:33.213Z" }, { url = "https://files.pythonhosted.org/packages/f0/39/89725d12a3552bb9113528d8f9aa7188e1660b377b74e7d72e8ab5eeff06/time_machine-2.15.0-cp39-cp39-win32.whl", hash = "sha256:1168eebd7af7e6e3e2fd378c16ca917b97dd81c89a1f1f9e1daa985c81699d90", size = 19410, upload-time = "2024-08-06T13:42:34.333Z" }, { url = "https://files.pythonhosted.org/packages/89/0c/50e86c4a7b72d2bdc658492b13e804f933814f86f34c4350758d1ab87586/time_machine-2.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:c344eb09fcfbf71e5b5847d4f188fec98e1c3a976125ef571eac5f1c39e7a5e5", size = 20281, upload-time = "2024-08-06T13:42:36.174Z" }, { url = "https://files.pythonhosted.org/packages/f6/4d/f8ad3b0c50a268a9ea766c9533866bba6a7717a5324c84e356abb7347fa4/time_machine-2.15.0-cp39-cp39-win_arm64.whl", hash = "sha256:899f1a856b3bebb82b6cbc3c0014834b583b83f246b28e462a031ec1b766130b", size = 18387, upload-time = "2024-08-06T13:42:37.271Z" }, ] [[package]] name = "tomli" version = "2.2.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", size = 17175, upload-time = "2024-11-27T22:38:36.873Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/43/ca/75707e6efa2b37c77dadb324ae7d9571cb424e61ea73fad7c56c2d14527f/tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", size = 131077, upload-time = "2024-11-27T22:37:54.956Z" }, { url = "https://files.pythonhosted.org/packages/c7/16/51ae563a8615d472fdbffc43a3f3d46588c264ac4f024f63f01283becfbb/tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", size = 123429, upload-time = "2024-11-27T22:37:56.698Z" }, { url = "https://files.pythonhosted.org/packages/f1/dd/4f6cd1e7b160041db83c694abc78e100473c15d54620083dbd5aae7b990e/tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", size = 226067, upload-time = "2024-11-27T22:37:57.63Z" }, { url = "https://files.pythonhosted.org/packages/a9/6b/c54ede5dc70d648cc6361eaf429304b02f2871a345bbdd51e993d6cdf550/tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", size = 236030, upload-time = "2024-11-27T22:37:59.344Z" }, { url = "https://files.pythonhosted.org/packages/1f/47/999514fa49cfaf7a92c805a86c3c43f4215621855d151b61c602abb38091/tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", size = 240898, upload-time = "2024-11-27T22:38:00.429Z" }, { url = "https://files.pythonhosted.org/packages/73/41/0a01279a7ae09ee1573b423318e7934674ce06eb33f50936655071d81a24/tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", size = 229894, upload-time = "2024-11-27T22:38:02.094Z" }, { url = "https://files.pythonhosted.org/packages/55/18/5d8bc5b0a0362311ce4d18830a5d28943667599a60d20118074ea1b01bb7/tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", size = 245319, upload-time = "2024-11-27T22:38:03.206Z" }, { url = "https://files.pythonhosted.org/packages/92/a3/7ade0576d17f3cdf5ff44d61390d4b3febb8a9fc2b480c75c47ea048c646/tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", size = 238273, upload-time = "2024-11-27T22:38:04.217Z" }, { url = "https://files.pythonhosted.org/packages/72/6f/fa64ef058ac1446a1e51110c375339b3ec6be245af9d14c87c4a6412dd32/tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", size = 98310, upload-time = "2024-11-27T22:38:05.908Z" }, { url = "https://files.pythonhosted.org/packages/6a/1c/4a2dcde4a51b81be3530565e92eda625d94dafb46dbeb15069df4caffc34/tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", size = 108309, upload-time = "2024-11-27T22:38:06.812Z" }, { url = "https://files.pythonhosted.org/packages/52/e1/f8af4c2fcde17500422858155aeb0d7e93477a0d59a98e56cbfe75070fd0/tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", size = 132762, upload-time = "2024-11-27T22:38:07.731Z" }, { url = "https://files.pythonhosted.org/packages/03/b8/152c68bb84fc00396b83e7bbddd5ec0bd3dd409db4195e2a9b3e398ad2e3/tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", size = 123453, upload-time = "2024-11-27T22:38:09.384Z" }, { url = "https://files.pythonhosted.org/packages/c8/d6/fc9267af9166f79ac528ff7e8c55c8181ded34eb4b0e93daa767b8841573/tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", size = 233486, upload-time = "2024-11-27T22:38:10.329Z" }, { url = "https://files.pythonhosted.org/packages/5c/51/51c3f2884d7bab89af25f678447ea7d297b53b5a3b5730a7cb2ef6069f07/tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", size = 242349, upload-time = "2024-11-27T22:38:11.443Z" }, { url = "https://files.pythonhosted.org/packages/ab/df/bfa89627d13a5cc22402e441e8a931ef2108403db390ff3345c05253935e/tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", size = 252159, upload-time = "2024-11-27T22:38:13.099Z" }, { url = "https://files.pythonhosted.org/packages/9e/6e/fa2b916dced65763a5168c6ccb91066f7639bdc88b48adda990db10c8c0b/tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", size = 237243, upload-time = "2024-11-27T22:38:14.766Z" }, { url = "https://files.pythonhosted.org/packages/b4/04/885d3b1f650e1153cbb93a6a9782c58a972b94ea4483ae4ac5cedd5e4a09/tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", size = 259645, upload-time = "2024-11-27T22:38:15.843Z" }, { url = "https://files.pythonhosted.org/packages/9c/de/6b432d66e986e501586da298e28ebeefd3edc2c780f3ad73d22566034239/tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", size = 244584, upload-time = "2024-11-27T22:38:17.645Z" }, { url = "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", size = 98875, upload-time = "2024-11-27T22:38:19.159Z" }, { url = "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", size = 109418, upload-time = "2024-11-27T22:38:20.064Z" }, { url = "https://files.pythonhosted.org/packages/04/90/2ee5f2e0362cb8a0b6499dc44f4d7d48f8fff06d28ba46e6f1eaa61a1388/tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7", size = 132708, upload-time = "2024-11-27T22:38:21.659Z" }, { url = "https://files.pythonhosted.org/packages/c0/ec/46b4108816de6b385141f082ba99e315501ccd0a2ea23db4a100dd3990ea/tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", size = 123582, upload-time = "2024-11-27T22:38:22.693Z" }, { url = "https://files.pythonhosted.org/packages/a0/bd/b470466d0137b37b68d24556c38a0cc819e8febe392d5b199dcd7f578365/tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", size = 232543, upload-time = "2024-11-27T22:38:24.367Z" }, { url = "https://files.pythonhosted.org/packages/d9/e5/82e80ff3b751373f7cead2815bcbe2d51c895b3c990686741a8e56ec42ab/tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", size = 241691, upload-time = "2024-11-27T22:38:26.081Z" }, { url = "https://files.pythonhosted.org/packages/05/7e/2a110bc2713557d6a1bfb06af23dd01e7dde52b6ee7dadc589868f9abfac/tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", size = 251170, upload-time = "2024-11-27T22:38:27.921Z" }, { url = "https://files.pythonhosted.org/packages/64/7b/22d713946efe00e0adbcdfd6d1aa119ae03fd0b60ebed51ebb3fa9f5a2e5/tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", size = 236530, upload-time = "2024-11-27T22:38:29.591Z" }, { url = "https://files.pythonhosted.org/packages/38/31/3a76f67da4b0cf37b742ca76beaf819dca0ebef26d78fc794a576e08accf/tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", size = 258666, upload-time = "2024-11-27T22:38:30.639Z" }, { url = "https://files.pythonhosted.org/packages/07/10/5af1293da642aded87e8a988753945d0cf7e00a9452d3911dd3bb354c9e2/tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", size = 243954, upload-time = "2024-11-27T22:38:31.702Z" }, { url = "https://files.pythonhosted.org/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", size = 98724, upload-time = "2024-11-27T22:38:32.837Z" }, { url = "https://files.pythonhosted.org/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", size = 109383, upload-time = "2024-11-27T22:38:34.455Z" }, { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257, upload-time = "2024-11-27T22:38:35.385Z" }, ] [[package]] name = "types-pytz" version = "2024.2.0.20241221" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version < '3.9'", ] sdist = { url = "https://files.pythonhosted.org/packages/54/26/516311b02b5a215e721155fb65db8a965d061372e388d6125ebce8d674b0/types_pytz-2024.2.0.20241221.tar.gz", hash = "sha256:06d7cde9613e9f7504766a0554a270c369434b50e00975b3a4a0f6eed0f2c1a9", size = 10213, upload-time = "2024-12-21T02:40:48.654Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/74/db/c92ca6920cccd9c2998b013601542e2ac5e59bc805bcff94c94ad254b7df/types_pytz-2024.2.0.20241221-py3-none-any.whl", hash = "sha256:8fc03195329c43637ed4f593663df721fef919b60a969066e22606edf0b53ad5", size = 10008, upload-time = "2024-12-21T02:40:47.047Z" }, ] [[package]] name = "types-pytz" version = "2025.2.0.20250326" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.9'", ] sdist = { url = "https://files.pythonhosted.org/packages/4b/66/38c89861242f2c61c8315ddbcc7d7bbf64979f4b0bdc48db0ba62aeec330/types_pytz-2025.2.0.20250326.tar.gz", hash = "sha256:deda02de24f527066fc8d6a19e284ab3f3ae716a42b4adb6b40e75e408c08d36", size = 10595, upload-time = "2025-03-26T02:53:12.504Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/4e/e0/17f3a6670db5c95dc195f346e2e7290f22ba8327c188133959389b578cbd/types_pytz-2025.2.0.20250326-py3-none-any.whl", hash = "sha256:3c397fd1b845cd2b3adc9398607764ced9e578a98a5d1fbb4a9bc9253edfb162", size = 10222, upload-time = "2025-03-26T02:53:11.145Z" }, ] [[package]] name = "typing-extensions" version = "4.13.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/f6/37/23083fcd6e35492953e8d2aaaa68b860eb422b34627b13f2ce3eb6106061/typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef", size = 106967, upload-time = "2025-04-10T14:19:05.416Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/8b/54/b1ae86c0973cc6f0210b53d508ca3641fb6d0c56823f288d108bc7ab3cc8/typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", size = 45806, upload-time = "2025-04-10T14:19:03.967Z" }, ] [[package]] name = "typing-inspection" version = "0.4.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions", marker = "python_full_version >= '3.9'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/82/5c/e6082df02e215b846b4b8c0b887a64d7d08ffaba30605502639d44c06b82/typing_inspection-0.4.0.tar.gz", hash = "sha256:9765c87de36671694a67904bf2c96e395be9c6439bb6c87b5142569dcdd65122", size = 76222, upload-time = "2025-02-25T17:27:59.638Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/31/08/aa4fdfb71f7de5176385bd9e90852eaf6b5d622735020ad600f2bab54385/typing_inspection-0.4.0-py3-none-any.whl", hash = "sha256:50e72559fcd2a6367a19f7a7e610e6afcb9fac940c650290eed893d61386832f", size = 14125, upload-time = "2025-02-25T17:27:57.754Z" }, ] [[package]] name = "tzdata" version = "2025.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/95/32/1a225d6164441be760d75c2c42e2780dc0873fe382da3e98a2e1e48361e5/tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9", size = 196380, upload-time = "2025-03-23T13:54:43.652Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839, upload-time = "2025-03-23T13:54:41.845Z" }, ] [[package]] name = "zipp" version = "3.20.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/54/bf/5c0000c44ebc80123ecbdddba1f5dcd94a5ada602a9c225d84b5aaa55e86/zipp-3.20.2.tar.gz", hash = "sha256:bc9eb26f4506fda01b81bcde0ca78103b6e62f991b381fec825435c836edbc29", size = 24199, upload-time = "2024-09-13T13:44:16.101Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/62/8b/5ba542fa83c90e09eac972fc9baca7a88e7e7ca4b221a89251954019308b/zipp-3.20.2-py3-none-any.whl", hash = "sha256:a817ac80d6cf4b23bf7f2828b7cabf326f15a001bea8b1f9b49631780ba28350", size = 9200, upload-time = "2024-09-13T13:44:14.38Z" }, ]