From e7cd00ac920f3db2855becd75193d2241b84e56d Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Fri, 31 May 2019 09:01:05 -0700 Subject: [PATCH 01/23] Preparing release version 4.6.0 --- CHANGELOG.rst | 78 ++++++++++++++++++++++++ changelog/2064.bugfix.rst | 1 - changelog/4559.feature.rst | 1 - changelog/4908.bugfix.rst | 1 - changelog/4956.feature.rst | 1 - changelog/5036.bugfix.rst | 1 - changelog/5062.feature.rst | 1 - changelog/5063.feature.rst | 1 - changelog/5091.feature.rst | 1 - changelog/5250.doc.rst | 1 - changelog/5256.bugfix.rst | 1 - changelog/5257.bugfix.rst | 1 - changelog/5269.feature.rst | 1 - changelog/5278.bugfix.rst | 1 - changelog/5286.bugfix.rst | 1 - changelog/5311.feature.rst | 2 - changelog/5312.feature.rst | 1 - changelog/5330.bugfix.rst | 2 - changelog/5333.bugfix.rst | 1 - doc/en/announce/index.rst | 1 + doc/en/announce/release-4.6.0.rst | 43 ++++++++++++++ doc/en/example/parametrize.rst | 4 +- doc/en/example/reportingdemo.rst | 98 +++++++++++++++---------------- doc/en/warnings.rst | 2 +- 24 files changed, 174 insertions(+), 72 deletions(-) delete mode 100644 changelog/2064.bugfix.rst delete mode 100644 changelog/4559.feature.rst delete mode 100644 changelog/4908.bugfix.rst delete mode 100644 changelog/4956.feature.rst delete mode 100644 changelog/5036.bugfix.rst delete mode 100644 changelog/5062.feature.rst delete mode 100644 changelog/5063.feature.rst delete mode 100644 changelog/5091.feature.rst delete mode 100644 changelog/5250.doc.rst delete mode 100644 changelog/5256.bugfix.rst delete mode 100644 changelog/5257.bugfix.rst delete mode 100644 changelog/5269.feature.rst delete mode 100644 changelog/5278.bugfix.rst delete mode 100644 changelog/5286.bugfix.rst delete mode 100644 changelog/5311.feature.rst delete mode 100644 changelog/5312.feature.rst delete mode 100644 changelog/5330.bugfix.rst delete mode 100644 changelog/5333.bugfix.rst create mode 100644 doc/en/announce/release-4.6.0.rst diff --git a/CHANGELOG.rst b/CHANGELOG.rst index a1bcd19178e..32267f4dd42 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -18,6 +18,84 @@ with advance notice in the **Deprecations** section of releases. .. towncrier release notes start +pytest 4.6.0 (2019-05-31) +========================= + +Important +--------- + +The ``4.6.X`` series will be the last series to support **Python 2 and Python 3.4**. + +For more details, see our `Python 2.7 and 3.4 support plan `__. + + +Features +-------- + +- `#4559 `_: Added the ``junit_log_passing_tests`` ini value which can be used to enable or disable logging of passing test output in the Junit XML file. + + +- `#4956 `_: pytester's ``testdir.spawn`` uses ``tmpdir`` as HOME/USERPROFILE directory. + + +- `#5062 `_: Unroll calls to ``all`` to full for-loops with assertion rewriting for better failure messages, especially when using Generator Expressions. + + +- `#5063 `_: Switch from ``pkg_resources`` to ``importlib-metadata`` for entrypoint detection for improved performance and import time. + + +- `#5091 `_: The output for ini options in ``--help`` has been improved. + + +- `#5269 `_: ``pytest.importorskip`` includes the ``ImportError`` now in the default ``reason``. + + +- `#5311 `_: Captured logs that are output for each failing test are formatted using the + ColoredLevelFormatter. + + +- `#5312 `_: Improved formatting of multiline log messages in Python 3. + + + +Bug Fixes +--------- + +- `#2064 `_: The debugging plugin imports the wrapped ``Pdb`` class (``--pdbcls``) on-demand now. + + +- `#4908 `_: The ``pytest_enter_pdb`` hook gets called with post-mortem (``--pdb``). + + +- `#5036 `_: Fix issue where fixtures dependent on other parametrized fixtures would be erroneously parametrized. + + +- `#5256 `_: Handle internal error due to a lone surrogate unicode character not being representable in Jython. + + +- `#5257 `_: Ensure that ``sys.stdout.mode`` does not include ``'b'`` as it is a text stream. + + +- `#5278 `_: Pytest's internal python plugin can be disabled using ``-p no:python`` again. + + +- `#5286 `_: Fix issue with ``disable_test_id_escaping_and_forfeit_all_rights_to_community_support`` option not working when using a list of test IDs in parametrized tests. + + +- `#5330 `_: Show the test module being collected when emitting ``PytestCollectionWarning`` messages for + test classes with ``__init__`` and ``__new__`` methods to make it easier to pin down the problem. + + +- `#5333 `_: Fix regression in 4.5.0 with ``--lf`` not re-running all tests with known failures from non-selected tests. + + + +Improved Documentation +---------------------- + +- `#5250 `_: Expand docs on use of ``setenv`` and ``delenv`` with ``monkeypatch``. + + pytest 4.5.0 (2019-05-11) ========================= diff --git a/changelog/2064.bugfix.rst b/changelog/2064.bugfix.rst deleted file mode 100644 index eba593fc568..00000000000 --- a/changelog/2064.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -The debugging plugin imports the wrapped ``Pdb`` class (``--pdbcls``) on-demand now. diff --git a/changelog/4559.feature.rst b/changelog/4559.feature.rst deleted file mode 100644 index ff076aff573..00000000000 --- a/changelog/4559.feature.rst +++ /dev/null @@ -1 +0,0 @@ -Added the ``junit_log_passing_tests`` ini value which can be used to enable and disable logging passing test output in the Junit XML file. diff --git a/changelog/4908.bugfix.rst b/changelog/4908.bugfix.rst deleted file mode 100644 index 2513618a1d9..00000000000 --- a/changelog/4908.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -The ``pytest_enter_pdb`` hook gets called with post-mortem (``--pdb``). diff --git a/changelog/4956.feature.rst b/changelog/4956.feature.rst deleted file mode 100644 index ab8357cdafe..00000000000 --- a/changelog/4956.feature.rst +++ /dev/null @@ -1 +0,0 @@ -pytester's ``testdir.spawn`` uses ``tmpdir`` as HOME/USERPROFILE directory. diff --git a/changelog/5036.bugfix.rst b/changelog/5036.bugfix.rst deleted file mode 100644 index a9c266538ef..00000000000 --- a/changelog/5036.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Fix issue where fixtures dependent on other parametrized fixtures would be erroneously parametrized. diff --git a/changelog/5062.feature.rst b/changelog/5062.feature.rst deleted file mode 100644 index e311d161d52..00000000000 --- a/changelog/5062.feature.rst +++ /dev/null @@ -1 +0,0 @@ -Unroll calls to ``all`` to full for-loops for better failure messages, especially when using Generator Expressions. diff --git a/changelog/5063.feature.rst b/changelog/5063.feature.rst deleted file mode 100644 index 21379ef0aa0..00000000000 --- a/changelog/5063.feature.rst +++ /dev/null @@ -1 +0,0 @@ -Switch from ``pkg_resources`` to ``importlib-metadata`` for entrypoint detection for improved performance and import time. diff --git a/changelog/5091.feature.rst b/changelog/5091.feature.rst deleted file mode 100644 index 122c91f533a..00000000000 --- a/changelog/5091.feature.rst +++ /dev/null @@ -1 +0,0 @@ -The output for ini options in ``--help`` has been improved. diff --git a/changelog/5250.doc.rst b/changelog/5250.doc.rst deleted file mode 100644 index 1b4c564a0a4..00000000000 --- a/changelog/5250.doc.rst +++ /dev/null @@ -1 +0,0 @@ -Expand docs on use of ``setenv`` and ``delenv`` with ``monkeypatch``. diff --git a/changelog/5256.bugfix.rst b/changelog/5256.bugfix.rst deleted file mode 100644 index 4df83454e03..00000000000 --- a/changelog/5256.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Handle internal error due to a lone surrogate unicode character not being representable in Jython. diff --git a/changelog/5257.bugfix.rst b/changelog/5257.bugfix.rst deleted file mode 100644 index 5205190882d..00000000000 --- a/changelog/5257.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Ensure that ``sys.stdout.mode`` does not include ``'b'`` as it is a text stream. diff --git a/changelog/5269.feature.rst b/changelog/5269.feature.rst deleted file mode 100644 index 6247bfd5cc1..00000000000 --- a/changelog/5269.feature.rst +++ /dev/null @@ -1 +0,0 @@ -``pytest.importorskip`` includes the ``ImportError`` now in the default ``reason``. diff --git a/changelog/5278.bugfix.rst b/changelog/5278.bugfix.rst deleted file mode 100644 index 4fe70c7fd0a..00000000000 --- a/changelog/5278.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Pytest's internal python plugin can be disabled using ``-p no:python`` again. diff --git a/changelog/5286.bugfix.rst b/changelog/5286.bugfix.rst deleted file mode 100644 index 1d6974b8964..00000000000 --- a/changelog/5286.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Fix issue with ``disable_test_id_escaping_and_forfeit_all_rights_to_community_support`` option doesn't work when using a list of test IDs in parametrized tests. diff --git a/changelog/5311.feature.rst b/changelog/5311.feature.rst deleted file mode 100644 index ae7ef99ac8f..00000000000 --- a/changelog/5311.feature.rst +++ /dev/null @@ -1,2 +0,0 @@ -Captured logs that are output for each failing test are formatted using the -ColoredLevelFormatter. diff --git a/changelog/5312.feature.rst b/changelog/5312.feature.rst deleted file mode 100644 index bcd5a736b58..00000000000 --- a/changelog/5312.feature.rst +++ /dev/null @@ -1 +0,0 @@ -Improved formatting of multiline log messages in python3. diff --git a/changelog/5330.bugfix.rst b/changelog/5330.bugfix.rst deleted file mode 100644 index 61c71555207..00000000000 --- a/changelog/5330.bugfix.rst +++ /dev/null @@ -1,2 +0,0 @@ -Show the test module being collected when emitting ``PytestCollectionWarning`` messages for -test classes with ``__init__`` and ``__new__`` methods to make it easier to pin down the problem. diff --git a/changelog/5333.bugfix.rst b/changelog/5333.bugfix.rst deleted file mode 100644 index ac1d79585f5..00000000000 --- a/changelog/5333.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Fix regression with ``--lf`` not re-running all tests with known failures from non-selected tests. diff --git a/doc/en/announce/index.rst b/doc/en/announce/index.rst index 8b5ca7b0a04..fa53441ce59 100644 --- a/doc/en/announce/index.rst +++ b/doc/en/announce/index.rst @@ -6,6 +6,7 @@ Release announcements :maxdepth: 2 + release-4.6.0 release-4.5.0 release-4.4.2 release-4.4.1 diff --git a/doc/en/announce/release-4.6.0.rst b/doc/en/announce/release-4.6.0.rst new file mode 100644 index 00000000000..373f5d66eb7 --- /dev/null +++ b/doc/en/announce/release-4.6.0.rst @@ -0,0 +1,43 @@ +pytest-4.6.0 +======================================= + +The pytest team is proud to announce the 4.6.0 release! + +pytest is a mature Python testing tool with more than a 2000 tests +against itself, passing on many different interpreters and platforms. + +This release contains a number of bugs fixes and improvements, so users are encouraged +to take a look at the CHANGELOG: + + https://docs.pytest.org/en/latest/changelog.html + +For complete documentation, please visit: + + https://docs.pytest.org/en/latest/ + +As usual, you can upgrade from pypi via: + + pip install -U pytest + +Thanks to all who contributed to this release, among them: + +* Akiomi Kamakura +* Anthony Sottile +* Bruno Oliveira +* Daniel Hahler +* David Röthlisberger +* Evan Kepner +* Jeffrey Rackauckas +* MyComputer +* Nikita Krokosh +* Raul Tambre +* Thomas Hisch +* Tim Hoffmann +* Tomer Keren +* Victor Maryama +* danielx123 +* oleg-yegorov + + +Happy testing, +The Pytest Development Team diff --git a/doc/en/example/parametrize.rst b/doc/en/example/parametrize.rst index c3f8252978e..ef792afe7b6 100644 --- a/doc/en/example/parametrize.rst +++ b/doc/en/example/parametrize.rst @@ -436,7 +436,7 @@ Running it results in some skips if we don't have all the python interpreters in . $ pytest -rs -q multipython.py ...sss...sssssssss...sss... [100%] ========================= short test summary info ========================== - SKIPPED [15] $REGENDOC_TMPDIR/CWD/multipython.py:30: 'python3.4' not found + SKIPPED [15] $REGENDOC_TMPDIR/CWD/multipython.py:31: 'python3.4' not found 12 passed, 15 skipped in 0.12 seconds Indirect parametrization of optional implementations/imports @@ -494,7 +494,7 @@ If you run this with reporting for skips enabled: test_module.py .s [100%] ========================= short test summary info ========================== - SKIPPED [1] $REGENDOC_TMPDIR/conftest.py:11: could not import 'opt2' + SKIPPED [1] $REGENDOC_TMPDIR/conftest.py:11: could not import 'opt2': No module named 'opt2' =================== 1 passed, 1 skipped in 0.12 seconds ==================== You'll see that we don't have an ``opt2`` module and thus the second test run diff --git a/doc/en/example/reportingdemo.rst b/doc/en/example/reportingdemo.rst index 1371d9cfa68..928c365cafc 100644 --- a/doc/en/example/reportingdemo.rst +++ b/doc/en/example/reportingdemo.rst @@ -26,7 +26,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: > assert param1 * 2 < param2 E assert (3 * 2) < 6 - failure_demo.py:20: AssertionError + failure_demo.py:21: AssertionError _________________________ TestFailing.test_simple __________________________ self = @@ -43,7 +43,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: E + where 42 = .f at 0xdeadbeef>() E + and 43 = .g at 0xdeadbeef>() - failure_demo.py:31: AssertionError + failure_demo.py:32: AssertionError ____________________ TestFailing.test_simple_multiline _____________________ self = @@ -51,7 +51,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: def test_simple_multiline(self): > otherfunc_multi(42, 6 * 9) - failure_demo.py:34: + failure_demo.py:35: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ a = 42, b = 54 @@ -60,7 +60,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: > assert a == b E assert 42 == 54 - failure_demo.py:15: AssertionError + failure_demo.py:16: AssertionError ___________________________ TestFailing.test_not ___________________________ self = @@ -73,7 +73,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: E assert not 42 E + where 42 = .f at 0xdeadbeef>() - failure_demo.py:40: AssertionError + failure_demo.py:41: AssertionError _________________ TestSpecialisedExplanations.test_eq_text _________________ self = @@ -84,7 +84,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: E - spam E + eggs - failure_demo.py:45: AssertionError + failure_demo.py:46: AssertionError _____________ TestSpecialisedExplanations.test_eq_similar_text _____________ self = @@ -97,7 +97,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: E + foo 2 bar E ? ^ - failure_demo.py:48: AssertionError + failure_demo.py:49: AssertionError ____________ TestSpecialisedExplanations.test_eq_multiline_text ____________ self = @@ -110,7 +110,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: E + eggs E bar - failure_demo.py:51: AssertionError + failure_demo.py:52: AssertionError ______________ TestSpecialisedExplanations.test_eq_long_text _______________ self = @@ -127,7 +127,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: E + 1111111111b222222222 E ? ^ - failure_demo.py:56: AssertionError + failure_demo.py:57: AssertionError _________ TestSpecialisedExplanations.test_eq_long_text_multiline __________ self = @@ -147,7 +147,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: E E ...Full output truncated (7 lines hidden), use '-vv' to show - failure_demo.py:61: AssertionError + failure_demo.py:62: AssertionError _________________ TestSpecialisedExplanations.test_eq_list _________________ self = @@ -158,7 +158,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: E At index 2 diff: 2 != 3 E Use -v to get the full diff - failure_demo.py:64: AssertionError + failure_demo.py:65: AssertionError ______________ TestSpecialisedExplanations.test_eq_list_long _______________ self = @@ -171,7 +171,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: E At index 100 diff: 1 != 2 E Use -v to get the full diff - failure_demo.py:69: AssertionError + failure_demo.py:70: AssertionError _________________ TestSpecialisedExplanations.test_eq_dict _________________ self = @@ -189,7 +189,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: E E ...Full output truncated (2 lines hidden), use '-vv' to show - failure_demo.py:72: AssertionError + failure_demo.py:73: AssertionError _________________ TestSpecialisedExplanations.test_eq_set __________________ self = @@ -207,7 +207,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: E E ...Full output truncated (2 lines hidden), use '-vv' to show - failure_demo.py:75: AssertionError + failure_demo.py:76: AssertionError _____________ TestSpecialisedExplanations.test_eq_longer_list ______________ self = @@ -218,7 +218,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: E Right contains one more item: 3 E Use -v to get the full diff - failure_demo.py:78: AssertionError + failure_demo.py:79: AssertionError _________________ TestSpecialisedExplanations.test_in_list _________________ self = @@ -227,7 +227,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: > assert 1 in [0, 2, 3, 4, 5] E assert 1 in [0, 2, 3, 4, 5] - failure_demo.py:81: AssertionError + failure_demo.py:82: AssertionError __________ TestSpecialisedExplanations.test_not_in_text_multiline __________ self = @@ -246,7 +246,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: E E ...Full output truncated (2 lines hidden), use '-vv' to show - failure_demo.py:85: AssertionError + failure_demo.py:86: AssertionError ___________ TestSpecialisedExplanations.test_not_in_text_single ____________ self = @@ -259,7 +259,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: E single foo line E ? +++ - failure_demo.py:89: AssertionError + failure_demo.py:90: AssertionError _________ TestSpecialisedExplanations.test_not_in_text_single_long _________ self = @@ -272,7 +272,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: E head head foo tail tail tail tail tail tail tail tail tail tail tail tail tail tail tail tail tail tail tail tail E ? +++ - failure_demo.py:93: AssertionError + failure_demo.py:94: AssertionError ______ TestSpecialisedExplanations.test_not_in_text_single_long_term _______ self = @@ -285,7 +285,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: E head head fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffftail tail tail tail tail tail tail tail tail tail tail tail tail tail tail tail tail tail tail tail E ? ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - failure_demo.py:97: AssertionError + failure_demo.py:98: AssertionError ______________ TestSpecialisedExplanations.test_eq_dataclass _______________ self = @@ -306,7 +306,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: E Differing attributes: E b: 'b' != 'c' - failure_demo.py:109: AssertionError + failure_demo.py:110: AssertionError ________________ TestSpecialisedExplanations.test_eq_attrs _________________ self = @@ -327,7 +327,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: E Differing attributes: E b: 'b' != 'c' - failure_demo.py:121: AssertionError + failure_demo.py:122: AssertionError ______________________________ test_attribute ______________________________ def test_attribute(): @@ -339,7 +339,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: E assert 1 == 2 E + where 1 = .Foo object at 0xdeadbeef>.b - failure_demo.py:129: AssertionError + failure_demo.py:130: AssertionError _________________________ test_attribute_instance __________________________ def test_attribute_instance(): @@ -351,7 +351,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: E + where 1 = .Foo object at 0xdeadbeef>.b E + where .Foo object at 0xdeadbeef> = .Foo'>() - failure_demo.py:136: AssertionError + failure_demo.py:137: AssertionError __________________________ test_attribute_failure __________________________ def test_attribute_failure(): @@ -364,7 +364,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: i = Foo() > assert i.b == 2 - failure_demo.py:147: + failure_demo.py:148: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = .Foo object at 0xdeadbeef> @@ -373,7 +373,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: > raise Exception("Failed to get attrib") E Exception: Failed to get attrib - failure_demo.py:142: Exception + failure_demo.py:143: Exception _________________________ test_attribute_multiple __________________________ def test_attribute_multiple(): @@ -390,7 +390,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: E + and 2 = .Bar object at 0xdeadbeef>.b E + where .Bar object at 0xdeadbeef> = .Bar'>() - failure_demo.py:157: AssertionError + failure_demo.py:158: AssertionError __________________________ TestRaises.test_raises __________________________ self = @@ -400,7 +400,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: > raises(TypeError, int, s) E ValueError: invalid literal for int() with base 10: 'qwe' - failure_demo.py:167: ValueError + failure_demo.py:168: ValueError ______________________ TestRaises.test_raises_doesnt _______________________ self = @@ -409,7 +409,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: > raises(IOError, int, "3") E Failed: DID NOT RAISE - failure_demo.py:170: Failed + failure_demo.py:171: Failed __________________________ TestRaises.test_raise ___________________________ self = @@ -418,7 +418,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: > raise ValueError("demo error") E ValueError: demo error - failure_demo.py:173: ValueError + failure_demo.py:174: ValueError ________________________ TestRaises.test_tupleerror ________________________ self = @@ -427,7 +427,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: > a, b = [1] # NOQA E ValueError: not enough values to unpack (expected 2, got 1) - failure_demo.py:176: ValueError + failure_demo.py:177: ValueError ______ TestRaises.test_reinterpret_fails_with_print_for_the_fun_of_it ______ self = @@ -438,7 +438,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: > a, b = items.pop() E TypeError: 'int' object is not iterable - failure_demo.py:181: TypeError + failure_demo.py:182: TypeError --------------------------- Captured stdout call --------------------------- items is [1, 2, 3] ________________________ TestRaises.test_some_error ________________________ @@ -449,7 +449,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: > if namenotexi: # NOQA E NameError: name 'namenotexi' is not defined - failure_demo.py:184: NameError + failure_demo.py:185: NameError ____________________ test_dynamic_compile_shows_nicely _____________________ def test_dynamic_compile_shows_nicely(): @@ -464,14 +464,14 @@ Here is a nice run of several failures and how ``pytest`` presents things: sys.modules[name] = module > module.foo() - failure_demo.py:202: + failure_demo.py:203: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def foo(): > assert 1 == 0 E AssertionError - <0-codegen 'abc-123' $REGENDOC_TMPDIR/assertion/failure_demo.py:199>:2: AssertionError + <0-codegen 'abc-123' $REGENDOC_TMPDIR/assertion/failure_demo.py:200>:2: AssertionError ____________________ TestMoreErrors.test_complex_error _____________________ self = @@ -485,9 +485,9 @@ Here is a nice run of several failures and how ``pytest`` presents things: > somefunc(f(), g()) - failure_demo.py:213: + failure_demo.py:214: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ - failure_demo.py:11: in somefunc + failure_demo.py:12: in somefunc otherfunc(x, y) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ @@ -497,7 +497,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: > assert a == b E assert 44 == 43 - failure_demo.py:7: AssertionError + failure_demo.py:8: AssertionError ___________________ TestMoreErrors.test_z1_unpack_error ____________________ self = @@ -507,7 +507,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: > a, b = items E ValueError: not enough values to unpack (expected 2, got 0) - failure_demo.py:217: ValueError + failure_demo.py:218: ValueError ____________________ TestMoreErrors.test_z2_type_error _____________________ self = @@ -517,7 +517,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: > a, b = items E TypeError: 'int' object is not iterable - failure_demo.py:221: TypeError + failure_demo.py:222: TypeError ______________________ TestMoreErrors.test_startswith ______________________ self = @@ -530,7 +530,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: E + where False = ('456') E + where = '123'.startswith - failure_demo.py:226: AssertionError + failure_demo.py:227: AssertionError __________________ TestMoreErrors.test_startswith_nested ___________________ self = @@ -549,7 +549,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: E + where '123' = .f at 0xdeadbeef>() E + and '456' = .g at 0xdeadbeef>() - failure_demo.py:235: AssertionError + failure_demo.py:236: AssertionError _____________________ TestMoreErrors.test_global_func ______________________ self = @@ -560,7 +560,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: E + where False = isinstance(43, float) E + where 43 = globf(42) - failure_demo.py:238: AssertionError + failure_demo.py:239: AssertionError _______________________ TestMoreErrors.test_instance _______________________ self = @@ -571,7 +571,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: E assert 42 != 42 E + where 42 = .x - failure_demo.py:242: AssertionError + failure_demo.py:243: AssertionError _______________________ TestMoreErrors.test_compare ________________________ self = @@ -581,7 +581,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: E assert 11 < 5 E + where 11 = globf(10) - failure_demo.py:245: AssertionError + failure_demo.py:246: AssertionError _____________________ TestMoreErrors.test_try_finally ______________________ self = @@ -592,7 +592,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: > assert x == 0 E assert 1 == 0 - failure_demo.py:250: AssertionError + failure_demo.py:251: AssertionError ___________________ TestCustomAssertMsg.test_single_line ___________________ self = @@ -607,7 +607,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: E assert 1 == 2 E + where 1 = .A'>.a - failure_demo.py:261: AssertionError + failure_demo.py:262: AssertionError ____________________ TestCustomAssertMsg.test_multiline ____________________ self = @@ -626,7 +626,7 @@ Here is a nice run of several failures and how ``pytest`` presents things: E assert 1 == 2 E + where 1 = .A'>.a - failure_demo.py:268: AssertionError + failure_demo.py:269: AssertionError ___________________ TestCustomAssertMsg.test_custom_repr ___________________ self = @@ -648,5 +648,5 @@ Here is a nice run of several failures and how ``pytest`` presents things: E assert 1 == 2 E + where 1 = This is JSON\n{\n 'foo': 'bar'\n}.a - failure_demo.py:281: AssertionError + failure_demo.py:282: AssertionError ======================== 44 failed in 0.12 seconds ========================= diff --git a/doc/en/warnings.rst b/doc/en/warnings.rst index dd10d94f41d..8f8d6f3e1c6 100644 --- a/doc/en/warnings.rst +++ b/doc/en/warnings.rst @@ -400,7 +400,7 @@ defines an ``__init__`` constructor, as this prevents the class from being insta ============================= warnings summary ============================= test_pytest_warnings.py:1 - $REGENDOC_TMPDIR/test_pytest_warnings.py:1: PytestCollectionWarning: cannot collect test class 'Test' because it has a __init__ constructor + $REGENDOC_TMPDIR/test_pytest_warnings.py:1: PytestCollectionWarning: cannot collect test class 'Test' because it has a __init__ constructor (from: test_pytest_warnings.py) class Test: -- Docs: https://docs.pytest.org/en/latest/warnings.html From e2ac4b782a0898557e511ba8cad6dcc9527de274 Mon Sep 17 00:00:00 2001 From: Hugo Date: Sat, 1 Jun 2019 23:27:20 +0300 Subject: [PATCH 02/23] Fix link anchor --- doc/en/py27-py34-deprecation.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/en/py27-py34-deprecation.rst b/doc/en/py27-py34-deprecation.rst index 95e96de0456..5c2f0610531 100644 --- a/doc/en/py27-py34-deprecation.rst +++ b/doc/en/py27-py34-deprecation.rst @@ -23,4 +23,4 @@ back-porting patches to the ``4.6-maintenance`` branch that affect Python 2 user branch will continue to exist so the community itself can contribute patches. The core team will be happy to accept those patches and make new ``4.6`` releases **until mid-2020**. -.. _`python_requires`: https://packaging.python.org/guides/distributing-packages-using-setuptools/#python-requires> +.. _`python_requires`: https://packaging.python.org/guides/distributing-packages-using-setuptools/#python-requires From cafb13c95f30d4f46f275fb60077966440643529 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sat, 1 Jun 2019 13:50:15 -0700 Subject: [PATCH 03/23] Fix `pytest.mark.parametrize` when the argvalue is an iterator --- changelog/5354.bugfix.rst | 1 + src/_pytest/mark/structures.py | 10 +++++++--- testing/test_mark.py | 22 ++++++++++++++++++++++ 3 files changed, 30 insertions(+), 3 deletions(-) create mode 100644 changelog/5354.bugfix.rst diff --git a/changelog/5354.bugfix.rst b/changelog/5354.bugfix.rst new file mode 100644 index 00000000000..812ea8364aa --- /dev/null +++ b/changelog/5354.bugfix.rst @@ -0,0 +1 @@ +Fix ``pytest.mark.parametrize`` when the argvalues is an iterator. diff --git a/src/_pytest/mark/structures.py b/src/_pytest/mark/structures.py index 561ccc3f45d..9602e8acfa3 100644 --- a/src/_pytest/mark/structures.py +++ b/src/_pytest/mark/structures.py @@ -113,14 +113,18 @@ def _parse_parametrize_args(argnames, argvalues, **_): force_tuple = len(argnames) == 1 else: force_tuple = False - parameters = [ + return argnames, force_tuple + + @staticmethod + def _parse_parametrize_parameters(argvalues, force_tuple): + return [ ParameterSet.extract_from(x, force_tuple=force_tuple) for x in argvalues ] - return argnames, parameters @classmethod def _for_parametrize(cls, argnames, argvalues, func, config, function_definition): - argnames, parameters = cls._parse_parametrize_args(argnames, argvalues) + argnames, force_tuple = cls._parse_parametrize_args(argnames, argvalues) + parameters = cls._parse_parametrize_parameters(argvalues, force_tuple) del argvalues if parameters: diff --git a/testing/test_mark.py b/testing/test_mark.py index 5bd97d547e8..dd9d352309d 100644 --- a/testing/test_mark.py +++ b/testing/test_mark.py @@ -413,6 +413,28 @@ def test_func(a, b): assert result.ret == 0 +def test_parametrize_iterator(testdir): + """parametrize should work with generators (#5354).""" + py_file = testdir.makepyfile( + """\ + import pytest + + def gen(): + yield 1 + yield 2 + yield 3 + + @pytest.mark.parametrize('a', gen()) + def test(a): + assert a >= 1 + """ + ) + result = testdir.runpytest(py_file) + assert result.ret == 0 + # should not skip any tests + result.stdout.fnmatch_lines(["*3 passed*"]) + + class TestFunctional(object): def test_merging_markers_deep(self, testdir): # issue 199 - propagate markers into nested classes From acdf30a52304f951852e013b4e6a0efcef9a7c41 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Sun, 2 Jun 2019 11:02:22 -0300 Subject: [PATCH 04/23] Fix all() unroll for non-generators/non-list comprehensions Fix #5358 --- changelog/5358.bugfix.rst | 1 + src/_pytest/assertion/rewrite.py | 16 ++++++++++++---- testing/test_assertrewrite.py | 29 +++++++++++++++++++++++++++-- 3 files changed, 40 insertions(+), 6 deletions(-) create mode 100644 changelog/5358.bugfix.rst diff --git a/changelog/5358.bugfix.rst b/changelog/5358.bugfix.rst new file mode 100644 index 00000000000..181da1e0ec2 --- /dev/null +++ b/changelog/5358.bugfix.rst @@ -0,0 +1 @@ +Fix assertion rewriting of ``all()`` calls to deal with non-generators. diff --git a/src/_pytest/assertion/rewrite.py b/src/_pytest/assertion/rewrite.py index 5e2c5397bb8..b9142147b12 100644 --- a/src/_pytest/assertion/rewrite.py +++ b/src/_pytest/assertion/rewrite.py @@ -949,11 +949,21 @@ def visit_BinOp(self, binop): res = self.assign(ast.BinOp(left_expr, binop.op, right_expr)) return res, explanation + @staticmethod + def _is_any_call_with_generator_or_list_comprehension(call): + """Return True if the Call node is an 'any' call with a generator or list comprehension""" + return ( + isinstance(call.func, ast.Name) + and call.func.id == "all" + and len(call.args) == 1 + and isinstance(call.args[0], (ast.GeneratorExp, ast.ListComp)) + ) + def visit_Call_35(self, call): """ visit `ast.Call` nodes on Python3.5 and after """ - if isinstance(call.func, ast.Name) and call.func.id == "all": + if self._is_any_call_with_generator_or_list_comprehension(call): return self._visit_all(call) new_func, func_expl = self.visit(call.func) arg_expls = [] @@ -980,8 +990,6 @@ def visit_Call_35(self, call): def _visit_all(self, call): """Special rewrite for the builtin all function, see #5062""" - if not isinstance(call.args[0], (ast.GeneratorExp, ast.ListComp)): - return gen_exp = call.args[0] assertion_module = ast.Module( body=[ast.Assert(test=gen_exp.elt, lineno=1, msg="", col_offset=1)] @@ -1009,7 +1017,7 @@ def visit_Call_legacy(self, call): """ visit `ast.Call nodes on 3.4 and below` """ - if isinstance(call.func, ast.Name) and call.func.id == "all": + if self._is_any_call_with_generator_or_list_comprehension(call): return self._visit_all(call) new_func, func_expl = self.visit(call.func) arg_expls = [] diff --git a/testing/test_assertrewrite.py b/testing/test_assertrewrite.py index 19d050f8769..22f53ab9550 100644 --- a/testing/test_assertrewrite.py +++ b/testing/test_assertrewrite.py @@ -677,7 +677,7 @@ def __repr__(self): assert "UnicodeDecodeError" not in msg assert "UnicodeEncodeError" not in msg - def test_unroll_generator(self, testdir): + def test_unroll_all_generator(self, testdir): testdir.makepyfile( """ def check_even(num): @@ -692,7 +692,7 @@ def test_generator(): result = testdir.runpytest() result.stdout.fnmatch_lines(["*assert False*", "*where False = check_even(1)*"]) - def test_unroll_list_comprehension(self, testdir): + def test_unroll_all_list_comprehension(self, testdir): testdir.makepyfile( """ def check_even(num): @@ -707,6 +707,31 @@ def test_list_comprehension(): result = testdir.runpytest() result.stdout.fnmatch_lines(["*assert False*", "*where False = check_even(1)*"]) + def test_unroll_all_object(self, testdir): + """all() for non generators/non list-comprehensions (#5358)""" + testdir.makepyfile( + """ + def test(): + assert all((1, 0)) + """ + ) + result = testdir.runpytest() + result.stdout.fnmatch_lines(["*assert False*", "*where False = all((1, 0))*"]) + + def test_unroll_all_starred(self, testdir): + """all() for non generators/non list-comprehensions (#5358)""" + testdir.makepyfile( + """ + def test(): + x = ((1, 0),) + assert all(*x) + """ + ) + result = testdir.runpytest() + result.stdout.fnmatch_lines( + ["*assert False*", "*where False = all(*((1, 0),))*"] + ) + def test_for_loop(self, testdir): testdir.makepyfile( """ From 4d49ba65297102110ae8aeecdb3b82b23a231fba Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Mon, 27 May 2019 20:31:52 -0300 Subject: [PATCH 05/23] Drop Python 2.7 and 3.4 support * Update setup.py requires and classifiers * Drop Python 2.7 and 3.4 from CI * Update docs dropping 2.7 and 3.4 support * Fix mock imports and remove tests related to pypi's mock module * Add py27 and 34 support docs to the sidebar * Remove usage of six from tmpdir * Remove six.PY* code blocks * Remove sys.version_info related code * Cleanup compat * Remove obsolete safe_str * Remove obsolete __unicode__ methods * Remove compat.PY35 and compat.PY36: not really needed anymore * Remove unused UNICODE_TYPES * Remove Jython specific code * Remove some Python 2 references from docs Related to #5275 --- .travis.yml | 36 +--- README.rst | 2 +- azure-pipelines.yml | 41 +--- doc/en/_templates/globaltoc.html | 1 + doc/en/example/markers.rst | 3 +- doc/en/getting-started.rst | 4 +- doc/en/goodpractices.rst | 3 +- doc/en/index.rst | 2 +- setup.cfg | 14 +- setup.py | 6 +- src/_pytest/_code/code.py | 142 +++++-------- src/_pytest/assertion/__init__.py | 4 - src/_pytest/assertion/rewrite.py | 102 +--------- src/_pytest/assertion/util.py | 2 +- src/_pytest/cacheprovider.py | 3 +- src/_pytest/capture.py | 27 +-- src/_pytest/compat.py | 191 ++++-------------- src/_pytest/config/__init__.py | 13 +- src/_pytest/doctest.py | 27 --- src/_pytest/fixtures.py | 6 +- src/_pytest/junitxml.py | 4 - src/_pytest/logging.py | 10 +- src/_pytest/main.py | 61 +----- src/_pytest/mark/structures.py | 4 +- src/_pytest/monkeypatch.py | 16 +- src/_pytest/pastebin.py | 15 +- src/_pytest/pathlib.py | 19 +- src/_pytest/pytester.py | 21 +- src/_pytest/python.py | 5 +- src/_pytest/python_api.py | 19 +- src/_pytest/recwarn.py | 35 +--- src/_pytest/skipping.py | 8 +- src/_pytest/terminal.py | 15 -- src/_pytest/tmpdir.py | 5 +- src/_pytest/unittest.py | 21 +- src/_pytest/warnings.py | 23 +-- testing/acceptance_test.py | 14 +- testing/code/test_code.py | 33 +-- testing/code/test_excinfo.py | 37 ++-- testing/code/test_source.py | 4 +- .../acceptance/fixture_mock_integration.py | 6 +- testing/python/approx.py | 3 +- testing/python/collect.py | 2 - testing/python/metafunc.py | 2 - testing/python/raises.py | 19 +- testing/test_argcomplete.py | 14 +- testing/test_assertion.py | 68 +------ testing/test_assertrewrite.py | 98 +-------- testing/test_capture.py | 73 +------ testing/test_collection.py | 2 - testing/test_compat.py | 7 - testing/test_config.py | 3 - testing/test_doctest.py | 10 +- testing/test_junitxml.py | 4 +- testing/test_mark.py | 13 +- testing/test_monkeypatch.py | 24 +-- testing/test_pastebin.py | 18 +- testing/test_pdb.py | 24 +-- testing/test_runner.py | 5 +- testing/test_skipping.py | 21 +- testing/test_tmpdir.py | 3 - testing/test_unittest.py | 18 +- testing/test_warnings.py | 95 --------- tox.ini | 19 +- 64 files changed, 222 insertions(+), 1327 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9914800f808..659af7273e9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,18 +19,13 @@ install: jobs: include: # OSX tests - first (in test stage), since they are the slower ones. - - &test-macos - os: osx + - os: osx + # NOTE: (tests with) pexpect appear to be buggy on Travis, + # at least with coverage. + # Log: https://travis-ci.org/pytest-dev/pytest/jobs/500358864 osx_image: xcode10.1 language: generic - # Coverage for: - # - py2 with symlink in test_cmdline_python_package_symlink. - env: TOXENV=py27-xdist PYTEST_COVERAGE=1 - before_install: - - python -V - - test $(python -c 'import sys; print("%d%d" % sys.version_info[0:2])') = 27 - - <<: *test-macos - env: TOXENV=py37-pexpect,py37-xdist PYTEST_COVERAGE=1 + env: TOXENV=py37-xdist PYTEST_COVERAGE=1 before_install: - which python3 - python3 -V @@ -38,20 +33,14 @@ jobs: - python -V - test $(python -c 'import sys; print("%d%d" % sys.version_info[0:2])') = 37 - # Full run of latest (major) supported versions, without xdist. - - env: TOXENV=py27 - python: '2.7' + # Full run of latest supported version, without xdist. - env: TOXENV=py37 python: '3.7' # Coverage tracking is slow with pypy, skip it. - - env: TOXENV=pypy-xdist - python: 'pypy' - env: TOXENV=pypy3-xdist python: 'pypy3' - - env: TOXENV=py34-xdist - python: '3.4' - env: TOXENV=py35-xdist python: '3.5' @@ -62,12 +51,6 @@ jobs: # Empty PYTEST_ADDOPTS to run this non-verbose. - env: TOXENV=py37-lsof-numpy-xdist PYTEST_COVERAGE=1 PYTEST_ADDOPTS= - # Specialized factors for py27. - - env: TOXENV=py27-nobyte-numpy-xdist - python: '2.7' - - env: TOXENV=py27-pluggymaster-xdist - python: '2.7' - # Specialized factors for py37. # Coverage for: # - test_sys_breakpoint_interception (via pexpect). @@ -81,12 +64,7 @@ jobs: if: type = cron - stage: baseline - # Coverage for: - # - _pytest.unittest._handle_skip (via pexpect). - env: TOXENV=py27-pexpect,py27-twisted PYTEST_COVERAGE=1 - python: '2.7' - # Use py36 here for faster baseline. - - env: TOXENV=py36-xdist + env: TOXENV=py36-xdist python: '3.6' - env: TOXENV=linting,docs,doctesting PYTEST_COVERAGE=1 cache: diff --git a/README.rst b/README.rst index 44fa8ac728d..9739a1bda68 100644 --- a/README.rst +++ b/README.rst @@ -85,7 +85,7 @@ Features - Can run `unittest `_ (or trial), `nose `_ test suites out of the box; -- Python 2.7, Python 3.4+, PyPy 2.3, Jython 2.5 (untested); +- Python 3.5+ and PyPy3; - Rich plugin architecture, with over 315+ `external plugins `_ and thriving community; diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 8e50486de55..72e4af732fe 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -4,7 +4,6 @@ trigger: variables: PYTEST_ADDOPTS: "--junitxml=build/test-results/$(tox.env).xml -vv" - python.needs_vc: False COVERAGE_FILE: "$(Build.Repository.LocalPath)/.coverage" COVERAGE_PROCESS_START: "$(Build.Repository.LocalPath)/.coveragerc" PYTEST_COVERAGE: '0' @@ -16,44 +15,10 @@ jobs: vmImage: "vs2017-win2016" strategy: matrix: - py27: - python.version: '2.7' - tox.env: 'py27' - py27-nobyte-lsof-numpy: - python.version: '2.7' - tox.env: 'py27-lsof-nobyte-numpy' - # Coverage for: - # - test_supports_breakpoint_module_global - # - test_terminal_reporter_writer_attr (without xdist) - # - "if write" branch in _pytest.assertion.rewrite - # - numpy - # - pytester's LsofFdLeakChecker (being skipped) - PYTEST_COVERAGE: '1' - py27-twisted: - python.version: '2.7' - tox.env: 'py27-twisted' - python.needs_vc: True - py27-pluggymaster-xdist: - python.version: '2.7' - tox.env: 'py27-pluggymaster-xdist' - # Coverage for: - # - except-IOError in _attempt_to_close_capture_file for py2. - # Also seen with py27-nobyte (using xdist), and py27-xdist. - # But no exception with py27-pexpect,py27-twisted,py27-numpy. - PYTEST_COVERAGE: '1' - # -- pypy2 and pypy3 are disabled for now: #5279 -- - # pypy: - # python.version: 'pypy2' - # tox.env: 'pypy' + # -- pypy3 disabled for now: #5279 -- # pypy3: # python.version: 'pypy3' # tox.env: 'pypy3' - py34-xdist: - python.version: '3.4' - tox.env: 'py34-xdist' - # Coverage for: - # - _pytest.compat._bytes_to_ascii - PYTEST_COVERAGE: '1' py35-xdist: python.version: '3.5' tox.env: 'py35-xdist' @@ -87,10 +52,6 @@ jobs: versionSpec: '$(python.version)' architecture: 'x64' - - script: choco install vcpython27 - condition: eq(variables['python.needs_vc'], True) - displayName: 'Install VC for py27' - - script: python -m pip install --upgrade pip && python -m pip install tox displayName: 'Install tox' diff --git a/doc/en/_templates/globaltoc.html b/doc/en/_templates/globaltoc.html index 0e088d67ef3..f4d06a99f68 100644 --- a/doc/en/_templates/globaltoc.html +++ b/doc/en/_templates/globaltoc.html @@ -10,6 +10,7 @@

{{ _('Table Of Contents') }}

  • Changelog
  • Contributing
  • Backwards Compatibility
  • +
  • Python 2.7 and 3.4 Support
  • License
  • Contact Channels
  • diff --git a/doc/en/example/markers.rst b/doc/en/example/markers.rst index b8d8bef0cb1..c3381600fb7 100644 --- a/doc/en/example/markers.rst +++ b/doc/en/example/markers.rst @@ -288,8 +288,7 @@ its test methods: This is equivalent to directly applying the decorator to the two test functions. -To remain backward-compatible with Python 2.4 you can also set a -``pytestmark`` attribute on a TestClass like this: +Due to legacy reasons, it is possible to set the ``pytestmark`` attribute on a TestClass like this: .. code-block:: python diff --git a/doc/en/getting-started.rst b/doc/en/getting-started.rst index d6c62cbe8c0..5a7b79ec3fa 100644 --- a/doc/en/getting-started.rst +++ b/doc/en/getting-started.rst @@ -1,9 +1,9 @@ Installation and Getting Started =================================== -**Pythons**: Python 2.7, 3.4, 3.5, 3.6, 3.7, Jython, PyPy-2.3 +**Pythons**: Python 3.5, 3.6, 3.7, PyPy3 -**Platforms**: Unix/Posix and Windows +**Platforms**: Linux and Windows **PyPI package name**: `pytest `_ diff --git a/doc/en/goodpractices.rst b/doc/en/goodpractices.rst index f08bd5c4078..2314c00660b 100644 --- a/doc/en/goodpractices.rst +++ b/doc/en/goodpractices.rst @@ -7,8 +7,7 @@ Good Integration Practices Install package with pip ------------------------------------------------- -For development, we recommend you use venv_ for virtual environments -(or virtualenv_ for Python 2.7) and +For development, we recommend you use venv_ for virtual environments and pip_ for installing your application and any dependencies, as well as the ``pytest`` package itself. This ensures your code and dependencies are isolated from your system Python installation. diff --git a/doc/en/index.rst b/doc/en/index.rst index 3ace95effe6..5439770fbde 100644 --- a/doc/en/index.rst +++ b/doc/en/index.rst @@ -61,7 +61,7 @@ Features - Can run :ref:`unittest ` (including trial) and :ref:`nose ` test suites out of the box; -- Python 2.7, Python 3.4+, PyPy 2.3, Jython 2.5 (untested); +- Python Python 3.5+ and PyPy 3; - Rich plugin architecture, with over 315+ `external plugins `_ and thriving community; diff --git a/setup.cfg b/setup.cfg index 9d0aa332e94..2d6e5bee1e7 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,5 +1,4 @@ [metadata] - name = pytest description = pytest: simple powerful testing with Python long_description = file: README.rst @@ -23,13 +22,11 @@ classifiers = Topic :: Software Development :: Testing Topic :: Software Development :: Libraries Topic :: Utilities - Programming Language :: Python :: 2 - Programming Language :: Python :: 2.7 - Programming Language :: Python :: 3 - Programming Language :: Python :: 3.4 + Programming Language :: Python :: 3 :: Only Programming Language :: Python :: 3.5 Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 + Programming Language :: Python :: 3.8 platforms = unix, linux, osx, cygwin, win32 [options] @@ -43,8 +40,7 @@ packages = _pytest.mark py_modules = pytest -python_requires = >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* - +python_requires = >=3.5 [options.entry_points] console_scripts = @@ -59,13 +55,9 @@ all_files = 1 [upload_sphinx] upload-dir = doc/en/build/html -[bdist_wheel] -universal = 1 - [check-manifest] ignore = _pytest/_version.py - [devpi:upload] formats = sdist.tgz,bdist_wheel diff --git a/setup.py b/setup.py index 18d32201caf..910fc839d3f 100644 --- a/setup.py +++ b/setup.py @@ -8,10 +8,8 @@ "six>=1.10.0", "packaging", "attrs>=17.4.0", - 'more-itertools>=4.0.0,<6.0.0;python_version<="2.7"', - 'more-itertools>=4.0.0;python_version>"2.7"', + "more-itertools>=4.0.0", "atomicwrites>=1.0", - 'funcsigs>=1.0;python_version<"3.0"', 'pathlib2>=2.2.0;python_version<"3.6"', 'colorama;sys_platform=="win32"', "pluggy>=0.12,<1.0", @@ -30,9 +28,9 @@ def main(): "testing": [ "argcomplete", "hypothesis>=3.56", + "mock", "nose", "requests", - "mock;python_version=='2.7'", ], }, # fmt: on diff --git a/src/_pytest/_code/code.py b/src/_pytest/_code/code.py index 8c73ccc6adc..8fd20f82d2a 100644 --- a/src/_pytest/_code/code.py +++ b/src/_pytest/_code/code.py @@ -9,25 +9,16 @@ import traceback from inspect import CO_VARARGS from inspect import CO_VARKEYWORDS +from traceback import format_exception_only from weakref import ref import attr import pluggy import py -from six import text_type import _pytest from _pytest._io.saferepr import safeformat from _pytest._io.saferepr import saferepr -from _pytest.compat import _PY2 -from _pytest.compat import _PY3 -from _pytest.compat import PY35 -from _pytest.compat import safe_str - -if _PY3: - from traceback import format_exception_only -else: - from ._py2traceback import format_exception_only class Code(object): @@ -208,8 +199,7 @@ def getlocals(self): locals = property(getlocals, None, None, "locals of underlaying frame") def getfirstlinesource(self): - # on Jython this firstlineno can be -1 apparently - return max(self.frame.code.firstlineno, 0) + return self.frame.code.firstlineno def getsource(self, astcache=None): """ return failing source code. """ @@ -391,9 +381,7 @@ class ExceptionInfo(object): help for navigating the traceback. """ - _assert_start_repr = ( - "AssertionError(u'assert " if _PY2 else "AssertionError('assert " - ) + _assert_start_repr = "AssertionError('assert " _excinfo = attr.ib() _striptext = attr.ib(default="") @@ -558,11 +546,6 @@ def __str__(self): loc = ReprFileLocation(entry.path, entry.lineno + 1, self.exconly()) return str(loc) - def __unicode__(self): - entry = self.traceback[-1] - loc = ReprFileLocation(entry.path, entry.lineno + 1, self.exconly()) - return text_type(loc) - def match(self, regexp): """ Check whether the regular expression 'regexp' is found in the string @@ -692,8 +675,7 @@ def repr_traceback_entry(self, entry, excinfo=None): source = _pytest._code.Source("???") line_index = 0 else: - # entry.getfirstlinesource() can be -1, should be 0 on jython - line_index = entry.lineno - max(entry.getfirstlinesource(), 0) + line_index = entry.lineno - entry.getfirstlinesource() lines = [] style = entry._repr_style @@ -733,7 +715,7 @@ def repr_traceback(self, excinfo): if self.tbfilter: traceback = traceback.filter() - if is_recursion_error(excinfo): + if excinfo.errisinstance(RecursionError): traceback, extraline = self._truncate_recursive_traceback(traceback) else: extraline = None @@ -769,7 +751,7 @@ def _truncate_recursive_traceback(self, traceback): " Displaying first and last {max_frames} stack frames out of {total}." ).format( exc_type=type(e).__name__, - exc_msg=safe_str(e), + exc_msg=str(e), max_frames=max_frames, total=len(traceback), ) @@ -784,64 +766,51 @@ def _truncate_recursive_traceback(self, traceback): return traceback, extraline def repr_excinfo(self, excinfo): - if _PY2: - reprtraceback = self.repr_traceback(excinfo) - reprcrash = excinfo._getreprcrash() - return ReprExceptionInfo(reprtraceback, reprcrash) - else: - repr_chain = [] - e = excinfo.value - descr = None - seen = set() - while e is not None and id(e) not in seen: - seen.add(id(e)) - if excinfo: - reprtraceback = self.repr_traceback(excinfo) - reprcrash = excinfo._getreprcrash() - else: - # fallback to native repr if the exception doesn't have a traceback: - # ExceptionInfo objects require a full traceback to work - reprtraceback = ReprTracebackNative( - traceback.format_exception(type(e), e, None) - ) - reprcrash = None - - repr_chain += [(reprtraceback, reprcrash, descr)] - if e.__cause__ is not None and self.chain: - e = e.__cause__ - excinfo = ( - ExceptionInfo((type(e), e, e.__traceback__)) - if e.__traceback__ - else None - ) - descr = "The above exception was the direct cause of the following exception:" - elif ( - e.__context__ is not None - and not e.__suppress_context__ - and self.chain - ): - e = e.__context__ - excinfo = ( - ExceptionInfo((type(e), e, e.__traceback__)) - if e.__traceback__ - else None - ) - descr = "During handling of the above exception, another exception occurred:" - else: - e = None - repr_chain.reverse() - return ExceptionChainRepr(repr_chain) + repr_chain = [] + e = excinfo.value + descr = None + seen = set() + while e is not None and id(e) not in seen: + seen.add(id(e)) + if excinfo: + reprtraceback = self.repr_traceback(excinfo) + reprcrash = excinfo._getreprcrash() + else: + # fallback to native repr if the exception doesn't have a traceback: + # ExceptionInfo objects require a full traceback to work + reprtraceback = ReprTracebackNative( + traceback.format_exception(type(e), e, None) + ) + reprcrash = None + + repr_chain += [(reprtraceback, reprcrash, descr)] + if e.__cause__ is not None and self.chain: + e = e.__cause__ + excinfo = ( + ExceptionInfo((type(e), e, e.__traceback__)) + if e.__traceback__ + else None + ) + descr = "The above exception was the direct cause of the following exception:" + elif ( + e.__context__ is not None and not e.__suppress_context__ and self.chain + ): + e = e.__context__ + excinfo = ( + ExceptionInfo((type(e), e, e.__traceback__)) + if e.__traceback__ + else None + ) + descr = "During handling of the above exception, another exception occurred:" + else: + e = None + repr_chain.reverse() + return ExceptionChainRepr(repr_chain) class TerminalRepr(object): def __str__(self): - s = self.__unicode__() - if _PY2: - s = s.encode("utf-8") - return s - - def __unicode__(self): # FYI this is called from pytest-xdist's serialization of exception # information. io = py.io.TextIO() @@ -1006,7 +975,7 @@ def toterminal(self, tw): if self.args: linesofar = "" for name, value in self.args: - ns = "%s = %s" % (safe_str(name), safe_str(value)) + ns = "%s = %s" % (name, value) if len(ns) + len(linesofar) + 2 > tw.fullwidth: if linesofar: tw.line(linesofar) @@ -1038,23 +1007,6 @@ def getrawcode(obj, trycall=True): return obj -if PY35: # RecursionError introduced in 3.5 - - def is_recursion_error(excinfo): - return excinfo.errisinstance(RecursionError) # noqa - - -else: - - def is_recursion_error(excinfo): - if not excinfo.errisinstance(RuntimeError): - return False - try: - return "maximum recursion depth exceeded" in str(excinfo.value) - except UnicodeError: - return False - - # relative paths that we use to filter traceback entries from appearing to the user; # see filter_traceback # note: if we need to add more paths than what we have now we should probably use a list diff --git a/src/_pytest/assertion/__init__.py b/src/_pytest/assertion/__init__.py index 6b6abb863a3..f959de29c02 100644 --- a/src/_pytest/assertion/__init__.py +++ b/src/_pytest/assertion/__init__.py @@ -74,10 +74,6 @@ def __init__(self, config, mode): def install_importhook(config): """Try to install the rewrite hook, raise SystemError if it fails.""" - # Jython has an AST bug that make the assertion rewriting hook malfunction. - if sys.platform.startswith("java"): - raise SystemError("rewrite not supported") - config._assertstate = AssertionState(config, "rewrite") config._assertstate.hook = hook = rewrite.AssertionRewritingHook(config) sys.meta_path.insert(0, hook) diff --git a/src/_pytest/assertion/rewrite.py b/src/_pytest/assertion/rewrite.py index b9142147b12..785a7b12f1d 100644 --- a/src/_pytest/assertion/rewrite.py +++ b/src/_pytest/assertion/rewrite.py @@ -15,6 +15,7 @@ import struct import sys import types +from importlib.util import spec_from_file_location import atomicwrites import py @@ -25,7 +26,6 @@ from _pytest.assertion.util import ( # noqa: F401 format_explanation as _format_explanation, ) -from _pytest.compat import spec_from_file_location from _pytest.pathlib import fnmatch_ex from _pytest.pathlib import PurePath @@ -35,8 +35,6 @@ else: if hasattr(sys, "pypy_version_info"): impl = "pypy" - elif sys.platform == "java": - impl = "jython" else: impl = "cpython" ver = sys.version_info @@ -46,15 +44,6 @@ PYC_EXT = ".py" + (__debug__ and "c" or "o") PYC_TAIL = "." + PYTEST_TAG + PYC_EXT -ASCII_IS_DEFAULT_ENCODING = sys.version_info[0] < 3 - -if sys.version_info >= (3, 5): - ast_Call = ast.Call -else: - - def ast_Call(a, b, c): - return ast.Call(a, b, c, None, None) - class AssertionRewritingHook(object): """PEP302 Import hook which rewrites asserts.""" @@ -364,37 +353,6 @@ def _rewrite_test(config, fn): source = fn.read("rb") except EnvironmentError: return None, None - if ASCII_IS_DEFAULT_ENCODING: - # ASCII is the default encoding in Python 2. Without a coding - # declaration, Python 2 will complain about any bytes in the file - # outside the ASCII range. Sadly, this behavior does not extend to - # compile() or ast.parse(), which prefer to interpret the bytes as - # latin-1. (At least they properly handle explicit coding cookies.) To - # preserve this error behavior, we could force ast.parse() to use ASCII - # as the encoding by inserting a coding cookie. Unfortunately, that - # messes up line numbers. Thus, we have to check ourselves if anything - # is outside the ASCII range in the case no encoding is explicitly - # declared. For more context, see issue #269. Yay for Python 3 which - # gets this right. - end1 = source.find("\n") - end2 = source.find("\n", end1 + 1) - if ( - not source.startswith(BOM_UTF8) - and cookie_re.match(source[0:end1]) is None - and cookie_re.match(source[end1 + 1 : end2]) is None - ): - if hasattr(state, "_indecode"): - # encodings imported us again, so don't rewrite. - return None, None - state._indecode = True - try: - try: - source.decode("ascii") - except UnicodeDecodeError: - # Let it fail in real import. - return None, None - finally: - del state._indecode try: tree = ast.parse(source, filename=fn.strpath) except SyntaxError: @@ -737,7 +695,7 @@ def helper(self, name, *args): """Call a helper in this module.""" py_name = ast.Name("@pytest_ar", ast.Load()) attr = ast.Attribute(py_name, name, ast.Load()) - return ast_Call(attr, list(args), []) + return ast.Call(attr, list(args), []) def builtin(self, name): """Return the builtin called *name*.""" @@ -847,11 +805,9 @@ def visit_Assert(self, assert_): msg = self.pop_format_context(template) fmt = self.helper("_format_explanation", msg) err_name = ast.Name("AssertionError", ast.Load()) - exc = ast_Call(err_name, [fmt], []) - if sys.version_info[0] >= 3: - raise_ = ast.Raise(exc, None) - else: - raise_ = ast.Raise(exc, None, None) + exc = ast.Call(err_name, [fmt], []) + raise_ = ast.Raise(exc, None) + body.append(raise_) # Clear temporary variables by setting them to None. if self.variables: @@ -893,7 +849,7 @@ def warn_about_none_ast(self, node, module_path, lineno): def visit_Name(self, name): # Display the repr of the name if it's a local variable or # _should_repr_global_name() thinks it's acceptable. - locs = ast_Call(self.builtin("locals"), [], []) + locs = ast.Call(self.builtin("locals"), [], []) inlocs = ast.Compare(ast.Str(name.id), [ast.In()], [locs]) dorepr = self.helper("_should_repr_global_name", name) test = ast.BoolOp(ast.Or(), [inlocs, dorepr]) @@ -920,7 +876,7 @@ def visit_BoolOp(self, boolop): res, expl = self.visit(v) body.append(ast.Assign([ast.Name(res_var, ast.Store())], res)) expl_format = self.pop_format_context(ast.Str(expl)) - call = ast_Call(app, [expl_format], []) + call = ast.Call(app, [expl_format], []) self.on_failure.append(ast.Expr(call)) if i < levels: cond = res @@ -959,9 +915,9 @@ def _is_any_call_with_generator_or_list_comprehension(call): and isinstance(call.args[0], (ast.GeneratorExp, ast.ListComp)) ) - def visit_Call_35(self, call): + def visit_Call(self, call): """ - visit `ast.Call` nodes on Python3.5 and after + visit `ast.Call` nodes """ if self._is_any_call_with_generator_or_list_comprehension(call): return self._visit_all(call) @@ -1013,46 +969,6 @@ def visit_Starred(self, starred): new_starred = ast.Starred(res, starred.ctx) return new_starred, "*" + expl - def visit_Call_legacy(self, call): - """ - visit `ast.Call nodes on 3.4 and below` - """ - if self._is_any_call_with_generator_or_list_comprehension(call): - return self._visit_all(call) - new_func, func_expl = self.visit(call.func) - arg_expls = [] - new_args = [] - new_kwargs = [] - new_star = new_kwarg = None - for arg in call.args: - res, expl = self.visit(arg) - new_args.append(res) - arg_expls.append(expl) - for keyword in call.keywords: - res, expl = self.visit(keyword.value) - new_kwargs.append(ast.keyword(keyword.arg, res)) - arg_expls.append(keyword.arg + "=" + expl) - if call.starargs: - new_star, expl = self.visit(call.starargs) - arg_expls.append("*" + expl) - if call.kwargs: - new_kwarg, expl = self.visit(call.kwargs) - arg_expls.append("**" + expl) - expl = "%s(%s)" % (func_expl, ", ".join(arg_expls)) - new_call = ast.Call(new_func, new_args, new_kwargs, new_star, new_kwarg) - res = self.assign(new_call) - res_expl = self.explanation_param(self.display(res)) - outer_expl = "%s\n{%s = %s\n}" % (res_expl, res_expl, expl) - return res, outer_expl - - # ast.Call signature changed on 3.5, - # conditionally change which methods is named - # visit_Call depending on Python version - if sys.version_info >= (3, 5): - visit_Call = visit_Call_35 - else: - visit_Call = visit_Call_legacy - def visit_Attribute(self, attr): if not isinstance(attr.ctx, ast.Load): return self.generic_visit(attr) diff --git a/src/_pytest/assertion/util.py b/src/_pytest/assertion/util.py index 1fee64ce08d..7bcb709466b 100644 --- a/src/_pytest/assertion/util.py +++ b/src/_pytest/assertion/util.py @@ -5,11 +5,11 @@ from __future__ import print_function import pprint +from collections.abc import Sequence import six import _pytest._code -from ..compat import Sequence from _pytest import outcomes from _pytest._io.saferepr import saferepr diff --git a/src/_pytest/cacheprovider.py b/src/_pytest/cacheprovider.py index 045248cb7c2..1eb9acc13ea 100755 --- a/src/_pytest/cacheprovider.py +++ b/src/_pytest/cacheprovider.py @@ -18,7 +18,6 @@ import six import pytest -from .compat import _PY2 as PY2 from .pathlib import Path from .pathlib import resolve_from_str from .pathlib import rmtree @@ -129,7 +128,7 @@ def set(self, key, value): if not cache_dir_exists_already: self._ensure_supporting_files() try: - f = path.open("wb" if PY2 else "w") + f = path.open("w") except (IOError, OSError): self.warn("cache could not write path {path}", path=path) else: diff --git a/src/_pytest/capture.py b/src/_pytest/capture.py index 68c17772f39..3587018b8af 100644 --- a/src/_pytest/capture.py +++ b/src/_pytest/capture.py @@ -18,7 +18,6 @@ import six import pytest -from _pytest.compat import _PY3 from _pytest.compat import CaptureIO patchsysdict = {0: "stdin", 1: "stdout", 2: "stderr"} @@ -283,10 +282,6 @@ def capsysbinary(request): ``out`` and ``err`` will be ``bytes`` objects. """ _ensure_only_one_capture_fixture(request, "capsysbinary") - # Currently, the implementation uses the python3 specific `.buffer` - # property of CaptureIO. - if sys.version_info < (3,): - raise request.raiseerror("capsysbinary is only supported on Python 3") with _install_capture_fixture_on_item(request, SysCaptureBinary) as fixture: yield fixture @@ -434,7 +429,7 @@ def __init__(self, buffer, encoding): def write(self, obj): if isinstance(obj, six.text_type): obj = obj.encode(self.encoding, "replace") - elif _PY3: + else: raise TypeError( "write() argument must be str, not {}".format(type(obj).__name__) ) @@ -608,7 +603,7 @@ def done(self): os.dup2(targetfd_save, self.targetfd) os.close(targetfd_save) self.syscapture.done() - _attempt_to_close_capture_file(self.tmpfile) + self.tmpfile.close() self._state = "done" def suspend(self): @@ -681,7 +676,7 @@ def snap(self): def done(self): setattr(sys, self.name, self._old) del self._old - _attempt_to_close_capture_file(self.tmpfile) + self.tmpfile.close() self._state = "done" def suspend(self): @@ -738,10 +733,7 @@ def close(self): @property def buffer(self): - if sys.version_info >= (3, 0): - return self - else: - raise AttributeError("redirected stdin has no attribute buffer") + return self def _colorama_workaround(): @@ -837,14 +829,3 @@ def _reopen_stdio(f, mode): sys.stdin = _reopen_stdio(sys.stdin, "rb") sys.stdout = _reopen_stdio(sys.stdout, "wb") sys.stderr = _reopen_stdio(sys.stderr, "wb") - - -def _attempt_to_close_capture_file(f): - """Suppress IOError when closing the temporary file used for capturing streams in py27 (#2370)""" - if six.PY2: - try: - f.close() - except IOError: - pass - else: - f.close() diff --git a/src/_pytest/compat.py b/src/_pytest/compat.py index 7668c3a94c7..9d38b97cb29 100644 --- a/src/_pytest/compat.py +++ b/src/_pytest/compat.py @@ -6,59 +6,28 @@ from __future__ import division from __future__ import print_function -import codecs import functools import inspect +import io import re import sys from contextlib import contextmanager +from inspect import Parameter +from inspect import signature import py -import six -from six import text_type import _pytest from _pytest._io.saferepr import saferepr from _pytest.outcomes import fail from _pytest.outcomes import TEST_OUTCOME -try: - import enum -except ImportError: # pragma: no cover - # Only available in Python 3.4+ or as a backport - enum = None - -_PY3 = sys.version_info > (3, 0) -_PY2 = not _PY3 - - -if _PY3: - from inspect import signature, Parameter as Parameter -else: - from funcsigs import signature, Parameter as Parameter NOTSET = object() -PY35 = sys.version_info[:2] >= (3, 5) -PY36 = sys.version_info[:2] >= (3, 6) -MODULE_NOT_FOUND_ERROR = "ModuleNotFoundError" if PY36 else "ImportError" - - -if _PY3: - from collections.abc import MutableMapping as MappingMixin - from collections.abc import Iterable, Mapping, Sequence, Sized -else: - # those raise DeprecationWarnings in Python >=3.7 - from collections import MutableMapping as MappingMixin # noqa - from collections import Iterable, Mapping, Sequence, Sized # noqa - - -if sys.version_info >= (3, 4): - from importlib.util import spec_from_file_location -else: - - def spec_from_file_location(*_, **__): - return None +MODULE_NOT_FOUND_ERROR = ( + "ModuleNotFoundError" if sys.version_info[:2] >= (3, 6) else "ImportError" +) def _format_args(func): @@ -195,72 +164,36 @@ def _translate_non_printable(s): return s.translate(_non_printable_ascii_translate_table) -if _PY3: - STRING_TYPES = bytes, str - UNICODE_TYPES = six.text_type - - if PY35: +STRING_TYPES = bytes, str - def _bytes_to_ascii(val): - return val.decode("ascii", "backslashreplace") - else: - - def _bytes_to_ascii(val): - if val: - # source: http://goo.gl/bGsnwC - encoded_bytes, _ = codecs.escape_encode(val) - return encoded_bytes.decode("ascii") - else: - # empty bytes crashes codecs.escape_encode (#1087) - return "" - - def ascii_escaped(val): - """If val is pure ascii, returns it as a str(). Otherwise, escapes - bytes objects into a sequence of escaped bytes: - - b'\xc3\xb4\xc5\xd6' -> u'\\xc3\\xb4\\xc5\\xd6' - - and escapes unicode objects into a sequence of escaped unicode - ids, e.g.: +def _bytes_to_ascii(val): + return val.decode("ascii", "backslashreplace") - '4\\nV\\U00043efa\\x0eMXWB\\x1e\\u3028\\u15fd\\xcd\\U0007d944' - note: - the obvious "v.decode('unicode-escape')" will return - valid utf-8 unicode if it finds them in bytes, but we - want to return escaped bytes for any byte, even if they match - a utf-8 string. +def ascii_escaped(val): + """If val is pure ascii, returns it as a str(). Otherwise, escapes + bytes objects into a sequence of escaped bytes: - """ - if isinstance(val, bytes): - ret = _bytes_to_ascii(val) - else: - ret = val.encode("unicode_escape").decode("ascii") - return _translate_non_printable(ret) + b'\xc3\xb4\xc5\xd6' -> u'\\xc3\\xb4\\xc5\\xd6' + and escapes unicode objects into a sequence of escaped unicode + ids, e.g.: -else: - STRING_TYPES = six.string_types - UNICODE_TYPES = six.text_type + '4\\nV\\U00043efa\\x0eMXWB\\x1e\\u3028\\u15fd\\xcd\\U0007d944' - def ascii_escaped(val): - """In py2 bytes and str are the same type, so return if it's a bytes - object, return it unchanged if it is a full ascii string, - otherwise escape it into its binary form. + note: + the obvious "v.decode('unicode-escape')" will return + valid utf-8 unicode if it finds them in bytes, but we + want to return escaped bytes for any byte, even if they match + a utf-8 string. - If it's a unicode string, change the unicode characters into - unicode escapes. - - """ - if isinstance(val, bytes): - try: - ret = val.decode("ascii") - except UnicodeDecodeError: - ret = val.encode("string-escape").decode("ascii") - else: - ret = val.encode("unicode-escape").decode("ascii") - return _translate_non_printable(ret) + """ + if isinstance(val, bytes): + ret = _bytes_to_ascii(val) + else: + ret = val.encode("unicode_escape").decode("ascii") + return _translate_non_printable(ret) class _PytestWrapper(object): @@ -357,36 +290,6 @@ def safe_isclass(obj): return False -def _is_unittest_unexpected_success_a_failure(): - """Return if the test suite should fail if an @expectedFailure unittest test PASSES. - - From https://docs.python.org/3/library/unittest.html?highlight=unittest#unittest.TestResult.wasSuccessful: - Changed in version 3.4: Returns False if there were any - unexpectedSuccesses from tests marked with the expectedFailure() decorator. - """ - return sys.version_info >= (3, 4) - - -if _PY3: - - def safe_str(v): - """returns v as string""" - return str(v) - - -else: - - def safe_str(v): - """returns v as string, converting to ascii if necessary""" - try: - return str(v) - except UnicodeError: - if not isinstance(v, text_type): - v = text_type(v) - errors = "replace" - return v.encode("utf-8", errors) - - COLLECT_FAKEMODULE_ATTRIBUTES = ( "Collector", "Module", @@ -410,27 +313,14 @@ def _setup_collect_fakemodule(): setattr(pytest.collect, attr, getattr(pytest, attr)) -if _PY2: - # Without this the test_dupfile_on_textio will fail, otherwise CaptureIO could directly inherit from StringIO. - from py.io import TextIO - - class CaptureIO(TextIO): - @property - def encoding(self): - return getattr(self, "_encoding", "UTF-8") - - -else: - import io - - class CaptureIO(io.TextIOWrapper): - def __init__(self): - super(CaptureIO, self).__init__( - io.BytesIO(), encoding="UTF-8", newline="", write_through=True - ) +class CaptureIO(io.TextIOWrapper): + def __init__(self): + super(CaptureIO, self).__init__( + io.BytesIO(), encoding="UTF-8", newline="", write_through=True + ) - def getvalue(self): - return self.buffer.getvalue().decode("UTF-8") + def getvalue(self): + return self.buffer.getvalue().decode("UTF-8") class FuncargnamesCompatAttr(object): @@ -442,16 +332,3 @@ class FuncargnamesCompatAttr(object): def funcargnames(self): """ alias attribute for ``fixturenames`` for pre-2.3 compatibility""" return self.fixturenames - - -if six.PY2: - - def lru_cache(*_, **__): - def dec(fn): - return fn - - return dec - - -else: - from functools import lru_cache # noqa: F401 diff --git a/src/_pytest/config/__init__.py b/src/_pytest/config/__init__.py index 7a5deb13f53..ee588be5ba5 100644 --- a/src/_pytest/config/__init__.py +++ b/src/_pytest/config/__init__.py @@ -12,6 +12,7 @@ import sys import types import warnings +from functools import lru_cache import importlib_metadata import py @@ -31,8 +32,6 @@ from _pytest import deprecated from _pytest._code import ExceptionInfo from _pytest._code import filter_traceback -from _pytest.compat import lru_cache -from _pytest.compat import safe_str from _pytest.outcomes import fail from _pytest.outcomes import Skipped from _pytest.warning_types import PytestConfigWarning @@ -73,7 +72,7 @@ def main(args=None, plugins=None): if exc_info.traceback else exc_info.exconly() ) - formatted_tb = safe_str(exc_repr) + formatted_tb = str(exc_repr) for line in formatted_tb.splitlines(): tw.line(line.rstrip(), red=True) return 4 @@ -403,12 +402,6 @@ def _getconftestmodules(self, path): else: directory = path - if six.PY2: # py2 is not using lru_cache. - try: - return self._dirpath2confmods[directory] - except KeyError: - pass - # XXX these days we may rather want to use config.rootdir # and allow users to opt into looking into the rootdir parent # directories instead of requiring to specify confcutdir @@ -566,7 +559,7 @@ def import_plugin(self, modname, consider_entry_points=False): except ImportError as e: new_exc_message = 'Error importing plugin "%s": %s' % ( modname, - safe_str(e.args[0]), + str(e.args[0]), ) new_exc = ImportError(new_exc_message) tb = sys.exc_info()[2] diff --git a/src/_pytest/doctest.py b/src/_pytest/doctest.py index 95a80bb4fa2..c6355470364 100644 --- a/src/_pytest/doctest.py +++ b/src/_pytest/doctest.py @@ -333,7 +333,6 @@ def collect(self): checker=_get_checker(), continue_on_failure=_get_continue_on_failure(self.config), ) - _fix_spoof_python2(runner, encoding) parser = doctest.DocTestParser() test = parser.get_doctest(text, globs, name, filename, 0) @@ -539,32 +538,6 @@ def _get_report_choice(key): }[key] -def _fix_spoof_python2(runner, encoding): - """ - Installs a "SpoofOut" into the given DebugRunner so it properly deals with unicode output. This - should patch only doctests for text files because they don't have a way to declare their - encoding. Doctests in docstrings from Python modules don't have the same problem given that - Python already decoded the strings. - - This fixes the problem related in issue #2434. - """ - from _pytest.compat import _PY2 - - if not _PY2: - return - - from doctest import _SpoofOut - - class UnicodeSpoof(_SpoofOut): - def getvalue(self): - result = _SpoofOut.getvalue(self) - if encoding and isinstance(result, bytes): - result = result.decode(encoding) - return result - - runner._fakeout = UnicodeSpoof() - - @pytest.fixture(scope="session") def doctest_namespace(): """ diff --git a/src/_pytest/fixtures.py b/src/_pytest/fixtures.py index 280a48608b6..53c916ebe2c 100644 --- a/src/_pytest/fixtures.py +++ b/src/_pytest/fixtures.py @@ -1303,11 +1303,7 @@ def parsefactories(self, node_or_obj, nodeid=NOTSET, unittest=False): # during fixture definition we wrap the original fixture function # to issue a warning if called directly, so here we unwrap it in order to not emit the warning # when pytest itself calls the fixture function - if six.PY2 and unittest: - # hack on Python 2 because of the unbound methods - obj = get_real_func(obj) - else: - obj = get_real_method(obj, holderobj) + obj = get_real_method(obj, holderobj) fixture_def = FixtureDef( self, diff --git a/src/_pytest/junitxml.py b/src/_pytest/junitxml.py index 3972113cbb0..9a169a2bb96 100644 --- a/src/_pytest/junitxml.py +++ b/src/_pytest/junitxml.py @@ -26,10 +26,6 @@ from _pytest import nodes from _pytest.config import filename_arg -# Python 2.X and 3.X compatibility -if sys.version_info[0] < 3: - from codecs import open - class Junit(py.xml.Namespace): pass diff --git a/src/_pytest/logging.py b/src/_pytest/logging.py index 577a5407be0..a5f41173a20 100644 --- a/src/_pytest/logging.py +++ b/src/_pytest/logging.py @@ -43,10 +43,7 @@ class ColoredLevelFormatter(logging.Formatter): def __init__(self, terminalwriter, *args, **kwargs): super(ColoredLevelFormatter, self).__init__(*args, **kwargs) - if six.PY2: - self._original_fmt = self._fmt - else: - self._original_fmt = self._style._fmt + self._original_fmt = self._style._fmt self._level_to_fmt_mapping = {} levelname_fmt_match = self.LEVELNAME_FMT_REGEX.search(self._fmt) @@ -70,10 +67,7 @@ def __init__(self, terminalwriter, *args, **kwargs): def format(self, record): fmt = self._level_to_fmt_mapping.get(record.levelno, self._original_fmt) - if six.PY2: - self._fmt = fmt - else: - self._style._fmt = fmt + self._style._fmt = fmt return super(ColoredLevelFormatter, self).format(record) diff --git a/src/_pytest/main.py b/src/_pytest/main.py index fa4d8d3d509..4978f8b532d 100644 --- a/src/_pytest/main.py +++ b/src/_pytest/main.py @@ -4,7 +4,6 @@ from __future__ import division from __future__ import print_function -import contextlib import fnmatch import functools import os @@ -342,46 +341,6 @@ def pytest_collection_modifyitems(items, config): items[:] = remaining -@contextlib.contextmanager -def _patched_find_module(): - """Patch bug in pkgutil.ImpImporter.find_module - - When using pkgutil.find_loader on python<3.4 it removes symlinks - from the path due to a call to os.path.realpath. This is not consistent - with actually doing the import (in these versions, pkgutil and __import__ - did not share the same underlying code). This can break conftest - discovery for pytest where symlinks are involved. - - The only supported python<3.4 by pytest is python 2.7. - """ - if six.PY2: # python 3.4+ uses importlib instead - - def find_module_patched(self, fullname, path=None): - # Note: we ignore 'path' argument since it is only used via meta_path - subname = fullname.split(".")[-1] - if subname != fullname and self.path is None: - return None - if self.path is None: - path = None - else: - # original: path = [os.path.realpath(self.path)] - path = [self.path] - try: - file, filename, etc = pkgutil.imp.find_module(subname, path) - except ImportError: - return None - return pkgutil.ImpLoader(fullname, file, filename, etc) - - old_find_module = pkgutil.ImpImporter.find_module - pkgutil.ImpImporter.find_module = find_module_patched - try: - yield - finally: - pkgutil.ImpImporter.find_module = old_find_module - else: - yield - - class FSHookProxy(object): def __init__(self, fspath, pm, remove_mods): self.fspath = fspath @@ -662,23 +621,14 @@ def _recurse(self, dirpath): ihook.pytest_collect_directory(path=dirpath, parent=self) return True - if six.PY2: - - @staticmethod - def _visit_filter(f): - return f.check(file=1) and not f.strpath.endswith("*.pyc") - - else: - - @staticmethod - def _visit_filter(f): - return f.check(file=1) + @staticmethod + def _visit_filter(f): + return f.check(file=1) def _tryconvertpyarg(self, x): """Convert a dotted module name to path.""" try: - with _patched_find_module(): - loader = pkgutil.find_loader(x) + loader = pkgutil.find_loader(x) except ImportError: return x if loader is None: @@ -686,8 +636,7 @@ def _tryconvertpyarg(self, x): # This method is sometimes invoked when AssertionRewritingHook, which # does not define a get_filename method, is already in place: try: - with _patched_find_module(): - path = loader.get_filename(x) + path = loader.get_filename(x) except AttributeError: # Retrieve path from AssertionRewritingHook: path = loader.modules[x][0].co_filename diff --git a/src/_pytest/mark/structures.py b/src/_pytest/mark/structures.py index 9602e8acfa3..59faaea29a2 100644 --- a/src/_pytest/mark/structures.py +++ b/src/_pytest/mark/structures.py @@ -2,6 +2,7 @@ import inspect import warnings from collections import namedtuple +from collections.abc import MutableMapping from operator import attrgetter import attr @@ -9,7 +10,6 @@ from ..compat import ascii_escaped from ..compat import getfslineno -from ..compat import MappingMixin from ..compat import NOTSET from _pytest.deprecated import PYTEST_PARAM_UNKNOWN_KWARGS from _pytest.outcomes import fail @@ -343,7 +343,7 @@ def __getattr__(self, name): MARK_GEN = MarkGenerator() -class NodeKeywords(MappingMixin): +class NodeKeywords(MutableMapping): def __init__(self, node): self.node = node self.parent = node.parent diff --git a/src/_pytest/monkeypatch.py b/src/_pytest/monkeypatch.py index e8671b0c702..5a017aa286b 100644 --- a/src/_pytest/monkeypatch.py +++ b/src/_pytest/monkeypatch.py @@ -222,15 +222,6 @@ def delitem(self, dic, name, raising=True): self._setitem.append((dic, name, dic.get(name, notset))) del dic[name] - def _warn_if_env_name_is_not_str(self, name): - """On Python 2, warn if the given environment variable name is not a native str (#4056)""" - if six.PY2 and not isinstance(name, str): - warnings.warn( - pytest.PytestWarning( - "Environment variable name {!r} should be str".format(name) - ) - ) - def setenv(self, name, value, prepend=None): """ Set environment variable ``name`` to ``value``. If ``prepend`` is a character, read the current environment variable value @@ -248,7 +239,6 @@ def setenv(self, name, value, prepend=None): value = str(value) if prepend and name in os.environ: value = value + prepend + os.environ[name] - self._warn_if_env_name_is_not_str(name) self.setitem(os.environ, name, value) def delenv(self, name, raising=True): @@ -258,7 +248,6 @@ def delenv(self, name, raising=True): If ``raising`` is set to False, no exception will be raised if the environment variable is missing. """ - self._warn_if_env_name_is_not_str(name) self.delitem(os.environ, name, raising=raising) def syspath_prepend(self, path): @@ -279,10 +268,9 @@ def syspath_prepend(self, path): # since then the mtime based FileFinder cache (that gets created in # this case already) gets not invalidated when writing the new files # quickly afterwards. - if sys.version_info >= (3, 3): - from importlib import invalidate_caches + from importlib import invalidate_caches - invalidate_caches() + invalidate_caches() def chdir(self, path): """ Change the current working directory to the specified path. diff --git a/src/_pytest/pastebin.py b/src/_pytest/pastebin.py index 3f4171207a3..78c8b587a6f 100644 --- a/src/_pytest/pastebin.py +++ b/src/_pytest/pastebin.py @@ -4,7 +4,6 @@ from __future__ import division from __future__ import print_function -import sys import tempfile import six @@ -70,18 +69,10 @@ def create_new_paste(contents): :returns: url to the pasted contents """ import re + from urllib.request import urlopen + from urllib.parse import urlencode - if sys.version_info < (3, 0): - from urllib import urlopen, urlencode - else: - from urllib.request import urlopen - from urllib.parse import urlencode - - params = { - "code": contents, - "lexer": "python3" if sys.version_info[0] == 3 else "python", - "expiry": "1week", - } + params = {"code": contents, "lexer": "python3", "expiry": "1week"} url = "https://bpaste.net" response = urlopen(url, data=urlencode(params).encode("ascii")).read() m = re.search(r'href="/raw/(\w+)"', response.decode("utf-8")) diff --git a/src/_pytest/pathlib.py b/src/_pytest/pathlib.py index 729c41797d9..2cd931b32a0 100644 --- a/src/_pytest/pathlib.py +++ b/src/_pytest/pathlib.py @@ -8,7 +8,6 @@ import shutil import sys import uuid -from functools import reduce from os.path import expanduser from os.path import expandvars from os.path import isabs @@ -18,9 +17,8 @@ import six from six.moves import map -from .compat import PY36 -if PY36: +if sys.version_info[:2] >= (3, 6): from pathlib import Path, PurePath else: from pathlib2 import Path, PurePath @@ -84,17 +82,6 @@ def parse_num(maybe_num): return -1 -if six.PY2: - - def _max(iterable, default): - """needed due to python2.7 lacking the default argument for max""" - return reduce(max, iterable, default) - - -else: - _max = max - - def _force_symlink(root, target, link_to): """helper to create the current symlink @@ -119,7 +106,7 @@ def make_numbered_dir(root, prefix): """create a directory with an increased number as suffix for the given prefix""" for i in range(10): # try up to 10 times to create the folder - max_existing = _max(map(parse_num, find_suffixes(root, prefix)), default=-1) + max_existing = max(map(parse_num, find_suffixes(root, prefix)), default=-1) new_number = max_existing + 1 new_path = root.joinpath("{}{}".format(prefix, new_number)) try: @@ -230,7 +217,7 @@ def try_cleanup(path, consider_lock_dead_if_created_before): def cleanup_candidates(root, prefix, keep): """lists candidates for numbered directories to be removed - follows py.path""" - max_existing = _max(map(parse_num, find_suffixes(root, prefix)), default=-1) + max_existing = max(map(parse_num, find_suffixes(root, prefix)), default=-1) max_delete = max_existing - keep paths = find_prefixed(root, prefix) paths, paths2 = itertools.tee(paths) diff --git a/src/_pytest/pytester.py b/src/_pytest/pytester.py index 605451630a6..d3611b338e1 100644 --- a/src/_pytest/pytester.py +++ b/src/_pytest/pytester.py @@ -13,6 +13,7 @@ import sys import time import traceback +from collections.abc import Sequence from fnmatch import fnmatch from weakref import WeakKeyDictionary @@ -25,8 +26,6 @@ from _pytest.assertion.rewrite import AssertionRewritingHook from _pytest.capture import MultiCapture from _pytest.capture import SysCapture -from _pytest.compat import safe_str -from _pytest.compat import Sequence from _pytest.main import EXIT_INTERRUPTED from _pytest.main import EXIT_OK from _pytest.main import Session @@ -911,7 +910,7 @@ def runpytest(self, *args, **kwargs): def _ensure_basetemp(self, args): args = list(args) for x in args: - if safe_str(x).startswith("--basetemp"): + if str(x).startswith("--basetemp"): break else: args.append("--basetemp=%s" % self.tmpdir.dirpath("basetemp")) @@ -1124,25 +1123,11 @@ def handle_timeout(): if timeout is None: ret = popen.wait() - elif six.PY3: + else: try: ret = popen.wait(timeout) except subprocess.TimeoutExpired: handle_timeout() - else: - end = time.time() + timeout - - resolution = min(0.1, timeout / 10) - - while True: - ret = popen.poll() - if ret is not None: - break - - if time.time() > end: - handle_timeout() - - time.sleep(resolution) finally: f1.close() f2.close() diff --git a/src/_pytest/python.py b/src/_pytest/python.py index 5f1e6885be3..e420f692437 100644 --- a/src/_pytest/python.py +++ b/src/_pytest/python.py @@ -5,6 +5,7 @@ from __future__ import print_function import collections +import enum import fnmatch import inspect import os @@ -22,7 +23,6 @@ from _pytest import nodes from _pytest._code import filter_traceback from _pytest.compat import ascii_escaped -from _pytest.compat import enum from _pytest.compat import get_default_arg_names from _pytest.compat import get_real_func from _pytest.compat import getfslineno @@ -35,7 +35,6 @@ from _pytest.compat import REGEX_TYPE from _pytest.compat import safe_getattr from _pytest.compat import safe_isclass -from _pytest.compat import safe_str from _pytest.compat import STRING_TYPES from _pytest.config import hookimpl from _pytest.main import FSHookProxy @@ -531,7 +530,7 @@ def _importtestmodule(self): if exc_info.traceback else exc_info.exconly() ) - formatted_tb = safe_str(exc_repr) + formatted_tb = str(exc_repr) raise self.CollectError( "ImportError while importing test module '{fspath}'.\n" "Hint: make sure your test modules/packages have valid Python names.\n" diff --git a/src/_pytest/python_api.py b/src/_pytest/python_api.py index df09aa32d8f..d5ee3f16040 100644 --- a/src/_pytest/python_api.py +++ b/src/_pytest/python_api.py @@ -5,6 +5,9 @@ import pprint import sys import warnings +from collections.abc import Iterable +from collections.abc import Mapping +from collections.abc import Sized from decimal import Decimal from numbers import Number @@ -15,9 +18,6 @@ import _pytest._code from _pytest import deprecated from _pytest.compat import isclass -from _pytest.compat import Iterable -from _pytest.compat import Mapping -from _pytest.compat import Sized from _pytest.compat import STRING_TYPES from _pytest.outcomes import fail @@ -81,9 +81,6 @@ def __eq__(self, actual): def __ne__(self, actual): return not (actual == self) - if sys.version_info[0] == 2: - __cmp__ = _cmp_raises_type_error - def _approx_scalar(self, x): return ApproxScalar(x, rel=self.rel, abs=self.abs, nan_ok=self.nan_ok) @@ -122,9 +119,6 @@ def __repr__(self): list_scalars = _recursive_list_map(self._approx_scalar, self.expected.tolist()) return "approx({!r})".format(list_scalars) - if sys.version_info[0] == 2: - __cmp__ = _cmp_raises_type_error - def __eq__(self, actual): import numpy as np @@ -251,10 +245,7 @@ def __repr__(self): except ValueError: vetted_tolerance = "???" - if sys.version_info[0] == 2: - return "{} +- {}".format(self.expected, vetted_tolerance) - else: - return u"{} \u00b1 {}".format(self.expected, vetted_tolerance) + return "{} \u00b1 {}".format(self.expected, vetted_tolerance) def __eq__(self, actual): """ @@ -736,8 +727,6 @@ def __exit__(self, *tp): fail(self.message) self.excinfo.__init__(tp) suppress_exception = issubclass(self.excinfo.type, self.expected_exception) - if sys.version_info[0] == 2 and suppress_exception: - sys.exc_clear() if self.match_expr is not None and suppress_exception: self.excinfo.match(self.match_expr) return suppress_exception diff --git a/src/_pytest/recwarn.py b/src/_pytest/recwarn.py index 574c6a1cced..409825f488a 100644 --- a/src/_pytest/recwarn.py +++ b/src/_pytest/recwarn.py @@ -9,8 +9,6 @@ import sys import warnings -import six - import _pytest._code from _pytest.deprecated import PYTEST_WARNS_UNKNOWN_KWARGS from _pytest.deprecated import WARNS_EXEC @@ -156,44 +154,13 @@ def __enter__(self): raise RuntimeError("Cannot enter %r twice" % self) self._list = super(WarningsRecorder, self).__enter__() warnings.simplefilter("always") - # python3 keeps track of a "filter version", when the filters are - # updated previously seen warnings can be re-warned. python2 has no - # concept of this so we must reset the warnings registry manually. - # trivial patching of `warnings.warn` seems to be enough somehow? - if six.PY2: - - def warn(message, category=None, stacklevel=1): - # duplicate the stdlib logic due to - # bad handing in the c version of warnings - if isinstance(message, Warning): - category = message.__class__ - # Check category argument - if category is None: - category = UserWarning - assert issubclass(category, Warning) - - # emulate resetting the warn registry - f_globals = sys._getframe(stacklevel).f_globals - if "__warningregistry__" in f_globals: - orig = f_globals["__warningregistry__"] - f_globals["__warningregistry__"] = None - try: - return self._saved_warn(message, category, stacklevel + 1) - finally: - f_globals["__warningregistry__"] = orig - else: - return self._saved_warn(message, category, stacklevel + 1) - - warnings.warn, self._saved_warn = warn, warnings.warn return self def __exit__(self, *exc_info): if not self._entered: __tracebackhide__ = True raise RuntimeError("Cannot exit %r without entering first" % self) - # see above where `self._saved_warn` is assigned - if six.PY2: - warnings.warn = self._saved_warn + super(WarningsRecorder, self).__exit__(*exc_info) # Built-in catch_warnings does not reset entered state so we do it diff --git a/src/_pytest/skipping.py b/src/_pytest/skipping.py index bc8b88e7178..94227c39c21 100644 --- a/src/_pytest/skipping.py +++ b/src/_pytest/skipping.py @@ -129,17 +129,13 @@ def pytest_runtest_makereport(item, call): evalxfail = getattr(item, "_evalxfail", None) # unitttest special case, see setting of _unexpectedsuccess if hasattr(item, "_unexpectedsuccess") and rep.when == "call": - from _pytest.compat import _is_unittest_unexpected_success_a_failure if item._unexpectedsuccess: rep.longrepr = "Unexpected success: {}".format(item._unexpectedsuccess) else: rep.longrepr = "Unexpected success" - if _is_unittest_unexpected_success_a_failure(): - rep.outcome = "failed" - else: - rep.outcome = "passed" - rep.wasxfail = rep.longrepr + rep.outcome = "failed" + elif item.config.option.runxfail: pass # don't interefere elif call.excinfo and call.excinfo.errisinstance(xfail.Exception): diff --git a/src/_pytest/terminal.py b/src/_pytest/terminal.py index eb1970d5103..e5ede1cadb8 100644 --- a/src/_pytest/terminal.py +++ b/src/_pytest/terminal.py @@ -992,21 +992,6 @@ def _get_line_with_reprcrash_message(config, rep, termwidth): msg = msg[:max_len_msg] while wcswidth(msg) > max_len_msg: msg = msg[:-1] - if six.PY2: - # on python 2 systems with narrow unicode compilation, trying to - # get a single character out of a multi-byte unicode character such as - # u'😄' will result in a High Surrogate (U+D83D) character, which is - # rendered as u'�'; in this case we just strip that character out as it - # serves no purpose being rendered - try: - surrogate = six.unichr(0xD83D) - msg = msg.rstrip(surrogate) - except ValueError: # pragma: no cover - # Jython cannot represent this lone surrogate at all (#5256): - # ValueError: unichr() arg is a lone surrogate in range - # (0xD800, 0xDFFF) (Jython UTF-16 encoding) - # ignore this case as it shouldn't appear in the string anyway - pass msg += ellipsis line += sep + msg return line diff --git a/src/_pytest/tmpdir.py b/src/_pytest/tmpdir.py index a8a7037713c..4a3686247c7 100644 --- a/src/_pytest/tmpdir.py +++ b/src/_pytest/tmpdir.py @@ -11,7 +11,6 @@ import attr import py -import six import pytest from .pathlib import ensure_reset_dir @@ -32,9 +31,7 @@ class TempPathFactory(object): # using os.path.abspath() to get absolute path instead of resolve() as it # does not work the same in all platforms (see #4427) # Path.absolute() exists, but it is not public (see https://bugs.python.org/issue25012) - converter=attr.converters.optional( - lambda p: Path(os.path.abspath(six.text_type(p))) - ) + converter=attr.converters.optional(lambda p: Path(os.path.abspath(str(p)))) ) _trace = attr.ib() _basetemp = attr.ib(default=None) diff --git a/src/_pytest/unittest.py b/src/_pytest/unittest.py index e2e7efdc539..4380f1295b3 100644 --- a/src/_pytest/unittest.py +++ b/src/_pytest/unittest.py @@ -113,23 +113,9 @@ class TestCaseFunction(Function): def setup(self): self._testcase = self.parent.obj(self.name) - self._fix_unittest_skip_decorator() if hasattr(self, "_request"): self._request._fillfixtures() - def _fix_unittest_skip_decorator(self): - """ - The @unittest.skip decorator calls functools.wraps(self._testcase) - The call to functools.wraps() fails unless self._testcase - has a __name__ attribute. This is usually automatically supplied - if the test is a function or method, but we need to add manually - here. - - See issue #1169 - """ - if sys.version_info[0] == 2: - setattr(self._testcase, "__name__", self.name) - def teardown(self): self._testcase = None @@ -208,12 +194,7 @@ def _handle_skip(self): skip_why = getattr( self._testcase.__class__, "__unittest_skip_why__", "" ) or getattr(testMethod, "__unittest_skip_why__", "") - try: # PY3, unittest2 on PY2 - self._testcase._addSkip(self, self._testcase, skip_why) - except TypeError: # PY2 - if sys.version_info[0] != 2: - raise - self._testcase._addSkip(self, skip_why) + self._testcase._addSkip(self, self._testcase, skip_why) return True return False diff --git a/src/_pytest/warnings.py b/src/_pytest/warnings.py index a3debae462f..a2579bf753b 100644 --- a/src/_pytest/warnings.py +++ b/src/_pytest/warnings.py @@ -8,7 +8,6 @@ from contextlib import contextmanager import pytest -from _pytest import compat SHOW_PYTEST_WARNINGS_ARG = "-Walways::pytest.RemovedInPytest4Warning" @@ -104,22 +103,8 @@ def catch_warnings_for_item(config, ihook, when, item): def warning_record_to_str(warning_message): - """Convert a warnings.WarningMessage to a string. - - This takes lot of unicode shenaningans into account for Python 2. - When Python 2 support is dropped this function can be greatly simplified. - """ + """Convert a warnings.WarningMessage to a string.""" warn_msg = warning_message.message - unicode_warning = False - if compat._PY2 and any(isinstance(m, compat.UNICODE_TYPES) for m in warn_msg.args): - new_args = [] - for m in warn_msg.args: - new_args.append( - compat.ascii_escaped(m) if isinstance(m, compat.UNICODE_TYPES) else m - ) - unicode_warning = list(warn_msg.args) != new_args - warn_msg.args = new_args - msg = warnings.formatwarning( warn_msg, warning_message.category, @@ -127,12 +112,6 @@ def warning_record_to_str(warning_message): warning_message.lineno, warning_message.line, ) - if unicode_warning: - warnings.warn( - "Warning is using unicode non convertible to ascii, " - "converting to a safe representation:\n {!r}".format(compat.safe_str(msg)), - UnicodeWarning, - ) return msg diff --git a/testing/acceptance_test.py b/testing/acceptance_test.py index 7016cf13b6e..5ed04d6382f 100644 --- a/testing/acceptance_test.py +++ b/testing/acceptance_test.py @@ -176,7 +176,6 @@ def test_this(): result = testdir.runpytest(p) result.stdout.fnmatch_lines( [ - # XXX on jython this fails: "> import import_fails", "ImportError while importing test module*", "*No module named *does_not_work*", ] @@ -222,9 +221,7 @@ def foo(): " foo()", "conftest.py:2: in foo", " import qwerty", - "E {}: No module named {q}qwerty{q}".format( - exc_name, q="'" if six.PY3 else "" - ), + "E {}: No module named 'qwerty'".format(exc_name), ] ) @@ -540,7 +537,6 @@ def test_earlyinit(self, testdir): result = testdir.runpython(p) assert result.ret == 0 - @pytest.mark.xfail("sys.platform.startswith('java')") def test_pydoc(self, testdir): for name in ("py.test", "pytest"): result = testdir.runpython_c("import {};help({})".format(name, name)) @@ -783,10 +779,7 @@ def test_cmdline_python_package_symlink(self, testdir, monkeypatch): d_local = testdir.mkdir("local") symlink_location = os.path.join(str(d_local), "lib") - if six.PY2: - os.symlink(str(d), symlink_location) - else: - os.symlink(str(d), symlink_location, target_is_directory=True) + os.symlink(str(d), symlink_location, target_is_directory=True) # The structure of the test directory is now: # . @@ -1185,9 +1178,6 @@ def test_usage_error_code(testdir): assert result.ret == EXIT_USAGEERROR -@pytest.mark.skipif( - sys.version_info[:2] < (3, 5), reason="async def syntax python 3.5+ only" -) @pytest.mark.filterwarnings("default") def test_warn_on_async_function(testdir): testdir.makepyfile( diff --git a/testing/code/test_code.py b/testing/code/test_code.py index 0b63fcf4d42..fcde20b4164 100644 --- a/testing/code/test_code.py +++ b/testing/code/test_code.py @@ -4,6 +4,7 @@ from __future__ import print_function import sys +from unittest import mock from six import text_type from test_excinfo import TWMock @@ -11,11 +12,6 @@ import _pytest._code import pytest -try: - import mock -except ImportError: - import unittest.mock as mock - def test_ne(): code1 = _pytest._code.Code(compile('foo = "bar"', "", "exec")) @@ -92,21 +88,6 @@ def f(): excinfo = pytest.raises(Exception, f) text_type(excinfo) - if sys.version_info < (3,): - bytes(excinfo) - - -@pytest.mark.skipif(sys.version_info[0] >= 3, reason="python 2 only issue") -def test_unicode_handling_syntax_error(): - value = u"ąć".encode("UTF-8") - - def f(): - raise SyntaxError("invalid syntax", (None, 1, 3, value)) - - excinfo = pytest.raises(Exception, f) - str(excinfo) - if sys.version_info[0] < 3: - text_type(excinfo) def test_code_getargs(): @@ -202,10 +183,8 @@ def test_not_raise_exception_with_mixed_encoding(self): r = ReprFuncArgs(args) r.toterminal(tw) - if sys.version_info[0] >= 3: - assert ( - tw.lines[0] - == r"unicode_string = São Paulo, utf8_string = b'S\xc3\xa3o Paulo'" - ) - else: - assert tw.lines[0] == "unicode_string = São Paulo, utf8_string = São Paulo" + + assert ( + tw.lines[0] + == r"unicode_string = São Paulo, utf8_string = b'S\xc3\xa3o Paulo'" + ) diff --git a/testing/code/test_excinfo.py b/testing/code/test_excinfo.py index a76797301dd..33cd7169b3a 100644 --- a/testing/code/test_excinfo.py +++ b/testing/code/test_excinfo.py @@ -17,7 +17,7 @@ from _pytest._code.code import ExceptionChainRepr from _pytest._code.code import ExceptionInfo from _pytest._code.code import FormattedExcinfo -from _pytest._code.code import ReprExceptionInfo + try: import importlib @@ -26,8 +26,6 @@ else: invalidate_import_caches = getattr(importlib, "invalidate_caches", None) -failsonjython = pytest.mark.xfail("sys.platform.startswith('java')") - pytest_version_info = tuple(map(int, pytest.__version__.split(".")[:3])) @@ -146,7 +144,6 @@ def test_traceback_entry_getsource(self): assert s.startswith("def f():") assert s.endswith("raise ValueError") - @failsonjython def test_traceback_entry_getsource_in_construct(self): source = _pytest._code.Source( """\ @@ -500,8 +497,7 @@ def test_repr_source_not_existing(self): excinfo = _pytest._code.ExceptionInfo.from_current() repr = pr.repr_excinfo(excinfo) assert repr.reprtraceback.reprentries[1].lines[0] == "> ???" - if sys.version_info[0] >= 3: - assert repr.chain[0][0].reprentries[1].lines[0] == "> ???" + assert repr.chain[0][0].reprentries[1].lines[0] == "> ???" def test_repr_many_line_source_not_existing(self): pr = FormattedExcinfo() @@ -519,8 +515,7 @@ def test_repr_many_line_source_not_existing(self): excinfo = _pytest._code.ExceptionInfo.from_current() repr = pr.repr_excinfo(excinfo) assert repr.reprtraceback.reprentries[1].lines[0] == "> ???" - if sys.version_info[0] >= 3: - assert repr.chain[0][0].reprentries[1].lines[0] == "> ???" + assert repr.chain[0][0].reprentries[1].lines[0] == "> ???" def test_repr_source_failing_fullsource(self): pr = FormattedExcinfo() @@ -577,14 +572,12 @@ class FakeRawTB(object): fail = IOError() repr = pr.repr_excinfo(excinfo) assert repr.reprtraceback.reprentries[0].lines[0] == "> ???" - if sys.version_info[0] >= 3: - assert repr.chain[0][0].reprentries[0].lines[0] == "> ???" + assert repr.chain[0][0].reprentries[0].lines[0] == "> ???" fail = py.error.ENOENT # noqa repr = pr.repr_excinfo(excinfo) assert repr.reprtraceback.reprentries[0].lines[0] == "> ???" - if sys.version_info[0] >= 3: - assert repr.chain[0][0].reprentries[0].lines[0] == "> ???" + assert repr.chain[0][0].reprentries[0].lines[0] == "> ???" def test_repr_local(self): p = FormattedExcinfo(showlocals=True) @@ -828,9 +821,9 @@ def entry(): repr = p.repr_excinfo(excinfo) assert repr.reprtraceback assert len(repr.reprtraceback.reprentries) == len(reprtb.reprentries) - if sys.version_info[0] >= 3: - assert repr.chain[0][0] - assert len(repr.chain[0][0].reprentries) == len(reprtb.reprentries) + + assert repr.chain[0][0] + assert len(repr.chain[0][0].reprentries) == len(reprtb.reprentries) assert repr.reprcrash.path.endswith("mod.py") assert repr.reprcrash.message == "ValueError: 0" @@ -916,13 +909,11 @@ def entry(): for style in ("short", "long", "no"): for showlocals in (True, False): repr = excinfo.getrepr(style=style, showlocals=showlocals) - if sys.version_info[0] < 3: - assert isinstance(repr, ReprExceptionInfo) assert repr.reprtraceback.style == style - if sys.version_info[0] >= 3: - assert isinstance(repr, ExceptionChainRepr) - for repr in repr.chain: - assert repr[0].style == style + + assert isinstance(repr, ExceptionChainRepr) + for repr in repr.chain: + assert repr[0].style == style def test_reprexcinfo_unicode(self): from _pytest._code.code import TerminalRepr @@ -1133,7 +1124,6 @@ def i(): msg.endswith("mod.py") assert tw.lines[20] == ":9: ValueError" - @pytest.mark.skipif("sys.version_info[0] < 3") def test_exc_chain_repr(self, importasmod): mod = importasmod( """ @@ -1219,7 +1209,6 @@ def h(): assert line.endswith("mod.py") assert tw.lines[47] == ":15: AttributeError" - @pytest.mark.skipif("sys.version_info[0] < 3") @pytest.mark.parametrize("mode", ["from_none", "explicit_suppress"]) def test_exc_repr_chain_suppression(self, importasmod, mode): """Check that exc repr does not show chained exceptions in Python 3. @@ -1261,7 +1250,6 @@ def g(): assert tw.lines[9] == ":6: AttributeError" assert len(tw.lines) == 10 - @pytest.mark.skipif("sys.version_info[0] < 3") @pytest.mark.parametrize( "reason, description", [ @@ -1321,7 +1309,6 @@ def g(): ] ) - @pytest.mark.skipif("sys.version_info[0] < 3") def test_exc_chain_repr_cycle(self, importasmod): mod = importasmod( """ diff --git a/testing/code/test_source.py b/testing/code/test_source.py index 0a2a98c0202..b86d18d0c8b 100644 --- a/testing/code/test_source.py +++ b/testing/code/test_source.py @@ -16,8 +16,6 @@ import pytest from _pytest._code import Source -failsonjython = pytest.mark.xfail("sys.platform.startswith('java')") - def test_source_str_function(): x = Source("3") @@ -122,7 +120,7 @@ def test_source_strip_multiline(): def test_syntaxerror_rerepresentation(): ex = pytest.raises(SyntaxError, _pytest._code.compile, "xyz xyz") assert ex.value.lineno == 1 - assert ex.value.offset in (4, 5, 7) # XXX pypy/jython versus cpython? + assert ex.value.offset == 7 assert ex.value.text.strip(), "x x" diff --git a/testing/example_scripts/acceptance/fixture_mock_integration.py b/testing/example_scripts/acceptance/fixture_mock_integration.py index c8ccdf1b488..58afe730e23 100644 --- a/testing/example_scripts/acceptance/fixture_mock_integration.py +++ b/testing/example_scripts/acceptance/fixture_mock_integration.py @@ -1,10 +1,6 @@ # -*- coding: utf-8 -*- """Reproduces issue #3774""" - -try: - import mock -except ImportError: - import unittest.mock as mock +from unittest import mock import pytest diff --git a/testing/python/approx.py b/testing/python/approx.py index cd8df5d274f..18508f1fe5c 100644 --- a/testing/python/approx.py +++ b/testing/python/approx.py @@ -1,7 +1,6 @@ # -*- coding: utf-8 -*- import doctest import operator -import sys from decimal import Decimal from fractions import Fraction from operator import eq @@ -28,7 +27,7 @@ def report_failure(self, out, test, example, got): class TestApprox(object): @pytest.fixture def plus_minus(self): - return u"\u00b1" if sys.version_info[0] > 2 else u"+-" + return u"\u00b1" def test_repr_string(self, plus_minus): tol1, tol2, infr = "1.0e-06", "2.0e-06", "inf" diff --git a/testing/python/collect.py b/testing/python/collect.py index 501b30a49b0..4a1aa724f94 100644 --- a/testing/python/collect.py +++ b/testing/python/collect.py @@ -679,8 +679,6 @@ def test_fail(): assert 0 assert fn1 == fn2 assert fn1 != modcol - if sys.version_info < (3, 0): - assert cmp(fn1, fn2) == 0 # NOQA assert hash(fn1) == hash(fn2) fn3 = testdir.collect_by_name(modcol, "test_fail") diff --git a/testing/python/metafunc.py b/testing/python/metafunc.py index 945ab8627cb..95343112639 100644 --- a/testing/python/metafunc.py +++ b/testing/python/metafunc.py @@ -13,8 +13,6 @@ from _pytest import python from _pytest.warnings import SHOW_PYTEST_WARNINGS_ARG -PY3 = sys.version_info >= (3, 0) - class TestMetafunc(object): def Metafunc(self, func, config=None): diff --git a/testing/python/raises.py b/testing/python/raises.py index cd463d74b07..4970f9a56c3 100644 --- a/testing/python/raises.py +++ b/testing/python/raises.py @@ -1,8 +1,6 @@ # -*- coding: utf-8 -*- import sys -import six - import pytest from _pytest.outcomes import Failed from _pytest.warning_types import PytestDeprecationWarning @@ -265,16 +263,7 @@ class CrappyClass(Exception): def __class__(self): assert False, "via __class__" - if six.PY2: - with pytest.raises(pytest.fail.Exception) as excinfo: - with pytest.raises(CrappyClass()): - pass - assert "DID NOT RAISE" in excinfo.value.args[0] - - with pytest.raises(CrappyClass) as excinfo: - raise CrappyClass() - else: - with pytest.raises(AssertionError) as excinfo: - with pytest.raises(CrappyClass()): - pass - assert "via __class__" in excinfo.value.args[0] + with pytest.raises(AssertionError) as excinfo: + with pytest.raises(CrappyClass()): + pass + assert "via __class__" in excinfo.value.args[0] diff --git a/testing/test_argcomplete.py b/testing/test_argcomplete.py index da7758e8e9e..bd681b0e68a 100644 --- a/testing/test_argcomplete.py +++ b/testing/test_argcomplete.py @@ -30,19 +30,7 @@ def equal_with_bash(prefix, ffc, fc, out=None): def _wrapcall(*args, **kargs): try: - if sys.version_info > (2, 7): - return subprocess.check_output(*args, **kargs).decode().splitlines() - if "stdout" in kargs: - raise ValueError("stdout argument not allowed, it will be overridden.") - process = subprocess.Popen(stdout=subprocess.PIPE, *args, **kargs) - output, unused_err = process.communicate() - retcode = process.poll() - if retcode: - cmd = kargs.get("args") - if cmd is None: - cmd = args[0] - raise subprocess.CalledProcessError(retcode, cmd) - return output.decode().splitlines() + return subprocess.check_output(*args, **kargs).decode().splitlines() except subprocess.CalledProcessError: return [] diff --git a/testing/test_assertion.py b/testing/test_assertion.py index 2085ffd8b44..1fbf7b120d0 100644 --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -3,6 +3,7 @@ from __future__ import division from __future__ import print_function +import collections.abc as collections_abc import sys import textwrap @@ -15,8 +16,6 @@ from _pytest.assertion import truncate from _pytest.assertion import util -PY3 = sys.version_info >= (3, 0) - def mock_config(): class Config(object): @@ -372,14 +371,6 @@ def test_list(self): {0, 2}, """ Full diff: - - set([0, 1]) - ? ^ - + set([0, 2]) - ? ^ - """ - if not PY3 - else """ - Full diff: - {0, 1} ? ^ + {0, 2} @@ -483,10 +474,7 @@ def test_frozenzet(self): assert len(expl) > 1 def test_Sequence(self): - if sys.version_info >= (3, 3): - import collections.abc as collections_abc - else: - import collections as collections_abc + if not hasattr(collections_abc, "MutableSequence"): pytest.skip("cannot import MutableSequence") MutableSequence = collections_abc.MutableSequence @@ -589,10 +577,7 @@ def __repr__(self): return "\xff" expl = callequal(A(), "1") - if PY3: - assert expl == ["ÿ == '1'", "+ 1"] - else: - assert expl == [u"\ufffd == '1'", u"+ 1"] + assert expl == ["ÿ == '1'", "+ 1"] def test_format_nonascii_explanation(self): assert util.format_explanation("λ") @@ -1100,10 +1085,6 @@ def test_onefails(): ) -@pytest.mark.skipif( - sys.version_info[:2] <= (3, 3), - reason="Python 3.4+ shows chained exceptions on multiprocess", -) def test_exception_handling_no_traceback(testdir): """ Handle chain exceptions in tasks submitted by the multiprocess module (#1984). @@ -1137,9 +1118,7 @@ def test_multitask_job(): ) -@pytest.mark.skipif( - "'__pypy__' in sys.builtin_module_names or sys.platform.startswith('java')" -) +@pytest.mark.skipif("'__pypy__' in sys.builtin_module_names") def test_warn_missing(testdir): testdir.makepyfile("") result = testdir.run(sys.executable, "-OO", "-m", "pytest", "-h") @@ -1187,45 +1166,6 @@ def test_hello(): ) -@pytest.mark.skipif(PY3, reason="This bug does not exist on PY3") -def test_set_with_unsortable_elements(): - # issue #718 - class UnsortableKey(object): - def __init__(self, name): - self.name = name - - def __lt__(self, other): - raise RuntimeError() - - def __repr__(self): - return "repr({})".format(self.name) - - def __eq__(self, other): - return self.name == other.name - - def __hash__(self): - return hash(self.name) - - left_set = {UnsortableKey(str(i)) for i in range(1, 3)} - right_set = {UnsortableKey(str(i)) for i in range(2, 4)} - expl = callequal(left_set, right_set, verbose=True) - # skip first line because it contains the "construction" of the set, which does not have a guaranteed order - expl = expl[1:] - dedent = textwrap.dedent( - """ - Extra items in the left set: - repr(1) - Extra items in the right set: - repr(3) - Full diff (fallback to calling repr on each item): - - repr(1) - repr(2) - + repr(3) - """ - ).strip() - assert "\n".join(expl) == dedent - - def test_diff_newline_at_end(monkeypatch, testdir): testdir.makepyfile( r""" diff --git a/testing/test_assertrewrite.py b/testing/test_assertrewrite.py index 22f53ab9550..cc9de30719a 100644 --- a/testing/test_assertrewrite.py +++ b/testing/test_assertrewrite.py @@ -3,6 +3,7 @@ from __future__ import division from __future__ import print_function +import ast import glob import os import py_compile @@ -22,11 +23,6 @@ from _pytest.assertion.rewrite import rewrite_asserts from _pytest.main import EXIT_NOTESTSCOLLECTED -ast = pytest.importorskip("ast") -if sys.platform.startswith("java"): - # XXX should be xfail - pytest.skip("assert rewrite does currently not work on jython") - def setup_module(mod): mod._old_reprcompare = util._reprcompare @@ -166,18 +162,12 @@ class X(object): msg = getmsg(f, {"cls": X}).splitlines() if verbose > 0: - if six.PY2: - assert msg == [ - "assert == 42", - " -", - " +42", - ] - else: - assert msg == [ - "assert .X'> == 42", - " -.X'>", - " +42", - ] + + assert msg == [ + "assert .X'> == 42", + " -.X'>", + " +42", + ] else: assert msg == ["assert cls == 42"] @@ -277,9 +267,6 @@ def test_foo(): ["*AssertionError: To be escaped: %", "*assert 1 == 2"] ) - @pytest.mark.skipif( - sys.version_info < (3,), reason="bytes is a string type in python 2" - ) def test_assertion_messages_bytes(self, testdir): testdir.makepyfile("def test_bytes_assertion():\n assert False, b'ohai!'\n") result = testdir.runpytest() @@ -426,7 +413,6 @@ def f(): assert getmsg(f) == "assert (False or (4 % 2))" - @pytest.mark.skipif("sys.version_info < (3,5)") def test_at_operator_issue1290(self, testdir): testdir.makepyfile( """ @@ -441,7 +427,6 @@ def test_multmat_operator(): ) testdir.runpytest().assert_outcomes(passed=1) - @pytest.mark.skipif("sys.version_info < (3,5)") def test_starred_with_side_effect(self, testdir): """See #4412""" testdir.makepyfile( @@ -822,9 +807,6 @@ def test_no_bytecode(): assert testdir.runpytest_subprocess().ret == 0 def test_orphaned_pyc_file(self, testdir): - if sys.version_info < (3, 0) and hasattr(sys, "pypy_version_info"): - pytest.skip("pypy2 doesn't run orphaned pyc files") - testdir.makepyfile( """ import orphan @@ -890,10 +872,6 @@ def test_translate_newlines(self, testdir): testdir.tmpdir.join("test_newlines.py").write(b, "wb") assert testdir.runpytest().ret == 0 - @pytest.mark.skipif( - sys.version_info < (3, 4), - reason="packages without __init__.py not supported on python 2", - ) def test_package_without__init__py(self, testdir): pkg = testdir.mkdir("a_package_without_init_py") pkg.join("module.py").ensure() @@ -976,26 +954,6 @@ def test(): result.stdout.fnmatch_lines(["*= 1 passed in *=*"]) assert "pytest-warning summary" not in result.stdout.str() - @pytest.mark.skipif(sys.version_info[0] > 2, reason="python 2 only") - def test_rewrite_future_imports(self, testdir): - """Test that rewritten modules don't inherit the __future__ flags - from the assertrewrite module. - - assertion.rewrite imports __future__.division (and others), so - ensure rewritten modules don't inherit those flags. - - The test below will fail if __future__.division is enabled - """ - testdir.makepyfile( - """ - def test(): - x = 1 / 2 - assert type(x) is int - """ - ) - result = testdir.runpytest() - assert result.ret == 0 - class TestAssertionRewriteHookDetails(object): def test_loader_is_package_false_for_module(self, testdir): @@ -1025,48 +983,6 @@ def test_missing(): result = testdir.runpytest() result.stdout.fnmatch_lines(["* 3 passed*"]) - @pytest.mark.skipif("sys.version_info[0] >= 3") - @pytest.mark.xfail("hasattr(sys, 'pypy_translation_info')") - def test_assume_ascii(self, testdir): - content = "u'\xe2\x99\xa5\x01\xfe'" - testdir.tmpdir.join("test_encoding.py").write(content, "wb") - res = testdir.runpytest() - assert res.ret != 0 - assert "SyntaxError: Non-ASCII character" in res.stdout.str() - - @pytest.mark.skipif("sys.version_info[0] >= 3") - def test_detect_coding_cookie(self, testdir): - testdir.makepyfile( - test_cookie=""" - # -*- coding: utf-8 -*- - u"St\xc3\xa4d" - def test_rewritten(): - assert "@py_builtins" in globals()""" - ) - assert testdir.runpytest().ret == 0 - - @pytest.mark.skipif("sys.version_info[0] >= 3") - def test_detect_coding_cookie_second_line(self, testdir): - testdir.makepyfile( - test_cookie=""" - # -*- coding: utf-8 -*- - u"St\xc3\xa4d" - def test_rewritten(): - assert "@py_builtins" in globals()""" - ) - assert testdir.runpytest().ret == 0 - - @pytest.mark.skipif("sys.version_info[0] >= 3") - def test_detect_coding_cookie_crlf(self, testdir): - testdir.makepyfile( - test_cookie=""" - # -*- coding: utf-8 -*- - u"St\xc3\xa4d" - def test_rewritten(): - assert "@py_builtins" in globals()""" - ) - assert testdir.runpytest().ret == 0 - def test_sys_meta_path_munged(self, testdir): testdir.makepyfile( """ diff --git a/testing/test_capture.py b/testing/test_capture.py index 01123bf5b40..f101c0ec36f 100644 --- a/testing/test_capture.py +++ b/testing/test_capture.py @@ -13,12 +13,10 @@ from io import UnsupportedOperation import py -from six import text_type import pytest from _pytest import capture from _pytest.capture import CaptureManager -from _pytest.compat import _PY3 from _pytest.main import EXIT_NOTESTSCOLLECTED # note: py.io capture tests where copied from @@ -100,10 +98,7 @@ def test_init_capturing(self): def test_capturing_unicode(testdir, method): if hasattr(sys, "pypy_version_info") and sys.pypy_version_info < (2, 2): pytest.xfail("does not work on pypy < 2.2") - if sys.version_info >= (3, 0): - obj = "'b\u00f6y'" - else: - obj = "u'\u00f6y'" + obj = "'b\u00f6y'" testdir.makepyfile( """ # -*- coding: utf-8 -*- @@ -545,9 +540,6 @@ def test_hello(capfdbinary): ) reprec.assertoutcome(passed=1) - @pytest.mark.skipif( - sys.version_info < (3,), reason="only have capsysbinary in python 3" - ) def test_capsysbinary(self, testdir): reprec = testdir.inline_runsource( """\ @@ -562,25 +554,6 @@ def test_hello(capsysbinary): ) reprec.assertoutcome(passed=1) - @pytest.mark.skipif( - sys.version_info >= (3,), reason="only have capsysbinary in python 3" - ) - def test_capsysbinary_forbidden_in_python2(self, testdir): - testdir.makepyfile( - """\ - def test_hello(capsysbinary): - pass - """ - ) - result = testdir.runpytest() - result.stdout.fnmatch_lines( - [ - "*test_hello*", - "*capsysbinary is only supported on Python 3*", - "*1 error in*", - ] - ) - def test_partial_setup_failure(self, testdir): p = testdir.makepyfile( """\ @@ -843,17 +816,9 @@ def test_text(self): def test_unicode_and_str_mixture(self): f = capture.CaptureIO() - if sys.version_info >= (3, 0): - f.write("\u00f6") - pytest.raises(TypeError, f.write, b"hello") - else: - f.write(u"\u00f6") - f.write(b"hello") - s = f.getvalue() - f.close() - assert isinstance(s, text_type) + f.write("\u00f6") + pytest.raises(TypeError, f.write, b"hello") - @pytest.mark.skipif(sys.version_info[0] == 2, reason="python 3 only behaviour") def test_write_bytes_to_buffer(self): """In python3, stdout / stderr are text io wrappers (exposing a buffer property of the underlying bytestream). See issue #1407 @@ -876,7 +841,6 @@ def test_dontreadfrominput(): f.close() # just for completeness -@pytest.mark.skipif("sys.version_info < (3,)", reason="python2 has no buffer") def test_dontreadfrominput_buffer_python3(): from _pytest.capture import DontReadFromInput @@ -891,17 +855,7 @@ def test_dontreadfrominput_buffer_python3(): f.close() # just for completeness -@pytest.mark.skipif("sys.version_info >= (3,)", reason="python2 has no buffer") -def test_dontreadfrominput_buffer_python2(): - from _pytest.capture import DontReadFromInput - - f = DontReadFromInput() - with pytest.raises(AttributeError): - f.buffer - f.close() # just for completeness - - -@pytest.yield_fixture +@pytest.fixture def tmpfile(testdir): f = testdir.makepyfile("").open("wb+") yield f @@ -1118,16 +1072,6 @@ def test_capturing_readouterr_unicode(self): out, err = cap.readouterr() assert out == u"hxąć\n" - @pytest.mark.skipif( - "sys.version_info >= (3,)", reason="text output different for bytes on python3" - ) - def test_capturing_readouterr_decode_error_handling(self): - with self.getcapture() as cap: - # triggered an internal error in pytest - print("\xa6") - out, err = cap.readouterr() - assert out == u"\ufffd\n" - def test_reset_twice_error(self): with self.getcapture() as cap: print("hello") @@ -1571,9 +1515,6 @@ def test_fails(): assert result_with_capture.ret == result_without_capture.ret - if _PY3: - result_with_capture.stdout.fnmatch_lines( - ["E TypeError: write() argument must be str, not bytes"] - ) - else: - assert result_with_capture.ret == 0 + result_with_capture.stdout.fnmatch_lines( + ["E TypeError: write() argument must be str, not bytes"] + ) diff --git a/testing/test_collection.py b/testing/test_collection.py index 1cc8938666f..1a42e425f5e 100644 --- a/testing/test_collection.py +++ b/testing/test_collection.py @@ -38,8 +38,6 @@ def test_fail(): assert 0 assert fn1 == fn2 assert fn1 != modcol - if sys.version_info < (3, 0): - assert cmp(fn1, fn2) == 0 # NOQA assert hash(fn1) == hash(fn2) fn3 = testdir.collect_by_name(modcol, "test_fail") diff --git a/testing/test_compat.py b/testing/test_compat.py index b4298d1531d..f0ae07e058f 100644 --- a/testing/test_compat.py +++ b/testing/test_compat.py @@ -6,8 +6,6 @@ import sys from functools import wraps -import six - import pytest from _pytest.compat import _PytestWrapper from _pytest.compat import get_real_func @@ -62,8 +60,6 @@ def decorator(f): def inner(): pass # pragma: no cover - if six.PY2: - inner.__wrapped__ = f return inner def func(): @@ -81,9 +77,6 @@ def func(): assert get_real_func(wrapped_func2) is wrapped_func -@pytest.mark.skipif( - sys.version_info < (3, 4), reason="asyncio available in Python 3.4+" -) def test_is_generator_asyncio(testdir): testdir.makepyfile( """ diff --git a/testing/test_config.py b/testing/test_config.py index e588c262a9c..2cda7f40ba7 100644 --- a/testing/test_config.py +++ b/testing/test_config.py @@ -218,12 +218,9 @@ def pytest_addoption(parser): assert config.getoption(x) == "this" pytest.raises(ValueError, config.getoption, "qweqwe") - @pytest.mark.skipif("sys.version_info[0] < 3") def test_config_getoption_unicode(self, testdir): testdir.makeconftest( """ - from __future__ import unicode_literals - def pytest_addoption(parser): parser.addoption('--hello', type=str) """ diff --git a/testing/test_doctest.py b/testing/test_doctest.py index 25a35c3c136..57eda456db3 100644 --- a/testing/test_doctest.py +++ b/testing/test_doctest.py @@ -3,7 +3,6 @@ from __future__ import division from __future__ import print_function -import sys import textwrap import pytest @@ -830,13 +829,11 @@ def test_unicode_string(self, testdir): """ ) reprec = testdir.inline_run() - passed = int(sys.version_info[0] >= 3) - reprec.assertoutcome(passed=passed, failed=int(not passed)) + reprec.assertoutcome(passed=1) def test_bytes_literal(self, testdir): """Test that doctests which output bytes fail in Python 3 when - the ALLOW_BYTES option is not used. The same test should pass - in Python 2 (#1287). + the ALLOW_BYTES option is not used. (#1287). """ testdir.maketxtfile( test_doc=""" @@ -845,8 +842,7 @@ def test_bytes_literal(self, testdir): """ ) reprec = testdir.inline_run() - passed = int(sys.version_info[0] == 2) - reprec.assertoutcome(passed=passed, failed=int(not passed)) + reprec.assertoutcome(failed=1) class TestDoctestSkips(object): diff --git a/testing/test_junitxml.py b/testing/test_junitxml.py index 4c21c94d365..b87f1a9ec4b 100644 --- a/testing/test_junitxml.py +++ b/testing/test_junitxml.py @@ -4,7 +4,6 @@ from __future__ import print_function import os -import sys from xml.dom import minidom import py @@ -585,8 +584,7 @@ def test_hello(): assert result.ret == 1 tnode = dom.find_first_by_tag("testcase") fnode = tnode.find_first_by_tag("failure") - if not sys.platform.startswith("java"): - assert "hx" in fnode.toxml() + assert "hx" in fnode.toxml() def test_assertion_binchars(self, testdir): """this test did fail when the escaping wasnt strict""" diff --git a/testing/test_mark.py b/testing/test_mark.py index dd9d352309d..dc6e28a7d49 100644 --- a/testing/test_mark.py +++ b/testing/test_mark.py @@ -5,8 +5,7 @@ import os import sys - -import six +from unittest import mock import pytest from _pytest.main import EXIT_INTERRUPTED @@ -17,11 +16,6 @@ from _pytest.warning_types import PytestDeprecationWarning from _pytest.warnings import SHOW_PYTEST_WARNINGS_ARG -try: - import mock -except ImportError: - import unittest.mock as mock - ignore_markinfo = pytest.mark.filterwarnings( "ignore:MarkInfo objects:pytest.RemovedInPytest4Warning" ) @@ -1009,10 +1003,7 @@ def test_pytest_param_id_requires_string(): with pytest.raises(TypeError) as excinfo: pytest.param(id=True) msg, = excinfo.value.args - if six.PY2: - assert msg == "Expected id to be a string, got : True" - else: - assert msg == "Expected id to be a string, got : True" + assert msg == "Expected id to be a string, got : True" @pytest.mark.parametrize("s", (None, "hello world")) diff --git a/testing/test_monkeypatch.py b/testing/test_monkeypatch.py index 9b2f4550240..279b0c4a47d 100644 --- a/testing/test_monkeypatch.py +++ b/testing/test_monkeypatch.py @@ -8,8 +8,6 @@ import sys import textwrap -import six - import pytest from _pytest.monkeypatch import MonkeyPatch @@ -209,22 +207,6 @@ class TestEnvironWarnings(object): VAR_NAME = u"PYTEST_INTERNAL_MY_VAR" - @pytest.mark.skipif(six.PY3, reason="Python 2 only test") - def test_setenv_unicode_key(self, monkeypatch): - with pytest.warns( - pytest.PytestWarning, - match="Environment variable name {!r} should be str".format(self.VAR_NAME), - ): - monkeypatch.setenv(self.VAR_NAME, "2") - - @pytest.mark.skipif(six.PY3, reason="Python 2 only test") - def test_delenv_unicode_key(self, monkeypatch): - with pytest.warns( - pytest.PytestWarning, - match="Environment variable name {!r} should be str".format(self.VAR_NAME), - ): - monkeypatch.delenv(self.VAR_NAME, raising=False) - def test_setenv_non_str_warning(self, monkeypatch): value = 2 msg = ( @@ -349,10 +331,8 @@ def test_importerror(monkeypatch): result = testdir.runpytest() result.stdout.fnmatch_lines( """ - *import error in package.a: No module named {0}doesnotexist{0}* - """.format( - "'" if sys.version_info > (3, 0) else "" - ) + *import error in package.a: No module named 'doesnotexist'* + """ ) diff --git a/testing/test_pastebin.py b/testing/test_pastebin.py index 9491f6d9019..0d17ad73fa6 100644 --- a/testing/test_pastebin.py +++ b/testing/test_pastebin.py @@ -3,8 +3,6 @@ from __future__ import division from __future__ import print_function -import sys - import pytest @@ -74,10 +72,7 @@ def test(): """ ) result = testdir.runpytest("--pastebin=all") - if sys.version_info[0] == 3: - expected_msg = "*assert '☺' == 1*" - else: - expected_msg = "*assert '\\xe2\\x98\\xba' == 1*" + expected_msg = "*assert '☺' == 1*" result.stdout.fnmatch_lines( [ expected_msg, @@ -110,14 +105,9 @@ def read(self): return DummyFile() - if sys.version_info < (3, 0): - import urllib - - monkeypatch.setattr(urllib, "urlopen", mocked) - else: - import urllib.request + import urllib.request - monkeypatch.setattr(urllib.request, "urlopen", mocked) + monkeypatch.setattr(urllib.request, "urlopen", mocked) return calls def test_create_new_paste(self, pastebin, mocked_urlopen): @@ -126,7 +116,7 @@ def test_create_new_paste(self, pastebin, mocked_urlopen): assert len(mocked_urlopen) == 1 url, data = mocked_urlopen[0] assert type(data) is bytes - lexer = "python3" if sys.version_info[0] == 3 else "python" + lexer = "python3" assert url == "https://bpaste.net" assert "lexer=%s" % lexer in data.decode() assert "code=full-paste-contents" in data.decode() diff --git a/testing/test_pdb.py b/testing/test_pdb.py index d31d60469cd..8746548027f 100644 --- a/testing/test_pdb.py +++ b/testing/test_pdb.py @@ -6,8 +6,6 @@ import os import sys -import six - import _pytest._code import pytest from _pytest.debugging import _validate_usepdb_cls @@ -537,10 +535,7 @@ def do_debug(self, arg): import sys import types - if sys.version_info < (3, ): - do_debug_func = pdb.Pdb.do_debug.im_func - else: - do_debug_func = pdb.Pdb.do_debug + do_debug_func = pdb.Pdb.do_debug newglobals = do_debug_func.__globals__.copy() newglobals['Pdb'] = self.__class__ @@ -866,8 +861,6 @@ def test_supports_breakpoint_module_global(self): assert SUPPORTS_BREAKPOINT_BUILTIN is True if sys.version_info.major == 3 and sys.version_info.minor == 5: assert SUPPORTS_BREAKPOINT_BUILTIN is False - if sys.version_info.major == 2 and sys.version_info.minor == 7: - assert SUPPORTS_BREAKPOINT_BUILTIN is False @pytest.mark.skipif( not SUPPORTS_BREAKPOINT_BUILTIN, reason="Requires breakpoint() builtin" @@ -1183,24 +1176,17 @@ def runcall(self, *args, **kwds): def test_raises_bdbquit_with_eoferror(testdir): """It is not guaranteed that DontReadFromInput's read is called.""" - if six.PY2: - builtin_module = "__builtin__" - input_func = "raw_input" - else: - builtin_module = "builtins" - input_func = "input" + p1 = testdir.makepyfile( """ def input_without_read(*args, **kwargs): raise EOFError() def test(monkeypatch): - import {builtin_module} - monkeypatch.setattr({builtin_module}, {input_func!r}, input_without_read) + import builtins + monkeypatch.setattr(builtins, "input", input_without_read) __import__('pdb').set_trace() - """.format( - builtin_module=builtin_module, input_func=input_func - ) + """ ) result = testdir.runpytest(str(p1)) result.stdout.fnmatch_lines(["E *BdbQuit", "*= 1 failed in*"]) diff --git a/testing/test_runner.py b/testing/test_runner.py index 6906efb910c..5b37d12dbbe 100644 --- a/testing/test_runner.py +++ b/testing/test_runner.py @@ -654,10 +654,7 @@ def test_hello(): % str_prefix ) result = testdir.runpytest() - if sys.version_info[0] >= 3: - result.stdout.fnmatch_lines(["*test_hello*", "oh oh: ☺"]) - else: - result.stdout.fnmatch_lines(["*test_hello*", "oh oh: *"]) + result.stdout.fnmatch_lines(["*test_hello*", "oh oh: ☺"]) assert "def test_hello" not in result.stdout.str() diff --git a/testing/test_skipping.py b/testing/test_skipping.py index 55119ae1269..ce183171fc6 100644 --- a/testing/test_skipping.py +++ b/testing/test_skipping.py @@ -49,22 +49,6 @@ def test_func(): expl = ev.getexplanation() assert expl == "condition: hasattr(os, 'sep')" - @pytest.mark.skipif("sys.version_info[0] >= 3") - def test_marked_one_arg_unicode(self, testdir): - item = testdir.getitem( - """ - import pytest - @pytest.mark.xyz(u"hasattr(os, 'sep')") - def test_func(): - pass - """ - ) - ev = MarkEvaluator(item, "xyz") - assert ev - assert ev.istrue() - expl = ev.getexplanation() - assert expl == "condition: hasattr(os, 'sep')" - def test_marked_one_arg_with_reason(self, testdir): item = testdir.getitem( """ @@ -893,10 +877,7 @@ def test_func(): ) result = testdir.runpytest() markline = " ^" - if sys.platform.startswith("java"): - # XXX report this to java - markline = "*" + markline[8:] - elif hasattr(sys, "pypy_version_info") and sys.pypy_version_info < (6,): + if hasattr(sys, "pypy_version_info") and sys.pypy_version_info < (6,): markline = markline[5:] elif sys.version_info >= (3, 8) or hasattr(sys, "pypy_version_info"): markline = markline[4:] diff --git a/testing/test_tmpdir.py b/testing/test_tmpdir.py index 40ffe98af98..14e5bcbcae4 100644 --- a/testing/test_tmpdir.py +++ b/testing/test_tmpdir.py @@ -6,7 +6,6 @@ import sys import attr -import six import pytest from _pytest import pathlib @@ -348,8 +347,6 @@ def test_removal_accepts_lock(self, tmp_path): def attempt_symlink_to(path, to_path): """Try to make a symlink from "path" to "to_path", skipping in case this platform does not support it or we don't have sufficient privileges (common on Windows).""" - if sys.platform.startswith("win") and six.PY2: - pytest.skip("pathlib for some reason cannot make symlinks on Python 2") try: Path(path).symlink_to(Path(to_path)) except OSError: diff --git a/testing/test_unittest.py b/testing/test_unittest.py index bb41952abbe..f310cd8cc67 100644 --- a/testing/test_unittest.py +++ b/testing/test_unittest.py @@ -459,9 +459,6 @@ def test_method(self): pass """ ) - from _pytest.compat import _is_unittest_unexpected_success_a_failure - - should_fail = _is_unittest_unexpected_success_a_failure() result = testdir.runpytest("-rxs", *self.ignore_unclosed_socket_warning) result.stdout.fnmatch_lines_random( [ @@ -472,12 +469,10 @@ def test_method(self): "*i2wanto*", "*sys.version_info*", "*skip_in_method*", - "*1 failed*4 skipped*3 xfailed*" - if should_fail - else "*4 skipped*3 xfail*1 xpass*", + "*1 failed*4 skipped*3 xfailed*", ] ) - assert result.ret == (1 if should_fail else 0) + assert result.ret == 1 def test_trial_error(self, testdir): testdir.makepyfile( @@ -745,22 +740,17 @@ def test_passing_test_is_fail(self): unittest.main() """ ) - from _pytest.compat import _is_unittest_unexpected_success_a_failure - should_fail = _is_unittest_unexpected_success_a_failure() if runner == "pytest": result = testdir.runpytest("-rxX") result.stdout.fnmatch_lines( - [ - "*MyTestCase*test_passing_test_is_fail*", - "*1 failed*" if should_fail else "*1 xpassed*", - ] + ["*MyTestCase*test_passing_test_is_fail*", "*1 failed*"] ) else: result = testdir.runpython(script) result.stderr.fnmatch_lines(["*1 test in*", "*(unexpected successes=1)*"]) - assert result.ret == (1 if should_fail else 0) + assert result.ret == 1 @pytest.mark.parametrize( diff --git a/testing/test_warnings.py b/testing/test_warnings.py index 092604d7db0..4a5ebac7d01 100644 --- a/testing/test_warnings.py +++ b/testing/test_warnings.py @@ -1,11 +1,8 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -import sys import warnings -import six - import pytest WARNINGS_SUMMARY_HEADER = "warnings summary" @@ -126,9 +123,6 @@ def test_ignore(testdir, pyfile_with_warnings, method): assert WARNINGS_SUMMARY_HEADER not in result.stdout.str() -@pytest.mark.skipif( - sys.version_info < (3, 0), reason="warnings message is unicode is ok in python3" -) @pytest.mark.filterwarnings("always") def test_unicode(testdir, pyfile_with_warnings): testdir.makepyfile( @@ -157,68 +151,6 @@ def test_func(fix): ) -@pytest.mark.skipif( - sys.version_info >= (3, 0), - reason="warnings message is broken as it is not str instance", -) -def test_py2_unicode(testdir, pyfile_with_warnings): - if getattr(sys, "pypy_version_info", ())[:2] == (5, 9) and sys.platform.startswith( - "win" - ): - pytest.xfail("fails with unicode error on PyPy2 5.9 and Windows (#2905)") - testdir.makepyfile( - """ - # -*- coding: utf-8 -*- - import warnings - import pytest - - - @pytest.fixture - def fix(): - warnings.warn(u"测试") - yield - - @pytest.mark.filterwarnings('always') - def test_func(fix): - pass - """ - ) - result = testdir.runpytest() - result.stdout.fnmatch_lines( - [ - "*== %s ==*" % WARNINGS_SUMMARY_HEADER, - "*test_py2_unicode.py:8: UserWarning: \\u6d4b\\u8bd5", - '*warnings.warn(u"\u6d4b\u8bd5")', - "*warnings.py:*: UnicodeWarning: Warning is using unicode non*", - "* 1 passed, 2 warnings*", - ] - ) - - -def test_py2_unicode_ascii(testdir): - """Ensure that our warning about 'unicode warnings containing non-ascii messages' - does not trigger with ascii-convertible messages""" - testdir.makeini("[pytest]") - testdir.makepyfile( - """ - import pytest - import warnings - - @pytest.mark.filterwarnings('always') - def test_func(): - warnings.warn(u"hello") - """ - ) - result = testdir.runpytest() - result.stdout.fnmatch_lines( - [ - "*== %s ==*" % WARNINGS_SUMMARY_HEADER, - '*warnings.warn(u"hello")', - "* 1 passed, 1 warnings in*", - ] - ) - - def test_works_with_filterwarnings(testdir): """Ensure our warnings capture does not mess with pre-installed filters (#2430).""" testdir.makepyfile( @@ -569,33 +501,6 @@ def test_hidden_by_system(self, testdir, monkeypatch): assert WARNINGS_SUMMARY_HEADER not in result.stdout.str() -@pytest.mark.skipif(six.PY3, reason="Python 2 only issue") -def test_infinite_loop_warning_against_unicode_usage_py2(testdir): - """ - We need to be careful when raising the warning about unicode usage with "warnings.warn" - because it might be overwritten by users and this itself causes another warning (#3691). - """ - testdir.makepyfile( - """ - # -*- coding: utf-8 -*- - from __future__ import unicode_literals - import warnings - import pytest - - def _custom_showwarning(message, *a, **b): - return "WARNING: {}".format(message) - - warnings.formatwarning = _custom_showwarning - - @pytest.mark.filterwarnings("default") - def test_custom_warning_formatter(): - warnings.warn("¥") - """ - ) - result = testdir.runpytest_subprocess() - result.stdout.fnmatch_lines(["*1 passed, * warnings in*"]) - - @pytest.mark.parametrize("change_default", [None, "ini", "cmdline"]) def test_removed_in_pytest4_warning_as_error(testdir, change_default): testdir.makepyfile( diff --git a/tox.ini b/tox.ini index 0b1be0d33fe..7e5b182f69b 100644 --- a/tox.ini +++ b/tox.ini @@ -5,16 +5,13 @@ distshare = {homedir}/.tox/distshare # make sure to update environment list in travis.yml and appveyor.yml envlist = linting - py27 - py34 py35 py36 py37 py38 pypy pypy3 - {py27,py37}-{pexpect,xdist,twisted,numpy,pluggymaster} - py27-nobyte-xdist + py37-{pexpect,xdist,twisted,numpy,pluggymaster} doctesting py37-freeze docs @@ -56,15 +53,6 @@ deps = {env:_PYTEST_TOX_EXTRA_DEP:} platform = {env:_PYTEST_TOX_PLATFORM:.*} -[testenv:py27-subprocess] -deps = - pytest-xdist>=1.13 - py27: mock - nose -commands = - pytest -n auto --runpytest=subprocess {posargs} - - [testenv:linting] skip_install = True basepython = python3 @@ -109,11 +97,6 @@ commands = rm -rf {envdir}/.pytest_cache make regen -[testenv:jython] -changedir = testing -commands = - {envpython} {envbindir}/py.test-jython {posargs} - [testenv:py37-freeze] changedir = testing/freeze # Disable PEP 517 with pip, which does not work with PyInstaller currently. From a6dc283133c6ee3a3fdedacf5d363d72b58ffa88 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Sun, 2 Jun 2019 20:19:34 +0200 Subject: [PATCH 06/23] Revert "ci: Travis: add pypy3 to allowed failures temporarily" This reverts commit 5ac498ea9634729d3281d67a8cd27d20a34cf684. The idea is that maybe https://github.com/pytest-dev/pytest/pull/5360 fixes the failures here also. --- .travis.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9914800f808..4b3736793b3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -112,9 +112,6 @@ matrix: allow_failures: - python: '3.8-dev' env: TOXENV=py38-xdist - # Temporary (https://github.com/pytest-dev/pytest/pull/5334). - - env: TOXENV=pypy3-xdist - python: 'pypy3' before_script: - | From 642ef6dc1b6f85406dc06ebb84958b2b6cd18bcf Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sun, 2 Jun 2019 11:47:26 -0700 Subject: [PATCH 07/23] Merge pull request #5362 from asottile/release-4.6.1 Preparing release version 4.6.1 --- CHANGELOG.rst | 12 ++++++++++++ doc/en/announce/index.rst | 1 + doc/en/announce/release-4.6.1.rst | 19 +++++++++++++++++++ doc/en/example/simple.rst | 2 +- 4 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 doc/en/announce/release-4.6.1.rst diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 32267f4dd42..a2bf12d7ea2 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -18,6 +18,18 @@ with advance notice in the **Deprecations** section of releases. .. towncrier release notes start +pytest 4.6.1 (2019-06-02) +========================= + +Bug Fixes +--------- + +- `#5354 `_: Fix ``pytest.mark.parametrize`` when the argvalues is an iterator. + + +- `#5358 `_: Fix assertion rewriting of ``all()`` calls to deal with non-generators. + + pytest 4.6.0 (2019-05-31) ========================= diff --git a/doc/en/announce/index.rst b/doc/en/announce/index.rst index fa53441ce59..2c05e2e59cb 100644 --- a/doc/en/announce/index.rst +++ b/doc/en/announce/index.rst @@ -6,6 +6,7 @@ Release announcements :maxdepth: 2 + release-4.6.1 release-4.6.0 release-4.5.0 release-4.4.2 diff --git a/doc/en/announce/release-4.6.1.rst b/doc/en/announce/release-4.6.1.rst new file mode 100644 index 00000000000..78d017544d2 --- /dev/null +++ b/doc/en/announce/release-4.6.1.rst @@ -0,0 +1,19 @@ +pytest-4.6.1 +======================================= + +pytest 4.6.1 has just been released to PyPI. + +This is a bug-fix release, being a drop-in replacement. To upgrade:: + + pip install --upgrade pytest + +The full changelog is available at https://docs.pytest.org/en/latest/changelog.html. + +Thanks to all who contributed to this release, among them: + +* Anthony Sottile +* Bruno Oliveira + + +Happy testing, +The pytest Development Team diff --git a/doc/en/example/simple.rst b/doc/en/example/simple.rst index 140f4b840f1..cf8298ddc2a 100644 --- a/doc/en/example/simple.rst +++ b/doc/en/example/simple.rst @@ -441,7 +441,7 @@ Now we can profile which test functions execute the slowest: ========================= slowest 3 test durations ========================= 0.30s call test_some_are_slow.py::test_funcslow2 - 0.20s call test_some_are_slow.py::test_funcslow1 + 0.21s call test_some_are_slow.py::test_funcslow1 0.10s call test_some_are_slow.py::test_funcfast ========================= 3 passed in 0.12 seconds ========================= From 25e728c78bbcf1dae618e7e1f6f4aa43d051cd47 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sun, 2 Jun 2019 10:06:41 -0700 Subject: [PATCH 08/23] Update release instructions for 4.6-maintenance --- HOWTORELEASE.rst | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/HOWTORELEASE.rst b/HOWTORELEASE.rst index b37a245c0be..d0704b17279 100644 --- a/HOWTORELEASE.rst +++ b/HOWTORELEASE.rst @@ -12,6 +12,8 @@ taking a lot of time to make a new one. #. Create a branch ``release-X.Y.Z`` with the version for the release. + * **maintenance releases**: from ``4.6-maintenance``; + * **patch releases**: from the latest ``master``; * **minor releases**: from the latest ``features``; then merge with the latest ``master``; @@ -24,7 +26,8 @@ taking a lot of time to make a new one. This will generate a commit with all the changes ready for pushing. -#. Open a PR for this branch targeting ``master``. +#. Open a PR for this branch targeting ``master`` (or ``4.6-maintenance`` for + maintenance releases). #. After all tests pass and the PR has been approved, publish to PyPI by pushing the tag:: @@ -33,7 +36,16 @@ taking a lot of time to make a new one. Wait for the deploy to complete, then make sure it is `available on PyPI `_. -#. Merge the PR into ``master``. +#. Merge the PR. + +#. If this is a maintenance release, cherry-pick the CHANGELOG / announce + files to the ``master`` branch:: + + git fetch --all --prune + git checkout origin/master -b cherry-pick-maintenance-release + git cherry-pick --no-commit -m1 origin/4.6-maintenance + git checkout origin/master -- changelog + git commit # no arguments #. Send an email announcement with the contents from:: From 5c016d10217cad03792b3756d6a0aaee4016feeb Mon Sep 17 00:00:00 2001 From: Yuri Apollov Date: Sun, 2 Jun 2019 23:55:28 +0300 Subject: [PATCH 09/23] Fix typo about interpreters count in doc/en/example/parametrize.html --- doc/en/example/parametrize.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/en/example/parametrize.rst b/doc/en/example/parametrize.rst index ef792afe7b6..d324fc106cb 100644 --- a/doc/en/example/parametrize.rst +++ b/doc/en/example/parametrize.rst @@ -429,7 +429,7 @@ is to be run with different sets of arguments for its three arguments: .. literalinclude:: multipython.py -Running it results in some skips if we don't have all the python interpreters installed and otherwise runs all combinations (5 interpreters times 5 interpreters times 3 objects to serialize/deserialize): +Running it results in some skips if we don't have all the python interpreters installed and otherwise runs all combinations (3 interpreters times 3 interpreters times 3 objects to serialize/deserialize): .. code-block:: pytest From 59997827684c58c90b8169184ef450f4ff29ade5 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Sun, 2 Jun 2019 19:20:00 -0300 Subject: [PATCH 10/23] Use python 3 interpreters in example --- doc/en/example/multipython.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/en/example/multipython.py b/doc/en/example/multipython.py index dc722aac91d..89caab15429 100644 --- a/doc/en/example/multipython.py +++ b/doc/en/example/multipython.py @@ -9,7 +9,7 @@ import pytest -pythonlist = ["python2.7", "python3.4", "python3.5"] +pythonlist = ["python3.5", "python3.6", "python3.7"] @pytest.fixture(params=pythonlist) From ef053193b5f726c20a875b0bbc9a3d46e7c03a60 Mon Sep 17 00:00:00 2001 From: Thomas Hisch Date: Wed, 29 May 2019 23:15:34 +0200 Subject: [PATCH 11/23] logging: Extend LEVELNAME_FMT_REGEX --- changelog/5335.bugfix.rst | 2 ++ src/_pytest/logging.py | 2 +- testing/logging/test_formatter.py | 25 +++++++++++++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 changelog/5335.bugfix.rst diff --git a/changelog/5335.bugfix.rst b/changelog/5335.bugfix.rst new file mode 100644 index 00000000000..0a2e99dc9f1 --- /dev/null +++ b/changelog/5335.bugfix.rst @@ -0,0 +1,2 @@ +Colorize level names when the level in the logging format is formatted using +'%(levelname).Xs' (truncated fixed width alignment), where X is an integer. diff --git a/src/_pytest/logging.py b/src/_pytest/logging.py index a5f41173a20..ee143cb4167 100644 --- a/src/_pytest/logging.py +++ b/src/_pytest/logging.py @@ -39,7 +39,7 @@ class ColoredLevelFormatter(logging.Formatter): logging.DEBUG: {"purple"}, logging.NOTSET: set(), } - LEVELNAME_FMT_REGEX = re.compile(r"%\(levelname\)([+-]?\d*s)") + LEVELNAME_FMT_REGEX = re.compile(r"%\(levelname\)([+-.]?\d*s)") def __init__(self, terminalwriter, *args, **kwargs): super(ColoredLevelFormatter, self).__init__(*args, **kwargs) diff --git a/testing/logging/test_formatter.py b/testing/logging/test_formatter.py index c851c34d784..7a63ab47ea7 100644 --- a/testing/logging/test_formatter.py +++ b/testing/logging/test_formatter.py @@ -65,3 +65,28 @@ def test_multiline_message(): "dummypath 10 INFO Test Message line1\n" " line2" ) + + +def test_colored_short_level(): + logfmt = "%(levelname).1s %(message)s" + + record = logging.LogRecord( + name="dummy", + level=logging.INFO, + pathname="dummypath", + lineno=10, + msg="Test Message", + args=(), + exc_info=False, + ) + + class ColorConfig(object): + class option(object): + pass + + tw = py.io.TerminalWriter() + tw.hasmarkup = True + formatter = ColoredLevelFormatter(tw, logfmt) + output = formatter.format(record) + # the I (of INFO) is colored + assert output == ("\x1b[32mI\x1b[0m Test Message") From 99057555e1859a6ad68d25d734b4d7e1063cc413 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sun, 2 Jun 2019 15:29:39 -0700 Subject: [PATCH 12/23] manual changes to .pre-commit-config.yaml --- .pre-commit-config.yaml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 34895e1a30f..12fa0d343f1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,17 +7,18 @@ repos: args: [--safe, --quiet] language_version: python3 - repo: https://github.com/asottile/blacken-docs - rev: v0.5.0 + rev: v1.0.0 hooks: - id: blacken-docs additional_dependencies: [black==19.3b0] language_version: python3 - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v2.2.2 + rev: v2.2.3 hooks: - id: trailing-whitespace - id: end-of-file-fixer - id: fix-encoding-pragma + args: [--remove] - id: check-yaml - id: debug-statements exclude: _pytest/debugging.py @@ -31,14 +32,14 @@ repos: rev: v1.4.0 hooks: - id: reorder-python-imports - args: ['--application-directories=.:src'] + args: ['--application-directories=.:src', --py3-plus] - repo: https://github.com/asottile/pyupgrade - rev: v1.15.0 + rev: v1.18.0 hooks: - id: pyupgrade - args: [--keep-percent-format] + args: [--py3-plus] - repo: https://github.com/pre-commit/pygrep-hooks - rev: v1.3.0 + rev: v1.4.0 hooks: - id: rst-backticks - repo: local From 5034399d7acc4bd14fdad3d056a9abc2fde13863 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sun, 2 Jun 2019 15:30:53 -0700 Subject: [PATCH 13/23] pre-commit run fix-encoding-pragma --all-files --- bench/bench.py | 1 - bench/bench_argcomplete.py | 1 - bench/empty.py | 1 - bench/manyparam.py | 1 - bench/skip.py | 1 - doc/en/_themes/flask_theme_support.py | 1 - doc/en/conf.py | 1 - doc/en/conftest.py | 1 - doc/en/example/assertion/failure_demo.py | 1 - doc/en/example/assertion/global_testmodule_config/conftest.py | 1 - .../assertion/global_testmodule_config/test_hello_world.py | 1 - doc/en/example/assertion/test_failures.py | 1 - doc/en/example/assertion/test_setup_flow_example.py | 1 - doc/en/example/conftest.py | 1 - doc/en/example/costlysetup/conftest.py | 1 - doc/en/example/costlysetup/sub_a/__init__.py | 1 - doc/en/example/costlysetup/sub_a/test_quick.py | 1 - doc/en/example/costlysetup/sub_b/__init__.py | 1 - doc/en/example/costlysetup/sub_b/test_two.py | 1 - doc/en/example/multipython.py | 1 - doc/en/example/nonpython/conftest.py | 1 - doc/en/example/py2py3/conftest.py | 1 - doc/en/example/py2py3/test_py3.py | 1 - doc/en/example/pythoncollection.py | 1 - doc/en/example/xfail_demo.py | 1 - extra/get_issues.py | 1 - extra/setup-py.test/setup.py | 1 - scripts/release.py | 1 - setup.py | 1 - src/_pytest/__init__.py | 1 - src/_pytest/_argcomplete.py | 1 - src/_pytest/_code/__init__.py | 1 - src/_pytest/_code/_py2traceback.py | 1 - src/_pytest/_code/code.py | 1 - src/_pytest/_code/source.py | 1 - src/_pytest/_io/saferepr.py | 1 - src/_pytest/assertion/__init__.py | 1 - src/_pytest/assertion/rewrite.py | 1 - src/_pytest/assertion/truncate.py | 1 - src/_pytest/assertion/util.py | 1 - src/_pytest/cacheprovider.py | 1 - src/_pytest/capture.py | 1 - src/_pytest/compat.py | 1 - src/_pytest/config/__init__.py | 1 - src/_pytest/config/argparsing.py | 1 - src/_pytest/config/exceptions.py | 1 - src/_pytest/config/findpaths.py | 1 - src/_pytest/debugging.py | 1 - src/_pytest/deprecated.py | 1 - src/_pytest/doctest.py | 1 - src/_pytest/fixtures.py | 1 - src/_pytest/freeze_support.py | 1 - src/_pytest/helpconfig.py | 1 - src/_pytest/hookspec.py | 1 - src/_pytest/junitxml.py | 1 - src/_pytest/logging.py | 1 - src/_pytest/main.py | 1 - src/_pytest/mark/__init__.py | 1 - src/_pytest/mark/evaluate.py | 1 - src/_pytest/mark/legacy.py | 1 - src/_pytest/mark/structures.py | 1 - src/_pytest/monkeypatch.py | 1 - src/_pytest/nodes.py | 1 - src/_pytest/nose.py | 1 - src/_pytest/outcomes.py | 1 - src/_pytest/pastebin.py | 1 - src/_pytest/pathlib.py | 1 - src/_pytest/pytester.py | 1 - src/_pytest/python.py | 1 - src/_pytest/python_api.py | 1 - src/_pytest/recwarn.py | 1 - src/_pytest/reports.py | 1 - src/_pytest/resultlog.py | 1 - src/_pytest/runner.py | 1 - src/_pytest/setuponly.py | 1 - src/_pytest/setupplan.py | 1 - src/_pytest/skipping.py | 1 - src/_pytest/stepwise.py | 1 - src/_pytest/terminal.py | 1 - src/_pytest/tmpdir.py | 1 - src/_pytest/unittest.py | 1 - src/_pytest/warning_types.py | 1 - src/_pytest/warnings.py | 1 - src/pytest.py | 1 - testing/acceptance_test.py | 1 - testing/code/test_code.py | 1 - testing/code/test_excinfo.py | 1 - testing/code/test_source.py | 1 - testing/conftest.py | 1 - testing/deprecated_test.py | 1 - testing/example_scripts/acceptance/fixture_mock_integration.py | 1 - .../example_scripts/collect/collect_init_tests/tests/__init__.py | 1 - .../example_scripts/collect/collect_init_tests/tests/test_foo.py | 1 - .../collect/package_infinite_recursion/conftest.py | 1 - .../collect/package_infinite_recursion/tests/test_basic.py | 1 - .../collect/package_init_given_as_arg/pkg/test_foo.py | 1 - testing/example_scripts/config/collect_pytest_prefix/conftest.py | 1 - testing/example_scripts/config/collect_pytest_prefix/test_foo.py | 1 - testing/example_scripts/conftest_usageerror/conftest.py | 1 - testing/example_scripts/dataclasses/test_compare_dataclasses.py | 1 - .../dataclasses/test_compare_dataclasses_field_comparison_off.py | 1 - .../dataclasses/test_compare_dataclasses_verbose.py | 1 - .../dataclasses/test_compare_two_different_dataclasses.py | 1 - testing/example_scripts/deprecated/test_fixture_named_request.py | 1 - testing/example_scripts/fixtures/custom_item/conftest.py | 1 - testing/example_scripts/fixtures/custom_item/foo/test_foo.py | 1 - .../sub1/conftest.py | 1 - .../sub1/test_in_sub1.py | 1 - .../sub2/conftest.py | 1 - .../sub2/test_in_sub2.py | 1 - .../fill_fixtures/test_detect_recursive_dependency_error.py | 1 - .../test_extend_fixture_conftest_conftest/conftest.py | 1 - .../test_extend_fixture_conftest_conftest/pkg/conftest.py | 1 - .../test_extend_fixture_conftest_conftest/pkg/test_spam.py | 1 - .../test_extend_fixture_conftest_module/conftest.py | 1 - .../test_extend_fixture_conftest_module.py | 1 - .../fixtures/fill_fixtures/test_extend_fixture_module_class.py | 1 - .../example_scripts/fixtures/fill_fixtures/test_funcarg_basic.py | 1 - .../fixtures/fill_fixtures/test_funcarg_lookup_classlevel.py | 1 - .../fixtures/fill_fixtures/test_funcarg_lookup_modulelevel.py | 1 - .../fixtures/fill_fixtures/test_funcarg_lookupfails.py | 1 - testing/example_scripts/fixtures/test_getfixturevalue_dynamic.py | 1 - .../example_scripts/issue88_initial_file_multinodes/conftest.py | 1 - .../issue88_initial_file_multinodes/test_hello.py | 1 - testing/example_scripts/issue_519.py | 1 - .../marks/marks_considered_keywords/test_marks_as_keywords.py | 1 - .../perf_examples/collect_stats/generate_folders.py | 1 - .../example_scripts/perf_examples/collect_stats/template_test.py | 1 - testing/example_scripts/tmpdir/tmpdir_fixture.py | 1 - .../unittest/test_parametrized_fixture_error_message.py | 1 - testing/example_scripts/unittest/test_setup_skip.py | 1 - testing/example_scripts/unittest/test_setup_skip_class.py | 1 - testing/example_scripts/unittest/test_setup_skip_module.py | 1 - .../example_scripts/warnings/test_group_warnings_by_message.py | 1 - testing/examples/test_issue519.py | 1 - testing/freeze/create_executable.py | 1 - testing/freeze/runtests_script.py | 1 - testing/freeze/tests/test_trivial.py | 1 - testing/freeze/tox_run.py | 1 - testing/io/test_saferepr.py | 1 - testing/logging/test_fixture.py | 1 - testing/logging/test_formatter.py | 1 - testing/logging/test_reporting.py | 1 - testing/python/approx.py | 1 - testing/python/collect.py | 1 - testing/python/fixtures.py | 1 - testing/python/integration.py | 1 - testing/python/metafunc.py | 1 - testing/python/raises.py | 1 - testing/python/setup_only.py | 1 - testing/python/setup_plan.py | 1 - testing/python/show_fixtures_per_test.py | 1 - testing/test_argcomplete.py | 1 - testing/test_assertion.py | 1 - testing/test_assertrewrite.py | 1 - testing/test_cacheprovider.py | 1 - testing/test_capture.py | 1 - testing/test_collection.py | 1 - testing/test_compat.py | 1 - testing/test_config.py | 1 - testing/test_conftest.py | 1 - testing/test_doctest.py | 1 - testing/test_entry_points.py | 1 - testing/test_helpconfig.py | 1 - testing/test_junitxml.py | 1 - testing/test_mark.py | 1 - testing/test_modimport.py | 1 - testing/test_monkeypatch.py | 1 - testing/test_nodes.py | 1 - testing/test_nose.py | 1 - testing/test_parseopt.py | 1 - testing/test_pastebin.py | 1 - testing/test_pathlib.py | 1 - testing/test_pdb.py | 1 - testing/test_pluginmanager.py | 1 - testing/test_pytester.py | 1 - testing/test_recwarn.py | 1 - testing/test_reports.py | 1 - testing/test_resultlog.py | 1 - testing/test_runner.py | 1 - testing/test_runner_xunit.py | 1 - testing/test_session.py | 1 - testing/test_skipping.py | 1 - testing/test_stepwise.py | 1 - testing/test_terminal.py | 1 - testing/test_tmpdir.py | 1 - testing/test_unittest.py | 1 - testing/test_warnings.py | 1 - 188 files changed, 188 deletions(-) diff --git a/bench/bench.py b/bench/bench.py index 468ef521957..31cc7ac137c 100644 --- a/bench/bench.py +++ b/bench/bench.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import sys if __name__ == "__main__": diff --git a/bench/bench_argcomplete.py b/bench/bench_argcomplete.py index 297637bad0d..335733df72b 100644 --- a/bench/bench_argcomplete.py +++ b/bench/bench_argcomplete.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # 10000 iterations, just for relative comparison # 2.7.5 3.3.2 # FilesCompleter 75.1109 69.2116 diff --git a/bench/empty.py b/bench/empty.py index bfda88235de..4e7371b6f80 100644 --- a/bench/empty.py +++ b/bench/empty.py @@ -1,3 +1,2 @@ -# -*- coding: utf-8 -*- for i in range(1000): exec("def test_func_%d(): pass" % i) diff --git a/bench/manyparam.py b/bench/manyparam.py index c47e25f5182..1226c73bd9c 100644 --- a/bench/manyparam.py +++ b/bench/manyparam.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import pytest diff --git a/bench/skip.py b/bench/skip.py index 29e03e54fc6..2fc8240e565 100644 --- a/bench/skip.py +++ b/bench/skip.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from six.moves import range import pytest diff --git a/doc/en/_themes/flask_theme_support.py b/doc/en/_themes/flask_theme_support.py index c5dcdbe2737..b107f2c892e 100644 --- a/doc/en/_themes/flask_theme_support.py +++ b/doc/en/_themes/flask_theme_support.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # flasky extensions. flasky pygments style based on tango style from pygments.style import Style from pygments.token import Comment diff --git a/doc/en/conf.py b/doc/en/conf.py index 5daa15a069e..5704b03e291 100644 --- a/doc/en/conf.py +++ b/doc/en/conf.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # # pytest documentation build configuration file, created by # sphinx-quickstart on Fri Oct 8 17:54:28 2010. diff --git a/doc/en/conftest.py b/doc/en/conftest.py index b51aae5b685..1a62e1b5df5 100644 --- a/doc/en/conftest.py +++ b/doc/en/conftest.py @@ -1,2 +1 @@ -# -*- coding: utf-8 -*- collect_ignore = ["conf.py"] diff --git a/doc/en/example/assertion/failure_demo.py b/doc/en/example/assertion/failure_demo.py index ba910ef6a88..5d36fa65924 100644 --- a/doc/en/example/assertion/failure_demo.py +++ b/doc/en/example/assertion/failure_demo.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import _pytest._code import pytest from pytest import raises diff --git a/doc/en/example/assertion/global_testmodule_config/conftest.py b/doc/en/example/assertion/global_testmodule_config/conftest.py index 8e04ac2ac46..da89047fe09 100644 --- a/doc/en/example/assertion/global_testmodule_config/conftest.py +++ b/doc/en/example/assertion/global_testmodule_config/conftest.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import py import pytest diff --git a/doc/en/example/assertion/global_testmodule_config/test_hello_world.py b/doc/en/example/assertion/global_testmodule_config/test_hello_world.py index bfccc94f712..a31a601a1ce 100644 --- a/doc/en/example/assertion/global_testmodule_config/test_hello_world.py +++ b/doc/en/example/assertion/global_testmodule_config/test_hello_world.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- hello = "world" diff --git a/doc/en/example/assertion/test_failures.py b/doc/en/example/assertion/test_failures.py index 60b5e213118..30ebc72dc37 100644 --- a/doc/en/example/assertion/test_failures.py +++ b/doc/en/example/assertion/test_failures.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import py failure_demo = py.path.local(__file__).dirpath("failure_demo.py") diff --git a/doc/en/example/assertion/test_setup_flow_example.py b/doc/en/example/assertion/test_setup_flow_example.py index f49d6d8ed31..eb339f47418 100644 --- a/doc/en/example/assertion/test_setup_flow_example.py +++ b/doc/en/example/assertion/test_setup_flow_example.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- def setup_module(module): module.TestStateFullThing.classcount = 0 diff --git a/doc/en/example/conftest.py b/doc/en/example/conftest.py index 1f5a961ada0..f905738c4f6 100644 --- a/doc/en/example/conftest.py +++ b/doc/en/example/conftest.py @@ -1,2 +1 @@ -# -*- coding: utf-8 -*- collect_ignore = ["nonpython"] diff --git a/doc/en/example/costlysetup/conftest.py b/doc/en/example/costlysetup/conftest.py index b90c774733b..57b08b5fa94 100644 --- a/doc/en/example/costlysetup/conftest.py +++ b/doc/en/example/costlysetup/conftest.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import pytest diff --git a/doc/en/example/costlysetup/sub_a/__init__.py b/doc/en/example/costlysetup/sub_a/__init__.py index ec51c5a2b9d..792d6005489 100644 --- a/doc/en/example/costlysetup/sub_a/__init__.py +++ b/doc/en/example/costlysetup/sub_a/__init__.py @@ -1,2 +1 @@ -# -*- coding: utf-8 -*- # diff --git a/doc/en/example/costlysetup/sub_a/test_quick.py b/doc/en/example/costlysetup/sub_a/test_quick.py index 4f7b9f1ac7d..38dda2660d2 100644 --- a/doc/en/example/costlysetup/sub_a/test_quick.py +++ b/doc/en/example/costlysetup/sub_a/test_quick.py @@ -1,3 +1,2 @@ -# -*- coding: utf-8 -*- def test_quick(setup): pass diff --git a/doc/en/example/costlysetup/sub_b/__init__.py b/doc/en/example/costlysetup/sub_b/__init__.py index ec51c5a2b9d..792d6005489 100644 --- a/doc/en/example/costlysetup/sub_b/__init__.py +++ b/doc/en/example/costlysetup/sub_b/__init__.py @@ -1,2 +1 @@ -# -*- coding: utf-8 -*- # diff --git a/doc/en/example/costlysetup/sub_b/test_two.py b/doc/en/example/costlysetup/sub_b/test_two.py index 4e08bc2b69e..b1653aaab88 100644 --- a/doc/en/example/costlysetup/sub_b/test_two.py +++ b/doc/en/example/costlysetup/sub_b/test_two.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- def test_something(setup): assert setup.timecostly == 1 diff --git a/doc/en/example/multipython.py b/doc/en/example/multipython.py index 89caab15429..ad6f7e2a806 100644 --- a/doc/en/example/multipython.py +++ b/doc/en/example/multipython.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ module containing a parametrized tests testing cross-python serialization via the pickle module. diff --git a/doc/en/example/nonpython/conftest.py b/doc/en/example/nonpython/conftest.py index 306aa250379..7c23025af9c 100644 --- a/doc/en/example/nonpython/conftest.py +++ b/doc/en/example/nonpython/conftest.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # content of conftest.py import pytest diff --git a/doc/en/example/py2py3/conftest.py b/doc/en/example/py2py3/conftest.py index a6b9af7a860..844510a25a3 100644 --- a/doc/en/example/py2py3/conftest.py +++ b/doc/en/example/py2py3/conftest.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import sys import pytest diff --git a/doc/en/example/py2py3/test_py3.py b/doc/en/example/py2py3/test_py3.py index 30151f914a8..d95702a5348 100644 --- a/doc/en/example/py2py3/test_py3.py +++ b/doc/en/example/py2py3/test_py3.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- def test_exception_syntax(): try: 0 / 0 diff --git a/doc/en/example/pythoncollection.py b/doc/en/example/pythoncollection.py index bbc3fe868ea..b134d809df2 100644 --- a/doc/en/example/pythoncollection.py +++ b/doc/en/example/pythoncollection.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # run this with $ pytest --collect-only test_collectonly.py # diff --git a/doc/en/example/xfail_demo.py b/doc/en/example/xfail_demo.py index 88384a1562a..01e6da1ad2e 100644 --- a/doc/en/example/xfail_demo.py +++ b/doc/en/example/xfail_demo.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import pytest xfail = pytest.mark.xfail diff --git a/extra/get_issues.py b/extra/get_issues.py index 598a1af409f..9407aeded7d 100644 --- a/extra/get_issues.py +++ b/extra/get_issues.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import json import py diff --git a/extra/setup-py.test/setup.py b/extra/setup-py.test/setup.py index cfe18c28f52..d0560ce1f5f 100644 --- a/extra/setup-py.test/setup.py +++ b/extra/setup-py.test/setup.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import sys from distutils.core import setup diff --git a/scripts/release.py b/scripts/release.py index 32178fcf674..5009df359e6 100644 --- a/scripts/release.py +++ b/scripts/release.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Invoke development tasks. """ diff --git a/setup.py b/setup.py index 910fc839d3f..2f49078fafb 100644 --- a/setup.py +++ b/setup.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from setuptools import setup # TODO: if py gets upgrade to >=1.6, diff --git a/src/_pytest/__init__.py b/src/_pytest/__init__.py index 17cc20b615a..46c7827ed5e 100644 --- a/src/_pytest/__init__.py +++ b/src/_pytest/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- __all__ = ["__version__"] try: diff --git a/src/_pytest/_argcomplete.py b/src/_pytest/_argcomplete.py index c6cf1d8fddd..455c3a7be08 100644 --- a/src/_pytest/_argcomplete.py +++ b/src/_pytest/_argcomplete.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """allow bash-completion for argparse with argcomplete if installed needs argcomplete>=0.5.6 for python 3.2/3.3 (older versions fail to find the magic string, so _ARGCOMPLETE env. var is never set, and diff --git a/src/_pytest/_code/__init__.py b/src/_pytest/_code/__init__.py index 1394b2b10e6..fe755a39911 100644 --- a/src/_pytest/_code/__init__.py +++ b/src/_pytest/_code/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ python inspection/code generation API """ from __future__ import absolute_import from __future__ import division diff --git a/src/_pytest/_code/_py2traceback.py b/src/_pytest/_code/_py2traceback.py index faacc02166e..8a8b7bc000a 100644 --- a/src/_pytest/_code/_py2traceback.py +++ b/src/_pytest/_code/_py2traceback.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # copied from python-2.7.3's traceback.py # CHANGES: # - some_str is replaced, trying to create unicode strings diff --git a/src/_pytest/_code/code.py b/src/_pytest/_code/code.py index 8fd20f82d2a..0324a1cee82 100644 --- a/src/_pytest/_code/code.py +++ b/src/_pytest/_code/code.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/src/_pytest/_code/source.py b/src/_pytest/_code/source.py index c8a4b6adf38..39701a39bb0 100644 --- a/src/_pytest/_code/source.py +++ b/src/_pytest/_code/source.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/src/_pytest/_io/saferepr.py b/src/_pytest/_io/saferepr.py index 9b412dccad9..d817e37457c 100644 --- a/src/_pytest/_io/saferepr.py +++ b/src/_pytest/_io/saferepr.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import pprint from six.moves import reprlib diff --git a/src/_pytest/assertion/__init__.py b/src/_pytest/assertion/__init__.py index f959de29c02..ad38e0c2d8a 100644 --- a/src/_pytest/assertion/__init__.py +++ b/src/_pytest/assertion/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ support for presenting detailed information in failing assertions. """ diff --git a/src/_pytest/assertion/rewrite.py b/src/_pytest/assertion/rewrite.py index 785a7b12f1d..0cdfe3dc4bf 100644 --- a/src/_pytest/assertion/rewrite.py +++ b/src/_pytest/assertion/rewrite.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Rewrite assertion AST to produce nice error messages""" from __future__ import absolute_import from __future__ import division diff --git a/src/_pytest/assertion/truncate.py b/src/_pytest/assertion/truncate.py index 525896ea9ad..69d6acdef80 100644 --- a/src/_pytest/assertion/truncate.py +++ b/src/_pytest/assertion/truncate.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Utilities for truncating assertion output. diff --git a/src/_pytest/assertion/util.py b/src/_pytest/assertion/util.py index 7bcb709466b..828b9689756 100644 --- a/src/_pytest/assertion/util.py +++ b/src/_pytest/assertion/util.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Utilities for assertion debugging""" from __future__ import absolute_import from __future__ import division diff --git a/src/_pytest/cacheprovider.py b/src/_pytest/cacheprovider.py index 1eb9acc13ea..0764d90c614 100755 --- a/src/_pytest/cacheprovider.py +++ b/src/_pytest/cacheprovider.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ merged implementation of the cache provider diff --git a/src/_pytest/capture.py b/src/_pytest/capture.py index 3587018b8af..bcfb721f1c9 100644 --- a/src/_pytest/capture.py +++ b/src/_pytest/capture.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ per-test stdout/stderr capturing mechanism. diff --git a/src/_pytest/compat.py b/src/_pytest/compat.py index 9d38b97cb29..f4820b9046e 100644 --- a/src/_pytest/compat.py +++ b/src/_pytest/compat.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ python version compatibility code """ diff --git a/src/_pytest/config/__init__.py b/src/_pytest/config/__init__.py index ee588be5ba5..688de3cedc9 100644 --- a/src/_pytest/config/__init__.py +++ b/src/_pytest/config/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ command line options, ini-file and conftest.py processing. """ from __future__ import absolute_import from __future__ import division diff --git a/src/_pytest/config/argparsing.py b/src/_pytest/config/argparsing.py index 37fb772db99..cc48ed337e0 100644 --- a/src/_pytest/config/argparsing.py +++ b/src/_pytest/config/argparsing.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import argparse import warnings diff --git a/src/_pytest/config/exceptions.py b/src/_pytest/config/exceptions.py index bf58fde5dbf..19fe5cb08ed 100644 --- a/src/_pytest/config/exceptions.py +++ b/src/_pytest/config/exceptions.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- class UsageError(Exception): """ error in pytest usage or invocation""" diff --git a/src/_pytest/config/findpaths.py b/src/_pytest/config/findpaths.py index 3ece3bdc130..fa202447013 100644 --- a/src/_pytest/config/findpaths.py +++ b/src/_pytest/config/findpaths.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import os import py diff --git a/src/_pytest/debugging.py b/src/_pytest/debugging.py index 99d35a5ab77..07107b2a08d 100644 --- a/src/_pytest/debugging.py +++ b/src/_pytest/debugging.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ interactive debugging with PDB, the Python Debugger. """ from __future__ import absolute_import from __future__ import division diff --git a/src/_pytest/deprecated.py b/src/_pytest/deprecated.py index 6283a840246..b65700417a4 100644 --- a/src/_pytest/deprecated.py +++ b/src/_pytest/deprecated.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ This module contains deprecation messages and bits of code used elsewhere in the codebase that is planned to be removed in the next pytest release. diff --git a/src/_pytest/doctest.py b/src/_pytest/doctest.py index c6355470364..9f7990a146d 100644 --- a/src/_pytest/doctest.py +++ b/src/_pytest/doctest.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ discover and run doctests in modules and test files.""" from __future__ import absolute_import from __future__ import division diff --git a/src/_pytest/fixtures.py b/src/_pytest/fixtures.py index 53c916ebe2c..b85d63ce6d7 100644 --- a/src/_pytest/fixtures.py +++ b/src/_pytest/fixtures.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/src/_pytest/freeze_support.py b/src/_pytest/freeze_support.py index aeeec2a56b4..5edf3454cd9 100644 --- a/src/_pytest/freeze_support.py +++ b/src/_pytest/freeze_support.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Provides a function to report all internal modules for using freezing tools pytest diff --git a/src/_pytest/helpconfig.py b/src/_pytest/helpconfig.py index 56811601608..756ad49cb87 100644 --- a/src/_pytest/helpconfig.py +++ b/src/_pytest/helpconfig.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ version info, help messages, tracing configuration. """ from __future__ import absolute_import from __future__ import division diff --git a/src/_pytest/hookspec.py b/src/_pytest/hookspec.py index 7ab6154b176..d40a368116c 100644 --- a/src/_pytest/hookspec.py +++ b/src/_pytest/hookspec.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ hook specifications for pytest plugins, invoked from main.py and builtin plugins. """ from pluggy import HookspecMarker diff --git a/src/_pytest/junitxml.py b/src/_pytest/junitxml.py index 9a169a2bb96..c387301b5c2 100644 --- a/src/_pytest/junitxml.py +++ b/src/_pytest/junitxml.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ report test results in JUnit-XML format, for use with Jenkins and build integration servers. diff --git a/src/_pytest/logging.py b/src/_pytest/logging.py index ee143cb4167..58b05ba9599 100644 --- a/src/_pytest/logging.py +++ b/src/_pytest/logging.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Access and control log capturing. """ from __future__ import absolute_import from __future__ import division diff --git a/src/_pytest/main.py b/src/_pytest/main.py index 4978f8b532d..a87b00abafe 100644 --- a/src/_pytest/main.py +++ b/src/_pytest/main.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ core implementation of testing process: init, session, runtest loop. """ from __future__ import absolute_import from __future__ import division diff --git a/src/_pytest/mark/__init__.py b/src/_pytest/mark/__init__.py index 6bc22fe27da..e98dc5c373a 100644 --- a/src/_pytest/mark/__init__.py +++ b/src/_pytest/mark/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ generic mechanism for marking and selecting python functions. """ from __future__ import absolute_import from __future__ import division diff --git a/src/_pytest/mark/evaluate.py b/src/_pytest/mark/evaluate.py index 506546e253a..793bff79e83 100644 --- a/src/_pytest/mark/evaluate.py +++ b/src/_pytest/mark/evaluate.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import os import platform import sys diff --git a/src/_pytest/mark/legacy.py b/src/_pytest/mark/legacy.py index c56482f14d0..f784ffa2043 100644 --- a/src/_pytest/mark/legacy.py +++ b/src/_pytest/mark/legacy.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ this is a place where we put datastructures used by legacy apis we hope ot remove diff --git a/src/_pytest/mark/structures.py b/src/_pytest/mark/structures.py index 59faaea29a2..e44ba14e0d3 100644 --- a/src/_pytest/mark/structures.py +++ b/src/_pytest/mark/structures.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import inspect import warnings from collections import namedtuple diff --git a/src/_pytest/monkeypatch.py b/src/_pytest/monkeypatch.py index 5a017aa286b..4446be0e0cc 100644 --- a/src/_pytest/monkeypatch.py +++ b/src/_pytest/monkeypatch.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ monkeypatching and mocking functionality. """ from __future__ import absolute_import from __future__ import division diff --git a/src/_pytest/nodes.py b/src/_pytest/nodes.py index 7342d960738..4dd0e1785c8 100644 --- a/src/_pytest/nodes.py +++ b/src/_pytest/nodes.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/src/_pytest/nose.py b/src/_pytest/nose.py index fbab91da249..49238826099 100644 --- a/src/_pytest/nose.py +++ b/src/_pytest/nose.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ run test suites written for nose. """ from __future__ import absolute_import from __future__ import division diff --git a/src/_pytest/outcomes.py b/src/_pytest/outcomes.py index 4620f957c7d..7ee1ce7c9f1 100644 --- a/src/_pytest/outcomes.py +++ b/src/_pytest/outcomes.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ exception classes and constants handling test outcomes as well as functions creating them diff --git a/src/_pytest/pastebin.py b/src/_pytest/pastebin.py index 78c8b587a6f..f0848465d30 100644 --- a/src/_pytest/pastebin.py +++ b/src/_pytest/pastebin.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ submit failure or test session information to a pastebin service. """ from __future__ import absolute_import from __future__ import division diff --git a/src/_pytest/pathlib.py b/src/_pytest/pathlib.py index 2cd931b32a0..36c8acf36de 100644 --- a/src/_pytest/pathlib.py +++ b/src/_pytest/pathlib.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import atexit import errno import fnmatch diff --git a/src/_pytest/pytester.py b/src/_pytest/pytester.py index d3611b338e1..a74ad33efdf 100644 --- a/src/_pytest/pytester.py +++ b/src/_pytest/pytester.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """(disabled by default) support for testing pytest and pytest plugins.""" from __future__ import absolute_import from __future__ import division diff --git a/src/_pytest/python.py b/src/_pytest/python.py index e420f692437..219e3e2f1a9 100644 --- a/src/_pytest/python.py +++ b/src/_pytest/python.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Python test discovery, setup and run of test functions. """ from __future__ import absolute_import from __future__ import division diff --git a/src/_pytest/python_api.py b/src/_pytest/python_api.py index d5ee3f16040..9339cb3ba1a 100644 --- a/src/_pytest/python_api.py +++ b/src/_pytest/python_api.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import absolute_import import math diff --git a/src/_pytest/recwarn.py b/src/_pytest/recwarn.py index 409825f488a..439127008e3 100644 --- a/src/_pytest/recwarn.py +++ b/src/_pytest/recwarn.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ recording warnings during test function execution. """ from __future__ import absolute_import from __future__ import division diff --git a/src/_pytest/reports.py b/src/_pytest/reports.py index 0bba6762c33..43d7e54a41b 100644 --- a/src/_pytest/reports.py +++ b/src/_pytest/reports.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from pprint import pprint import py diff --git a/src/_pytest/resultlog.py b/src/_pytest/resultlog.py index bd30b5071e9..cd3fde80fbc 100644 --- a/src/_pytest/resultlog.py +++ b/src/_pytest/resultlog.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ log machine-parseable test session result information in a plain text file. """ diff --git a/src/_pytest/runner.py b/src/_pytest/runner.py index d51e859f1d1..7fb343d4ef2 100644 --- a/src/_pytest/runner.py +++ b/src/_pytest/runner.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ basic collect and runtest protocol implementations """ from __future__ import absolute_import from __future__ import division diff --git a/src/_pytest/setuponly.py b/src/_pytest/setuponly.py index 0859011241a..4bd4ad6d88f 100644 --- a/src/_pytest/setuponly.py +++ b/src/_pytest/setuponly.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/src/_pytest/setupplan.py b/src/_pytest/setupplan.py index 47b0fe82ef6..351e0be650f 100644 --- a/src/_pytest/setupplan.py +++ b/src/_pytest/setupplan.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/src/_pytest/skipping.py b/src/_pytest/skipping.py index 94227c39c21..941d0473759 100644 --- a/src/_pytest/skipping.py +++ b/src/_pytest/skipping.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ support for skip/xfail functions and markers. """ from __future__ import absolute_import from __future__ import division diff --git a/src/_pytest/stepwise.py b/src/_pytest/stepwise.py index 0427cd0ea45..68e53a31cb4 100644 --- a/src/_pytest/stepwise.py +++ b/src/_pytest/stepwise.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import pytest diff --git a/src/_pytest/terminal.py b/src/_pytest/terminal.py index e5ede1cadb8..063cda0175b 100644 --- a/src/_pytest/terminal.py +++ b/src/_pytest/terminal.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ terminal reporting of the full testing process. This is a good source for looking at the various reporting hooks. diff --git a/src/_pytest/tmpdir.py b/src/_pytest/tmpdir.py index 4a3686247c7..140c75c3264 100644 --- a/src/_pytest/tmpdir.py +++ b/src/_pytest/tmpdir.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ support for providing temporary directories to test functions. """ from __future__ import absolute_import from __future__ import division diff --git a/src/_pytest/unittest.py b/src/_pytest/unittest.py index 4380f1295b3..d4ea4f3610c 100644 --- a/src/_pytest/unittest.py +++ b/src/_pytest/unittest.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ discovery and running of std-library "unittest" style tests. """ from __future__ import absolute_import from __future__ import division diff --git a/src/_pytest/warning_types.py b/src/_pytest/warning_types.py index 861010a1275..2777aabeaaf 100644 --- a/src/_pytest/warning_types.py +++ b/src/_pytest/warning_types.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import attr diff --git a/src/_pytest/warnings.py b/src/_pytest/warnings.py index a2579bf753b..5e79ec265a4 100644 --- a/src/_pytest/warnings.py +++ b/src/_pytest/warnings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/src/pytest.py b/src/pytest.py index ccc77b476f5..a6376843d24 100644 --- a/src/pytest.py +++ b/src/pytest.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # PYTHON_ARGCOMPLETE_OK """ pytest: unit and functional testing with Python. diff --git a/testing/acceptance_test.py b/testing/acceptance_test.py index 5ed04d6382f..ba17e4b1b50 100644 --- a/testing/acceptance_test.py +++ b/testing/acceptance_test.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/testing/code/test_code.py b/testing/code/test_code.py index fcde20b4164..1386ad299b0 100644 --- a/testing/code/test_code.py +++ b/testing/code/test_code.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/testing/code/test_excinfo.py b/testing/code/test_excinfo.py index 33cd7169b3a..c461f33aaf6 100644 --- a/testing/code/test_excinfo.py +++ b/testing/code/test_excinfo.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/testing/code/test_source.py b/testing/code/test_source.py index b86d18d0c8b..c72f7da5ab4 100644 --- a/testing/code/test_source.py +++ b/testing/code/test_source.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # flake8: noqa # disable flake check on this file because some constructs are strange # or redundant on purpose and can't be disable on a line-by-line basis diff --git a/testing/conftest.py b/testing/conftest.py index 6e01d710d11..35d5f9661b4 100644 --- a/testing/conftest.py +++ b/testing/conftest.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import pytest diff --git a/testing/deprecated_test.py b/testing/deprecated_test.py index a072f6b210c..4818379fee3 100644 --- a/testing/deprecated_test.py +++ b/testing/deprecated_test.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/testing/example_scripts/acceptance/fixture_mock_integration.py b/testing/example_scripts/acceptance/fixture_mock_integration.py index 58afe730e23..5b00ac90e1b 100644 --- a/testing/example_scripts/acceptance/fixture_mock_integration.py +++ b/testing/example_scripts/acceptance/fixture_mock_integration.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Reproduces issue #3774""" from unittest import mock diff --git a/testing/example_scripts/collect/collect_init_tests/tests/__init__.py b/testing/example_scripts/collect/collect_init_tests/tests/__init__.py index 6211055718f..9cd366295e7 100644 --- a/testing/example_scripts/collect/collect_init_tests/tests/__init__.py +++ b/testing/example_scripts/collect/collect_init_tests/tests/__init__.py @@ -1,3 +1,2 @@ -# -*- coding: utf-8 -*- def test_init(): pass diff --git a/testing/example_scripts/collect/collect_init_tests/tests/test_foo.py b/testing/example_scripts/collect/collect_init_tests/tests/test_foo.py index 8c560fd139f..8f2d73cfa4f 100644 --- a/testing/example_scripts/collect/collect_init_tests/tests/test_foo.py +++ b/testing/example_scripts/collect/collect_init_tests/tests/test_foo.py @@ -1,3 +1,2 @@ -# -*- coding: utf-8 -*- def test_foo(): pass diff --git a/testing/example_scripts/collect/package_infinite_recursion/conftest.py b/testing/example_scripts/collect/package_infinite_recursion/conftest.py index 9c3d9a791c0..9629fa646af 100644 --- a/testing/example_scripts/collect/package_infinite_recursion/conftest.py +++ b/testing/example_scripts/collect/package_infinite_recursion/conftest.py @@ -1,3 +1,2 @@ -# -*- coding: utf-8 -*- def pytest_ignore_collect(path): return False diff --git a/testing/example_scripts/collect/package_infinite_recursion/tests/test_basic.py b/testing/example_scripts/collect/package_infinite_recursion/tests/test_basic.py index 10c5f605202..f174823854e 100644 --- a/testing/example_scripts/collect/package_infinite_recursion/tests/test_basic.py +++ b/testing/example_scripts/collect/package_infinite_recursion/tests/test_basic.py @@ -1,3 +1,2 @@ -# -*- coding: utf-8 -*- def test(): pass diff --git a/testing/example_scripts/collect/package_init_given_as_arg/pkg/test_foo.py b/testing/example_scripts/collect/package_init_given_as_arg/pkg/test_foo.py index 10c5f605202..f174823854e 100644 --- a/testing/example_scripts/collect/package_init_given_as_arg/pkg/test_foo.py +++ b/testing/example_scripts/collect/package_init_given_as_arg/pkg/test_foo.py @@ -1,3 +1,2 @@ -# -*- coding: utf-8 -*- def test(): pass diff --git a/testing/example_scripts/config/collect_pytest_prefix/conftest.py b/testing/example_scripts/config/collect_pytest_prefix/conftest.py index 13397ccc4c8..56a4c71d358 100644 --- a/testing/example_scripts/config/collect_pytest_prefix/conftest.py +++ b/testing/example_scripts/config/collect_pytest_prefix/conftest.py @@ -1,3 +1,2 @@ -# -*- coding: utf-8 -*- class pytest_something(object): pass diff --git a/testing/example_scripts/config/collect_pytest_prefix/test_foo.py b/testing/example_scripts/config/collect_pytest_prefix/test_foo.py index 8c560fd139f..8f2d73cfa4f 100644 --- a/testing/example_scripts/config/collect_pytest_prefix/test_foo.py +++ b/testing/example_scripts/config/collect_pytest_prefix/test_foo.py @@ -1,3 +1,2 @@ -# -*- coding: utf-8 -*- def test_foo(): pass diff --git a/testing/example_scripts/conftest_usageerror/conftest.py b/testing/example_scripts/conftest_usageerror/conftest.py index d2f040578fa..8973e4252d3 100644 --- a/testing/example_scripts/conftest_usageerror/conftest.py +++ b/testing/example_scripts/conftest_usageerror/conftest.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- def pytest_configure(config): import pytest diff --git a/testing/example_scripts/dataclasses/test_compare_dataclasses.py b/testing/example_scripts/dataclasses/test_compare_dataclasses.py index 5381b5ed071..3bbebe2aa26 100644 --- a/testing/example_scripts/dataclasses/test_compare_dataclasses.py +++ b/testing/example_scripts/dataclasses/test_compare_dataclasses.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from dataclasses import dataclass from dataclasses import field diff --git a/testing/example_scripts/dataclasses/test_compare_dataclasses_field_comparison_off.py b/testing/example_scripts/dataclasses/test_compare_dataclasses_field_comparison_off.py index d418dd6b0cf..63b9f534e6e 100644 --- a/testing/example_scripts/dataclasses/test_compare_dataclasses_field_comparison_off.py +++ b/testing/example_scripts/dataclasses/test_compare_dataclasses_field_comparison_off.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from dataclasses import dataclass from dataclasses import field diff --git a/testing/example_scripts/dataclasses/test_compare_dataclasses_verbose.py b/testing/example_scripts/dataclasses/test_compare_dataclasses_verbose.py index a72ca5119e6..17835c0c3fc 100644 --- a/testing/example_scripts/dataclasses/test_compare_dataclasses_verbose.py +++ b/testing/example_scripts/dataclasses/test_compare_dataclasses_verbose.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from dataclasses import dataclass from dataclasses import field diff --git a/testing/example_scripts/dataclasses/test_compare_two_different_dataclasses.py b/testing/example_scripts/dataclasses/test_compare_two_different_dataclasses.py index b77b70d3c2d..24f185d8ac4 100644 --- a/testing/example_scripts/dataclasses/test_compare_two_different_dataclasses.py +++ b/testing/example_scripts/dataclasses/test_compare_two_different_dataclasses.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from dataclasses import dataclass from dataclasses import field diff --git a/testing/example_scripts/deprecated/test_fixture_named_request.py b/testing/example_scripts/deprecated/test_fixture_named_request.py index 36addc29954..75514bf8b8c 100644 --- a/testing/example_scripts/deprecated/test_fixture_named_request.py +++ b/testing/example_scripts/deprecated/test_fixture_named_request.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import pytest diff --git a/testing/example_scripts/fixtures/custom_item/conftest.py b/testing/example_scripts/fixtures/custom_item/conftest.py index fa41d0fba68..25299d72690 100644 --- a/testing/example_scripts/fixtures/custom_item/conftest.py +++ b/testing/example_scripts/fixtures/custom_item/conftest.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import pytest diff --git a/testing/example_scripts/fixtures/custom_item/foo/test_foo.py b/testing/example_scripts/fixtures/custom_item/foo/test_foo.py index 10c5f605202..f174823854e 100644 --- a/testing/example_scripts/fixtures/custom_item/foo/test_foo.py +++ b/testing/example_scripts/fixtures/custom_item/foo/test_foo.py @@ -1,3 +1,2 @@ -# -*- coding: utf-8 -*- def test(): pass diff --git a/testing/example_scripts/fixtures/fill_fixtures/test_conftest_funcargs_only_available_in_subdir/sub1/conftest.py b/testing/example_scripts/fixtures/fill_fixtures/test_conftest_funcargs_only_available_in_subdir/sub1/conftest.py index 952e7d60a69..79af4bc4790 100644 --- a/testing/example_scripts/fixtures/fill_fixtures/test_conftest_funcargs_only_available_in_subdir/sub1/conftest.py +++ b/testing/example_scripts/fixtures/fill_fixtures/test_conftest_funcargs_only_available_in_subdir/sub1/conftest.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import pytest diff --git a/testing/example_scripts/fixtures/fill_fixtures/test_conftest_funcargs_only_available_in_subdir/sub1/test_in_sub1.py b/testing/example_scripts/fixtures/fill_fixtures/test_conftest_funcargs_only_available_in_subdir/sub1/test_in_sub1.py index b824f4e99ef..df36da1369b 100644 --- a/testing/example_scripts/fixtures/fill_fixtures/test_conftest_funcargs_only_available_in_subdir/sub1/test_in_sub1.py +++ b/testing/example_scripts/fixtures/fill_fixtures/test_conftest_funcargs_only_available_in_subdir/sub1/test_in_sub1.py @@ -1,3 +1,2 @@ -# -*- coding: utf-8 -*- def test_1(arg1): pass diff --git a/testing/example_scripts/fixtures/fill_fixtures/test_conftest_funcargs_only_available_in_subdir/sub2/conftest.py b/testing/example_scripts/fixtures/fill_fixtures/test_conftest_funcargs_only_available_in_subdir/sub2/conftest.py index 2be90b4dfe7..00981c5dc12 100644 --- a/testing/example_scripts/fixtures/fill_fixtures/test_conftest_funcargs_only_available_in_subdir/sub2/conftest.py +++ b/testing/example_scripts/fixtures/fill_fixtures/test_conftest_funcargs_only_available_in_subdir/sub2/conftest.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import pytest diff --git a/testing/example_scripts/fixtures/fill_fixtures/test_conftest_funcargs_only_available_in_subdir/sub2/test_in_sub2.py b/testing/example_scripts/fixtures/fill_fixtures/test_conftest_funcargs_only_available_in_subdir/sub2/test_in_sub2.py index a1432042bfd..1c34f94acc4 100644 --- a/testing/example_scripts/fixtures/fill_fixtures/test_conftest_funcargs_only_available_in_subdir/sub2/test_in_sub2.py +++ b/testing/example_scripts/fixtures/fill_fixtures/test_conftest_funcargs_only_available_in_subdir/sub2/test_in_sub2.py @@ -1,3 +1,2 @@ -# -*- coding: utf-8 -*- def test_2(arg2): pass diff --git a/testing/example_scripts/fixtures/fill_fixtures/test_detect_recursive_dependency_error.py b/testing/example_scripts/fixtures/fill_fixtures/test_detect_recursive_dependency_error.py index d1e54eea7e4..d1efcbb338c 100644 --- a/testing/example_scripts/fixtures/fill_fixtures/test_detect_recursive_dependency_error.py +++ b/testing/example_scripts/fixtures/fill_fixtures/test_detect_recursive_dependency_error.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import pytest diff --git a/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_conftest/conftest.py b/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_conftest/conftest.py index 87756e6491f..5dfd2f77957 100644 --- a/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_conftest/conftest.py +++ b/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_conftest/conftest.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import pytest diff --git a/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_conftest/pkg/conftest.py b/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_conftest/pkg/conftest.py index 1cd88524b6f..4e22ce5a137 100644 --- a/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_conftest/pkg/conftest.py +++ b/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_conftest/pkg/conftest.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import pytest diff --git a/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_conftest/pkg/test_spam.py b/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_conftest/pkg/test_spam.py index 65690c49f23..0d891fbb503 100644 --- a/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_conftest/pkg/test_spam.py +++ b/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_conftest/pkg/test_spam.py @@ -1,3 +1,2 @@ -# -*- coding: utf-8 -*- def test_spam(spam): assert spam == "spamspam" diff --git a/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_module/conftest.py b/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_module/conftest.py index 87756e6491f..5dfd2f77957 100644 --- a/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_module/conftest.py +++ b/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_module/conftest.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import pytest diff --git a/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_module/test_extend_fixture_conftest_module.py b/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_module/test_extend_fixture_conftest_module.py index 5b344c122f1..46d1446f470 100644 --- a/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_module/test_extend_fixture_conftest_module.py +++ b/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_conftest_module/test_extend_fixture_conftest_module.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import pytest diff --git a/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_module_class.py b/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_module_class.py index 4332c66017b..2b8218ed7ca 100644 --- a/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_module_class.py +++ b/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_module_class.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import pytest diff --git a/testing/example_scripts/fixtures/fill_fixtures/test_funcarg_basic.py b/testing/example_scripts/fixtures/fill_fixtures/test_funcarg_basic.py index ba302c49e6c..0661cb301fc 100644 --- a/testing/example_scripts/fixtures/fill_fixtures/test_funcarg_basic.py +++ b/testing/example_scripts/fixtures/fill_fixtures/test_funcarg_basic.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import pytest diff --git a/testing/example_scripts/fixtures/fill_fixtures/test_funcarg_lookup_classlevel.py b/testing/example_scripts/fixtures/fill_fixtures/test_funcarg_lookup_classlevel.py index 1004d5d1352..7b7183dd94e 100644 --- a/testing/example_scripts/fixtures/fill_fixtures/test_funcarg_lookup_classlevel.py +++ b/testing/example_scripts/fixtures/fill_fixtures/test_funcarg_lookup_classlevel.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import pytest diff --git a/testing/example_scripts/fixtures/fill_fixtures/test_funcarg_lookup_modulelevel.py b/testing/example_scripts/fixtures/fill_fixtures/test_funcarg_lookup_modulelevel.py index 79d283e9f66..227abb59374 100644 --- a/testing/example_scripts/fixtures/fill_fixtures/test_funcarg_lookup_modulelevel.py +++ b/testing/example_scripts/fixtures/fill_fixtures/test_funcarg_lookup_modulelevel.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import pytest diff --git a/testing/example_scripts/fixtures/fill_fixtures/test_funcarg_lookupfails.py b/testing/example_scripts/fixtures/fill_fixtures/test_funcarg_lookupfails.py index 18f426af9c9..b775203231f 100644 --- a/testing/example_scripts/fixtures/fill_fixtures/test_funcarg_lookupfails.py +++ b/testing/example_scripts/fixtures/fill_fixtures/test_funcarg_lookupfails.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import pytest diff --git a/testing/example_scripts/fixtures/test_getfixturevalue_dynamic.py b/testing/example_scripts/fixtures/test_getfixturevalue_dynamic.py index 219e57421d8..055a1220b1c 100644 --- a/testing/example_scripts/fixtures/test_getfixturevalue_dynamic.py +++ b/testing/example_scripts/fixtures/test_getfixturevalue_dynamic.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import pytest diff --git a/testing/example_scripts/issue88_initial_file_multinodes/conftest.py b/testing/example_scripts/issue88_initial_file_multinodes/conftest.py index 8f3e7b4e52a..aa5d878313c 100644 --- a/testing/example_scripts/issue88_initial_file_multinodes/conftest.py +++ b/testing/example_scripts/issue88_initial_file_multinodes/conftest.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import pytest diff --git a/testing/example_scripts/issue88_initial_file_multinodes/test_hello.py b/testing/example_scripts/issue88_initial_file_multinodes/test_hello.py index 653d570a88c..56444d14748 100644 --- a/testing/example_scripts/issue88_initial_file_multinodes/test_hello.py +++ b/testing/example_scripts/issue88_initial_file_multinodes/test_hello.py @@ -1,3 +1,2 @@ -# -*- coding: utf-8 -*- def test_hello(): pass diff --git a/testing/example_scripts/issue_519.py b/testing/example_scripts/issue_519.py index 24d864a5380..7199df820fb 100644 --- a/testing/example_scripts/issue_519.py +++ b/testing/example_scripts/issue_519.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import pprint import pytest diff --git a/testing/example_scripts/marks/marks_considered_keywords/test_marks_as_keywords.py b/testing/example_scripts/marks/marks_considered_keywords/test_marks_as_keywords.py index 61d969a36b8..35a2c7b7628 100644 --- a/testing/example_scripts/marks/marks_considered_keywords/test_marks_as_keywords.py +++ b/testing/example_scripts/marks/marks_considered_keywords/test_marks_as_keywords.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import pytest diff --git a/testing/example_scripts/perf_examples/collect_stats/generate_folders.py b/testing/example_scripts/perf_examples/collect_stats/generate_folders.py index 32ca818ead9..ff1eaf7d6bb 100644 --- a/testing/example_scripts/perf_examples/collect_stats/generate_folders.py +++ b/testing/example_scripts/perf_examples/collect_stats/generate_folders.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import argparse import pathlib diff --git a/testing/example_scripts/perf_examples/collect_stats/template_test.py b/testing/example_scripts/perf_examples/collect_stats/template_test.py index 5d0cd5a7164..064ade190a1 100644 --- a/testing/example_scripts/perf_examples/collect_stats/template_test.py +++ b/testing/example_scripts/perf_examples/collect_stats/template_test.py @@ -1,3 +1,2 @@ -# -*- coding: utf-8 -*- def test_x(): pass diff --git a/testing/example_scripts/tmpdir/tmpdir_fixture.py b/testing/example_scripts/tmpdir/tmpdir_fixture.py index 33f0315d52f..f4ad07462cb 100644 --- a/testing/example_scripts/tmpdir/tmpdir_fixture.py +++ b/testing/example_scripts/tmpdir/tmpdir_fixture.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import pytest diff --git a/testing/example_scripts/unittest/test_parametrized_fixture_error_message.py b/testing/example_scripts/unittest/test_parametrized_fixture_error_message.py index cef950ee782..d421ce927c9 100644 --- a/testing/example_scripts/unittest/test_parametrized_fixture_error_message.py +++ b/testing/example_scripts/unittest/test_parametrized_fixture_error_message.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import unittest import pytest diff --git a/testing/example_scripts/unittest/test_setup_skip.py b/testing/example_scripts/unittest/test_setup_skip.py index 26b6195e96d..93f79bb3b2e 100644 --- a/testing/example_scripts/unittest/test_setup_skip.py +++ b/testing/example_scripts/unittest/test_setup_skip.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Skipping an entire subclass with unittest.skip() should *not* call setUp from a base class.""" import unittest diff --git a/testing/example_scripts/unittest/test_setup_skip_class.py b/testing/example_scripts/unittest/test_setup_skip_class.py index 0c4a3775723..4f251dcba17 100644 --- a/testing/example_scripts/unittest/test_setup_skip_class.py +++ b/testing/example_scripts/unittest/test_setup_skip_class.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """Skipping an entire subclass with unittest.skip() should *not* call setUpClass from a base class.""" import unittest diff --git a/testing/example_scripts/unittest/test_setup_skip_module.py b/testing/example_scripts/unittest/test_setup_skip_module.py index abf782a6217..98befbe510f 100644 --- a/testing/example_scripts/unittest/test_setup_skip_module.py +++ b/testing/example_scripts/unittest/test_setup_skip_module.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """setUpModule is always called, even if all tests in the module are skipped""" import unittest diff --git a/testing/example_scripts/warnings/test_group_warnings_by_message.py b/testing/example_scripts/warnings/test_group_warnings_by_message.py index 29d89597452..c736135b7b9 100644 --- a/testing/example_scripts/warnings/test_group_warnings_by_message.py +++ b/testing/example_scripts/warnings/test_group_warnings_by_message.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import warnings import pytest diff --git a/testing/examples/test_issue519.py b/testing/examples/test_issue519.py index 7da1f4ee664..e83f18fdc93 100644 --- a/testing/examples/test_issue519.py +++ b/testing/examples/test_issue519.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- def test_510(testdir): testdir.copy_example("issue_519.py") testdir.runpytest("issue_519.py") diff --git a/testing/freeze/create_executable.py b/testing/freeze/create_executable.py index ab8013317b2..b53eb09f53b 100644 --- a/testing/freeze/create_executable.py +++ b/testing/freeze/create_executable.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Generates an executable with pytest runner embedded using PyInstaller. """ diff --git a/testing/freeze/runtests_script.py b/testing/freeze/runtests_script.py index f7381f56863..d03bca8406d 100644 --- a/testing/freeze/runtests_script.py +++ b/testing/freeze/runtests_script.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ This is the script that is actually frozen into an executable: simply executes py.test main(). diff --git a/testing/freeze/tests/test_trivial.py b/testing/freeze/tests/test_trivial.py index 449dbf9d362..08a55552abb 100644 --- a/testing/freeze/tests/test_trivial.py +++ b/testing/freeze/tests/test_trivial.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- def test_upper(): assert "foo".upper() == "FOO" diff --git a/testing/freeze/tox_run.py b/testing/freeze/tox_run.py index 29b72792384..678a69c858a 100644 --- a/testing/freeze/tox_run.py +++ b/testing/freeze/tox_run.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Called by tox.ini: uses the generated executable to run the tests in ./tests/ directory. diff --git a/testing/io/test_saferepr.py b/testing/io/test_saferepr.py index 90120308889..4643d3f92d6 100644 --- a/testing/io/test_saferepr.py +++ b/testing/io/test_saferepr.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from _pytest._io.saferepr import saferepr diff --git a/testing/logging/test_fixture.py b/testing/logging/test_fixture.py index ff772e7ec62..f50522b7fd7 100644 --- a/testing/logging/test_fixture.py +++ b/testing/logging/test_fixture.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import logging import pytest diff --git a/testing/logging/test_formatter.py b/testing/logging/test_formatter.py index 7a63ab47ea7..18f8f0aa17a 100644 --- a/testing/logging/test_formatter.py +++ b/testing/logging/test_formatter.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import logging import py.io diff --git a/testing/logging/test_reporting.py b/testing/logging/test_reporting.py index e7a3a80ebf1..dab5b662c8b 100644 --- a/testing/logging/test_reporting.py +++ b/testing/logging/test_reporting.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import os import re from io import open diff --git a/testing/python/approx.py b/testing/python/approx.py index 18508f1fe5c..c3ab9c12039 100644 --- a/testing/python/approx.py +++ b/testing/python/approx.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import doctest import operator from decimal import Decimal diff --git a/testing/python/collect.py b/testing/python/collect.py index 4a1aa724f94..5e59b21b707 100644 --- a/testing/python/collect.py +++ b/testing/python/collect.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import os import sys import textwrap diff --git a/testing/python/fixtures.py b/testing/python/fixtures.py index bd1b1d97541..4d9ff0ba499 100644 --- a/testing/python/fixtures.py +++ b/testing/python/fixtures.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import sys import textwrap diff --git a/testing/python/integration.py b/testing/python/integration.py index d2fea2dc5ca..a6274701416 100644 --- a/testing/python/integration.py +++ b/testing/python/integration.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import pytest from _pytest import python from _pytest import runner diff --git a/testing/python/metafunc.py b/testing/python/metafunc.py index 95343112639..c6a8e161cb6 100644 --- a/testing/python/metafunc.py +++ b/testing/python/metafunc.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import re import sys import textwrap diff --git a/testing/python/raises.py b/testing/python/raises.py index 4970f9a56c3..5f5ca6b8fda 100644 --- a/testing/python/raises.py +++ b/testing/python/raises.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import sys import pytest diff --git a/testing/python/setup_only.py b/testing/python/setup_only.py index ba4ceb00fce..4ae24b15a6d 100644 --- a/testing/python/setup_only.py +++ b/testing/python/setup_only.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import pytest diff --git a/testing/python/setup_plan.py b/testing/python/setup_plan.py index ad64e42c29c..0321939a8aa 100644 --- a/testing/python/setup_plan.py +++ b/testing/python/setup_plan.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- def test_show_fixtures_and_test(testdir): """ Verifies that fixtures are not executed. """ p = testdir.makepyfile( diff --git a/testing/python/show_fixtures_per_test.py b/testing/python/show_fixtures_per_test.py index e14344d4ebf..8fdaa24f4b3 100644 --- a/testing/python/show_fixtures_per_test.py +++ b/testing/python/show_fixtures_per_test.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- def test_no_items_should_not_show_output(testdir): diff --git a/testing/test_argcomplete.py b/testing/test_argcomplete.py index bd681b0e68a..e0a45daad1f 100644 --- a/testing/test_argcomplete.py +++ b/testing/test_argcomplete.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/testing/test_assertion.py b/testing/test_assertion.py index 1fbf7b120d0..4e19fe00a2a 100644 --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/testing/test_assertrewrite.py b/testing/test_assertrewrite.py index cc9de30719a..f7a8f443519 100644 --- a/testing/test_assertrewrite.py +++ b/testing/test_assertrewrite.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/testing/test_cacheprovider.py b/testing/test_cacheprovider.py index 6de0b312929..21ae7e6f282 100644 --- a/testing/test_cacheprovider.py +++ b/testing/test_cacheprovider.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/testing/test_capture.py b/testing/test_capture.py index f101c0ec36f..54c4230fec1 100644 --- a/testing/test_capture.py +++ b/testing/test_capture.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/testing/test_collection.py b/testing/test_collection.py index 1a42e425f5e..d6803ea89e2 100644 --- a/testing/test_collection.py +++ b/testing/test_collection.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/testing/test_compat.py b/testing/test_compat.py index f0ae07e058f..f61e2f9d9ce 100644 --- a/testing/test_compat.py +++ b/testing/test_compat.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/testing/test_config.py b/testing/test_config.py index 2cda7f40ba7..85831144200 100644 --- a/testing/test_config.py +++ b/testing/test_config.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/testing/test_conftest.py b/testing/test_conftest.py index f8e3dfa92e4..acb9b52b4cd 100644 --- a/testing/test_conftest.py +++ b/testing/test_conftest.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/testing/test_doctest.py b/testing/test_doctest.py index 57eda456db3..d357c8607b8 100644 --- a/testing/test_doctest.py +++ b/testing/test_doctest.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/testing/test_entry_points.py b/testing/test_entry_points.py index ad64d004f1c..0adae0b1acf 100644 --- a/testing/test_entry_points.py +++ b/testing/test_entry_points.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/testing/test_helpconfig.py b/testing/test_helpconfig.py index 75888fe14cb..9c7806d5489 100644 --- a/testing/test_helpconfig.py +++ b/testing/test_helpconfig.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/testing/test_junitxml.py b/testing/test_junitxml.py index b87f1a9ec4b..9fcf0ac7284 100644 --- a/testing/test_junitxml.py +++ b/testing/test_junitxml.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/testing/test_mark.py b/testing/test_mark.py index dc6e28a7d49..a210267a8d5 100644 --- a/testing/test_mark.py +++ b/testing/test_mark.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/testing/test_modimport.py b/testing/test_modimport.py index 5dd057c55e2..3d7a073232c 100644 --- a/testing/test_modimport.py +++ b/testing/test_modimport.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import subprocess import sys diff --git a/testing/test_monkeypatch.py b/testing/test_monkeypatch.py index 279b0c4a47d..5fbabc42106 100644 --- a/testing/test_monkeypatch.py +++ b/testing/test_monkeypatch.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/testing/test_nodes.py b/testing/test_nodes.py index e86bd5f793e..b13ce1fe604 100644 --- a/testing/test_nodes.py +++ b/testing/test_nodes.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import py import pytest diff --git a/testing/test_nose.py b/testing/test_nose.py index 6eb5f085e84..2140a4c8bf9 100644 --- a/testing/test_nose.py +++ b/testing/test_nose.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/testing/test_parseopt.py b/testing/test_parseopt.py index c570ed60b2f..91f9a7d2bec 100644 --- a/testing/test_parseopt.py +++ b/testing/test_parseopt.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/testing/test_pastebin.py b/testing/test_pastebin.py index 0d17ad73fa6..7b323cabf92 100644 --- a/testing/test_pastebin.py +++ b/testing/test_pastebin.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/testing/test_pathlib.py b/testing/test_pathlib.py index 541d289f777..8ac4040702a 100644 --- a/testing/test_pathlib.py +++ b/testing/test_pathlib.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import sys import py diff --git a/testing/test_pdb.py b/testing/test_pdb.py index 8746548027f..bb34442f81c 100644 --- a/testing/test_pdb.py +++ b/testing/test_pdb.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/testing/test_pluginmanager.py b/testing/test_pluginmanager.py index 23655164343..9bd8a96cb50 100644 --- a/testing/test_pluginmanager.py +++ b/testing/test_pluginmanager.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/testing/test_pytester.py b/testing/test_pytester.py index 54d364ca1fd..747d3d291f4 100644 --- a/testing/test_pytester.py +++ b/testing/test_pytester.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/testing/test_recwarn.py b/testing/test_recwarn.py index 2246085f59e..982e246d744 100644 --- a/testing/test_recwarn.py +++ b/testing/test_recwarn.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/testing/test_reports.py b/testing/test_reports.py index 5c6851e49bd..6d2b167f871 100644 --- a/testing/test_reports.py +++ b/testing/test_reports.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import pytest from _pytest.pathlib import Path from _pytest.reports import CollectReport diff --git a/testing/test_resultlog.py b/testing/test_resultlog.py index 1ef49d5e2d9..aba5713af52 100644 --- a/testing/test_resultlog.py +++ b/testing/test_resultlog.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/testing/test_runner.py b/testing/test_runner.py index 5b37d12dbbe..444ebe7e6b4 100644 --- a/testing/test_runner.py +++ b/testing/test_runner.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/testing/test_runner_xunit.py b/testing/test_runner_xunit.py index 5be7297f6c5..6b5752b77ad 100644 --- a/testing/test_runner_xunit.py +++ b/testing/test_runner_xunit.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ test correct setup/teardowns at module, class, and instance level diff --git a/testing/test_session.py b/testing/test_session.py index 9acad5deafd..03f30f32b07 100644 --- a/testing/test_session.py +++ b/testing/test_session.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/testing/test_skipping.py b/testing/test_skipping.py index ce183171fc6..b31a74ece65 100644 --- a/testing/test_skipping.py +++ b/testing/test_skipping.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/testing/test_stepwise.py b/testing/test_stepwise.py index 68e5989ecdb..2202bbf1b60 100644 --- a/testing/test_stepwise.py +++ b/testing/test_stepwise.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- import pytest diff --git a/testing/test_terminal.py b/testing/test_terminal.py index 1b2e46c7c2b..42cdf1a737f 100644 --- a/testing/test_terminal.py +++ b/testing/test_terminal.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ terminal reporting of the full testing process. """ diff --git a/testing/test_tmpdir.py b/testing/test_tmpdir.py index 14e5bcbcae4..454cbbd4db2 100644 --- a/testing/test_tmpdir.py +++ b/testing/test_tmpdir.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/testing/test_unittest.py b/testing/test_unittest.py index f310cd8cc67..1bc12542b4a 100644 --- a/testing/test_unittest.py +++ b/testing/test_unittest.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import absolute_import from __future__ import division from __future__ import print_function diff --git a/testing/test_warnings.py b/testing/test_warnings.py index 4a5ebac7d01..db6fa9cc9ba 100644 --- a/testing/test_warnings.py +++ b/testing/test_warnings.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from __future__ import unicode_literals import warnings From 3f1ec520fcb88fd4051829e660b6faefc1c542ea Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sun, 2 Jun 2019 15:31:29 -0700 Subject: [PATCH 14/23] pre-commit run reorder-python-imports --all-files --- bench/skip.py | 2 -- src/_pytest/_argcomplete.py | 4 ---- src/_pytest/_code/__init__.py | 4 ---- src/_pytest/_code/_py2traceback.py | 5 ----- src/_pytest/_code/code.py | 4 ---- src/_pytest/_code/source.py | 4 ---- src/_pytest/_io/saferepr.py | 3 +-- src/_pytest/assertion/__init__.py | 4 ---- src/_pytest/assertion/rewrite.py | 4 ---- src/_pytest/assertion/truncate.py | 4 ---- src/_pytest/assertion/util.py | 4 ---- src/_pytest/cacheprovider.py | 4 ---- src/_pytest/capture.py | 4 ---- src/_pytest/compat.py | 4 ---- src/_pytest/config/__init__.py | 4 ---- src/_pytest/debugging.py | 4 ---- src/_pytest/deprecated.py | 4 ---- src/_pytest/doctest.py | 4 ---- src/_pytest/fixtures.py | 4 ---- src/_pytest/freeze_support.py | 3 --- src/_pytest/helpconfig.py | 4 ---- src/_pytest/junitxml.py | 4 ---- src/_pytest/logging.py | 4 ---- src/_pytest/main.py | 4 ---- src/_pytest/mark/__init__.py | 4 ---- src/_pytest/monkeypatch.py | 4 ---- src/_pytest/nodes.py | 4 ---- src/_pytest/nose.py | 4 ---- src/_pytest/outcomes.py | 4 ---- src/_pytest/pastebin.py | 4 ---- src/_pytest/pathlib.py | 1 - src/_pytest/pytester.py | 4 ---- src/_pytest/python.py | 4 ---- src/_pytest/python_api.py | 5 +---- src/_pytest/recwarn.py | 4 ---- src/_pytest/resultlog.py | 4 ---- src/_pytest/runner.py | 4 ---- src/_pytest/setuponly.py | 4 ---- src/_pytest/setupplan.py | 4 ---- src/_pytest/skipping.py | 4 ---- src/_pytest/terminal.py | 4 ---- src/_pytest/tmpdir.py | 4 ---- src/_pytest/unittest.py | 4 ---- src/_pytest/warnings.py | 4 ---- testing/acceptance_test.py | 4 ---- testing/code/test_code.py | 4 ---- testing/code/test_excinfo.py | 6 +----- testing/code/test_source.py | 4 ---- testing/deprecated_test.py | 4 ---- testing/test_argcomplete.py | 4 ---- testing/test_assertion.py | 4 ---- testing/test_assertrewrite.py | 4 ---- testing/test_cacheprovider.py | 4 ---- testing/test_capture.py | 4 ---- testing/test_collection.py | 4 ---- testing/test_compat.py | 4 ---- testing/test_config.py | 4 ---- testing/test_conftest.py | 4 ---- testing/test_doctest.py | 4 ---- testing/test_entry_points.py | 4 ---- testing/test_helpconfig.py | 4 ---- testing/test_junitxml.py | 4 ---- testing/test_mark.py | 4 ---- testing/test_monkeypatch.py | 4 ---- testing/test_nose.py | 4 ---- testing/test_parseopt.py | 4 ---- testing/test_pastebin.py | 4 ---- testing/test_pdb.py | 4 ---- testing/test_pluginmanager.py | 4 ---- testing/test_pytester.py | 4 ---- testing/test_recwarn.py | 4 ---- testing/test_resultlog.py | 4 ---- testing/test_runner.py | 4 ---- testing/test_runner_xunit.py | 4 ---- testing/test_session.py | 4 ---- testing/test_skipping.py | 4 ---- testing/test_terminal.py | 4 ---- testing/test_tmpdir.py | 4 ---- testing/test_unittest.py | 4 ---- testing/test_warnings.py | 2 -- 80 files changed, 3 insertions(+), 312 deletions(-) diff --git a/bench/skip.py b/bench/skip.py index 2fc8240e565..f0c9d1ddbef 100644 --- a/bench/skip.py +++ b/bench/skip.py @@ -1,5 +1,3 @@ -from six.moves import range - import pytest SKIP = True diff --git a/src/_pytest/_argcomplete.py b/src/_pytest/_argcomplete.py index 455c3a7be08..95a78a926b9 100644 --- a/src/_pytest/_argcomplete.py +++ b/src/_pytest/_argcomplete.py @@ -53,10 +53,6 @@ which should throw a KeyError: 'COMPLINE' (which is properly set by the global argcomplete script). """ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import os import sys from glob import glob diff --git a/src/_pytest/_code/__init__.py b/src/_pytest/_code/__init__.py index fe755a39911..370e41dc9f3 100644 --- a/src/_pytest/_code/__init__.py +++ b/src/_pytest/_code/__init__.py @@ -1,8 +1,4 @@ """ python inspection/code generation API """ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - from .code import Code # noqa from .code import ExceptionInfo # noqa from .code import filter_traceback # noqa diff --git a/src/_pytest/_code/_py2traceback.py b/src/_pytest/_code/_py2traceback.py index 8a8b7bc000a..35dc198247a 100644 --- a/src/_pytest/_code/_py2traceback.py +++ b/src/_pytest/_code/_py2traceback.py @@ -2,11 +2,6 @@ # CHANGES: # - some_str is replaced, trying to create unicode strings # -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function -from __future__ import unicode_literals - import types from six import text_type diff --git a/src/_pytest/_code/code.py b/src/_pytest/_code/code.py index 0324a1cee82..ee056587505 100644 --- a/src/_pytest/_code/code.py +++ b/src/_pytest/_code/code.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import inspect import re import sys diff --git a/src/_pytest/_code/source.py b/src/_pytest/_code/source.py index 39701a39bb0..c0175409637 100644 --- a/src/_pytest/_code/source.py +++ b/src/_pytest/_code/source.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import ast import inspect import linecache diff --git a/src/_pytest/_io/saferepr.py b/src/_pytest/_io/saferepr.py index d817e37457c..e96c5ffbf64 100644 --- a/src/_pytest/_io/saferepr.py +++ b/src/_pytest/_io/saferepr.py @@ -1,6 +1,5 @@ import pprint - -from six.moves import reprlib +import reprlib def _call_and_format_exception(call, x, *args): diff --git a/src/_pytest/assertion/__init__.py b/src/_pytest/assertion/__init__.py index ad38e0c2d8a..e8ea6a3b70f 100644 --- a/src/_pytest/assertion/__init__.py +++ b/src/_pytest/assertion/__init__.py @@ -1,10 +1,6 @@ """ support for presenting detailed information in failing assertions. """ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import sys import six diff --git a/src/_pytest/assertion/rewrite.py b/src/_pytest/assertion/rewrite.py index 0cdfe3dc4bf..0905645c739 100644 --- a/src/_pytest/assertion/rewrite.py +++ b/src/_pytest/assertion/rewrite.py @@ -1,8 +1,4 @@ """Rewrite assertion AST to produce nice error messages""" -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import ast import errno import imp diff --git a/src/_pytest/assertion/truncate.py b/src/_pytest/assertion/truncate.py index 69d6acdef80..ed3fcafc96e 100644 --- a/src/_pytest/assertion/truncate.py +++ b/src/_pytest/assertion/truncate.py @@ -4,10 +4,6 @@ Current default behaviour is to truncate assertion explanations at ~8 terminal lines, unless running in "-vv" mode or running on CI. """ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import os import six diff --git a/src/_pytest/assertion/util.py b/src/_pytest/assertion/util.py index 828b9689756..16c3cbdb103 100644 --- a/src/_pytest/assertion/util.py +++ b/src/_pytest/assertion/util.py @@ -1,8 +1,4 @@ """Utilities for assertion debugging""" -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import pprint from collections.abc import Sequence diff --git a/src/_pytest/cacheprovider.py b/src/_pytest/cacheprovider.py index 0764d90c614..3a32f16657f 100755 --- a/src/_pytest/cacheprovider.py +++ b/src/_pytest/cacheprovider.py @@ -4,10 +4,6 @@ the name cache was not chosen to ensure pluggy automatically ignores the external pytest-cache """ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import json import os from collections import OrderedDict diff --git a/src/_pytest/capture.py b/src/_pytest/capture.py index bcfb721f1c9..b7b5ef2e578 100644 --- a/src/_pytest/capture.py +++ b/src/_pytest/capture.py @@ -2,10 +2,6 @@ per-test stdout/stderr capturing mechanism. """ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import collections import contextlib import io diff --git a/src/_pytest/compat.py b/src/_pytest/compat.py index f4820b9046e..0590175e012 100644 --- a/src/_pytest/compat.py +++ b/src/_pytest/compat.py @@ -1,10 +1,6 @@ """ python version compatibility code """ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import functools import inspect import io diff --git a/src/_pytest/config/__init__.py b/src/_pytest/config/__init__.py index 688de3cedc9..0357d8d36f1 100644 --- a/src/_pytest/config/__init__.py +++ b/src/_pytest/config/__init__.py @@ -1,8 +1,4 @@ """ command line options, ini-file and conftest.py processing. """ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import argparse import copy import inspect diff --git a/src/_pytest/debugging.py b/src/_pytest/debugging.py index 07107b2a08d..1ff2b8aa8d5 100644 --- a/src/_pytest/debugging.py +++ b/src/_pytest/debugging.py @@ -1,8 +1,4 @@ """ interactive debugging with PDB, the Python Debugger. """ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import argparse import pdb import sys diff --git a/src/_pytest/deprecated.py b/src/_pytest/deprecated.py index b65700417a4..f80773fe577 100644 --- a/src/_pytest/deprecated.py +++ b/src/_pytest/deprecated.py @@ -8,10 +8,6 @@ All constants defined in this module should be either PytestWarning instances or UnformattedWarning in case of warnings which need to format their messages. """ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - from _pytest.warning_types import PytestDeprecationWarning from _pytest.warning_types import RemovedInPytest4Warning from _pytest.warning_types import UnformattedWarning diff --git a/src/_pytest/doctest.py b/src/_pytest/doctest.py index 9f7990a146d..b109c73f34e 100644 --- a/src/_pytest/doctest.py +++ b/src/_pytest/doctest.py @@ -1,8 +1,4 @@ """ discover and run doctests in modules and test files.""" -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import inspect import platform import sys diff --git a/src/_pytest/fixtures.py b/src/_pytest/fixtures.py index b85d63ce6d7..2081ee235e8 100644 --- a/src/_pytest/fixtures.py +++ b/src/_pytest/fixtures.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import functools import inspect import itertools diff --git a/src/_pytest/freeze_support.py b/src/_pytest/freeze_support.py index 5edf3454cd9..f9d613a2b64 100644 --- a/src/_pytest/freeze_support.py +++ b/src/_pytest/freeze_support.py @@ -2,9 +2,6 @@ Provides a function to report all internal modules for using freezing tools pytest """ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function def freeze_includes(): diff --git a/src/_pytest/helpconfig.py b/src/_pytest/helpconfig.py index 756ad49cb87..7e3334e3cfa 100644 --- a/src/_pytest/helpconfig.py +++ b/src/_pytest/helpconfig.py @@ -1,8 +1,4 @@ """ version info, help messages, tracing configuration. """ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import os import sys from argparse import Action diff --git a/src/_pytest/junitxml.py b/src/_pytest/junitxml.py index c387301b5c2..9958a373c7f 100644 --- a/src/_pytest/junitxml.py +++ b/src/_pytest/junitxml.py @@ -8,10 +8,6 @@ Output conforms to https://github.com/jenkinsci/xunit-plugin/blob/master/ src/main/resources/org/jenkinsci/plugins/xunit/types/model/xsd/junit-10.xsd """ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import functools import os import re diff --git a/src/_pytest/logging.py b/src/_pytest/logging.py index 58b05ba9599..8b329ecf4d1 100644 --- a/src/_pytest/logging.py +++ b/src/_pytest/logging.py @@ -1,8 +1,4 @@ """ Access and control log capturing. """ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import logging import re from contextlib import contextmanager diff --git a/src/_pytest/main.py b/src/_pytest/main.py index a87b00abafe..49c9f9c5f82 100644 --- a/src/_pytest/main.py +++ b/src/_pytest/main.py @@ -1,8 +1,4 @@ """ core implementation of testing process: init, session, runtest loop. """ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import fnmatch import functools import os diff --git a/src/_pytest/mark/__init__.py b/src/_pytest/mark/__init__.py index e98dc5c373a..30c6e0048f5 100644 --- a/src/_pytest/mark/__init__.py +++ b/src/_pytest/mark/__init__.py @@ -1,8 +1,4 @@ """ generic mechanism for marking and selecting python functions. """ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - from .legacy import matchkeyword from .legacy import matchmark from .structures import EMPTY_PARAMETERSET_OPTION diff --git a/src/_pytest/monkeypatch.py b/src/_pytest/monkeypatch.py index 4446be0e0cc..88fa2ecd758 100644 --- a/src/_pytest/monkeypatch.py +++ b/src/_pytest/monkeypatch.py @@ -1,8 +1,4 @@ """ monkeypatching and mocking functionality. """ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import os import re import sys diff --git a/src/_pytest/nodes.py b/src/_pytest/nodes.py index 4dd0e1785c8..1c3817ba0d4 100644 --- a/src/_pytest/nodes.py +++ b/src/_pytest/nodes.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import os import warnings diff --git a/src/_pytest/nose.py b/src/_pytest/nose.py index 49238826099..16cb0b63dae 100644 --- a/src/_pytest/nose.py +++ b/src/_pytest/nose.py @@ -1,8 +1,4 @@ """ run test suites written for nose. """ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import sys import six diff --git a/src/_pytest/outcomes.py b/src/_pytest/outcomes.py index 7ee1ce7c9f1..71bd7092763 100644 --- a/src/_pytest/outcomes.py +++ b/src/_pytest/outcomes.py @@ -2,10 +2,6 @@ exception classes and constants handling test outcomes as well as functions creating them """ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import sys from packaging.version import Version diff --git a/src/_pytest/pastebin.py b/src/_pytest/pastebin.py index f0848465d30..71d81c19946 100644 --- a/src/_pytest/pastebin.py +++ b/src/_pytest/pastebin.py @@ -1,8 +1,4 @@ """ submit failure or test session information to a pastebin service. """ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import tempfile import six diff --git a/src/_pytest/pathlib.py b/src/_pytest/pathlib.py index 36c8acf36de..5ffaa84e1b1 100644 --- a/src/_pytest/pathlib.py +++ b/src/_pytest/pathlib.py @@ -14,7 +14,6 @@ from posixpath import sep as posix_sep import six -from six.moves import map if sys.version_info[:2] >= (3, 6): diff --git a/src/_pytest/pytester.py b/src/_pytest/pytester.py index a74ad33efdf..26a88ea30a2 100644 --- a/src/_pytest/pytester.py +++ b/src/_pytest/pytester.py @@ -1,8 +1,4 @@ """(disabled by default) support for testing pytest and pytest plugins.""" -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import codecs import gc import os diff --git a/src/_pytest/python.py b/src/_pytest/python.py index 219e3e2f1a9..003172dc4ec 100644 --- a/src/_pytest/python.py +++ b/src/_pytest/python.py @@ -1,8 +1,4 @@ """ Python test discovery, setup and run of test functions. """ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import collections import enum import fnmatch diff --git a/src/_pytest/python_api.py b/src/_pytest/python_api.py index 9339cb3ba1a..4508ce56a6b 100644 --- a/src/_pytest/python_api.py +++ b/src/_pytest/python_api.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import - import math import pprint import sys @@ -8,11 +6,10 @@ from collections.abc import Mapping from collections.abc import Sized from decimal import Decimal +from itertools import filterfalse from numbers import Number from more_itertools.more import always_iterable -from six.moves import filterfalse -from six.moves import zip import _pytest._code from _pytest import deprecated diff --git a/src/_pytest/recwarn.py b/src/_pytest/recwarn.py index 439127008e3..f3078d00388 100644 --- a/src/_pytest/recwarn.py +++ b/src/_pytest/recwarn.py @@ -1,8 +1,4 @@ """ recording warnings during test function execution. """ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import inspect import re import sys diff --git a/src/_pytest/resultlog.py b/src/_pytest/resultlog.py index cd3fde80fbc..3dc58ab2817 100644 --- a/src/_pytest/resultlog.py +++ b/src/_pytest/resultlog.py @@ -1,10 +1,6 @@ """ log machine-parseable test session result information in a plain text file. """ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import os import py diff --git a/src/_pytest/runner.py b/src/_pytest/runner.py index 7fb343d4ef2..40c8f5e82c4 100644 --- a/src/_pytest/runner.py +++ b/src/_pytest/runner.py @@ -1,8 +1,4 @@ """ basic collect and runtest protocol implementations """ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import bdb import os import sys diff --git a/src/_pytest/setuponly.py b/src/_pytest/setuponly.py index 4bd4ad6d88f..70d6ed12f86 100644 --- a/src/_pytest/setuponly.py +++ b/src/_pytest/setuponly.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import sys import pytest diff --git a/src/_pytest/setupplan.py b/src/_pytest/setupplan.py index 351e0be650f..697746f205a 100644 --- a/src/_pytest/setupplan.py +++ b/src/_pytest/setupplan.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import pytest diff --git a/src/_pytest/skipping.py b/src/_pytest/skipping.py index 941d0473759..53737816f5c 100644 --- a/src/_pytest/skipping.py +++ b/src/_pytest/skipping.py @@ -1,8 +1,4 @@ """ support for skip/xfail functions and markers. """ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - from _pytest.config import hookimpl from _pytest.mark.evaluate import MarkEvaluator from _pytest.outcomes import fail diff --git a/src/_pytest/terminal.py b/src/_pytest/terminal.py index 063cda0175b..99ad1f2a343 100644 --- a/src/_pytest/terminal.py +++ b/src/_pytest/terminal.py @@ -2,10 +2,6 @@ This is a good source for looking at the various reporting hooks. """ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import argparse import collections import platform diff --git a/src/_pytest/tmpdir.py b/src/_pytest/tmpdir.py index 140c75c3264..33a3628ba46 100644 --- a/src/_pytest/tmpdir.py +++ b/src/_pytest/tmpdir.py @@ -1,8 +1,4 @@ """ support for providing temporary directories to test functions. """ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import os import re import tempfile diff --git a/src/_pytest/unittest.py b/src/_pytest/unittest.py index d4ea4f3610c..da45e312f3a 100644 --- a/src/_pytest/unittest.py +++ b/src/_pytest/unittest.py @@ -1,8 +1,4 @@ """ discovery and running of std-library "unittest" style tests. """ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import sys import traceback diff --git a/src/_pytest/warnings.py b/src/_pytest/warnings.py index 5e79ec265a4..660fdef5b91 100644 --- a/src/_pytest/warnings.py +++ b/src/_pytest/warnings.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import sys import warnings from contextlib import contextmanager diff --git a/testing/acceptance_test.py b/testing/acceptance_test.py index ba17e4b1b50..3a13806f193 100644 --- a/testing/acceptance_test.py +++ b/testing/acceptance_test.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import os import sys import textwrap diff --git a/testing/code/test_code.py b/testing/code/test_code.py index 1386ad299b0..552e8d5468d 100644 --- a/testing/code/test_code.py +++ b/testing/code/test_code.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import sys from unittest import mock diff --git a/testing/code/test_excinfo.py b/testing/code/test_excinfo.py index c461f33aaf6..de8f73c6820 100644 --- a/testing/code/test_excinfo.py +++ b/testing/code/test_excinfo.py @@ -1,15 +1,11 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import operator import os +import queue import sys import textwrap import py import six -from six.moves import queue import _pytest import pytest diff --git a/testing/code/test_source.py b/testing/code/test_source.py index c72f7da5ab4..2d62a58f06a 100644 --- a/testing/code/test_source.py +++ b/testing/code/test_source.py @@ -1,10 +1,6 @@ # flake8: noqa # disable flake check on this file because some constructs are strange # or redundant on purpose and can't be disable on a line-by-line basis -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import ast import inspect import sys diff --git a/testing/deprecated_test.py b/testing/deprecated_test.py index 4818379fee3..f64db798b2c 100644 --- a/testing/deprecated_test.py +++ b/testing/deprecated_test.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import os import pytest diff --git a/testing/test_argcomplete.py b/testing/test_argcomplete.py index e0a45daad1f..98d51bc258a 100644 --- a/testing/test_argcomplete.py +++ b/testing/test_argcomplete.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import subprocess import sys diff --git a/testing/test_assertion.py b/testing/test_assertion.py index 4e19fe00a2a..79970ea97a7 100644 --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import collections.abc as collections_abc import sys import textwrap diff --git a/testing/test_assertrewrite.py b/testing/test_assertrewrite.py index f7a8f443519..b629a407728 100644 --- a/testing/test_assertrewrite.py +++ b/testing/test_assertrewrite.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import ast import glob import os diff --git a/testing/test_cacheprovider.py b/testing/test_cacheprovider.py index 21ae7e6f282..31bf530f70b 100644 --- a/testing/test_cacheprovider.py +++ b/testing/test_cacheprovider.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import os import shutil import sys diff --git a/testing/test_capture.py b/testing/test_capture.py index 54c4230fec1..f2879dce9d1 100644 --- a/testing/test_capture.py +++ b/testing/test_capture.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import contextlib import io import os diff --git a/testing/test_collection.py b/testing/test_collection.py index d6803ea89e2..0ecc7cf22f3 100644 --- a/testing/test_collection.py +++ b/testing/test_collection.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import os import pprint import sys diff --git a/testing/test_compat.py b/testing/test_compat.py index f61e2f9d9ce..7464752ac3a 100644 --- a/testing/test_compat.py +++ b/testing/test_compat.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import sys from functools import wraps diff --git a/testing/test_config.py b/testing/test_config.py index 85831144200..a406eccef14 100644 --- a/testing/test_config.py +++ b/testing/test_config.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import sys import textwrap diff --git a/testing/test_conftest.py b/testing/test_conftest.py index acb9b52b4cd..1750c02118d 100644 --- a/testing/test_conftest.py +++ b/testing/test_conftest.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import textwrap import py diff --git a/testing/test_doctest.py b/testing/test_doctest.py index d357c8607b8..0b6587b9b7a 100644 --- a/testing/test_doctest.py +++ b/testing/test_doctest.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import textwrap import pytest diff --git a/testing/test_entry_points.py b/testing/test_entry_points.py index 0adae0b1acf..9812ce998d9 100644 --- a/testing/test_entry_points.py +++ b/testing/test_entry_points.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import importlib_metadata diff --git a/testing/test_helpconfig.py b/testing/test_helpconfig.py index 9c7806d5489..ec061cad99d 100644 --- a/testing/test_helpconfig.py +++ b/testing/test_helpconfig.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import pytest from _pytest.main import EXIT_NOTESTSCOLLECTED diff --git a/testing/test_junitxml.py b/testing/test_junitxml.py index 9fcf0ac7284..808aad615b1 100644 --- a/testing/test_junitxml.py +++ b/testing/test_junitxml.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import os from xml.dom import minidom diff --git a/testing/test_mark.py b/testing/test_mark.py index a210267a8d5..997ed047230 100644 --- a/testing/test_mark.py +++ b/testing/test_mark.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import os import sys from unittest import mock diff --git a/testing/test_monkeypatch.py b/testing/test_monkeypatch.py index 5fbabc42106..efa8fe46471 100644 --- a/testing/test_monkeypatch.py +++ b/testing/test_monkeypatch.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import os import re import sys diff --git a/testing/test_nose.py b/testing/test_nose.py index 2140a4c8bf9..a114c5bb3d0 100644 --- a/testing/test_nose.py +++ b/testing/test_nose.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import pytest diff --git a/testing/test_parseopt.py b/testing/test_parseopt.py index 91f9a7d2bec..549a7efda56 100644 --- a/testing/test_parseopt.py +++ b/testing/test_parseopt.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import argparse import distutils.spawn import os diff --git a/testing/test_pastebin.py b/testing/test_pastebin.py index 7b323cabf92..29b66e6ac0e 100644 --- a/testing/test_pastebin.py +++ b/testing/test_pastebin.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import pytest diff --git a/testing/test_pdb.py b/testing/test_pdb.py index bb34442f81c..b566c12191f 100644 --- a/testing/test_pdb.py +++ b/testing/test_pdb.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import os import sys diff --git a/testing/test_pluginmanager.py b/testing/test_pluginmanager.py index 9bd8a96cb50..d70a98a8474 100644 --- a/testing/test_pluginmanager.py +++ b/testing/test_pluginmanager.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import os import sys import types diff --git a/testing/test_pytester.py b/testing/test_pytester.py index 747d3d291f4..e898d3c2ce2 100644 --- a/testing/test_pytester.py +++ b/testing/test_pytester.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import os import subprocess import sys diff --git a/testing/test_recwarn.py b/testing/test_recwarn.py index 982e246d744..10fd8a48144 100644 --- a/testing/test_recwarn.py +++ b/testing/test_recwarn.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import re import warnings diff --git a/testing/test_resultlog.py b/testing/test_resultlog.py index aba5713af52..5f284f2a287 100644 --- a/testing/test_resultlog.py +++ b/testing/test_resultlog.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import os import py diff --git a/testing/test_runner.py b/testing/test_runner.py index 444ebe7e6b4..8aedce2759e 100644 --- a/testing/test_runner.py +++ b/testing/test_runner.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import inspect import os import sys diff --git a/testing/test_runner_xunit.py b/testing/test_runner_xunit.py index 6b5752b77ad..34a086551fd 100644 --- a/testing/test_runner_xunit.py +++ b/testing/test_runner_xunit.py @@ -2,10 +2,6 @@ test correct setup/teardowns at module, class, and instance level """ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import pytest diff --git a/testing/test_session.py b/testing/test_session.py index 03f30f32b07..ebf7712037a 100644 --- a/testing/test_session.py +++ b/testing/test_session.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import pytest from _pytest.main import EXIT_NOTESTSCOLLECTED diff --git a/testing/test_skipping.py b/testing/test_skipping.py index b31a74ece65..a848650b88b 100644 --- a/testing/test_skipping.py +++ b/testing/test_skipping.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import sys import pytest diff --git a/testing/test_terminal.py b/testing/test_terminal.py index 42cdf1a737f..37f4c9dba0f 100644 --- a/testing/test_terminal.py +++ b/testing/test_terminal.py @@ -1,10 +1,6 @@ """ terminal reporting of the full testing process. """ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import collections import os import sys diff --git a/testing/test_tmpdir.py b/testing/test_tmpdir.py index 454cbbd4db2..8330c7871d2 100644 --- a/testing/test_tmpdir.py +++ b/testing/test_tmpdir.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import sys import attr diff --git a/testing/test_unittest.py b/testing/test_unittest.py index 1bc12542b4a..bee6629e84a 100644 --- a/testing/test_unittest.py +++ b/testing/test_unittest.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - import gc import pytest diff --git a/testing/test_warnings.py b/testing/test_warnings.py index db6fa9cc9ba..ad4ad614c32 100644 --- a/testing/test_warnings.py +++ b/testing/test_warnings.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - import warnings import pytest From a91fe1feddbded535a4322ab854429e3a3961fb4 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sun, 2 Jun 2019 15:32:00 -0700 Subject: [PATCH 15/23] pre-commit run pyupgrade --all-files --- doc/en/conf.py | 18 ++-- doc/en/example/assertion/failure_demo.py | 30 +++---- .../assertion/test_setup_flow_example.py | 2 +- doc/en/example/costlysetup/conftest.py | 2 +- doc/en/example/multipython.py | 2 +- doc/en/example/nonpython/conftest.py | 2 +- doc/en/example/pythoncollection.py | 2 +- src/_pytest/_argcomplete.py | 2 +- src/_pytest/_code/_py2traceback.py | 4 +- src/_pytest/_code/code.py | 36 ++++---- src/_pytest/_code/source.py | 5 +- src/_pytest/_io/saferepr.py | 13 ++- src/_pytest/assertion/__init__.py | 8 +- src/_pytest/assertion/rewrite.py | 62 +++++++------- src/_pytest/assertion/truncate.py | 4 +- src/_pytest/assertion/util.py | 84 ++++++++++--------- src/_pytest/cacheprovider.py | 15 ++-- src/_pytest/capture.py | 47 +++++------ src/_pytest/compat.py | 12 ++- src/_pytest/config/__init__.py | 44 +++++----- src/_pytest/config/argparsing.py | 17 ++-- src/_pytest/debugging.py | 22 ++--- src/_pytest/doctest.py | 8 +- src/_pytest/fixtures.py | 28 +++---- src/_pytest/helpconfig.py | 16 ++-- src/_pytest/junitxml.py | 21 +++-- src/_pytest/logging.py | 10 +-- src/_pytest/main.py | 34 +++----- src/_pytest/mark/evaluate.py | 6 +- src/_pytest/mark/legacy.py | 4 +- src/_pytest/mark/structures.py | 15 ++-- src/_pytest/monkeypatch.py | 24 +++--- src/_pytest/nodes.py | 15 ++-- src/_pytest/nose.py | 4 +- src/_pytest/outcomes.py | 6 +- src/_pytest/pastebin.py | 8 +- src/_pytest/pathlib.py | 11 ++- src/_pytest/pytester.py | 67 +++++++-------- src/_pytest/python.py | 43 +++++----- src/_pytest/python_api.py | 4 +- src/_pytest/recwarn.py | 10 +-- src/_pytest/reports.py | 27 ++---- src/_pytest/resultlog.py | 4 +- src/_pytest/runner.py | 6 +- src/_pytest/terminal.py | 41 +++++---- src/_pytest/tmpdir.py | 4 +- src/_pytest/warning_types.py | 2 +- src/_pytest/warnings.py | 4 +- testing/acceptance_test.py | 19 ++--- testing/code/test_code.py | 15 ++-- testing/code/test_excinfo.py | 29 ++++--- testing/code/test_source.py | 32 +++---- .../config/collect_pytest_prefix/conftest.py | 2 +- .../dataclasses/test_compare_dataclasses.py | 2 +- ...ompare_dataclasses_field_comparison_off.py | 2 +- .../test_compare_dataclasses_verbose.py | 2 +- .../test_compare_two_different_dataclasses.py | 4 +- .../test_extend_fixture_module_class.py | 2 +- .../test_funcarg_lookup_classlevel.py | 2 +- .../test_funcarg_lookup_modulelevel.py | 2 +- testing/io/test_saferepr.py | 6 +- testing/logging/test_fixture.py | 8 +- testing/logging/test_formatter.py | 4 +- testing/logging/test_reporting.py | 2 +- testing/python/approx.py | 6 +- testing/python/collect.py | 22 ++--- testing/python/fixtures.py | 30 +++---- testing/python/integration.py | 10 +-- testing/python/metafunc.py | 61 +++++++------- testing/python/raises.py | 11 +-- testing/python/show_fixtures_per_test.py | 2 - testing/test_argcomplete.py | 4 +- testing/test_assertion.py | 47 +++++------ testing/test_assertrewrite.py | 29 ++++--- testing/test_cacheprovider.py | 10 +-- testing/test_capture.py | 20 ++--- testing/test_collection.py | 22 ++--- testing/test_compat.py | 4 +- testing/test_config.py | 40 ++++----- testing/test_conftest.py | 6 +- testing/test_doctest.py | 18 ++-- testing/test_junitxml.py | 24 +++--- testing/test_mark.py | 10 +-- testing/test_monkeypatch.py | 16 ++-- testing/test_nose.py | 4 +- testing/test_parseopt.py | 4 +- testing/test_pastebin.py | 6 +- testing/test_pdb.py | 10 +-- testing/test_pluginmanager.py | 12 +-- testing/test_pytester.py | 20 ++--- testing/test_recwarn.py | 6 +- testing/test_reports.py | 4 +- testing/test_resultlog.py | 2 +- testing/test_runner.py | 12 +-- testing/test_session.py | 4 +- testing/test_skipping.py | 12 +-- testing/test_terminal.py | 52 ++++++------ testing/test_tmpdir.py | 8 +- testing/test_unittest.py | 2 +- testing/test_warnings.py | 2 +- 100 files changed, 739 insertions(+), 801 deletions(-) diff --git a/doc/en/conf.py b/doc/en/conf.py index 5704b03e291..42dc18fd8cf 100644 --- a/doc/en/conf.py +++ b/doc/en/conf.py @@ -62,9 +62,9 @@ master_doc = "contents" # General information about the project. -project = u"pytest" +project = "pytest" year = datetime.datetime.utcnow().year -copyright = u"2015–2019 , holger krekel and pytest-dev team" +copyright = "2015–2019 , holger krekel and pytest-dev team" # The language for content autogenerated by Sphinx. Refer to documentation @@ -232,8 +232,8 @@ ( "contents", "pytest.tex", - u"pytest Documentation", - u"holger krekel, trainer and consultant, http://merlinux.eu", + "pytest Documentation", + "holger krekel, trainer and consultant, http://merlinux.eu", "manual", ) ] @@ -265,16 +265,16 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [("usage", "pytest", u"pytest usage", [u"holger krekel at merlinux eu"], 1)] +man_pages = [("usage", "pytest", "pytest usage", ["holger krekel at merlinux eu"], 1)] # -- Options for Epub output --------------------------------------------------- # Bibliographic Dublin Core info. -epub_title = u"pytest" -epub_author = u"holger krekel at merlinux eu" -epub_publisher = u"holger krekel at merlinux eu" -epub_copyright = u"2013, holger krekel et alii" +epub_title = "pytest" +epub_author = "holger krekel at merlinux eu" +epub_publisher = "holger krekel at merlinux eu" +epub_copyright = "2013, holger krekel et alii" # The language of the text. It defaults to the language option # or en if the language is not set. diff --git a/doc/en/example/assertion/failure_demo.py b/doc/en/example/assertion/failure_demo.py index 5d36fa65924..3a307816f00 100644 --- a/doc/en/example/assertion/failure_demo.py +++ b/doc/en/example/assertion/failure_demo.py @@ -20,7 +20,7 @@ def test_generative(param1, param2): assert param1 * 2 < param2 -class TestFailing(object): +class TestFailing: def test_simple(self): def f(): return 42 @@ -40,7 +40,7 @@ def f(): assert not f() -class TestSpecialisedExplanations(object): +class TestSpecialisedExplanations: def test_eq_text(self): assert "spam" == "eggs" @@ -100,7 +100,7 @@ def test_eq_dataclass(self): from dataclasses import dataclass @dataclass - class Foo(object): + class Foo: a: int b: str @@ -112,7 +112,7 @@ def test_eq_attrs(self): import attr @attr.s - class Foo(object): + class Foo: a = attr.ib() b = attr.ib() @@ -122,7 +122,7 @@ class Foo(object): def test_attribute(): - class Foo(object): + class Foo: b = 1 i = Foo() @@ -130,14 +130,14 @@ class Foo(object): def test_attribute_instance(): - class Foo(object): + class Foo: b = 1 assert Foo().b == 2 def test_attribute_failure(): - class Foo(object): + class Foo: def _get_b(self): raise Exception("Failed to get attrib") @@ -148,10 +148,10 @@ def _get_b(self): def test_attribute_multiple(): - class Foo(object): + class Foo: b = 1 - class Bar(object): + class Bar: b = 2 assert Foo().b == Bar().b @@ -161,7 +161,7 @@ def globf(x): return x + 1 -class TestRaises(object): +class TestRaises: def test_raises(self): s = "qwe" raises(TypeError, int, s) @@ -202,7 +202,7 @@ def test_dynamic_compile_shows_nicely(): module.foo() -class TestMoreErrors(object): +class TestMoreErrors: def test_complex_error(self): def f(): return 44 @@ -252,16 +252,16 @@ def test_try_finally(self): x = 0 -class TestCustomAssertMsg(object): +class TestCustomAssertMsg: def test_single_line(self): - class A(object): + class A: a = 1 b = 2 assert A.a == b, "A.a appears not to be b" def test_multiline(self): - class A(object): + class A: a = 1 b = 2 @@ -270,7 +270,7 @@ class A(object): ), "A.a appears not to be b\nor does not appear to be b\none of those" def test_custom_repr(self): - class JSON(object): + class JSON: a = 1 def __repr__(self): diff --git a/doc/en/example/assertion/test_setup_flow_example.py b/doc/en/example/assertion/test_setup_flow_example.py index eb339f47418..0e7eded06b6 100644 --- a/doc/en/example/assertion/test_setup_flow_example.py +++ b/doc/en/example/assertion/test_setup_flow_example.py @@ -2,7 +2,7 @@ def setup_module(module): module.TestStateFullThing.classcount = 0 -class TestStateFullThing(object): +class TestStateFullThing: def setup_class(cls): cls.classcount += 1 diff --git a/doc/en/example/costlysetup/conftest.py b/doc/en/example/costlysetup/conftest.py index 57b08b5fa94..8fa9c9fe475 100644 --- a/doc/en/example/costlysetup/conftest.py +++ b/doc/en/example/costlysetup/conftest.py @@ -8,7 +8,7 @@ def setup(request): setup.finalize() -class CostlySetup(object): +class CostlySetup: def __init__(self): import time diff --git a/doc/en/example/multipython.py b/doc/en/example/multipython.py index ad6f7e2a806..c06e452df26 100644 --- a/doc/en/example/multipython.py +++ b/doc/en/example/multipython.py @@ -22,7 +22,7 @@ def python2(request, python1): return Python(request.param, python1.picklefile) -class Python(object): +class Python: def __init__(self, version, picklefile): self.pythonpath = distutils.spawn.find_executable(version) if not self.pythonpath: diff --git a/doc/en/example/nonpython/conftest.py b/doc/en/example/nonpython/conftest.py index 7c23025af9c..a1210320ea3 100644 --- a/doc/en/example/nonpython/conftest.py +++ b/doc/en/example/nonpython/conftest.py @@ -18,7 +18,7 @@ def collect(self): class YamlItem(pytest.Item): def __init__(self, name, parent, spec): - super(YamlItem, self).__init__(name, parent) + super().__init__(name, parent) self.spec = spec def runtest(self): diff --git a/doc/en/example/pythoncollection.py b/doc/en/example/pythoncollection.py index b134d809df2..8742526a191 100644 --- a/doc/en/example/pythoncollection.py +++ b/doc/en/example/pythoncollection.py @@ -6,7 +6,7 @@ def test_function(): pass -class TestClass(object): +class TestClass: def test_method(self): pass diff --git a/src/_pytest/_argcomplete.py b/src/_pytest/_argcomplete.py index 95a78a926b9..1ebf7432ca1 100644 --- a/src/_pytest/_argcomplete.py +++ b/src/_pytest/_argcomplete.py @@ -58,7 +58,7 @@ from glob import glob -class FastFilesCompleter(object): +class FastFilesCompleter: "Fast file completer class" def __init__(self, directories=True): diff --git a/src/_pytest/_code/_py2traceback.py b/src/_pytest/_code/_py2traceback.py index 35dc198247a..68c44afdabf 100644 --- a/src/_pytest/_code/_py2traceback.py +++ b/src/_pytest/_code/_py2traceback.py @@ -4,8 +4,6 @@ # import types -from six import text_type - def format_exception_only(etype, value): """Format the exception part of a traceback. @@ -80,7 +78,7 @@ def _format_final_exc_line(etype, value): def _some_str(value): try: - return text_type(value) + return str(value) except Exception: try: return bytes(value).decode("UTF-8", "replace") diff --git a/src/_pytest/_code/code.py b/src/_pytest/_code/code.py index ee056587505..c4ed961ace4 100644 --- a/src/_pytest/_code/code.py +++ b/src/_pytest/_code/code.py @@ -16,7 +16,7 @@ from _pytest._io.saferepr import saferepr -class Code(object): +class Code: """ wrapper around Python code objects """ def __init__(self, rawcode): @@ -27,7 +27,7 @@ def __init__(self, rawcode): self.firstlineno = rawcode.co_firstlineno - 1 self.name = rawcode.co_name except AttributeError: - raise TypeError("not a code object: %r" % (rawcode,)) + raise TypeError("not a code object: {!r}".format(rawcode)) self.raw = rawcode def __eq__(self, other): @@ -86,7 +86,7 @@ def getargs(self, var=False): return raw.co_varnames[:argcount] -class Frame(object): +class Frame: """Wrapper around a Python frame holding f_locals and f_globals in which expressions can be evaluated.""" @@ -149,7 +149,7 @@ def getargs(self, var=False): return retval -class TracebackEntry(object): +class TracebackEntry: """ a single entry in a traceback """ _repr_style = None @@ -309,7 +309,7 @@ def cut(self, path=None, lineno=None, firstlineno=None, excludepath=None): return self def __getitem__(self, key): - val = super(Traceback, self).__getitem__(key) + val = super().__getitem__(key) if isinstance(key, type(slice(0))): val = self.__class__(val) return val @@ -371,7 +371,7 @@ def recursionindex(self): @attr.s(repr=False) -class ExceptionInfo(object): +class ExceptionInfo: """ wraps sys.exc_info() objects and offers help for navigating the traceback. """ @@ -556,7 +556,7 @@ def match(self, regexp): @attr.s -class FormattedExcinfo(object): +class FormattedExcinfo: """ presenting information about failing Functions and Generators. """ # for traceback entries @@ -655,7 +655,7 @@ def repr_locals(self, locals): str_repr = safeformat(value) # if len(str_repr) < 70 or not isinstance(value, # (list, tuple, dict)): - lines.append("%-10s = %s" % (name, str_repr)) + lines.append("{:<10} = {}".format(name, str_repr)) # else: # self._line("%-10s =\\" % (name,)) # # XXX @@ -804,7 +804,7 @@ def repr_excinfo(self, excinfo): return ExceptionChainRepr(repr_chain) -class TerminalRepr(object): +class TerminalRepr: def __str__(self): # FYI this is called from pytest-xdist's serialization of exception # information. @@ -814,7 +814,7 @@ def __str__(self): return io.getvalue().strip() def __repr__(self): - return "<%s instance at %0x>" % (self.__class__, id(self)) + return "<{} instance at {:0x}>".format(self.__class__, id(self)) class ExceptionRepr(TerminalRepr): @@ -832,7 +832,7 @@ def toterminal(self, tw): class ExceptionChainRepr(ExceptionRepr): def __init__(self, chain): - super(ExceptionChainRepr, self).__init__() + super().__init__() self.chain = chain # reprcrash and reprtraceback of the outermost (the newest) exception # in the chain @@ -845,18 +845,18 @@ def toterminal(self, tw): if element[2] is not None: tw.line("") tw.line(element[2], yellow=True) - super(ExceptionChainRepr, self).toterminal(tw) + super().toterminal(tw) class ReprExceptionInfo(ExceptionRepr): def __init__(self, reprtraceback, reprcrash): - super(ReprExceptionInfo, self).__init__() + super().__init__() self.reprtraceback = reprtraceback self.reprcrash = reprcrash def toterminal(self, tw): self.reprtraceback.toterminal(tw) - super(ReprExceptionInfo, self).toterminal(tw) + super().toterminal(tw) class ReprTraceback(TerminalRepr): @@ -933,7 +933,9 @@ def toterminal(self, tw): self.reprfileloc.toterminal(tw) def __str__(self): - return "%s\n%s\n%s" % ("\n".join(self.lines), self.reprlocals, self.reprfileloc) + return "{}\n{}\n{}".format( + "\n".join(self.lines), self.reprlocals, self.reprfileloc + ) class ReprFileLocation(TerminalRepr): @@ -950,7 +952,7 @@ def toterminal(self, tw): if i != -1: msg = msg[:i] tw.write(self.path, bold=True, red=True) - tw.line(":%s: %s" % (self.lineno, msg)) + tw.line(":{}: {}".format(self.lineno, msg)) class ReprLocals(TerminalRepr): @@ -970,7 +972,7 @@ def toterminal(self, tw): if self.args: linesofar = "" for name, value in self.args: - ns = "%s = %s" % (name, value) + ns = "{} = {}".format(name, value) if len(ns) + len(linesofar) + 2 > tw.fullwidth: if linesofar: tw.line(linesofar) diff --git a/src/_pytest/_code/source.py b/src/_pytest/_code/source.py index c0175409637..70d5f8fcdca 100644 --- a/src/_pytest/_code/source.py +++ b/src/_pytest/_code/source.py @@ -9,10 +9,9 @@ from bisect import bisect_right import py -import six -class Source(object): +class Source: """ an immutable object holding a source code fragment, possibly deindenting it. """ @@ -29,7 +28,7 @@ def __init__(self, *parts, **kwargs): partlines = part.lines elif isinstance(part, (tuple, list)): partlines = [x.rstrip("\n") for x in part] - elif isinstance(part, six.string_types): + elif isinstance(part, str): partlines = part.split("\n") else: partlines = getsource(part, deindent=de).lines diff --git a/src/_pytest/_io/saferepr.py b/src/_pytest/_io/saferepr.py index e96c5ffbf64..74f75124f38 100644 --- a/src/_pytest/_io/saferepr.py +++ b/src/_pytest/_io/saferepr.py @@ -12,11 +12,8 @@ def _call_and_format_exception(call, x, *args): exc_info = str(exc) except Exception: exc_info = "unknown" - return '<[%s("%s") raised in repr()] %s object at 0x%x>' % ( - exc_name, - exc_info, - x.__class__.__name__, - id(x), + return '<[{}("{}") raised in repr()] {} object at 0x{:x}>'.format( + exc_name, exc_info, x.__class__.__name__, id(x) ) @@ -32,11 +29,11 @@ def repr_unicode(self, x, level): # Strictly speaking wrong on narrow builds def repr(u): if "'" not in u: - return u"'%s'" % u + return "'%s'" % u elif '"' not in u: - return u'"%s"' % u + return '"%s"' % u else: - return u"'%s'" % u.replace("'", r"\'") + return "'%s'" % u.replace("'", r"\'") s = repr(x[: self.maxstring]) if len(s) > self.maxstring: diff --git a/src/_pytest/assertion/__init__.py b/src/_pytest/assertion/__init__.py index e8ea6a3b70f..e52101c9f16 100644 --- a/src/_pytest/assertion/__init__.py +++ b/src/_pytest/assertion/__init__.py @@ -3,8 +3,6 @@ """ import sys -import six - from _pytest.assertion import rewrite from _pytest.assertion import truncate from _pytest.assertion import util @@ -51,14 +49,14 @@ def register_assert_rewrite(*names): importhook.mark_rewrite(*names) -class DummyRewriteHook(object): +class DummyRewriteHook: """A no-op import hook for when rewriting is disabled.""" def mark_rewrite(self, *names): pass -class AssertionState(object): +class AssertionState: """State for the assertion plugin.""" def __init__(self, config, mode): @@ -124,7 +122,7 @@ def callbinrepr(op, left, right): if new_expl: new_expl = truncate.truncate_if_required(new_expl, item) new_expl = [line.replace("\n", "\\n") for line in new_expl] - res = six.text_type("\n~").join(new_expl) + res = "\n~".join(new_expl) if item.config.getvalue("assertmode") == "rewrite": res = res.replace("%", "%%") return res diff --git a/src/_pytest/assertion/rewrite.py b/src/_pytest/assertion/rewrite.py index 0905645c739..4226a97b329 100644 --- a/src/_pytest/assertion/rewrite.py +++ b/src/_pytest/assertion/rewrite.py @@ -33,14 +33,14 @@ else: impl = "cpython" ver = sys.version_info - PYTEST_TAG = "%s-%s%s-PYTEST" % (impl, ver[0], ver[1]) + PYTEST_TAG = "{}-{}{}-PYTEST".format(impl, ver[0], ver[1]) del ver, impl PYC_EXT = ".py" + (__debug__ and "c" or "o") PYC_TAIL = "." + PYTEST_TAG + PYC_EXT -class AssertionRewritingHook(object): +class AssertionRewritingHook: """PEP302 Import hook which rewrites asserts.""" def __init__(self, config): @@ -149,7 +149,7 @@ def find_module(self, name, path=None): # to check for a cached pyc. This may not be optimal... co = _read_pyc(fn_pypath, pyc, state.trace) if co is None: - state.trace("rewriting %r" % (fn,)) + state.trace("rewriting {!r}".format(fn)) source_stat, co = _rewrite_test(self.config, fn_pypath) if co is None: # Probably a SyntaxError in the test. @@ -161,7 +161,7 @@ def find_module(self, name, path=None): finally: self._writing_pyc = False else: - state.trace("found cached rewritten pyc for %r" % (fn,)) + state.trace("found cached rewritten pyc for {!r}".format(fn)) self.modules[name] = co, pyc return self @@ -200,26 +200,28 @@ def _early_rewrite_bailout(self, name, state): if self._is_marked_for_rewrite(name, state): return False - state.trace("early skip of rewriting module: %s" % (name,)) + state.trace("early skip of rewriting module: {}".format(name)) return True def _should_rewrite(self, name, fn_pypath, state): # always rewrite conftest files fn = str(fn_pypath) if fn_pypath.basename == "conftest.py": - state.trace("rewriting conftest file: %r" % (fn,)) + state.trace("rewriting conftest file: {!r}".format(fn)) return True if self.session is not None: if self.session.isinitpath(fn): - state.trace("matched test file (was specified on cmdline): %r" % (fn,)) + state.trace( + "matched test file (was specified on cmdline): {!r}".format(fn) + ) return True # modules not passed explicitly on the command line are only # rewritten if they match the naming convention for test files for pat in self.fnpats: if fn_pypath.fnmatch(pat): - state.trace("matched test file %r" % (fn,)) + state.trace("matched test file {!r}".format(fn)) return True return self._is_marked_for_rewrite(name, state) @@ -230,7 +232,9 @@ def _is_marked_for_rewrite(self, name, state): except KeyError: for marked in self._must_rewrite: if name == marked or name.startswith(marked + "."): - state.trace("matched marked file %r (from %r)" % (name, marked)) + state.trace( + "matched marked file {!r} (from {!r})".format(name, marked) + ) self._marked_for_rewrite_cache[name] = True return True @@ -325,7 +329,7 @@ def _write_pyc(state, co, source_stat, pyc): fp.write(struct.pack(""]: @@ -72,13 +70,13 @@ def _format_lines(lines): for line in lines[1:]: if line.startswith("{"): if stackcnt[-1]: - s = u"and " + s = "and " else: - s = u"where " + s = "where " stack.append(len(result)) stackcnt[-1] += 1 stackcnt.append(0) - result.append(u" +" + u" " * (len(stack) - 1) + s + line[1:]) + result.append(" +" + " " * (len(stack) - 1) + s + line[1:]) elif line.startswith("}"): stack.pop() stackcnt.pop() @@ -87,7 +85,7 @@ def _format_lines(lines): assert line[0] in ["~", ">"] stack[-1] += 1 indent = len(stack) if line.startswith("~") else len(stack) - 1 - result.append(u" " * indent + line[1:]) + result.append(" " * indent + line[1:]) assert len(stack) == 1 return result @@ -137,7 +135,7 @@ def assertrepr_compare(config, op, left, right): left_repr = saferepr(left, maxsize=int(width // 2)) right_repr = saferepr(right, maxsize=width - len(left_repr)) - summary = u"%s %s %s" % (ecu(left_repr), op, ecu(right_repr)) + summary = "{} {} {}".format(ecu(left_repr), op, ecu(right_repr)) verbose = config.getoption("verbose") explanation = None @@ -170,9 +168,9 @@ def assertrepr_compare(config, op, left, right): raise except Exception: explanation = [ - u"(pytest_assertion plugin: representation of details failed. " - u"Probably an object has a faulty __repr__.)", - six.text_type(_pytest._code.ExceptionInfo.from_current()), + "(pytest_assertion plugin: representation of details failed. " + "Probably an object has a faulty __repr__.)", + str(_pytest._code.ExceptionInfo.from_current()), ] if not explanation: @@ -199,7 +197,7 @@ def escape_for_readable_diff(binary_text): This is done using repr() which then needs post-processing to fix the encompassing quotes and un-escape newlines and carriage returns (#429). """ - r = six.text_type(repr(binary_text)[1:-1]) + r = str(repr(binary_text)[1:-1]) r = r.replace(r"\n", "\n") r = r.replace(r"\r", "\r") return r @@ -216,7 +214,7 @@ def escape_for_readable_diff(binary_text): if i > 42: i -= 10 # Provide some context explanation = [ - u"Skipping %s identical leading characters in diff, use -v to show" % i + "Skipping %s identical leading characters in diff, use -v to show" % i ] left = left[i:] right = right[i:] @@ -227,8 +225,8 @@ def escape_for_readable_diff(binary_text): if i > 42: i -= 10 # Provide some context explanation += [ - u"Skipping {} identical trailing " - u"characters in diff, use -v to show".format(i) + "Skipping {} identical trailing " + "characters in diff, use -v to show".format(i) ] left = left[:-i] right = right[:-i] @@ -236,7 +234,7 @@ def escape_for_readable_diff(binary_text): if left.isspace() or right.isspace(): left = repr(str(left)) right = repr(str(right)) - explanation += [u"Strings contain only whitespace, escaping them using repr()"] + explanation += ["Strings contain only whitespace, escaping them using repr()"] explanation += [ line.strip("\n") for line in ndiff(left.splitlines(keepends), right.splitlines(keepends)) @@ -250,29 +248,29 @@ def _compare_eq_verbose(left, right): right_lines = repr(right).splitlines(keepends) explanation = [] - explanation += [u"-" + line for line in left_lines] - explanation += [u"+" + line for line in right_lines] + explanation += ["-" + line for line in left_lines] + explanation += ["+" + line for line in right_lines] return explanation def _compare_eq_iterable(left, right, verbose=0): if not verbose: - return [u"Use -v to get the full diff"] + return ["Use -v to get the full diff"] # dynamic import to speedup pytest import difflib try: left_formatting = pprint.pformat(left).splitlines() right_formatting = pprint.pformat(right).splitlines() - explanation = [u"Full diff:"] + explanation = ["Full diff:"] except Exception: # hack: PrettyPrinter.pformat() in python 2 fails when formatting items that can't be sorted(), ie, calling # sorted() on a list would raise. See issue #718. # As a workaround, the full diff is generated by using the repr() string of each item of each container. left_formatting = sorted(repr(x) for x in left) right_formatting = sorted(repr(x) for x in right) - explanation = [u"Full diff (fallback to calling repr on each item):"] + explanation = ["Full diff (fallback to calling repr on each item):"] explanation.extend( line.strip() for line in difflib.ndiff(left_formatting, right_formatting) ) @@ -285,7 +283,9 @@ def _compare_eq_sequence(left, right, verbose=0): len_right = len(right) for i in range(min(len_left, len_right)): if left[i] != right[i]: - explanation += [u"At index %s diff: %r != %r" % (i, left[i], right[i])] + explanation += [ + "At index {} diff: {!r} != {!r}".format(i, left[i], right[i]) + ] break len_diff = len_left - len_right @@ -299,10 +299,12 @@ def _compare_eq_sequence(left, right, verbose=0): extra = saferepr(right[len_left]) if len_diff == 1: - explanation += [u"%s contains one more item: %s" % (dir_with_more, extra)] + explanation += [ + "{} contains one more item: {}".format(dir_with_more, extra) + ] else: explanation += [ - u"%s contains %d more items, first extra item: %s" + "%s contains %d more items, first extra item: %s" % (dir_with_more, len_diff, extra) ] return explanation @@ -313,11 +315,11 @@ def _compare_eq_set(left, right, verbose=0): diff_left = left - right diff_right = right - left if diff_left: - explanation.append(u"Extra items in the left set:") + explanation.append("Extra items in the left set:") for item in diff_left: explanation.append(saferepr(item)) if diff_right: - explanation.append(u"Extra items in the right set:") + explanation.append("Extra items in the right set:") for item in diff_right: explanation.append(saferepr(item)) return explanation @@ -330,20 +332,20 @@ def _compare_eq_dict(left, right, verbose=0): common = set_left.intersection(set_right) same = {k: left[k] for k in common if left[k] == right[k]} if same and verbose < 2: - explanation += [u"Omitting %s identical items, use -vv to show" % len(same)] + explanation += ["Omitting %s identical items, use -vv to show" % len(same)] elif same: - explanation += [u"Common items:"] + explanation += ["Common items:"] explanation += pprint.pformat(same).splitlines() diff = {k for k in common if left[k] != right[k]} if diff: - explanation += [u"Differing items:"] + explanation += ["Differing items:"] for k in diff: explanation += [saferepr({k: left[k]}) + " != " + saferepr({k: right[k]})] extra_left = set_left - set_right len_extra_left = len(extra_left) if len_extra_left: explanation.append( - u"Left contains %d more item%s:" + "Left contains %d more item%s:" % (len_extra_left, "" if len_extra_left == 1 else "s") ) explanation.extend( @@ -353,7 +355,7 @@ def _compare_eq_dict(left, right, verbose=0): len_extra_right = len(extra_right) if len_extra_right: explanation.append( - u"Right contains %d more item%s:" + "Right contains %d more item%s:" % (len_extra_right, "" if len_extra_right == 1 else "s") ) explanation.extend( @@ -381,15 +383,15 @@ def _compare_eq_cls(left, right, verbose, type_fns): explanation = [] if same and verbose < 2: - explanation.append(u"Omitting %s identical items, use -vv to show" % len(same)) + explanation.append("Omitting %s identical items, use -vv to show" % len(same)) elif same: - explanation += [u"Matching attributes:"] + explanation += ["Matching attributes:"] explanation += pprint.pformat(same).splitlines() if diff: - explanation += [u"Differing attributes:"] + explanation += ["Differing attributes:"] for field in diff: explanation += [ - (u"%s: %r != %r") % (field, getattr(left, field), getattr(right, field)) + ("%s: %r != %r") % (field, getattr(left, field), getattr(right, field)) ] return explanation @@ -400,14 +402,14 @@ def _notin_text(term, text, verbose=0): tail = text[index + len(term) :] correct_text = head + tail diff = _diff_text(correct_text, text, verbose) - newdiff = [u"%s is contained here:" % saferepr(term, maxsize=42)] + newdiff = ["%s is contained here:" % saferepr(term, maxsize=42)] for line in diff: - if line.startswith(u"Skipping"): + if line.startswith("Skipping"): continue - if line.startswith(u"- "): + if line.startswith("- "): continue - if line.startswith(u"+ "): - newdiff.append(u" " + line[2:]) + if line.startswith("+ "): + newdiff.append(" " + line[2:]) else: newdiff.append(line) return newdiff diff --git a/src/_pytest/cacheprovider.py b/src/_pytest/cacheprovider.py index 3a32f16657f..17463959fb4 100755 --- a/src/_pytest/cacheprovider.py +++ b/src/_pytest/cacheprovider.py @@ -10,14 +10,13 @@ import attr import py -import six import pytest from .pathlib import Path from .pathlib import resolve_from_str from .pathlib import rmtree -README_CONTENT = u"""\ +README_CONTENT = """\ # pytest cache directory # This directory contains data from the pytest's cache plugin, @@ -37,7 +36,7 @@ @attr.s -class Cache(object): +class Cache: _cachedir = attr.ib(repr=False) _config = attr.ib(repr=False) @@ -136,14 +135,14 @@ def _ensure_supporting_files(self): readme_path.write_text(README_CONTENT) gitignore_path = self._cachedir.joinpath(".gitignore") - msg = u"# Created by pytest automatically.\n*" + msg = "# Created by pytest automatically.\n*" gitignore_path.write_text(msg, encoding="UTF-8") cachedir_tag_path = self._cachedir.joinpath("CACHEDIR.TAG") cachedir_tag_path.write_bytes(CACHEDIR_TAG_CONTENT) -class LFPlugin(object): +class LFPlugin: """ Plugin which implements the --lf (run last-failing) option """ def __init__(self, config): @@ -256,7 +255,7 @@ def pytest_sessionfinish(self, session): config.cache.set("cache/lastfailed", self.lastfailed) -class NFPlugin(object): +class NFPlugin: """ Plugin which implements the --nf (run new-first) option """ def __init__(self, config): @@ -275,8 +274,8 @@ def pytest_collection_modifyitems(self, session, config, items): other_items[item.nodeid] = item items[:] = self._get_increasing_order( - six.itervalues(new_items) - ) + self._get_increasing_order(six.itervalues(other_items)) + new_items.values() + ) + self._get_increasing_order(other_items.values()) self.cached_nodeids = [x.nodeid for x in items if isinstance(x, pytest.Item)] def _get_increasing_order(self, items): diff --git a/src/_pytest/capture.py b/src/_pytest/capture.py index b7b5ef2e578..302979ef4be 100644 --- a/src/_pytest/capture.py +++ b/src/_pytest/capture.py @@ -10,8 +10,6 @@ from io import UnsupportedOperation from tempfile import TemporaryFile -import six - import pytest from _pytest.compat import CaptureIO @@ -61,7 +59,7 @@ def pytest_load_initial_conftests(early_config, parser, args): sys.stderr.write(err) -class CaptureManager(object): +class CaptureManager: """ Capture plugin, manages that the appropriate capture method is enabled/disabled during collection and each test phase (setup, call, teardown). After each of those points, the captured output is obtained and @@ -80,10 +78,8 @@ def __init__(self, method): self._current_item = None def __repr__(self): - return "" % ( - self._method, - self._global_capturing, - self._current_item, + return "".format( + self._method, self._global_capturing, self._current_item ) def _getcapture(self, method): @@ -335,7 +331,7 @@ def _install_capture_fixture_on_item(request, capture_class): del request.node._capture_fixture -class CaptureFixture(object): +class CaptureFixture: """ Object returned by :py:func:`capsys`, :py:func:`capsysbinary`, :py:func:`capfd` and :py:func:`capfdbinary` fixtures. @@ -414,7 +410,7 @@ def safe_text_dupfile(f, mode, default_encoding="UTF8"): return EncodedFile(f, encoding or default_encoding) -class EncodedFile(object): +class EncodedFile: errors = "strict" # possibly needed by py3 code (issue555) def __init__(self, buffer, encoding): @@ -422,7 +418,7 @@ def __init__(self, buffer, encoding): self.encoding = encoding def write(self, obj): - if isinstance(obj, six.text_type): + if isinstance(obj, str): obj = obj.encode(self.encoding, "replace") else: raise TypeError( @@ -450,7 +446,7 @@ def __getattr__(self, name): CaptureResult = collections.namedtuple("CaptureResult", ["out", "err"]) -class MultiCapture(object): +class MultiCapture: out = err = in_ = None _state = None @@ -463,7 +459,7 @@ def __init__(self, out=True, err=True, in_=True, Capture=None): self.err = Capture(2) def __repr__(self): - return "" % ( + return "".format( self.out, self.err, self.in_, @@ -529,12 +525,12 @@ def readouterr(self): ) -class NoCapture(object): +class NoCapture: EMPTY_BUFFER = None __init__ = start = done = suspend = resume = lambda *args: None -class FDCaptureBinary(object): +class FDCaptureBinary: """Capture IO to/from a given os-level filedescriptor. snap() produces `bytes` @@ -568,10 +564,8 @@ def __init__(self, targetfd, tmpfile=None): self.tmpfile_fd = tmpfile.fileno() def __repr__(self): - return "" % ( - self.targetfd, - getattr(self, "targetfd_save", None), - self._state, + return "".format( + self.targetfd, getattr(self, "targetfd_save", None), self._state ) def start(self): @@ -613,7 +607,7 @@ def resume(self): def writeorg(self, data): """ write to original file descriptor. """ - if isinstance(data, six.text_type): + if isinstance(data, str): data = data.encode("utf8") # XXX use encoding of original stream os.write(self.targetfd_save, data) @@ -627,14 +621,14 @@ class FDCapture(FDCaptureBinary): EMPTY_BUFFER = str() def snap(self): - res = super(FDCapture, self).snap() + res = super().snap() enc = getattr(self.tmpfile, "encoding", None) if enc and isinstance(res, bytes): - res = six.text_type(res, enc, "replace") + res = str(res, enc, "replace") return res -class SysCapture(object): +class SysCapture: EMPTY_BUFFER = str() _state = None @@ -651,11 +645,8 @@ def __init__(self, fd, tmpfile=None): self.tmpfile = tmpfile def __repr__(self): - return "" % ( - self.name, - self._old, - self.tmpfile, - self._state, + return "".format( + self.name, self._old, self.tmpfile, self._state ) def start(self): @@ -697,7 +688,7 @@ def snap(self): return res -class DontReadFromInput(six.Iterator): +class DontReadFromInput: """Temporary stub class. Ideally when stdin is accessed, the capturing should be turned off, with possibly all data captured so far sent to the screen. This should be configurable, though, diff --git a/src/_pytest/compat.py b/src/_pytest/compat.py index 0590175e012..a4f3bc00319 100644 --- a/src/_pytest/compat.py +++ b/src/_pytest/compat.py @@ -148,10 +148,10 @@ def get_default_arg_names(function): _non_printable_ascii_translate_table = { - i: u"\\x{:02x}".format(i) for i in range(128) if i not in range(32, 127) + i: "\\x{:02x}".format(i) for i in range(128) if i not in range(32, 127) } _non_printable_ascii_translate_table.update( - {ord("\t"): u"\\t", ord("\r"): u"\\r", ord("\n"): u"\\n"} + {ord("\t"): "\\t", ord("\r"): "\\r", ord("\n"): "\\n"} ) @@ -191,7 +191,7 @@ def ascii_escaped(val): return _translate_non_printable(ret) -class _PytestWrapper(object): +class _PytestWrapper: """Dummy wrapper around a function object for internal use only. Used to correctly unwrap the underlying function object @@ -310,15 +310,13 @@ def _setup_collect_fakemodule(): class CaptureIO(io.TextIOWrapper): def __init__(self): - super(CaptureIO, self).__init__( - io.BytesIO(), encoding="UTF-8", newline="", write_through=True - ) + super().__init__(io.BytesIO(), encoding="UTF-8", newline="", write_through=True) def getvalue(self): return self.buffer.getvalue().decode("UTF-8") -class FuncargnamesCompatAttr(object): +class FuncargnamesCompatAttr: """ helper class so that Metafunc, Function and FixtureRequest don't need to each define the "funcargnames" compatibility attribute. """ diff --git a/src/_pytest/config/__init__.py b/src/_pytest/config/__init__.py index 0357d8d36f1..40f37480b4c 100644 --- a/src/_pytest/config/__init__.py +++ b/src/_pytest/config/__init__.py @@ -11,7 +11,6 @@ import importlib_metadata import py -import six from packaging.version import Version from pluggy import HookimplMarker from pluggy import HookspecMarker @@ -83,7 +82,7 @@ def main(args=None, plugins=None): return EXIT_USAGEERROR -class cmdline(object): # compatibility namespace +class cmdline: # compatibility namespace main = staticmethod(main) @@ -189,7 +188,7 @@ def _prepareconfig(args=None, plugins=None): try: if plugins: for plugin in plugins: - if isinstance(plugin, six.string_types): + if isinstance(plugin, str): pluginmanager.consider_pluginarg(plugin) else: pluginmanager.register(plugin) @@ -216,7 +215,7 @@ class PytestPluginManager(PluginManager): """ def __init__(self): - super(PytestPluginManager, self).__init__("pytest") + super().__init__("pytest") self._conftest_plugins = set() # state related to local conftest plugins @@ -264,7 +263,7 @@ def parse_hookimpl_opts(self, plugin, name): return method = getattr(plugin, name) - opts = super(PytestPluginManager, self).parse_hookimpl_opts(plugin, name) + opts = super().parse_hookimpl_opts(plugin, name) # consider only actual functions for hooks (#3775) if not inspect.isroutine(method): @@ -283,9 +282,7 @@ def parse_hookimpl_opts(self, plugin, name): return opts def parse_hookspec_opts(self, module_or_class, name): - opts = super(PytestPluginManager, self).parse_hookspec_opts( - module_or_class, name - ) + opts = super().parse_hookspec_opts(module_or_class, name) if opts is None: method = getattr(module_or_class, name) @@ -312,7 +309,7 @@ def register(self, plugin, name=None): ) ) return - ret = super(PytestPluginManager, self).register(plugin, name) + ret = super().register(plugin, name) if ret: self.hook.pytest_plugin_registered.call_historic( kwargs=dict(plugin=plugin, manager=self) @@ -473,7 +470,7 @@ def consider_preparse(self, args): while i < n: opt = args[i] i += 1 - if isinstance(opt, six.string_types): + if isinstance(opt, str): if opt == "-p": try: parg = args[i] @@ -534,7 +531,7 @@ def import_plugin(self, modname, consider_entry_points=False): # "terminal" or "capture". Those plugins are registered under their # basename for historic purposes but must be imported with the # _pytest prefix. - assert isinstance(modname, six.string_types), ( + assert isinstance(modname, str), ( "module name as text required, got %r" % modname ) modname = str(modname) @@ -552,20 +549,19 @@ def import_plugin(self, modname, consider_entry_points=False): try: __import__(importspec) except ImportError as e: - new_exc_message = 'Error importing plugin "%s": %s' % ( - modname, - str(e.args[0]), + new_exc_message = 'Error importing plugin "{}": {}'.format( + modname, str(e.args[0]) ) new_exc = ImportError(new_exc_message) tb = sys.exc_info()[2] - six.reraise(ImportError, new_exc, tb) + raise new_exc.with_traceback(tb) except Skipped as e: from _pytest.warnings import _issue_warning_captured _issue_warning_captured( - PytestConfigWarning("skipped plugin %r: %s" % (modname, e.msg)), + PytestConfigWarning("skipped plugin {!r}: {}".format(modname, e.msg)), self.hook, stacklevel=1, ) @@ -583,7 +579,7 @@ def _get_plugin_specs_as_list(specs): empty list is returned. """ if specs is not None and not isinstance(specs, types.ModuleType): - if isinstance(specs, six.string_types): + if isinstance(specs, str): specs = specs.split(",") if specs else [] if not isinstance(specs, (list, tuple)): raise UsageError( @@ -601,7 +597,7 @@ def _ensure_removed_sysmodule(modname): pass -class Notset(object): +class Notset: def __repr__(self): return "" @@ -621,7 +617,7 @@ def _iter_rewritable_modules(package_files): yield package_name -class Config(object): +class Config: """ access to configuration values, pluginmanager and plugin hooks. """ def __init__(self, pluginmanager): @@ -632,7 +628,7 @@ def __init__(self, pluginmanager): _a = FILE_OR_DIR self._parser = Parser( - usage="%%(prog)s [options] [%s] [%s] [...]" % (_a, _a), + usage="%(prog)s [options] [{}] [{}] [...]".format(_a, _a), processopt=self._processopt, ) #: a pluginmanager instance @@ -920,7 +916,7 @@ def _getini(self, name): try: description, type, default = self._parser._inidict[name] except KeyError: - raise ValueError("unknown configuration value: %r" % (name,)) + raise ValueError("unknown configuration value: {!r}".format(name)) value = self._get_override_ini_value(name) if value is None: try: @@ -997,8 +993,8 @@ def getoption(self, name, default=notset, skip=False): if skip: import pytest - pytest.skip("no %r option found" % (name,)) - raise ValueError("no option named %r" % (name,)) + pytest.skip("no {!r} option found".format(name)) + raise ValueError("no option named {!r}".format(name)) def getvalue(self, name, path=None): """ (deprecated, use getoption()) """ @@ -1086,4 +1082,4 @@ def _strtobool(val): elif val in ("n", "no", "f", "false", "off", "0"): return 0 else: - raise ValueError("invalid truth value %r" % (val,)) + raise ValueError("invalid truth value {!r}".format(val)) diff --git a/src/_pytest/config/argparsing.py b/src/_pytest/config/argparsing.py index cc48ed337e0..fb36c798526 100644 --- a/src/_pytest/config/argparsing.py +++ b/src/_pytest/config/argparsing.py @@ -2,14 +2,13 @@ import warnings import py -import six from _pytest.config.exceptions import UsageError FILE_OR_DIR = "file_or_dir" -class Parser(object): +class Parser: """ Parser for command line arguments and ini-file values. :ivar extra_info: dict of generic param -> value to display in case @@ -144,12 +143,12 @@ def __init__(self, msg, option): def __str__(self): if self.option_id: - return "option %s: %s" % (self.option_id, self.msg) + return "option {}: {}".format(self.option_id, self.msg) else: return self.msg -class Argument(object): +class Argument: """class that mimics the necessary behaviour of optparse.Option it's currently a least effort implementation @@ -178,7 +177,7 @@ def __init__(self, *names, **attrs): pass else: # this might raise a keyerror as well, don't want to catch that - if isinstance(typ, six.string_types): + if isinstance(typ, str): if typ == "choice": warnings.warn( "`type` argument to addoption() is the string %r." @@ -281,7 +280,7 @@ def __repr__(self): return "Argument({})".format(", ".join(args)) -class OptionGroup(object): +class OptionGroup: def __init__(self, name, description="", parser=None): self.name = name self.description = description @@ -336,10 +335,10 @@ def __init__(self, parser, extra_info=None, prog=None): def error(self, message): """Transform argparse error message into UsageError.""" - msg = "%s: error: %s" % (self.prog, message) + msg = "{}: error: {}".format(self.prog, message) if hasattr(self._parser, "_config_source_hint"): - msg = "%s (%s)" % (msg, self._parser._config_source_hint) + msg = "{} ({})".format(msg, self._parser._config_source_hint) raise UsageError(self.format_usage() + msg) @@ -351,7 +350,7 @@ def parse_args(self, args=None, namespace=None): if arg and arg[0] == "-": lines = ["unrecognized arguments: %s" % (" ".join(argv))] for k, v in sorted(self.extra_info.items()): - lines.append(" %s: %s" % (k, v)) + lines.append(" {}: {}".format(k, v)) self.error("\n".join(lines)) getattr(args, FILE_OR_DIR).extend(argv) return args diff --git a/src/_pytest/debugging.py b/src/_pytest/debugging.py index 1ff2b8aa8d5..891630b432d 100644 --- a/src/_pytest/debugging.py +++ b/src/_pytest/debugging.py @@ -69,7 +69,7 @@ def fin(): config._cleanup.append(fin) -class pytestPDB(object): +class pytestPDB: """ Pseudo PDB that defers to the real pdb. """ _pluginmanager = None @@ -123,18 +123,18 @@ def _import_pdb_cls(cls, capman): def _get_pdb_wrapper_class(cls, pdb_cls, capman): import _pytest.config - class PytestPdbWrapper(pdb_cls, object): + class PytestPdbWrapper(pdb_cls): _pytest_capman = capman _continued = False def do_debug(self, arg): cls._recursive_debug += 1 - ret = super(PytestPdbWrapper, self).do_debug(arg) + ret = super().do_debug(arg) cls._recursive_debug -= 1 return ret def do_continue(self, arg): - ret = super(PytestPdbWrapper, self).do_continue(arg) + ret = super().do_continue(arg) if cls._recursive_debug == 0: tw = _pytest.config.create_terminal_writer(cls._config) tw.line() @@ -166,7 +166,7 @@ def do_quit(self, arg): could be handled, but this would require to wrap the whole pytest run, and adjust the report etc. """ - ret = super(PytestPdbWrapper, self).do_quit(arg) + ret = super().do_quit(arg) if cls._recursive_debug == 0: outcomes.exit("Quitting debugger") @@ -182,7 +182,7 @@ def setup(self, f, tb): Needed after do_continue resumed, and entering another breakpoint again. """ - ret = super(PytestPdbWrapper, self).setup(f, tb) + ret = super().setup(f, tb) if not ret and self._continued: # pdb.setup() returns True if the command wants to exit # from the interaction: do not suspend capturing then. @@ -191,7 +191,7 @@ def setup(self, f, tb): return ret def get_stack(self, f, t): - stack, i = super(PytestPdbWrapper, self).get_stack(f, t) + stack, i = super().get_stack(f, t) if f is None: # Find last non-hidden frame. i = max(0, len(stack) - 1) @@ -225,7 +225,7 @@ def _init_pdb(cls, method, *args, **kwargs): else: capturing = cls._is_capturing(capman) if capturing == "global": - tw.sep(">", "PDB %s (IO-capturing turned off)" % (method,)) + tw.sep(">", "PDB {} (IO-capturing turned off)".format(method)) elif capturing: tw.sep( ">", @@ -233,7 +233,7 @@ def _init_pdb(cls, method, *args, **kwargs): % (method, capturing), ) else: - tw.sep(">", "PDB %s" % (method,)) + tw.sep(">", "PDB {}".format(method)) _pdb = cls._import_pdb_cls(capman)(**kwargs) @@ -249,7 +249,7 @@ def set_trace(cls, *args, **kwargs): _pdb.set_trace(frame) -class PdbInvoke(object): +class PdbInvoke: def pytest_exception_interact(self, node, call, report): capman = node.config.pluginmanager.getplugin("capturemanager") if capman: @@ -264,7 +264,7 @@ def pytest_internalerror(self, excrepr, excinfo): post_mortem(tb) -class PdbTrace(object): +class PdbTrace: @hookimpl(hookwrapper=True) def pytest_pyfunc_call(self, pyfuncitem): _test_pytest_function(pyfuncitem) diff --git a/src/_pytest/doctest.py b/src/_pytest/doctest.py index b109c73f34e..afb7ede4cc7 100644 --- a/src/_pytest/doctest.py +++ b/src/_pytest/doctest.py @@ -121,7 +121,7 @@ def toterminal(self, tw): class MultipleDoctestFailures(Exception): def __init__(self, failures): - super(MultipleDoctestFailures, self).__init__() + super().__init__() self.failures = failures @@ -176,7 +176,7 @@ def _get_runner(checker=None, verbose=None, optionflags=0, continue_on_failure=T class DoctestItem(pytest.Item): def __init__(self, name, parent, runner=None, dtest=None): - super(DoctestItem, self).__init__(name, parent) + super().__init__(name, parent) self.runner = runner self.dtest = dtest self.obj = None @@ -253,7 +253,7 @@ def repr_failure(self, excinfo): ] indent = ">>>" for line in example.source.splitlines(): - lines.append("??? %s %s" % (indent, line)) + lines.append("??? {} {}".format(indent, line)) indent = "..." if isinstance(failure, doctest.DocTestFailure): lines += checker.output_difference( @@ -266,7 +266,7 @@ def repr_failure(self, excinfo): reprlocation_lines.append((reprlocation, lines)) return ReprFailDoctest(reprlocation_lines) else: - return super(DoctestItem, self).repr_failure(excinfo) + return super().repr_failure(excinfo) def reportinfo(self): return self.fspath, self.dtest.lineno, "[doctest] %s" % self.name diff --git a/src/_pytest/fixtures.py b/src/_pytest/fixtures.py index 2081ee235e8..365f0ae6b08 100644 --- a/src/_pytest/fixtures.py +++ b/src/_pytest/fixtures.py @@ -36,7 +36,7 @@ @attr.s(frozen=True) -class PseudoFixtureDef(object): +class PseudoFixtureDef: cached_result = attr.ib() scope = attr.ib() @@ -76,7 +76,7 @@ def provide(self): if func.__name__ in scope2props[self.scope]: return func(self) raise AttributeError( - "%s not available in %s-scoped context" % (scopename, self.scope) + "{} not available in {}-scoped context".format(scopename, self.scope) ) return property(provide, None, None, func.__doc__) @@ -89,7 +89,7 @@ def get_scope_package(node, fixturedef): cls = pytest.Package current = node - fixture_package_name = "%s/%s" % (fixturedef.baseid, "__init__.py") + fixture_package_name = "{}/{}".format(fixturedef.baseid, "__init__.py") while current and ( type(current) is not cls or fixture_package_name != current.nodeid ): @@ -296,7 +296,7 @@ def get_direct_param_fixture_func(request): @attr.s(slots=True) -class FuncFixtureInfo(object): +class FuncFixtureInfo: # original function argument names argnames = attr.ib(type=tuple) # argnames that function immediately requires. These include argnames + @@ -652,7 +652,7 @@ def __init__(self, request, scope, param, param_index, fixturedef): self._fixturemanager = request._fixturemanager def __repr__(self): - return "" % (self.fixturename, self._pyfuncitem) + return "".format(self.fixturename, self._pyfuncitem) def addfinalizer(self, finalizer): self._fixturedef.addfinalizer(finalizer) @@ -665,7 +665,7 @@ def _schedule_finalizers(self, fixturedef, subrequest): fixturedef.addfinalizer( functools.partial(self._fixturedef.finish, request=self) ) - super(SubRequest, self)._schedule_finalizers(fixturedef, subrequest) + super()._schedule_finalizers(fixturedef, subrequest) scopes = "session package module class function".split() @@ -718,7 +718,7 @@ def formatrepr(self): error_msg = "file %s, line %s: source code not available" addline(error_msg % (fspath, lineno + 1)) else: - addline("file %s, line %s" % (fspath, lineno + 1)) + addline("file {}, line {}".format(fspath, lineno + 1)) for i, line in enumerate(lines): line = line.rstrip() addline(" " + line) @@ -774,7 +774,7 @@ def toterminal(self, tw): def fail_fixturefunc(fixturefunc, msg): fs, lineno = getfslineno(fixturefunc) - location = "%s:%s" % (fs, lineno + 1) + location = "{}:{}".format(fs, lineno + 1) source = _pytest._code.Source(fixturefunc) fail(msg + ":\n\n" + str(source.indent()) + "\n" + location, pytrace=False) @@ -804,7 +804,7 @@ def _teardown_yield_fixture(fixturefunc, it): ) -class FixtureDef(object): +class FixtureDef: """ A container for a factory definition. """ def __init__( @@ -889,10 +889,8 @@ def execute(self, request): return hook.pytest_fixture_setup(fixturedef=self, request=request) def __repr__(self): - return "" % ( - self.argname, - self.scope, - self.baseid, + return "".format( + self.argname, self.scope, self.baseid ) @@ -964,7 +962,7 @@ def result(*args, **kwargs): @attr.s(frozen=True) -class FixtureFunctionMarker(object): +class FixtureFunctionMarker: scope = attr.ib() params = attr.ib(converter=attr.converters.optional(tuple)) autouse = attr.ib(default=False) @@ -1078,7 +1076,7 @@ def pytest_addoption(parser): ) -class FixtureManager(object): +class FixtureManager: """ pytest fixtures definitions and information is stored and managed from this class. diff --git a/src/_pytest/helpconfig.py b/src/_pytest/helpconfig.py index 7e3334e3cfa..b379fae01dc 100644 --- a/src/_pytest/helpconfig.py +++ b/src/_pytest/helpconfig.py @@ -19,7 +19,7 @@ class HelpAction(Action): """ def __init__(self, option_strings, dest=None, default=False, help=None): - super(HelpAction, self).__init__( + super().__init__( option_strings=option_strings, dest=dest, const=True, @@ -117,7 +117,7 @@ def unset_tracing(): def showversion(config): p = py.path.local(pytest.__file__) sys.stderr.write( - "This is pytest version %s, imported from %s\n" % (pytest.__version__, p) + "This is pytest version {}, imported from {}\n".format(pytest.__version__, p) ) plugininfo = getpluginversioninfo(config) if plugininfo: @@ -155,7 +155,7 @@ def showhelp(config): help, type, default = config._parser._inidict[name] if type is None: type = "string" - spec = "%s (%s):" % (name, type) + spec = "{} ({}):".format(name, type) tw.write(" %s" % spec) spec_len = len(spec) if spec_len > (indent_len - 3): @@ -189,7 +189,7 @@ def showhelp(config): ("PYTEST_DEBUG", "set to enable debug tracing of pytest's internals"), ] for name, help in vars: - tw.line(" %-24s %s" % (name, help)) + tw.line(" {:<24} {}".format(name, help)) tw.line() tw.line() @@ -216,7 +216,7 @@ def getpluginversioninfo(config): lines.append("setuptools registered plugins:") for plugin, dist in plugininfo: loc = getattr(plugin, "__file__", repr(plugin)) - content = "%s-%s at %s" % (dist.project_name, dist.version, loc) + content = "{}-{} at {}".format(dist.project_name, dist.version, loc) lines.append(" " + content) return lines @@ -224,7 +224,9 @@ def getpluginversioninfo(config): def pytest_report_header(config): lines = [] if config.option.debug or config.option.traceconfig: - lines.append("using: pytest-%s pylib-%s" % (pytest.__version__, py.__version__)) + lines.append( + "using: pytest-{} pylib-{}".format(pytest.__version__, py.__version__) + ) verinfo = getpluginversioninfo(config) if verinfo: @@ -238,5 +240,5 @@ def pytest_report_header(config): r = plugin.__file__ else: r = repr(plugin) - lines.append(" %-20s: %s" % (name, r)) + lines.append(" {:<20}: {}".format(name, r)) return lines diff --git a/src/_pytest/junitxml.py b/src/_pytest/junitxml.py index 9958a373c7f..ea33e606c30 100644 --- a/src/_pytest/junitxml.py +++ b/src/_pytest/junitxml.py @@ -15,7 +15,6 @@ import time import py -import six import pytest from _pytest import nodes @@ -34,12 +33,12 @@ class Junit(py.xml.Namespace): _legal_chars = (0x09, 0x0A, 0x0D) _legal_ranges = ((0x20, 0x7E), (0x80, 0xD7FF), (0xE000, 0xFFFD), (0x10000, 0x10FFFF)) _legal_xml_re = [ - u"%s-%s" % (six.unichr(low), six.unichr(high)) + "{}-{}".format(chr(low), chr(high)) for (low, high) in _legal_ranges if low < sys.maxunicode ] -_legal_xml_re = [six.unichr(x) for x in _legal_chars] + _legal_xml_re -illegal_xml_re = re.compile(u"[^%s]" % u"".join(_legal_xml_re)) +_legal_xml_re = [chr(x) for x in _legal_chars] + _legal_xml_re +illegal_xml_re = re.compile("[^%s]" % "".join(_legal_xml_re)) del _legal_chars del _legal_ranges del _legal_xml_re @@ -51,9 +50,9 @@ def bin_xml_escape(arg): def repl(matchobj): i = ord(matchobj.group()) if i <= 0xFF: - return u"#x%02X" % i + return "#x%02X" % i else: - return u"#x%04X" % i + return "#x%04X" % i return py.xml.raw(illegal_xml_re.sub(repl, py.xml.escape(arg))) @@ -80,7 +79,7 @@ def merge_family(left, right): families["xunit2"] = families["_base"] -class _NodeReporter(object): +class _NodeReporter: def __init__(self, nodeid, xml): self.id = nodeid self.xml = xml @@ -220,7 +219,7 @@ def append_failure(self, report): else: if hasattr(report.longrepr, "reprcrash"): message = report.longrepr.reprcrash.message - elif isinstance(report.longrepr, six.string_types): + elif isinstance(report.longrepr, str): message = report.longrepr else: message = str(report.longrepr) @@ -259,7 +258,7 @@ def append_skipped(self, report): filename, lineno, skipreason = report.longrepr if skipreason.startswith("Skipped: "): skipreason = skipreason[9:] - details = "%s:%s: %s" % (filename, lineno, skipreason) + details = "{}:{}: {}".format(filename, lineno, skipreason) self.append( Junit.skipped( @@ -344,7 +343,7 @@ def _check_record_param_type(param, v): """Used by record_testsuite_property to check that the given parameter name is of the proper type""" __tracebackhide__ = True - if not isinstance(v, six.string_types): + if not isinstance(v, str): msg = "{param} parameter needs to be a string, but {g} given" raise TypeError(msg.format(param=param, g=type(v).__name__)) @@ -464,7 +463,7 @@ def mangle_test_address(address): return names -class LogXML(object): +class LogXML: def __init__( self, logfile, diff --git a/src/_pytest/logging.py b/src/_pytest/logging.py index 8b329ecf4d1..f3034d8e5dd 100644 --- a/src/_pytest/logging.py +++ b/src/_pytest/logging.py @@ -37,7 +37,7 @@ class ColoredLevelFormatter(logging.Formatter): LEVELNAME_FMT_REGEX = re.compile(r"%\(levelname\)([+-.]?\d*s)") def __init__(self, terminalwriter, *args, **kwargs): - super(ColoredLevelFormatter, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self._original_fmt = self._style._fmt self._level_to_fmt_mapping = {} @@ -63,7 +63,7 @@ def __init__(self, terminalwriter, *args, **kwargs): def format(self, record): fmt = self._level_to_fmt_mapping.get(record.levelno, self._original_fmt) self._style._fmt = fmt - return super(ColoredLevelFormatter, self).format(record) + return super().format(record) if not six.PY2: @@ -235,7 +235,7 @@ def reset(self): self.stream = py.io.TextIO() -class LogCaptureFixture(object): +class LogCaptureFixture: """Provides access and control of log capturing.""" def __init__(self, item): @@ -382,7 +382,7 @@ def get_actual_log_level(config, *setting_names): else: return - if isinstance(log_level, six.string_types): + if isinstance(log_level, str): log_level = log_level.upper() try: return int(getattr(logging, log_level, log_level)) @@ -401,7 +401,7 @@ def pytest_configure(config): config.pluginmanager.register(LoggingPlugin(config), "logging-plugin") -class LoggingPlugin(object): +class LoggingPlugin: """Attaches to the logging module and captures log messages for each test. """ diff --git a/src/_pytest/main.py b/src/_pytest/main.py index 49c9f9c5f82..735d60bd68e 100644 --- a/src/_pytest/main.py +++ b/src/_pytest/main.py @@ -8,7 +8,6 @@ import attr import py -import six import _pytest._code from _pytest import nodes @@ -166,7 +165,7 @@ def pytest_addoption(parser): ) -class _ConfigDeprecated(object): +class _ConfigDeprecated: def __init__(self, config): self.__dict__["_config"] = config @@ -305,10 +304,7 @@ def pytest_ignore_collect(path, config): if excludeglobopt: ignore_globs.extend([py.path.local(x) for x in excludeglobopt]) - if any( - fnmatch.fnmatch(six.text_type(path), six.text_type(glob)) - for glob in ignore_globs - ): + if any(fnmatch.fnmatch(str(path), str(glob)) for glob in ignore_globs): return True allow_in_venv = config.getoption("collect_in_virtualenv") @@ -336,7 +332,7 @@ def pytest_collection_modifyitems(items, config): items[:] = remaining -class FSHookProxy(object): +class FSHookProxy: def __init__(self, fspath, pm, remove_mods): self.fspath = fspath self.pm = pm @@ -476,8 +472,8 @@ def _perform_collect(self, args, genitems): if self._notfound: errors = [] for arg, exc in self._notfound: - line = "(no name %r in any of %r)" % (arg, exc.args[0]) - errors.append("not found: %s\n%s" % (arg, line)) + line = "(no name {!r} in any of {!r})".format(arg, exc.args[0]) + errors.append("not found: {}\n{}".format(arg, line)) # XXX: test this raise UsageError(*errors) if not genitems: @@ -494,8 +490,7 @@ def collect(self): self.trace("processing argument", arg) self.trace.root.indent += 1 try: - for x in self._collect(arg): - yield x + yield from self._collect(arg) except NoMatch: # we are inside a make_report hook so # we cannot directly pass through the exception @@ -532,7 +527,7 @@ def _collect(self, arg): # If it's a directory argument, recurse and look for any Subpackages. # Let the Package collector deal with subnodes, don't collect here. if argpath.check(dir=1): - assert not names, "invalid arg %r" % (arg,) + assert not names, "invalid arg {!r}".format(arg) seen_dirs = set() for path in argpath.visit( @@ -577,15 +572,13 @@ def _collect(self, arg): if argpath.basename == "__init__.py": yield next(m[0].collect()) return - for y in m: - yield y + yield from m def _collectfile(self, path, handle_dupes=True): - assert path.isfile(), "%r is not a file (isdir=%r, exists=%r, islink=%r)" % ( - path, - path.isdir(), - path.exists(), - path.islink(), + assert ( + path.isfile() + ), "{!r} is not a file (isdir={!r}, exists={!r}, islink={!r})".format( + path, path.isdir(), path.exists(), path.islink() ) ihook = self.gethookproxy(path) if not self.isinitpath(path): @@ -713,6 +706,5 @@ def genitems(self, node): rep = collect_one_node(node) if rep.passed: for subnode in rep.result: - for x in self.genitems(subnode): - yield x + yield from self.genitems(subnode) node.ihook.pytest_collectreport(report=rep) diff --git a/src/_pytest/mark/evaluate.py b/src/_pytest/mark/evaluate.py index 793bff79e83..898278e30b3 100644 --- a/src/_pytest/mark/evaluate.py +++ b/src/_pytest/mark/evaluate.py @@ -3,8 +3,6 @@ import sys import traceback -import six - from ..outcomes import fail from ..outcomes import TEST_OUTCOME @@ -22,7 +20,7 @@ def cached_eval(config, expr, d): return x -class MarkEvaluator(object): +class MarkEvaluator: def __init__(self, item, name): self.item = item self._marks = None @@ -86,7 +84,7 @@ def _istrue(self): for expr in args: self.expr = expr - if isinstance(expr, six.string_types): + if isinstance(expr, str): d = self._getglobals() result = cached_eval(self.item.config, expr, d) else: diff --git a/src/_pytest/mark/legacy.py b/src/_pytest/mark/legacy.py index f784ffa2043..d14ea3a8274 100644 --- a/src/_pytest/mark/legacy.py +++ b/src/_pytest/mark/legacy.py @@ -10,7 +10,7 @@ @attr.s -class MarkMapping(object): +class MarkMapping: """Provides a local mapping for markers where item access resolves to True if the marker is present. """ @@ -25,7 +25,7 @@ def __getitem__(self, name): return name in self.own_mark_names -class KeywordMapping(object): +class KeywordMapping: """Provides a local mapping for keywords. Given a list of names, map any substring of one of these names to True. """ diff --git a/src/_pytest/mark/structures.py b/src/_pytest/mark/structures.py index e44ba14e0d3..39cdb57e46d 100644 --- a/src/_pytest/mark/structures.py +++ b/src/_pytest/mark/structures.py @@ -5,7 +5,6 @@ from operator import attrgetter import attr -import six from ..compat import ascii_escaped from ..compat import getfslineno @@ -71,7 +70,7 @@ def param(cls, *values, **kwargs): id_ = kwargs.pop("id", None) if id_ is not None: - if not isinstance(id_, six.string_types): + if not isinstance(id_, str): raise TypeError( "Expected id to be a string, got {}: {!r}".format(type(id_), id_) ) @@ -157,7 +156,7 @@ def _for_parametrize(cls, argnames, argvalues, func, config, function_definition @attr.s(frozen=True) -class Mark(object): +class Mark: #: name of the mark name = attr.ib(type=str) #: positional arguments of the mark decorator @@ -180,7 +179,7 @@ def combined_with(self, other): @attr.s -class MarkDecorator(object): +class MarkDecorator: """ A decorator for test functions and test classes. When applied it will create :class:`MarkInfo` objects which may be :ref:`retrieved by hooks as item keywords `. @@ -228,7 +227,7 @@ def __eq__(self, other): return self.mark == other.mark if isinstance(other, MarkDecorator) else False def __repr__(self): - return "" % (self.mark,) + return "".format(self.mark) def with_args(self, *args, **kwargs): """ return a MarkDecorator with extra arguments added @@ -289,7 +288,7 @@ def store_mark(obj, mark): obj.pytestmark = get_unpacked_marks(obj) + [mark] -class MarkGenerator(object): +class MarkGenerator: """ Factory for :class:`MarkDecorator` objects - exposed as a ``pytest.mark`` singleton instance. Example:: @@ -376,11 +375,11 @@ def __len__(self): return len(self._seen()) def __repr__(self): - return "" % (self.node,) + return "".format(self.node) @attr.s(cmp=False, hash=False) -class NodeMarkers(object): +class NodeMarkers: """ internal structure for storing marks belonging to a node diff --git a/src/_pytest/monkeypatch.py b/src/_pytest/monkeypatch.py index 88fa2ecd758..090bf61d6e9 100644 --- a/src/_pytest/monkeypatch.py +++ b/src/_pytest/monkeypatch.py @@ -5,8 +5,6 @@ import warnings from contextlib import contextmanager -import six - import pytest from _pytest.fixtures import fixture from _pytest.pathlib import Path @@ -62,7 +60,7 @@ def resolve(name): if expected == used: raise else: - raise ImportError("import error in %s: %s" % (used, ex)) + raise ImportError("import error in {}: {}".format(used, ex)) found = annotated_getattr(found, part, used) return found @@ -72,14 +70,18 @@ def annotated_getattr(obj, name, ann): obj = getattr(obj, name) except AttributeError: raise AttributeError( - "%r object at %s has no attribute %r" % (type(obj).__name__, ann, name) + "{!r} object at {} has no attribute {!r}".format( + type(obj).__name__, ann, name + ) ) return obj def derive_importpath(import_path, raising): - if not isinstance(import_path, six.string_types) or "." not in import_path: - raise TypeError("must be absolute import path string, not %r" % (import_path,)) + if not isinstance(import_path, str) or "." not in import_path: + raise TypeError( + "must be absolute import path string, not {!r}".format(import_path) + ) module, attr = import_path.rsplit(".", 1) target = resolve(module) if raising: @@ -87,7 +89,7 @@ def derive_importpath(import_path, raising): return attr, target -class Notset(object): +class Notset: def __repr__(self): return "" @@ -95,7 +97,7 @@ def __repr__(self): notset = Notset() -class MonkeyPatch(object): +class MonkeyPatch: """ Object returned by the ``monkeypatch`` fixture keeping a record of setattr/item/env/syspath changes. """ @@ -146,7 +148,7 @@ def setattr(self, target, name, value=notset, raising=True): import inspect if value is notset: - if not isinstance(target, six.string_types): + if not isinstance(target, str): raise TypeError( "use setattr(target, name, value) or " "setattr(target, value) with target being a dotted " @@ -157,7 +159,7 @@ def setattr(self, target, name, value=notset, raising=True): oldval = getattr(target, name, notset) if raising and oldval is notset: - raise AttributeError("%r has no attribute %r" % (target, name)) + raise AttributeError("{!r} has no attribute {!r}".format(target, name)) # avoid class descriptors like staticmethod/classmethod if inspect.isclass(target): @@ -180,7 +182,7 @@ def delattr(self, target, name=notset, raising=True): import inspect if name is notset: - if not isinstance(target, six.string_types): + if not isinstance(target, str): raise TypeError( "use delattr(target, name) or " "delattr(target) with target being a dotted " diff --git a/src/_pytest/nodes.py b/src/_pytest/nodes.py index 1c3817ba0d4..f476e414168 100644 --- a/src/_pytest/nodes.py +++ b/src/_pytest/nodes.py @@ -2,7 +2,6 @@ import warnings import py -import six import _pytest._code from _pytest.compat import getfslineno @@ -50,7 +49,7 @@ def ischildnode(baseid, nodeid): return node_parts[: len(base_parts)] == base_parts -class Node(object): +class Node: """ base class for Collector and Item the test collection tree. Collector subclasses have children, Items are terminal nodes.""" @@ -98,7 +97,7 @@ def ihook(self): return self.session.gethookproxy(self.fspath) def __repr__(self): - return "<%s %s>" % (self.__class__.__name__, getattr(self, "name", None)) + return "<{} {}>".format(self.__class__.__name__, getattr(self, "name", None)) def warn(self, warning): """Issue a warning for this item. @@ -168,7 +167,7 @@ def add_marker(self, marker, append=True): """ from _pytest.mark import MarkDecorator, MARK_GEN - if isinstance(marker, six.string_types): + if isinstance(marker, str): marker = getattr(MARK_GEN, marker) elif not isinstance(marker, MarkDecorator): raise ValueError("is not a string or pytest.mark.* Marker") @@ -239,7 +238,7 @@ def _prunetraceback(self, excinfo): def _repr_failure_py(self, excinfo, style=None): if excinfo.errisinstance(fail.Exception): if not excinfo.value.pytrace: - return six.text_type(excinfo.value) + return str(excinfo.value) fm = self.session._fixturemanager if excinfo.errisinstance(fm.FixtureLookupError): return excinfo.value.formatrepr() @@ -366,9 +365,7 @@ def __init__(self, fspath, parent=None, config=None, session=None, nodeid=None): if nodeid and os.sep != SEP: nodeid = nodeid.replace(os.sep, SEP) - super(FSCollector, self).__init__( - name, parent, config, session, nodeid=nodeid, fspath=fspath - ) + super().__init__(name, parent, config, session, nodeid=nodeid, fspath=fspath) class File(FSCollector): @@ -383,7 +380,7 @@ class Item(Node): nextitem = None def __init__(self, name, parent=None, config=None, session=None, nodeid=None): - super(Item, self).__init__(name, parent, config, session, nodeid=nodeid) + super().__init__(name, parent, config, session, nodeid=nodeid) self._report_sections = [] #: user properties is a list of tuples (name, value) that holds user diff --git a/src/_pytest/nose.py b/src/_pytest/nose.py index 16cb0b63dae..bb5ca198c79 100644 --- a/src/_pytest/nose.py +++ b/src/_pytest/nose.py @@ -1,8 +1,6 @@ """ run test suites written for nose. """ import sys -import six - import pytest from _pytest import python from _pytest import runner @@ -23,7 +21,7 @@ def pytest_runtest_makereport(item, call): if call.excinfo and call.excinfo.errisinstance(get_skip_exceptions()): # let's substitute the excinfo with a pytest.skip one call2 = runner.CallInfo.from_call( - lambda: pytest.skip(six.text_type(call.excinfo.value)), call.when + lambda: pytest.skip(str(call.excinfo.value)), call.when ) call.excinfo = call2.excinfo diff --git a/src/_pytest/outcomes.py b/src/_pytest/outcomes.py index 71bd7092763..c63c80e106d 100644 --- a/src/_pytest/outcomes.py +++ b/src/_pytest/outcomes.py @@ -23,7 +23,7 @@ def __repr__(self): if isinstance(val, bytes): val = val.decode("UTF-8", errors="replace") return val - return "<%s instance>" % (self.__class__.__name__,) + return "<{} instance>".format(self.__class__.__name__) __str__ = __repr__ @@ -53,7 +53,7 @@ class Exit(Exception): def __init__(self, msg="unknown reason", returncode=None): self.msg = msg self.returncode = returncode - super(Exit, self).__init__(msg) + super().__init__(msg) # exposed helper methods @@ -166,7 +166,7 @@ def importorskip(modname, minversion=None, reason=None): import_exc = exc if import_exc: if reason is None: - reason = "could not import %r: %s" % (modname, import_exc) + reason = "could not import {!r}: {}".format(modname, import_exc) raise Skipped(reason, allow_module_level=True) mod = sys.modules[modname] if minversion is None: diff --git a/src/_pytest/pastebin.py b/src/_pytest/pastebin.py index 71d81c19946..ce0e73accc2 100644 --- a/src/_pytest/pastebin.py +++ b/src/_pytest/pastebin.py @@ -1,8 +1,6 @@ """ submit failure or test session information to a pastebin service. """ import tempfile -import six - import pytest @@ -33,7 +31,7 @@ def pytest_configure(config): def tee_write(s, **kwargs): oldwrite(s, **kwargs) - if isinstance(s, six.text_type): + if isinstance(s, str): s = s.encode("utf-8") config._pastebinfile.write(s) @@ -72,7 +70,7 @@ def create_new_paste(contents): response = urlopen(url, data=urlencode(params).encode("ascii")).read() m = re.search(r'href="/raw/(\w+)"', response.decode("utf-8")) if m: - return "%s/show/%s" % (url, m.group(1)) + return "{}/show/{}".format(url, m.group(1)) else: return "bad response: " + response @@ -97,4 +95,4 @@ def pytest_terminal_summary(terminalreporter): s = tw.stringio.getvalue() assert len(s) pastebinurl = create_new_paste(s) - tr.write_line("%s --> %s" % (msg, pastebinurl)) + tr.write_line("{} --> {}".format(msg, pastebinurl)) diff --git a/src/_pytest/pathlib.py b/src/_pytest/pathlib.py index 5ffaa84e1b1..09b1bb3d53e 100644 --- a/src/_pytest/pathlib.py +++ b/src/_pytest/pathlib.py @@ -13,8 +13,6 @@ from os.path import sep from posixpath import sep as posix_sep -import six - if sys.version_info[:2] >= (3, 6): from pathlib import Path, PurePath @@ -128,9 +126,10 @@ def create_cleanup_lock(p): fd = os.open(str(lock_path), os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o644) except OSError as e: if e.errno == errno.EEXIST: - six.raise_from( - EnvironmentError("cannot create lockfile in {path}".format(path=p)), e - ) + raise EnvironmentError( + "cannot create lockfile in {path}".format(path=p) + ) from e + else: raise else: @@ -296,7 +295,7 @@ def fnmatch_ex(pattern, path): if sep not in pattern: name = path.name else: - name = six.text_type(path) + name = str(path) return fnmatch.fnmatch(name, pattern) diff --git a/src/_pytest/pytester.py b/src/_pytest/pytester.py index 26a88ea30a2..572a41f895c 100644 --- a/src/_pytest/pytester.py +++ b/src/_pytest/pytester.py @@ -13,7 +13,6 @@ from weakref import WeakKeyDictionary import py -import six import pytest from _pytest._code import Source @@ -28,7 +27,7 @@ from _pytest.pathlib import Path IGNORE_PAM = [ # filenames added when obtaining details about the current user - u"/var/lib/sss/mc/passwd" + "/var/lib/sss/mc/passwd" ] @@ -78,7 +77,7 @@ def raise_on_kwargs(kwargs): ) -class LsofFdLeakChecker(object): +class LsofFdLeakChecker: def get_open_files(self): out = self._exec_lsof() open_files = self._parse_lsof_output(out) @@ -160,7 +159,7 @@ def _pytest(request): return PytestArg(request) -class PytestArg(object): +class PytestArg: def __init__(self, request): self.request = request @@ -175,7 +174,7 @@ def get_public_names(values): return [x for x in values if x[0] != "_"] -class ParsedCall(object): +class ParsedCall: def __init__(self, name, kwargs): self.__dict__.update(kwargs) self._name = name @@ -183,10 +182,10 @@ def __init__(self, name, kwargs): def __repr__(self): d = self.__dict__.copy() del d["_name"] - return "" % (self._name, d) + return "".format(self._name, d) -class HookRecorder(object): +class HookRecorder: """Record all hooks called in a plugin manager. This wraps all the hook calls in the plugin manager, recording each call @@ -233,7 +232,7 @@ def assert_contains(self, entries): break print("NONAMEMATCH", name, "with", call) else: - pytest.fail("could not find %r check %r" % (name, check)) + pytest.fail("could not find {!r} check {!r}".format(name, check)) def popcall(self, name): __tracebackhide__ = True @@ -241,7 +240,7 @@ def popcall(self, name): if call._name == name: del self.calls[i] return call - lines = ["could not find call %r, in:" % (name,)] + lines = ["could not find call {!r}, in:".format(name)] lines.extend([" %s" % x for x in self.calls]) pytest.fail("\n".join(lines)) @@ -278,7 +277,9 @@ def matchreport( ) if len(values) > 1: raise ValueError( - "found 2 or more testreports matching %r: %s" % (inamepart, values) + "found 2 or more testreports matching {!r}: {}".format( + inamepart, values + ) ) return values[0] @@ -352,7 +353,7 @@ def _config_for_test(): rex_outcome = re.compile(r"(\d+) ([\w-]+)") -class RunResult(object): +class RunResult: """The result of running a command. Attributes: @@ -424,7 +425,7 @@ def assert_outcomes( assert obtained == expected -class CwdSnapshot(object): +class CwdSnapshot: def __init__(self): self.__saved = os.getcwd() @@ -432,7 +433,7 @@ def restore(self): os.chdir(self.__saved) -class SysModulesSnapshot(object): +class SysModulesSnapshot: def __init__(self, preserve=None): self.__preserve = preserve self.__saved = dict(sys.modules) @@ -446,7 +447,7 @@ def restore(self): sys.modules.update(self.__saved) -class SysPathsSnapshot(object): +class SysPathsSnapshot: def __init__(self): self.__saved = list(sys.path), list(sys.meta_path) @@ -454,7 +455,7 @@ def restore(self): sys.path[:], sys.meta_path[:] = self.__saved -class Testdir(object): +class Testdir: """Temporary test directory with tools to test/run pytest itself. This is based on the ``tmpdir`` fixture but provides a number of methods @@ -507,7 +508,7 @@ def __init__(self, request, tmpdir_factory): self._env_run_update = {"HOME": tmphome, "USERPROFILE": tmphome} def __repr__(self): - return "" % (self.tmpdir,) + return "".format(self.tmpdir) def __str__(self): return str(self.tmpdir) @@ -552,10 +553,10 @@ def _makefile(self, ext, args, kwargs, encoding="utf-8"): items = list(kwargs.items()) def to_text(s): - return s.decode(encoding) if isinstance(s, bytes) else six.text_type(s) + return s.decode(encoding) if isinstance(s, bytes) else str(s) if args: - source = u"\n".join(to_text(x) for x in args) + source = "\n".join(to_text(x) for x in args) basename = self.request.function.__name__ items.insert(0, (basename, source)) @@ -564,7 +565,7 @@ def to_text(s): p = self.tmpdir.join(basename).new(ext=ext) p.dirpath().ensure_dir() source = Source(value) - source = u"\n".join(to_text(line) for line in source.lines) + source = "\n".join(to_text(line) for line in source.lines) p.write(source.strip().encode(encoding), "wb") if ret is None: ret = p @@ -833,7 +834,7 @@ def revert_warn_already_imported(): rec = [] - class Collect(object): + class Collect: def pytest_configure(x, config): rec.append(self.make_hook_recorder(config.pluginmanager)) @@ -843,7 +844,7 @@ def pytest_configure(x, config): reprec = rec.pop() else: - class reprec(object): + class reprec: pass reprec.ret = ret @@ -875,13 +876,13 @@ def runpytest_inprocess(self, *args, **kwargs): reprec = self.inline_run(*args, **kwargs) except SystemExit as e: - class reprec(object): + class reprec: ret = e.args[0] except Exception: traceback.print_exc() - class reprec(object): + class reprec: ret = 3 finally: @@ -963,10 +964,8 @@ def getitem(self, source, funcname="test_func"): for item in items: if item.name == funcname: return item - assert 0, "%r item not found in module:\n%s\nitems: %s" % ( - funcname, - source, - items, + assert 0, "{!r} item not found in module:\n{}\nitems: {}".format( + funcname, source, items ) def getitems(self, source): @@ -1143,7 +1142,7 @@ def _dump_lines(self, lines, fp): for line in lines: print(line, file=fp) except UnicodeEncodeError: - print("couldn't print to %s because of encoding" % (fp,)) + print("couldn't print to {} because of encoding".format(fp)) def _getpytestargs(self): return sys.executable, "-mpytest" @@ -1200,7 +1199,7 @@ def spawn_pytest(self, string, expect_timeout=10.0): """ basetemp = self.tmpdir.mkdir("temp-pexpect") invoke = " ".join(map(str, self._getpytestargs())) - cmd = "%s --basetemp=%s %s" % (invoke, basetemp, string) + cmd = "{} --basetemp={} {}".format(invoke, basetemp, string) return self.spawn(cmd, expect_timeout=expect_timeout) def spawn(self, cmd, expect_timeout=10.0): @@ -1230,10 +1229,12 @@ def getdecoded(out): try: return out.decode("utf-8") except UnicodeDecodeError: - return "INTERNAL not-utf8-decodeable, truncated string:\n%s" % (saferepr(out),) + return "INTERNAL not-utf8-decodeable, truncated string:\n{}".format( + saferepr(out) + ) -class LineComp(object): +class LineComp: def __init__(self): self.stringio = py.io.TextIO() @@ -1251,7 +1252,7 @@ def assert_contains_lines(self, lines2): return LineMatcher(lines1).fnmatch_lines(lines2) -class LineMatcher(object): +class LineMatcher: """Flexible matching of text. This is a convenience class to test large texts like the output of @@ -1389,5 +1390,5 @@ def _match_lines(self, lines2, match_func, match_nickname): self._log(" and:", repr(nextline)) extralines.append(nextline) else: - self._log("remains unmatched: %r" % (line,)) + self._log("remains unmatched: {!r}".format(line)) pytest.fail(self._log_text) diff --git a/src/_pytest/python.py b/src/_pytest/python.py index 003172dc4ec..b4d8f5ae0b0 100644 --- a/src/_pytest/python.py +++ b/src/_pytest/python.py @@ -10,7 +10,6 @@ from textwrap import dedent import py -import six import _pytest from _pytest import deprecated @@ -49,8 +48,8 @@ def get(self): if node is not None: return node.obj - doc = "python %s object this node was collected from (can be None)." % ( - name.lower(), + doc = "python {} object this node was collected from (can be None).".format( + name.lower() ) return property(get, None, None, doc) @@ -233,7 +232,7 @@ def pytest_make_parametrize_id(config, val, argname=None): return None -class PyobjContext(object): +class PyobjContext: module = pyobj_property("Module") cls = pyobj_property("Class") instance = pyobj_property("Instance") @@ -243,7 +242,7 @@ class PyobjMixin(PyobjContext): _ALLOW_MARKERS = True def __init__(self, *k, **kw): - super(PyobjMixin, self).__init__(*k, **kw) + super().__init__(*k, **kw) @property def obj(self): @@ -415,7 +414,7 @@ def _genfunctions(self, name, funcobj): fixtureinfo.prune_dependency_tree() for callspec in metafunc._calls: - subname = "%s[%s]" % (name, callspec.id) + subname = "{}[{}]".format(name, callspec.id) yield Function( name=subname, parent=self, @@ -437,7 +436,7 @@ def collect(self): self._inject_setup_module_fixture() self._inject_setup_function_fixture() self.session._fixturemanager.parsefactories(self) - return super(Module, self).collect() + return super().collect() def _inject_setup_module_fixture(self): """Injects a hidden autouse, module scoped fixture into the collected module object @@ -600,11 +599,10 @@ def gethookproxy(self, fspath): return proxy def _collectfile(self, path, handle_dupes=True): - assert path.isfile(), "%r is not a file (isdir=%r, exists=%r, islink=%r)" % ( - path, - path.isdir(), - path.exists(), - path.islink(), + assert ( + path.isfile() + ), "{!r} is not a file (isdir={!r}, exists={!r}, islink={!r})".format( + path, path.isdir(), path.exists(), path.islink() ) ihook = self.gethookproxy(path) if not self.isinitpath(path): @@ -651,8 +649,7 @@ def collect(self): continue if is_file: - for x in self._collectfile(path): - yield x + yield from self._collectfile(path) elif not path.isdir(): # Broken symlink or invalid/missing file. continue @@ -794,7 +791,7 @@ def _getobj(self): def collect(self): self.session._fixturemanager.parsefactories(self) - return super(Instance, self).collect() + return super().collect() def newinstance(self): self.obj = self._getobj() @@ -852,7 +849,7 @@ def hasnew(obj): return new != object.__new__ -class CallSpec2(object): +class CallSpec2: def __init__(self, metafunc): self.metafunc = metafunc self.funcargs = {} @@ -878,7 +875,7 @@ def copy(self): def _checkargnotcontained(self, arg): if arg in self.params or arg in self.funcargs: - raise ValueError("duplicate %r" % (arg,)) + raise ValueError("duplicate {!r}".format(arg)) def getparam(self, name): try: @@ -1054,7 +1051,7 @@ def _resolve_arg_ids(self, argnames, ids, parameters, item): msg = "In {}: {} parameter sets specified, with different number of ids: {}" fail(msg.format(func_name, len(parameters), len(ids)), pytrace=False) for id_value in ids: - if id_value is not None and not isinstance(id_value, six.string_types): + if id_value is not None and not isinstance(id_value, str): msg = "In {}: ids must be list of strings, found: {} (type: {!r})" fail( msg.format(func_name, saferepr(id_value), type(id_value)), @@ -1177,7 +1174,7 @@ def _idval(val, argname, idx, idfn, item, config): msg = msg.format(item.nodeid, argname, idx) # we only append the exception type and message because on Python 2 reraise does nothing msg += " {}: {}\n".format(type(e).__name__, e) - six.raise_from(ValueError(msg), e) + raise ValueError(msg) from e elif config: hook_id = config.hook.pytest_make_parametrize_id( config=config, val=val, argname=argname @@ -1329,7 +1326,7 @@ def _showfixtures_main(config, session): if currentmodule != module: if not module.startswith("_pytest."): tw.line() - tw.sep("-", "fixtures defined from %s" % (module,)) + tw.sep("-", "fixtures defined from {}".format(module)) currentmodule = module if verbose <= 0 and argname[0] == "_": continue @@ -1344,7 +1341,7 @@ def _showfixtures_main(config, session): if doc: write_docstring(tw, doc) else: - tw.line(" %s: no docstring available" % (loc,), red=True) + tw.line(" {}: no docstring available".format(loc), red=True) tw.line() @@ -1384,7 +1381,7 @@ def __init__( fixtureinfo=None, originalname=None, ): - super(Function, self).__init__(name, parent, config=config, session=session) + super().__init__(name, parent, config=config, session=session) self._args = args if callobj is not NOTSET: self.obj = callobj @@ -1458,7 +1455,7 @@ def runtest(self): self.ihook.pytest_pyfunc_call(pyfuncitem=self) def setup(self): - super(Function, self).setup() + super().setup() fixtures.fillfixtures(self) diff --git a/src/_pytest/python_api.py b/src/_pytest/python_api.py index 4508ce56a6b..011181a4071 100644 --- a/src/_pytest/python_api.py +++ b/src/_pytest/python_api.py @@ -46,7 +46,7 @@ def _non_numeric_type_error(value, at): # builtin pytest.approx helper -class ApproxBase(object): +class ApproxBase: """ Provide shared utilities for making approximate comparisons between numbers or sequences of numbers. @@ -706,7 +706,7 @@ def raises(expected_exception, *args, **kwargs): raises.Exception = fail.Exception -class RaisesContext(object): +class RaisesContext: def __init__(self, expected_exception, message, match_expr): self.expected_exception = expected_exception self.message = message diff --git a/src/_pytest/recwarn.py b/src/_pytest/recwarn.py index f3078d00388..006d97e7fc7 100644 --- a/src/_pytest/recwarn.py +++ b/src/_pytest/recwarn.py @@ -110,7 +110,7 @@ class WarningsRecorder(warnings.catch_warnings): """ def __init__(self): - super(WarningsRecorder, self).__init__(record=True) + super().__init__(record=True) self._entered = False self._list = [] @@ -147,7 +147,7 @@ def __enter__(self): if self._entered: __tracebackhide__ = True raise RuntimeError("Cannot enter %r twice" % self) - self._list = super(WarningsRecorder, self).__enter__() + self._list = super().__enter__() warnings.simplefilter("always") return self @@ -156,7 +156,7 @@ def __exit__(self, *exc_info): __tracebackhide__ = True raise RuntimeError("Cannot exit %r without entering first" % self) - super(WarningsRecorder, self).__exit__(*exc_info) + super().__exit__(*exc_info) # Built-in catch_warnings does not reset entered state so we do it # manually here for this context manager to become reusable. @@ -165,7 +165,7 @@ def __exit__(self, *exc_info): class WarningsChecker(WarningsRecorder): def __init__(self, expected_warning=None, match_expr=None): - super(WarningsChecker, self).__init__() + super().__init__() msg = "exceptions must be old-style classes or derived from Warning, not %s" if isinstance(expected_warning, tuple): @@ -181,7 +181,7 @@ def __init__(self, expected_warning=None, match_expr=None): self.match_expr = match_expr def __exit__(self, *exc_info): - super(WarningsChecker, self).__exit__(*exc_info) + super().__exit__(*exc_info) __tracebackhide__ = True diff --git a/src/_pytest/reports.py b/src/_pytest/reports.py index 43d7e54a41b..d2f1f33e2fe 100644 --- a/src/_pytest/reports.py +++ b/src/_pytest/reports.py @@ -1,7 +1,6 @@ from pprint import pprint import py -import six from _pytest._code.code import ExceptionInfo from _pytest._code.code import ReprEntry @@ -22,16 +21,13 @@ def getslaveinfoline(node): except AttributeError: d = node.slaveinfo ver = "%s.%s.%s" % d["version_info"][:3] - node._slaveinfocache = s = "[%s] %s -- Python %s %s" % ( - d["id"], - d["sysplatform"], - ver, - d["executable"], + node._slaveinfocache = s = "[{}] {} -- Python {} {}".format( + d["id"], d["sysplatform"], ver, d["executable"] ) return s -class BaseReport(object): +class BaseReport: when = None location = None @@ -194,7 +190,7 @@ def disassembled_report(rep): ): d["longrepr"] = disassembled_report(self) else: - d["longrepr"] = six.text_type(self.longrepr) + d["longrepr"] = str(self.longrepr) else: d["longrepr"] = self.longrepr for name in d: @@ -334,11 +330,8 @@ def __init__( self.__dict__.update(extra) def __repr__(self): - return "<%s %r when=%r outcome=%r>" % ( - self.__class__.__name__, - self.nodeid, - self.when, - self.outcome, + return "<{} {!r} when={!r} outcome={!r}>".format( + self.__class__.__name__, self.nodeid, self.when, self.outcome ) @classmethod @@ -371,7 +364,7 @@ def from_item_and_call(cls, item, call): excinfo, style=item.config.getoption("tbstyle", "auto") ) for rwhen, key, content in item._report_sections: - sections.append(("Captured %s %s" % (key, rwhen), content)) + sections.append(("Captured {} {}".format(key, rwhen), content)) return cls( item.nodeid, item.location, @@ -401,10 +394,8 @@ def location(self): return (self.fspath, None, self.fspath) def __repr__(self): - return "" % ( - self.nodeid, - len(self.result), - self.outcome, + return "".format( + self.nodeid, len(self.result), self.outcome ) diff --git a/src/_pytest/resultlog.py b/src/_pytest/resultlog.py index 3dc58ab2817..a977b29da43 100644 --- a/src/_pytest/resultlog.py +++ b/src/_pytest/resultlog.py @@ -43,13 +43,13 @@ def pytest_unconfigure(config): config.pluginmanager.unregister(resultlog) -class ResultLog(object): +class ResultLog: def __init__(self, config, logfile): self.config = config self.logfile = logfile # preferably line buffered def write_log_entry(self, testpath, lettercode, longrepr): - print("%s %s" % (lettercode, testpath), file=self.logfile) + print("{} {}".format(lettercode, testpath), file=self.logfile) for line in longrepr.splitlines(): print(" %s" % line, file=self.logfile) diff --git a/src/_pytest/runner.py b/src/_pytest/runner.py index 40c8f5e82c4..2561aaf466a 100644 --- a/src/_pytest/runner.py +++ b/src/_pytest/runner.py @@ -57,7 +57,7 @@ def pytest_terminal_summary(terminalreporter): tr.write_line("") tr.write_line("(0.00 durations hidden. Use -vv to show these durations.)") break - tr.write_line("%02.2fs %-8s %s" % (rep.duration, rep.when, rep.nodeid)) + tr.write_line("{:02.2f}s {:<8} {}".format(rep.duration, rep.when, rep.nodeid)) def pytest_sessionstart(session): @@ -195,7 +195,7 @@ def call_runtest_hook(item, when, **kwds): @attr.s(repr=False) -class CallInfo(object): +class CallInfo: """ Result/Exception info a function invocation. """ _result = attr.ib() @@ -270,7 +270,7 @@ def pytest_make_collect_report(collector): return rep -class SetupState(object): +class SetupState: """ shared state for setting up/tearing down test items or collectors. """ def __init__(self): diff --git a/src/_pytest/terminal.py b/src/_pytest/terminal.py index 99ad1f2a343..6f989030175 100644 --- a/src/_pytest/terminal.py +++ b/src/_pytest/terminal.py @@ -12,7 +12,6 @@ import attr import pluggy import py -import six from more_itertools import collapse import pytest @@ -35,7 +34,7 @@ class MoreQuietAction(argparse.Action): """ def __init__(self, option_strings, dest, default=None, required=False, help=None): - super(MoreQuietAction, self).__init__( + super().__init__( option_strings=option_strings, dest=dest, nargs=0, @@ -186,7 +185,7 @@ def pytest_report_teststatus(report): @attr.s -class WarningReport(object): +class WarningReport: """ Simple structure to hold warnings information captured by ``pytest_warning_captured``. @@ -214,13 +213,13 @@ def get_location(self, config): relpath = py.path.local(filename).relto(config.invocation_dir) if not relpath: relpath = str(filename) - return "%s:%s" % (relpath, linenum) + return "{}:{}".format(relpath, linenum) else: return str(self.fslocation) return None -class TerminalReporter(object): +class TerminalReporter: def __init__(self, config, file=None): import _pytest.config @@ -315,8 +314,8 @@ def write(self, content, **markup): self._tw.write(content, **markup) def write_line(self, line, **markup): - if not isinstance(line, six.text_type): - line = six.text_type(line, errors="replace") + if not isinstance(line, str): + line = str(line, errors="replace") self.ensure_newline() self._tw.line(line, **markup) @@ -349,7 +348,7 @@ def line(self, msg, **kw): self._tw.line(msg, **kw) def pytest_internalerror(self, excrepr): - for line in six.text_type(excrepr).split("\n"): + for line in str(excrepr).split("\n"): self.write_line("INTERNALERROR> " + line) return 1 @@ -369,7 +368,7 @@ def pytest_warning_captured(self, warning_message, item): def pytest_plugin_registered(self, plugin): if self.config.option.traceconfig: - msg = "PLUGIN registered: %s" % (plugin,) + msg = "PLUGIN registered: {}".format(plugin) # XXX this event may happen during setup/teardown time # which unfortunately captures our output here # which garbles our output if we use self.write_line @@ -556,14 +555,12 @@ def pytest_sessionstart(self, session): return self.write_sep("=", "test session starts", bold=True) verinfo = platform.python_version() - msg = "platform %s -- Python %s" % (sys.platform, verinfo) + msg = "platform {} -- Python {}".format(sys.platform, verinfo) if hasattr(sys, "pypy_version_info"): verinfo = ".".join(map(str, sys.pypy_version_info[:3])) - msg += "[pypy-%s-%s]" % (verinfo, sys.pypy_version_info[3]) - msg += ", pytest-%s, py-%s, pluggy-%s" % ( - pytest.__version__, - py.__version__, - pluggy.__version__, + msg += "[pypy-{}-{}]".format(verinfo, sys.pypy_version_info[3]) + msg += ", pytest-{}, py-{}, pluggy-{}".format( + pytest.__version__, py.__version__, pluggy.__version__ ) if ( self.verbosity > 0 @@ -645,11 +642,11 @@ def _printcollecteditems(self, items): if col.name == "()": # Skip Instances. continue indent = (len(stack) - 1) * " " - self._tw.line("%s%s" % (indent, col)) + self._tw.line("{}{}".format(indent, col)) if self.config.option.verbose >= 1: if hasattr(col, "_obj") and col._obj.__doc__: for line in col._obj.__doc__.strip().splitlines(): - self._tw.line("%s%s" % (indent + " ", line.strip())) + self._tw.line("{}{}".format(indent + " ", line.strip())) @pytest.hookimpl(hookwrapper=True) def pytest_sessionfinish(self, exitstatus): @@ -849,7 +846,7 @@ def summary_errors(self): if rep.when == "collect": msg = "ERROR collecting " + msg else: - msg = "ERROR at %s of %s" % (rep.when, msg) + msg = "ERROR at {} of {}".format(rep.when, msg) self.write_sep("_", msg, red=True, bold=True) self._outrep_summary(rep) @@ -869,7 +866,7 @@ def _outrep_summary(self, rep): def summary_stats(self): session_duration = time.time() - self._sessionstarttime (line, color) = build_summary_stats_line(self.stats) - msg = "%s in %.2f seconds" % (line, session_duration) + msg = "{} in {:.2f} seconds".format(line, session_duration) markup = {color: True, "bold": True} if self.verbosity >= 0: @@ -896,7 +893,7 @@ def show_xfailed(lines): for rep in xfailed: verbose_word = rep._get_verbose_word(self.config) pos = _get_pos(self.config, rep) - lines.append("%s %s" % (verbose_word, pos)) + lines.append("{} {}".format(verbose_word, pos)) reason = rep.wasxfail if reason: lines.append(" " + str(reason)) @@ -907,7 +904,7 @@ def show_xpassed(lines): verbose_word = rep._get_verbose_word(self.config) pos = _get_pos(self.config, rep) reason = rep.wasxfail - lines.append("%s %s %s" % (verbose_word, pos, reason)) + lines.append("{} {} {}".format(verbose_word, pos, reason)) def show_skipped(lines): skipped = self.stats.get("skipped", []) @@ -961,7 +958,7 @@ def _get_line_with_reprcrash_message(config, rep, termwidth): verbose_word = rep._get_verbose_word(config) pos = _get_pos(config, rep) - line = "%s %s" % (verbose_word, pos) + line = "{} {}".format(verbose_word, pos) len_line = wcswidth(line) ellipsis, len_ellipsis = "...", 3 if len_line > termwidth - len_ellipsis: diff --git a/src/_pytest/tmpdir.py b/src/_pytest/tmpdir.py index 33a3628ba46..f2c4d905cf5 100644 --- a/src/_pytest/tmpdir.py +++ b/src/_pytest/tmpdir.py @@ -17,7 +17,7 @@ @attr.s -class TempPathFactory(object): +class TempPathFactory: """Factory for temporary directories under the common base temp directory. The base directory can be configured using the ``--basetemp`` option.""" @@ -77,7 +77,7 @@ def getbasetemp(self): @attr.s -class TempdirFactory(object): +class TempdirFactory: """ backward comptibility wrapper that implements :class:``py.path.local`` for :class:``TempPathFactory`` diff --git a/src/_pytest/warning_types.py b/src/_pytest/warning_types.py index 2777aabeaaf..d7d37b4bbe0 100644 --- a/src/_pytest/warning_types.py +++ b/src/_pytest/warning_types.py @@ -94,7 +94,7 @@ class RemovedInPytest4Warning(PytestDeprecationWarning): @attr.s -class UnformattedWarning(object): +class UnformattedWarning: """Used to hold warnings that need to format their message at runtime, as opposed to a direct message. Using this class avoids to keep all the warning types and messages in this module, avoiding misuse. diff --git a/src/_pytest/warnings.py b/src/_pytest/warnings.py index 660fdef5b91..2f10862251a 100644 --- a/src/_pytest/warnings.py +++ b/src/_pytest/warnings.py @@ -13,7 +13,7 @@ def _setoption(wmod, arg): """ parts = arg.split(":") if len(parts) > 5: - raise wmod._OptionError("too many fields (max 5): %r" % (arg,)) + raise wmod._OptionError("too many fields (max 5): {!r}".format(arg)) while len(parts) < 5: parts.append("") action, message, category, module, lineno = [s.strip() for s in parts] @@ -25,7 +25,7 @@ def _setoption(wmod, arg): if lineno < 0: raise ValueError except (ValueError, OverflowError): - raise wmod._OptionError("invalid lineno %r" % (lineno,)) + raise wmod._OptionError("invalid lineno {!r}".format(lineno)) else: lineno = 0 wmod.filterwarnings(action, message, category, module, lineno) diff --git a/testing/acceptance_test.py b/testing/acceptance_test.py index 3a13806f193..9d0d7f86317 100644 --- a/testing/acceptance_test.py +++ b/testing/acceptance_test.py @@ -6,7 +6,6 @@ import attr import importlib_metadata import py -import six import pytest from _pytest.main import EXIT_NOTESTSCOLLECTED @@ -21,7 +20,7 @@ def prepend_pythonpath(*dirs): return os.pathsep.join(str(p) for p in dirs) -class TestGeneralUsage(object): +class TestGeneralUsage: def test_config_error(self, testdir): testdir.copy_example("conftest_usageerror/conftest.py") result = testdir.runpytest(testdir.tmpdir) @@ -115,7 +114,7 @@ def test_early_load_setuptools_name(self, testdir, monkeypatch, load_cov_early): loaded = [] @attr.s - class DummyEntryPoint(object): + class DummyEntryPoint: name = attr.ib() module = attr.ib() group = "pytest11" @@ -132,7 +131,7 @@ def load(self): ] @attr.s - class DummyDist(object): + class DummyDist: entry_points = attr.ib() files = () @@ -508,7 +507,7 @@ def test_stuff(r): def test_parametrized_with_null_bytes(self, testdir): """Test parametrization with values that contain null bytes and unicode characters (#2644, #2957)""" p = testdir.makepyfile( - u""" + """ # encoding: UTF-8 import pytest @@ -521,7 +520,7 @@ def test_foo(data): res.assert_outcomes(passed=3) -class TestInvocationVariants(object): +class TestInvocationVariants: def test_earlyinit(self, testdir): p = testdir.makepyfile( """ @@ -618,7 +617,7 @@ def test_invoke_with_path(self, tmpdir, capsys): out, err = capsys.readouterr() def test_invoke_plugin_api(self, testdir, capsys): - class MyPlugin(object): + class MyPlugin: def pytest_addoption(self, parser): parser.addoption("--myopt") @@ -756,7 +755,7 @@ def test_cmdline_python_package_symlink(self, testdir, monkeypatch): str(testdir.tmpdir.join("tmpfile2")), ) except OSError as e: - pytest.skip(six.text_type(e.args[0])) + pytest.skip(str(e.args[0])) monkeypatch.delenv("PYTHONDONTWRITEBYTECODE", raising=False) dirname = "lib" @@ -871,7 +870,7 @@ def test_has_plugin(self, request): assert request.config.pluginmanager.hasplugin("python") -class TestDurations(object): +class TestDurations: source = """ import time frag = 0.002 @@ -949,7 +948,7 @@ def test_with_not(self, testdir): assert result.ret == 0 -class TestDurationWithFixture(object): +class TestDurationWithFixture: source = """ import pytest import time diff --git a/testing/code/test_code.py b/testing/code/test_code.py index 552e8d5468d..d4579596735 100644 --- a/testing/code/test_code.py +++ b/testing/code/test_code.py @@ -1,7 +1,6 @@ import sys from unittest import mock -from six import text_type from test_excinfo import TWMock import _pytest._code @@ -25,7 +24,7 @@ def test_code_gives_back_name_for_not_existing_file(): def test_code_with_class(): - class A(object): + class A: pass pytest.raises(TypeError, _pytest._code.Code, A) @@ -76,13 +75,13 @@ def test_code_from_func(): def test_unicode_handling(): - value = u"ąć".encode("UTF-8") + value = "ąć".encode() def f(): raise Exception(value) excinfo = pytest.raises(Exception, f) - text_type(excinfo) + str(excinfo) def test_code_getargs(): @@ -137,7 +136,7 @@ def f4(x, *y, **z): assert fr4.getargs(var=True) == [("x", "a"), ("y", ("b",)), ("z", {"c": "d"})] -class TestExceptionInfo(object): +class TestExceptionInfo: def test_bad_getsource(self): try: if False: @@ -153,7 +152,7 @@ def test_from_current_with_missing(self): _pytest._code.ExceptionInfo.from_current() -class TestTracebackEntry(object): +class TestTracebackEntry: def test_getsource(self): try: if False: @@ -168,13 +167,13 @@ def test_getsource(self): assert "assert False" in source[5] -class TestReprFuncArgs(object): +class TestReprFuncArgs: def test_not_raise_exception_with_mixed_encoding(self): from _pytest._code.code import ReprFuncArgs tw = TWMock() - args = [("unicode_string", u"São Paulo"), ("utf8_string", b"S\xc3\xa3o Paulo")] + args = [("unicode_string", "São Paulo"), ("utf8_string", b"S\xc3\xa3o Paulo")] r = ReprFuncArgs(args) r.toterminal(tw) diff --git a/testing/code/test_excinfo.py b/testing/code/test_excinfo.py index de8f73c6820..3eac94a287e 100644 --- a/testing/code/test_excinfo.py +++ b/testing/code/test_excinfo.py @@ -5,7 +5,6 @@ import textwrap import py -import six import _pytest import pytest @@ -32,7 +31,7 @@ def limited_recursion_depth(): sys.setrecursionlimit(before) -class TWMock(object): +class TWMock: WRITE = object() def __init__(self): @@ -113,7 +112,7 @@ def h(): # -class TestTraceback_f_g_h(object): +class TestTraceback_f_g_h: def setup_method(self, method): try: h() @@ -252,7 +251,7 @@ def reraise_me(): import sys exc, val, tb = sys.exc_info() - six.reraise(exc, val, tb) + raise val.with_traceback(tb) def f(n): try: @@ -429,7 +428,7 @@ def test_division_zero(): result.stdout.fnmatch_lines(["*AssertionError*Pattern*[123]*not found*"]) -class TestFormattedExcinfo(object): +class TestFormattedExcinfo: @pytest.fixture def importasmod(self, request, _sys_snapshot): def importasmod(source): @@ -515,8 +514,8 @@ def test_repr_many_line_source_not_existing(self): def test_repr_source_failing_fullsource(self): pr = FormattedExcinfo() - class FakeCode(object): - class raw(object): + class FakeCode: + class raw: co_filename = "?" path = "?" @@ -527,7 +526,7 @@ def fullsource(self): fullsource = property(fullsource) - class FakeFrame(object): + class FakeFrame: code = FakeCode() f_locals = {} f_globals = {} @@ -558,7 +557,7 @@ def errisinstance(self, cls): excinfo = FakeExcinfo() - class FakeRawTB(object): + class FakeRawTB: tb_next = None tb = FakeRawTB() @@ -915,10 +914,10 @@ def test_reprexcinfo_unicode(self): class MyRepr(TerminalRepr): def toterminal(self, tw): - tw.line(u"я") + tw.line("я") - x = six.text_type(MyRepr()) - assert x == u"я" + x = str(MyRepr()) + assert x == "я" def test_toterminal_long(self, importasmod): mod = importasmod( @@ -1351,7 +1350,7 @@ def unreraise(): @pytest.mark.parametrize("style", ["short", "long"]) @pytest.mark.parametrize("encoding", [None, "utf8", "utf16"]) def test_repr_traceback_with_unicode(style, encoding): - msg = u"☹" + msg = "☹" if encoding is not None: msg = msg.encode(encoding) try: @@ -1385,7 +1384,7 @@ def test_exception_repr_extraction_error_on_recursion(): """ from _pytest.pytester import LineMatcher - class numpy_like(object): + class numpy_like: def __eq__(self, other): if type(other) is numpy_like: raise ValueError( @@ -1419,7 +1418,7 @@ def test_no_recursion_index_on_recursion_error(): during a recursion error (#2486). """ - class RecursionDepthError(object): + class RecursionDepthError: def __getattr__(self, attr): return getattr(self, "_" + attr) diff --git a/testing/code/test_source.py b/testing/code/test_source.py index 2d62a58f06a..2462d773e7e 100644 --- a/testing/code/test_source.py +++ b/testing/code/test_source.py @@ -28,11 +28,11 @@ def test_source_str_function(): def test_unicode(): - x = Source(u"4") + x = Source("4") assert str(x) == "4" - co = _pytest._code.compile(u'u"å"', mode="eval") + co = _pytest._code.compile('u"å"', mode="eval") val = eval(co) - assert isinstance(val, six.text_type) + assert isinstance(val, str) def test_source_from_function(): @@ -41,7 +41,7 @@ def test_source_from_function(): def test_source_from_method(): - class TestClass(object): + class TestClass: def test_method(self): pass @@ -128,7 +128,7 @@ def test_isparseable(): assert not Source(chr(0)).isparseable() -class TestAccesses(object): +class TestAccesses: source = Source( """\ def f(x): @@ -156,7 +156,7 @@ def test_iter(self): assert len(values) == 4 -class TestSourceParsingAndCompiling(object): +class TestSourceParsingAndCompiling: source = Source( """\ def f(x): @@ -333,7 +333,7 @@ def test_offsetless_synerr(self): def test_getstartingblock_singleline(): - class A(object): + class A: def __init__(self, *args): frame = sys._getframe(1) self.source = _pytest._code.Frame(frame).statement @@ -480,7 +480,7 @@ def f(x): assert fspath.basename == "test_source.py" assert lineno == _pytest._code.getrawcode(f).co_firstlineno - 1 # see findsource - class A(object): + class A: pass fspath, lineno = getfslineno(A) @@ -491,7 +491,7 @@ class A(object): assert getfslineno(3) == ("", -1) - class B(object): + class B: pass B.__name__ = "B2" @@ -499,19 +499,19 @@ class B(object): def test_code_of_object_instance_with_call(): - class A(object): + class A: pass pytest.raises(TypeError, lambda: _pytest._code.Source(A())) - class WithCall(object): + class WithCall: def __call__(self): pass code = _pytest._code.Code(WithCall()) assert "pass" in str(code.source()) - class Hello(object): + class Hello: def __call__(self): pass @@ -620,7 +620,7 @@ def test_multiline(): assert str(source) == "raise ValueError(\n 23\n)" -class TestTry(object): +class TestTry: source = """\ try: raise ValueError @@ -647,7 +647,7 @@ def test_else(self): assert str(source) == " raise KeyError()" -class TestTryFinally(object): +class TestTryFinally: source = """\ try: raise ValueError @@ -664,7 +664,7 @@ def test_finally(self): assert str(source) == " raise IndexError(1)" -class TestIf(object): +class TestIf: source = """\ if 1: y = 3 @@ -720,7 +720,7 @@ def XXX_test_expression_multiline(): def test_getstartingblock_multiline(): - class A(object): + class A: def __init__(self, *args): frame = sys._getframe(1) self.source = _pytest._code.Frame(frame).statement diff --git a/testing/example_scripts/config/collect_pytest_prefix/conftest.py b/testing/example_scripts/config/collect_pytest_prefix/conftest.py index 56a4c71d358..2da4ffe2fed 100644 --- a/testing/example_scripts/config/collect_pytest_prefix/conftest.py +++ b/testing/example_scripts/config/collect_pytest_prefix/conftest.py @@ -1,2 +1,2 @@ -class pytest_something(object): +class pytest_something: pass diff --git a/testing/example_scripts/dataclasses/test_compare_dataclasses.py b/testing/example_scripts/dataclasses/test_compare_dataclasses.py index 3bbebe2aa26..82a685c6314 100644 --- a/testing/example_scripts/dataclasses/test_compare_dataclasses.py +++ b/testing/example_scripts/dataclasses/test_compare_dataclasses.py @@ -4,7 +4,7 @@ def test_dataclasses(): @dataclass - class SimpleDataObject(object): + class SimpleDataObject: field_a: int = field() field_b: int = field() diff --git a/testing/example_scripts/dataclasses/test_compare_dataclasses_field_comparison_off.py b/testing/example_scripts/dataclasses/test_compare_dataclasses_field_comparison_off.py index 63b9f534e6e..fa89e4a2044 100644 --- a/testing/example_scripts/dataclasses/test_compare_dataclasses_field_comparison_off.py +++ b/testing/example_scripts/dataclasses/test_compare_dataclasses_field_comparison_off.py @@ -4,7 +4,7 @@ def test_dataclasses_with_attribute_comparison_off(): @dataclass - class SimpleDataObject(object): + class SimpleDataObject: field_a: int = field() field_b: int = field(compare=False) diff --git a/testing/example_scripts/dataclasses/test_compare_dataclasses_verbose.py b/testing/example_scripts/dataclasses/test_compare_dataclasses_verbose.py index 17835c0c3fc..06634565b16 100644 --- a/testing/example_scripts/dataclasses/test_compare_dataclasses_verbose.py +++ b/testing/example_scripts/dataclasses/test_compare_dataclasses_verbose.py @@ -4,7 +4,7 @@ def test_dataclasses_verbose(): @dataclass - class SimpleDataObject(object): + class SimpleDataObject: field_a: int = field() field_b: int = field() diff --git a/testing/example_scripts/dataclasses/test_compare_two_different_dataclasses.py b/testing/example_scripts/dataclasses/test_compare_two_different_dataclasses.py index 24f185d8ac4..4c638e1fcd6 100644 --- a/testing/example_scripts/dataclasses/test_compare_two_different_dataclasses.py +++ b/testing/example_scripts/dataclasses/test_compare_two_different_dataclasses.py @@ -4,12 +4,12 @@ def test_comparing_two_different_data_classes(): @dataclass - class SimpleDataObjectOne(object): + class SimpleDataObjectOne: field_a: int = field() field_b: int = field() @dataclass - class SimpleDataObjectTwo(object): + class SimpleDataObjectTwo: field_a: int = field() field_b: int = field() diff --git a/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_module_class.py b/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_module_class.py index 2b8218ed7ca..87a0c894111 100644 --- a/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_module_class.py +++ b/testing/example_scripts/fixtures/fill_fixtures/test_extend_fixture_module_class.py @@ -6,7 +6,7 @@ def spam(): return "spam" -class TestSpam(object): +class TestSpam: @pytest.fixture def spam(self, spam): return spam * 2 diff --git a/testing/example_scripts/fixtures/fill_fixtures/test_funcarg_lookup_classlevel.py b/testing/example_scripts/fixtures/fill_fixtures/test_funcarg_lookup_classlevel.py index 7b7183dd94e..256b92a17dd 100644 --- a/testing/example_scripts/fixtures/fill_fixtures/test_funcarg_lookup_classlevel.py +++ b/testing/example_scripts/fixtures/fill_fixtures/test_funcarg_lookup_classlevel.py @@ -1,7 +1,7 @@ import pytest -class TestClass(object): +class TestClass: @pytest.fixture def something(self, request): return request.instance diff --git a/testing/example_scripts/fixtures/fill_fixtures/test_funcarg_lookup_modulelevel.py b/testing/example_scripts/fixtures/fill_fixtures/test_funcarg_lookup_modulelevel.py index 227abb59374..e15dbd2ca45 100644 --- a/testing/example_scripts/fixtures/fill_fixtures/test_funcarg_lookup_modulelevel.py +++ b/testing/example_scripts/fixtures/fill_fixtures/test_funcarg_lookup_modulelevel.py @@ -6,7 +6,7 @@ def something(request): return request.function.__name__ -class TestClass(object): +class TestClass: def test_method(self, something): assert something == "test_method" diff --git a/testing/io/test_saferepr.py b/testing/io/test_saferepr.py index 4643d3f92d6..e57b53f81e9 100644 --- a/testing/io/test_saferepr.py +++ b/testing/io/test_saferepr.py @@ -52,7 +52,7 @@ def test_big_repr(): def test_repr_on_newstyle(): - class Function(object): + class Function: def __repr__(self): return "<%s>" % (self.name) @@ -60,6 +60,6 @@ def __repr__(self): def test_unicode(): - val = u"£€" - reprval = u"'£€'" + val = "£€" + reprval = "'£€'" assert saferepr(val) == reprval diff --git a/testing/logging/test_fixture.py b/testing/logging/test_fixture.py index f50522b7fd7..5d2ff4654d0 100644 --- a/testing/logging/test_fixture.py +++ b/testing/logging/test_fixture.py @@ -102,15 +102,15 @@ def test_record_tuples(caplog): def test_unicode(caplog): caplog.set_level(logging.INFO) - logger.info(u"bū") + logger.info("bū") assert caplog.records[0].levelname == "INFO" - assert caplog.records[0].msg == u"bū" - assert u"bū" in caplog.text + assert caplog.records[0].msg == "bū" + assert "bū" in caplog.text def test_clear(caplog): caplog.set_level(logging.INFO) - logger.info(u"bū") + logger.info("bū") assert len(caplog.records) assert caplog.text caplog.clear() diff --git a/testing/logging/test_formatter.py b/testing/logging/test_formatter.py index 18f8f0aa17a..8adc266139c 100644 --- a/testing/logging/test_formatter.py +++ b/testing/logging/test_formatter.py @@ -20,8 +20,8 @@ def test_coloredlogformatter(): exc_info=False, ) - class ColorConfig(object): - class option(object): + class ColorConfig: + class option: pass tw = py.io.TerminalWriter() diff --git a/testing/logging/test_reporting.py b/testing/logging/test_reporting.py index dab5b662c8b..f845f5c39a6 100644 --- a/testing/logging/test_reporting.py +++ b/testing/logging/test_reporting.py @@ -860,7 +860,7 @@ def test_log_file(): with open(log_file, encoding="utf-8") as rfh: contents = rfh.read() assert "Normal message" in contents - assert u"├" in contents + assert "├" in contents assert "Another normal message" in contents diff --git a/testing/python/approx.py b/testing/python/approx.py index c3ab9c12039..0575557ae78 100644 --- a/testing/python/approx.py +++ b/testing/python/approx.py @@ -23,10 +23,10 @@ def report_failure(self, out, test, example, got): ) -class TestApprox(object): +class TestApprox: @pytest.fixture def plus_minus(self): - return u"\u00b1" + return "\u00b1" def test_repr_string(self, plus_minus): tol1, tol2, infr = "1.0e-06", "2.0e-06", "inf" @@ -496,7 +496,7 @@ def test_numpy_scalar_with_array(self): assert approx(expected, rel=5e-8, abs=0) != actual def test_generic_sized_iterable_object(self): - class MySizedIterable(object): + class MySizedIterable: def __iter__(self): return iter([1, 2, 3, 4]) diff --git a/testing/python/collect.py b/testing/python/collect.py index 5e59b21b707..544e71f25cb 100644 --- a/testing/python/collect.py +++ b/testing/python/collect.py @@ -8,7 +8,7 @@ from _pytest.nodes import Collector -class TestModule(object): +class TestModule: def test_failing_import(self, testdir): modcol = testdir.getmodulecol("import alksdjalskdjalkjals") pytest.raises(Collector.CollectError, modcol.collect) @@ -117,7 +117,7 @@ def test_show_traceback_import_error_unicode(self, testdir): are handled properly (#2336). """ testdir.makepyfile( - u""" + """ # -*- coding: utf-8 -*- raise ImportError(u'Something bad happened ☺') """ @@ -133,7 +133,7 @@ def test_show_traceback_import_error_unicode(self, testdir): assert result.ret == 2 -class TestClass(object): +class TestClass: def test_class_with_init_warning(self, testdir): testdir.makepyfile( """ @@ -254,7 +254,7 @@ def prop(self): assert result.ret == EXIT_NOTESTSCOLLECTED -class TestFunction(object): +class TestFunction: def test_getmodulecollector(self, testdir): item = testdir.getitem("def test_func(): pass") modcol = item.getparent(pytest.Module) @@ -513,11 +513,11 @@ def test_pyfunc_call(self, testdir): item = testdir.getitem("def test_func(): raise ValueError") config = item.config - class MyPlugin1(object): + class MyPlugin1: def pytest_pyfunc_call(self, pyfuncitem): raise ValueError - class MyPlugin2(object): + class MyPlugin2: def pytest_pyfunc_call(self, pyfuncitem): return True @@ -663,7 +663,7 @@ def test_func(arg): assert [x.originalname for x in items] == ["test_func", "test_func"] -class TestSorting(object): +class TestSorting: def test_check_equality(self, testdir): modcol = testdir.getmodulecol( """ @@ -715,7 +715,7 @@ def test_a(y): assert [item.name for item in colitems] == ["test_b", "test_a"] -class TestConftestCustomization(object): +class TestConftestCustomization: def test_pytest_pycollect_module(self, testdir): testdir.makeconftest( """ @@ -890,7 +890,7 @@ def test_modulecol_roundtrip(testdir): assert modcol.name == newcol.name -class TestTracebackCutting(object): +class TestTracebackCutting: def test_skip_simple(self): with pytest.raises(pytest.skip.Exception) as excinfo: pytest.skip("xxx") @@ -1019,7 +1019,7 @@ def foo(): assert filter_traceback(tb[-1]) -class TestReportInfo(object): +class TestReportInfo: def test_itemreport_reportinfo(self, testdir, linecomp): testdir.makeconftest( """ @@ -1257,7 +1257,7 @@ def test_syntax_error_with_non_ascii_chars(testdir): """Fix decoding issue while formatting SyntaxErrors during collection (#578) """ testdir.makepyfile( - u""" + """ # -*- coding: utf-8 -*- ☃ diff --git a/testing/python/fixtures.py b/testing/python/fixtures.py index 4d9ff0ba499..3b14dc835c6 100644 --- a/testing/python/fixtures.py +++ b/testing/python/fixtures.py @@ -31,7 +31,7 @@ def h(arg1, arg2, arg3="hello"): assert fixtures.getfuncargnames(h) == ("arg1", "arg2") - class A(object): + class A: def f(self, arg1, arg2="hello"): pass @@ -44,7 +44,7 @@ def static(arg1, arg2): @pytest.mark.pytester_example_path("fixtures/fill_fixtures") -class TestFillFixtures(object): +class TestFillFixtures: def test_fillfuncargs_exposed(self): # used by oejskit, kept for compatibility assert pytest._fillfuncargs == fixtures.fillfixtures @@ -442,7 +442,7 @@ def test_leak(leak): assert result.ret == 0 -class TestRequestBasic(object): +class TestRequestBasic: def test_request_attributes(self, testdir): item = testdir.getitem( """ @@ -901,7 +901,7 @@ def test_1(arg): reprec.assertoutcome(passed=2) -class TestRequestMarking(object): +class TestRequestMarking: def test_applymarker(self, testdir): item1, item2 = testdir.getitems( """ @@ -971,7 +971,7 @@ def test_fun2(keywords): reprec.assertoutcome(passed=2) -class TestFixtureUsages(object): +class TestFixtureUsages: def test_noargfixturedec(self, testdir): testdir.makepyfile( """ @@ -1302,7 +1302,7 @@ def test_printer_2(self): result.stdout.fnmatch_lines(["* 2 passed in *"]) -class TestFixtureManagerParseFactories(object): +class TestFixtureManagerParseFactories: @pytest.fixture def testdir(self, request): testdir = request.getfixturevalue("testdir") @@ -1528,7 +1528,7 @@ def test_collect_custom_items(self, testdir): result.stdout.fnmatch_lines(["*passed*"]) -class TestAutouseDiscovery(object): +class TestAutouseDiscovery: @pytest.fixture def testdir(self, testdir): testdir.makeconftest( @@ -1704,7 +1704,7 @@ def test_world(self): reprec.assertoutcome(passed=3) -class TestAutouseManagement(object): +class TestAutouseManagement: def test_autouse_conftest_mid_directory(self, testdir): pkgdir = testdir.mkpydir("xyz123") pkgdir.join("conftest.py").write( @@ -1952,7 +1952,7 @@ def test_check(): reprec.assertoutcome(passed=2) -class TestFixtureMarker(object): +class TestFixtureMarker: def test_parametrize(self, testdir): testdir.makepyfile( """ @@ -2908,7 +2908,7 @@ def test_foo(B): assert out1 == out2 -class TestRequestScopeAccess(object): +class TestRequestScopeAccess: pytestmark = pytest.mark.parametrize( ("scope", "ok", "error"), [ @@ -2962,7 +2962,7 @@ def test_func(arg): reprec.assertoutcome(passed=1) -class TestErrors(object): +class TestErrors: def test_subfactory_missing_funcarg(self, testdir): testdir.makepyfile( """ @@ -3029,7 +3029,7 @@ def test_something(): ) -class TestShowFixtures(object): +class TestShowFixtures: def test_funcarg_compat(self, testdir): config = testdir.parseconfigure("--funcargs") assert config.option.showfixtures @@ -3317,7 +3317,7 @@ def foo(): pass -class TestContextManagerFixtureFuncs(object): +class TestContextManagerFixtureFuncs: @pytest.fixture(params=["fixture", "yield_fixture"]) def flavor(self, request, testdir, monkeypatch): monkeypatch.setenv("PYTEST_FIXTURE_FLAVOR", request.param) @@ -3465,7 +3465,7 @@ def test_1(meow): result.stdout.fnmatch_lines(["*mew*"]) -class TestParameterizedSubRequest(object): +class TestParameterizedSubRequest: def test_call_from_fixture(self, testdir): testdir.makepyfile( test_call_from_fixture=""" @@ -3644,7 +3644,7 @@ def test_func(my_fixture): ) -class TestScopeOrdering(object): +class TestScopeOrdering: """Class of tests that ensure fixtures are ordered based on their scopes (#2405)""" @pytest.mark.parametrize("variant", ["mark", "autouse"]) diff --git a/testing/python/integration.py b/testing/python/integration.py index a6274701416..0b87fea3327 100644 --- a/testing/python/integration.py +++ b/testing/python/integration.py @@ -3,7 +3,7 @@ from _pytest import runner -class TestOEJSKITSpecials(object): +class TestOEJSKITSpecials: def test_funcarg_non_pycollectobj(self, testdir): # rough jstests usage testdir.makeconftest( """ @@ -86,7 +86,7 @@ def wrapped_func(x, y, z): assert lineno > lineno2, "getfslineno does not unwrap correctly" -class TestMockDecoration(object): +class TestMockDecoration: def test_wrapped_getfuncargnames(self): from _pytest.compat import getfuncargnames @@ -263,7 +263,7 @@ def test_simple_thing(self, mock_path, mock_getcwd): reprec.assertoutcome(passed=1) -class TestReRunTests(object): +class TestReRunTests: def test_rerun(self, testdir): testdir.makeconftest( """ @@ -309,7 +309,7 @@ def test_pytestconfig_is_session_scoped(): assert pytestconfig._pytestfixturefunction.scope == "session" -class TestNoselikeTestAttribute(object): +class TestNoselikeTestAttribute: def test_module_with_global_test(self, testdir): testdir.makepyfile( """ @@ -393,7 +393,7 @@ def test_blah(self): assert not call.items -class TestParameterize(object): +class TestParameterize: """#351""" def test_idfn_marker(self, testdir): diff --git a/testing/python/metafunc.py b/testing/python/metafunc.py index c6a8e161cb6..30534678231 100644 --- a/testing/python/metafunc.py +++ b/testing/python/metafunc.py @@ -4,7 +4,6 @@ import attr import hypothesis -import six from hypothesis import strategies import pytest @@ -13,19 +12,19 @@ from _pytest.warnings import SHOW_PYTEST_WARNINGS_ARG -class TestMetafunc(object): +class TestMetafunc: def Metafunc(self, func, config=None): # the unit tests of this class check if things work correctly # on the funcarg level, so we don't need a full blown # initiliazation - class FixtureInfo(object): + class FixtureInfo: name2fixturedefs = None def __init__(self, names): self.names_closure = names @attr.s - class DefinitionMock(object): + class DefinitionMock: obj = attr.ib() names = fixtures.getfuncargnames(func) @@ -79,7 +78,7 @@ def test_find_parametrized_scope(self): from _pytest.python import _find_parametrized_scope @attr.s - class DummyFixtureDef(object): + class DummyFixtureDef: scope = attr.ib() fixtures_defs = dict( @@ -138,9 +137,9 @@ def func(x): pass metafunc = self.Metafunc(func) - metafunc.parametrize("x", [1, 2], ids=[u"basic", u"advanced"]) + metafunc.parametrize("x", [1, 2], ids=["basic", "advanced"]) ids = [x.id for x in metafunc._calls] - assert ids == [u"basic", u"advanced"] + assert ids == ["basic", "advanced"] def test_parametrize_with_wrong_number_of_ids(self, testdir): def func(x, y): @@ -162,7 +161,7 @@ def test_parametrize_empty_list(self): def func(y): pass - class MockConfig(object): + class MockConfig: def getini(self, name): return "" @@ -183,7 +182,7 @@ def func(x, y): metafunc = self.Metafunc(func) - class A(object): + class A: pass metafunc.parametrize("x", [A(), A()]) @@ -201,7 +200,7 @@ def test_idval_hypothesis(self, value): from _pytest.python import _idval escaped = _idval(value, "a", 6, None, item=None, config=None) - assert isinstance(escaped, six.text_type) + assert isinstance(escaped, str) escaped.encode("ascii") def test_unicode_idval(self): @@ -213,12 +212,12 @@ def test_unicode_idval(self): from _pytest.python import _idval values = [ - (u"", ""), - (u"ascii", "ascii"), - (u"ação", "a\\xe7\\xe3o"), - (u"josé@blah.com", "jos\\xe9@blah.com"), + ("", ""), + ("ascii", "ascii"), + ("ação", "a\\xe7\\xe3o"), + ("josé@blah.com", "jos\\xe9@blah.com"), ( - u"δοκ.ιμή@παράδειγμα.δοκιμή", + "δοκ.ιμή@παράδειγμα.δοκιμή", "\\u03b4\\u03bf\\u03ba.\\u03b9\\u03bc\\u03ae@\\u03c0\\u03b1\\u03c1\\u03ac\\u03b4\\u03b5\\u03b9\\u03b3" "\\u03bc\\u03b1.\\u03b4\\u03bf\\u03ba\\u03b9\\u03bc\\u03ae", ), @@ -233,7 +232,7 @@ def test_unicode_idval_with_config(self): """ from _pytest.python import _idval - class MockConfig(object): + class MockConfig: def __init__(self, config): self.config = config @@ -250,8 +249,8 @@ def getini(self, name): option = "disable_test_id_escaping_and_forfeit_all_rights_to_community_support" values = [ - (u"ação", MockConfig({option: True}), u"ação"), - (u"ação", MockConfig({option: False}), "a\\xe7\\xe3o"), + ("ação", MockConfig({option: True}), "ação"), + ("ação", MockConfig({option: False}), "a\\xe7\\xe3o"), ] for val, config, expected in values: assert _idval(val, "a", 6, None, item=None, config=config) == expected @@ -269,7 +268,7 @@ def test_bytes_idval(self): (b"", ""), (b"\xc3\xb4\xff\xe4", "\\xc3\\xb4\\xff\\xe4"), (b"ascii", "ascii"), - (u"αρά".encode("utf-8"), "\\xce\\xb1\\xcf\\x81\\xce\\xac"), + ("αρά".encode(), "\\xce\\xb1\\xcf\\x81\\xce\\xac"), ] for val, expected in values: assert _idval(val, "a", 6, idfn=None, item=None, config=None) == expected @@ -280,7 +279,7 @@ def test_class_or_function_idval(self): """ from _pytest.python import _idval - class TestClass(object): + class TestClass: pass def test_function(): @@ -304,7 +303,7 @@ def test_idmaker_autoname(self): ) assert result == ["a0-1.0", "a1-b1"] # unicode mixing, issue250 - result = idmaker((u"a", "b"), [pytest.param({}, b"\xc3\xb4")]) + result = idmaker(("a", "b"), [pytest.param({}, b"\xc3\xb4")]) assert result == ["a0-\\xc3\\xb4"] def test_idmaker_with_bytes_regex(self): @@ -330,7 +329,7 @@ def test_idmaker_native_strings(self): pytest.param({7}, set("seven")), pytest.param(tuple("eight"), (8, -8, 8)), pytest.param(b"\xc3\xb4", b"name"), - pytest.param(b"\xc3\xb4", u"other"), + pytest.param(b"\xc3\xb4", "other"), ], ) assert result == [ @@ -428,7 +427,7 @@ def test_idmaker_with_idfn_and_config(self): """ from _pytest.python import idmaker - class MockConfig(object): + class MockConfig: def __init__(self, config): self.config = config @@ -445,12 +444,12 @@ def getini(self, name): option = "disable_test_id_escaping_and_forfeit_all_rights_to_community_support" values = [ - (MockConfig({option: True}), u"ação"), + (MockConfig({option: True}), "ação"), (MockConfig({option: False}), "a\\xe7\\xe3o"), ] for config, expected in values: result = idmaker( - ("a",), [pytest.param("string")], idfn=lambda _: u"ação", config=config + ("a",), [pytest.param("string")], idfn=lambda _: "ação", config=config ) assert result == [expected] @@ -461,7 +460,7 @@ def test_idmaker_with_ids_and_config(self): """ from _pytest.python import idmaker - class MockConfig(object): + class MockConfig: def __init__(self, config): self.config = config @@ -478,12 +477,12 @@ def getini(self, name): option = "disable_test_id_escaping_and_forfeit_all_rights_to_community_support" values = [ - (MockConfig({option: True}), u"ação"), + (MockConfig({option: True}), "ação"), (MockConfig({option: False}), "a\\xe7\\xe3o"), ] for config, expected in values: result = idmaker( - ("a",), [pytest.param("string")], ids=[u"ação"], config=config + ("a",), [pytest.param("string")], ids=["ação"], config=config ) assert result == [expected] @@ -888,7 +887,7 @@ def function4(arg1, *args, **kwargs): assert fixtures._format_args(function4) == "(arg1, *args, **kwargs)" -class TestMetafuncFunctional(object): +class TestMetafuncFunctional: def test_attributes(self, testdir): p = testdir.makepyfile( """ @@ -1324,7 +1323,7 @@ def test_foo(x): ) -class TestMetafuncFunctionalAuto(object): +class TestMetafuncFunctionalAuto: """ Tests related to automatically find out the correct scope for parametrized tests (#1832). """ @@ -1486,7 +1485,7 @@ def pytest_generate_tests(metafunc): assert output.count("preparing foo-3") == 1 -class TestMarkersWithParametrization(object): +class TestMarkersWithParametrization: """#308""" def test_simple_mark(self, testdir): diff --git a/testing/python/raises.py b/testing/python/raises.py index 5f5ca6b8fda..bfcb3dbb163 100644 --- a/testing/python/raises.py +++ b/testing/python/raises.py @@ -5,7 +5,7 @@ from _pytest.warning_types import PytestDeprecationWarning -class TestRaises(object): +class TestRaises: def test_raises(self): source = "int('qwe')" with pytest.warns(PytestDeprecationWarning): @@ -33,7 +33,7 @@ def test_raises_function(self): pytest.raises(ValueError, int, "hello") def test_raises_callable_no_exception(self): - class A(object): + class A: def __call__(self): pass @@ -187,7 +187,7 @@ def test_raises_cyclic_reference(self, method): """ import gc - class T(object): + class T: def __call__(self): raise ValueError @@ -235,8 +235,6 @@ def test_raises_match_wrong_type(self): int("asdf") def test_raises_exception_looks_iterable(self): - from six import add_metaclass - class Meta(type(object)): def __getitem__(self, item): return 1 / 0 @@ -244,8 +242,7 @@ def __getitem__(self, item): def __len__(self): return 1 - @add_metaclass(Meta) - class ClassLooksIterableException(Exception): + class ClassLooksIterableException(Exception, metaclass=Meta): pass with pytest.raises( diff --git a/testing/python/show_fixtures_per_test.py b/testing/python/show_fixtures_per_test.py index 8fdaa24f4b3..aff8aa0e5e2 100644 --- a/testing/python/show_fixtures_per_test.py +++ b/testing/python/show_fixtures_per_test.py @@ -1,5 +1,3 @@ - - def test_no_items_should_not_show_output(testdir): result = testdir.runpytest("--fixtures-per-test") assert "fixtures used by" not in result.stdout.str() diff --git a/testing/test_argcomplete.py b/testing/test_argcomplete.py index 98d51bc258a..7ccca11ba70 100644 --- a/testing/test_argcomplete.py +++ b/testing/test_argcomplete.py @@ -30,7 +30,7 @@ def _wrapcall(*args, **kargs): return [] -class FilesCompleter(object): +class FilesCompleter: "File completer class, optionally takes a list of allowed extensions" def __init__(self, allowednames=(), directories=True): @@ -73,7 +73,7 @@ def __call__(self, prefix, **kwargs): return completion -class TestArgComplete(object): +class TestArgComplete: @pytest.mark.skipif("sys.platform in ('win32', 'darwin')") def test_compare_with_compgen(self, tmpdir): from _pytest._argcomplete import FastFilesCompleter diff --git a/testing/test_assertion.py b/testing/test_assertion.py index 79970ea97a7..6102f957831 100644 --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -3,7 +3,6 @@ import textwrap import attr -import six import _pytest.assertion as plugin import pytest @@ -13,7 +12,7 @@ def mock_config(): - class Config(object): + class Config: verbose = False def getoption(self, name): @@ -24,7 +23,7 @@ def getoption(self, name): return Config() -class TestImportHookInstallation(object): +class TestImportHookInstallation: @pytest.mark.parametrize("initial_conftest", [True, False]) @pytest.mark.parametrize("mode", ["plain", "rewrite"]) def test_conftest_assertion_rewrite(self, testdir, initial_conftest, mode): @@ -269,7 +268,7 @@ def test_register_assert_rewrite_checks_types(self): ) -class TestBinReprIntegration(object): +class TestBinReprIntegration: def test_pytest_assertrepr_compare_called(self, testdir): testdir.makeconftest( """ @@ -301,7 +300,7 @@ def callequal(left, right, verbose=False): return plugin.pytest_assertrepr_compare(config, "==", left, right) -class TestAssert_reprcompare(object): +class TestAssert_reprcompare: def test_different_types(self): assert callequal([0, 1], "foo") is None @@ -527,7 +526,7 @@ def __repr__(self): assert "+" + repr(nums_y) in expl def test_list_bad_repr(self): - class A(object): + class A: def __repr__(self): raise ValueError(42) @@ -554,12 +553,12 @@ def test_repr_no_exc(self): assert "raised in repr()" not in expl def test_unicode(self): - left = u"£€" - right = u"£" + left = "£€" + right = "£" expl = callequal(left, right) - assert expl[0] == u"'£€' == '£'" - assert expl[1] == u"- £€" - assert expl[2] == u"+ £" + assert expl[0] == "'£€' == '£'" + assert expl[1] == "- £€" + assert expl[2] == "+ £" def test_nonascii_text(self): """ @@ -583,12 +582,12 @@ def test_mojibake(self): right = b"\xc3\xa9" expl = callequal(left, right) for line in expl: - assert isinstance(line, six.text_type) - msg = u"\n".join(expl) + assert isinstance(line, str) + msg = "\n".join(expl) assert msg -class TestAssert_reprcompare_dataclass(object): +class TestAssert_reprcompare_dataclass: @pytest.mark.skipif(sys.version_info < (3, 7), reason="Dataclasses in Python3.7+") def test_dataclasses(self, testdir): p = testdir.copy_example("dataclasses/test_compare_dataclasses.py") @@ -633,10 +632,10 @@ def test_comparing_two_different_data_classes(self, testdir): result.assert_outcomes(failed=0, passed=1) -class TestAssert_reprcompare_attrsclass(object): +class TestAssert_reprcompare_attrsclass: def test_attrs(self): @attr.s - class SimpleDataObject(object): + class SimpleDataObject: field_a = attr.ib() field_b = attr.ib() @@ -651,7 +650,7 @@ class SimpleDataObject(object): def test_attrs_verbose(self): @attr.s - class SimpleDataObject(object): + class SimpleDataObject: field_a = attr.ib() field_b = attr.ib() @@ -665,7 +664,7 @@ class SimpleDataObject(object): def test_attrs_with_attribute_comparison_off(self): @attr.s - class SimpleDataObject(object): + class SimpleDataObject: field_a = attr.ib() field_b = attr.ib(cmp=False) @@ -681,12 +680,12 @@ class SimpleDataObject(object): def test_comparing_two_different_attrs_classes(self): @attr.s - class SimpleDataObjectOne(object): + class SimpleDataObjectOne: field_a = attr.ib() field_b = attr.ib() @attr.s - class SimpleDataObjectTwo(object): + class SimpleDataObjectTwo: field_a = attr.ib() field_b = attr.ib() @@ -697,7 +696,7 @@ class SimpleDataObjectTwo(object): assert lines is None -class TestFormatExplanation(object): +class TestFormatExplanation: def test_special_chars_full(self, testdir): # Issue 453, for the bug this would raise IndexError testdir.makepyfile( @@ -784,7 +783,7 @@ def test_fmt_multi_newline_before_where(self): assert util.format_explanation(expl) == res -class TestTruncateExplanation(object): +class TestTruncateExplanation: """ Confirm assertion output is truncated as expected """ @@ -1218,7 +1217,7 @@ def test_tuple(): def test_assert_with_unicode(monkeypatch, testdir): testdir.makepyfile( - u""" + """ # -*- coding: utf-8 -*- def test_unicode(): assert u'유니코드' == u'Unicode' @@ -1243,7 +1242,7 @@ def test_raise_assertion_error(): def test_raise_assertion_error_raisin_repr(testdir): testdir.makepyfile( - u""" + """ class RaisingRepr(object): def __repr__(self): raise Exception() diff --git a/testing/test_assertrewrite.py b/testing/test_assertrewrite.py index b629a407728..6720a790f50 100644 --- a/testing/test_assertrewrite.py +++ b/testing/test_assertrewrite.py @@ -8,7 +8,6 @@ import zipfile import py -import six import _pytest._code import pytest @@ -50,7 +49,7 @@ def getmsg(f, extra_ns=None, must_pass=False): except AssertionError: if must_pass: pytest.fail("shouldn't have raised") - s = six.text_type(sys.exc_info()[1]) + s = str(sys.exc_info()[1]) if not s.startswith("assert"): return "AssertionError: " + s return s @@ -59,7 +58,7 @@ def getmsg(f, extra_ns=None, must_pass=False): pytest.fail("function didn't raise at all") -class TestAssertionRewrite(object): +class TestAssertionRewrite: def test_place_initial_imports(self): s = """'Doc string'\nother = stuff""" m = rewrite(s) @@ -152,7 +151,7 @@ def f(): def f(): assert cls == 42 # noqa: F821 - class X(object): + class X: pass msg = getmsg(f, {"cls": X}).splitlines() @@ -167,7 +166,7 @@ class X(object): assert msg == ["assert cls == 42"] def test_dont_rewrite_if_hasattr_fails(self, request): - class Y(object): + class Y: """ A class whos getattr fails, but not with `AttributeError` """ def __getattr__(self, attribute_name): @@ -506,7 +505,7 @@ def f(): ) def test_attribute(self): - class X(object): + class X: g = 3 ns = {"x": X} @@ -596,7 +595,7 @@ def f(): def test_assert_raising_nonzero_in_comparison(self): def f(): - class A(object): + class A: def __nonzero__(self): raise ValueError(42) @@ -621,7 +620,7 @@ def f(): def test_custom_repr(self, request): def f(): - class Foo(object): + class Foo: a = 1 def __repr__(self): @@ -644,8 +643,8 @@ def f(): def test_custom_repr_non_ascii(self): def f(): - class A(object): - name = u"ä" + class A: + name = "ä" def __repr__(self): return self.name.encode("UTF-8") # only legal in python2 @@ -730,7 +729,7 @@ def test_for_loop(): result.stdout.fnmatch_lines(["*assert False*", "*where False = check_even(1)*"]) -class TestRewriteOnImport(object): +class TestRewriteOnImport: def test_pycache_is_a_file(self, testdir): testdir.tmpdir.join("__pycache__").write("Hello") testdir.makepyfile( @@ -950,7 +949,7 @@ def test(): assert "pytest-warning summary" not in result.stdout.str() -class TestAssertionRewriteHookDetails(object): +class TestAssertionRewriteHookDetails: def test_loader_is_package_false_for_module(self, testdir): testdir.makepyfile( test_fun=""" @@ -1169,7 +1168,7 @@ def test_long_repr(): assert "unbalanced braces" not in result.stdout.str() -class TestIssue925(object): +class TestIssue925: def test_simple_case(self, testdir): testdir.makepyfile( """ @@ -1276,7 +1275,7 @@ def spy_write_pyc(*args, **kwargs): assert len(write_pyc_called) == 1 -class TestEarlyRewriteBailout(object): +class TestEarlyRewriteBailout: @pytest.fixture def hook(self, pytestconfig, monkeypatch, testdir): """Returns a patched AssertionRewritingHook instance so we can configure its initial paths and track @@ -1287,7 +1286,7 @@ def hook(self, pytestconfig, monkeypatch, testdir): self.find_module_calls = [] self.initial_paths = set() - class StubSession(object): + class StubSession: _initialpaths = self.initial_paths def isinitpath(self, p): diff --git a/testing/test_cacheprovider.py b/testing/test_cacheprovider.py index 31bf530f70b..a2e701740a0 100644 --- a/testing/test_cacheprovider.py +++ b/testing/test_cacheprovider.py @@ -11,7 +11,7 @@ pytest_plugins = ("pytester",) -class TestNewAPI(object): +class TestNewAPI: def test_config_cache_makedir(self, testdir): testdir.makeini("[pytest]") config = testdir.parseconfigure() @@ -236,7 +236,7 @@ def pytest_configure(config): assert result.ret == 0 -class TestLastFailed(object): +class TestLastFailed: def test_lastfailed_usecase(self, testdir, monkeypatch): monkeypatch.setenv("PYTHONDONTWRITEBYTECODE", "1") p = testdir.makepyfile( @@ -870,7 +870,7 @@ def test_lastfailed_with_known_failures_not_being_selected(self, testdir): ) -class TestNewFirst(object): +class TestNewFirst: def test_newfirst_usecase(self, testdir): testdir.makepyfile( **{ @@ -995,7 +995,7 @@ def test_1(num): assert num ) -class TestReadme(object): +class TestReadme: def check_readme(self, testdir): config = testdir.parseconfigure() readme = config.cache._cachedir.joinpath("README.md") @@ -1034,7 +1034,7 @@ def test_gitignore(testdir): assert gitignore_path.read_text(encoding="UTF-8") == msg # Does not overwrite existing/custom one. - gitignore_path.write_text(u"custom") + gitignore_path.write_text("custom") cache.set("something", "else") assert gitignore_path.read_text(encoding="UTF-8") == "custom" diff --git a/testing/test_capture.py b/testing/test_capture.py index f2879dce9d1..1657f05d933 100644 --- a/testing/test_capture.py +++ b/testing/test_capture.py @@ -31,7 +31,7 @@ def StdCapture(out=True, err=True, in_=True): return capture.MultiCapture(out, err, in_, Capture=capture.SysCapture) -class TestCaptureManager(object): +class TestCaptureManager: def test_getmethod_default_no_fd(self, monkeypatch): from _pytest.capture import pytest_addoption from _pytest.config.argparsing import Parser @@ -142,7 +142,7 @@ def test_collect_capturing(testdir): ) -class TestPerTestCapturing(object): +class TestPerTestCapturing: def test_capture_and_fixtures(self, testdir): p = testdir.makepyfile( """ @@ -285,7 +285,7 @@ def test_capturing_error(): ) -class TestLoggingInteraction(object): +class TestLoggingInteraction: def test_logging_stream_ownership(self, testdir): p = testdir.makepyfile( """\ @@ -423,7 +423,7 @@ def test_hello(log_on_teardown): ) -class TestCaptureFixture(object): +class TestCaptureFixture: @pytest.mark.parametrize("opt", [[], ["-s"]]) def test_std_functional(self, testdir, opt): reprec = testdir.inline_runsource( @@ -801,7 +801,7 @@ def bad_snap(self): ) -class TestCaptureIO(object): +class TestCaptureIO: def test_text(self): f = capture.CaptureIO() f.write("hello") @@ -916,7 +916,7 @@ def lsof_check(): assert len2 < len1 + 3, out2 -class TestFDCapture(object): +class TestFDCapture: pytestmark = needsosdup def test_simple(self, tmpfile): @@ -1014,7 +1014,7 @@ def saved_fd(fd): os.close(new_fd) -class TestStdCapture(object): +class TestStdCapture: captureclass = staticmethod(StdCapture) @contextlib.contextmanager @@ -1065,7 +1065,7 @@ def test_capturing_readouterr_unicode(self): with self.getcapture() as cap: print("hxąć") out, err = cap.readouterr() - assert out == u"hxąć\n" + assert out == "hxąć\n" def test_reset_twice_error(self): with self.getcapture() as cap: @@ -1175,7 +1175,7 @@ def test_many(self, capfd): cap.stop_capturing() -class TestStdCaptureFDinvalidFD(object): +class TestStdCaptureFDinvalidFD: pytestmark = needsosdup def test_stdcapture_fd_invalid_fd(self, testdir): @@ -1338,7 +1338,7 @@ def test_py36_windowsconsoleio_workaround_non_standard_streams(): """ from _pytest.capture import _py36_windowsconsoleio_workaround - class DummyStream(object): + class DummyStream: def write(self, s): pass diff --git a/testing/test_collection.py b/testing/test_collection.py index 0ecc7cf22f3..c938a915d1d 100644 --- a/testing/test_collection.py +++ b/testing/test_collection.py @@ -12,7 +12,7 @@ from _pytest.main import Session -class TestCollector(object): +class TestCollector: def test_collect_versus_item(self): from pytest import Collector, Item @@ -102,7 +102,7 @@ def test_foo(): result.stdout.fnmatch_lines(["collected 0 items", "*no tests ran in*"]) -class TestCollectFS(object): +class TestCollectFS: def test_ignored_certain_directories(self, testdir): tmpdir = testdir.tmpdir tmpdir.ensure("build", "test_notfound.py") @@ -239,11 +239,11 @@ def test_testpaths_ini(self, testdir, monkeypatch): assert [x.name for x in items] == ["test_%s" % dirname] -class TestCollectPluginHookRelay(object): +class TestCollectPluginHookRelay: def test_pytest_collect_file(self, testdir): wascalled = [] - class Plugin(object): + class Plugin: def pytest_collect_file(self, path, parent): if not path.basename.startswith("."): # Ignore hidden files, e.g. .testmondata. @@ -257,7 +257,7 @@ def pytest_collect_file(self, path, parent): def test_pytest_collect_directory(self, testdir): wascalled = [] - class Plugin(object): + class Plugin: def pytest_collect_directory(self, path, parent): wascalled.append(path.basename) @@ -268,7 +268,7 @@ def pytest_collect_directory(self, path, parent): assert "world" in wascalled -class TestPrunetraceback(object): +class TestPrunetraceback: def test_custom_repr_failure(self, testdir): p = testdir.makepyfile( """ @@ -317,7 +317,7 @@ def pytest_make_collect_report(): result.stdout.fnmatch_lines(["*ERROR collecting*", "*header1*"]) -class TestCustomConftests(object): +class TestCustomConftests: def test_ignore_collect_path(self, testdir): testdir.makeconftest( """ @@ -438,7 +438,7 @@ def pytest_collect_file(path, parent): result.stdout.fnmatch_lines(["*MyModule1*", "*MyModule2*", "*test_x*"]) -class TestSession(object): +class TestSession: def test_parsearg(self, testdir): p = testdir.makepyfile("def test_func(): pass") subdir = testdir.mkdir("sub") @@ -629,7 +629,7 @@ def test_method(self): assert [x.name for x in self.get_reported_items(hookrec)] == ["test_method"] -class Test_getinitialnodes(object): +class Test_getinitialnodes: def test_global_file(self, testdir, tmpdir): x = tmpdir.ensure("x.py") with tmpdir.as_cwd(): @@ -663,7 +663,7 @@ def test_pkgfile(self, testdir): assert col.config is config -class Test_genitems(object): +class Test_genitems: def test_check_collect_hashes(self, testdir): p = testdir.makepyfile( """ @@ -776,7 +776,7 @@ def runtest(self): res.stdout.fnmatch_lines(["*1 passed*"]) -class TestNodekeywords(object): +class TestNodekeywords: def test_no_under(self, testdir): modcol = testdir.getmodulecol( """ diff --git a/testing/test_compat.py b/testing/test_compat.py index 7464752ac3a..028d48bed30 100644 --- a/testing/test_compat.py +++ b/testing/test_compat.py @@ -22,7 +22,7 @@ def foo(): def test_real_func_loop_limit(): - class Evil(object): + class Evil: def __init__(self): self.left = 1000 @@ -113,7 +113,7 @@ async def bar(): result.stdout.fnmatch_lines(["*1 passed*"]) -class ErrorsHelper(object): +class ErrorsHelper: @property def raise_exception(self): raise Exception("exception should be catched") diff --git a/testing/test_config.py b/testing/test_config.py index a406eccef14..7b2a1209eaf 100644 --- a/testing/test_config.py +++ b/testing/test_config.py @@ -16,7 +16,7 @@ from _pytest.main import EXIT_USAGEERROR -class TestParseIni(object): +class TestParseIni: @pytest.mark.parametrize( "section, filename", [("pytest", "pytest.ini"), ("tool:pytest", "setup.cfg")] ) @@ -139,7 +139,7 @@ def test_confcutdir(self, testdir): assert result.ret == 0 -class TestConfigCmdlineParsing(object): +class TestConfigCmdlineParsing: def test_parsing_again_fails(self, testdir): config = testdir.parseconfig() pytest.raises(AssertionError, lambda: config.parse([])) @@ -192,7 +192,7 @@ def test_absolute_win32_path(self, testdir): assert ret == _pytest.main.EXIT_OK -class TestConfigAPI(object): +class TestConfigAPI: def test_config_trace(self, testdir): config = testdir.parseconfig() values = [] @@ -428,7 +428,7 @@ def test_iter_rewritable_modules(self, names, expected): assert list(_iter_rewritable_modules(["/".join(names)])) == expected -class TestConfigFromdictargs(object): +class TestConfigFromdictargs: def test_basic_behavior(self, _sys_snapshot): from _pytest.config import Config @@ -526,17 +526,17 @@ def test_f2(): assert 0 def test_preparse_ordering_with_setuptools(testdir, monkeypatch): monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD", raising=False) - class EntryPoint(object): + class EntryPoint: name = "mytestplugin" group = "pytest11" def load(self): - class PseudoPlugin(object): + class PseudoPlugin: x = 42 return PseudoPlugin() - class Dist(object): + class Dist: files = () entry_points = (EntryPoint(),) @@ -558,14 +558,14 @@ def my_dists(): def test_setuptools_importerror_issue1479(testdir, monkeypatch): monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD", raising=False) - class DummyEntryPoint(object): + class DummyEntryPoint: name = "mytestplugin" group = "pytest11" def load(self): raise ImportError("Don't hide me!") - class Distribution(object): + class Distribution: version = "1.0" files = ("foo.txt",) entry_points = (DummyEntryPoint(),) @@ -584,14 +584,14 @@ def test_plugin_preparse_prevents_setuptools_loading(testdir, monkeypatch, block plugin_module_placeholder = object() - class DummyEntryPoint(object): + class DummyEntryPoint: name = "mytestplugin" group = "pytest11" def load(self): return plugin_module_placeholder - class Distribution(object): + class Distribution: version = "1.0" files = ("foo.txt",) entry_points = (DummyEntryPoint(),) @@ -616,7 +616,7 @@ def distributions(): "parse_args,should_load", [(("-p", "mytestplugin"), True), ((), False)] ) def test_disable_plugin_autoload(testdir, monkeypatch, parse_args, should_load): - class DummyEntryPoint(object): + class DummyEntryPoint: project_name = name = "mytestplugin" group = "pytest11" version = "1.0" @@ -624,11 +624,11 @@ class DummyEntryPoint(object): def load(self): return sys.modules[self.name] - class Distribution(object): + class Distribution: entry_points = (DummyEntryPoint(),) files = () - class PseudoPlugin(object): + class PseudoPlugin: x = 42 def distributions(): @@ -740,7 +740,7 @@ def test_notify_exception(testdir, capfd): out, err = capfd.readouterr() assert "ValueError" in err - class A(object): + class A: def pytest_internalerror(self, excrepr): return True @@ -760,7 +760,7 @@ def pytest_internalerror(self, excrepr): def test_load_initial_conftest_last_ordering(testdir, _config_for_test): pm = _config_for_test.pluginmanager - class My(object): + class My: def pytest_load_initial_conftests(self): pass @@ -798,15 +798,15 @@ def test_collect_pytest_prefix_bug_integration(testdir): def test_collect_pytest_prefix_bug(pytestconfig): """Ensure we collect only actual functions from conftest files (#3775)""" - class Dummy(object): - class pytest_something(object): + class Dummy: + class pytest_something: pass pm = pytestconfig.pluginmanager assert pm.parse_hookimpl_opts(Dummy(), "pytest_something") is None -class TestRootdir(object): +class TestRootdir: def test_simple_noini(self, tmpdir): assert get_common_ancestor([tmpdir]) == tmpdir a = tmpdir.mkdir("a") @@ -864,7 +864,7 @@ def test_with_specific_inifile(self, tmpdir): assert rootdir == tmpdir -class TestOverrideIniArgs(object): +class TestOverrideIniArgs: @pytest.mark.parametrize("name", "setup.cfg tox.ini pytest.ini".split()) def test_override_ini_names(self, testdir, name): section = "[pytest]" if name != "setup.cfg" else "[tool:pytest]" diff --git a/testing/test_conftest.py b/testing/test_conftest.py index 1750c02118d..f29531eb7bd 100644 --- a/testing/test_conftest.py +++ b/testing/test_conftest.py @@ -16,7 +16,7 @@ def ConftestWithSetinitial(path): def conftest_setinitial(conftest, args, confcutdir=None): - class Namespace(object): + class Namespace: def __init__(self): self.file_or_dir = args self.confcutdir = str(confcutdir) @@ -27,7 +27,7 @@ def __init__(self): @pytest.mark.usefixtures("_sys_snapshot") -class TestConftestValueAccessGlobal(object): +class TestConftestValueAccessGlobal: @pytest.fixture(scope="module", params=["global", "inpackage"]) def basedir(self, request, tmpdir_factory): tmpdir = tmpdir_factory.mktemp("basedir", numbered=True) @@ -396,7 +396,7 @@ def pytest_addoption(parser): ) -class TestConftestVisibility(object): +class TestConftestVisibility: def _setup_tree(self, testdir): # for issue616 # example mostly taken from: # https://mail.python.org/pipermail/pytest-dev/2014-September/002617.html diff --git a/testing/test_doctest.py b/testing/test_doctest.py index 0b6587b9b7a..54b23e15d09 100644 --- a/testing/test_doctest.py +++ b/testing/test_doctest.py @@ -7,7 +7,7 @@ from _pytest.doctest import DoctestTextfile -class TestDoctests(object): +class TestDoctests: def test_collect_testtextfile(self, testdir): w = testdir.maketxtfile(whatever="") checkfile = testdir.maketxtfile( @@ -139,7 +139,7 @@ def test_multiple_patterns(self, testdir): @pytest.mark.parametrize( " test_string, encoding", - [(u"foo", "ascii"), (u"öäü", "latin1"), (u"öäü", "utf-8")], + [("foo", "ascii"), ("öäü", "latin1"), ("öäü", "utf-8")], ) def test_encoding(self, testdir, test_string, encoding): """Test support for doctest_encoding ini option. @@ -152,7 +152,7 @@ def test_encoding(self, testdir, test_string, encoding): encoding ) ) - doctest = u""" + doctest = """ >>> u"{}" {} """.format( @@ -574,7 +574,7 @@ def test_contains_unicode(self, testdir): """Fix internal error with docstrings containing non-ascii characters. """ testdir.makepyfile( - u''' + ''' # -*- coding: utf-8 -*- def foo(): """ @@ -733,7 +733,7 @@ def test_foo(): result.stdout.fnmatch_lines(["*collected 1 item*"]) -class TestLiterals(object): +class TestLiterals: @pytest.mark.parametrize("config_mode", ["ini", "comment"]) def test_allow_unicode(self, testdir, config_mode): """Test that doctests which output unicode work in all python versions @@ -840,7 +840,7 @@ def test_bytes_literal(self, testdir): reprec.assertoutcome(failed=1) -class TestDoctestSkips(object): +class TestDoctestSkips: """ If all examples in a doctest are skipped due to the SKIP option, then the tests should be SKIPPED rather than PASSED. (#957) @@ -921,7 +921,7 @@ def test_continue_on_failure(self, testdir): ) -class TestDoctestAutoUseFixtures(object): +class TestDoctestAutoUseFixtures: SCOPES = ["module", "session", "class", "function"] @@ -1065,7 +1065,7 @@ def auto(request): result.stdout.fnmatch_lines(["*=== 1 passed in *"]) -class TestDoctestNamespaceFixture(object): +class TestDoctestNamespaceFixture: SCOPES = ["module", "session", "class", "function"] @@ -1127,7 +1127,7 @@ def foo(): reprec.assertoutcome(passed=1) -class TestDoctestReportingOption(object): +class TestDoctestReportingOption: def _run_doctest_report(self, testdir, format): testdir.makepyfile( """ diff --git a/testing/test_junitxml.py b/testing/test_junitxml.py index 808aad615b1..aa7287fb531 100644 --- a/testing/test_junitxml.py +++ b/testing/test_junitxml.py @@ -28,7 +28,7 @@ def nodeval(node, name): assert on_node == expected -class DomNode(object): +class DomNode: def __init__(self, dom): self.__node = dom @@ -79,7 +79,7 @@ def next_siebling(self): return type(self)(self.__node.nextSibling) -class TestPython(object): +class TestPython: def test_summing_simple(self, testdir): testdir.makepyfile( """ @@ -696,7 +696,7 @@ def test_mangle_test_address(): def test_dont_configure_on_slaves(tmpdir): gotten = [] - class FakeConfig(object): + class FakeConfig: def __init__(self): self.pluginmanager = self self.option = self @@ -719,7 +719,7 @@ def getini(self, name): assert len(gotten) == 1 -class TestNonPython(object): +class TestNonPython: def test_summing_simple(self, testdir): testdir.makeconftest( """ @@ -922,7 +922,7 @@ def test_func(self, param): def test_unicode_issue368(testdir): path = testdir.tmpdir.join("test.xml") log = LogXML(str(path), None) - ustr = u"ВНИ!" + ustr = "ВНИ!" class Report(BaseReport): longrepr = ustr @@ -1166,13 +1166,13 @@ def test_pass(): pprint.pprint(items) assert items == [ - u"conftest a", - u"conftest a", - u"conftest b", - u"test_fancy_items_regression a", - u"test_fancy_items_regression a", - u"test_fancy_items_regression b", - u"test_fancy_items_regression test_pass", + "conftest a", + "conftest a", + "conftest b", + "test_fancy_items_regression a", + "test_fancy_items_regression a", + "test_fancy_items_regression b", + "test_fancy_items_regression test_pass", ] diff --git a/testing/test_mark.py b/testing/test_mark.py index 997ed047230..c66b85568aa 100644 --- a/testing/test_mark.py +++ b/testing/test_mark.py @@ -16,7 +16,7 @@ ) -class TestMark(object): +class TestMark: @pytest.mark.parametrize("attr", ["mark", "param"]) @pytest.mark.parametrize("modulename", ["py.test", "pytest"]) def test_pytest_exists_in_namespace_all(self, attr, modulename): @@ -31,7 +31,7 @@ def test_mark_with_param(self): def some_function(abc): pass - class SomeClass(object): + class SomeClass: pass assert pytest.mark.foo(some_function) is some_function @@ -424,7 +424,7 @@ def test(a): result.stdout.fnmatch_lines(["*3 passed*"]) -class TestFunctional(object): +class TestFunctional: def test_merging_markers_deep(self, testdir): # issue 199 - propagate markers into nested classes p = testdir.makepyfile( @@ -693,7 +693,7 @@ def test_1(parameter): reprec.assertoutcome(skipped=1) -class TestKeywordSelection(object): +class TestKeywordSelection: def test_select_simple(self, testdir): file_test = testdir.makepyfile( """ @@ -824,7 +824,7 @@ def assert_test_is_not_selected(keyword): assert_test_is_not_selected("()") -class TestMarkDecorator(object): +class TestMarkDecorator: @pytest.mark.parametrize( "lhs, rhs, expected", [ diff --git a/testing/test_monkeypatch.py b/testing/test_monkeypatch.py index efa8fe46471..eee8baf3a69 100644 --- a/testing/test_monkeypatch.py +++ b/testing/test_monkeypatch.py @@ -17,7 +17,7 @@ def mp(): def test_setattr(): - class A(object): + class A: x = 1 monkeypatch = MonkeyPatch() @@ -40,7 +40,7 @@ class A(object): assert A.x == 5 -class TestSetattrWithImportPath(object): +class TestSetattrWithImportPath: def test_string_expression(self, monkeypatch): monkeypatch.setattr("os.path.abspath", lambda x: "hello2") assert os.path.abspath("123") == "hello2" @@ -82,7 +82,7 @@ def test_delattr(self, monkeypatch): def test_delattr(): - class A(object): + class A: x = 1 monkeypatch = MonkeyPatch() @@ -193,14 +193,14 @@ def test_delenv(): del os.environ[name] -class TestEnvironWarnings(object): +class TestEnvironWarnings: """ os.environ keys and values should be native strings, otherwise it will cause problems with other modules (notably subprocess). On Python 2 os.environ accepts anything without complaining, while Python 3 does the right thing and raises an error. """ - VAR_NAME = u"PYTEST_INTERNAL_MY_VAR" + VAR_NAME = "PYTEST_INTERNAL_MY_VAR" def test_setenv_non_str_warning(self, monkeypatch): value = 2 @@ -331,7 +331,7 @@ def test_importerror(monkeypatch): ) -class SampleNew(object): +class SampleNew: @staticmethod def hello(): return True @@ -341,7 +341,7 @@ class SampleNewInherit(SampleNew): pass -class SampleOld(object): +class SampleOld: # oldstyle on python2 @staticmethod def hello(): @@ -368,7 +368,7 @@ def test_issue156_undo_staticmethod(Sample): def test_undo_class_descriptors_delattr(): - class SampleParent(object): + class SampleParent: @classmethod def hello(_cls): pass diff --git a/testing/test_nose.py b/testing/test_nose.py index a114c5bb3d0..b726c9682cf 100644 --- a/testing/test_nose.py +++ b/testing/test_nose.py @@ -31,7 +31,7 @@ def test_setup_func_with_setup_decorator(): values = [] - class A(object): + class A: @pytest.fixture(autouse=True) def f(self): values.append(1) @@ -43,7 +43,7 @@ def f(self): def test_setup_func_not_callable(): from _pytest.nose import call_optional - class A(object): + class A: f = 1 call_optional(A(), "f") diff --git a/testing/test_parseopt.py b/testing/test_parseopt.py index 549a7efda56..7c581cce164 100644 --- a/testing/test_parseopt.py +++ b/testing/test_parseopt.py @@ -15,7 +15,7 @@ def parser(): return parseopt.Parser() -class TestParser(object): +class TestParser: def test_no_help_by_default(self): parser = parseopt.Parser(usage="xyz") pytest.raises(UsageError, lambda: parser.parse(["-h"])) @@ -152,7 +152,7 @@ def test_parse_setoption(self, parser): parser.addoption("--hello", dest="hello", action="store") parser.addoption("--world", dest="world", default=42) - class A(object): + class A: pass option = A() diff --git a/testing/test_pastebin.py b/testing/test_pastebin.py index 29b66e6ac0e..eb2fd8faef6 100644 --- a/testing/test_pastebin.py +++ b/testing/test_pastebin.py @@ -1,7 +1,7 @@ import pytest -class TestPasteCapture(object): +class TestPasteCapture: @pytest.fixture def pastebinlist(self, monkeypatch, request): pastebinlist = [] @@ -77,7 +77,7 @@ def test(): ) -class TestPaste(object): +class TestPaste: @pytest.fixture def pastebin(self, request): return request.config.pluginmanager.getplugin("pastebin") @@ -93,7 +93,7 @@ def mocked_urlopen(self, monkeypatch): def mocked(url, data): calls.append((url, data)) - class DummyFile(object): + class DummyFile: def read(self): # part of html of a normal response return b'View raw.' diff --git a/testing/test_pdb.py b/testing/test_pdb.py index b566c12191f..f3f7ca70233 100644 --- a/testing/test_pdb.py +++ b/testing/test_pdb.py @@ -29,7 +29,7 @@ def custom_pdb_calls(): called = [] # install dummy debugger class and track which methods were called on it - class _CustomPdb(object): + class _CustomPdb: quitting = False def __init__(self, *args, **kwargs): @@ -50,7 +50,7 @@ def custom_debugger_hook(): called = [] # install dummy debugger class and track which methods were called on it - class _CustomDebugger(object): + class _CustomDebugger: def __init__(self, *args, **kwargs): called.append("init") @@ -69,7 +69,7 @@ def set_trace(self, frame): del _pytest._CustomDebugger -class TestPDB(object): +class TestPDB: @pytest.fixture def pdblist(self, request): monkeypatch = request.getfixturevalue("monkeypatch") @@ -666,7 +666,7 @@ def do_continue(self, arg): set_trace() """ ) - child = testdir.spawn_pytest("--tb=short %s %s" % (p1, capture_arg)) + child = testdir.spawn_pytest("--tb=short {} {}".format(p1, capture_arg)) child.expect("=== SET_TRACE ===") before = child.before.decode("utf8") if not capture_arg: @@ -846,7 +846,7 @@ def test_foo(): self.flush(child) -class TestDebuggingBreakpoints(object): +class TestDebuggingBreakpoints: def test_supports_breakpoint_module_global(self): """ Test that supports breakpoint global marks on Python 3.7+ and not on diff --git a/testing/test_pluginmanager.py b/testing/test_pluginmanager.py index d70a98a8474..4e476fc0154 100644 --- a/testing/test_pluginmanager.py +++ b/testing/test_pluginmanager.py @@ -14,7 +14,7 @@ def pytestpm(): return PytestPluginManager() -class TestPytestPluginInteractions(object): +class TestPytestPluginInteractions: def test_addhooks_conftestplugin(self, testdir, _config_for_test): testdir.makepyfile( newhooks=""" @@ -70,7 +70,7 @@ def test_configure(self, testdir): config = testdir.parseconfig() values = [] - class A(object): + class A: def pytest_configure(self, config): values.append(self) @@ -90,11 +90,11 @@ def test_hook_tracing(self, _config_for_test): pytestpm = _config_for_test.pluginmanager # fully initialized with plugins saveindent = [] - class api1(object): + class api1: def pytest_plugin_registered(self): saveindent.append(pytestpm.trace.root.indent) - class api2(object): + class api2: def pytest_plugin_registered(self): saveindent.append(pytestpm.trace.root.indent) raise ValueError() @@ -165,7 +165,7 @@ def test_traceback(): assert "in test_traceback" in str(excinfo.traceback[-1]) -class TestPytestPluginManager(object): +class TestPytestPluginManager: def test_register_imported_modules(self): pm = PytestPluginManager() mod = types.ModuleType("x.y.pytest_hello") @@ -295,7 +295,7 @@ def test_consider_conftest_deps(self, testdir, pytestpm): pytestpm.consider_conftest(mod) -class TestPytestPluginManagerBootstrapming(object): +class TestPytestPluginManagerBootstrapming: def test_preparse_args(self, pytestpm): pytest.raises( ImportError, lambda: pytestpm.consider_preparse(["xyz", "-p", "hello123"]) diff --git a/testing/test_pytester.py b/testing/test_pytester.py index e898d3c2ce2..82ff37c139a 100644 --- a/testing/test_pytester.py +++ b/testing/test_pytester.py @@ -25,7 +25,7 @@ def test_make_hook_recorder(testdir): pytest.xfail("internal reportrecorder tests need refactoring") - class rep(object): + class rep: excinfo = None passed = False failed = True @@ -38,7 +38,7 @@ class rep(object): failures = recorder.getfailures() assert failures == [rep] - class rep(object): + class rep: excinfo = None passed = False failed = False @@ -153,7 +153,7 @@ def test_potato(): def make_holder(): - class apiclass(object): + class apiclass: def pytest_xyz(self, arg): "x" @@ -199,17 +199,17 @@ def test_makepyfile_unicode(testdir): def test_makepyfile_utf8(testdir): """Ensure makepyfile accepts utf-8 bytes as input (#2738)""" - utf8_contents = u""" + utf8_contents = """ def setup_function(function): mixed_encoding = u'São Paulo' """.encode( "utf-8" ) p = testdir.makepyfile(utf8_contents) - assert u"mixed_encoding = u'São Paulo'".encode("utf-8") in p.read("rb") + assert "mixed_encoding = u'São Paulo'".encode() in p.read("rb") -class TestInlineRunModulesCleanup(object): +class TestInlineRunModulesCleanup: def test_inline_run_test_module_not_cleaned_up(self, testdir): test_mod = testdir.makepyfile("def test_foo(): assert True") result = testdir.inline_run(str(test_mod)) @@ -220,7 +220,7 @@ def test_inline_run_test_module_not_cleaned_up(self, testdir): assert result2.ret == EXIT_TESTSFAILED def spy_factory(self): - class SysModulesSnapshotSpy(object): + class SysModulesSnapshotSpy: instances = [] def __init__(self, preserve=None): @@ -303,7 +303,7 @@ def test_cwd_snapshot(tmpdir): assert py.path.local() == foo -class TestSysModulesSnapshot(object): +class TestSysModulesSnapshot: key = "my-test-module" def test_remove_added(self): @@ -366,7 +366,7 @@ def test_preserve_container(self, monkeypatch): @pytest.mark.parametrize("path_type", ("path", "meta_path")) -class TestSysPathsSnapshot(object): +class TestSysPathsSnapshot: other_path = {"path": "meta_path", "meta_path": "path"} @staticmethod @@ -417,7 +417,7 @@ def test_testdir_subprocess(testdir): def test_unicode_args(testdir): - result = testdir.runpytest("-k", u"💩") + result = testdir.runpytest("-k", "💩") assert result.ret == EXIT_NOTESTSCOLLECTED diff --git a/testing/test_recwarn.py b/testing/test_recwarn.py index 10fd8a48144..1c68b378752 100644 --- a/testing/test_recwarn.py +++ b/testing/test_recwarn.py @@ -26,7 +26,7 @@ def test_method(recwarn): reprec.assertoutcome(passed=1) -class TestWarningsRecorderChecker(object): +class TestWarningsRecorderChecker: def test_recording(self): rec = WarningsRecorder() with rec: @@ -73,7 +73,7 @@ def test_invalid_enter_exit(self): pass # can't enter twice -class TestDeprecatedCall(object): +class TestDeprecatedCall: """test pytest.deprecated_call()""" def dep(self, i, j=None): @@ -205,7 +205,7 @@ def test_deprecated_call_supports_match(self): warnings.warn("this is not here", DeprecationWarning) -class TestWarns(object): +class TestWarns: def test_strings(self): # different messages, b/c Python suppresses multiple identical warnings source1 = "warnings.warn('w1', RuntimeWarning)" diff --git a/testing/test_reports.py b/testing/test_reports.py index 6d2b167f871..b8b1a5406d1 100644 --- a/testing/test_reports.py +++ b/testing/test_reports.py @@ -4,7 +4,7 @@ from _pytest.reports import TestReport -class TestReportSerialization(object): +class TestReportSerialization: def test_xdist_longrepr_to_str_issue_241(self, testdir): """ Regarding issue pytest-xdist#241 @@ -43,7 +43,7 @@ def test_fail(): reports = reprec.getreports("pytest_runtest_logreport") assert len(reports) == 3 rep = reports[1] - added_section = ("Failure Metadata", str("metadata metadata"), "*") + added_section = ("Failure Metadata", "metadata metadata", "*") rep.longrepr.sections.append(added_section) d = rep._to_json() a = TestReport._from_json(d) diff --git a/testing/test_resultlog.py b/testing/test_resultlog.py index 5f284f2a287..9e8f621355b 100644 --- a/testing/test_resultlog.py +++ b/testing/test_resultlog.py @@ -50,7 +50,7 @@ def test_write_log_entry(): assert entry_lines[1:] == [" " + line for line in longrepr.splitlines()] -class TestWithFunctionIntegration(object): +class TestWithFunctionIntegration: # XXX (hpk) i think that the resultlog plugin should # provide a Parser object so that one can remain # ignorant regarding formatting details. diff --git a/testing/test_runner.py b/testing/test_runner.py index 8aedce2759e..61828294be4 100644 --- a/testing/test_runner.py +++ b/testing/test_runner.py @@ -13,7 +13,7 @@ from _pytest import runner -class TestSetupState(object): +class TestSetupState: def test_setup(self, testdir): ss = runner.SetupState() item = testdir.getitem("def test_func(): pass") @@ -101,7 +101,7 @@ def fin_module(): assert module_teardown -class BaseFunctionalTests(object): +class BaseFunctionalTests: def test_passfunction(self, testdir): reports = testdir.runitem( """ @@ -436,7 +436,7 @@ def test_func(): assert rep.when == "???" -class TestSessionReports(object): +class TestSessionReports: def test_collect_result(self, testdir): col = testdir.getmodulecol( """ @@ -639,7 +639,7 @@ def test_pytest_fail_notrace_non_ascii(testdir, str_prefix): This tests with native and unicode strings containing non-ascii chars. """ testdir.makepyfile( - u""" + """ # -*- coding: utf-8 -*- import pytest @@ -868,7 +868,7 @@ def test_store_except_info_on_error(): sys.last_traceback and friends. """ # Simulate item that might raise a specific exception, depending on `raise_error` class var - class ItemMightRaise(object): + class ItemMightRaise: nodeid = "item_that_raises" raise_error = True @@ -925,7 +925,7 @@ def test(fix): assert "PYTEST_CURRENT_TEST" not in os.environ -class TestReportContents(object): +class TestReportContents: """ Test user-level API of ``TestReport`` objects. """ diff --git a/testing/test_session.py b/testing/test_session.py index ebf7712037a..1a0ae808076 100644 --- a/testing/test_session.py +++ b/testing/test_session.py @@ -2,7 +2,7 @@ from _pytest.main import EXIT_NOTESTSCOLLECTED -class SessionTests(object): +class SessionTests: def test_basic_testitem_events(self, testdir): tfile = testdir.makepyfile( """ @@ -71,7 +71,7 @@ def test_syntax_error_module(self, testdir): values = reprec.getfailedcollections() assert len(values) == 1 out = str(values[0].longrepr) - assert out.find(str("not python")) != -1 + assert out.find("not python") != -1 def test_exit_first_problem(self, testdir): reprec = testdir.inline_runsource( diff --git a/testing/test_skipping.py b/testing/test_skipping.py index a848650b88b..6bb5f7aff7a 100644 --- a/testing/test_skipping.py +++ b/testing/test_skipping.py @@ -6,7 +6,7 @@ from _pytest.skipping import pytest_runtest_setup -class TestEvaluator(object): +class TestEvaluator: def test_no_marker(self, testdir): item = testdir.getitem("def test_func(): pass") evalskipif = MarkEvaluator(item, "skipif") @@ -131,7 +131,7 @@ def test_func(self): assert expl == "condition: config._hackxyz" -class TestXFail(object): +class TestXFail: @pytest.mark.parametrize("strict", [True, False]) def test_xfail_simple(self, testdir, strict): item = testdir.getitem( @@ -498,7 +498,7 @@ def test_foo(): assert result.ret == (1 if strict else 0) -class TestXFailwithSetupTeardown(object): +class TestXFailwithSetupTeardown: def test_failing_setup_issue9(self, testdir): testdir.makepyfile( """ @@ -530,7 +530,7 @@ def test_func(): result.stdout.fnmatch_lines(["*1 xfail*"]) -class TestSkip(object): +class TestSkip: def test_skip_class(self, testdir): testdir.makepyfile( """ @@ -627,7 +627,7 @@ def test_hello(): result.stdout.fnmatch_lines(["*unconditional skip*", "*1 skipped*"]) -class TestSkipif(object): +class TestSkipif: def test_skipif_conditional(self, testdir): item = testdir.getitem( """ @@ -982,7 +982,7 @@ def pytest_runtest_setup(item): ) -class TestBooleanCondition(object): +class TestBooleanCondition: def test_skipif(self, testdir): testdir.makepyfile( """ diff --git a/testing/test_terminal.py b/testing/test_terminal.py index 37f4c9dba0f..f53cb6837bf 100644 --- a/testing/test_terminal.py +++ b/testing/test_terminal.py @@ -22,7 +22,7 @@ DistInfo = collections.namedtuple("DistInfo", ["project_name", "version"]) -class Option(object): +class Option: def __init__(self, verbosity=0, fulltrace=False): self.verbosity = verbosity self.fulltrace = fulltrace @@ -70,7 +70,7 @@ def test_plugin_nameversion(input, expected): assert result == expected -class TestTerminal(object): +class TestTerminal: def test_pass_skip_fail(self, testdir, option): testdir.makepyfile( """ @@ -277,7 +277,7 @@ def test_rewrite(self, testdir, monkeypatch): assert f.getvalue() == "hello" + "\r" + "hey" + (6 * " ") -class TestCollectonly(object): +class TestCollectonly: def test_collectonly_basic(self, testdir): testdir.makepyfile( """ @@ -385,7 +385,7 @@ def test_collectonly_more_quiet(self, testdir): result.stdout.fnmatch_lines(["*test_fun.py: 1*"]) -class TestFixtureReporting(object): +class TestFixtureReporting: def test_setup_fixture_error(self, testdir): testdir.makepyfile( """ @@ -485,7 +485,7 @@ def teardown_function(function): ) -class TestTerminalFunctional(object): +class TestTerminalFunctional: def test_deselected(self, testdir): testpath = testdir.makepyfile( """ @@ -858,8 +858,8 @@ def test_this(i): def test_getreportopt(): - class Config(object): - class Option(object): + class Config: + class Option: reportchars = "" disable_warnings = True @@ -940,7 +940,7 @@ def test_traceconfig(testdir, monkeypatch): assert result.ret == EXIT_NOTESTSCOLLECTED -class TestGenericReporting(object): +class TestGenericReporting: """ this test class can be subclassed with a different option provider to run e.g. distributed tests. """ @@ -1320,7 +1320,7 @@ class DummyReport(BaseReport): assert res == ("1 failed", "red") -class TestClassicOutputStyle(object): +class TestClassicOutputStyle: """Ensure classic output style works as expected (#3883)""" @pytest.fixture @@ -1366,7 +1366,7 @@ def test_quiet(self, testdir, test_files): result.stdout.fnmatch_lines([".F.F.", "*2 failed, 3 passed in*"]) -class TestProgressOutputStyle(object): +class TestProgressOutputStyle: @pytest.fixture def many_tests_files(self, testdir): testdir.makepyfile( @@ -1497,7 +1497,7 @@ def test_capture_no(self, many_tests_files, testdir): assert "%]" not in output.stdout.str() -class TestProgressWithTeardown(object): +class TestProgressWithTeardown: """Ensure we show the correct percentages for tests that fail during teardown (#3088)""" @pytest.fixture @@ -1584,7 +1584,7 @@ def test_skip_reasons_folding(): message = "justso" longrepr = (path, lineno, message) - class X(object): + class X: pass ev1 = X() @@ -1625,10 +1625,10 @@ def mock_get_pos(*args): monkeypatch.setattr(_pytest.terminal, "_get_pos", mock_get_pos) - class config(object): + class config: pass - class rep(object): + class rep: def _get_verbose_word(self, *args): return mocked_verbose_word @@ -1643,7 +1643,7 @@ def check(msg, width, expected): actual = _get_line_with_reprcrash_message(config, rep(), width) assert actual == expected - if actual != "%s %s" % (mocked_verbose_word, mocked_pos): + if actual != "{} {}".format(mocked_verbose_word, mocked_pos): assert len(actual) <= width assert wcswidth(actual) <= width @@ -1665,17 +1665,17 @@ def check(msg, width, expected): check("some\nmessage", 80, "FAILED some::nodeid - some") # Test unicode safety. - check(u"😄😄😄😄😄\n2nd line", 25, u"FAILED some::nodeid - ...") - check(u"😄😄😄😄😄\n2nd line", 26, u"FAILED some::nodeid - ...") - check(u"😄😄😄😄😄\n2nd line", 27, u"FAILED some::nodeid - 😄...") - check(u"😄😄😄😄😄\n2nd line", 28, u"FAILED some::nodeid - 😄...") - check(u"😄😄😄😄😄\n2nd line", 29, u"FAILED some::nodeid - 😄😄...") + check("😄😄😄😄😄\n2nd line", 25, "FAILED some::nodeid - ...") + check("😄😄😄😄😄\n2nd line", 26, "FAILED some::nodeid - ...") + check("😄😄😄😄😄\n2nd line", 27, "FAILED some::nodeid - 😄...") + check("😄😄😄😄😄\n2nd line", 28, "FAILED some::nodeid - 😄...") + check("😄😄😄😄😄\n2nd line", 29, "FAILED some::nodeid - 😄😄...") # NOTE: constructed, not sure if this is supported. # It would fail if not using u"" in Python 2 for mocked_pos. - mocked_pos = u"nodeid::😄::withunicode" - check(u"😄😄😄😄😄\n2nd line", 29, u"FAILED nodeid::😄::withunicode") - check(u"😄😄😄😄😄\n2nd line", 40, u"FAILED nodeid::😄::withunicode - 😄😄...") - check(u"😄😄😄😄😄\n2nd line", 41, u"FAILED nodeid::😄::withunicode - 😄😄...") - check(u"😄😄😄😄😄\n2nd line", 42, u"FAILED nodeid::😄::withunicode - 😄😄😄...") - check(u"😄😄😄😄😄\n2nd line", 80, u"FAILED nodeid::😄::withunicode - 😄😄😄😄😄") + mocked_pos = "nodeid::😄::withunicode" + check("😄😄😄😄😄\n2nd line", 29, "FAILED nodeid::😄::withunicode") + check("😄😄😄😄😄\n2nd line", 40, "FAILED nodeid::😄::withunicode - 😄😄...") + check("😄😄😄😄😄\n2nd line", 41, "FAILED nodeid::😄::withunicode - 😄😄...") + check("😄😄😄😄😄\n2nd line", 42, "FAILED nodeid::😄::withunicode - 😄😄😄...") + check("😄😄😄😄😄\n2nd line", 80, "FAILED nodeid::😄::withunicode - 😄😄😄😄😄") diff --git a/testing/test_tmpdir.py b/testing/test_tmpdir.py index 8330c7871d2..a7c0ed7eaa7 100644 --- a/testing/test_tmpdir.py +++ b/testing/test_tmpdir.py @@ -22,7 +22,7 @@ def test_ensuretemp(recwarn): @attr.s -class FakeConfig(object): +class FakeConfig: basetemp = attr.ib() trace = attr.ib(default=None) @@ -38,7 +38,7 @@ def option(self): return self -class TestTempdirHandler(object): +class TestTempdirHandler: def test_mktemp(self, tmp_path): from _pytest.tmpdir import TempdirFactory, TempPathFactory @@ -63,7 +63,7 @@ def test_tmppath_relative_basetemp_absolute(self, tmp_path, monkeypatch): assert t.getbasetemp().resolve() == (tmp_path / "hello").resolve() -class TestConfigTmpdir(object): +class TestConfigTmpdir: def test_getbasetemp_custom_removes_old(self, testdir): mytemp = testdir.tmpdir.join("xyz") p = testdir.makepyfile( @@ -228,7 +228,7 @@ def test_get_user(monkeypatch): assert get_user() is None -class TestNumberedDir(object): +class TestNumberedDir: PREFIX = "fun-" def test_make(self, tmp_path): diff --git a/testing/test_unittest.py b/testing/test_unittest.py index bee6629e84a..410dabfcec4 100644 --- a/testing/test_unittest.py +++ b/testing/test_unittest.py @@ -388,7 +388,7 @@ def test_func1(self): reprec.assertoutcome(skipped=1) -class TestTrialUnittest(object): +class TestTrialUnittest: def setup_class(cls): cls.ut = pytest.importorskip("twisted.trial.unittest") # on windows trial uses a socket for a reactor and apparently doesn't close it properly diff --git a/testing/test_warnings.py b/testing/test_warnings.py index ad4ad614c32..0046709f39d 100644 --- a/testing/test_warnings.py +++ b/testing/test_warnings.py @@ -493,7 +493,7 @@ def test_hidden_by_cmdline(self, testdir): def test_hidden_by_system(self, testdir, monkeypatch): self.create_file(testdir) - monkeypatch.setenv(str("PYTHONWARNINGS"), str("once::UserWarning")) + monkeypatch.setenv("PYTHONWARNINGS", "once::UserWarning") result = testdir.runpytest_subprocess() assert WARNINGS_SUMMARY_HEADER not in result.stdout.str() From 4df529e5b9e36b32fbe715386200729788478b6c Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sun, 2 Jun 2019 15:40:34 -0700 Subject: [PATCH 16/23] Clean up __future__ and coding: in tests --- doc/en/writing_plugins.rst | 2 -- testing/acceptance_test.py | 5 ++--- testing/logging/test_reporting.py | 6 ++---- testing/python/collect.py | 15 ++------------- testing/python/fixtures.py | 5 ----- testing/test_assertion.py | 5 ++--- testing/test_capture.py | 7 ++----- testing/test_doctest.py | 8 ++------ testing/test_junitxml.py | 4 ++-- testing/test_mark.py | 1 - testing/test_nose.py | 5 ++--- testing/test_pastebin.py | 5 ++--- testing/test_pluginmanager.py | 7 +++---- testing/test_runner.py | 10 ++++------ testing/test_warnings.py | 5 ++--- 15 files changed, 27 insertions(+), 63 deletions(-) diff --git a/doc/en/writing_plugins.rst b/doc/en/writing_plugins.rst index 04dc68b642d..469ee57ca5c 100644 --- a/doc/en/writing_plugins.rst +++ b/doc/en/writing_plugins.rst @@ -335,8 +335,6 @@ string value of ``Hello World!`` if we do not supply a value or ``Hello .. code-block:: python - # -*- coding: utf-8 -*- - import pytest diff --git a/testing/acceptance_test.py b/testing/acceptance_test.py index 9d0d7f86317..9d903f80233 100644 --- a/testing/acceptance_test.py +++ b/testing/acceptance_test.py @@ -507,14 +507,13 @@ def test_stuff(r): def test_parametrized_with_null_bytes(self, testdir): """Test parametrization with values that contain null bytes and unicode characters (#2644, #2957)""" p = testdir.makepyfile( - """ - # encoding: UTF-8 + """\ import pytest @pytest.mark.parametrize("data", [b"\\x00", "\\x00", u'ação']) def test_foo(data): assert data - """ + """ ) res = testdir.runpytest(p) res.assert_outcomes(passed=3) diff --git a/testing/logging/test_reporting.py b/testing/logging/test_reporting.py index f845f5c39a6..fc775b951f9 100644 --- a/testing/logging/test_reporting.py +++ b/testing/logging/test_reporting.py @@ -840,16 +840,14 @@ def test_log_file_unicode(testdir): ) ) testdir.makepyfile( - """ - # -*- coding: utf-8 -*- - from __future__ import unicode_literals + """\ import logging def test_log_file(): logging.getLogger('catchlog').info("Normal message") logging.getLogger('catchlog').info("├") logging.getLogger('catchlog').info("Another normal message") - """ + """ ) result = testdir.runpytest() diff --git a/testing/python/collect.py b/testing/python/collect.py index 544e71f25cb..981e30fc3bc 100644 --- a/testing/python/collect.py +++ b/testing/python/collect.py @@ -116,12 +116,7 @@ def test_show_traceback_import_error_unicode(self, testdir): """Check test modules collected which raise ImportError with unicode messages are handled properly (#2336). """ - testdir.makepyfile( - """ - # -*- coding: utf-8 -*- - raise ImportError(u'Something bad happened ☺') - """ - ) + testdir.makepyfile("raise ImportError(u'Something bad happened ☺')") result = testdir.runpytest() result.stdout.fnmatch_lines( [ @@ -1256,13 +1251,7 @@ def test_injection(self): def test_syntax_error_with_non_ascii_chars(testdir): """Fix decoding issue while formatting SyntaxErrors during collection (#578) """ - testdir.makepyfile( - """ - # -*- coding: utf-8 -*- - - ☃ - """ - ) + testdir.makepyfile("☃") result = testdir.runpytest() result.stdout.fnmatch_lines(["*ERROR collecting*", "*SyntaxError*", "*1 error in*"]) diff --git a/testing/python/fixtures.py b/testing/python/fixtures.py index 3b14dc835c6..2dc3b4308d4 100644 --- a/testing/python/fixtures.py +++ b/testing/python/fixtures.py @@ -3338,7 +3338,6 @@ def flavor(self, request, testdir, monkeypatch): def test_simple(self, testdir, flavor): testdir.makepyfile( """ - from __future__ import print_function from test_context import fixture @fixture def arg1(): @@ -3367,7 +3366,6 @@ def test_2(arg1): def test_scoped(self, testdir, flavor): testdir.makepyfile( """ - from __future__ import print_function from test_context import fixture @fixture(scope="module") def arg1(): @@ -3601,7 +3599,6 @@ def test_foo(request): def test_pytest_fixture_setup_and_post_finalizer_hook(testdir): testdir.makeconftest( """ - from __future__ import print_function def pytest_fixture_setup(fixturedef, request): print('ROOT setup hook called for {0} from {1}'.format(fixturedef.argname, request.node.name)) def pytest_fixture_post_finalizer(fixturedef, request): @@ -3611,14 +3608,12 @@ def pytest_fixture_post_finalizer(fixturedef, request): testdir.makepyfile( **{ "tests/conftest.py": """ - from __future__ import print_function def pytest_fixture_setup(fixturedef, request): print('TESTS setup hook called for {0} from {1}'.format(fixturedef.argname, request.node.name)) def pytest_fixture_post_finalizer(fixturedef, request): print('TESTS finalizer hook called for {0} from {1}'.format(fixturedef.argname, request.node.name)) """, "tests/test_hooks.py": """ - from __future__ import print_function import pytest @pytest.fixture() diff --git a/testing/test_assertion.py b/testing/test_assertion.py index 6102f957831..e651c09cef6 100644 --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -1217,11 +1217,10 @@ def test_tuple(): def test_assert_with_unicode(monkeypatch, testdir): testdir.makepyfile( - """ - # -*- coding: utf-8 -*- + """\ def test_unicode(): assert u'유니코드' == u'Unicode' - """ + """ ) result = testdir.runpytest() result.stdout.fnmatch_lines(["*AssertionError*"]) diff --git a/testing/test_capture.py b/testing/test_capture.py index 1657f05d933..0825745ad39 100644 --- a/testing/test_capture.py +++ b/testing/test_capture.py @@ -95,14 +95,13 @@ def test_capturing_unicode(testdir, method): pytest.xfail("does not work on pypy < 2.2") obj = "'b\u00f6y'" testdir.makepyfile( - """ - # -*- coding: utf-8 -*- + """\ # taken from issue 227 from nosetests def test_unicode(): import sys print(sys.stdout) print(%s) - """ + """ % obj ) result = testdir.runpytest("--capture=%s" % method) @@ -624,7 +623,6 @@ def test_fixture_use_by_other_fixtures(self, testdir, fixture): """ testdir.makepyfile( """\ - from __future__ import print_function import sys import pytest @@ -1363,7 +1361,6 @@ def test_capattr(): def test_crash_on_closing_tmpfile_py27(testdir): p = testdir.makepyfile( """ - from __future__ import print_function import threading import sys diff --git a/testing/test_doctest.py b/testing/test_doctest.py index 54b23e15d09..65c8cf3664f 100644 --- a/testing/test_doctest.py +++ b/testing/test_doctest.py @@ -574,14 +574,13 @@ def test_contains_unicode(self, testdir): """Fix internal error with docstrings containing non-ascii characters. """ testdir.makepyfile( - ''' - # -*- coding: utf-8 -*- + '''\ def foo(): """ >>> name = 'с' # not letter 'c' but instead Cyrillic 's'. 'anything' """ - ''' + ''' ) result = testdir.runpytest("--doctest-modules") result.stdout.fnmatch_lines(["Got nothing", "* 1 failed in*"]) @@ -652,9 +651,6 @@ def test_unicode_doctest_module(self, testdir): """ p = testdir.makepyfile( test_unicode_doctest_module=""" - # -*- coding: utf-8 -*- - from __future__ import unicode_literals - def fix_bad_unicode(text): ''' >>> print(fix_bad_unicode('único')) diff --git a/testing/test_junitxml.py b/testing/test_junitxml.py index aa7287fb531..69b9c09c3f1 100644 --- a/testing/test_junitxml.py +++ b/testing/test_junitxml.py @@ -567,12 +567,12 @@ def test_collect_error(self, testdir): def test_unicode(self, testdir): value = "hx\xc4\x85\xc4\x87\n" testdir.makepyfile( - """ + """\ # coding: latin1 def test_hello(): print(%r) assert 0 - """ + """ % value ) result, dom = runandparse(testdir) diff --git a/testing/test_mark.py b/testing/test_mark.py index c66b85568aa..8d97f8b4ef5 100644 --- a/testing/test_mark.py +++ b/testing/test_mark.py @@ -960,7 +960,6 @@ def test_markers_from_parametrize(testdir): """#3605""" testdir.makepyfile( """ - from __future__ import print_function import pytest first_custom_mark = pytest.mark.custom_marker diff --git a/testing/test_nose.py b/testing/test_nose.py index b726c9682cf..8a3ce6454e7 100644 --- a/testing/test_nose.py +++ b/testing/test_nose.py @@ -366,13 +366,12 @@ def test_method(self): def test_skip_test_with_unicode(testdir): testdir.makepyfile( - """ - # -*- coding: utf-8 -*- + """\ import unittest class TestClass(): def test_io(self): raise unittest.SkipTest(u'😊') - """ + """ ) result = testdir.runpytest() result.stdout.fnmatch_lines(["* 1 skipped *"]) diff --git a/testing/test_pastebin.py b/testing/test_pastebin.py index eb2fd8faef6..48dea14bdc8 100644 --- a/testing/test_pastebin.py +++ b/testing/test_pastebin.py @@ -60,11 +60,10 @@ def test_non_ascii_paste_text(self, testdir): correctly. See #1219. """ testdir.makepyfile( - test_unicode=""" - # -*- coding: utf-8 -*- + test_unicode="""\ def test(): assert '☺' == 1 - """ + """ ) result = testdir.runpytest("--pastebin=all") expected_msg = "*assert '☺' == 1*" diff --git a/testing/test_pluginmanager.py b/testing/test_pluginmanager.py index 4e476fc0154..8afb37fa149 100644 --- a/testing/test_pluginmanager.py +++ b/testing/test_pluginmanager.py @@ -149,12 +149,11 @@ def test_importplugin_error_message(testdir, pytestpm): """ testdir.syspathinsert(testdir.tmpdir) testdir.makepyfile( - qwe=""" - # -*- coding: utf-8 -*- + qwe="""\ def test_traceback(): - raise ImportError(u'Not possible to import: ☺') + raise ImportError('Not possible to import: ☺') test_traceback() - """ + """ ) with pytest.raises(ImportError) as excinfo: pytestpm.import_plugin("qwe") diff --git a/testing/test_runner.py b/testing/test_runner.py index 61828294be4..77fdcecc3fa 100644 --- a/testing/test_runner.py +++ b/testing/test_runner.py @@ -639,13 +639,12 @@ def test_pytest_fail_notrace_non_ascii(testdir, str_prefix): This tests with native and unicode strings containing non-ascii chars. """ testdir.makepyfile( - """ - # -*- coding: utf-8 -*- + """\ import pytest def test_hello(): pytest.fail(%s'oh oh: ☺', pytrace=False) - """ + """ % str_prefix ) result = testdir.runpytest() @@ -784,8 +783,7 @@ def test_hello(): def test_unicode_in_longrepr(testdir): testdir.makeconftest( - """ - # -*- coding: utf-8 -*- + """\ import pytest @pytest.hookimpl(hookwrapper=True) def pytest_runtest_makereport(): @@ -793,7 +791,7 @@ def pytest_runtest_makereport(): rep = outcome.get_result() if rep.when == "call": rep.longrepr = u'ä' - """ + """ ) testdir.makepyfile( """ diff --git a/testing/test_warnings.py b/testing/test_warnings.py index 0046709f39d..1d6128273e7 100644 --- a/testing/test_warnings.py +++ b/testing/test_warnings.py @@ -123,8 +123,7 @@ def test_ignore(testdir, pyfile_with_warnings, method): @pytest.mark.filterwarnings("always") def test_unicode(testdir, pyfile_with_warnings): testdir.makepyfile( - """ - # -*- coding: utf-8 -*- + """\ import warnings import pytest @@ -136,7 +135,7 @@ def fix(): def test_func(fix): pass - """ + """ ) result = testdir.runpytest() result.stdout.fnmatch_lines( From c63320cc31998593583a7c0e3477788fdd456ac8 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sun, 2 Jun 2019 15:41:48 -0700 Subject: [PATCH 17/23] codecs.open / io.open --- src/_pytest/pytester.py | 9 ++++----- testing/logging/test_reporting.py | 1 - 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/_pytest/pytester.py b/src/_pytest/pytester.py index 572a41f895c..c7a8ca693e4 100644 --- a/src/_pytest/pytester.py +++ b/src/_pytest/pytester.py @@ -1,5 +1,4 @@ """(disabled by default) support for testing pytest and pytest plugins.""" -import codecs import gc import os import platform @@ -1089,8 +1088,8 @@ def run(self, *cmdargs, **kwargs): p2 = self.tmpdir.join("stderr") print("running:", *cmdargs) print(" in:", py.path.local()) - f1 = codecs.open(str(p1), "w", encoding="utf8") - f2 = codecs.open(str(p2), "w", encoding="utf8") + f1 = open(str(p1), "w", encoding="utf8") + f2 = open(str(p2), "w", encoding="utf8") try: now = time.time() popen = self.popen( @@ -1125,8 +1124,8 @@ def handle_timeout(): finally: f1.close() f2.close() - f1 = codecs.open(str(p1), "r", encoding="utf8") - f2 = codecs.open(str(p2), "r", encoding="utf8") + f1 = open(str(p1), "r", encoding="utf8") + f2 = open(str(p2), "r", encoding="utf8") try: out = f1.read().splitlines() err = f2.read().splitlines() diff --git a/testing/logging/test_reporting.py b/testing/logging/test_reporting.py index fc775b951f9..690a0c5b868 100644 --- a/testing/logging/test_reporting.py +++ b/testing/logging/test_reporting.py @@ -1,6 +1,5 @@ import os import re -from io import open import six From ca1efd57bd64b2c6ab736d9517a419e3269e1b67 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sun, 2 Jun 2019 15:44:58 -0700 Subject: [PATCH 18/23] git rm src/_pytest/_code/_py2traceback.py --- src/_pytest/_code/_py2traceback.py | 87 ------------------------------ 1 file changed, 87 deletions(-) delete mode 100644 src/_pytest/_code/_py2traceback.py diff --git a/src/_pytest/_code/_py2traceback.py b/src/_pytest/_code/_py2traceback.py deleted file mode 100644 index 68c44afdabf..00000000000 --- a/src/_pytest/_code/_py2traceback.py +++ /dev/null @@ -1,87 +0,0 @@ -# copied from python-2.7.3's traceback.py -# CHANGES: -# - some_str is replaced, trying to create unicode strings -# -import types - - -def format_exception_only(etype, value): - """Format the exception part of a traceback. - - The arguments are the exception type and value such as given by - sys.last_type and sys.last_value. The return value is a list of - strings, each ending in a newline. - - Normally, the list contains a single string; however, for - SyntaxError exceptions, it contains several lines that (when - printed) display detailed information about where the syntax - error occurred. - - The message indicating which exception occurred is always the last - string in the list. - - """ - - # An instance should not have a meaningful value parameter, but - # sometimes does, particularly for string exceptions, such as - # >>> raise string1, string2 # deprecated - # - # Clear these out first because issubtype(string1, SyntaxError) - # would throw another exception and mask the original problem. - if ( - isinstance(etype, BaseException) - or isinstance(etype, types.InstanceType) - or etype is None - or type(etype) is str - ): - return [_format_final_exc_line(etype, value)] - - stype = etype.__name__ - - if not issubclass(etype, SyntaxError): - return [_format_final_exc_line(stype, value)] - - # It was a syntax error; show exactly where the problem was found. - lines = [] - try: - msg, (filename, lineno, offset, badline) = value.args - except Exception: - pass - else: - filename = filename or "" - lines.append(' File "{}", line {}\n'.format(filename, lineno)) - if badline is not None: - if isinstance(badline, bytes): # python 2 only - badline = badline.decode("utf-8", "replace") - lines.append(" {}\n".format(badline.strip())) - if offset is not None: - caretspace = badline.rstrip("\n")[:offset].lstrip() - # non-space whitespace (likes tabs) must be kept for alignment - caretspace = ((c.isspace() and c or " ") for c in caretspace) - # only three spaces to account for offset1 == pos 0 - lines.append(" {}^\n".format("".join(caretspace))) - value = msg - - lines.append(_format_final_exc_line(stype, value)) - return lines - - -def _format_final_exc_line(etype, value): - """Return a list of a single line -- normal case for format_exception_only""" - valuestr = _some_str(value) - if value is None or not valuestr: - line = "{}\n".format(etype) - else: - line = "{}: {}\n".format(etype, valuestr) - return line - - -def _some_str(value): - try: - return str(value) - except Exception: - try: - return bytes(value).decode("UTF-8", "replace") - except Exception: - pass - return "".format(type(value).__name__) From 5dcf85c17e6137c5c4b8e3b4bda233e019b37953 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sun, 2 Jun 2019 15:53:45 -0700 Subject: [PATCH 19/23] manual: remove dependence on six --- setup.py | 1 - src/_pytest/assertion/rewrite.py | 3 +- src/_pytest/fixtures.py | 10 +++--- src/_pytest/logging.py | 51 ++++++++++++++----------------- src/_pytest/runner.py | 10 +++--- testing/code/test_source.py | 2 -- testing/logging/test_formatter.py | 5 --- testing/logging/test_reporting.py | 5 ++- testing/python/fixtures.py | 5 ++- testing/python/metafunc.py | 4 +-- testing/test_unittest.py | 2 +- 11 files changed, 42 insertions(+), 56 deletions(-) diff --git a/setup.py b/setup.py index 2f49078fafb..4c87c6429bb 100644 --- a/setup.py +++ b/setup.py @@ -4,7 +4,6 @@ # remove _width_of_current_line in terminal.py INSTALL_REQUIRES = [ "py>=1.5.0", - "six>=1.10.0", "packaging", "attrs>=17.4.0", "more-itertools>=4.0.0", diff --git a/src/_pytest/assertion/rewrite.py b/src/_pytest/assertion/rewrite.py index 4226a97b329..9b431b9849b 100644 --- a/src/_pytest/assertion/rewrite.py +++ b/src/_pytest/assertion/rewrite.py @@ -14,7 +14,6 @@ import atomicwrites import py -import six from _pytest._io.saferepr import saferepr from _pytest.assertion import util @@ -612,7 +611,7 @@ def run(self, mod): # Insert some special imports at the top of the module but after any # docstrings and __future__ imports. aliases = [ - ast.alias(six.moves.builtins.__name__, "@py_builtins"), + ast.alias("builtins", "@py_builtins"), ast.alias("_pytest.assertion.rewrite", "@pytest_ar"), ] doc = getattr(mod, "docstring", None) diff --git a/src/_pytest/fixtures.py b/src/_pytest/fixtures.py index 365f0ae6b08..2f9b10b85d8 100644 --- a/src/_pytest/fixtures.py +++ b/src/_pytest/fixtures.py @@ -9,7 +9,6 @@ import attr import py -import six import _pytest from _pytest import nodes @@ -848,10 +847,10 @@ def finish(self, request): except: # noqa exceptions.append(sys.exc_info()) if exceptions: - e = exceptions[0] + _, val, tb = exceptions[0] # Ensure to not keep frame references through traceback. del exceptions - six.reraise(*e) + raise val.with_traceback(tb) finally: hook = self._fixturemanager.session.gethookproxy(request.node.fspath) hook.pytest_fixture_post_finalizer(fixturedef=self, request=request) @@ -877,7 +876,8 @@ def execute(self, request): result, cache_key, err = cached_result if my_cache_key == cache_key: if err is not None: - six.reraise(*err) + _, val, tb = err + raise val.with_traceback(tb) else: return result # we have a previous but differently parametrized fixture instance @@ -950,7 +950,7 @@ def wrap_function_to_error_out_if_called_directly(function, fixture_marker): name=fixture_marker.name or function.__name__ ) - @six.wraps(function) + @functools.wraps(function) def result(*args, **kwargs): fail(message, pytrace=False) diff --git a/src/_pytest/logging.py b/src/_pytest/logging.py index f3034d8e5dd..ac0c4c2b337 100644 --- a/src/_pytest/logging.py +++ b/src/_pytest/logging.py @@ -4,7 +4,6 @@ from contextlib import contextmanager import py -import six import pytest from _pytest.compat import dummy_context_manager @@ -66,34 +65,31 @@ def format(self, record): return super().format(record) -if not six.PY2: - # Formatter classes don't support format styles in PY2 +class PercentStyleMultiline(logging.PercentStyle): + """A logging style with special support for multiline messages. - class PercentStyleMultiline(logging.PercentStyle): - """A logging style with special support for multiline messages. + If the message of a record consists of multiple lines, this style + formats the message as if each line were logged separately. + """ - If the message of a record consists of multiple lines, this style - formats the message as if each line were logged separately. - """ + @staticmethod + def _update_message(record_dict, message): + tmp = record_dict.copy() + tmp["message"] = message + return tmp - @staticmethod - def _update_message(record_dict, message): - tmp = record_dict.copy() - tmp["message"] = message - return tmp - - def format(self, record): - if "\n" in record.message: - lines = record.message.splitlines() - formatted = self._fmt % self._update_message(record.__dict__, lines[0]) - # TODO optimize this by introducing an option that tells the - # logging framework that the indentation doesn't - # change. This allows to compute the indentation only once. - indentation = _remove_ansi_escape_sequences(formatted).find(lines[0]) - lines[0] = formatted - return ("\n" + " " * indentation).join(lines) - else: - return self._fmt % record.__dict__ + def format(self, record): + if "\n" in record.message: + lines = record.message.splitlines() + formatted = self._fmt % self._update_message(record.__dict__, lines[0]) + # TODO optimize this by introducing an option that tells the + # logging framework that the indentation doesn't + # change. This allows to compute the indentation only once. + indentation = _remove_ansi_escape_sequences(formatted).find(lines[0]) + lines[0] = formatted + return ("\n" + " " * indentation).join(lines) + else: + return self._fmt % record.__dict__ def get_option_ini(config, *names): @@ -464,8 +460,7 @@ def _create_formatter(self, log_format, log_date_format): else: formatter = logging.Formatter(log_format, log_date_format) - if not six.PY2: - formatter._style = PercentStyleMultiline(formatter._style._fmt) + formatter._style = PercentStyleMultiline(formatter._style._fmt) return formatter def _setup_cli_logging(self): diff --git a/src/_pytest/runner.py b/src/_pytest/runner.py index 2561aaf466a..9c91a49a5e9 100644 --- a/src/_pytest/runner.py +++ b/src/_pytest/runner.py @@ -5,7 +5,6 @@ from time import time import attr -import six from .reports import CollectErrorRepr from .reports import CollectReport @@ -304,7 +303,8 @@ def _callfinalizers(self, colitem): if exc is None: exc = sys.exc_info() if exc: - six.reraise(*exc) + _, val, tb = exc + raise val.with_traceback(tb) def _teardown_with_finalization(self, colitem): self._callfinalizers(colitem) @@ -339,7 +339,8 @@ def _teardown_towards(self, needed_collectors): if exc is None: exc = sys.exc_info() if exc: - six.reraise(*exc) + _, val, tb = exc + raise val.with_traceback(tb) def prepare(self, colitem): """ setup objects along the collector chain to the test-method @@ -350,7 +351,8 @@ def prepare(self, colitem): # check if the last collection node has raised an error for col in self.stack: if hasattr(col, "_prepare_exc"): - six.reraise(*col._prepare_exc) + _, val, tb = col._prepare_exc + raise val.with_traceback(tb) for col in needed_collectors[len(self.stack) :]: self.stack.append(col) try: diff --git a/testing/code/test_source.py b/testing/code/test_source.py index 2462d773e7e..72bc628ab02 100644 --- a/testing/code/test_source.py +++ b/testing/code/test_source.py @@ -5,8 +5,6 @@ import inspect import sys -import six - import _pytest._code import pytest from _pytest._code import Source diff --git a/testing/logging/test_formatter.py b/testing/logging/test_formatter.py index 8adc266139c..806f4563a89 100644 --- a/testing/logging/test_formatter.py +++ b/testing/logging/test_formatter.py @@ -1,9 +1,7 @@ import logging import py.io -import six -import pytest from _pytest.logging import ColoredLevelFormatter @@ -38,9 +36,6 @@ class option: assert output == ("dummypath 10 INFO Test Message") -@pytest.mark.skipif( - six.PY2, reason="Formatter classes don't support format styles in PY2" -) def test_multiline_message(): from _pytest.logging import PercentStyleMultiline diff --git a/testing/logging/test_reporting.py b/testing/logging/test_reporting.py index 690a0c5b868..68be819b9a4 100644 --- a/testing/logging/test_reporting.py +++ b/testing/logging/test_reporting.py @@ -1,8 +1,7 @@ +import io import os import re -import six - import pytest @@ -885,7 +884,7 @@ def global_and_fixture_disabled(self): yield self.calls.append("exit disabled") - class DummyTerminal(six.StringIO): + class DummyTerminal(io.StringIO): def section(self, *args, **kwargs): pass diff --git a/testing/python/fixtures.py b/testing/python/fixtures.py index 2dc3b4308d4..a9ea333adc4 100644 --- a/testing/python/fixtures.py +++ b/testing/python/fixtures.py @@ -1357,9 +1357,8 @@ def test_hello(item, fm): def test_parsefactories_conftest_and_module_and_class(self, testdir): testdir.makepyfile( - """ + """\ import pytest - import six @pytest.fixture def hello(request): @@ -1376,7 +1375,7 @@ def test_hello(self, item, fm): assert faclist[0].func(item._request) == "conftest" assert faclist[1].func(item._request) == "module" assert faclist[2].func(item._request) == "class" - """ + """ ) reprec = testdir.inline_run("-s") reprec.assertoutcome(passed=1) diff --git a/testing/python/metafunc.py b/testing/python/metafunc.py index 30534678231..4702f0b57d2 100644 --- a/testing/python/metafunc.py +++ b/testing/python/metafunc.py @@ -892,7 +892,7 @@ def test_attributes(self, testdir): p = testdir.makepyfile( """ # assumes that generate/provide runs in the same process - import sys, pytest, six + import sys, pytest def pytest_generate_tests(metafunc): metafunc.parametrize('metafunc', [metafunc]) @@ -910,7 +910,7 @@ class TestClass(object): def test_method(self, metafunc, pytestconfig): assert metafunc.config == pytestconfig assert metafunc.module.__name__ == __name__ - unbound = six.get_unbound_function(TestClass.test_method) + unbound = TestClass.test_method assert metafunc.function == unbound assert metafunc.cls == TestClass """ diff --git a/testing/test_unittest.py b/testing/test_unittest.py index 410dabfcec4..a8555b35357 100644 --- a/testing/test_unittest.py +++ b/testing/test_unittest.py @@ -917,7 +917,7 @@ def test_should_not_run(self): @pytest.mark.parametrize( - "base", ["six.moves.builtins.object", "unittest.TestCase", "unittest2.TestCase"] + "base", ["builtins.object", "unittest.TestCase", "unittest2.TestCase"] ) def test_usefixtures_marker_on_unittest(base, testdir): """#3498""" From 96fd44e040b86b60c0ef056455e37150a2ebc9db Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sun, 2 Jun 2019 15:59:44 -0700 Subject: [PATCH 20/23] Update line number for warning --- testing/test_warnings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/test_warnings.py b/testing/test_warnings.py index 1d6128273e7..1654024785f 100644 --- a/testing/test_warnings.py +++ b/testing/test_warnings.py @@ -141,7 +141,7 @@ def test_func(fix): result.stdout.fnmatch_lines( [ "*== %s ==*" % WARNINGS_SUMMARY_HEADER, - "*test_unicode.py:8: UserWarning: \u6d4b\u8bd5*", + "*test_unicode.py:7: UserWarning: \u6d4b\u8bd5*", "* 1 passed, 1 warnings*", ] ) From 8292644015f33b885d1747fefc0d38a1196ab28e Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sun, 2 Jun 2019 18:02:14 -0700 Subject: [PATCH 21/23] Allow multiple positions for the SyntaxError in pypy3.6 --- testing/code/test_source.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/code/test_source.py b/testing/code/test_source.py index 72bc628ab02..a12a102a057 100644 --- a/testing/code/test_source.py +++ b/testing/code/test_source.py @@ -113,7 +113,7 @@ def test_source_strip_multiline(): def test_syntaxerror_rerepresentation(): ex = pytest.raises(SyntaxError, _pytest._code.compile, "xyz xyz") assert ex.value.lineno == 1 - assert ex.value.offset == 7 + assert ex.value.offset in {5, 7} # cpython: 7, pypy3.6 7.1.1: 5 assert ex.value.text.strip(), "x x" From 6d393c5dc8bfc9e437f85dae83914004409b1bc2 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Mon, 3 Jun 2019 11:27:07 -0300 Subject: [PATCH 22/23] Enable coverage for 'py37' environment --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 8483ee8f66d..2f6df4d9ad0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -34,7 +34,7 @@ jobs: - test $(python -c 'import sys; print("%d%d" % sys.version_info[0:2])') = 37 # Full run of latest supported version, without xdist. - - env: TOXENV=py37 + - env: TOXENV=py37 PYTEST_COVERAGE=1 python: '3.7' # Coverage tracking is slow with pypy, skip it. From ce78c9adeff54d2b8ac71a803113c136c22ffecc Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Mon, 3 Jun 2019 12:08:50 -0300 Subject: [PATCH 23/23] Fix linting --- testing/logging/test_formatter.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testing/logging/test_formatter.py b/testing/logging/test_formatter.py index 806f4563a89..6850a83cdb7 100644 --- a/testing/logging/test_formatter.py +++ b/testing/logging/test_formatter.py @@ -74,8 +74,8 @@ def test_colored_short_level(): exc_info=False, ) - class ColorConfig(object): - class option(object): + class ColorConfig: + class option: pass tw = py.io.TerminalWriter()