Repository navigation
168 lines (160 loc) · 6.76 KB
/
Copy pathpython-package.yml
File metadata and controls
168 lines (160 loc) · 6.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# 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
name: Test the Python package
on:
workflow_dispatch:
push:
branches: [ master ]
pull_request:
branches: [ master ]
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.11", "3.12", "3.13", "3.14", "3.15"]
env:
# Without this, uv sync honors .python-version (3.11) over the
# matrix interpreter and every job silently tests 3.11.
UV_PYTHON: ${{ matrix.python-version }}
# Coverage is collected in ONE job, the one that uploads it; the
# others would pay for a report nobody reads. 3.14 because
# coverage.py runs its sys.monitoring core there by default, which
# stops reporting a line once it is recorded: a line tracer
# (sys.settrace, its core below 3.14) is called on every line
# every time, and cost CI's 3.12 job most of its ~12 minutes on
# the property grids in tests/v2/test_properties.py (measured
# 2026-09-29: the three #397 grids took 139s under the settrace core
# on 3.12, 24s under sys.monitoring, 17s with no coverage). The package
# has no version-conditional code, so one interpreter's report
# stands for all of them.
COVERAGE_ON: ${{ matrix.python-version == '3.14' }}
steps:
- uses: actions/checkout@v7
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v7
with:
python-version: ${{ matrix.python-version }}
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
- name: Install dependencies
run: uv sync --group dev
- name: Run linter
run: uv run ruff check
- name: Check types
run: uv run mypy
- name: Run Tests
run: |
# Two passes: the suite in parallel (pyproject's addopts), which
# deselects the clock-timed `serial` tests, then those alone, since
# other workers' load fails their timing ratios (tests/conftest.py).
if [ "$COVERAGE_ON" = "true" ]; then
uv run pytest --cov=nameparser --cov-report=
uv run pytest -n0 -m serial --cov=nameparser --cov-append --cov-report=xml
else
uv run pytest
uv run pytest -n0 -m serial
fi
uv run --with build python -m build --sdist
uv run --with twine twine check dist/*
uv run sphinx-build -b html docs dist/docs
uv run sphinx-build -b doctest docs dist/doctest
uv run python -m doctest README.rst
- name: Upload coverage to Codecov
if: env.COVERAGE_ON == 'true'
uses: codecov/codecov-action@v7
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./coverage.xml
fail_ci_if_error: false
# The suite as a distribution packager runs it: an export of the tree
# with no repository and nameparser NOT installed, imported from the
# tree alone. The build job's editable install hides a test that
# leans on an installed package, and its checkout hides one that
# reads git: #949's test passed here only through the install, and
# was reported from a packager's build two releases after it landed.
# The dev dependencies come from the lock, so this job lists none.
source-tree:
runs-on: ubuntu-latest
env:
UV_PYTHON: "3.14"
steps:
- uses: actions/checkout@v7
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
- name: Export the tree
run: |
mkdir "$RUNNER_TEMP/export"
git archive HEAD | tar -x -C "$RUNNER_TEMP/export"
- name: Run Tests
working-directory: ${{ runner.temp }}/export
run: |
uv sync --group dev --no-install-project
# The import check first: an installed nameparser would make
# this job the build job again, passing for the same reason.
uv run --no-sync python -P -c "import importlib.util, sys; sys.exit(importlib.util.find_spec('nameparser') is not None)"
uv run --no-sync pytest
# The optional nameparser[ja] segmenter (#272). Its own job, not a
# matrix entry: the matrix above must keep proving that the package
# installs and passes with NO third-party dependency at all, which is
# the promise the extra is carved out of. Everything the extra adds
# is under tests/v2/ (the ja pack's integration tests, which skip
# without it).
ja-extra:
runs-on: ubuntu-latest
# The floor and the newest Python whose wheels the lock pins: uv.lock
# splits numpy and scipy at 3.12, so the floor is the only row that
# installs the older branch. namedivider-python's compiled
# dependencies (numpy, scipy, pandas, regex; lightgbm is py3-none)
# had no cp315 wheels at the versions uv.lock pinned before #259,
# and numpy's and scipy's sdist builds fail, so moving the top row to
# a new Python can need a lock bump first.
strategy:
fail-fast: false
matrix:
python-version: ["3.11", "3.15"]
env:
UV_PYTHON: ${{ matrix.python-version }}
steps:
- uses: actions/checkout@v7
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v7
with:
python-version: ${{ matrix.python-version }}
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
- name: Install dependencies
run: uv sync --group dev --extra ja
- name: Run Tests
# The import check first: every test the extra adds is guarded by
# a find_spec("namedivider") skipif, so a job where the extra
# silently failed to install is a job where all of them SKIP and
# the step still passes green. This line is what makes that
# failure loud -- without it the job proves nothing on the day it
# matters.
#
# The _PREFIXED_SHAPES clock guard in tests/v2/test_benchmark.py
# skips under a LINE tracer (sys.settrace -- coverage's core below
# py3.14), which dilutes the C-level cost it measures below its
# bound (#553). No CI job installs one today -- coverage runs on
# 3.14 alone, under its sys.monitoring core, which does not dilute
# the cost -- but this job is the one that must measure it
# whatever the build matrix's coverage setup becomes, so the env
# var below makes a line tracer here fail those rows rather than
# skip them: a Python downgrade under coverage,
# COVERAGE_CORE=ctrace, or a debugger.
env:
NAMEPARSER_REQUIRE_CLOCK_GUARDS: "1"
run: |
uv run python -c "import namedivider"
uv run pytest tests/v2/ -q
uv run pytest tests/v2/ -q -n0 -m serial