diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 18deaa19..6001e213 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 3.5.1 +current_version = 3.10.0 commit = True tag = True @@ -19,8 +19,6 @@ replace = : str = "{new_version}" search = version = "{current_version}" replace = version = "{new_version}" -[bumpversion:file:setup.cfg] -search = version = {current_version} -replace = version = {new_version} - [bumpversion:file:.github/workflows/conda_ci.yml] +search = ={current_version}=py_1 +replace = ={new_version}=py_1 diff --git a/.dependabot/config.yml b/.dependabot/config.yml deleted file mode 100644 index 45849245..00000000 --- a/.dependabot/config.yml +++ /dev/null @@ -1,9 +0,0 @@ -# This file is managed by 'repo_helper'. Don't edit it directly. ---- -version: 1 -update_configs: -- package_manager: python - directory: / - update_schedule: weekly - default_reviewers: - - domdfcoding diff --git a/.github/dependabot.yml b/.github/dependabot.yml index e769ad3a..454225a2 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -6,5 +6,6 @@ updates: directory: / schedule: interval: weekly + open-pull-requests-limit: 0 reviewers: - domdfcoding diff --git a/.github/workflows/conda_ci.yml b/.github/workflows/conda_ci.yml index dc9c0292..57ba7b59 100644 --- a/.github/workflows/conda_ci.yml +++ b/.github/workflows/conda_ci.yml @@ -12,32 +12,35 @@ permissions: jobs: tests: name: "Conda" - runs-on: ubuntu-18.04 + runs-on: ubuntu-22.04 defaults: run: shell: bash -l {0} steps: - name: Checkout πŸ›ŽοΈ - uses: "actions/checkout@v3" + uses: "actions/checkout@v4" - name: Setup Python 🐍 - uses: "actions/setup-python@v4" + uses: "actions/setup-python@v5" with: - python-version: "3.8" + python-version: "3.11" - name: Setup Conda - uses: conda-incubator/setup-miniconda@v2 + uses: conda-incubator/setup-miniconda@v2.1.1 with: activate-environment: env - conda-build-version: 3.21.0 + conda-build-version: 3.28.4 + miniconda-version: py311_24.1.2-0 + python-version: "3.11" + miniforge-variant: Mambaforge - name: Install dependencies πŸ”§ run: | python -VV python -m site python -m pip install --upgrade pip setuptools wheel - python -m pip install --upgrade "whey-conda" "setuptools!=61.*,>=40.6.0" "wheel>=0.34.2" + python -m pip install --upgrade "whey-conda" "hatch-requirements-txt" # $CONDA is an environment variable pointing to the root of the miniconda directory $CONDA/bin/conda update -n base conda $CONDA/bin/conda config --add channels conda-forge @@ -55,7 +58,7 @@ jobs: - name: "Install package" run: | - $CONDA/bin/conda install -c file://$(pwd)/conda-bld domdf_python_tools=3.5.1=py_1 -y || exit 1 + $CONDA/bin/conda install -c file://$(pwd)/conda-bld domdf_python_tools=3.10.0=py_1 -y || exit 1 - name: "Run Tests" run: | diff --git a/.github/workflows/docs_test_action.yml b/.github/workflows/docs_test_action.yml index b09bde34..8f60ba5a 100644 --- a/.github/workflows/docs_test_action.yml +++ b/.github/workflows/docs_test_action.yml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout πŸ›ŽοΈ - uses: "actions/checkout@v3" + uses: "actions/checkout@v4" - name: Check for changed files uses: dorny/paths-filter@v2 diff --git a/.github/workflows/flake8.yml b/.github/workflows/flake8.yml index 5b6260e7..af1b3940 100644 --- a/.github/workflows/flake8.yml +++ b/.github/workflows/flake8.yml @@ -16,11 +16,11 @@ permissions: jobs: Run: name: "Flake8" - runs-on: "ubuntu-20.04" + runs-on: "ubuntu-22.04" steps: - name: Checkout πŸ›ŽοΈ - uses: "actions/checkout@v3" + uses: "actions/checkout@v4" - name: Check for changed files uses: dorny/paths-filter@v2 @@ -33,9 +33,9 @@ jobs: - name: Setup Python 🐍 if: steps.changes.outputs.code == 'true' - uses: "actions/setup-python@v4" + uses: "actions/setup-python@v5" with: - python-version: "3.6" + python-version: "3.8" - name: Install dependencies πŸ”§ if: steps.changes.outputs.code == 'true' diff --git a/.github/workflows/mypy.yml b/.github/workflows/mypy.yml index 882a62f4..bd74787b 100644 --- a/.github/workflows/mypy.yml +++ b/.github/workflows/mypy.yml @@ -20,12 +20,12 @@ jobs: strategy: matrix: - os: ['ubuntu-20.04', 'windows-2019'] + os: ['ubuntu-22.04', 'windows-2019'] fail-fast: false steps: - name: Checkout πŸ›ŽοΈ - uses: "actions/checkout@v3" + uses: "actions/checkout@v4" - name: Check for changed files uses: dorny/paths-filter@v2 @@ -38,9 +38,9 @@ jobs: - name: Setup Python 🐍 if: steps.changes.outputs.code == 'true' - uses: "actions/setup-python@v4" + uses: "actions/setup-python@v5" with: - python-version: "3.6" + python-version: "3.8" - name: Install dependencies πŸ”§ run: | diff --git a/.github/workflows/python_ci.yml b/.github/workflows/python_ci.yml index abbed83c..f6491d97 100644 --- a/.github/workflows/python_ci.yml +++ b/.github/workflows/python_ci.yml @@ -22,27 +22,27 @@ jobs: runs-on: "windows-2019" continue-on-error: ${{ matrix.config.experimental }} env: - USING_COVERAGE: '3.6,3.7,3.8,3.9,3.10,3.11,3.12.0-alpha.3,pypy-3.6,pypy-3.7,pypy-3.8,pypy-3.9' + USING_COVERAGE: '3.7,3.8,3.9,3.10,3.11,3.12,3.13,pypy-3.7,pypy-3.8,pypy-3.9,pypy-3.10' strategy: fail-fast: False matrix: config: - - {python-version: "3.6", testenvs: "py36,build", experimental: False} - {python-version: "3.7", testenvs: "py37,build", experimental: False} - {python-version: "3.8", testenvs: "py38,build", experimental: False} - {python-version: "3.9", testenvs: "py39,build", experimental: False} - {python-version: "3.10", testenvs: "py310,build", experimental: False} - {python-version: "3.11", testenvs: "py311,build", experimental: False} - - {python-version: "3.12.0-alpha.3", testenvs: "py312-dev,build", experimental: True} - - {python-version: "pypy-3.6", testenvs: "pypy36,build", experimental: False} - - {python-version: "pypy-3.7", testenvs: "pypy37,build", experimental: True} - - {python-version: "pypy-3.8", testenvs: "pypy38,build", experimental: True} - - {python-version: "pypy-3.9", testenvs: "pypy39", experimental: True} + - {python-version: "3.12", testenvs: "py312,build", experimental: False} + - {python-version: "3.13", testenvs: "py313,build", experimental: False} + - {python-version: "pypy-3.7", testenvs: "pypy37,build", experimental: False} + - {python-version: "pypy-3.8", testenvs: "pypy38,build", experimental: False} + - {python-version: "pypy-3.9-v7.3.15", testenvs: "pypy39,build", experimental: True} + - {python-version: "pypy-3.10-v7.3.15", testenvs: "pypy310,build", experimental: True} steps: - name: Checkout πŸ›ŽοΈ - uses: "actions/checkout@v3" + uses: "actions/checkout@v4" - name: Check for changed files if: startsWith(github.ref, 'refs/tags/') != true @@ -57,7 +57,7 @@ jobs: - name: Setup Python 🐍 id: setup-python if: ${{ steps.changes.outputs.code == 'true' || steps.changes.outcome == 'skipped' }} - uses: "actions/setup-python@v4" + uses: "actions/setup-python@v5" with: python-version: "${{ matrix.config.python-version }}" @@ -74,8 +74,9 @@ jobs: run: python -m tox -e "${{ matrix.config.testenvs }}" -s false - name: "Upload Coverage πŸš€" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ always() && steps.setup-python.outcome == 'success' }} with: name: "coverage-${{ matrix.config.python-version }}" path: .coverage + include-hidden-files: true diff --git a/.github/workflows/python_ci_alt_linux.yml b/.github/workflows/python_ci_alt_linux.yml index 6aa867fd..8401ea3d 100644 --- a/.github/workflows/python_ci_alt_linux.yml +++ b/.github/workflows/python_ci_alt_linux.yml @@ -20,7 +20,7 @@ permissions: jobs: tests: name: "alt-linux / Python ${{ matrix.config.python-version }}" - runs-on: "ubuntu-20.04" + runs-on: "ubuntu-22.04" container: image: ghcr.io/domdfcoding/alt-linux-python:latest continue-on-error: ${{ matrix.config.experimental }} diff --git a/.github/workflows/python_ci_linux.yml b/.github/workflows/python_ci_linux.yml index 35f7b2e4..fb7d97ac 100644 --- a/.github/workflows/python_ci_linux.yml +++ b/.github/workflows/python_ci_linux.yml @@ -19,31 +19,31 @@ permissions: jobs: tests: - name: "ubuntu-20.04 / Python ${{ matrix.config.python-version }}" - runs-on: "ubuntu-20.04" + name: "ubuntu-22.04 / Python ${{ matrix.config.python-version }}" + runs-on: "ubuntu-22.04" continue-on-error: ${{ matrix.config.experimental }} env: - USING_COVERAGE: '3.6,3.7,3.8,3.9,3.10,3.11,3.12.0-alpha.3,pypy-3.6,pypy-3.7,pypy-3.8,pypy-3.9' + USING_COVERAGE: '3.7,3.8,3.9,3.10,3.11,3.12,3.13,pypy-3.7,pypy-3.8,pypy-3.9,pypy-3.10' strategy: fail-fast: False matrix: config: - - {python-version: "3.6", testenvs: "py36,build", experimental: False} - {python-version: "3.7", testenvs: "py37,build", experimental: False} - {python-version: "3.8", testenvs: "py38,build", experimental: False} - {python-version: "3.9", testenvs: "py39,build", experimental: False} - {python-version: "3.10", testenvs: "py310,build", experimental: False} - {python-version: "3.11", testenvs: "py311,build", experimental: False} - - {python-version: "3.12.0-alpha.3", testenvs: "py312-dev,build", experimental: True} - - {python-version: "pypy-3.6", testenvs: "pypy36,build", experimental: False} - - {python-version: "pypy-3.7", testenvs: "pypy37,build", experimental: True} - - {python-version: "pypy-3.8", testenvs: "pypy38,build", experimental: True} - - {python-version: "pypy-3.9", testenvs: "pypy39", experimental: True} + - {python-version: "3.12", testenvs: "py312,build", experimental: False} + - {python-version: "3.13", testenvs: "py313,build", experimental: False} + - {python-version: "pypy-3.7", testenvs: "pypy37,build", experimental: False} + - {python-version: "pypy-3.8", testenvs: "pypy38,build", experimental: False} + - {python-version: "pypy-3.9", testenvs: "pypy39,build", experimental: True} + - {python-version: "pypy-3.10", testenvs: "pypy310,build", experimental: True} steps: - name: Checkout πŸ›ŽοΈ - uses: "actions/checkout@v3" + uses: "actions/checkout@v4" - name: Check for changed files if: startsWith(github.ref, 'refs/tags/') != true @@ -58,7 +58,7 @@ jobs: - name: Setup Python 🐍 id: setup-python if: ${{ steps.changes.outputs.code == 'true' || steps.changes.outcome == 'skipped' }} - uses: "actions/setup-python@v4" + uses: "actions/setup-python@v5" with: python-version: "${{ matrix.config.python-version }}" @@ -76,22 +76,23 @@ jobs: run: python -m tox -e "${{ matrix.config.testenvs }}" -s false - name: "Upload Coverage πŸš€" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ always() && steps.setup-python.outcome == 'success' }} with: name: "coverage-${{ matrix.config.python-version }}" path: .coverage + include-hidden-files: true Coverage: needs: tests - runs-on: "ubuntu-20.04" + runs-on: "ubuntu-22.04" steps: - name: Checkout πŸ›ŽοΈ - uses: "actions/checkout@v3" + uses: "actions/checkout@v4" - name: Setup Python 🐍 - uses: "actions/setup-python@v4" + uses: "actions/setup-python@v5" with: python-version: 3.8 @@ -101,7 +102,7 @@ jobs: python -m pip install --upgrade "coveralls>=3.0.0" coverage_pyver_pragma - name: "Download Coverage πŸͺ‚" - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: path: coverage @@ -119,10 +120,11 @@ jobs: - name: "Upload Combined Coverage Artefact πŸš€" if: ${{ steps.show.outcome != 'failure' }} - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: "combined-coverage" path: .coverage + include-hidden-files: true - name: "Upload Combined Coverage to Coveralls" if: ${{ steps.show.outcome != 'failure' }} @@ -134,14 +136,14 @@ jobs: Deploy: needs: tests - runs-on: "ubuntu-20.04" + runs-on: "ubuntu-22.04" steps: - name: Checkout πŸ›ŽοΈ - uses: "actions/checkout@v3" + uses: "actions/checkout@v4" if: startsWith(github.ref, 'refs/tags/') - name: Setup Python 🐍 - uses: "actions/setup-python@v4" + uses: "actions/setup-python@v5" if: startsWith(github.ref, 'refs/tags/') with: python-version: 3.8 @@ -178,33 +180,37 @@ jobs: Conda: needs: deploy - runs-on: "ubuntu-18.04" + runs-on: ubuntu-22.04 if: startsWith(github.ref, 'refs/tags/') || (startsWith(github.event.head_commit.message, 'Bump version') != true) steps: - name: Checkout πŸ›ŽοΈ - uses: "actions/checkout@v3" + uses: "actions/checkout@v4" - name: Setup Python 🐍 - uses: "actions/setup-python@v4" + uses: "actions/setup-python@v5" with: - python-version: 3.8 + python-version: 3.11 - name: Setup Conda - uses: conda-incubator/setup-miniconda@v2 + uses: conda-incubator/setup-miniconda@v2.1.1 with: activate-environment: env - conda-build-version: 3.21.0 + conda-build-version: 3.28.4 + miniconda-version: py311_24.1.2-0 + python-version: "3.11" + miniforge-variant: Mambaforge - name: Install dependencies πŸ”§ run: | python -VV python -m site python -m pip install --upgrade pip setuptools wheel - python -m pip install --upgrade "mkrecipe" "setuptools!=61.*,>=40.6.0" "wheel>=0.34.2" + python -m pip install --upgrade "mkrecipe" "hatch-requirements-txt" # $CONDA is an environment variable pointing to the root of the miniconda directory $CONDA/bin/conda config --set always_yes yes --set changeps1 no $CONDA/bin/conda update -n base conda $CONDA/bin/conda info -a + $CONDA/bin/conda install conda-forge::py-lief=0.14.1 $CONDA/bin/conda config --add channels conda-forge $CONDA/bin/conda config --add channels domdfcoding diff --git a/.github/workflows/python_ci_macos.yml b/.github/workflows/python_ci_macos.yml index 35d27f14..d672cecf 100644 --- a/.github/workflows/python_ci_macos.yml +++ b/.github/workflows/python_ci_macos.yml @@ -18,30 +18,31 @@ permissions: jobs: tests: - name: "macos-latest / Python ${{ matrix.config.python-version }}" - runs-on: "macos-latest" + name: "macos-${{ matrix.config.os-ver }} / Python ${{ matrix.config.python-version }}" + runs-on: "macos-${{ matrix.config.os-ver }}" continue-on-error: ${{ matrix.config.experimental }} env: - USING_COVERAGE: '3.6,3.7,3.8,3.9,3.10,3.11,3.12.0-alpha.3,pypy-3.7,pypy-3.8,pypy-3.9' + USING_COVERAGE: '3.7,3.8,3.9,3.10,3.11,3.12,3.13,pypy-3.7,pypy-3.8,pypy-3.9,pypy-3.10' strategy: fail-fast: False matrix: config: - - {python-version: "3.6", testenvs: "py36,build", experimental: False} - - {python-version: "3.7", testenvs: "py37,build", experimental: False} - - {python-version: "3.8", testenvs: "py38,build", experimental: False} - - {python-version: "3.9", testenvs: "py39,build", experimental: False} - - {python-version: "3.10", testenvs: "py310,build", experimental: False} - - {python-version: "3.11", testenvs: "py311,build", experimental: False} - - {python-version: "3.12.0-alpha.3", testenvs: "py312-dev,build", experimental: True} - - {python-version: "pypy-3.7", testenvs: "pypy37,build", experimental: True} - - {python-version: "pypy-3.8", testenvs: "pypy38,build", experimental: True} - - {python-version: "pypy-3.9", testenvs: "pypy39", experimental: True} + - {python-version: "3.7", os-ver: "13", testenvs: "py37,build", experimental: False} + - {python-version: "3.8", os-ver: "14", testenvs: "py38,build", experimental: False} + - {python-version: "3.9", os-ver: "14", testenvs: "py39,build", experimental: False} + - {python-version: "3.10", os-ver: "14", testenvs: "py310,build", experimental: False} + - {python-version: "3.11", os-ver: "14", testenvs: "py311,build", experimental: False} + - {python-version: "3.12", os-ver: "14", testenvs: "py312,build", experimental: False} + - {python-version: "3.13", os-ver: "14", testenvs: "py313,build", experimental: False} + - {python-version: "pypy-3.7", os-ver: "13", testenvs: "pypy37,build", experimental: False} + - {python-version: "pypy-3.8", os-ver: "14", testenvs: "pypy38,build", experimental: False} + - {python-version: "pypy-3.9", os-ver: "14", testenvs: "pypy39,build", experimental: True} + - {python-version: "pypy-3.10", os-ver: "14", testenvs: "pypy310,build", experimental: True} steps: - name: Checkout πŸ›ŽοΈ - uses: "actions/checkout@v3" + uses: "actions/checkout@v4" - name: Check for changed files if: startsWith(github.ref, 'refs/tags/') != true @@ -56,7 +57,7 @@ jobs: - name: Setup Python 🐍 id: setup-python if: ${{ steps.changes.outputs.code == 'true' || steps.changes.outcome == 'skipped' }} - uses: "actions/setup-python@v4" + uses: "actions/setup-python@v5" with: python-version: "${{ matrix.config.python-version }}" @@ -73,8 +74,9 @@ jobs: run: python -m tox -e "${{ matrix.config.testenvs }}" -s false - name: "Upload Coverage πŸš€" - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ always() && steps.setup-python.outcome == 'success' }} with: name: "coverage-${{ matrix.config.python-version }}" path: .coverage + include-hidden-files: true diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index dd6103ff..bc4c3b7d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -8,7 +8,7 @@ ci: repos: - repo: https://github.com/repo-helper/pyproject-parser - rev: v0.7.0 + rev: v0.13.0 hooks: - id: reformat-pyproject @@ -42,19 +42,19 @@ repos: exclude: ^(doc-source/conf|__pkginfo__|setup|tests/.*)\.py$ - id: bind-requirements - - repo: https://github.com/domdfcoding/flake8-dunder-all - rev: v0.2.2 + - repo: https://github.com/python-formate/flake8-dunder-all + rev: v0.4.1 hooks: - id: ensure-dunder-all files: ^domdf_python_tools/.*\.py$ - repo: https://github.com/domdfcoding/flake2lint - rev: v0.4.2 + rev: v0.4.3 hooks: - id: flake2lint - repo: https://github.com/pre-commit/pygrep-hooks - rev: v1.9.0 + rev: v1.10.0 hooks: - id: python-no-eval - id: rst-backticks @@ -70,24 +70,24 @@ repos: - --keep-runtime-typing - repo: https://github.com/Lucas-C/pre-commit-hooks - rev: v1.3.1 + rev: v1.5.1 hooks: - id: remove-crlf - id: forbid-crlf - repo: https://github.com/python-formate/snippet-fmt - rev: v0.1.4 + rev: v0.1.5 hooks: - id: snippet-fmt - repo: https://github.com/python-formate/formate - rev: v0.4.10 + rev: v0.8.0 hooks: - id: formate exclude: ^(doc-source/conf|__pkginfo__|setup)\.(_)?py$ - - repo: https://github.com/domdfcoding/dep_checker - rev: v0.7.0 + - repo: https://github.com/python-coincidence/dep_checker + rev: v0.8.0 hooks: - id: dep_checker args: diff --git a/.readthedocs.yml b/.readthedocs.yml index 6dfba21c..e73aa4ab 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -9,11 +9,16 @@ formats: - pdf - htmlzip python: - version: 3.8 install: - requirements: requirements.txt - requirements: doc-source/requirements.txt - - method: pip - path: . - extra_requirements: - - all +build: + os: ubuntu-22.04 + tools: + python: '3.9' + jobs: + post_create_environment: + - pip install .[all] + post_install: + - pip install sphinxcontrib-applehelp==1.0.4 sphinxcontrib-devhelp==1.0.2 sphinxcontrib-htmlhelp==2.0.1 + sphinxcontrib-jsmath==1.0.1 sphinxcontrib-qthelp==1.0.3 sphinxcontrib-serializinghtml==1.1.5 diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 4c3b5a2c..35c62f8f 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -38,11 +38,11 @@ Automated tests ------------------- Tests are run with ``tox`` and ``pytest``. -To run tests for a specific Python version, such as Python 3.6: +To run tests for a specific Python version, such as Python 3.10: .. code-block:: bash - $ tox -e py36 + $ tox -e py310 To run tests for all Python versions, simply run: diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index bb6de38a..00000000 --- a/MANIFEST.in +++ /dev/null @@ -1,7 +0,0 @@ -include __pkginfo__.py -include LICENSE -include requirements.txt -prune **/__pycache__ -include domdf_python_tools/google-10000-english-no-swears.txt -recursive-include domdf_python_tools *.pyi -include domdf_python_tools/py.typed diff --git a/README.rst b/README.rst index bdeb6521..641fd161 100644 --- a/README.rst +++ b/README.rst @@ -29,8 +29,8 @@ domdf_python_tools * - Other - |license| |language| |requires| -.. |docs| image:: https://img.shields.io/readthedocs/domdf_python_tools/latest?logo=read-the-docs - :target: https://domdf_python_tools.readthedocs.io/en/latest +.. |docs| image:: https://img.shields.io/readthedocs/domdf-python-tools/latest?logo=read-the-docs + :target: https://domdf-python-tools.readthedocs.io/en/latest :alt: Documentation Build Status .. |docs_check| image:: https://github.com/domdfcoding/domdf_python_tools/workflows/Docs%20Check/badge.svg @@ -100,7 +100,7 @@ domdf_python_tools .. |language| image:: https://img.shields.io/github/languages/top/domdfcoding/domdf_python_tools :alt: GitHub top language -.. |commits-since| image:: https://img.shields.io/github/commits-since/domdfcoding/domdf_python_tools/v3.5.1 +.. |commits-since| image:: https://img.shields.io/github/commits-since/domdfcoding/domdf_python_tools/v3.10.0 :target: https://github.com/domdfcoding/domdf_python_tools/pulse :alt: GitHub commits since tagged version @@ -108,7 +108,7 @@ domdf_python_tools :target: https://github.com/domdfcoding/domdf_python_tools/commit/master :alt: GitHub last commit -.. |maintained| image:: https://img.shields.io/maintenance/yes/2022 +.. |maintained| image:: https://img.shields.io/maintenance/yes/2025 :alt: Maintenance .. |pypi-downloads| image:: https://img.shields.io/pypi/dm/domdf_python_tools diff --git a/doc-source/conf.py b/doc-source/conf.py index 959b96d9..2cca2611 100644 --- a/doc-source/conf.py +++ b/doc-source/conf.py @@ -75,11 +75,32 @@ } +# Fix for pathlib issue with sphinxemoji on Python 3.9 and Sphinx 4.x +def copy_asset_files(app, exc): + # 3rd party + from domdf_python_tools.compat import importlib_resources + from sphinx.util.fileutil import copy_asset + + if exc: + return + + asset_files = ["twemoji.js", "twemoji.css"] + for path in asset_files: + path_str = os.fspath(importlib_resources.files("sphinxemoji") / path) + copy_asset(path_str, os.path.join(app.outdir, "_static")) + + def setup(app): # 3rd party from sphinx_toolbox.latex import better_header_layout + from sphinxemoji import sphinxemoji app.connect("config-inited", lambda app, config: better_header_layout(config)) + app.connect("build-finished", copy_asset_files) + app.add_js_file("https://unpkg.com/twemoji@latest/dist/twemoji.min.js") + app.add_js_file("twemoji.js") + app.add_css_file("twemoji.css") + app.add_transform(sphinxemoji.EmojiSubstitutions) manpages_url = "https://manpages.debian.org/{path}" diff --git a/doc-source/contributing.rst b/doc-source/contributing.rst index f155af05..d3e8a02b 100644 --- a/doc-source/contributing.rst +++ b/doc-source/contributing.rst @@ -37,11 +37,11 @@ Automated tests ------------------- Tests are run with ``tox`` and ``pytest``. -To run tests for a specific Python version, such as Python 3.6: +To run tests for a specific Python version, such as Python 3.10: .. prompt:: bash - tox -e py36 + tox -e py310 To run tests for all Python versions, simply run: diff --git a/doc-source/index.rst b/doc-source/index.rst index 5791318e..12f8540e 100644 --- a/doc-source/index.rst +++ b/doc-source/index.rst @@ -34,7 +34,7 @@ domdf_python_tools - |license| |language| |requires| .. |docs| rtfd-shield:: - :project: domdf_python_tools + :project: domdf-python-tools :alt: Documentation Build Status .. |docs_check| actions-shield:: @@ -108,14 +108,14 @@ domdf_python_tools :alt: GitHub top language .. |commits-since| github-shield:: - :commits-since: v3.5.1 + :commits-since: v3.10.0 :alt: GitHub commits since tagged version .. |commits-latest| github-shield:: :last-commit: :alt: GitHub last commit - .. |maintained| maintained-shield:: 2022 + .. |maintained| maintained-shield:: 2025 :alt: Maintenance .. |pypi-downloads| pypi-shield:: diff --git a/doc-source/requirements.txt b/doc-source/requirements.txt index 584c8d62..254a6964 100644 --- a/doc-source/requirements.txt +++ b/doc-source/requirements.txt @@ -1,24 +1,27 @@ -default-values>=0.5.0 +default-values>=0.6.0 domdf-sphinx-theme>=0.3.0 -extras-require>=0.2.0 -html-section>=0.1.0 -jinja2<3.1 +extras-require>=0.5.0 +html-section>=0.3.0 pandas>=1.1.2 pytest>=6.2.0 pytest-regressions>=2.0.2 pytz>=2019.1 -seed-intersphinx-mapping>=0.3.1 +seed-intersphinx-mapping>=1.2.2 sphinx>=3.0.3 sphinx-autofixture>=0.2.1 sphinx-copybutton>=0.2.12 -sphinx-debuginfo>=0.1.0 +sphinx-debuginfo>=0.2.2 sphinx-highlights>=0.1.0 -sphinx-licenseinfo>=0.1.1 +sphinx-licenseinfo>=0.3.1 sphinx-notfound-page>=0.7.1 -sphinx-prompt>=1.1.0 sphinx-pyproject>=0.1.0 -sphinx-tabs>=1.1.13 -sphinx-toolbox>=3.0.0 +sphinx-toolbox>=3.5.0 +sphinxcontrib-applehelp==1.0.4 +sphinxcontrib-devhelp==1.0.2 +sphinxcontrib-htmlhelp==2.0.1 sphinxcontrib-httpdomain>=1.7.0 +sphinxcontrib-jsmath==1.0.1 +sphinxcontrib-qthelp==1.0.3 +sphinxcontrib-serializinghtml==1.1.5 sphinxemoji>=0.1.6 -toctree-plus>=0.5.0 +toctree-plus>=0.6.1 diff --git a/domdf_python_tools/__init__.py b/domdf_python_tools/__init__.py index 51ce85b2..ee5e90b3 100644 --- a/domdf_python_tools/__init__.py +++ b/domdf_python_tools/__init__.py @@ -29,7 +29,7 @@ __author__: str = "Dominic Davis-Foster" __copyright__: str = "2014-2020 Dominic Davis-Foster" __license__: str = "MIT" -__version__: str = "3.5.1" +__version__: str = "3.10.0" __email__: str = "dominic@davis-foster.co.uk" __docs = False diff --git a/domdf_python_tools/bases.py b/domdf_python_tools/bases.py index c01515d7..d25b380e 100644 --- a/domdf_python_tools/bases.py +++ b/domdf_python_tools/bases.py @@ -106,7 +106,7 @@ def __getstate__(self) -> Dict[str, _V]: return self.__dict__ def __setstate__(self, state): - self.__init__(**state) # type: ignore + self.__init__(**state) # type: ignore[misc] def __copy__(self): return self.__class__(**self.__dict__) @@ -219,7 +219,7 @@ def __setitem__(self, i: int, o: _T) -> None: ... def __setitem__(self, i: slice, o: Iterable[_T]) -> None: ... def __setitem__(self, i: Union[int, slice], item: Union[_T, Iterable[_T]]) -> None: - self.data[i] = item # type: ignore + self.data[i] = item # type: ignore[index, assignment] def __delitem__(self, i: Union[int, slice]): del self.data[i] @@ -422,7 +422,7 @@ def __sub__(self: _F, other: float) -> _F: def __mul__(self: _F, other: float) -> _F: return self.__class__(float(self).__mul__(other)) - def __floordiv__(self: _F, other: float) -> _F: # type: ignore + def __floordiv__(self: _F, other: float) -> _F: # type: ignore[override] return self.__class__(float(self).__floordiv__(other)) def __truediv__(self: _F, other: float) -> _F: @@ -432,7 +432,7 @@ def __mod__(self: _F, other: float) -> _F: return self.__class__(float(self).__mod__(other)) def __divmod__(self: _F, other: float) -> Tuple[_F, _F]: - return tuple(self.__class__(x) for x in float(self).__divmod__(other)) # type: ignore + return tuple(self.__class__(x) for x in float(self).__divmod__(other)) # type: ignore[return-value] def __pow__(self: _F, other: float, mod=None) -> _F: return self.__class__(float(self).__pow__(other, mod)) @@ -446,7 +446,7 @@ def __rsub__(self: _F, other: float) -> _F: def __rmul__(self: _F, other: float) -> _F: return self.__class__(float(self).__rmul__(other)) - def __rfloordiv__(self: _F, other: float) -> _F: # type: ignore + def __rfloordiv__(self: _F, other: float) -> _F: # type: ignore[override] return self.__class__(float(self).__rfloordiv__(other)) def __rtruediv__(self: _F, other: float) -> _F: diff --git a/domdf_python_tools/compat/__init__.py b/domdf_python_tools/compat/__init__.py index 5d9b3bf8..2571ab3b 100644 --- a/domdf_python_tools/compat/__init__.py +++ b/domdf_python_tools/compat/__init__.py @@ -103,7 +103,11 @@ "PYPY39_PLUS", ] -if sys.version_info[:2] < (3, 7) or domdf_python_tools.__docs or TYPE_CHECKING: # pragma: no cover (py37+) +if TYPE_CHECKING: # pragma: no cover + # stdlib + from contextlib import nullcontext + +elif sys.version_info[:2] < (3, 7) or domdf_python_tools.__docs: # pragma: no cover (py37+) _T = TypeVar("_T") diff --git a/domdf_python_tools/compat/importlib_resources.py b/domdf_python_tools/compat/importlib_resources.py index 087d6717..cefee9fb 100644 --- a/domdf_python_tools/compat/importlib_resources.py +++ b/domdf_python_tools/compat/importlib_resources.py @@ -5,7 +5,7 @@ import sys from typing import Any, BinaryIO, TextIO -if sys.version_info[:2] < (3, 7): # pragma: no cover (py37+) +if sys.version_info[:2] < (3, 9): # pragma: no cover (py39+) # 3rd party import importlib_resources @@ -16,7 +16,7 @@ import importlib.resources globals().update(importlib.resources.__dict__) -if not ((3, 7) <= sys.version_info < (3, 11)): # pragma: no cover (py37 OR py38 OR py39 OR py310): +if not ((3, 9) <= sys.version_info < (3, 11)): # pragma: no cover (py39 OR py310): def _normalize_path(path: Any) -> str: """ @@ -30,14 +30,14 @@ def _normalize_path(path: Any) -> str: raise ValueError(f'{path!r} must be only a file name') return file_name - def open_binary(package: Package, resource: Resource) -> BinaryIO: + def open_binary(package: "Package", resource: "Resource") -> BinaryIO: """ Return a file-like object opened for binary reading of the resource. """ return (files(package) / _normalize_path(resource)).open("rb") - def read_binary(package: Package, resource: Resource) -> bytes: + def read_binary(package: "Package", resource: "Resource") -> bytes: """ Return the binary contents of the resource. """ @@ -45,8 +45,8 @@ def read_binary(package: Package, resource: Resource) -> bytes: return (files(package) / _normalize_path(resource)).read_bytes() def open_text( - package: Package, - resource: Resource, + package: "Package", + resource: "Resource", encoding: str = "utf-8", errors: str = "strict", ) -> TextIO: @@ -61,8 +61,8 @@ def open_text( ) def read_text( - package: Package, - resource: Resource, + package: "Package", + resource: "Resource", encoding: str = "utf-8", errors: str = "strict", ) -> str: diff --git a/domdf_python_tools/dates.py b/domdf_python_tools/dates.py index 110114d6..22dc0833 100644 --- a/domdf_python_tools/dates.py +++ b/domdf_python_tools/dates.py @@ -288,7 +288,7 @@ def get_utc_offset( """ if date is None: - date = datetime.datetime.utcnow() + date = datetime.datetime.now(pytz.utc) timezone: Optional[datetime.tzinfo] @@ -313,7 +313,7 @@ def get_timezone(tz: str, date: Optional[datetime.datetime] = None) -> Optional[ """ if date is None: # pragma: no cover (hard to test) - date = datetime.datetime.utcnow() + date = datetime.datetime.now(pytz.utc) d = date.replace(tzinfo=None) @@ -324,7 +324,8 @@ def is_bst(the_date: Union[time.struct_time, datetime.date]) -> bool: """ Calculates whether the given day falls within British Summer Time. - This function should also be applicable to other timezones which change to summer time on the same date (e.g. Central European Summer Time). + This function should also be applicable to other timezones + which change to summer time on the same date (e.g. Central European Summer Time). .. note:: diff --git a/domdf_python_tools/pagesizes/__init__.py b/domdf_python_tools/pagesizes/__init__.py index 347f6f49..2d69859a 100644 --- a/domdf_python_tools/pagesizes/__init__.py +++ b/domdf_python_tools/pagesizes/__init__.py @@ -39,7 +39,7 @@ # # this package -from .classes import * -from .sizes import * -from .units import * -from .utils import * +from .classes import * # noqa: F401 +from .sizes import * # noqa: F401 +from .units import * # noqa: F401 +from .utils import * # noqa: F401 diff --git a/domdf_python_tools/paths.py b/domdf_python_tools/paths.py index a84fdd0f..f7c6b7b3 100644 --- a/domdf_python_tools/paths.py +++ b/domdf_python_tools/paths.py @@ -130,6 +130,7 @@ ".tox4", ".nox", "__pypackages__", + "dosdevices", ) """ A list of directories which will likely be unwanted when searching directory trees for files. @@ -401,12 +402,7 @@ def __new__(cls: Type[_PP], *args, **kwargs) -> _PP: # noqa: D102 if cls is PathPlus: cls = WindowsPathPlus if os.name == "nt" else PosixPathPlus # type: ignore - self = cls._from_parts(args, init=False) - if not self._flavour.is_supported: - raise NotImplementedError(f"cannot instantiate {cls.__name__!r} on your system") - - self._init() - return self + return super().__new__(cls, *args, **kwargs) def make_executable(self) -> None: """ @@ -741,7 +737,7 @@ def is_mount(self) -> bool: if sys.version_info < (3, 8): # pragma: no cover (py38+) - def rename(self: _P, target: Union[str, pathlib.PurePath]) -> _P: # type: ignore + def rename(self: _P, target: Union[str, pathlib.PurePath]) -> _P: """ Rename this path to the target path. @@ -760,7 +756,7 @@ def rename(self: _P, target: Union[str, pathlib.PurePath]) -> _P: # type: ignor os.rename(self, target) return self.__class__(target) - def replace(self: _P, target: Union[str, pathlib.PurePath]) -> _P: # type: ignore + def replace(self: _P, target: Union[str, pathlib.PurePath]) -> _P: """ Rename this path to the target path, overwriting if that path exists. diff --git a/domdf_python_tools/stringlist.py b/domdf_python_tools/stringlist.py index 2d8524ca..4b0c173a 100644 --- a/domdf_python_tools/stringlist.py +++ b/domdf_python_tools/stringlist.py @@ -79,7 +79,7 @@ def size(self) -> int: def size(self, size: int) -> None: self._size = int(size) - @property # noqa: A003 # pylint: disable=redefined-builtin + @property def type(self) -> str: """ The indent character. @@ -87,7 +87,7 @@ def type(self) -> str: return self._type - @type.setter # noqa: A003 # pylint: disable=redefined-builtin + @type.setter def type(self, type: str) -> None: # noqa: A002 # pylint: disable=redefined-builtin if not str(type): raise ValueError("'type' cannot an empty string.") @@ -463,6 +463,18 @@ def with_indent_type(self, indent_type: str = '\t'): finally: self.indent_type = original_indent_type + def splitlines(self, keepends: bool = False) -> List[str]: + """ + Analagous to :meth:`str.splitlines`. + + .. versionadded:: 3.8.0 + """ + + if keepends: + return [line + '\n' for line in self] + else: + return self + class DelimitedList(List[_S]): """ @@ -513,7 +525,7 @@ def splitlines(string: str) -> List[Tuple[str, str]]: while i < str_len: # Find a line and append it - while i < str_len and not string[i] in "\n\r": + while i < str_len and string[i] not in "\n\r": i += 1 # Skip the line break reading CRLF as one line break diff --git a/formate.toml b/formate.toml index b6364ffa..95093bce 100644 --- a/formate.toml +++ b/formate.toml @@ -6,21 +6,17 @@ noqa-reformat = 60 ellipsis-reformat = 70 squish_stubs = 80 -[config] -indent = "\t" -line_length = 115 - [hooks.yapf] priority = 30 -[hooks.isort] -priority = 50 - [hooks.yapf.kwargs] yapf_style = ".style.yapf" +[hooks.isort] +priority = 50 + [hooks.isort.kwargs] -indent = "\t\t" +indent = " " multi_line_output = 8 import_heading_stdlib = "stdlib" import_heading_thirdparty = "3rd party" @@ -56,4 +52,8 @@ known_third_party = [ "requests", "typing_extensions", ] -known_first_party = "domdf_python_tools" +known_first_party = [ "domdf_python_tools",] + +[config] +indent = " " +line_length = 115 diff --git a/pyproject.toml b/pyproject.toml index a04d1883..35144b6f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,10 +1,10 @@ [build-system] -requires = [ "setuptools!=61.*,>=40.6.0", "wheel>=0.34.2",] -build-backend = "setuptools.build_meta" +requires = [ "hatch-requirements-txt",] +build-backend = "hatchling.build" [project] name = "domdf_python_tools" -version = "3.5.1" +version = "3.10.0" description = "Helpful functions for Pythonβ€‚πŸβ€‚πŸ› οΈ" readme = "README.rst" requires-python = ">=3.6" @@ -16,12 +16,13 @@ classifiers = [ "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "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", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Software Development :: Libraries :: Python Modules", @@ -29,19 +30,18 @@ classifiers = [ ] dynamic = [ "dependencies",] +[project.license] +file = "LICENSE" + [[project.authors]] name = "Dominic Davis-Foster" email = "dominic@davis-foster.co.uk" - -[project.license] -file = "LICENSE" - [project.urls] Homepage = "https://github.com/domdfcoding/domdf_python_tools" "Issue Tracker" = "https://github.com/domdfcoding/domdf_python_tools/issues" "Source Code" = "https://github.com/domdfcoding/domdf_python_tools" -Documentation = "https://domdf_python_tools.readthedocs.io/en/latest" +Documentation = "https://domdf-python-tools.readthedocs.io/en/latest" [project.optional-dependencies] dates = [ "pytz>=2019.1",] @@ -74,7 +74,6 @@ extensions = [ "sphinx.ext.mathjax", "sphinxcontrib.extras_require", "sphinx.ext.todo", - "sphinxemoji.sphinxemoji", "notfound.extension", "sphinx_copybutton", "sphinxcontrib.default_values", @@ -88,7 +87,6 @@ extensions = [ "sphinx_toolbox.latex.succinct_seealso", "latex_unicode", ] -sphinxemoji_style = "twemoji" gitstamp_fmt = "%d %b %Y" templates_path = [ "_templates",] html_static_path = [ "_static",] @@ -144,14 +142,14 @@ base-classifiers = [ "Topic :: Software Development :: Libraries :: Python Modules", "Typing :: Typed", ] -python-versions = [ "3.6", "3.7", "3.8", "3.9", "3.10", "3.11",] +python-versions = [ "3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13",] python-implementations = [ "CPython", "PyPy",] platforms = [ "Windows", "macOS", "Linux",] license-key = "MIT" additional-files = [ "include domdf_python_tools/google-10000-english-no-swears.txt",] [tool.mypy] -python_version = "3.6" +python_version = "3.8" namespace_packages = true check_untyped_defs = true warn_unused_ignores = true @@ -161,6 +159,16 @@ show_error_codes = true [tool.snippet-fmt] directives = [ "code-block",] +[tool.snippet-fmt.languages.python] +reformat = true + +[tool.snippet-fmt.languages.TOML] +reformat = true + +[tool.snippet-fmt.languages.ini] + +[tool.snippet-fmt.languages.json] + [tool.setuptools] zip-safe = false include-package-data = true @@ -177,12 +185,21 @@ include = false order = 30 include = false -[tool.snippet-fmt.languages.python] -reformat = true +[tool.hatch.build] +exclude = [ + "/*", + "!/domdf_python_tools", + "!/domdf_python_tools/**/requirements.txt", + "!/requirements.txt", + "tests", + "doc-source", +] -[tool.snippet-fmt.languages.TOML] -reformat = true +[tool.hatch.build.sdist] +include = [ "domdf_python_tools", "requirements.txt",] -[tool.snippet-fmt.languages.ini] +[tool.hatch.build.wheel] +include = [ "domdf_python_tools",] -[tool.snippet-fmt.languages.json] +[tool.hatch.metadata.hooks.requirements_txt] +files = [ "requirements.txt",] diff --git a/repo_helper.yml b/repo_helper.yml index bef9302a..e2f87c8e 100644 --- a/repo_helper.yml +++ b/repo_helper.yml @@ -3,34 +3,34 @@ modname: domdf_python_tools copyright_years: "2019-2022" author: "Dominic Davis-Foster" email: "dominic@davis-foster.co.uk" -version: "3.5.1" +version: "3.10.0" username: "domdfcoding" license: 'MIT' short_desc: 'Helpful functions for Pythonβ€‚πŸβ€‚πŸ› οΈ' -python_deploy_version: 3.6 +python_deploy_version: 3.8 requires_python: 3.6 min_coverage: 95 tox_testenv_extras: all pre_commit_exclude: "^domdf_python_tools/compat/importlib_resources.py$" docs_fail_on_warning: true +use_hatch: true conda_channels: - conda-forge python_versions: - 3.6: 3.7: 3.8: 3.9: "3.10": "3.11": - "3.12-dev": - experimental: true - pypy36: + "3.12": + "3.13": pypy37: pypy38: pypy39: + pypy310: classifiers: - 'Development Status :: 5 - Production/Stable' diff --git a/requirements.txt b/requirements.txt index f228c8da..d38fb0b1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ importlib-metadata>=3.6.0; python_version < "3.9" -importlib-resources>=3.0.0; python_version < "3.7" +importlib-resources>=3.0.0; python_version < "3.9" natsort>=7.0.1 typing-extensions>=3.7.4.1 diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 063a0215..00000000 --- a/setup.cfg +++ /dev/null @@ -1,52 +0,0 @@ -# This file is managed by 'repo_helper'. -# You may add new sections, but any changes made to the following sections will be lost: -# * metadata -# * options -# * options.packages.find -# * mypy -# * options.entry_points - -[metadata] -name = domdf_python_tools -version = 3.5.1 -author = Dominic Davis-Foster -author_email = dominic@davis-foster.co.uk -license = MIT License -keywords = utilities -long_description = file: README.rst -long_description_content_type = text/x-rst -platforms = Windows, macOS, Linux -url = https://github.com/domdfcoding/domdf_python_tools -project_urls = - Documentation = https://domdf_python_tools.readthedocs.io/en/latest - Issue Tracker = https://github.com/domdfcoding/domdf_python_tools/issues - Source Code = https://github.com/domdfcoding/domdf_python_tools -classifiers = - Development Status :: 5 - Production/Stable - Intended Audience :: Developers - License :: OSI Approved :: MIT License - Operating System :: OS Independent - Programming Language :: Python - Programming Language :: Python :: 3 :: Only - Programming Language :: Python :: 3.6 - Programming Language :: Python :: 3.7 - Programming Language :: Python :: 3.8 - Programming Language :: Python :: 3.9 - Programming Language :: Python :: 3.10 - Programming Language :: Python :: 3.11 - Programming Language :: Python :: Implementation :: CPython - Programming Language :: Python :: Implementation :: PyPy - Topic :: Software Development :: Libraries :: Python Modules - Typing :: Typed - -[options] -python_requires = >=3.6 -zip_safe = False -include_package_data = True -packages = find: - -[options.packages.find] -exclude = - doc-source - tests - tests.* diff --git a/setup.py b/setup.py deleted file mode 100644 index 5bed656d..00000000 --- a/setup.py +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env python -# This file is managed by 'repo_helper'. Don't edit it directly. - -# stdlib -import pathlib -import shutil -import sys - -# 3rd party -from setuptools import setup - -sys.path.append('.') - -# this package -from __pkginfo__ import * # pylint: disable=wildcard-import - -repo_root = pathlib.Path(__file__).parent -install_requires = (repo_root / "requirements.txt").read_text(encoding="UTF-8").split('\n') - -setup( - description="Helpful functions for Pythonβ€‚πŸβ€‚πŸ› οΈ", - extras_require=extras_require, - install_requires=install_requires, - name="domdf-python-tools", - py_modules=[], - ) - -shutil.rmtree("domdf_python_tools.egg-info", ignore_errors=True) diff --git a/stubs.txt b/stubs.txt index c181ed15..2471af61 100644 --- a/stubs.txt +++ b/stubs.txt @@ -1,4 +1,3 @@ -git+https://github.com/domdfcoding/natsort-stubs pandas-stubs; implementation_name == "cpython" and python_version < "3.10" types-click types-pytz diff --git a/tests/list_tests.py b/tests/list_tests.py index 5bed3be8..2c6f7050 100644 --- a/tests/list_tests.py +++ b/tests/list_tests.py @@ -74,9 +74,10 @@ def test_repr(self): assert repr(a2) == "[0, 1, 2, [...], 3]" @not_pypy() + @pytest.mark.skipif(sys.version_info >= (3, 12), reason="Doesn't error on newer Pythons") def test_repr_deep(self): a = self.type2test([]) - for i in range(sys.getrecursionlimit() + 100): + for i in range(1500 + 1): # sys.getrecursionlimit() + 100 a = self.type2test([a]) with pytest.raises(RecursionError): repr(a) diff --git a/tests/test_dates.py b/tests/test_dates.py index 0fc5b603..df5d7764 100644 --- a/tests/test_dates.py +++ b/tests/test_dates.py @@ -25,7 +25,7 @@ import pytz test_date = datetime(1996, 10, 13, 2, 20).replace(tzinfo=pytz.utc) - today = datetime.utcnow().replace(tzinfo=pytz.utc) # make sure UTC + today = datetime.now(pytz.utc) # make sure UTC def test_utc_offset(): # Check that the correct UTC offsets are given for common timezones @@ -198,7 +198,7 @@ def test_utc_offset_no_pytz(): # ): # # # this package -# from domdf_python_tools.dates import get_utc_offset # noqa: F401 +# from domdf_python_tools.dates import get_utc_offset @pytest.mark.parametrize("month_idx, month", enumerate(dates.month_full_names)) diff --git a/tests/test_docstrings.py b/tests/test_docstrings.py index f67adaea..049a1965 100644 --- a/tests/test_docstrings.py +++ b/tests/test_docstrings.py @@ -39,4 +39,4 @@ def test_docstrings(module): print(indent(stdout.getvalue(), " ")) if runner.failures: - pytest.fail(msg=f"{runner.failures} tests failed") + pytest.fail(f"{runner.failures} tests failed") diff --git a/tests/test_doctools.py b/tests/test_doctools.py index c47cd2fa..55358b41 100644 --- a/tests/test_doctools.py +++ b/tests/test_doctools.py @@ -8,6 +8,7 @@ # stdlib import math +import sys from typing import Iterable, NamedTuple, get_type_hints # 3rd party @@ -353,7 +354,16 @@ def demo_function(): return math.pi - assert demo_function.__doc__ == """ + if sys.version_info >= (3, 13): + assert demo_function.__doc__ == """ +This is a docstring that contains references to :class:`str`, :class:`int`, and :class:`float` +but lacks proper references to them when rendered in Sphinx. + +:return: pi +:rtype: float +""" + else: + assert demo_function.__doc__ == """ This is a docstring that contains references to :class:`str`, :class:`int`, and :class:`float` but lacks proper references to them when rendered in Sphinx. diff --git a/tests/test_getters.py b/tests/test_getters.py index 9ddd208c..dd433626 100644 --- a/tests/test_getters.py +++ b/tests/test_getters.py @@ -55,13 +55,13 @@ class A: f([a, b]) with pytest.raises(TypeError, match="attribute name must be a string"): - attrgetter(0, 2) # type: ignore + attrgetter(0, 2) # type: ignore[arg-type] with pytest.raises(TypeError, match="'idx' must be an integer"): - attrgetter("hello", 0) # type: ignore + attrgetter("hello", 0) # type: ignore[arg-type] with pytest.raises(TypeError, match=r"__init__\(\) missing 1 required positional argument: 'attr'"): - attrgetter(0) # type: ignore + attrgetter(0) # type: ignore[call-arg] f = attrgetter(1, "name") diff --git a/tests/test_import_tools_/test_iter_submodules_asyncio__3_9_pypy_.yml b/tests/test_import_tools_/test_iter_submodules_asyncio__3_9_pypy_.yml index 5eadfe18..d742bfa1 100644 --- a/tests/test_import_tools_/test_iter_submodules_asyncio__3_9_pypy_.yml +++ b/tests/test_import_tools_/test_iter_submodules_asyncio__3_9_pypy_.yml @@ -4,7 +4,6 @@ - asyncio.base_futures - asyncio.base_subprocess - asyncio.base_tasks -- asyncio.compat - asyncio.constants - asyncio.coroutines - asyncio.events @@ -23,7 +22,6 @@ - asyncio.streams - asyncio.subprocess - asyncio.tasks -- asyncio.test_utils - asyncio.threads - asyncio.transports - asyncio.trsock diff --git a/tests/test_import_tools_/test_iter_submodules_consolekit_3_10_.yml b/tests/test_import_tools_/test_iter_submodules_consolekit_3_10_.yml index c571a184..a20a9ba3 100644 --- a/tests/test_import_tools_/test_iter_submodules_consolekit_3_10_.yml +++ b/tests/test_import_tools_/test_iter_submodules_consolekit_3_10_.yml @@ -1,4 +1,5 @@ - consolekit +- consolekit._readline - consolekit._types - consolekit.commands - consolekit.input @@ -7,3 +8,4 @@ - consolekit.testing - consolekit.tracebacks - consolekit.utils +- consolekit.versions diff --git a/tests/test_import_tools_/test_iter_submodules_consolekit_3_6_.yml b/tests/test_import_tools_/test_iter_submodules_consolekit_3_6_.yml index c571a184..a20a9ba3 100644 --- a/tests/test_import_tools_/test_iter_submodules_consolekit_3_6_.yml +++ b/tests/test_import_tools_/test_iter_submodules_consolekit_3_6_.yml @@ -1,4 +1,5 @@ - consolekit +- consolekit._readline - consolekit._types - consolekit.commands - consolekit.input @@ -7,3 +8,4 @@ - consolekit.testing - consolekit.tracebacks - consolekit.utils +- consolekit.versions diff --git a/tests/test_import_tools_/test_iter_submodules_consolekit_3_7_.yml b/tests/test_import_tools_/test_iter_submodules_consolekit_3_7_.yml index c571a184..a20a9ba3 100644 --- a/tests/test_import_tools_/test_iter_submodules_consolekit_3_7_.yml +++ b/tests/test_import_tools_/test_iter_submodules_consolekit_3_7_.yml @@ -1,4 +1,5 @@ - consolekit +- consolekit._readline - consolekit._types - consolekit.commands - consolekit.input @@ -7,3 +8,4 @@ - consolekit.testing - consolekit.tracebacks - consolekit.utils +- consolekit.versions diff --git a/tests/test_import_tools_/test_iter_submodules_consolekit_3_7_pypy_.yml b/tests/test_import_tools_/test_iter_submodules_consolekit_3_7_pypy_.yml index c571a184..a20a9ba3 100644 --- a/tests/test_import_tools_/test_iter_submodules_consolekit_3_7_pypy_.yml +++ b/tests/test_import_tools_/test_iter_submodules_consolekit_3_7_pypy_.yml @@ -1,4 +1,5 @@ - consolekit +- consolekit._readline - consolekit._types - consolekit.commands - consolekit.input @@ -7,3 +8,4 @@ - consolekit.testing - consolekit.tracebacks - consolekit.utils +- consolekit.versions diff --git a/tests/test_import_tools_/test_iter_submodules_consolekit_3_8_.yml b/tests/test_import_tools_/test_iter_submodules_consolekit_3_8_.yml index c571a184..a20a9ba3 100644 --- a/tests/test_import_tools_/test_iter_submodules_consolekit_3_8_.yml +++ b/tests/test_import_tools_/test_iter_submodules_consolekit_3_8_.yml @@ -1,4 +1,5 @@ - consolekit +- consolekit._readline - consolekit._types - consolekit.commands - consolekit.input @@ -7,3 +8,4 @@ - consolekit.testing - consolekit.tracebacks - consolekit.utils +- consolekit.versions diff --git a/tests/test_import_tools_/test_iter_submodules_consolekit_3_8_pypy_.yml b/tests/test_import_tools_/test_iter_submodules_consolekit_3_8_pypy_.yml index c571a184..a20a9ba3 100644 --- a/tests/test_import_tools_/test_iter_submodules_consolekit_3_8_pypy_.yml +++ b/tests/test_import_tools_/test_iter_submodules_consolekit_3_8_pypy_.yml @@ -1,4 +1,5 @@ - consolekit +- consolekit._readline - consolekit._types - consolekit.commands - consolekit.input @@ -7,3 +8,4 @@ - consolekit.testing - consolekit.tracebacks - consolekit.utils +- consolekit.versions diff --git a/tests/test_import_tools_/test_iter_submodules_consolekit_3_9_.yml b/tests/test_import_tools_/test_iter_submodules_consolekit_3_9_.yml index c571a184..a20a9ba3 100644 --- a/tests/test_import_tools_/test_iter_submodules_consolekit_3_9_.yml +++ b/tests/test_import_tools_/test_iter_submodules_consolekit_3_9_.yml @@ -1,4 +1,5 @@ - consolekit +- consolekit._readline - consolekit._types - consolekit.commands - consolekit.input @@ -7,3 +8,4 @@ - consolekit.testing - consolekit.tracebacks - consolekit.utils +- consolekit.versions diff --git a/tests/test_import_tools_/test_iter_submodules_consolekit_3_9_pypy_.yml b/tests/test_import_tools_/test_iter_submodules_consolekit_3_9_pypy_.yml index c571a184..a20a9ba3 100644 --- a/tests/test_import_tools_/test_iter_submodules_consolekit_3_9_pypy_.yml +++ b/tests/test_import_tools_/test_iter_submodules_consolekit_3_9_pypy_.yml @@ -1,4 +1,5 @@ - consolekit +- consolekit._readline - consolekit._types - consolekit.commands - consolekit.input @@ -7,3 +8,4 @@ - consolekit.testing - consolekit.tracebacks - consolekit.utils +- consolekit.versions diff --git a/tests/test_iterative.py b/tests/test_iterative.py index 06a85c9c..ca7b3524 100644 --- a/tests/test_iterative.py +++ b/tests/test_iterative.py @@ -313,10 +313,10 @@ def test_count(): assert take(2, zip("abc", count(-3))) == [('a', -3), ('b', -2)] with pytest.raises(TypeError, match=r"count\(\) takes from 0 to 2 positional arguments but 3 were given"): - count(2, 3, 4) # type: ignore + count(2, 3, 4) # type: ignore[call-arg] with pytest.raises(TypeError, match="a number is required"): - count('a') # type: ignore + count('a') # type: ignore[type-var] assert take(10, count(sys.maxsize - 5)) == list(range(sys.maxsize - 5, sys.maxsize + 5)) assert take(10, count(-sys.maxsize - 5)) == list(range(-sys.maxsize - 5, -sys.maxsize + 5)) @@ -364,10 +364,10 @@ def test_count_with_stride(): assert lzip("abc", count(step=-1)) == [('a', 0), ('b', -1), ('c', -2)] with pytest.raises(TypeError, match="a number is required"): - count('a', 'b') # type: ignore + count('a', 'b') # type: ignore[type-var] with pytest.raises(TypeError, match="a number is required"): - count(5, 'b') # type: ignore + count(5, 'b') # type: ignore[type-var] assert lzip("abc", count(2, 0)) == [('a', 2), ('b', 2), ('c', 2)] assert lzip("abc", count(2, 1)) == [('a', 2), ('b', 3), ('c', 4)] @@ -474,5 +474,5 @@ def test_subclassing_count(): match="type 'domdf_python_tools.iterative.count' is not an acceptable base type", ): - class MyCount(CountType): # type: ignore + class MyCount(CountType): # type: ignore[valid-type,misc] pass diff --git a/tests/test_namedlist.py b/tests/test_namedlist.py index 7cfc115a..81bdac2d 100644 --- a/tests/test_namedlist.py +++ b/tests/test_namedlist.py @@ -82,7 +82,7 @@ class NamedListTest: str_out = "ShoppingList['egg and bacon', 'egg sausage and bacon', 'egg and spam', 'egg bacon and spam']" cls_str: str - def test(self, capsys): + def test_(self, capsys): assert isinstance(self.shopping_list, UserList) assert self.shopping_list[0] == "egg and bacon" diff --git a/tests/test_pagesizes/test_pagesizes.py b/tests/test_pagesizes/test_pagesizes.py index 5b04cadd..382a5a58 100644 --- a/tests/test_pagesizes/test_pagesizes.py +++ b/tests/test_pagesizes/test_pagesizes.py @@ -178,7 +178,7 @@ def test_convert_size(unit: Unit): pytest.param(2, 5, 10, id="not isinstance(from_, Unit)"), ], ) -def test_convert_from(value: List[int], unit, expects: Tuple[float, ...]): +def test_convert_from(value: List[int], unit: Unit, expects: Tuple[float, ...]): assert convert_from(value, unit) == expects diff --git a/tests/test_paths.py b/tests/test_paths.py index d4dea3ed..22e411be 100644 --- a/tests/test_paths.py +++ b/tests/test_paths.py @@ -350,6 +350,7 @@ def test_make_executable(): assert os.access(tempfile, os.X_OK) +@pytest.mark.skipif(sys.version_info[:2] > (3, 11), reason="No longer valid on Python 3.12+") def test_instantiate_wrong_platform(): if os.name == "nt": with pytest.raises(NotImplementedError, match="cannot instantiate .* on your system"): diff --git a/tests/test_paths_/test_iterchildren_match.yml b/tests/test_paths_/test_iterchildren_match.yml index 9fcd4b87..5b019781 100644 --- a/tests/test_paths_/test_iterchildren_match.yml +++ b/tests/test_paths_/test_iterchildren_match.yml @@ -29,7 +29,6 @@ - domdf_python_tools/utils.py - domdf_python_tools/versions.py - domdf_python_tools/words.py -- setup.py - tests/__init__.py - tests/conftest.py - tests/discover_demo_module/__init__.py diff --git a/tests/test_paths_stdlib.py b/tests/test_paths_stdlib.py index e8d414d6..82d0a85c 100644 --- a/tests/test_paths_stdlib.py +++ b/tests/test_paths_stdlib.py @@ -204,6 +204,9 @@ def test_lstat_nosymlink(BASE: PathPlus): def test_owner(BASE: PathPlus): pwd = pytest.importorskip("pwd", reason="the pwd module is needed for this test") + if sys.platform == "win32": + return + p = PathPlus(BASE) / "fileA" uid = p.stat().st_uid try: @@ -216,6 +219,9 @@ def test_owner(BASE: PathPlus): def test_group(BASE: PathPlus): grp = pytest.importorskip("grp", reason="the grp module is needed for this test") + if sys.platform == "win32": + return + p = PathPlus(BASE) / "fileA" gid = p.stat().st_gid try: diff --git a/tests/test_stringlist.py b/tests/test_stringlist.py index 83af8e98..42e95b3e 100644 --- a/tests/test_stringlist.py +++ b/tests/test_stringlist.py @@ -1,6 +1,8 @@ # stdlib import pickle +import textwrap from textwrap import dedent +from typing import no_type_check # 3rd party import pytest @@ -80,6 +82,9 @@ def test_setitem(self): sl[3:4] = "\nfoo\nbar\n", "baz" assert sl == ["foo", "bar", '', '', "foo", "bar", '', "baz", '', "world", '', '', '', "1234"] + sl[3:5] = iter(["foo", "bar", "baz"]) + assert sl == ["foo", "bar", '', "foo", "bar", "baz", '', "baz", '', "world", '', '', '', "1234"] + def test_blankline(self): sl = StringList(['', '', "hello", "world", '', '', '', "1234"]) @@ -558,3 +563,18 @@ def test_splitlines(string, lines): @joinlines_splitlines_param def test_joinlines(string, lines): assert string == joinlines(lines) + + +@no_type_check +def test_stringlist_textwrap_indent(): + sl = StringList(['', '', "hello", "world", '', '', '', "1234"]) + assert textwrap.indent(sl, " ") == "\n\n hello\n world\n\n\n\n 1234\n" + assert textwrap.indent(sl, '\t') == "\n\n\thello\n\tworld\n\n\n\n\t1234\n" + assert textwrap.indent(sl, ">>> ") == "\n\n>>> hello\n>>> world\n\n\n\n>>> 1234\n" + + +def test_stringlist_splitlines(): + sl = StringList(['', '', "hello", "world", '', '', '', "1234"]) + assert sl.splitlines() is sl + assert list(sl.splitlines()) == ['', '', "hello", "world", '', '', '', "1234"] + assert sl.splitlines(keepends=True) == ['\n', '\n', "hello\n", "world\n", '\n', '\n', '\n', "1234\n"] diff --git a/tests/test_utils.py b/tests/test_utils.py index 7ef7c8c3..768bd836 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -124,11 +124,17 @@ def test_printr(obj, expects, capsys): assert re.match(expects, stdout[0]) +if sys.version_info >= (3, 13): + pure_posix_path_expected = "" +else: + pure_posix_path_expected = "" + + @pytest.mark.parametrize( "obj, expects", [ ("This is a test", ""), - (pathlib.PurePosixPath("foo.txt"), ""), + (pathlib.PurePosixPath("foo.txt"), pure_posix_path_expected), (1234, ""), (12.34, ""), (CustomRepr(), ""), diff --git a/tox.ini b/tox.ini index dc8400ea..f9e840ae 100644 --- a/tox.ini +++ b/tox.ini @@ -2,7 +2,11 @@ # You may add new sections, but any changes made to the following sections will be lost: # * tox # * envlists +# * testenv:.package +# * testenv:py313-dev +# * testenv:py313 # * testenv:py312-dev +# * testenv:py312 # * testenv:docs # * testenv:build # * testenv:lint @@ -18,17 +22,17 @@ [tox] envlist = - py36 py37 py38 py39 py310 py311 - py312-dev - pypy36 + py312 + py313 pypy37 pypy38 pypy39 + pypy310 mypy build skip_missing_interpreters = True @@ -41,21 +45,34 @@ requires = [envlists] test = - py36 py37 py38 py39 py310 py311 - py312-dev - pypy36 + py312 + py313 pypy37 pypy38 pypy39 + pypy310 qa = mypy, lint -cov = py36, coverage +cov = py38, coverage -[testenv:py312-dev] +[testenv:.package] +setenv = + PYTHONDEVMODE=1 + PIP_DISABLE_PIP_VERSION_CHECK=1 + +[testenv:py313] +download = True +setenv = + PYTHONDEVMODE=1 + PIP_DISABLE_PIP_VERSION_CHECK=1 + UNSAFE_PYO3_SKIP_VERSION_CHECK=1 + +[testenv:py312] +download = True setenv = PYTHONDEVMODE=1 PIP_DISABLE_PIP_VERSION_CHECK=1 @@ -70,19 +87,25 @@ deps = -r{toxinidir}/doc-source/requirements.txt commands = sphinx-build -M {env:SPHINX_BUILDER:html} . ./build {posargs} [testenv:build] +setenv = + PYTHONDEVMODE=1 + PIP_DISABLE_PIP_VERSION_CHECK=1 + PIP_PREFER_BINARY=1 + UNSAFE_PYO3_SKIP_VERSION_CHECK=1 skip_install = True changedir = {toxinidir} deps = build[virtualenv]>=0.3.1 check-wheel-contents>=0.1.0 twine>=3.2.0 + cryptography<40; implementation_name == "pypy" and python_version <= "3.7" commands = python -m build --sdist --wheel "{toxinidir}" twine check dist/*.tar.gz dist/*.whl check-wheel-contents dist/ [testenv:lint] -basepython = python3.6 +basepython = python3.8 changedir = {toxinidir} ignore_errors = True skip_install = False @@ -96,7 +119,7 @@ deps = flake8-github-actions>=0.1.0 flake8-noqa>=1.1.0,<=1.2.2 flake8-pyi>=20.10.0,<=22.8.0 - flake8-pytest-style>=1.3.0 + flake8-pytest-style>=1.3.0,<2 flake8-quotes>=3.3.0 flake8-slots>=0.1.0 flake8-sphinx-links>=0.0.4 @@ -112,7 +135,7 @@ deps = commands = python3 -m flake8_rst_docstrings_sphinx domdf_python_tools tests --allow-toolbox {posargs} [testenv:perflint] -basepython = python3.6 +basepython = python3.8 changedir = {toxinidir} ignore_errors = True skip_install = True @@ -120,7 +143,7 @@ deps = perflint commands = python3 -m perflint domdf_python_tools {posargs} [testenv:mypy] -basepython = python3.6 +basepython = python3.8 ignore_errors = True changedir = {toxinidir} extras = all @@ -132,7 +155,7 @@ deps = commands = mypy domdf_python_tools tests {posargs} [testenv:pyup] -basepython = python3.6 +basepython = python3.8 skip_install = True ignore_errors = True changedir = {toxinidir} @@ -141,7 +164,7 @@ extras = all commands = pyup_dirs domdf_python_tools tests --py36-plus --recursive [testenv:coverage] -basepython = python3.6 +basepython = python3.8 skip_install = True ignore_errors = True whitelist_externals = /bin/bash @@ -161,7 +184,7 @@ commands = [flake8] max-line-length = 120 -select = E111 E112 E113 E121 E122 E125 E127 E128 E129 E131 E133 E201 E202 E203 E211 E222 E223 E224 E225 E225 E226 E227 E228 E231 E241 E242 E251 E261 E262 E265 E271 E272 E303 E304 E306 E402 E502 E703 E711 E712 E713 E714 E721 W291 W292 W293 W391 W504 YTT101 YTT102 YTT103 YTT201 YTT202 YTT203 YTT204 YTT301 YTT302 YTT303 STRFTIME001 STRFTIME002 SXL001 PT001 PT002 PT003 PT006 PT007 PT008 PT009 PT010 PT011 PT012 PT013 PT014 PT015 PT016 PT017 PT018 PT019 PT020 PT021 RST201 RST202 RST203 RST204 RST205 RST206 RST207 RST208 RST210 RST211 RST212 RST213 RST214 RST215 RST216 RST217 RST218 RST219 RST299 RST301 RST302 RST303 RST304 RST305 RST306 RST399 RST401 RST499 RST900 RST901 RST902 RST903 Q001 Q002 Q003 A001 A002 A003 TYP001 TYP002 TYP003 TYP004 TYP005 TYP006 ENC001 ENC002 ENC003 ENC004 ENC011 ENC012 ENC021 ENC022 ENC023 ENC024 ENC025 ENC026 Y001,Y002 Y003 Y004 Y005 Y006 Y007 Y008 Y009 Y010 Y011 Y012 Y013 Y014 Y015 Y090 Y091 NQA001 NQA002 NQA003 NQA004 NQA005 NQA102 NQA103 E301 E302 E305 D100 D101 D102 D103 D104 D106 D201 D204 D207 D208 D209 D210 D211 D212 D213 D214 D215 D300 D301 D400 D402 D403 D404 D415 D417 DALL000 SLOT000 SLOT001 SLOT002 +select = E111 E112 E113 E121 E122 E125 E127 E128 E129 E131 E133 E201 E202 E203 E211 E222 E223 E224 E225 E225 E226 E227 E228 E231 E241 E242 E251 E261 E262 E265 E271 E272 E303 E304 E306 E402 E502 E703 E711 E712 E713 E714 E721 W291 W292 W293 W391 W504 YTT101 YTT102 YTT103 YTT201 YTT202 YTT203 YTT204 YTT301 YTT302 YTT303 STRFTIME001 STRFTIME002 SXL001 PT001 PT002 PT003 PT006 PT007 PT008 PT009 PT010 PT011 PT012 PT013 PT014 PT015 PT016 PT017 PT018 PT019 PT020 PT021 RST201 RST202 RST203 RST204 RST205 RST206 RST207 RST208 RST210 RST211 RST212 RST213 RST214 RST215 RST216 RST217 RST218 RST219 RST299 RST301 RST302 RST303 RST304 RST305 RST306 RST399 RST401 RST499 RST900 RST901 RST902 RST903 Q001 Q002 Q003 A001 A002 TYP001 TYP002 TYP003 TYP004 TYP005 TYP006 ENC001 ENC002 ENC003 ENC004 ENC011 ENC012 ENC021 ENC022 ENC023 ENC024 ENC025 ENC026 Y001,Y002 Y003 Y004 Y005 Y006 Y007 Y008 Y009 Y010 Y011 Y012 Y013 Y014 Y015 Y090 Y091 NQA001 NQA002 NQA003 NQA004 NQA005 NQA102 NQA103 E301 E302 E305 D100 D101 D102 D103 D104 D106 D201 D204 D207 D208 D209 D210 D211 D212 D213 D214 D215 D300 D301 D400 D402 D403 D404 D415 D417 DALL000 SLOT000 SLOT001 SLOT002 extend-exclude = doc-source,old,build,dist,__pkginfo__.py,setup.py,venv rst-directives = TODO @@ -200,13 +223,14 @@ plugins = coverage_pyver_pragma [coverage:report] fail_under = 95 +show_missing = True exclude_lines = raise AssertionError raise NotImplementedError if 0: if False: - if TYPE_CHECKING: - if typing.TYPE_CHECKING: + if TYPE_CHECKING + if typing.TYPE_CHECKING if __name__ == .__main__.: [check-wheel-contents] @@ -221,14 +245,21 @@ filterwarnings = error ignore:can't resolve package from __spec__ or __package__, falling back on __name__ and __path__:ImportWarning ignore::DeprecationWarning:certifi + always:ast.Str is deprecated and will be removed in Python 3.14; use ast.Constant instead:DeprecationWarning + always:Attribute s is deprecated and will be removed in Python 3.14; use value instead:DeprecationWarning + always:ast.Num is deprecated and will be removed in Python 3.14; use ast.Constant instead:DeprecationWarning + always:ast.NameConstant is deprecated and will be removed in Python 3.14; use ast.Constant:DeprecationWarning + always:datetime.utcfromtimestamp\(\) is deprecated and scheduled for removal in a future version:DeprecationWarning:pytz.tzinfo + always:the imp module is deprecated in favour of importlib:DeprecationWarning + always:The distutils package is deprecated and slated for removal in Python 3.12:DeprecationWarning + always:The distutils.sysconfig module is deprecated:DeprecationWarning [testenv] setenv = - PYTHONDEVMODE = 1 + PYTHONDEVMODE=1 PIP_DISABLE_PIP_VERSION_CHECK=1 -deps = - -r{toxinidir}/tests/requirements.txt - py311: py@git+https://github.com/pytest-dev/py@master + SETUPTOOLS_USE_DISTUTILS=stdlib +deps = -r{toxinidir}/tests/requirements.txt extras = all ignore_errors = True commands =