Repository: pytest-dev/pytest-forked (language: python)

Issue:
next release ETA
Hello, I see that you have prepared commit merged in master about python3.10 support.
When do you plan to release the version including this [commit](https://github.com/pytest-dev/pytest-forked/commit/90b141fbb9206c17b36ff16b08d111adeed12f74)?
Thanks


Discussion / hints:

Fix patch:
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 84e18a0..d56e01e 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -5,13 +5,12 @@ on: [push, pull_request]
 jobs:
   build:
 
-    runs-on: ${{ matrix.os }}
+    runs-on: ubuntu-latest
 
     strategy:
       fail-fast: false
       matrix:
         python: ["3.6", "3.7", "3.8", "3.9", "3.10"]
-        os: [ubuntu-latest, windows-latest]
         include:
           - python: "3.6"
             tox_env: "py36"
@@ -22,7 +21,7 @@ jobs:
           - python: "3.9"
             tox_env: "py39"
           - python: "3.10"
-            tox_env: "py310"  
+            tox_env: "py310"
 
     steps:
     - uses: actions/checkout@v1
@@ -63,4 +62,4 @@ jobs:
       uses: pypa/gh-action-pypi-publish@master
       with:
         user: __token__
-        password: ${{ secrets.pypi_token }}    
+        password: ${{ secrets.pypi_token }}
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000..cd3a2e9
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,29 @@
+repos:
+  - repo: https://github.com/asottile/pyupgrade
+    rev: v2.29.1
+    hooks:
+    -   id: pyupgrade
+        args: [--py36-plus]
+  - repo: https://github.com/psf/black
+    rev: 21.9b0
+    hooks:
+      - id: black
+        args: [--safe, --quiet]
+  - repo: https://github.com/pre-commit/pre-commit-hooks
+    rev: v4.0.1
+    hooks:
+      - id: trailing-whitespace
+      - id: end-of-file-fixer
+  - repo: local
+    hooks:
+      - id: rst
+        name: rst
+        entry: rst-lint --encoding utf-8
+        files: ^(CHANGELOG|README.rst)$
+        language: python
+        additional_dependencies: [pygments, restructuredtext_lint]
+  - repo: https://github.com/asottile/reorder_python_imports
+    rev: v2.6.0
+    hooks:
+    - id: reorder-python-imports
+      args: ['--application-directories=.:src']
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 4fcbd74..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,52 +0,0 @@
-language: python
-python:
-- '3.10-dev'
-- '3.9'
-- '3.8'
-- '3.7'
-- '3.6'
-cache: pip
-install: pip install -U tox setuptools_scm
-env:
-  matrix:
-  - TOXENV=py-pytest310
-  - TOXENV=py-pytest46
-  - TOXENV=py-pytest54
-  - TOXENV=py-pytest62
-  - TOXENV=py-pytestlatest
-  - TOXENV=py-pytestmain
-matrix:
-  include:
-  - python: '3.8'
-    env: TOXENV=flakes
-  - stage: Release
-    name: Build and verify dists (and publish if tagged)
-    python: '3.8'
-    env:
-      TOXENV: build-dists,metadata-validation
-
-    # piggyback on existing build for releases
-    before_deploy:
-    # make setup.py no-op because tox has already produced verified dists:
-    - echo > setup.py
-    deploy:
-      provider: pypi
-      user: nicoddemus
-      password:
-        secure: KJgDEXYiKYNiV1Ef0kCYrJr3LvIUrZbEnwc/x5eTXpLHZCLmiJ33tbYDRLzX+uWcvqXpFjVjEtWHOOfhP9sRPl4jbmM0MJrNmO4mqTSCzN1VnVx9fPJXpD74rtjLxMsZNrHjqEWWjeqsqDryGID7O3zm0f/p/FqKEYKBCffhc2AyJN4Bb1d564JLwM1dZUPGAWU5spkDB/0gSvTGtQ1gxl5xtEAwMX59gWzwJ96kj5qKGPBXdQLWPkhXz45/5XQUdxjwJjyRJws5EoCzOD+E/C+Tcc3NKCkksZUGejt7cBpU+rFpqzGSUDv5KBsQoXELElC2yXxFJhqrfoTFkxZqFc4qSvnYRlOlx9M2FPsUqnOwS5RlEgGmadjN4CJe0mlxS+/Yx1V1aDSnaFFCWLsApMDbKgoozB6NPQvSraOvRF28J7CsTSFCvbI1dR1lEYhZVc5XTwt0mI/0w4iXkvGNMJ0Sb0grqj7rPEPiuf1RU/Y9CNtR/yhez02zbYjIzgERUB6Sq3YGg1q2cefkvoiq3eWWV4vf8e1rXVdvs/UdJnj8zTwMbiaWh13CCu+Z8bTEKgaiUAOaTs0y1mxPg4dRGJdVCPceUn3pMeeTl2XBxWr9CkMhDY06IMLd2PmyYfVYIWUkssT235ALZ5kPdk1TmiqmtbKyd+pAga1IWtFbOCY=
-      on:
-        tags: true
-        repo: pytest-dev/pytest-forked
-      # keep the dists generated by tox:
-      skip-cleanup: true
-
-script: tox
-notifications:
-  irc:
-    channels:
-    - chat.freenode.net#pytest
-    on_success: change
-    on_failure: change
-    skip_join: true
-  email:
-  - pytest-commit@python.org
diff --git a/CHANGELOG b/CHANGELOG.rst
similarity index 89%
rename from CHANGELOG
rename to CHANGELOG.rst
index 7117c95..a940f5e 100644
--- a/CHANGELOG
+++ b/CHANGELOG.rst
@@ -1,3 +1,9 @@
+v1.4.0
+======
+
+* Dropped support for Python 2.7 and 3.5.
+* Added official support for Python 3.10.
+
 v1.3.0
 ======
 
diff --git a/LICENSE b/LICENSE
index 31ecdfb..ff33b8f 100644
--- a/LICENSE
+++ b/LICENSE
@@ -5,10 +5,10 @@
   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   copies of the Software, and to permit persons to whom the Software is
   furnished to do so, subject to the following conditions:
-     
+
   The above copyright notice and this permission notice shall be included in all
   copies or substantial portions of the Software.
- 
+
   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -16,4 +16,3 @@
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
   SOFTWARE.
-
diff --git a/MANIFEST.in b/MANIFEST.in
deleted file mode 100644
index 493b5d0..0000000
--- a/MANIFEST.in
+++ /dev/null
@@ -1,8 +0,0 @@
-include CHANGELOG
-include LICENSE 
-include pyproject.toml
-include README.txt
-include setup.py
-include tox.ini
-graft testing
-prune .git
diff --git a/README.rst b/README.rst
index 086a43f..b432712 100644
--- a/README.rst
+++ b/README.rst
@@ -14,6 +14,22 @@ This plugin **does not work on Windows** because there's no ``fork`` support.
 * ``--forked``: run each test in a forked
   subprocess to survive ``SEGFAULTS`` or otherwise dying processes.
 
+|python| |version| |ci| |pre-commit| |black|
+
+.. |version| image:: http://img.shields.io/pypi/v/pytest-forked.svg
+  :target: https://pypi.python.org/pypi/pytest-forked
+
+.. |ci| image:: https://github.com/pytest-dev/pytest-forked/workflows/build/badge.svg
+  :target: https://github.com/pytest-dev/pytest-forked/actions
+
+.. |python| image:: https://img.shields.io/pypi/pyversions/pytest-forked.svg
+  :target: https://pypi.python.org/pypi/pytest-forked/
+
+.. |black| image:: https://img.shields.io/badge/code%20style-black-000000.svg
+  :target: https://github.com/ambv/black
+
+.. |pre-commit| image:: https://results.pre-commit.ci/badge/github/pytest-dev/pytest-forked/master.svg
+   :target: https://results.pre-commit.ci/latest/github/pytest-dev/pytest-forked/master
 
 Installation
 -----------------------
diff --git a/RELEASING.rst b/RELEASING.rst
new file mode 100644
index 0000000..1a9d8f2
--- /dev/null
+++ b/RELEASING.rst
@@ -0,0 +1,7 @@
+Here are the steps on how to make a new release.
+
+1. Create a ``release-VERSION`` branch from ``upstream/master``.
+2. Update ``CHANGELOG.rst``.
+3. Push a branch with the changes.
+4. Once all builds pass, push a tag to ``upstream``.
+5. Merge the PR.
diff --git a/example/boxed.txt b/example/boxed.txt
index 2e36ae0..58d06e3 100644
--- a/example/boxed.txt
+++ b/example/boxed.txt
@@ -14,7 +14,7 @@ to run each test in a controlled subprocess.  Here is a basic example::
     @pytest.mark.parametrize("arg", range(50))
     def test_func(arg):
         time.sleep(0.05) # each tests takes a while
-        if arg % 19 == 0: 
+        if arg % 19 == 0:
             os.kill(os.getpid(), 15)
 
 If you run this with::
@@ -24,9 +24,9 @@ If you run this with::
     platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev8
     plugins: xdist, bugzilla, cache, oejskit, cli, pep8, cov
     collecting ... collected 50 items
-    
+
     test_module.py f..................f..................f...........
-    
+
     ================================= FAILURES =================================
     _______________________________ test_func[0] _______________________________
     /home/hpk/tmp/doc-exec-420/test_module.py:6: running the test CRASHED with signal 15
@@ -46,7 +46,7 @@ the xdist-provided parallelization feature to speed up your testing::
     plugins: xdist, bugzilla, cache, oejskit, cli, pep8, cov
     gw0 I / gw1 I / gw2 I
     gw0 [50] / gw1 [50] / gw2 [50]
-    
+
     scheduling tests via LoadScheduling
     ..f...............f..................f............
     ================================= FAILURES =================================
diff --git a/setup.py b/setup.py
index e208ae5..03233ee 100644
--- a/setup.py
+++ b/setup.py
@@ -3,42 +3,42 @@
 setup(
     name="pytest-forked",
     use_scm_version=True,
-    description='run tests in isolated forked subprocesses',
-    long_description=open('README.rst').read(),
-    long_description_content_type='text/x-rst',
-    license='MIT',
-    author='pytest-dev',
-    author_email='pytest-dev@python.org',
-    url='https://github.com/pytest-dev/pytest-forked',
-    platforms=['linux', 'osx'],
-    packages=['pytest_forked'],
-    package_dir={'': 'src'},
+    description="run tests in isolated forked subprocesses",
+    long_description=open("README.rst").read(),
+    long_description_content_type="text/x-rst",
+    license="MIT",
+    author="pytest-dev",
+    author_email="pytest-dev@python.org",
+    url="https://github.com/pytest-dev/pytest-forked",
+    platforms=["linux", "osx"],
+    packages=["pytest_forked"],
+    package_dir={"": "src"},
     entry_points={
-        'pytest11': [
-            'pytest_forked = pytest_forked',
+        "pytest11": [
+            "pytest_forked = pytest_forked",
         ],
     },
     zip_safe=False,
-    install_requires=['py', 'pytest>=3.10'],
-    setup_requires=['setuptools_scm'],
-    python_requires='>=3.6',
+    install_requires=["py", "pytest>=3.10"],
+    setup_requires=["setuptools_scm"],
+    python_requires=">=3.6",
     classifiers=[
-        'Development Status :: 7 - Inactive',
-        'Framework :: Pytest',
-        'Intended Audience :: Developers',
-        'License :: OSI Approved :: MIT License',
-        'Operating System :: POSIX',
-        'Operating System :: MacOS :: MacOS X',
-        'Topic :: Software Development :: Testing',
-        'Topic :: Software Development :: Quality Assurance',
-        'Topic :: Utilities',
-        'Programming Language :: Python',
-        'Programming Language :: Python :: 3',
-        'Programming Language :: Python :: 3.6',
-        'Programming Language :: Python :: 3.7',
-        'Programming Language :: Python :: 3.8',
-        'Programming Language :: Python :: 3.9',
-        'Programming Language :: Python :: 3.10',
-        'Programming Language :: Python :: 3 :: Only',
+        "Development Status :: 7 - Inactive",
+        "Framework :: Pytest",
+        "Intended Audience :: Developers",
+        "License :: OSI Approved :: MIT License",
+        "Operating System :: POSIX",
+        "Operating System :: MacOS :: MacOS X",
+        "Topic :: Software Development :: Testing",
+        "Topic :: Software Development :: Quality Assurance",
+        "Topic :: Utilities",
+        "Programming Language :: Python",
+        "Programming Language :: Python :: 3",
+        "Programming Language :: Python :: 3.6",
+        "Programming Language :: Python :: 3.7",
+        "Programming Language :: Python :: 3.8",
+        "Programming Language :: Python :: 3.9",
+        "Programming Language :: Python :: 3.10",
+        "Programming Language :: Python :: 3 :: Only",
     ],
 )


Test patch:
diff --git a/src/pytest_forked/__init__.py b/src/pytest_forked/__init__.py
index 57d2454..a4e5d94 100644
--- a/src/pytest_forked/__init__.py
+++ b/src/pytest_forked/__init__.py
@@ -2,19 +2,21 @@
 import warnings
 
 import py
-# we know this bit is bad, but we cant help it with the current pytest setup
-from _pytest import runner
 import pytest
+from _pytest import runner
+
+# we know this bit is bad, but we cant help it with the current pytest setup
 
 
 # copied from xdist remote
 def serialize_report(rep):
     import py
+
     d = rep.__dict__.copy()
-    if hasattr(rep.longrepr, 'toterminal'):
-        d['longrepr'] = str(rep.longrepr)
+    if hasattr(rep.longrepr, "toterminal"):
+        d["longrepr"] = str(rep.longrepr)
     else:
-        d['longrepr'] = rep.longrepr
+        d["longrepr"] = rep.longrepr
     for name in d:
         if isinstance(d[name], py.path.local):
             d[name] = str(d[name])
@@ -26,9 +28,12 @@ def serialize_report(rep):
 def pytest_addoption(parser):
     group = parser.getgroup("forked", "forked subprocess test execution")
     group.addoption(
-        '--forked',
-        action="store_true", dest="forked", default=False,
-        help="box each test run in a separate process (unix)")
+        "--forked",
+        action="store_true",
+        dest="forked",
+        default=False,
+        help="box each test run in a separate process (unix)",
+    )
 
 
 def pytest_load_initial_conftests(early_config, parser, args):
@@ -54,6 +59,7 @@ def forked_run_report(item):
     # for now, we run setup/teardown in the subprocess
     # XXX optionally allow sharing of setup/teardown
     from _pytest.runner import runtestprotocol
+
     EXITSTATUS_TESTEXIT = 4
     import marshal
 
@@ -77,16 +83,21 @@ def runforked():
 
 def report_process_crash(item, result):
     from _pytest._code import getfslineno
+
     path, lineno = getfslineno(item)
-    info = ("%s:%s: running the test CRASHED with signal %d" %
-            (path, lineno, result.signal))
+    info = "%s:%s: running the test CRASHED with signal %d" % (
+        path,
+        lineno,
+        result.signal,
+    )
     from _pytest import runner
+
     # pytest >= 4.1
     has_from_call = getattr(runner.CallInfo, "from_call", None) is not None
     if has_from_call:
-        call = runner.CallInfo.from_call(lambda: 0/0, "???")
+        call = runner.CallInfo.from_call(lambda: 0 / 0, "???")
     else:
-        call = runner.CallInfo(lambda: 0/0, "???")
+        call = runner.CallInfo(lambda: 0 / 0, "???")
     call.excinfo = info
     rep = runner.pytest_runtest_makereport(item, call)
     if result.out:
@@ -94,22 +105,21 @@ def report_process_crash(item, result):
     if result.err:
         rep.sections.append(("captured stderr", result.err))
 
-    xfail_marker = item.get_closest_marker('xfail')
+    xfail_marker = item.get_closest_marker("xfail")
     if not xfail_marker:
         return rep
 
     rep.outcome = "skipped"
     rep.wasxfail = (
         "reason: {xfail_reason}; "
-        "pytest-forked reason: {crash_info}".
-        format(
-            xfail_reason=xfail_marker.kwargs['reason'],
+        "pytest-forked reason: {crash_info}".format(
+            xfail_reason=xfail_marker.kwargs["reason"],
             crash_info=info,
         )
     )
     warnings.warn(
-        'pytest-forked xfail support is incomplete at the moment and may '
-        'output a misleading reason message',
+        "pytest-forked xfail support is incomplete at the moment and may "
+        "output a misleading reason message",
         RuntimeWarning,
     )
 
diff --git a/testing/conftest.py b/testing/conftest.py
index 6ac720b..e43687f 100644
--- a/testing/conftest.py
+++ b/testing/conftest.py
@@ -7,6 +7,7 @@
 @pytest.fixture(autouse=True)
 def _divert_atexit(request, monkeypatch):
     import atexit
+
     atexit_fns = []
 
     def atexit_register(func, *args, **kwargs):
diff --git a/testing/test_boxed.py b/testing/test_boxed.py
index 25b0234..6ea430e 100644
--- a/testing/test_boxed.py
+++ b/testing/test_boxed.py
@@ -1,64 +1,70 @@
-import pytest
 import os
 
-needsfork = pytest.mark.skipif(not hasattr(os, "fork"),
-                               reason="os.fork required")
+import pytest
+
+needsfork = pytest.mark.skipif(not hasattr(os, "fork"), reason="os.fork required")
 
 
 @needsfork
 def test_functional_boxed(testdir):
-    p1 = testdir.makepyfile("""
+    p1 = testdir.makepyfile(
+        """
         import os
         def test_function():
             os.kill(os.getpid(), 15)
-    """)
+    """
+    )
     result = testdir.runpytest(p1, "--forked")
-    result.stdout.fnmatch_lines([
-        "*CRASHED*",
-        "*1 failed*"
-    ])
+    result.stdout.fnmatch_lines(["*CRASHED*", "*1 failed*"])
 
 
 @needsfork
 def test_functional_boxed_per_test(testdir):
-    p1 = testdir.makepyfile("""
+    p1 = testdir.makepyfile(
+        """
         import os
         import pytest
 
         @pytest.mark.forked
         def test_function():
             os.kill(os.getpid(), 15)
-    """)
+    """
+    )
     result = testdir.runpytest(p1)
-    result.stdout.fnmatch_lines([
-        "*CRASHED*",
-        "*1 failed*"
-    ])
+    result.stdout.fnmatch_lines(["*CRASHED*", "*1 failed*"])
 
 
 @needsfork
-@pytest.mark.parametrize("capmode", [
-    "no",
-    pytest.param("sys", marks=pytest.mark.xfail(reason="capture cleanup needed")),
-    pytest.param("fd", marks=pytest.mark.xfail(reason="capture cleanup needed"))])
+@pytest.mark.parametrize(
+    "capmode",
+    [
+        "no",
+        pytest.param("sys", marks=pytest.mark.xfail(reason="capture cleanup needed")),
+        pytest.param("fd", marks=pytest.mark.xfail(reason="capture cleanup needed")),
+    ],
+)
 def test_functional_boxed_capturing(testdir, capmode):
-    p1 = testdir.makepyfile("""
+    p1 = testdir.makepyfile(
+        """
         import os
         import sys
         def test_function():
             sys.stdout.write("hello\\n")
             sys.stderr.write("world\\n")
             os.kill(os.getpid(), 15)
-    """)
+    """
+    )
     result = testdir.runpytest(p1, "--forked", "--capture=%s" % capmode)
-    result.stdout.fnmatch_lines("""
+    result.stdout.fnmatch_lines(
+        """
         *CRASHED*
         *stdout*
         hello
         *stderr*
         world
         *1 failed*
-""")
+"""
+    )
 
 
 def test_is_not_boxed_by_default(testdir):
diff --git a/testing/test_xfail_behavior.py b/testing/test_xfail_behavior.py
index 4f0a7c5..8c6e55a 100644
--- a/testing/test_xfail_behavior.py
+++ b/testing/test_xfail_behavior.py
@@ -5,21 +5,21 @@
 import pytest
 
 IS_PYTEST4_PLUS = int(pytest.__version__[0]) >= 4  # noqa: WPS609
-FAILED_WORD = 'FAILED' if IS_PYTEST4_PLUS else 'FAIL'
+FAILED_WORD = "FAILED" if IS_PYTEST4_PLUS else "FAIL"
 
 pytestmark = pytest.mark.skipif(  # pylint: disable=invalid-name
-    not hasattr(os, 'fork'),  # noqa: WPS421
-    reason='os.fork required',
+    not hasattr(os, "fork"),  # noqa: WPS421
+    reason="os.fork required",
 )
 
 
 @pytest.mark.parametrize(
-    ('is_crashing', 'is_strict'),
+    ("is_crashing", "is_strict"),
     (
-        pytest.param(True, True, id='strict xfail'),
-        pytest.param(False, True, id='strict xpass'),
-        pytest.param(True, False, id='non-strict xfail'),
-        pytest.param(False, False, id='non-strict xpass'),
+        pytest.param(True, True, id="strict xfail"),
+        pytest.param(False, True, id="strict xpass"),
+        pytest.param(True, False, id="non-strict xfail"),
+        pytest.param(False, False, id="non-strict xpass"),
     ),
 )
 def test_xfail(is_crashing, is_strict, testdir):
@@ -28,54 +28,52 @@ def test_xfail(is_crashing, is_strict, testdir):
     sig_num = signal.SIGTERM.numerator
 
     test_func_body = (
-        'os.kill(os.getpid(), signal.SIGTERM)'
-        if is_crashing
-        else 'assert True'
+        "os.kill(os.getpid(), signal.SIGTERM)" if is_crashing else "assert True"
     )
 
     if is_crashing:
         # marked xfailed and crashing, no matter strict or not
-        expected_letter = 'x'  # XFAILED
-        expected_lowercase = 'xfailed'
-        expected_word = 'XFAIL'
+        expected_letter = "x"  # XFAILED
+        expected_lowercase = "xfailed"
+        expected_word = "XFAIL"
     elif is_strict:
         # strict and not failing as expected should cause failure
-        expected_letter = 'F'  # FAILED
-        expected_lowercase = 'failed'
+        expected_letter = "F"  # FAILED
+        expected_lowercase = "failed"
         expected_word = FAILED_WORD
     elif not is_strict:
         # non-strict and not failing as expected should cause xpass
-        expected_letter = 'X'  # XPASS
-        expected_lowercase = 'xpassed'
-        expected_word = 'XPASS'
+        expected_letter = "X"  # XPASS
+        expected_lowercase = "xpassed"
+        expected_word = "XPASS"
 
-    session_start_title = '*==== test session starts ====*'
-    loaded_pytest_plugins = 'plugins: forked*'
-    collected_tests_num = 'collected 1 item'
-    expected_progress = 'test_xfail.py {expected_letter!s}*'.format(**locals())
-    failures_title = '*==== FAILURES ====*'
-    failures_test_name = '*____ test_function ____*'
-    failures_test_reason = '[XPASS(strict)] The process gets terminated'
-    short_test_summary_title = '*==== short test summary info ====*'
-    short_test_summary = (
-        '{expected_word!s} test_xfail.py::test_function'.
-        format(**locals())
+    session_start_title = "*==== test session starts ====*"
+    loaded_pytest_plugins = "plugins: forked*"
+    collected_tests_num = "collected 1 item"
+    expected_progress = "test_xfail.py {expected_letter!s}*".format(**locals())
+    failures_title = "*==== FAILURES ====*"
+    failures_test_name = "*____ test_function ____*"
+    failures_test_reason = "[XPASS(strict)] The process gets terminated"
+    short_test_summary_title = "*==== short test summary info ====*"
+    short_test_summary = "{expected_word!s} test_xfail.py::test_function".format(
+        **locals()
     )
-    if expected_lowercase == 'xpassed':
+    if expected_lowercase == "xpassed":
         # XPASS wouldn't have the crash message from
         # pytest-forked because the crash doesn't happen
-        short_test_summary = ' '.join((
-            short_test_summary, 'The process gets terminated',
-        ))
+        short_test_summary = " ".join(
+            (
+                short_test_summary,
+                "The process gets terminated",
+            )
+        )
     reason_string = (
-        '  reason: The process gets terminated; '
-        'pytest-forked reason: '
-        '*:*: running the test CRASHED with signal {sig_num:d}'.
-        format(**locals())
+        "  reason: The process gets terminated; "
+        "pytest-forked reason: "
+        "*:*: running the test CRASHED with signal {sig_num:d}".format(**locals())
     )
-    total_summary_line = (
-        '*==== 1 {expected_lowercase!s} in 0.*s* ====*'.
-        format(**locals())
+    total_summary_line = "*==== 1 {expected_lowercase!s} in 0.*s* ====*".format(
+        **locals()
     )
 
     expected_lines = (
@@ -95,17 +93,13 @@ def test_xfail(is_crashing, is_strict, testdir):
         short_test_summary_title,
         short_test_summary,
     )
-    if expected_lowercase == 'xpassed' and expected_word == FAILED_WORD:
+    if expected_lowercase == "xpassed" and expected_word == FAILED_WORD:
         # XPASS(strict)
-        expected_lines += (
-            reason_string,
-        )
-    expected_lines += (
-        total_summary_line,
-    )
+        expected_lines += (reason_string,)
+    expected_lines += (total_summary_line,)
 
     test_module = testdir.makepyfile(
-        """
+        f"""
         import os
         import signal
 
@@ -121,9 +115,8 @@ def test_xfail(is_crashing, is_strict, testdir):
         @pytest.mark.forked
         def test_function():
             {test_func_body!s}
-        """.
-        format(**locals())
+        """
     )
 
-    pytest_run_result = testdir.runpytest(test_module, '-ra')
+    pytest_run_result = testdir.runpytest(test_module, "-ra")
     pytest_run_result.stdout.fnmatch_lines(expected_lines)