Refactor async_context_manager type annotations using ParamSpec - #828
Refactor async_context_manager type annotations using ParamSpec#828junyilou wants to merge 1 commit into
async_context_manager type annotations using ParamSpec#828Conversation
Updated async_context_manager function to use ParamSpec for better type hinting.
|
Thanks for this PR! I experimented with ParamSpec early on, but never could get it working the way I wanted to. Also, as you pointed out, ParamSpec is now a part of Python 3.10 which is the minimum supported version by AsyncSSH, so this is a good time to revisit this. Unfortunately, I'm still seeing errors from mypy after making this change: I still need to go through these errors in detail -- it's possible some of the Protocol classes need to be adjusted now that we're doing stricter type checking on these ACM types. If you see a way to address these, please let me know! |
|
Yes, as mentioned, because we're doing stricter type checking now, I think the mypy error in In @async_context_manager
async def open(self, path: bytes, mode: str,
block_size: int = -1) -> SFTPFileProtocol:
...This means that an implementation of fs.open(path, mode, block_size)where the third positional argument is However, @async_context_manager
async def open(self, path: _SFTPPath,
pflags_or_mode: Union[int, str] = FXF_READ,
attrs: SFTPAttrs = SFTPAttrs(),
encoding: Optional[str] = 'utf-8',
errors: str = 'strict',
block_size: int = -1,
max_requests: int = -1) -> SFTPClientFile:
...So In particular, this is not only a difference in parameter names ( # Required by _SFTPFSProtocol
fs.open(path, mode, block_size)
# ^ third positional argument = block_size
# But SFTPClient.open() interprets it as:
sftp.open(path, mode, attrs)
# ^ third positional argument = attrsPreviously, the I haven't had the time to read through enough of the rest of the codebase to confidently suggest how this particular issue should be addressed, so I don't want to speculate about a specific fix at this point. My main reason for raising this PR is actually the benefit of preserving the decorated function's signature in the first place. With I hope the existing type inconsistencies can be addressed in a way that keeps this improved type information, as I think preserving the decorated function’s signature would be a valuable improvement to the developer experience. |

Refactored the type annotations for the
async_context_managerdecorator inasyncssh/misc.pyby replacingCallable[..., ...]withParamSpec(_ACMParam). By capturing parameter types withParamSpec, static analysis tools and IDEs now accurately inspect and auto-complete the original function's arguments (names, types, and defaults) when calling decorated functions, significantly improving type safety and developer experience.typing.ParamSpecwas introduced in Python 3.10, which aligns with the project's target Python version.