Fix two plugin-loading bugs: labconfig defaults read as plugin flags, and a setup retry that re-runs side effects - #123
Open
ispielma wants to merge 2 commits into
Open
Conversation
ConfigParser sections inherit [DEFAULT], so items('BLACS/plugins')
returns the section's own options plus every labconfig default. Against a
typical labconfig that means apparatus_name, userlib, labscriptlib,
shared_drive and friends are all seen as configured plugins:
line 90 sees: ['apparatus_name', 'userlib', 'labscript_suite',
'connection_table']
A plugin directory whose name collides with a [DEFAULT] key therefore
never had an enable flag written into the section, and getboolean() then
read the default's value instead:
ValueError: Not a boolean: /home/u/labscript-suite/userlib
That call is unguarded and this whole block runs at module scope, so
`import blacs.plugins` raised and BLACS did not start at all, rather than
skipping a single plugin.
Write a real flag into the section when the inherited value is not a
boolean; a section option shadows [DEFAULT], so the plugin resolves from
then on. An installation that legitimately sets the flag in both places
is unaffected, since the section value already wins:
collision only in [DEFAULT] before: ValueError after: starts, plugin disabled
set in both places before: enabled after: enabled
Also swap the list-membership test for has_option(), which expresses the
same question directly.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The old-API fallback was driven by catching Exception from the call
itself, so any failure inside a correctly-written
plugin_setup_complete(data) triggered a second invocation.
For a plugin whose hook accepts both arities, such as
def plugin_setup_complete(self, data=None)
the retry re-enters the body, so whatever the first, partially completed
call had already done - started a thread, registered a listener, opened a
connection - is done a second time:
plugin_setup_complete(self, data=None) before: side effect ran 2x
after: side effect ran 1x
Plugins with a strict arity were never double-run, because the retry
failed on argument count before reaching the body, which is why this has
been easy to miss.
Bind the signature first and call once with the arguments it accepts.
Old no-argument plugins still work and still get the deprecation warning;
plugins with no introspectable signature fall back to the current API. A
genuine error now produces one clear log entry rather than a misleading
"Trying again with old call signature" followed by an arity error.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two independent plugin bugs found while Claude audite
labscript-utilsand itscallers. Separate commits, both reproduced against
masterfirst.1. Labconfig
[DEFAULT]keys are read as plugin enable flagsConfigParsersections inherit[DEFAULT], soexp_config.items('BLACS/plugins')returns the section's own options plusevery labconfig default. Against a typical labconfig:
A plugin directory whose name collides with a
[DEFAULT]key therefore neverhad an enable flag written into the section, and
getboolean()then read thedefault's value instead:
That call is unguarded and the whole block runs at module scope, so
import blacs.pluginsraises and BLACS does not start at all, rather thanskipping a single plugin.
The fix writes a real flag into the section when the inherited value is not a
boolean — a section option shadows
[DEFAULT], so the plugin resolves fromthen on — and swaps the list-membership test for
has_option(), which asks thequestion directly. An installation that legitimately sets the flag in both
places is unaffected, because the section value already wins:
2.
plugin_setup_completeretry re-runs side effectsThe old-API fallback is driven by catching
Exceptionfrom the call itself, soany failure inside a correctly-written
plugin_setup_complete(data)triggers asecond invocation.
For a plugin whose hook accepts both arities:
the retry re-enters the body, so whatever the first, partially completed call
had already done — started a thread, registered a listener, opened a
connection — happens a second time:
Plugins with a strict arity were never double-run, because the retry failed on
argument count before reaching the body, which is why this has been easy to
miss. Note that
labscript_utils.plugins.BasePlugindeclares exactly theoptional-argument signature, so this shape is not hypothetical.
The fix binds the signature first and calls once with the arguments it
accepts. Old no-argument plugins still work and still get the deprecation
warning; plugins with no introspectable signature fall back to the current
API. A genuine error now produces one clear log entry instead of a misleading
"Trying again with old call signature" followed by an arity error.
2 files changed, 35 insertions(+), 10 deletions(-)