diff --git a/.bumpversion.cfg b/.bumpversion.cfg index f86dfcc..b663f17 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -22,3 +22,7 @@ replace = version = release = '{new_version}' [bumpversion:file:src/hunter/__init__.py] search = __version__ = '{current_version}' replace = __version__ = '{new_version}' + +[bumpversion:file:.cookiecutterrc] +search = version: {current_version} +replace = version: {new_version} diff --git a/.cookiecutterrc b/.cookiecutterrc index 2dd10c3..e7d0fe6 100644 --- a/.cookiecutterrc +++ b/.cookiecutterrc @@ -1,9 +1,6 @@ # Generated by cookiepatcher, a small shim around cookiecutter (pip install cookiepatcher) default_context: - allow_tests_inside_package: 'no' - c_extension_function: '-' - c_extension_module: '-' c_extension_optional: 'yes' c_extension_support: cython codacy: 'no' @@ -17,17 +14,19 @@ default_context: email: contact@ionelmc.ro formatter_quote_style: single full_name: Ionel Cristian Mărieș + function_name: compute github_actions: 'yes' github_actions_osx: 'yes' github_actions_windows: 'yes' license: BSD 2-Clause License + module_name: core package_name: hunter pre_commit: 'yes' project_name: Hunter project_short_description: Hunter is a flexible code tracing toolkit, not for measuring coverage, but for debugging, logging, inspection and other nefarious purposes. It has a simple Python API and a convenient terminal API (see `Environment variable activation `_). pypi_badge: 'yes' pypi_disable_upload: 'no' - release_date: '2022-09-27' + release_date: '2023-04-26' repo_hosting: github.com repo_hosting_domain: github.com repo_main_branch: master @@ -38,10 +37,11 @@ default_context: sphinx_docs: 'yes' sphinx_docs_hosting: https://python-hunter.readthedocs.io/ sphinx_doctest: 'no' - sphinx_theme: sphinx-py3doc-enhanced-theme + sphinx_theme: furo test_matrix_separate_coverage: 'yes' - version: 3.5.1 + tests_inside_package: 'no' + version: 3.6.1 version_manager: bump2version website: https://blog.ionelmc.ro year_from: '2015' - year_to: '2023' + year_to: '2024' diff --git a/.coveragerc b/.coveragerc index b74227a..2d8a895 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,6 +1,11 @@ +[paths] +source = src + [run] branch = true -source = src +source = + src + tests parallel = true plugins = Cython.Coverage diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e4081de..5177597 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -9,7 +9,7 @@ repos: rev: v0.4.2 hooks: - id: ruff - args: [--fix, --exit-non-zero-on-fix, --show-fixes] + args: [--fix, --exit-non-zero-on-fix, --show-fixes, --unsafe-fixes] - repo: https://github.com/psf/black rev: 24.4.2 hooks: diff --git a/.readthedocs.yml b/.readthedocs.yml index 59ff5c0..009a913 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -3,6 +3,10 @@ version: 2 sphinx: configuration: docs/conf.py formats: all +build: + os: ubuntu-22.04 + tools: + python: "3" python: install: - requirements: docs/requirements.txt diff --git a/LICENSE b/LICENSE index 0906fcc..d50735b 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ BSD 2-Clause License -Copyright (c) 2015-2023, Ionel Cristian Mărieș. All rights reserved. +Copyright (c) 2015-2024, Ionel Cristian Mărieș. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/README.rst b/README.rst index 92421af..9183b9e 100644 --- a/README.rst +++ b/README.rst @@ -10,13 +10,11 @@ Overview * - docs - |docs| * - tests - - | |github-actions| - | |codecov| + - |github-actions| |codecov| * - package - - | |version| |wheel| |supported-versions| |supported-implementations| - | |commits-since| + - |version| |wheel| |supported-versions| |supported-implementations| |commits-since| .. |docs| image:: https://readthedocs.org/projects/python-hunter/badge/?style=flat - :target: https://python-hunter.readthedocs.io/ + :target: https://readthedocs.org/projects/python-hunter/ :alt: Documentation Status .. |github-actions| image:: https://github.com/ionelmc/python-hunter/actions/workflows/github-actions.yml/badge.svg @@ -25,7 +23,7 @@ Overview .. |codecov| image:: https://codecov.io/gh/ionelmc/python-hunter/branch/master/graphs/badge.svg?branch=master :alt: Coverage Status - :target: https://codecov.io/github/ionelmc/python-hunter + :target: https://app.codecov.io/github/ionelmc/python-hunter .. |version| image:: https://img.shields.io/pypi/v/hunter.svg :alt: PyPI Package latest release diff --git a/ci/bootstrap.py b/ci/bootstrap.py index 9b807b9..f3c9a7e 100755 --- a/ci/bootstrap.py +++ b/ci/bootstrap.py @@ -64,7 +64,7 @@ def main(): tox_environments = [line for line in tox_environments if line.startswith('py')] for template in templates_path.rglob('*'): if template.is_file(): - template_path = str(template.relative_to(templates_path)) + template_path = template.relative_to(templates_path).as_posix() destination = base_path / template_path destination.parent.mkdir(parents=True, exist_ok=True) destination.write_text(jinja.get_template(template_path).render(tox_environments=tox_environments)) diff --git a/ci/templates/.github/workflows/github-actions.yml b/ci/templates/.github/workflows/github-actions.yml index c98c13e..7dad0fb 100644 --- a/ci/templates/.github/workflows/github-actions.yml +++ b/ci/templates/.github/workflows/github-actions.yml @@ -1,5 +1,5 @@ name: build -on: [push, pull_request] +on: [push, pull_request, workflow_dispatch] jobs: test: name: {{ '${{ matrix.name }}' }} @@ -22,9 +22,9 @@ jobs: {% for env in tox_environments %} {% set prefix = env.split('-')[0] -%} {% if prefix.startswith('pypy') %} -{% set python %}pypy-{{ prefix[4] }}.{{ prefix[5] }}{% endset %} +{% set python %}pypy-{{ prefix[4] }}.{{ prefix[5:] }}{% endset %} {% set cpython %}pp{{ prefix[4:5] }}{% endset %} -{% set toxpython %}pypy{{ prefix[4] }}.{{ prefix[5] }}{% endset %} +{% set toxpython %}pypy{{ prefix[4] }}.{{ prefix[5:] }}{% endset %} {% else %} {% set python %}{{ prefix[2] }}.{{ prefix[3:] }}{% endset %} {% set cpython %}cp{{ prefix[2:] }}{% endset %} @@ -46,7 +46,10 @@ jobs: python: '{{ python }}' toxpython: '{{ toxpython }}' python_arch: '{{ python_arch }}' - tox_env: '{{ env }}{% if 'cover' in env %},codecov{% endif %}' + tox_env: '{{ env }}' +{% if 'cover' in env %} + cover: true +{% endif %} cibw_arch: '{{ cibw_arch }}' {% if env.endswith('cython-nocov') and not prefix.startswith('pypy') %} cibw_build: '{{ cpython }}-{{ wheel_arch }}' @@ -58,14 +61,14 @@ jobs: {% endfor %} {% endfor %} steps: - - uses: docker/setup-qemu-action@v2 + - uses: docker/setup-qemu-action@v3 if: matrix.cibw_arch == 'aarch64' with: platforms: arm64 - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: {{ '${{ matrix.python }}' }} architecture: {{ '${{ matrix.python_arch }}' }} @@ -105,6 +108,11 @@ jobs: !matrix.cibw_build run: > tox -e {{ '${{ matrix.tox_env }}' }} -v + - uses: codecov/codecov-action@v3 + if: matrix.cover + with: + verbose: true + flags: {{ '${{ matrix.tox_env }}' }} - name: check wheel if: matrix.cibw_build run: twine check wheelhouse/*.whl @@ -113,3 +121,11 @@ jobs: if: matrix.cibw_build with: path: wheelhouse/*.whl + finish: + needs: test + if: {{ '${{ always() }}' }} + runs-on: ubuntu-latest + steps: + - uses: codecov/codecov-action@v3 + with: + CODECOV_TOKEN: {% raw %}${{ secrets.CODECOV_TOKEN }}{% endraw %} diff --git a/docs/conf.py b/docs/conf.py index dad6e8e..3c5b13e 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,7 +1,4 @@ import os -import traceback - -import sphinx_py3doc_enhanced_theme os.environ['PUREPYTHONHUNTER'] = 'yes' @@ -20,7 +17,7 @@ source_suffix = '.rst' master_doc = 'index' project = 'Hunter' -year = '2015-2023' +year = '2015-2024' author = 'Ionel Cristian Mărieș' copyright = f'{year}, {author}' try: @@ -28,17 +25,19 @@ version = release = get_distribution('hunter').version except Exception: + import traceback + traceback.print_exc() version = release = '3.6.1' pygments_style = 'trac' templates_path = ['.'] extlinks = { - 'issue': ('https://github.com/ionelmc/python-hunter/issues/%s', '#'), - 'pr': ('https://github.com/ionelmc/python-hunter/pull/%s', 'PR #'), + 'issue': ('https://github.com/ionelmc/python-hunter/issues/%s', '#%s'), + 'pr': ('https://github.com/ionelmc/python-hunter/pull/%s', 'PR #%s'), } -html_theme = 'sphinx_py3doc_enhanced_theme' -html_theme_path = [sphinx_py3doc_enhanced_theme.get_html_theme_path()] + +html_theme = 'furo' html_theme_options = { 'githuburl': 'https://github.com/ionelmc/python-hunter/', } @@ -46,9 +45,6 @@ html_use_smartypants = True html_last_updated_fmt = '%b %d, %Y' html_split_index = False -html_sidebars = { - '**': ['searchbox.html', 'globaltoc.html', 'sourcelink.html'], -} html_short_title = f'{project}-{version}' napoleon_use_ivar = True diff --git a/docs/requirements.txt b/docs/requirements.txt index 6234ed0..c03e307 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,2 +1,2 @@ sphinx>=1.3 -sphinx-py3doc-enhanced-theme>=2.3.2 +furo diff --git a/pyproject.toml b/pyproject.toml index 68667ca..bc129a9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,19 +7,25 @@ requires = [ build-backend = "backend" backend-path = ["build_backend"] -[tool.ruff.per-file-ignores] +[tool.ruff] +extend-exclude = ["static", "ci/templates"] +line-length = 140 +src = ["src", "tests"] +target-version = "py38" +[tool.cython-lint] +max-line-length = 140 + +[tool.ruff.lint.per-file-ignores] "ci/*" = ["S"] "tests/*" = ["ALL"] -[tool.ruff] -extend-exclude = ["static", "ci/templates"] +[tool.ruff.lint] ignore = [ "RUF001", # ruff-specific rules ambiguous-unicode-character-string "S101", # flake8-bandit assert "S308", # flake8-bandit suspicious-mark-safe-usage "E501", # pycodestyle line-too-long ] -line-length = 140 select = [ "B", # flake8-bugbear "C4", # flake8-comprehensions @@ -40,22 +46,20 @@ select = [ "UP", # pyupgrade "W", # pycodestyle warnings ] -src = ["src", "tests"] -target-version = "py37" -[tool.ruff.flake8-pytest-style] +[tool.ruff.lint.flake8-pytest-style] fixture-parentheses = false mark-parentheses = false -[tool.ruff.isort] +[tool.ruff.lint.flake8-quotes] +inline-quotes = "single" + +[tool.ruff.lint.isort] extra-standard-library = ["opcode"] forced-separate = ["conftest"] force-single-line = true [tool.black] line-length = 140 -target-version = ["py37"] +target-version = ["py38"] skip-string-normalization = true - -[tool.ruff.flake8-quotes] -inline-quotes = "single" diff --git a/setup.py b/setup.py index 6bc77a7..8ac9838 100755 --- a/setup.py +++ b/setup.py @@ -2,13 +2,13 @@ import os import re import sys -from distutils.command.build import build from itertools import chain from pathlib import Path from setuptools import Extension from setuptools import find_packages from setuptools import setup +from setuptools.command.build import build from setuptools.command.build_ext import build_ext from setuptools.command.develop import develop from setuptools.command.easy_install import easy_install @@ -139,11 +139,11 @@ def read(*names, **kwargs): 'Programming Language :: Python', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3 :: Only', - '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 :: Implementation :: CPython', 'Programming Language :: Python :: Implementation :: PyPy', 'Topic :: Utilities', @@ -163,19 +163,21 @@ def read(*names, **kwargs): 'code', 'source', ], - python_requires='>=3.7', + python_requires='>=3.8', install_requires=[], extras_require={ ':platform_system != "Windows"': ['manhole >= 1.5'], }, - setup_requires=[ - 'setuptools_scm>=3.3.1,!=4.0.0', - 'cython', - ] - if Cython - else [ - 'setuptools_scm>=3.3.1,!=4.0.0', - ], + setup_requires=( + [ + 'setuptools_scm>=3.3.1,!=4.0.0', + 'cython', + ] + if Cython + else [ + 'setuptools_scm>=3.3.1,!=4.0.0', + ] + ), entry_points={ 'console_scripts': [ 'hunter-trace = hunter.remote:main', @@ -188,17 +190,19 @@ def read(*names, **kwargs): 'develop': DevelopWithPTH, 'build_ext': OptionalBuildExt, }, - ext_modules=[] - if hasattr(sys, 'pypy_version_info') - else [ - Extension( - str(path.relative_to('src').with_suffix('')).replace(os.sep, '.'), - sources=[str(path)], - extra_compile_args=CFLAGS.split(), - extra_link_args=LFLAGS.split(), - include_dirs=[str(path.parent)], - ) - for path in Path('src').glob('**/*.pyx' if Cython else '**/*.c') - ], + ext_modules=( + [] + if hasattr(sys, 'pypy_version_info') + else [ + Extension( + str(path.relative_to('src').with_suffix('')).replace(os.sep, '.'), + sources=[str(path)], + extra_compile_args=CFLAGS.split(), + extra_link_args=LFLAGS.split(), + include_dirs=[str(path.parent)], + ) + for path in Path('src').glob('**/*.pyx' if Cython else '**/*.c') + ] + ), distclass=BinaryDistribution, ) diff --git a/tests/setup.py b/tests/setup.py index c8203db..ce9de4d 100644 --- a/tests/setup.py +++ b/tests/setup.py @@ -25,21 +25,25 @@ setup( package_dir={'': 'tests'}, zip_safe=False, - setup_requires=[ - 'cython', - ] - if Cython - else [], - ext_modules=[] - if hasattr(sys, 'pypy_version_info') - else [ - Extension( - splitext(relpath(path, 'tests').replace(os.sep, '.'))[0], - sources=[path], - include_dirs=[dirname(path), 'src', 'src/hunter'], - define_macros=[('CYTHON_TRACE', '1')], - ) - for root, _, _ in os.walk('tests') - for path in glob(join(root, '*.pyx' if Cython else '*.c')) - ], + setup_requires=( + [ + 'cython', + ] + if Cython + else [] + ), + ext_modules=( + [] + if hasattr(sys, 'pypy_version_info') + else [ + Extension( + splitext(relpath(path, 'tests').replace(os.sep, '.'))[0], + sources=[path], + include_dirs=[dirname(path), 'src', 'src/hunter'], + define_macros=[('CYTHON_TRACE', '1')], + ) + for root, _, _ in os.walk('tests') + for path in glob(join(root, '*.pyx' if Cython else '*.c')) + ] + ), ) diff --git a/tox.ini b/tox.ini index 508ceb3..9e3d52e 100644 --- a/tox.ini +++ b/tox.ini @@ -14,20 +14,20 @@ envlist = clean, check, docs, - {py37,py38,py39,py310,py311,pypy37,pypy38,pypy39}-{pure,cython}-{cover,nocov}, + {py38,py39,py310,py311,py312,pypy38,pypy39,pypy310}-{pure,cython}-{cover,nocov}, report ignore_basepython_conflict = true [testenv] basepython = - pypy37: {env:TOXPYTHON:pypy3.7} pypy38: {env:TOXPYTHON:pypy3.8} pypy39: {env:TOXPYTHON:pypy3.9} - py37: {env:TOXPYTHON:python3.7} + pypy310: {env:TOXPYTHON:pypy3.10} py38: {env:TOXPYTHON:python3.8} py39: {env:TOXPYTHON:python3.9} py310: {env:TOXPYTHON:python3.10} py311: {env:TOXPYTHON:python3.11} + py312: {env:TOXPYTHON:python3.12} {bootstrap,clean,check,report,docs,codecov}: {env:TOXPYTHON:python3} setenv = PYTHONPATH={toxinidir}/tests @@ -42,7 +42,7 @@ deps = pytest pytest-benchmark cover: pytest-cov - {cython,cover}: cython==3.0.0b2 + {cython,cover}: cython==3.0.10 manhole==1.8.0 process-tests setuptools-scm @@ -77,7 +77,7 @@ commands = basepython = {env:TOXPYTHON:python} pip_pre = true deps = - cython==3.0.0b2 + cython==3.0.10 skip_install = true commands = {posargs:python setup.py clean --all build_ext --force} @@ -104,7 +104,7 @@ commands = [testenv:codecov] deps = codecov - cython==3.0.0b2 + cython==3.0.10 skip_install = true setenv = PYTHONPATH={toxinidir}/src @@ -114,7 +114,7 @@ commands = [testenv:report] deps = coverage - cython==3.0.0b2 + cython==3.0.10 skip_install = true setenv = PYTHONPATH={toxinidir}/src @@ -127,4 +127,4 @@ commands = coverage erase skip_install = true deps = coverage - cython==3.0.0b2 + cython==3.0.10