This is on top of #2225. The goal is to be able to skip specific tests. Many core test sets have just one test that uses subprocess or threads. Others have a few tests that are failing due to upstream problems in emscripten. I went through and switched to skipping specific tests in as many cases as I could. In modules where most or all tests use threading or subprocess, I gave up and put a comment saying something like 35/50 tests fork and I didn't want to bother to salvage the remaining ones.

In order to accommodate using patterns to skip specific tests (and also extra comments) I switched the format of `python_tests` to a yaml file. This gives us significantly more flexibility in the structure of the file and allows us to use `ruamel.yaml` to update it. We gain a lot flexibility while reducing the length of `make_test_lists.py` modestly from 108 to 78 loc.

In the future, hopefully we should be able to make fixes by deleting one skip pattern and looking into why that particular test fails.

Rework core tests. This is on top of #2225. The goal is to be able to skip specific tests. Many core test sets have just one test that uses subprocess or threads. Others have a few tests that are failing due to upstream problems in emscripten. I went through and switched to skipping specific tests in as many cases as I could. In modules where most or all tests use threading or subprocess, I gave up and put a comment saying something like 35/50 tests fork and I didn't want to bother to salvage the remaining ones.

In order to accommodate using patterns to skip specific tests (and also extra comments) I switched the format of `python_tests` to a yaml file. This gives us significantly more flexibility in the structure of the file and allows us to use `ruamel.yaml` to update it. We gain a lot flexibility while reducing the length of `make_test_lists.py` modestly from 108 to 78 loc.

In the future, hopefully we should be able to make fixes by deleting one skip pattern and looking into why that particular test fails.

From 4867d140e8613d5fdf999b4354f1ef6958dfeffb Mon Sep 17 00:00:00 2001
From: Corentin Cadiou <corentin.cadiou@cphyc.me>
Date: Thu, 3 Mar 2022 12:47:23 +0100
Subject: [PATCH] Merge pull request #3831 from neutrinoceros/migrate2tomli

MNT: migrate from toml to tomli + tomli_w

diff --git a/yt/config.py b/yt/config.py
index 5dfc809a56..c5da7ad93a 100644
--- a/yt/config.py
+++ b/yt/config.py
@@ -1,7 +1,9 @@
 import os
 import warnings
 
-import toml
+# TODO: import tomllib from the standard library instead in Python >= 3.11
+import tomli as tomllib
+import tomli_w
 from more_itertools import always_iterable
 
 from yt._maintenance.deprecation import issue_deprecation_warning
@@ -154,14 +156,16 @@ def read(self, file_names):
             if not os.path.exists(fname):
                 continue
             metadata = {"source": f"file: {fname}"}
-            self.update(toml.load(fname), metadata=metadata)
+            with open(fname, "rb") as fh:
+                data = tomllib.load(fh)
+            self.update(data, metadata=metadata)
             file_names_read.append(fname)
 
         return file_names_read
 
     def write(self, file_handler):
         value = self.config_root.as_dict()
-        config_as_str = toml.dumps(value)
+        config_as_str = tomli_w.dumps(value)
 
         try:
             # Assuming file_handler has a write attribute
@@ -222,8 +226,8 @@ def _repr_json_(self):
 if not os.path.exists(_global_config_file):
     cfg = {"yt": {}}
     try:
-        with open(_global_config_file, mode="w") as fd:
-            toml.dump(cfg, fd)
+        with open(_global_config_file, mode="wb") as fd:
+            tomli_w.dump(cfg, fd)
     except OSError:
         warnings.warn("unable to write new config file")
 

From 4867d140e8613d5fdf999b4354f1ef6958dfeffb Mon Sep 17 00:00:00 2001
From: Corentin Cadiou <corentin.cadiou@cphyc.me>
Date: Thu, 3 Mar 2022 12:47:23 +0100
Subject: [PATCH] Merge pull request #3831 from neutrinoceros/migrate2tomli

MNT: migrate from toml to tomli + tomli_w

diff --git a/yt/config.py b/yt/config.py
index 5dfc809a56..c5da7ad93a 100644
--- a/yt/config.py
+++ b/yt/config.py
@@ -1,7 +1,9 @@
 import os
 import warnings
 
-import toml
+# TODO: import tomllib from the standard library instead in Python >= 3.11
+import tomli as tomllib
+import tomli_w
 from more_itertools import always_iterable
 
 from yt._maintenance.deprecation import issue_deprecation_warning
@@ -154,14 +156,16 @@ def read(self, file_names):
             if not os.path.exists(fname):
                 continue
             metadata = {"source": f"file: {fname}"}
-            self.update(toml.load(fname), metadata=metadata)
+            with open(fname, "rb") as fh:
+                data = tomllib.load(fh)
+            self.update(data, metadata=metadata)
             file_names_read.append(fname)
 
         return file_names_read
 
     def write(self, file_handler):
         value = self.config_root.as_dict()
-        config_as_str = toml.dumps(value)
+        config_as_str = tomli_w.dumps(value)
 
         try:
             # Assuming file_handler has a write attribute
@@ -222,8 +226,8 @@ def _repr_json_(self):
 if not os.path.exists(_global_config_file):
     cfg = {"yt": {}}
     try:
-        with open(_global_config_file, mode="w") as fd:
-            toml.dump(cfg, fd)
+        with open(_global_config_file, mode="wb") as fd:
+            tomli_w.dump(cfg, fd)
     except OSError:
         warnings.warn("unable to write new config file")
 
