diff --git a/Android.bp b/Android.bp
deleted file mode 100644
index e3996cc..0000000
--- a/Android.bp
+++ /dev/null
@@ -1,31 +0,0 @@
-//
-// Copyright (C) 2021 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package {
-    default_applicable_licenses: ["external_python_mock_license"],
-}
-
-// Added automatically by a large-scale-change
-// See: http://go/android-license-faq
-license {
-    name: "external_python_mock_license",
-    visibility: [":__subpackages__"],
-    license_kinds: [
-        "SPDX-license-identifier-BSD",
-    ],
-    license_text: [
-        "LICENSE.txt",
-    ],
-}
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
deleted file mode 100644
index 919648b..0000000
--- a/CHANGELOG.rst
+++ /dev/null
@@ -1,206 +0,0 @@
-3.0.5
------
-
-- Issue #31855: :func:`unittest.mock.mock_open` results now respects the
-  argument of read([size]). Patch contributed by Rémi Lapeyre.
-
-3.0.4
------
-
-- Include the license, readme and changelog in the source distribution.
-
-3.0.3
------
-
-- Fixed patching of dictionaries, when specifying the target with a
-  unicode on Python 2.
-
-3.0.2
------
-
-- Add missing ``funcsigs`` dependency on Python 2.
-
-3.0.1
------
-
-- Fix packaging issue where ``six`` was missed as a dependency.
-
-3.0.0
------
-
-- Issue #35226: Recursively check arguments when testing for equality of
-  :class:`unittest.mock.call` objects and add note that tracking of
-  parameters used to create ancestors of mocks in ``mock_calls`` is not
-  possible.
-
-- Issue #31177: Fix bug that prevented using :meth:`reset_mock
-  <unittest.mock.Mock.reset_mock>` on mock instances with deleted attributes
-
-- Issue #26704: Added test demonstrating double-patching of an instance
-  method.  Patch by Anthony Sottile.
-
-- Issue #35500: Write expected and actual call parameters on separate lines
-  in :meth:`unittest.mock.Mock.assert_called_with` assertion errors.
-  Contributed by Susan Su.
-
-- Issue #35330: When a :class:`Mock` instance was used to wrap an object, if
-  `side_effect` is used in one of the mocks of it methods, don't call the
-  original implementation and return the result of using the side effect the
-  same way that it is done with return_value.
-
-- Issue #30541: Add new function to seal a mock and prevent the
-  automatically creation of child mocks. Patch by Mario Corchero.
-
-- Issue #35022: :class:`unittest.mock.MagicMock` now supports the
-  ``__fspath__`` method (from :class:`os.PathLike`).
-
-- Issue #33516: :class:`unittest.mock.MagicMock` now supports the
-  ``__round__`` magic method.
-
-- Issue #35512: :func:`unittest.mock.patch.dict` used as a decorator with
-  string target resolves the target during function call instead of during
-  decorator construction. Patch by Karthikeyan Singaravelan.
-
-- Issue #36366: Calling ``stop()`` on an unstarted or stopped
-  :func:`unittest.mock.patch` object will now return `None` instead of
-  raising :exc:`RuntimeError`, making the method idempotent. Patch
-  byKarthikeyan Singaravelan.
-
-- Issue #35357: Internal attributes' names of unittest.mock._Call and
-  unittest.mock.MagicProxy (name, parent & from_kall) are now prefixed with
-  _mock_ in order to prevent clashes with widely used object attributes.
-  Fixed minor typo in test function name.
-
-- Issue #20239: Allow repeated assignment deletion of
-  :class:`unittest.mock.Mock` attributes. Patch by Pablo Galindo.
-
-- Issue #35082: Don't return deleted attributes when calling dir on a
-  :class:`unittest.mock.Mock`.
-
-- Issue #0: Improved an error message when mock assert_has_calls fails.
-
-- Issue #23078: Add support for :func:`classmethod` and :func:`staticmethod`
-  to :func:`unittest.mock.create_autospec`.  Initial patch by Felipe Ochoa.
-
-- Issue #21478: Calls to a child function created with
-  :func:`unittest.mock.create_autospec` should propagate to the parent.
-  Patch by Karthikeyan Singaravelan.
-
-- Issue #36598: Fix ``isinstance`` check for Mock objects with spec when the
-  code is executed under tracing. Patch by Karthikeyan Singaravelan.
-
-- Issue #32933: :func:`unittest.mock.mock_open` now supports iteration over
-  the file contents. Patch by Tony Flury.
-
-- Issue #21269: Add ``args`` and ``kwargs`` properties to mock call objects.
-  Contributed by Kumar Akshay.
-
-- Issue #17185: Set ``__signature__`` on mock for :mod:`inspect` to get
-  signature. Patch by Karthikeyan Singaravelan.
-
-- Issue #35047: ``unittest.mock`` now includes mock calls in exception
-  messages if ``assert_not_called``, ``assert_called_once``, or
-  ``assert_called_once_with`` fails. Patch by Petter Strandmark.
-
-- Issue #28380: unittest.mock Mock autospec functions now properly support
-  assert_called, assert_not_called, and assert_called_once.
-  
-- Issue #28735: Fixed the comparison of mock.MagickMock with mock.ANY.
-
-- Issue #20804: The unittest.mock.sentinel attributes now preserve their
-  identity when they are copied or pickled.
-
-- Issue #28961: Fix unittest.mock._Call helper: don't ignore the name parameter
-  anymore. Patch written by Jiajun Huang.
-
-- Issue #26750: unittest.mock.create_autospec() now works properly for
-  subclasses of property() and other data descriptors.
-
-- Issue #21271: New keyword only parameters in reset_mock call.
-
-- Issue #26807: mock_open 'files' no longer error on readline at end of file.
-  Patch from Yolanda Robla.
-
-- Issue #25195: Fix a regression in mock.MagicMock. _Call is a subclass of
-  tuple (changeset 3603bae63c13 only works for classes) so we need to
-  implement __ne__ ourselves.  Patch by Andrew Plummer.
-
-2.0.0 and earlier
------------------
-
-- Issue #26323: Add Mock.assert_called() and Mock.assert_called_once()
-  methods to unittest.mock. Patch written by Amit Saha.
-
-- Issue #22138: Fix mock.patch behavior when patching descriptors. Restore
-  original values after patching. Patch contributed by Sean McCully.
-
-- Issue #24857: Comparing call_args to a long sequence now correctly returns a
-  boolean result instead of raising an exception.  Patch by A Kaptur.
-
-- Issue #23004: mock_open() now reads binary data correctly when the type of
-  read_data is bytes.  Initial patch by Aaron Hill.
-
-- Issue #21750: mock_open.read_data can now be read from each instance, as it
-  could in Python 3.3.
-
-- Issue #18622: unittest.mock.mock_open().reset_mock would recurse infinitely.
-  Patch from Nicola Palumbo and Laurent De Buyst.
-
-- Issue #23661: unittest.mock side_effects can now be exceptions again. This
-  was a regression vs Python 3.4. Patch from Ignacio Rossi
-
-- Issue #23310: Fix MagicMock's initializer to work with __methods__, just
-  like configure_mock().  Patch by Kasia Jachim.
-
-- Issue #23568: Add rdivmod support to MagicMock() objects.
-  Patch by Håkan Lövdahl.
-
-- Issue #23581: Add matmul support to MagicMock. Patch by Håkan Lövdahl.
-
-- Issue #23326: Removed __ne__ implementations.  Since fixing default __ne__
-  implementation in issue #21408 they are redundant. *** NOT BACKPORTED ***
-
-- Issue #21270: We now override tuple methods in mock.call objects so that
-  they can be used as normal call attributes.
-
-- Issue #21256: Printout of keyword args should be in deterministic order in
-  a mock function call. This will help to write better doctests.
-
-- Issue #21262: New method assert_not_called for Mock.
-  It raises AssertionError if the mock has been called.
-
-- Issue #21238: New keyword argument `unsafe` to Mock. It raises
-  `AttributeError` incase of an attribute startswith assert or assret.
-
-- Issue #21239: patch.stopall() didn't work deterministically when the same
-  name was patched more than once.
-
-- Issue #21222: Passing name keyword argument to mock.create_autospec now
-  works.
-
-- Issue #17826: setting an iterable side_effect on a mock function created by
-  create_autospec now works. Patch by Kushal Das.
-
-- Issue #17826: setting an iterable side_effect on a mock function created by
-  create_autospec now works. Patch by Kushal Das.
-
-- Issue #20968: unittest.mock.MagicMock now supports division.
-  Patch by Johannes Baiter.
-
-- Issue #20189: unittest.mock now no longer assumes that any object for
-  which it could get an inspect.Signature is a callable written in Python.
-  Fix courtesy of Michael Foord.
-
-- Issue #17467: add readline and readlines support to mock_open in
-  unittest.mock.
-
-- Issue #17015: When it has a spec, a Mock object now inspects its signature
-  when matching calls, so that arguments can be matched positionally or
-  by name.
-
-- Issue #15323: improve failure message of Mock.assert_called_once_with
-
-- Issue #14857: fix regression in references to PEP 3135 implicit __class__
-  closure variable (Reopens issue #12370)
-
-- Issue #14295: Add unittest.mock
diff --git a/LICENSE.txt b/LICENSE.txt
deleted file mode 100644
index c820924..0000000
--- a/LICENSE.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright (c) 2003-2013, Michael Foord & the mock team
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-
-    * Redistributions in binary form must reproduce the above
-      copyright notice, this list of conditions and the following
-      disclaimer in the documentation and/or other materials provided
-      with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/MANIFEST.in b/MANIFEST.in
deleted file mode 100644
index 7f47ab6..0000000
--- a/MANIFEST.in
+++ /dev/null
@@ -1,2 +0,0 @@
-include LICENSE.txt
-include *.rst
diff --git a/METADATA b/METADATA
deleted file mode 100644
index e0d0615..0000000
--- a/METADATA
+++ /dev/null
@@ -1,19 +0,0 @@
-name: "mock"
-description:
-    "mock is a library for testing in Python. It allows you to replace parts of "
-    "your system under test with mock objects and make assertions about how "
-    "they have been used."
-
-third_party {
-  url {
-    type: HOMEPAGE
-    value: "https://pypi.org/project/mock/"
-  }
-  url {
-    type: GIT
-    value: "https://github.com/testing-cabal/mock"
-  }
-  version: "2.0.0"
-  last_upgrade_date { year: 2018 month: 8 day: 1 }
-  license_type: NOTICE
-}
diff --git a/MODULE_LICENSE_BSD b/MODULE_LICENSE_BSD
deleted file mode 100644
index e69de29..0000000
--- a/MODULE_LICENSE_BSD
+++ /dev/null
diff --git a/NOTICE b/NOTICE
deleted file mode 120000
index 85de3d4..0000000
--- a/NOTICE
+++ /dev/null
@@ -1 +0,0 @@
-LICENSE.txt
\ No newline at end of file
diff --git a/OWNERS b/OWNERS
index fcb8c0e..7529cb9 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,4 +1 @@
-# Default owners are top 3 or more active developers of the past 1 or 2 years
-# or people with more than 10 commits last year.
-# Please update this list if you find better owner candidates.
-kevcheng@google.com
+include platform/system/core:/janitors/OWNERS
diff --git a/README.rst b/README.rst
deleted file mode 100644
index b4f3163..0000000
--- a/README.rst
+++ /dev/null
@@ -1,36 +0,0 @@
-mock is a library for testing in Python. It allows you to replace parts of
-your system under test with mock objects and make assertions about how they
-have been used.
-
-mock is now part of the Python standard library, available as `unittest.mock
-<https://docs.python.org/dev/library/unittest.mock.html>`_ in Python 3.3
-onwards.
-
-This package contains a rolling backport of the standard library mock code
-compatible with Python 2.7 and 3.4 and up.
-
-Please see the standard library documentation for more details.
-
-:Homepage: `Mock Homepage`_
-:Download: `Mock on PyPI`_
-:Documentation: `Python Docs`_
-:License: `BSD License`_
-:Support: `Mailing list (testing-in-python@lists.idyll.org)
- <http://lists.idyll.org/listinfo/testing-in-python>`_
-:Code: `GitHub
- <https://github.com/testing-cabal/mock>`_
-:Issue tracker: `GitHub Issues
- <https://github.com/testing-cabal/mock/issues>`_
-:Build status:
-    |CircleCI|_ |Docs|_
-
-    .. |CircleCI| image:: https://circleci.com/gh/testing-cabal/mock/tree/master.svg?style=shield
-    .. _CircleCI: https://circleci.com/gh/testing-cabal/mock/tree/master
-
-    .. |Docs| image:: https://readthedocs.org/projects/mock/badge/?version=latest
-    .. _Docs: http://mock.readthedocs.org/en/latest/
-
-.. _Mock Homepage: http://mock.readthedocs.org/en/latest/
-.. _BSD License: https://github.com/testing-cabal/mock/blob/master/LICENSE.txt
-.. _Python Docs: https://docs.python.org/dev/library/unittest.mock.html
-.. _mock on PyPI: https://pypi.org/project/mock/
diff --git a/backport.py b/backport.py
deleted file mode 100644
index b2ab523..0000000
--- a/backport.py
+++ /dev/null
@@ -1,147 +0,0 @@
-import re
-from argparse import ArgumentParser
-from os.path import dirname, abspath, join
-from subprocess import check_output, call
-
-
-def git(command, repo):
-    return check_output('git '+command, cwd=repo, shell=True).decode()
-
-
-def repo_state_bad(mock_repo):
-    status = git('status', mock_repo)
-    if 'You are in the middle of an am session' in status:
-        print(f'Mock repo at {mock_repo} needs cleanup:\n')
-        call('git status', shell=True)
-        return True
-
-
-def cleanup_old_patches(mock_repo):
-    print('cleaning up old patches:')
-    call('rm -vf /tmp/*.mock.patch', shell=True)
-    call('find . -name "*.rej" -print -delete', shell=True, cwd=mock_repo)
-
-
-def find_initial_cpython_rev():
-    with open('lastsync.txt') as source:
-        return source.read().strip()
-
-
-def cpython_revs_affecting_mock(cpython_repo, start):
-    revs = git(f'log --no-merges --format=%H {start}..  '
-               f'-- Lib/unittest/mock.py Lib/unittest/test/testmock/',
-               repo=cpython_repo).split()
-    revs.reverse()
-    print(f'{len(revs)} patches that may need backporting')
-    return revs
-
-
-def has_been_backported(mock_repo, cpython_rev):
-    backport_rev = git(f'log --format=%H --grep "Backports: {cpython_rev}"',
-                       repo=mock_repo).strip()
-    if backport_rev:
-        print(f'{cpython_rev} backported in {backport_rev}')
-        return True
-    print(f'{cpython_rev} has not been backported')
-
-
-def extract_patch_for(cpython_repo, rev):
-    return git(f'format-patch -1 --no-stat --keep-subject --signoff --stdout {rev}',
-               repo=cpython_repo)
-
-
-def munge(rev, patch):
-
-    sign_off = 'Signed-off-by:'
-    patch = patch.replace(sign_off, f'Backports: {rev}\n{sign_off}', 1)
-
-    for pattern, sub in (
-        ('(a|b)/Lib/unittest/mock.py', r'\1/mock/mock.py'),
-        (r'(a|b)/Lib/unittest/test/testmock/(\S+)', r'\1/mock/tests/\2'),
-        ('(a|b)/Misc/NEWS', r'\1/NEWS'),
-        ('(a|b)/NEWS.d/next/[^/]+/(.+\.rst)', r'\1/NEWS.d/\2'),
-    ):
-        patch = re.sub(pattern, sub, patch)
-    return patch
-
-
-def apply_patch(mock_repo, rev, patch):
-    patch_path = f'/tmp/{rev}.mock.patch'
-
-    with open(patch_path, 'w') as target:
-        target.write(patch)
-    print(f'wrote {patch_path}')
-
-    call(f'git am -k '
-         f'--include "mock/*" --include NEWS --include "NEWS.d/*" '
-         f'--reject {patch_path} ',
-         cwd=mock_repo, shell=True)
-
-
-def update_last_sync(mock_repo, rev):
-    with open(join(mock_repo, 'lastsync.txt'), 'w') as target:
-        target.write(rev+'\n')
-    print(f'update lastsync.txt to {rev}')
-
-
-def rev_from_mock_patch(text):
-    match = re.search('Backports: ([a-z0-9]+)', text)
-    return match.group(1)
-
-
-def skip_current(mock_repo, reason):
-    text = git('am --show-current-patch', repo=mock_repo)
-    rev = rev_from_mock_patch(text)
-    git('am --abort', repo=mock_repo)
-    print(f'skipping {rev}')
-    update_last_sync(mock_repo, rev)
-    call(f'git commit -m "Backports: {rev}, skipped: {reason}" lastsync.txt', shell=True, cwd=mock_repo)
-    cleanup_old_patches(mock_repo)
-
-
-def commit_last_sync(revs, mock_repo):
-    print('Yay! All caught up!')
-    if len(revs):
-        git('commit -m "latest sync point" lastsync.txt', repo=mock_repo)
-
-
-def main():
-    args = parse_args()
-
-    if args.skip_current:
-        return skip_current(args.mock, args.skip_reason)
-
-    if repo_state_bad(args.mock):
-        return
-
-    cleanup_old_patches(args.mock)
-
-    initial_cpython_rev = find_initial_cpython_rev()
-
-    revs = cpython_revs_affecting_mock(args.cpython, initial_cpython_rev)
-    for rev in revs:
-
-        if has_been_backported(args.mock, rev):
-            update_last_sync(args.mock, rev)
-            continue
-
-        patch = extract_patch_for(args.cpython, rev)
-        patch = munge(rev, patch)
-        apply_patch(args.mock, rev, patch)
-        break
-
-    else:
-        commit_last_sync(revs, args.mock)
-
-
-def parse_args():
-    parser = ArgumentParser()
-    parser.add_argument('--cpython', default='../cpython')
-    parser.add_argument('--mock', default=abspath(dirname(__file__)))
-    parser.add_argument('--skip-current', action='store_true')
-    parser.add_argument('--skip-reason', default='it has no changes needed here.')
-    return parser.parse_args()
-
-
-if __name__ == '__main__':
-    main()
diff --git a/docs/changelog.txt b/docs/changelog.txt
deleted file mode 100644
index 4de03af..0000000
--- a/docs/changelog.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Changelog
-=========
-
-.. include:: ../CHANGELOG.rst
diff --git a/docs/conf.py b/docs/conf.py
deleted file mode 100644
index d2be5a5..0000000
--- a/docs/conf.py
+++ /dev/null
@@ -1,206 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Mock documentation build configuration file, created by
-# sphinx-quickstart on Mon Nov 17 18:12:00 2008.
-#
-# This file is execfile()d with the current directory set to its containing dir.
-#
-# The contents of this file are pickled, so don't put values in the namespace
-# that aren't pickleable (module imports are okay, they're removed automatically).
-#
-# All configuration values have a default value; values that are commented out
-# serve to show the default value.
-
-import sys, os
-sys.path.insert(0, os.path.abspath('..'))
-
-import mock
-
-# If your extensions are in another directory, add it here. If the directory
-# is relative to the documentation root, use os.path.abspath to make it
-# absolute, like shown here.
-#sys.path.append(os.path.abspath('some/directory'))
-
-# General configuration
-# ---------------------
-
-# Add any Sphinx extension module names here, as strings. They can be extensions
-# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = ['sphinx.ext.doctest']
-
-doctest_global_setup = """
-import os
-import sys
-import mock
-from mock import * # yeah, I know :-/
-import __main__
-
-if os.getcwd() not in sys.path:
-    sys.path.append(os.getcwd())
-
-# keep a reference to __main__
-sys.modules['__main'] = __main__
-
-class ProxyModule(object):
-    def __init__(self):
-        self.__dict__ = globals()
-
-sys.modules['__main__'] = ProxyModule()
-"""
-
-doctest_global_cleanup = """
-sys.modules['__main__'] = sys.modules['__main']
-"""
-
-html_theme = 'nature'
-html_theme_options = {}
-
-# Add any paths that contain templates here, relative to this directory.
-#templates_path = ['_templates']
-
-# The suffix of source filenames.
-source_suffix = '.txt'
-
-# The master toctree document.
-master_doc = 'index'
-
-# General substitutions.
-project = u'Mock'
-copyright = u'2007-2015, Michael Foord & the mock team'
-
-# The default replacements for |version| and |release|, also used in various
-# other places throughout the built documents. Supplied by pbr.
-#
-version = release = mock.mock.__version__
-
-# There are two options for replacing |today|: either, you set today to some
-# non-false value, then it is used: (Set from pbr)
-today = ''
-# Else, today_fmt is used as the format for a strftime call.
-# today_fmt = '%B %d, %Y'
-
-# List of documents that shouldn't be included in the build.
-#unused_docs = []
-
-# List of directories, relative to source directories, that shouldn't be searched
-# for source files.
-exclude_trees = []
-
-# The reST default role (used for this markup: `text`) to use for all documents.
-#default_role = None
-
-# If true, '()' will be appended to :func: etc. cross-reference text.
-#add_function_parentheses = True
-
-# If true, the current module name will be prepended to all description
-# unit titles (such as .. function::).
-add_module_names = False
-
-# If true, sectionauthor and moduleauthor directives will be shown in the
-# output. They are ignored by default.
-#show_authors = False
-
-# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'friendly'
-
-
-# Options for HTML output
-# -----------------------
-
-# The style sheet to use for HTML and HTML Help pages. A file of that name
-# must exist either in Sphinx' static/ path, or in one of the custom paths
-# given in html_static_path.
-#html_style = 'adctheme.css'
-
-# The name for this set of Sphinx documents.  If None, it defaults to
-# "<project> v<release> documentation".
-#html_title = None
-
-# A shorter title for the navigation bar.  Default is the same as html_title.
-#html_short_title = None
-
-# The name of an image file (relative to this directory) to place at the top
-# of the sidebar.
-#html_logo = None
-
-# The name of an image file (within the static path) to use as favicon of the
-# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
-# pixels large.
-#html_favicon = None
-
-# Add any paths that contain custom static files (such as style sheets) here,
-# relative to this directory. They are copied after the builtin static files,
-# so a file named "default.css" will overwrite the builtin "default.css".
-#html_static_path = ['_static']
-
-# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
-# using the given strftime format.
-html_last_updated_fmt = '%b %d, %Y'
-
-# If true, SmartyPants will be used to convert quotes and dashes to
-# typographically correct entities.
-#html_use_smartypants = True
-
-# Custom sidebar templates, maps document names to template names.
-#html_sidebars = {}
-
-# Additional templates that should be rendered to pages, maps page names to
-# template names.
-#html_additional_pages = {}
-
-# If false, no module index is generated.
-html_use_modindex = False
-
-# If false, no index is generated.
-#html_use_index = True
-
-# If true, the index is split into individual pages for each letter.
-#html_split_index = False
-
-# If true, the reST sources are included in the HTML build as _sources/<name>.
-#html_copy_source = True
-
-# If true, an OpenSearch description file will be output, and all pages will
-# contain a <link> tag referring to it.  The value of this option must be the
-# base URL from which the finished HTML is served.
-#html_use_opensearch = ''
-
-# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
-#html_file_suffix = ''
-
-# Output file base name for HTML help builder.
-htmlhelp_basename = 'Mockdoc'
-
-
-# Options for LaTeX output
-# ------------------------
-
-# The paper size ('letter' or 'a4').
-#latex_paper_size = 'letter'
-
-# The font size ('10pt', '11pt' or '12pt').
-latex_font_size = '12pt'
-
-# Grouping the document tree into LaTeX files. List of tuples
-# (source start file, target name, title, author, document class [howto/manual]).
-latex_documents = [
-  ('index', 'Mock.tex', u'Mock Documentation',
-   u'Michael Foord', 'manual'),
-]
-
-# The name of an image file (relative to this directory) to place at the top of
-# the title page.
-#latex_logo = None
-
-# For "manual" documents, if this is true, then toplevel headings are parts,
-# not chapters.
-#latex_use_parts = False
-
-# Additional stuff for the LaTeX preamble.
-#latex_preamble = ''
-
-# Documents to append as an appendix to all manuals.
-#latex_appendices = []
-
-# If false, no module index is generated.
-latex_use_modindex = False
diff --git a/docs/index.txt b/docs/index.txt
deleted file mode 100644
index 4e8bc17..0000000
--- a/docs/index.txt
+++ /dev/null
@@ -1,181 +0,0 @@
-===================================
- Mock - Mocking and Testing Library
-===================================
-
-.. include:: ../README.rst
-
-.. module:: mock
-   :synopsis: Mock object and testing library.
-
-.. index:: introduction
-
-.. toctree::
-   :hidden:
-
-   changelog
-
-Python Version Compatibility
-++++++++++++++++++++++++++++
-
-* Version 1.0.1 is the last version compatible with Python < 2.6.
-
-* Version 1.3.0 is the last version compatible with Python 3.2.
-
-* Version 2.0.0 is the last version compatible with Python 2.6.
-
-* Version 2.0.0 is the last version offering official Jython support.
-
-.. index:: installing
-.. _installing:
-
-Installing
-++++++++++
-
-.. index:: repository
-.. index:: git
-
-You can checkout the latest development version from GitHub
-repository with the following command:
-
-    ``git clone https://github.com/testing-cabal/mock.git``
-
-
-.. index:: pip
-
-You can install mock with pip:
-
-    | ``pip install -U mock``
-
-.. index:: bug reports
-
-Bug Reports
-+++++++++++
-
-Issues with the backport process, such as compatibility with a particular
-Python, should be reported to the `bug tracker
-<https://github.com/testing-cabal/mock/issues>`_. Feature requests and issues
-with Mock functionality should be reported to the `Python bug tracker
-<https://bugs.python.org>`_.
-
-.. index:: python changes
-
-Changelog
-+++++++++
-
-See the :doc:`change log <changelog>`.
-
-.. index:: maintainer notes
-
-Maintainer Notes
-++++++++++++++++
-
-Development
------------
-
-Checkout from git (see :ref:`installing`) and submit pull requests.
-
-Committers can just push as desired: since all semantic development takes
-place in cPython, the backport process is as lightweight as we can make it.
-
-mock is CI tested using Travis-CI on Python versions 2.7, 3.4,
-3.5, 3.6, pypy, pypy3.
-
-If you end up fixing anything backport-specific, please add an entry
-to the top of ``CHANGELOG.rst`` so it shows up in the next release
-notes.
-
-Releasing
----------
-
-NB: please use semver. Bump the major component on API breaks, minor on all
-non-bugfix changes, patch on bugfix only changes.
-
-1. Run ``release.py [major|minor|bugfix]`` which will roll out new
-   NEWS items, bump the version number and create a commit for the release.
-
-2. Review that commit, feel free to amend it if you want to note anything
-   manually in ``CHANGELOG.rst``.
-
-3. Push to the ``master`` branch on
-   https://github.com/testing-cabal/mock.git and the Circle CI
-   automation will take care of pushing releases to PyPI and
-   creating a tag.
-
-Backporting rules
------------------
-
-- ``isinstance`` checks in cPython to ``type`` need to check ``ClassTypes``.
-  Code calling ``obj.isidentifier`` needs to change to ``_isidentifier(obj)``.
-
-- f-strings need to be rewritten using some other string substitution.
-
-- ``assertRaisesRegex`` needs to be ``assertRaisesRegexp`` for Python 2.
-
-- If test code won't compile on a particular version of Python, move it to
-  a matching ``_py{version}.py`` file. If ``{version}`` isn't 3, adjust
-  ``conftest.py``.
-
-- If code such as this causes coverage checking to drop below 100%:
-
-  .. code-block:: python
-
-      def will_never_be_called():
-          pass
-
-  It should be adjusted to the following pattern, preferably upstream,
-  so that the ``.coveragerc`` in this repo knows to ignore it:
-
-  .. code-block:: python
-
-      def will_never_be_called(): pass
-
-Backporting process
--------------------
-
-1. Clone cpython and mock into the same directory, eg:
-
-   .. code-block:: bash
-
-       mkdir vcs
-       cd vcs
-       git clone https://github.com/python/cpython.git
-       git clone https://github.com/testing-cabal/mock.git
-
-   Make sure they both on master and up to date!
-
-2. Create a branch in your ``mock`` clone and switch to it.
-
-3. Make sure you build a suitable virtualenv for Mock development
-   and activate it. For backporting, this should use Python 3.7+.
-
-4. Run ``backport.py``:
-
-   .. code-block:: bash
-
-       cd vcs/mock
-       python backport.py
-
-   This will find the next cpython patch that needs to be applied, munge it
-   and attempt to apply it with ``git am``.
-
-   If it succeeds, run the tests and/or push your branch up to a fork and
-   do a pull request into the master branch of the main repo to kick off
-   the continuous integration tests.
-
-   If it fails, you'll have to manually work with what ``git status`` shows
-   to get the patch committed.
-
-   If it turns out that there's nothing that should be applied from the failed commit,
-   run ``python backport.py --skip-current``, maybe with ``--skip-reason``.
-
-   If you have to make changes, please do a ``git commit --amend`` and add notes
-   about what needed doing below the ``Signed-off-by`` block.
-
-   If you have to make changes because tests fail with an applied patch, please
-   make those changes in a followup commit and take note of the "Backporting rules"
-   above.
-
-5. Rinse and repeat until ``backport.py`` reports no more patches need applying.
-
-6. If ``backport.py`` has updated ``lastsync.txt``, now would be a good time
-   to commit that change.
diff --git a/lastsync.txt b/lastsync.txt
deleted file mode 100644
index 1f18392..0000000
--- a/lastsync.txt
+++ /dev/null
@@ -1 +0,0 @@
-11a8832c98b3db78727312154dd1d3ba76d639ec
diff --git a/mock/Android.bp b/mock/Android.bp
deleted file mode 100644
index 5a30424..0000000
--- a/mock/Android.bp
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2018 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "external_python_mock_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-BSD
-    default_applicable_licenses: ["external_python_mock_license"],
-}
-
-python_library {
-    name: "py-mock",
-    host_supported: true,
-    srcs: [
-        "*.py",
-    ],
-    version: {
-        py2: {
-            enabled: true,
-        },
-        py3: {
-            enabled: true,
-        },
-    },
-    libs: [
-        "py-funcsigs",
-        "py-six",
-    ],
-    pkg_path: "mock",
-}
diff --git a/mock/__init__.py b/mock/__init__.py
deleted file mode 100644
index 8f383f0..0000000
--- a/mock/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-from __future__ import absolute_import
-import mock.mock as _mock
-from mock.mock import *
-__all__ = _mock.__all__
diff --git a/mock/mock.py b/mock/mock.py
deleted file mode 100644
index 2d39253..0000000
--- a/mock/mock.py
+++ /dev/null
@@ -1,2619 +0,0 @@
-# mock.py
-# Test tools for mocking and patching.
-# E-mail: fuzzyman AT voidspace DOT org DOT uk
-#
-# http://www.voidspace.org.uk/python/mock/
-#
-# Copyright (c) 2007-2013, Michael Foord & the mock team
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#     * Redistributions of source code must retain the above copyright
-#       notice, this list of conditions and the following disclaimer.
-#
-#     * Redistributions in binary form must reproduce the above
-#       copyright notice, this list of conditions and the following
-#       disclaimer in the documentation and/or other materials provided
-#       with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-from __future__ import absolute_import
-
-__all__ = (
-    '__version__',
-    'version_info',
-    'Mock',
-    'MagicMock',
-    'patch',
-    'sentinel',
-    'DEFAULT',
-    'ANY',
-    'call',
-    'create_autospec',
-    'FILTER_DIR',
-    'CallableMixin',
-    'NonCallableMock',
-    'NonCallableMagicMock',
-    'mock_open',
-    'PropertyMock',
-    'seal',
-)
-
-
-from functools import partial
-import io
-import inspect
-import pprint
-import sys
-try:
-    import builtins
-except ImportError:
-    import __builtin__ as builtins
-from types import ModuleType, MethodType
-from unittest.util import safe_repr
-
-import six
-from six import wraps
-
-__version__ = '3.0.5'
-version_info = tuple(int(p) for p in __version__.split('.'))
-
-import mock
-
-try:
-    inspectsignature = inspect.signature
-except AttributeError:
-    import funcsigs
-    inspectsignature = funcsigs.signature
-
-
-# TODO: use six.
-try:
-    unicode
-except NameError:
-    # Python 3
-    basestring = unicode = str
-
-try:
-    long
-except NameError:
-    # Python 3
-    long = int
-
-if six.PY2:
-    # Python 2's next() can't handle a non-iterator with a __next__ method.
-    _next = next
-    def next(obj, _next=_next):
-        if getattr(obj, '__next__', None):
-            return obj.__next__()
-        return _next(obj)
-
-    del _next
-
-
-_builtins = {name for name in dir(builtins) if not name.startswith('_')}
-
-try:
-    _isidentifier = str.isidentifier
-except AttributeError:
-    # Python 2.X
-    import keyword
-    import re
-    regex = re.compile(r'^[a-z_][a-z0-9_]*$', re.I)
-    def _isidentifier(string):
-        if string in keyword.kwlist:
-            return False
-        return regex.match(string)
-
-
-# NOTE: This FILTER_DIR is not used. The binding in mock.FILTER_DIR is.
-FILTER_DIR = True
-
-# Workaround for Python issue #12370
-# Without this, the __class__ properties wouldn't be set correctly
-_safe_super = super
-
-def _is_instance_mock(obj):
-    # can't use isinstance on Mock objects because they override __class__
-    # The base class for all mocks is NonCallableMock
-    return issubclass(type(obj), NonCallableMock)
-
-
-def _is_exception(obj):
-    return (
-        isinstance(obj, BaseException) or
-        isinstance(obj, ClassTypes) and issubclass(obj, BaseException)
-    )
-
-
-class _slotted(object):
-    __slots__ = ['a']
-
-
-# Do not use this tuple.  It was never documented as a public API.
-# It will be removed.  It has no obvious signs of users on github.
-DescriptorTypes = (
-    type(_slotted.a),
-    property,
-)
-
-
-def _get_signature_object(func, as_instance, eat_self):
-    """
-    Given an arbitrary, possibly callable object, try to create a suitable
-    signature object.
-    Return a (reduced func, signature) tuple, or None.
-    """
-    if isinstance(func, ClassTypes) and not as_instance:
-        # If it's a type and should be modelled as a type, use __init__.
-        try:
-            func = func.__init__
-        except AttributeError:
-            return None
-        # Skip the `self` argument in __init__
-        eat_self = True
-    elif not isinstance(func, FunctionTypes):
-        # If we really want to model an instance of the passed type,
-        # __call__ should be looked up, not __init__.
-        try:
-            func = func.__call__
-        except AttributeError:
-            return None
-    if eat_self:
-        sig_func = partial(func, None)
-    else:
-        sig_func = func
-
-    try:
-        return func, inspectsignature(sig_func)
-    except ValueError:
-        # Certain callable types are not supported by inspect.signature()
-        return None
-
-
-def _check_signature(func, mock, skipfirst, instance=False):
-    sig = _get_signature_object(func, instance, skipfirst)
-    if sig is None:
-        return
-    func, sig = sig
-    def checksig(_mock_self, *args, **kwargs):
-        sig.bind(*args, **kwargs)
-    _copy_func_details(func, checksig)
-    type(mock)._mock_check_sig = checksig
-    type(mock).__signature__ = sig
-
-
-def _copy_func_details(func, funcopy):
-    # we explicitly don't copy func.__dict__ into this copy as it would
-    # expose original attributes that should be mocked
-    for attribute in (
-        '__name__', '__doc__', '__text_signature__',
-        '__module__', '__defaults__', '__kwdefaults__',
-    ):
-        try:
-            setattr(funcopy, attribute, getattr(func, attribute))
-        except AttributeError:
-            pass
-    if six.PY2:
-        try:
-            funcopy.func_defaults = func.func_defaults
-        except AttributeError:
-            pass
-
-
-def _callable(obj):
-    if isinstance(obj, ClassTypes):
-        return True
-    if isinstance(obj, (staticmethod, classmethod, MethodType)):
-        return _callable(obj.__func__)
-    if getattr(obj, '__call__', None) is not None:
-        return True
-    return False
-
-
-def _is_list(obj):
-    # checks for list or tuples
-    # XXXX badly named!
-    return type(obj) in (list, tuple)
-
-
-def _instance_callable(obj):
-    """Given an object, return True if the object is callable.
-    For classes, return True if instances would be callable."""
-    if not isinstance(obj, ClassTypes):
-        # already an instance
-        return getattr(obj, '__call__', None) is not None
-
-    if six.PY3:
-        # *could* be broken by a class overriding __mro__ or __dict__ via
-        # a metaclass
-        for base in (obj,) + obj.__mro__:
-            if base.__dict__.get('__call__') is not None:
-                return True
-    else:
-        klass = obj
-        # uses __bases__ instead of __mro__ so that we work with old style classes
-        if klass.__dict__.get('__call__') is not None:
-            return True
-
-        for base in klass.__bases__:
-            if _instance_callable(base):
-                return True
-    return False
-
-
-def _set_signature(mock, original, instance=False):
-    # creates a function with signature (*args, **kwargs) that delegates to a
-    # mock. It still does signature checking by calling a lambda with the same
-    # signature as the original.
-
-    skipfirst = isinstance(original, ClassTypes)
-    result = _get_signature_object(original, instance, skipfirst)
-    if result is None:
-        return mock
-    func, sig = result
-    def checksig(*args, **kwargs):
-        sig.bind(*args, **kwargs)
-    _copy_func_details(func, checksig)
-
-    name = original.__name__
-    if not _isidentifier(name):
-        name = 'funcopy'
-    context = {'_checksig_': checksig, 'mock': mock}
-    src = """def %s(*args, **kwargs):
-    _checksig_(*args, **kwargs)
-    return mock(*args, **kwargs)""" % name
-    six.exec_(src, context)
-    funcopy = context[name]
-    _setup_func(funcopy, mock, sig)
-    return funcopy
-
-
-def _setup_func(funcopy, mock, sig):
-    funcopy.mock = mock
-
-    def assert_called(*args, **kwargs):
-        return mock.assert_called(*args, **kwargs)
-    def assert_not_called(*args, **kwargs):
-        return mock.assert_not_called(*args, **kwargs)
-    def assert_called_once(*args, **kwargs):
-        return mock.assert_called_once(*args, **kwargs)
-    def assert_called_with(*args, **kwargs):
-        return mock.assert_called_with(*args, **kwargs)
-    def assert_called_once_with(*args, **kwargs):
-        return mock.assert_called_once_with(*args, **kwargs)
-    def assert_has_calls(*args, **kwargs):
-        return mock.assert_has_calls(*args, **kwargs)
-    def assert_any_call(*args, **kwargs):
-        return mock.assert_any_call(*args, **kwargs)
-    def reset_mock():
-        funcopy.method_calls = _CallList()
-        funcopy.mock_calls = _CallList()
-        mock.reset_mock()
-        ret = funcopy.return_value
-        if _is_instance_mock(ret) and not ret is mock:
-            ret.reset_mock()
-
-    funcopy.called = False
-    funcopy.call_count = 0
-    funcopy.call_args = None
-    funcopy.call_args_list = _CallList()
-    funcopy.method_calls = _CallList()
-    funcopy.mock_calls = _CallList()
-
-    funcopy.return_value = mock.return_value
-    funcopy.side_effect = mock.side_effect
-    funcopy._mock_children = mock._mock_children
-
-    funcopy.assert_called_with = assert_called_with
-    funcopy.assert_called_once_with = assert_called_once_with
-    funcopy.assert_has_calls = assert_has_calls
-    funcopy.assert_any_call = assert_any_call
-    funcopy.reset_mock = reset_mock
-    funcopy.assert_called = assert_called
-    funcopy.assert_not_called = assert_not_called
-    funcopy.assert_called_once = assert_called_once
-    funcopy.__signature__ = sig
-
-    mock._mock_delegate = funcopy
-
-
-def _is_magic(name):
-    return '__%s__' % name[2:-2] == name
-
-
-class _SentinelObject(object):
-    "A unique, named, sentinel object."
-    def __init__(self, name):
-        self.name = name
-
-    def __repr__(self):
-        return 'sentinel.%s' % self.name
-
-    def __reduce__(self):
-        return _unpickle_sentinel, (self.name, )
-
-
-def _unpickle_sentinel(name):
-    return getattr(sentinel, name)
-
-
-class _Sentinel(object):
-    """Access attributes to return a named object, usable as a sentinel."""
-    def __init__(self):
-        self._sentinels = {}
-
-    def __getattr__(self, name):
-        if name == '__bases__':
-            # Without this help(unittest.mock) raises an exception
-            raise AttributeError
-        return self._sentinels.setdefault(name, _SentinelObject(name))
-
-
-sentinel = _Sentinel()
-
-DEFAULT = sentinel.DEFAULT
-_missing = sentinel.MISSING
-_deleted = sentinel.DELETED
-
-
-class OldStyleClass:
-    pass
-ClassType = type(OldStyleClass)
-
-
-ClassTypes = (type,)
-if six.PY2:
-    ClassTypes = (type, ClassType)
-
-_allowed_names = {
-    'return_value', '_mock_return_value', 'side_effect',
-    '_mock_side_effect', '_mock_parent', '_mock_new_parent',
-    '_mock_name', '_mock_new_name'
-}
-
-
-def _delegating_property(name):
-    _allowed_names.add(name)
-    _the_name = '_mock_' + name
-    def _get(self, name=name, _the_name=_the_name):
-        sig = self._mock_delegate
-        if sig is None:
-            return getattr(self, _the_name)
-        return getattr(sig, name)
-    def _set(self, value, name=name, _the_name=_the_name):
-        sig = self._mock_delegate
-        if sig is None:
-            self.__dict__[_the_name] = value
-        else:
-            setattr(sig, name, value)
-
-    return property(_get, _set)
-
-
-
-class _CallList(list):
-
-    def __contains__(self, value):
-        if not isinstance(value, list):
-            return list.__contains__(self, value)
-        len_value = len(value)
-        len_self = len(self)
-        if len_value > len_self:
-            return False
-
-        for i in range(0, len_self - len_value + 1):
-            sub_list = self[i:i+len_value]
-            if sub_list == value:
-                return True
-        return False
-
-    def __repr__(self):
-        return pprint.pformat(list(self))
-
-
-def _check_and_set_parent(parent, value, name, new_name):
-    # function passed to create_autospec will have mock
-    # attribute attached to which parent must be set
-    if isinstance(value, FunctionTypes):
-        try:
-            value = value.mock
-        except AttributeError:
-            pass
-
-    if not _is_instance_mock(value):
-        return False
-    if ((value._mock_name or value._mock_new_name) or
-        (value._mock_parent is not None) or
-        (value._mock_new_parent is not None)):
-        return False
-
-    _parent = parent
-    while _parent is not None:
-        # setting a mock (value) as a child or return value of itself
-        # should not modify the mock
-        if _parent is value:
-            return False
-        _parent = _parent._mock_new_parent
-
-    if new_name:
-        value._mock_new_parent = parent
-        value._mock_new_name = new_name
-    if name:
-        value._mock_parent = parent
-        value._mock_name = name
-    return True
-
-# Internal class to identify if we wrapped an iterator object or not.
-class _MockIter(object):
-    def __init__(self, obj):
-        self.obj = iter(obj)
-    def __next__(self):
-        return next(self.obj)
-
-class Base(object):
-    _mock_return_value = DEFAULT
-    _mock_side_effect = None
-    def __init__(self, *args, **kwargs):
-        pass
-
-
-
-class NonCallableMock(Base):
-    """A non-callable version of `Mock`"""
-
-    def __new__(cls, *args, **kw):
-        # every instance has its own class
-        # so we can create magic methods on the
-        # class without stomping on other mocks
-        new = type(cls.__name__, (cls,), {'__doc__': cls.__doc__})
-        instance = object.__new__(new)
-        return instance
-
-
-    def __init__(
-            self, spec=None, wraps=None, name=None, spec_set=None,
-            parent=None, _spec_state=None, _new_name='', _new_parent=None,
-            _spec_as_instance=False, _eat_self=None, unsafe=False, **kwargs
-        ):
-        if _new_parent is None:
-            _new_parent = parent
-
-        __dict__ = self.__dict__
-        __dict__['_mock_parent'] = parent
-        __dict__['_mock_name'] = name
-        __dict__['_mock_new_name'] = _new_name
-        __dict__['_mock_new_parent'] = _new_parent
-        __dict__['_mock_sealed'] = False
-
-        if spec_set is not None:
-            spec = spec_set
-            spec_set = True
-        if _eat_self is None:
-            _eat_self = parent is not None
-
-        self._mock_add_spec(spec, spec_set, _spec_as_instance, _eat_self)
-
-        __dict__['_mock_children'] = {}
-        __dict__['_mock_wraps'] = wraps
-        __dict__['_mock_delegate'] = None
-
-        __dict__['_mock_called'] = False
-        __dict__['_mock_call_args'] = None
-        __dict__['_mock_call_count'] = 0
-        __dict__['_mock_call_args_list'] = _CallList()
-        __dict__['_mock_mock_calls'] = _CallList()
-
-        __dict__['method_calls'] = _CallList()
-        __dict__['_mock_unsafe'] = unsafe
-
-        if kwargs:
-            self.configure_mock(**kwargs)
-
-        _safe_super(NonCallableMock, self).__init__(
-            spec, wraps, name, spec_set, parent,
-            _spec_state
-        )
-
-
-    def attach_mock(self, mock, attribute):
-        """
-        Attach a mock as an attribute of this one, replacing its name and
-        parent. Calls to the attached mock will be recorded in the
-        `method_calls` and `mock_calls` attributes of this one."""
-        mock._mock_parent = None
-        mock._mock_new_parent = None
-        mock._mock_name = ''
-        mock._mock_new_name = None
-
-        setattr(self, attribute, mock)
-
-
-    def mock_add_spec(self, spec, spec_set=False):
-        """Add a spec to a mock. `spec` can either be an object or a
-        list of strings. Only attributes on the `spec` can be fetched as
-        attributes from the mock.
-
-        If `spec_set` is True then only attributes on the spec can be set."""
-        self._mock_add_spec(spec, spec_set)
-
-
-    def _mock_add_spec(self, spec, spec_set, _spec_as_instance=False,
-                       _eat_self=False):
-        _spec_class = None
-        _spec_signature = None
-
-        if spec is not None and not _is_list(spec):
-            if isinstance(spec, ClassTypes):
-                _spec_class = spec
-            else:
-                _spec_class = type(spec)
-            res = _get_signature_object(spec,
-                                        _spec_as_instance, _eat_self)
-            _spec_signature = res and res[1]
-
-            spec = dir(spec)
-
-        __dict__ = self.__dict__
-        __dict__['_spec_class'] = _spec_class
-        __dict__['_spec_set'] = spec_set
-        __dict__['_spec_signature'] = _spec_signature
-        __dict__['_mock_methods'] = spec
-
-
-    def __get_return_value(self):
-        ret = self._mock_return_value
-        if self._mock_delegate is not None:
-            ret = self._mock_delegate.return_value
-
-        if ret is DEFAULT:
-            ret = self._get_child_mock(
-                _new_parent=self, _new_name='()'
-            )
-            self.return_value = ret
-        return ret
-
-
-    def __set_return_value(self, value):
-        if self._mock_delegate is not None:
-            self._mock_delegate.return_value = value
-        else:
-            self._mock_return_value = value
-            _check_and_set_parent(self, value, None, '()')
-
-    __return_value_doc = "The value to be returned when the mock is called."
-    return_value = property(__get_return_value, __set_return_value,
-                            __return_value_doc)
-
-
-    @property
-    def __class__(self):
-        if self._spec_class is None:
-            return type(self)
-        return self._spec_class
-
-    called = _delegating_property('called')
-    call_count = _delegating_property('call_count')
-    call_args = _delegating_property('call_args')
-    call_args_list = _delegating_property('call_args_list')
-    mock_calls = _delegating_property('mock_calls')
-
-
-    def __get_side_effect(self):
-        delegated = self._mock_delegate
-        if delegated is None:
-            return self._mock_side_effect
-        sf = delegated.side_effect
-        if (sf is not None and not callable(sf)
-                and not isinstance(sf, _MockIter) and not _is_exception(sf)):
-            sf = _MockIter(sf)
-            delegated.side_effect = sf
-        return sf
-
-    def __set_side_effect(self, value):
-        value = _try_iter(value)
-        delegated = self._mock_delegate
-        if delegated is None:
-            self._mock_side_effect = value
-        else:
-            delegated.side_effect = value
-
-    side_effect = property(__get_side_effect, __set_side_effect)
-
-
-    def reset_mock(self,  visited=None, return_value=False, side_effect=False):
-        "Restore the mock object to its initial state."
-        if visited is None:
-            visited = []
-        if id(self) in visited:
-            return
-        visited.append(id(self))
-
-        self.called = False
-        self.call_args = None
-        self.call_count = 0
-        self.mock_calls = _CallList()
-        self.call_args_list = _CallList()
-        self.method_calls = _CallList()
-
-        if return_value:
-            self._mock_return_value = DEFAULT
-        if side_effect:
-            self._mock_side_effect = None
-
-        for child in self._mock_children.values():
-            if isinstance(child, _SpecState) or child is _deleted:
-                continue
-            child.reset_mock(visited)
-
-        ret = self._mock_return_value
-        if _is_instance_mock(ret) and ret is not self:
-            ret.reset_mock(visited)
-
-
-    def configure_mock(self, **kwargs):
-        """Set attributes on the mock through keyword arguments.
-
-        Attributes plus return values and side effects can be set on child
-        mocks using standard dot notation and unpacking a dictionary in the
-        method call:
-
-        >>> attrs = {'method.return_value': 3, 'other.side_effect': KeyError}
-        >>> mock.configure_mock(**attrs)"""
-        for arg, val in sorted(kwargs.items(),
-                               # we sort on the number of dots so that
-                               # attributes are set before we set attributes on
-                               # attributes
-                               key=lambda entry: entry[0].count('.')):
-            args = arg.split('.')
-            final = args.pop()
-            obj = self
-            for entry in args:
-                obj = getattr(obj, entry)
-            setattr(obj, final, val)
-
-
-    def __getattr__(self, name):
-        if name in ('_mock_methods', '_mock_unsafe'):
-            raise AttributeError(name)
-        elif self._mock_methods is not None:
-            if name not in self._mock_methods or name in _all_magics:
-                raise AttributeError("Mock object has no attribute %r" % name)
-        elif _is_magic(name):
-            raise AttributeError(name)
-        if not self._mock_unsafe:
-            if name.startswith(('assert', 'assret')):
-                raise AttributeError(name)
-
-        result = self._mock_children.get(name)
-        if result is _deleted:
-            raise AttributeError(name)
-        elif result is None:
-            wraps = None
-            if self._mock_wraps is not None:
-                # XXXX should we get the attribute without triggering code
-                # execution?
-                wraps = getattr(self._mock_wraps, name)
-
-            result = self._get_child_mock(
-                parent=self, name=name, wraps=wraps, _new_name=name,
-                _new_parent=self
-            )
-            self._mock_children[name]  = result
-
-        elif isinstance(result, _SpecState):
-            result = create_autospec(
-                result.spec, result.spec_set, result.instance,
-                result.parent, result.name
-            )
-            self._mock_children[name]  = result
-
-        return result
-
-
-    def _extract_mock_name(self):
-        _name_list = [self._mock_new_name]
-        _parent = self._mock_new_parent
-        last = self
-
-        dot = '.'
-        if _name_list == ['()']:
-            dot = ''
-
-        while _parent is not None:
-            last = _parent
-
-            _name_list.append(_parent._mock_new_name + dot)
-            dot = '.'
-            if _parent._mock_new_name == '()':
-                dot = ''
-
-            _parent = _parent._mock_new_parent
-
-        _name_list = list(reversed(_name_list))
-        _first = last._mock_name or 'mock'
-        if len(_name_list) > 1:
-            if _name_list[1] not in ('()', '().'):
-                _first += '.'
-        _name_list[0] = _first
-        return ''.join(_name_list)
-
-    def __repr__(self):
-        name = self._extract_mock_name()
-
-        name_string = ''
-        if name not in ('mock', 'mock.'):
-            name_string = ' name=%r' % name
-
-        spec_string = ''
-        if self._spec_class is not None:
-            spec_string = ' spec=%r'
-            if self._spec_set:
-                spec_string = ' spec_set=%r'
-            spec_string = spec_string % self._spec_class.__name__
-        return "<{}{}{} id='{}'>".format(
-            type(self).__name__,
-            name_string,
-            spec_string,
-            id(self)
-        )
-
-
-    def __dir__(self):
-        """Filter the output of `dir(mock)` to only useful members."""
-        if not mock.FILTER_DIR and getattr(object, '__dir__', None):
-            # object.__dir__ is not in 2.7
-            return object.__dir__(self)
-
-        extras = self._mock_methods or []
-        from_type = dir(type(self))
-        from_dict = list(self.__dict__)
-        from_child_mocks = [
-            m_name for m_name, m_value in self._mock_children.items()
-            if m_value is not _deleted]
-
-        if mock.FILTER_DIR:
-            # object.__dir__ is not in 2.7
-            from_type = [e for e in from_type if not e.startswith('_')]
-            from_dict = [e for e in from_dict if not e.startswith('_') or
-                         _is_magic(e)]
-
-        return sorted(set(extras + from_type + from_dict + from_child_mocks))
-
-
-    def __setattr__(self, name, value):
-        if name in _allowed_names:
-            # property setters go through here
-            return object.__setattr__(self, name, value)
-        elif (self._spec_set and self._mock_methods is not None and
-            name not in self._mock_methods and
-            name not in self.__dict__):
-            raise AttributeError("Mock object has no attribute '%s'" % name)
-        elif name in _unsupported_magics:
-            msg = 'Attempting to set unsupported magic method %r.' % name
-            raise AttributeError(msg)
-        elif name in _all_magics:
-            if self._mock_methods is not None and name not in self._mock_methods:
-                raise AttributeError("Mock object has no attribute '%s'" % name)
-
-            if not _is_instance_mock(value):
-                setattr(type(self), name, _get_method(name, value))
-                original = value
-                value = lambda *args, **kw: original(self, *args, **kw)
-            else:
-                # only set _new_name and not name so that mock_calls is tracked
-                # but not method calls
-                _check_and_set_parent(self, value, None, name)
-                setattr(type(self), name, value)
-                self._mock_children[name] = value
-        elif name == '__class__':
-            self._spec_class = value
-            return
-        else:
-            if _check_and_set_parent(self, value, name, name):
-                self._mock_children[name] = value
-
-        if self._mock_sealed and not hasattr(self, name):
-            mock_name = self._extract_mock_name()+'.'+name
-            raise AttributeError('Cannot set '+mock_name)
-
-        return object.__setattr__(self, name, value)
-
-
-    def __delattr__(self, name):
-        if name in _all_magics and name in type(self).__dict__:
-            delattr(type(self), name)
-            if name not in self.__dict__:
-                # for magic methods that are still MagicProxy objects and
-                # not set on the instance itself
-                return
-
-        obj = self._mock_children.get(name, _missing)
-        if name in self.__dict__:
-            _safe_super(NonCallableMock, self).__delattr__(name)
-        elif obj is _deleted:
-            raise AttributeError(name)
-        if obj is not _missing:
-            del self._mock_children[name]
-        self._mock_children[name] = _deleted
-
-
-    def _format_mock_call_signature(self, args, kwargs):
-        name = self._mock_name or 'mock'
-        return _format_call_signature(name, args, kwargs)
-
-
-    def _format_mock_failure_message(self, args, kwargs):
-        message = 'expected call not found.\nExpected: %s\nActual: %s'
-        expected_string = self._format_mock_call_signature(args, kwargs)
-        call_args = self.call_args
-        actual_string = self._format_mock_call_signature(*call_args)
-        return message % (expected_string, actual_string)
-
-
-    def _call_matcher(self, _call):
-        """
-        Given a call (or simply an (args, kwargs) tuple), return a
-        comparison key suitable for matching with other calls.
-        This is a best effort method which relies on the spec's signature,
-        if available, or falls back on the arguments themselves.
-        """
-        sig = self._spec_signature
-        if sig is not None:
-            if len(_call) == 2:
-                name = ''
-                args, kwargs = _call
-            else:
-                name, args, kwargs = _call
-            try:
-                return name, sig.bind(*args, **kwargs)
-            except TypeError as e:
-                e.__traceback__ = None
-                return e
-        else:
-            return _call
-
-    def assert_not_called(_mock_self):
-        """assert that the mock was never called.
-        """
-        self = _mock_self
-        if self.call_count != 0:
-            msg = ("Expected '%s' to not have been called. Called %s times.%s"
-                   % (self._mock_name or 'mock',
-                      self.call_count,
-                      self._calls_repr()))
-            raise AssertionError(msg)
-
-    def assert_called(_mock_self):
-        """assert that the mock was called at least once
-        """
-        self = _mock_self
-        if self.call_count == 0:
-            msg = ("Expected '%s' to have been called." %
-                   self._mock_name or 'mock')
-            raise AssertionError(msg)
-
-    def assert_called_once(_mock_self):
-        """assert that the mock was called only once.
-        """
-        self = _mock_self
-        if not self.call_count == 1:
-            msg = ("Expected '%s' to have been called once. Called %s times.%s"
-                   % (self._mock_name or 'mock',
-                      self.call_count,
-                      self._calls_repr()))
-            raise AssertionError(msg)
-
-    def assert_called_with(_mock_self, *args, **kwargs):
-        """assert that the mock was called with the specified arguments.
-
-        Raises an AssertionError if the args and keyword args passed in are
-        different to the last call to the mock."""
-        self = _mock_self
-        if self.call_args is None:
-            expected = self._format_mock_call_signature(args, kwargs)
-            actual = 'not called.'
-            error_message = ('expected call not found.\nExpected: %s\nActual: %s'
-                             % (expected, actual))
-            raise AssertionError(error_message)
-
-        def _error_message(cause):
-            msg = self._format_mock_failure_message(args, kwargs)
-            if six.PY2 and cause is not None:
-                # Tack on some diagnostics for Python without __cause__
-                msg = '{}\n{}'.format(msg, str(cause))
-            return msg
-        expected = self._call_matcher((args, kwargs))
-        actual = self._call_matcher(self.call_args)
-        if expected != actual:
-            cause = expected if isinstance(expected, Exception) else None
-            six.raise_from(AssertionError(_error_message(cause)), cause)
-
-
-    def assert_called_once_with(_mock_self, *args, **kwargs):
-        """assert that the mock was called exactly once and that that call was
-        with the specified arguments."""
-        self = _mock_self
-        if not self.call_count == 1:
-            msg = ("Expected '%s' to be called once. Called %s times.%s"
-                   % (self._mock_name or 'mock',
-                      self.call_count,
-                      self._calls_repr()))
-            raise AssertionError(msg)
-        return self.assert_called_with(*args, **kwargs)
-
-
-    def assert_has_calls(self, calls, any_order=False):
-        """assert the mock has been called with the specified calls.
-        The `mock_calls` list is checked for the calls.
-
-        If `any_order` is False (the default) then the calls must be
-        sequential. There can be extra calls before or after the
-        specified calls.
-
-        If `any_order` is True then the calls can be in any order, but
-        they must all appear in `mock_calls`."""
-        expected = [self._call_matcher(c) for c in calls]
-        cause = expected if isinstance(expected, Exception) else None
-        all_calls = _CallList(self._call_matcher(c) for c in self.mock_calls)
-        if not any_order:
-            if expected not in all_calls:
-                six.raise_from(AssertionError(
-                    'Calls not found.\nExpected: %r%s'
-                    % (_CallList(calls), self._calls_repr(prefix="Actual"))
-                ), cause)
-            return
-
-        all_calls = list(all_calls)
-
-        not_found = []
-        for kall in expected:
-            try:
-                all_calls.remove(kall)
-            except ValueError:
-                not_found.append(kall)
-        if not_found:
-            six.raise_from(AssertionError(
-                '%r does not contain all of %r in its call list, '
-                'found %r instead' % (self._mock_name or 'mock',
-                                      tuple(not_found), all_calls)
-            ), cause)
-
-
-    def assert_any_call(self, *args, **kwargs):
-        """assert the mock has been called with the specified arguments.
-
-        The assert passes if the mock has *ever* been called, unlike
-        `assert_called_with` and `assert_called_once_with` that only pass if
-        the call is the most recent one."""
-        expected = self._call_matcher((args, kwargs))
-        actual = [self._call_matcher(c) for c in self.call_args_list]
-        if expected not in actual:
-            cause = expected if isinstance(expected, Exception) else None
-            expected_string = self._format_mock_call_signature(args, kwargs)
-            six.raise_from(AssertionError(
-                '%s call not found' % expected_string
-            ), cause)
-
-
-    def _get_child_mock(self, **kw):
-        """Create the child mocks for attributes and return value.
-        By default child mocks will be the same type as the parent.
-        Subclasses of Mock may want to override this to customize the way
-        child mocks are made.
-
-        For non-callable mocks the callable variant will be used (rather than
-        any custom subclass)."""
-        _type = type(self)
-        if not issubclass(_type, CallableMixin):
-            if issubclass(_type, NonCallableMagicMock):
-                klass = MagicMock
-            elif issubclass(_type, NonCallableMock) :
-                klass = Mock
-        else:
-            klass = _type.__mro__[1]
-
-        if self._mock_sealed:
-            attribute = "." + kw["name"] if "name" in kw else "()"
-            mock_name = self._extract_mock_name() + attribute
-            raise AttributeError(mock_name)
-
-        return klass(**kw)
-
-
-    def _calls_repr(self, prefix="Calls"):
-        """Renders self.mock_calls as a string.
-
-        Example: "\nCalls: [call(1), call(2)]."
-
-        If self.mock_calls is empty, an empty string is returned. The
-        output will be truncated if very long.
-        """
-        if not self.mock_calls:
-            return ""
-        return "\n"+prefix+": "+safe_repr(self.mock_calls)+"."
-
-
-
-def _try_iter(obj):
-    if obj is None:
-        return obj
-    if _is_exception(obj):
-        return obj
-    if _callable(obj):
-        return obj
-    try:
-        return iter(obj)
-    except TypeError:
-        # XXXX backwards compatibility
-        # but this will blow up on first call - so maybe we should fail early?
-        return obj
-
-
-
-class CallableMixin(Base):
-
-    def __init__(self, spec=None, side_effect=None, return_value=DEFAULT,
-                 wraps=None, name=None, spec_set=None, parent=None,
-                 _spec_state=None, _new_name='', _new_parent=None, **kwargs):
-        self.__dict__['_mock_return_value'] = return_value
-
-        _safe_super(CallableMixin, self).__init__(
-            spec, wraps, name, spec_set, parent,
-            _spec_state, _new_name, _new_parent, **kwargs
-        )
-
-        self.side_effect = side_effect
-
-
-    def _mock_check_sig(self, *args, **kwargs):
-        # stub method that can be replaced with one with a specific signature
-        pass
-
-
-    def __call__(_mock_self, *args, **kwargs):
-        # can't use self in-case a function / method we are mocking uses self
-        # in the signature
-        _mock_self._mock_check_sig(*args, **kwargs)
-        return _mock_self._mock_call(*args, **kwargs)
-
-
-    def _mock_call(_mock_self, *args, **kwargs):
-        self = _mock_self
-        self.called = True
-        self.call_count += 1
-
-        # handle call_args
-        _call = _Call((args, kwargs), two=True)
-        self.call_args = _call
-        self.call_args_list.append(_call)
-
-        # initial stuff for method_calls:
-        do_method_calls = self._mock_parent is not None
-        method_call_name = self._mock_name
-
-        # initial stuff for mock_calls:
-        mock_call_name = self._mock_new_name
-        is_a_call = mock_call_name == '()'
-        self.mock_calls.append(_Call(('', args, kwargs)))
-
-        # follow up the chain of mocks:
-        _new_parent = self._mock_new_parent
-        while _new_parent is not None:
-
-            # handle method_calls:
-            if do_method_calls:
-                _new_parent.method_calls.append(_Call((method_call_name, args, kwargs)))
-                do_method_calls = _new_parent._mock_parent is not None
-                if do_method_calls:
-                    method_call_name = _new_parent._mock_name + '.' + method_call_name
-
-            # handle mock_calls:
-            this_mock_call = _Call((mock_call_name, args, kwargs))
-            _new_parent.mock_calls.append(this_mock_call)
-
-            if _new_parent._mock_new_name:
-                if is_a_call:
-                    dot = ''
-                else:
-                    dot = '.'
-                is_a_call = _new_parent._mock_new_name == '()'
-                mock_call_name = _new_parent._mock_new_name + dot + mock_call_name
-
-            # follow the parental chain:
-            _new_parent = _new_parent._mock_new_parent
-
-        effect = self.side_effect
-        if effect is not None:
-            if _is_exception(effect):
-                raise effect
-            elif not _callable(effect):
-                result = next(effect)
-                if _is_exception(result):
-                    raise result
-            else:
-                result = effect(*args, **kwargs)
-
-            if result is not DEFAULT:
-                return result
-
-        if self._mock_return_value is not DEFAULT:
-            return self.return_value
-
-        if self._mock_wraps is not None:
-            return self._mock_wraps(*args, **kwargs)
-
-        return self.return_value
-
-
-
-class Mock(CallableMixin, NonCallableMock):
-    """
-    Create a new `Mock` object. `Mock` takes several optional arguments
-    that specify the behaviour of the Mock object:
-
-    * `spec`: This can be either a list of strings or an existing object (a
-      class or instance) that acts as the specification for the mock object. If
-      you pass in an object then a list of strings is formed by calling dir on
-      the object (excluding unsupported magic attributes and methods). Accessing
-      any attribute not in this list will raise an `AttributeError`.
-
-      If `spec` is an object (rather than a list of strings) then
-      `mock.__class__` returns the class of the spec object. This allows mocks
-      to pass `isinstance` tests.
-
-    * `spec_set`: A stricter variant of `spec`. If used, attempting to *set*
-      or get an attribute on the mock that isn't on the object passed as
-      `spec_set` will raise an `AttributeError`.
-
-    * `side_effect`: A function to be called whenever the Mock is called. See
-      the `side_effect` attribute. Useful for raising exceptions or
-      dynamically changing return values. The function is called with the same
-      arguments as the mock, and unless it returns `DEFAULT`, the return
-      value of this function is used as the return value.
-
-      Alternatively `side_effect` can be an exception class or instance. In
-      this case the exception will be raised when the mock is called.
-
-      If `side_effect` is an iterable then each call to the mock will return
-      the next value from the iterable. If any of the members of the iterable
-      are exceptions they will be raised instead of returned.
-
-    * `return_value`: The value returned when the mock is called. By default
-      this is a new Mock (created on first access). See the
-      `return_value` attribute.
-
-    * `wraps`: Item for the mock object to wrap. If `wraps` is not None then
-      calling the Mock will pass the call through to the wrapped object
-      (returning the real result). Attribute access on the mock will return a
-      Mock object that wraps the corresponding attribute of the wrapped object
-      (so attempting to access an attribute that doesn't exist will raise an
-      `AttributeError`).
-
-      If the mock has an explicit `return_value` set then calls are not passed
-      to the wrapped object and the `return_value` is returned instead.
-
-    * `name`: If the mock has a name then it will be used in the repr of the
-      mock. This can be useful for debugging. The name is propagated to child
-      mocks.
-
-    Mocks can also be called with arbitrary keyword arguments. These will be
-    used to set attributes on the mock after it is created.
-    """
-
-
-
-def _dot_lookup(thing, comp, import_path):
-    try:
-        return getattr(thing, comp)
-    except AttributeError:
-        __import__(import_path)
-        return getattr(thing, comp)
-
-
-def _importer(target):
-    components = target.split('.')
-    import_path = components.pop(0)
-    thing = __import__(import_path)
-
-    for comp in components:
-        import_path += ".%s" % comp
-        thing = _dot_lookup(thing, comp, import_path)
-    return thing
-
-
-def _is_started(patcher):
-    # XXXX horrible
-    return hasattr(patcher, 'is_local')
-
-
-class _patch(object):
-
-    attribute_name = None
-    _active_patches = []
-
-    def __init__(
-            self, getter, attribute, new, spec, create,
-            spec_set, autospec, new_callable, kwargs
-        ):
-        if new_callable is not None:
-            if new is not DEFAULT:
-                raise ValueError(
-                    "Cannot use 'new' and 'new_callable' together"
-                )
-            if autospec is not None:
-                raise ValueError(
-                    "Cannot use 'autospec' and 'new_callable' together"
-                )
-
-        self.getter = getter
-        self.attribute = attribute
-        self.new = new
-        self.new_callable = new_callable
-        self.spec = spec
-        self.create = create
-        self.has_local = False
-        self.spec_set = spec_set
-        self.autospec = autospec
-        self.kwargs = kwargs
-        self.additional_patchers = []
-
-
-    def copy(self):
-        patcher = _patch(
-            self.getter, self.attribute, self.new, self.spec,
-            self.create, self.spec_set,
-            self.autospec, self.new_callable, self.kwargs
-        )
-        patcher.attribute_name = self.attribute_name
-        patcher.additional_patchers = [
-            p.copy() for p in self.additional_patchers
-        ]
-        return patcher
-
-
-    def __call__(self, func):
-        if isinstance(func, ClassTypes):
-            return self.decorate_class(func)
-        return self.decorate_callable(func)
-
-
-    def decorate_class(self, klass):
-        for attr in dir(klass):
-            if not attr.startswith(patch.TEST_PREFIX):
-                continue
-
-            attr_value = getattr(klass, attr)
-            if not hasattr(attr_value, "__call__"):
-                continue
-
-            patcher = self.copy()
-            setattr(klass, attr, patcher(attr_value))
-        return klass
-
-
-    def decorate_callable(self, func):
-        if hasattr(func, 'patchings'):
-            func.patchings.append(self)
-            return func
-
-        @wraps(func)
-        def patched(*args, **keywargs):
-            extra_args = []
-            entered_patchers = []
-
-            exc_info = tuple()
-            try:
-                for patching in patched.patchings:
-                    arg = patching.__enter__()
-                    entered_patchers.append(patching)
-                    if patching.attribute_name is not None:
-                        keywargs.update(arg)
-                    elif patching.new is DEFAULT:
-                        extra_args.append(arg)
-
-                args += tuple(extra_args)
-                return func(*args, **keywargs)
-            except:
-                if (patching not in entered_patchers and
-                    _is_started(patching)):
-                    # the patcher may have been started, but an exception
-                    # raised whilst entering one of its additional_patchers
-                    entered_patchers.append(patching)
-                # Pass the exception to __exit__
-                exc_info = sys.exc_info()
-                # re-raise the exception
-                raise
-            finally:
-                for patching in reversed(entered_patchers):
-                    patching.__exit__(*exc_info)
-
-        patched.patchings = [self]
-        return patched
-
-
-    def get_original(self):
-        target = self.getter()
-        name = self.attribute
-
-        original = DEFAULT
-        local = False
-
-        try:
-            original = target.__dict__[name]
-        except (AttributeError, KeyError):
-            original = getattr(target, name, DEFAULT)
-        else:
-            local = True
-
-        if name in _builtins and isinstance(target, ModuleType):
-            self.create = True
-
-        if not self.create and original is DEFAULT:
-            raise AttributeError(
-                "{} does not have the attribute {!r}".format(target, name)
-            )
-        return original, local
-
-
-    def __enter__(self):
-        """Perform the patch."""
-        new, spec, spec_set = self.new, self.spec, self.spec_set
-        autospec, kwargs = self.autospec, self.kwargs
-        new_callable = self.new_callable
-        self.target = self.getter()
-
-        # normalise False to None
-        if spec is False:
-            spec = None
-        if spec_set is False:
-            spec_set = None
-        if autospec is False:
-            autospec = None
-
-        if spec is not None and autospec is not None:
-            raise TypeError("Can't specify spec and autospec")
-        if ((spec is not None or autospec is not None) and
-            spec_set not in (True, None)):
-            raise TypeError("Can't provide explicit spec_set *and* spec or autospec")
-
-        original, local = self.get_original()
-
-        if new is DEFAULT and autospec is None:
-            inherit = False
-            if spec is True:
-                # set spec to the object we are replacing
-                spec = original
-                if spec_set is True:
-                    spec_set = original
-                    spec = None
-            elif spec is not None:
-                if spec_set is True:
-                    spec_set = spec
-                    spec = None
-            elif spec_set is True:
-                spec_set = original
-
-            if spec is not None or spec_set is not None:
-                if original is DEFAULT:
-                    raise TypeError("Can't use 'spec' with create=True")
-                if isinstance(original, ClassTypes):
-                    # If we're patching out a class and there is a spec
-                    inherit = True
-
-            Klass = MagicMock
-            _kwargs = {}
-            if new_callable is not None:
-                Klass = new_callable
-            elif spec is not None or spec_set is not None:
-                this_spec = spec
-                if spec_set is not None:
-                    this_spec = spec_set
-                if _is_list(this_spec):
-                    not_callable = '__call__' not in this_spec
-                else:
-                    not_callable = not _callable(this_spec)
-                if not_callable:
-                    Klass = NonCallableMagicMock
-
-            if spec is not None:
-                _kwargs['spec'] = spec
-            if spec_set is not None:
-                _kwargs['spec_set'] = spec_set
-
-            # add a name to mocks
-            if (isinstance(Klass, type) and
-                issubclass(Klass, NonCallableMock) and self.attribute):
-                _kwargs['name'] = self.attribute
-
-            _kwargs.update(kwargs)
-            new = Klass(**_kwargs)
-
-            if inherit and _is_instance_mock(new):
-                # we can only tell if the instance should be callable if the
-                # spec is not a list
-                this_spec = spec
-                if spec_set is not None:
-                    this_spec = spec_set
-                if (not _is_list(this_spec) and not
-                    _instance_callable(this_spec)):
-                    Klass = NonCallableMagicMock
-
-                _kwargs.pop('name')
-                new.return_value = Klass(_new_parent=new, _new_name='()',
-                                         **_kwargs)
-        elif autospec is not None:
-            # spec is ignored, new *must* be default, spec_set is treated
-            # as a boolean. Should we check spec is not None and that spec_set
-            # is a bool?
-            if new is not DEFAULT:
-                raise TypeError(
-                    "autospec creates the mock for you. Can't specify "
-                    "autospec and new."
-                )
-            if original is DEFAULT:
-                raise TypeError("Can't use 'autospec' with create=True")
-            spec_set = bool(spec_set)
-            if autospec is True:
-                autospec = original
-
-            new = create_autospec(autospec, spec_set=spec_set,
-                                  _name=self.attribute, **kwargs)
-        elif kwargs:
-            # can't set keyword args when we aren't creating the mock
-            # XXXX If new is a Mock we could call new.configure_mock(**kwargs)
-            raise TypeError("Can't pass kwargs to a mock we aren't creating")
-
-        new_attr = new
-
-        self.temp_original = original
-        self.is_local = local
-        setattr(self.target, self.attribute, new_attr)
-        if self.attribute_name is not None:
-            extra_args = {}
-            if self.new is DEFAULT:
-                extra_args[self.attribute_name] =  new
-            for patching in self.additional_patchers:
-                arg = patching.__enter__()
-                if patching.new is DEFAULT:
-                    extra_args.update(arg)
-            return extra_args
-
-        return new
-
-
-    def __exit__(self, *exc_info):
-        """Undo the patch."""
-        if not _is_started(self):
-            return
-
-        if self.is_local and self.temp_original is not DEFAULT:
-            setattr(self.target, self.attribute, self.temp_original)
-        else:
-            delattr(self.target, self.attribute)
-            if not self.create and (not hasattr(self.target, self.attribute) or
-                        self.attribute in ('__doc__', '__module__',
-                                           '__defaults__', '__annotations__',
-                                           '__kwdefaults__')):
-                # needed for proxy objects like django settings
-                setattr(self.target, self.attribute, self.temp_original)
-
-        del self.temp_original
-        del self.is_local
-        del self.target
-        for patcher in reversed(self.additional_patchers):
-            if _is_started(patcher):
-                patcher.__exit__(*exc_info)
-
-
-    def start(self):
-        """Activate a patch, returning any created mock."""
-        result = self.__enter__()
-        self._active_patches.append(self)
-        return result
-
-
-    def stop(self):
-        """Stop an active patch."""
-        try:
-            self._active_patches.remove(self)
-        except ValueError:
-            # If the patch hasn't been started this will fail
-            pass
-
-        return self.__exit__()
-
-
-
-def _get_target(target):
-    try:
-        target, attribute = target.rsplit('.', 1)
-    except (TypeError, ValueError):
-        raise TypeError("Need a valid target to patch. You supplied: %r" %
-                        (target,))
-    getter = lambda: _importer(target)
-    return getter, attribute
-
-
-def _patch_object(
-        target, attribute, new=DEFAULT, spec=None,
-        create=False, spec_set=None, autospec=None,
-        new_callable=None, **kwargs
-    ):
-    """
-    patch the named member (`attribute`) on an object (`target`) with a mock
-    object.
-
-    `patch.object` can be used as a decorator, class decorator or a context
-    manager. Arguments `new`, `spec`, `create`, `spec_set`,
-    `autospec` and `new_callable` have the same meaning as for `patch`. Like
-    `patch`, `patch.object` takes arbitrary keyword arguments for configuring
-    the mock object it creates.
-
-    When used as a class decorator `patch.object` honours `patch.TEST_PREFIX`
-    for choosing which methods to wrap.
-    """
-    getter = lambda: target
-    return _patch(
-        getter, attribute, new, spec, create,
-        spec_set, autospec, new_callable, kwargs
-    )
-
-
-def _patch_multiple(target, spec=None, create=False, spec_set=None,
-                    autospec=None, new_callable=None, **kwargs):
-    """Perform multiple patches in a single call. It takes the object to be
-    patched (either as an object or a string to fetch the object by importing)
-    and keyword arguments for the patches::
-
-        with patch.multiple(settings, FIRST_PATCH='one', SECOND_PATCH='two'):
-            ...
-
-    Use `DEFAULT` as the value if you want `patch.multiple` to create
-    mocks for you. In this case the created mocks are passed into a decorated
-    function by keyword, and a dictionary is returned when `patch.multiple` is
-    used as a context manager.
-
-    `patch.multiple` can be used as a decorator, class decorator or a context
-    manager. The arguments `spec`, `spec_set`, `create`,
-    `autospec` and `new_callable` have the same meaning as for `patch`. These
-    arguments will be applied to *all* patches done by `patch.multiple`.
-
-    When used as a class decorator `patch.multiple` honours `patch.TEST_PREFIX`
-    for choosing which methods to wrap.
-    """
-    if type(target) in (unicode, str):
-        getter = lambda: _importer(target)
-    else:
-        getter = lambda: target
-
-    if not kwargs:
-        raise ValueError(
-            'Must supply at least one keyword argument with patch.multiple'
-        )
-    # need to wrap in a list for python 3, where items is a view
-    items = list(kwargs.items())
-    attribute, new = items[0]
-    patcher = _patch(
-        getter, attribute, new, spec, create, spec_set,
-        autospec, new_callable, {}
-    )
-    patcher.attribute_name = attribute
-    for attribute, new in items[1:]:
-        this_patcher = _patch(
-            getter, attribute, new, spec, create, spec_set,
-            autospec, new_callable, {}
-        )
-        this_patcher.attribute_name = attribute
-        patcher.additional_patchers.append(this_patcher)
-    return patcher
-
-
-def patch(
-        target, new=DEFAULT, spec=None, create=False,
-        spec_set=None, autospec=None, new_callable=None, **kwargs
-    ):
-    """
-    `patch` acts as a function decorator, class decorator or a context
-    manager. Inside the body of the function or with statement, the `target`
-    is patched with a `new` object. When the function/with statement exits
-    the patch is undone.
-
-    If `new` is omitted, then the target is replaced with a
-    `MagicMock`. If `patch` is used as a decorator and `new` is
-    omitted, the created mock is passed in as an extra argument to the
-    decorated function. If `patch` is used as a context manager the created
-    mock is returned by the context manager.
-
-    `target` should be a string in the form `'package.module.ClassName'`. The
-    `target` is imported and the specified object replaced with the `new`
-    object, so the `target` must be importable from the environment you are
-    calling `patch` from. The target is imported when the decorated function
-    is executed, not at decoration time.
-
-    The `spec` and `spec_set` keyword arguments are passed to the `MagicMock`
-    if patch is creating one for you.
-
-    In addition you can pass `spec=True` or `spec_set=True`, which causes
-    patch to pass in the object being mocked as the spec/spec_set object.
-
-    `new_callable` allows you to specify a different class, or callable object,
-    that will be called to create the `new` object. By default `MagicMock` is
-    used.
-
-    A more powerful form of `spec` is `autospec`. If you set `autospec=True`
-    then the mock will be created with a spec from the object being replaced.
-    All attributes of the mock will also have the spec of the corresponding
-    attribute of the object being replaced. Methods and functions being
-    mocked will have their arguments checked and will raise a `TypeError` if
-    they are called with the wrong signature. For mocks replacing a class,
-    their return value (the 'instance') will have the same spec as the class.
-
-    Instead of `autospec=True` you can pass `autospec=some_object` to use an
-    arbitrary object as the spec instead of the one being replaced.
-
-    By default `patch` will fail to replace attributes that don't exist. If
-    you pass in `create=True`, and the attribute doesn't exist, patch will
-    create the attribute for you when the patched function is called, and
-    delete it again afterwards. This is useful for writing tests against
-    attributes that your production code creates at runtime. It is off by
-    default because it can be dangerous. With it switched on you can write
-    passing tests against APIs that don't actually exist!
-
-    Patch can be used as a `TestCase` class decorator. It works by
-    decorating each test method in the class. This reduces the boilerplate
-    code when your test methods share a common patchings set. `patch` finds
-    tests by looking for method names that start with `patch.TEST_PREFIX`.
-    By default this is `test`, which matches the way `unittest` finds tests.
-    You can specify an alternative prefix by setting `patch.TEST_PREFIX`.
-
-    Patch can be used as a context manager, with the with statement. Here the
-    patching applies to the indented block after the with statement. If you
-    use "as" then the patched object will be bound to the name after the
-    "as"; very useful if `patch` is creating a mock object for you.
-
-    `patch` takes arbitrary keyword arguments. These will be passed to
-    the `Mock` (or `new_callable`) on construction.
-
-    `patch.dict(...)`, `patch.multiple(...)` and `patch.object(...)` are
-    available for alternate use-cases.
-    """
-    getter, attribute = _get_target(target)
-    return _patch(
-        getter, attribute, new, spec, create,
-        spec_set, autospec, new_callable, kwargs
-    )
-
-
-class _patch_dict(object):
-    """
-    Patch a dictionary, or dictionary like object, and restore the dictionary
-    to its original state after the test.
-
-    `in_dict` can be a dictionary or a mapping like container. If it is a
-    mapping then it must at least support getting, setting and deleting items
-    plus iterating over keys.
-
-    `in_dict` can also be a string specifying the name of the dictionary, which
-    will then be fetched by importing it.
-
-    `values` can be a dictionary of values to set in the dictionary. `values`
-    can also be an iterable of `(key, value)` pairs.
-
-    If `clear` is True then the dictionary will be cleared before the new
-    values are set.
-
-    `patch.dict` can also be called with arbitrary keyword arguments to set
-    values in the dictionary::
-
-        with patch.dict('sys.modules', mymodule=Mock(), other_module=Mock()):
-            ...
-
-    `patch.dict` can be used as a context manager, decorator or class
-    decorator. When used as a class decorator `patch.dict` honours
-    `patch.TEST_PREFIX` for choosing which methods to wrap.
-    """
-
-    def __init__(self, in_dict, values=(), clear=False, **kwargs):
-        self.in_dict = in_dict
-        # support any argument supported by dict(...) constructor
-        self.values = dict(values)
-        self.values.update(kwargs)
-        self.clear = clear
-        self._original = None
-
-
-    def __call__(self, f):
-        if isinstance(f, ClassTypes):
-            return self.decorate_class(f)
-        @wraps(f)
-        def _inner(*args, **kw):
-            self._patch_dict()
-            try:
-                return f(*args, **kw)
-            finally:
-                self._unpatch_dict()
-
-        return _inner
-
-
-    def decorate_class(self, klass):
-        for attr in dir(klass):
-            attr_value = getattr(klass, attr)
-            if (attr.startswith(patch.TEST_PREFIX) and
-                 hasattr(attr_value, "__call__")):
-                decorator = _patch_dict(self.in_dict, self.values, self.clear)
-                decorated = decorator(attr_value)
-                setattr(klass, attr, decorated)
-        return klass
-
-
-    def __enter__(self):
-        """Patch the dict."""
-        self._patch_dict()
-
-
-    def _patch_dict(self):
-        values = self.values
-        if isinstance(self.in_dict, basestring):
-            self.in_dict = _importer(self.in_dict)
-        in_dict = self.in_dict
-        clear = self.clear
-
-        try:
-            original = in_dict.copy()
-        except AttributeError:
-            # dict like object with no copy method
-            # must support iteration over keys
-            original = {}
-            for key in in_dict:
-                original[key] = in_dict[key]
-        self._original = original
-
-        if clear:
-            _clear_dict(in_dict)
-
-        try:
-            in_dict.update(values)
-        except AttributeError:
-            # dict like object with no update method
-            for key in values:
-                in_dict[key] = values[key]
-
-
-    def _unpatch_dict(self):
-        in_dict = self.in_dict
-        original = self._original
-
-        _clear_dict(in_dict)
-
-        try:
-            in_dict.update(original)
-        except AttributeError:
-            for key in original:
-                in_dict[key] = original[key]
-
-
-    def __exit__(self, *args):
-        """Unpatch the dict."""
-        self._unpatch_dict()
-        return False
-
-    start = __enter__
-    stop = __exit__
-
-
-def _clear_dict(in_dict):
-    try:
-        in_dict.clear()
-    except AttributeError:
-        keys = list(in_dict)
-        for key in keys:
-            del in_dict[key]
-
-
-def _patch_stopall():
-    """Stop all active patches. LIFO to unroll nested patches."""
-    for patch in reversed(_patch._active_patches):
-        patch.stop()
-
-
-patch.object = _patch_object
-patch.dict = _patch_dict
-patch.multiple = _patch_multiple
-patch.stopall = _patch_stopall
-patch.TEST_PREFIX = 'test'
-
-magic_methods = (
-    "lt le gt ge eq ne "
-    "getitem setitem delitem "
-    "len contains iter "
-    "hash str sizeof "
-    "enter exit "
-    # we added divmod and rdivmod here instead of numerics
-    # because there is no idivmod
-    "divmod rdivmod neg pos abs invert "
-    "complex int float index "
-    "round trunc floor ceil "
-)
-
-numerics = (
-    "add sub mul matmul div floordiv mod lshift rshift and xor or pow"
-)
-if six.PY3:
-    numerics += ' truediv'
-inplace = ' '.join('i%s' % n for n in numerics.split())
-right = ' '.join('r%s' % n for n in numerics.split())
-extra = ''
-if six.PY3:
-    extra = 'bool next '
-    if sys.version_info >= (3, 6):
-        extra += 'fspath '
-else:
-    extra = 'unicode long nonzero oct hex truediv rtruediv '
-
-# not including __prepare__, __instancecheck__, __subclasscheck__
-# (as they are metaclass methods)
-# __del__ is not supported at all as it causes problems if it exists
-
-_non_defaults = {
-    '__cmp__', '__getslice__', '__setslice__', '__coerce__', # <3.x
-    '__get__', '__set__', '__delete__', '__reversed__', '__missing__',
-    '__reduce__', '__reduce_ex__', '__getinitargs__', '__getnewargs__',
-    '__getstate__', '__setstate__', '__getformat__', '__setformat__',
-    '__repr__', '__dir__', '__subclasses__', '__format__',
-    '__getnewargs_ex__',
-}
-
-
-def _get_method(name, func):
-    "Turns a callable object (like a mock) into a real function"
-    def method(self, *args, **kw):
-        return func(self, *args, **kw)
-    method.__name__ = name
-    return method
-
-
-_magics = {
-    '__%s__' % method for method in
-    ' '.join([magic_methods, numerics, inplace, right, extra]).split()
-}
-
-_all_magics = _magics | _non_defaults
-
-_unsupported_magics = {
-    '__getattr__', '__setattr__',
-    '__init__', '__new__', '__prepare__',
-    '__instancecheck__', '__subclasscheck__',
-    '__del__'
-}
-
-_calculate_return_value = {
-    '__hash__': lambda self: object.__hash__(self),
-    '__str__': lambda self: object.__str__(self),
-    '__sizeof__': lambda self: object.__sizeof__(self),
-    '__unicode__': lambda self: unicode(object.__str__(self)),
-    '__fspath__': lambda self: type(self).__name__+'/'+self._extract_mock_name()+'/'+str(id(self)),
-}
-
-_return_values = {
-    '__lt__': NotImplemented,
-    '__gt__': NotImplemented,
-    '__le__': NotImplemented,
-    '__ge__': NotImplemented,
-    '__int__': 1,
-    '__contains__': False,
-    '__len__': 0,
-    '__exit__': False,
-    '__complex__': 1j,
-    '__float__': 1.0,
-    '__bool__': True,
-    '__nonzero__': True,
-    '__oct__': '1',
-    '__hex__': '0x1',
-    '__long__': long(1),
-    '__index__': 1,
-}
-
-
-def _get_eq(self):
-    def __eq__(other):
-        ret_val = self.__eq__._mock_return_value
-        if ret_val is not DEFAULT:
-            return ret_val
-        if self is other:
-            return True
-        return NotImplemented
-    return __eq__
-
-def _get_ne(self):
-    def __ne__(other):
-        if self.__ne__._mock_return_value is not DEFAULT:
-            return DEFAULT
-        if self is other:
-            return False
-        return NotImplemented
-    return __ne__
-
-def _get_iter(self):
-    def __iter__():
-        ret_val = self.__iter__._mock_return_value
-        if ret_val is DEFAULT:
-            return iter([])
-        # if ret_val was already an iterator, then calling iter on it should
-        # return the iterator unchanged
-        return iter(ret_val)
-    return __iter__
-
-_side_effect_methods = {
-    '__eq__': _get_eq,
-    '__ne__': _get_ne,
-    '__iter__': _get_iter,
-}
-
-
-
-def _set_return_value(mock, method, name):
-    fixed = _return_values.get(name, DEFAULT)
-    if fixed is not DEFAULT:
-        method.return_value = fixed
-        return
-
-    return_calulator = _calculate_return_value.get(name)
-    if return_calulator is not None:
-        try:
-            return_value = return_calulator(mock)
-        except AttributeError:
-            # XXXX why do we return AttributeError here?
-            #      set it as a side_effect instead?
-            # Answer: it makes magic mocks work on pypy?!
-            return_value = AttributeError(name)
-        method.return_value = return_value
-        return
-
-    side_effector = _side_effect_methods.get(name)
-    if side_effector is not None:
-        method.side_effect = side_effector(mock)
-
-
-
-class MagicMixin(object):
-    def __init__(self, *args, **kw):
-        self._mock_set_magics()  # make magic work for kwargs in init
-        _safe_super(MagicMixin, self).__init__(*args, **kw)
-        self._mock_set_magics()  # fix magic broken by upper level init
-
-
-    def _mock_set_magics(self):
-        these_magics = _magics
-
-        if getattr(self, "_mock_methods", None) is not None:
-            these_magics = _magics.intersection(self._mock_methods)
-
-            remove_magics = set()
-            remove_magics = _magics - these_magics
-
-            for entry in remove_magics:
-                if entry in type(self).__dict__:
-                    # remove unneeded magic methods
-                    delattr(self, entry)
-
-        # don't overwrite existing attributes if called a second time
-        these_magics = these_magics - set(type(self).__dict__)
-
-        _type = type(self)
-        for entry in these_magics:
-            setattr(_type, entry, MagicProxy(entry, self))
-
-
-
-class NonCallableMagicMock(MagicMixin, NonCallableMock):
-    """A version of `MagicMock` that isn't callable."""
-    def mock_add_spec(self, spec, spec_set=False):
-        """Add a spec to a mock. `spec` can either be an object or a
-        list of strings. Only attributes on the `spec` can be fetched as
-        attributes from the mock.
-
-        If `spec_set` is True then only attributes on the spec can be set."""
-        self._mock_add_spec(spec, spec_set)
-        self._mock_set_magics()
-
-
-
-class MagicMock(MagicMixin, Mock):
-    """
-    MagicMock is a subclass of Mock with default implementations
-    of most of the magic methods. You can use MagicMock without having to
-    configure the magic methods yourself.
-
-    If you use the `spec` or `spec_set` arguments then *only* magic
-    methods that exist in the spec will be created.
-
-    Attributes and the return value of a `MagicMock` will also be `MagicMocks`.
-    """
-    def mock_add_spec(self, spec, spec_set=False):
-        """Add a spec to a mock. `spec` can either be an object or a
-        list of strings. Only attributes on the `spec` can be fetched as
-        attributes from the mock.
-
-        If `spec_set` is True then only attributes on the spec can be set."""
-        self._mock_add_spec(spec, spec_set)
-        self._mock_set_magics()
-
-
-
-class MagicProxy(object):
-    def __init__(self, name, parent):
-        self.name = name
-        self.parent = parent
-
-    def create_mock(self):
-        entry = self.name
-        parent = self.parent
-        m = parent._get_child_mock(name=entry, _new_name=entry,
-                                   _new_parent=parent)
-        setattr(parent, entry, m)
-        _set_return_value(parent, m, entry)
-        return m
-
-    def __get__(self, obj, _type=None):
-        return self.create_mock()
-
-
-
-class _ANY(object):
-    "A helper object that compares equal to everything."
-
-    def __eq__(self, other):
-        return True
-
-    def __ne__(self, other):
-        return False
-
-    def __repr__(self):
-        return '<ANY>'
-
-    __hash__ = None
-
-ANY = _ANY()
-
-
-
-def _format_call_signature(name, args, kwargs):
-    message = '%s(%%s)' % name
-    formatted_args = ''
-    args_string = ', '.join([repr(arg) for arg in args])
-
-    def encode_item(item):
-        if six.PY2 and isinstance(item, unicode):
-            return item.encode("utf-8")
-        else:
-            return item
-
-    kwargs_string = ', '.join([
-        '{}={!r}'.format(encode_item(key), value) for key, value in sorted(kwargs.items())
-    ])
-    if args_string:
-        formatted_args = args_string
-    if kwargs_string:
-        if formatted_args:
-            formatted_args += ', '
-        formatted_args += kwargs_string
-
-    return message % formatted_args
-
-
-
-class _Call(tuple):
-    """
-    A tuple for holding the results of a call to a mock, either in the form
-    `(args, kwargs)` or `(name, args, kwargs)`.
-
-    If args or kwargs are empty then a call tuple will compare equal to
-    a tuple without those values. This makes comparisons less verbose::
-
-        _Call(('name', (), {})) == ('name',)
-        _Call(('name', (1,), {})) == ('name', (1,))
-        _Call(((), {'a': 'b'})) == ({'a': 'b'},)
-
-    The `_Call` object provides a useful shortcut for comparing with call::
-
-        _Call(((1, 2), {'a': 3})) == call(1, 2, a=3)
-        _Call(('foo', (1, 2), {'a': 3})) == call.foo(1, 2, a=3)
-
-    If the _Call has no name then it will match any name.
-    """
-    def __new__(cls, value=(), name='', parent=None, two=False,
-                from_kall=True):
-        args = ()
-        kwargs = {}
-        _len = len(value)
-        if _len == 3:
-            name, args, kwargs = value
-        elif _len == 2:
-            first, second = value
-            if isinstance(first, basestring):
-                name = first
-                if isinstance(second, tuple):
-                    args = second
-                else:
-                    kwargs = second
-            else:
-                args, kwargs = first, second
-        elif _len == 1:
-            value, = value
-            if isinstance(value, basestring):
-                name = value
-            elif isinstance(value, tuple):
-                args = value
-            else:
-                kwargs = value
-
-        if two:
-            return tuple.__new__(cls, (args, kwargs))
-
-        return tuple.__new__(cls, (name, args, kwargs))
-
-
-    def __init__(self, value=(), name=None, parent=None, two=False,
-                 from_kall=True):
-        self._mock_name = name
-        self._mock_parent = parent
-        self._mock_from_kall = from_kall
-
-
-    def __eq__(self, other):
-        if other is ANY:
-            return True
-        try:
-            len_other = len(other)
-        except TypeError:
-            return False
-
-        self_name = ''
-        if len(self) == 2:
-            self_args, self_kwargs = self
-        else:
-            self_name, self_args, self_kwargs = self
-
-        if (getattr(self, '_mock_parent', None) and getattr(other, '_mock_parent', None)
-                and self._mock_parent != other._mock_parent):
-            return False
-
-        other_name = ''
-        if len_other == 0:
-            other_args, other_kwargs = (), {}
-        elif len_other == 3:
-            other_name, other_args, other_kwargs = other
-        elif len_other == 1:
-            value, = other
-            if isinstance(value, tuple):
-                other_args = value
-                other_kwargs = {}
-            elif isinstance(value, basestring):
-                other_name = value
-                other_args, other_kwargs = (), {}
-            else:
-                other_args = ()
-                other_kwargs = value
-        elif len_other == 2:
-            # could be (name, args) or (name, kwargs) or (args, kwargs)
-            first, second = other
-            if isinstance(first, basestring):
-                other_name = first
-                if isinstance(second, tuple):
-                    other_args, other_kwargs = second, {}
-                else:
-                    other_args, other_kwargs = (), second
-            else:
-                other_args, other_kwargs = first, second
-        else:
-            return False
-
-        if self_name and other_name != self_name:
-            return False
-
-        # this order is important for ANY to work!
-        return (other_args, other_kwargs) == (self_args, self_kwargs)
-
-
-    def __ne__(self, other):
-        return not self.__eq__(other)
-
-    __hash__ = None
-
-    def __call__(self, *args, **kwargs):
-        if self._mock_name is None:
-            return _Call(('', args, kwargs), name='()')
-
-        name = self._mock_name + '()'
-        return _Call((self._mock_name, args, kwargs), name=name, parent=self)
-
-
-    def __getattr__(self, attr):
-        if self._mock_name is None:
-            return _Call(name=attr, from_kall=False)
-        name = '{}.{}'.format(self._mock_name, attr)
-        return _Call(name=name, parent=self, from_kall=False)
-
-
-    def count(self, *args, **kwargs):
-        return self.__getattr__('count')(*args, **kwargs)
-
-    def index(self, *args, **kwargs):
-        return self.__getattr__('index')(*args, **kwargs)
-
-    def _get_call_arguments(self):
-        if len(self) == 2:
-            args, kwargs = self
-        else:
-            name, args, kwargs = self
-
-        return args, kwargs
-
-    @property
-    def args(self):
-        return self._get_call_arguments()[0]
-
-    @property
-    def kwargs(self):
-        return self._get_call_arguments()[1]
-
-    def __repr__(self):
-        if not self._mock_from_kall:
-            name = self._mock_name or 'call'
-            if name.startswith('()'):
-                name = 'call%s' % name
-            return name
-
-        if len(self) == 2:
-            name = 'call'
-            args, kwargs = self
-        else:
-            name, args, kwargs = self
-            if not name:
-                name = 'call'
-            elif not name.startswith('()'):
-                name = 'call.%s' % name
-            else:
-                name = 'call%s' % name
-        return _format_call_signature(name, args, kwargs)
-
-
-    def call_list(self):
-        """For a call object that represents multiple calls, `call_list`
-        returns a list of all the intermediate calls as well as the
-        final call."""
-        vals = []
-        thing = self
-        while thing is not None:
-            if thing._mock_from_kall:
-                vals.append(thing)
-            thing = thing._mock_parent
-        return _CallList(reversed(vals))
-
-
-call = _Call(from_kall=False)
-
-
-
-def create_autospec(spec, spec_set=False, instance=False, _parent=None,
-                    _name=None, **kwargs):
-    """Create a mock object using another object as a spec. Attributes on the
-    mock will use the corresponding attribute on the `spec` object as their
-    spec.
-
-    Functions or methods being mocked will have their arguments checked
-    to check that they are called with the correct signature.
-
-    If `spec_set` is True then attempting to set attributes that don't exist
-    on the spec object will raise an `AttributeError`.
-
-    If a class is used as a spec then the return value of the mock (the
-    instance of the class) will have the same spec. You can use a class as the
-    spec for an instance object by passing `instance=True`. The returned mock
-    will only be callable if instances of the mock are callable.
-
-    `create_autospec` also takes arbitrary keyword arguments that are passed to
-    the constructor of the created mock."""
-    if _is_list(spec):
-        # can't pass a list instance to the mock constructor as it will be
-        # interpreted as a list of strings
-        spec = type(spec)
-
-    is_type = isinstance(spec, ClassTypes)
-
-    _kwargs = {'spec': spec}
-    if spec_set:
-        _kwargs = {'spec_set': spec}
-    elif spec is None:
-        # None we mock with a normal mock without a spec
-        _kwargs = {}
-    if _kwargs and instance:
-        _kwargs['_spec_as_instance'] = True
-
-    _kwargs.update(kwargs)
-
-    Klass = MagicMock
-    if inspect.isdatadescriptor(spec):
-        # descriptors don't have a spec
-        # because we don't know what type they return
-        _kwargs = {}
-    elif not _callable(spec):
-        Klass = NonCallableMagicMock
-    elif is_type and instance and not _instance_callable(spec):
-        Klass = NonCallableMagicMock
-
-    _name = _kwargs.pop('name', _name)
-
-    _new_name = _name
-    if _parent is None:
-        # for a top level object no _new_name should be set
-        _new_name = ''
-
-    mock = Klass(parent=_parent, _new_parent=_parent, _new_name=_new_name,
-                 name=_name, **_kwargs)
-
-    if isinstance(spec, FunctionTypes):
-        # should only happen at the top level because we don't
-        # recurse for functions
-        mock = _set_signature(mock, spec)
-    else:
-        _check_signature(spec, mock, is_type, instance)
-
-    if _parent is not None and not instance:
-        _parent._mock_children[_name] = mock
-
-    if is_type and not instance and 'return_value' not in kwargs:
-        mock.return_value = create_autospec(spec, spec_set, instance=True,
-                                            _name='()', _parent=mock)
-
-    for entry in dir(spec):
-
-        # This are __ and so treated as magic on Py3, on Py2 we need to
-        # explicitly ignore them:
-        if six.PY2 and (entry.startswith('im_') or entry.startswith('func_')):
-            continue
-
-        if _is_magic(entry):
-            # MagicMock already does the useful magic methods for us
-            continue
-
-        # XXXX do we need a better way of getting attributes without
-        # triggering code execution (?) Probably not - we need the actual
-        # object to mock it so we would rather trigger a property than mock
-        # the property descriptor. Likewise we want to mock out dynamically
-        # provided attributes.
-        # XXXX what about attributes that raise exceptions other than
-        # AttributeError on being fetched?
-        # we could be resilient against it, or catch and propagate the
-        # exception when the attribute is fetched from the mock
-        try:
-            original = getattr(spec, entry)
-        except AttributeError:
-            continue
-
-        kwargs = {'spec': original}
-        if spec_set:
-            kwargs = {'spec_set': original}
-
-        if not isinstance(original, FunctionTypes):
-            new = _SpecState(original, spec_set, mock, entry, instance)
-            mock._mock_children[entry] = new
-        else:
-            parent = mock
-            if isinstance(spec, FunctionTypes):
-                parent = mock.mock
-
-            skipfirst = _must_skip(spec, entry, is_type)
-            kwargs['_eat_self'] = skipfirst
-            new = MagicMock(parent=parent, name=entry, _new_name=entry,
-                            _new_parent=parent,
-                            **kwargs)
-            mock._mock_children[entry] = new
-            _check_signature(original, new, skipfirst=skipfirst)
-
-        # so functions created with _set_signature become instance attributes,
-        # *plus* their underlying mock exists in _mock_children of the parent
-        # mock. Adding to _mock_children may be unnecessary where we are also
-        # setting as an instance attribute?
-        if isinstance(new, FunctionTypes):
-            setattr(mock, entry, new)
-
-    return mock
-
-
-def _must_skip(spec, entry, is_type):
-    """
-    Return whether we should skip the first argument on spec's `entry`
-    attribute.
-    """
-    if not isinstance(spec, ClassTypes):
-        if entry in getattr(spec, '__dict__', {}):
-            # instance attribute - shouldn't skip
-            return False
-        spec = spec.__class__
-    if not hasattr(spec, '__mro__'):
-        # old style class: can't have descriptors anyway
-        return is_type
-
-    for klass in spec.__mro__:
-        result = klass.__dict__.get(entry, DEFAULT)
-        if result is DEFAULT:
-            continue
-        if isinstance(result, (staticmethod, classmethod)):
-            return False
-        elif isinstance(getattr(result, '__get__', None), MethodWrapperTypes):
-            # Normal method => skip if looked up on type
-            # (if looked up on instance, self is already skipped)
-            return is_type
-        else:
-            return False
-
-    # function is a dynamically provided attribute
-    return is_type
-
-
-class _SpecState(object):
-
-    def __init__(self, spec, spec_set=False, parent=None,
-                 name=None, ids=None, instance=False):
-        self.spec = spec
-        self.ids = ids
-        self.spec_set = spec_set
-        self.parent = parent
-        self.instance = instance
-        self.name = name
-
-
-FunctionTypes = (
-    # python function
-    type(create_autospec),
-    # instance method
-    type(ANY.__eq__),
-)
-
-MethodWrapperTypes = (
-    type(ANY.__eq__.__get__),
-)
-
-
-file_spec = None
-
-
-def _to_stream(read_data):
-    if isinstance(read_data, bytes):
-        return io.BytesIO(read_data)
-    else:
-        return io.StringIO(read_data)
-
-
-def mock_open(mock=None, read_data=''):
-    """
-    A helper function to create a mock to replace the use of `open`. It works
-    for `open` called directly or used as a context manager.
-
-    The `mock` argument is the mock object to configure. If `None` (the
-    default) then a `MagicMock` will be created for you, with the API limited
-    to methods or attributes available on standard file handles.
-
-    `read_data` is a string for the `read`, `readline` and `readlines` of the
-    file handle to return.  This is an empty string by default.
-    """
-    _read_data = _to_stream(read_data)
-    _state = [_read_data, None]
-
-    def _readlines_side_effect(*args, **kwargs):
-        if handle.readlines.return_value is not None:
-            return handle.readlines.return_value
-        return _state[0].readlines(*args, **kwargs)
-
-    def _read_side_effect(*args, **kwargs):
-        if handle.read.return_value is not None:
-            return handle.read.return_value
-        return _state[0].read(*args, **kwargs)
-
-    def  _readline_side_effect(*args, **kwargs):
-        for item in _iter_side_effect():
-            yield item
-        while True:
-            yield _state[0].readline(*args, **kwargs)
-
-    def _iter_side_effect():
-        if handle.readline.return_value is not None:
-            while True:
-                yield handle.readline.return_value
-        for line in _state[0]:
-            yield line
-
-    global file_spec
-    if file_spec is None:
-        # set on first use
-        if six.PY3:
-            import _io
-            file_spec = list(set(dir(_io.TextIOWrapper)).union(set(dir(_io.BytesIO))))
-        else:
-            file_spec = file
-
-    if mock is None:
-        mock = MagicMock(name='open', spec=open)
-
-    handle = MagicMock(spec=file_spec)
-    handle.__enter__.return_value = handle
-
-    handle.write.return_value = None
-    handle.read.return_value = None
-    handle.readline.return_value = None
-    handle.readlines.return_value = None
-
-    handle.read.side_effect = _read_side_effect
-    _state[1] = _readline_side_effect()
-    handle.readline.side_effect = _state[1]
-    handle.readlines.side_effect = _readlines_side_effect
-    handle.__iter__.side_effect = _iter_side_effect
-
-    def reset_data(*args, **kwargs):
-        _state[0] = _to_stream(read_data)
-        if handle.readline.side_effect == _state[1]:
-            # Only reset the side effect if the user hasn't overridden it.
-            _state[1] = _readline_side_effect()
-            handle.readline.side_effect = _state[1]
-        return DEFAULT
-
-    mock.side_effect = reset_data
-    mock.return_value = handle
-    return mock
-
-
-class PropertyMock(Mock):
-    """
-    A mock intended to be used as a property, or other descriptor, on a class.
-    `PropertyMock` provides `__get__` and `__set__` methods so you can specify
-    a return value when it is fetched.
-
-    Fetching a `PropertyMock` instance from an object calls the mock, with
-    no args. Setting it calls the mock with the value being set.
-    """
-    def _get_child_mock(self, **kwargs):
-        return MagicMock(**kwargs)
-
-    def __get__(self, obj, obj_type):
-        return self()
-    def __set__(self, obj, val):
-        self(val)
-
-
-def seal(mock):
-    """Disable the automatic generation of child mocks.
-
-    Given an input Mock, seals it to ensure no further mocks will be generated
-    when accessing an attribute that was not already defined.
-
-    The operation recursively seals the mock passed in, meaning that
-    the mock itself, any mocks generated by accessing one of its attributes,
-    and all assigned mocks without a name or spec will be sealed.
-    """
-    mock._mock_sealed = True
-    for attr in dir(mock):
-        try:
-            m = getattr(mock, attr)
-        except AttributeError:
-            continue
-        if not isinstance(m, NonCallableMock):
-            continue
-        if m._mock_new_parent is mock:
-            seal(m)
diff --git a/mock/tests/__init__.py b/mock/tests/__init__.py
deleted file mode 100644
index 54ddf2e..0000000
--- a/mock/tests/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright (C) 2007-2012 Michael Foord & the mock team
-# E-mail: fuzzyman AT voidspace DOT org DOT uk
-# http://www.voidspace.org.uk/python/mock/
diff --git a/mock/tests/__main__.py b/mock/tests/__main__.py
deleted file mode 100644
index 45c633a..0000000
--- a/mock/tests/__main__.py
+++ /dev/null
@@ -1,18 +0,0 @@
-import os
-import unittest
-
-
-def load_tests(loader, standard_tests, pattern):
-    # top level directory cached on loader instance
-    this_dir = os.path.dirname(__file__)
-    pattern = pattern or "test*.py"
-    # We are inside unittest.test.testmock, so the top-level is three notches up
-    top_level_dir = os.path.dirname(os.path.dirname(os.path.dirname(this_dir)))
-    package_tests = loader.discover(start_dir=this_dir, pattern=pattern,
-                                    top_level_dir=top_level_dir)
-    standard_tests.addTests(package_tests)
-    return standard_tests
-
-
-if __name__ == '__main__':
-    unittest.main()
diff --git a/mock/tests/conftest.py b/mock/tests/conftest.py
deleted file mode 100644
index 78831f6..0000000
--- a/mock/tests/conftest.py
+++ /dev/null
@@ -1,6 +0,0 @@
-import six
-
-
-def pytest_ignore_collect(path):
-    if 'py3' in path.basename and six.PY2:
-        return True
diff --git a/mock/tests/support.py b/mock/tests/support.py
deleted file mode 100644
index d57a372..0000000
--- a/mock/tests/support.py
+++ /dev/null
@@ -1,46 +0,0 @@
-import contextlib
-import sys
-
-
-target = {'foo': 'FOO'}
-
-
-def is_instance(obj, klass):
-    """Version of is_instance that doesn't access __class__"""
-    return issubclass(type(obj), klass)
-
-
-class SomeClass(object):
-    class_attribute = None
-
-    def wibble(self): pass
-
-
-class X(object):
-    pass
-
-
-@contextlib.contextmanager
-def uncache(*names):
-    """Uncache a module from sys.modules.
-
-    A basic sanity check is performed to prevent uncaching modules that either
-    cannot/shouldn't be uncached.
-
-    """
-    for name in names:
-        if name in ('sys', 'marshal', 'imp'):
-            raise ValueError(
-                "cannot uncache {0}".format(name))
-        try:
-            del sys.modules[name]
-        except KeyError:
-            pass
-    try:
-        yield
-    finally:
-        for name in names:
-            try:
-                del sys.modules[name]
-            except KeyError:
-                pass
diff --git a/mock/tests/testcallable.py b/mock/tests/testcallable.py
deleted file mode 100644
index 729947e..0000000
--- a/mock/tests/testcallable.py
+++ /dev/null
@@ -1,156 +0,0 @@
-# Copyright (C) 2007-2012 Michael Foord & the mock team
-# E-mail: fuzzyman AT voidspace DOT org DOT uk
-# http://www.voidspace.org.uk/python/mock/
-
-import unittest
-from mock.tests.support import is_instance, X, SomeClass
-
-from mock import (
-    Mock, MagicMock, NonCallableMagicMock,
-    NonCallableMock, patch, create_autospec,
-    CallableMixin
-)
-
-
-
-class TestCallable(unittest.TestCase):
-
-    def assertNotCallable(self, mock):
-        self.assertTrue(is_instance(mock, NonCallableMagicMock))
-        self.assertFalse(is_instance(mock, CallableMixin))
-
-
-    def test_non_callable(self):
-        for mock in NonCallableMagicMock(), NonCallableMock():
-            self.assertRaises(TypeError, mock)
-            self.assertFalse(hasattr(mock, '__call__'))
-            self.assertIn(mock.__class__.__name__, repr(mock))
-
-
-    def test_hierarchy(self):
-        self.assertTrue(issubclass(MagicMock, Mock))
-        self.assertTrue(issubclass(NonCallableMagicMock, NonCallableMock))
-
-
-    def test_attributes(self):
-        one = NonCallableMock()
-        self.assertTrue(issubclass(type(one.one), Mock))
-
-        two = NonCallableMagicMock()
-        self.assertTrue(issubclass(type(two.two), MagicMock))
-
-
-    def test_subclasses(self):
-        class MockSub(Mock):
-            pass
-
-        one = MockSub()
-        self.assertTrue(issubclass(type(one.one), MockSub))
-
-        class MagicSub(MagicMock):
-            pass
-
-        two = MagicSub()
-        self.assertTrue(issubclass(type(two.two), MagicSub))
-
-
-    def test_patch_spec(self):
-        patcher = patch('%s.X' % __name__, spec=True)
-        mock = patcher.start()
-        self.addCleanup(patcher.stop)
-
-        instance = mock()
-        mock.assert_called_once_with()
-
-        self.assertNotCallable(instance)
-        self.assertRaises(TypeError, instance)
-
-
-    def test_patch_spec_set(self):
-        patcher = patch('%s.X' % __name__, spec_set=True)
-        mock = patcher.start()
-        self.addCleanup(patcher.stop)
-
-        instance = mock()
-        mock.assert_called_once_with()
-
-        self.assertNotCallable(instance)
-        self.assertRaises(TypeError, instance)
-
-
-    def test_patch_spec_instance(self):
-        patcher = patch('%s.X' % __name__, spec=X())
-        mock = patcher.start()
-        self.addCleanup(patcher.stop)
-
-        self.assertNotCallable(mock)
-        self.assertRaises(TypeError, mock)
-
-
-    def test_patch_spec_set_instance(self):
-        patcher = patch('%s.X' % __name__, spec_set=X())
-        mock = patcher.start()
-        self.addCleanup(patcher.stop)
-
-        self.assertNotCallable(mock)
-        self.assertRaises(TypeError, mock)
-
-
-    def test_patch_spec_callable_class(self):
-        class CallableX(X):
-            def __call__(self): pass
-
-        class Sub(CallableX):
-            pass
-
-        class Multi(SomeClass, Sub):
-            pass
-
-        class OldStyle:
-            def __call__(self): pass
-
-        class OldStyleSub(OldStyle):
-            pass
-
-        for arg in 'spec', 'spec_set':
-            for Klass in CallableX, Sub, Multi, OldStyle, OldStyleSub:
-                with patch('%s.X' % __name__, **{arg: Klass}) as mock:
-                    instance = mock()
-                    mock.assert_called_once_with()
-
-                    self.assertTrue(is_instance(instance, MagicMock))
-                    # inherited spec
-                    self.assertRaises(AttributeError, getattr, instance,
-                                      'foobarbaz')
-
-                    result = instance()
-                    # instance is callable, result has no spec
-                    instance.assert_called_once_with()
-
-                    result(3, 2, 1)
-                    result.assert_called_once_with(3, 2, 1)
-                    result.foo(3, 2, 1)
-                    result.foo.assert_called_once_with(3, 2, 1)
-
-
-    def test_create_autospec(self):
-        mock = create_autospec(X)
-        instance = mock()
-        self.assertRaises(TypeError, instance)
-
-        mock = create_autospec(X())
-        self.assertRaises(TypeError, mock)
-
-
-    def test_create_autospec_instance(self):
-        mock = create_autospec(SomeClass, instance=True)
-
-        self.assertRaises(TypeError, mock)
-        mock.wibble()
-        mock.wibble.assert_called_once_with()
-
-        self.assertRaises(TypeError, mock.wibble, 'some',  'args')
-
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/mock/tests/testhelpers.py b/mock/tests/testhelpers.py
deleted file mode 100644
index d56a47f..0000000
--- a/mock/tests/testhelpers.py
+++ /dev/null
@@ -1,1187 +0,0 @@
-# Copyright (C) 2007-2012 Michael Foord & the mock team
-# E-mail: fuzzyman AT voidspace DOT org DOT uk
-# http://www.voidspace.org.uk/python/mock/
-import socket
-
-import inspect
-import six
-import sys
-import time
-import unittest
-
-from mock import (
-    call, create_autospec, MagicMock,
-    Mock, ANY, patch, PropertyMock
-)
-from mock.mock import _Call, _CallList, _callable
-
-from datetime import datetime
-from functools import partial
-
-
-if six.PY2:
-    import funcsigs
-
-
-class SomeClass(object):
-    def one(self, a, b): pass
-    def two(self): pass
-    def three(self, a=None): pass
-
-
-
-class AnyTest(unittest.TestCase):
-
-    def test_any(self):
-        self.assertEqual(ANY, object())
-
-        mock = Mock()
-        mock(ANY)
-        mock.assert_called_with(ANY)
-
-        mock = Mock()
-        mock(foo=ANY)
-        mock.assert_called_with(foo=ANY)
-
-    def test_repr(self):
-        self.assertEqual(repr(ANY), '<ANY>')
-        self.assertEqual(str(ANY), '<ANY>')
-
-
-    def test_any_and_datetime(self):
-        mock = Mock()
-        mock(datetime.now(), foo=datetime.now())
-
-        mock.assert_called_with(ANY, foo=ANY)
-
-
-    def test_any_mock_calls_comparison_order(self):
-        mock = Mock()
-        class Foo(object):
-            def __eq__(self, other): pass
-            def __ne__(self, other): pass
-
-        for d in datetime.now(), Foo():
-            mock.reset_mock()
-
-            mock(d, foo=d, bar=d)
-            mock.method(d, zinga=d, alpha=d)
-            mock().method(a1=d, z99=d)
-
-            expected = [
-                call(ANY, foo=ANY, bar=ANY),
-                call.method(ANY, zinga=ANY, alpha=ANY),
-                call(), call().method(a1=ANY, z99=ANY)
-            ]
-            self.assertEqual(expected, mock.mock_calls)
-            self.assertEqual(mock.mock_calls, expected)
-
-
-
-class CallTest(unittest.TestCase):
-
-    def test_call_with_call(self):
-        kall = _Call()
-        self.assertEqual(kall, _Call())
-        self.assertEqual(kall, _Call(('',)))
-        self.assertEqual(kall, _Call(((),)))
-        self.assertEqual(kall, _Call(({},)))
-        self.assertEqual(kall, _Call(('', ())))
-        self.assertEqual(kall, _Call(('', {})))
-        self.assertEqual(kall, _Call(('', (), {})))
-        self.assertEqual(kall, _Call(('foo',)))
-        self.assertEqual(kall, _Call(('bar', ())))
-        self.assertEqual(kall, _Call(('baz', {})))
-        self.assertEqual(kall, _Call(('spam', (), {})))
-
-        kall = _Call(((1, 2, 3),))
-        self.assertEqual(kall, _Call(((1, 2, 3),)))
-        self.assertEqual(kall, _Call(('', (1, 2, 3))))
-        self.assertEqual(kall, _Call(((1, 2, 3), {})))
-        self.assertEqual(kall, _Call(('', (1, 2, 3), {})))
-
-        kall = _Call(((1, 2, 4),))
-        self.assertNotEqual(kall, _Call(('', (1, 2, 3))))
-        self.assertNotEqual(kall, _Call(('', (1, 2, 3), {})))
-
-        kall = _Call(('foo', (1, 2, 4),))
-        self.assertNotEqual(kall, _Call(('', (1, 2, 4))))
-        self.assertNotEqual(kall, _Call(('', (1, 2, 4), {})))
-        self.assertNotEqual(kall, _Call(('bar', (1, 2, 4))))
-        self.assertNotEqual(kall, _Call(('bar', (1, 2, 4), {})))
-
-        kall = _Call(({'a': 3},))
-        self.assertEqual(kall, _Call(('', (), {'a': 3})))
-        self.assertEqual(kall, _Call(('', {'a': 3})))
-        self.assertEqual(kall, _Call(((), {'a': 3})))
-        self.assertEqual(kall, _Call(({'a': 3},)))
-
-
-    def test_empty__Call(self):
-        args = _Call()
-
-        self.assertEqual(args, ())
-        self.assertEqual(args, ('foo',))
-        self.assertEqual(args, ((),))
-        self.assertEqual(args, ('foo', ()))
-        self.assertEqual(args, ('foo',(), {}))
-        self.assertEqual(args, ('foo', {}))
-        self.assertEqual(args, ({},))
-
-
-    def test_named_empty_call(self):
-        args = _Call(('foo', (), {}))
-
-        self.assertEqual(args, ('foo',))
-        self.assertEqual(args, ('foo', ()))
-        self.assertEqual(args, ('foo',(), {}))
-        self.assertEqual(args, ('foo', {}))
-
-        self.assertNotEqual(args, ((),))
-        self.assertNotEqual(args, ())
-        self.assertNotEqual(args, ({},))
-        self.assertNotEqual(args, ('bar',))
-        self.assertNotEqual(args, ('bar', ()))
-        self.assertNotEqual(args, ('bar', {}))
-
-
-    def test_call_with_args(self):
-        args = _Call(((1, 2, 3), {}))
-
-        self.assertEqual(args, ((1, 2, 3),))
-        self.assertEqual(args, ('foo', (1, 2, 3)))
-        self.assertEqual(args, ('foo', (1, 2, 3), {}))
-        self.assertEqual(args, ((1, 2, 3), {}))
-        self.assertEqual(args.args, (1, 2, 3))
-        self.assertEqual(args.kwargs, {})
-
-
-    def test_named_call_with_args(self):
-        args = _Call(('foo', (1, 2, 3), {}))
-
-        self.assertEqual(args, ('foo', (1, 2, 3)))
-        self.assertEqual(args, ('foo', (1, 2, 3), {}))
-        self.assertEqual(args.args, (1, 2, 3))
-        self.assertEqual(args.kwargs, {})
-
-        self.assertNotEqual(args, ((1, 2, 3),))
-        self.assertNotEqual(args, ((1, 2, 3), {}))
-
-
-    def test_call_with_kwargs(self):
-        args = _Call(((), dict(a=3, b=4)))
-
-        self.assertEqual(args, (dict(a=3, b=4),))
-        self.assertEqual(args, ('foo', dict(a=3, b=4)))
-        self.assertEqual(args, ('foo', (), dict(a=3, b=4)))
-        self.assertEqual(args, ((), dict(a=3, b=4)))
-        self.assertEqual(args.args, ())
-        self.assertEqual(args.kwargs, dict(a=3, b=4))
-
-
-    def test_named_call_with_kwargs(self):
-        args = _Call(('foo', (), dict(a=3, b=4)))
-
-        self.assertEqual(args, ('foo', dict(a=3, b=4)))
-        self.assertEqual(args, ('foo', (), dict(a=3, b=4)))
-        self.assertEqual(args.args, ())
-        self.assertEqual(args.kwargs, dict(a=3, b=4))
-
-        self.assertNotEqual(args, (dict(a=3, b=4),))
-        self.assertNotEqual(args, ((), dict(a=3, b=4)))
-
-
-    def test_call_with_args_call_empty_name(self):
-        args = _Call(((1, 2, 3), {}))
-
-        self.assertEqual(args, call(1, 2, 3))
-        self.assertEqual(call(1, 2, 3), args)
-        self.assertIn(call(1, 2, 3), [args])
-
-
-    def test_call_ne(self):
-        self.assertNotEqual(_Call(((1, 2, 3),)), call(1, 2))
-        self.assertFalse(_Call(((1, 2, 3),)) != call(1, 2, 3))
-        self.assertTrue(_Call(((1, 2), {})) != call(1, 2, 3))
-
-
-    def test_call_non_tuples(self):
-        kall = _Call(((1, 2, 3),))
-        for value in 1, None, self, int:
-            self.assertNotEqual(kall, value)
-            self.assertFalse(kall == value)
-
-
-    def test_repr(self):
-        self.assertEqual(repr(_Call()), 'call()')
-        self.assertEqual(repr(_Call(('foo',))), 'call.foo()')
-
-        self.assertEqual(repr(_Call(((1, 2, 3), {'a': 'b'}))),
-                         "call(1, 2, 3, a='b')")
-        self.assertEqual(repr(_Call(('bar', (1, 2, 3), {'a': 'b'}))),
-                         "call.bar(1, 2, 3, a='b')")
-
-        self.assertEqual(repr(call), 'call')
-        self.assertEqual(str(call), 'call')
-
-        self.assertEqual(repr(call()), 'call()')
-        self.assertEqual(repr(call(1)), 'call(1)')
-        self.assertEqual(repr(call(zz='thing')), "call(zz='thing')")
-
-        self.assertEqual(repr(call().foo), 'call().foo')
-        self.assertEqual(repr(call(1).foo.bar(a=3).bing),
-                         'call().foo.bar().bing')
-        self.assertEqual(
-            repr(call().foo(1, 2, a=3)),
-            "call().foo(1, 2, a=3)"
-        )
-        self.assertEqual(repr(call()()), "call()()")
-        self.assertEqual(repr(call(1)(2)), "call()(2)")
-        self.assertEqual(
-            repr(call()().bar().baz.beep(1)),
-            "call()().bar().baz.beep(1)"
-        )
-
-
-    def test_call(self):
-        self.assertEqual(call(), ('', (), {}))
-        self.assertEqual(call('foo', 'bar', one=3, two=4),
-                         ('', ('foo', 'bar'), {'one': 3, 'two': 4}))
-
-        mock = Mock()
-        mock(1, 2, 3)
-        mock(a=3, b=6)
-        self.assertEqual(mock.call_args_list,
-                         [call(1, 2, 3), call(a=3, b=6)])
-
-    def test_attribute_call(self):
-        self.assertEqual(call.foo(1), ('foo', (1,), {}))
-        self.assertEqual(call.bar.baz(fish='eggs'),
-                         ('bar.baz', (), {'fish': 'eggs'}))
-
-        mock = Mock()
-        mock.foo(1, 2 ,3)
-        mock.bar.baz(a=3, b=6)
-        self.assertEqual(mock.method_calls,
-                         [call.foo(1, 2, 3), call.bar.baz(a=3, b=6)])
-
-
-    def test_extended_call(self):
-        result = call(1).foo(2).bar(3, a=4)
-        self.assertEqual(result, ('().foo().bar', (3,), dict(a=4)))
-
-        mock = MagicMock()
-        mock(1, 2, a=3, b=4)
-        self.assertEqual(mock.call_args, call(1, 2, a=3, b=4))
-        self.assertNotEqual(mock.call_args, call(1, 2, 3))
-
-        self.assertEqual(mock.call_args_list, [call(1, 2, a=3, b=4)])
-        self.assertEqual(mock.mock_calls, [call(1, 2, a=3, b=4)])
-
-        mock = MagicMock()
-        mock.foo(1).bar()().baz.beep(a=6)
-
-        last_call = call.foo(1).bar()().baz.beep(a=6)
-        self.assertEqual(mock.mock_calls[-1], last_call)
-        self.assertEqual(mock.mock_calls, last_call.call_list())
-
-
-    def test_extended_not_equal(self):
-        a = call(x=1).foo
-        b = call(x=2).foo
-        self.assertEqual(a, a)
-        self.assertEqual(b, b)
-        self.assertNotEqual(a, b)
-
-
-    def test_nested_calls_not_equal(self):
-        a = call(x=1).foo().bar
-        b = call(x=2).foo().bar
-        self.assertEqual(a, a)
-        self.assertEqual(b, b)
-        self.assertNotEqual(a, b)
-
-
-    def test_call_list(self):
-        mock = MagicMock()
-        mock(1)
-        self.assertEqual(call(1).call_list(), mock.mock_calls)
-
-        mock = MagicMock()
-        mock(1).method(2)
-        self.assertEqual(call(1).method(2).call_list(),
-                         mock.mock_calls)
-
-        mock = MagicMock()
-        mock(1).method(2)(3)
-        self.assertEqual(call(1).method(2)(3).call_list(),
-                         mock.mock_calls)
-
-        mock = MagicMock()
-        int(mock(1).method(2)(3).foo.bar.baz(4)(5))
-        kall = call(1).method(2)(3).foo.bar.baz(4)(5).__int__()
-        self.assertEqual(kall.call_list(), mock.mock_calls)
-
-
-    def test_call_any(self):
-        self.assertEqual(call, ANY)
-
-        m = MagicMock()
-        int(m)
-        self.assertEqual(m.mock_calls, [ANY])
-        self.assertEqual([ANY], m.mock_calls)
-
-
-    def test_two_args_call(self):
-        args = _Call(((1, 2), {'a': 3}), two=True)
-        self.assertEqual(len(args), 2)
-        self.assertEqual(args[0], (1, 2))
-        self.assertEqual(args[1], {'a': 3})
-
-        other_args = _Call(((1, 2), {'a': 3}))
-        self.assertEqual(args, other_args)
-
-    def test_call_with_name(self):
-        self.assertEqual(_Call((), 'foo')[0], 'foo')
-        self.assertEqual(_Call((('bar', 'barz'),),)[0], '')
-        self.assertEqual(_Call((('bar', 'barz'), {'hello': 'world'}),)[0], '')
-
-
-class SpecSignatureTest(unittest.TestCase):
-
-    def _check_someclass_mock(self, mock):
-        self.assertRaises(AttributeError, getattr, mock, 'foo')
-        mock.one(1, 2)
-        mock.one.assert_called_with(1, 2)
-        self.assertRaises(AssertionError,
-                          mock.one.assert_called_with, 3, 4)
-        self.assertRaises(TypeError, mock.one, 1)
-
-        mock.two()
-        mock.two.assert_called_with()
-        self.assertRaises(AssertionError,
-                          mock.two.assert_called_with, 3)
-        self.assertRaises(TypeError, mock.two, 1)
-
-        mock.three()
-        mock.three.assert_called_with()
-        self.assertRaises(AssertionError,
-                          mock.three.assert_called_with, 3)
-        self.assertRaises(TypeError, mock.three, 3, 2)
-
-        mock.three(1)
-        mock.three.assert_called_with(1)
-
-        mock.three(a=1)
-        mock.three.assert_called_with(a=1)
-
-
-    def test_basic(self):
-        mock = create_autospec(SomeClass)
-        self._check_someclass_mock(mock)
-        mock = create_autospec(SomeClass())
-        self._check_someclass_mock(mock)
-
-
-    def test_create_autospec_return_value(self):
-        def f(): pass
-        mock = create_autospec(f, return_value='foo')
-        self.assertEqual(mock(), 'foo')
-
-        class Foo(object):
-            pass
-
-        mock = create_autospec(Foo, return_value='foo')
-        self.assertEqual(mock(), 'foo')
-
-
-    def test_autospec_reset_mock(self):
-        m = create_autospec(int)
-        int(m)
-        m.reset_mock()
-        self.assertEqual(m.__int__.call_count, 0)
-
-
-    def test_mocking_unbound_methods(self):
-        class Foo(object):
-            def foo(self, foo): pass
-        p = patch.object(Foo, 'foo')
-        mock_foo = p.start()
-        Foo().foo(1)
-
-        mock_foo.assert_called_with(1)
-
-
-    def test_create_autospec_keyword_arguments(self):
-        class Foo(object):
-            a = 3
-        m = create_autospec(Foo, a='3')
-        self.assertEqual(m.a, '3')
-
-    @unittest.skipUnless(six.PY3, "Keyword only arguments Python 3 specific")
-    def test_create_autospec_keyword_only_arguments(self):
-        func_def = "def foo(a, *, b=None): pass\n"
-        namespace = {}
-        exec (func_def, namespace)
-        foo = namespace['foo']
-
-        m = create_autospec(foo)
-        m(1)
-        m.assert_called_with(1)
-        self.assertRaises(TypeError, m, 1, 2)
-
-        m(2, b=3)
-        m.assert_called_with(2, b=3)
-
-    def test_function_as_instance_attribute(self):
-        obj = SomeClass()
-        def f(a): pass
-        obj.f = f
-
-        mock = create_autospec(obj)
-        mock.f('bing')
-        mock.f.assert_called_with('bing')
-
-
-    def test_spec_as_list(self):
-        # because spec as a list of strings in the mock constructor means
-        # something very different we treat a list instance as the type.
-        mock = create_autospec([])
-        mock.append('foo')
-        mock.append.assert_called_with('foo')
-
-        self.assertRaises(AttributeError, getattr, mock, 'foo')
-
-        class Foo(object):
-            foo = []
-
-        mock = create_autospec(Foo)
-        mock.foo.append(3)
-        mock.foo.append.assert_called_with(3)
-        self.assertRaises(AttributeError, getattr, mock.foo, 'foo')
-
-
-    def test_attributes(self):
-        class Sub(SomeClass):
-            attr = SomeClass()
-
-        sub_mock = create_autospec(Sub)
-
-        for mock in (sub_mock, sub_mock.attr):
-            self._check_someclass_mock(mock)
-
-
-    @unittest.skipIf('PyPy' in sys.version,
-                     "This fails on pypy, "
-                     "see https://github.com/testing-cabal/mock/issues/452")
-    def test_spec_has_descriptor_returning_function(self):
-        class CrazyDescriptor(object):
-            def __get__(self, obj, type_):
-                if obj is None:
-                    return lambda x: None
-
-        class MyClass(object):
-            some_attr = CrazyDescriptor()
-
-        mock = create_autospec(MyClass)
-        mock.some_attr(1)
-        with self.assertRaises(TypeError):
-            mock.some_attr()
-        with self.assertRaises(TypeError):
-            mock.some_attr(1, 2)
-
-    @unittest.skipIf(six.PY2, "object.__dir__ doesn't exist in Python 2")
-    def test_spec_has_function_not_in_bases(self):
-        class CrazyClass(object):
-            def __dir__(self):
-                return super(CrazyClass, self).__dir__() + ['crazy']
-
-            def __getattr__(self, item):
-                if item == 'crazy':
-                    return lambda x: x
-                raise AttributeError(item)
-
-        inst = CrazyClass()
-        with self.assertRaises(AttributeError):
-            inst.other
-        self.assertEqual(inst.crazy(42), 42)
-        mock = create_autospec(inst)
-        mock.crazy(42)
-        with self.assertRaises(TypeError):
-            mock.crazy()
-        with self.assertRaises(TypeError):
-            mock.crazy(1, 2)
-
-
-    @unittest.skipIf('PyPy' in sys.version and sys.version_info < (3, 0),
-                     "Fails on pypy2 due to incorrect signature for dict.pop from funcsigs")
-    def test_builtin_functions_types(self):
-        # we could replace builtin functions / methods with a function
-        # with *args / **kwargs signature. Using the builtin method type
-        # as a spec seems to work fairly well though.
-        class BuiltinSubclass(list):
-            def bar(self, arg): pass
-            sorted = sorted
-            attr = {}
-
-        mock = create_autospec(BuiltinSubclass)
-        mock.append(3)
-        mock.append.assert_called_with(3)
-        self.assertRaises(AttributeError, getattr, mock.append, 'foo')
-
-        mock.bar('foo')
-        mock.bar.assert_called_with('foo')
-        self.assertRaises(TypeError, mock.bar, 'foo', 'bar')
-        self.assertRaises(AttributeError, getattr, mock.bar, 'foo')
-
-        mock.sorted([1, 2])
-        mock.sorted.assert_called_with([1, 2])
-        self.assertRaises(AttributeError, getattr, mock.sorted, 'foo')
-
-        mock.attr.pop(3)
-        mock.attr.pop.assert_called_with(3)
-        self.assertRaises(AttributeError, getattr, mock.attr, 'foo')
-
-
-    def test_method_calls(self):
-        class Sub(SomeClass):
-            attr = SomeClass()
-
-        mock = create_autospec(Sub)
-        mock.one(1, 2)
-        mock.two()
-        mock.three(3)
-
-        expected = [call.one(1, 2), call.two(), call.three(3)]
-        self.assertEqual(mock.method_calls, expected)
-
-        mock.attr.one(1, 2)
-        mock.attr.two()
-        mock.attr.three(3)
-
-        expected.extend(
-            [call.attr.one(1, 2), call.attr.two(), call.attr.three(3)]
-        )
-        self.assertEqual(mock.method_calls, expected)
-
-
-    def test_magic_methods(self):
-        class BuiltinSubclass(list):
-            attr = {}
-
-        mock = create_autospec(BuiltinSubclass)
-        self.assertEqual(list(mock), [])
-        self.assertRaises(TypeError, int, mock)
-        self.assertRaises(TypeError, int, mock.attr)
-        self.assertEqual(list(mock), [])
-
-        self.assertIsInstance(mock['foo'], MagicMock)
-        self.assertIsInstance(mock.attr['foo'], MagicMock)
-
-
-    def test_spec_set(self):
-        class Sub(SomeClass):
-            attr = SomeClass()
-
-        for spec in (Sub, Sub()):
-            mock = create_autospec(spec, spec_set=True)
-            self._check_someclass_mock(mock)
-
-            self.assertRaises(AttributeError, setattr, mock, 'foo', 'bar')
-            self.assertRaises(AttributeError, setattr, mock.attr, 'foo', 'bar')
-
-
-    def test_descriptors(self):
-        class Foo(object):
-            @classmethod
-            def f(cls, a, b): pass
-            @staticmethod
-            def g(a, b): pass
-
-        class Bar(Foo): pass
-
-        class Baz(SomeClass, Bar): pass
-
-        for spec in (Foo, Foo(), Bar, Bar(), Baz, Baz()):
-            mock = create_autospec(spec)
-            mock.f(1, 2)
-            mock.f.assert_called_once_with(1, 2)
-
-            mock.g(3, 4)
-            mock.g.assert_called_once_with(3, 4)
-
-
-    @unittest.skipIf(six.PY3, "No old style classes in Python 3")
-    def test_old_style_classes(self):
-        class Foo:
-            def f(self, a, b): pass
-
-        class Bar(Foo):
-            g = Foo()
-
-        for spec in (Foo, Foo(), Bar, Bar()):
-            mock = create_autospec(spec)
-            mock.f(1, 2)
-            mock.f.assert_called_once_with(1, 2)
-
-            self.assertRaises(AttributeError, getattr, mock, 'foo')
-            self.assertRaises(AttributeError, getattr, mock.f, 'foo')
-
-        mock.g.f(1, 2)
-        mock.g.f.assert_called_once_with(1, 2)
-        self.assertRaises(AttributeError, getattr, mock.g, 'foo')
-
-
-    def test_recursive(self):
-        class A(object):
-            def a(self): pass
-            foo = 'foo bar baz'
-            bar = foo
-
-        A.B = A
-        mock = create_autospec(A)
-
-        mock()
-        self.assertFalse(mock.B.called)
-
-        mock.a()
-        mock.B.a()
-        self.assertEqual(mock.method_calls, [call.a(), call.B.a()])
-
-        self.assertIs(A.foo, A.bar)
-        self.assertIsNot(mock.foo, mock.bar)
-        mock.foo.lower()
-        self.assertRaises(AssertionError, mock.bar.lower.assert_called_with)
-
-
-    def test_spec_inheritance_for_classes(self):
-        class Foo(object):
-            def a(self, x): pass
-            class Bar(object):
-                def f(self, y): pass
-
-        class_mock = create_autospec(Foo)
-
-        self.assertIsNot(class_mock, class_mock())
-
-        for this_mock in class_mock, class_mock():
-            this_mock.a(x=5)
-            this_mock.a.assert_called_with(x=5)
-            this_mock.a.assert_called_with(5)
-            self.assertRaises(TypeError, this_mock.a, 'foo', 'bar')
-            self.assertRaises(AttributeError, getattr, this_mock, 'b')
-
-        instance_mock = create_autospec(Foo())
-        instance_mock.a(5)
-        instance_mock.a.assert_called_with(5)
-        instance_mock.a.assert_called_with(x=5)
-        self.assertRaises(TypeError, instance_mock.a, 'foo', 'bar')
-        self.assertRaises(AttributeError, getattr, instance_mock, 'b')
-
-        # The return value isn't isn't callable
-        self.assertRaises(TypeError, instance_mock)
-
-        instance_mock.Bar.f(6)
-        instance_mock.Bar.f.assert_called_with(6)
-        instance_mock.Bar.f.assert_called_with(y=6)
-        self.assertRaises(AttributeError, getattr, instance_mock.Bar, 'g')
-
-        instance_mock.Bar().f(6)
-        instance_mock.Bar().f.assert_called_with(6)
-        instance_mock.Bar().f.assert_called_with(y=6)
-        self.assertRaises(AttributeError, getattr, instance_mock.Bar(), 'g')
-
-
-    def test_inherit(self):
-        class Foo(object):
-            a = 3
-
-        Foo.Foo = Foo
-
-        # class
-        mock = create_autospec(Foo)
-        instance = mock()
-        self.assertRaises(AttributeError, getattr, instance, 'b')
-
-        attr_instance = mock.Foo()
-        self.assertRaises(AttributeError, getattr, attr_instance, 'b')
-
-        # instance
-        mock = create_autospec(Foo())
-        self.assertRaises(AttributeError, getattr, mock, 'b')
-        self.assertRaises(TypeError, mock)
-
-        # attribute instance
-        call_result = mock.Foo()
-        self.assertRaises(AttributeError, getattr, call_result, 'b')
-
-
-    def test_builtins(self):
-        # used to fail with infinite recursion
-        create_autospec(1)
-
-        create_autospec(int)
-        create_autospec('foo')
-        create_autospec(str)
-        create_autospec({})
-        create_autospec(dict)
-        create_autospec([])
-        create_autospec(list)
-        create_autospec(set())
-        create_autospec(set)
-        create_autospec(1.0)
-        create_autospec(float)
-        create_autospec(1j)
-        create_autospec(complex)
-        create_autospec(False)
-        create_autospec(True)
-
-
-    def test_function(self):
-        def f(a, b): pass
-
-        mock = create_autospec(f)
-        self.assertRaises(TypeError, mock)
-        mock(1, 2)
-        mock.assert_called_with(1, 2)
-        mock.assert_called_with(1, b=2)
-        mock.assert_called_with(a=1, b=2)
-
-        f.f = f
-        mock = create_autospec(f)
-        self.assertRaises(TypeError, mock.f)
-        mock.f(3, 4)
-        mock.f.assert_called_with(3, 4)
-        mock.f.assert_called_with(a=3, b=4)
-
-
-    def test_skip_attributeerrors(self):
-        class Raiser(object):
-            def __get__(self, obj, type=None):
-                if obj is None:
-                    raise AttributeError('Can only be accessed via an instance')
-
-        class RaiserClass(object):
-            raiser = Raiser()
-
-            @staticmethod
-            def existing(a, b):
-                return a + b
-
-        self.assertEqual(RaiserClass.existing(1, 2), 3)
-        s = create_autospec(RaiserClass)
-        self.assertRaises(TypeError, lambda x: s.existing(1, 2, 3))
-        self.assertEqual(s.existing(1, 2), s.existing.return_value)
-        self.assertRaises(AttributeError, lambda: s.nonexisting)
-
-        # check we can fetch the raiser attribute and it has no spec
-        obj = s.raiser
-        obj.foo, obj.bar
-
-
-    def test_signature_class(self):
-        class Foo(object):
-            def __init__(self, a, b=3): pass
-
-        mock = create_autospec(Foo)
-
-        self.assertRaises(TypeError, mock)
-        mock(1)
-        mock.assert_called_once_with(1)
-
-        mock(4, 5)
-        mock.assert_called_with(4, 5)
-
-
-    @unittest.skipIf(six.PY3, 'no old style classes in Python 3')
-    def test_signature_old_style_class(self):
-        class Foo:
-            def __init__(self, a, b=3): pass
-
-        mock = create_autospec(Foo)
-
-        self.assertRaises(TypeError, mock)
-        mock(1)
-        mock.assert_called_once_with(1)
-        mock.assert_called_once_with(a=1)
-        self.assertRaises(AssertionError, mock.assert_called_once_with, 2)
-
-        mock(4, 5)
-        mock.assert_called_with(4, 5)
-        mock.assert_called_with(a=4, b=5)
-        self.assertRaises(AssertionError, mock.assert_called_with, a=5, b=4)
-
-
-    def test_class_with_no_init(self):
-        # this used to raise an exception
-        # due to trying to get a signature from object.__init__
-        class Foo(object):
-            pass
-        create_autospec(Foo)
-
-
-    @unittest.skipIf(six.PY3, 'no old style classes in Python 3')
-    def test_old_style_class_with_no_init(self):
-        # this used to raise an exception
-        # due to Foo.__init__ raising an AttributeError
-        class Foo:
-            pass
-        create_autospec(Foo)
-
-
-    def test_signature_callable(self):
-        class Callable(object):
-            def __init__(self, x, y): pass
-            def __call__(self, a): pass
-
-        mock = create_autospec(Callable)
-        mock(1, 2)
-        mock.assert_called_once_with(1, 2)
-        mock.assert_called_once_with(x=1, y=2)
-        self.assertRaises(TypeError, mock, 'a')
-
-        instance = mock(1, 2)
-        self.assertRaises(TypeError, instance)
-        instance(a='a')
-        instance.assert_called_once_with('a')
-        instance.assert_called_once_with(a='a')
-        instance('a')
-        instance.assert_called_with('a')
-        instance.assert_called_with(a='a')
-
-        mock = create_autospec(Callable(1, 2))
-        mock(a='a')
-        mock.assert_called_once_with(a='a')
-        self.assertRaises(TypeError, mock)
-        mock('a')
-        mock.assert_called_with('a')
-
-
-    def test_signature_noncallable(self):
-        class NonCallable(object):
-            def __init__(self):
-                pass
-
-        mock = create_autospec(NonCallable)
-        instance = mock()
-        mock.assert_called_once_with()
-        self.assertRaises(TypeError, mock, 'a')
-        self.assertRaises(TypeError, instance)
-        self.assertRaises(TypeError, instance, 'a')
-
-        mock = create_autospec(NonCallable())
-        self.assertRaises(TypeError, mock)
-        self.assertRaises(TypeError, mock, 'a')
-
-
-    def test_create_autospec_none(self):
-        class Foo(object):
-            bar = None
-
-        mock = create_autospec(Foo)
-        none = mock.bar
-        self.assertNotIsInstance(none, type(None))
-
-        none.foo()
-        none.foo.assert_called_once_with()
-
-
-    def test_autospec_functions_with_self_in_odd_place(self):
-        class Foo(object):
-            def f(a, self): pass
-
-        a = create_autospec(Foo)
-        a.f(10)
-        a.f.assert_called_with(10)
-        a.f.assert_called_with(self=10)
-        a.f(self=10)
-        a.f.assert_called_with(10)
-        a.f.assert_called_with(self=10)
-
-
-    def test_autospec_property(self):
-        class Foo(object):
-            @property
-            def foo(self): pass
-
-        foo = create_autospec(Foo)
-        mock_property = foo.foo
-
-        # no spec on properties
-        self.assertIsInstance(mock_property, MagicMock)
-        mock_property(1, 2, 3)
-        mock_property.abc(4, 5, 6)
-        mock_property.assert_called_once_with(1, 2, 3)
-        mock_property.abc.assert_called_once_with(4, 5, 6)
-
-
-    def test_autospec_slots(self):
-        class Foo(object):
-            __slots__ = ['a']
-
-        foo = create_autospec(Foo)
-        mock_slot = foo.a
-
-        # no spec on slots
-        mock_slot(1, 2, 3)
-        mock_slot.abc(4, 5, 6)
-        mock_slot.assert_called_once_with(1, 2, 3)
-        mock_slot.abc.assert_called_once_with(4, 5, 6)
-
-
-    def test_autospec_data_descriptor(self):
-        class Descriptor(object):
-            def __init__(self, value):
-                self.value = value
-
-            def __get__(self, obj, cls=None):
-                return self
-
-            def __set__(self, obj, value): pass
-
-        class MyProperty(property):
-            pass
-
-        class Foo(object):
-            __slots__ = ['slot']
-
-            @property
-            def prop(self): pass
-
-            @MyProperty
-            def subprop(self): pass
-
-            desc = Descriptor(42)
-
-        foo = create_autospec(Foo)
-
-        def check_data_descriptor(mock_attr):
-            # Data descriptors don't have a spec.
-            self.assertIsInstance(mock_attr, MagicMock)
-            mock_attr(1, 2, 3)
-            mock_attr.abc(4, 5, 6)
-            mock_attr.assert_called_once_with(1, 2, 3)
-            mock_attr.abc.assert_called_once_with(4, 5, 6)
-
-        # property
-        check_data_descriptor(foo.prop)
-        # property subclass
-        check_data_descriptor(foo.subprop)
-        # class __slot__
-        check_data_descriptor(foo.slot)
-        # plain data descriptor
-        check_data_descriptor(foo.desc)
-
-
-    @unittest.skipIf('PyPy' in sys.version and sys.version_info > (3, 0),
-                     "See https://github.com/testing-cabal/mock/issues/452")
-    def test_autospec_on_bound_builtin_function(self):
-        meth = six.create_bound_method(time.ctime, time.time())
-        self.assertIsInstance(meth(), str)
-        mocked = create_autospec(meth)
-
-        # no signature, so no spec to check against
-        mocked()
-        mocked.assert_called_once_with()
-        mocked.reset_mock()
-        mocked(4, 5, 6)
-        mocked.assert_called_once_with(4, 5, 6)
-
-    def test_autospec_socket(self):
-        sock_class = create_autospec(socket.socket)
-        self.assertRaises(TypeError, sock_class, foo=1)
-
-
-    def test_autospec_getattr_partial_function(self):
-        # bpo-32153 : getattr returning partial functions without
-        # __name__ should not create AttributeError in create_autospec
-        class Foo(object):
-            def __getattr__(self, attribute):
-                return partial(lambda name: name, attribute)
-        proxy = Foo()
-        autospec = create_autospec(proxy)
-        self.assertFalse(hasattr(autospec, '__name__'))
-
-
-    def test_spec_inspect_signature(self):
-
-        def myfunc(x, y): pass
-
-        mock = create_autospec(myfunc)
-        mock(1, 2)
-        mock(x=1, y=2)
-
-        if six.PY2:
-            self.assertEqual(funcsigs.signature(mock), funcsigs.signature(myfunc))
-        else:
-            self.assertEqual(inspect.getfullargspec(mock), inspect.getfullargspec(myfunc))
-        self.assertEqual(mock.mock_calls, [call(1, 2), call(x=1, y=2)])
-        self.assertRaises(TypeError, mock, 1)
-
-
-    def test_spec_function_no_name(self):
-        func = lambda: 'nope'
-        mock = create_autospec(func)
-        self.assertEqual(mock.__name__, 'funcopy')
-
-
-    @unittest.skipIf(six.PY3, "Here to test our Py2 _isidentifier")
-    def test_spec_function_has_identifier_name(self):
-        func = lambda: 'nope'
-        func.__name__ = 'global'
-        mock = create_autospec(func)
-        self.assertEqual(mock.__name__, 'funcopy')
-
-
-    def test_spec_function_assert_has_calls(self):
-        def f(a): pass
-        mock = create_autospec(f)
-        mock(1)
-        mock.assert_has_calls([call(1)])
-        with self.assertRaises(AssertionError):
-            mock.assert_has_calls([call(2)])
-
-
-    def test_spec_function_assert_any_call(self):
-        def f(a): pass
-        mock = create_autospec(f)
-        mock(1)
-        mock.assert_any_call(1)
-        with self.assertRaises(AssertionError):
-            mock.assert_any_call(2)
-
-
-    def test_spec_function_reset_mock(self):
-        def f(a): pass
-        rv = Mock()
-        mock = create_autospec(f, return_value=rv)
-        mock(1)(2)
-        self.assertEqual(mock.mock_calls, [call(1)])
-        self.assertEqual(rv.mock_calls, [call(2)])
-        mock.reset_mock()
-        self.assertEqual(mock.mock_calls, [])
-        self.assertEqual(rv.mock_calls, [])
-
-
-class TestCallList(unittest.TestCase):
-
-    def test_args_list_contains_call_list(self):
-        mock = Mock()
-        self.assertIsInstance(mock.call_args_list, _CallList)
-
-        mock(1, 2)
-        mock(a=3)
-        mock(3, 4)
-        mock(b=6)
-
-        for kall in call(1, 2), call(a=3), call(3, 4), call(b=6):
-            self.assertIn(kall, mock.call_args_list)
-
-        calls = [call(a=3), call(3, 4)]
-        self.assertIn(calls, mock.call_args_list)
-        calls = [call(1, 2), call(a=3)]
-        self.assertIn(calls, mock.call_args_list)
-        calls = [call(3, 4), call(b=6)]
-        self.assertIn(calls, mock.call_args_list)
-        calls = [call(3, 4)]
-        self.assertIn(calls, mock.call_args_list)
-
-        self.assertNotIn(call('fish'), mock.call_args_list)
-        self.assertNotIn([call('fish')], mock.call_args_list)
-
-
-    def test_call_list_str(self):
-        mock = Mock()
-        mock(1, 2)
-        mock.foo(a=3)
-        mock.foo.bar().baz('fish', cat='dog')
-
-        expected = (
-            "[call(1, 2),\n"
-            " call.foo(a=3),\n"
-            " call.foo.bar(),\n"
-            " call.foo.bar().baz('fish', cat='dog')]"
-        )
-        self.assertEqual(str(mock.mock_calls), expected)
-
-
-    @unittest.skipIf(six.PY3, "Unicode is properly handled with Python 3")
-    def test_call_list_unicode(self):
-        # See github issue #328
-        mock = Mock()
-
-        class NonAsciiRepr(object):
-            def __repr__(self):
-                return "\xe9"
-
-        mock(**{unicode("a"): NonAsciiRepr()})
-
-        self.assertEqual(str(mock.mock_calls), "[call(a=\xe9)]")
-
-
-    def test_propertymock(self):
-        p = patch('%s.SomeClass.one' % __name__, new_callable=PropertyMock)
-        mock = p.start()
-        try:
-            SomeClass.one
-            mock.assert_called_once_with()
-
-            s = SomeClass()
-            s.one
-            mock.assert_called_with()
-            self.assertEqual(mock.mock_calls, [call(), call()])
-
-            s.one = 3
-            self.assertEqual(mock.mock_calls, [call(), call(), call(3)])
-        finally:
-            p.stop()
-
-
-    def test_propertymock_returnvalue(self):
-        m = MagicMock()
-        p = PropertyMock()
-        type(m).foo = p
-
-        returned = m.foo
-        p.assert_called_once_with()
-        self.assertIsInstance(returned, MagicMock)
-        self.assertNotIsInstance(returned, PropertyMock)
-
-
-class TestCallablePredicate(unittest.TestCase):
-
-    def test_type(self):
-        for obj in [str, bytes, int, list, tuple, SomeClass]:
-            self.assertTrue(_callable(obj))
-
-    def test_call_magic_method(self):
-        class Callable:
-            def __call__(self): pass
-        instance = Callable()
-        self.assertTrue(_callable(instance))
-
-    def test_staticmethod(self):
-        class WithStaticMethod:
-            @staticmethod
-            def staticfunc(): pass
-        self.assertTrue(_callable(WithStaticMethod.staticfunc))
-
-    def test_non_callable_staticmethod(self):
-        class BadStaticMethod:
-            not_callable = staticmethod(None)
-        self.assertFalse(_callable(BadStaticMethod.not_callable))
-
-    def test_classmethod(self):
-        class WithClassMethod:
-            @classmethod
-            def classfunc(cls): pass
-        self.assertTrue(_callable(WithClassMethod.classfunc))
-
-    def test_non_callable_classmethod(self):
-        class BadClassMethod:
-            not_callable = classmethod(None)
-        self.assertFalse(_callable(BadClassMethod.not_callable))
-
-
-if __name__ == '__main__':
-    unittest.main()
diff --git a/mock/tests/testhelpers_py3.py b/mock/tests/testhelpers_py3.py
deleted file mode 100644
index 64d62f8..0000000
--- a/mock/tests/testhelpers_py3.py
+++ /dev/null
@@ -1,23 +0,0 @@
-import inspect
-import unittest
-
-from mock import call, create_autospec
-
-
-class CallTest(unittest.TestCase):
-
-
-    def test_spec_inspect_signature_annotations(self):
-
-        def foo(a: int, b: int=10, *, c:int) -> int:
-            return a + b + c
-
-        self.assertEqual(foo(1, 2, c=3), 6)
-        mock = create_autospec(foo)
-        mock(1, 2, c=3)
-        mock(1, c=3)
-
-        self.assertEqual(inspect.getfullargspec(mock), inspect.getfullargspec(foo))
-        self.assertEqual(mock.mock_calls, [call(1, 2, c=3), call(1, c=3)])
-        self.assertRaises(TypeError, mock, 1)
-        self.assertRaises(TypeError, mock, 1, 2, 3, c=4)
diff --git a/mock/tests/testmagicmethods.py b/mock/tests/testmagicmethods.py
deleted file mode 100644
index f6c25fb..0000000
--- a/mock/tests/testmagicmethods.py
+++ /dev/null
@@ -1,553 +0,0 @@
-# Copyright (C) 2007-2012 Michael Foord & the mock team
-# E-mail: fuzzyman AT voidspace DOT org DOT uk
-# http://www.voidspace.org.uk/python/mock/
-
-from __future__ import division
-
-try:
-    unicode
-except NameError:
-    # Python 3
-    unicode = str
-    long = int
-
-import math
-import os
-import sys
-import textwrap
-import unittest
-
-import six
-
-from mock import Mock, MagicMock
-from mock.mock import _magics
-
-
-
-class TestMockingMagicMethods(unittest.TestCase):
-
-    def test_deleting_magic_methods(self):
-        mock = Mock()
-        self.assertFalse(hasattr(mock, '__getitem__'))
-
-        mock.__getitem__ = Mock()
-        self.assertTrue(hasattr(mock, '__getitem__'))
-
-        del mock.__getitem__
-        self.assertFalse(hasattr(mock, '__getitem__'))
-
-
-    def test_magicmock_del(self):
-        mock = MagicMock()
-        # before using getitem
-        del mock.__getitem__
-        self.assertRaises(TypeError, lambda: mock['foo'])
-
-        mock = MagicMock()
-        # this time use it first
-        mock['foo']
-        del mock.__getitem__
-        self.assertRaises(TypeError, lambda: mock['foo'])
-
-
-    def test_magic_method_wrapping(self):
-        mock = Mock()
-        def f(self, name):
-            return self, 'fish'
-
-        mock.__getitem__ = f
-        self.assertIsNot(mock.__getitem__, f)
-        self.assertEqual(mock['foo'], (mock, 'fish'))
-        self.assertEqual(mock.__getitem__('foo'), (mock, 'fish'))
-
-        mock.__getitem__ = mock
-        self.assertIs(mock.__getitem__, mock)
-
-
-    def test_magic_methods_isolated_between_mocks(self):
-        mock1 = Mock()
-        mock2 = Mock()
-
-        mock1.__iter__ = Mock(return_value=iter([]))
-        self.assertEqual(list(mock1), [])
-        self.assertRaises(TypeError, lambda: list(mock2))
-
-
-    def test_repr(self):
-        mock = Mock()
-        self.assertEqual(repr(mock), "<Mock id='%s'>" % id(mock))
-        mock.__repr__ = lambda s: 'foo'
-        self.assertEqual(repr(mock), 'foo')
-
-
-    def test_str(self):
-        mock = Mock()
-        self.assertEqual(str(mock), object.__str__(mock))
-        mock.__str__ = lambda s: 'foo'
-        self.assertEqual(str(mock), 'foo')
-
-
-    @unittest.skipIf(six.PY3, "no unicode in Python 3")
-    def test_unicode(self):
-        mock = Mock()
-        self.assertEqual(unicode(mock), unicode(str(mock)))
-
-        mock.__unicode__ = lambda s: unicode('foo')
-        self.assertEqual(unicode(mock), unicode('foo'))
-
-
-    def test_dict_methods(self):
-        mock = Mock()
-
-        self.assertRaises(TypeError, lambda: mock['foo'])
-        def _del():
-            del mock['foo']
-        def _set():
-            mock['foo'] = 3
-        self.assertRaises(TypeError, _del)
-        self.assertRaises(TypeError, _set)
-
-        _dict = {}
-        def getitem(s, name):
-            return _dict[name]
-        def setitem(s, name, value):
-            _dict[name] = value
-        def delitem(s, name):
-            del _dict[name]
-
-        mock.__setitem__ = setitem
-        mock.__getitem__ = getitem
-        mock.__delitem__ = delitem
-
-        self.assertRaises(KeyError, lambda: mock['foo'])
-        mock['foo'] = 'bar'
-        self.assertEqual(_dict, {'foo': 'bar'})
-        self.assertEqual(mock['foo'], 'bar')
-        del mock['foo']
-        self.assertEqual(_dict, {})
-
-
-    def test_numeric(self):
-        original = mock = Mock()
-        mock.value = 0
-
-        self.assertRaises(TypeError, lambda: mock + 3)
-
-        def add(self, other):
-            mock.value += other
-            return self
-        mock.__add__ = add
-        self.assertEqual(mock + 3, mock)
-        self.assertEqual(mock.value, 3)
-
-        del mock.__add__
-        def iadd(mock):
-            mock += 3
-        self.assertRaises(TypeError, iadd, mock)
-        mock.__iadd__ = add
-        mock += 6
-        self.assertEqual(mock, original)
-        self.assertEqual(mock.value, 9)
-
-        self.assertRaises(TypeError, lambda: 3 + mock)
-        mock.__radd__ = add
-        self.assertEqual(7 + mock, mock)
-        self.assertEqual(mock.value, 16)
-
-    def test_division(self):
-        original = mock = Mock()
-        mock.value = 32
-        self.assertRaises(TypeError, lambda: mock / 2)
-
-        def truediv(self, other):
-            mock.value /= other
-            return self
-        mock.__truediv__ = truediv
-        self.assertEqual(mock / 2, mock)
-        self.assertEqual(mock.value, 16)
-
-        del mock.__truediv__
-        if six.PY3:
-            def itruediv(mock):
-                mock /= 4
-            self.assertRaises(TypeError, itruediv, mock)
-            mock.__itruediv__ = truediv
-            mock /= 8
-            self.assertEqual(mock, original)
-            self.assertEqual(mock.value, 2)
-        else:
-            mock.value = 2
-
-        self.assertRaises(TypeError, lambda: 8 / mock)
-        mock.__rtruediv__ = truediv
-        self.assertEqual(0.5 / mock, mock)
-        self.assertEqual(mock.value, 4)
-
-    def test_hash(self):
-        mock = Mock()
-        # test delegation
-        self.assertEqual(hash(mock), Mock.__hash__(mock))
-
-        def _hash(s):
-            return 3
-        mock.__hash__ = _hash
-        self.assertEqual(hash(mock), 3)
-
-
-    def test_nonzero(self):
-        m = Mock()
-        self.assertTrue(bool(m))
-
-        nonzero = lambda s: False
-        if six.PY2:
-            m.__nonzero__ = nonzero
-        else:
-            m.__bool__ = nonzero
-
-        self.assertFalse(bool(m))
-
-
-    def test_comparison(self):
-        mock = Mock()
-        def comp(s, o):
-            return True
-        mock.__lt__ = mock.__gt__ = mock.__le__ = mock.__ge__ = comp
-        self. assertTrue(mock < 3)
-        self. assertTrue(mock > 3)
-        self. assertTrue(mock <= 3)
-        self. assertTrue(mock >= 3)
-
-        if six.PY2:
-            # incomparable in Python 3
-            self.assertEqual(Mock() < 3, object() < 3)
-            self.assertEqual(Mock() > 3, object() > 3)
-            self.assertEqual(Mock() <= 3, object() <= 3)
-            self.assertEqual(Mock() >= 3, object() >= 3)
-        else:
-            self.assertRaises(TypeError, lambda: MagicMock() < object())
-            self.assertRaises(TypeError, lambda: object() < MagicMock())
-            self.assertRaises(TypeError, lambda: MagicMock() < MagicMock())
-            self.assertRaises(TypeError, lambda: MagicMock() > object())
-            self.assertRaises(TypeError, lambda: object() > MagicMock())
-            self.assertRaises(TypeError, lambda: MagicMock() > MagicMock())
-            self.assertRaises(TypeError, lambda: MagicMock() <= object())
-            self.assertRaises(TypeError, lambda: object() <= MagicMock())
-            self.assertRaises(TypeError, lambda: MagicMock() <= MagicMock())
-            self.assertRaises(TypeError, lambda: MagicMock() >= object())
-            self.assertRaises(TypeError, lambda: object() >= MagicMock())
-            self.assertRaises(TypeError, lambda: MagicMock() >= MagicMock())
-
-
-    def test_equality(self):
-        for mock in Mock(), MagicMock():
-            self.assertEqual(mock == mock, True)
-            self.assertIsInstance(mock == mock, bool)
-            self.assertEqual(mock != mock, False)
-            self.assertIsInstance(mock != mock, bool)
-            self.assertEqual(mock == object(), False)
-            self.assertEqual(mock != object(), True)
-
-            def eq(self, other):
-                return other == 3
-            mock.__eq__ = eq
-            self.assertTrue(mock == 3)
-            self.assertFalse(mock == 4)
-
-            def ne(self, other):
-                return other == 3
-            mock.__ne__ = ne
-            self.assertTrue(mock != 3)
-            self.assertFalse(mock != 4)
-
-        mock = MagicMock()
-        mock.__eq__.return_value = True
-        self.assertIsInstance(mock == 3, bool)
-        self.assertEqual(mock == 3, True)
-
-        mock.__ne__.return_value = False
-        self.assertIsInstance(mock != 3, bool)
-        self.assertEqual(mock != 3, False)
-
-
-    def test_len_contains_iter(self):
-        mock = Mock()
-
-        self.assertRaises(TypeError, len, mock)
-        self.assertRaises(TypeError, iter, mock)
-        self.assertRaises(TypeError, lambda: 'foo' in mock)
-
-        mock.__len__ = lambda s: 6
-        self.assertEqual(len(mock), 6)
-
-        mock.__contains__ = lambda s, o: o == 3
-        self.assertIn(3, mock)
-        self.assertNotIn(6, mock)
-
-        mock.__iter__ = lambda s: iter('foobarbaz')
-        self.assertEqual(list(mock), list('foobarbaz'))
-
-
-    def test_magicmock(self):
-        mock = MagicMock()
-
-        mock.__iter__.return_value = iter([1, 2, 3])
-        self.assertEqual(list(mock), [1, 2, 3])
-
-        name = '__nonzero__'
-        other = '__bool__'
-        if six.PY3:
-            name, other = other, name
-        getattr(mock, name).return_value = False
-        self.assertFalse(hasattr(mock, other))
-        self.assertFalse(bool(mock))
-
-        for entry in _magics:
-            self.assertTrue(hasattr(mock, entry))
-        self.assertFalse(hasattr(mock, '__imaginary__'))
-
-
-    def test_magic_mock_equality(self):
-        mock = MagicMock()
-        self.assertIsInstance(mock == object(), bool)
-        self.assertIsInstance(mock != object(), bool)
-
-        self.assertEqual(mock == object(), False)
-        self.assertEqual(mock != object(), True)
-        self.assertEqual(mock == mock, True)
-        self.assertEqual(mock != mock, False)
-
-
-    def test_magicmock_defaults(self):
-        mock = MagicMock()
-        self.assertEqual(int(mock), 1)
-        self.assertEqual(complex(mock), 1j)
-        self.assertEqual(float(mock), 1.0)
-        self.assertEqual(long(mock), long(1))
-        self.assertNotIn(object(), mock)
-        self.assertEqual(len(mock), 0)
-        self.assertEqual(list(mock), [])
-        self.assertEqual(hash(mock), object.__hash__(mock))
-        self.assertEqual(str(mock), object.__str__(mock))
-        self.assertEqual(unicode(mock), object.__str__(mock))
-        self.assertIsInstance(unicode(mock), unicode)
-        self.assertTrue(bool(mock))
-        self.assertEqual(math.trunc(mock), mock.__trunc__())
-        if six.PY2:
-            # These fall back to __float__ in Python 2:
-            self.assertEqual(round(mock), 1.0)
-            self.assertEqual(math.floor(mock), 1.0)
-            self.assertEqual(math.ceil(mock), 1.0)
-        else:
-            self.assertEqual(round(mock), mock.__round__())
-            self.assertEqual(math.floor(mock), mock.__floor__())
-            self.assertEqual(math.ceil(mock), mock.__ceil__())
-        if six.PY2:
-            self.assertEqual(oct(mock), '1')
-        else:
-            # in Python 3 oct and hex use __index__
-            # so these tests are for __index__ in py3k
-            self.assertEqual(oct(mock), '0o1')
-        self.assertEqual(hex(mock), '0x1')
-        # how to test __sizeof__ ?
-
-
-    @unittest.skipIf(six.PY3, "no __cmp__ in Python 3")
-    def test_non_default_magic_methods(self):
-        mock = MagicMock()
-        self.assertRaises(AttributeError, lambda: mock.__cmp__)
-
-        mock = Mock()
-        mock.__cmp__ = lambda s, o: 0
-
-        self.assertEqual(mock, object())
-
-
-    def test_magic_methods_fspath(self):
-        mock = MagicMock()
-        if sys.version_info < (3, 6):
-            self.assertRaises(AttributeError, lambda: mock.__fspath__)
-        else:
-            expected_path = mock.__fspath__()
-            mock.reset_mock()
-            self.assertEqual(os.fspath(mock), expected_path)
-            mock.__fspath__.assert_called_once()
-
-
-    def test_magic_methods_and_spec(self):
-        class Iterable(object):
-            def __iter__(self): pass
-
-        mock = Mock(spec=Iterable)
-        self.assertRaises(AttributeError, lambda: mock.__iter__)
-
-        mock.__iter__ = Mock(return_value=iter([]))
-        self.assertEqual(list(mock), [])
-
-        class NonIterable(object):
-            pass
-        mock = Mock(spec=NonIterable)
-        self.assertRaises(AttributeError, lambda: mock.__iter__)
-
-        def set_int():
-            mock.__int__ = Mock(return_value=iter([]))
-        self.assertRaises(AttributeError, set_int)
-
-        mock = MagicMock(spec=Iterable)
-        self.assertEqual(list(mock), [])
-        self.assertRaises(AttributeError, set_int)
-
-
-    def test_magic_methods_and_spec_set(self):
-        class Iterable(object):
-            def __iter__(self): pass
-
-        mock = Mock(spec_set=Iterable)
-        self.assertRaises(AttributeError, lambda: mock.__iter__)
-
-        mock.__iter__ = Mock(return_value=iter([]))
-        self.assertEqual(list(mock), [])
-
-        class NonIterable(object):
-            pass
-        mock = Mock(spec_set=NonIterable)
-        self.assertRaises(AttributeError, lambda: mock.__iter__)
-
-        def set_int():
-            mock.__int__ = Mock(return_value=iter([]))
-        self.assertRaises(AttributeError, set_int)
-
-        mock = MagicMock(spec_set=Iterable)
-        self.assertEqual(list(mock), [])
-        self.assertRaises(AttributeError, set_int)
-
-
-    def test_setting_unsupported_magic_method(self):
-        mock = MagicMock()
-        def set_setattr():
-            mock.__setattr__ = lambda self, name: None
-        self.assertRaisesRegexp(AttributeError,
-            "Attempting to set unsupported magic method '__setattr__'.",
-            set_setattr
-        )
-
-
-    def test_attributes_and_return_value(self):
-        mock = MagicMock()
-        attr = mock.foo
-        def _get_type(obj):
-            # the type of every mock (or magicmock) is a custom subclass
-            # so the real type is the second in the mro
-            return type(obj).__mro__[1]
-        self.assertEqual(_get_type(attr), MagicMock)
-
-        returned = mock()
-        self.assertEqual(_get_type(returned), MagicMock)
-
-
-    def test_magic_methods_are_magic_mocks(self):
-        mock = MagicMock()
-        self.assertIsInstance(mock.__getitem__, MagicMock)
-
-        mock[1][2].__getitem__.return_value = 3
-        self.assertEqual(mock[1][2][3], 3)
-
-
-    def test_magic_method_reset_mock(self):
-        mock = MagicMock()
-        str(mock)
-        self.assertTrue(mock.__str__.called)
-        mock.reset_mock()
-        self.assertFalse(mock.__str__.called)
-
-    def test_dir(self):
-        # overriding the default implementation
-        for mock in Mock(), MagicMock():
-            def _dir(self):
-                return ['foo']
-            mock.__dir__ = _dir
-            self.assertEqual(dir(mock), ['foo'])
-
-
-    @unittest.skipIf('PyPy' in sys.version, "This fails differently on pypy")
-    def test_bound_methods(self):
-        m = Mock()
-
-        # XXXX should this be an expected failure instead?
-
-        # this seems like it should work, but is hard to do without introducing
-        # other api inconsistencies. Failure message could be better though.
-        m.__iter__ = [3].__iter__
-        self.assertRaises(TypeError, iter, m)
-
-
-    def test_magic_method_type(self):
-        class Foo(MagicMock):
-            pass
-
-        foo = Foo()
-        self.assertIsInstance(foo.__int__, Foo)
-
-
-    def test_descriptor_from_class(self):
-        m = MagicMock()
-        type(m).__str__.return_value = 'foo'
-        self.assertEqual(str(m), 'foo')
-
-
-    def test_iterable_as_iter_return_value(self):
-        m = MagicMock()
-        m.__iter__.return_value = [1, 2, 3]
-        self.assertEqual(list(m), [1, 2, 3])
-        self.assertEqual(list(m), [1, 2, 3])
-
-        m.__iter__.return_value = iter([4, 5, 6])
-        self.assertEqual(list(m), [4, 5, 6])
-        self.assertEqual(list(m), [])
-
-    @unittest.skipIf(sys.version_info < (3, 5), "@ added in Python 3.5")
-    def test_matmul(self):
-        src = textwrap.dedent("""\
-            m = MagicMock()
-            self.assertIsInstance(m @ 1, MagicMock)
-            m.__matmul__.return_value = 42
-            m.__rmatmul__.return_value = 666
-            m.__imatmul__.return_value = 24
-            self.assertEqual(m @ 1, 42)
-            self.assertEqual(1 @ m, 666)
-            m @= 24
-            self.assertEqual(m, 24)
-        """)
-        exec(src)
-
-    def test_divmod_and_rdivmod(self):
-        m = MagicMock()
-        self.assertIsInstance(divmod(5, m), MagicMock)
-        m.__divmod__.return_value = (2, 1)
-        self.assertEqual(divmod(m, 2), (2, 1))
-        m = MagicMock()
-        foo = divmod(2, m)
-        self.assertIsInstance(foo, MagicMock)
-        foo_direct = m.__divmod__(2)
-        self.assertIsInstance(foo_direct, MagicMock)
-        bar = divmod(m, 2)
-        self.assertIsInstance(bar, MagicMock)
-        bar_direct = m.__rdivmod__(2)
-        self.assertIsInstance(bar_direct, MagicMock)
-
-    # http://bugs.python.org/issue23310
-    # Check if you can change behaviour of magic methods in MagicMock init
-    def test_magic_in_initialization(self):
-        m = MagicMock(**{'__str__.return_value': "12"})
-        self.assertEqual(str(m), "12")
-
-    def test_changing_magic_set_in_initialization(self):
-        m = MagicMock(**{'__str__.return_value': "12"})
-        m.__str__.return_value = "13"
-        self.assertEqual(str(m), "13")
-        m = MagicMock(**{'__str__.return_value': "12"})
-        m.configure_mock(**{'__str__.return_value': "14"})
-        self.assertEqual(str(m), "14")
-
-
-if __name__ == '__main__':
-    unittest.main()
diff --git a/mock/tests/testmock.py b/mock/tests/testmock.py
deleted file mode 100644
index 5f6045a..0000000
--- a/mock/tests/testmock.py
+++ /dev/null
@@ -1,1977 +0,0 @@
-# Copyright (C) 2007-2012 Michael Foord & the mock team
-# E-mail: fuzzyman AT voidspace DOT org DOT uk
-# http://www.voidspace.org.uk/python/mock/
-
-import copy
-import pickle
-import re
-import sys
-import tempfile
-
-import six
-import unittest
-
-import mock
-from mock.mock import (
-    call, DEFAULT, patch, sentinel,
-    MagicMock, Mock, NonCallableMock,
-    NonCallableMagicMock, _Call, _CallList,
-    create_autospec
-)
-from mock.tests.support import is_instance
-
-
-try:
-    unicode
-except NameError:
-    unicode = str
-
-
-class Iter(object):
-    def __init__(self):
-        self.thing = iter(['this', 'is', 'an', 'iter'])
-
-    def __iter__(self):
-        return self
-
-    def next(self):
-        return next(self.thing)
-
-    __next__ = next
-
-
-class Something(object):
-    def meth(self, a, b, c, d=None): pass
-
-    @classmethod
-    def cmeth(cls, a, b, c, d=None): pass
-
-    @staticmethod
-    def smeth(a, b, c, d=None): pass
-
-
-class Subclass(MagicMock):
-    pass
-
-
-class Thing(object):
-    attribute = 6
-    foo = 'bar'
-
-
-
-class MockTest(unittest.TestCase):
-
-    def test_all(self):
-        # if __all__ is badly defined then import * will raise an error
-        # We have to exec it because you can't import * inside a method
-        # in Python 3
-        exec("from mock import *")
-
-
-    def test_constructor(self):
-        mock = Mock()
-
-        self.assertFalse(mock.called, "called not initialised correctly")
-        self.assertEqual(mock.call_count, 0,
-                         "call_count not initialised correctly")
-        self.assertTrue(is_instance(mock.return_value, Mock),
-                        "return_value not initialised correctly")
-
-        self.assertEqual(mock.call_args, None,
-                         "call_args not initialised correctly")
-        self.assertEqual(mock.call_args_list, [],
-                         "call_args_list not initialised correctly")
-        self.assertEqual(mock.method_calls, [],
-                          "method_calls not initialised correctly")
-
-        # Can't use hasattr for this test as it always returns True on a mock
-        self.assertNotIn('_items', mock.__dict__,
-                         "default mock should not have '_items' attribute")
-
-        self.assertIsNone(mock._mock_parent,
-                          "parent not initialised correctly")
-        self.assertIsNone(mock._mock_methods,
-                          "methods not initialised correctly")
-        self.assertEqual(mock._mock_children, {},
-                         "children not initialised incorrectly")
-
-
-    def test_return_value_in_constructor(self):
-        mock = Mock(return_value=None)
-        self.assertIsNone(mock.return_value,
-                          "return value in constructor not honoured")
-
-
-    def test_change_return_value_via_delegate(self):
-        def f(): pass
-        mock = create_autospec(f)
-        mock.mock.return_value = 1
-        self.assertEqual(mock(), 1)
-
-
-    def test_change_side_effect_via_delegate(self):
-        def f(): pass
-        mock = create_autospec(f)
-        mock.mock.side_effect = TypeError()
-        with self.assertRaises(TypeError):
-            mock()
-
-
-    def test_repr(self):
-        mock = Mock(name='foo')
-        self.assertIn('foo', repr(mock))
-        self.assertIn("'%s'" % id(mock), repr(mock))
-
-        mocks = [(Mock(), 'mock'), (Mock(name='bar'), 'bar')]
-        for mock, name in mocks:
-            self.assertIn('%s.bar' % name, repr(mock.bar))
-            self.assertIn('%s.foo()' % name, repr(mock.foo()))
-            self.assertIn('%s.foo().bing' % name, repr(mock.foo().bing))
-            self.assertIn('%s()' % name, repr(mock()))
-            self.assertIn('%s()()' % name, repr(mock()()))
-            self.assertIn('%s()().foo.bar.baz().bing' % name,
-                          repr(mock()().foo.bar.baz().bing))
-
-
-    def test_repr_with_spec(self):
-        class X(object):
-            pass
-
-        mock = Mock(spec=X)
-        self.assertIn(" spec='X' ", repr(mock))
-
-        mock = Mock(spec=X())
-        self.assertIn(" spec='X' ", repr(mock))
-
-        mock = Mock(spec_set=X)
-        self.assertIn(" spec_set='X' ", repr(mock))
-
-        mock = Mock(spec_set=X())
-        self.assertIn(" spec_set='X' ", repr(mock))
-
-        mock = Mock(spec=X, name='foo')
-        self.assertIn(" spec='X' ", repr(mock))
-        self.assertIn(" name='foo' ", repr(mock))
-
-        mock = Mock(name='foo')
-        self.assertNotIn("spec", repr(mock))
-
-        mock = Mock()
-        self.assertNotIn("spec", repr(mock))
-
-        mock = Mock(spec=['foo'])
-        self.assertNotIn("spec", repr(mock))
-
-
-    def test_side_effect(self):
-        mock = Mock()
-
-        def effect(*args, **kwargs):
-            raise SystemError('kablooie')
-
-        mock.side_effect = effect
-        self.assertRaises(SystemError, mock, 1, 2, fish=3)
-        mock.assert_called_with(1, 2, fish=3)
-
-        results = [1, 2, 3]
-        def effect():
-            return results.pop()
-        mock.side_effect = effect
-
-        self.assertEqual([mock(), mock(), mock()], [3, 2, 1],
-                          "side effect not used correctly")
-
-        mock = Mock(side_effect=sentinel.SideEffect)
-        self.assertEqual(mock.side_effect, sentinel.SideEffect,
-                          "side effect in constructor not used")
-
-        def side_effect():
-            return DEFAULT
-        mock = Mock(side_effect=side_effect, return_value=sentinel.RETURN)
-        self.assertEqual(mock(), sentinel.RETURN)
-
-    def test_autospec_side_effect(self):
-        # Test for issue17826
-        results = [1, 2, 3]
-        def effect():
-            return results.pop()
-        def f(): pass
-
-        mock = create_autospec(f)
-        mock.side_effect = [1, 2, 3]
-        self.assertEqual([mock(), mock(), mock()], [1, 2, 3],
-                          "side effect not used correctly in create_autospec")
-        # Test where side effect is a callable
-        results = [1, 2, 3]
-        mock = create_autospec(f)
-        mock.side_effect = effect
-        self.assertEqual([mock(), mock(), mock()], [3, 2, 1],
-                          "callable side effect not used correctly")
-
-    def test_autospec_side_effect_exception(self):
-        # Test for issue 23661
-        def f(): pass
-
-        mock = create_autospec(f)
-        mock.side_effect = ValueError('Bazinga!')
-        self.assertRaisesRegexp(ValueError, 'Bazinga!', mock)
-
-    def test_reset_mock(self):
-        parent = Mock()
-        spec = ["something"]
-        mock = Mock(name="child", parent=parent, spec=spec)
-        mock(sentinel.Something, something=sentinel.SomethingElse)
-        something = mock.something
-        mock.something()
-        mock.side_effect = sentinel.SideEffect
-        return_value = mock.return_value
-        return_value()
-
-        mock.reset_mock()
-
-        self.assertEqual(mock._mock_name, "child",
-                         "name incorrectly reset")
-        self.assertEqual(mock._mock_parent, parent,
-                         "parent incorrectly reset")
-        self.assertEqual(mock._mock_methods, spec,
-                         "methods incorrectly reset")
-
-        self.assertFalse(mock.called, "called not reset")
-        self.assertEqual(mock.call_count, 0, "call_count not reset")
-        self.assertEqual(mock.call_args, None, "call_args not reset")
-        self.assertEqual(mock.call_args_list, [], "call_args_list not reset")
-        self.assertEqual(mock.method_calls, [],
-                        "method_calls not initialised correctly: %r != %r" %
-                        (mock.method_calls, []))
-        self.assertEqual(mock.mock_calls, [])
-
-        self.assertEqual(mock.side_effect, sentinel.SideEffect,
-                          "side_effect incorrectly reset")
-        self.assertEqual(mock.return_value, return_value,
-                          "return_value incorrectly reset")
-        self.assertFalse(return_value.called, "return value mock not reset")
-        self.assertEqual(mock._mock_children, {'something': something},
-                          "children reset incorrectly")
-        self.assertEqual(mock.something, something,
-                          "children incorrectly cleared")
-        self.assertFalse(mock.something.called, "child not reset")
-
-
-    def test_reset_mock_recursion(self):
-        mock = Mock()
-        mock.return_value = mock
-
-        # used to cause recursion
-        mock.reset_mock()
-
-    def test_reset_mock_on_mock_open_issue_18622(self):
-        a = mock.mock_open()
-        a.reset_mock()
-
-    def test_call(self):
-        mock = Mock()
-        self.assertTrue(is_instance(mock.return_value, Mock),
-                        "Default return_value should be a Mock")
-
-        result = mock()
-        self.assertEqual(mock(), result,
-                         "different result from consecutive calls")
-        mock.reset_mock()
-
-        ret_val = mock(sentinel.Arg)
-        self.assertTrue(mock.called, "called not set")
-        self.assertEqual(mock.call_count, 1, "call_count incoreect")
-        self.assertEqual(mock.call_args, ((sentinel.Arg,), {}),
-                         "call_args not set")
-        self.assertEqual(mock.call_args.args, (sentinel.Arg,),
-                         "call_args not set")
-        self.assertEqual(mock.call_args.kwargs, {},
-                         "call_args not set")
-        self.assertEqual(mock.call_args_list, [((sentinel.Arg,), {})],
-                         "call_args_list not initialised correctly")
-
-        mock.return_value = sentinel.ReturnValue
-        ret_val = mock(sentinel.Arg, key=sentinel.KeyArg)
-        self.assertEqual(ret_val, sentinel.ReturnValue,
-                         "incorrect return value")
-
-        self.assertEqual(mock.call_count, 2, "call_count incorrect")
-        self.assertEqual(mock.call_args,
-                         ((sentinel.Arg,), {'key': sentinel.KeyArg}),
-                         "call_args not set")
-        self.assertEqual(mock.call_args_list, [
-            ((sentinel.Arg,), {}),
-            ((sentinel.Arg,), {'key': sentinel.KeyArg})
-        ],
-            "call_args_list not set")
-
-
-    def test_call_args_comparison(self):
-        mock = Mock()
-        mock()
-        mock(sentinel.Arg)
-        mock(kw=sentinel.Kwarg)
-        mock(sentinel.Arg, kw=sentinel.Kwarg)
-        self.assertEqual(mock.call_args_list, [
-            (),
-            ((sentinel.Arg,),),
-            ({"kw": sentinel.Kwarg},),
-            ((sentinel.Arg,), {"kw": sentinel.Kwarg})
-        ])
-        self.assertEqual(mock.call_args,
-                         ((sentinel.Arg,), {"kw": sentinel.Kwarg}))
-        self.assertEqual(mock.call_args.args, (sentinel.Arg,))
-        self.assertEqual(mock.call_args.kwargs, {"kw": sentinel.Kwarg})
-
-        # Comparing call_args to a long sequence should not raise
-        # an exception. See issue 24857.
-        self.assertFalse(mock.call_args == "a long sequence")
-
-
-    def test_calls_equal_with_any(self):
-        # Check that equality and non-equality is consistent even when
-        # comparing with mock.ANY
-        mm = mock.MagicMock()
-        self.assertTrue(mm == mm)
-        self.assertFalse(mm != mm)
-        self.assertFalse(mm == mock.MagicMock())
-        self.assertTrue(mm != mock.MagicMock())
-        self.assertTrue(mm == mock.ANY)
-        self.assertFalse(mm != mock.ANY)
-        self.assertTrue(mock.ANY == mm)
-        self.assertFalse(mock.ANY != mm)
-
-        call1 = mock.call(mock.MagicMock())
-        call2 = mock.call(mock.ANY)
-        self.assertTrue(call1 == call2)
-        self.assertFalse(call1 != call2)
-        self.assertTrue(call2 == call1)
-        self.assertFalse(call2 != call1)
-
-
-    def test_assert_called_with(self):
-        mock = Mock()
-        mock()
-
-        # Will raise an exception if it fails
-        mock.assert_called_with()
-        self.assertRaises(AssertionError, mock.assert_called_with, 1)
-
-        mock.reset_mock()
-        self.assertRaises(AssertionError, mock.assert_called_with)
-
-        mock(1, 2, 3, a='fish', b='nothing')
-        mock.assert_called_with(1, 2, 3, a='fish', b='nothing')
-
-
-    def test_assert_called_with_any(self):
-        m = MagicMock()
-        m(MagicMock())
-        m.assert_called_with(mock.ANY)
-
-
-    def test_assert_called_with_function_spec(self):
-        def f(a, b, c, d=None): pass
-
-        mock = Mock(spec=f)
-
-        mock(1, b=2, c=3)
-        mock.assert_called_with(1, 2, 3)
-        mock.assert_called_with(a=1, b=2, c=3)
-        self.assertRaises(AssertionError, mock.assert_called_with,
-                          1, b=3, c=2)
-        # Expected call doesn't match the spec's signature
-        with self.assertRaises(AssertionError) as cm:
-            mock.assert_called_with(e=8)
-        if hasattr(cm.exception, '__cause__'):
-            self.assertIsInstance(cm.exception.__cause__, TypeError)
-
-
-    def test_assert_called_with_method_spec(self):
-        def _check(mock):
-            mock(1, b=2, c=3)
-            mock.assert_called_with(1, 2, 3)
-            mock.assert_called_with(a=1, b=2, c=3)
-            self.assertRaises(AssertionError, mock.assert_called_with,
-                              1, b=3, c=2)
-
-        mock = Mock(spec=Something().meth)
-        _check(mock)
-        mock = Mock(spec=Something.cmeth)
-        _check(mock)
-        mock = Mock(spec=Something().cmeth)
-        _check(mock)
-        mock = Mock(spec=Something.smeth)
-        _check(mock)
-        mock = Mock(spec=Something().smeth)
-        _check(mock)
-
-
-    def test_assert_called_once_with(self):
-        mock = Mock()
-        mock()
-
-        # Will raise an exception if it fails
-        mock.assert_called_once_with()
-
-        mock()
-        self.assertRaises(AssertionError, mock.assert_called_once_with)
-
-        mock.reset_mock()
-        self.assertRaises(AssertionError, mock.assert_called_once_with)
-
-        mock('foo', 'bar', baz=2)
-        mock.assert_called_once_with('foo', 'bar', baz=2)
-
-        mock.reset_mock()
-        mock('foo', 'bar', baz=2)
-        self.assertRaises(
-            AssertionError,
-            lambda: mock.assert_called_once_with('bob', 'bar', baz=2)
-        )
-
-    def test_assert_called_once_with_call_list(self):
-        m = Mock()
-        m(1)
-        m(2)
-        self.assertRaisesRegexp(AssertionError,
-            re.escape("Calls: [call(1), call(2)]"),
-            lambda: m.assert_called_once_with(2))
-
-
-    def test_assert_called_once_with_function_spec(self):
-        def f(a, b, c, d=None): pass
-
-        mock = Mock(spec=f)
-
-        mock(1, b=2, c=3)
-        mock.assert_called_once_with(1, 2, 3)
-        mock.assert_called_once_with(a=1, b=2, c=3)
-        self.assertRaises(AssertionError, mock.assert_called_once_with,
-                          1, b=3, c=2)
-        # Expected call doesn't match the spec's signature
-        with self.assertRaises(AssertionError) as cm:
-            mock.assert_called_once_with(e=8)
-        if hasattr(cm.exception, '__cause__'):
-            self.assertIsInstance(cm.exception.__cause__, TypeError)
-        # Mock called more than once => always fails
-        mock(4, 5, 6)
-        self.assertRaises(AssertionError, mock.assert_called_once_with,
-                          1, 2, 3)
-        self.assertRaises(AssertionError, mock.assert_called_once_with,
-                          4, 5, 6)
-
-
-    def test_attribute_access_returns_mocks(self):
-        mock = Mock()
-        something = mock.something
-        self.assertTrue(is_instance(something, Mock), "attribute isn't a mock")
-        self.assertEqual(mock.something, something,
-                         "different attributes returned for same name")
-
-        # Usage example
-        mock = Mock()
-        mock.something.return_value = 3
-
-        self.assertEqual(mock.something(), 3, "method returned wrong value")
-        self.assertTrue(mock.something.called,
-                        "method didn't record being called")
-
-
-    def test_attributes_have_name_and_parent_set(self):
-        mock = Mock()
-        something = mock.something
-
-        self.assertEqual(something._mock_name, "something",
-                         "attribute name not set correctly")
-        self.assertEqual(something._mock_parent, mock,
-                         "attribute parent not set correctly")
-
-
-    def test_method_calls_recorded(self):
-        mock = Mock()
-        mock.something(3, fish=None)
-        mock.something_else.something(6, cake=sentinel.Cake)
-
-        self.assertEqual(mock.something_else.method_calls,
-                          [("something", (6,), {'cake': sentinel.Cake})],
-                          "method calls not recorded correctly")
-        self.assertEqual(mock.method_calls, [
-            ("something", (3,), {'fish': None}),
-            ("something_else.something", (6,), {'cake': sentinel.Cake})
-        ],
-            "method calls not recorded correctly")
-
-
-    def test_method_calls_compare_easily(self):
-        mock = Mock()
-        mock.something()
-        self.assertEqual(mock.method_calls, [('something',)])
-        self.assertEqual(mock.method_calls, [('something', (), {})])
-
-        mock = Mock()
-        mock.something('different')
-        self.assertEqual(mock.method_calls, [('something', ('different',))])
-        self.assertEqual(mock.method_calls,
-                         [('something', ('different',), {})])
-
-        mock = Mock()
-        mock.something(x=1)
-        self.assertEqual(mock.method_calls, [('something', {'x': 1})])
-        self.assertEqual(mock.method_calls, [('something', (), {'x': 1})])
-
-        mock = Mock()
-        mock.something('different', some='more')
-        self.assertEqual(mock.method_calls, [
-            ('something', ('different',), {'some': 'more'})
-        ])
-
-
-    def test_only_allowed_methods_exist(self):
-        for spec in ['something'], ('something',):
-            for arg in 'spec', 'spec_set':
-                mock = Mock(**{arg: spec})
-
-                # this should be allowed
-                mock.something
-                self.assertRaisesRegexp(
-                    AttributeError,
-                    "Mock object has no attribute 'something_else'",
-                    getattr, mock, 'something_else'
-                )
-
-
-    def test_from_spec(self):
-        class Something(object):
-            x = 3
-            __something__ = None
-            def y(self): pass
-
-        def test_attributes(mock):
-            # should work
-            mock.x
-            mock.y
-            mock.__something__
-            self.assertRaisesRegexp(
-                AttributeError,
-                "Mock object has no attribute 'z'",
-                getattr, mock, 'z'
-            )
-            self.assertRaisesRegexp(
-                AttributeError,
-                "Mock object has no attribute '__foobar__'",
-                getattr, mock, '__foobar__'
-            )
-
-        test_attributes(Mock(spec=Something))
-        test_attributes(Mock(spec=Something()))
-
-
-    def test_wraps_calls(self):
-        real = Mock()
-
-        mock = Mock(wraps=real)
-        self.assertEqual(mock(), real())
-
-        real.reset_mock()
-
-        mock(1, 2, fish=3)
-        real.assert_called_with(1, 2, fish=3)
-
-
-    def test_wraps_prevents_automatic_creation_of_mocks(self):
-        class Real(object):
-            pass
-
-        real = Real()
-        mock = Mock(wraps=real)
-
-        self.assertRaises(AttributeError, lambda: mock.new_attr())
-
-
-    def test_wraps_call_with_nondefault_return_value(self):
-        real = Mock()
-
-        mock = Mock(wraps=real)
-        mock.return_value = 3
-
-        self.assertEqual(mock(), 3)
-        self.assertFalse(real.called)
-
-
-    def test_wraps_attributes(self):
-        class Real(object):
-            attribute = Mock()
-
-        real = Real()
-
-        mock = Mock(wraps=real)
-        self.assertEqual(mock.attribute(), real.attribute())
-        self.assertRaises(AttributeError, lambda: mock.fish)
-
-        self.assertNotEqual(mock.attribute, real.attribute)
-        result = mock.attribute.frog(1, 2, fish=3)
-        Real.attribute.frog.assert_called_with(1, 2, fish=3)
-        self.assertEqual(result, Real.attribute.frog())
-
-
-    def test_customize_wrapped_object_with_side_effect_iterable_with_default(self):
-        class Real(object):
-            def method(self):
-                return sentinel.ORIGINAL_VALUE
-
-        real = Real()
-        mock = Mock(wraps=real)
-        mock.method.side_effect = [sentinel.VALUE1, DEFAULT]
-
-        self.assertEqual(mock.method(), sentinel.VALUE1)
-        self.assertEqual(mock.method(), sentinel.ORIGINAL_VALUE)
-        self.assertRaises(StopIteration, mock.method)
-
-
-    def test_customize_wrapped_object_with_side_effect_iterable(self):
-        class Real(object):
-            def method(self): pass
-
-        real = Real()
-        mock = Mock(wraps=real)
-        mock.method.side_effect = [sentinel.VALUE1, sentinel.VALUE2]
-
-        self.assertEqual(mock.method(), sentinel.VALUE1)
-        self.assertEqual(mock.method(), sentinel.VALUE2)
-        self.assertRaises(StopIteration, mock.method)
-
-
-    def test_customize_wrapped_object_with_side_effect_exception(self):
-        class Real(object):
-            def method(self): pass
-
-        real = Real()
-        mock = Mock(wraps=real)
-        mock.method.side_effect = RuntimeError
-
-        self.assertRaises(RuntimeError, mock.method)
-
-
-    def test_customize_wrapped_object_with_side_effect_function(self):
-        class Real(object):
-            def method(self): pass
-        def side_effect():
-            return sentinel.VALUE
-
-        real = Real()
-        mock = Mock(wraps=real)
-        mock.method.side_effect = side_effect
-
-        self.assertEqual(mock.method(), sentinel.VALUE)
-
-
-    def test_customize_wrapped_object_with_return_value(self):
-        class Real(object):
-            def method(self): pass
-
-        real = Real()
-        mock = Mock(wraps=real)
-        mock.method.return_value = sentinel.VALUE
-
-        self.assertEqual(mock.method(), sentinel.VALUE)
-
-
-    def test_customize_wrapped_object_with_return_value_and_side_effect(self):
-        # side_effect should always take precedence over return_value.
-        class Real(object):
-            def method(self): pass
-
-        real = Real()
-        mock = Mock(wraps=real)
-        mock.method.side_effect = [sentinel.VALUE1, sentinel.VALUE2]
-        mock.method.return_value = sentinel.WRONG_VALUE
-
-        self.assertEqual(mock.method(), sentinel.VALUE1)
-        self.assertEqual(mock.method(), sentinel.VALUE2)
-        self.assertRaises(StopIteration, mock.method)
-
-
-    def test_customize_wrapped_object_with_return_value_and_side_effect2(self):
-        # side_effect can return DEFAULT to default to return_value
-        class Real(object):
-            def method(self): pass
-
-        real = Real()
-        mock = Mock(wraps=real)
-        mock.method.side_effect = lambda: DEFAULT
-        mock.method.return_value = sentinel.VALUE
-
-        self.assertEqual(mock.method(), sentinel.VALUE)
-
-
-    def test_customize_wrapped_object_with_return_value_and_side_effect_default(self):
-        class Real(object):
-            def method(self): pass
-
-        real = Real()
-        mock = Mock(wraps=real)
-        mock.method.side_effect = [sentinel.VALUE1, DEFAULT]
-        mock.method.return_value = sentinel.RETURN
-
-        self.assertEqual(mock.method(), sentinel.VALUE1)
-        self.assertEqual(mock.method(), sentinel.RETURN)
-        self.assertRaises(StopIteration, mock.method)
-
-
-    def test_exceptional_side_effect(self):
-        mock = Mock(side_effect=AttributeError)
-        self.assertRaises(AttributeError, mock)
-
-        mock = Mock(side_effect=AttributeError('foo'))
-        self.assertRaises(AttributeError, mock)
-
-
-    def test_baseexceptional_side_effect(self):
-        mock = Mock(side_effect=KeyboardInterrupt)
-        self.assertRaises(KeyboardInterrupt, mock)
-
-        mock = Mock(side_effect=KeyboardInterrupt('foo'))
-        self.assertRaises(KeyboardInterrupt, mock)
-
-
-    def test_assert_called_with_message(self):
-        mock = Mock()
-        self.assertRaisesRegexp(AssertionError, 'not called',
-                                mock.assert_called_with)
-
-
-    def test_assert_called_once_with_message(self):
-        mock = Mock(name='geoffrey')
-        self.assertRaisesRegexp(AssertionError,
-                     r"Expected 'geoffrey' to be called once\.",
-                     mock.assert_called_once_with)
-
-
-    def test__name__(self):
-        mock = Mock()
-        self.assertRaises(AttributeError, lambda: mock.__name__)
-
-        mock.__name__ = 'foo'
-        self.assertEqual(mock.__name__, 'foo')
-
-
-    def test_spec_list_subclass(self):
-        class Sub(list):
-            pass
-        mock = Mock(spec=Sub(['foo']))
-
-        mock.append(3)
-        mock.append.assert_called_with(3)
-        self.assertRaises(AttributeError, getattr, mock, 'foo')
-
-
-    def test_spec_class(self):
-        class X(object):
-            pass
-
-        mock = Mock(spec=X)
-        self.assertIsInstance(mock, X)
-
-        mock = Mock(spec=X())
-        self.assertIsInstance(mock, X)
-
-        self.assertIs(mock.__class__, X)
-        self.assertEqual(Mock().__class__.__name__, 'Mock')
-
-        mock = Mock(spec_set=X)
-        self.assertIsInstance(mock, X)
-
-        mock = Mock(spec_set=X())
-        self.assertIsInstance(mock, X)
-
-
-    def test_spec_class_no_object_base(self):
-        class X:
-            pass
-
-        mock = Mock(spec=X)
-        self.assertIsInstance(mock, X)
-
-        if not six.PY2:
-            # This isn't true on Py2, we should fix if anyone complains:
-            mock = Mock(spec=X())
-            self.assertIsInstance(mock, X)
-
-        self.assertIs(mock.__class__, X)
-        self.assertEqual(Mock().__class__.__name__, 'Mock')
-
-        mock = Mock(spec_set=X)
-        self.assertIsInstance(mock, X)
-
-        if not six.PY2:
-        # This isn't true on Py2, we should fix if anyone complains:
-            mock = Mock(spec_set=X())
-            self.assertIsInstance(mock, X)
-
-
-    def test_setting_attribute_with_spec_set(self):
-        class X(object):
-            y = 3
-
-        mock = Mock(spec=X)
-        mock.x = 'foo'
-
-        mock = Mock(spec_set=X)
-        def set_attr():
-            mock.x = 'foo'
-
-        mock.y = 'foo'
-        self.assertRaises(AttributeError, set_attr)
-
-
-    def test_copy(self):
-        current = sys.getrecursionlimit()
-        self.addCleanup(sys.setrecursionlimit, current)
-
-        # can't use sys.maxint as this doesn't exist in Python 3
-        sys.setrecursionlimit(int(10e8))
-        # this segfaults without the fix in place
-        copy.copy(Mock())
-
-
-    @unittest.skipIf(six.PY3, "no old style classes in Python 3")
-    def test_spec_old_style_classes(self):
-        class Foo:
-            bar = 7
-
-        mock = Mock(spec=Foo)
-        mock.bar = 6
-        self.assertRaises(AttributeError, lambda: mock.foo)
-
-        mock = Mock(spec=Foo())
-        mock.bar = 6
-        self.assertRaises(AttributeError, lambda: mock.foo)
-
-
-    @unittest.skipIf(six.PY3, "no old style classes in Python 3")
-    def test_spec_set_old_style_classes(self):
-        class Foo:
-            bar = 7
-
-        mock = Mock(spec_set=Foo)
-        mock.bar = 6
-        self.assertRaises(AttributeError, lambda: mock.foo)
-
-        def _set():
-            mock.foo = 3
-        self.assertRaises(AttributeError, _set)
-
-        mock = Mock(spec_set=Foo())
-        mock.bar = 6
-        self.assertRaises(AttributeError, lambda: mock.foo)
-
-        def _set():
-            mock.foo = 3
-        self.assertRaises(AttributeError, _set)
-
-
-    def test_subclass_with_properties(self):
-        class SubClass(Mock):
-            def _get(self):
-                return 3
-            def _set(self, value):
-                raise NameError('strange error')
-            some_attribute = property(_get, _set)
-
-        s = SubClass(spec_set=SubClass)
-        self.assertEqual(s.some_attribute, 3)
-
-        def test():
-            s.some_attribute = 3
-        self.assertRaises(NameError, test)
-
-        def test():
-            s.foo = 'bar'
-        self.assertRaises(AttributeError, test)
-
-
-    def test_setting_call(self):
-        mock = Mock()
-        def __call__(self, a):
-            return self._mock_call(a)
-
-        type(mock).__call__ = __call__
-        mock('one')
-        mock.assert_called_with('one')
-
-        self.assertRaises(TypeError, mock, 'one', 'two')
-
-
-    def test_dir(self):
-        mock = Mock()
-        attrs = set(dir(mock))
-        type_attrs = {m for m in dir(Mock) if not m.startswith('_')}
-
-        # all public attributes from the type are included
-        self.assertEqual(set(), type_attrs - attrs)
-
-        # creates these attributes
-        mock.a, mock.b
-        self.assertIn('a', dir(mock))
-        self.assertIn('b', dir(mock))
-
-        # instance attributes
-        mock.c = mock.d = None
-        self.assertIn('c', dir(mock))
-        self.assertIn('d', dir(mock))
-
-        # magic methods
-        mock.__iter__ = lambda s: iter([])
-        self.assertIn('__iter__', dir(mock))
-
-
-    def test_dir_from_spec(self):
-        mock = Mock(spec=unittest.TestCase)
-        testcase_attrs = set(dir(unittest.TestCase))
-        attrs = set(dir(mock))
-
-        # all attributes from the spec are included
-        self.assertEqual(set(), testcase_attrs - attrs)
-
-        # shadow a sys attribute
-        mock.version = 3
-        self.assertEqual(dir(mock).count('version'), 1)
-
-
-    def test_filter_dir(self):
-        patcher = patch.object(mock, 'FILTER_DIR', False)
-        patcher.start()
-        try:
-            attrs = set(dir(Mock()))
-            type_attrs = set(dir(Mock))
-
-            # ALL attributes from the type are included
-            self.assertEqual(set(), type_attrs - attrs)
-        finally:
-            patcher.stop()
-
-
-    def test_dir_does_not_include_deleted_attributes(self):
-        mock = Mock()
-        mock.child.return_value = 1
-
-        self.assertIn('child', dir(mock))
-        del mock.child
-        self.assertNotIn('child', dir(mock))
-
-
-    def test_configure_mock(self):
-        mock = Mock(foo='bar')
-        self.assertEqual(mock.foo, 'bar')
-
-        mock = MagicMock(foo='bar')
-        self.assertEqual(mock.foo, 'bar')
-
-        kwargs = {'side_effect': KeyError, 'foo.bar.return_value': 33,
-                  'foo': MagicMock()}
-        mock = Mock(**kwargs)
-        self.assertRaises(KeyError, mock)
-        self.assertEqual(mock.foo.bar(), 33)
-        self.assertIsInstance(mock.foo, MagicMock)
-
-        mock = Mock()
-        mock.configure_mock(**kwargs)
-        self.assertRaises(KeyError, mock)
-        self.assertEqual(mock.foo.bar(), 33)
-        self.assertIsInstance(mock.foo, MagicMock)
-
-
-    def assertRaisesWithMsg(self, exception, message, func, *args, **kwargs):
-        # needed because assertRaisesRegex doesn't work easily with newlines
-        with self.assertRaises(exception) as context:
-            func(*args, **kwargs)
-        msg = str(context.exception)
-        self.assertEqual(msg, message)
-
-
-    def test_assert_called_with_failure_message(self):
-        mock = NonCallableMock()
-
-        actual = 'not called.'
-        expected = "mock(1, '2', 3, bar='foo')"
-        message = 'expected call not found.\nExpected: %s\nActual: %s'
-        self.assertRaisesWithMsg(
-            AssertionError, message % (expected, actual),
-            mock.assert_called_with, 1, '2', 3, bar='foo'
-        )
-
-        mock.foo(1, '2', 3, foo='foo')
-
-
-        asserters = [
-            mock.foo.assert_called_with, mock.foo.assert_called_once_with
-        ]
-        for meth in asserters:
-            actual = "foo(1, '2', 3, foo='foo')"
-            expected = "foo(1, '2', 3, bar='foo')"
-            message = 'expected call not found.\nExpected: %s\nActual: %s'
-            self.assertRaisesWithMsg(
-                AssertionError, message % (expected, actual),
-                meth, 1, '2', 3, bar='foo'
-            )
-
-        # just kwargs
-        for meth in asserters:
-            actual = "foo(1, '2', 3, foo='foo')"
-            expected = "foo(bar='foo')"
-            message = 'expected call not found.\nExpected: %s\nActual: %s'
-            self.assertRaisesWithMsg(
-                AssertionError, message % (expected, actual),
-                meth, bar='foo'
-            )
-
-        # just args
-        for meth in asserters:
-            actual = "foo(1, '2', 3, foo='foo')"
-            expected = "foo(1, 2, 3)"
-            message = 'expected call not found.\nExpected: %s\nActual: %s'
-            self.assertRaisesWithMsg(
-                AssertionError, message % (expected, actual),
-                meth, 1, 2, 3
-            )
-
-        # empty
-        for meth in asserters:
-            actual = "foo(1, '2', 3, foo='foo')"
-            expected = "foo()"
-            message = 'expected call not found.\nExpected: %s\nActual: %s'
-            self.assertRaisesWithMsg(
-                AssertionError, message % (expected, actual), meth
-            )
-
-
-    def test_mock_calls(self):
-        mock = MagicMock()
-
-        # need to do this because MagicMock.mock_calls used to just return
-        # a MagicMock which also returned a MagicMock when __eq__ was called
-        self.assertIs(mock.mock_calls == [], True)
-
-        mock = MagicMock()
-        mock()
-        expected = [('', (), {})]
-        self.assertEqual(mock.mock_calls, expected)
-
-        mock.foo()
-        expected.append(call.foo())
-        self.assertEqual(mock.mock_calls, expected)
-        # intermediate mock_calls work too
-        self.assertEqual(mock.foo.mock_calls, [('', (), {})])
-
-        mock = MagicMock()
-        mock().foo(1, 2, 3, a=4, b=5)
-        expected = [
-            ('', (), {}), ('().foo', (1, 2, 3), dict(a=4, b=5))
-        ]
-        self.assertEqual(mock.mock_calls, expected)
-        self.assertEqual(mock.return_value.foo.mock_calls,
-                         [('', (1, 2, 3), dict(a=4, b=5))])
-        self.assertEqual(mock.return_value.mock_calls,
-                         [('foo', (1, 2, 3), dict(a=4, b=5))])
-
-        mock = MagicMock()
-        mock().foo.bar().baz()
-        expected = [
-            ('', (), {}), ('().foo.bar', (), {}),
-            ('().foo.bar().baz', (), {})
-        ]
-        self.assertEqual(mock.mock_calls, expected)
-        self.assertEqual(mock().mock_calls,
-                         call.foo.bar().baz().call_list())
-
-        for kwargs in dict(), dict(name='bar'):
-            mock = MagicMock(**kwargs)
-            int(mock.foo)
-            expected = [('foo.__int__', (), {})]
-            self.assertEqual(mock.mock_calls, expected)
-
-            mock = MagicMock(**kwargs)
-            mock.a()()
-            expected = [('a', (), {}), ('a()', (), {})]
-            self.assertEqual(mock.mock_calls, expected)
-            self.assertEqual(mock.a().mock_calls, [call()])
-
-            mock = MagicMock(**kwargs)
-            mock(1)(2)(3)
-            self.assertEqual(mock.mock_calls, call(1)(2)(3).call_list())
-            self.assertEqual(mock().mock_calls, call(2)(3).call_list())
-            self.assertEqual(mock()().mock_calls, call(3).call_list())
-
-            mock = MagicMock(**kwargs)
-            mock(1)(2)(3).a.b.c(4)
-            self.assertEqual(mock.mock_calls,
-                             call(1)(2)(3).a.b.c(4).call_list())
-            self.assertEqual(mock().mock_calls,
-                             call(2)(3).a.b.c(4).call_list())
-            self.assertEqual(mock()().mock_calls,
-                             call(3).a.b.c(4).call_list())
-
-            mock = MagicMock(**kwargs)
-            int(mock().foo.bar().baz())
-            last_call = ('().foo.bar().baz().__int__', (), {})
-            self.assertEqual(mock.mock_calls[-1], last_call)
-            self.assertEqual(mock().mock_calls,
-                             call.foo.bar().baz().__int__().call_list())
-            self.assertEqual(mock().foo.bar().mock_calls,
-                             call.baz().__int__().call_list())
-            self.assertEqual(mock().foo.bar().baz.mock_calls,
-                             call().__int__().call_list())
-
-
-    def test_child_mock_call_equal(self):
-        m = Mock()
-        result = m()
-        result.wibble()
-        # parent looks like this:
-        self.assertEqual(m.mock_calls, [call(), call().wibble()])
-        # but child should look like this:
-        self.assertEqual(result.mock_calls, [call.wibble()])
-
-
-    def test_mock_call_not_equal_leaf(self):
-        m = Mock()
-        m.foo().something()
-        self.assertNotEqual(m.mock_calls[1], call.foo().different())
-        self.assertEqual(m.mock_calls[0], call.foo())
-
-
-    def test_mock_call_not_equal_non_leaf(self):
-        m = Mock()
-        m.foo().bar()
-        self.assertNotEqual(m.mock_calls[1], call.baz().bar())
-        self.assertNotEqual(m.mock_calls[0], call.baz())
-
-
-    def test_mock_call_not_equal_non_leaf_params_different(self):
-        m = Mock()
-        m.foo(x=1).bar()
-        # This isn't ideal, but there's no way to fix it without breaking backwards compatibility:
-        self.assertEqual(m.mock_calls[1], call.foo(x=2).bar())
-
-
-    def test_mock_call_not_equal_non_leaf_attr(self):
-        m = Mock()
-        m.foo.bar()
-        self.assertNotEqual(m.mock_calls[0], call.baz.bar())
-
-
-    def test_mock_call_not_equal_non_leaf_call_versus_attr(self):
-        m = Mock()
-        m.foo.bar()
-        self.assertNotEqual(m.mock_calls[0], call.foo().bar())
-
-
-    def test_mock_call_repr(self):
-        m = Mock()
-        m.foo().bar().baz.bob()
-        self.assertEqual(repr(m.mock_calls[0]), 'call.foo()')
-        self.assertEqual(repr(m.mock_calls[1]), 'call.foo().bar()')
-        self.assertEqual(repr(m.mock_calls[2]), 'call.foo().bar().baz.bob()')
-
-
-    def test_mock_call_repr_loop(self):
-        m = Mock()
-        m.foo = m
-        repr(m.foo())
-        self.assertRegexpMatches(repr(m.foo()), r"<Mock name='mock\(\)' id='\d+'>")
-
-
-    def test_mock_calls_contains(self):
-        m = Mock()
-        self.assertFalse([call()] in m.mock_calls)
-
-
-    def test_subclassing(self):
-        class Subclass(Mock):
-            pass
-
-        mock = Subclass()
-        self.assertIsInstance(mock.foo, Subclass)
-        self.assertIsInstance(mock(), Subclass)
-
-        class Subclass(Mock):
-            def _get_child_mock(self, **kwargs):
-                return Mock(**kwargs)
-
-        mock = Subclass()
-        self.assertNotIsInstance(mock.foo, Subclass)
-        self.assertNotIsInstance(mock(), Subclass)
-
-
-    def test_arg_lists(self):
-        mocks = [
-            Mock(),
-            MagicMock(),
-            NonCallableMock(),
-            NonCallableMagicMock()
-        ]
-
-        def assert_attrs(mock):
-            names = 'call_args_list', 'method_calls', 'mock_calls'
-            for name in names:
-                attr = getattr(mock, name)
-                self.assertIsInstance(attr, _CallList)
-                self.assertIsInstance(attr, list)
-                self.assertEqual(attr, [])
-
-        for mock in mocks:
-            assert_attrs(mock)
-
-            if callable(mock):
-                mock()
-                mock(1, 2)
-                mock(a=3)
-
-                mock.reset_mock()
-                assert_attrs(mock)
-
-            mock.foo()
-            mock.foo.bar(1, a=3)
-            mock.foo(1).bar().baz(3)
-
-            mock.reset_mock()
-            assert_attrs(mock)
-
-
-    def test_call_args_two_tuple(self):
-        mock = Mock()
-        mock(1, a=3)
-        mock(2, b=4)
-
-        self.assertEqual(len(mock.call_args), 2)
-        self.assertEqual(mock.call_args.args, (2,))
-        self.assertEqual(mock.call_args.kwargs, dict(b=4))
-
-        expected_list = [((1,), dict(a=3)), ((2,), dict(b=4))]
-        for expected, call_args in zip(expected_list, mock.call_args_list):
-            self.assertEqual(len(call_args), 2)
-            self.assertEqual(expected[0], call_args[0])
-            self.assertEqual(expected[1], call_args[1])
-
-
-    def test_side_effect_iterator(self):
-        mock = Mock(side_effect=iter([1, 2, 3]))
-        self.assertEqual([mock(), mock(), mock()], [1, 2, 3])
-        self.assertRaises(StopIteration, mock)
-
-        mock = MagicMock(side_effect=['a', 'b', 'c'])
-        self.assertEqual([mock(), mock(), mock()], ['a', 'b', 'c'])
-        self.assertRaises(StopIteration, mock)
-
-        mock = Mock(side_effect='ghi')
-        self.assertEqual([mock(), mock(), mock()], ['g', 'h', 'i'])
-        self.assertRaises(StopIteration, mock)
-
-        class Foo(object):
-            pass
-        mock = MagicMock(side_effect=Foo)
-        self.assertIsInstance(mock(), Foo)
-
-        mock = Mock(side_effect=Iter())
-        self.assertEqual([mock(), mock(), mock(), mock()],
-                         ['this', 'is', 'an', 'iter'])
-        self.assertRaises(StopIteration, mock)
-
-
-    def test_side_effect_setting_iterator(self):
-        mock = Mock()
-        mock.side_effect = iter([1, 2, 3])
-        self.assertEqual([mock(), mock(), mock()], [1, 2, 3])
-        self.assertRaises(StopIteration, mock)
-        side_effect = mock.side_effect
-        self.assertIsInstance(side_effect, type(iter([])))
-
-        mock.side_effect = ['a', 'b', 'c']
-        self.assertEqual([mock(), mock(), mock()], ['a', 'b', 'c'])
-        self.assertRaises(StopIteration, mock)
-        side_effect = mock.side_effect
-        self.assertIsInstance(side_effect, type(iter([])))
-
-        this_iter = Iter()
-        mock.side_effect = this_iter
-        self.assertEqual([mock(), mock(), mock(), mock()],
-                         ['this', 'is', 'an', 'iter'])
-        self.assertRaises(StopIteration, mock)
-        self.assertIs(mock.side_effect, this_iter)
-
-
-    def test_side_effect_iterator_exceptions(self):
-        for Klass in Mock, MagicMock:
-            iterable = (ValueError, 3, KeyError, 6)
-            m = Klass(side_effect=iterable)
-            self.assertRaises(ValueError, m)
-            self.assertEqual(m(), 3)
-            self.assertRaises(KeyError, m)
-            self.assertEqual(m(), 6)
-
-
-    def test_side_effect_iterator_default(self):
-        mock = Mock(return_value=2)
-        mock.side_effect = iter([1, DEFAULT])
-        self.assertEqual([mock(), mock()], [1, 2])
-
-    def test_assert_has_calls_any_order(self):
-        mock = Mock()
-        mock(1, 2)
-        mock(a=3)
-        mock(3, 4)
-        mock(b=6)
-        mock(b=6)
-
-        kalls = [
-            call(1, 2), ({'a': 3},),
-            ((3, 4),), ((), {'a': 3}),
-            ('', (1, 2)), ('', {'a': 3}),
-            ('', (1, 2), {}), ('', (), {'a': 3})
-        ]
-        for kall in kalls:
-            mock.assert_has_calls([kall], any_order=True)
-
-        for kall in call(1, '2'), call(b=3), call(), 3, None, 'foo':
-            self.assertRaises(
-                AssertionError, mock.assert_has_calls,
-                [kall], any_order=True
-            )
-
-        kall_lists = [
-            [call(1, 2), call(b=6)],
-            [call(3, 4), call(1, 2)],
-            [call(b=6), call(b=6)],
-        ]
-
-        for kall_list in kall_lists:
-            mock.assert_has_calls(kall_list, any_order=True)
-
-        kall_lists = [
-            [call(b=6), call(b=6), call(b=6)],
-            [call(1, 2), call(1, 2)],
-            [call(3, 4), call(1, 2), call(5, 7)],
-            [call(b=6), call(3, 4), call(b=6), call(1, 2), call(b=6)],
-        ]
-        for kall_list in kall_lists:
-            self.assertRaises(
-                AssertionError, mock.assert_has_calls,
-                kall_list, any_order=True
-            )
-
-    def test_assert_has_calls(self):
-        kalls1 = [
-                call(1, 2), ({'a': 3},),
-                ((3, 4),), call(b=6),
-                ('', (1,), {'b': 6}),
-        ]
-        kalls2 = [call.foo(), call.bar(1)]
-        kalls2.extend(call.spam().baz(a=3).call_list())
-        kalls2.extend(call.bam(set(), foo={}).fish([1]).call_list())
-
-        mocks = []
-        for mock in Mock(), MagicMock():
-            mock(1, 2)
-            mock(a=3)
-            mock(3, 4)
-            mock(b=6)
-            mock(1, b=6)
-            mocks.append((mock, kalls1))
-
-        mock = Mock()
-        mock.foo()
-        mock.bar(1)
-        mock.spam().baz(a=3)
-        mock.bam(set(), foo={}).fish([1])
-        mocks.append((mock, kalls2))
-
-        for mock, kalls in mocks:
-            for i in range(len(kalls)):
-                for step in 1, 2, 3:
-                    these = kalls[i:i+step]
-                    mock.assert_has_calls(these)
-
-                    if len(these) > 1:
-                        self.assertRaises(
-                            AssertionError,
-                            mock.assert_has_calls,
-                            list(reversed(these))
-                        )
-
-
-    def test_assert_has_calls_with_function_spec(self):
-        def f(a, b, c, d=None): pass
-
-        mock = Mock(spec=f)
-
-        mock(1, b=2, c=3)
-        mock(4, 5, c=6, d=7)
-        mock(10, 11, c=12)
-        calls = [
-            ('', (1, 2, 3), {}),
-            ('', (4, 5, 6), {'d': 7}),
-            ((10, 11, 12), {}),
-            ]
-        mock.assert_has_calls(calls)
-        mock.assert_has_calls(calls, any_order=True)
-        mock.assert_has_calls(calls[1:])
-        mock.assert_has_calls(calls[1:], any_order=True)
-        mock.assert_has_calls(calls[:-1])
-        mock.assert_has_calls(calls[:-1], any_order=True)
-        # Reversed order
-        calls = list(reversed(calls))
-        with self.assertRaises(AssertionError):
-            mock.assert_has_calls(calls)
-        mock.assert_has_calls(calls, any_order=True)
-        with self.assertRaises(AssertionError):
-            mock.assert_has_calls(calls[1:])
-        mock.assert_has_calls(calls[1:], any_order=True)
-        with self.assertRaises(AssertionError):
-            mock.assert_has_calls(calls[:-1])
-        mock.assert_has_calls(calls[:-1], any_order=True)
-
-
-    def test_assert_any_call(self):
-        mock = Mock()
-        mock(1, 2)
-        mock(a=3)
-        mock(1, b=6)
-
-        mock.assert_any_call(1, 2)
-        mock.assert_any_call(a=3)
-        mock.assert_any_call(1, b=6)
-
-        self.assertRaises(
-            AssertionError,
-            mock.assert_any_call
-        )
-        self.assertRaises(
-            AssertionError,
-            mock.assert_any_call,
-            1, 3
-        )
-        self.assertRaises(
-            AssertionError,
-            mock.assert_any_call,
-            a=4
-        )
-
-
-    def test_assert_any_call_with_function_spec(self):
-        def f(a, b, c, d=None): pass
-
-        mock = Mock(spec=f)
-
-        mock(1, b=2, c=3)
-        mock(4, 5, c=6, d=7)
-        mock.assert_any_call(1, 2, 3)
-        mock.assert_any_call(a=1, b=2, c=3)
-        mock.assert_any_call(4, 5, 6, 7)
-        mock.assert_any_call(a=4, b=5, c=6, d=7)
-        self.assertRaises(AssertionError, mock.assert_any_call,
-                          1, b=3, c=2)
-        # Expected call doesn't match the spec's signature
-        with self.assertRaises(AssertionError) as cm:
-            mock.assert_any_call(e=8)
-        if hasattr(cm.exception, '__cause__'):
-            self.assertIsInstance(cm.exception.__cause__, TypeError)
-
-
-    def test_mock_calls_create_autospec(self):
-        def f(a, b): pass
-        obj = Iter()
-        obj.f = f
-
-        funcs = [
-            create_autospec(f),
-            create_autospec(obj).f
-        ]
-        for func in funcs:
-            func(1, 2)
-            func(3, 4)
-
-            self.assertEqual(
-                func.mock_calls, [call(1, 2), call(3, 4)]
-            )
-
-    #Issue21222
-    def test_create_autospec_with_name(self):
-        m = mock.create_autospec(object(), name='sweet_func')
-        self.assertIn('sweet_func', repr(m))
-
-    #Issue23078
-    def test_create_autospec_classmethod_and_staticmethod(self):
-        class TestClass:
-            @classmethod
-            def class_method(cls): pass
-
-            @staticmethod
-            def static_method(): pass
-        for method in ('class_method', 'static_method'):
-                mock_method = mock.create_autospec(getattr(TestClass, method))
-                mock_method()
-                mock_method.assert_called_once_with()
-                self.assertRaises(TypeError, mock_method, 'extra_arg')
-
-    #Issue21238
-    def test_mock_unsafe(self):
-        m = Mock()
-        with self.assertRaises(AttributeError):
-            m.assert_foo_call()
-        with self.assertRaises(AttributeError):
-            m.assret_foo_call()
-        m = Mock(unsafe=True)
-        m.assert_foo_call()
-        m.assret_foo_call()
-
-    #Issue21262
-    def test_assert_not_called(self):
-        m = Mock()
-        m.hello.assert_not_called()
-        m.hello()
-        with self.assertRaises(AssertionError):
-            m.hello.assert_not_called()
-
-    def test_assert_not_called_message(self):
-        m = Mock()
-        m(1, 2)
-        self.assertRaisesRegexp(AssertionError,
-            re.escape("Calls: [call(1, 2)]"),
-            m.assert_not_called)
-
-    def test_assert_called(self):
-        m = Mock()
-        with self.assertRaises(AssertionError):
-            m.hello.assert_called()
-        m.hello()
-        m.hello.assert_called()
-
-        m.hello()
-        m.hello.assert_called()
-
-    def test_assert_called_once(self):
-        m = Mock()
-        with self.assertRaises(AssertionError):
-            m.hello.assert_called_once()
-        m.hello()
-        m.hello.assert_called_once()
-
-        m.hello()
-        with self.assertRaises(AssertionError):
-            m.hello.assert_called_once()
-
-    def test_assert_called_once_message(self):
-        m = Mock()
-        m(1, 2)
-        m(3)
-        self.assertRaisesRegexp(AssertionError,
-            re.escape("Calls: [call(1, 2), call(3)]"),
-            m.assert_called_once)
-
-    def test_assert_called_once_message_not_called(self):
-        m = Mock()
-        with self.assertRaises(AssertionError) as e:
-            m.assert_called_once()
-        self.assertNotIn("Calls:", str(e.exception))
-
-    #Issue21256 printout of keyword args should be in deterministic order
-    def test_sorted_call_signature(self):
-        m = Mock()
-        m.hello(name='hello', daddy='hero')
-        text = "call(daddy='hero', name='hello')"
-        self.assertEqual(repr(m.hello.call_args), text)
-
-    #Issue21270 overrides tuple methods for mock.call objects
-    def test_override_tuple_methods(self):
-        c = call.count()
-        i = call.index(132,'hello')
-        m = Mock()
-        m.count()
-        m.index(132,"hello")
-        self.assertEqual(m.method_calls[0], c)
-        self.assertEqual(m.method_calls[1], i)
-
-    def test_reset_return_sideeffect(self):
-        m = Mock(return_value=10, side_effect=[2,3])
-        m.reset_mock(return_value=True, side_effect=True)
-        self.assertIsInstance(m.return_value, Mock)
-        self.assertEqual(m.side_effect, None)
-
-    def test_reset_return(self):
-        m = Mock(return_value=10, side_effect=[2,3])
-        m.reset_mock(return_value=True)
-        self.assertIsInstance(m.return_value, Mock)
-        self.assertNotEqual(m.side_effect, None)
-
-    def test_reset_sideeffect(self):
-        m = Mock(return_value=10, side_effect=[2,3])
-        m.reset_mock(side_effect=True)
-        self.assertEqual(m.return_value, 10)
-        self.assertEqual(m.side_effect, None)
-
-    def test_mock_add_spec(self):
-        class _One(object):
-            one = 1
-        class _Two(object):
-            two = 2
-        class Anything(object):
-            one = two = three = 'four'
-
-        klasses = [
-            Mock, MagicMock, NonCallableMock, NonCallableMagicMock
-        ]
-        for Klass in list(klasses):
-            klasses.append(lambda K=Klass: K(spec=Anything))
-            klasses.append(lambda K=Klass: K(spec_set=Anything))
-
-        for Klass in klasses:
-            for kwargs in dict(), dict(spec_set=True):
-                mock = Klass()
-                #no error
-                mock.one, mock.two, mock.three
-
-                for One, Two in [(_One, _Two), (['one'], ['two'])]:
-                    for kwargs in dict(), dict(spec_set=True):
-                        mock.mock_add_spec(One, **kwargs)
-
-                        mock.one
-                        self.assertRaises(
-                            AttributeError, getattr, mock, 'two'
-                        )
-                        self.assertRaises(
-                            AttributeError, getattr, mock, 'three'
-                        )
-                        if 'spec_set' in kwargs:
-                            self.assertRaises(
-                                AttributeError, setattr, mock, 'three', None
-                            )
-
-                        mock.mock_add_spec(Two, **kwargs)
-                        self.assertRaises(
-                            AttributeError, getattr, mock, 'one'
-                        )
-                        mock.two
-                        self.assertRaises(
-                            AttributeError, getattr, mock, 'three'
-                        )
-                        if 'spec_set' in kwargs:
-                            self.assertRaises(
-                                AttributeError, setattr, mock, 'three', None
-                            )
-            # note that creating a mock, setting an instance attribute, and
-            # *then* setting a spec doesn't work. Not the intended use case
-
-
-    def test_mock_add_spec_magic_methods(self):
-        for Klass in MagicMock, NonCallableMagicMock:
-            mock = Klass()
-            int(mock)
-
-            mock.mock_add_spec(object)
-            self.assertRaises(TypeError, int, mock)
-
-            mock = Klass()
-            mock['foo']
-            mock.__int__.return_value =4
-
-            mock.mock_add_spec(int)
-            self.assertEqual(int(mock), 4)
-            self.assertRaises(TypeError, lambda: mock['foo'])
-
-
-    def test_adding_child_mock(self):
-        for Klass in NonCallableMock, Mock, MagicMock, NonCallableMagicMock:
-            mock = Klass()
-
-            mock.foo = Mock()
-            mock.foo()
-
-            self.assertEqual(mock.method_calls, [call.foo()])
-            self.assertEqual(mock.mock_calls, [call.foo()])
-
-            mock = Klass()
-            mock.bar = Mock(name='name')
-            mock.bar()
-            self.assertEqual(mock.method_calls, [])
-            self.assertEqual(mock.mock_calls, [])
-
-            # mock with an existing _new_parent but no name
-            mock = Klass()
-            mock.baz = MagicMock()()
-            mock.baz()
-            self.assertEqual(mock.method_calls, [])
-            self.assertEqual(mock.mock_calls, [])
-
-
-    def test_adding_return_value_mock(self):
-        for Klass in Mock, MagicMock:
-            mock = Klass()
-            mock.return_value = MagicMock()
-
-            mock()()
-            self.assertEqual(mock.mock_calls, [call(), call()()])
-
-
-    def test_manager_mock(self):
-        class Foo(object):
-            one = 'one'
-            two = 'two'
-        manager = Mock()
-        p1 = patch.object(Foo, 'one')
-        p2 = patch.object(Foo, 'two')
-
-        mock_one = p1.start()
-        self.addCleanup(p1.stop)
-        mock_two = p2.start()
-        self.addCleanup(p2.stop)
-
-        manager.attach_mock(mock_one, 'one')
-        manager.attach_mock(mock_two, 'two')
-
-        Foo.two()
-        Foo.one()
-
-        self.assertEqual(manager.mock_calls, [call.two(), call.one()])
-
-
-    def test_magic_methods_mock_calls(self):
-        for Klass in Mock, MagicMock:
-            m = Klass()
-            m.__int__ = Mock(return_value=3)
-            m.__float__ = MagicMock(return_value=3.0)
-            int(m)
-            float(m)
-
-            self.assertEqual(m.mock_calls, [call.__int__(), call.__float__()])
-            self.assertEqual(m.method_calls, [])
-
-    def test_mock_open_reuse_issue_21750(self):
-        mocked_open = mock.mock_open(read_data='data')
-        f1 = mocked_open('a-name')
-        f1_data = f1.read()
-        f2 = mocked_open('another-name')
-        f2_data = f2.read()
-        self.assertEqual(f1_data, f2_data)
-
-    def test_mock_open_dunder_iter_issue(self):
-        # Test dunder_iter method generates the expected result and
-        # consumes the iterator.
-        mocked_open = mock.mock_open(read_data='Remarkable\nNorwegian Blue')
-        f1 = mocked_open('a-name')
-        lines = [line for line in f1]
-        self.assertEqual(lines[0], 'Remarkable\n')
-        self.assertEqual(lines[1], 'Norwegian Blue')
-        self.assertEqual(list(f1), [])
-
-    def test_mock_open_write(self):
-        # Test exception in file writing write()
-        mock_namedtemp = mock.mock_open(mock.MagicMock(name='JLV'))
-        with mock.patch('tempfile.NamedTemporaryFile', mock_namedtemp):
-            mock_filehandle = mock_namedtemp.return_value
-            mock_write = mock_filehandle.write
-            mock_write.side_effect = OSError('Test 2 Error')
-            def attempt():
-                tempfile.NamedTemporaryFile().write('asd')
-            self.assertRaises(OSError, attempt)
-
-    def test_mock_open_alter_readline(self):
-        mopen = mock.mock_open(read_data='foo\nbarn')
-        mopen.return_value.readline.side_effect = lambda *args:'abc'
-        first = mopen().readline()
-        second = mopen().readline()
-        self.assertEqual('abc', first)
-        self.assertEqual('abc', second)
-
-
-    def test_mock_open_after_eof(self):
-        # read, readline and readlines should work after end of file.
-        _open = mock.mock_open(read_data='foo')
-        h = _open('bar')
-        h.read()
-        self.assertEqual('', h.read())
-        self.assertEqual('', h.read())
-        self.assertEqual('', h.readline())
-        self.assertEqual('', h.readline())
-        self.assertEqual([], h.readlines())
-        self.assertEqual([], h.readlines())
-
-
-    def test_mock_parents(self):
-        for Klass in Mock, MagicMock:
-            m = Klass()
-            original_repr = repr(m)
-            m.return_value = m
-            self.assertIs(m(), m)
-            self.assertEqual(repr(m), original_repr)
-
-            m.reset_mock()
-            self.assertIs(m(), m)
-            self.assertEqual(repr(m), original_repr)
-
-            m = Klass()
-            m.b = m.a
-            self.assertIn("name='mock.a'", repr(m.b))
-            self.assertIn("name='mock.a'", repr(m.a))
-            m.reset_mock()
-            self.assertIn("name='mock.a'", repr(m.b))
-            self.assertIn("name='mock.a'", repr(m.a))
-
-            m = Klass()
-            original_repr = repr(m)
-            m.a = m()
-            m.a.return_value = m
-
-            self.assertEqual(repr(m), original_repr)
-            self.assertEqual(repr(m.a()), original_repr)
-
-
-    def test_attach_mock(self):
-        classes = Mock, MagicMock, NonCallableMagicMock, NonCallableMock
-        for Klass in classes:
-            for Klass2 in classes:
-                m = Klass()
-
-                m2 = Klass2(name='foo')
-                m.attach_mock(m2, 'bar')
-
-                self.assertIs(m.bar, m2)
-                self.assertIn("name='mock.bar'", repr(m2))
-
-                m.bar.baz(1)
-                self.assertEqual(m.mock_calls, [call.bar.baz(1)])
-                self.assertEqual(m.method_calls, [call.bar.baz(1)])
-
-
-    def test_attach_mock_return_value(self):
-        classes = Mock, MagicMock, NonCallableMagicMock, NonCallableMock
-        for Klass in Mock, MagicMock:
-            for Klass2 in classes:
-                m = Klass()
-
-                m2 = Klass2(name='foo')
-                m.attach_mock(m2, 'return_value')
-
-                self.assertIs(m(), m2)
-                self.assertIn("name='mock()'", repr(m2))
-
-                m2.foo()
-                self.assertEqual(m.mock_calls, call().foo().call_list())
-
-
-    def test_attribute_deletion(self):
-        for mock in (Mock(), MagicMock(), NonCallableMagicMock(),
-                     NonCallableMock()):
-            self.assertTrue(hasattr(mock, 'm'))
-
-            del mock.m
-            self.assertFalse(hasattr(mock, 'm'))
-
-            del mock.f
-            self.assertFalse(hasattr(mock, 'f'))
-            self.assertRaises(AttributeError, getattr, mock, 'f')
-
-
-    def test_mock_does_not_raise_on_repeated_attribute_deletion(self):
-        # bpo-20239: Assigning and deleting twice an attribute raises.
-        for mock in (Mock(), MagicMock(), NonCallableMagicMock(),
-                     NonCallableMock()):
-            mock.foo = 3
-            self.assertTrue(hasattr(mock, 'foo'))
-            self.assertEqual(mock.foo, 3)
-
-            del mock.foo
-            self.assertFalse(hasattr(mock, 'foo'))
-
-            mock.foo = 4
-            self.assertTrue(hasattr(mock, 'foo'))
-            self.assertEqual(mock.foo, 4)
-
-            del mock.foo
-            self.assertFalse(hasattr(mock, 'foo'))
-
-
-    def test_mock_raises_when_deleting_nonexistent_attribute(self):
-        for mock in (Mock(), MagicMock(), NonCallableMagicMock(),
-                     NonCallableMock()):
-            del mock.foo
-            with self.assertRaises(AttributeError):
-                del mock.foo
-
-
-    def test_reset_mock_does_not_raise_on_attr_deletion(self):
-        # bpo-31177: reset_mock should not raise AttributeError when attributes
-        # were deleted in a mock instance
-        mock = Mock()
-        mock.child = True
-        del mock.child
-        mock.reset_mock()
-        self.assertFalse(hasattr(mock, 'child'))
-
-
-    def test_class_assignable(self):
-        for mock in Mock(), MagicMock():
-            self.assertNotIsInstance(mock, int)
-
-            mock.__class__ = int
-            self.assertIsInstance(mock, int)
-            mock.foo
-
-    def test_name_attribute_of_call(self):
-        # bpo-35357: _Call should not disclose any attributes whose names
-        # may clash with popular ones (such as ".name")
-        self.assertIsNotNone(call.name)
-        self.assertEqual(type(call.name), _Call)
-        self.assertEqual(type(call.name().name), _Call)
-
-    def test_parent_attribute_of_call(self):
-        # bpo-35357: _Call should not disclose any attributes whose names
-        # may clash with popular ones (such as ".parent")
-        self.assertIsNotNone(call.parent)
-        self.assertEqual(type(call.parent), _Call)
-        self.assertEqual(type(call.parent().parent), _Call)
-
-    def test_parent_propagation_with_create_autospec(self):
-        def foo(a, b): pass
-
-        mock = Mock()
-        mock.child = create_autospec(foo)
-        mock.child(1, 2)
-        self.assertRaises(TypeError, mock.child, 1)
-        self.assertEqual(mock.mock_calls, [call.child(1, 2)])
-
-    def test_isinstance_under_settrace(self):
-        # bpo-36593 : __class__ is not set for a class that has __class__
-        # property defined when it's used with sys.settrace(trace) set.
-        # Delete the module to force reimport with tracing function set
-        # restore the old reference later since there are other tests that are
-        # dependent on unittest.mock.patch. In testpatch.PatchTest
-        # test_patch_dict_test_prefix and test_patch_test_prefix not restoring
-        # causes the objects patched to go out of sync
-        old_patch = mock.patch
-        # Directly using __setattr__ on unittest.mock causes current imported
-        # reference to be updated. Use a lambda so that during cleanup the
-        # re-imported new reference is updated.
-        self.addCleanup(lambda patch: setattr(mock, 'patch', patch),
-                        old_patch)
-        with patch.dict('sys.modules'):
-            del sys.modules['mock.mock']
-            # This trace will stop coverage being measured ;-)
-            def trace(frame, event, arg):  # pragma: no cover
-                return trace
-            self.addCleanup(sys.settrace, sys.gettrace())
-            sys.settrace(trace)
-            from mock.mock import (
-                Mock, MagicMock, NonCallableMock, NonCallableMagicMock
-            )
-            mocks = [
-                Mock, MagicMock, NonCallableMock, NonCallableMagicMock
-            ]
-            for mock_ in mocks:
-                obj = mock_(spec=Something)
-                self.assertIsInstance(obj, Something)
-
-
-if __name__ == '__main__':
-    unittest.main()
diff --git a/mock/tests/testpatch.py b/mock/tests/testpatch.py
deleted file mode 100644
index bbd6d26..0000000
--- a/mock/tests/testpatch.py
+++ /dev/null
@@ -1,1898 +0,0 @@
-# Copyright (C) 2007-2012 Michael Foord & the mock team
-# E-mail: fuzzyman AT voidspace DOT org DOT uk
-# http://www.voidspace.org.uk/python/mock/
-
-import os
-import sys
-
-import six
-import unittest
-
-from mock.tests import support
-from mock.tests.support import SomeClass, is_instance, uncache
-
-from mock import (
-    NonCallableMock, CallableMixin, patch, sentinel,
-    MagicMock, Mock, NonCallableMagicMock,
-    DEFAULT, call
-)
-from mock.mock import _patch, _get_target
-
-builtin_string = '__builtin__'
-if six.PY3:
-    builtin_string = 'builtins'
-    unicode = str
-
-PTModule = sys.modules[__name__]
-MODNAME = '%s.PTModule' % __name__
-
-
-def _get_proxy(obj, get_only=True):
-    class Proxy(object):
-        def __getattr__(self, name):
-            return getattr(obj, name)
-    if not get_only:
-        def __setattr__(self, name, value):
-            setattr(obj, name, value)
-        def __delattr__(self, name):
-            delattr(obj, name)
-        Proxy.__setattr__ = __setattr__
-        Proxy.__delattr__ = __delattr__
-    return Proxy()
-
-
-# for use in the test
-something  = sentinel.Something
-something_else  = sentinel.SomethingElse
-
-
-class Foo(object):
-    def __init__(self, a): pass
-    def f(self, a): pass
-    def g(self): pass
-    foo = 'bar'
-
-    @staticmethod
-    def static_method(): pass
-
-    @classmethod
-    def class_method(cls): pass
-
-    class Bar(object):
-        def a(self): pass
-
-foo_name = '%s.Foo' % __name__
-
-
-def function(a, b=Foo): pass
-
-
-class Container(object):
-    def __init__(self):
-        self.values = {}
-
-    def __getitem__(self, name):
-        return self.values[name]
-
-    def __setitem__(self, name, value):
-        self.values[name] = value
-
-    def __delitem__(self, name):
-        del self.values[name]
-
-    def __iter__(self):
-        return iter(self.values)
-
-
-
-class PatchTest(unittest.TestCase):
-
-    def assertNotCallable(self, obj, magic=True):
-        MockClass = NonCallableMagicMock
-        if not magic:
-            MockClass = NonCallableMock
-
-        self.assertRaises(TypeError, obj)
-        self.assertTrue(is_instance(obj, MockClass))
-        self.assertFalse(is_instance(obj, CallableMixin))
-
-
-    def test_single_patchobject(self):
-        class Something(object):
-            attribute = sentinel.Original
-
-        @patch.object(Something, 'attribute', sentinel.Patched)
-        def test():
-            self.assertEqual(Something.attribute, sentinel.Patched, "unpatched")
-
-        test()
-        self.assertEqual(Something.attribute, sentinel.Original,
-                         "patch not restored")
-
-
-    def test_patchobject_with_none(self):
-        class Something(object):
-            attribute = sentinel.Original
-
-        @patch.object(Something, 'attribute', None)
-        def test():
-            self.assertIsNone(Something.attribute, "unpatched")
-
-        test()
-        self.assertEqual(Something.attribute, sentinel.Original,
-                         "patch not restored")
-
-
-    def test_multiple_patchobject(self):
-        class Something(object):
-            attribute = sentinel.Original
-            next_attribute = sentinel.Original2
-
-        @patch.object(Something, 'attribute', sentinel.Patched)
-        @patch.object(Something, 'next_attribute', sentinel.Patched2)
-        def test():
-            self.assertEqual(Something.attribute, sentinel.Patched,
-                             "unpatched")
-            self.assertEqual(Something.next_attribute, sentinel.Patched2,
-                             "unpatched")
-
-        test()
-        self.assertEqual(Something.attribute, sentinel.Original,
-                         "patch not restored")
-        self.assertEqual(Something.next_attribute, sentinel.Original2,
-                         "patch not restored")
-
-
-    def test_object_lookup_is_quite_lazy(self):
-        global something
-        original = something
-        @patch('%s.something' % __name__, sentinel.Something2)
-        def test():
-            pass
-
-        try:
-            something = sentinel.replacement_value
-            test()
-            self.assertEqual(something, sentinel.replacement_value)
-        finally:
-            something = original
-
-
-    def test_patch(self):
-        @patch('%s.something' % __name__, sentinel.Something2)
-        def test():
-            self.assertEqual(PTModule.something, sentinel.Something2,
-                             "unpatched")
-
-        test()
-        self.assertEqual(PTModule.something, sentinel.Something,
-                         "patch not restored")
-
-        @patch('%s.something' % __name__, sentinel.Something2)
-        @patch('%s.something_else' % __name__, sentinel.SomethingElse)
-        def test():
-            self.assertEqual(PTModule.something, sentinel.Something2,
-                             "unpatched")
-            self.assertEqual(PTModule.something_else, sentinel.SomethingElse,
-                             "unpatched")
-
-        self.assertEqual(PTModule.something, sentinel.Something,
-                         "patch not restored")
-        self.assertEqual(PTModule.something_else, sentinel.SomethingElse,
-                         "patch not restored")
-
-        # Test the patching and restoring works a second time
-        test()
-
-        self.assertEqual(PTModule.something, sentinel.Something,
-                         "patch not restored")
-        self.assertEqual(PTModule.something_else, sentinel.SomethingElse,
-                         "patch not restored")
-
-        mock = Mock()
-        mock.return_value = sentinel.Handle
-        @patch('%s.open' % builtin_string, mock)
-        def test():
-            self.assertEqual(open('filename', 'r'), sentinel.Handle,
-                             "open not patched")
-        test()
-        test()
-
-        self.assertNotEqual(open, mock, "patch not restored")
-
-
-    def test_patch_class_attribute(self):
-        @patch('%s.SomeClass.class_attribute' % __name__,
-               sentinel.ClassAttribute)
-        def test():
-            self.assertEqual(PTModule.SomeClass.class_attribute,
-                             sentinel.ClassAttribute, "unpatched")
-        test()
-
-        self.assertIsNone(PTModule.SomeClass.class_attribute,
-                          "patch not restored")
-
-
-    def test_patchobject_with_default_mock(self):
-        class Test(object):
-            something = sentinel.Original
-            something2 = sentinel.Original2
-
-        @patch.object(Test, 'something')
-        def test(mock):
-            self.assertEqual(mock, Test.something,
-                             "Mock not passed into test function")
-            self.assertIsInstance(mock, MagicMock,
-                            "patch with two arguments did not create a mock")
-
-        test()
-
-        @patch.object(Test, 'something')
-        @patch.object(Test, 'something2')
-        def test(this1, this2, mock1, mock2):
-            self.assertEqual(this1, sentinel.this1,
-                             "Patched function didn't receive initial argument")
-            self.assertEqual(this2, sentinel.this2,
-                             "Patched function didn't receive second argument")
-            self.assertEqual(mock1, Test.something2,
-                             "Mock not passed into test function")
-            self.assertEqual(mock2, Test.something,
-                             "Second Mock not passed into test function")
-            self.assertIsInstance(mock2, MagicMock,
-                            "patch with two arguments did not create a mock")
-            self.assertIsInstance(mock2, MagicMock,
-                            "patch with two arguments did not create a mock")
-
-            # A hack to test that new mocks are passed the second time
-            self.assertNotEqual(outerMock1, mock1, "unexpected value for mock1")
-            self.assertNotEqual(outerMock2, mock2, "unexpected value for mock1")
-            return mock1, mock2
-
-        outerMock1 = outerMock2 = None
-        outerMock1, outerMock2 = test(sentinel.this1, sentinel.this2)
-
-        # Test that executing a second time creates new mocks
-        test(sentinel.this1, sentinel.this2)
-
-
-    def test_patch_with_spec(self):
-        @patch('%s.SomeClass' % __name__, spec=SomeClass)
-        def test(MockSomeClass):
-            self.assertEqual(SomeClass, MockSomeClass)
-            self.assertTrue(is_instance(SomeClass.wibble, MagicMock))
-            self.assertRaises(AttributeError, lambda: SomeClass.not_wibble)
-
-        test()
-
-
-    def test_patchobject_with_spec(self):
-        @patch.object(SomeClass, 'class_attribute', spec=SomeClass)
-        def test(MockAttribute):
-            self.assertEqual(SomeClass.class_attribute, MockAttribute)
-            self.assertTrue(is_instance(SomeClass.class_attribute.wibble,
-                                       MagicMock))
-            self.assertRaises(AttributeError,
-                              lambda: SomeClass.class_attribute.not_wibble)
-
-        test()
-
-
-    def test_patch_with_spec_as_list(self):
-        @patch('%s.SomeClass' % __name__, spec=['wibble'])
-        def test(MockSomeClass):
-            self.assertEqual(SomeClass, MockSomeClass)
-            self.assertTrue(is_instance(SomeClass.wibble, MagicMock))
-            self.assertRaises(AttributeError, lambda: SomeClass.not_wibble)
-
-        test()
-
-
-    def test_patchobject_with_spec_as_list(self):
-        @patch.object(SomeClass, 'class_attribute', spec=['wibble'])
-        def test(MockAttribute):
-            self.assertEqual(SomeClass.class_attribute, MockAttribute)
-            self.assertTrue(is_instance(SomeClass.class_attribute.wibble,
-                                       MagicMock))
-            self.assertRaises(AttributeError,
-                              lambda: SomeClass.class_attribute.not_wibble)
-
-        test()
-
-
-    def test_nested_patch_with_spec_as_list(self):
-        # regression test for nested decorators
-        @patch('%s.open' % builtin_string)
-        @patch('%s.SomeClass' % __name__, spec=['wibble'])
-        def test(MockSomeClass, MockOpen):
-            self.assertEqual(SomeClass, MockSomeClass)
-            self.assertTrue(is_instance(SomeClass.wibble, MagicMock))
-            self.assertRaises(AttributeError, lambda: SomeClass.not_wibble)
-        test()
-
-
-    def test_patch_with_spec_as_boolean(self):
-        @patch('%s.SomeClass' % __name__, spec=True)
-        def test(MockSomeClass):
-            self.assertEqual(SomeClass, MockSomeClass)
-            # Should not raise attribute error
-            MockSomeClass.wibble
-
-            self.assertRaises(AttributeError, lambda: MockSomeClass.not_wibble)
-
-        test()
-
-
-    def test_patch_object_with_spec_as_boolean(self):
-        @patch.object(PTModule, 'SomeClass', spec=True)
-        def test(MockSomeClass):
-            self.assertEqual(SomeClass, MockSomeClass)
-            # Should not raise attribute error
-            MockSomeClass.wibble
-
-            self.assertRaises(AttributeError, lambda: MockSomeClass.not_wibble)
-
-        test()
-
-
-    def test_patch_class_acts_with_spec_is_inherited(self):
-        @patch('%s.SomeClass' % __name__, spec=True)
-        def test(MockSomeClass):
-            self.assertTrue(is_instance(MockSomeClass, MagicMock))
-            instance = MockSomeClass()
-            self.assertNotCallable(instance)
-            # Should not raise attribute error
-            instance.wibble
-
-            self.assertRaises(AttributeError, lambda: instance.not_wibble)
-
-        test()
-
-
-    def test_patch_with_create_mocks_non_existent_attributes(self):
-        @patch('%s.frooble' % builtin_string, sentinel.Frooble, create=True)
-        def test():
-            self.assertEqual(frooble, sentinel.Frooble)
-
-        test()
-        self.assertRaises(NameError, lambda: frooble)
-
-
-    def test_patchobject_with_create_mocks_non_existent_attributes(self):
-        @patch.object(SomeClass, 'frooble', sentinel.Frooble, create=True)
-        def test():
-            self.assertEqual(SomeClass.frooble, sentinel.Frooble)
-
-        test()
-        self.assertFalse(hasattr(SomeClass, 'frooble'))
-
-
-    def test_patch_wont_create_by_default(self):
-        with self.assertRaises(AttributeError):
-            @patch('%s.frooble' % builtin_string, sentinel.Frooble)
-            def test(): pass
-
-            test()
-        self.assertRaises(NameError, lambda: frooble)
-
-
-    def test_patchobject_wont_create_by_default(self):
-        with self.assertRaises(AttributeError):
-            @patch.object(SomeClass, 'ord', sentinel.Frooble)
-            def test(): pass
-            test()
-        self.assertFalse(hasattr(SomeClass, 'ord'))
-
-
-    def test_patch_builtins_without_create(self):
-        @patch(__name__+'.ord')
-        def test_ord(mock_ord):
-            mock_ord.return_value = 101
-            return ord('c')
-
-        @patch(__name__+'.open')
-        def test_open(mock_open):
-            m = mock_open.return_value
-            m.read.return_value = 'abcd'
-
-            fobj = open('doesnotexists.txt')
-            data = fobj.read()
-            fobj.close()
-            return data
-
-        self.assertEqual(test_ord(), 101)
-        self.assertEqual(test_open(), 'abcd')
-
-
-    def test_patch_with_static_methods(self):
-        class Foo(object):
-            @staticmethod
-            def woot():
-                return sentinel.Static
-
-        @patch.object(Foo, 'woot', staticmethod(lambda: sentinel.Patched))
-        def anonymous():
-            self.assertEqual(Foo.woot(), sentinel.Patched)
-        anonymous()
-
-        self.assertEqual(Foo.woot(), sentinel.Static)
-
-
-    def test_patch_local(self):
-        foo = sentinel.Foo
-        @patch.object(sentinel, 'Foo', 'Foo')
-        def anonymous():
-            self.assertEqual(sentinel.Foo, 'Foo')
-        anonymous()
-
-        self.assertEqual(sentinel.Foo, foo)
-
-
-    def test_patch_slots(self):
-        class Foo(object):
-            __slots__ = ('Foo',)
-
-        foo = Foo()
-        foo.Foo = sentinel.Foo
-
-        @patch.object(foo, 'Foo', 'Foo')
-        def anonymous():
-            self.assertEqual(foo.Foo, 'Foo')
-        anonymous()
-
-        self.assertEqual(foo.Foo, sentinel.Foo)
-
-
-    def test_patchobject_class_decorator(self):
-        class Something(object):
-            attribute = sentinel.Original
-
-        class Foo(object):
-            def test_method(other_self):
-                self.assertEqual(Something.attribute, sentinel.Patched,
-                                 "unpatched")
-            def not_test_method(other_self):
-                self.assertEqual(Something.attribute, sentinel.Original,
-                                 "non-test method patched")
-
-        Foo = patch.object(Something, 'attribute', sentinel.Patched)(Foo)
-
-        f = Foo()
-        f.test_method()
-        f.not_test_method()
-
-        self.assertEqual(Something.attribute, sentinel.Original,
-                         "patch not restored")
-
-
-    def test_patch_class_decorator(self):
-        class Something(object):
-            attribute = sentinel.Original
-
-        class Foo(object):
-
-            test_class_attr = 'whatever'
-
-            def test_method(other_self, mock_something):
-                self.assertEqual(PTModule.something, mock_something,
-                                 "unpatched")
-            def not_test_method(other_self):
-                self.assertEqual(PTModule.something, sentinel.Something,
-                                 "non-test method patched")
-        Foo = patch('%s.something' % __name__)(Foo)
-
-        f = Foo()
-        f.test_method()
-        f.not_test_method()
-
-        self.assertEqual(Something.attribute, sentinel.Original,
-                         "patch not restored")
-        self.assertEqual(PTModule.something, sentinel.Something,
-                         "patch not restored")
-
-
-    def test_patchobject_twice(self):
-        class Something(object):
-            attribute = sentinel.Original
-            next_attribute = sentinel.Original2
-
-        @patch.object(Something, 'attribute', sentinel.Patched)
-        @patch.object(Something, 'attribute', sentinel.Patched)
-        def test():
-            self.assertEqual(Something.attribute, sentinel.Patched, "unpatched")
-
-        test()
-
-        self.assertEqual(Something.attribute, sentinel.Original,
-                         "patch not restored")
-
-
-    def test_patch_dict(self):
-        foo = {'initial': object(), 'other': 'something'}
-        original = foo.copy()
-
-        @patch.dict(foo)
-        def test():
-            foo['a'] = 3
-            del foo['initial']
-            foo['other'] = 'something else'
-
-        test()
-
-        self.assertEqual(foo, original)
-
-        @patch.dict(foo, {'a': 'b'})
-        def test():
-            self.assertEqual(len(foo), 3)
-            self.assertEqual(foo['a'], 'b')
-
-        test()
-
-        self.assertEqual(foo, original)
-
-        @patch.dict(foo, [('a', 'b')])
-        def test():
-            self.assertEqual(len(foo), 3)
-            self.assertEqual(foo['a'], 'b')
-
-        test()
-
-        self.assertEqual(foo, original)
-
-
-    def test_patch_dict_with_container_object(self):
-        foo = Container()
-        foo['initial'] = object()
-        foo['other'] =  'something'
-
-        original = foo.values.copy()
-
-        @patch.dict(foo)
-        def test():
-            foo['a'] = 3
-            del foo['initial']
-            foo['other'] = 'something else'
-
-        test()
-
-        self.assertEqual(foo.values, original)
-
-        @patch.dict(foo, {'a': 'b'})
-        def test():
-            self.assertEqual(len(foo.values), 3)
-            self.assertEqual(foo['a'], 'b')
-
-        test()
-
-        self.assertEqual(foo.values, original)
-
-
-    def test_patch_dict_with_clear(self):
-        foo = {'initial': object(), 'other': 'something'}
-        original = foo.copy()
-
-        @patch.dict(foo, clear=True)
-        def test():
-            self.assertEqual(foo, {})
-            foo['a'] = 3
-            foo['other'] = 'something else'
-
-        test()
-
-        self.assertEqual(foo, original)
-
-        @patch.dict(foo, {'a': 'b'}, clear=True)
-        def test():
-            self.assertEqual(foo, {'a': 'b'})
-
-        test()
-
-        self.assertEqual(foo, original)
-
-        @patch.dict(foo, [('a', 'b')], clear=True)
-        def test():
-            self.assertEqual(foo, {'a': 'b'})
-
-        test()
-
-        self.assertEqual(foo, original)
-
-
-    def test_patch_dict_with_container_object_and_clear(self):
-        foo = Container()
-        foo['initial'] = object()
-        foo['other'] =  'something'
-
-        original = foo.values.copy()
-
-        @patch.dict(foo, clear=True)
-        def test():
-            self.assertEqual(foo.values, {})
-            foo['a'] = 3
-            foo['other'] = 'something else'
-
-        test()
-
-        self.assertEqual(foo.values, original)
-
-        @patch.dict(foo, {'a': 'b'}, clear=True)
-        def test():
-            self.assertEqual(foo.values, {'a': 'b'})
-
-        test()
-
-        self.assertEqual(foo.values, original)
-
-
-    def test_name_preserved(self):
-        foo = {}
-
-        @patch('%s.SomeClass' % __name__, object())
-        @patch('%s.SomeClass' % __name__, object(), autospec=True)
-        @patch.object(SomeClass, object())
-        @patch.dict(foo)
-        def some_name(): pass
-
-        self.assertEqual(some_name.__name__, 'some_name')
-
-
-    def test_patch_with_exception(self):
-        foo = {}
-
-        @patch.dict(foo, {'a': 'b'})
-        def test():
-            raise NameError('Konrad')
-
-        with self.assertRaises(NameError):
-            test()
-
-        self.assertEqual(foo, {})
-
-
-    def test_patch_dict_with_string(self):
-        @patch.dict('os.environ', {'konrad_delong': 'some value'})
-        def test():
-            self.assertIn('konrad_delong', os.environ)
-
-        test()
-
-
-    def test_patch_dict_with_unicode(self):
-        @patch.dict(u'os.environ', {'konrad_delong': 'some value'})
-        def test():
-            self.assertIn('konrad_delong', os.environ)
-
-        test()
-
-
-    def test_patch_dict_decorator_resolution(self):
-        # bpo-35512: Ensure that patch with a string target resolves to
-        # the new dictionary during function call
-        original = support.target.copy()
-        @patch.dict('mock.tests.support.target', {'bar': 'BAR'})
-        def test():
-            self.assertEqual(support.target, {'foo': 'BAZ', 'bar': 'BAR'})
-        try:
-            support.target = {'foo': 'BAZ'}
-            test()
-            self.assertEqual(support.target, {'foo': 'BAZ'})
-        finally:
-            support.target = original
-
-
-    def test_patch_spec_set(self):
-        @patch('%s.SomeClass' % __name__, spec=SomeClass, spec_set=True)
-        def test(MockClass):
-            MockClass.z = 'foo'
-
-        self.assertRaises(AttributeError, test)
-
-        @patch.object(support, 'SomeClass', spec=SomeClass, spec_set=True)
-        def test(MockClass):
-            MockClass.z = 'foo'
-
-        self.assertRaises(AttributeError, test)
-        @patch('%s.SomeClass' % __name__, spec_set=True)
-        def test(MockClass):
-            MockClass.z = 'foo'
-
-        self.assertRaises(AttributeError, test)
-
-        @patch.object(support, 'SomeClass', spec_set=True)
-        def test(MockClass):
-            MockClass.z = 'foo'
-
-        self.assertRaises(AttributeError, test)
-
-
-    def test_spec_set_inherit(self):
-        @patch('%s.SomeClass' % __name__, spec_set=True)
-        def test(MockClass):
-            instance = MockClass()
-            instance.z = 'foo'
-
-        self.assertRaises(AttributeError, test)
-
-
-    def test_patch_start_stop(self):
-        original = something
-        patcher = patch('%s.something' % __name__)
-        self.assertIs(something, original)
-        mock = patcher.start()
-        try:
-            self.assertIsNot(mock, original)
-            self.assertIs(something, mock)
-        finally:
-            patcher.stop()
-        self.assertIs(something, original)
-
-
-    def test_stop_without_start(self):
-        # bpo-36366: calling stop without start will return None.
-        patcher = patch(foo_name, 'bar', 3)
-        self.assertIsNone(patcher.stop())
-
-
-    def test_stop_idempotent(self):
-        # bpo-36366: calling stop on an already stopped patch will return None.
-        patcher = patch(foo_name, 'bar', 3)
-
-        patcher.start()
-        patcher.stop()
-        self.assertIsNone(patcher.stop())
-
-
-    def test_patchobject_start_stop(self):
-        original = something
-        patcher = patch.object(PTModule, 'something', 'foo')
-        self.assertIs(something, original)
-        replaced = patcher.start()
-        try:
-            self.assertEqual(replaced, 'foo')
-            self.assertIs(something, replaced)
-        finally:
-            patcher.stop()
-        self.assertIs(something, original)
-
-
-    def test_patch_dict_start_stop(self):
-        d = {'foo': 'bar'}
-        original = d.copy()
-        patcher = patch.dict(d, [('spam', 'eggs')], clear=True)
-        self.assertEqual(d, original)
-
-        patcher.start()
-        try:
-            self.assertEqual(d, {'spam': 'eggs'})
-        finally:
-            patcher.stop()
-        self.assertEqual(d, original)
-
-
-    def test_patch_dict_class_decorator(self):
-        this = self
-        d = {'spam': 'eggs'}
-        original = d.copy()
-
-        class Test(object):
-            def test_first(self):
-                this.assertEqual(d, {'foo': 'bar'})
-            def test_second(self):
-                this.assertEqual(d, {'foo': 'bar'})
-
-        Test = patch.dict(d, {'foo': 'bar'}, clear=True)(Test)
-        self.assertEqual(d, original)
-
-        test = Test()
-
-        test.test_first()
-        self.assertEqual(d, original)
-
-        test.test_second()
-        self.assertEqual(d, original)
-
-        test = Test()
-
-        test.test_first()
-        self.assertEqual(d, original)
-
-        test.test_second()
-        self.assertEqual(d, original)
-
-
-    def test_get_only_proxy(self):
-        class Something(object):
-            foo = 'foo'
-        class SomethingElse:
-            foo = 'foo'
-
-        for thing in Something, SomethingElse, Something(), SomethingElse:
-            proxy = _get_proxy(thing)
-
-            @patch.object(proxy, 'foo', 'bar')
-            def test():
-                self.assertEqual(proxy.foo, 'bar')
-            test()
-            self.assertEqual(proxy.foo, 'foo')
-            self.assertEqual(thing.foo, 'foo')
-            self.assertNotIn('foo', proxy.__dict__)
-
-
-    def test_get_set_delete_proxy(self):
-        class Something(object):
-            foo = 'foo'
-        class SomethingElse:
-            foo = 'foo'
-
-        for thing in Something, SomethingElse, Something(), SomethingElse:
-            proxy = _get_proxy(Something, get_only=False)
-
-            @patch.object(proxy, 'foo', 'bar')
-            def test():
-                self.assertEqual(proxy.foo, 'bar')
-            test()
-            self.assertEqual(proxy.foo, 'foo')
-            self.assertEqual(thing.foo, 'foo')
-            self.assertNotIn('foo', proxy.__dict__)
-
-
-    def test_patch_keyword_args(self):
-        kwargs = {'side_effect': KeyError, 'foo.bar.return_value': 33,
-                  'foo': MagicMock()}
-
-        patcher = patch(foo_name, **kwargs)
-        mock = patcher.start()
-        patcher.stop()
-
-        self.assertRaises(KeyError, mock)
-        self.assertEqual(mock.foo.bar(), 33)
-        self.assertIsInstance(mock.foo, MagicMock)
-
-
-    def test_patch_object_keyword_args(self):
-        kwargs = {'side_effect': KeyError, 'foo.bar.return_value': 33,
-                  'foo': MagicMock()}
-
-        patcher = patch.object(Foo, 'f', **kwargs)
-        mock = patcher.start()
-        patcher.stop()
-
-        self.assertRaises(KeyError, mock)
-        self.assertEqual(mock.foo.bar(), 33)
-        self.assertIsInstance(mock.foo, MagicMock)
-
-
-    def test_patch_dict_keyword_args(self):
-        original = {'foo': 'bar'}
-        copy = original.copy()
-
-        patcher = patch.dict(original, foo=3, bar=4, baz=5)
-        patcher.start()
-
-        try:
-            self.assertEqual(original, dict(foo=3, bar=4, baz=5))
-        finally:
-            patcher.stop()
-
-        self.assertEqual(original, copy)
-
-
-    def test_autospec(self):
-        class Boo(object):
-            def __init__(self, a): pass
-            def f(self, a): pass
-            def g(self): pass
-            foo = 'bar'
-
-            class Bar(object):
-                def a(self): pass
-
-        def _test(mock):
-            mock(1)
-            mock.assert_called_with(1)
-            self.assertRaises(TypeError, mock)
-
-        def _test2(mock):
-            mock.f(1)
-            mock.f.assert_called_with(1)
-            self.assertRaises(TypeError, mock.f)
-
-            mock.g()
-            mock.g.assert_called_with()
-            self.assertRaises(TypeError, mock.g, 1)
-
-            self.assertRaises(AttributeError, getattr, mock, 'h')
-
-            mock.foo.lower()
-            mock.foo.lower.assert_called_with()
-            self.assertRaises(AttributeError, getattr, mock.foo, 'bar')
-
-            mock.Bar()
-            mock.Bar.assert_called_with()
-
-            mock.Bar.a()
-            mock.Bar.a.assert_called_with()
-            self.assertRaises(TypeError, mock.Bar.a, 1)
-
-            mock.Bar().a()
-            mock.Bar().a.assert_called_with()
-            self.assertRaises(TypeError, mock.Bar().a, 1)
-
-            self.assertRaises(AttributeError, getattr, mock.Bar, 'b')
-            self.assertRaises(AttributeError, getattr, mock.Bar(), 'b')
-
-        def function(mock):
-            _test(mock)
-            _test2(mock)
-            _test2(mock(1))
-            self.assertIs(mock, Foo)
-            return mock
-
-        test = patch(foo_name, autospec=True)(function)
-
-        mock = test()
-        self.assertIsNot(Foo, mock)
-        # test patching a second time works
-        test()
-
-        module = sys.modules[__name__]
-        test = patch.object(module, 'Foo', autospec=True)(function)
-
-        mock = test()
-        self.assertIsNot(Foo, mock)
-        # test patching a second time works
-        test()
-
-
-    def test_autospec_function(self):
-        @patch('%s.function' % __name__, autospec=True)
-        def test(mock):
-            function.assert_not_called()
-            self.assertRaises(AssertionError, function.assert_called)
-            self.assertRaises(AssertionError, function.assert_called_once)
-            function(1)
-            self.assertRaises(AssertionError, function.assert_not_called)
-            function.assert_called_with(1)
-            function.assert_called()
-            function.assert_called_once()
-            function(2, 3)
-            function.assert_called_with(2, 3)
-
-            self.assertRaises(TypeError, function)
-            self.assertRaises(AttributeError, getattr, function, 'foo')
-
-        test()
-
-
-    def test_autospec_keywords(self):
-        @patch('%s.function' % __name__, autospec=True,
-               return_value=3)
-        def test(mock_function):
-            #self.assertEqual(function.abc, 'foo')
-            return function(1, 2)
-
-        result = test()
-        self.assertEqual(result, 3)
-
-
-    def test_autospec_staticmethod(self):
-        with patch('%s.Foo.static_method' % __name__, autospec=True) as method:
-            Foo.static_method()
-            method.assert_called_once_with()
-
-
-    def test_autospec_classmethod(self):
-        with patch('%s.Foo.class_method' % __name__, autospec=True) as method:
-            Foo.class_method()
-            method.assert_called_once_with()
-
-
-    def test_autospec_with_new(self):
-        patcher = patch('%s.function' % __name__, new=3, autospec=True)
-        self.assertRaises(TypeError, patcher.start)
-
-        module = sys.modules[__name__]
-        patcher = patch.object(module, 'function', new=3, autospec=True)
-        self.assertRaises(TypeError, patcher.start)
-
-
-    def test_autospec_with_object(self):
-        class Bar(Foo):
-            extra = []
-
-        patcher = patch(foo_name, autospec=Bar)
-        mock = patcher.start()
-        try:
-            self.assertIsInstance(mock, Bar)
-            self.assertIsInstance(mock.extra, list)
-        finally:
-            patcher.stop()
-
-
-    def test_autospec_inherits(self):
-        FooClass = Foo
-        patcher = patch(foo_name, autospec=True)
-        mock = patcher.start()
-        try:
-            self.assertIsInstance(mock, FooClass)
-            self.assertIsInstance(mock(3), FooClass)
-        finally:
-            patcher.stop()
-
-
-    def test_autospec_name(self):
-        patcher = patch(foo_name, autospec=True)
-        mock = patcher.start()
-
-        try:
-            self.assertIn(" name='Foo'", repr(mock))
-            self.assertIn(" name='Foo.f'", repr(mock.f))
-            self.assertIn(" name='Foo()'", repr(mock(None)))
-            self.assertIn(" name='Foo().f'", repr(mock(None).f))
-        finally:
-            patcher.stop()
-
-
-    def test_tracebacks(self):
-        @patch.object(Foo, 'f', object())
-        def test():
-            raise AssertionError
-        try:
-            test()
-        except:
-            err = sys.exc_info()
-
-        result = unittest.TextTestResult(None, None, 0)
-        traceback = result._exc_info_to_string(err, self)
-        self.assertIn('raise AssertionError', traceback)
-
-
-    def test_new_callable_patch(self):
-        patcher = patch(foo_name, new_callable=NonCallableMagicMock)
-
-        m1 = patcher.start()
-        patcher.stop()
-        m2 = patcher.start()
-        patcher.stop()
-
-        self.assertIsNot(m1, m2)
-        for mock in m1, m2:
-            self.assertNotCallable(m1)
-
-
-    def test_new_callable_patch_object(self):
-        patcher = patch.object(Foo, 'f', new_callable=NonCallableMagicMock)
-
-        m1 = patcher.start()
-        patcher.stop()
-        m2 = patcher.start()
-        patcher.stop()
-
-        self.assertIsNot(m1, m2)
-        for mock in m1, m2:
-            self.assertNotCallable(m1)
-
-
-    def test_new_callable_keyword_arguments(self):
-        class Bar(object):
-            kwargs = None
-            def __init__(self, **kwargs):
-                Bar.kwargs = kwargs
-
-        patcher = patch(foo_name, new_callable=Bar, arg1=1, arg2=2)
-        m = patcher.start()
-        try:
-            self.assertIs(type(m), Bar)
-            self.assertEqual(Bar.kwargs, dict(arg1=1, arg2=2))
-        finally:
-            patcher.stop()
-
-
-    def test_new_callable_spec(self):
-        class Bar(object):
-            kwargs = None
-            def __init__(self, **kwargs):
-                Bar.kwargs = kwargs
-
-        patcher = patch(foo_name, new_callable=Bar, spec=Bar)
-        patcher.start()
-        try:
-            self.assertEqual(Bar.kwargs, dict(spec=Bar))
-        finally:
-            patcher.stop()
-
-        patcher = patch(foo_name, new_callable=Bar, spec_set=Bar)
-        patcher.start()
-        try:
-            self.assertEqual(Bar.kwargs, dict(spec_set=Bar))
-        finally:
-            patcher.stop()
-
-
-    def test_new_callable_create(self):
-        non_existent_attr = '%s.weeeee' % foo_name
-        p = patch(non_existent_attr, new_callable=NonCallableMock)
-        self.assertRaises(AttributeError, p.start)
-
-        p = patch(non_existent_attr, new_callable=NonCallableMock,
-                  create=True)
-        m = p.start()
-        try:
-            self.assertNotCallable(m, magic=False)
-        finally:
-            p.stop()
-
-
-    def test_new_callable_incompatible_with_new(self):
-        self.assertRaises(
-            ValueError, patch, foo_name, new=object(), new_callable=MagicMock
-        )
-        self.assertRaises(
-            ValueError, patch.object, Foo, 'f', new=object(),
-            new_callable=MagicMock
-        )
-
-
-    def test_new_callable_incompatible_with_autospec(self):
-        self.assertRaises(
-            ValueError, patch, foo_name, new_callable=MagicMock,
-            autospec=True
-        )
-        self.assertRaises(
-            ValueError, patch.object, Foo, 'f', new_callable=MagicMock,
-            autospec=True
-        )
-
-
-    def test_new_callable_inherit_for_mocks(self):
-        class MockSub(Mock):
-            pass
-
-        MockClasses = (
-            NonCallableMock, NonCallableMagicMock, MagicMock, Mock, MockSub
-        )
-        for Klass in MockClasses:
-            for arg in 'spec', 'spec_set':
-                kwargs = {arg: True}
-                p = patch(foo_name, new_callable=Klass, **kwargs)
-                m = p.start()
-                try:
-                    instance = m.return_value
-                    self.assertRaises(AttributeError, getattr, instance, 'x')
-                finally:
-                    p.stop()
-
-
-    def test_new_callable_inherit_non_mock(self):
-        class NotAMock(object):
-            def __init__(self, spec):
-                self.spec = spec
-
-        p = patch(foo_name, new_callable=NotAMock, spec=True)
-        m = p.start()
-        try:
-            self.assertTrue(is_instance(m, NotAMock))
-            self.assertRaises(AttributeError, getattr, m, 'return_value')
-        finally:
-            p.stop()
-
-        self.assertEqual(m.spec, Foo)
-
-
-    def test_new_callable_class_decorating(self):
-        test = self
-        original = Foo
-        class SomeTest(object):
-
-            def _test(self, mock_foo):
-                test.assertIsNot(Foo, original)
-                test.assertIs(Foo, mock_foo)
-                test.assertIsInstance(Foo, SomeClass)
-
-            def test_two(self, mock_foo):
-                self._test(mock_foo)
-            def test_one(self, mock_foo):
-                self._test(mock_foo)
-
-        SomeTest = patch(foo_name, new_callable=SomeClass)(SomeTest)
-        SomeTest().test_one()
-        SomeTest().test_two()
-        self.assertIs(Foo, original)
-
-
-    def test_patch_multiple(self):
-        original_foo = Foo
-        original_f = Foo.f
-        original_g = Foo.g
-
-        patcher1 = patch.multiple(foo_name, f=1, g=2)
-        patcher2 = patch.multiple(Foo, f=1, g=2)
-
-        for patcher in patcher1, patcher2:
-            patcher.start()
-            try:
-                self.assertIs(Foo, original_foo)
-                self.assertEqual(Foo.f, 1)
-                self.assertEqual(Foo.g, 2)
-            finally:
-                patcher.stop()
-
-            self.assertIs(Foo, original_foo)
-            self.assertEqual(Foo.f, original_f)
-            self.assertEqual(Foo.g, original_g)
-
-
-        @patch.multiple(foo_name, f=3, g=4)
-        def test():
-            self.assertIs(Foo, original_foo)
-            self.assertEqual(Foo.f, 3)
-            self.assertEqual(Foo.g, 4)
-
-        test()
-
-
-    def test_patch_multiple_no_kwargs(self):
-        self.assertRaises(ValueError, patch.multiple, foo_name)
-        self.assertRaises(ValueError, patch.multiple, Foo)
-
-
-    def test_patch_multiple_create_mocks(self):
-        original_foo = Foo
-        original_f = Foo.f
-        original_g = Foo.g
-
-        @patch.multiple(foo_name, f=DEFAULT, g=3, foo=DEFAULT)
-        def test(f, foo):
-            self.assertIs(Foo, original_foo)
-            self.assertIs(Foo.f, f)
-            self.assertEqual(Foo.g, 3)
-            self.assertIs(Foo.foo, foo)
-            self.assertTrue(is_instance(f, MagicMock))
-            self.assertTrue(is_instance(foo, MagicMock))
-
-        test()
-        self.assertEqual(Foo.f, original_f)
-        self.assertEqual(Foo.g, original_g)
-
-
-    def test_patch_multiple_create_mocks_different_order(self):
-        original_f = Foo.f
-        original_g = Foo.g
-
-        patcher = patch.object(Foo, 'f', 3)
-        patcher.attribute_name = 'f'
-
-        other = patch.object(Foo, 'g', DEFAULT)
-        other.attribute_name = 'g'
-        patcher.additional_patchers = [other]
-
-        @patcher
-        def test(g):
-            self.assertIs(Foo.g, g)
-            self.assertEqual(Foo.f, 3)
-
-        test()
-        self.assertEqual(Foo.f, original_f)
-        self.assertEqual(Foo.g, original_g)
-
-
-    def test_patch_multiple_stacked_decorators(self):
-        original_foo = Foo
-        original_f = Foo.f
-        original_g = Foo.g
-
-        @patch.multiple(foo_name, f=DEFAULT)
-        @patch.multiple(foo_name, foo=DEFAULT)
-        @patch(foo_name + '.g')
-        def test1(g, **kwargs):
-            _test(g, **kwargs)
-
-        @patch.multiple(foo_name, f=DEFAULT)
-        @patch(foo_name + '.g')
-        @patch.multiple(foo_name, foo=DEFAULT)
-        def test2(g, **kwargs):
-            _test(g, **kwargs)
-
-        @patch(foo_name + '.g')
-        @patch.multiple(foo_name, f=DEFAULT)
-        @patch.multiple(foo_name, foo=DEFAULT)
-        def test3(g, **kwargs):
-            _test(g, **kwargs)
-
-        def _test(g, **kwargs):
-            f = kwargs.pop('f')
-            foo = kwargs.pop('foo')
-            self.assertFalse(kwargs)
-
-            self.assertIs(Foo, original_foo)
-            self.assertIs(Foo.f, f)
-            self.assertIs(Foo.g, g)
-            self.assertIs(Foo.foo, foo)
-            self.assertTrue(is_instance(f, MagicMock))
-            self.assertTrue(is_instance(g, MagicMock))
-            self.assertTrue(is_instance(foo, MagicMock))
-
-        test1()
-        test2()
-        test3()
-        self.assertEqual(Foo.f, original_f)
-        self.assertEqual(Foo.g, original_g)
-
-
-    def test_patch_multiple_create_mocks_patcher(self):
-        original_foo = Foo
-        original_f = Foo.f
-        original_g = Foo.g
-
-        patcher = patch.multiple(foo_name, f=DEFAULT, g=3, foo=DEFAULT)
-
-        result = patcher.start()
-        try:
-            f = result['f']
-            foo = result['foo']
-            self.assertEqual(set(result), {'f', 'foo'})
-
-            self.assertIs(Foo, original_foo)
-            self.assertIs(Foo.f, f)
-            self.assertIs(Foo.foo, foo)
-            self.assertTrue(is_instance(f, MagicMock))
-            self.assertTrue(is_instance(foo, MagicMock))
-        finally:
-            patcher.stop()
-
-        self.assertEqual(Foo.f, original_f)
-        self.assertEqual(Foo.g, original_g)
-
-
-    def test_patch_multiple_decorating_class(self):
-        test = self
-        original_foo = Foo
-        original_f = Foo.f
-        original_g = Foo.g
-
-        class SomeTest(object):
-
-            def _test(self, f, foo):
-                test.assertIs(Foo, original_foo)
-                test.assertIs(Foo.f, f)
-                test.assertEqual(Foo.g, 3)
-                test.assertIs(Foo.foo, foo)
-                test.assertTrue(is_instance(f, MagicMock))
-                test.assertTrue(is_instance(foo, MagicMock))
-
-            def test_two(self, f, foo):
-                self._test(f, foo)
-            def test_one(self, f, foo):
-                self._test(f, foo)
-
-        SomeTest = patch.multiple(
-            foo_name, f=DEFAULT, g=3, foo=DEFAULT
-        )(SomeTest)
-
-        thing = SomeTest()
-        thing.test_one()
-        thing.test_two()
-
-        self.assertEqual(Foo.f, original_f)
-        self.assertEqual(Foo.g, original_g)
-
-
-    def test_patch_multiple_create(self):
-        patcher = patch.multiple(Foo, blam='blam')
-        self.assertRaises(AttributeError, patcher.start)
-
-        patcher = patch.multiple(Foo, blam='blam', create=True)
-        patcher.start()
-        try:
-            self.assertEqual(Foo.blam, 'blam')
-        finally:
-            patcher.stop()
-
-        self.assertFalse(hasattr(Foo, 'blam'))
-
-
-    def test_patch_multiple_spec_set(self):
-        # if spec_set works then we can assume that spec and autospec also
-        # work as the underlying machinery is the same
-        patcher = patch.multiple(Foo, foo=DEFAULT, spec_set=['a', 'b'])
-        result = patcher.start()
-        try:
-            self.assertEqual(Foo.foo, result['foo'])
-            Foo.foo.a(1)
-            Foo.foo.b(2)
-            Foo.foo.a.assert_called_with(1)
-            Foo.foo.b.assert_called_with(2)
-            self.assertRaises(AttributeError, setattr, Foo.foo, 'c', None)
-        finally:
-            patcher.stop()
-
-
-    def test_patch_multiple_new_callable(self):
-        class Thing(object):
-            pass
-
-        patcher = patch.multiple(
-            Foo, f=DEFAULT, g=DEFAULT, new_callable=Thing
-        )
-        result = patcher.start()
-        try:
-            self.assertIs(Foo.f, result['f'])
-            self.assertIs(Foo.g, result['g'])
-            self.assertIsInstance(Foo.f, Thing)
-            self.assertIsInstance(Foo.g, Thing)
-            self.assertIsNot(Foo.f, Foo.g)
-        finally:
-            patcher.stop()
-
-
-    def test_nested_patch_failure(self):
-        original_f = Foo.f
-        original_g = Foo.g
-
-        @patch.object(Foo, 'g', 1)
-        @patch.object(Foo, 'missing', 1)
-        @patch.object(Foo, 'f', 1)
-        def thing1(): pass
-
-        @patch.object(Foo, 'missing', 1)
-        @patch.object(Foo, 'g', 1)
-        @patch.object(Foo, 'f', 1)
-        def thing2(): pass
-
-        @patch.object(Foo, 'g', 1)
-        @patch.object(Foo, 'f', 1)
-        @patch.object(Foo, 'missing', 1)
-        def thing3(): pass
-
-        for func in thing1, thing2, thing3:
-            self.assertRaises(AttributeError, func)
-            self.assertEqual(Foo.f, original_f)
-            self.assertEqual(Foo.g, original_g)
-
-
-    def test_new_callable_failure(self):
-        original_f = Foo.f
-        original_g = Foo.g
-        original_foo = Foo.foo
-
-        def crasher():
-            raise NameError('crasher')
-
-        @patch.object(Foo, 'g', 1)
-        @patch.object(Foo, 'foo', new_callable=crasher)
-        @patch.object(Foo, 'f', 1)
-        def thing1(): pass
-
-        @patch.object(Foo, 'foo', new_callable=crasher)
-        @patch.object(Foo, 'g', 1)
-        @patch.object(Foo, 'f', 1)
-        def thing2(): pass
-
-        @patch.object(Foo, 'g', 1)
-        @patch.object(Foo, 'f', 1)
-        @patch.object(Foo, 'foo', new_callable=crasher)
-        def thing3(): pass
-
-        for func in thing1, thing2, thing3:
-            self.assertRaises(NameError, func)
-            self.assertEqual(Foo.f, original_f)
-            self.assertEqual(Foo.g, original_g)
-            self.assertEqual(Foo.foo, original_foo)
-
-
-    def test_patch_multiple_failure(self):
-        original_f = Foo.f
-        original_g = Foo.g
-
-        patcher = patch.object(Foo, 'f', 1)
-        patcher.attribute_name = 'f'
-
-        good = patch.object(Foo, 'g', 1)
-        good.attribute_name = 'g'
-
-        bad = patch.object(Foo, 'missing', 1)
-        bad.attribute_name = 'missing'
-
-        for additionals in [good, bad], [bad, good]:
-            patcher.additional_patchers = additionals
-
-            @patcher
-            def func(): pass
-
-            self.assertRaises(AttributeError, func)
-            self.assertEqual(Foo.f, original_f)
-            self.assertEqual(Foo.g, original_g)
-
-
-    def test_patch_multiple_new_callable_failure(self):
-        original_f = Foo.f
-        original_g = Foo.g
-        original_foo = Foo.foo
-
-        def crasher():
-            raise NameError('crasher')
-
-        patcher = patch.object(Foo, 'f', 1)
-        patcher.attribute_name = 'f'
-
-        good = patch.object(Foo, 'g', 1)
-        good.attribute_name = 'g'
-
-        bad = patch.object(Foo, 'foo', new_callable=crasher)
-        bad.attribute_name = 'foo'
-
-        for additionals in [good, bad], [bad, good]:
-            patcher.additional_patchers = additionals
-
-            @patcher
-            def func(): pass
-
-            self.assertRaises(NameError, func)
-            self.assertEqual(Foo.f, original_f)
-            self.assertEqual(Foo.g, original_g)
-            self.assertEqual(Foo.foo, original_foo)
-
-
-    def test_patch_multiple_string_subclasses(self):
-        for base in (str, unicode):
-            Foo = type('Foo', (base,), {'fish': 'tasty'})
-            foo = Foo()
-            @patch.multiple(foo, fish='nearly gone')
-            def test():
-                self.assertEqual(foo.fish, 'nearly gone')
-
-            test()
-            self.assertEqual(foo.fish, 'tasty')
-
-
-    @patch('mock.patch.TEST_PREFIX', 'foo')
-    def test_patch_test_prefix(self):
-        class Foo(object):
-            thing = 'original'
-
-            def foo_one(self):
-                return self.thing
-            def foo_two(self):
-                return self.thing
-            def test_one(self):
-                return self.thing
-            def test_two(self):
-                return self.thing
-
-        Foo = patch.object(Foo, 'thing', 'changed')(Foo)
-
-        foo = Foo()
-        self.assertEqual(foo.foo_one(), 'changed')
-        self.assertEqual(foo.foo_two(), 'changed')
-        self.assertEqual(foo.test_one(), 'original')
-        self.assertEqual(foo.test_two(), 'original')
-
-
-    @patch('mock.patch.TEST_PREFIX', 'bar')
-    def test_patch_dict_test_prefix(self):
-        class Foo(object):
-            def bar_one(self):
-                return dict(the_dict)
-            def bar_two(self):
-                return dict(the_dict)
-            def test_one(self):
-                return dict(the_dict)
-            def test_two(self):
-                return dict(the_dict)
-
-        the_dict = {'key': 'original'}
-        Foo = patch.dict(the_dict, key='changed')(Foo)
-
-        foo =Foo()
-        self.assertEqual(foo.bar_one(), {'key': 'changed'})
-        self.assertEqual(foo.bar_two(), {'key': 'changed'})
-        self.assertEqual(foo.test_one(), {'key': 'original'})
-        self.assertEqual(foo.test_two(), {'key': 'original'})
-
-
-    def test_patch_with_spec_mock_repr(self):
-        for arg in ('spec', 'autospec', 'spec_set'):
-            p = patch('%s.SomeClass' % __name__, **{arg: True})
-            m = p.start()
-            try:
-                self.assertIn(" name='SomeClass'", repr(m))
-                self.assertIn(" name='SomeClass.class_attribute'",
-                              repr(m.class_attribute))
-                self.assertIn(" name='SomeClass()'", repr(m()))
-                self.assertIn(" name='SomeClass().class_attribute'",
-                              repr(m().class_attribute))
-            finally:
-                p.stop()
-
-
-    def test_patch_nested_autospec_repr(self):
-        p = patch('mock.tests.support', autospec=True)
-        m = p.start()
-        try:
-            self.assertIn(" name='support.SomeClass.wibble()'",
-                          repr(m.SomeClass.wibble()))
-            self.assertIn(" name='support.SomeClass().wibble()'",
-                          repr(m.SomeClass().wibble()))
-        finally:
-            p.stop()
-
-
-    def test_mock_calls_with_patch(self):
-        for arg in ('spec', 'autospec', 'spec_set'):
-            p = patch('%s.SomeClass' % __name__, **{arg: True})
-            m = p.start()
-            try:
-                m.wibble()
-
-                kalls = [call.wibble()]
-                self.assertEqual(m.mock_calls, kalls)
-                self.assertEqual(m.method_calls, kalls)
-                self.assertEqual(m.wibble.mock_calls, [call()])
-
-                result = m()
-                kalls.append(call())
-                self.assertEqual(m.mock_calls, kalls)
-
-                result.wibble()
-                kalls.append(call().wibble())
-                self.assertEqual(m.mock_calls, kalls)
-
-                self.assertEqual(result.mock_calls, [call.wibble()])
-                self.assertEqual(result.wibble.mock_calls, [call()])
-                self.assertEqual(result.method_calls, [call.wibble()])
-            finally:
-                p.stop()
-
-
-    def test_patch_imports_lazily(self):
-        p1 = patch('squizz.squozz')
-        self.assertRaises(ImportError, p1.start)
-
-        with uncache('squizz'):
-            squizz = Mock()
-            sys.modules['squizz'] = squizz
-
-            squizz.squozz = 6
-            p1 = patch('squizz.squozz')
-            squizz.squozz = 3
-            p1.start()
-            p1.stop()
-        self.assertEqual(squizz.squozz, 3)
-
-    def test_patch_propogrates_exc_on_exit(self):
-        class holder:
-            exc_info = None, None, None
-
-        class custom_patch(_patch):
-            def __exit__(self, etype=None, val=None, tb=None):
-                _patch.__exit__(self, etype, val, tb)
-                holder.exc_info = etype, val, tb
-            stop = __exit__
-
-        def with_custom_patch(target):
-            getter, attribute = _get_target(target)
-            return custom_patch(
-                getter, attribute, DEFAULT, None, False, None,
-                None, None, {}
-            )
-
-        @with_custom_patch('squizz.squozz')
-        def test(mock):
-            raise RuntimeError
-
-        with uncache('squizz'):
-            squizz = Mock()
-            sys.modules['squizz'] = squizz
-
-            self.assertRaises(RuntimeError, test)
-
-        self.assertIs(holder.exc_info[0], RuntimeError)
-        self.assertIsNotNone(holder.exc_info[1],
-                            'exception value not propgated')
-        self.assertIsNotNone(holder.exc_info[2],
-                            'exception traceback not propgated')
-
-
-    def test_create_and_specs(self):
-        for kwarg in ('spec', 'spec_set', 'autospec'):
-            p = patch('%s.doesnotexist' % __name__, create=True,
-                      **{kwarg: True})
-            self.assertRaises(TypeError, p.start)
-            self.assertRaises(NameError, lambda: doesnotexist)
-
-            # check that spec with create is innocuous if the original exists
-            p = patch(MODNAME, create=True, **{kwarg: True})
-            p.start()
-            p.stop()
-
-
-    def test_multiple_specs(self):
-        original = PTModule
-        for kwarg in ('spec', 'spec_set'):
-            p = patch(MODNAME, autospec=0, **{kwarg: 0})
-            self.assertRaises(TypeError, p.start)
-            self.assertIs(PTModule, original)
-
-        for kwarg in ('spec', 'autospec'):
-            p = patch(MODNAME, spec_set=0, **{kwarg: 0})
-            self.assertRaises(TypeError, p.start)
-            self.assertIs(PTModule, original)
-
-        for kwarg in ('spec_set', 'autospec'):
-            p = patch(MODNAME, spec=0, **{kwarg: 0})
-            self.assertRaises(TypeError, p.start)
-            self.assertIs(PTModule, original)
-
-
-    def test_specs_false_instead_of_none(self):
-        p = patch(MODNAME, spec=False, spec_set=False, autospec=False)
-        mock = p.start()
-        try:
-            # no spec should have been set, so attribute access should not fail
-            mock.does_not_exist
-            mock.does_not_exist = 3
-        finally:
-            p.stop()
-
-
-    def test_falsey_spec(self):
-        for kwarg in ('spec', 'autospec', 'spec_set'):
-            p = patch(MODNAME, **{kwarg: 0})
-            m = p.start()
-            try:
-                self.assertRaises(AttributeError, getattr, m, 'doesnotexit')
-            finally:
-                p.stop()
-
-
-    def test_spec_set_true(self):
-        for kwarg in ('spec', 'autospec'):
-            p = patch(MODNAME, spec_set=True, **{kwarg: True})
-            m = p.start()
-            try:
-                self.assertRaises(AttributeError, setattr, m,
-                                  'doesnotexist', 'something')
-                self.assertRaises(AttributeError, getattr, m, 'doesnotexist')
-            finally:
-                p.stop()
-
-
-    def test_callable_spec_as_list(self):
-        spec = ('__call__',)
-        p = patch(MODNAME, spec=spec)
-        m = p.start()
-        try:
-            self.assertTrue(callable(m))
-        finally:
-            p.stop()
-
-
-    def test_not_callable_spec_as_list(self):
-        spec = ('foo', 'bar')
-        p = patch(MODNAME, spec=spec)
-        m = p.start()
-        try:
-            self.assertFalse(callable(m))
-        finally:
-            p.stop()
-
-
-    def test_patch_stopall(self):
-        unlink = os.unlink
-        chdir = os.chdir
-        path = os.path
-        patch('os.unlink', something).start()
-        patch('os.chdir', something_else).start()
-
-        @patch('os.path')
-        def patched(mock_path):
-            patch.stopall()
-            self.assertIs(os.path, mock_path)
-            self.assertIs(os.unlink, unlink)
-            self.assertIs(os.chdir, chdir)
-
-        patched()
-        self.assertIs(os.path, path)
-
-
-    def test_wrapped_patch(self):
-        decorated = patch('sys.modules')(function)
-        self.assertIs(decorated.__wrapped__, function)
-
-
-    def test_wrapped_several_times_patch(self):
-        decorated = patch('sys.modules')(function)
-        decorated = patch('sys.modules')(decorated)
-        self.assertIs(decorated.__wrapped__, function)
-
-
-    def test_wrapped_patch_object(self):
-        decorated = patch.object(sys, 'modules')(function)
-        self.assertIs(decorated.__wrapped__, function)
-
-
-    def test_wrapped_patch_dict(self):
-        decorated = patch.dict('sys.modules')(function)
-        self.assertIs(decorated.__wrapped__, function)
-
-
-    def test_wrapped_patch_multiple(self):
-        decorated = patch.multiple('sys', modules={})(function)
-        self.assertIs(decorated.__wrapped__, function)
-
-    def test_stopall_lifo(self):
-        stopped = []
-        class thing(object):
-            one = two = three = None
-
-        def get_patch(attribute):
-            class mypatch(_patch):
-                def stop(self):
-                    stopped.append(attribute)
-                    return super(mypatch, self).stop()
-            return mypatch(lambda: thing, attribute, None, None,
-                           False, None, None, None, {})
-        [get_patch(val).start() for val in ("one", "two", "three")]
-        patch.stopall()
-
-        self.assertEqual(stopped, ["three", "two", "one"])
-
-
-    def test_special_attrs(self):
-        def foo(x=0):
-            """TEST"""
-            return x
-        with patch.object(foo, '__defaults__', (1, )):
-            self.assertEqual(foo(), 1)
-        self.assertEqual(foo(), 0)
-
-        with patch.object(foo, '__doc__', "FUN"):
-            self.assertEqual(foo.__doc__, "FUN")
-        self.assertEqual(foo.__doc__, "TEST")
-
-        with patch.object(foo, '__module__', "testpatch2"):
-            self.assertEqual(foo.__module__, "testpatch2")
-        self.assertEqual(foo.__module__, __name__)
-
-        if hasattr(self.test_special_attrs, '__annotations__'):
-            with patch.object(foo, '__annotations__', dict([('s', 1, )])):
-                self.assertEqual(foo.__annotations__, dict([('s', 1, )]))
-            self.assertEqual(foo.__annotations__, dict())
-
-        if hasattr(self.test_special_attrs, '__kwdefaults__'):
-            foo = eval("lambda *a, x=0: x")
-            with patch.object(foo, '__kwdefaults__', dict([('x', 1, )])):
-                self.assertEqual(foo(), 1)
-            self.assertEqual(foo(), 0)
-
-
-    def test_dotted_but_module_not_loaded(self):
-        # This exercises the AttributeError branch of _dot_lookup.
-        # make sure it's there
-        import mock.tests.support
-        # now make sure it's not:
-        with patch.dict('sys.modules'):
-            del sys.modules['mock.tests.support']
-            del sys.modules['mock.tests']
-            del sys.modules['mock.mock']
-            del sys.modules['mock']
-            # now make sure we can patch based on a dotted path:
-            @patch('mock.tests.support.X')
-            def test(mock):
-                pass
-            test()
-
-
-    def test_invalid_target(self):
-        with self.assertRaises(TypeError):
-            patch('')
-
-
-    def test_cant_set_kwargs_when_passing_a_mock(self):
-        @patch('mock.tests.support.X', new=object(), x=1)
-        def test(): pass
-        with self.assertRaises(TypeError):
-            test()
-
-
-if __name__ == '__main__':
-    unittest.main()
diff --git a/mock/tests/testsealable.py b/mock/tests/testsealable.py
deleted file mode 100644
index 63a8541..0000000
--- a/mock/tests/testsealable.py
+++ /dev/null
@@ -1,176 +0,0 @@
-import unittest
-import mock
-
-
-class SampleObject:
-
-    def method_sample1(self): pass
-
-    def method_sample2(self): pass
-
-
-class TestSealable(unittest.TestCase):
-
-    def test_attributes_return_more_mocks_by_default(self):
-        m = mock.Mock()
-
-        self.assertIsInstance(m.test, mock.Mock)
-        self.assertIsInstance(m.test(), mock.Mock)
-        self.assertIsInstance(m.test().test2(), mock.Mock)
-
-    def test_new_attributes_cannot_be_accessed_on_seal(self):
-        m = mock.Mock()
-
-        mock.seal(m)
-        with self.assertRaises(AttributeError):
-            m.test
-        with self.assertRaises(AttributeError):
-            m()
-
-    def test_new_attributes_cannot_be_set_on_seal(self):
-        m = mock.Mock()
-
-        mock.seal(m)
-        with self.assertRaises(AttributeError):
-            m.test = 1
-
-    def test_existing_attributes_can_be_set_on_seal(self):
-        m = mock.Mock()
-        m.test.test2 = 1
-
-        mock.seal(m)
-        m.test.test2 = 2
-        self.assertEqual(m.test.test2, 2)
-
-    def test_new_attributes_cannot_be_set_on_child_of_seal(self):
-        m = mock.Mock()
-        m.test.test2 = 1
-
-        mock.seal(m)
-        with self.assertRaises(AttributeError):
-            m.test.test3 = 1
-
-    def test_existing_attributes_allowed_after_seal(self):
-        m = mock.Mock()
-
-        m.test.return_value = 3
-
-        mock.seal(m)
-        self.assertEqual(m.test(), 3)
-
-    def test_initialized_attributes_allowed_after_seal(self):
-        m = mock.Mock(test_value=1)
-
-        mock.seal(m)
-        self.assertEqual(m.test_value, 1)
-
-    def test_call_on_sealed_mock_fails(self):
-        m = mock.Mock()
-
-        mock.seal(m)
-        with self.assertRaises(AttributeError):
-            m()
-
-    def test_call_on_defined_sealed_mock_succeeds(self):
-        m = mock.Mock(return_value=5)
-
-        mock.seal(m)
-        self.assertEqual(m(), 5)
-
-    def test_seals_recurse_on_added_attributes(self):
-        m = mock.Mock()
-
-        m.test1.test2().test3 = 4
-
-        mock.seal(m)
-        self.assertEqual(m.test1.test2().test3, 4)
-        with self.assertRaises(AttributeError):
-            m.test1.test2().test4
-        with self.assertRaises(AttributeError):
-            m.test1.test3
-
-    def test_seals_recurse_on_magic_methods(self):
-        m = mock.MagicMock()
-
-        m.test1.test2["a"].test3 = 4
-        m.test1.test3[2:5].test3 = 4
-
-        mock.seal(m)
-        self.assertEqual(m.test1.test2["a"].test3, 4)
-        self.assertEqual(m.test1.test2[2:5].test3, 4)
-        with self.assertRaises(AttributeError):
-            m.test1.test2["a"].test4
-        with self.assertRaises(AttributeError):
-            m.test1.test3[2:5].test4
-
-    def test_seals_dont_recurse_on_manual_attributes(self):
-        m = mock.Mock(name="root_mock")
-
-        m.test1.test2 = mock.Mock(name="not_sealed")
-        m.test1.test2.test3 = 4
-
-        mock.seal(m)
-        self.assertEqual(m.test1.test2.test3, 4)
-        m.test1.test2.test4  # Does not raise
-        m.test1.test2.test4 = 1  # Does not raise
-
-    def test_integration_with_spec_att_definition(self):
-        """You are not restricted when using mock with spec"""
-        m = mock.Mock(SampleObject)
-
-        m.attr_sample1 = 1
-        m.attr_sample3 = 3
-
-        mock.seal(m)
-        self.assertEqual(m.attr_sample1, 1)
-        self.assertEqual(m.attr_sample3, 3)
-        with self.assertRaises(AttributeError):
-            m.attr_sample2
-
-    def test_integration_with_spec_method_definition(self):
-        """You need to defin the methods, even if they are in the spec"""
-        m = mock.Mock(SampleObject)
-
-        m.method_sample1.return_value = 1
-
-        mock.seal(m)
-        self.assertEqual(m.method_sample1(), 1)
-        with self.assertRaises(AttributeError):
-            m.method_sample2()
-
-    def test_integration_with_spec_method_definition_respects_spec(self):
-        """You cannot define methods out of the spec"""
-        m = mock.Mock(SampleObject)
-
-        with self.assertRaises(AttributeError):
-            m.method_sample3.return_value = 3
-
-    def test_sealed_exception_has_attribute_name(self):
-        m = mock.Mock()
-
-        mock.seal(m)
-        with self.assertRaises(AttributeError) as cm:
-            m.SECRETE_name
-        self.assertIn("SECRETE_name", str(cm.exception))
-
-    def test_attribute_chain_is_maintained(self):
-        m = mock.Mock(name="mock_name")
-        m.test1.test2.test3.test4
-
-        mock.seal(m)
-        with self.assertRaises(AttributeError) as cm:
-            m.test1.test2.test3.test4.boom
-        self.assertIn("mock_name.test1.test2.test3.test4.boom", str(cm.exception))
-
-    def test_call_chain_is_maintained(self):
-        m = mock.Mock()
-        m.test1().test2.test3().test4
-
-        mock.seal(m)
-        with self.assertRaises(AttributeError) as cm:
-            m.test1().test2.test3().test4()
-        self.assertIn("mock.test1().test2.test3().test4", str(cm.exception))
-
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/mock/tests/testsentinel.py b/mock/tests/testsentinel.py
deleted file mode 100644
index 1411445..0000000
--- a/mock/tests/testsentinel.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# Copyright (C) 2007-2012 Michael Foord & the mock team
-# E-mail: fuzzyman AT voidspace DOT org DOT uk
-# http://www.voidspace.org.uk/python/mock/
-
-import unittest
-import copy
-import pickle
-from mock import sentinel, DEFAULT
-
-
-class SentinelTest(unittest.TestCase):
-
-    def testSentinels(self):
-        self.assertEqual(sentinel.whatever, sentinel.whatever,
-                         'sentinel not stored')
-        self.assertNotEqual(sentinel.whatever, sentinel.whateverelse,
-                            'sentinel should be unique')
-
-
-    def testSentinelName(self):
-        self.assertEqual(str(sentinel.whatever), 'sentinel.whatever',
-                         'sentinel name incorrect')
-
-
-    def testDEFAULT(self):
-        self.assertIs(DEFAULT, sentinel.DEFAULT)
-
-    def testBases(self):
-        # If this doesn't raise an AttributeError then help(mock) is broken
-        self.assertRaises(AttributeError, lambda: sentinel.__bases__)
-
-    def testPickle(self):
-        for proto in range(pickle.HIGHEST_PROTOCOL+1):
-                pickled = pickle.dumps(sentinel.whatever, proto)
-                unpickled = pickle.loads(pickled)
-                self.assertIs(unpickled, sentinel.whatever)
-
-    def testCopy(self):
-        self.assertIs(copy.copy(sentinel.whatever), sentinel.whatever)
-        self.assertIs(copy.deepcopy(sentinel.whatever), sentinel.whatever)
-
-
-if __name__ == '__main__':
-    unittest.main()
diff --git a/mock/tests/testsupport.py b/mock/tests/testsupport.py
deleted file mode 100644
index 4882572..0000000
--- a/mock/tests/testsupport.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# Tests to make sure helpers we backport are actually working!
-from unittest import TestCase
-
-from .support import uncache
-
-
-class TestUncache(TestCase):
-
-    def test_cant_uncache_sys(self):
-        with self.assertRaises(ValueError):
-            with uncache('sys'): pass
-
-    def test_uncache_non_existent(self):
-        with uncache('mock.tests.support.bad'): pass
diff --git a/mock/tests/testwith.py b/mock/tests/testwith.py
deleted file mode 100644
index 587fde9..0000000
--- a/mock/tests/testwith.py
+++ /dev/null
@@ -1,337 +0,0 @@
-# Copyright (C) 2007-2012 Michael Foord & the mock team
-# E-mail: fuzzyman AT voidspace DOT org DOT uk
-# http://www.voidspace.org.uk/python/mock/
-
-from warnings import catch_warnings
-
-import unittest
-
-from mock.tests.support import is_instance
-from mock import MagicMock, Mock, patch, sentinel, mock_open, call
-
-
-something  = sentinel.Something
-something_else  = sentinel.SomethingElse
-
-
-class SampleException(Exception): pass
-
-
-class WithTest(unittest.TestCase):
-
-    def test_with_statement(self):
-        with patch('%s.something' % __name__, sentinel.Something2):
-            self.assertEqual(something, sentinel.Something2, "unpatched")
-        self.assertEqual(something, sentinel.Something)
-
-
-    def test_with_statement_exception(self):
-        with self.assertRaises(SampleException):
-            with patch('%s.something' % __name__, sentinel.Something2):
-                self.assertEqual(something, sentinel.Something2, "unpatched")
-                raise SampleException()
-        self.assertEqual(something, sentinel.Something)
-
-
-    def test_with_statement_as(self):
-        with patch('%s.something' % __name__) as mock_something:
-            self.assertEqual(something, mock_something, "unpatched")
-            self.assertTrue(is_instance(mock_something, MagicMock),
-                            "patching wrong type")
-        self.assertEqual(something, sentinel.Something)
-
-
-    def test_patch_object_with_statement(self):
-        class Foo(object):
-            something = 'foo'
-        original = Foo.something
-        with patch.object(Foo, 'something'):
-            self.assertNotEqual(Foo.something, original, "unpatched")
-        self.assertEqual(Foo.something, original)
-
-
-    def test_with_statement_nested(self):
-        with catch_warnings(record=True):
-            with patch('%s.something' % __name__) as mock_something:
-                with patch('%s.something_else' % __name__) as mock_something_else:
-                    self.assertEqual(something, mock_something, "unpatched")
-                    self.assertEqual(something_else, mock_something_else,
-                                     "unpatched")
-
-        self.assertEqual(something, sentinel.Something)
-        self.assertEqual(something_else, sentinel.SomethingElse)
-
-
-    def test_with_statement_specified(self):
-        with patch('%s.something' % __name__, sentinel.Patched) as mock_something:
-            self.assertEqual(something, mock_something, "unpatched")
-            self.assertEqual(mock_something, sentinel.Patched, "wrong patch")
-        self.assertEqual(something, sentinel.Something)
-
-
-    def testContextManagerMocking(self):
-        mock = Mock()
-        mock.__enter__ = Mock()
-        mock.__exit__ = Mock()
-        mock.__exit__.return_value = False
-
-        with mock as m:
-            self.assertEqual(m, mock.__enter__.return_value)
-        mock.__enter__.assert_called_with()
-        mock.__exit__.assert_called_with(None, None, None)
-
-
-    def test_context_manager_with_magic_mock(self):
-        mock = MagicMock()
-
-        with self.assertRaises(TypeError):
-            with mock:
-                'foo' + 3
-        mock.__enter__.assert_called_with()
-        self.assertTrue(mock.__exit__.called)
-
-
-    def test_with_statement_same_attribute(self):
-        with patch('%s.something' % __name__, sentinel.Patched) as mock_something:
-            self.assertEqual(something, mock_something, "unpatched")
-
-            with patch('%s.something' % __name__) as mock_again:
-                self.assertEqual(something, mock_again, "unpatched")
-
-            self.assertEqual(something, mock_something,
-                             "restored with wrong instance")
-
-        self.assertEqual(something, sentinel.Something, "not restored")
-
-
-    def test_with_statement_imbricated(self):
-        with patch('%s.something' % __name__) as mock_something:
-            self.assertEqual(something, mock_something, "unpatched")
-
-            with patch('%s.something_else' % __name__) as mock_something_else:
-                self.assertEqual(something_else, mock_something_else,
-                                 "unpatched")
-
-        self.assertEqual(something, sentinel.Something)
-        self.assertEqual(something_else, sentinel.SomethingElse)
-
-
-    def test_dict_context_manager(self):
-        foo = {}
-        with patch.dict(foo, {'a': 'b'}):
-            self.assertEqual(foo, {'a': 'b'})
-        self.assertEqual(foo, {})
-
-        with self.assertRaises(NameError):
-            with patch.dict(foo, {'a': 'b'}):
-                self.assertEqual(foo, {'a': 'b'})
-                raise NameError('Konrad')
-
-        self.assertEqual(foo, {})
-
-    def test_double_patch_instance_method(self):
-        class C:
-            def f(self): pass
-
-        c = C()
-
-        with patch.object(c, 'f', autospec=True) as patch1:
-            with patch.object(c, 'f', autospec=True) as patch2:
-                c.f()
-            self.assertEqual(patch2.call_count, 1)
-            self.assertEqual(patch1.call_count, 0)
-            c.f()
-        self.assertEqual(patch1.call_count, 1)
-
-
-class TestMockOpen(unittest.TestCase):
-
-    def test_mock_open(self):
-        mock = mock_open()
-        with patch('%s.open' % __name__, mock, create=True) as patched:
-            self.assertIs(patched, mock)
-            open('foo')
-
-        mock.assert_called_once_with('foo')
-
-
-    def test_mock_open_context_manager(self):
-        mock = mock_open()
-        handle = mock.return_value
-        with patch('%s.open' % __name__, mock, create=True):
-            with open('foo') as f:
-                f.read()
-
-        expected_calls = [call('foo'), call().__enter__(), call().read(),
-                          call().__exit__(None, None, None)]
-        self.assertEqual(mock.mock_calls, expected_calls)
-        self.assertIs(f, handle)
-
-    def test_mock_open_context_manager_multiple_times(self):
-        mock = mock_open()
-        with patch('%s.open' % __name__, mock, create=True):
-            with open('foo') as f:
-                f.read()
-            with open('bar') as f:
-                f.read()
-
-        expected_calls = [
-            call('foo'), call().__enter__(), call().read(),
-            call().__exit__(None, None, None),
-            call('bar'), call().__enter__(), call().read(),
-            call().__exit__(None, None, None)]
-        self.assertEqual(mock.mock_calls, expected_calls)
-
-    def test_explicit_mock(self):
-        mock = MagicMock()
-        mock_open(mock)
-
-        with patch('%s.open' % __name__, mock, create=True) as patched:
-            self.assertIs(patched, mock)
-            open('foo')
-
-        mock.assert_called_once_with('foo')
-
-
-    def test_read_data(self):
-        mock = mock_open(read_data='foo')
-        with patch('%s.open' % __name__, mock, create=True):
-            h = open('bar')
-            result = h.read()
-
-        self.assertEqual(result, 'foo')
-
-
-    def test_readline_data(self):
-        # Check that readline will return all the lines from the fake file
-        # And that once fully consumed, readline will return an empty string.
-        mock = mock_open(read_data='foo\nbar\nbaz\n')
-        with patch('%s.open' % __name__, mock, create=True):
-            h = open('bar')
-            line1 = h.readline()
-            line2 = h.readline()
-            line3 = h.readline()
-        self.assertEqual(line1, 'foo\n')
-        self.assertEqual(line2, 'bar\n')
-        self.assertEqual(line3, 'baz\n')
-        self.assertEqual(h.readline(), '')
-
-        # Check that we properly emulate a file that doesn't end in a newline
-        mock = mock_open(read_data='foo')
-        with patch('%s.open' % __name__, mock, create=True):
-            h = open('bar')
-            result = h.readline()
-        self.assertEqual(result, 'foo')
-        self.assertEqual(h.readline(), '')
-
-
-    def test_dunder_iter_data(self):
-        # Check that dunder_iter will return all the lines from the fake file.
-        mock = mock_open(read_data='foo\nbar\nbaz\n')
-        with patch('%s.open' % __name__, mock, create=True):
-            h = open('bar')
-            lines = [l for l in h]
-        self.assertEqual(lines[0], 'foo\n')
-        self.assertEqual(lines[1], 'bar\n')
-        self.assertEqual(lines[2], 'baz\n')
-        self.assertEqual(h.readline(), '')
-
-
-    def test_readlines_data(self):
-        # Test that emulating a file that ends in a newline character works
-        mock = mock_open(read_data='foo\nbar\nbaz\n')
-        with patch('%s.open' % __name__, mock, create=True):
-            h = open('bar')
-            result = h.readlines()
-        self.assertEqual(result, ['foo\n', 'bar\n', 'baz\n'])
-
-        # Test that files without a final newline will also be correctly
-        # emulated
-        mock = mock_open(read_data='foo\nbar\nbaz')
-        with patch('%s.open' % __name__, mock, create=True):
-            h = open('bar')
-            result = h.readlines()
-
-        self.assertEqual(result, ['foo\n', 'bar\n', 'baz'])
-
-
-    def test_read_bytes(self):
-        mock = mock_open(read_data=b'\xc6')
-        with patch('%s.open' % __name__, mock, create=True):
-            with open('abc', 'rb') as f:
-                result = f.read()
-        self.assertEqual(result, b'\xc6')
-
-
-    def test_readline_bytes(self):
-        m = mock_open(read_data=b'abc\ndef\nghi\n')
-        with patch('%s.open' % __name__, m, create=True):
-            with open('abc', 'rb') as f:
-                line1 = f.readline()
-                line2 = f.readline()
-                line3 = f.readline()
-        self.assertEqual(line1, b'abc\n')
-        self.assertEqual(line2, b'def\n')
-        self.assertEqual(line3, b'ghi\n')
-
-
-    def test_readlines_bytes(self):
-        m = mock_open(read_data=b'abc\ndef\nghi\n')
-        with patch('%s.open' % __name__, m, create=True):
-            with open('abc', 'rb') as f:
-                result = f.readlines()
-        self.assertEqual(result, [b'abc\n', b'def\n', b'ghi\n'])
-
-
-    def test_mock_open_read_with_argument(self):
-        # At one point calling read with an argument was broken
-        # for mocks returned by mock_open
-        some_data = 'foo\nbar\nbaz'
-        mock = mock_open(read_data=some_data)
-        self.assertEqual(mock().read(10), some_data[:10])
-        self.assertEqual(mock().read(10), some_data[:10])
-
-        f = mock()
-        self.assertEqual(f.read(10), some_data[:10])
-        self.assertEqual(f.read(10), some_data[10:])
-
-
-    def test_interleaved_reads(self):
-        # Test that calling read, readline, and readlines pulls data
-        # sequentially from the data we preload with
-        mock = mock_open(read_data='foo\nbar\nbaz\n')
-        with patch('%s.open' % __name__, mock, create=True):
-            h = open('bar')
-            line1 = h.readline()
-            rest = h.readlines()
-        self.assertEqual(line1, 'foo\n')
-        self.assertEqual(rest, ['bar\n', 'baz\n'])
-
-        mock = mock_open(read_data='foo\nbar\nbaz\n')
-        with patch('%s.open' % __name__, mock, create=True):
-            h = open('bar')
-            line1 = h.readline()
-            rest = h.read()
-        self.assertEqual(line1, 'foo\n')
-        self.assertEqual(rest, 'bar\nbaz\n')
-
-
-    def test_overriding_return_values(self):
-        mock = mock_open(read_data='foo')
-        handle = mock()
-
-        handle.read.return_value = 'bar'
-        handle.readline.return_value = 'bar'
-        handle.readlines.return_value = ['bar']
-
-        self.assertEqual(handle.read(), 'bar')
-        self.assertEqual(handle.readline(), 'bar')
-        self.assertEqual(handle.readlines(), ['bar'])
-
-        # call repeatedly to check that a StopIteration is not propagated
-        self.assertEqual(handle.readline(), 'bar')
-        self.assertEqual(handle.readline(), 'bar')
-
-
-if __name__ == '__main__':
-    unittest.main()
diff --git a/release.py b/release.py
deleted file mode 100644
index 2556d50..0000000
--- a/release.py
+++ /dev/null
@@ -1,92 +0,0 @@
-import re
-from glob import glob
-from os.path import join
-from subprocess import call
-
-import blurb as blurb_module
-from argparse import ArgumentParser
-from mock import version_info
-
-VERSION_TYPES = ['major', 'minor', 'bugfix']
-
-
-def incremented_version(version_info, type_):
-    type_index = VERSION_TYPES.index(type_)
-    version_info = tuple(e+(1 if i==type_index else 0)
-                         for i, e in enumerate(version_info))
-    return '.'.join(str(p) for p in version_info)
-
-
-def text_from_news():
-    # hack:
-    blurb_module.sections.append('NEWS.d')
-
-    blurbs = blurb_module.Blurbs()
-    for path in glob(join('NEWS.d', '*')):
-        blurbs.load_next(path)
-
-    text = []
-    for metadata, body in blurbs:
-        bpo = metadata['bpo']
-        body = f"- Issue #{bpo}: " + body
-        text.append(blurb_module.textwrap_body(body, subsequent_indent='  '))
-
-    return '\n'.join(text)
-
-
-def news_to_changelog(version):
-    with open('CHANGELOG.rst') as source:
-        current_changelog = source.read()
-
-    text = [version]
-    text.append('-'*len(version))
-    text.append('')
-    text.append(text_from_news())
-    text.append(current_changelog)
-
-    new_changelog = '\n'.join(text)
-    with open('CHANGELOG.rst', 'w') as target:
-        target.write(new_changelog)
-
-
-def update_version(new_version):
-    path = join('mock', 'mock.py')
-    with open(path) as source:
-        text = source.read()
-
-    text = re.sub("(__version__ = ')[^']+(')",
-                  r"\g<1>"+new_version+r"\2",
-                  text)
-
-    with open(path, 'w') as target:
-        target.write(text)
-
-
-def git(command):
-    return call('git '+command, shell=True)
-
-
-def git_commit(new_version):
-    git('rm NEWS.d/*')
-    git('add CHANGELOG.rst')
-    git('add mock/mock.py')
-    git(f'commit -m "Preparing for {new_version} release."')
-
-
-def parse_args():
-    parser = ArgumentParser()
-    parser.add_argument('type', choices=VERSION_TYPES)
-    return parser.parse_args()
-
-
-def main():
-    args = parse_args()
-    new_version = incremented_version(version_info, args.type)
-    news_to_changelog(new_version)
-    update_version(new_version)
-    git_commit(new_version)
-    print(f'{new_version} ready to push, please check the HEAD commit first!')
-
-
-if __name__ == '__main__':
-    main()
diff --git a/setup.cfg b/setup.cfg
deleted file mode 100644
index 7283b79..0000000
--- a/setup.cfg
+++ /dev/null
@@ -1,55 +0,0 @@
-[metadata]
-name = mock
-summary = Rolling backport of unittest.mock for all Pythons
-home-page = http://mock.readthedocs.org/en/latest/
-description-file = README.rst
-author = Testing Cabal
-author-email = testing-in-python@lists.idyll.org
-license = OSI Approved :: BSD License
-classifier =
-    Development Status :: 5 - Production/Stable
-    Environment :: Console
-    Intended Audience :: Developers
-    License :: OSI Approved :: BSD License
-    Operating System :: OS Independent
-    Programming Language :: Python
-    Programming Language :: Python :: 2
-    Programming Language :: Python :: 2.7
-    Programming Language :: Python :: 3
-    Programming Language :: Python :: 3.4
-    Programming Language :: Python :: 3.5
-    Programming Language :: Python :: 3.6
-    Programming Language :: Python :: 3.7
-    Programming Language :: Python :: Implementation :: CPython
-    Programming Language :: Python :: Implementation :: PyPy
-    Topic :: Software Development :: Libraries
-    Topic :: Software Development :: Libraries :: Python Modules
-    Topic :: Software Development :: Testing
-keyword =
-    testing, test, mock, mocking, unittest, patching, stubs, fakes, doubles
-
-[options]
-install_requires =
-  six
-  funcsigs>=1;python_version<"3.3"
-python_requires=>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*
-packages = mock
-
-[options.extras_require]
-docs =
-  sphinx
-test =
-  pytest
-  pytest-cov
-build =
-  twine
-  wheel
-  blurb
-
-[bdist_wheel]
-universal = 1
-
-[tool:pytest]
-python_files=test*.py
-filterwarnings =
-    ignore::DeprecationWarning
diff --git a/setup.py b/setup.py
deleted file mode 100755
index d47345f..0000000
--- a/setup.py
+++ /dev/null
@@ -1,10 +0,0 @@
-import re
-from os.path import join
-
-import setuptools
-
-setuptools.setup(
-    version=re.search("__version__ = '([^']+)'",
-                      open(join('mock', 'mock.py')).read()).group(1),
-    long_description=open('README.rst').read(),
-)
diff --git a/tox.ini b/tox.ini
deleted file mode 100644
index 90ca455..0000000
--- a/tox.ini
+++ /dev/null
@@ -1,12 +0,0 @@
-[tox]
-envlist = py27,pypy,py34,py35,py36,py37,docs
-
-[testenv]
-commands =
-    {envbindir}/pytest {posargs}
-
-[testenv:docs]
-deps =
-    sphinx
-commands =
-    {envbindir}/python setup.py build_sphinx
