Python mock: @wraps (f) problems

I want to check out a simple decorator that I wrote:

It looks like this:

#utilities.py import other_module def decor(f): @wraps(f) def wrapper(*args, **kwds): other_module.startdoingsomething() try: return f(*args, **kwds) finally: other_module.enddoingsomething() return wrapper 

Then I check this using python-mock:

 #test_utilities.py def test_decor(self): mock_func = Mock() decorated_func = self.utilities.decor(mock_func) decorated_func(1,2,3) self.assertTrue(self.other_module.startdoingsomething.called) self.assertTrue(self.other_module.enddoingsomething.called) mock_func.assert_called_with(1,2,3) 

But he answers:

 Traceback (most recent call last): File "test_utilities.py", line 25, in test_decor decorated_func = Mock(wraps=self.utilities.decor(mock_func)) File "utilities.py", line 35, in decor @wraps(f) File "/usr/lib/python2.7/functools.py", line 33, in update_wrapper setattr(wrapper, attr, getattr(wrapped, attr)) File "/usr/local/lib/python2.7/dist-packages/mock.py", line 660, in __getattr__ raise AttributeError(name) AttributeError: __name__ 

I know that functools.wraps() is just a helper shell. So if I take it, the test works.

Can I get Mock to play well with functools.wraps ()?

Python 2.7.3

+8
source share
1 answer

Just give your layout to this attribute:

 mock_func.__name__ = 'foo' 

What is that really.

Demo:

 >>> from functools import wraps >>> from mock import Mock >>> def decor(f): ... @wraps(f) ... def wrapper(*args, **kwds): ... return f(*args, **kwds) ... return wrapper ... >>> mock_func = Mock() >>> decor(mock_func) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 2, in decor File ".../opt/lib/python2.7/functools.py", line 33, in update_wrapper setattr(wrapper, attr, getattr(wrapped, attr)) File ".../lib/python2.7/site-packages/mock.py", line 660, in __getattr__ raise AttributeError(name) AttributeError: __name__ >>> mock_func.__name__ = 'foo' >>> decor(mock_func) <function foo at 0x10c4321b8> 

The __name__ setting is perfectly fine; the @wraps decorator simply copies the __name__ attribute to the shell, and in function objects this attribute is usually set to a string value. This is a record attribute for functions anyway, and as long as you use function.__name__ , you can set any value.

+11
source

All Articles