Skip to content

Commit 4af4ce3

Browse files
alexvbrdnclaude
andcommitted
Align repo with the Java and JS SDKs, and make the lint gate pass
The CI lint job could not pass: flake8 reported ~700 violations (mostly from the generated package) and mypy 2 errors. Generated code is now excluded from both, and the real issues in hand-written code are fixed: 18 malformed continuation lines, 6 overlong docstrings, and a cast(Any, ...) in cardinality.py that was the intent behind the unused cast import. Packaging had three sources of version truth: pyproject.toml, setup.py, and the generator-emitted requirements files, which nothing consumes. pyproject is now the single manifest, matching the Java pom and the JS package.json. generate-api.sh appended pytest-asyncio to test-requirements.txt on every run; both files are now generator-ignored. - publish.yml runs the test suite before building, 2-space indentation like the other workflows, and spells PyPI correctly - README: the API overview claimed every method accepts response_format; analyze operations and determinize() take execution_timeout only. Added the async notes after each table, as in the Java README, and fixed a typo - pinned openapi-generator 7.21.0, as in the Java and JS repos - .gitignore rewritten in the shared layout, with .env and IDE entries Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent c32f8e3 commit 4af4ce3

16 files changed

Lines changed: 185 additions & 187 deletions

‎.flake8‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[flake8]
2+
max-line-length = 120
3+
# E203 (whitespace before ':') conflicts with black's slice formatting.
4+
extend-ignore = E203
5+
extend-exclude =
6+
regexsolver/_generated,
7+
.venv,
8+
venv,
9+
build,
10+
dist

‎.github/workflows/publish.yml‎

Lines changed: 70 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,73 @@
1-
name: Publish to PyPi
1+
name: Publish to PyPI
22

33
on:
4-
push:
5-
tags:
6-
- 'v*'
7-
4+
push:
5+
tags:
6+
- "v*"
7+
88
jobs:
9-
build:
10-
name: Build distribution
11-
runs-on: ubuntu-latest
12-
13-
steps:
14-
- uses: actions/checkout@v4
15-
- name: Set up Python
16-
uses: actions/setup-python@v5
17-
with:
18-
python-version: "3.x"
19-
- name: Install pypa/build
20-
run: >-
21-
python3 -m
22-
pip install
23-
build
24-
--user
25-
- name: Build a binary wheel and a source tarball
26-
run: python3 -m build
27-
- name: Store the distribution packages
28-
uses: actions/upload-artifact@v4
29-
with:
30-
name: python-package-distributions
31-
path: dist/
32-
publish-to-pypi:
33-
name: Publish to PyPI
34-
needs:
35-
- build
36-
runs-on: ubuntu-latest
37-
environment:
38-
name: pypi
39-
url: https://pypi.org/p/regexsolver
40-
permissions:
41-
id-token: write
42-
steps:
43-
- name: Download all the dists
44-
uses: actions/download-artifact@v4
45-
with:
46-
name: python-package-distributions
47-
path: dist/
48-
- name: Publish distribution to PyPI
49-
uses: pypa/gh-action-pypi-publish@release/v1
9+
test:
10+
name: Test
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- uses: actions/checkout@v4
15+
16+
- name: Set up Python
17+
uses: actions/setup-python@v5
18+
with:
19+
python-version: "3.12"
20+
cache: "pip"
21+
22+
- name: Install dependencies
23+
run: |
24+
python -m pip install --upgrade pip
25+
pip install -e ".[test]"
26+
27+
- name: Run tests with pytest
28+
run: pytest
29+
30+
build:
31+
name: Build distribution
32+
needs: test
33+
runs-on: ubuntu-latest
34+
35+
steps:
36+
- uses: actions/checkout@v4
37+
38+
- name: Set up Python
39+
uses: actions/setup-python@v5
40+
with:
41+
python-version: "3.12"
42+
43+
- name: Install pypa/build
44+
run: python3 -m pip install build --user
45+
46+
- name: Build a binary wheel and a source tarball
47+
run: python3 -m build
48+
49+
- name: Store the distribution packages
50+
uses: actions/upload-artifact@v4
51+
with:
52+
name: python-package-distributions
53+
path: dist/
54+
55+
publish:
56+
name: Publish to PyPI
57+
needs: build
58+
runs-on: ubuntu-latest
59+
environment:
60+
name: pypi
61+
url: https://pypi.org/p/regexsolver
62+
permissions:
63+
id-token: write
64+
65+
steps:
66+
- name: Download all the dists
67+
uses: actions/download-artifact@v4
68+
with:
69+
name: python-package-distributions
70+
path: dist/
71+
72+
- name: Publish distribution to PyPI
73+
uses: pypa/gh-action-pypi-publish@release/v1

‎.gitignore‎

Lines changed: 28 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,49 @@
1+
# Build output
2+
build/
3+
dist/
4+
sdist/
5+
*.egg-info/
6+
*.egg
7+
.eggs/
8+
develop-eggs/
9+
.installed.cfg
10+
111
# Byte-compiled / optimized / DLL files
212
__pycache__/
313
*.py[cod]
414
*$py.class
5-
6-
# C extensions
715
*.so
816

9-
# Distribution / packaging
17+
# Virtual environments
1018
.Python
1119
env/
12-
build/
13-
develop-eggs/
14-
dist/
15-
downloads/
16-
eggs/
17-
.eggs/
20+
venv/
21+
.venv/
1822
lib/
1923
lib64/
2024
parts/
21-
sdist/
2225
var/
23-
*.egg-info/
24-
.installed.cfg
25-
*.egg
26-
27-
# PyInstaller
28-
# Usually these files are written by a python script from a template
29-
# before PyInstaller builds the exe, so as to inject date/other infos into it.
30-
*.manifest
31-
*.spec
32-
33-
# Installer logs
34-
pip-log.txt
35-
pip-delete-this-directory.txt
26+
.python-version
3627

37-
# Unit test / coverage reports
38-
htmlcov/
28+
# Test / coverage / type checking
29+
.pytest_cache/
30+
.mypy_cache/
3931
.tox/
32+
.cache
33+
htmlcov/
4034
.coverage
4135
.coverage.*
42-
.cache
43-
nosetests.xml
4436
coverage.xml
45-
*,cover
37+
nosetests.xml
4638
.hypothesis/
47-
venv/
48-
.venv/
49-
.python-version
50-
.pytest_cache
51-
52-
# Translations
53-
*.mo
54-
*.pot
55-
56-
# Django stuff:
57-
*.log
5839

59-
# Sphinx documentation
60-
docs/_build/
40+
# Environment
41+
.env
6142

62-
# PyBuilder
63-
target/
43+
# IDE
44+
.idea/
45+
.vscode/
46+
*.iml
6447

65-
# Ipython Notebook
66-
.ipynb_checkpoints
48+
# OS
49+
.DS_Store

‎.openapi-generator-ignore‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
setup.py
22
setup.cfg
33
tox.ini
4+
.gitignore
5+
requirements.txt
6+
test-requirements.txt
47
git_push.sh
58
.travis.yml
69
.gitlab-ci.yml
@@ -10,8 +13,7 @@ docs/
1013
test/
1114
README.md
1215

13-
1416
regexsolver/__init__.py
15-
regexsolver/client.py
17+
regexsolver/clients/*
1618
regexsolver/exceptions.py
1719
regexsolver/models/*

‎README.md‎

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ The API can handle terms in two formats:
7070
- `regex`: a regular expression pattern
7171
- `fair`: FAIR (Fast Automaton Internal Representation), a stable, signed format used internally by the engine
7272

73-
By default, the engine returns whatever the operation produces, with no extra convertion. Override with `response_format`:
73+
By default, the engine returns whatever the operation produces, with no extra conversion. Override with `response_format`, accepted by the operations that return a term:
74+
7475
```python
7576
from regexsolver import ResponseFormat
7677

@@ -109,7 +110,7 @@ Timeout is best effort. The exact time is not guaranteed.
109110

110111
## API Overview
111112

112-
`RegexSolverClient` and `AsyncRegexSolverClient` exposes the following methods. All methods accept optional keyword arguments `response_format` and `execution_timeout`.
113+
`RegexSolverClient` and `AsyncRegexSolverClient` expose the following methods. Every method accepts optional keyword arguments: operations that return a term take `response_format`, `deterministic` and `execution_timeout`, while analyze operations and `determinize()` take `execution_timeout` only — the response format is not theirs to choose.
113114

114115
### Analyze
115116

@@ -126,6 +127,8 @@ Timeout is best effort. The exact time is not guaranteed.
126127
| `client.is_deterministic(term, **kwargs)` | `bool` | `True` if the term's automaton is deterministic. Only a deterministic FAIR guarantees consistent string ordering across paginated `generate_strings()` calls; call `determinize()` first if this is `False`. |
127128
| `client.subset(term1, term2, **kwargs)` | `bool` | `True` if every string matched by `term1` is also matched by `term2`. |
128129

130+
*Note: For `AsyncRegexSolverClient`, these methods are coroutines and must be awaited.*
131+
129132
### Compute
130133

131134
| Method | Return | Description |
@@ -138,12 +141,16 @@ Timeout is best effort. The exact time is not guaranteed.
138141
| `client.repeat(term, min, max, **kwargs)` | `Term` | Computes the repetition of the term between `min` and `max` times. |
139142
| `client.union(term1, term2, ..., **kwargs)` | `Term` | Computes the union of the given terms. |
140143

144+
*Note: For `AsyncRegexSolverClient`, these methods are coroutines and must be awaited.*
145+
141146
### Generate
142147

143148
| Method | Return | Description |
144149
| -------- | ------- | ------- |
145150
| `client.generate_strings(term, limit, offset, **kwargs)` | `List[str]` | Generates up to `limit` unique strings matched by `term`, skipping the first `offset` strings. |
146151

152+
*Note: For `AsyncRegexSolverClient`, this method is a coroutine and must be awaited.*
153+
147154
## Cross-Language Support
148155

149156
If you want to use this library with other programming languages, we provide:

‎generate-api.sh‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,4 @@ openapi-generator-cli generate \
1111
-o "$OUT_DIR" \
1212
--additional-properties=packageName="$PACKAGE_NAME",library=asyncio
1313

14-
15-
echo "pytest-asyncio >= 1.3.0" >> test-requirements.txt
14+
echo "API Generation Complete."

‎openapitools.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
"$schema": "./node_modules/@openapitools/openapi-generator-cli/config.schema.json",
33
"spaces": 2,
44
"generator-cli": {
5-
"version": "7.20.0"
5+
"version": "7.21.0"
66
}
77
}

‎pyproject.toml‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,18 @@ Issues = "https://github.com/RegexSolver/regexsolver-python/issues"
6464
Documentation = "https://docs.regexsolver.com/"
6565
"Source Code" = "https://github.com/RegexSolver/regexsolver-python"
6666

67+
[tool.setuptools.packages.find]
68+
include = ["regexsolver*"]
69+
70+
[tool.mypy]
71+
exclude = ["regexsolver/_generated/"]
72+
73+
# Generated code is not linted or type checked; it is regenerated from
74+
# ../m-lab/shared/openapi.yaml by ./generate-api.sh.
75+
[[tool.mypy.overrides]]
76+
module = "regexsolver._generated.*"
77+
follow_imports = "silent"
78+
6779
[tool.pytest.ini_options]
6880
asyncio_mode = "auto"
6981
asyncio_default_fixture_loop_scope = "function"

0 commit comments

Comments
 (0)