Skip to content

Commit ed3c792

Browse files
Modernize project configuration: uv, Python 3.10+, PEP 639, CI coverage
- Require Python >= 3.10 (3.9 is EOL and held back the toolchain: tokenizer >= 3.6.3, current mypy and setuptools all need 3.10+); bump version to 3.7.0, tokenizer floor to >= 3.6.3 - Adopt uv properly: commit uv.lock, move dev dependencies to PEP 735 [dependency-groups] (adding ruff and mypy; mypy excluded on PyPy where its native dependencies don't build), use astral-sh/setup-uv and 'uv sync --locked' in CI - Switch license metadata to PEP 639 SPDX form (license = "MIT", license-files), drop the deprecated license classifier, require setuptools >= 77.0.3 in the build system - Move mypy configuration into pyproject.toml [tool.mypy] (target 3.10); drop the unused [tool.isort] section - Test on Windows and macOS (one job each) in addition to the Linux matrix, since wheels are shipped for all three platforms - Pin cibuildwheel (4.1.0) in the wheels workflow; build cp310 abi3 wheels; remove vestigial git-lfs configuration (no files use LFS) - Update README and CLAUDE.md accordingly Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 676bb96 commit ed3c792

8 files changed

Lines changed: 616 additions & 60 deletions

File tree

.gitattributes

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
src/reynir/resources/ordalisti-*.bin filter=lfs diff=lfs merge=lfs -text
2-
src/reynir/resources/ord.compressed filter=lfs diff=lfs merge=lfs -text
3-
41
# Set the default line ending behavior to auto
52
* text=auto
63

.github/workflows/python-package.yml

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,25 +13,27 @@ jobs:
1313
strategy:
1414
matrix:
1515
os: [ubuntu-latest]
16-
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14", "pypy-3.11"]
16+
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "pypy3.11"]
17+
# The Windows and macOS wheels are built from the same sources,
18+
# so test at least one Python version on each of those platforms
19+
include:
20+
- os: windows-latest
21+
python-version: "3.13"
22+
- os: macos-latest
23+
python-version: "3.13"
1724

1825
steps:
1926
- uses: actions/checkout@v4
20-
- name: Set up Python ${{ matrix.python-version }}
21-
uses: actions/setup-python@v5
27+
- name: Install uv
28+
uses: astral-sh/setup-uv@v8
2229
with:
2330
python-version: ${{ matrix.python-version }}
2431
- name: Install GreynirEngine
25-
run: |
26-
python -m pip install uv
27-
uv pip install --system wheel setuptools pytest ruff
28-
uv pip install --system -e .
32+
run: uv sync --locked
2933
- name: Lint with ruff
30-
run: |
31-
ruff check src/reynir
34+
run: uv run ruff check src/reynir
3235
- name: Test with pytest
33-
run: |
34-
python -m pytest
36+
run: uv run pytest
3537
- name: Slack notification
3638
uses: 8398a7/action-slack@v3
3739
with:

.github/workflows/wheels.yml

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,26 +16,25 @@ jobs:
1616

1717
steps:
1818
- uses: actions/checkout@v4
19-
with:
20-
lfs: true
2119

2220
- uses: actions/setup-python@v5
2321
with:
2422
python-version: '3.11'
2523

2624
- name: Install cibuildwheel
27-
run: python -m pip install --upgrade pip wheel setuptools cibuildwheel
25+
# Pinned so that releases only change toolchain when we choose to
26+
run: python -m pip install --upgrade pip wheel setuptools cibuildwheel==4.1.0
2827

2928
- name: Build wheels
3029
run: python -m cibuildwheel --output-dir wheelhouse
3130
# Options (https://cibuildwheel.readthedocs.io/en/stable/options/)
3231
env:
33-
# Build abi3 wheel for CPython 3.9+ (one wheel for all versions)
32+
# Build abi3 wheel for CPython 3.10+ (one wheel for all versions)
3433
# Build version-specific wheel for PyPy (which doesn't support abi3)
35-
CIBW_BUILD: cp39-* pp311-*
34+
CIBW_BUILD: cp310-* pp311-*
3635
CIBW_SKIP: "*musllinux*"
3736
CIBW_ENABLE: pypy
38-
CIBW_PROJECT_REQUIRES_PYTHON: ">=3.9"
37+
CIBW_PROJECT_REQUIRES_PYTHON: ">=3.10"
3938
CIBW_BEFORE_BUILD_MACOS: python3 -m pip install --upgrade setuptools wheel cffi
4039
CIBW_ARCHS_MACOS: "x86_64 arm64"
4140
CIBW_ARCHS_WINDOWS: "AMD64"
@@ -54,8 +53,6 @@ jobs:
5453

5554
steps:
5655
- uses: actions/checkout@v4
57-
with:
58-
lfs: true
5956

6057
- uses: actions/setup-python@v5
6158
with:

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,6 @@ p37/
9595
pypy*
9696

9797
# uv stuff
98-
uv.lock
9998
.python-version
10099

101100
# Installer logs

CLAUDE.md

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,32 +7,38 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
77
GreynirEngine (PyPI package name: `reynir`, imported as `reynir`) is an NLP engine
88
for parsing Icelandic text into sentence trees. It combines a hand-written
99
context-free grammar for Icelandic with a C++ Earley-Scott parser core, wrapped
10-
via CFFI. Source lives in `src/reynir/`. Supports CPython 3.9+ and PyPy 3.11+.
10+
via CFFI. Source lives in `src/reynir/`. Supports CPython 3.10+ and PyPy 3.11+.
1111

1212
## Commands
1313

14+
The project uses [uv](https://docs.astral.sh/uv/) with a committed `uv.lock`;
15+
dev dependencies live in `[dependency-groups]` in `pyproject.toml`.
16+
1417
```sh
15-
# Install for development (compiles the C++ parser extension via CFFI)
16-
pip install -e .
18+
# Set up the dev environment (installs dev deps from uv.lock and
19+
# compiles the C++ parser extension via CFFI)
20+
uv sync
1721

1822
# Run all tests
19-
python -m pytest
23+
uv run pytest
2024

2125
# Run a single test file / single test
22-
python -m pytest test/test_parse.py
23-
python -m pytest test/test_parse.py::test_long_parse
26+
uv run pytest test/test_parse.py
27+
uv run pytest test/test_parse.py::test_long_parse
2428

2529
# Lint (CI runs this)
26-
ruff check src/reynir
30+
uv run ruff check src/reynir
2731

28-
# Type check (config in mypy.ini, targets Python 3.9)
29-
mypy src/reynir
32+
# Type check (config in pyproject.toml [tool.mypy]; carries a handful of
33+
# known pre-existing errors, so it is not a CI gate)
34+
uv run mypy src/reynir
3035
```
3136

32-
Note: `pip install -e .` must be re-run after changing the C++ sources
33-
(`eparser.cpp`, `eparser.h`) or `eparser_build.py`, since the `_eparser`
34-
CFFI extension is compiled at install time (see `setup.py`, which exists only
35-
for the `cffi_modules` hook; all other metadata is in `pyproject.toml`).
37+
Note: after changing the C++ sources (`eparser.cpp`, `eparser.h`) or
38+
`eparser_build.py`, force a rebuild of the `_eparser` CFFI extension with
39+
`uv sync --reinstall-package reynir` (the extension is compiled at install
40+
time; see `setup.py`, which exists only for the `cffi_modules` hook — all
41+
other metadata is in `pyproject.toml`).
3642

3743
## Architecture
3844

@@ -92,8 +98,9 @@ The public API is defined by the exports in `src/reynir/__init__.py`.
9298
`so`=verb, `nf`/`þf`/`þgf`/`ef`=cases, `et`/`ft`=number, `kk`/`kvk`/`hk`=gender);
9399
these appear throughout the code, tests and grammar files.
94100
- Ruff line length is 88; `E731` (lambda assignment) is ignored.
95-
- CI (`.github/workflows/python-package.yml`) runs ruff + pytest on
96-
Python 3.9–3.14 and PyPy 3.11. Wheels are built via cibuildwheel on tag push
97-
(abi3 wheel for CPython, version-specific for PyPy).
101+
- CI (`.github/workflows/python-package.yml`) runs ruff + pytest via
102+
`uv sync --locked` on Python 3.10–3.14 and PyPy 3.11 on Linux, plus one
103+
job each on Windows and macOS. Wheels are built on tag push via a pinned
104+
cibuildwheel (`cp310` abi3 wheel for CPython, version-specific for PyPy).
98105
- The `old/` and `build/` directories contain legacy/build artifacts — do not
99106
edit code there.

README.md

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
2-
[![Python 3.9](https://img.shields.io/badge/python-3.9-blue.svg)](https://www.python.org/downloads/release/python-3817/)
2+
[![Python 3.10](https://img.shields.io/badge/python-3.10-blue.svg)](https://www.python.org/downloads/)
33
![Release](https://shields.io/github/v/release/mideind/GreynirEngine?display_name=tag)
44
![PyPI](https://img.shields.io/pypi/v/reynir)
55
[![Build](https://github.com/mideind/GreynirEngine/actions/workflows/python-package.yml/badge.svg)]()
@@ -12,7 +12,7 @@
1212

1313
## Overview
1414

15-
Greynir is a Python 3 (>=3.9) package,
15+
Greynir is a Python 3 (>=3.10) package,
1616
published by [Miðeind ehf.](https://mideind.is), for
1717
**working with Icelandic natural language text**.
1818
Greynir can parse text into **sentence trees**, find **lemmas**,
@@ -147,7 +147,7 @@ and each token annotated with its lemma and POS tag (`no`=noun, `so`=verb):
147147

148148
## Prerequisites
149149

150-
This package runs on CPython 3.9 or newer, and on PyPy 3.11 or newer.
150+
This package runs on CPython 3.10 or newer, and on PyPy 3.11 or newer.
151151

152152
To find out which version of Python you have, enter:
153153

@@ -195,14 +195,17 @@ The package source code is in `GreynirEngine/src/reynir`.
195195

196196
## Tests
197197

198-
To run the built-in tests, install [pytest](https://docs.pytest.org/en/latest),
199-
`cd` to your `GreynirEngine` subdirectory (and optionally activate your
200-
virtualenv), then run:
198+
To run the built-in tests, `cd` to your `GreynirEngine` subdirectory and,
199+
using [uv](https://docs.astral.sh/uv/), run:
201200

202201
````sh
203-
python -m pytest
202+
uv sync
203+
uv run pytest
204204
````
205205

206+
Alternatively, install [pytest](https://docs.pytest.org/en/latest) into
207+
your virtualenv and run `python -m pytest`.
208+
206209
## Evaluation
207210

208211
A parsing test pipeline for different parsing schemas, including the Greynir schema,

pyproject.toml

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,29 @@
11
[build-system]
2-
requires = ["setuptools>=61.0", "cffi>=1.15.1"]
2+
requires = ["setuptools>=77.0.3", "cffi>=1.15.1"]
33
build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "reynir"
7-
version = "3.6.2"
7+
version = "3.7.0"
88
description = "A natural language parser for Icelandic"
99
authors = [{ name = "Miðeind ehf.", email = "mideind@mideind.is" }]
1010
maintainers = [{ name = "Miðeind ehf.", email = "mideind@mideind.is" }]
1111
readme = { file = "README.md", content-type = "text/markdown" }
12-
license = { text = "MIT License" }
12+
license = "MIT"
13+
license-files = ["LICENSE.txt"]
1314
keywords = ["nlp", "parser", "icelandic"]
1415
classifiers = [
1516
# complete classifier list: http://pypi.python.org/pypi?%3Aaction=list_classifiers
1617
"Development Status :: 5 - Production/Stable",
1718
"Intended Audience :: Developers",
1819
"Intended Audience :: Science/Research",
19-
"License :: OSI Approved :: MIT License",
2020
"Operating System :: Unix",
2121
"Operating System :: POSIX",
2222
"Operating System :: Microsoft :: Windows",
2323
"Operating System :: MacOS",
2424
"Natural Language :: Icelandic",
2525
"Programming Language :: Python",
2626
"Programming Language :: Python :: 3",
27-
"Programming Language :: Python :: 3.9",
2827
"Programming Language :: Python :: 3.10",
2928
"Programming Language :: Python :: 3.11",
3029
"Programming Language :: Python :: 3.12",
@@ -36,10 +35,10 @@ classifiers = [
3635
"Topic :: Utilities",
3736
"Topic :: Text Processing :: Linguistic",
3837
]
39-
requires-python = ">=3.9"
38+
requires-python = ">=3.10"
4039
dependencies = [
4140
"cffi>=1.17.1",
42-
"tokenizer>=3.6.0",
41+
"tokenizer>=3.6.3",
4342
"islenska>=1.3.2",
4443
"filelock>=3.9.0",
4544
"typing_extensions",
@@ -51,9 +50,16 @@ Homepage = "https://greynir.is"
5150
Documentation = "https://greynir.is/doc/"
5251
Issues = "https://github.com/mideind/GreynirEngine/issues"
5352

54-
[project.optional-dependencies]
55-
# dev dependencies
56-
dev = ["pytest", "setuptools"]
53+
[dependency-groups]
54+
# Development dependencies: uv installs these automatically with 'uv sync';
55+
# with pip (>=25.1), use 'pip install --group dev'.
56+
# mypy is excluded on PyPy, where its native dependencies don't build.
57+
dev = [
58+
"pytest",
59+
"ruff",
60+
"mypy; implementation_name != 'pypy'",
61+
"setuptools",
62+
]
5763

5864
# *** Configuration of tools ***
5965

@@ -78,7 +84,6 @@ ignore = [
7884
"E731", # 'E731: Do not assign a lambda expression, use a def'
7985
]
8086

81-
[tool.isort]
82-
# This forces these imports to placed at the top
83-
known_future_library = ["__future__", "typing", "typing_extensions"]
84-
line_length = 88
87+
[tool.mypy]
88+
python_version = "3.10"
89+
exclude = ['doc/conf\.py']

0 commit comments

Comments
 (0)