feat(client): make dir()/help() work through _SyncProxy
The sync REPL proxy forwarded methods via __getattr__, so dir()/tab-completion never saw them and the sync wrapper reported (*args, **kwargs) instead of the real signature. Add __dir__ delegating to the wrapped target, and decorate the async wrapper with functools.wraps so inspect.signature()/help() report the real params + docstring. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
"""Main Proxmark3 client with nested API."""
|
||||
import asyncio
|
||||
import functools
|
||||
import glob
|
||||
import inspect
|
||||
import logging
|
||||
@@ -161,13 +162,20 @@ class _SyncProxy:
|
||||
if hasattr(attr, '_t'):
|
||||
return _SyncProxy(attr, self._loop)
|
||||
if callable(attr) and inspect.iscoroutinefunction(attr):
|
||||
# functools.wraps copies __doc__/__name__ AND sets __wrapped__, so
|
||||
# inspect.signature() and help() report the real params (block, uid=None)
|
||||
# instead of the wrapper's (*args, **kwargs).
|
||||
@functools.wraps(attr)
|
||||
def sync_wrapper(*args, **kwargs):
|
||||
return self._loop.run_until_complete(attr(*args, **kwargs))
|
||||
sync_wrapper.__name__ = name
|
||||
sync_wrapper.__doc__ = attr.__doc__
|
||||
return sync_wrapper
|
||||
return attr
|
||||
|
||||
def __dir__(self):
|
||||
# Surface the wrapped target's command methods and sub-modules so
|
||||
# dir()/REPL tab-completion and help() discovery work through the proxy.
|
||||
return sorted(set(object.__dir__(self)) | set(dir(self._target)))
|
||||
|
||||
def close(self):
|
||||
"""Disconnect and close the event loop."""
|
||||
self._loop.run_until_complete(self._target.disconnect())
|
||||
|
||||
Reference in New Issue
Block a user