Whole file

testing-cabal/mock

The author described this change as Fix callargs call comparisons. It counts as a record because the check below fails on the code as it stood at d5590a43c and passes on 2265b42d5, with nothing else changed between the two runs.

Fix saved2011-07-19
Sharing licenceBSD-2-Clause · LICENSE.txt
Change size+1226 1218

What the code was meant to do, written into the code itself as a save note

Fix callargs call comparisons

The change

428428 """
429429 def __eq__(self, other):
430430 if len(self) == 3:
431- if other[0] != self[0]:
432- return False
433- args_kwargs = self[1:]
434- other_args_kwargs = other[1:]
435- else:
436- args_kwargs = tuple(self)
437- other_args_kwargs = other
438-
439- if len(other_args_kwargs) == 0:
440- other_args, other_kwargs = (), {}
441- elif len(other_args_kwargs) == 3:
442- # the first unused argument is the name
443- _, other_args, other_kwargs = other_args_kwargs
444- elif len(other_args_kwargs) == 1:
445- if isinstance(other_args_kwargs[0], tuple):
446- other_args = other_args_kwargs[0]
447- other_kwargs = {}
448- elif isinstance(other_args_kwargs[0], basestring):
449- other_args, other_kwargs = (), {}
450- else:
451- other_args = ()
452- other_kwargs = other_args_kwargs[0]
453- else:
454- # len 2
455- # could be (name, args) or (name, kwargs) or (args, kwargs)
456- first, second = other_args_kwargs
457- if isinstance(first, basestring):
458- if isinstance(second, tuple):
459- other_args, other_kwargs = second, {}
460- else:
461- other_args, other_kwargs = (), second
462- else:
463- other_args, other_kwargs = first, second
464-
465- return tuple(args_kwargs) == (other_args, other_kwargs)
466-
467-
468-
469-class Base(object):
470- _mock_return_value = DEFAULT
471- _mock_side_effect = None
472- def __init__(self, *args, **kwargs):
473- pass
474-
475-
476-
477-class NonCallableMock(Base):
478- """
479- Create a new ``Mock`` object. ``Mock`` takes several optional arguments
480- that specify the behaviour of the Mock object:
481-
482- * ``spec``: This can be either a list of strings or an existing object (a
483- class or instance) that acts as the specification for the mock object. If
484- you pass in an object then a list of strings is formed by calling dir on
485- the object (excluding unsupported magic attributes and methods). Accessing
486- any attribute not in this list will raise an ``AttributeError``.
487-
488- If ``spec`` is an object (rather than a list of strings) then
489- `mock.__class__` returns the class of the spec object. This allows mocks
490- to pass `isinstance` tests.
491-
492- * ``spec_set``: A stricter variant of ``spec``. If used, attempting to *set*
493- or get an attribute on the mock that isn't on the object passed as
494- ``spec_set`` will raise an ``AttributeError``.
495-
496- * ``side_effect``: A function to be called whenever the Mock is called. See
497- the :attr:`Mock.side_effect` attribute. Useful for raising exceptions or
498- dynamically changing return values. The function is called with the same
499- arguments as the mock, and unless it returns :data:`DEFAULT`, the return
500- value of this function is used as the return value.
501-
502- Alternatively ``side_effect`` can be an exception class or instance. In
503- this case the exception will be raised when the mock is called.
504-
505- * ``return_value``: The value returned when the mock is called. By default
506- this is a new Mock (created on first access). See the
507- :attr:`Mock.return_value` attribute.
508-
509- * ``wraps``: Item for the mock object to wrap. If ``wraps`` is not None
510- then calling the Mock will pass the call through to the wrapped object
511- (returning the real result and ignoring ``return_value``). Attribute
512- access on the mock will return a Mock object that wraps the corresponding
513- attribute of the wrapped object (so attempting to access an attribute that
514- doesn't exist will raise an ``AttributeError``).
515-
516- If the mock has an explicit ``return_value`` set then calls are not passed
517- to the wrapped object and the ``return_value`` is returned instead.
518-
519- * ``name``: If the mock has a name then it will be used in the repr of the
520- mock. This can be useful for debugging. The name is propagated to child
521- mocks.
522- """
523-
524- def __new__(cls, *args, **kw):
525- # every instance has its own class
526- # so we can create magic methods on the
527- # class without stomping on other mocks
528- new = type(cls.__name__, (cls,), {'__doc__': cls.__doc__})
529- return object.__new__(new)
530-
531-
532- def __init__(
533- self, spec=None, wraps=None, name=None, spec_set=None,
534- parent=None, _spec_state=None, _new_name='', _new_parent=None,
535- **kwargs
536- ):
537- self._mock_parent = parent
538- self._mock_name = name
539- self._mock_new_name = _new_name
540- self._mock_new_parent = _new_parent
541-
542- self._spec_state = _spec_state
543-
544- _spec_class = None
545- if spec_set is not None:
546- spec = spec_set
547- spec_set = True
548-
549- if spec is not None and type(spec) is not list:
550- if isinstance(spec, ClassTypes):
551- _spec_class = spec
552- else:
553- _spec_class = _get_class(spec)
554-
555- spec = dir(spec)
556-
557- self._spec_class = _spec_class
558- self._spec_set = spec_set
559- self._mock_methods = spec
560- self._mock_children = {}
561- self._mock_wraps = wraps
562- self._mock_signature = None
563-
564- self._mock_called = False
565- self._mock_call_args = None
566- self._mock_call_count = 0
567- self._mock_call_args_list = []
568-
569- self.reset_mock()
570- self.configure_mock(**kwargs)
571-
572- _super(NonCallableMock, self).__init__(
573- spec, wraps, name, spec_set, parent,
574- _spec_state, **kwargs
575- )
576-
577-
578- def __get_return_value(self):
579- ret = self._mock_return_value
580- if self._mock_signature is not None:
581- ret = self._mock_signature.return_value
582-
583- if ret is DEFAULT:
584- ret = self._get_child_mock(
585- _new_parent=self, _new_name='()'
586- )
587- self.return_value = ret
588- return ret
589-
590-
591- def __set_return_value(self, value):
592- if self._mock_signature is not None:
593- self._mock_signature.return_value = value
594- else:
595- self._mock_return_value = value
596-
597- __return_value_doc = "The value to be returned when the mock is called."
598- return_value = property(__get_return_value, __set_return_value,
599- __return_value_doc)
600-
601-
602- @property
603- def __class__(self):
604- if self._spec_class is None:
605- return type(self)
606- return self._spec_class
607-
608- called = _mock_signature_property('called')
609- call_count = _mock_signature_property('call_count')
610- call_args = _mock_signature_property('call_args')
611- call_args_list = _mock_signature_property('call_args_list')
612- side_effect = _mock_signature_property('side_effect')
613-
614-
615- def reset_mock(self):
616- "Restore the mock object to its initial state."
617- self.called = False
618- self.call_args = None
619- self.call_count = 0
620- self.mock_calls = []
621- self.call_args_list = []
622- self.method_calls = []
623-
624- for child in self._mock_children.values():
625- child.reset_mock()
626-
627- ret = self._mock_return_value
628- if _is_instance_mock(ret) and ret is not self:
629- ret.reset_mock()
630-
631-
632- def configure_mock(self, **kwargs):
633- """XXX needs docstring"""
634- for arg, val in sorted(kwargs.items(),
635- # we sort on the number of dots so that
636- # attributes are set before we set attributes on
637- # attributes
638- key=lambda entry: entry[0].count('.')):
639- args = arg.split('.')
640- final = args.pop()
641- obj = self
642- for entry in args:
643- obj = getattr(obj, entry)
644- setattr(obj, final, val)
645-
646-
647- def __getattr__(self, name):
648- if name == '_mock_methods':
649- raise AttributeError(name)
650- elif self._mock_methods is not None:
651- if name not in self._mock_methods or name in _all_magics:
652- raise AttributeError("Mock object has no attribute %r" % name)
653- elif _is_magic(name):
654- raise AttributeError(name)
655-
656- result = self._mock_children.get(name)
657- if result is None:
658- wraps = None
659- if self._mock_wraps is not None:
660- # XXXX should we get the attribute without triggering code
661- # execution?
662- wraps = getattr(self._mock_wraps, name)
663-
664- result = self._get_child_mock(
665- parent=self, name=name, wraps=wraps, _new_name=name,
666- _new_parent=self
667- )
668- self._mock_children[name] = result
669-
670- elif isinstance(result, _SpecState):
671- result = create_autospec(
672- result.spec, result.spec_set, result.instance,
673- None, result.parent, result.name
674- )
675- self._mock_children[name] = result
676-
677- return result
678-
679-
680- def __repr__(self):
681- if self._mock_name is None and self._spec_class is None:
682- return object.__repr__(self)
683-
684- name_string = ''
685- spec_string = ''
686- if self._mock_name is not None:
687- def get_name(name):
688- if name is None:
689- return 'mock'
690- return name
691- parent = self._mock_parent
692- name = self._mock_name
693- while parent is not None:
694- name = get_name(parent._mock_name) + '.' + name
695- parent = parent._mock_parent
696- name_string = ' name=%r' % name
697- if self._spec_class is not None:
698- spec_string = ' spec=%r'
699- if self._spec_set:
700- spec_string = ' spec_set=%r'
701- spec_string = spec_string % self._spec_class.__name__
702- return "<%s%s%s id='%s'>" % (type(self).__name__,
703- name_string,
704- spec_string,
705- id(self))
706-
707-
708- def __dir__(self):
709- extras = self._mock_methods or []
710- from_type = dir(type(self))
711- from_dict = list(self.__dict__)
712-
713- if FILTER_DIR:
714- from_type = [e for e in from_type if not e.startswith('_')]
715- from_dict = [e for e in from_dict if not e.startswith('_') or
716- _is_magic(e)]
717- return sorted(set(extras + from_type + from_dict +
718- list(self._mock_children)))
719-
720-
721- def __setattr__(self, name, value):
722- if not 'method_calls' in self.__dict__:
723- # allow all attribute setting until initialisation is complete
724- return object.__setattr__(self, name, value)
725-
726- if (self._spec_set and self._mock_methods is not None and name not in
727- self._mock_methods and name not in self.__dict__ and
728- name not in _allowed_names):
729- raise AttributeError("Mock object has no attribute '%s'" % name)
730- if name in _unsupported_magics:
731- msg = 'Attempting to set unsupported magic method %r.' % name
732- raise AttributeError(msg)
733- elif name in _all_magics:
734- if self._mock_methods is not None and name not in self._mock_methods:
735- raise AttributeError("Mock object has no attribute '%s'" % name)
736-
737- if isinstance(value, MagicProxy):
738- setattr(type(self), name, value)
739- return
740-
741- if not _is_instance_mock(value):
742- setattr(type(self), name, _get_method(name, value))
743- original = value
744- real = lambda *args, **kw: original(self, *args, **kw)
745- value = mocksignature(value, real, skipfirst=True)
746- else:
747- setattr(type(self), name, value)
748- return object.__setattr__(self, name, value)
749-
750-
751- def __delattr__(self, name):
752- if name in _all_magics and name in type(self).__dict__:
753- delattr(type(self), name)
754- return object.__delattr__(self, name)
755-
756-
757- def _format_mock_call_signature(self, args, kwargs):
758- name = self._mock_name or 'mock'
759- message = '%s(%%s)' % name
760- formatted_args = ''
761- args_string = ', '.join([repr(arg) for arg in args])
762- kwargs_string = ', '.join([
763- '%s=%r' % (key, value) for key, value in kwargs.items()
764- ])
765- if args_string:
766- formatted_args = args_string
767- if kwargs_string:
768- if formatted_args:
769- formatted_args += ', '
770- formatted_args += kwargs_string
771-
772- return message % formatted_args
773-
774-
775- def _format_mock_failure_message(self, args, kwargs):
776- message = 'Expected call: %s\nActual call: %s'
777- expected_string = self._format_mock_call_signature(args, kwargs)
778- actual_string = self._format_mock_call_signature(*self.call_args)
779- return message % (expected_string, actual_string)
780-
781-
782- def assert_called_with(_mock_self, *args, **kwargs):
783- """
784- assert that the mock was called with the specified arguments.
785-
786- Raises an AssertionError if the args and keyword args passed in are
787- different to the last call to the mock.
788- """
789- self = _mock_self
790- if self.call_args is None:
791- expected = self._format_mock_call_signature(args, kwargs)
792- raise AssertionError('Expected call: %s\nNot called' % (expected,))
793-
794- if self.call_args != (args, kwargs):
795- msg = self._format_mock_failure_message(args, kwargs)
796- raise AssertionError(msg)
797-
798-
799- def assert_called_once_with(_mock_self, *args, **kwargs):
800- """
801- assert that the mock was called exactly once and with the specified
802- arguments.
803- """
804- self = _mock_self
805- if not self.call_count == 1:
806- msg = ("Expected to be called once. Called %s times." %
807- self.call_count)
808- raise AssertionError(msg)
809- return self.assert_called_with(*args, **kwargs)
810-
811-
812- def _get_child_mock(self, **kw):
813- _type = type(self)
814- if not issubclass(_type, CallableMixin):
815- if issubclass(_type, NonCallableMagicMock):
816- klass = MagicMock
817- elif issubclass(_type, NonCallableMock) :
818- klass = Mock
819- else:
820- klass = _type.__mro__[1]
821- return klass(**kw)
822-
823-
824-
825-class CallableMixin(Base):
826-
827- def __init__(self, spec=None, side_effect=None, return_value=DEFAULT,
2050 further changed lines not shown

The check that tells the two apart

failpass·tests/testhelpers.py::CallargsTest::test_callargs_with_args_call_empty_name

Check file tests/testhelpers.py, taken without changes from the fix and copied onto the older code, so the exact same check runs against both versions.

Origin and history

The code before itd5590a43cda5ffacc53a7a2aa37ba828535ae6c3
Broken version dated2011-07-18
Modulemock
Units changed_Call, callargs
Fingerprint9eba03ca8f9dc304
Checked2026-08-18 by goldset/0.1

Every field above is generated by our program. None of it is written by hand.

Other bugs found in testing-cabal/mock