diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ab1871e..4b1bbbb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,5 +1,5 @@ -# This workflow will install Python dependencies, run tests and lint with a variety of Python versions -# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions +# Install the project with uv, lint with ruff, and run tests across a +# matrix of Python versions. name: build @@ -18,26 +18,14 @@ jobs: matrix: python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] steps: - - uses: actions/checkout@v3 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v3 + - uses: actions/checkout@v6 + - name: Install uv and set Python ${{ matrix.python-version }} + uses: astral-sh/setup-uv@v8.0.0 with: python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: | - python -m pip install --upgrade pip - python -m pip install flake8 pytest - python -m pip install numpy - if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - - name: Lint with flake8 - run: | - # stop the build if there are Python syntax errors or undefined names - flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics - # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide - flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics - - name: Install as editable package - run: | - python -m pip install -e . + - name: Install the project and dev dependencies + run: uv sync --group dev + - name: Lint with ruff + run: uv run ruff check - name: Test with pytest - run: | - pytest + run: uv run pytest diff --git a/.github/workflows/upload_pypi.yml b/.github/workflows/upload_pypi.yml index 26c464a..a927088 100644 --- a/.github/workflows/upload_pypi.yml +++ b/.github/workflows/upload_pypi.yml @@ -1,10 +1,4 @@ -# This workflow will upload a Python Package using Twine when a release is created -# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries - -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. +# Build and publish to PyPI when a GitHub release is published. name: Upload Python Package @@ -21,17 +15,11 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - name: Set up Python - uses: actions/setup-python@v3 - with: - python-version: '3.x' - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install build + - uses: actions/checkout@v6 + - name: Install uv + uses: astral-sh/setup-uv@v8.0.0 - name: Build package - run: python -m build + run: uv build - name: Publish package uses: pypa/gh-action-pypi-publish@v1.13.0 with: diff --git a/.gitignore b/.gitignore index aa7f212..13711d1 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,6 @@ dist/ .venv*/ .pytest_cache/ + +# Library — dev-only lockfile, not pinned for consumers. +uv.lock diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a804c0..a700770 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,12 @@ ## Fixed - Python 3.12+ compatibility: `tb.tb_lineno` and `frame.f_lineno` can return `None` when an instruction has no line mapping (for example at some async suspension points or on synthetic RESUME/CACHE opcodes). `extraction.get_info` now substitutes `frame.f_code.co_firstlineno` in that case instead of crashing with `AssertionError` in `source_inspection.annotate`. +## Changed +- `source_inspection.annotate` now raises `TypeError` instead of `assert isinstance(...)` for bad input types, so the check is still enforced when Python is run under `-O`. +- Packaging migrated from `setup.py` to `pyproject.toml` (PEP 621) using the `uv_build` backend; the installed wheel layout is unchanged. +- CI test matrix extended to Python 3.13 and 3.14. +- CI switched from `actions/setup-python` + `pip` to `astral-sh/setup-uv` + `uv sync`, and from `flake8` to `ruff` for linting. + # 0.2.8 - August 25, 2022 ## Fixed diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..898e0a4 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,46 @@ +[project] +name = "stackprinter" +version = "0.2.13" +description = "Debug-friendly stack traces, with variable values and semantic highlighting" +readme = "README.md" +requires-python = ">=3.8" +license = "MIT" +license-files = ["LICENSE.txt"] +authors = [{ name = "cknd", email = "ck-github@mailbox.org" }] +urls = { Homepage = "https://github.com/cknd/stackprinter" } +classifiers = [ + "Programming Language :: Python :: 3", + "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 :: 3.14", + "Operating System :: OS Independent", +] +dependencies = [] + +[dependency-groups] +dev = [ + "pytest", + "numpy", + "ruff", +] + +[build-system] +requires = ["uv_build>=0.9,<0.10"] +build-backend = "uv_build" + +[tool.uv.build-backend] +module-name = "stackprinter" +module-root = "" + +[tool.ruff] +target-version = "py38" + +[tool.ruff.lint] +# Match the pre-ruff flake8 gate: syntax errors and undefined names only. +# Broader rulesets would light up unrelated pre-existing violations that +# are out of scope for the ARE-2675 fix. +select = ["E9", "F63", "F7", "F82"] diff --git a/setup.py b/setup.py deleted file mode 100644 index f902320..0000000 --- a/setup.py +++ /dev/null @@ -1,22 +0,0 @@ -import setuptools - -with open("README.md", "r") as fh: - long_description = fh.read() - -setuptools.setup( - python_requires=">=3.4", - name="stackprinter", - version="0.2.13", - author="cknd", - author_email="ck-github@mailbox.org", - description="Debug-friendly stack traces, with variable values and semantic highlighting", - long_description=long_description, - long_description_content_type="text/markdown", - url="https://github.com/cknd/stackprinter", - packages=setuptools.find_packages(), - classifiers=[ - "Programming Language :: Python :: 3", - "License :: OSI Approved :: MIT License", - "Operating System :: OS Independent", - ], -) diff --git a/stackprinter/source_inspection.py b/stackprinter/source_inspection.py index 63bc52c..e34e13c 100644 --- a/stackprinter/source_inspection.py +++ b/stackprinter/source_inspection.py @@ -58,9 +58,12 @@ def annotate(source_lines, line_offset=0, lineno=0, max_line=2**15): if not source_lines: return {}, {}, {}, [], lineno - assert isinstance(line_offset, int) - assert isinstance(lineno, int) - assert isinstance(max_line, int) + for name, value in (("line_offset", line_offset), + ("lineno", lineno), + ("max_line", max_line)): + if not isinstance(value, int): + raise TypeError( + "annotate() expected %s to be an int, got %r" % (name, value)) source_lines, lineno_corrections = join_broken_lines(source_lines) lineno += lineno_corrections[lineno - line_offset]