Merge RP1A.190822.001

Change-Id: I4cf52186d3277bd68872fb6a45eaa6d74d5754dd
diff --git a/.carthorse.yml b/.carthorse.yml
new file mode 100644
index 0000000..d8f3a9a
--- /dev/null
+++ b/.carthorse.yml
@@ -0,0 +1,9 @@
+carthorse:
+  version-from: setup.py
+  tag-format: "{version}"
+  when:
+    - version-not-tagged
+  actions:
+    - run: "sudo pip install -e .[build]"
+    - run: "twine upload -u carthorse-mock -p $PYPI_PASS dist/*"
+    - create-tag
diff --git a/.circleci/config.yml b/.circleci/config.yml
new file mode 100644
index 0000000..8416914
--- /dev/null
+++ b/.circleci/config.yml
@@ -0,0 +1,118 @@
+version: 2.1
+
+orbs:
+  python: cjw296/python-ci@2
+
+jobs:
+  check-package:
+    parameters:
+      image:
+        type: string
+      python:
+        type: string
+        default: "python"
+    docker:
+      - image: << parameters.image >>
+    steps:
+      - python/check-package:
+          package: "mock"
+          test:
+          - run:
+              name: "Import package"
+              command: << parameters.python >> -c "import mock"
+
+
+common: &common
+  jobs:
+    - python/pip-run-tests:
+        name: python27
+        image: circleci/python:2.7
+    - python/pip-run-tests:
+        name: python34
+        image: circleci/python:3.4
+    - python/pip-run-tests:
+        name: python35
+        image: circleci/python:3.5
+    - python/pip-run-tests:
+        name: python36
+        image: circleci/python:3.6
+    - python/pip-run-tests:
+        name: python37
+        image: circleci/python:3.7
+    - python/pip-run-tests:
+        name: pypy27
+        image: pypy:2.7
+    - python/pip-run-tests:
+        name: pypy36
+        image: pypy:3.6
+
+    - python/coverage:
+        name: coverage
+        requires:
+          - python27
+          - python34
+          - python35
+          - python36
+          - python37
+          - pypy27
+          - pypy36
+
+    - python/pip-docs:
+        name: docs
+        requires:
+          - coverage
+
+    - python/pip-setuptools-build-package:
+        name: package
+        requires:
+          - docs
+        filters:
+          branches:
+            only: master
+
+    - check-package:
+        name: check-package-python27
+        image: circleci/python:2.7
+        requires:
+          - package
+
+    - check-package:
+        name: check-package-python37
+        image: circleci/python:3.7
+        requires:
+          - package
+
+    - check-package:
+        name: check-package-pypy27
+        image: pypy:2.7
+        python: pypy
+        requires:
+          - package
+
+    - check-package:
+        name: check-package-pypy36
+        image: pypy:3.6
+        python: pypy3
+        requires:
+          - package
+
+    - python/release:
+        name: release
+        config: .carthorse.yml
+        requires:
+          - check-package-python27
+          - check-package-python37
+          - check-package-pypy27
+          - check-package-pypy36
+
+workflows:
+  push:
+    <<: *common
+  periodic:
+    <<: *common
+    triggers:
+      - schedule:
+          cron: "0 1 * * *"
+          filters:
+            branches:
+              only: master
diff --git a/.coveragerc b/.coveragerc
new file mode 100644
index 0000000..5a29219
--- /dev/null
+++ b/.coveragerc
@@ -0,0 +1,14 @@
+[run]
+source = mock
+omit = mock/tests/__main__.py
+
+[report]
+exclude_lines =
+    pragma: no cover
+    if __name__ == .__main__.:
+    : pass
+
+[paths]
+source =
+    mock/
+    /root/project/mock/
diff --git a/.gitignore b/.gitignore
index 93d1155..b488ed9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,4 @@
 .*\.pyc
-*.rej
 html/
 mock\.egg-info/
 mock\.wpu
@@ -13,8 +12,6 @@
 *.pyc
 .testrepository
 .*.swp
-AUTHORS
-ChangeLog
-.eggs
-README.saved
 README.html
+.coverage
+.coverage.*
diff --git a/.readthedocs.yml b/.readthedocs.yml
new file mode 100644
index 0000000..7687b8a
--- /dev/null
+++ b/.readthedocs.yml
@@ -0,0 +1,8 @@
+version: 2
+python:
+  version: 3.7
+  install:
+    - method: pip
+      path: .
+      extra_requirements:
+        - docs
diff --git a/.testr.conf b/.testr.conf
deleted file mode 100644
index 8a65628..0000000
--- a/.testr.conf
+++ /dev/null
@@ -1,4 +0,0 @@
-[DEFAULT]
-test_command=${PYTHON:-python} -m subunit.run discover . $LISTOPT $IDOPTION
-test_id_option=--load-list $IDFILE
-test_list_option=--list
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index a13b528..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,26 +0,0 @@
-sudo: false
-language: python
-python:
-  - "2.7"
-  - "3.3"
-  - "3.4"
-  - "3.5"
-  - "3.6"
-  - pypy
-  - pypy3
-matrix:
-  include:
-# Travis nightly look to be 3.5.0a4, b3 is out and the syntax error we see
-# doesn't happen in trunk.
-    - python: "nightly"
-      env: SKIP_DOCS=1
-install:
- - pip install -U pip
- - pip install -U wheel setuptools
- - pip install -U .[docs,test]
- - pip list
- - python --version
-script:
- - unit2
- - if [ -z "$SKIP_DOCS" ]; then python setup.py build_sphinx; fi
- - rst2html.py --strict README.rst README.html
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
new file mode 100644
index 0000000..919648b
--- /dev/null
+++ b/CHANGELOG.rst
@@ -0,0 +1,206 @@
+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/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 0000000..7f47ab6
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1,2 @@
+include LICENSE.txt
+include *.rst
diff --git a/NEWS b/NEWS
deleted file mode 100644
index 2120418..0000000
--- a/NEWS
+++ /dev/null
@@ -1,79 +0,0 @@
-Library
--------
-
-- 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/README.rst b/README.rst
index 2ba1b38..b4f3163 100644
--- a/README.rst
+++ b/README.rst
@@ -7,7 +7,7 @@
 onwards.
 
 This package contains a rolling backport of the standard library mock code
-compatible with Python 2.7 and 3.3 and up.
+compatible with Python 2.7 and 3.4 and up.
 
 Please see the standard library documentation for more details.
 
@@ -17,13 +17,20 @@
 :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:
-  .. image:: https://travis-ci.org/testing-cabal/mock.svg?branch=master
-      :target: https://travis-ci.org/testing-cabal/mock
+    |CircleCI|_ |Docs|_
 
-.. _Mock Homepage: https://github.com/testing-cabal/mock
-.. _BSD License: http://github.com/testing-cabal/mock/blob/master/LICENSE.txt
+    .. |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: http://pypi.python.org/pypi/mock
+.. _mock on PyPI: https://pypi.org/project/mock/
diff --git a/TEST_MAPPING b/TEST_MAPPING
new file mode 100644
index 0000000..61a80b2
--- /dev/null
+++ b/TEST_MAPPING
@@ -0,0 +1,8 @@
+{
+  "presubmit" : [
+    {
+      "name" : "acloud_test",
+      "host" : true
+    }
+  ]
+}
diff --git a/backport.py b/backport.py
new file mode 100644
index 0000000..b2ab523
--- /dev/null
+++ b/backport.py
@@ -0,0 +1,147 @@
+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 120000
index 22ec9b8..0000000
--- a/docs/changelog.txt
+++ /dev/null
@@ -1 +0,0 @@
-../ChangeLog
\ No newline at end of file
diff --git a/docs/changelog.txt b/docs/changelog.txt
new file mode 100644
index 0000000..4de03af
--- /dev/null
+++ b/docs/changelog.txt
@@ -0,0 +1,4 @@
+Changelog
+=========
+
+.. include:: ../CHANGELOG.rst
diff --git a/docs/conf.py b/docs/conf.py
index d32357d..d2be5a5 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -33,7 +33,6 @@
 import sys
 import mock
 from mock import * # yeah, I know :-/
-import unittest2
 import __main__
 
 if os.getcwd() not in sys.path:
@@ -72,10 +71,7 @@
 # The default replacements for |version| and |release|, also used in various
 # other places throughout the built documents. Supplied by pbr.
 #
-# The short X.Y version.
-version = mock.mock._v.brief_string()
-# The full version, including alpha/beta/rc tags.
-release = mock.__version__
+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)
diff --git a/docs/index.txt b/docs/index.txt
index 6c8e37b..4e8bc17 100644
--- a/docs/index.txt
+++ b/docs/index.txt
@@ -1,58 +1,29 @@
-====================================
+===================================
  Mock - Mocking and Testing Library
-====================================
+===================================
 
-:Version: |release|
-:Date: |today|
-: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>`_
-:Issue tracker: `GitHub Issues
- <https://github.com/testing-cabal/mock/issues>`_
-:Last sync: cb6aab1248c4aec4dd578bea717854505a6fb55d
-
-.. _Mock Homepage: https://github.com/testing-cabal/mock
-.. _BSD License: http://github.com/testing-cabal/mock/blob/master/LICENSE.txt
-.. _Python Docs: https://docs.python.org/dev/library/unittest.mock.html
+.. include:: ../README.rst
 
 .. module:: mock
    :synopsis: Mock object and testing library.
 
 .. index:: introduction
 
-TOC
-+++
-
 .. toctree::
-   :maxdepth: 2
+   :hidden:
 
    changelog
 
-Introduction
-++++++++++++
+Python Version Compatibility
+++++++++++++++++++++++++++++
 
-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.
+* Version 1.0.1 is the last version compatible with Python < 2.6.
 
-mock is now part of the Python standard library, available as
-``unittest.mock`` in Python 3.3 onwards. However, if you are writing code that
-runs on multiple versions of Python the ``mock`` package is better, as you get
-the newest features from the latest release of Python available for all
-Pythons.
+* Version 1.3.0 is the last version compatible with Python 3.2.
 
-The ``mock`` package contains a rolling backport of the standard library mock
-code compatible with Python 2.7 and 3.3 and up.
+* Version 2.0.0 is the last version compatible with Python 2.6.
 
-* Python 2.6 is supported by mock 2.0.0 and below.
-
-* Python 3.2 is supported by mock 1.3.0 and below - with pip no longer
-supporting 3.2, we cannot test against that version anymore.
-
-Please see the standard library documentation for usage details.
+* Version 2.0.0 is the last version offering official Jython support.
 
 .. index:: installing
 .. _installing:
@@ -60,17 +31,13 @@
 Installing
 ++++++++++
 
-The current version is |release|. Mock is stable and widely used.
-
-* `mock on PyPI <http://pypi.python.org/pypi/mock>`_
-
 .. 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 clone https://github.com/testing-cabal/mock.git``
 
 
 .. index:: pip
@@ -79,18 +46,11 @@
 
     | ``pip install -U mock``
 
-Alternatively you can download the mock distribution from PyPI and after
-unpacking run:
-
-   ``python setup.py install``
-
-
 .. index:: bug reports
 
 Bug Reports
 +++++++++++
 
-Mock uses `unittest2 <http://pypi.python.org/pypi/unittest2>`_ for its own
 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
@@ -99,21 +59,10 @@
 
 .. index:: python changes
 
-Python Changes
-++++++++++++++
+Changelog
++++++++++
 
-Python NEWS entries from cPython:
-
-.. include:: ../NEWS
-
-.. index:: older versions
-
-Older Versions of Python
-++++++++++++++++++++++++
-
-Version 1.0.1 is the last version compatible with Python < 2.6.
-
-Version 2.0.0 is the last version compatible with Python 2.6.
+See the :doc:`change log <changelog>`.
 
 .. index:: maintainer notes
 
@@ -121,74 +70,112 @@
 ++++++++++++++++
 
 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.3, 3.4,
-3.5, nightly Python 3 builds, pypy, pypy3. Jython support is desired, if
-someone could contribute a patch to .travis.yml to support it that would be
-excellent.
+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. tag -s, push --tags origin master
-2. setup.py sdist bdist_wheel upload -s
+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)``.
+- ``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. Patch your git am with `my patch <https://github.com/rbtcollins/git>`_.
-2. Install the applypatch-transform hook from tools/ to your .git hooks dir.
-3. Configure a pre-applypatch hook to test at least all the cPython versions
-   we support on each patch that is applied. I use containers, and a sample
-   script is in tools/pre-applypatch.
-4. Pull down the cPython git mirror: https://github.com/python/cpython.git
-5. Export the new revisions since the ``Last sync`` at the top of this
-   document::
+1. Clone cpython and mock into the same directory, eg:
 
-     revs=${lastsync}
-     rm migrate-export
-     git log --pretty="format:%H " $revs.. -- Lib/unittest/mock.py \
-       Lib/unittest/test/testmock/ > migrate-revs
-     tac migrate-revs > migrate-sorted-revs
-     for rev in $(< migrate-sorted-revs); do
-           git format-patch -1 $rev -k --stdout >> migrate-export;
-           done
-     echo NEW SYNC POINT: $(git rev-parse HEAD)
+   .. code-block:: bash
 
-6. Import into mock::
+       mkdir vcs
+       cd vcs
+       git clone https://github.com/python/cpython.git
+       git clone https://github.com/testing-cabal/mock.git
 
-     git am -k --reject $path-to-cpython/migrate-export
+   Make sure they both on master and up to date!
 
-   This will transform the patches automatically. Currently it will error
-   on every NEWS change as I haven't gotten around to making those patches
-   automatic. Fixup any errors that occur. When the patch is ready, do a ``git
-   add -u`` to update the index and then ``git am --continue`` to move onto
-   the next patch. If the patch is inappropriate e.g. the patch removing
-   __ne__ which would break older pythons, then either do ``git reset --hard;
-   git am --skip`` to discard any partially applied changes and skip over it,
-   or, if it has a NEWS entry thats worth preserving, edit it down to just
-   that, with a note such as we have for the ``__ne__`` patch, and continue on
-   from there.
+2. Create a branch in your ``mock`` clone and switch to it.
 
-   The goal is that every patch work at all times.
+3. Make sure you build a suitable virtualenv for Mock development
+   and activate it. For backporting, this should use Python 3.7+.
 
-7. After the import is complete, update this document with the new sync point.
+4. Run ``backport.py``:
 
-8. Push to a personal branch and propose a PR to the main repo. This will make
-   Travis-CI test it. If it works, push to the main repo.
+   .. 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/extendmock.py b/extendmock.py
deleted file mode 100644
index 0550d9f..0000000
--- a/extendmock.py
+++ /dev/null
@@ -1 +0,0 @@
-# merged into mock.py in Mock 0.7
diff --git a/lastsync.txt b/lastsync.txt
new file mode 100644
index 0000000..1f18392
--- /dev/null
+++ b/lastsync.txt
@@ -0,0 +1 @@
+11a8832c98b3db78727312154dd1d3ba76d639ec
diff --git a/mock.wpr b/mock.wpr
deleted file mode 100644
index e1ded97..0000000
--- a/mock.wpr
+++ /dev/null
@@ -1,26 +0,0 @@
-#!wing
-#!version=4.0
-##################################################################
-# Wing IDE project file                                          #
-##################################################################
-[project attributes]
-proj.directory-list = [{'dirloc': loc('.'),
-                        'excludes': [u'latex',
-                                     u'.hg',
-                                     u'.tox',
-                                     u'dist',
-                                     u'htmlcov',
-                                     u'extendmock.py',
-                                     u'__pycache__',
-                                     u'html',
-                                     u'build',
-                                     u'mock.egg-info',
-                                     u'tests/__pycache__',
-                                     u'.hgignore',
-                                     u'.hgtags'],
-                        'filter': '*',
-                        'include_hidden': 0,
-                        'recursive': 1,
-                        'watch_for_changes': 1}]
-proj.file-type = 'shared'
-testing.auto-test-file-specs = ('test*.py',)
diff --git a/mock/mock.py b/mock/mock.py
index beedd69..2d39253 100644
--- a/mock/mock.py
+++ b/mock/mock.py
@@ -2,7 +2,6 @@
 # Test tools for mocking and patching.
 # E-mail: fuzzyman AT voidspace DOT org DOT uk
 #
-# mock 2.0.0
 # http://www.voidspace.org.uk/python/mock/
 #
 # Copyright (c) 2007-2013, Michael Foord & the mock team
@@ -51,10 +50,12 @@
     'NonCallableMagicMock',
     'mock_open',
     'PropertyMock',
+    'seal',
 )
 
 
 from functools import partial
+import io
 import inspect
 import pprint
 import sys
@@ -62,21 +63,14 @@
     import builtins
 except ImportError:
     import __builtin__ as builtins
-from types import ModuleType
+from types import ModuleType, MethodType
+from unittest.util import safe_repr
 
 import six
 from six import wraps
-# GOOGLE
-# We're going to avoid using pbr so we don't have to import it into AOSP just
-# for the version info, instead we'll hardcode it. This will be safe since mock
-# dev is essentially stable and hasn't been changed in months.
-# from pbr.version import VersionInfo
 
-# _v = VersionInfo('mock').semantic_version()
-# __version__ = _v.release_string()
-# version_info = _v.version_tuple()
-__version__ = '2.0.0'
-version_info = (2, 0, 0, 'final', 0)
+__version__ = '3.0.5'
+version_info = tuple(int(p) for p in __version__.split('.'))
 
 import mock
 
@@ -111,13 +105,7 @@
     del _next
 
 
-_builtins = set(name for name in dir(builtins) if not name.startswith('_'))
-
-BaseExceptions = (BaseException,)
-if 'java' in sys.platform:
-    # jython
-    import java
-    BaseExceptions = (BaseException, java.lang.Throwable)
+_builtins = {name for name in dir(builtins) if not name.startswith('_')}
 
 try:
     _isidentifier = str.isidentifier
@@ -131,11 +119,6 @@
             return False
         return regex.match(string)
 
-self = 'im_self'
-builtin = '__builtin__'
-if six.PY3:
-    self = '__self__'
-    builtin = 'builtins'
 
 # NOTE: This FILTER_DIR is not used. The binding in mock.FILTER_DIR is.
 FILTER_DIR = True
@@ -152,8 +135,8 @@
 
 def _is_exception(obj):
     return (
-        isinstance(obj, BaseExceptions) or
-        isinstance(obj, ClassTypes) and issubclass(obj, BaseExceptions)
+        isinstance(obj, BaseException) or
+        isinstance(obj, ClassTypes) and issubclass(obj, BaseException)
     )
 
 
@@ -161,6 +144,8 @@
     __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,
@@ -209,37 +194,32 @@
         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):
-    funcopy.__name__ = func.__name__
-    funcopy.__doc__ = func.__doc__
-    try:
-        funcopy.__text_signature__ = func.__text_signature__
-    except AttributeError:
-        pass
     # we explicitly don't copy func.__dict__ into this copy as it would
     # expose original attributes that should be mocked
-    try:
-        funcopy.__module__ = func.__module__
-    except AttributeError:
-        pass
-    try:
-        funcopy.__defaults__ = func.__defaults__
-    except AttributeError:
-        pass
-    try:
-        funcopy.__kwdefaults__ = func.__kwdefaults__
-    except AttributeError:
-        pass
+    for attribute in (
+        '__name__', '__doc__', '__text_signature__',
+        '__module__', '__defaults__', '__kwdefaults__',
+    ):
+        try:
+            setattr(funcopy, attribute, getattr(func, attribute))
+        except AttributeError:
+            pass
     if six.PY2:
-        funcopy.func_defaults = func.func_defaults
-        return
+        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
@@ -280,13 +260,11 @@
     # 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.
-    if not _callable(original):
-        return
 
     skipfirst = isinstance(original, ClassTypes)
     result = _get_signature_object(original, instance, skipfirst)
     if result is None:
-        return
+        return mock
     func, sig = result
     def checksig(*args, **kwargs):
         sig.bind(*args, **kwargs)
@@ -301,17 +279,19 @@
     return mock(*args, **kwargs)""" % name
     six.exec_(src, context)
     funcopy = context[name]
-    _setup_func(funcopy, mock)
+    _setup_func(funcopy, mock, sig)
     return funcopy
 
 
-def _setup_func(funcopy, mock):
+def _setup_func(funcopy, mock, sig):
     funcopy.mock = mock
 
-    # can't use isinstance with mocks
-    if not _is_instance_mock(mock):
-        return
-
+    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):
@@ -344,6 +324,10 @@
     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
 
@@ -360,6 +344,13 @@
     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."""
@@ -385,21 +376,15 @@
 ClassType = type(OldStyleClass)
 
 
-def _copy(value):
-    if type(value) in (dict, list, tuple, set):
-        return type(value)(value)
-    return value
-
-
 ClassTypes = (type,)
 if six.PY2:
     ClassTypes = (type, ClassType)
 
-_allowed_names = set((
+_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):
@@ -442,6 +427,14 @@
 
 
 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
@@ -469,8 +462,6 @@
 class _MockIter(object):
     def __init__(self, obj):
         self.obj = iter(obj)
-    def __iter__(self):
-        return self
     def __next__(self):
         return next(self.obj)
 
@@ -507,6 +498,7 @@
         __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
@@ -569,7 +561,7 @@
             if isinstance(spec, ClassTypes):
                 _spec_class = spec
             else:
-                _spec_class = _get_class(spec)
+                _spec_class = type(spec)
             res = _get_signature_object(spec,
                                         _spec_as_instance, _eat_self)
             _spec_signature = res and res[1]
@@ -643,7 +635,7 @@
     side_effect = property(__get_side_effect, __set_side_effect)
 
 
-    def reset_mock(self, visited=None):
+    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 = []
@@ -658,8 +650,13 @@
         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):
+            if isinstance(child, _SpecState) or child is _deleted:
                 continue
             child.reset_mock(visited)
 
@@ -728,7 +725,7 @@
         return result
 
 
-    def __repr__(self):
+    def _extract_mock_name(self):
         _name_list = [self._mock_new_name]
         _parent = self._mock_new_parent
         last = self
@@ -736,7 +733,7 @@
         dot = '.'
         if _name_list == ['()']:
             dot = ''
-        seen = set()
+
         while _parent is not None:
             last = _parent
 
@@ -747,18 +744,16 @@
 
             _parent = _parent._mock_new_parent
 
-            # use ids here so as not to call __hash__ on the mocks
-            if id(_parent) in seen:
-                break
-            seen.add(id(_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
-        name = ''.join(_name_list)
+        return ''.join(_name_list)
+
+    def __repr__(self):
+        name = self._extract_mock_name()
 
         name_string = ''
         if name not in ('mock', 'mock.'):
@@ -770,7 +765,7 @@
             if self._spec_set:
                 spec_string = ' spec_set=%r'
             spec_string = spec_string % self._spec_class.__name__
-        return "<%s%s%s id='%s'>" % (
+        return "<{}{}{} id='{}'>".format(
             type(self).__name__,
             name_string,
             spec_string,
@@ -787,14 +782,17 @@
         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 +
-                          list(self._mock_children)))
+
+        return sorted(set(extras + from_type + from_dict + from_child_mocks))
 
 
     def __setattr__(self, name, value):
@@ -828,6 +826,11 @@
         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)
 
 
@@ -839,11 +842,10 @@
                 # not set on the instance itself
                 return
 
-        if name in self.__dict__:
-            object.__delattr__(self, name)
-
         obj = self._mock_children.get(name, _missing)
-        if obj is _deleted:
+        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]
@@ -856,18 +858,16 @@
 
 
     def _format_mock_failure_message(self, args, kwargs):
-        message = 'Expected call: %s\nActual call: %s'
+        message = 'expected call not found.\nExpected: %s\nActual: %s'
         expected_string = self._format_mock_call_signature(args, kwargs)
         call_args = self.call_args
-        if len(call_args) == 3:
-            call_args = call_args[1:]
         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 a (args, kwargs) tuple), return a
+        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.
@@ -892,8 +892,10 @@
         """
         self = _mock_self
         if self.call_count != 0:
-            msg = ("Expected '%s' to not have been called. Called %s times." %
-                   (self._mock_name or 'mock', self.call_count))
+            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):
@@ -910,8 +912,10 @@
         """
         self = _mock_self
         if not self.call_count == 1:
-            msg = ("Expected '%s' to have been called once. Called %s times." %
-                   (self._mock_name or 'mock', self.call_count))
+            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):
@@ -922,13 +926,16 @@
         self = _mock_self
         if self.call_args is None:
             expected = self._format_mock_call_signature(args, kwargs)
-            raise AssertionError('Expected call: %s\nNot called' % (expected,))
+            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 = '%s\n%s' % (msg, str(cause))
+                msg = '{}\n{}'.format(msg, str(cause))
             return msg
         expected = self._call_matcher((args, kwargs))
         actual = self._call_matcher(self.call_args)
@@ -938,12 +945,14 @@
 
 
     def assert_called_once_with(_mock_self, *args, **kwargs):
-        """assert that the mock was called exactly once and with the specified
-        arguments."""
+        """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." %
-                   (self._mock_name or 'mock', self.call_count))
+            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)
 
@@ -964,8 +973,8 @@
         if not any_order:
             if expected not in all_calls:
                 six.raise_from(AssertionError(
-                    'Calls not found.\nExpected: %r\n'
-                    'Actual: %r' % (_CallList(calls), self.mock_calls)
+                    'Calls not found.\nExpected: %r%s'
+                    % (_CallList(calls), self._calls_repr(prefix="Actual"))
                 ), cause)
             return
 
@@ -979,7 +988,9 @@
                 not_found.append(kall)
         if not_found:
             six.raise_from(AssertionError(
-                '%r not all found in call list' % (tuple(not_found),)
+                '%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)
 
 
@@ -1015,9 +1026,28 @@
                 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:
@@ -1066,73 +1096,68 @@
         self = _mock_self
         self.called = True
         self.call_count += 1
-        _new_name = self._mock_new_name
-        _new_parent = self._mock_new_parent
 
+        # 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)))
 
-        seen = set()
-        skip_next_dot = _new_name == '()'
-        do_method_calls = self._mock_parent is not None
-        name = self._mock_name
+        # follow up the chain of mocks:
+        _new_parent = self._mock_new_parent
         while _new_parent is not None:
-            this_mock_call = _Call((_new_name, args, kwargs))
-            if _new_parent._mock_new_name:
-                dot = '.'
-                if skip_next_dot:
-                    dot = ''
 
-                skip_next_dot = False
-                if _new_parent._mock_new_name == '()':
-                    skip_next_dot = True
-
-                _new_name = _new_parent._mock_new_name + dot + _new_name
-
+            # handle method_calls:
             if do_method_calls:
-                if _new_name == name:
-                    this_method_call = this_mock_call
-                else:
-                    this_method_call = _Call((name, args, kwargs))
-                _new_parent.method_calls.append(this_method_call)
-
+                _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:
-                    name = _new_parent._mock_name + '.' + name
+                    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
 
-            # use ids here so as not to call __hash__ on the mocks
-            _new_parent_id = id(_new_parent)
-            if _new_parent_id in seen:
-                break
-            seen.add(_new_parent_id)
-
-        ret_val = DEFAULT
         effect = self.side_effect
         if effect is not None:
             if _is_exception(effect):
                 raise effect
-
-            if not _callable(effect):
+            elif not _callable(effect):
                 result = next(effect)
                 if _is_exception(result):
                     raise result
-                if result is DEFAULT:
-                    result = self.return_value
+            else:
+                result = effect(*args, **kwargs)
+
+            if result is not DEFAULT:
                 return result
 
-            ret_val = effect(*args, **kwargs)
+        if self._mock_return_value is not DEFAULT:
+            return self.return_value
 
-        if (self._mock_wraps is not None and
-             self._mock_return_value is DEFAULT):
+        if self._mock_wraps is not None:
             return self._mock_wraps(*args, **kwargs)
-        if ret_val is DEFAULT:
-            ret_val = self.return_value
-        return ret_val
+
+        return self.return_value
 
 
 
@@ -1340,7 +1365,7 @@
 
         if not self.create and original is DEFAULT:
             raise AttributeError(
-                "%s does not have the attribute %r" % (target, name)
+                "{} does not have the attribute {!r}".format(target, name)
             )
         return original, local
 
@@ -1474,7 +1499,7 @@
     def __exit__(self, *exc_info):
         """Undo the patch."""
         if not _is_started(self):
-            raise RuntimeError('stop called on unstarted patcher')
+            return
 
         if self.is_local and self.temp_original is not DEFAULT:
             setattr(self.target, self.attribute, self.temp_original)
@@ -1704,8 +1729,6 @@
     """
 
     def __init__(self, in_dict, values=(), clear=False, **kwargs):
-        if isinstance(in_dict, basestring):
-            in_dict = _importer(in_dict)
         self.in_dict = in_dict
         # support any argument supported by dict(...) constructor
         self.values = dict(values)
@@ -1746,6 +1769,8 @@
 
     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
 
@@ -1823,7 +1848,7 @@
     # because there is no idivmod
     "divmod rdivmod neg pos abs invert "
     "complex int float index "
-    "trunc floor ceil "
+    "round trunc floor ceil "
 )
 
 numerics = (
@@ -1836,6 +1861,8 @@
 extra = ''
 if six.PY3:
     extra = 'bool next '
+    if sys.version_info >= (3, 6):
+        extra += 'fspath '
 else:
     extra = 'unicode long nonzero oct hex truediv rtruediv '
 
@@ -1843,13 +1870,14 @@
 # (as they are metaclass methods)
 # __del__ is not supported at all as it causes problems if it exists
 
-_non_defaults = set((
+_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):
@@ -1860,25 +1888,26 @@
     return method
 
 
-_magics = set(
+_magics = {
     '__%s__' % method for method in
     ' '.join([magic_methods, numerics, inplace, right, extra]).split()
-)
+}
 
 _all_magics = _magics | _non_defaults
 
-_unsupported_magics = set((
+_unsupported_magics = {
     '__getattr__', '__setattr__',
-    '__init__', '__new__', '__prepare__'
+    '__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 = {
@@ -1906,14 +1935,18 @@
         ret_val = self.__eq__._mock_return_value
         if ret_val is not DEFAULT:
             return ret_val
-        return self is other
+        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
-        return self is not other
+        if self is other:
+            return False
+        return NotImplemented
     return __ne__
 
 def _get_iter(self):
@@ -1947,6 +1980,7 @@
         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
@@ -2027,10 +2061,6 @@
         self.name = name
         self.parent = parent
 
-    def __call__(self, *args, **kwargs):
-        m = self.create_mock()
-        return m(*args, **kwargs)
-
     def create_mock(self):
         entry = self.name
         parent = self.parent
@@ -2075,7 +2105,7 @@
             return item
 
     kwargs_string = ', '.join([
-        '%s=%r' % (encode_item(key), value) for key, value in sorted(kwargs.items())
+        '{}={!r}'.format(encode_item(key), value) for key, value in sorted(kwargs.items())
     ])
     if args_string:
         formatted_args = args_string
@@ -2107,9 +2137,8 @@
 
     If the _Call has no name then it will match any name.
     """
-    def __new__(cls, value=(), name=None, parent=None, two=False,
+    def __new__(cls, value=(), name='', parent=None, two=False,
                 from_kall=True):
-        name = ''
         args = ()
         kwargs = {}
         _len = len(value)
@@ -2142,9 +2171,9 @@
 
     def __init__(self, value=(), name=None, parent=None, two=False,
                  from_kall=True):
-        self.name = name
-        self.parent = parent
-        self.from_kall = from_kall
+        self._mock_name = name
+        self._mock_parent = parent
+        self._mock_from_kall = from_kall
 
 
     def __eq__(self, other):
@@ -2161,6 +2190,10 @@
         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 = (), {}
@@ -2204,17 +2237,17 @@
     __hash__ = None
 
     def __call__(self, *args, **kwargs):
-        if self.name is None:
+        if self._mock_name is None:
             return _Call(('', args, kwargs), name='()')
 
-        name = self.name + '()'
-        return _Call((self.name, args, kwargs), name=name, parent=self)
+        name = self._mock_name + '()'
+        return _Call((self._mock_name, args, kwargs), name=name, parent=self)
 
 
     def __getattr__(self, attr):
-        if self.name is None:
+        if self._mock_name is None:
             return _Call(name=attr, from_kall=False)
-        name = '%s.%s' % (self.name, attr)
+        name = '{}.{}'.format(self._mock_name, attr)
         return _Call(name=name, parent=self, from_kall=False)
 
 
@@ -2224,9 +2257,25 @@
     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.from_kall:
-            name = self.name or 'call'
+        if not self._mock_from_kall:
+            name = self._mock_name or 'call'
             if name.startswith('()'):
                 name = 'call%s' % name
             return name
@@ -2252,9 +2301,9 @@
         vals = []
         thing = self
         while thing is not None:
-            if thing.from_kall:
+            if thing._mock_from_kall:
                 vals.append(thing)
-            thing = thing.parent
+            thing = thing._mock_parent
         return _CallList(reversed(vals))
 
 
@@ -2300,7 +2349,7 @@
     _kwargs.update(kwargs)
 
     Klass = MagicMock
-    if type(spec) in DescriptorTypes:
+    if inspect.isdatadescriptor(spec):
         # descriptors don't have a spec
         # because we don't know what type they return
         _kwargs = {}
@@ -2334,6 +2383,12 @@
                                             _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
@@ -2409,19 +2464,10 @@
         else:
             return False
 
-    # shouldn't get here unless function is a dynamically provided attribute
-    # XXXX untested behaviour
+    # function is a dynamically provided attribute
     return is_type
 
 
-def _get_class(obj):
-    try:
-        return obj.__class__
-    except AttributeError:
-        # it is possible for objects to have no __class__
-        return type(obj)
-
-
 class _SpecState(object):
 
     def __init__(self, spec, spec_set=False, parent=None,
@@ -2448,25 +2494,13 @@
 
 file_spec = None
 
-def _iterate_read_data(read_data):
-    # Helper for mock_open:
-    # Retrieve lines from read_data via a generator so that separate calls to
-    # readline, read, and readlines are properly interleaved
-    sep = b'\n' if isinstance(read_data, bytes) else '\n'
-    data_as_list = [l + sep for l in read_data.split(sep)]
 
-    if data_as_list[-1] == sep:
-        # If the last line ended in a newline, the list comprehension will have an
-        # extra entry that's just a newline.  Remove this.
-        data_as_list = data_as_list[:-1]
+def _to_stream(read_data):
+    if isinstance(read_data, bytes):
+        return io.BytesIO(read_data)
     else:
-        # If there wasn't an extra newline by itself, then the file being
-        # emulated doesn't have a newline to end the last line  remove the
-        # newline that our naive format() added
-        data_as_list[-1] = data_as_list[-1][:-1]
+        return io.StringIO(read_data)
 
-    for line in data_as_list:
-        yield line
 
 def mock_open(mock=None, read_data=''):
     """
@@ -2477,27 +2511,35 @@
     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` methoddline`, and `readlines` of the
+    `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 list(_state[0])
+        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 type(read_data)().join(_state[0])
+        return _state[0].read(*args, **kwargs)
 
-    def _readline_side_effect():
+    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
@@ -2513,8 +2555,6 @@
     handle = MagicMock(spec=file_spec)
     handle.__enter__.return_value = handle
 
-    _state = [_iterate_read_data(read_data), None]
-
     handle.write.return_value = None
     handle.read.return_value = None
     handle.readline.return_value = None
@@ -2524,9 +2564,10 @@
     _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] = _iterate_read_data(read_data)
+        _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()
@@ -2554,3 +2595,25 @@
         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/conftest.py b/mock/tests/conftest.py
new file mode 100644
index 0000000..78831f6
--- /dev/null
+++ b/mock/tests/conftest.py
@@ -0,0 +1,6 @@
+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
index c7ad20b..d57a372 100644
--- a/mock/tests/support.py
+++ b/mock/tests/support.py
@@ -1,3 +1,10 @@
+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)
@@ -6,9 +13,34 @@
 class SomeClass(object):
     class_attribute = None
 
-    def wibble(self):
-        pass
+    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
index 10acdc3..729947e 100644
--- a/mock/tests/testcallable.py
+++ b/mock/tests/testcallable.py
@@ -2,7 +2,7 @@
 # E-mail: fuzzyman AT voidspace DOT org DOT uk
 # http://www.voidspace.org.uk/python/mock/
 
-import unittest2 as unittest
+import unittest
 from mock.tests.support import is_instance, X, SomeClass
 
 from mock import (
@@ -27,7 +27,7 @@
             self.assertIn(mock.__class__.__name__, repr(mock))
 
 
-    def test_heirarchy(self):
+    def test_hierarchy(self):
         self.assertTrue(issubclass(MagicMock, Mock))
         self.assertTrue(issubclass(NonCallableMagicMock, NonCallableMock))
 
@@ -98,8 +98,7 @@
 
     def test_patch_spec_callable_class(self):
         class CallableX(X):
-            def __call__(self):
-                pass
+            def __call__(self): pass
 
         class Sub(CallableX):
             pass
@@ -108,8 +107,7 @@
             pass
 
         class OldStyle:
-            def __call__(self):
-                pass
+            def __call__(self): pass
 
         class OldStyleSub(OldStyle):
             pass
diff --git a/mock/tests/testhelpers.py b/mock/tests/testhelpers.py
index a87df1b..d56a47f 100644
--- a/mock/tests/testhelpers.py
+++ b/mock/tests/testhelpers.py
@@ -1,25 +1,32 @@
 # 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 unittest2 as unittest
+import sys
+import time
+import unittest
 
 from mock import (
     call, create_autospec, MagicMock,
     Mock, ANY, patch, PropertyMock
 )
-from mock.mock import _Call, _CallList
+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
+    def one(self, a, b): pass
+    def two(self): pass
+    def three(self, a=None): pass
 
 
 
@@ -50,12 +57,9 @@
 
     def test_any_mock_calls_comparison_order(self):
         mock = Mock()
-        d = datetime.now()
         class Foo(object):
-            def __eq__(self, other):
-                return False
-            def __ne__(self, other):
-                return True
+            def __eq__(self, other): pass
+            def __ne__(self, other): pass
 
         for d in datetime.now(), Foo():
             mock.reset_mock()
@@ -148,6 +152,8 @@
         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):
@@ -155,6 +161,8 @@
 
         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), {}))
@@ -167,6 +175,8 @@
         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):
@@ -174,6 +184,8 @@
 
         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)))
@@ -181,6 +193,7 @@
 
     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])
@@ -273,6 +286,22 @@
         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)
@@ -312,6 +341,11 @@
         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):
 
@@ -350,8 +384,7 @@
 
 
     def test_create_autospec_return_value(self):
-        def f():
-            pass
+        def f(): pass
         mock = create_autospec(f, return_value='foo')
         self.assertEqual(mock(), 'foo')
 
@@ -371,8 +404,7 @@
 
     def test_mocking_unbound_methods(self):
         class Foo(object):
-            def foo(self, foo):
-                pass
+            def foo(self, foo): pass
         p = patch.object(Foo, 'foo')
         mock_foo = p.start()
         Foo().foo(1)
@@ -380,23 +412,6 @@
         mock_foo.assert_called_with(1)
 
 
-    @unittest.expectedFailure
-    def test_create_autospec_unbound_methods(self):
-        # see mock issue 128
-        class Foo(object):
-            def foo(self):
-                pass
-
-        klass = create_autospec(Foo)
-        instance = klass()
-        self.assertRaises(TypeError, instance.foo, 1)
-
-        # Note: no type checking on the "self" parameter
-        klass.foo(1)
-        klass.foo.assert_called_with(1)
-        self.assertRaises(TypeError, klass.foo)
-
-
     def test_create_autospec_keyword_arguments(self):
         class Foo(object):
             a = 3
@@ -405,7 +420,7 @@
 
     @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):\n    pass\n"
+        func_def = "def foo(a, *, b=None): pass\n"
         namespace = {}
         exec (func_def, namespace)
         foo = namespace['foo']
@@ -420,8 +435,7 @@
 
     def test_function_as_instance_attribute(self):
         obj = SomeClass()
-        def f(a):
-            pass
+        def f(a): pass
         obj.f = f
 
         mock = create_autospec(obj)
@@ -457,13 +471,56 @@
             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
+            def bar(self, arg): pass
             sorted = sorted
             attr = {}
 
@@ -537,17 +594,13 @@
     def test_descriptors(self):
         class Foo(object):
             @classmethod
-            def f(cls, a, b):
-                pass
+            def f(cls, a, b): pass
             @staticmethod
-            def g(a, b):
-                pass
+            def g(a, b): pass
 
-        class Bar(Foo):
-            pass
+        class Bar(Foo): pass
 
-        class Baz(SomeClass, Bar):
-            pass
+        class Baz(SomeClass, Bar): pass
 
         for spec in (Foo, Foo(), Bar, Bar(), Baz, Baz()):
             mock = create_autospec(spec)
@@ -561,8 +614,7 @@
     @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
+            def f(self, a, b): pass
 
         class Bar(Foo):
             g = Foo()
@@ -582,8 +634,7 @@
 
     def test_recursive(self):
         class A(object):
-            def a(self):
-                pass
+            def a(self): pass
             foo = 'foo bar baz'
             bar = foo
 
@@ -605,11 +656,9 @@
 
     def test_spec_inheritance_for_classes(self):
         class Foo(object):
-            def a(self, x):
-                pass
+            def a(self, x): pass
             class Bar(object):
-                def f(self, y):
-                    pass
+                def f(self, y): pass
 
         class_mock = create_autospec(Foo)
 
@@ -689,8 +738,7 @@
 
 
     def test_function(self):
-        def f(a, b):
-            pass
+        def f(a, b): pass
 
         mock = create_autospec(f)
         self.assertRaises(TypeError, mock)
@@ -720,9 +768,10 @@
             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))
-        s.existing(1, 2)
+        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
@@ -732,8 +781,7 @@
 
     def test_signature_class(self):
         class Foo(object):
-            def __init__(self, a, b=3):
-                pass
+            def __init__(self, a, b=3): pass
 
         mock = create_autospec(Foo)
 
@@ -748,8 +796,7 @@
     @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
+            def __init__(self, a, b=3): pass
 
         mock = create_autospec(Foo)
 
@@ -784,10 +831,8 @@
 
     def test_signature_callable(self):
         class Callable(object):
-            def __init__(self, x, y):
-                pass
-            def __call__(self, a):
-                pass
+            def __init__(self, x, y): pass
+            def __call__(self, a): pass
 
         mock = create_autospec(Callable)
         mock(1, 2)
@@ -843,8 +888,7 @@
 
     def test_autospec_functions_with_self_in_odd_place(self):
         class Foo(object):
-            def f(a, self):
-                pass
+            def f(a, self): pass
 
         a = create_autospec(Foo)
         a.f(10)
@@ -858,8 +902,7 @@
     def test_autospec_property(self):
         class Foo(object):
             @property
-            def foo(self):
-                return 3
+            def foo(self): pass
 
         foo = create_autospec(Foo)
         mock_property = foo.foo
@@ -886,6 +929,140 @@
         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):
@@ -971,5 +1148,40 @@
         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
new file mode 100644
index 0000000..64d62f8
--- /dev/null
+++ b/mock/tests/testhelpers_py3.py
@@ -0,0 +1,23 @@
+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
index f47a202..f6c25fb 100644
--- a/mock/tests/testmagicmethods.py
+++ b/mock/tests/testmagicmethods.py
@@ -11,12 +11,13 @@
     unicode = str
     long = int
 
-import inspect
+import math
+import os
 import sys
 import textwrap
+import unittest
 
 import six
-import unittest2 as unittest
 
 from mock import Mock, MagicMock
 from mock.mock import _magics
@@ -302,7 +303,7 @@
 
         for entry in _magics:
             self.assertTrue(hasattr(mock, entry))
-        self.assertFalse(hasattr(mock, '__imaginery__'))
+        self.assertFalse(hasattr(mock, '__imaginary__'))
 
 
     def test_magic_mock_equality(self):
@@ -330,6 +331,16 @@
         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:
@@ -351,10 +362,20 @@
         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
+            def __iter__(self): pass
 
         mock = Mock(spec=Iterable)
         self.assertRaises(AttributeError, lambda: mock.__iter__)
@@ -378,8 +399,7 @@
 
     def test_magic_methods_and_spec_set(self):
         class Iterable(object):
-            def __iter__(self):
-                pass
+            def __iter__(self): pass
 
         mock = Mock(spec_set=Iterable)
         self.assertRaises(AttributeError, lambda: mock.__iter__)
@@ -405,7 +425,7 @@
         mock = MagicMock()
         def set_setattr():
             mock.__setattr__ = lambda self, name: None
-        self.assertRaisesRegex(AttributeError,
+        self.assertRaisesRegexp(AttributeError,
             "Attempting to set unsupported magic method '__setattr__'.",
             set_setattr
         )
@@ -515,7 +535,7 @@
         self.assertIsInstance(bar_direct, MagicMock)
 
     # http://bugs.python.org/issue23310
-    # Check if you can change behaviour of magic methds in MagicMock init
+    # 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")
diff --git a/mock/tests/testmock.py b/mock/tests/testmock.py
index 66323e9..5f6045a 100644
--- a/mock/tests/testmock.py
+++ b/mock/tests/testmock.py
@@ -4,20 +4,20 @@
 
 import copy
 import pickle
+import re
 import sys
 import tempfile
 
 import six
-import unittest2 as unittest
+import unittest
 
 import mock
-from mock import (
+from mock.mock import (
     call, DEFAULT, patch, sentinel,
     MagicMock, Mock, NonCallableMock,
-    NonCallableMagicMock,
+    NonCallableMagicMock, _Call, _CallList,
     create_autospec
 )
-from mock.mock import _CallList
 from mock.tests.support import is_instance
 
 
@@ -41,16 +41,13 @@
 
 
 class Something(object):
-    def meth(self, a, b, c, d=None):
-        pass
+    def meth(self, a, b, c, d=None): pass
 
     @classmethod
-    def cmeth(cls, a, b, c, d=None):
-        pass
+    def cmeth(cls, a, b, c, d=None): pass
 
     @staticmethod
-    def smeth(a, b, c, d=None):
-        pass
+    def smeth(a, b, c, d=None): pass
 
 
 class Subclass(MagicMock):
@@ -106,6 +103,21 @@
                           "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))
@@ -184,8 +196,7 @@
         results = [1, 2, 3]
         def effect():
             return results.pop()
-        def f():
-            pass
+        def f(): pass
 
         mock = create_autospec(f)
         mock.side_effect = [1, 2, 3]
@@ -200,28 +211,11 @@
 
     def test_autospec_side_effect_exception(self):
         # Test for issue 23661
-        def f():
-            pass
+        def f(): pass
 
         mock = create_autospec(f)
         mock.side_effect = ValueError('Bazinga!')
-        self.assertRaisesRegex(ValueError, 'Bazinga!', mock)
-
-    @unittest.skipUnless('java' in sys.platform,
-                          'This test only applies to Jython')
-    def test_java_exception_side_effect(self):
-        import java
-        mock = Mock(side_effect=java.lang.RuntimeException("Boom!"))
-
-        # can't use assertRaises with java exceptions
-        try:
-            mock(1, 2, fish=3)
-        except java.lang.RuntimeException:
-            pass
-        else:
-            self.fail('java exception not raised')
-        mock.assert_called_with(1,2, fish=3)
-
+        self.assertRaisesRegexp(ValueError, 'Bazinga!', mock)
 
     def test_reset_mock(self):
         parent = Mock()
@@ -290,6 +284,10 @@
         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")
 
@@ -323,11 +321,35 @@
         ])
         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()
@@ -343,9 +365,14 @@
         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
+        def f(a, b, c, d=None): pass
 
         mock = Mock(spec=f)
 
@@ -404,10 +431,17 @@
             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
+        def f(a, b, c, d=None): pass
 
         mock = Mock(spec=f)
 
@@ -501,7 +535,7 @@
 
                 # this should be allowed
                 mock.something
-                self.assertRaisesRegex(
+                self.assertRaisesRegexp(
                     AttributeError,
                     "Mock object has no attribute 'something_else'",
                     getattr, mock, 'something_else'
@@ -512,20 +546,19 @@
         class Something(object):
             x = 3
             __something__ = None
-            def y(self):
-                pass
+            def y(self): pass
 
         def test_attributes(mock):
             # should work
             mock.x
             mock.y
             mock.__something__
-            self.assertRaisesRegex(
+            self.assertRaisesRegexp(
                 AttributeError,
                 "Mock object has no attribute 'z'",
                 getattr, mock, 'z'
             )
-            self.assertRaisesRegex(
+            self.assertRaisesRegexp(
                 AttributeError,
                 "Mock object has no attribute '__foobar__'",
                 getattr, mock, '__foobar__'
@@ -547,6 +580,16 @@
         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()
 
@@ -573,6 +616,110 @@
         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)
@@ -591,13 +738,13 @@
 
     def test_assert_called_with_message(self):
         mock = Mock()
-        self.assertRaisesRegex(AssertionError, 'Not called',
+        self.assertRaisesRegexp(AssertionError, 'not called',
                                 mock.assert_called_with)
 
 
     def test_assert_called_once_with_message(self):
         mock = Mock(name='geoffrey')
-        self.assertRaisesRegex(AssertionError,
+        self.assertRaisesRegexp(AssertionError,
                      r"Expected 'geoffrey' to be called once\.",
                      mock.assert_called_once_with)
 
@@ -640,6 +787,30 @@
         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
@@ -782,6 +953,15 @@
             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')
@@ -805,25 +985,20 @@
 
     def assertRaisesWithMsg(self, exception, message, func, *args, **kwargs):
         # needed because assertRaisesRegex doesn't work easily with newlines
-        try:
+        with self.assertRaises(exception) as context:
             func(*args, **kwargs)
-        except:
-            instance = sys.exc_info()[1]
-            self.assertIsInstance(instance, exception)
-        else:
-            self.fail('Exception %r not raised' % (exception,))
-
-        msg = str(instance)
+        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: %s\nNot called'
+        message = 'expected call not found.\nExpected: %s\nActual: %s'
         self.assertRaisesWithMsg(
-            AssertionError, message % (expected,),
+            AssertionError, message % (expected, actual),
             mock.assert_called_with, 1, '2', 3, bar='foo'
         )
 
@@ -836,7 +1011,7 @@
         for meth in asserters:
             actual = "foo(1, '2', 3, foo='foo')"
             expected = "foo(1, '2', 3, bar='foo')"
-            message = 'Expected call: %s\nActual call: %s'
+            message = 'expected call not found.\nExpected: %s\nActual: %s'
             self.assertRaisesWithMsg(
                 AssertionError, message % (expected, actual),
                 meth, 1, '2', 3, bar='foo'
@@ -846,7 +1021,7 @@
         for meth in asserters:
             actual = "foo(1, '2', 3, foo='foo')"
             expected = "foo(bar='foo')"
-            message = 'Expected call: %s\nActual call: %s'
+            message = 'expected call not found.\nExpected: %s\nActual: %s'
             self.assertRaisesWithMsg(
                 AssertionError, message % (expected, actual),
                 meth, bar='foo'
@@ -856,7 +1031,7 @@
         for meth in asserters:
             actual = "foo(1, '2', 3, foo='foo')"
             expected = "foo(1, 2, 3)"
-            message = 'Expected call: %s\nActual call: %s'
+            message = 'expected call not found.\nExpected: %s\nActual: %s'
             self.assertRaisesWithMsg(
                 AssertionError, message % (expected, actual),
                 meth, 1, 2, 3
@@ -866,7 +1041,7 @@
         for meth in asserters:
             actual = "foo(1, '2', 3, foo='foo')"
             expected = "foo()"
-            message = 'Expected call: %s\nActual call: %s'
+            message = 'expected call not found.\nExpected: %s\nActual: %s'
             self.assertRaisesWithMsg(
                 AssertionError, message % (expected, actual), meth
             )
@@ -950,6 +1125,69 @@
                              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
@@ -1008,9 +1246,8 @@
         mock(2, b=4)
 
         self.assertEqual(len(mock.call_args), 2)
-        args, kwargs = mock.call_args
-        self.assertEqual(args, (2,))
-        self.assertEqual(kwargs, dict(b=4))
+        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):
@@ -1165,8 +1402,7 @@
 
 
     def test_assert_has_calls_with_function_spec(self):
-        def f(a, b, c, d=None):
-            pass
+        def f(a, b, c, d=None): pass
 
         mock = Mock(spec=f)
 
@@ -1224,8 +1460,7 @@
 
 
     def test_assert_any_call_with_function_spec(self):
-        def f(a, b, c, d=None):
-            pass
+        def f(a, b, c, d=None): pass
 
         mock = Mock(spec=f)
 
@@ -1245,8 +1480,7 @@
 
 
     def test_mock_calls_create_autospec(self):
-        def f(a, b):
-            pass
+        def f(a, b): pass
         obj = Iter()
         obj.f = f
 
@@ -1267,6 +1501,20 @@
         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()
@@ -1286,6 +1534,13 @@
         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):
@@ -1307,6 +1562,20 @@
         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()
@@ -1324,6 +1593,24 @@
         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
@@ -1468,6 +1755,16 @@
         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'))
@@ -1486,7 +1783,21 @@
         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()
@@ -1562,6 +1873,43 @@
             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)
@@ -1570,21 +1918,59 @@
             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)
 
-    @unittest.expectedFailure
-    def test_pickle(self):
-        for Klass in (MagicMock, Mock, Subclass, NonCallableMagicMock):
-            mock = Klass(name='foo', attribute=3)
-            mock.foo(1, 2, 3)
-            data = pickle.dumps(mock)
-            new = pickle.loads(data)
+    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)
 
-            new.foo.assert_called_once_with(1, 2, 3)
-            self.assertFalse(new.called)
-            self.assertTrue(is_instance(new, Klass))
-            self.assertIsInstance(new, Thing)
-            self.assertIn('name="foo"', repr(new))
-            self.assertEqual(new.attribute, 3)
+    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__':
diff --git a/mock/tests/testpatch.py b/mock/tests/testpatch.py
index f31ccef..bbd6d26 100644
--- a/mock/tests/testpatch.py
+++ b/mock/tests/testpatch.py
@@ -6,14 +6,14 @@
 import sys
 
 import six
-import unittest2 as unittest
+import unittest
 
 from mock.tests import support
-from mock.tests.support import SomeClass, is_instance
+from mock.tests.support import SomeClass, is_instance, uncache
 
 from mock import (
     NonCallableMock, CallableMixin, patch, sentinel,
-    MagicMock, Mock, NonCallableMagicMock, patch,
+    MagicMock, Mock, NonCallableMagicMock,
     DEFAULT, call
 )
 from mock.mock import _patch, _get_target
@@ -47,23 +47,24 @@
 
 
 class Foo(object):
-    def __init__(self, a):
-        pass
-    def f(self, a):
-        pass
-    def g(self):
-        pass
+    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
+        def a(self): pass
 
 foo_name = '%s.Foo' % __name__
 
 
-def function(a, b=Foo):
-    pass
+def function(a, b=Foo): pass
 
 
 class Container(object):
@@ -366,31 +367,19 @@
 
 
     def test_patch_wont_create_by_default(self):
-        try:
+        with self.assertRaises(AttributeError):
             @patch('%s.frooble' % builtin_string, sentinel.Frooble)
-            def test():
-                self.assertEqual(frooble, sentinel.Frooble)
+            def test(): pass
 
             test()
-        except AttributeError:
-            pass
-        else:
-            self.fail('Patching non existent attributes should fail')
-
         self.assertRaises(NameError, lambda: frooble)
 
 
     def test_patchobject_wont_create_by_default(self):
-        try:
+        with self.assertRaises(AttributeError):
             @patch.object(SomeClass, 'ord', sentinel.Frooble)
-            def test():
-                self.fail('Patching non existent attributes should fail')
-
+            def test(): pass
             test()
-        except AttributeError:
-            pass
-        else:
-            self.fail('Patching non existent attributes should fail')
         self.assertFalse(hasattr(SomeClass, 'ord'))
 
 
@@ -480,6 +469,9 @@
             attribute = sentinel.Original
 
         class Foo(object):
+
+            test_class_attr = 'whatever'
+
             def test_method(other_self, mock_something):
                 self.assertEqual(PTModule.something, mock_something,
                                  "unpatched")
@@ -638,8 +630,7 @@
         @patch('%s.SomeClass' % __name__, object(), autospec=True)
         @patch.object(SomeClass, object())
         @patch.dict(foo)
-        def some_name():
-            pass
+        def some_name(): pass
 
         self.assertEqual(some_name.__name__, 'some_name')
 
@@ -650,12 +641,9 @@
         @patch.dict(foo, {'a': 'b'})
         def test():
             raise NameError('Konrad')
-        try:
+
+        with self.assertRaises(NameError):
             test()
-        except NameError:
-            pass
-        else:
-            self.fail('NameError not raised by test')
 
         self.assertEqual(foo, {})
 
@@ -668,57 +656,37 @@
         test()
 
 
-    @unittest.expectedFailure
-    def test_patch_descriptor(self):
-        # would be some effort to fix this - we could special case the
-        # builtin descriptors: classmethod, property, staticmethod
-        class Nothing(object):
-            foo = None
+    def test_patch_dict_with_unicode(self):
+        @patch.dict(u'os.environ', {'konrad_delong': 'some value'})
+        def test():
+            self.assertIn('konrad_delong', os.environ)
 
-        class Something(object):
-            foo = {}
+        test()
 
-            @patch.object(Nothing, 'foo', 2)
-            @classmethod
-            def klass(cls):
-                self.assertIs(cls, Something)
 
-            @patch.object(Nothing, 'foo', 2)
-            @staticmethod
-            def static(arg):
-                return arg
-
-            @patch.dict(foo)
-            @classmethod
-            def klass_dict(cls):
-                self.assertIs(cls, Something)
-
-            @patch.dict(foo)
-            @staticmethod
-            def static_dict(arg):
-                return arg
-
-        # these will raise exceptions if patching descriptors is broken
-        self.assertEqual(Something.static('f00'), 'f00')
-        Something.klass()
-        self.assertEqual(Something.static_dict('f00'), 'f00')
-        Something.klass_dict()
-
-        something = Something()
-        self.assertEqual(something.static('f00'), 'f00')
-        something.klass()
-        self.assertEqual(something.static_dict('f00'), 'f00')
-        something.klass_dict()
+    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_set=SomeClass)
+        @patch('%s.SomeClass' % __name__, spec=SomeClass, spec_set=True)
         def test(MockClass):
             MockClass.z = 'foo'
 
         self.assertRaises(AttributeError, test)
 
-        @patch.object(support, 'SomeClass', spec_set=SomeClass)
+        @patch.object(support, 'SomeClass', spec=SomeClass, spec_set=True)
         def test(MockClass):
             MockClass.z = 'foo'
 
@@ -759,10 +727,18 @@
 
 
     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)
 
-        # calling stop without start used to produce a very obscure error
-        self.assertRaises(RuntimeError, patcher.stop)
+        patcher.start()
+        patcher.stop()
+        self.assertIsNone(patcher.stop())
 
 
     def test_patchobject_start_stop(self):
@@ -902,17 +878,13 @@
 
     def test_autospec(self):
         class Boo(object):
-            def __init__(self, a):
-                pass
-            def f(self, a):
-                pass
-            def g(self):
-                pass
+            def __init__(self, a): pass
+            def f(self, a): pass
+            def g(self): pass
             foo = 'bar'
 
             class Bar(object):
-                def a(self):
-                    pass
+                def a(self): pass
 
         def _test(mock):
             mock(1)
@@ -974,8 +946,14 @@
     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)
 
@@ -996,6 +974,18 @@
         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)
@@ -1265,7 +1255,6 @@
 
 
     def test_patch_multiple_create_mocks_different_order(self):
-        # bug revealed by Jython!
         original_f = Foo.f
         original_g = Foo.g
 
@@ -1442,20 +1431,17 @@
         @patch.object(Foo, 'g', 1)
         @patch.object(Foo, 'missing', 1)
         @patch.object(Foo, 'f', 1)
-        def thing1():
-            pass
+        def thing1(): pass
 
         @patch.object(Foo, 'missing', 1)
         @patch.object(Foo, 'g', 1)
         @patch.object(Foo, 'f', 1)
-        def thing2():
-            pass
+        def thing2(): pass
 
         @patch.object(Foo, 'g', 1)
         @patch.object(Foo, 'f', 1)
         @patch.object(Foo, 'missing', 1)
-        def thing3():
-            pass
+        def thing3(): pass
 
         for func in thing1, thing2, thing3:
             self.assertRaises(AttributeError, func)
@@ -1474,20 +1460,17 @@
         @patch.object(Foo, 'g', 1)
         @patch.object(Foo, 'foo', new_callable=crasher)
         @patch.object(Foo, 'f', 1)
-        def thing1():
-            pass
+        def thing1(): pass
 
         @patch.object(Foo, 'foo', new_callable=crasher)
         @patch.object(Foo, 'g', 1)
         @patch.object(Foo, 'f', 1)
-        def thing2():
-            pass
+        def thing2(): pass
 
         @patch.object(Foo, 'g', 1)
         @patch.object(Foo, 'f', 1)
         @patch.object(Foo, 'foo', new_callable=crasher)
-        def thing3():
-            pass
+        def thing3(): pass
 
         for func in thing1, thing2, thing3:
             self.assertRaises(NameError, func)
@@ -1513,8 +1496,7 @@
             patcher.additional_patchers = additionals
 
             @patcher
-            def func():
-                pass
+            def func(): pass
 
             self.assertRaises(AttributeError, func)
             self.assertEqual(Foo.f, original_f)
@@ -1542,8 +1524,7 @@
             patcher.additional_patchers = additionals
 
             @patcher
-            def func():
-                pass
+            def func(): pass
 
             self.assertRaises(NameError, func)
             self.assertEqual(Foo.f, original_f)
@@ -1663,20 +1644,19 @@
 
 
     def test_patch_imports_lazily(self):
-        sys.modules.pop('squizz', None)
-
         p1 = patch('squizz.squozz')
         self.assertRaises(ImportError, p1.start)
 
-        squizz = Mock()
-        squizz.squozz = 6
-        sys.modules['squizz'] = squizz
-        p1 = patch('squizz.squozz')
-        squizz.squozz = 3
-        p1.start()
-        p1.stop()
-        self.assertEqual(squizz.squozz, 3)
+        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:
@@ -1699,7 +1679,12 @@
         def test(mock):
             raise RuntimeError
 
-        self.assertRaises(RuntimeError, test)
+        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')
@@ -1879,5 +1864,35 @@
                 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
new file mode 100644
index 0000000..63a8541
--- /dev/null
+++ b/mock/tests/testsealable.py
@@ -0,0 +1,176 @@
+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
index 69b2042..1411445 100644
--- a/mock/tests/testsentinel.py
+++ b/mock/tests/testsentinel.py
@@ -2,8 +2,9 @@
 # E-mail: fuzzyman AT voidspace DOT org DOT uk
 # http://www.voidspace.org.uk/python/mock/
 
-import unittest2 as unittest
-
+import unittest
+import copy
+import pickle
 from mock import sentinel, DEFAULT
 
 
@@ -28,6 +29,16 @@
         # 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
new file mode 100644
index 0000000..4882572
--- /dev/null
+++ b/mock/tests/testsupport.py
@@ -0,0 +1,14 @@
+# 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
index aa7812b..587fde9 100644
--- a/mock/tests/testwith.py
+++ b/mock/tests/testwith.py
@@ -4,7 +4,7 @@
 
 from warnings import catch_warnings
 
-import unittest2 as unittest
+import unittest
 
 from mock.tests.support import is_instance
 from mock import MagicMock, Mock, patch, sentinel, mock_open, call
@@ -14,6 +14,8 @@
 something_else  = sentinel.SomethingElse
 
 
+class SampleException(Exception): pass
+
 
 class WithTest(unittest.TestCase):
 
@@ -24,14 +26,10 @@
 
 
     def test_with_statement_exception(self):
-        try:
+        with self.assertRaises(SampleException):
             with patch('%s.something' % __name__, sentinel.Something2):
                 self.assertEqual(something, sentinel.Something2, "unpatched")
-                raise Exception('pow')
-        except Exception:
-            pass
-        else:
-            self.fail("patch swallowed exception")
+                raise SampleException()
         self.assertEqual(something, sentinel.Something)
 
 
@@ -131,6 +129,19 @@
 
         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):
@@ -193,6 +204,7 @@
 
     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')
@@ -202,6 +214,7 @@
         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')
@@ -209,6 +222,19 @@
             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):
@@ -262,7 +288,12 @@
         # 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)
+        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):
diff --git a/release.py b/release.py
new file mode 100644
index 0000000..2556d50
--- /dev/null
+++ b/release.py
@@ -0,0 +1,92 @@
+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/requirements.txt b/requirements.txt
deleted file mode 100644
index 31bbe5d..0000000
--- a/requirements.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-funcsigs>=1;python_version<"3.3"
-# For runtime needs this is correct. For setup_requires needs, 1.2.0 is needed
-# but setuptools can't cope with conflicts in setup_requires, so thats
-# unversioned.
-pbr>=0.11
-six>=1.9
diff --git a/setup.cfg b/setup.cfg
index 25c280b..7283b79 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,11 +1,12 @@
 [metadata]
 name = mock
 summary = Rolling backport of unittest.mock for all Pythons
-home-page = https://github.com/testing-cabal/mock
+home-page = http://mock.readthedocs.org/en/latest/
 description-file = README.rst
 author = Testing Cabal
 author-email = testing-in-python@lists.idyll.org
-classifier = 
+license = OSI Approved :: BSD License
+classifier =
     Development Status :: 5 - Production/Stable
     Environment :: Console
     Intended Audience :: Developers
@@ -15,12 +16,11 @@
     Programming Language :: Python :: 2
     Programming Language :: Python :: 2.7
     Programming Language :: Python :: 3
-    Programming Language :: Python :: 3.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 :: Jython
     Programming Language :: Python :: Implementation :: PyPy
     Topic :: Software Development :: Libraries
     Topic :: Software Development :: Libraries :: Python Modules
@@ -28,14 +28,28 @@
 keyword =
     testing, test, mock, mocking, unittest, patching, stubs, fakes, doubles
 
-[extras]
-test =
-  unittest2>=1.1.0
+[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
-
-[files]
-packages = mock
+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
index 5f727ae..d47345f 100755
--- a/setup.py
+++ b/setup.py
@@ -1,6 +1,10 @@
-#!/usr/bin/env python
+import re
+from os.path import join
+
 import setuptools
 
 setuptools.setup(
-    setup_requires=['pbr>=1.3', 'setuptools>=17.1'],
-    pbr=True)
+    version=re.search("__version__ = '([^']+)'",
+                      open(join('mock', 'mock.py')).read()).group(1),
+    long_description=open('README.rst').read(),
+)
diff --git a/tools/applypatch-transform b/tools/applypatch-transform
deleted file mode 100755
index 52fcd93..0000000
--- a/tools/applypatch-transform
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/sh
-#
-# An example hook script to transform a patch taken from an email
-# by git am.
-#
-# The hook should exit with non-zero status after issuing an
-# appropriate message if it wants to stop the commit.  The hook is
-# allowed to edit the patch file.
-#
-# To enable this hook, rename this file to "applypatch-transform".
-#
-# This example changes the path of Lib/unittest/mock.py to mock.py
-# Lib/unittest/tests/testmock to tests and Misc/NEWS to NEWS, and
-# finally skips any patches that did not alter mock.py or its tests.
-
-set -eux
-
-patch_path=$1
-
-# Pull out mock.py
-filterdiff --clean --strip 3 --addprefix=a/mock/ -i 'a/Lib/unittest/mock.py' -i 'b/Lib/unittest/mock.py' $patch_path > $patch_path.mock
-# And the tests
-filterdiff --clean --strip 5 --addprefix=a/mock/tests/ -i 'a/Lib/unittest/test/testmock/*.py' -i 'b/Lib/unittest/test/testmock/*.py' $patch_path > $patch_path.tests
-# Lastly we want to pick up any NEWS entries.
-filterdiff --strip 2 --addprefix=a/ -i a/Misc/NEWS -i b/Misc/NEWS $patch_path > $patch_path.NEWS
-cp $patch_path $patch_path.orig
-# bash
-cat $patch_path.mock $patch_path.tests > $patch_path
-filtered=$(cat $patch_path)
-if [ -n "${filtered}" ]; then
-  cat $patch_path.NEWS >> $patch_path
-  exitcode=0
-else
-  exitcode=1
-fi
-
-rm $patch_path.mock $patch_path.tests $patch_path.NEWS
-exit $exitcode
diff --git a/tools/pre-applypatch b/tools/pre-applypatch
deleted file mode 100755
index 28ab636..0000000
--- a/tools/pre-applypatch
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/bin/bash
-#
-# An example hook script to verify what is about to be committed
-# by applypatch from an e-mail message.
-#
-# The hook should exit with non-zero status after issuing an
-# appropriate message if it wants to stop the commit.
-#
-# To enable this hook, rename this file to "pre-applypatch".
-
-set -eu
-
-#. git-sh-setup
-echo "** in hook **"
-
-function test_version {
-  version=$1
-  host=$(ls ~/.virtualenvs/mock-$version-* -d | sed -e "s/^.*mock-$version-//")
-  if [ -z "$host" ]; then
-    echo "No host found for $version"
-    return 1
-  fi
-  echo testing $version in virtualenv mock-$version-$host on ssh host $host
-  ssh $host "cd work/mock && . ~/.virtualenvs/mock-$version-$host/bin/activate && pip install .[test] && unit2"
-}
-
-find . -name "*.pyc" -exec rm "{}" \;
-
-test_version 2.7
-test_version 3.3
-test_version 3.4
-test_version 3.5
-test_version cpython
-test_version pypy
-
-echo '** pre-apply complete and successful **'
diff --git a/tox.ini b/tox.ini
index d7fef31..90ca455 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,22 +1,12 @@
 [tox]
-envlist = py27,pypy,py33,jython
+envlist = py27,pypy,py34,py35,py36,py37,docs
 
 [testenv]
-deps=unittest2
-commands={envbindir}/unit2 discover []
+commands =
+    {envbindir}/pytest {posargs}
 
-[testenv:py27]
-commands=
-    {envbindir}/unit2 discover []
-    {envbindir}/sphinx-build -E -b doctest docs html
+[testenv:docs]
 deps =
-    unittest2
     sphinx
-
-[testenv:py33]
-commands=
-    {envbindir}/python -m unittest discover []
-deps =
-
-# note for jython. Execute in tests directory:
-# rm `find . -name '*$py.class'`
\ No newline at end of file
+commands =
+    {envbindir}/python setup.py build_sphinx
diff --git a/unittest.cfg b/unittest.cfg
deleted file mode 100644
index b2d6f67..0000000
--- a/unittest.cfg
+++ /dev/null
@@ -1,95 +0,0 @@
-
-[unittest]
-plugins = 
-    unittest2.plugins.debugger
-    unittest2.plugins.checker
-    unittest2.plugins.doctestloader
-    unittest2.plugins.matchregexp
-    unittest2.plugins.moduleloading
-    unittest2.plugins.testcoverage
-    unittest2.plugins.growl
-    unittest2.plugins.filtertests
-    unittest2.plugins.junitxml
-    unittest2.plugins.timed
-    unittest2.plugins.counttests
-    unittest2.plugins.logchannels
-
-excluded-plugins =
-
-# 0, 1 or 2 (default is 1)
-# quiet, normal or verbose
-# can be overriden at command line
-verbosity = normal
-
-# true or false
-# even if false can be switched on at command line
-catch =
-buffer =
-failfast =
-
-
-[matchregexp]
-always-on = False
-full-path = True
-
-[debugger]
-always-on = False
-errors-only = True
-
-[coverage]
-always-on = False
-config =
-report-html = False
-# only used if report-html is false
-annotate = False
-# defaults to './htmlcov/'
-html-directory =
-# if unset will output to console
-text-file =
-branch = False
-timid = False
-cover-pylib = False
-exclude-lines = 
-    # Have to re-enable the standard pragma
-    pragma: no cover
-
-    # Don't complain about missing debug-only code:
-    def __repr__
-    if self\.debug
-
-    # Don't complain if tests don't hit defensive assertion code:
-    raise AssertionError
-    raise NotImplementedError
-
-    # Don't complain if non-runnable code isn't run:
-    if 0:
-    if __name__ == .__main__.
-    
-ignore-errors = False
-modules =
-
-[growl]
-always-on = False
-
-[doctest]
-always-on = False
-
-[module-loading]
-always-on = False
-
-[checker]
-always-on = False
-pep8 = False
-pyflakes = True
-
-[junit-xml]
-always-on = False
-path = junit.xml
-
-[timed]
-always-on = True
-threshold = 0.01
-
-[count]
-always-on = True
-enhanced = False