~0x44/nova/extdoc

« back to all changes in this revision

Viewing changes to vendor/Twisted-10.0.0/twisted/python/monkey.py

  • Committer: Jesse Andrews
  • Date: 2010-05-28 06:05:26 UTC
  • Revision ID: git-v1:bf6e6e718cdc7488e2da87b21e258ccc065fe499
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- test-case-name: twisted.test.test_monkey -*-
 
2
 
 
3
# Copyright (c) 2007 Twisted Matrix Laboratories.
 
4
# See LICENSE for details.
 
5
 
 
6
 
 
7
class MonkeyPatcher(object):
 
8
    """
 
9
    Cover up attributes with new objects. Neat for monkey-patching things for
 
10
    unit-testing purposes.
 
11
    """
 
12
 
 
13
    def __init__(self, *patches):
 
14
        # List of patches to apply in (obj, name, value).
 
15
        self._patchesToApply = []
 
16
        # List of the original values for things that have been patched.
 
17
        # (obj, name, value) format.
 
18
        self._originals = []
 
19
        for patch in patches:
 
20
            self.addPatch(*patch)
 
21
 
 
22
 
 
23
    def addPatch(self, obj, name, value):
 
24
        """
 
25
        Add a patch so that the attribute C{name} on C{obj} will be assigned to
 
26
        C{value} when C{patch} is called or during C{runWithPatches}.
 
27
 
 
28
        You can restore the original values with a call to restore().
 
29
        """
 
30
        self._patchesToApply.append((obj, name, value))
 
31
 
 
32
 
 
33
    def _alreadyPatched(self, obj, name):
 
34
        """
 
35
        Has the C{name} attribute of C{obj} already been patched by this
 
36
        patcher?
 
37
        """
 
38
        for o, n, v in self._originals:
 
39
            if (o, n) == (obj, name):
 
40
                return True
 
41
        return False
 
42
 
 
43
 
 
44
    def patch(self):
 
45
        """
 
46
        Apply all of the patches that have been specified with L{addPatch}.
 
47
        Reverse this operation using L{restore}.
 
48
        """
 
49
        for obj, name, value in self._patchesToApply:
 
50
            if not self._alreadyPatched(obj, name):
 
51
                self._originals.append((obj, name, getattr(obj, name)))
 
52
            setattr(obj, name, value)
 
53
 
 
54
 
 
55
    def restore(self):
 
56
        """
 
57
        Restore all original values to any patched objects.
 
58
        """
 
59
        while self._originals:
 
60
            obj, name, value = self._originals.pop()
 
61
            setattr(obj, name, value)
 
62
 
 
63
 
 
64
    def runWithPatches(self, f, *args, **kw):
 
65
        """
 
66
        Apply each patch already specified. Then run the function f with the
 
67
        given args and kwargs. Restore everything when done.
 
68
        """
 
69
        self.patch()
 
70
        try:
 
71
            return f(*args, **kw)
 
72
        finally:
 
73
            self.restore()