@@ -59,28 +59,28 @@ def pytest_addoption(parser):
5959 )
6060
6161
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 {}
6767
6868
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
7674
7775
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 ()
8484
8585
8686def pytest_configure (config ):
@@ -89,7 +89,9 @@ def pytest_configure(config):
8989 register a custom marker for MypyItems,
9090 and configure the plugin based on the CLI.
9191 """
92- if _is_xdist_controller (config ):
92+ xdist_worker = _xdist_worker (config )
93+ if not xdist_worker :
94+ config .pluginmanager .register (MypyReportingPlugin ())
9395
9496 # Get the path to a temporary file and delete it.
9597 # The first MypyItem to run will see the file does not exist,
@@ -104,15 +106,12 @@ def pytest_configure(config):
104106 # If xdist is enabled, then the results path should be exposed to
105107 # the workers so that they know where to read parsed results from.
106108 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+ )
116115
117116 config .addinivalue_line (
118117 "markers" ,
@@ -278,13 +277,7 @@ def from_mypy(
278277 @classmethod
279278 def from_session (cls , session ) -> "MypyResults" :
280279 """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
288281 with FileLock (str (mypy_results_path ) + ".lock" ):
289282 try :
290283 with open (mypy_results_path , mode = "r" ) as results_f :
@@ -313,22 +306,23 @@ class MypyWarning(pytest.PytestWarning):
313306 """A non-failure message regarding the mypy run."""
314307
315308
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