Modernize build system, CI/CD, types, tests, and docs (phases 01-05)#237
Modernize build system, CI/CD, types, tests, and docs (phases 01-05)#237
Conversation
- Add [build-system] with uv_build backend - Add [project] with metadata migrated from setup.py - Add [project.scripts] entry points (stl, stl2ascii, stl2bin) - Add [project.optional-dependencies] with modernized docs/tests/dev extras - Add [tool.uv.build-backend] with module-root - Migrate pytest config from pytest.ini to [tool.pytest.ini_options] - Preserve existing [tool.mypy], [tool.pyright], [tool.pyrefly] sections
- Read version from installed package metadata at runtime - Fallback to '0.0.0' when package not installed (build time) - Preserve all other metadata fields for backwards compatibility
- Update target-version from py39 to py310 per D-09 decision - Aligns with new Python >=3.10 requirement floor
… config - Fix UP035: import TypeAlias from typing instead of typing_extensions - Fix RUF022: sort __all__ in stl/__init__.py - Fix SIM905: replace str.split with string literal in __about__.py - Fix I001: sort imports in test files - Fix ruff format violations in stl/base.py - Fix sphinx dep to support Python 3.10 (environment marker) - Add module-name to uv build-backend config (Rule 3: blocking fix)
- Remove setup.py (metadata migrated to pyproject.toml) - Remove setup.cfg (Sphinx dirs handled by docs/conf.py, bdist_wheel not needed) - Remove MANIFEST.in (uv_build auto-includes package contents) - Remove tox.ini (test matrix info preserved for Phase 3 CI) - Remove pytest.ini (migrated to [tool.pytest.ini_options] in pyproject.toml) - Remove tests/requirements.txt (migrated to [project.optional-dependencies])
- Create stl/_compat.py with find_spec-based speedups detection - Export has_speedups(), ascii_read, ascii_write from _compat module - Add [project.optional-dependencies] fast = ["speedups"] to pyproject.toml
# Conflicts: # .planning/REQUIREMENTS.md # .planning/ROADMAP.md # .planning/STATE.md
- Replace _speedups import with _compat ascii_read/ascii_write imports - Remove pyright suppression comment and type: ignore[redundant-expr] - Remove --disable-speedups CLI flag from main.py - Fix duplicate [project.optional-dependencies] section in pyproject.toml
- Remove -s flag usage from test_commandline.py - Create test_compat.py with unit tests for _compat.py detection layer - Delete stl/_speedups.pyx and stl/_speedups.pyi (moved to external project)
…pe_check.yml - Create ci.yml with test (Python 3.10-3.13 x numpy1/numpy2), lint, and type-check jobs - Use uv + astral-sh/setup-uv@v7 instead of tox - Enforce 100% coverage via --cov-fail-under=100 - Run ruff check/format, ty check, pyrefly check - Delete legacy tox-based main.yml and standalone type_check.yml
- Three parallel commands: ruff check, ruff format (auto-stage), ty check - No pyrefly in hooks (too slow, CI-only per DEV-04) - No pre-push hook (CI catches everything on push) - staged_files with glob for ruff, whole-project for ty
- Trigger on v* tags for release automation - Build with uv build, upload artifact between jobs - Publish via pypa/gh-action-pypi-publish with OIDC (no API keys) - Requires GitHub environment 'pypi' and PyPI Trusted Publisher config
- Delete appveyor.yml (dead Windows CI config) - Remove AppVeyor and Coveralls badges from README.rst - Update GitHub Actions badge URL from main.yml to ci.yml - Replace Travis CI reference in CONTRIBUTING.rst with generic CI - Update Python versions in CONTRIBUTING.rst to 3.10-3.13 - Replace travis reference in stl/stl.py comment with CI - Remove dead Travis Python 3.6 skip in tests/test_ascii.py
# Conflicts: # .planning/REQUIREMENTS.md # .planning/ROADMAP.md # .planning/STATE.md
- Add TypeAlias to main typing import (line 7) - Replace 18 'TypeAlias' string annotations with bare TypeAlias - Fixes all invalid-type-form errors from ty checker
- Add ty error codes to dual-checker suppression comments (base.py) - Add ty:unresolved-attribute to name-mangling ignore (base.py) - Fix _get_name to always return str, eliminating return None path (main.py) - Add config-level suppressions for speedups import (pyproject.toml) - Replace deprecated in-place .shape assignment with .reshape() (base.py)
- Cover exception handler at __about__.py:7-8 via monkeypatch reload - Verify normal version matches importlib.metadata.version - Closes __about__.py coverage from 83% to 100%
…overage - Add if _speedups_available: to .coveragerc exclude_lines - Add test-speedups CI job with continue-on-error for optional speedups - Coverage now passes at 100% with branch measurement
- Change readme field from README.rst to README.md - Add furo>=2025.1 to docs extras - Create .readthedocs.yaml with v2 config for Python 3.13
- Replace 377-line 2014 conf.py with minimal 40-line Furo config - Replace index.rst with 3-tier toctree (getting-started, guide, api) - Create 2 getting-started pages (installation, quickstart) - Create 5 guide pages (reading-writing, mesh-operations, properties, cli, speedups) - Create 2 API pages (index with enums/constants, mesh with autoclass) - Remove Python 2 intersphinx URLs and dead links - Add napoleon extension for Google-style docstrings
- Write fresh Markdown README with badges, quick-start code, features list - Add dedicated Performance/Speedups section - Include usage examples (mesh creation, transforms, mass properties, plotting) - Update all badge URLs to ci.yml workflow - Remove dead Tidelift and blog links from old README
- Write modern CONTRIBUTING.md with uv, lefthook, ruff, ty workflow - Create CHANGELOG.md with 11 entries in Keep a Changelog format - Backfill dates from git tags (v2.0.0 through v3.2.0) - No legacy tools referenced (flake8, tox, virtualenvwrapper removed)
- Remove README.rst (replaced by README.md) - Remove CONTRIBUTING.rst (replaced by CONTRIBUTING.md) - Remove docs/_theme/wolph/ directory (replaced by Furo theme) - Remove docs/usage.rst, docs/tests.rst, docs/stl.rst (replaced by 3-tier structure)
- Add class docstring to Dimension enum - Rewrite RemoveDuplicates docstring to Google-style with single quotes - Add docstring to RemoveDuplicates.map classmethod - Add docstring to logged() function - Rewrite BaseMesh class preamble to Google-style Args format - Add one-line docstrings to 12 minor accessor properties - Add expanded docstrings with examples to 5 cached properties - Preserve all existing BaseMesh.__init__ doctests byte-for-byte
- Add Google-style docstrings with Args/Returns/Raises to all public methods - Add >>> examples to rotate, translate, get_mass_properties - Add Warning sections for is_closed, check, rotate, rotate_using_matrix - Add edge case documentation for 6 methods (cache, closure, rotation) - Convert remaining triple-double-quote strings to single quotes - All existing doctests preserved, all new doctests passing
… utils.py - Add Mode enum docstring with usage guidance - Add Google-style docstrings to all BaseStl methods (load, save, from_file, etc.) - Add >>> examples to from_file, from_multi_file, from_files, from_3mf_file, save - Add Warning/Note sections for save (binary handle), from_multi_file (ASCII-only), 3MF (experimental) - Add Mesh class docstring with example - Add CLI function docstrings (main, to_ascii, to_binary) - Add module-level docstring to __init__.py with quick start example - Add docstring to utils.b() function
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request delivers a comprehensive modernization of the Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Ignored Files
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
cf4b49b to
c41361a
Compare
There was a problem hiding this comment.
Pull request overview
Modernizes the numpy-stl repository across packaging, optional speedups, CI/tooling, typing/testing, and documentation, aligning the project with a pyproject/uv-based workflow and refreshed Sphinx docs.
Changes:
- Migrates legacy build/test config (setup.py/tox/pytest.ini/etc.) to
pyproject.tomland uv tooling; adds lefthook and updated CI workflows. - Externalizes Cython speedups into an optional
speedupsdependency via a new_compatdetection layer and[fast]extra; removes in-repo Cython sources. - Rebuilds documentation (README + Sphinx structure), adds/updates tests for new import-time/version behaviors, and adds project planning/audit artifacts.
Reviewed changes
Copilot reviewed 58 out of 58 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tox.ini | Remove legacy tox config |
| tests/test_rotate.py | Import formatting cleanup |
| tests/test_mesh.py | Import formatting cleanup |
| tests/test_compat.py | New tests for _compat exports/detection |
| tests/test_commandline.py | Update CLI tests after removing -s/--disable-speedups |
| tests/test_ascii.py | Import reorder; remove legacy Travis-specific skip |
| tests/test_about.py | New tests for __about__ version fallback/normal path |
| tests/requirements.txt | Remove legacy test requirements file |
| stl/utils.py | Add Google-style docstring for b() |
| stl/mesh.py | Add class docstring/example for Mesh |
| stl/main.py | Remove disable-speedups flag; improve _get_name; add CLI docstrings |
| stl/_speedups.pyx | Remove in-repo Cython speedups source |
| stl/_speedups.pyi | Remove in-repo speedups type stub |
| stl/_compat.py | New optional speedups compatibility/detection layer |
| stl/init.py | Add module docstring; reorder __all__ |
| stl/about.py | Switch to importlib.metadata version lookup with fallback |
| setup.py | Remove legacy setuptools build script |
| setup.cfg | Remove legacy setuptools config |
| ruff.toml | Bump target version to py310 |
| pytest.ini | Remove legacy pytest config file |
| pyproject.toml | Centralize build/project/tool config; extras; pytest opts; typing tool config |
| lefthook.yml | Add pre-commit hooks (ruff + ty) |
| docs/usage.rst | Remove legacy docs include page |
| docs/tests.rst | Remove legacy test listing page |
| docs/stl.rst | Remove legacy API page |
| docs/index.rst | New 3-tier docs navigation structure |
| docs/guide/speedups.rst | New speedups documentation page |
| docs/guide/reading-writing.rst | New I/O guide page |
| docs/guide/properties.rst | New properties guide page |
| docs/guide/mesh-operations.rst | New mesh operations guide page |
| docs/guide/cli.rst | New CLI guide page |
| docs/getting-started/quickstart.rst | New quickstart page |
| docs/getting-started/installation.rst | New installation page |
| docs/api/mesh.rst | New Mesh API reference page |
| docs/api/index.rst | New API reference index page |
| docs/_theme/wolph/theme.conf | Remove custom legacy Sphinx theme config |
| docs/_theme/wolph/static/small_flask.css | Remove legacy theme CSS |
| docs/_theme/wolph/relations.html | Remove legacy theme template |
| docs/_theme/wolph/layout.html | Remove legacy theme template |
| docs/_theme/flask_theme_support.py | Remove legacy theme support code |
| docs/_theme/LICENSE | Remove legacy theme license file |
| appveyor.yml | Remove legacy AppVeyor CI config |
| README.md | Add modern Markdown README |
| MANIFEST.in | Remove legacy manifest config |
| CONTRIBUTING.rst | Remove legacy contributing guide |
| CONTRIBUTING.md | Add modern contributing guide (uv/lefthook/ruff/ty) |
| CHANGELOG.md | Add Keep-a-Changelog style changelog |
| .readthedocs.yaml | Add Read the Docs configuration |
| .planning/phases/05-documentation-and-community/05-DISCUSSION-LOG.md | Add planning/audit log for phase 5 |
| .planning/phases/05-documentation-and-community/05-CONTEXT.md | Add phase 5 context |
| .planning/phases/05-documentation-and-community/05-02-SUMMARY.md | Add phase 5 plan 02 summary |
| .planning/phases/05-documentation-and-community/05-01-SUMMARY.md | Add phase 5 plan 01 summary |
| .planning/phases/04-type-hints-and-testing/04-DISCUSSION-LOG.md | Add planning/audit log for phase 4 |
| .planning/phases/04-type-hints-and-testing/04-CONTEXT.md | Add phase 4 context |
| .planning/phases/04-type-hints-and-testing/04-02-SUMMARY.md | Add phase 4 plan 02 summary |
| .planning/phases/04-type-hints-and-testing/04-01-SUMMARY.md | Add phase 4 plan 01 summary |
| .planning/phases/03-ci-cd-and-developer-tooling/03-VERIFICATION.md | Add phase 3 verification report |
| .planning/phases/03-ci-cd-and-developer-tooling/03-DISCUSSION-LOG.md | Add planning/audit log for phase 3 |
| .planning/phases/03-ci-cd-and-developer-tooling/03-CONTEXT.md | Add phase 3 context |
| .planning/phases/03-ci-cd-and-developer-tooling/03-02-SUMMARY.md | Add phase 3 plan 02 summary |
| .planning/phases/03-ci-cd-and-developer-tooling/03-01-SUMMARY.md | Add phase 3 plan 01 summary |
| .planning/phases/02-speedups-externalization/02-VERIFICATION.md | Add phase 2 verification report |
| .planning/phases/02-speedups-externalization/02-DISCUSSION-LOG.md | Add planning/audit log for phase 2 |
| .planning/phases/02-speedups-externalization/02-CONTEXT.md | Add phase 2 context |
| .planning/phases/02-speedups-externalization/02-02-SUMMARY.md | Add phase 2 plan 02 summary |
| .planning/phases/02-speedups-externalization/02-01-SUMMARY.md | Add phase 2 plan 01 summary |
| .planning/phases/01-build-system-foundation/01-VERIFICATION.md | Add phase 1 verification report |
| .planning/phases/01-build-system-foundation/01-DISCUSSION-LOG.md | Add planning/audit log for phase 1 |
| .planning/phases/01-build-system-foundation/01-CONTEXT.md | Add phase 1 context |
| .planning/phases/01-build-system-foundation/01-02-SUMMARY.md | Add phase 1 plan 02 summary |
| .planning/phases/01-build-system-foundation/01-01-SUMMARY.md | Add phase 1 plan 01 summary |
| .planning/codebase/STRUCTURE.md | Add codebase structure doc |
| .planning/codebase/STACK.md | Add technology stack doc |
| .planning/codebase/INTEGRATIONS.md | Add integrations inventory doc |
| .planning/codebase/CONVENTIONS.md | Add conventions doc |
| .planning/codebase/CONCERNS.md | Add concerns/risks doc |
| .planning/STATE.md | Add planning state tracker |
| .planning/ROADMAP.md | Add roadmap doc |
| .planning/REQUIREMENTS.md | Add requirements doc |
| .planning/PROJECT.md | Add project overview doc |
| .github/workflows/type_check.yml | Remove legacy type-check workflow |
| .github/workflows/publish.yml | Add PyPI publish workflow (Trusted Publishing) |
| .github/workflows/main.yml | Remove legacy tox workflow |
| .github/workflows/ci.yml | Add consolidated CI workflow (tests/lint/types) |
| .coveragerc | Exclude optional speedups import-time branch from coverage |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| from stl import mesh | ||
|
|
||
| # Auto-detect format | ||
| m = mesh.Mesh.from_file('model.stl') | ||
|
|
||
| # Force a specific format | ||
| m = mesh.Mesh.from_file('model.stl', mode=stl.Mode.ASCII) | ||
| m = mesh.Mesh.from_file('model.stl', mode=stl.Mode.BINARY) |
There was a problem hiding this comment.
The examples in this section use stl.Mode.* but stl isn’t imported in the snippet, so readers copying this will get a NameError. Import stl (or import Mode directly) in the same code block before referencing stl.Mode.
| """Compatibility layer for optional speedups package.""" | ||
|
|
There was a problem hiding this comment.
This module docstring uses triple double-quotes, but the repo’s documented style is single quotes for all strings (including docstrings). Update this docstring quoting to match CONTRIBUTING.md’s code style guidance.
| def has_speedups() -> bool: | ||
| """Return True when the external speedups package is installed.""" | ||
| return _speedups_available |
There was a problem hiding this comment.
The has_speedups() docstring uses triple double-quotes, which conflicts with the project’s stated convention of single quotes for docstrings. Align this docstring quoting with CONTRIBUTING.md to keep style consistent.
| try: | ||
| from importlib.metadata import version as _version | ||
|
|
||
| __version__: Final[str] = _version('numpy-stl') | ||
| except Exception: | ||
| __version__: Final[str] = '0.0.0' # type: ignore[misc] |
There was a problem hiding this comment.
Catching a blanket Exception here can mask unexpected import-time failures and make debugging harder. Since the intended fallback is only when the distribution metadata isn’t available, prefer catching importlib.metadata.PackageNotFoundError (and optionally ImportError for very old environments) instead of all exceptions.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cf4b49b299
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
.github/workflows/ci.yml
Outdated
| continue-on-error: true | ||
| - name: Run tests | ||
| if: success() | ||
| run: pytest -x -q | ||
| continue-on-error: true |
There was a problem hiding this comment.
Make speedups CI job fail on regressions
The test-speedups job currently marks both the dependency install and test execution as continue-on-error, so breakages in the fast-path can pass CI unnoticed. In practice, if .[tests,fast] stops installing or speedups tests fail, the workflow can still report success, which defeats the purpose of adding this validation job and allows speedups regressions to reach master/develop.
Useful? React with 👍 / 👎.
|
Warning Gemini encountered an error creating the review. You can try again by commenting |
…rrors - Remove pragma:no-cover from speedups code paths in stl.py - Add noqa:F401 to _compat.py re-exports, fix import ordering in stl.py - Scope ty check to stl/ package only to avoid test file errors - Run tests with and without speedups, combine coverage for 100% - Add test_import_error_fallback to cover _compat.py ImportError branch - Restore appveyor.yml modernized for Python 3.10-3.13 with uv - Apply ruff format to all source and test files
The PyPI 'speedups' package is unrelated (psycopg). Install from the correct GitHub repo until the package name is resolved.
Summary
__about__.pyto useimportlib.metadata, bump ruff target to py310, remove legacy build/config files_compat.pydetection layer and[fast]optional extra, rewirestl.pyto use compat module, remove Cython filestest_about.pyfor full coverage, speedups CI jobStats
Test plan
pytestpasses with full coveragemypy --strictandpyrightpassstl,stl2ascii,stl2bin) work