| 23 | | __version__ = '0.4.0' |
| 24 | | |
| 25 | | DEFAULT = object() |
| | 26 | __version__ = '0.7.2' |
| | 27 | |
| | 28 | __unittest = True |
| | 29 | |
| | 30 | |
| | 31 | import sys |
| | 32 | import warnings |
| | 33 | |
| | 34 | try: |
| | 35 | import inspect |
| | 36 | except ImportError: |
| | 37 | # for alternative platforms that |
| | 38 | # may not have inspect |
| | 39 | inspect = None |
| | 40 | |
| | 41 | try: |
| | 42 | BaseException |
| | 43 | except NameError: |
| | 44 | # Python 2.4 compatibility |
| | 45 | BaseException = Exception |
| | 46 | |
| | 47 | try: |
| | 48 | from functools import wraps |
| | 49 | except ImportError: |
| | 50 | # Python 2.4 compatibility |
| | 51 | def wraps(original): |
| | 52 | def inner(f): |
| | 53 | f.__name__ = original.__name__ |
| | 54 | f.__doc__ = original.__doc__ |
| | 55 | f.__module__ = original.__module__ |
| | 56 | return f |
| | 57 | return inner |
| | 58 | |
| | 59 | try: |
| | 60 | unicode |
| | 61 | except NameError: |
| | 62 | # Python 3 |
| | 63 | basestring = unicode = str |
| | 64 | |
| | 65 | try: |
| | 66 | long |
| | 67 | except NameError: |
| | 68 | # Python 3 |
| | 69 | long = int |
| | 70 | |
| | 71 | inPy3k = sys.version_info[0] == 3 |
| | 72 | |
| | 73 | if inPy3k: |
| | 74 | self = '__self__' |
| | 75 | else: |
| | 76 | self = 'im_self' |
| | 77 | |
| | 78 | |
| | 79 | # getsignature and mocksignature heavily "inspired" by |
| | 80 | # the decorator module: http://pypi.python.org/pypi/decorator/ |
| | 81 | # by Michele Simionato |
| | 82 | |
| | 83 | def _getsignature(func, skipfirst): |
| | 84 | if inspect is None: |
| | 85 | raise ImportError('inspect module not available') |
| | 86 | |
| | 87 | if inspect.isclass(func): |
| | 88 | func = func.__init__ |
| | 89 | # will have a self arg |
| | 90 | skipfirst = True |
| | 91 | elif not (inspect.ismethod(func) or inspect.isfunction(func)): |
| | 92 | func = func.__call__ |
| | 93 | |
| | 94 | regargs, varargs, varkwargs, defaults = inspect.getargspec(func) |
| | 95 | |
| | 96 | # instance methods need to lose the self argument |
| | 97 | if getattr(func, self, None) is not None: |
| | 98 | regargs = regargs[1:] |
| | 99 | |
| | 100 | _msg = "_mock_ is a reserved argument name, can't mock signatures using _mock_" |
| | 101 | assert '_mock_' not in regargs, _msg |
| | 102 | if varargs is not None: |
| | 103 | assert '_mock_' not in varargs, _msg |
| | 104 | if varkwargs is not None: |
| | 105 | assert '_mock_' not in varkwargs, _msg |
| | 106 | if skipfirst: |
| | 107 | regargs = regargs[1:] |
| | 108 | signature = inspect.formatargspec(regargs, varargs, varkwargs, defaults, |
| | 109 | formatvalue=lambda value: "") |
| | 110 | return signature[1:-1], func |
| | 111 | |
| | 112 | |
| | 113 | def _copy_func_details(func, funcopy): |
| | 114 | funcopy.__name__ = func.__name__ |
| | 115 | funcopy.__doc__ = func.__doc__ |
| | 116 | funcopy.__dict__.update(func.__dict__) |
| | 117 | funcopy.__module__ = func.__module__ |
| | 118 | if not inPy3k: |
| | 119 | funcopy.func_defaults = func.func_defaults |
| | 120 | else: |
| | 121 | funcopy.__defaults__ = func.__defaults__ |
| | 122 | funcopy.__kwdefaults__ = func.__kwdefaults__ |
| | 123 | |
| | 124 | |
| | 125 | def mocksignature(func, mock=None, skipfirst=False): |
| | 126 | """ |
| | 127 | mocksignature(func, mock=None, skipfirst=False) |
| | 128 | |
| | 129 | Create a new function with the same signature as `func` that delegates |
| | 130 | to `mock`. If `skipfirst` is True the first argument is skipped, useful |
| | 131 | for methods where `self` needs to be omitted from the new function. |
| | 132 | |
| | 133 | If you don't pass in a `mock` then one will be created for you. |
| | 134 | |
| | 135 | The mock is set as the `mock` attribute of the returned function for easy |
| | 136 | access. |
| | 137 | |
| | 138 | `mocksignature` can also be used with classes. It copies the signature of |
| | 139 | the `__init__` method. |
| | 140 | |
| | 141 | When used with callable objects (instances) it copies the signature of the |
| | 142 | `__call__` method. |
| | 143 | """ |
| | 144 | if mock is None: |
| | 145 | mock = Mock() |
| | 146 | signature, func = _getsignature(func, skipfirst) |
| | 147 | src = "lambda %(signature)s: _mock_(%(signature)s)" % { |
| | 148 | 'signature': signature |
| | 149 | } |
| | 150 | |
| | 151 | funcopy = eval(src, dict(_mock_=mock)) |
| | 152 | _copy_func_details(func, funcopy) |
| | 153 | funcopy.mock = mock |
| | 154 | return funcopy |
| | 155 | |
| | 156 | |
| | 157 | def _is_magic(name): |
| | 158 | return '__%s__' % name[2:-2] == name |
| | 159 | |
| | 160 | |
| | 161 | class SentinelObject(object): |
| | 162 | "A unique, named, sentinel object." |
| | 163 | def __init__(self, name): |
| | 164 | self.name = name |
| | 165 | |
| | 166 | def __repr__(self): |
| | 167 | return '<SentinelObject "%s">' % self.name |
| | 168 | |
| | 169 | |
| | 170 | class Sentinel(object): |
| | 171 | """Access attributes to return a named object, usable as a sentinel.""" |
| | 172 | def __init__(self): |
| | 173 | self._sentinels = {} |
| | 174 | |
| | 175 | def __getattr__(self, name): |
| | 176 | if name == '__bases__': |
| | 177 | # Without this help(mock) raises an exception |
| | 178 | raise AttributeError |
| | 179 | return self._sentinels.setdefault(name, SentinelObject(name)) |
| | 180 | |
| | 181 | |
| | 182 | sentinel = Sentinel() |
| | 183 | |
| | 184 | DEFAULT = sentinel.DEFAULT |
| | 185 | |
| | 186 | |
| | 187 | class OldStyleClass: |
| | 188 | pass |
| | 189 | ClassType = type(OldStyleClass) |
| | 190 | |
| | 191 | |
| | 192 | def _copy(value): |
| | 193 | if type(value) in (dict, list, tuple, set): |
| | 194 | return type(value)(value) |
| | 195 | return value |
| | 196 | |
| | 197 | |
| | 198 | if inPy3k: |
| | 199 | class_types = type |
| | 200 | else: |
| | 201 | class_types = (type, ClassType) |
| 29 | | def __init__(self, methods=None, spec=None, side_effect=None, |
| 30 | | return_value=DEFAULT, name=None, parent=None): |
| | 205 | """ |
| | 206 | Create a new ``Mock`` object. ``Mock`` takes several optional arguments |
| | 207 | that specify the behaviour of the Mock object: |
| | 208 | |
| | 209 | * ``spec``: This can be either a list of strings or an existing object (a |
| | 210 | class or instance) that acts as the specification for the mock object. If |
| | 211 | you pass in an object then a list of strings is formed by calling dir on |
| | 212 | the object (excluding unsupported magic attributes and methods). Accessing |
| | 213 | any attribute not in this list will raise an ``AttributeError``. |
| | 214 | |
| | 215 | If ``spec`` is an object (rather than a list of strings) then |
| | 216 | `mock.__class__` returns the class of the spec object. This allows mocks |
| | 217 | to pass `isinstance` tests. |
| | 218 | |
| | 219 | * ``spec_set``: A stricter variant of ``spec``. If used, attempting to *set* |
| | 220 | or get an attribute on the mock that isn't on the object passed as |
| | 221 | ``spec_set`` will raise an ``AttributeError``. |
| | 222 | |
| | 223 | * ``side_effect``: A function to be called whenever the Mock is called. See |
| | 224 | the :attr:`Mock.side_effect` attribute. Useful for raising exceptions or |
| | 225 | dynamically changing return values. The function is called with the same |
| | 226 | arguments as the mock, and unless it returns :data:`DEFAULT`, the return |
| | 227 | value of this function is used as the return value. |
| | 228 | |
| | 229 | Alternatively ``side_effect`` can be an exception class or instance. In |
| | 230 | this case the exception will be raised when the mock is called. |
| | 231 | |
| | 232 | * ``return_value``: The value returned when the mock is called. By default |
| | 233 | this is a new Mock (created on first access). See the |
| | 234 | :attr:`Mock.return_value` attribute. |
| | 235 | |
| | 236 | * ``wraps``: Item for the mock object to wrap. If ``wraps`` is not None |
| | 237 | then calling the Mock will pass the call through to the wrapped object |
| | 238 | (returning the real result and ignoring ``return_value``). Attribute |
| | 239 | access on the mock will return a Mock object that wraps the corresponding |
| | 240 | attribute of the wrapped object (so attempting to access an attribute that |
| | 241 | doesn't exist will raise an ``AttributeError``). |
| | 242 | |
| | 243 | If the mock has an explicit ``return_value`` set then calls are not passed |
| | 244 | to the wrapped object and the ``return_value`` is returned instead. |
| | 245 | |
| | 246 | * ``name``: If the mock has a name then it will be used in the repr of the |
| | 247 | mock. This can be useful for debugging. The name is propagated to child |
| | 248 | mocks. |
| | 249 | """ |
| | 250 | def __new__(cls, *args, **kw): |
| | 251 | # every instance has its own class |
| | 252 | # so we can create magic methods on the |
| | 253 | # class without stomping on other mocks |
| | 254 | new = type(cls.__name__, (cls,), {'__doc__': cls.__doc__}) |
| | 255 | return object.__new__(new) |
| | 256 | |
| | 257 | |
| | 258 | def __init__(self, spec=None, side_effect=None, return_value=DEFAULT, |
| | 259 | wraps=None, name=None, spec_set=None, parent=None): |
| 96 | | |
| 97 | | |
| | 368 | |
| | 369 | |
| | 370 | def __repr__(self): |
| | 371 | if self._name is None and self._spec_class is None: |
| | 372 | return object.__repr__(self) |
| | 373 | |
| | 374 | name_string = '' |
| | 375 | spec_string = '' |
| | 376 | if self._name is not None: |
| | 377 | def get_name(name): |
| | 378 | if name is None: |
| | 379 | return 'mock' |
| | 380 | return name |
| | 381 | parent = self._parent |
| | 382 | name = self._name |
| | 383 | while parent is not None: |
| | 384 | name = get_name(parent._name) + '.' + name |
| | 385 | parent = parent._parent |
| | 386 | name_string = ' name=%r' % name |
| | 387 | if self._spec_class is not None: |
| | 388 | spec_string = ' spec=%r' |
| | 389 | if self._spec_set: |
| | 390 | spec_string = ' spec_set=%r' |
| | 391 | spec_string = spec_string % self._spec_class.__name__ |
| | 392 | return "<%s%s%s id='%s'>" % (type(self).__name__, |
| | 393 | name_string, |
| | 394 | spec_string, |
| | 395 | id(self)) |
| | 396 | |
| | 397 | |
| | 398 | def __setattr__(self, name, value): |
| | 399 | if not 'method_calls' in self.__dict__: |
| | 400 | # allow all attribute setting until initialisation is complete |
| | 401 | return object.__setattr__(self, name, value) |
| | 402 | if (self._spec_set and self._methods is not None and name not in |
| | 403 | self._methods and name not in self.__dict__ and |
| | 404 | name != 'return_value'): |
| | 405 | raise AttributeError("Mock object has no attribute '%s'" % name) |
| | 406 | if name in _unsupported_magics: |
| | 407 | msg = 'Attempting to set unsupported magic method %r.' % name |
| | 408 | raise AttributeError(msg) |
| | 409 | elif name in _all_magics: |
| | 410 | if self._methods is not None and name not in self._methods: |
| | 411 | raise AttributeError("Mock object has no attribute '%s'" % name) |
| | 412 | |
| | 413 | if not isinstance(value, Mock): |
| | 414 | setattr(type(self), name, _get_method(name, value)) |
| | 415 | original = value |
| | 416 | real = lambda *args, **kw: original(self, *args, **kw) |
| | 417 | value = mocksignature(value, real, skipfirst=True) |
| | 418 | else: |
| | 419 | setattr(type(self), name, value) |
| | 420 | return object.__setattr__(self, name, value) |
| | 421 | |
| | 422 | |
| | 423 | def __delattr__(self, name): |
| | 424 | if name in _all_magics and name in type(self).__dict__: |
| | 425 | delattr(type(self), name) |
| | 426 | return object.__delattr__(self, name) |
| | 427 | |
| | 428 | |
| 99 | | assert self.call_args == (args, kwargs), 'Expected: %s\nCalled with: %s' % ((args, kwargs), self.call_args) |
| 100 | | |
| 101 | | |
| 102 | | |
| | 430 | """ |
| | 431 | assert that the mock was called with the specified arguments. |
| | 432 | |
| | 433 | Raises an AssertionError if the args and keyword args passed in are |
| | 434 | different to the last call to the mock. |
| | 435 | """ |
| | 436 | if self.call_args is None: |
| | 437 | raise AssertionError('Expected: %s\nNot called' % ((args, kwargs),)) |
| | 438 | if not self.call_args == (args, kwargs): |
| | 439 | raise AssertionError( |
| | 440 | 'Expected: %s\nCalled with: %s' % ((args, kwargs), self.call_args) |
| | 441 | ) |
| | 442 | |
| | 443 | |
| | 444 | def assert_called_once_with(self, *args, **kwargs): |
| | 445 | """ |
| | 446 | assert that the mock was called exactly once and with the specified |
| | 447 | arguments. |
| | 448 | """ |
| | 449 | if not self.call_count == 1: |
| | 450 | msg = ("Expected to be called once. Called %s times." % |
| | 451 | self.call_count) |
| | 452 | raise AssertionError(msg) |
| | 453 | return self.assert_called_with(*args, **kwargs) |
| | 454 | |
| | 455 | |
| | 456 | def _get_child_mock(self, **kw): |
| | 457 | klass = type(self).__mro__[1] |
| | 458 | return klass(**kw) |
| | 459 | |
| | 460 | |
| | 461 | |
| | 462 | class callargs(tuple): |
| | 463 | """ |
| | 464 | A tuple for holding the results of a call to a mock, either in the form |
| | 465 | `(args, kwargs)` or `(name, args, kwargs)`. |
| | 466 | |
| | 467 | If args or kwargs are empty then a callargs tuple will compare equal to |
| | 468 | a tuple without those values. This makes comparisons less verbose:: |
| | 469 | |
| | 470 | callargs('name', (), {}) == ('name',) |
| | 471 | callargs('name', (1,), {}) == ('name', (1,)) |
| | 472 | callargs((), {'a': 'b'}) == ({'a': 'b'},) |
| | 473 | """ |
| | 474 | def __eq__(self, other): |
| | 475 | if len(self) == 3: |
| | 476 | if other[0] != self[0]: |
| | 477 | return False |
| | 478 | args_kwargs = self[1:] |
| | 479 | other_args_kwargs = other[1:] |
| | 480 | else: |
| | 481 | args_kwargs = tuple(self) |
| | 482 | other_args_kwargs = other |
| | 483 | |
| | 484 | if len(other_args_kwargs) == 0: |
| | 485 | other_args, other_kwargs = (), {} |
| | 486 | elif len(other_args_kwargs) == 1: |
| | 487 | if isinstance(other_args_kwargs[0], tuple): |
| | 488 | other_args = other_args_kwargs[0] |
| | 489 | other_kwargs = {} |
| | 490 | else: |
| | 491 | other_args = () |
| | 492 | other_kwargs = other_args_kwargs[0] |
| | 493 | else: |
| | 494 | other_args, other_kwargs = other_args_kwargs |
| | 495 | |
| | 496 | return tuple(args_kwargs) == (other_args, other_kwargs) |
| | 497 | |
| | 498 | |
| 122 | | def _patch(target, attribute, new): |
| 123 | | |
| 124 | | def patcher(func): |
| 125 | | original = getattr(target, attribute) |
| 126 | | if hasattr(func, 'restore_list'): |
| 127 | | func.restore_list.append((target, attribute, original)) |
| 128 | | func.patch_list.append((target, attribute, new)) |
| | 518 | class _patch(object): |
| | 519 | def __init__(self, target, attribute, new, spec, create, |
| | 520 | mocksignature, spec_set): |
| | 521 | self.target = target |
| | 522 | self.attribute = attribute |
| | 523 | self.new = new |
| | 524 | self.spec = spec |
| | 525 | self.create = create |
| | 526 | self.has_local = False |
| | 527 | self.mocksignature = mocksignature |
| | 528 | self.spec_set = spec_set |
| | 529 | |
| | 530 | |
| | 531 | def copy(self): |
| | 532 | return _patch(self.target, self.attribute, self.new, self.spec, |
| | 533 | self.create, self.mocksignature, self.spec_set) |
| | 534 | |
| | 535 | |
| | 536 | def __call__(self, func): |
| | 537 | if isinstance(func, class_types): |
| | 538 | return self.decorate_class(func) |
| | 539 | else: |
| | 540 | return self.decorate_callable(func) |
| | 541 | |
| | 542 | |
| | 543 | def decorate_class(self, klass): |
| | 544 | for attr in dir(klass): |
| | 545 | attr_value = getattr(klass, attr) |
| | 546 | if attr.startswith("test") and hasattr(attr_value, "__call__"): |
| | 547 | setattr(klass, attr, self.copy()(attr_value)) |
| | 548 | return klass |
| | 549 | |
| | 550 | |
| | 551 | def decorate_callable(self, func): |
| | 552 | if hasattr(func, 'patchings'): |
| | 553 | func.patchings.append(self) |
| 150 | | |
| 151 | | return patcher |
| 152 | | |
| 153 | | |
| 154 | | def patch_object(target, attribute, new=DEFAULT): |
| 155 | | return _patch(target, attribute, new) |
| 156 | | |
| 157 | | |
| 158 | | def patch(target, new=DEFAULT): |
| | 577 | |
| | 578 | |
| | 579 | def get_original(self): |
| | 580 | target = self.target |
| | 581 | name = self.attribute |
| | 582 | |
| | 583 | original = DEFAULT |
| | 584 | local = False |
| | 585 | |
| | 586 | try: |
| | 587 | original = target.__dict__[name] |
| | 588 | except (AttributeError, KeyError): |
| | 589 | original = getattr(target, name, DEFAULT) |
| | 590 | else: |
| | 591 | local = True |
| | 592 | |
| | 593 | if not self.create and original is DEFAULT: |
| | 594 | raise AttributeError("%s does not have the attribute %r" % (target, name)) |
| | 595 | return original, local |
| | 596 | |
| | 597 | |
| | 598 | def __enter__(self): |
| | 599 | """Perform the patch.""" |
| | 600 | new, spec, spec_set = self.new, self.spec, self.spec_set |
| | 601 | original, local = self.get_original() |
| | 602 | if new is DEFAULT: |
| | 603 | # XXXX what if original is DEFAULT - shouldn't use it as a spec |
| | 604 | inherit = False |
| | 605 | if spec_set == True: |
| | 606 | spec_set = original |
| | 607 | if isinstance(spec_set, class_types): |
| | 608 | inherit = True |
| | 609 | elif spec == True: |
| | 610 | # set spec to the object we are replacing |
| | 611 | spec = original |
| | 612 | if isinstance(spec, class_types): |
| | 613 | inherit = True |
| | 614 | new = Mock(spec=spec, spec_set=spec_set) |
| | 615 | if inherit: |
| | 616 | new.return_value = Mock(spec=spec, spec_set=spec_set) |
| | 617 | new_attr = new |
| | 618 | if self.mocksignature: |
| | 619 | new_attr = mocksignature(original, new) |
| | 620 | |
| | 621 | self.temp_original = original |
| | 622 | self.is_local = local |
| | 623 | setattr(self.target, self.attribute, new_attr) |
| | 624 | return new |
| | 625 | |
| | 626 | |
| | 627 | def __exit__(self, *_): |
| | 628 | """Undo the patch.""" |
| | 629 | if self.is_local and self.temp_original is not DEFAULT: |
| | 630 | setattr(self.target, self.attribute, self.temp_original) |
| | 631 | else: |
| | 632 | delattr(self.target, self.attribute) |
| | 633 | if not self.create and not hasattr(self.target, self.attribute): |
| | 634 | # needed for proxy objects like django settings |
| | 635 | setattr(self.target, self.attribute, self.temp_original) |
| | 636 | |
| | 637 | del self.temp_original |
| | 638 | del self.is_local |
| | 639 | |
| | 640 | start = __enter__ |
| | 641 | stop = __exit__ |
| | 642 | |
| | 643 | |
| | 644 | def _patch_object(target, attribute, new=DEFAULT, spec=None, create=False, |
| | 645 | mocksignature=False, spec_set=None): |
| | 646 | """ |
| | 647 | patch.object(target, attribute, new=DEFAULT, spec=None, create=False, |
| | 648 | mocksignature=False, spec_set=None) |
| | 649 | |
| | 650 | patch the named member (`attribute`) on an object (`target`) with a mock |
| | 651 | object. |
| | 652 | |
| | 653 | Arguments new, spec, create, mocksignature and spec_set have the same |
| | 654 | meaning as for patch. |
| | 655 | """ |
| | 656 | return _patch(target, attribute, new, spec, create, mocksignature, |
| | 657 | spec_set) |
| | 658 | |
| | 659 | |
| | 660 | def patch_object(*args, **kwargs): |
| | 661 | "A deprecated form of patch.object(...)" |
| | 662 | warnings.warn(('Please use patch.object instead.'), DeprecationWarning, 2) |
| | 663 | return _patch_object(*args, **kwargs) |
| | 664 | |
| | 665 | |
| | 666 | def patch(target, new=DEFAULT, spec=None, create=False, |
| | 667 | mocksignature=False, spec_set=None): |
| | 668 | """ |
| | 669 | ``patch`` acts as a function decorator, class decorator or a context |
| | 670 | manager. Inside the body of the function or with statement, the ``target`` |
| | 671 | (specified in the form `'PackageName.ModuleName.ClassName'`) is patched |
| | 672 | with a ``new`` object. When the function/with statement exits the patch is |
| | 673 | undone. |
| | 674 | |
| | 675 | The ``target`` is imported and the specified attribute patched with the new |
| | 676 | object, so it must be importable from the environment you are calling the |
| | 677 | decorator from. |
| | 678 | |
| | 679 | If ``new`` is omitted, then a new ``Mock`` is created and passed in as an |
| | 680 | extra argument to the decorated function. |
| | 681 | |
| | 682 | The ``spec`` and ``spec_set`` keyword arguments are passed to the ``Mock`` |
| | 683 | if patch is creating one for you. |
| | 684 | |
| | 685 | In addition you can pass ``spec=True`` or ``spec_set=True``, which causes |
| | 686 | patch to pass in the object being mocked as the spec/spec_set object. |
| | 687 | |
| | 688 | If ``mocksignature`` is True then the patch will be done with a function |
| | 689 | created by mocking the one being replaced. If the object being replaced is |
| | 690 | a class then the signature of `__init__` will be copied. If the object |
| | 691 | being replaced is a callable object then the signature of `__call__` will |
| | 692 | be copied. |
| | 693 | |
| | 694 | By default ``patch`` will fail to replace attributes that don't exist. If |
| | 695 | you pass in 'create=True' and the attribute doesn't exist, patch will |
| | 696 | create the attribute for you when the patched function is called, and |
| | 697 | delete it again afterwards. This is useful for writing tests against |
| | 698 | attributes that your production code creates at runtime. It is off by by |
| | 699 | default because it can be dangerous. With it switched on you can write |
| | 700 | passing tests against APIs that don't actually exist! |
| | 701 | |
| | 702 | Patch can be used as a TestCase class decorator. It works by |
| | 703 | decorating each test method in the class. This reduces the boilerplate |
| | 704 | code when your test methods share a common patchings set. |
| | 705 | |
| | 706 | Patch can be used with the with statement, if this is available in your |
| | 707 | version of Python. Here the patching applies to the indented block after |
| | 708 | the with statement. If you use "as" then the patched object will be bound |
| | 709 | to the name after the "as"; very useful if `patch` is creating a mock |
| | 710 | object for you. |
| | 711 | |
| | 712 | `patch.dict(...)` and `patch.object(...)` are available for alternate |
| | 713 | use-cases. |
| | 714 | """ |
| 164 | | return _patch(target, attribute, new) |
| 165 | | |
| 166 | | |
| 167 | | class SentinelObject(object): |
| 168 | | def __init__(self, name): |
| 169 | | self.name = name |
| 170 | | |
| 171 | | def __repr__(self): |
| 172 | | return '<SentinelObject "%s">' % self.name |
| 173 | | |
| 174 | | |
| 175 | | class Sentinel(object): |
| 176 | | def __init__(self): |
| 177 | | self._sentinels = {} |
| 178 | | |
| 179 | | def __getattr__(self, name): |
| 180 | | return self._sentinels.setdefault(name, SentinelObject(name)) |
| 181 | | |
| 182 | | |
| 183 | | sentinel = Sentinel() |
| | 721 | return _patch(target, attribute, new, spec, create, mocksignature, spec_set) |
| | 722 | |
| | 723 | |
| | 724 | class _patch_dict(object): |
| | 725 | """ |
| | 726 | Patch a dictionary and restore the dictionary to its original state after |
| | 727 | the test. |
| | 728 | |
| | 729 | `in_dict` can be a dictionary or a mapping like container. If it is a |
| | 730 | mapping then it must at least support getting, setting and deleting items |
| | 731 | plus iterating over keys. |
| | 732 | |
| | 733 | `in_dict` can also be a string specifying the name of the dictionary, which |
| | 734 | will then be fetched by importing it. |
| | 735 | |
| | 736 | `values` can be a dictionary of values to set in the dictionary. `values` |
| | 737 | can also be an iterable of ``(key, value)`` pairs. |
| | 738 | |
| | 739 | If `clear` is True then the dictionary will be cleared before the new |
| | 740 | values are set. |
| | 741 | """ |
| | 742 | |
| | 743 | def __init__(self, in_dict, values=(), clear=False): |
| | 744 | if isinstance(in_dict, basestring): |
| | 745 | in_dict = _importer(in_dict) |
| | 746 | self.in_dict = in_dict |
| | 747 | # support any argument supported by dict(...) constructor |
| | 748 | self.values = dict(values) |
| | 749 | self.clear = clear |
| | 750 | self._original = None |
| | 751 | |
| | 752 | |
| | 753 | def __call__(self, f): |
| | 754 | if isinstance(f, class_types): |
| | 755 | return self.decorate_class(f) |
| | 756 | @wraps(f) |
| | 757 | def _inner(*args, **kw): |
| | 758 | self._patch_dict() |
| | 759 | try: |
| | 760 | return f(*args, **kw) |
| | 761 | finally: |
| | 762 | self._unpatch_dict() |
| | 763 | |
| | 764 | return _inner |
| | 765 | |
| | 766 | |
| | 767 | def decorate_class(self, klass): |
| | 768 | for attr in dir(klass): |
| | 769 | attr_value = getattr(klass, attr) |
| | 770 | if attr.startswith("test") and hasattr(attr_value, "__call__"): |
| | 771 | decorator = _patch_dict(self.in_dict, self.values, self.clear) |
| | 772 | decorated = decorator(attr_value) |
| | 773 | setattr(klass, attr, decorated) |
| | 774 | return klass |
| | 775 | |
| | 776 | |
| | 777 | def __enter__(self): |
| | 778 | """Patch the dict.""" |
| | 779 | self._patch_dict() |
| | 780 | |
| | 781 | |
| | 782 | def _patch_dict(self): |
| | 783 | """Unpatch the dict.""" |
| | 784 | values = self.values |
| | 785 | in_dict = self.in_dict |
| | 786 | clear = self.clear |
| | 787 | |
| | 788 | try: |
| | 789 | original = in_dict.copy() |
| | 790 | except AttributeError: |
| | 791 | # dict like object with no copy method |
| | 792 | # must support iteration over keys |
| | 793 | original = {} |
| | 794 | for key in in_dict: |
| | 795 | original[key] = in_dict[key] |
| | 796 | self._original = original |
| | 797 | |
| | 798 | if clear: |
| | 799 | _clear_dict(in_dict) |
| | 800 | |
| | 801 | try: |
| | 802 | in_dict.update(values) |
| | 803 | except AttributeError: |
| | 804 | # dict like object with no update method |
| | 805 | for key in values: |
| | 806 | in_dict[key] = values[key] |
| | 807 | |
| | 808 | |
| | 809 | def _unpatch_dict(self): |
| | 810 | in_dict = self.in_dict |
| | 811 | original = self._original |
| | 812 | |
| | 813 | _clear_dict(in_dict) |
| | 814 | |
| | 815 | try: |
| | 816 | in_dict.update(original) |
| | 817 | except AttributeError: |
| | 818 | for key in original: |
| | 819 | in_dict[key] = original[key] |
| | 820 | |
| | 821 | |
| | 822 | def __exit__(self, *args): |
| | 823 | self._unpatch_dict() |
| | 824 | return False |
| | 825 | |
| | 826 | start = __enter__ |
| | 827 | stop = __exit__ |
| | 828 | |
| | 829 | |
| | 830 | def _clear_dict(in_dict): |
| | 831 | try: |
| | 832 | in_dict.clear() |
| | 833 | except AttributeError: |
| | 834 | keys = list(in_dict) |
| | 835 | for key in keys: |
| | 836 | del in_dict[key] |
| | 837 | |
| | 838 | |
| | 839 | patch.object = _patch_object |
| | 840 | patch.dict = _patch_dict |
| | 841 | |
| | 842 | |
| | 843 | magic_methods = ( |
| | 844 | "lt le gt ge eq ne " |
| | 845 | "getitem setitem delitem " |
| | 846 | "len contains iter " |
| | 847 | "hash str sizeof " |
| | 848 | "enter exit " |
| | 849 | "divmod neg pos abs invert " |
| | 850 | "complex int float index " |
| | 851 | "trunc floor ceil " |
| | 852 | ) |
| | 853 | |
| | 854 | numerics = "add sub mul div truediv floordiv mod lshift rshift and xor or pow " |
| | 855 | inplace = ' '.join('i%s' % n for n in numerics.split()) |
| | 856 | right = ' '.join('r%s' % n for n in numerics.split()) |
| | 857 | extra = '' |
| | 858 | if inPy3k: |
| | 859 | extra = 'bool next ' |
| | 860 | else: |
| | 861 | extra = 'unicode long nonzero oct hex ' |
| | 862 | # __truediv__ and __rtruediv__ not available in Python 3 either |
| | 863 | |
| | 864 | # not including __prepare__, __instancecheck__, __subclasscheck__ |
| | 865 | # (as they are metaclass methods) |
| | 866 | # __del__ is not supported at all as it causes problems if it exists |
| | 867 | |
| | 868 | _non_defaults = set('__%s__' % method for method in [ |
| | 869 | 'cmp', 'getslice', 'setslice', 'coerce', 'subclasses', |
| | 870 | 'dir', 'format', 'get', 'set', 'delete', 'reversed', |
| | 871 | 'missing', 'reduce', 'reduce_ex', 'getinitargs', |
| | 872 | 'getnewargs', 'getstate', 'setstate', 'getformat', |
| | 873 | 'setformat', 'repr' |
| | 874 | ]) |
| | 875 | |
| | 876 | |
| | 877 | def _get_method(name, func): |
| | 878 | "Turns a callable object (like a mock) into a real function" |
| | 879 | def method(self, *args, **kw): |
| | 880 | return func(self, *args, **kw) |
| | 881 | method.__name__ = name |
| | 882 | return method |
| | 883 | |
| | 884 | |
| | 885 | _magics = set( |
| | 886 | '__%s__' % method for method in |
| | 887 | ' '.join([magic_methods, numerics, inplace, right, extra]).split() |
| | 888 | ) |
| | 889 | |
| | 890 | _all_magics = _magics | _non_defaults |
| | 891 | |
| | 892 | _unsupported_magics = set([ |
| | 893 | '__getattr__', '__setattr__', |
| | 894 | '__init__', '__new__', '__prepare__' |
| | 895 | '__instancecheck__', '__subclasscheck__', |
| | 896 | '__del__' |
| | 897 | ]) |
| | 898 | |
| | 899 | _calculate_return_value = { |
| | 900 | '__hash__': lambda self: object.__hash__(self), |
| | 901 | '__str__': lambda self: object.__str__(self), |
| | 902 | '__sizeof__': lambda self: object.__sizeof__(self), |
| | 903 | '__unicode__': lambda self: unicode(object.__str__(self)), |
| | 904 | } |
| | 905 | |
| | 906 | _return_values = { |
| | 907 | '__int__': 1, |
| | 908 | '__contains__': False, |
| | 909 | '__len__': 0, |
| | 910 | '__iter__': iter([]), |
| | 911 | '__exit__': False, |
| | 912 | '__complex__': 1j, |
| | 913 | '__float__': 1.0, |
| | 914 | '__bool__': True, |
| | 915 | '__nonzero__': True, |
| | 916 | '__oct__': '1', |
| | 917 | '__hex__': '0x1', |
| | 918 | '__long__': long(1), |
| | 919 | '__index__': 1, |
| | 920 | } |
| | 921 | |
| | 922 | |
| | 923 | def _get_eq(self): |
| | 924 | def __eq__(other): |
| | 925 | ret_val = self.__eq__._return_value |
| | 926 | if ret_val is not DEFAULT: |
| | 927 | return ret_val |
| | 928 | return self is other |
| | 929 | return __eq__ |
| | 930 | |
| | 931 | def _get_ne(self): |
| | 932 | def __ne__(other): |
| | 933 | if self.__ne__._return_value is not DEFAULT: |
| | 934 | return DEFAULT |
| | 935 | return self is not other |
| | 936 | return __ne__ |
| | 937 | |
| | 938 | _side_effect_methods = { |
| | 939 | '__eq__': _get_eq, |
| | 940 | '__ne__': _get_ne, |
| | 941 | } |
| | 942 | |
| | 943 | |
| | 944 | |
| | 945 | def _set_return_value(mock, method, name): |
| | 946 | return_value = DEFAULT |
| | 947 | if name in _return_values: |
| | 948 | return_value = _return_values[name] |
| | 949 | elif name in _calculate_return_value: |
| | 950 | try: |
| | 951 | return_value = _calculate_return_value[name](mock) |
| | 952 | except AttributeError: |
| | 953 | return_value = AttributeError(name) |
| | 954 | elif name in _side_effect_methods: |
| | 955 | side_effect = _side_effect_methods[name](mock) |
| | 956 | method.side_effect = side_effect |
| | 957 | if return_value is not DEFAULT: |
| | 958 | method.return_value = return_value |
| | 959 | |
| | 960 | |
| | 961 | class MagicMock(Mock): |
| | 962 | """ |
| | 963 | MagicMock is a subclass of :Mock with default implementations |
| | 964 | of most of the magic methods. You can use MagicMock without having to |
| | 965 | configure the magic methods yourself. |
| | 966 | |
| | 967 | If you use the ``spec`` or ``spec_set`` arguments then *only* magic |
| | 968 | methods that exist in the spec will be created. |
| | 969 | |
| | 970 | Attributes and the return value of a `MagicMock` will also be `MagicMocks`. |
| | 971 | """ |
| | 972 | def __init__(self, *args, **kw): |
| | 973 | Mock.__init__(self, *args, **kw) |
| | 974 | |
| | 975 | these_magics = _magics |
| | 976 | if self._methods is not None: |
| | 977 | these_magics = _magics.intersection(self._methods) |
| | 978 | |
| | 979 | for entry in these_magics: |
| | 980 | # could specify parent? |
| | 981 | m = Mock() |
| | 982 | setattr(self, entry, m) |
| | 983 | _set_return_value(self, m, entry) |