We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
setuptools 49.2.0 will warn if distutils is imported first
xref pypa/setuptools#2261, numpy/numpy#16851

We are trying to understand why pytest-xdist is failing to run after updating setuptools to 49.2.0. I think one problem might be [this import](https://github.com/HypothesisWorks/hypothesis/blob/master/hypothesis-python/src/hypothesis/extra/pytestplugin.py#L16). I think it would be best to `import setuptools` just before that. Although I think setuptools will move quickly to rectify that warning since it is causing much anguish across different projects, so maybe just weather the storm and wait for the next version.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `hypothesis-python/src/hypothesis/extra/pytestplugin.py`
Content:
```
1 # This file is part of Hypothesis, which may be found at
2 # https://github.com/HypothesisWorks/hypothesis/
3 #
4 # Most of this work is copyright (C) 2013-2020 David R. MacIver
5 # (david@drmaciver.com), but it contains contributions by others. See
6 # CONTRIBUTING.rst for a full list of people who may hold copyright, and
7 # consult the git log if you need to determine who owns an individual
8 # contribution.
9 #
10 # This Source Code Form is subject to the terms of the Mozilla Public License,
11 # v. 2.0. If a copy of the MPL was not distributed with this file, You can
12 # obtain one at https://mozilla.org/MPL/2.0/.
13 #
14 # END HEADER
15 
16 from distutils.version import LooseVersion
17 from inspect import signature
18 
19 import pytest
20 
21 from hypothesis import Verbosity, core, settings
22 from hypothesis._settings import note_deprecation
23 from hypothesis.errors import InvalidArgument
24 from hypothesis.internal.detection import is_hypothesis_test
25 from hypothesis.reporting import default as default_reporter, with_reporter
26 from hypothesis.statistics import collector, describe_statistics
27 
28 LOAD_PROFILE_OPTION = "--hypothesis-profile"
29 VERBOSITY_OPTION = "--hypothesis-verbosity"
30 PRINT_STATISTICS_OPTION = "--hypothesis-show-statistics"
31 SEED_OPTION = "--hypothesis-seed"
32 
33 
34 class StoringReporter:
35     def __init__(self, config):
36         self.config = config
37         self.results = []
38 
39     def __call__(self, msg):
40         if self.config.getoption("capture", "fd") == "no":
41             default_reporter(msg)
42         if not isinstance(msg, str):
43             msg = repr(msg)
44         self.results.append(msg)
45 
46 
47 if LooseVersion(pytest.__version__) < "4.3":  # pragma: no cover
48     import warnings
49     from hypothesis.errors import HypothesisWarning
50 
51     PYTEST_TOO_OLD_MESSAGE = """
52         You are using Pytest version %s.  Hypothesis tests work with any test
53         runner, but our Pytest plugin requires Pytest  4.3 or newer.
54         Note that the Pytest developers no longer support this version either!
55         Disabling the Hypothesis pytest plugin...
56     """
57     warnings.warn(PYTEST_TOO_OLD_MESSAGE % (pytest.__version__,), HypothesisWarning)
58 
59 else:
60 
61     def pytest_addoption(parser):
62         group = parser.getgroup("hypothesis", "Hypothesis")
63         group.addoption(
64             LOAD_PROFILE_OPTION,
65             action="store",
66             help="Load in a registered hypothesis.settings profile",
67         )
68         group.addoption(
69             VERBOSITY_OPTION,
70             action="store",
71             choices=[opt.name for opt in Verbosity],
72             help="Override profile with verbosity setting specified",
73         )
74         group.addoption(
75             PRINT_STATISTICS_OPTION,
76             action="store_true",
77             help="Configure when statistics are printed",
78             default=False,
79         )
80         group.addoption(
81             SEED_OPTION,
82             action="store",
83             help="Set a seed to use for all Hypothesis tests",
84         )
85 
86     def pytest_report_header(config):
87         profile = config.getoption(LOAD_PROFILE_OPTION)
88         if not profile:
89             profile = settings._current_profile
90         settings_str = settings.get_profile(profile).show_changed()
91         if settings_str != "":
92             settings_str = " -> %s" % (settings_str)
93         if (
94             config.option.verbose >= 1
95             or settings.default.verbosity >= Verbosity.verbose
96         ):
97             return "hypothesis profile %r%s" % (profile, settings_str)
98 
99     def pytest_configure(config):
100         core.running_under_pytest = True
101         profile = config.getoption(LOAD_PROFILE_OPTION)
102         if profile:
103             settings.load_profile(profile)
104         verbosity_name = config.getoption(VERBOSITY_OPTION)
105         if verbosity_name:
106             verbosity_value = Verbosity[verbosity_name]
107             profile_name = "%s-with-%s-verbosity" % (
108                 settings._current_profile,
109                 verbosity_name,
110             )
111             # register_profile creates a new profile, exactly like the current one,
112             # with the extra values given (in this case 'verbosity')
113             settings.register_profile(profile_name, verbosity=verbosity_value)
114             settings.load_profile(profile_name)
115         seed = config.getoption(SEED_OPTION)
116         if seed is not None:
117             try:
118                 seed = int(seed)
119             except ValueError:
120                 pass
121             core.global_force_seed = seed
122         config.addinivalue_line("markers", "hypothesis: Tests which use hypothesis.")
123 
124     @pytest.hookimpl(hookwrapper=True)
125     def pytest_runtest_call(item):
126         if not hasattr(item, "obj"):
127             yield
128         elif not is_hypothesis_test(item.obj):
129             # If @given was not applied, check whether other hypothesis
130             # decorators were applied, and raise an error if they were.
131             if getattr(item.obj, "is_hypothesis_strategy_function", False):
132                 raise InvalidArgument(
133                     "%s is a function that returns a Hypothesis strategy, but pytest "
134                     "has collected it as a test function.  This is useless as the "
135                     "function body will never be executed.  To define a test "
136                     "function, use @given instead of @composite." % (item.nodeid,)
137                 )
138             message = "Using `@%s` on a test without `@given` is completely pointless."
139             for name, attribute in [
140                 ("example", "hypothesis_explicit_examples"),
141                 ("seed", "_hypothesis_internal_use_seed"),
142                 ("settings", "_hypothesis_internal_settings_applied"),
143                 ("reproduce_example", "_hypothesis_internal_use_reproduce_failure"),
144             ]:
145                 if hasattr(item.obj, attribute):
146                     raise InvalidArgument(message % (name,))
147             yield
148         else:
149             # Warn about function-scoped fixtures, excluding autouse fixtures because
150             # the advice is probably not actionable and the status quo seems OK...
151             # See https://github.com/HypothesisWorks/hypothesis/issues/377 for detail.
152             msg = (
153                 "%s uses the %r fixture, which is reset between function calls but not "
154                 "between test cases generated by `@given(...)`.  You can change it to "
155                 "a module- or session-scoped fixture if it is safe to reuse; if not "
156                 "we recommend using a context manager inside your test function.  See "
157                 "https://docs.pytest.org/en/latest/fixture.html#sharing-test-data "
158                 "for details on fixture scope."
159             )
160             argnames = None
161             for fx_defs in item._request._fixturemanager.getfixtureinfo(
162                 node=item, func=item.function, cls=None
163             ).name2fixturedefs.values():
164                 if argnames is None:
165                     argnames = frozenset(signature(item.function).parameters)
166                 for fx in fx_defs:
167                     if fx.argname in argnames:
168                         active_fx = item._request._get_active_fixturedef(fx.argname)
169                         if active_fx.scope == "function":
170                             note_deprecation(
171                                 msg % (item.nodeid, fx.argname), since="2020-02-29"
172                             )
173 
174             if item.get_closest_marker("parametrize") is not None:
175                 # Give every parametrized test invocation a unique database key
176                 key = item.nodeid.encode("utf-8")
177                 item.obj.hypothesis.inner_test._hypothesis_internal_add_digest = key
178 
179             store = StoringReporter(item.config)
180 
181             def note_statistics(stats):
182                 stats["nodeid"] = item.nodeid
183                 item.hypothesis_statistics = describe_statistics(stats)
184 
185             with collector.with_value(note_statistics):
186                 with with_reporter(store):
187                     yield
188             if store.results:
189                 item.hypothesis_report_information = list(store.results)
190 
191     @pytest.hookimpl(hookwrapper=True)
192     def pytest_runtest_makereport(item, call):
193         report = (yield).get_result()
194         if hasattr(item, "hypothesis_report_information"):
195             report.sections.append(
196                 ("Hypothesis", "\n".join(item.hypothesis_report_information))
197             )
198         if hasattr(item, "hypothesis_statistics") and report.when == "teardown":
199             val = ("hypothesis-stats", item.hypothesis_statistics)
200             report.user_properties.append(val)
201 
202     def pytest_terminal_summary(terminalreporter):
203         if not terminalreporter.config.getoption(PRINT_STATISTICS_OPTION):
204             return
205         terminalreporter.section("Hypothesis Statistics")
206         # terminalreporter.stats is a dict, where the empty string appears to
207         # always be the key for a list of _pytest.reports.TestReport objects
208         # (where we stored the statistics data in pytest_runtest_makereport above)
209         for test_report in terminalreporter.stats.get("", []):
210             for name, value in test_report.user_properties:
211                 if name == "hypothesis-stats" and test_report.when == "teardown":
212                     terminalreporter.write_line(value + "\n\n")
213 
214     def pytest_collection_modifyitems(items):
215         for item in items:
216             if isinstance(item, pytest.Function) and is_hypothesis_test(item.obj):
217                 item.add_marker("hypothesis")
218 
219 
220 def load():
221     """Required for `pluggy` to load a plugin from setuptools entrypoints."""
222
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/hypothesis-python/src/hypothesis/extra/pytestplugin.py b/hypothesis-python/src/hypothesis/extra/pytestplugin.py
--- a/hypothesis-python/src/hypothesis/extra/pytestplugin.py
+++ b/hypothesis-python/src/hypothesis/extra/pytestplugin.py
@@ -13,7 +13,6 @@
 #
 # END HEADER
 
-from distutils.version import LooseVersion
 from inspect import signature
 
 import pytest
@@ -44,7 +43,9 @@
         self.results.append(msg)
 
 
-if LooseVersion(pytest.__version__) < "4.3":  # pragma: no cover
+# Avoiding distutils.version.LooseVersion due to
+# https://github.com/HypothesisWorks/hypothesis/issues/2490
+if tuple(map(int, pytest.__version__.split(".")[:2])) < (4, 3):  # pragma: no cover
     import warnings
     from hypothesis.errors import HypothesisWarning

{"golden_diff": "diff --git a/hypothesis-python/src/hypothesis/extra/pytestplugin.py b/hypothesis-python/src/hypothesis/extra/pytestplugin.py\n--- a/hypothesis-python/src/hypothesis/extra/pytestplugin.py\n+++ b/hypothesis-python/src/hypothesis/extra/pytestplugin.py\n@@ -13,7 +13,6 @@\n #\n # END HEADER\n \n-from distutils.version import LooseVersion\n from inspect import signature\n \n import pytest\n@@ -44,7 +43,9 @@\n         self.results.append(msg)\n \n \n-if LooseVersion(pytest.__version__) < \"4.3\":  # pragma: no cover\n+# Avoiding distutils.version.LooseVersion due to\n+# https://github.com/HypothesisWorks/hypothesis/issues/2490\n+if tuple(map(int, pytest.__version__.split(\".\")[:2])) < (4, 3):  # pragma: no cover\n     import warnings\n     from hypothesis.errors import HypothesisWarning\n", "issue": "setuptools 49.2.0 will warn if distutils is imported first\nxref pypa/setuptools#2261, numpy/numpy#16851\r\n\r\nWe are trying to understand why pytest-xdist is failing to run after updating setuptools to 49.2.0. I think one problem might be [this import](https://github.com/HypothesisWorks/hypothesis/blob/master/hypothesis-python/src/hypothesis/extra/pytestplugin.py#L16). I think it would be best to `import setuptools` just before that. Although I think setuptools will move quickly to rectify that warning since it is causing much anguish across different projects, so maybe just weather the storm and wait for the next version.\n", "before_files": [{"content": "# This file is part of Hypothesis, which may be found at\n# https://github.com/HypothesisWorks/hypothesis/\n#\n# Most of this work is copyright (C) 2013-2020 David R. MacIver\n# (david@drmaciver.com), but it contains contributions by others. See\n# CONTRIBUTING.rst for a full list of people who may hold copyright, and\n# consult the git log if you need to determine who owns an individual\n# contribution.\n#\n# This Source Code Form is subject to the terms of the Mozilla Public License,\n# v. 2.0. If a copy of the MPL was not distributed with this file, You can\n# obtain one at https://mozilla.org/MPL/2.0/.\n#\n# END HEADER\n\nfrom distutils.version import LooseVersion\nfrom inspect import signature\n\nimport pytest\n\nfrom hypothesis import Verbosity, core, settings\nfrom hypothesis._settings import note_deprecation\nfrom hypothesis.errors import InvalidArgument\nfrom hypothesis.internal.detection import is_hypothesis_test\nfrom hypothesis.reporting import default as default_reporter, with_reporter\nfrom hypothesis.statistics import collector, describe_statistics\n\nLOAD_PROFILE_OPTION = \"--hypothesis-profile\"\nVERBOSITY_OPTION = \"--hypothesis-verbosity\"\nPRINT_STATISTICS_OPTION = \"--hypothesis-show-statistics\"\nSEED_OPTION = \"--hypothesis-seed\"\n\n\nclass StoringReporter:\n    def __init__(self, config):\n        self.config = config\n        self.results = []\n\n    def __call__(self, msg):\n        if self.config.getoption(\"capture\", \"fd\") == \"no\":\n            default_reporter(msg)\n        if not isinstance(msg, str):\n            msg = repr(msg)\n        self.results.append(msg)\n\n\nif LooseVersion(pytest.__version__) < \"4.3\":  # pragma: no cover\n    import warnings\n    from hypothesis.errors import HypothesisWarning\n\n    PYTEST_TOO_OLD_MESSAGE = \"\"\"\n        You are using Pytest version %s.  Hypothesis tests work with any test\n        runner, but our Pytest plugin requires Pytest  4.3 or newer.\n        Note that the Pytest developers no longer support this version either!\n        Disabling the Hypothesis pytest plugin...\n    \"\"\"\n    warnings.warn(PYTEST_TOO_OLD_MESSAGE % (pytest.__version__,), HypothesisWarning)\n\nelse:\n\n    def pytest_addoption(parser):\n        group = parser.getgroup(\"hypothesis\", \"Hypothesis\")\n        group.addoption(\n            LOAD_PROFILE_OPTION,\n            action=\"store\",\n            help=\"Load in a registered hypothesis.settings profile\",\n        )\n        group.addoption(\n            VERBOSITY_OPTION,\n            action=\"store\",\n            choices=[opt.name for opt in Verbosity],\n            help=\"Override profile with verbosity setting specified\",\n        )\n        group.addoption(\n            PRINT_STATISTICS_OPTION,\n            action=\"store_true\",\n            help=\"Configure when statistics are printed\",\n            default=False,\n        )\n        group.addoption(\n            SEED_OPTION,\n            action=\"store\",\n            help=\"Set a seed to use for all Hypothesis tests\",\n        )\n\n    def pytest_report_header(config):\n        profile = config.getoption(LOAD_PROFILE_OPTION)\n        if not profile:\n            profile = settings._current_profile\n        settings_str = settings.get_profile(profile).show_changed()\n        if settings_str != \"\":\n            settings_str = \" -> %s\" % (settings_str)\n        if (\n            config.option.verbose >= 1\n            or settings.default.verbosity >= Verbosity.verbose\n        ):\n            return \"hypothesis profile %r%s\" % (profile, settings_str)\n\n    def pytest_configure(config):\n        core.running_under_pytest = True\n        profile = config.getoption(LOAD_PROFILE_OPTION)\n        if profile:\n            settings.load_profile(profile)\n        verbosity_name = config.getoption(VERBOSITY_OPTION)\n        if verbosity_name:\n            verbosity_value = Verbosity[verbosity_name]\n            profile_name = \"%s-with-%s-verbosity\" % (\n                settings._current_profile,\n                verbosity_name,\n            )\n            # register_profile creates a new profile, exactly like the current one,\n            # with the extra values given (in this case 'verbosity')\n            settings.register_profile(profile_name, verbosity=verbosity_value)\n            settings.load_profile(profile_name)\n        seed = config.getoption(SEED_OPTION)\n        if seed is not None:\n            try:\n                seed = int(seed)\n            except ValueError:\n                pass\n            core.global_force_seed = seed\n        config.addinivalue_line(\"markers\", \"hypothesis: Tests which use hypothesis.\")\n\n    @pytest.hookimpl(hookwrapper=True)\n    def pytest_runtest_call(item):\n        if not hasattr(item, \"obj\"):\n            yield\n        elif not is_hypothesis_test(item.obj):\n            # If @given was not applied, check whether other hypothesis\n            # decorators were applied, and raise an error if they were.\n            if getattr(item.obj, \"is_hypothesis_strategy_function\", False):\n                raise InvalidArgument(\n                    \"%s is a function that returns a Hypothesis strategy, but pytest \"\n                    \"has collected it as a test function.  This is useless as the \"\n                    \"function body will never be executed.  To define a test \"\n                    \"function, use @given instead of @composite.\" % (item.nodeid,)\n                )\n            message = \"Using `@%s` on a test without `@given` is completely pointless.\"\n            for name, attribute in [\n                (\"example\", \"hypothesis_explicit_examples\"),\n                (\"seed\", \"_hypothesis_internal_use_seed\"),\n                (\"settings\", \"_hypothesis_internal_settings_applied\"),\n                (\"reproduce_example\", \"_hypothesis_internal_use_reproduce_failure\"),\n            ]:\n                if hasattr(item.obj, attribute):\n                    raise InvalidArgument(message % (name,))\n            yield\n        else:\n            # Warn about function-scoped fixtures, excluding autouse fixtures because\n            # the advice is probably not actionable and the status quo seems OK...\n            # See https://github.com/HypothesisWorks/hypothesis/issues/377 for detail.\n            msg = (\n                \"%s uses the %r fixture, which is reset between function calls but not \"\n                \"between test cases generated by `@given(...)`.  You can change it to \"\n                \"a module- or session-scoped fixture if it is safe to reuse; if not \"\n                \"we recommend using a context manager inside your test function.  See \"\n                \"https://docs.pytest.org/en/latest/fixture.html#sharing-test-data \"\n                \"for details on fixture scope.\"\n            )\n            argnames = None\n            for fx_defs in item._request._fixturemanager.getfixtureinfo(\n                node=item, func=item.function, cls=None\n            ).name2fixturedefs.values():\n                if argnames is None:\n                    argnames = frozenset(signature(item.function).parameters)\n                for fx in fx_defs:\n                    if fx.argname in argnames:\n                        active_fx = item._request._get_active_fixturedef(fx.argname)\n                        if active_fx.scope == \"function\":\n                            note_deprecation(\n                                msg % (item.nodeid, fx.argname), since=\"2020-02-29\"\n                            )\n\n            if item.get_closest_marker(\"parametrize\") is not None:\n                # Give every parametrized test invocation a unique database key\n                key = item.nodeid.encode(\"utf-8\")\n                item.obj.hypothesis.inner_test._hypothesis_internal_add_digest = key\n\n            store = StoringReporter(item.config)\n\n            def note_statistics(stats):\n                stats[\"nodeid\"] = item.nodeid\n                item.hypothesis_statistics = describe_statistics(stats)\n\n            with collector.with_value(note_statistics):\n                with with_reporter(store):\n                    yield\n            if store.results:\n                item.hypothesis_report_information = list(store.results)\n\n    @pytest.hookimpl(hookwrapper=True)\n    def pytest_runtest_makereport(item, call):\n        report = (yield).get_result()\n        if hasattr(item, \"hypothesis_report_information\"):\n            report.sections.append(\n                (\"Hypothesis\", \"\\n\".join(item.hypothesis_report_information))\n            )\n        if hasattr(item, \"hypothesis_statistics\") and report.when == \"teardown\":\n            val = (\"hypothesis-stats\", item.hypothesis_statistics)\n            report.user_properties.append(val)\n\n    def pytest_terminal_summary(terminalreporter):\n        if not terminalreporter.config.getoption(PRINT_STATISTICS_OPTION):\n            return\n        terminalreporter.section(\"Hypothesis Statistics\")\n        # terminalreporter.stats is a dict, where the empty string appears to\n        # always be the key for a list of _pytest.reports.TestReport objects\n        # (where we stored the statistics data in pytest_runtest_makereport above)\n        for test_report in terminalreporter.stats.get(\"\", []):\n            for name, value in test_report.user_properties:\n                if name == \"hypothesis-stats\" and test_report.when == \"teardown\":\n                    terminalreporter.write_line(value + \"\\n\\n\")\n\n    def pytest_collection_modifyitems(items):\n        for item in items:\n            if isinstance(item, pytest.Function) and is_hypothesis_test(item.obj):\n                item.add_marker(\"hypothesis\")\n\n\ndef load():\n    \"\"\"Required for `pluggy` to load a plugin from setuptools entrypoints.\"\"\"\n", "path": "hypothesis-python/src/hypothesis/extra/pytestplugin.py"}], "after_files": [{"content": "# This file is part of Hypothesis, which may be found at\n# https://github.com/HypothesisWorks/hypothesis/\n#\n# Most of this work is copyright (C) 2013-2020 David R. MacIver\n# (david@drmaciver.com), but it contains contributions by others. See\n# CONTRIBUTING.rst for a full list of people who may hold copyright, and\n# consult the git log if you need to determine who owns an individual\n# contribution.\n#\n# This Source Code Form is subject to the terms of the Mozilla Public License,\n# v. 2.0. If a copy of the MPL was not distributed with this file, You can\n# obtain one at https://mozilla.org/MPL/2.0/.\n#\n# END HEADER\n\nfrom inspect import signature\n\nimport pytest\n\nfrom hypothesis import Verbosity, core, settings\nfrom hypothesis._settings import note_deprecation\nfrom hypothesis.errors import InvalidArgument\nfrom hypothesis.internal.detection import is_hypothesis_test\nfrom hypothesis.reporting import default as default_reporter, with_reporter\nfrom hypothesis.statistics import collector, describe_statistics\n\nLOAD_PROFILE_OPTION = \"--hypothesis-profile\"\nVERBOSITY_OPTION = \"--hypothesis-verbosity\"\nPRINT_STATISTICS_OPTION = \"--hypothesis-show-statistics\"\nSEED_OPTION = \"--hypothesis-seed\"\n\n\nclass StoringReporter:\n    def __init__(self, config):\n        self.config = config\n        self.results = []\n\n    def __call__(self, msg):\n        if self.config.getoption(\"capture\", \"fd\") == \"no\":\n            default_reporter(msg)\n        if not isinstance(msg, str):\n            msg = repr(msg)\n        self.results.append(msg)\n\n\n# Avoiding distutils.version.LooseVersion due to\n# https://github.com/HypothesisWorks/hypothesis/issues/2490\nif tuple(map(int, pytest.__version__.split(\".\")[:2])) < (4, 3):  # pragma: no cover\n    import warnings\n    from hypothesis.errors import HypothesisWarning\n\n    PYTEST_TOO_OLD_MESSAGE = \"\"\"\n        You are using Pytest version %s.  Hypothesis tests work with any test\n        runner, but our Pytest plugin requires Pytest  4.3 or newer.\n        Note that the Pytest developers no longer support this version either!\n        Disabling the Hypothesis pytest plugin...\n    \"\"\"\n    warnings.warn(PYTEST_TOO_OLD_MESSAGE % (pytest.__version__,), HypothesisWarning)\n\nelse:\n\n    def pytest_addoption(parser):\n        group = parser.getgroup(\"hypothesis\", \"Hypothesis\")\n        group.addoption(\n            LOAD_PROFILE_OPTION,\n            action=\"store\",\n            help=\"Load in a registered hypothesis.settings profile\",\n        )\n        group.addoption(\n            VERBOSITY_OPTION,\n            action=\"store\",\n            choices=[opt.name for opt in Verbosity],\n            help=\"Override profile with verbosity setting specified\",\n        )\n        group.addoption(\n            PRINT_STATISTICS_OPTION,\n            action=\"store_true\",\n            help=\"Configure when statistics are printed\",\n            default=False,\n        )\n        group.addoption(\n            SEED_OPTION,\n            action=\"store\",\n            help=\"Set a seed to use for all Hypothesis tests\",\n        )\n\n    def pytest_report_header(config):\n        profile = config.getoption(LOAD_PROFILE_OPTION)\n        if not profile:\n            profile = settings._current_profile\n        settings_str = settings.get_profile(profile).show_changed()\n        if settings_str != \"\":\n            settings_str = \" -> %s\" % (settings_str)\n        if (\n            config.option.verbose >= 1\n            or settings.default.verbosity >= Verbosity.verbose\n        ):\n            return \"hypothesis profile %r%s\" % (profile, settings_str)\n\n    def pytest_configure(config):\n        core.running_under_pytest = True\n        profile = config.getoption(LOAD_PROFILE_OPTION)\n        if profile:\n            settings.load_profile(profile)\n        verbosity_name = config.getoption(VERBOSITY_OPTION)\n        if verbosity_name:\n            verbosity_value = Verbosity[verbosity_name]\n            profile_name = \"%s-with-%s-verbosity\" % (\n                settings._current_profile,\n                verbosity_name,\n            )\n            # register_profile creates a new profile, exactly like the current one,\n            # with the extra values given (in this case 'verbosity')\n            settings.register_profile(profile_name, verbosity=verbosity_value)\n            settings.load_profile(profile_name)\n        seed = config.getoption(SEED_OPTION)\n        if seed is not None:\n            try:\n                seed = int(seed)\n            except ValueError:\n                pass\n            core.global_force_seed = seed\n        config.addinivalue_line(\"markers\", \"hypothesis: Tests which use hypothesis.\")\n\n    @pytest.hookimpl(hookwrapper=True)\n    def pytest_runtest_call(item):\n        if not hasattr(item, \"obj\"):\n            yield\n        elif not is_hypothesis_test(item.obj):\n            # If @given was not applied, check whether other hypothesis\n            # decorators were applied, and raise an error if they were.\n            if getattr(item.obj, \"is_hypothesis_strategy_function\", False):\n                raise InvalidArgument(\n                    \"%s is a function that returns a Hypothesis strategy, but pytest \"\n                    \"has collected it as a test function.  This is useless as the \"\n                    \"function body will never be executed.  To define a test \"\n                    \"function, use @given instead of @composite.\" % (item.nodeid,)\n                )\n            message = \"Using `@%s` on a test without `@given` is completely pointless.\"\n            for name, attribute in [\n                (\"example\", \"hypothesis_explicit_examples\"),\n                (\"seed\", \"_hypothesis_internal_use_seed\"),\n                (\"settings\", \"_hypothesis_internal_settings_applied\"),\n                (\"reproduce_example\", \"_hypothesis_internal_use_reproduce_failure\"),\n            ]:\n                if hasattr(item.obj, attribute):\n                    raise InvalidArgument(message % (name,))\n            yield\n        else:\n            # Warn about function-scoped fixtures, excluding autouse fixtures because\n            # the advice is probably not actionable and the status quo seems OK...\n            # See https://github.com/HypothesisWorks/hypothesis/issues/377 for detail.\n            msg = (\n                \"%s uses the %r fixture, which is reset between function calls but not \"\n                \"between test cases generated by `@given(...)`.  You can change it to \"\n                \"a module- or session-scoped fixture if it is safe to reuse; if not \"\n                \"we recommend using a context manager inside your test function.  See \"\n                \"https://docs.pytest.org/en/latest/fixture.html#sharing-test-data \"\n                \"for details on fixture scope.\"\n            )\n            argnames = None\n            for fx_defs in item._request._fixturemanager.getfixtureinfo(\n                node=item, func=item.function, cls=None\n            ).name2fixturedefs.values():\n                if argnames is None:\n                    argnames = frozenset(signature(item.function).parameters)\n                for fx in fx_defs:\n                    if fx.argname in argnames:\n                        active_fx = item._request._get_active_fixturedef(fx.argname)\n                        if active_fx.scope == \"function\":\n                            note_deprecation(\n                                msg % (item.nodeid, fx.argname), since=\"2020-02-29\"\n                            )\n\n            if item.get_closest_marker(\"parametrize\") is not None:\n                # Give every parametrized test invocation a unique database key\n                key = item.nodeid.encode(\"utf-8\")\n                item.obj.hypothesis.inner_test._hypothesis_internal_add_digest = key\n\n            store = StoringReporter(item.config)\n\n            def note_statistics(stats):\n                stats[\"nodeid\"] = item.nodeid\n                item.hypothesis_statistics = describe_statistics(stats)\n\n            with collector.with_value(note_statistics):\n                with with_reporter(store):\n                    yield\n            if store.results:\n                item.hypothesis_report_information = list(store.results)\n\n    @pytest.hookimpl(hookwrapper=True)\n    def pytest_runtest_makereport(item, call):\n        report = (yield).get_result()\n        if hasattr(item, \"hypothesis_report_information\"):\n            report.sections.append(\n                (\"Hypothesis\", \"\\n\".join(item.hypothesis_report_information))\n            )\n        if hasattr(item, \"hypothesis_statistics\") and report.when == \"teardown\":\n            val = (\"hypothesis-stats\", item.hypothesis_statistics)\n            report.user_properties.append(val)\n\n    def pytest_terminal_summary(terminalreporter):\n        if not terminalreporter.config.getoption(PRINT_STATISTICS_OPTION):\n            return\n        terminalreporter.section(\"Hypothesis Statistics\")\n        # terminalreporter.stats is a dict, where the empty string appears to\n        # always be the key for a list of _pytest.reports.TestReport objects\n        # (where we stored the statistics data in pytest_runtest_makereport above)\n        for test_report in terminalreporter.stats.get(\"\", []):\n            for name, value in test_report.user_properties:\n                if name == \"hypothesis-stats\" and test_report.when == \"teardown\":\n                    terminalreporter.write_line(value + \"\\n\\n\")\n\n    def pytest_collection_modifyitems(items):\n        for item in items:\n            if isinstance(item, pytest.Function) and is_hypothesis_test(item.obj):\n                item.add_marker(\"hypothesis\")\n\n\ndef load():\n    \"\"\"Required for `pluggy` to load a plugin from setuptools entrypoints.\"\"\"\n", "path": "hypothesis-python/src/hypothesis/extra/pytestplugin.py"}]}