From 32a07205a41020019add7a9e4e9bbf2def1d5aaf Mon Sep 17 00:00:00 2001 From: Graham Dumpleton Date: Thu, 12 Jan 2023 16:33:07 +1100 Subject: [PATCH] Fix issues when using keyword argument named self with weak function proxy. --- docs/changes.rst | 4 ++++ src/wrapt/wrappers.py | 7 ++++++- tests/test_weak_function_proxy.py | 10 ++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/docs/changes.rst b/docs/changes.rst index 7e0f5132..2e5c6c34 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -56,6 +56,10 @@ Version 1.15.0 Python version of wrapt and did not occur when using the C extension based implementation. +* When using ``WeakFunctionProxy`` as a wrapper for a function, when calling the + function via the proxy object, it was not possible to pass a keyword argument + named ``self``. + Version 1.14.1 -------------- diff --git a/src/wrapt/wrappers.py b/src/wrapt/wrappers.py index 062b0956..48f334ee 100644 --- a/src/wrapt/wrappers.py +++ b/src/wrapt/wrappers.py @@ -992,7 +992,12 @@ def __init__(self, wrapped, callback=None): super(WeakFunctionProxy, self).__init__( weakref.proxy(wrapped, _callback)) - def __call__(self, *args, **kwargs): + def __call__(*args, **kwargs): + def _unpack_self(self, *args): + return self, args + + self, args = _unpack_self(*args) + # We perform a boolean check here on the instance and wrapped # function as that will trigger the reference error prior to # calling if the reference had expired. diff --git a/tests/test_weak_function_proxy.py b/tests/test_weak_function_proxy.py index d34da0e1..fa4b516b 100644 --- a/tests/test_weak_function_proxy.py +++ b/tests/test_weak_function_proxy.py @@ -190,5 +190,15 @@ def squeal(self): self.assertEqual(method(), 'bark') +class TestArgumentUnpackingWeakFunctionProxy(unittest.TestCase): + + def test_self_keyword_argument(self): + def function(self, *args, **kwargs): + return self, args, kwargs + + proxy = wrapt.wrappers.WeakFunctionProxy(function) + + self.assertEqual(proxy(self='self', arg1='arg1'), ('self', (), dict(arg1='arg1'))) + if __name__ == '__main__': unittest.main()