diff --git a/arraycontext/context.py b/arraycontext/context.py
index a4fbbdc576c1693d4e935a8c589238fe38ca83e4..38c52ddb357692583791effe00460604fe18f352 100644
--- a/arraycontext/context.py
+++ b/arraycontext/context.py
@@ -583,4 +583,8 @@ def tag_axes(
 
 # }}}
 
+
+class UntransformedCodeWarning(UserWarning):
+    pass
+
 # vim: foldmethod=marker
diff --git a/arraycontext/impl/pyopencl/__init__.py b/arraycontext/impl/pyopencl/__init__.py
index e2deea52869e9e12bff5ecd8409afcfd1bb81112..990a4223c5ea1bc164a7524f48f316c53cd142e4 100644
--- a/arraycontext/impl/pyopencl/__init__.py
+++ b/arraycontext/impl/pyopencl/__init__.py
@@ -1,4 +1,7 @@
-"""
+from __future__ import annotations
+
+
+__doc__ = """
 .. currentmodule:: arraycontext
 .. autoclass:: PyOpenCLArrayContext
 .. automodule:: arraycontext.impl.pyopencl.taggable_cl_array
@@ -36,7 +39,13 @@ import numpy as np
 from pytools.tag import ToTagSetConvertible
 
 from arraycontext.container.traversal import rec_map_array_container, with_array_context
-from arraycontext.context import Array, ArrayContext, ArrayOrContainer, ScalarLike
+from arraycontext.context import (
+    Array,
+    ArrayContext,
+    ArrayOrContainer,
+    ScalarLike,
+    UntransformedCodeWarning,
+)
 
 
 if TYPE_CHECKING:
@@ -72,8 +81,8 @@ class PyOpenCLArrayContext(ArrayContext):
     """
 
     def __init__(self,
-            queue: "pyopencl.CommandQueue",
-            allocator: Optional["pyopencl.tools.AllocatorBase"] = None,
+            queue: pyopencl.CommandQueue,
+            allocator: Optional[pyopencl.tools.AllocatorBase] = None,
             wait_event_queue_length: Optional[int] = None,
             force_device_scalars: bool = False) -> None:
         r"""
@@ -301,16 +310,19 @@ class PyOpenCLArrayContext(ArrayContext):
 
     # {{{ transform_loopy_program
 
-    def transform_loopy_program(self, t_unit):
+    def transform_loopy_program(self, t_unit: lp.TranslationUnit) -> lp.TranslationUnit:
         from warnings import warn
-        warn("Using arraycontext.PyOpenCLArrayContext.transform_loopy_program "
-                "to transform a program. This is deprecated and will stop working "
-                "in 2022. Instead, subclass PyOpenCLArrayContext and implement "
-                "the specific logic required to transform the program for your "
-                "package or application. Check higher-level packages "
+        warn("Using the base "
+                f"{type(self).__name__}.transform_loopy_program "
+                "to transform a translation unit. "
+                "This is largely a no-op and unlikely to result in fast generated "
+                "code."
+                f"Instead, subclass {type(self).__name__} and implement "
+                "the specific transform logic required to transform the program "
+                "for your package or application. Check higher-level packages "
                 "(e.g. meshmode), which may already have subclasses you may want "
                 "to build on.",
-                DeprecationWarning, stacklevel=2)
+                UntransformedCodeWarning, stacklevel=2)
 
         # accommodate loopy with and without kernel callables
 
diff --git a/arraycontext/impl/pytato/__init__.py b/arraycontext/impl/pytato/__init__.py
index c030de7188b484d69c00e8fcf29bf9fc8668f694..8737e5fae5b003d5de119c7e7a22e4d005aac478 100644
--- a/arraycontext/impl/pytato/__init__.py
+++ b/arraycontext/impl/pytato/__init__.py
@@ -1,4 +1,7 @@
-"""
+from __future__ import annotations
+
+
+__doc__ = """
 .. currentmodule:: arraycontext
 
 A :mod:`pytato`-based array context defers the evaluation of an array until its
@@ -62,11 +65,18 @@ from pytools import memoize_method
 from pytools.tag import Tag, ToTagSetConvertible, normalize_tags
 
 from arraycontext.container.traversal import rec_map_array_container, with_array_context
-from arraycontext.context import Array, ArrayContext, ArrayOrContainer, ScalarLike
+from arraycontext.context import (
+    Array,
+    ArrayContext,
+    ArrayOrContainer,
+    ScalarLike,
+    UntransformedCodeWarning,
+)
 from arraycontext.metadata import NameHint
 
 
 if TYPE_CHECKING:
+    import loopy as lp
     import pyopencl as cl
     import pytato
 
@@ -137,7 +147,6 @@ class _BasePytatoArrayContext(ArrayContext, abc.ABC):
         """
         super().__init__()
 
-        import loopy as lp
         import pytato as pt
         self._freeze_prg_cache: Dict[pt.DictOfNamedArrays, lp.TranslationUnit] = {}
         self._dag_transform_cache: Dict[
@@ -180,8 +189,8 @@ class _BasePytatoArrayContext(ArrayContext, abc.ABC):
 
     # {{{ compilation
 
-    def transform_dag(self, dag: "pytato.DictOfNamedArrays"
-                      ) -> "pytato.DictOfNamedArrays":
+    def transform_dag(self, dag: pytato.DictOfNamedArrays
+                      ) -> pytato.DictOfNamedArrays:
         """
         Returns a transformed version of *dag*. Sub-classes are supposed to
         override this method to implement context-specific transformations on
@@ -194,10 +203,22 @@ class _BasePytatoArrayContext(ArrayContext, abc.ABC):
         """
         return dag
 
-    def transform_loopy_program(self, t_unit):
-        raise ValueError(
-            f"{type(self).__name__} does not implement transform_loopy_program. "
-            "Sub-classes are supposed to implement it.")
+    def transform_loopy_program(self, t_unit: lp.TranslationUnit) -> lp.TranslationUnit:
+        from warnings import warn
+        warn("Using the base "
+                f"{type(self).__name__}.transform_loopy_program "
+                "to transform a translation unit. "
+                "This is a no-op and will result in unoptimized C code for"
+                "the requested optimization, all in a single statement."
+                "This will work, but is unlikely to be performatn."
+                f"Instead, subclass {type(self).__name__} and implement "
+                "the specific transform logic required to transform the program "
+                "for your package or application. Check higher-level packages "
+                "(e.g. meshmode), which may already have subclasses you may want "
+                "to build on.",
+                UntransformedCodeWarning, stacklevel=2)
+
+        return t_unit
 
     @abc.abstractmethod
     def einsum(self, spec, *args, arg_names=None, tagged=()):
@@ -250,7 +271,7 @@ class PytatoPyOpenCLArrayContext(_BasePytatoArrayContext):
     .. automethod:: compile
     """
     def __init__(
-            self, queue: "cl.CommandQueue", allocator=None, *,
+            self, queue: cl.CommandQueue, allocator=None, *,
             use_memory_pool: Optional[bool] = None,
             compile_trace_callback: Optional[Callable[[Any, str, Any], None]] = None,
 
@@ -642,8 +663,8 @@ class PytatoPyOpenCLArrayContext(_BasePytatoArrayContext):
         from .compile import LazilyPyOpenCLCompilingFunctionCaller
         return LazilyPyOpenCLCompilingFunctionCaller(self, f)
 
-    def transform_dag(self, dag: "pytato.DictOfNamedArrays"
-                      ) -> "pytato.DictOfNamedArrays":
+    def transform_dag(self, dag: pytato.DictOfNamedArrays
+                      ) -> pytato.DictOfNamedArrays:
         import pytato as pt
         dag = pt.transform.materialize_with_mpms(dag)
         return dag
diff --git a/arraycontext/pytest.py b/arraycontext/pytest.py
index d3d719e515c573ae618d5005c86b7feca6c0c160..8a1e027416cb7d7b509069b42cd1fd9009550ef1 100644
--- a/arraycontext/pytest.py
+++ b/arraycontext/pytest.py
@@ -144,7 +144,6 @@ class _PytestPytatoPyOpenCLArrayContextFactory(PytestPyOpenCLArrayContextFactory
     def actx_class(self):
         from arraycontext import PytatoPyOpenCLArrayContext
         actx_cls = PytatoPyOpenCLArrayContext
-        actx_cls.transform_loopy_program = lambda s, t_unit: t_unit
         return actx_cls
 
     def __call__(self):