Skip to content

Commit e546392

Browse files
zeevdrclaude
andauthored
fix(packaging): include py.typed and .pyi stubs in wheel (#77)
Without [tool.setuptools.package-data], setuptools omits non-Python files from the built wheel. This means py.typed and the generated .pyi stubs were never shipped, silently breaking the "Typing :: Typed" classifier. Add the package-data declaration, a CI wheel-check job that builds the wheel and asserts py.typed is present, and a README Typing section that documents the guarantee. Closes #47 Co-authored-by: Claude <noreply@anthropic.com>
1 parent 10ab157 commit e546392

3 files changed

Lines changed: 43 additions & 1 deletion

File tree

.github/workflows/ci.yml

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,10 +127,45 @@ jobs:
127127
python -m py_compile examples/error-handling/main.py
128128
python -m py_compile examples/setup.py
129129
130+
wheel-check:
131+
name: Wheel contents
132+
runs-on: ubuntu-latest
133+
timeout-minutes: 10
134+
steps:
135+
- name: Checkout
136+
uses: actions/checkout@v6
137+
with:
138+
persist-credentials: false
139+
140+
- name: Set up Python
141+
uses: actions/setup-python@v6
142+
with:
143+
python-version: "3.12"
144+
145+
- name: Build wheel
146+
run: |
147+
pip install build
148+
python -m build sdk/ --wheel --outdir /tmp/dist
149+
150+
- name: Assert py.typed present
151+
run: |
152+
pip install zipfile36
153+
python - <<'EOF'
154+
import zipfile, glob, sys
155+
wheels = glob.glob("/tmp/dist/*.whl")
156+
assert wheels, "no wheel found"
157+
with zipfile.ZipFile(wheels[0]) as whl:
158+
names = whl.namelist()
159+
found = [n for n in names if n.endswith("py.typed")]
160+
if not found:
161+
print("FAIL: py.typed missing from wheel"); print("\n".join(names)); sys.exit(1)
162+
print(f"OK: {found[0]}")
163+
EOF
164+
130165
check:
131166
name: CI check
132167
if: always()
133-
needs: [lint, typecheck, test, examples]
168+
needs: [lint, typecheck, test, examples, wheel-check]
134169
runs-on: ubuntu-latest
135170
timeout-minutes: 5
136171
steps:

sdk/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ async with AsyncConfigClient("localhost:9090", subject="myapp") as client:
6868

6969
For detailed concepts (schemas, typed values, versioning, auth), see the [main OpenDecree docs](https://github.com/opendecree/decree).
7070

71+
## Typing
72+
73+
This package is fully typed. It ships a `py.typed` marker and `.pyi` stub files for the generated gRPC layer, so mypy, pyright, and similar tools work without additional configuration.
74+
7175
## Requirements
7276

7377
- Python 3.11+

sdk/pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ Issues = "https://github.com/opendecree/decree-python/issues"
4747
[tool.setuptools.packages.find]
4848
where = ["src"]
4949

50+
[tool.setuptools.package-data]
51+
opendecree = ["py.typed", "_generated/**/*.pyi"]
52+
5053
[tool.ruff]
5154
target-version = "py311"
5255
line-length = 100

0 commit comments

Comments
 (0)