-
Notifications
You must be signed in to change notification settings - Fork 22
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
How to write a wrapper around these functions? #111
Comments
Consider how def jsobj(*args: Any, vars_only: bool = True, **kwargs: Any) -> Dict[str, Any]:
argnames: Tuple[str, ...] = argname("args", vars_only=vars_only)
out = dict(zip(argnames, args))
out.update(kwargs)
return out When you wrap from varname import argname
from varname.helpers import jsobj
from functools import wraps
import unittest
def jsobj_to_be_wrapped(*args, vars_only=True, **kwargs):
argnames = argname("args", vars_only=vars_only, frame=2)
out = dict(zip(argnames, args))
out.update(kwargs)
return out
def return_dict_items(func):
@wraps(func)
def wrapper(*args, **kwargs):
return func(*args, **kwargs).items()
return wrapper
class TestWrapper(unittest.TestCase):
def test_wrapper(self):
foo = return_dict_items(jsobj_to_be_wrapped)
a = 1
self.assertEqual([("a", 1)], list(foo(a)))
if __name__ == '__main__':
unittest.main() |
Seems a little "off" to have two versions of a function, one that can be wrapped and another which can't, but considering playing about with frames and stacks and the like is always a bit "hacky" it's not the end of the world. |
Also, this has the drawback that this needs to know how many times it will be decorated, and I can't decorate it indefinitely (or not at all). |
The def myjsobj(*args, **kwargs):
return jsobj(*args, vars_only=False, frame=2, **kwargs)
x = lambda: None
x.b = 2
obj = myjsobj(x.b)
assert obj == {"x.b": 2} |
Here is now it works in your case: from varname.helpers import jsobj
from functools import wraps
import unittest
def return_dict_items(func):
@wraps(func)
def wrapper(*args, **kwargs):
return func(*args, **kwargs, vars_only=False, frame=2).items()
return wrapper
class TestWrapper(unittest.TestCase):
def test_wrapper(self):
foo = return_dict_items(jsobj)
a = 1
self.assertEqual([("a", 1)], list(foo(a)))
if __name__ == '__main__':
unittest.main() |
Perfect. |
jsobj
returns a dictionary. If I wanted to write a decorator which returns the.items()
of whatever it is decorating (presumably a function which returns dictionaries), how would I do this, as my naive implementation didn't work. Can the functions in this module even be decorated in "the usual" manner?My attempt:
However:
The text was updated successfully, but these errors were encountered: