23 class StubOutForTesting:
25 You want os.path.exists() to always return true during testing.
27 stubs = StubOutForTesting()
28 stubs.Set(os.path, 'exists', lambda x: 1)
32 The above changes os.path.exists into a lambda that returns 1. Once
33 the ... part of the code finishes, the UnsetAll() looks up the old value
34 of os.path.exists and restores it.
46 """Replace obj.attr_name with new_attr. This method is smart and works
47 at the module, class, and instance level while preserving proper
48 inheritance. It will not stub out C types however unless that has been
49 explicitly allowed by the type.
51 This method supports the case where attr_name is a staticmethod or a
55 - If obj is an instance, then it is its class that will actually be
56 stubbed. Note that the method Set() does not do that: if obj is
57 an instance, it (and not its class) will be stubbed.
58 - The stubbing is using the builtin getattr and setattr. So, the __get__
59 and __set__ will be called when stubbing (TODO: A better idea would
60 probably be to manipulate obj.__dict__ instead of getattr() and
63 Raises AttributeError if the attribute cannot be found.
65 if (inspect.ismodule(obj)
or
66 (
not inspect.isclass(obj)
and obj.__dict__.has_key(attr_name))):
68 orig_attr = getattr(obj, attr_name)
71 if not inspect.isclass(obj):
72 mro = list(inspect.getmro(obj.__class__))
74 mro = list(inspect.getmro(obj))
83 orig_attr = getattr(obj, attr_name)
84 except AttributeError:
88 raise AttributeError(
"Attribute not found.")
92 old_attribute = obj.__dict__.get(attr_name)
93 if old_attribute
is not None and isinstance(old_attribute, staticmethod):
94 orig_attr = staticmethod(orig_attr)
96 self.
stubs.append((orig_obj, attr_name, orig_attr))
97 setattr(orig_obj, attr_name, new_attr)
100 """Reverses all the SmartSet() calls, restoring things to their original
101 definition. Its okay to call SmartUnsetAll() repeatedly, as later calls
102 have no effect if no SmartSet() calls have been made.
107 for args
in self.
stubs:
112 def Set(self, parent, child_name, new_child):
113 """Replace child_name's old definition with new_child, in the context
114 of the given parent. The parent could be a module when the child is a
115 function at module scope. Or the parent could be a class when a class'
116 method is being replaced. The named child is set to new_child, while
117 the prior definition is saved away for later, when UnsetAll() is called.
119 This method supports the case where child_name is a staticmethod or a
120 classmethod of parent.
122 old_child = getattr(parent, child_name)
124 old_attribute = parent.__dict__.get(child_name)
125 if old_attribute
is not None and isinstance(old_attribute, staticmethod):
126 old_child = staticmethod(old_child)
128 self.
cache.append((parent, old_child, child_name))
129 setattr(parent, child_name, new_child)
132 """Reverses all the Set() calls, restoring things to their original
133 definition. Its okay to call UnsetAll() repeatedly, as later calls have
134 no effect if no Set() calls have been made.
141 for (parent, old_child, child_name)
in self.
cache:
142 setattr(parent, child_name, old_child)