Skip to content

Commit 2abec3b

Browse files
authored
Drop support for EOL Python 2.7 and 3.4 (#176)
Drop support for EOL Python 2.7 and 3.4
2 parents 67357f1 + d675b65 commit 2abec3b

File tree

7 files changed

+40
-68
lines changed

7 files changed

+40
-68
lines changed

.github/workflows/main.yml

+1-3
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,9 @@ jobs:
1010
strategy:
1111
fail-fast: false
1212
matrix:
13-
python: ["2.7", "3.5", "3.6", "3.7", "3.8"]
13+
python: ["3.5", "3.6", "3.7", "3.8"]
1414
os: [ubuntu-latest, windows-latest]
1515
include:
16-
- python: "2.7"
17-
tox_env: "py27"
1816
- python: "3.5"
1917
tox_env: "py35"
2018
- python: "3.6"

.pre-commit-config.yaml

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
exclude: '^($|.*\.bin)'
22
repos:
33
- repo: https://github.com/ambv/black
4-
rev: 18.6b4
4+
rev: 19.10b0
55
hooks:
66
- id: black
77
args: [--safe, --quiet]
8-
language_version: python3.6
98
- repo: https://github.com/pre-commit/pre-commit-hooks
10-
rev: v1.3.0
9+
rev: v2.4.0
1110
hooks:
1211
- id: trailing-whitespace
1312
- id: end-of-file-fixer

README.rst

+3-4
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ entries from the ``mock`` module.
149149

150150
It also adds introspection information on differing call arguments when
151151
calling the helper methods. This features catches `AssertionError` raised in
152-
the method, and uses py.test's own `advanced assertions`_ to return a better
152+
the method, and uses pytest's own `advanced assertions`_ to return a better
153153
diff::
154154

155155

@@ -235,9 +235,8 @@ function decorators for mocking unnecessary.
235235
Requirements
236236
============
237237

238-
* Python 2.7, Python 3.4+
238+
* Python Python 3.5+
239239
* pytest
240-
* mock (for Python 2)
241240

242241

243242
Install
@@ -349,7 +348,7 @@ Tests are run with ``tox``, you can run the baseline environments before submitt
349348

350349
.. code-block:: console
351350
352-
$ tox -e py27,py36,linting
351+
$ tox -e py38,linting
353352
354353
Style checks and formatting are done automatically during commit courtesy of
355354
`pre-commit <https://pre-commit.com>`_.

setup.py

+4-6
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@
88
packages=find_packages(where="src"),
99
package_dir={"": "src"},
1010
platforms="any",
11-
python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*",
12-
install_requires=["pytest>=2.7", 'mock;python_version<"3.0"'],
11+
python_requires=">=3.5",
12+
install_requires=["pytest>=2.7"],
1313
use_scm_version={"write_to": "src/pytest_mock/_version.py"},
1414
setup_requires=["setuptools_scm"],
1515
url="https://github.com/pytest-dev/pytest-mock/",
1616
license="MIT",
1717
author="Bruno Oliveira",
1818
author_email="[email protected]",
19-
description="Thin-wrapper around the mock package for easier use with py.test",
19+
description="Thin-wrapper around the mock package for easier use with pytest",
2020
long_description=open("README.rst", encoding="utf-8").read(),
2121
keywords="pytest mock",
2222
extras_require={"dev": ["pre-commit", "tox"]},
@@ -26,14 +26,12 @@
2626
"Intended Audience :: Developers",
2727
"License :: OSI Approved :: MIT License",
2828
"Operating System :: OS Independent",
29-
"Programming Language :: Python :: 2",
30-
"Programming Language :: Python :: 2.7",
3129
"Programming Language :: Python :: 3",
32-
"Programming Language :: Python :: 3.4",
3330
"Programming Language :: Python :: 3.5",
3431
"Programming Language :: Python :: 3.6",
3532
"Programming Language :: Python :: 3.7",
3633
"Programming Language :: Python :: 3.8",
34+
"Programming Language :: Python :: 3 :: Only",
3735
"Topic :: Software Development :: Testing",
3836
],
3937
)

src/pytest_mock/plugin.py

+11-26
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,24 @@
1-
from __future__ import unicode_literals
2-
31
import functools
42
import inspect
5-
import sys
63

74
import pytest
85

96
from ._version import version
107

118
__version__ = version
129

13-
# pseudo-six; if this starts to require more than this, depend on six already
14-
if sys.version_info[0] == 2: # pragma: no cover
15-
text_type = unicode # noqa
16-
else:
17-
text_type = str
18-
1910

2011
def _get_mock_module(config):
2112
"""
22-
Import and return the actual "mock" module. By default this is "mock" for Python 2 and
23-
"unittest.mock" for Python 3, but the user can force to always use "mock" on Python 3 using
13+
Import and return the actual "mock" module. By default this is
14+
"unittest.mock", but the user can force to always use "mock" using
2415
the mock_use_standalone_module ini option.
2516
"""
2617
if not hasattr(_get_mock_module, "_module"):
2718
use_standalone_module = parse_ini_boolean(
2819
config.getini("mock_use_standalone_module")
2920
)
30-
if sys.version_info[0] == 2 or use_standalone_module:
21+
if use_standalone_module:
3122
import mock
3223

3324
_get_mock_module._module = mock
@@ -39,7 +30,7 @@ def _get_mock_module(config):
3930
return _get_mock_module._module
4031

4132

42-
class MockFixture(object):
33+
class MockFixture:
4334
"""
4435
Fixture that provides the same interface to functions in the mock module,
4536
ensuring that they are uninstalled at the end of each test.
@@ -105,13 +96,7 @@ def spy(self, obj, name):
10596
if isinstance(value, (classmethod, staticmethod)):
10697
autospec = False
10798

108-
if sys.version_info[0] == 2:
109-
assigned = [x for x in functools.WRAPPER_ASSIGNMENTS if hasattr(method, x)]
110-
w = functools.wraps(method, assigned=assigned)
111-
else:
112-
w = functools.wraps(method)
113-
114-
@w
99+
@functools.wraps(method)
115100
def wrapper(*args, **kwargs):
116101
spy_obj.spy_return = None
117102
spy_obj.spy_exception = None
@@ -140,7 +125,7 @@ def stub(self, name=None):
140125
"""
141126
return self.mock_module.MagicMock(spec=lambda *args, **kwargs: None, name=name)
142127

143-
class _Patcher(object):
128+
class _Patcher:
144129
"""
145130
Object to provide the same interface as mock.patch, mock.patch.object,
146131
etc. We need this indirection to keep the same API of the mock package.
@@ -219,21 +204,21 @@ def assert_wrapper(__wrapped_mock_method__, *args, **kwargs):
219204
return
220205
except AssertionError as e:
221206
if getattr(e, "_mock_introspection_applied", 0):
222-
msg = text_type(e)
207+
msg = str(e)
223208
else:
224209
__mock_self = args[0]
225-
msg = text_type(e)
210+
msg = str(e)
226211
if __mock_self.call_args is not None:
227212
actual_args, actual_kwargs = __mock_self.call_args
228213
introspection = ""
229214
try:
230215
assert actual_args == args[1:]
231216
except AssertionError as e:
232-
introspection += "\nArgs:\n" + text_type(e)
217+
introspection += "\nArgs:\n" + str(e)
233218
try:
234219
assert actual_kwargs == kwargs
235220
except AssertionError as e:
236-
introspection += "\nKwargs:\n" + text_type(e)
221+
introspection += "\nKwargs:\n" + str(e)
237222

238223
if introspection:
239224
msg += "\n\npytest introspection follows:\n" + introspection
@@ -324,7 +309,7 @@ def unwrap_assert_methods():
324309
# so we need to catch this error here and ignore it;
325310
# unfortunately there's no public API to check if a patch
326311
# has been started, so catching the error it is
327-
if text_type(e) == "stop called on unstarted patcher":
312+
if str(e) == "stop called on unstarted patcher":
328313
pass
329314
else:
330315
raise

tests/test_pytest_mock.py

+18-25
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
)
1515

1616
# Python 3.8 changed the output formatting (bpo-35500), which has been ported to mock 3.0
17-
NEW_FORMATTING = sys.version_info >= (3, 8) or sys.version_info[0] == 2
17+
NEW_FORMATTING = sys.version_info >= (3, 8)
1818

1919

2020
@pytest.fixture
@@ -32,7 +32,7 @@ def needs_assert_rewrite(pytestconfig):
3232
)
3333

3434

35-
class UnixFS(object):
35+
class UnixFS:
3636
"""
3737
Wrapper to os functions to simulate a Unix file system, used for testing
3838
the mock fixture.
@@ -183,7 +183,7 @@ def test_repr_with_no_name(self, mocker):
183183
def test_repr_with_name(self, mocker):
184184
test_name = "funny walk"
185185
stub = mocker.stub(name=test_name)
186-
assert "name={0!r}".format(test_name) in repr(stub)
186+
assert "name={!r}".format(test_name) in repr(stub)
187187

188188
def __test_failure_message(self, mocker, **kwargs):
189189
expected_name = kwargs.get("name") or "mock"
@@ -206,7 +206,7 @@ def test_failure_message_with_name(self, mocker, name):
206206

207207

208208
def test_instance_method_spy(mocker):
209-
class Foo(object):
209+
class Foo:
210210
def bar(self, arg):
211211
return arg * 2
212212

@@ -222,7 +222,7 @@ def bar(self, arg):
222222

223223

224224
def test_instance_method_spy_exception(mocker):
225-
class Foo(object):
225+
class Foo:
226226
def bar(self, arg):
227227
raise Exception("Error with {}".format(arg))
228228

@@ -266,7 +266,7 @@ def bar(self, x):
266266

267267
@skip_pypy
268268
def test_instance_method_by_class_spy(mocker):
269-
class Foo(object):
269+
class Foo:
270270
def bar(self, arg):
271271
return arg * 2
272272

@@ -281,7 +281,7 @@ def bar(self, arg):
281281

282282
@skip_pypy
283283
def test_instance_method_by_subclass_spy(mocker):
284-
class Base(object):
284+
class Base:
285285
def bar(self, arg):
286286
return arg * 2
287287

@@ -300,7 +300,7 @@ class Foo(Base):
300300

301301
@skip_pypy
302302
def test_class_method_spy(mocker):
303-
class Foo(object):
303+
class Foo:
304304
@classmethod
305305
def bar(cls, arg):
306306
return arg * 2
@@ -314,9 +314,8 @@ def bar(cls, arg):
314314

315315

316316
@skip_pypy
317-
@pytest.mark.xfail(sys.version_info[0] == 2, reason="does not work on Python 2")
318317
def test_class_method_subclass_spy(mocker):
319-
class Base(object):
318+
class Base:
320319
@classmethod
321320
def bar(self, arg):
322321
return arg * 2
@@ -337,7 +336,7 @@ def test_class_method_with_metaclass_spy(mocker):
337336
class MetaFoo(type):
338337
pass
339338

340-
class Foo(object):
339+
class Foo:
341340

342341
__metaclass__ = MetaFoo
343342

@@ -355,7 +354,7 @@ def bar(cls, arg):
355354

356355
@skip_pypy
357356
def test_static_method_spy(mocker):
358-
class Foo(object):
357+
class Foo:
359358
@staticmethod
360359
def bar(arg):
361360
return arg * 2
@@ -369,9 +368,8 @@ def bar(arg):
369368

370369

371370
@skip_pypy
372-
@pytest.mark.xfail(sys.version_info[0] == 2, reason="does not work on Python 2")
373371
def test_static_method_subclass_spy(mocker):
374-
class Base(object):
372+
class Base:
375373
@staticmethod
376374
def bar(arg):
377375
return arg * 2
@@ -442,10 +440,6 @@ def assert_argument_introspection(left, right):
442440
raise AssertionError("DID NOT RAISE")
443441

444442

445-
@pytest.mark.skipif(
446-
sys.version_info[:2] == (3, 4),
447-
reason="assert_not_called not available in Python 3.4",
448-
)
449443
def test_assert_not_called_wrapper(mocker):
450444
stub = mocker.stub()
451445
stub.assert_not_called()
@@ -498,8 +492,8 @@ def test_assert_called_wrapper(mocker):
498492
def test_assert_called_args_with_introspection(mocker):
499493
stub = mocker.stub()
500494

501-
complex_args = ("a", 1, set(["test"]))
502-
wrong_args = ("b", 2, set(["jest"]))
495+
complex_args = ("a", 1, {"test"})
496+
wrong_args = ("b", 2, {"jest"})
503497

504498
stub(*complex_args)
505499
stub.assert_called_with(*complex_args)
@@ -631,7 +625,6 @@ def test_foo(mocker):
631625
assert result.stdout.lines == []
632626

633627

634-
@pytest.mark.skipif(sys.version_info[0] < 3, reason="Py3 only")
635628
def test_standalone_mock(testdir):
636629
"""Check that the "mock_use_standalone" is being used.
637630
"""
@@ -720,7 +713,7 @@ def test_assert_called_with_unicode_arguments(mocker):
720713
stub(b"l\xc3\xb6k".decode("UTF-8"))
721714

722715
with pytest.raises(AssertionError):
723-
stub.assert_called_with(u"lak")
716+
stub.assert_called_with("lak")
724717

725718

726719
def test_plain_stopall(testdir):
@@ -745,15 +738,15 @@ def test_get_random_number(mocker):
745738

746739

747740
def test_abort_patch_object_context_manager(mocker):
748-
class A(object):
741+
class A:
749742
def doIt(self):
750743
return False
751744

752745
a = A()
753746

754747
with pytest.raises(ValueError) as excinfo:
755748
with mocker.patch.object(a, "doIt", return_value=True):
756-
assert a.doIt() == True
749+
assert a.doIt() is True
757750

758751
expected_error_msg = (
759752
"Using mocker in a with context is not supported. "
@@ -803,7 +796,7 @@ def test_foo(mocker):
803796
result = testdir.runpytest()
804797
result.stdout.fnmatch_lines("* 1 passed *")
805798

806-
kwargs = {"legacy": True} if sys.version_info[0] >= 3 else {}
799+
kwargs = {"legacy": True}
807800
assert compileall.compile_file(str(py_fn), **kwargs)
808801

809802
pyc_fn = str(py_fn) + "c"

tox.ini

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[tox]
2-
envlist = py{27,34,35,36,37,38}, linting, norewrite
2+
envlist = py{35,36,37,38}, linting, norewrite
33

44
[testenv]
55
passenv = USER USERNAME

0 commit comments

Comments
 (0)