@@ -59,28 +59,28 @@ def pytest_addoption(parser):
59
59
)
60
60
61
61
62
- XDIST_WORKERINPUT_ATTRIBUTE_NAMES = (
63
- "workerinput" ,
64
- # xdist < 2.0.0:
65
- "slaveinput" ,
66
- )
62
+ def _xdist_worker ( config ):
63
+ try :
64
+ return { "input" : _xdist_workerinput ( config )}
65
+ except AttributeError :
66
+ return {}
67
67
68
68
69
- def _get_xdist_workerinput (config_node ):
70
- workerinput = None
71
- for attr_name in XDIST_WORKERINPUT_ATTRIBUTE_NAMES :
72
- workerinput = getattr (config_node , attr_name , None )
73
- if workerinput is not None :
74
- break
75
- return workerinput
69
+ def _xdist_workerinput (node ):
70
+ try :
71
+ return node .workerinput
72
+ except AttributeError : # compat xdist < 2.0
73
+ return node .slaveinput
76
74
77
75
78
- def _is_xdist_controller (config ):
79
- """
80
- True if the code running the given pytest.config object is running in
81
- an xdist controller node or not running xdist at all.
82
- """
83
- return _get_xdist_workerinput (config ) is None
76
+ class MypyXdistControllerPlugin :
77
+ """A plugin that is only registered on xdist controller processes."""
78
+
79
+ def pytest_configure_node (self , node ):
80
+ """Pass the config stash to workers."""
81
+ _xdist_workerinput (node )["mypy_config_stash_serialized" ] = node .config .stash [
82
+ stash_key ["config" ]
83
+ ].serialized ()
84
84
85
85
86
86
def pytest_configure (config ):
@@ -89,7 +89,9 @@ def pytest_configure(config):
89
89
register a custom marker for MypyItems,
90
90
and configure the plugin based on the CLI.
91
91
"""
92
- if _is_xdist_controller (config ):
92
+ xdist_worker = _xdist_worker (config )
93
+ if not xdist_worker :
94
+ config .pluginmanager .register (MypyReportingPlugin ())
93
95
94
96
# Get the path to a temporary file and delete it.
95
97
# The first MypyItem to run will see the file does not exist,
@@ -104,15 +106,12 @@ def pytest_configure(config):
104
106
# If xdist is enabled, then the results path should be exposed to
105
107
# the workers so that they know where to read parsed results from.
106
108
if config .pluginmanager .getplugin ("xdist" ):
107
-
108
- class _MypyXdistPlugin :
109
- def pytest_configure_node (self , node ): # xdist hook
110
- """Pass the mypy results path to workers."""
111
- _get_xdist_workerinput (node )["mypy_config_stash_serialized" ] = (
112
- node .config .stash [stash_key ["config" ]].serialized ()
113
- )
114
-
115
- config .pluginmanager .register (_MypyXdistPlugin ())
109
+ config .pluginmanager .register (MypyXdistControllerPlugin ())
110
+ else :
111
+ # xdist workers create the stash using input from the controller plugin.
112
+ config .stash [stash_key ["config" ]] = MypyConfigStash .from_serialized (
113
+ xdist_worker ["input" ]["mypy_config_stash_serialized" ]
114
+ )
116
115
117
116
config .addinivalue_line (
118
117
"markers" ,
@@ -278,13 +277,7 @@ def from_mypy(
278
277
@classmethod
279
278
def from_session (cls , session ) -> "MypyResults" :
280
279
"""Load (or generate) cached mypy results for a pytest session."""
281
- if _is_xdist_controller (session .config ):
282
- mypy_config_stash = session .config .stash [stash_key ["config" ]]
283
- else :
284
- mypy_config_stash = MypyConfigStash .from_serialized (
285
- _get_xdist_workerinput (session .config )["mypy_config_stash_serialized" ]
286
- )
287
- mypy_results_path = mypy_config_stash .mypy_results_path
280
+ mypy_results_path = session .config .stash [stash_key ["config" ]].mypy_results_path
288
281
with FileLock (str (mypy_results_path ) + ".lock" ):
289
282
try :
290
283
with open (mypy_results_path , mode = "r" ) as results_f :
@@ -313,22 +306,23 @@ class MypyWarning(pytest.PytestWarning):
313
306
"""A non-failure message regarding the mypy run."""
314
307
315
308
316
- def pytest_terminal_summary (terminalreporter , config ):
317
- """Report stderr and unrecognized lines from stdout."""
318
- if not _is_xdist_controller (config ):
319
- return
320
- mypy_results_path = config .stash [stash_key ["config" ]].mypy_results_path
321
- try :
322
- with open (mypy_results_path , mode = "r" ) as results_f :
323
- results = MypyResults .load (results_f )
324
- except FileNotFoundError :
325
- # No MypyItems executed.
326
- return
327
- if results .unmatched_stdout or results .stderr :
328
- terminalreporter .section (terminal_summary_title )
329
- if results .unmatched_stdout :
330
- color = {"red" : True } if results .status else {"green" : True }
331
- terminalreporter .write_line (results .unmatched_stdout , ** color )
332
- if results .stderr :
333
- terminalreporter .write_line (results .stderr , yellow = True )
334
- mypy_results_path .unlink ()
309
+ class MypyReportingPlugin :
310
+ """A Pytest plugin that reports mypy results."""
311
+
312
+ def pytest_terminal_summary (self , terminalreporter , config ):
313
+ """Report stderr and unrecognized lines from stdout."""
314
+ mypy_results_path = config .stash [stash_key ["config" ]].mypy_results_path
315
+ try :
316
+ with open (mypy_results_path , mode = "r" ) as results_f :
317
+ results = MypyResults .load (results_f )
318
+ except FileNotFoundError :
319
+ # No MypyItems executed.
320
+ return
321
+ if results .unmatched_stdout or results .stderr :
322
+ terminalreporter .section (terminal_summary_title )
323
+ if results .unmatched_stdout :
324
+ color = {"red" : True } if results .status else {"green" : True }
325
+ terminalreporter .write_line (results .unmatched_stdout , ** color )
326
+ if results .stderr :
327
+ terminalreporter .write_line (results .stderr , yellow = True )
328
+ mypy_results_path .unlink ()
0 commit comments