Ignore child events in adaptors#73
Conversation
Most of the time, the user doesn't want to know about child changes
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Updates adaptor event handling to ignore relayed “child” events that bubble up to a parent model when the parent adaptor doesn’t implement a corresponding setter, avoiding erroneous AttributeErrors while still logging useful debug info.
Changes:
- Detect bubbled/relayed events via
EmissionInfo.pathlength and ignore them when no setter exists. - Add debug logging describing the ignored nested event path and value.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # Parent change events are handled by the parent adaptor. | ||
| return | ||
|
|
||
| arg = info.args[0] |
There was a problem hiding this comment.
info.args[0] can raise IndexError if an emission occurs with no positional args (even if uncommon). Since this value is only used for logging and passing to the setter, consider guarding (e.g., check info.args length) or using a safe fallback before indexing.
|
Feel free to proceed. But this does have a faint smell to me. Is the camera controller the very first field for which this applies? Are you confident that this diversion from the original model (in which fields on the model corresponded to things that an adapter would genuinely need to respond to) is a generally useful future direction that warrants ignoring what used to be a smell? The alternative here of course is just to keep the original model and explicitly just add the set center method as a no-op. (I.e. maybe we shouldn't be so sure that they shouldn't have that method after all...). Haven't thought my way through all this, and haven't foreseen the next case where you might want to ignore it again: just noting what seems like a possible smell |
Codecov Report❌ Patch coverage is
❌ Your patch check has failed because the patch coverage (20.00%) is below the target coverage (85.00%). You can increase the patch coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## main #73 +/- ##
==========================================
- Coverage 88.09% 87.97% -0.12%
==========================================
Files 64 64
Lines 3174 3178 +4
==========================================
Hits 2796 2796
- Misses 378 382 +4 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Actually, no! I just never encountered it before because it's a code path we don't often encounter in scenex, but the camera controller seems uniquely vulnerable to this. Most of our models are insulated from this because they use import scenex as snx
# Create a view
view = snx.View()
# Create the adaptor to add a listener
view._get_adaptors(create=True)
# Call setattr
view.camera = snx.Camera(interactive=True)
# Update the child
view.camera.interactive = False # LOGS AN ERRORLogs out:
Well, no 😆 I actually had an idea recently for an organizational structure that you might like better. More to come soon on that! |
Currently, adaptors receive updates from changes to their own backing model via
Adaptor.handle_event. Once this listener is set up, setting a field of the model to some other evented class will relay child events back to the parent.Take, for example, a scenex
Camera. If you make an adaptor for that camera, and then later set its controller to anOrbit, updating its center will relay that update to theCamera. Before these changes, that would log an error, because theCameraadaptors don't have a_snx_set_centermethod, nor should they.I could foresee the relay being useful, so for now, if a relay occurs (checked here using
EmissionInfo.path), we'll just log a debug message when the adaptor doesn't have the child