sorenisanerd / mock

Automatically exported from code.google.com/p/mock
BSD 2-Clause "Simplified" License
0 stars 0 forks source link

Mock doesn't work for objects that define getattr and setattr but not delattr #192

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Install tornado 2.4.1 and mock 1.0.1
2. Run this test program:
import mock
from tornado.options import define, options

define('foo', default=1)

with mock.patch.object(options, 'foo', 2):
  print options.foo

What is the expected output? What do you see instead?

Upon exiting the with block, mock throws an exception:
Traceback (most recent call last):
  File "test.py", line 7, in <module>
    print options.foo
  File "/private/tmp/mockbugreport/lib/python2.7/site-packages/mock.py", line 1381, in __exit__
    delattr(self.target, self.attribute)
AttributeError: foo

What version of the product are you using? On what operating system?
1.0.1 on mac with python 2.7

Please provide any additional information below.

Tornado's options object defines getattr and setattr, but not delattr.  The 
getattr hook means that the attribute is considered non-local, so mock tries to 
delete it before setting it back to its original value.  I'd suggest that mock 
only call delattr if A) self.create is true or B) self.temp_original is DEFAULT 
or C) the original value was non-local but it became local after we set it in 
__enter__.

Original issue reported on code.google.com by ben.darn...@gmail.com on 1 Dec 2012 at 6:05

GoogleCodeExporter commented 9 years ago
The trouble is that calling delattr is the correct thing to do if (for example) 
overriding an attribute inherited from a class. In this case "hasattr(obj, 
attr)" will return True, but the original value will be non-local and become 
local after setting. When patching is complete the correct way to restore the 
original value is to delete the value we set.

If you can propose a patch that passes all the existing tests (retains current 
behaviour), but fixes the issue, then I'll happily consider it.

Original comment by fuzzyman on 2 Dec 2012 at 7:58

GoogleCodeExporter commented 9 years ago
Here's a patch that passes the current tests and adds a new one:

https://code.google.com/r/bendarnell-mock/source/detail?r=32f174a14fac7af66d7301
8eda14e573c27b7df0

Original comment by ben.darn...@gmail.com on 3 Dec 2012 at 4:58

GoogleCodeExporter commented 9 years ago
Scratch that.  The unittest2 tests pass, but the doctests fail (when the target 
of the patch is itself a Mock)

Original comment by ben.darn...@gmail.com on 3 Dec 2012 at 5:05