Skip to content

Wrap async_to_sync with functools.update_wrapper#565

Open
patrickwehbe wants to merge 1 commit into
django:mainfrom
patrickwehbe:fix/async-to-sync-update-wrapper
Open

Wrap async_to_sync with functools.update_wrapper#565
patrickwehbe wants to merge 1 commit into
django:mainfrom
patrickwehbe:fix/async-to-sync-update-wrapper

Conversation

@patrickwehbe

Copy link
Copy Markdown

Fixes #500.

async_to_sync doesn't copy the wrapped function's metadata onto the callable it returns, so attributes like __name__ and __wrapped__ are missing. People work around it by wrapping the result in functools.wraps themselves (the issue shows this).

sync_to_async already calls functools.update_wrapper(self, func) in its __init__, and AsyncToSync.__get__ does the same when used as a method decorator. AsyncToSync.__init__ was the only one that didn't, so this was just an inconsistency.

The fix is one line in AsyncToSync.__init__. I also added a test next to the existing sync_to_async attribute test. Without the fix the new test fails with AttributeError: 'AsyncToSync' object has no attribute '__name__'; with it the name, docstring, __wrapped__ and custom attributes all carry over.

async_to_sync didn't copy the wrapped function's metadata onto the
returned callable, so things like __name__ and __wrapped__ were missing.
sync_to_async already does this in its __init__, and AsyncToSync.__get__
does it too, so the __init__ case was just inconsistent.

Add the update_wrapper call in AsyncToSync.__init__ and a test that
mirrors the existing sync_to_async one.

Fixes django#500
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

`async_to_sync' is not wrapped properly:

1 participant