0
0
Fork 0

fix(symbol-config): mutate configured_access via get_all_signatures, not configured view (#7)

set_symbol_access and set_signature_access_bulk both looked up the target
signature via sc_obj.get_only_configured_signatures() first and only fell
back to get_all_signatures() if not found. The objects returned by
get_only_configured_signatures() are a read-only view; assigning to
.configured_access on them raises:

  The access of the variable can only be changed in the list of all
  signatures/data types.

This was hidden during initial testing because the bulk variant was
exercised before any variables were configured (so the configured view
was empty and the all-signatures fallback fired). Once the configured
set was populated, the single-var set_symbol_access path always picked
up the read-only object and broke.

Fix: always look up the mutation target via get_all_signatures(); use
get_only_configured_signatures() only as a tracking-only flag for
'was this signature already exported'. Verified live on MCPTest.project
under SP22 P1: bulk-set PLC_PRG to ReadWrite (4 vars), then per-var
set_symbol_access PLC_PRG.s1 = None succeeds and list_configured_symbols
reflects effective_access=None on s1.

Co-authored-by: Karstein Phobic Nyvold Kvistad <karstein.kvistad@maritimerobotics.com>
This commit is contained in:
phobicdotno 2026-04-29 10:17:07 +02:00 committed by GitHub
parent 05d0e37e21
commit 3dcdb34b58
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 30 additions and 22 deletions

View file

@ -80,18 +80,20 @@ try:
library_id = LIBRARY_ID if LIBRARY_ID else None
# IMPORTANT: configured_access is mutable ONLY on signature objects
# obtained from get_all_signatures(); the objects returned by
# get_only_configured_signatures() are a read-only view and assigning
# to .configured_access on them raises
# "The access of the variable can only be changed in the list
# of all signatures/data types."
# So we always look up via get_all_signatures, never the configured
# view, for the mutation target.
sig = None
try:
configured = sc_obj.get_only_configured_signatures()
sig = _find_signature_in(configured, SIGNATURE_FQN, library_id)
all_sigs = sc_obj.get_all_signatures(False)
sig = _find_signature_in(all_sigs, SIGNATURE_FQN, library_id)
except Exception:
pass
if sig is None:
try:
all_sigs = sc_obj.get_all_signatures(False)
sig = _find_signature_in(all_sigs, SIGNATURE_FQN, library_id)
except Exception:
pass
if sig is None:
try:
all_sigs = sc_obj.get_all_signatures(True)

View file

@ -122,30 +122,36 @@ try:
requested_access = _resolve_access(ACCESS)
print("DEBUG: requested_access resolved to %r" % requested_access)
# Try the configured set first (these are the variables already
# selected for export). Fall back to the all-signatures view if the
# variable isn't yet configured -- setting access on a not-yet-configured
# variable is the standard way to "tick" it.
# IMPORTANT: configured_access is mutable ONLY on signature objects
# obtained from get_all_signatures(); the objects returned by
# get_only_configured_signatures() are a read-only view and assigning
# to .configured_access on them raises
# "The access of the variable can only be changed in the list
# of all signatures/data types."
# So we always look up via get_all_signatures first. The configured
# view is kept only as a final fallback (and to report whether the
# variable was already exported), never as the mutation target.
sig = None
library_id = LIBRARY_ID if LIBRARY_ID else None
try:
configured = sc_obj.get_only_configured_signatures()
sig = _find_signature_in(configured, SIGNATURE_FQN, library_id)
all_sigs = sc_obj.get_all_signatures(False)
sig = _find_signature_in(all_sigs, SIGNATURE_FQN, library_id)
except Exception as e:
print("DEBUG: get_only_configured_signatures failed: %s" % e)
found_in_configured = sig is not None
if sig is None:
try:
all_sigs = sc_obj.get_all_signatures(False)
sig = _find_signature_in(all_sigs, SIGNATURE_FQN, library_id)
except Exception as e:
print("DEBUG: get_all_signatures(False) failed: %s" % e)
print("DEBUG: get_all_signatures(False) failed: %s" % e)
if sig is None:
try:
all_sigs = sc_obj.get_all_signatures(True)
sig = _find_signature_in(all_sigs, SIGNATURE_FQN, library_id)
except Exception as e:
print("DEBUG: get_all_signatures(True) failed: %s" % e)
# Tracking-only: was this signature already in the configured set?
found_in_configured = False
try:
configured = sc_obj.get_only_configured_signatures()
if _find_signature_in(configured, SIGNATURE_FQN, library_id) is not None:
found_in_configured = True
except Exception:
pass
if sig is None:
raise RuntimeError(
"Signature '%s' not found (library_id=%s). "