So there's still a lot of duplication. Both functions get a mismatch, check for early return, then add details. The only difference is what they do when there is a mismatch: one raises, one manually attaches an exception and then sets force-failure.

So this structure should work:

def _blahhelper(self, matchee, matcher, message, verbose)
 mismatch = _match(matchee, matcher, message)
 if not mismatch:
      return
 for (name, value) in mismatch.get_details().items():
       self.addDetailUniqueName(name, value)
 return MismatchError(matchee, matcher, mismatch, verbose)

(which would let _addMismatchDetails not exist )

and then assert can raise the result, and expect can attach it.