Skip to content

Commit

Permalink
Adopt uv (#38)
Browse files Browse the repository at this point in the history
* switch to uv

* linting and ci setup
  • Loading branch information
samuelcolvin authored Nov 15, 2024
1 parent a805f9b commit 82d260a
Show file tree
Hide file tree
Showing 19 changed files with 669 additions and 314 deletions.
96 changes: 60 additions & 36 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,85 +14,109 @@ env:
jobs:
lint:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: set up python
uses: actions/setup-python@v4
- uses: astral-sh/setup-uv@v3
with:
python-version: '3.10'
enable-cache: true

- run: pip install -r requirements/linting.txt
- name: Install dependencies
run: uv sync --python 3.12 --frozen

- uses: pre-commit/[email protected]
with:
extra_args: --all-files --verbose
env:
SKIP: no-commit-to-branch

test:
name: test py${{ matrix.python-version }}
runs-on: ubuntu-latest

strategy:
fail-fast: false
matrix:
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12']
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']

env:
UV_PYTHON: ${{ matrix.python-version }}

steps:
- uses: actions/checkout@v4

- uses: astral-sh/setup-uv@v3
with:
enable-cache: true

- run: mkdir coverage
- run: uv run --frozen coverage run -m pytest
env:
COVERAGE_FILE: coverage/.coverage.${{ runner.os }}-py${{ matrix.python-version }}

- name: store coverage files
uses: actions/upload-artifact@v4
with:
name: coverage-${{ matrix.python-version }}
path: coverage
include-hidden-files: true

coverage:
runs-on: ubuntu-latest
needs: [test]
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: set up python
uses: actions/setup-python@v4
- uses: astral-sh/setup-uv@v3
with:
python-version: ${{ matrix.python-version }}
enable-cache: true

- run: pip install -r requirements/pyproject.txt
- run: pip install -r requirements/testing.txt
- name: get coverage files
uses: actions/download-artifact@v4
with:
merge-multiple: true
path: coverage

- run: pip install -e .
- run: pip freeze
- run: pytest
- run: uv run --frozen coverage combine coverage

- run: uv run --frozen coverage report --fail-under 85

# https://github.com/marketplace/actions/alls-green#why used for branch protection checks
check:
if: always()
needs: [lint, test]
needs: [lint, test, coverage]
runs-on: ubuntu-latest
steps:
- name: Decide whether the needed jobs succeeded or failed
uses: re-actors/alls-green@release/v1
with:
jobs: ${{ toJSON(needs) }}

deploy:
release:
name: Deploy
needs: [check]
if: "success() && startsWith(github.ref, 'refs/tags/')"
runs-on: ubuntu-latest
environment: release

permissions:
id-token: write

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4

- name: set up python
uses: actions/setup-python@v4
- uses: astral-sh/setup-uv@v3
with:
python-version: '3.10'

- name: install
run: pip install -U twine build
enable-cache: true

- name: check GITHUB_REF matches package version
uses: samuelcolvin/check-python-version@v3
uses: samuelcolvin/check-python-version@v4.1
with:
version_file_path: pytest_examples/__init__.py

- name: build
run: python -m build
version_file_path: pyproject.toml

- run: twine check --strict dist/*
- run: uv build

- name: upload to pypi
run: twine upload dist/*
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.pypi_token }}
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
skip-existing: true
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ venv/
.venv/
env3*/
Pipfile
*.lock
*.py[cod]
*.egg-info/
.python-version
Expand Down
28 changes: 15 additions & 13 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,25 @@ repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.3.0
hooks:
- id: no-commit-to-branch # prevent direct commits to the `main` branch
- id: check-yaml
- id: check-toml
- id: end-of-file-fixer
- id: trailing-whitespace

- repo: local
hooks:
- id: ruff
name: Ruff
entry: ruff check
args: [--fix, --exit-non-zero-on-fix]
types: [python]
language: system
exclude: cases_update
- id: black
name: Black
entry: black
types: [python]
language: system
exclude: cases_update
- id: format
name: Format
entry: make
args: [format]
language: system
types: [python]
pass_filenames: false
- id: lint
name: Lint
entry: make
args: [lint]
types: [python]
language: system
pass_filenames: false
59 changes: 20 additions & 39 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,53 +1,34 @@
.DEFAULT_GOAL := all
sources = pytest_examples tests example

.PHONY: install
install:
pip install -U pip
pip install -r requirements/all.txt
pip install -e .
pre-commit install
.PHONY: .uv # Check that uv is installed
.uv:
@uv --version || echo 'Please install uv: https://docs.astral.sh/uv/getting-started/installation/'

.PHONY: refresh-lockfiles
refresh-lockfiles:
find requirements/ -name '*.txt' ! -name 'all.txt' -type f -delete
make update-lockfiles
.PHONY: install # Install the package, dependencies, and pre-commit for local development
install: .uv
uv sync --frozen
uv run pre-commit install --install-hooks

.PHONY: update-lockfiles
update-lockfiles:
@echo "Updating requirements/*.txt files using pip-compile"
pip-compile -q --resolver backtracking -o requirements/linting.txt requirements/linting.in
pip-compile -q --resolver backtracking -o requirements/testing.txt requirements/testing.in
pip-compile -q --resolver backtracking -o requirements/pyproject.txt pyproject.toml
pip install --dry-run -r requirements/all.txt

.PHONY: format
.PHONY: format # Format the code
format:
black $(sources)
ruff format $(sources)
uv run ruff format
uv run ruff check --fix --fix-only

.PHONY: lint
.PHONY: lint # Lint the code
lint:
black $(sources) --check --diff
ruff check $(sources) --fix
uv run ruff format --check
uv run ruff check

.PHONY: test
test:
pytest

.PHONY: all
all: lint test
.PHONY: testcov # Run tests and collect coverage data
testcov:
uv run coverage run -m pytest
@uv run coverage report
@uv run coverage html

.PHONY: clean
clean:
rm -rf `find . -name __pycache__`
rm -f `find . -type f -name '*.py[co]' `
rm -f `find . -type f -name '*~' `
rm -f `find . -type f -name '.*~' `
rm -rf .cache
rm -rf .pytest_cache
rm -rf htmlcov
rm -rf *.egg-info
rm -f .coverage
rm -f .coverage.*
rm -rf build
.PHONY: all
all: format lint testcov
74 changes: 45 additions & 29 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,30 @@
requires = ['hatchling']
build-backend = 'hatchling.build'

[tool.hatch.version]
path = 'pytest_examples/__init__.py'

[tool.hatch.build.targets.sdist]
# limit which files are included in the sdist (.tar.gz) asset,
# see https://github.com/pydantic/pydantic/pull/4542
include = [
'/README.md',
'/Makefile',
'/pytest_examples',
'/requirements',
'/tests',
]
include = ['/README.md', '/Makefile', '/pytest_examples', '/tests']

[project]
name = 'pytest-examples'
version = '0.0.14'
description = 'Pytest plugin for testing examples in docstrings and markdown files.'
authors = [
{name = 'Samuel Colvin', email = '[email protected]'},
]
license = 'MIT'
readme = 'README.md'
classifiers = [
'Development Status :: 4 - Beta',
'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 :: 3.13',
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
'Operating System :: Unix',
Expand All @@ -43,8 +35,7 @@ classifiers = [
'Framework :: Pytest',
'Topic :: Software Development :: Libraries :: Python Modules',
]
requires-python = '>=3.7'
dynamic = ['version']
requires-python = '>=3.8'
dependencies = [
'pytest>=7',
'black>=23',
Expand All @@ -57,24 +48,56 @@ examples = 'pytest_examples'
[project.urls]
repository = 'https://github.com/pydantic/pytest-examples'

[dependency-groups]
dev = [
'coverage[toml]>=7.6.1',
'pre-commit>=3.5.0',
'pytest-pretty>=1.2.0',
'ruff>=0.7.4',
]

[tool.pytest.ini_options]
testpaths = ['tests', 'example']
filterwarnings = 'error'
xfail_strict = true

[tool.ruff]
line-length = 120
target-version = 'py37'
exclude = ['cases_update']
lint.extend-ignore = [
'E721', # using type() instead of isinstance() - we use this in tests
target-version = 'py39'
include = [
'pytest_examples/**/*.py',
'tests/**/*.py',
'examples/**/*.py',
]
lint.extend-select = ['Q', 'RUF100', 'C90', 'UP', 'I']
lint.flake8-quotes = {inline-quotes = 'single', multiline-quotes = 'double'}
lint.mccabe = { max-complexity = 14 }
lint.isort = { known-first-party = ['pytest_examples'] }
exclude = ['tests/cases_update/*.py']

[tool.ruff.lint]
extend-select = [
'Q',
'RUF100',
'C90',
'UP',
'I',
'D',
]
flake8-quotes = { inline-quotes = 'single', multiline-quotes = 'double' }
isort = { combine-as-imports = true, known-first-party = ['pytest_examples'] }
mccabe = { max-complexity = 15 }
ignore = [
'D101', # ignore missing docstring in public class
'D102', # ignore missing docstring in public method
'D103', # ignore missing docstring in public function
'D107', # ignore missing docstring in __init__ methods
'D100', # ignore missing docstring in module
'D104', # ignore missing docstring in public package
'D105', # ignore missing docstring in magic methods
]

[tool.ruff.lint.pydocstyle]
convention = 'google'

[tool.ruff.format]
docstring-code-format = true
quote-style = 'single'

[tool.coverage.run]
Expand All @@ -89,10 +112,3 @@ exclude_lines = [
'if TYPE_CHECKING:',
'@overload',
]

[tool.black]
exclude = '.*/cases_update/.*'
color = true
line-length = 120
target-version = ['py310']
skip-string-normalization = true
Loading

0 comments on commit 82d260a

Please sign in to comment.