-
Notifications
You must be signed in to change notification settings - Fork 1k
Improve types #2824
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
base: dev
Are you sure you want to change the base?
Improve types #2824
Conversation
examples/server_async.py
Outdated
| # Continuing, or use a sparse DataBlock which can have gaps | ||
| datablock = lambda : ModbusSparseDataBlock({0x00: 0, 0x05: 1}) # pylint: disable=unnecessary-lambda-assignment | ||
| elif args.store == "factory": # pragma: no cover | ||
| elif args.store == "factory" or True: # pragma: no cover # pylint: disable=condition-evals-to-constant |
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.
Just to make it explicit what the final/default value is
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.
You replace one pylint disable with another and make it more difficult to read.
Why does this need to be changed ? (and if changed it should be changed to something without a pylint disable.
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.
I had done it this way to make it clear the final conditional is == factory.
The alternative here is to just use a default else.
--- elif args.store == "factory" or True: # pragma: no cover # pylint: disable=condition-evals-to-constant
+++ else: # args.store == "factory"| """Return a summary of the modbus plus statistics. | ||
| :returns: 54 16-bit words representing the status | ||
| :returns: An iterator over lists of 8-bit integers representing each statistic |
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.
I think this docstring has been wrong for a long time...
janiversen
left a comment
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.
A couple of comments.
examples/server_async.py
Outdated
| # Continuing, or use a sparse DataBlock which can have gaps | ||
| datablock = lambda : ModbusSparseDataBlock({0x00: 0, 0x05: 1}) # pylint: disable=unnecessary-lambda-assignment | ||
| elif args.store == "factory": # pragma: no cover | ||
| elif args.store == "factory" or True: # pragma: no cover # pylint: disable=condition-evals-to-constant |
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.
You replace one pylint disable with another and make it more difficult to read.
Why does this need to be changed ? (and if changed it should be changed to something without a pylint disable.
pymodbus/datastore/context.py
Outdated
| """ | ||
| self.single = single | ||
| self._devices = devices or {} | ||
| self._devices: dict = devices or {} |
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.
No need for type declaration, the None is removed.
The type should be added in line 157 "dict | None"
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.
Agreed line 157 is better. Upon looking close, nobody ever calls ModbusDeviceContext(devices = None) so changing the default value to {} is cleaner all around.
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.
Bah, pylint complains about {}: https://pylint.pycqa.org/en/latest/user_guide/messages/warning/dangerous-default-value.html
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.
Actually, this has revealed a tiny error in either the docstring or examples.
It's possible to pass Modbus*Context directly, as long as you pass single=True!
pymodbus/examples/custom_msg.py
Lines 122 to 131 in 431fb6c
| async def main(host="localhost", port=5020): | |
| """Run versions of read coil.""" | |
| store = ModbusServerContext(devices=ModbusDeviceContext( | |
| di=ModbusSequentialDataBlock(0, [17] * 100), | |
| co=ModbusSequentialDataBlock(0, [17] * 100), | |
| hr=ModbusSequentialDataBlock(0, [17] * 100), | |
| ir=ModbusSequentialDataBlock(0, [17] * 100), | |
| ), | |
| single=True | |
| ) |
pymodbus/transport/transport.py
Outdated
| return new_sslctx | ||
|
|
||
| def copy(self) -> CommParams: | ||
| def copy(self: CommParams) -> CommParams: |
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.
This looks wrong, self already have the correct type ??
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.
dataclasses.replace() on line 131 is.. imperfect. mypy is slightly too forgiving, but zuban is stricter.
See https://discuss.python.org/t/better-typing-for-copy-replace-functions-that-operate-on-dataclasses/105004/9
error: Argument 1 to "replace" has incompatible type "Self"; expected a dataclass [misc]
This seemed like a good workaround. Other options:
(1) typing.Self (but that requires 3.11)
(2) an explicit cast - ugly
(3) Using copy.copy()
Make types either more explicit or clearer, to help more powerful type checkers than
mypy(I'm tryingpyrightandzuban)