Skip to content

fix(graph): gcurve/gdots constructor honours size= (#287) - #290

Merged
sspickle merged 2 commits into
masterfrom
fix/gobj-size-derived
Aug 15, 2026
Merged

fix(graph): gcurve/gdots constructor honours size= (#287)#290
sspickle merged 2 commits into
masterfrom
fix/gobj-size-derived

Conversation

@sspickle

Copy link
Copy Markdown
Contributor

Fixes #287.

gcurve(size=...) / gdots(size=...) silently ignored the argument: the constructor wrote a dead _size attribute, while the size property is derived and kept reporting the default. This routes the constructor argument through the real property so the given size actually reaches the plot, with tests covering constructor-arg, post-construction assignment, and the default for both objects (7 tests, passing locally and on the rebased #289-green matrix).

Rebased onto current master (post-#289).

`gobj.size` is DERIVED from `_radius`:

    @Property
    def size(self): return 2*self._radius

but `gobj.setup`'s scalar loop writes the private name by convention —
`setattr(self, '_'+a, val)` — so `size=8` set a `_size` that nothing ever reads.
The send loop immediately below then read the value back through the property
(`getattr(self, a)`), got `2*self._radius` = 6, and shipped the DEFAULT to the
browser. `gdots(size=8)` silently plotted 6-pixel dots.

`radius=` was unaffected for the same reason in reverse: `_radius` IS the backing
store, so the convention happened to be right for it. Assigning `.size` after
construction was never broken either — only the constructor argument was lost.

`_radius` is set directly rather than through the `size` setter because that
setter also calls `addattr('radius')`, which spins on `baseObj.sent`. Here that
is redundant — this constructor's own `cmd` already carries the value — and on a
single-threaded host such as Pyodide a spin-wait inside a constructor is a
deadlock rather than a wait.

I swept every `@property` in the `gobj` class body for getters that are not
`return self._<name>`: `size` is the only one, so this is a single-attribute bug
rather than a pattern. The same shape exists in other classes' `setup` methods
where `size`/`axis` interact deliberately; those are left alone and noted in the
issue.

Tests drive `gobj.setup` directly against a stub — no transport, no browser, no
event loop — and assert on the WIRE package as well as the object, since shipping
the default was the visible symptom. Verified RED on master: the four size cases
fail without the fix, the radius/default/setter cases pass either way.
…hon)

CI runs 'pytest vpython', so a root-level tests/ dir is invisible to it —
the PR's first green run exercised the build, not these tests. Moved to
vpython/test/ alongside test_namespace.py; 8 collected locally.
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.

gcurve/gdots constructor ignores size= (writes a dead _size; the derived property reports the default)

1 participant