diff --git a/.cookiecutter.json b/.cookiecutter.json index 89fc1ace..fb30767e 100644 --- a/.cookiecutter.json +++ b/.cookiecutter.json @@ -2,7 +2,7 @@ "cookiecutter": { "codeowner_github_usernames": "@itdependsnetworks @jeffkala @qduk", "full_name": "Network to Code, LLC", - "email": "info@networktocode.com", + "email": "opensource@networktocode.com", "github_org": "networktocode", "description": "Common helper functions useful in network automation.", "project_name": "netutils", @@ -10,20 +10,21 @@ "repo_url": "https://github.com/networktocode/netutils", "base_url": "netutils", "project_python_name": "netutils", - "project_python_base_version": "3.9", + "project_python_base_version": "3.10", "project_with_config_settings": "no", "generate_docs": "yes", "version": "1.15.1", + "original_publish_year": "2021", "_drift_manager": { "template": "https://github.com/networktocode-llc/cookiecutter-ntc.git", "template_dir": "python", "template_ref": "main", "cookie_dir": "", "branch_prefix": "drift-manager", - "pull_request_strategy": "create", + "pull_request_strategy": "update-or-create", "post_actions": [], "draft": false, - "baked_commit_ref": "cb8b5e31dece5ab2663d2ffd218a96ca1ae794c5" + "baked_commit_ref": "6e903d3c14d2fd9a9e73ac9725d2eb2efdc315e7" } } } diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 1a093633..a77d66ac 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -4,7 +4,7 @@ about: Report a reproducible bug in the current release of netutils --- ### Environment -* Python version: +* Python version: * netutils version: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 34f96191..bc9af434 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,8 +8,6 @@ on: # yamllint disable-line rule:truthy rule:comments branches: - "main" - "develop" - tags: - - "v*" pull_request: ~ env: @@ -86,10 +84,6 @@ jobs: poetry-version: "2.1.3" - name: "Checking: poetry lock file" run: "poetry run invoke lock --check" - needs: - - "ruff-format" - - "ruff-lint" - - "yamllint" yamllint: runs-on: "ubuntu-latest" env: @@ -103,15 +97,17 @@ jobs: poetry-version: "2.1.3" - name: "Linting: yamllint" run: "poetry run invoke yamllint" + check-in-docker: needs: - "ruff-format" - "ruff-lint" - pylint: + - "poetry" + - "yamllint" runs-on: "ubuntu-latest" strategy: fail-fast: true matrix: - python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] + python-version: ["3.10", "3.13"] env: PYTHON_VER: "${{ matrix.python-version }}" steps: @@ -141,13 +137,13 @@ jobs: PYTHON_VER=${{ env.PYTHON_VER }} - name: "Linting: Pylint" run: "poetry run invoke pylint" - needs: - - "poetry" pytest: + needs: + - "check-in-docker" strategy: fail-fast: true matrix: - python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] + python-version: ["3.10", "3.11", "3.12", "3.13"] runs-on: "ubuntu-latest" env: PYTHON_VER: "${{ matrix.python-version }}" @@ -178,8 +174,6 @@ jobs: PYTHON_VER=${{ env.PYTHON_VER }} - name: "Run Tests" run: "poetry run invoke pytest" - needs: - - "poetry" changelog: if: > contains(fromJson('["develop"]'), github.base_ref) && @@ -198,99 +192,3 @@ jobs: run: | git fetch --no-tags origin +refs/heads/${{ github.base_ref }}:refs/remotes/origin/${{ github.base_ref }} poetry run towncrier check --compare-with origin/${{ github.base_ref }} - publish_gh: - name: "Publish to GitHub" - runs-on: "ubuntu-latest" - # yamllint disable-line rule:quoted-strings - if: startsWith(github.ref, 'refs/tags/v') - env: - INVOKE_NETUTILS_LOCAL: "True" - steps: - - name: "Check out repository code" - uses: "actions/checkout@v4" - - name: "Setup environment" - uses: "networktocode/gh-action-setup-poetry-environment@v6" - with: - poetry-version: "2.1.3" - python-version: "3.12" - poetry-install-options: "--no-root" - - name: "Set env" - run: "echo RELEASE_VERSION=${GITHUB_REF:10} >> $GITHUB_ENV" - - name: "Run Poetry Version" - run: "poetry version $RELEASE_VERSION" - - name: "Build Documentation" - run: "poetry run invoke build-and-check-docs" - - name: "Run Poetry Build" - run: "poetry build" - - name: "Upload binaries to release" - run: "gh release upload ${{ github.ref_name }} dist/*.{tar.gz,whl}" - env: - GH_TOKEN: "${{ secrets.NTC_GITHUB_TOKEN }}" - needs: - - "pytest" - publish_pypi: - name: "Push Package to PyPI" - runs-on: "ubuntu-latest" - # yamllint disable-line rule:quoted-strings - if: startsWith(github.ref, 'refs/tags/v') - env: - INVOKE_NETUTILS_LOCAL: "True" - steps: - - name: "Check out repository code" - uses: "actions/checkout@v4" - - name: "Setup environment" - uses: "networktocode/gh-action-setup-poetry-environment@v6" - with: - poetry-version: "2.1.3" - - name: "Set env" - run: "echo RELEASE_VERSION=${GITHUB_REF:10} >> $GITHUB_ENV" - - name: "Run Poetry Version" - run: "poetry version $RELEASE_VERSION" - - name: "Install Dependencies (needed for mkdocs)" - run: "poetry install --no-root" - - name: "Build Documentation" - run: "poetry run invoke build-and-check-docs" - - name: "Run Poetry Build" - run: "poetry build" - - name: "Push to PyPI" - uses: "pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc" # v1.12.4 - with: - user: "__token__" - password: "${{ secrets.PYPI_API_TOKEN }}" - needs: - - "pytest" - slack-notify: - needs: - - "publish_gh" - - "publish_pypi" - runs-on: "ubuntu-latest" - env: - SLACK_WEBHOOK_URL: "${{ secrets.SLACK_WEBHOOK_URL }}" - SLACK_MESSAGE: >- - *NOTIFICATION: NEW-RELEASE-PUBLISHED*\n - Repository: <${{ github.server_url }}/${{ github.repository }}|${{ github.repository }}>\n - Release: <${{ github.server_url }}/${{ github.repository }}/releases/tag/${{ github.ref_name }}|${{ github.ref_name }}>\n - Published by: <${{ github.server_url }}/${{ github.actor }}|${{ github.actor }}> - steps: - - name: "Send a notification to Slack" - # ENVs cannot be used directly in job.if. This is a workaround to check - # if SLACK_WEBHOOK_URL is present. - if: "env.SLACK_WEBHOOK_URL != ''" - uses: "slackapi/slack-github-action@fcfb566f8b0aab22203f066d80ca1d7e4b5d05b3" # v1.27.1 - with: - payload: | - { - "text": "${{ env.SLACK_MESSAGE }}", - "blocks": [ - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "${{ env.SLACK_MESSAGE }}" - } - } - ] - } - env: - SLACK_WEBHOOK_URL: "${{ secrets.SLACK_WEBHOOK_URL }}" - SLACK_WEBHOOK_TYPE: "INCOMING_WEBHOOK" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..ee870479 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,106 @@ +--- +name: "Release" +on: # yamllint disable-line rule:truthy rule:comments + release: + types: ["published"] + +jobs: + build: + name: "Build package with poetry" + runs-on: "ubuntu-latest" + if: "startsWith(github.ref, 'refs/tags/v')" + steps: + - uses: "actions/checkout@v4" + - name: "Setup environment" + uses: "networktocode/gh-action-setup-poetry-environment@v6" + with: + poetry-version: "2.1.3" + python-version: "3.13" + poetry-install-options: "--no-root" + - name: "Build Documentation" + run: "poetry run invoke build-and-check-docs" + - name: "Run Poetry Build" + run: "poetry build" + + - name: "Check that the release tag matches the version in pyproject.toml" + run: | + if [ "${{ github.ref_name }}" != "v$(poetry version -s)" ]; then exit 1; fi + + - uses: "actions/upload-artifact@v4" + with: + name: "distfiles" + path: "dist/" + if-no-files-found: "error" + + publish-github: + name: "Publish to GitHub" + runs-on: "ubuntu-latest" + if: "startsWith(github.ref, 'refs/tags/v')" + permissions: + contents: "write" + needs: "build" + steps: + - uses: "actions/checkout@v4" + - name: "Retrieve built package from cache" + uses: "actions/download-artifact@v4" + with: + name: "distfiles" + path: "dist/" + + - name: "Upload binaries to release" + run: "gh release upload ${{ github.ref_name }} dist/*.{tar.gz,whl}" + env: + GH_TOKEN: "${{ secrets.NTC_GITHUB_TOKEN }}" + + publish-pypi: + name: "Push Package to PyPI" + runs-on: "ubuntu-latest" + if: "startsWith(github.ref, 'refs/tags/v')" + needs: "build" + environment: "pypi" + permissions: + # IMPORTANT: this permission is mandatory for Trusted Publishing + id-token: "write" + steps: + - name: "Retrieve built package from cache" + uses: "actions/download-artifact@v4" + with: + name: "distfiles" + path: "dist/" + + - name: "Publish package distributions to PyPI" + uses: "pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e" # v1.13.0 + + slack-notify: + needs: + - "publish-github" + - "publish-pypi" + runs-on: "ubuntu-latest" + env: + # Secrets cannot be directly referenced in if: conditionals. They must be set as a job env var first. + # Ref: https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#example-using-secrets + SLACK_WEBHOOK_URL: "${{ secrets.OSS_PYPI_SLACK_WEBHOOK_URL }}" + SLACK_WEBHOOK_TYPE: "INCOMING_WEBHOOK" + SLACK_MESSAGE: >- + *NOTIFICATION: NEW-RELEASE-PUBLISHED*\n + Repository: <${{ github.server_url }}/${{ github.repository }}|${{ github.repository }}>\n + Release: <${{ github.server_url }}/${{ github.repository }}/releases/tag/${{ github.ref_name }}|${{ github.ref_name }}>\n + Published by: <${{ github.server_url }}/${{ github.actor }}|${{ github.actor }}> + steps: + - name: "Send a notification to Slack" + if: "${{ env.SLACK_WEBHOOK_URL != '' }}" + uses: "slackapi/slack-github-action@fcfb566f8b0aab22203f066d80ca1d7e4b5d05b3" # v1.27.1 + with: + payload: | + { + "text": "${{ env.SLACK_MESSAGE }}", + "blocks": [ + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "${{ env.SLACK_MESSAGE }}" + } + } + ] + } diff --git a/.readthedocs.yml b/.readthedocs.yml index 8d81895f..36f32f00 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -10,7 +10,7 @@ version: 2 build: os: "ubuntu-lts-latest" tools: - python: "3.12" + python: "3.13" jobs: post_install: # Install poetry diff --git a/Dockerfile b/Dockerfile index f7e6c66c..3c1fdca0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -ARG PYTHON_VER="3.9" +ARG PYTHON_VER="3.10" FROM python:${PYTHON_VER}-slim diff --git a/README.md b/README.md index 969516fe..932a2201 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@
- +
@@ -16,7 +16,7 @@ A Python library that is a collection of functions that are used in the common n ## Documentation -Full web-based HTML documentation for this library can be found over on the [Netutils Docs](https://netutils.readthedocs.io) website: +Full documentation for this library can be found over on the [Netutils Docs](https://netutils.readthedocs.io/) website: - [User Guide](https://netutils.readthedocs.io/en/latest/user/lib_overview/) - Overview, Using the library, Getting Started. - [Administrator Guide](https://netutils.readthedocs.io/en/latest/admin/install/) - How to Install, Configure, Upgrade, or Uninstall the library. @@ -24,11 +24,11 @@ Full web-based HTML documentation for this library can be found over on the [Net - [Release Notes / Changelog](https://netutils.readthedocs.io/en/latest/admin/release_notes/). - [Frequently Asked Questions](https://netutils.readthedocs.io/en/latest/user/faq/). -### Contributing to the Docs +### Contributing to the Documentation -All the Markdown source for the library documentation can be found under the [docs](https://github.com/networktocode/netutils/tree/develop/docs) folder in this repository. For simple edits, a Markdown capable editor is sufficient - clone the repository and edit away. +You can find all the Markdown source for the library documentation under the [`docs`](https://github.com/networktocode/netutils/tree/develop/docs) folder in this repository. For simple edits, a Markdown capable editor is sufficient: clone the repository and edit away. -If you need to view the fully generated documentation site, you can build it with [mkdocs](https://www.mkdocs.org/). A container hosting the docs will be started using the invoke commands (details in the [Development Environment Guide](https://netutils.readthedocs.io/en/latest/dev/dev_environment/#docker-development-environment)) on [http://localhost:8001](http://localhost:8001). As your changes are saved, the live docs will be automatically reloaded. +If you need to view the fully-generated documentation site, you can build it with [MkDocs](https://www.mkdocs.org/). A container hosting the documentation can be started using the `invoke` commands (details in the [Development Environment Guide](https://netutils/dev/dev_environment/#docker-development-environment)) on [http://localhost:8001](http://localhost:8001). Using this container, as your changes to the documentation are saved, they will be automatically rebuilt and any pages currently being viewed will be reloaded in your browser. Any PRs with fixes or improvements are very welcome! diff --git a/changes/+mainv2.housekeeping b/changes/+mainv2.housekeeping new file mode 100644 index 00000000..3433adf6 --- /dev/null +++ b/changes/+mainv2.housekeeping @@ -0,0 +1 @@ +Rebaked from the cookie `main`. diff --git a/changes/.gitkeep b/changes/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/docs/dev/contributing.md b/docs/dev/contributing.md index 5be51ea7..55b1c5a7 100644 --- a/docs/dev/contributing.md +++ b/docs/dev/contributing.md @@ -109,7 +109,7 @@ The branching policy includes the following tenets: - PRs intended to address bug fixes and security patches should be sourced from the develop branch. - PRs intended to add new features that break backward compatibility should be discussed before a PR is created. -Netutils will observe semantic versioning, as of 1.0. This may result in an quick turn around in minor versions to keep pace with an ever growing feature set. +Netutils will observe Semantic Versioning, as of 1.0. This may result in an quick turn around in minor versions to keep pace with an ever growing feature set. ## Release Policy diff --git a/example.invoke.yml b/example.invoke.yml index 199f8277..6206b5f9 100644 --- a/example.invoke.yml +++ b/example.invoke.yml @@ -1,6 +1,6 @@ --- "netutils": - python_ver: "3.9" + python_ver: "3.10" local: false # image_name: "netutils" # image_ver: "latest" diff --git a/mkdocs.yml b/mkdocs.yml index 174fd3d1..dab6370e 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -93,6 +93,9 @@ plugins: - "netutils.config.parser" classy_libraries: - "netutils" + - "glightbox": + manual: true # See https://blueswen.github.io/mkdocs-glightbox/flexibility/enable-by-image-or-page/ + - "section-index" - "mkdocstrings": default_handler: "python" handlers: diff --git a/netutils/log.py b/netutils/log.py new file mode 100644 index 00000000..b81a396b --- /dev/null +++ b/netutils/log.py @@ -0,0 +1,79 @@ +""" +Logging utilities for netutils. + +This module contains helpers and wrappers for making logging more consistent across applications. + +How to use me: + + >>> from netutils.log import initialize_logging + >>> log = initialize_logging(level="debug") +""" + +import logging.config +from typing import Any, Dict, Optional + +APP = "netutils" + + +def initialize_logging( + config: Optional[Dict[str, Any]] = None, + level: str = "INFO", + filename: Optional[str] = None, +) -> None: + """Initialize logging using sensible defaults. + + Args: + config (dict): User provided configuration dictionary. + level (str): The level of logging for STDOUT logging. + filename (str): Where to output debug logging to file. + + """ + if not config: + config = { + "version": 1, + "disable_existing_loggers": False, + "formatters": { + "standard": { + "format": "%(asctime)s [%(levelname)s] %(name)s: %(message)s", + "datefmt": "%Y-%m-%dT%H:%M:%S%z", + }, + "debug": { + "format": "%(asctime)s [%(levelname)s] [%(module)s] [%(funcName)s] %(name)s: %(message)s", + "datefmt": "%Y-%m-%dT%H:%M:%S%z", + }, + }, + "handlers": { + "standard": { + "class": "logging.StreamHandler", + "formatter": "standard", + "level": level.upper(), + }, + }, + "loggers": { + "": { + "handlers": ["standard"], + "level": "DEBUG", + } + }, + } + + # If a filename is passed in, let's add a FileHandler + if filename: + config["handlers"].update( + { + "file_output": { + "class": "logging.FileHandler", + "formatter": "debug", + "level": "DEBUG", + "filename": filename, + } + } + ) + config["loggers"][""]["handlers"].append("file_output") + + # Configure the logging + logging.config.dictConfig(config) + + # Initialize root logger and advise logging has been initialized + log = logging.getLogger(APP) + log.debug("Logging initialized.") diff --git a/poetry.lock b/poetry.lock index 123c5c17..0014bdb2 100644 --- a/poetry.lock +++ b/poetry.lock @@ -361,124 +361,6 @@ files = [ ] markers = {dev = "sys_platform == \"win32\" or platform_system == \"Windows\""} -[[package]] -name = "coverage" -version = "7.10.7" -description = "Code coverage measurement for Python" -optional = false -python-versions = ">=3.9" -groups = ["dev"] -markers = "python_version < \"3.11\"" -files = [ - {file = "coverage-7.10.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:fc04cc7a3db33664e0c2d10eb8990ff6b3536f6842c9590ae8da4c614b9ed05a"}, - {file = "coverage-7.10.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e201e015644e207139f7e2351980feb7040e6f4b2c2978892f3e3789d1c125e5"}, - {file = "coverage-7.10.7-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:240af60539987ced2c399809bd34f7c78e8abe0736af91c3d7d0e795df633d17"}, - {file = "coverage-7.10.7-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8421e088bc051361b01c4b3a50fd39a4b9133079a2229978d9d30511fd05231b"}, - {file = "coverage-7.10.7-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6be8ed3039ae7f7ac5ce058c308484787c86e8437e72b30bf5e88b8ea10f3c87"}, - {file = "coverage-7.10.7-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e28299d9f2e889e6d51b1f043f58d5f997c373cc12e6403b90df95b8b047c13e"}, - {file = "coverage-7.10.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c4e16bd7761c5e454f4efd36f345286d6f7c5fa111623c355691e2755cae3b9e"}, - {file = "coverage-7.10.7-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b1c81d0e5e160651879755c9c675b974276f135558cf4ba79fee7b8413a515df"}, - {file = "coverage-7.10.7-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:606cc265adc9aaedcc84f1f064f0e8736bc45814f15a357e30fca7ecc01504e0"}, - {file = "coverage-7.10.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:10b24412692df990dbc34f8fb1b6b13d236ace9dfdd68df5b28c2e39cafbba13"}, - {file = "coverage-7.10.7-cp310-cp310-win32.whl", hash = "sha256:b51dcd060f18c19290d9b8a9dd1e0181538df2ce0717f562fff6cf74d9fc0b5b"}, - {file = "coverage-7.10.7-cp310-cp310-win_amd64.whl", hash = "sha256:3a622ac801b17198020f09af3eaf45666b344a0d69fc2a6ffe2ea83aeef1d807"}, - {file = "coverage-7.10.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a609f9c93113be646f44c2a0256d6ea375ad047005d7f57a5c15f614dc1b2f59"}, - {file = "coverage-7.10.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:65646bb0359386e07639c367a22cf9b5bf6304e8630b565d0626e2bdf329227a"}, - {file = "coverage-7.10.7-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:5f33166f0dfcce728191f520bd2692914ec70fac2713f6bf3ce59c3deacb4699"}, - {file = "coverage-7.10.7-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:35f5e3f9e455bb17831876048355dca0f758b6df22f49258cb5a91da23ef437d"}, - {file = "coverage-7.10.7-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4da86b6d62a496e908ac2898243920c7992499c1712ff7c2b6d837cc69d9467e"}, - {file = "coverage-7.10.7-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6b8b09c1fad947c84bbbc95eca841350fad9cbfa5a2d7ca88ac9f8d836c92e23"}, - {file = "coverage-7.10.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4376538f36b533b46f8971d3a3e63464f2c7905c9800db97361c43a2b14792ab"}, - {file = "coverage-7.10.7-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:121da30abb574f6ce6ae09840dae322bef734480ceafe410117627aa54f76d82"}, - {file = "coverage-7.10.7-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:88127d40df529336a9836870436fc2751c339fbaed3a836d42c93f3e4bd1d0a2"}, - {file = "coverage-7.10.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ba58bbcd1b72f136080c0bccc2400d66cc6115f3f906c499013d065ac33a4b61"}, - {file = "coverage-7.10.7-cp311-cp311-win32.whl", hash = "sha256:972b9e3a4094b053a4e46832b4bc829fc8a8d347160eb39d03f1690316a99c14"}, - {file = "coverage-7.10.7-cp311-cp311-win_amd64.whl", hash = "sha256:a7b55a944a7f43892e28ad4bc0561dfd5f0d73e605d1aa5c3c976b52aea121d2"}, - {file = "coverage-7.10.7-cp311-cp311-win_arm64.whl", hash = "sha256:736f227fb490f03c6488f9b6d45855f8e0fd749c007f9303ad30efab0e73c05a"}, - {file = "coverage-7.10.7-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7bb3b9ddb87ef7725056572368040c32775036472d5a033679d1fa6c8dc08417"}, - {file = "coverage-7.10.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:18afb24843cbc175687225cab1138c95d262337f5473512010e46831aa0c2973"}, - {file = "coverage-7.10.7-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:399a0b6347bcd3822be369392932884b8216d0944049ae22925631a9b3d4ba4c"}, - {file = "coverage-7.10.7-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:314f2c326ded3f4b09be11bc282eb2fc861184bc95748ae67b360ac962770be7"}, - {file = "coverage-7.10.7-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c41e71c9cfb854789dee6fc51e46743a6d138b1803fab6cb860af43265b42ea6"}, - {file = "coverage-7.10.7-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc01f57ca26269c2c706e838f6422e2a8788e41b3e3c65e2f41148212e57cd59"}, - {file = "coverage-7.10.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a6442c59a8ac8b85812ce33bc4d05bde3fb22321fa8294e2a5b487c3505f611b"}, - {file = "coverage-7.10.7-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:78a384e49f46b80fb4c901d52d92abe098e78768ed829c673fbb53c498bef73a"}, - {file = "coverage-7.10.7-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:5e1e9802121405ede4b0133aa4340ad8186a1d2526de5b7c3eca519db7bb89fb"}, - {file = "coverage-7.10.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d41213ea25a86f69efd1575073d34ea11aabe075604ddf3d148ecfec9e1e96a1"}, - {file = "coverage-7.10.7-cp312-cp312-win32.whl", hash = "sha256:77eb4c747061a6af8d0f7bdb31f1e108d172762ef579166ec84542f711d90256"}, - {file = "coverage-7.10.7-cp312-cp312-win_amd64.whl", hash = "sha256:f51328ffe987aecf6d09f3cd9d979face89a617eacdaea43e7b3080777f647ba"}, - {file = "coverage-7.10.7-cp312-cp312-win_arm64.whl", hash = "sha256:bda5e34f8a75721c96085903c6f2197dc398c20ffd98df33f866a9c8fd95f4bf"}, - {file = "coverage-7.10.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:981a651f543f2854abd3b5fcb3263aac581b18209be49863ba575de6edf4c14d"}, - {file = "coverage-7.10.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:73ab1601f84dc804f7812dc297e93cd99381162da39c47040a827d4e8dafe63b"}, - {file = "coverage-7.10.7-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:a8b6f03672aa6734e700bbcd65ff050fd19cddfec4b031cc8cf1c6967de5a68e"}, - {file = "coverage-7.10.7-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:10b6ba00ab1132a0ce4428ff68cf50a25efd6840a42cdf4239c9b99aad83be8b"}, - {file = "coverage-7.10.7-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c79124f70465a150e89340de5963f936ee97097d2ef76c869708c4248c63ca49"}, - {file = "coverage-7.10.7-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:69212fbccdbd5b0e39eac4067e20a4a5256609e209547d86f740d68ad4f04911"}, - {file = "coverage-7.10.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7ea7c6c9d0d286d04ed3541747e6597cbe4971f22648b68248f7ddcd329207f0"}, - {file = "coverage-7.10.7-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b9be91986841a75042b3e3243d0b3cb0b2434252b977baaf0cd56e960fe1e46f"}, - {file = "coverage-7.10.7-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:b281d5eca50189325cfe1f365fafade89b14b4a78d9b40b05ddd1fc7d2a10a9c"}, - {file = "coverage-7.10.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:99e4aa63097ab1118e75a848a28e40d68b08a5e19ce587891ab7fd04475e780f"}, - {file = "coverage-7.10.7-cp313-cp313-win32.whl", hash = "sha256:dc7c389dce432500273eaf48f410b37886be9208b2dd5710aaf7c57fd442c698"}, - {file = "coverage-7.10.7-cp313-cp313-win_amd64.whl", hash = "sha256:cac0fdca17b036af3881a9d2729a850b76553f3f716ccb0360ad4dbc06b3b843"}, - {file = "coverage-7.10.7-cp313-cp313-win_arm64.whl", hash = "sha256:4b6f236edf6e2f9ae8fcd1332da4e791c1b6ba0dc16a2dc94590ceccb482e546"}, - {file = "coverage-7.10.7-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a0ec07fd264d0745ee396b666d47cef20875f4ff2375d7c4f58235886cc1ef0c"}, - {file = "coverage-7.10.7-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:dd5e856ebb7bfb7672b0086846db5afb4567a7b9714b8a0ebafd211ec7ce6a15"}, - {file = "coverage-7.10.7-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:f57b2a3c8353d3e04acf75b3fed57ba41f5c0646bbf1d10c7c282291c97936b4"}, - {file = "coverage-7.10.7-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:1ef2319dd15a0b009667301a3f84452a4dc6fddfd06b0c5c53ea472d3989fbf0"}, - {file = "coverage-7.10.7-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:83082a57783239717ceb0ad584de3c69cf581b2a95ed6bf81ea66034f00401c0"}, - {file = "coverage-7.10.7-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:50aa94fb1fb9a397eaa19c0d5ec15a5edd03a47bf1a3a6111a16b36e190cff65"}, - {file = "coverage-7.10.7-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:2120043f147bebb41c85b97ac45dd173595ff14f2a584f2963891cbcc3091541"}, - {file = "coverage-7.10.7-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:2fafd773231dd0378fdba66d339f84904a8e57a262f583530f4f156ab83863e6"}, - {file = "coverage-7.10.7-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:0b944ee8459f515f28b851728ad224fa2d068f1513ef6b7ff1efafeb2185f999"}, - {file = "coverage-7.10.7-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4b583b97ab2e3efe1b3e75248a9b333bd3f8b0b1b8e5b45578e05e5850dfb2c2"}, - {file = "coverage-7.10.7-cp313-cp313t-win32.whl", hash = "sha256:2a78cd46550081a7909b3329e2266204d584866e8d97b898cd7fb5ac8d888b1a"}, - {file = "coverage-7.10.7-cp313-cp313t-win_amd64.whl", hash = "sha256:33a5e6396ab684cb43dc7befa386258acb2d7fae7f67330ebb85ba4ea27938eb"}, - {file = "coverage-7.10.7-cp313-cp313t-win_arm64.whl", hash = "sha256:86b0e7308289ddde73d863b7683f596d8d21c7d8664ce1dee061d0bcf3fbb4bb"}, - {file = "coverage-7.10.7-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:b06f260b16ead11643a5a9f955bd4b5fd76c1a4c6796aeade8520095b75de520"}, - {file = "coverage-7.10.7-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:212f8f2e0612778f09c55dd4872cb1f64a1f2b074393d139278ce902064d5b32"}, - {file = "coverage-7.10.7-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3445258bcded7d4aa630ab8296dea4d3f15a255588dd535f980c193ab6b95f3f"}, - {file = "coverage-7.10.7-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:bb45474711ba385c46a0bfe696c695a929ae69ac636cda8f532be9e8c93d720a"}, - {file = "coverage-7.10.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:813922f35bd800dca9994c5971883cbc0d291128a5de6b167c7aa697fcf59360"}, - {file = "coverage-7.10.7-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:93c1b03552081b2a4423091d6fb3787265b8f86af404cff98d1b5342713bdd69"}, - {file = "coverage-7.10.7-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:cc87dd1b6eaf0b848eebb1c86469b9f72a1891cb42ac7adcfbce75eadb13dd14"}, - {file = "coverage-7.10.7-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:39508ffda4f343c35f3236fe8d1a6634a51f4581226a1262769d7f970e73bffe"}, - {file = "coverage-7.10.7-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:925a1edf3d810537c5a3abe78ec5530160c5f9a26b1f4270b40e62cc79304a1e"}, - {file = "coverage-7.10.7-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2c8b9a0636f94c43cd3576811e05b89aa9bc2d0a85137affc544ae5cb0e4bfbd"}, - {file = "coverage-7.10.7-cp314-cp314-win32.whl", hash = "sha256:b7b8288eb7cdd268b0304632da8cb0bb93fadcfec2fe5712f7b9cc8f4d487be2"}, - {file = "coverage-7.10.7-cp314-cp314-win_amd64.whl", hash = "sha256:1ca6db7c8807fb9e755d0379ccc39017ce0a84dcd26d14b5a03b78563776f681"}, - {file = "coverage-7.10.7-cp314-cp314-win_arm64.whl", hash = "sha256:097c1591f5af4496226d5783d036bf6fd6cd0cbc132e071b33861de756efb880"}, - {file = "coverage-7.10.7-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:a62c6ef0d50e6de320c270ff91d9dd0a05e7250cac2a800b7784bae474506e63"}, - {file = "coverage-7.10.7-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:9fa6e4dd51fe15d8738708a973470f67a855ca50002294852e9571cdbd9433f2"}, - {file = "coverage-7.10.7-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:8fb190658865565c549b6b4706856d6a7b09302c797eb2cf8e7fe9dabb043f0d"}, - {file = "coverage-7.10.7-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:affef7c76a9ef259187ef31599a9260330e0335a3011732c4b9effa01e1cd6e0"}, - {file = "coverage-7.10.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e16e07d85ca0cf8bafe5f5d23a0b850064e8e945d5677492b06bbe6f09cc699"}, - {file = "coverage-7.10.7-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:03ffc58aacdf65d2a82bbeb1ffe4d01ead4017a21bfd0454983b88ca73af94b9"}, - {file = "coverage-7.10.7-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:1b4fd784344d4e52647fd7857b2af5b3fbe6c239b0b5fa63e94eb67320770e0f"}, - {file = "coverage-7.10.7-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:0ebbaddb2c19b71912c6f2518e791aa8b9f054985a0769bdb3a53ebbc765c6a1"}, - {file = "coverage-7.10.7-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:a2d9a3b260cc1d1dbdb1c582e63ddcf5363426a1a68faa0f5da28d8ee3c722a0"}, - {file = "coverage-7.10.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a3cc8638b2480865eaa3926d192e64ce6c51e3d29c849e09d5b4ad95efae5399"}, - {file = "coverage-7.10.7-cp314-cp314t-win32.whl", hash = "sha256:67f8c5cbcd3deb7a60b3345dffc89a961a484ed0af1f6f73de91705cc6e31235"}, - {file = "coverage-7.10.7-cp314-cp314t-win_amd64.whl", hash = "sha256:e1ed71194ef6dea7ed2d5cb5f7243d4bcd334bfb63e59878519be558078f848d"}, - {file = "coverage-7.10.7-cp314-cp314t-win_arm64.whl", hash = "sha256:7fe650342addd8524ca63d77b2362b02345e5f1a093266787d210c70a50b471a"}, - {file = "coverage-7.10.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fff7b9c3f19957020cac546c70025331113d2e61537f6e2441bc7657913de7d3"}, - {file = "coverage-7.10.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:bc91b314cef27742da486d6839b677b3f2793dfe52b51bbbb7cf736d5c29281c"}, - {file = "coverage-7.10.7-cp39-cp39-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:567f5c155eda8df1d3d439d40a45a6a5f029b429b06648235f1e7e51b522b396"}, - {file = "coverage-7.10.7-cp39-cp39-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2af88deffcc8a4d5974cf2d502251bc3b2db8461f0b66d80a449c33757aa9f40"}, - {file = "coverage-7.10.7-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c7315339eae3b24c2d2fa1ed7d7a38654cba34a13ef19fbcb9425da46d3dc594"}, - {file = "coverage-7.10.7-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:912e6ebc7a6e4adfdbb1aec371ad04c68854cd3bf3608b3514e7ff9062931d8a"}, - {file = "coverage-7.10.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f49a05acd3dfe1ce9715b657e28d138578bc40126760efb962322c56e9ca344b"}, - {file = "coverage-7.10.7-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:cce2109b6219f22ece99db7644b9622f54a4e915dad65660ec435e89a3ea7cc3"}, - {file = "coverage-7.10.7-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:f3c887f96407cea3916294046fc7dab611c2552beadbed4ea901cbc6a40cc7a0"}, - {file = "coverage-7.10.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:635adb9a4507c9fd2ed65f39693fa31c9a3ee3a8e6dc64df033e8fdf52a7003f"}, - {file = "coverage-7.10.7-cp39-cp39-win32.whl", hash = "sha256:5a02d5a850e2979b0a014c412573953995174743a3f7fa4ea5a6e9a3c5617431"}, - {file = "coverage-7.10.7-cp39-cp39-win_amd64.whl", hash = "sha256:c134869d5ffe34547d14e174c866fd8fe2254918cc0a95e99052903bc1543e07"}, - {file = "coverage-7.10.7-py3-none-any.whl", hash = "sha256:f7941f6f2fe6dd6807a1208737b8a0cbcf1cc6d7b07d24998ad2d63590868260"}, - {file = "coverage-7.10.7.tar.gz", hash = "sha256:f4ab143ab113be368a3e9b795f9cd7906c5ef407d6173fe9675a902e1fffc239"}, -] - -[package.extras] -toml = ["tomli ; python_full_version <= \"3.11.0a6\""] - [[package]] name = "coverage" version = "7.11.0" @@ -486,7 +368,6 @@ description = "Code coverage measurement for Python" optional = false python-versions = ">=3.10" groups = ["dev"] -markers = "python_version >= \"3.11\"" files = [ {file = "coverage-7.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:eb53f1e8adeeb2e78962bade0c08bfdc461853c7969706ed901821e009b35e31"}, {file = "coverage-7.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d9a03ec6cb9f40a5c360f138b88266fd8f58408d71e89f536b4f91d85721d075"}, @@ -659,7 +540,7 @@ description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" groups = ["dev"] -markers = "python_version < \"3.11\"" +markers = "python_version == \"3.10\"" files = [ {file = "exceptiongroup-1.3.0-py3-none-any.whl", hash = "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10"}, {file = "exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88"}, @@ -745,55 +626,6 @@ markers = {main = "extra == \"optionals\""} [package.extras] all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] -[[package]] -name = "importlib-metadata" -version = "8.5.0" -description = "Read metadata from Python packages" -optional = false -python-versions = ">=3.8" -groups = ["dev", "docs"] -markers = "python_version == \"3.9\"" -files = [ - {file = "importlib_metadata-8.5.0-py3-none-any.whl", hash = "sha256:45e54197d28b7a7f1559e60b95e7c567032b602131fbd588f1497f47880aa68b"}, - {file = "importlib_metadata-8.5.0.tar.gz", hash = "sha256:71522656f0abace1d072b9e5481a48f07c138e00f079c38c8f883823f9c26bd7"}, -] - -[package.dependencies] -zipp = ">=3.20" - -[package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] -cover = ["pytest-cov"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -enabler = ["pytest-enabler (>=2.2)"] -perf = ["ipython"] -test = ["flufl.flake8", "importlib-resources (>=1.3) ; python_version < \"3.9\"", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"] -type = ["pytest-mypy"] - -[[package]] -name = "importlib-resources" -version = "6.4.5" -description = "Read resources from Python packages" -optional = false -python-versions = ">=3.8" -groups = ["dev"] -markers = "python_version == \"3.9\"" -files = [ - {file = "importlib_resources-6.4.5-py3-none-any.whl", hash = "sha256:ac29d5f956f01d5e4bb63102a5a19957f1b9175e45649977264a1416783bb717"}, - {file = "importlib_resources-6.4.5.tar.gz", hash = "sha256:980862a1d16c9e147a59603677fa2aa5fd82b87f223b6cb870695bcfce830065"}, -] - -[package.dependencies] -zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} - -[package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] -cover = ["pytest-cov"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -enabler = ["pytest-enabler (>=2.2)"] -test = ["jaraco.test (>=5.4)", "pytest (>=6,!=8.1.*)", "zipp (>=3.17)"] -type = ["pytest-mypy"] - [[package]] name = "iniconfig" version = "2.1.0" @@ -1052,9 +884,6 @@ files = [ {file = "markdown-3.7.tar.gz", hash = "sha256:2ae2471477cfd02dbbf038d5d9bc226d40def84b4fe2986e49b59b6b472bbed2"}, ] -[package.dependencies] -importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} - [package.extras] docs = ["mdx-gh-links (>=0.2)", "mkdocs (>=1.5)", "mkdocs-gen-files", "mkdocs-literate-nav", "mkdocs-nature (>=0.6)", "mkdocs-section-index", "mkdocstrings[python]"] testing = ["coverage", "pyyaml"] @@ -1202,7 +1031,6 @@ files = [ click = ">=7.0" colorama = {version = ">=0.4", markers = "platform_system == \"Windows\""} ghp-import = ">=1.0" -importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} jinja2 = ">=2.11.1" markdown = ">=3.3.6" markupsafe = ">=2.0.1" @@ -1263,7 +1091,6 @@ files = [ ] [package.dependencies] -importlib-metadata = {version = ">=4.3", markers = "python_version < \"3.10\""} mergedeep = ">=1.3.4" platformdirs = ">=2.2.0" pyyaml = ">=5.1" @@ -1408,7 +1235,6 @@ files = [ [package.dependencies] click = ">=7.0" -importlib-metadata = {version = ">=4.6", markers = "python_version < \"3.10\""} Jinja2 = ">=2.11.1" Markdown = ">=3.6" MarkupSafe = ">=1.1" @@ -1416,7 +1242,6 @@ mkdocs = ">=1.4" mkdocs-autorefs = ">=1.2" platformdirs = ">=2.2" pymdown-extensions = ">=6.3" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.10\""} [package.extras] crystal = ["mkdocstrings-crystal (>=0.3.4)"] @@ -1803,7 +1628,6 @@ mccabe = ">=0.6,<0.8" platformdirs = ">=2.2.0" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} tomlkit = ">=0.10.1" -typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""} [package.extras] spelling = ["pyenchant (>=3.2,<4.0)"] @@ -2270,22 +2094,6 @@ files = [ [package.extras] widechars = ["wcwidth"] -[[package]] -name = "termcolor" -version = "3.1.0" -description = "ANSI color formatting for output in terminal" -optional = false -python-versions = ">=3.9" -groups = ["docs"] -markers = "python_version < \"3.11\"" -files = [ - {file = "termcolor-3.1.0-py3-none-any.whl", hash = "sha256:591dd26b5c2ce03b9e43f391264626557873ce1d379019786f99b0c2bee140aa"}, - {file = "termcolor-3.1.0.tar.gz", hash = "sha256:6a6dd7fbee581909eeec6a756cff1d7f7c376063b14e4a298dc4980309e55970"}, -] - -[package.extras] -tests = ["pytest", "pytest-cov"] - [[package]] name = "termcolor" version = "3.2.0" @@ -2293,7 +2101,6 @@ description = "ANSI color formatting for output in terminal" optional = false python-versions = ">=3.10" groups = ["docs"] -markers = "python_version >= \"3.11\"" files = [ {file = "termcolor-3.2.0-py3-none-any.whl", hash = "sha256:a10343879eba4da819353c55cb8049b0933890c2ebf9ad5d3ecd2bb32ea96ea6"}, {file = "termcolor-3.2.0.tar.gz", hash = "sha256:610e6456feec42c4bcd28934a8c87a06c3fa28b01561d46aa09a9881b8622c58"}, @@ -2338,7 +2145,7 @@ description = "A lil' TOML parser" optional = false python-versions = ">=3.8" groups = ["dev"] -markers = "python_version < \"3.11\"" +markers = "python_version == \"3.10\"" files = [ {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, @@ -2400,8 +2207,6 @@ files = [ [package.dependencies] click = "*" -importlib-metadata = {version = ">=4.6", markers = "python_version < \"3.10\""} -importlib-resources = {version = ">=5", markers = "python_version < \"3.10\""} jinja2 = "*" tomli = {version = "*", markers = "python_version < \"3.11\""} @@ -2470,12 +2275,12 @@ version = "4.13.2" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" -groups = ["main", "dev", "docs"] +groups = ["main", "dev"] files = [ {file = "typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c"}, {file = "typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef"}, ] -markers = {main = "extra == \"optionals\"", docs = "python_version == \"3.9\""} +markers = {main = "extra == \"optionals\""} [[package]] name = "urllib3" @@ -2579,31 +2384,10 @@ files = [ [package.dependencies] pyyaml = "*" -[[package]] -name = "zipp" -version = "3.20.2" -description = "Backport of pathlib-compatible object wrapper for zip files" -optional = false -python-versions = ">=3.8" -groups = ["dev", "docs"] -markers = "python_version == \"3.9\"" -files = [ - {file = "zipp-3.20.2-py3-none-any.whl", hash = "sha256:a817ac80d6cf4b23bf7f2828b7cabf326f15a001bea8b1f9b49631780ba28350"}, - {file = "zipp-3.20.2.tar.gz", hash = "sha256:bc9eb26f4506fda01b81bcde0ca78103b6e62f991b381fec825435c836edbc29"}, -] - -[package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] -cover = ["pytest-cov"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -enabler = ["pytest-enabler (>=2.2)"] -test = ["big-O", "importlib-resources ; python_version < \"3.9\"", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] -type = ["pytest-mypy"] - [extras] optionals = ["jsonschema", "legacycrypt", "napalm"] [metadata] lock-version = "2.1" -python-versions = ">=3.9,<3.14" -content-hash = "10ef70aa9d370afe0aacccb79db57c48e45846c8475923eae719e5db733e5f1c" +python-versions = ">=3.10,<3.14" +content-hash = "c4cf31cc632f033968394d1d6ec010ef947a9caca89860db6fdee82b0baec0ae" diff --git a/pyproject.toml b/pyproject.toml index 93821ab4..48389a24 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,6 @@ classifiers = [ "Intended Audience :: Developers", "Development Status :: 5 - Production/Stable", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", @@ -26,7 +25,7 @@ include = [ ] [tool.poetry.dependencies] -python = ">=3.9,<3.14" +python = ">=3.10,<3.14" napalm = {version = "^4.0.0", optional = true} jsonschema = {version = "^4.17.3", optional = true} legacycrypt = {version = "0.3", optional = true} @@ -77,7 +76,7 @@ mkdocs-python-classy = "0.1.3" [tool.ruff] line-length = 120 -target-version = "py39" +target-version = "py310" [tool.ruff.lint] select = [ @@ -177,6 +176,11 @@ template = "towncrier_template.j2" start_string = "" issue_format = "[#{issue}](https://github.com/networktocode/netutils/issues/{issue})" +[[tool.towncrier.type]] +directory = "breaking" +name = "Breaking Changes" +showcontent = true + [[tool.towncrier.type]] directory = "security" name = "Security" diff --git a/tasks.py b/tasks.py index 55122783..01be98f5 100644 --- a/tasks.py +++ b/tasks.py @@ -36,7 +36,7 @@ def is_truthy(arg): { "netutils": { "project_name": "netutils", - "python_ver": "3.9", + "python_ver": "3.10", "local": is_truthy(os.getenv("INVOKE_NETUTILS_LOCAL", "false")), "image_name": "netutils", "image_ver": os.getenv("INVOKE_PARSER_IMAGE_VER", "latest"), diff --git a/tests/integration/__init__.py b/tests/integration/__init__.py index e69de29b..c66cd71b 100644 --- a/tests/integration/__init__.py +++ b/tests/integration/__init__.py @@ -0,0 +1 @@ +"""Integration tests package.""" diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py index e69de29b..ea3f8b92 100644 --- a/tests/unit/__init__.py +++ b/tests/unit/__init__.py @@ -0,0 +1 @@ +"""Unit tests package.""" diff --git a/tests/unit/test_basics.py b/tests/unit/test_basics.py index 99d07ac7..2c31462e 100644 --- a/tests/unit/test_basics.py +++ b/tests/unit/test_basics.py @@ -1,4 +1,4 @@ -"""Basic tests that do not require netutils.""" +"""Basic tests that do not require Netutils.""" import os import re diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py index e27b1560..82545817 100644 --- a/tests/unit/test_utils.py +++ b/tests/unit/test_utils.py @@ -29,6 +29,7 @@ "jinja2_convenience_function", "import_module", "get_network_driver", + "initialize_logging", ]