[Python-modules-commits] [pytest-mock] 01/07: New upstream release.

Vincent Bernat bernat at moszumanska.debian.org
Mon Sep 18 17:32:50 UTC 2017


This is an automated email from the git hooks/post-receive script.

bernat pushed a commit to branch debian/master
in repository pytest-mock.

commit 506682a7c50e3bdc970eb257781ecc44cddb1714
Author: Vincent Bernat <bernat at debian.org>
Date:   Mon Sep 18 19:14:14 2017 +0200

    New upstream release.
---
 .travis.yml                      |  23 ++++---
 CHANGELOG.rst                    |  73 +++++++++++++++++++++-
 MANIFEST.in                      |   2 -
 PKG-INFO                         |  99 ++++++++++++++++++++++++------
 README.rst                       |  97 +++++++++++++++++++++++------
 _pytest_mock_version.py          |   2 +-
 appveyor.yml                     |   4 +-
 pytest_mock.egg-info/PKG-INFO    |  99 ++++++++++++++++++++++++------
 pytest_mock.egg-info/SOURCES.txt |   1 -
 pytest_mock.py                   | 107 ++++++++++++++++++++++----------
 setup.cfg                        |   1 -
 setup.py                         |   2 -
 test_pytest_mock.py              | 128 ++++++++++++++++++++++++++-------------
 tox.ini                          |   3 +-
 14 files changed, 495 insertions(+), 146 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 46396d4..5f88103 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,14 +1,22 @@
 language: python
 python:
+  - "2.6"
+  - "2.7"
+  - "3.3"
+  - "3.4"
   - "3.5"
-  - "3.6-dev"
+  - "3.6"
+
+matrix:
+  include:
+    - python: '3.6'
+      env: TOXENV=linting
 
 install:
-  - pip install tox coveralls
+  - pip install tox-travis coveralls
 
 script:
-  - if [[ $TRAVIS_PYTHON_VERSION != 3.6-dev ]]; then tox; fi
-  - if [[ $TRAVIS_PYTHON_VERSION == 3.6-dev ]]; then tox -e py36-pytest28,py36-pytest29,py36-pytest30; fi
+  - tox
 
 after_success:
   - coveralls
@@ -16,10 +24,11 @@ after_success:
 deploy:
   provider: pypi
   user: nicoddemus
+  skip_upload_docs: true
+  distributions: sdist bdist_wheel
   password:
-    secure: bB4adUZVIkt31cmNklskyIDNehujKToGnStnlunp7P8CBF6CGeNqkYU17emAPvfZbTb/ClUpiO9r6AD1ej32Uyr+I8qUyhuYtHG3JGp+WRR/tw+ytAZIJ9i+PMjBv1RAdyLENJ/Tx0LKHKsABr8dQIieLFqKZJuT77f/5ZkvI/U=
+    secure: OEWrbk09CZRrwFE6sBpRqQHu45zRu1S0Ly1ZeprkFCKxMd9tZOnrYM5qxCDQXxFHIvuyajuJ+qWTOgxUvurQMNsD6DbvJKTJ0R8upH1b1Q95KK8xiJFedhqBEUga5GrInK59oo0Sgblse2jtH5NnHXRUClSdT+iHdLY5sljCTRg=
   on:
     tags: true
-    distributions: sdist bdist_wheel
     repo: pytest-dev/pytest-mock
-    condition: $TRAVIS_PYTHON_VERSION = 3.5
+    condition: $TRAVIS_PYTHON_VERSION = 3.6
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 09beec4..9b7945f 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -1,5 +1,74 @@
-1.3
----
+1.6.3
+-----
+
+* Fix ``UnicodeDecodeError`` during assert introspection in ``assert_called_with`` in Python 2.
+  Thanks `@AndreasHogstrom`_ for the report (`#91`_).
+
+
+.. _ at AndreasHogstrom: https://github.com/AndreasHogstrom
+
+.. _#91: https://github.com/pytest-dev/pytest-mock/issues/91
+
+1.6.2
+-----
+
+* Provide source package in ``tar.gz`` format and remove obsolete ``MANIFEST.in``.
+
+1.6.1
+-----
+
+* Fix ``mocker.resetall()`` by ignoring mocker objects which don't have a
+  ``resetall`` method, like for example ``patch.dict``.
+  Thanks `@jdavisp3`_ for the PR (`#88`_).
+
+.. _ at jdavisp3: https://github.com/jdavisp3
+
+.. _#88: https://github.com/pytest-dev/pytest-mock/pull/88
+
+1.6.0
+-----
+
+* The original assertions raised by the various ``Mock.assert_*`` methods
+  now appear in the failure message, in addition to the message obtained from
+  pytest introspection.
+  Thanks `@quodlibetor`_ for the initial patch (`#79`_).
+
+.. _ at quodlibetor: https://github.com/quodlibetor
+
+.. _#79: https://github.com/pytest-dev/pytest-mock/pull/79
+
+1.5.0
+-----
+
+* New ``mocker.mock_module`` variable points to the underlying mock module being used
+  (``unittest.mock`` or ``mock``).
+  Thanks `@blueyed`_ for the request (`#71`_).
+
+.. _#71: https://github.com/pytest-dev/pytest-mock/pull/71
+
+1.4.0
+-----
+
+* New configuration variable, ``mock_use_standalone_module`` (defaults to ``False``). This forces
+  the plugin to import ``mock`` instead of ``unittest.mock`` on Python 3. This is useful to import
+  a newer version than the one available in the Python distribution.
+
+* Previously the plugin would first try to import ``mock`` and fallback to ``unittest.mock``
+  in case of an ``ImportError``, but this behavior has been removed because it could hide
+  hard to debug import errors (`#68`_).
+
+* Now ``mock`` (Python 2) and ``unittest.mock`` (Python 3) are lazy-loaded to make it possible to
+  implement the new ``mock_use_standlone_module`` configuration option. As a consequence of this
+  the undocumented ``pytest_mock.mock_module`` variable, which pointed to the actual mock module
+  being used by the plugin, has been removed.
+
+* `DEFAULT <https://docs.python.org/3/library/unittest.mock.html#default>`_ is now available from
+  the ``mocker`` fixture.
+
+.. _#68: https://github.com/pytest-dev/pytest-mock/issues/68
+
+1.3.0
+-----
 
 * Add support for Python 3.6. Thanks `@hackebrot`_ for the report (`#59`_).
 
diff --git a/MANIFEST.in b/MANIFEST.in
deleted file mode 100644
index 74215c3..0000000
--- a/MANIFEST.in
+++ /dev/null
@@ -1,2 +0,0 @@
-include README.md
-include LICENSE
\ No newline at end of file
diff --git a/PKG-INFO b/PKG-INFO
index 653efb9..e4952bd 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: pytest-mock
-Version: 1.3.0
+Version: 1.6.3
 Summary: Thin-wrapper around the mock package for easier use with py.test
 Home-page: https://github.com/pytest-dev/pytest-mock/
 Author: Bruno Oliveira
@@ -17,7 +17,14 @@ Description: ===========
         
         .. code-block:: python
         
-        
+            import os
+            
+            class UnixFS:
+            
+                @staticmethod
+                def rm(filename):
+                    os.remove(filename)
+            
             def test_unix_fs(mocker):
                 mocker.patch('os.remove')
                 UnixFS.rm('file')
@@ -26,21 +33,21 @@ Description: ===========
         
         .. Using PNG badges because PyPI doesn't support SVG
         
-        |python| |version| |downloads| |ci| |appveyor| |coverage|
+        |python| |version| |anaconda| |ci| |appveyor| |coverage|
         
-        .. |version| image:: http://img.shields.io/pypi/v/pytest-mock.png
+        .. |version| image:: http://img.shields.io/pypi/v/pytest-mock.svg
           :target: https://pypi.python.org/pypi/pytest-mock
         
-        .. |downloads| image:: http://img.shields.io/pypi/dm/pytest-mock.png
-          :target: https://pypi.python.org/pypi/pytest-mock
+        .. |anaconda| image:: https://anaconda.org/conda-forge/pytest-mock/badges/version.svg
+            :target: https://anaconda.org/conda-forge/pytest-mock
         
-        .. |ci| image:: http://img.shields.io/travis/pytest-dev/pytest-mock.png
+        .. |ci| image:: http://img.shields.io/travis/pytest-dev/pytest-mock.svg
           :target: https://travis-ci.org/pytest-dev/pytest-mock
         
         .. |appveyor| image:: https://ci.appveyor.com/api/projects/status/pid1t7iuwhkm9eh6/branch/master?svg=true
           :target: https://ci.appveyor.com/project/pytestbot/pytest-mock
         
-        .. |coverage| image:: http://img.shields.io/coveralls/pytest-dev/pytest-mock.png
+        .. |coverage| image:: http://img.shields.io/coveralls/pytest-dev/pytest-mock.svg
           :target: https://coveralls.io/r/pytest-dev/pytest-mock
         
         .. |python| image:: https://img.shields.io/pypi/pyversions/pytest-mock.svg
@@ -76,6 +83,7 @@ Description: ===========
         * `MagicMock <https://docs.python.org/3/library/unittest.mock.html#unittest.mock.MagicMock>`_
         * `PropertyMock <https://docs.python.org/3/library/unittest.mock.html#unittest.mock.PropertyMock>`_
         * `ANY <https://docs.python.org/3/library/unittest.mock.html#any>`_
+        * `DEFAULT <https://docs.python.org/3/library/unittest.mock.html#default>`_ *(Version 1.4)*
         * `call <https://docs.python.org/3/library/unittest.mock.html#call>`_ *(Version 1.1)*
         * `sentinel <https://docs.python.org/3/library/unittest.mock.html#sentinel>`_ *(Version 1.2)*
         * `mock_open <https://docs.python.org/3/library/unittest.mock.html#mock-open>`_
@@ -133,16 +141,32 @@ Description: ===========
         diff::
         
         
-                    m = mocker.patch.object(DS, 'create_char')
-                    DS().create_char('Raistlin', class_='mag', gift=12)
-            >       m.assert_called_once_with('Raistlin', class_='mage', gift=12)
-            E       assert {'class_': 'mag', 'gift': 12} == {'class_': 'mage', 'gift': 12}
-            E         Omitting 1 identical items, use -v to show
-            E         Differing items:
-            E         {'class_': 'mag'} != {'class_': 'mage'}
+            mocker = <pytest_mock.MockFixture object at 0x0381E2D0>
+        
+                def test(mocker):
+                    m = mocker.Mock()
+                    m('fo')
+            >       m.assert_called_once_with('', bar=4)
+            E       AssertionError: Expected call: mock('', bar=4)
+            E       Actual call: mock('fo')
+            E
+            E       pytest introspection follows:
+            E
+            E       Args:
+            E       assert ('fo',) == ('',)
+            E         At index 0 diff: 'fo' != ''
+            E         Use -v to get the full diff
+            E       Kwargs:
+            E       assert {} == {'bar': 4}
+            E         Right contains more items:
+            E         {'bar': 4}
             E         Use -v to get the full diff
         
         
+        test_foo.py:6: AssertionError
+        ========================== 1 failed in 0.03 seconds ===========================
+        
+        
         This is useful when asserting mock calls with many/nested arguments and trying
         to quickly see the difference.
         
@@ -158,7 +182,25 @@ Description: ===========
         mechanism used to suppress traceback entries from ``mock`` module does not work with that option
         anyway plus it generates confusing messages on Python 3.5 due to exception chaining
         
-        .. _advanced assertions: https://pytest.org/latest/assert.html
+        .. _advanced assertions: http://pytest.org/latest/assert.html
+        
+        
+        Use standalone "mock" package
+        -----------------------------
+        
+        *New in version 1.4.0.*
+        
+        Python 3 users might want to use a newest version of the ``mock`` package as published on PyPI
+        than the one that comes with the Python distribution.
+        
+        .. code-block:: ini
+        
+            [pytest]
+            mock_use_standalone_module = true
+        
+        This will force the plugin to import ``mock`` instead of the ``unittest.mock`` module bundled with
+        Python 3.3+. Note that this option is only used in Python 3+, as Python 2 users only have the option
+        to use the ``mock`` package from PyPI anyway.
         
         
         Requirements
@@ -240,9 +282,13 @@ Description: ===========
         - you can't easily undo the mocking during the test execution;
         
         
-        **Note**
+        **Note about usage as context manager**
         
-        Although mocker's API is intentionally the same as ``mock.patch``'s, its uses as context managers and function decorators are **not** supported. The purpose of this plugin is to make the use of context managers and function decorators for mocking unnecessary. Indeed, trying to use the functionality in ``mocker`` in this manner can lead to non-intuitive errors:
+        Although mocker's API is intentionally the same as ``mock.patch``'s, its use
+        as context manager and function decorator is **not** supported through the
+        fixture. The purpose of this plugin is to make the use of context managers and
+        function decorators for mocking unnecessary. Indeed, trying to use the
+        functionality in ``mocker`` in this manner can lead to non-intuitive errors:
         
         .. code-block:: python
         
@@ -259,6 +305,23 @@ Description: ===========
                 with mocker.patch.object(a, 'doIt', return_value=True, autospec=True):
             E   AttributeError: __exit__
         
+        You can however use ``mocker.mock_module`` to access the underlying ``mock``
+        module, e.g. to return a context manager in a fixture that mocks something
+        temporarily:
+        
+        .. code-block:: python
+        
+            @pytest.fixture
+            def fixture_cm(mocker):
+                @contextlib.contextmanager
+                def my_cm():
+                    def mocked():
+                        pass
+        
+                    with mocker.mock_module.patch.object(SomeClass, 'method', mocked):
+                        yield
+                return my_cm
+        
         
         License
         =======
diff --git a/README.rst b/README.rst
index bc87fa4..691c2ca 100644
--- a/README.rst
+++ b/README.rst
@@ -9,7 +9,14 @@ of a test:
 
 .. code-block:: python
 
-
+    import os
+    
+    class UnixFS:
+    
+        @staticmethod
+        def rm(filename):
+            os.remove(filename)
+    
     def test_unix_fs(mocker):
         mocker.patch('os.remove')
         UnixFS.rm('file')
@@ -18,21 +25,21 @@ of a test:
 
 .. Using PNG badges because PyPI doesn't support SVG
 
-|python| |version| |downloads| |ci| |appveyor| |coverage|
+|python| |version| |anaconda| |ci| |appveyor| |coverage|
 
-.. |version| image:: http://img.shields.io/pypi/v/pytest-mock.png
+.. |version| image:: http://img.shields.io/pypi/v/pytest-mock.svg
   :target: https://pypi.python.org/pypi/pytest-mock
 
-.. |downloads| image:: http://img.shields.io/pypi/dm/pytest-mock.png
-  :target: https://pypi.python.org/pypi/pytest-mock
+.. |anaconda| image:: https://anaconda.org/conda-forge/pytest-mock/badges/version.svg
+    :target: https://anaconda.org/conda-forge/pytest-mock
 
-.. |ci| image:: http://img.shields.io/travis/pytest-dev/pytest-mock.png
+.. |ci| image:: http://img.shields.io/travis/pytest-dev/pytest-mock.svg
   :target: https://travis-ci.org/pytest-dev/pytest-mock
 
 .. |appveyor| image:: https://ci.appveyor.com/api/projects/status/pid1t7iuwhkm9eh6/branch/master?svg=true
   :target: https://ci.appveyor.com/project/pytestbot/pytest-mock
 
-.. |coverage| image:: http://img.shields.io/coveralls/pytest-dev/pytest-mock.png
+.. |coverage| image:: http://img.shields.io/coveralls/pytest-dev/pytest-mock.svg
   :target: https://coveralls.io/r/pytest-dev/pytest-mock
 
 .. |python| image:: https://img.shields.io/pypi/pyversions/pytest-mock.svg
@@ -68,6 +75,7 @@ Some objects from the ``mock`` module are accessible directly from ``mocker`` fo
 * `MagicMock <https://docs.python.org/3/library/unittest.mock.html#unittest.mock.MagicMock>`_
 * `PropertyMock <https://docs.python.org/3/library/unittest.mock.html#unittest.mock.PropertyMock>`_
 * `ANY <https://docs.python.org/3/library/unittest.mock.html#any>`_
+* `DEFAULT <https://docs.python.org/3/library/unittest.mock.html#default>`_ *(Version 1.4)*
 * `call <https://docs.python.org/3/library/unittest.mock.html#call>`_ *(Version 1.1)*
 * `sentinel <https://docs.python.org/3/library/unittest.mock.html#sentinel>`_ *(Version 1.2)*
 * `mock_open <https://docs.python.org/3/library/unittest.mock.html#mock-open>`_
@@ -125,16 +133,32 @@ the method, and uses py.test's own `advanced assertions`_ to return a better
 diff::
 
 
-            m = mocker.patch.object(DS, 'create_char')
-            DS().create_char('Raistlin', class_='mag', gift=12)
-    >       m.assert_called_once_with('Raistlin', class_='mage', gift=12)
-    E       assert {'class_': 'mag', 'gift': 12} == {'class_': 'mage', 'gift': 12}
-    E         Omitting 1 identical items, use -v to show
-    E         Differing items:
-    E         {'class_': 'mag'} != {'class_': 'mage'}
+    mocker = <pytest_mock.MockFixture object at 0x0381E2D0>
+
+        def test(mocker):
+            m = mocker.Mock()
+            m('fo')
+    >       m.assert_called_once_with('', bar=4)
+    E       AssertionError: Expected call: mock('', bar=4)
+    E       Actual call: mock('fo')
+    E
+    E       pytest introspection follows:
+    E
+    E       Args:
+    E       assert ('fo',) == ('',)
+    E         At index 0 diff: 'fo' != ''
+    E         Use -v to get the full diff
+    E       Kwargs:
+    E       assert {} == {'bar': 4}
+    E         Right contains more items:
+    E         {'bar': 4}
     E         Use -v to get the full diff
 
 
+test_foo.py:6: AssertionError
+========================== 1 failed in 0.03 seconds ===========================
+
+
 This is useful when asserting mock calls with many/nested arguments and trying
 to quickly see the difference.
 
@@ -150,7 +174,25 @@ Note that this feature is automatically disabled with the ``--tb=native`` option
 mechanism used to suppress traceback entries from ``mock`` module does not work with that option
 anyway plus it generates confusing messages on Python 3.5 due to exception chaining
 
-.. _advanced assertions: https://pytest.org/latest/assert.html
+.. _advanced assertions: http://pytest.org/latest/assert.html
+
+
+Use standalone "mock" package
+-----------------------------
+
+*New in version 1.4.0.*
+
+Python 3 users might want to use a newest version of the ``mock`` package as published on PyPI
+than the one that comes with the Python distribution.
+
+.. code-block:: ini
+
+    [pytest]
+    mock_use_standalone_module = true
+
+This will force the plugin to import ``mock`` instead of the ``unittest.mock`` module bundled with
+Python 3.3+. Note that this option is only used in Python 3+, as Python 2 users only have the option
+to use the ``mock`` package from PyPI anyway.
 
 
 Requirements
@@ -232,9 +274,13 @@ But this poses a few disadvantages:
 - you can't easily undo the mocking during the test execution;
 
 
-**Note**
+**Note about usage as context manager**
 
-Although mocker's API is intentionally the same as ``mock.patch``'s, its uses as context managers and function decorators are **not** supported. The purpose of this plugin is to make the use of context managers and function decorators for mocking unnecessary. Indeed, trying to use the functionality in ``mocker`` in this manner can lead to non-intuitive errors:
+Although mocker's API is intentionally the same as ``mock.patch``'s, its use
+as context manager and function decorator is **not** supported through the
+fixture. The purpose of this plugin is to make the use of context managers and
+function decorators for mocking unnecessary. Indeed, trying to use the
+functionality in ``mocker`` in this manner can lead to non-intuitive errors:
 
 .. code-block:: python
 
@@ -251,6 +297,23 @@ Although mocker's API is intentionally the same as ``mock.patch``'s, its uses as
         with mocker.patch.object(a, 'doIt', return_value=True, autospec=True):
     E   AttributeError: __exit__
 
+You can however use ``mocker.mock_module`` to access the underlying ``mock``
+module, e.g. to return a context manager in a fixture that mocks something
+temporarily:
+
+.. code-block:: python
+
+    @pytest.fixture
+    def fixture_cm(mocker):
+        @contextlib.contextmanager
+        def my_cm():
+            def mocked():
+                pass
+
+            with mocker.mock_module.patch.object(SomeClass, 'method', mocked):
+                yield
+        return my_cm
+
 
 License
 =======
diff --git a/_pytest_mock_version.py b/_pytest_mock_version.py
index 021c6a0..33686e7 100644
--- a/_pytest_mock_version.py
+++ b/_pytest_mock_version.py
@@ -1,4 +1,4 @@
 # coding: utf-8
 # file generated by setuptools_scm
 # don't change, don't track in version control
-version = '1.3.0'
+version = '1.6.3'
diff --git a/appveyor.yml b/appveyor.yml
index 31aaa37..71b4015 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,7 +1,7 @@
 install:
-  - C:\Python35\python -m pip install tox
+  - C:\Python36\python -m pip install tox
 
 build: false  # Not a C# project
 
 test_script:
-  - C:\Python35\scripts\tox
+  - C:\Python36\scripts\tox
diff --git a/pytest_mock.egg-info/PKG-INFO b/pytest_mock.egg-info/PKG-INFO
index 653efb9..e4952bd 100644
--- a/pytest_mock.egg-info/PKG-INFO
+++ b/pytest_mock.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: pytest-mock
-Version: 1.3.0
+Version: 1.6.3
 Summary: Thin-wrapper around the mock package for easier use with py.test
 Home-page: https://github.com/pytest-dev/pytest-mock/
 Author: Bruno Oliveira
@@ -17,7 +17,14 @@ Description: ===========
         
         .. code-block:: python
         
-        
+            import os
+            
+            class UnixFS:
+            
+                @staticmethod
+                def rm(filename):
+                    os.remove(filename)
+            
             def test_unix_fs(mocker):
                 mocker.patch('os.remove')
                 UnixFS.rm('file')
@@ -26,21 +33,21 @@ Description: ===========
         
         .. Using PNG badges because PyPI doesn't support SVG
         
-        |python| |version| |downloads| |ci| |appveyor| |coverage|
+        |python| |version| |anaconda| |ci| |appveyor| |coverage|
         
-        .. |version| image:: http://img.shields.io/pypi/v/pytest-mock.png
+        .. |version| image:: http://img.shields.io/pypi/v/pytest-mock.svg
           :target: https://pypi.python.org/pypi/pytest-mock
         
-        .. |downloads| image:: http://img.shields.io/pypi/dm/pytest-mock.png
-          :target: https://pypi.python.org/pypi/pytest-mock
+        .. |anaconda| image:: https://anaconda.org/conda-forge/pytest-mock/badges/version.svg
+            :target: https://anaconda.org/conda-forge/pytest-mock
         
-        .. |ci| image:: http://img.shields.io/travis/pytest-dev/pytest-mock.png
+        .. |ci| image:: http://img.shields.io/travis/pytest-dev/pytest-mock.svg
           :target: https://travis-ci.org/pytest-dev/pytest-mock
         
         .. |appveyor| image:: https://ci.appveyor.com/api/projects/status/pid1t7iuwhkm9eh6/branch/master?svg=true
           :target: https://ci.appveyor.com/project/pytestbot/pytest-mock
         
-        .. |coverage| image:: http://img.shields.io/coveralls/pytest-dev/pytest-mock.png
+        .. |coverage| image:: http://img.shields.io/coveralls/pytest-dev/pytest-mock.svg
           :target: https://coveralls.io/r/pytest-dev/pytest-mock
         
         .. |python| image:: https://img.shields.io/pypi/pyversions/pytest-mock.svg
@@ -76,6 +83,7 @@ Description: ===========
         * `MagicMock <https://docs.python.org/3/library/unittest.mock.html#unittest.mock.MagicMock>`_
         * `PropertyMock <https://docs.python.org/3/library/unittest.mock.html#unittest.mock.PropertyMock>`_
         * `ANY <https://docs.python.org/3/library/unittest.mock.html#any>`_
+        * `DEFAULT <https://docs.python.org/3/library/unittest.mock.html#default>`_ *(Version 1.4)*
         * `call <https://docs.python.org/3/library/unittest.mock.html#call>`_ *(Version 1.1)*
         * `sentinel <https://docs.python.org/3/library/unittest.mock.html#sentinel>`_ *(Version 1.2)*
         * `mock_open <https://docs.python.org/3/library/unittest.mock.html#mock-open>`_
@@ -133,16 +141,32 @@ Description: ===========
         diff::
         
         
-                    m = mocker.patch.object(DS, 'create_char')
-                    DS().create_char('Raistlin', class_='mag', gift=12)
-            >       m.assert_called_once_with('Raistlin', class_='mage', gift=12)
-            E       assert {'class_': 'mag', 'gift': 12} == {'class_': 'mage', 'gift': 12}
-            E         Omitting 1 identical items, use -v to show
-            E         Differing items:
-            E         {'class_': 'mag'} != {'class_': 'mage'}
+            mocker = <pytest_mock.MockFixture object at 0x0381E2D0>
+        
+                def test(mocker):
+                    m = mocker.Mock()
+                    m('fo')
+            >       m.assert_called_once_with('', bar=4)
+            E       AssertionError: Expected call: mock('', bar=4)
+            E       Actual call: mock('fo')
+            E
+            E       pytest introspection follows:
+            E
+            E       Args:
+            E       assert ('fo',) == ('',)
+            E         At index 0 diff: 'fo' != ''
+            E         Use -v to get the full diff
+            E       Kwargs:
+            E       assert {} == {'bar': 4}
+            E         Right contains more items:
+            E         {'bar': 4}
             E         Use -v to get the full diff
         
         
+        test_foo.py:6: AssertionError
+        ========================== 1 failed in 0.03 seconds ===========================
+        
+        
         This is useful when asserting mock calls with many/nested arguments and trying
         to quickly see the difference.
         
@@ -158,7 +182,25 @@ Description: ===========
         mechanism used to suppress traceback entries from ``mock`` module does not work with that option
         anyway plus it generates confusing messages on Python 3.5 due to exception chaining
         
-        .. _advanced assertions: https://pytest.org/latest/assert.html
+        .. _advanced assertions: http://pytest.org/latest/assert.html
+        
+        
+        Use standalone "mock" package
+        -----------------------------
+        
+        *New in version 1.4.0.*
+        
+        Python 3 users might want to use a newest version of the ``mock`` package as published on PyPI
+        than the one that comes with the Python distribution.
+        
+        .. code-block:: ini
+        
+            [pytest]
+            mock_use_standalone_module = true
+        
+        This will force the plugin to import ``mock`` instead of the ``unittest.mock`` module bundled with
+        Python 3.3+. Note that this option is only used in Python 3+, as Python 2 users only have the option
+        to use the ``mock`` package from PyPI anyway.
         
         
         Requirements
@@ -240,9 +282,13 @@ Description: ===========
         - you can't easily undo the mocking during the test execution;
         
         
-        **Note**
+        **Note about usage as context manager**
         
-        Although mocker's API is intentionally the same as ``mock.patch``'s, its uses as context managers and function decorators are **not** supported. The purpose of this plugin is to make the use of context managers and function decorators for mocking unnecessary. Indeed, trying to use the functionality in ``mocker`` in this manner can lead to non-intuitive errors:
+        Although mocker's API is intentionally the same as ``mock.patch``'s, its use
+        as context manager and function decorator is **not** supported through the
+        fixture. The purpose of this plugin is to make the use of context managers and
+        function decorators for mocking unnecessary. Indeed, trying to use the
+        functionality in ``mocker`` in this manner can lead to non-intuitive errors:
         
         .. code-block:: python
         
@@ -259,6 +305,23 @@ Description: ===========
                 with mocker.patch.object(a, 'doIt', return_value=True, autospec=True):
             E   AttributeError: __exit__
         
+        You can however use ``mocker.mock_module`` to access the underlying ``mock``
+        module, e.g. to return a context manager in a fixture that mocks something
+        temporarily:
+        
+        .. code-block:: python
+        
+            @pytest.fixture
+            def fixture_cm(mocker):
+                @contextlib.contextmanager
+                def my_cm():
+                    def mocked():
+                        pass
+        
+                    with mocker.mock_module.patch.object(SomeClass, 'method', mocked):
+                        yield
+                return my_cm
+        
         
         License
         =======
diff --git a/pytest_mock.egg-info/SOURCES.txt b/pytest_mock.egg-info/SOURCES.txt
index 60fecfe..77fbde7 100644
--- a/pytest_mock.egg-info/SOURCES.txt
+++ b/pytest_mock.egg-info/SOURCES.txt
@@ -2,7 +2,6 @@
 .travis.yml
 CHANGELOG.rst
 LICENSE
-MANIFEST.in
 README.rst
 _pytest_mock_version.py
 appveyor.yml
diff --git a/pytest_mock.py b/pytest_mock.py
index 7fc3afe..190d3ca 100644
--- a/pytest_mock.py
+++ b/pytest_mock.py
@@ -1,15 +1,38 @@
+from __future__ import unicode_literals
+
 import inspect
+import sys
 
 import pytest
 
-try:
-    import mock as mock_module
-except ImportError:
-    import unittest.mock as mock_module
-
 from _pytest_mock_version import version
+
 __version__ = version
 
+# pseudo-six; if this starts to require more than this, depend on six already
+if sys.version_info[0] == 2:  # pragma: no cover
+    text_type = unicode  # noqa
+else:
+    text_type = str
+
+
+def _get_mock_module(config):
+    """
+    Import and return the actual "mock" module. By default this is "mock" for Python 2 and
+    "unittest.mock" for Python 3, but the user can force to always use "mock" on Python 3 using
+    the mock_use_standalone_module ini option.
+    """
+    if not hasattr(_get_mock_module, '_module'):
+        use_standalone_module = parse_ini_boolean(config.getini('mock_use_standalone_module'))
+        if sys.version_info[0] == 2 or use_standalone_module:
+            import mock
+            _get_mock_module._module = mock
+        else:
+            import unittest.mock
+            _get_mock_module._module = unittest.mock
+
+    return _get_mock_module._module
+
 
 class MockFixture(object):
     """
@@ -17,20 +40,18 @@ class MockFixture(object):
     ensuring that they are uninstalled at the end of each test.
     """
 
-    Mock = mock_module.Mock
-    MagicMock = mock_module.MagicMock
-    PropertyMock = mock_module.PropertyMock
-    call = mock_module.call
-    ANY = mock_module.ANY
-    sentinel = mock_module.sentinel
-    mock_open = mock_module.mock_open
-
-    def __init__(self):
+    def __init__(self, config):
         self._patches = []  # list of mock._patch objects
         self._mocks = []  # list of MagicMock objects
-        self.patch = self._Patcher(self._patches, self._mocks)
-        # temporary fix: this should be at class level, but is blowing
-        # up in Python 3.6
+        self.mock_module = mock_module = _get_mock_module(config)
+        self.patch = self._Patcher(self._patches, self._mocks, mock_module)
+        # aliases for convenience
+        self.Mock = mock_module.Mock
+        self.MagicMock = mock_module.MagicMock
+        self.PropertyMock = mock_module.PropertyMock
+        self.call = mock_module.call
+        self.ANY = mock_module.ANY
+        self.DEFAULT = mock_module.DEFAULT
         self.sentinel = mock_module.sentinel
         self.mock_open = mock_module.mock_open
 
@@ -90,7 +111,7 @@ class MockFixture(object):
         :rtype: mock.MagicMock
         :return: Stub object.
         """
-        return mock_module.MagicMock(spec=lambda *args, **kwargs: None, name=name)
+        return self.mock_module.MagicMock(spec=lambda *args, **kwargs: None, name=name)
 
     class _Patcher(object):
         """
@@ -98,9 +119,10 @@ class MockFixture(object):
         etc. We need this indirection to keep the same API of the mock package.
         """
 
-        def __init__(self, patches, mocks):
+        def __init__(self, patches, mocks, mock_module):
             self._patches = patches
             self._mocks = mocks
+            self.mock_module = mock_module
 
         def _start_patch(self, mock_func, *args, **kwargs):
             """Patches something by calling the given function from the mock
@@ -110,34 +132,35 @@ class MockFixture(object):
             p = mock_func(*args, **kwargs)
             mocked = p.start()
             self._patches.append(p)
-            self._mocks.append(mocked)
+            if hasattr(mocked, 'reset_mock'):
+                self._mocks.append(mocked)
             return mocked
 
         def object(self, *args, **kwargs):
             """API to mock.patch.object"""
-            return self._start_patch(mock_module.patch.object, *args, **kwargs)
+            return self._start_patch(self.mock_module.patch.object, *args, **kwargs)
 
         def multiple(self, *args, **kwargs):
             """API to mock.patch.multiple"""
-            return self._start_patch(mock_module.patch.multiple, *args,
+            return self._start_patch(self.mock_module.patch.multiple, *args,
                                      **kwargs)
 
         def dict(self, *args, **kwargs):
             """API to mock.patch.dict"""
-            return self._start_patch(mock_module.patch.dict, *args, **kwargs)
+            return self._start_patch(self.mock_module.patch.dict, *args, **kwargs)
 
         def __call__(self, *args, **kwargs):
             """API to mock.patch"""
-            return self._start_patch(mock_module.patch, *args, **kwargs)
+            return self._start_patch(self.mock_module.patch, *args, **kwargs)
 
 
 @pytest.yield_fixture
-def mocker():
+def mocker(pytestconfig):
     """
     return an object that has the same interface to the `mock` module, but
     takes care of automatically undoing all patches after each test method.
     """
-    result = MockFixture()
+    result = MockFixture(pytestconfig)
     yield result
     result.stopall()
 
@@ -161,13 +184,27 @@ def assert_wrapper(__wrapped_mock_method__, *args, **kwargs):
     __tracebackhide__ = True
     try:
         __wrapped_mock_method__(*args, **kwargs)
+        return
     except AssertionError as e:
-        __mock_self = args[0]
-        if __mock_self.call_args is not None:
-            actual_args, actual_kwargs = __mock_self.call_args
-            assert actual_args == args[1:]
-            assert actual_kwargs == kwargs
-        raise AssertionError(*e.args)
+        if getattr(e, '_mock_introspection_applied', 0):
+            msg = text_type(e)
+        else:
+            __mock_self = args[0]
+            msg = text_type(e)
+            if __mock_self.call_args is not None:
+                actual_args, actual_kwargs = __mock_self.call_args
+                msg += '\n\npytest introspection follows:\n'
+                try:
+                    assert actual_args == args[1:]
+                except AssertionError as e:
+                    msg += '\nArgs:\n' + text_type(e)
+                try:
+                    assert actual_kwargs == kwargs
+                except AssertionError as e:
+                    msg += '\nKwargs:\n' + text_type(e)
+    e = AssertionError(msg)
+    e._mock_introspection_applied = True
+    raise e
 
 
 def wrap_assert_not_called(*args, **kwargs):
@@ -209,6 +246,8 @@ def wrap_assert_methods(config):
     if _mock_module_originals:
         return
 
+    mock_module = _get_mock_module(config)
+
     wrappers = {
         'assert_not_called': wrap_assert_not_called,
         'assert_called_with': wrap_assert_called_with,
@@ -247,6 +286,10 @@ def pytest_addoption(parser):
                   'Monkeypatch the mock library to improve reporting of the '
                   'assert_called_... methods',
                   default=True)
+    parser.addini('mock_use_standalone_module',
+                  'Use standalone "mock" (from PyPI) instead of builtin "unittest.mock" '
+                  'on Python 3',
+                  default=False)
 
 
 def parse_ini_boolean(value):
diff --git a/setup.cfg b/setup.cfg
index 6f08d0e..adf5ed7 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -4,5 +4,4 @@ universal = 1
 [egg_info]
 tag_build = 
 tag_date = 0
-tag_svn_revision = 0
 
diff --git a/setup.py b/setup.py
index 16c8319..15a347e 100644
--- a/setup.py
+++ b/setup.py
@@ -1,5 +1,3 @@
-import re
-
 from setuptools import setup
 
 
diff --git a/test_pytest_mock.py b/test_pytest_mock.py
index ad439d6..ec2cf73 100644
--- a/test_pytest_mock.py
+++ b/test_pytest_mock.py
@@ -4,7 +4,6 @@ import sys
 from contextlib import contextmanager
 
 import py.code
-
 import pytest
 
 pytest_plugins = 'pytester'
@@ -69,10 +68,8 @@ def mock_using_patch(mocker):
 
 
 def mock_using_patch_multiple(mocker):
-    from pytest_mock import mock_module
-
-    r = mocker.patch.multiple('os', remove=mock_module.DEFAULT,
-                              listdir=mock_module.DEFAULT)
+    r = mocker.patch.multiple('os', remove=mocker.DEFAULT,
+                              listdir=mocker.DEFAULT)
     return r['remove'], r['listdir']
 
 
@@ -89,6 +86,8 @@ def test_mock_patches(mock_fs, mocker, check_unix_fs_mocked):
     mock_fs(mocker)
     mocked_rm, mocked_ls = mock_fs(mocker)
     check_unix_fs_mocked(mocked_rm, mocked_ls)
+    mocker.resetall()
+    mocker.stopall()
 
 
 def test_mock_patch_dict(mocker):
@@ -103,23 +102,16 @@ def test_mock_patch_dict(mocker):
     assert x == {'original': 1}
 
 
-def test_mock_fixture_is_deprecated(testdir):
+def test_mock_patch_dict_resetall(mocker):
     """
-    Test that a warning emitted when using deprecated "mock" fixture.
+    We can call resetall after patching a dict.
+    :param mock:
     """
-    testdir.makepyfile('''
-        import warnings
-        import os
-        warnings.simplefilter('always')
-
-        def test_foo(mock, tmpdir):
-            mock.patch('os.listdir', return_value=['mocked'])
-            assert os.listdir(str(tmpdir)) == ['mocked']
-            mock.stopall()
-            assert os.listdir(str(tmpdir)) == []
-    ''')
-    result = testdir.runpytest('-s')
-    result.stderr.fnmatch_lines(['*"mock" fixture has been deprecated*'])
+    x = {'original': 1}
+    mocker.patch.dict(x, values=[('new', 10)], clear=True)
+    assert x == {'new': 10}
+    mocker.resetall()
+    assert x == {'new': 10}
 
 
 def test_deprecated_mock(mock, tmpdir):
@@ -133,10 +125,12 @@ def test_deprecated_mock(mock, tmpdir):
 
 
 @pytest.mark.parametrize('name', ['MagicMock', 'PropertyMock', 'Mock', 'call', 'ANY', 'sentinel', 'mock_open'])
-def test_mocker_aliases(name):
-    from pytest_mock import mock_module, MockFixture
+def test_mocker_aliases(name, pytestconfig):
+    from pytest_mock import _get_mock_module, MockFixture
 
-    mocker = MockFixture()
+    mock_module = _get_mock_module(pytestconfig)
+
+    mocker = MockFixture(pytestconfig)
     assert getattr(mocker, name) is getattr(mock_module, name)
 
 
@@ -203,8 +197,6 @@ def test_instance_method_spy(mocker):
 
... 158 lines suppressed ...

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/pytest-mock.git



More information about the Python-modules-commits mailing list