Skip to content

Commit 24be320

Browse files
authored
Upgrade to uv and ty and support Python 3.13, deprecate 3.8 (#41)
1 parent 7252c64 commit 24be320

File tree

16 files changed

+830
-106
lines changed

16 files changed

+830
-106
lines changed

.github/workflows/main.yml

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,13 @@ jobs:
2222

2323
steps:
2424
- uses: actions/checkout@v4
25-
- uses: actions/setup-python@v5
25+
- name: Install uv
26+
uses: astral-sh/setup-uv@v4
2627
with:
27-
python-version-file: .python-version
28-
allow-prereleases: true
29-
cache: pip
30-
- run: pip install tox-uv
31-
- run: tox -e typing
28+
enable-cache: true
29+
- name: Install just
30+
uses: extractions/setup-just@v2
31+
- run: just typing
3232

3333
run-tests:
3434

@@ -39,33 +39,30 @@ jobs:
3939
fail-fast: false
4040
matrix:
4141
os: ['ubuntu-latest', 'macos-latest', 'windows-latest']
42-
python-version: ['3.8', '3.9', '3.10', '3.11']
42+
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
4343

4444
steps:
4545
- uses: actions/checkout@v4
46-
- uses: actions/setup-python@v5
46+
- name: Install uv
47+
uses: astral-sh/setup-uv@v4
4748
with:
48-
python-version: ${{ matrix.python-version }}
49-
cache: pip
50-
allow-prereleases: true
51-
- run: pip install tox-uv
49+
enable-cache: true
50+
- name: Install just
51+
uses: extractions/setup-just@v2
52+
- name: Set up Python ${{ matrix.python-version }}
53+
run: uv python install ${{ matrix.python-version }}
5254

53-
# Unit, integration, and end-to-end tests.
54-
55-
- name: Run unit tests and doctests.
55+
- name: Run tests
5656
shell: bash -l {0}
57-
run: tox -e test -- -m "unit or (not integration and not end_to_end)" --cov=./ --cov-report=xml -n auto
57+
run: just test
5858

59-
- name: Upload unit test coverage reports to Codecov with GitHub Action
59+
- name: Upload test coverage reports to Codecov with GitHub Action
6060
uses: codecov/codecov-action@v4
61-
with:
62-
flags: unit
6361

64-
- name: Run end-to-end tests.
65-
shell: bash -l {0}
66-
run: tox -e test -- -m end_to_end --cov=./ --cov-report=xml -n auto
62+
- name: Run tests with lowest resolution
63+
if: matrix.python-version == '3.9' && matrix.os == 'ubuntu-latest'
64+
run: just test-lowest
6765

68-
- name: Upload end_to_end test coverage reports to Codecov with GitHub Action
69-
uses: codecov/codecov-action@v4
70-
with:
71-
flags: end_to_end
66+
- name: Run tests with highest resolution
67+
if: matrix.python-version == '3.13' && matrix.os == 'ubuntu-latest'
68+
run: just test-highest

.pre-commit-config.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@ repos:
2929
hooks:
3030
- id: ruff
3131
- id: ruff-format
32-
- repo: https://github.com/dosisod/refurb
33-
rev: v2.1.0
32+
- repo: https://github.com/astral-sh/uv-pre-commit
33+
rev: 0.8.3
3434
hooks:
35-
- id: refurb
35+
- id: uv-lock
3636
- repo: https://github.com/executablebooks/mdformat
3737
rev: 0.7.22
3838
hooks:

CHANGES.md renamed to CHANGELOG.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@ chronological order. Releases follow [semantic versioning](https://semver.org/)
55
releases are available on [PyPI](https://pypi.org/project/pytask-stata) and
66
[Anaconda.org](https://anaconda.org/conda-forge/pytask-stata).
77

8-
## 0.4.1 - 2024-xx-xx
8+
## 0.5.0 - 2025-07-26
99

1010
- {pull}`37` updates the CI.
11-
- {pull}`38` updates tests for pytask v0.5.
11+
- {pull}`38` updates tests for pytask v0.5.0.
12+
- {pull}`41` use uv, use ty, update tests and CI, raise minimum python version to 3.9
13+
and support Python 3.13.
1214

1315
## 0.4.0 - 2024-03-19
1416

justfile

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Install all dependencies
2+
install:
3+
uv sync --all-groups
4+
5+
# Run tests
6+
test:
7+
uv run --group test pytest --cov=src --cov=tests --cov-report=xml
8+
9+
# Run type checking
10+
typing:
11+
uv run --group typing --group test ty check
12+
13+
# Run linting and formatting
14+
lint:
15+
uvx --with pre-commit-uv pre-commit run -a
16+
17+
# Run all checks (format, lint, typing, test)
18+
check: lint typing test
19+
20+
# Run tests with lowest dependency resolution
21+
test-lowest:
22+
uv run --group test --resolution lowest-direct pytest
23+
24+
# Run tests with highest dependency resolution
25+
test-highest:
26+
uv run --group test --resolution highest pytest

pyproject.toml

Lines changed: 8 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,14 @@ classifiers = [
1414
"Programming Language :: Python :: 3",
1515
"Programming Language :: Python :: 3 :: Only",
1616
]
17-
requires-python = ">=3.8"
18-
dependencies = ["click", "pytask>=0.4"]
17+
requires-python = ">=3.9"
18+
dependencies = ["click>=8.1.8,!=8.2.0", "pytask>=0.5.2"]
1919
dynamic = ["version"]
2020

2121
[project.readme]
2222
file = "README.md"
2323
content-type = "text/markdown"
2424

25-
[project.optional-dependencies]
26-
test = ["pytest", "pytest-cov", "pytest-xdist"]
27-
typing = ["mypy"]
28-
2925
[project.urls]
3026
Homepage = "https://github.com/pytask-dev/pytask-stata"
3127
Documentation = "https://github.com/pytask-dev/pytask-stata"
@@ -36,11 +32,13 @@ Changelog = "https://github.com/pytask-dev/pytask-stata/blob/main/CHANGES.md"
3632
[project.entry-points]
3733
pytask = { pytask_stata = "pytask_stata.plugin" }
3834

39-
[tool.rye]
40-
managed = true
41-
dev-dependencies = [
42-
"tox-uv>=1.8.2",
35+
[dependency-groups]
36+
test = [
37+
"pytest>=8.4.0",
38+
"pytest-cov>=5.0.0",
39+
"pytest-xdist>=3.6.1",
4340
]
41+
typing = ["pytask-parallel>=0.5.1", "ty"]
4442

4543
[tool.hatch.build.hooks.vcs]
4644
version-file = "src/pytask_stata/_version.py"
@@ -59,31 +57,13 @@ source = "vcs"
5957
[tool.hatch.metadata]
6058
allow-direct-references = true
6159

62-
[tool.mypy]
63-
files = ["src", "tests"]
64-
check_untyped_defs = true
65-
disallow_any_generics = true
66-
disallow_incomplete_defs = true
67-
disallow_untyped_defs = true
68-
no_implicit_optional = true
69-
warn_redundant_casts = true
70-
warn_unused_ignores = true
71-
72-
[[tool.mypy.overrides]]
73-
module = "tests.*"
74-
disallow_untyped_defs = false
75-
ignore_errors = true
76-
7760
[tool.ruff]
78-
target-version = "py38"
7961
fix = true
8062
unsafe-fixes = true
8163

8264
[tool.ruff.lint]
8365
select = ["ALL"]
8466
ignore = [
85-
"ANN101",
86-
"ANN102",
8767
"ANN401", # flake8-annotate typing.Any
8868
"COM812", # Comply with ruff-format.
8969
"ISC001", # Comply with ruff-format.
@@ -104,8 +84,5 @@ convention = "numpy"
10484
testpaths = ["tests"]
10585
markers = [
10686
"wip: Tests that are work-in-progress.",
107-
"unit: Flag for unit tests which target mainly a single function.",
108-
"integration: Flag for integration tests which may comprise of multiple unit tests.",
109-
"end_to_end: Flag for tests that cover the whole program.",
11087
]
11188
norecursedirs = [".idea", ".tox"]

src/pytask_stata/collect.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ def pytask_collect_task(
6262
raise ValueError(msg)
6363

6464
mark = _parse_stata_mark(mark=marks[0])
65-
script, options = stata(**marks[0].kwargs)
66-
obj.pytask_meta.markers.append(mark)
65+
script, options = stata(**marks[0].kwargs) # ty: ignore[missing-argument]
66+
obj.pytask_meta.markers.append(mark) # ty: ignore[possibly-unbound-attribute]
6767

6868
# Collect the nodes in @pytask.mark.julia and validate them.
6969
path_nodes = Path.cwd() if path is None else path.parent
@@ -141,7 +141,7 @@ def pytask_collect_task(
141141
dependencies["_executable"] = executable_node
142142

143143
partialed = functools.partial(run_stata_script, _cwd=path.parent)
144-
markers = obj.pytask_meta.markers if hasattr(obj, "pytask_meta") else []
144+
markers = obj.pytask_meta.markers if hasattr(obj, "pytask_meta") else [] # ty: ignore[unresolved-attribute]
145145

146146
task: PTask
147147
if path is None:
@@ -187,6 +187,6 @@ def pytask_collect_task(
187187

188188
def _parse_stata_mark(mark: Mark) -> Mark:
189189
"""Parse a Stata mark."""
190-
script, options = stata(**mark.kwargs)
190+
script, options = stata(**mark.kwargs) # ty: ignore[missing-argument]
191191
parsed_kwargs = {"script": script or None, "options": options or []}
192192
return Mark("stata", (), parsed_kwargs)

src/pytask_stata/execute.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,14 @@ def pytask_execute_task_teardown(session: Session, task: PTask) -> None:
4040
"""
4141
if has_mark(task, "stata"):
4242
if session.config["platform"] == "win32":
43-
log_name = task.depends_on["_log_name"].load()
43+
log_name = task.depends_on["_log_name"].load() # ty: ignore[call-non-callable]
4444
if isinstance(task, PTaskWithPath):
4545
path_to_log = task.path.with_name(log_name).with_suffix(".log")
4646
else:
47-
path_to_log = Path.cwd(log_name).with_name(log_name).with_suffix(".log")
47+
path_to_log = Path.cwd() / f"{log_name}.log"
4848
else:
4949
node = task.depends_on["_script"]
50-
path_to_log = node.path.with_suffix(".log")
50+
path_to_log = node.path.with_suffix(".log") # ty: ignore[call-non-callable,possibly-unbound-attribute]
5151

5252
n_lines = session.config["stata_check_log_lines"]
5353

src/pytask_stata/shared.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
from __future__ import annotations
44

55
import sys
6+
from collections.abc import Iterable
7+
from collections.abc import Sequence
68
from typing import TYPE_CHECKING
79
from typing import Any
8-
from typing import Iterable
9-
from typing import Sequence
1010

1111
if TYPE_CHECKING:
1212
from pathlib import Path

tests/test_collect.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
from pytask_stata.collect import stata
1010

1111

12-
@pytest.mark.unit
1312
@pytest.mark.parametrize(
1413
("args", "kwargs", "expectation", "expected"),
1514
[
@@ -29,11 +28,10 @@
2928
)
3029
def test_stata(args, kwargs, expectation, expected):
3130
with expectation:
32-
options = stata(*args, **kwargs)
31+
options = stata(*args, **kwargs) # ty: ignore[missing-argument]
3332
assert options == expected
3433

3534

36-
@pytest.mark.unit
3735
@pytest.mark.parametrize(
3836
("mark", "expectation", "expected"),
3937
[

tests/test_config.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
from __future__ import annotations
22

3-
import pytest
43
from pytask import build
54

65

7-
@pytest.mark.end_to_end
86
def test_marker_is_configured(tmp_path):
97
session = build(paths=tmp_path)
108

0 commit comments

Comments
 (0)