Follow-up from review of fc8e710 (#358 / PR #360).
The CA id validator (src/fastcs/transports/epics/ca/util.py:16) accepts ids matching [A-Za-z0-9_-]+. So "___" and "-" are valid CA ids.
_coerce_pascal_name in emission.py then routes them through pvi.device.enforce_pascal_case, whose body strips all non-Pascal characters and then unconditionally indexes s[0]:
s = NON_PASCAL_CHARS_RE.sub(lambda _: "", s)
return s[0].upper() + s[1:]
When all characters are stripped, s == "" and s[0].upper() raises IndexError: string index out of range — before our guard runs:
candidate = enforce_pascal_case(controller_id) # raises here
if candidate and not candidate[0].isupper():
candidate = "X" + candidate
return candidate
Reproduced locally:
>>> enforce_pascal_case('___')
IndexError: string index out of range
>>> enforce_pascal_case('-')
IndexError: string index out of range
So GUI emission blows up at connect() time for a small but legitimate slice of CA-valid ids.
Suggested fix
Pre-strip and check before calling enforce_pascal_case, or fall back to a safe constant:
def _coerce_pascal_name(controller_id: str) -> str:
stripped = NON_PASCAL_CHARS_RE.sub("", controller_id)
if not stripped:
return "X" # or raise, depending on policy
candidate = enforce_pascal_case(controller_id)
if not candidate[0].isupper():
candidate = "X" + candidate
return candidate
Refs
src/fastcs/transports/epics/emission.py:25-35
src/fastcs/transports/epics/ca/util.py:16 (validator regex that lets these ids through)
Follow-up from review of fc8e710 (#358 / PR #360).
The CA id validator (
src/fastcs/transports/epics/ca/util.py:16) accepts ids matching[A-Za-z0-9_-]+. So"___"and"-"are valid CA ids._coerce_pascal_nameinemission.pythen routes them throughpvi.device.enforce_pascal_case, whose body strips all non-Pascal characters and then unconditionally indexess[0]:When all characters are stripped,
s == ""ands[0].upper()raisesIndexError: string index out of range— before our guard runs:Reproduced locally:
So GUI emission blows up at
connect()time for a small but legitimate slice of CA-valid ids.Suggested fix
Pre-strip and check before calling
enforce_pascal_case, or fall back to a safe constant:Refs
src/fastcs/transports/epics/emission.py:25-35src/fastcs/transports/epics/ca/util.py:16(validator regex that lets these ids through)