1515from typing import Any , Dict , List , Optional , Tuple
1616
1717if sys .platform == "win32" :
18- from namedpipe import NPopen
18+ from namedpipe import NPopen # pylint: disable=import-error # cspell: disable-line
1919
2020
2121script_dir = pathlib .Path (__file__ ).parent .parent .parent
@@ -54,7 +54,7 @@ def create_symlink(root: pathlib.Path, target_ext: str, destination_ext: str):
5454 print ("destination already exists" , destination )
5555 try :
5656 destination .symlink_to (target )
57- except Exception as e :
57+ except OSError as e :
5858 print ("error occurred when attempting to create a symlink" , e )
5959 yield target , destination
6060 finally :
@@ -82,12 +82,57 @@ def process_data_received(data: str) -> List[Dict[str, Any]]:
8282 elif json_data ["jsonrpc" ] != "2.0" :
8383 raise ValueError ("Invalid JSON-RPC version received, not version 2.0" )
8484 else :
85- json_messages .append (json_data ["params" ])
85+ json_messages .append (expand_compact_discovery_payload ( json_data ["params" ]) )
8686
8787 return json_messages # return the list of json messages
8888
8989
90- def parse_rpc_message (data : str ) -> Tuple [Dict [str , str ], str ]:
90+ def expand_path (path_value : str , path_base : str ) -> str :
91+ if not path_base or pathlib .Path (path_value ).is_absolute ():
92+ return path_value
93+ if path_value == "." :
94+ return path_base
95+ return os .fspath (pathlib .Path (path_base , path_value ))
96+
97+
98+ def expand_test_id (test_id : str , id_base : str ) -> str :
99+ test_path , separator , selector = test_id .partition ("::" )
100+ expanded_test_path = expand_path (test_path , id_base )
101+ return f"{ expanded_test_path } { separator } { selector } " if separator else expanded_test_path
102+
103+
104+ def expand_compact_discovery_node (
105+ test_node : Dict [str , Any ] | None , path_base : str , id_base : str
106+ ) -> Dict [str , Any ] | None :
107+ if test_node is None :
108+ return None
109+ expanded_node = dict (test_node )
110+ if "path" in expanded_node :
111+ expanded_node ["path" ] = expand_path (expanded_node ["path" ], path_base )
112+ if "id_" in expanded_node :
113+ expanded_node ["id_" ] = expand_test_id (expanded_node ["id_" ], id_base )
114+ if "runID" in expanded_node :
115+ expanded_node ["runID" ] = expand_test_id (expanded_node ["runID" ], id_base )
116+ if "children" in expanded_node :
117+ expanded_node ["children" ] = [
118+ expand_compact_discovery_node (child , path_base , id_base )
119+ for child in expanded_node ["children" ]
120+ ]
121+ return expanded_node
122+
123+
124+ def expand_compact_discovery_payload (payload : Dict [str , Any ]) -> Dict [str , Any ]:
125+ path_base = payload .get ("pathBase" )
126+ if not path_base or "tests" not in payload or payload ["tests" ] is None :
127+ return payload
128+
129+ expanded_payload = dict (payload )
130+ id_base = payload .get ("idBase" , path_base )
131+ expanded_payload ["tests" ] = expand_compact_discovery_node (payload ["tests" ], path_base , id_base )
132+ return expanded_payload
133+
134+
135+ def parse_rpc_message (data : str ) -> Tuple [Dict [str , Any ], str ]:
91136 """Process the JSON data which comes from the server.
92137
93138 A single rpc payload is in the format:
@@ -122,7 +167,7 @@ def parse_rpc_message(data: str) -> Tuple[Dict[str, str], str]:
122167 line : str = str_stream .readline (length )
123168 try :
124169 # try to parse the json, if successful it is single payload so return with remaining data
125- json_data : dict [str , str ] = json .loads (line )
170+ json_data : dict [str , Any ] = json .loads (line )
126171 return json_data , str_stream .read ()
127172 except json .JSONDecodeError :
128173 print ("json decode error" )
@@ -131,7 +176,7 @@ def parse_rpc_message(data: str) -> Tuple[Dict[str, str], str]:
131176def _listen_on_fifo (pipe_name : str , result : List [str ], completed : threading .Event ):
132177 # Open the FIFO for reading
133178 fifo_path = pathlib .Path (pipe_name )
134- with fifo_path .open () as fifo :
179+ with fifo_path .open (encoding = "utf-8" ) as fifo :
135180 print ("Waiting for data..." )
136181 while True :
137182 if completed .is_set ():
@@ -198,7 +243,7 @@ def _listen_on_pipe_new(listener, result: List[str], completed: threading.Event)
198243
199244
200245def _run_test_code (proc_args : List [str ], proc_env , proc_cwd : str , completed : threading .Event ):
201- result = subprocess .run (proc_args , env = proc_env , cwd = proc_cwd )
246+ result = subprocess .run (proc_args , env = proc_env , cwd = proc_cwd , check = False )
202247 completed .set ()
203248 return result
204249
@@ -257,7 +302,7 @@ def runner_with_cwd_env(
257302 )
258303 env_add .update ({"RUN_TEST_IDS_PIPE" : test_ids_pipe })
259304 test_ids_arr = after_ids
260- with open (test_ids_pipe , "w" ) as f : # noqa: PTH123
305+ with open (test_ids_pipe , "w" , encoding = "utf-8" ) as f : # noqa: PTH123
261306 f .write ("\n " .join (test_ids_arr ))
262307 else :
263308 process_args = [sys .executable , "-m" , "pytest" , "-p" , "vscode_pytest" , "-s" , * args ]
@@ -379,7 +424,7 @@ def find_test_line_number(test_name: str, test_file_path) -> str:
379424 test_file_path: The path to the test file where the test is located.
380425 """
381426 test_file_unique_id : str = "test_marker--" + test_name .split ("[" )[0 ]
382- with open (test_file_path ) as f : # noqa: PTH123
427+ with open (test_file_path , encoding = "utf-8" ) as f : # noqa: PTH123
383428 for i , line in enumerate (f ):
384429 if test_file_unique_id in line :
385430 return str (i + 1 )
@@ -395,7 +440,7 @@ def find_class_line_number(class_name: str, test_file_path) -> str:
395440 test_file_path: The path to the test file where the class is located.
396441 """
397442 # Look for the class definition line (or function for pytest-describe)
398- with open (test_file_path ) as f : # noqa: PTH123
443+ with open (test_file_path , encoding = "utf-8" ) as f : # noqa: PTH123
399444 for i , line in enumerate (f ):
400445 # Match "class ClassName" or "class ClassName(" or "class ClassName:"
401446 # Also match "def ClassName(" for pytest-describe blocks
0 commit comments