def __getattr__(self, attr: str):
    """Fallback to get a missing method from an ``EffectRequest``."""
    eff_proto = self.effect_protocol()
    if hasattr(eff_proto, attr) and callable(getattr(eff_proto, attr)):
      # This attribute is a protocol method of the effect. This probably means
      # that some layer is trying to access an effect that hasn't been handled.
      def unhandled_effect_stub(*args, **kwargs):
        del args, kwargs
        raise UnhandledEffectError(
            f"Effect method {repr(attr)} was called on a non-handled effect"
            f" request of type {type(self).__name__}! This usually means that"
            " an effectful layer has been called without wrapping that layer"
            " in an effect handler that knows how to interpret the effect."
            " Instances of (subclasses of) EffectRequest must be replaced"
            " before the layer is called."
        )

      return unhandled_effect_stub
    else:
      raise AttributeError(
          f"'{type(self).__name__}' object has no attribute '{attr}'",
          name=attr,
          obj=self,
      )
Fallback to get a missing method from an ``EffectRequest``.
penzai/deprecated/v1/data_effects/effect_base.py