Skip to content

Fix test suite for OCC 7.9 / Python 3.14; add CI, docs, examples & lint toolchain#1

Merged
LayerDynamics merged 2 commits into
mainfrom
chore/harden-suite-tooling-docs
Jun 10, 2026
Merged

Fix test suite for OCC 7.9 / Python 3.14; add CI, docs, examples & lint toolchain#1
LayerDynamics merged 2 commits into
mainfrom
chore/harden-suite-tooling-docs

Conversation

@LayerDynamics

Copy link
Copy Markdown
Contributor

Summary

Brings PyOCC to a green, lint-clean state on the current conda-forge stack
(pythonocc-core 7.9.3, NumPy 2, Python 3.14) and stands up the project
tooling that was previously empty (CI, license, contributing guide, docs,
examples, markdown lint).

Starting point: the suite couldn't even be collected (a repo-root __init__.py
shadowed the installed package), and once collectable it was 59 failed + 1
collection error
. End state: 275 passed, 19 skipped, 0 failed, with
ruff + black + pymarkdown all clean.

Core / runtime fixes

  • Shape hierarchy: reparent Vertex/Edge/Wire/Shell/Solid/Compound under
    Shape, pruning the mixins Shape already provides to avoid C3 MRO errors;
    shape.py imports the concrete wrappers lazily to break the import cycle.
  • OCC 7.x API drift: rewrite get_triangles() to the 7.6+ triangulation API
    (BRep_Tool.Triangulation + NbNodes/Node/NbTriangles/Triangle().Get()); the
    pyocc_shape()/create_from_topods() factory now down-casts to the concrete
    TopoDS_* type so load_stl/load_brep and topology explorers wrap correctly.
  • Unified find_closest_point_data() to the (point, middle, distance)
    3-tuple contract every caller already indexed.
  • Bug fixes: Edge.point() raw-parameter branch (Interval.a/.b),
    DisplayMaterial mutable-numpy dataclass defaults (default_factory), an
    undefined Shell reference in Solid.make_from_shell, de-duplication in
    vertices_from_face/edges_from_vertex, and wires_from_face double-wrapping.
  • API completeness: boolean ops are now instance methods (a.union(b) and
    Solid.union(a, b)); OffscreenRenderer(width=, height=); the missing
    MultiViewRenderer/BatchProcessor/viewer methods are implemented; the
    _process_single_shape stub data is replaced with real analysis/exports.
  • New: UniformGrid + sample_face_uniformly/sample_edge_uniformly;
    2D uv_bounds + Box.__iter__; arc-length finder precision.

Tests

275 passed, 19 skipped, 0 failed. The 19 skips are the OpenGL offscreen
viewer/render tests — they need a display, so CI runs them under Xvfb.
Added io_test.py (STEP/STL/BREP round-trips, previously untested) and an
Edge.point() raw-parameter regression test.

Tooling / docs

  • CI workflows (check.yml, build.yml, publish.yml): micromamba env;
    ruff + black + pymarkdown gates; pytest under Xvfb; sdist/wheel build +
    conda smoke-import; PyPI trusted publishing on release.
  • Lint to zero: cleared all ruff issues; switched import sorting to ruff's
    black-compatible isort (the standalone isort oscillated with black); added
    PyMarkdown + a shared .markdownlint.jsonc config; fixed pyproject URLs.
  • Docs: LICENSE, CONTRIBUTING.md, docs/ (architecture, developer guide,
    API reference), and runnable examples/. Removed the dead repo-root
    __init__.py shim.

Notes for review

  • The OpenCASCADE offscreen-render paths are CI-verified-only (they can't run
    without a GL display, so they're exercised under Xvfb in CI rather than locally).
  • CLAUDE.md is intentionally gitignored and not included.

🤖 Generated with Claude Code

…t toolchain

Bring the package to a green, lint-clean state on the current conda-forge stack
(pythonocc-core 7.9.3, NumPy 2, Python 3.14) and stand up the project tooling
that was previously empty.

Core/runtime fixes:
- Reparent Vertex/Edge/Wire/Shell/Solid/Compound under Shape, pruning the mixins
  Shape already provides to avoid C3 MRO errors; shape.py imports the concrete
  wrappers lazily to break the resulting import cycle.
- get_triangles(): use the OCC 7.6+ triangulation API (BRep_Tool.Triangulation +
  NbNodes/Node/NbTriangles/Triangle().Get()) instead of removed Nodes()/IsNull().
- Unify find_closest_point_data() to the (point, middle, distance) 3-tuple
  contract every caller already expected.
- pyocc_shape()/create_from_topods(): down-cast to the concrete TopoDS_* type so
  the file loaders (load_stl/load_brep) and explorers wrap shapes correctly.
- Fix Edge.point() raw-parameter branch (Interval.a/.b, not .start/.end),
  DisplayMaterial mutable-numpy dataclass defaults (default_factory), an
  undefined Shell reference in Solid.make_from_shell, dedup in
  vertices_from_face/edges_from_vertex, and wires_from_face double-wrapping.
- Boolean ops (union/difference/intersection/subtraction) are now instance
  methods; OffscreenRenderer accepts width/height; implement the missing
  MultiViewRenderer/BatchProcessor methods and the 5 missing viewer methods;
  replace the _process_single_shape stub data with real analysis/exports.
- Add UniformGrid + sample_face_uniformly/sample_edge_uniformly; make uv_bounds
  2D + add Box.__iter__; improve arc-length finder precision.

Tests: 275 passed, 19 skipped (display-gated; run under Xvfb in CI), 0 failed.
Added io_test.py round-trips and an Edge.point raw-parameter regression test.

Tooling/docs:
- Implement check.yml / build.yml / publish.yml (micromamba env; ruff + black +
  pymarkdown gates; pytest under Xvfb; sdist/wheel + smoke import; PyPI trusted
  publishing).
- Drive ruff to zero; switch import sorting to ruff (black-compatible, no
  oscillation); add PyMarkdown + markdownlint config; fix pyproject URLs.
- Add LICENSE, CONTRIBUTING.md, docs/ (architecture, developer guide, API), and
  runnable examples/. Remove the dead repo-root __init__.py shim that shadowed
  the installed src/pyocc package under pytest.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @LayerDynamics, your pull request is larger than the review limit of 150000 diff characters

The check.yml step listed CLAUDE.md explicitly, but CLAUDE.md is gitignored, so a
fresh CI checkout has no such file and PyMarkdown failed with "path does not
exist" (exit 1). Scan `git ls-files '*.md'` instead so ignored files are never
referenced; updated the documented command to match.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@LayerDynamics LayerDynamics merged commit 3fd5356 into main Jun 10, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant