BaseController exposes a growing number of public names that collide with names a driver author might reasonably want to use for Attribute, Command, or Scan members.
These can be overwritten with no error, breaking internal logic.
Currently reserved public names
From BaseController / Tracer:
| Name |
Kind |
root_attribute |
class attribute (override hook) |
description |
class attribute (override hook) |
initialise |
async method (override hook) |
post_initialise |
method |
path |
property |
set_path |
method |
add_attribute |
method |
add_sub_controller |
method |
add_command |
method |
add_scan |
method |
attributes |
property |
sub_controllers |
property |
command_methods |
property |
scan_methods |
property |
connected |
property |
log_event |
method |
enable_tracing |
method |
disable_tracing |
method |
add_tracing_filter |
method |
remove_tracing_filter |
method |
clear_tracing_filters |
method |
From Controller:
| Name |
Kind |
connect |
async method (override hook) |
reconnect |
async method |
disconnect |
async method (override hook) |
Note: _bind_attrs already filters out _-prefixed names, so _ is the existing implicit convention separating framework internals from driver-exposed members. The public names above break this.
Possible Solutions
Option A: Add a runtime guard in add_attribute / add_command / add_scan
Raise a ValueError at registration time if the name clashes with any name already present on BaseController:
_RESERVED_NAMES = frozenset(dir(BaseController))
def add_attribute(self, name, attr):
if name in _RESERVED_NAMES:
raise ValueError(f"'{name}' is reserved by FastCS and cannot be used as an attribute name")
...
- Pro: catches conflicts early with a clear error, no API change
- Con: doesn't remove the pollution; reserved names grow silently over time
Option B: Prefix all framework-internal members with _
Apply _ consistently to everything that is framework infrastructure rather than a driver API, e.g.:
-
path → _path (already the backing field)
-
set_path → _set_path
-
add_attribute, add_sub_controller, add_command, add_scan → _add_*
-
attributes, sub_controllers, command_methods, scan_methods → _attributes, etc.
-
post_initialise → _post_initialise
-
Pro: clean and consistent; drivers get a large open namespace; aligns with the existing _bind_attrs filter
-
Con: breaking change for driver code that calls controller.add_attribute(...) or accesses controller.attributes directly; Tracer methods would also need renaming. These are really public methods and may need to be called externally, e.g. by FastCS.
Option C: Isolate framework state into a nested object
Move all framework-managed state and accessors onto a single attribute, e.g. self.fastcs:
controller.fastcs.attributes
controller.fastcs.add_attribute(...)
controller.fastcs.connected
- Pro: fully isolated namespace, no reserved names beyond
fastcs
- Con: most invasive refactor; changes all internal call sites
BaseControllerexposes a growing number of public names that collide with names a driver author might reasonably want to use forAttribute,Command, orScanmembers.These can be overwritten with no error, breaking internal logic.
Currently reserved public names
From
BaseController/Tracer:root_attributedescriptioninitialisepost_initialisepathset_pathadd_attributeadd_sub_controlleradd_commandadd_scanattributessub_controllerscommand_methodsscan_methodsconnectedlog_eventenable_tracingdisable_tracingadd_tracing_filterremove_tracing_filterclear_tracing_filtersFrom
Controller:connectreconnectdisconnectNote:
_bind_attrsalready filters out_-prefixed names, so_is the existing implicit convention separating framework internals from driver-exposed members. The public names above break this.Possible Solutions
Option A: Add a runtime guard in
add_attribute/add_command/add_scanRaise a
ValueErrorat registration time if the name clashes with any name already present onBaseController:Option B: Prefix all framework-internal members with
_Apply
_consistently to everything that is framework infrastructure rather than a driver API, e.g.:path→_path(already the backing field)set_path→_set_pathadd_attribute,add_sub_controller,add_command,add_scan→_add_*attributes,sub_controllers,command_methods,scan_methods→_attributes, etc.post_initialise→_post_initialisePro: clean and consistent; drivers get a large open namespace; aligns with the existing
_bind_attrsfilterCon: breaking change for driver code that calls
controller.add_attribute(...)or accessescontroller.attributesdirectly;Tracermethods would also need renaming. These are really public methods and may need to be called externally, e.g. by FastCS.Option C: Isolate framework state into a nested object
Move all framework-managed state and accessors onto a single attribute, e.g.
self.fastcs:fastcs