[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