-
Notifications
You must be signed in to change notification settings - Fork 207
Change attribute getters and setters into methods #371
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -73,6 +73,9 @@ def send_command(self, code: int): | |
|
||
@property | ||
def state(self) -> str: | ||
return self.get_state() | ||
|
||
def get_state(self) -> str: | ||
Comment on lines
+76
to
+78
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we want to go this route, this adds another layer of indirection, which has a small runtime penalty. Couldn't the properties be created by specifying the |
||
"""Attribute to get or set node's state as a string. | ||
|
||
Can be one of: | ||
|
@@ -93,6 +96,10 @@ def state(self) -> str: | |
|
||
@state.setter | ||
def state(self, new_state: str): | ||
logger.warning("Accessing NmtBase.state setter is deprecated, use set_state()") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please not this :-) It'll cause a truckload of log spam in existing code, without anyone digging in to fix things as long as they keep working somehow. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The DRY principle in python guides us not to, well, repeat ourselves. Having an API with multiple set/get methods is in my opinion not ideal and thus I wanted to propose to inform the user that the property based attr access is no longer the preferred way to do it. However, I do acknowledge that this is how this library has been designed. I won't argue if we decide that either There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Breaking existing code is even worse than repeating yourself. But I'd still like to see a solution where we don't need any repetition, or at least reduce it to the absolute minimum. Haven't thought it through, but I imagine some very basic code like this to "extract" the existing functions:
My experience with |
||
self.set_state(new_state) | ||
|
||
def set_state(self, new_state: str): | ||
if new_state in NMT_COMMANDS: | ||
code = NMT_COMMANDS[new_state] | ||
else: | ||
|
@@ -148,7 +155,7 @@ def wait_for_heartbeat(self, timeout: float = 10): | |
self.state_update.wait(timeout) | ||
if self._state_received is None: | ||
raise NmtError("No boot-up or heartbeat received") | ||
return self.state | ||
return self.get_state() | ||
|
||
def wait_for_bootup(self, timeout: float = 10) -> None: | ||
"""Wait until a boot-up message is received.""" | ||
|
@@ -218,7 +225,7 @@ def send_command(self, code: int) -> None: | |
# The heartbeat service should start on the transition | ||
# between INITIALIZING and PRE-OPERATIONAL state | ||
if old_state == 0 and self._state == 127: | ||
heartbeat_time_ms = self._local_node.sdo[0x1017].raw | ||
heartbeat_time_ms = self._local_node.sdo[0x1017].get_raw() | ||
self.start_heartbeat(heartbeat_time_ms) | ||
else: | ||
self.update_heartbeat() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, in my eyes this really kills the spirit of the Python library, it's just more reading without any more information. The whole point of properties and their accessors is that the (average) API user should not care about where it comes from, they just want the value. In this case, it is stored somewhere else, so must be fetched.
Of course for advanced use cases, blocking I/O functions should be clearly noted. I'm fine with having variants that will work with async etc. We just shouldn't burden the user with more complicated names, or warn them when using a perfectly fine (synchronous, blocking) API.