diff --git a/python_files/vscode_pytest/__init__.py b/python_files/vscode_pytest/__init__.py index 2764d1c89782..baa9df90eddd 100644 --- a/python_files/vscode_pytest/__init__.py +++ b/python_files/vscode_pytest/__init__.py @@ -1,6 +1,8 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. +from __future__ import annotations + import atexit import json import os @@ -8,24 +10,24 @@ import sys import traceback from typing import ( + TYPE_CHECKING, Any, Dict, Generator, - List, Literal, - Optional, TypedDict, - Union, ) import pytest -from pluggy import Result script_dir = pathlib.Path(__file__).parent.parent sys.path.append(os.fspath(script_dir)) sys.path.append(os.fspath(script_dir / "lib" / "python")) from testing_tools import socket_manager # noqa: E402 +if TYPE_CHECKING: + from pluggy import Result + class TestData(TypedDict): """A general class that all test objects inherit from.""" @@ -46,7 +48,7 @@ class TestItem(TestData): class TestNode(TestData): """A general class that handles all test data which contains children.""" - children: "list[Union[TestNode, TestItem, None]]" + children: list[TestNode | TestItem | None] class VSCodePytestError(Exception): @@ -209,17 +211,17 @@ class TestOutcome(Dict): test: str outcome: Literal["success", "failure", "skipped", "error"] - message: Union[str, None] - traceback: Union[str, None] - subtest: Optional[str] + message: str | None + traceback: str | None + subtest: str | None def create_test_outcome( testid: str, outcome: str, - message: Union[str, None], - traceback: Union[str, None], - subtype: Optional[str] = None, # noqa: ARG001 + message: str | None, + traceback: str | None, + subtype: str | None = None, # noqa: ARG001 ) -> TestOutcome: """A function that creates a TestOutcome object.""" return TestOutcome( @@ -235,7 +237,7 @@ class TestRunResultDict(Dict[str, Dict[str, TestOutcome]]): """A class that stores all test run results.""" outcome: str - tests: Dict[str, TestOutcome] + tests: dict[str, TestOutcome] @pytest.hookimpl(hookwrapper=True, trylast=True) @@ -384,7 +386,7 @@ def pytest_sessionfinish(session, exitstatus): } post_response(os.fsdecode(cwd), error_node) try: - session_node: Union[TestNode, None] = build_test_tree(session) + session_node: TestNode | None = build_test_tree(session) if not session_node: raise VSCodePytestError( "Something went wrong following pytest finish, \ @@ -430,10 +432,10 @@ def build_test_tree(session: pytest.Session) -> TestNode: session -- the pytest session object. """ session_node = create_session_node(session) - session_children_dict: Dict[str, TestNode] = {} - file_nodes_dict: Dict[Any, TestNode] = {} - class_nodes_dict: Dict[str, TestNode] = {} - function_nodes_dict: Dict[str, TestNode] = {} + session_children_dict: dict[str, TestNode] = {} + file_nodes_dict: dict[Any, TestNode] = {} + class_nodes_dict: dict[str, TestNode] = {} + function_nodes_dict: dict[str, TestNode] = {} # Check to see if the global variable for symlink path is set if SYMLINK_PATH: @@ -492,7 +494,7 @@ def build_test_tree(session: pytest.Session) -> TestNode: if isinstance(test_case.parent, pytest.Class): case_iter = test_case.parent node_child_iter = test_node - test_class_node: Union[TestNode, None] = None + test_class_node: TestNode | None = None while isinstance(case_iter, pytest.Class): # While the given node is a class, create a class and nest the previous node as a child. try: @@ -529,7 +531,7 @@ def build_test_tree(session: pytest.Session) -> TestNode: parent_test_case = create_file_node(test_case.parent) file_nodes_dict[test_case.parent] = parent_test_case parent_test_case["children"].append(test_node) - created_files_folders_dict: Dict[str, TestNode] = {} + created_files_folders_dict: dict[str, TestNode] = {} for file_node in file_nodes_dict.values(): # Iterate through all the files that exist and construct them into nested folders. root_folder_node: TestNode @@ -562,7 +564,7 @@ def build_test_tree(session: pytest.Session) -> TestNode: def build_nested_folders( file_node: TestNode, - created_files_folders_dict: Dict[str, TestNode], + created_files_folders_dict: dict[str, TestNode], session_node: TestNode, ) -> TestNode: """Takes a file or folder and builds the nested folder structure for it. @@ -722,8 +724,8 @@ class DiscoveryPayloadDict(TypedDict): cwd: str status: Literal["success", "error"] - tests: Optional[TestNode] - error: Optional[List[str]] + tests: TestNode | None + error: list[str] | None class ExecutionPayloadDict(Dict): @@ -731,9 +733,9 @@ class ExecutionPayloadDict(Dict): cwd: str status: Literal["success", "error"] - result: Union[TestRunResultDict, None] - not_found: Union[List[str], None] # Currently unused need to check - error: Union[str, None] # Currently unused need to check + result: TestRunResultDict | None + not_found: list[str] | None # Currently unused need to check + error: str | None # Currently unused need to check class EOTPayloadDict(TypedDict): @@ -782,9 +784,7 @@ def get_node_path(node: Any) -> pathlib.Path: atexit.register(lambda: __writer.close() if __writer else None) -def execution_post( - cwd: str, status: Literal["success", "error"], tests: Union[TestRunResultDict, None] -): +def execution_post(cwd: str, status: Literal["success", "error"], tests: TestRunResultDict | None): """Sends a POST request with execution payload details. Args: @@ -829,7 +829,7 @@ def default(self, obj): def send_post_request( - payload: Union[ExecutionPayloadDict, DiscoveryPayloadDict, EOTPayloadDict], + payload: ExecutionPayloadDict | DiscoveryPayloadDict | EOTPayloadDict, cls_encoder=None, ): """