Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

* Created `compas_plotter.__all_plugins__`, so COMPAS's plugin manager discovers the
`register_scene_objects` factory through the standard `collect_all` path (the
same mechanism `compas_viewer` uses).

### Changed

### Removed

* Removed Eager, import-time `register_scene_objects()` call in
`compas_plotter.scene`, and the `from . import scene` side-effect import in
`compas_plotter/__init__.py`. These populated COMPAS's global
`ITEM_SCENEOBJECT` at import time, which suppressed the lazy
`if not ITEM_SCENEOBJECT` discovery trigger in `compas.scene.context` and left
every other backend unregistered.

## [1.0.0] 2026-07-11

### Added
Expand Down
8 changes: 3 additions & 5 deletions src/compas_plotter/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,8 @@
from .__version__ import __version__
from .plotter import Plotter

# Importing the scene subpackage triggers registration of the Plotter scene
# objects. When this package is pip-installed, COMPAS would also discover the
# @plugin-decorated factory through the entry point; importing here guarantees
# registration works in editable / non-installed setups as well.
from . import scene # noqa: E402,F401
# COMPAS plugin discovery imports the modules listed here to find the
# ``@plugin``-decorated ``register_scene_objects`` factory.
__all_plugins__ = ["compas_plotter.scene"]

__all__ = ["Plotter", "__version__"]
5 changes: 0 additions & 5 deletions src/compas_plotter/scene/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,6 @@ def register_scene_objects():
# objects are implemented (Breps additionally need e.g. compas_occ).


# Eager registration so that the Plotter works in editable / non-installed setups
# (where the entry-point-based plugin discovery does not run).
register_scene_objects()


__all__ = [
"PlotterScene",
"PlotterSceneObject",
Expand Down
34 changes: 30 additions & 4 deletions tests/test_plotter.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import subprocess
import sys
import textwrap

import matplotlib

matplotlib.use("Agg")
Expand All @@ -19,6 +23,8 @@
from compas.geometry import Sphere
from compas.geometry import Torus
from compas.geometry import Vector
from compas.geometry import Translation
from compas.scene import Scene

from compas_plotter import Plotter
from compas_plotter.scene import BoxObject
Expand All @@ -33,6 +39,7 @@
from compas_plotter.scene import PolylineObject
from compas_plotter.scene import ShapeObject
from compas_plotter.scene import VectorObject
from compas_plotter.scene import PlotterScene


def test_add_point_returns_pointobject():
Expand Down Expand Up @@ -128,9 +135,6 @@ def test_redraw_clears_and_redraws():


def test_scene_is_a_compas_scene():
from compas.scene import Scene

from compas_plotter.scene import PlotterScene

plotter = Plotter()
assert isinstance(plotter.scene, PlotterScene)
Expand All @@ -139,7 +143,6 @@ def test_scene_is_a_compas_scene():


def test_scene_hierarchy_and_world_transform():
from compas.geometry import Translation

plotter = Plotter()
parent = plotter.add(Point(0, 0, 0))
Expand Down Expand Up @@ -217,3 +220,26 @@ def frame(f):

assert obj.vertex_xyz[1][1] == 3.0
assert obj.vertex_xyz[3][2] == 3.0


def test_import_does_not_populate_registry_eagerly():
script = textwrap.dedent(
"""
import compas.scene.context as ctx
import compas_plotter # must not register anything on its own
assert not ctx.ITEM_SCENEOBJECT, ctx.ITEM_SCENEOBJECT

# Discovery through the plugin path still finds the Plotter backend and,
# critically, the base COMPAS context too.
from compas.scene.context import register_scene_objects
register_scene_objects()
from compas.datastructures import Mesh
assert "Plotter" in ctx.ITEM_SCENEOBJECT
assert Mesh in ctx.ITEM_SCENEOBJECT["Plotter"]
assert Mesh in ctx.ITEM_SCENEOBJECT[None]
print("OK")
"""
)
result = subprocess.run([sys.executable, "-c", script], capture_output=True, text=True)
assert result.returncode == 0, result.stderr
assert "OK" in result.stdout
Loading