diff --git a/pyproject.toml b/pyproject.toml
index 819895fa8f6cf7f6a4a4adbfbe1e6b1d0e7ca972..6e245635cdb31a26b7b061b96ddbed5611907f5f 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -113,6 +113,8 @@ lines-after-imports = 2
 python_version = "3.8"
 ignore_missing_imports = true
 warn_unused_ignores = true
+# TODO: enable this at some point
+# check_untyped_defs = true
 
 [tool.typos.default]
 extend-ignore-re = [
diff --git a/pytools/__init__.py b/pytools/__init__.py
index 08c3ed1adf549055fb839bb0050c9331c3734668..af4b0fd82d0f62de5ed2c26115b0fce03c1246cc 100644
--- a/pytools/__init__.py
+++ b/pytools/__init__.py
@@ -32,6 +32,7 @@ import sys
 from functools import reduce, wraps
 from sys import intern
 from typing import (
+    TYPE_CHECKING,
     Any,
     Callable,
     ClassVar,
@@ -52,15 +53,21 @@ from typing import (
 )
 
 
-try:
-    from typing import Concatenate, SupportsIndex
-except ImportError:
-    from typing_extensions import Concatenate, SupportsIndex
+if TYPE_CHECKING:
+    # NOTE: mypy seems to be confused by the `try.. except` below when called with
+    #   python -m mypy --python-version 3.8 ...
+    # see https://github.com/python/mypy/issues/14220
+    from typing_extensions import Concatenate, ParamSpec, SupportsIndex
+else:
+    try:
+        from typing import Concatenate, SupportsIndex
+    except ImportError:
+        from typing_extensions import Concatenate, SupportsIndex
 
-try:
-    from typing import ParamSpec
-except ImportError:
-    from typing_extensions import ParamSpec  # type: ignore[assignment]
+    try:
+        from typing import ParamSpec
+    except ImportError:
+        from typing_extensions import ParamSpec  # type: ignore[assignment]
 
 
 # These are deprecated and will go away in 2022.
diff --git a/pytools/convergence.py b/pytools/convergence.py
index aa85c2014f9dfd5367a10d45bfca8f377a0ea295..4ad5d9219bae5822f4ff931977c13f513de85d6f 100644
--- a/pytools/convergence.py
+++ b/pytools/convergence.py
@@ -75,7 +75,7 @@ class EOCRecorder:
             gliding_mean = size
 
         data_points = size - gliding_mean + 1
-        result = np.zeros((data_points, 2), float)
+        result: np.ndarray = np.zeros((data_points, 2), float)
         for i in range(data_points):
             result[i, 0], result[i, 1] = estimate_order_of_convergence(
                 abscissae[i:i+gliding_mean], errors[i:i+gliding_mean])
diff --git a/pytools/graph.py b/pytools/graph.py
index f500805997a8f5593b96f8a699a8fa2cdf3610a1..91f2bffa7a2096d10a46d76b7dbacd22f0b57a4c 100644
--- a/pytools/graph.py
+++ b/pytools/graph.py
@@ -66,6 +66,7 @@ Type Variables Used
 
 from dataclasses import dataclass
 from typing import (
+    TYPE_CHECKING,
     Any,
     Callable,
     Collection,
@@ -83,10 +84,16 @@ from typing import (
 )
 
 
-try:
-    from typing import TypeAlias
-except ImportError:
+if TYPE_CHECKING:
+    # NOTE: mypy seems to be confused by the `try.. except` below when called with
+    #   python -m mypy --python-version 3.8 ...
+    # see https://github.com/python/mypy/issues/14220
     from typing_extensions import TypeAlias
+else:
+    try:
+        from typing import TypeAlias
+    except ImportError:
+        from typing_extensions import TypeAlias
 
 
 NodeT = TypeVar("NodeT", bound=Hashable)
diff --git a/pytools/persistent_dict.py b/pytools/persistent_dict.py
index bd86a0c5c4f370ff682f7da4f198ecd816b3f729..8ba7074f8673a1114c1ce5b25a67faf7e26d7a32 100644
--- a/pytools/persistent_dict.py
+++ b/pytools/persistent_dict.py
@@ -77,6 +77,10 @@ else:
 
 logger = logging.getLogger(__name__)
 
+# NOTE: not always available so they get hardcoded here
+SQLITE_BUSY = getattr(sqlite3, "SQLITE_BUSY", 5)
+SQLITE_CONSTRAINT_PRIMARYKEY = getattr(sqlite3, "SQLITE_CONSTRAINT_PRIMARYKEY", 1555)
+
 __doc__ = """
 Persistent Hashing and Persistent Dictionaries
 ==============================================
@@ -574,7 +578,7 @@ class _PersistentDictBase(Mapping[K, V]):
                 except sqlite3.OperationalError as e:
                     # If the database is busy, retry
                     if (hasattr(e, "sqlite_errorcode")
-                            and not e.sqlite_errorcode == sqlite3.SQLITE_BUSY):
+                        and e.sqlite_errorcode != SQLITE_BUSY):
                         raise
                     if n % 20 == 0:
                         warn(f"PersistentDict: database '{self.filename}' busy, {n} "
@@ -721,7 +725,7 @@ class WriteOncePersistentDict(_PersistentDictBase[K, V]):
                 self._exec_sql("INSERT INTO dict VALUES (?, ?)", (keyhash, v))
             except sqlite3.IntegrityError as e:
                 if hasattr(e, "sqlite_errorcode"):
-                    if e.sqlite_errorcode == sqlite3.SQLITE_CONSTRAINT_PRIMARYKEY:
+                    if e.sqlite_errorcode == SQLITE_CONSTRAINT_PRIMARYKEY:
                         raise ReadOnlyEntryError("WriteOncePersistentDict, "
                                                  "tried overwriting key") from e
                     else:
diff --git a/pytools/test/test_pytools.py b/pytools/test/test_pytools.py
index 07b59a9ce1b2996ee94d791630ac8bb04aaacbdf..c6f6fda482b6a9b4070760b6eb668190e839a9c2 100644
--- a/pytools/test/test_pytools.py
+++ b/pytools/test/test_pytools.py
@@ -497,7 +497,7 @@ def test_obj_array_vectorize(c=1):
 # }}}
 
 
-def test_tag():
+def test_tag() -> None:
     from pytools.tag import (
         NonUniqueTagError,
         Tag,
@@ -552,7 +552,7 @@ def test_tag():
     # a subclass of Tag
     with pytest.raises(TypeError):
         check_tag_uniqueness(frozenset((
-            "I am not a tag", best_in_show_ribbon,
+            "I am not a tag", best_in_show_ribbon,  # type: ignore[arg-type]
             blue_ribbon, red_ribbon)))
 
     # Test that instantiation succeeds if there are multiple instances
@@ -583,7 +583,7 @@ def test_tag():
 
     # Test that tagged() fails if tags are not a FrozenSet of Tags
     with pytest.raises(TypeError):
-        t1.tagged(tags=frozenset((1,)))
+        t1.tagged(tags=frozenset((1,)))  # type: ignore[arg-type]
 
     # Test without_tags() function
     t4 = t2.without_tags(red_ribbon)