Cleanup workarounds for Python < 3.8 (#13882)

Cleanup workarounds for Python < 3.8

Fix #11087
diff --git a/build_tools/benchmarks/common/benchmark_driver.py b/build_tools/benchmarks/common/benchmark_driver.py
index 5e2b0c0..c22afdf 100644
--- a/build_tools/benchmarks/common/benchmark_driver.py
+++ b/build_tools/benchmarks/common/benchmark_driver.py
@@ -136,11 +136,10 @@
           self.run_benchmark_case(benchmark_case, results_path, capture_path)
         except Exception as e:
           # Delete unfinished results if they exist.
-          # TODO(#11087): Use missing_ok=True once we move to Python 3.8.
-          if results_path is not None and results_path.is_file():
-            results_path.unlink()
-          if capture_path is not None and capture_path.is_file():
-            capture_path.unlink()
+          if results_path is not None:
+            results_path.unlink(missing_ok=True)
+          if capture_path is not None:
+            capture_path.unlink(missing_ok=True)
 
           if not self.config.keep_going:
             raise e
diff --git a/build_tools/python/e2e_test_framework/serialization.py b/build_tools/python/e2e_test_framework/serialization.py
index ac70484..bc430c7 100644
--- a/build_tools/python/e2e_test_framework/serialization.py
+++ b/build_tools/python/e2e_test_framework/serialization.py
@@ -119,19 +119,19 @@
   if deserialize_func is not None:
     return deserialize_func(data, keyed_obj_map, obj_cache)
 
-  elif _get_type_origin(obj_type) == list:
-    subtype, = _get_type_args(obj_type)
+  elif typing.get_origin(obj_type) == list:
+    subtype, = typing.get_args(obj_type)
     return [
         _deserialize(item, subtype, keyed_obj_map, obj_cache) for item in data
     ]
 
-  elif _get_type_origin(obj_type) == dict:
-    _, value_type = _get_type_args(obj_type)
+  elif typing.get_origin(obj_type) == dict:
+    _, value_type = typing.get_args(obj_type)
     return dict((key, _deserialize(value, value_type, keyed_obj_map, obj_cache))
                 for key, value in data.items())
 
-  elif _get_type_origin(obj_type) == Union:
-    subtypes = _get_type_args(obj_type)
+  elif typing.get_origin(obj_type) == Union:
+    subtypes = typing.get_args(obj_type)
     if len(subtypes) != 2 or NONE_TYPE not in subtypes:
       raise ValueError(f"Unsupported union type: {obj_type}.")
     subtype = subtypes[0] if subtypes[1] == NONE_TYPE else subtypes[1]
@@ -146,24 +146,6 @@
   return data
 
 
-def _get_type_origin(tp):
-  """Get the unsubscripted type. Returns None is unsupported.
-
-  This is similar to typing.get_origin, but only exists after Python 3.8.
-  TODO(#11087): Replace with typing.get_origin after upgrading to 3.8.
-  """
-  return getattr(tp, "__origin__", None)
-
-
-def _get_type_args(tp) -> Tuple:
-  """Get the type arguments.
-
-  This is similar to typing.get_args, but only exists after Python 3.8.
-  TODO(#11087): Replace with typing.get_origin after upgrading to 3.8.
-  """
-  return getattr(tp, "__args__", ())
-
-
 def serializable(cls=None,
                  type_key: Optional[str] = None,
                  id_field: str = "id"):