summaryrefslogtreecommitdiff
path: root/mox3/stubout.py
diff options
context:
space:
mode:
Diffstat (limited to 'mox3/stubout.py')
-rw-r--r--mox3/stubout.py91
1 files changed, 49 insertions, 42 deletions
diff --git a/mox3/stubout.py b/mox3/stubout.py
index 2681e5d..a02ed40 100644
--- a/mox3/stubout.py
+++ b/mox3/stubout.py
@@ -12,7 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
-#
# This is a fork of the pymox library intended to work with Python 3.
# The file was modified by quermit@gmail.com and dawid.fatyga@gmail.com
@@ -21,16 +20,17 @@ import inspect
class StubOutForTesting(object):
"""Sample Usage:
- You want os.path.exists() to always return true during testing.
- stubs = StubOutForTesting()
- stubs.Set(os.path, 'exists', lambda x: 1)
- ...
- stubs.UnsetAll()
+ You want os.path.exists() to always return true during testing.
- The above changes os.path.exists into a lambda that returns 1. Once
- the ... part of the code finishes, the UnsetAll() looks up the old value
- of os.path.exists and restores it.
+ stubs = StubOutForTesting()
+ stubs.Set(os.path, 'exists', lambda x: 1)
+ ...
+ stubs.UnsetAll()
+
+ The above changes os.path.exists into a lambda that returns 1. Once
+ the ... part of the code finishes, the UnsetAll() looks up the old value
+ of os.path.exists and restores it.
"""
def __init__(self):
@@ -42,24 +42,25 @@ class StubOutForTesting(object):
self.UnsetAll()
def SmartSet(self, obj, attr_name, new_attr):
- """Replace obj.attr_name with new_attr. This method is smart and works
- at the module, class, and instance level while preserving proper
- inheritance. It will not stub out C types however unless that has been
- explicitly allowed by the type.
-
- This method supports the case where attr_name is a staticmethod or a
- classmethod of obj.
-
- Notes:
- - If obj is an instance, then it is its class that will actually be
- stubbed. Note that the method Set() does not do that: if obj is
- an instance, it (and not its class) will be stubbed.
- - The stubbing is using the builtin getattr and setattr. So, the __get__
- and __set__ will be called when stubbing (TODO: A better idea would
- probably be to manipulate obj.__dict__ instead of getattr() and
- setattr()).
-
- Raises AttributeError if the attribute cannot be found.
+ """Replace obj.attr_name with new_attr.
+
+ This method is smart and works at the module, class, and instance level
+ while preserving proper inheritance. It will not stub out C types
+ however unless that has been explicitly allowed by the type.
+
+ This method supports the case where attr_name is a staticmethod or a
+ classmethod of obj.
+
+ Notes:
+ - If obj is an instance, then it is its class that will actually be
+ stubbed. Note that the method Set() does not do that: if obj is
+ an instance, it (and not its class) will be stubbed.
+ - The stubbing is using the builtin getattr and setattr. So, the
+ __get__ and __set__ will be called when stubbing (TODO: A better
+ idea would probably be to manipulate obj.__dict__ instead of
+ getattr() and setattr()).
+
+ Raises AttributeError if the attribute cannot be found.
"""
if (inspect.ismodule(obj) or
(not inspect.isclass(obj) and attr_name in obj.__dict__)):
@@ -86,20 +87,22 @@ class StubOutForTesting(object):
if orig_attr is None:
raise AttributeError("Attribute not found.")
- # Calling getattr() on a staticmethod transforms it to a 'normal' function.
- # We need to ensure that we put it back as a staticmethod.
+ # Calling getattr() on a staticmethod transforms it to a 'normal'
+ # function. We need to ensure that we put it back as a staticmethod.
old_attribute = obj.__dict__.get(attr_name)
- if old_attribute is not None and isinstance(old_attribute, staticmethod):
+ if (old_attribute is not None
+ and isinstance(old_attribute, staticmethod)):
orig_attr = staticmethod(orig_attr)
self.stubs.append((orig_obj, attr_name, orig_attr))
setattr(orig_obj, attr_name, new_attr)
def SmartUnsetAll(self):
- """Reverses all the SmartSet() calls, restoring things to their original
- definition. Its okay to call SmartUnsetAll() repeatedly, as later calls
- have no effect if no SmartSet() calls have been made.
+ """Reverses all the SmartSet() calls.
+ Restores things to their original definition. Its okay to call
+ SmartUnsetAll() repeatedly, as later calls have no effect if no
+ SmartSet() calls have been made.
"""
self.stubs.reverse()
@@ -109,11 +112,13 @@ class StubOutForTesting(object):
self.stubs = []
def Set(self, parent, child_name, new_child):
- """Replace child_name's old definition with new_child, in the context
- of the given parent. The parent could be a module when the child is a
- function at module scope. Or the parent could be a class when a class'
- method is being replaced. The named child is set to new_child, while
- the prior definition is saved away for later, when UnsetAll() is called.
+ """Replace child_name's old definition with new_child.
+
+ Replace definiion in the context of the given parent. The parent could
+ be a module when the child is a function at module scope. Or the parent
+ could be a class when a class' method is being replaced. The named
+ child is set to new_child, while the prior definition is saved away
+ for later, when UnsetAll() is called.
This method supports the case where child_name is a staticmethod or a
classmethod of parent.
@@ -131,13 +136,15 @@ class StubOutForTesting(object):
setattr(parent, child_name, new_child)
def UnsetAll(self):
- """Reverses all the Set() calls, restoring things to their original
- definition. Its okay to call UnsetAll() repeatedly, as later calls have
- no effect if no Set() calls have been made.
+ """Reverses all the Set() calls.
+ Restores things to their original definition. Its okay to call
+ UnsetAll() repeatedly, as later calls have no effect if no Set()
+ calls have been made.
"""
# Undo calls to Set() in reverse order, in case Set() was called on the
- # same arguments repeatedly (want the original call to be last one undone)
+ # same arguments repeatedly (want the original call to be last one
+ # undone)
self.cache.reverse()
for (parent, old_child, child_name) in self.cache: