Repository: litestar-org/litestar

Issue:
StaticFilesConfig and virtual directories
I'm trying to write a ``FileSystemProtocol`` to load files from the package data using [importlib_resources](https://importlib-resources.readthedocs.io/en/latest/using.html#). But because ``directories`` is defined as ``DirectoryPath``, pydantic checks if the given directories exist in the local filesystem. 

This is not generally true, especially in any kind of virtual filesystem (e.g. a zipped package). I think this condition should be relaxed to support virtual filesystems.

https://github.com/starlite-api/starlite/blob/9bb6dcd57c10a591377cf8e3a537e9292566d5b9/starlite/config/static_files.py#L32


Discussion:
I agree. Do you want to submit a PR?

Resolving patch:
diff --git a/starlite/handlers/base.py b/starlite/handlers/base.py
--- a/starlite/handlers/base.py
+++ b/starlite/handlers/base.py
@@ -22,7 +22,7 @@
     from starlite.di import Provide
     from starlite.params import ParameterKwarg
     from starlite.router import Router
-    from starlite.types import AnyCallable, AsyncAnyCallable, ExceptionHandler
+    from starlite.types import AsyncAnyCallable, ExceptionHandler
     from starlite.types.composite_types import MaybePartial
 
 T = TypeVar("T", bound="BaseRouteHandler")
@@ -34,10 +34,10 @@ class BaseRouteHandler(Generic[T]):
     Serves as a subclass for all route handlers
     """
 
-    fn: Ref[MaybePartial[AnyCallable]]
     signature: Signature
 
     __slots__ = (
+        "_fn",
         "_resolved_dependencies",
         "_resolved_guards",
         "_resolved_layered_parameters",
@@ -45,7 +45,6 @@ class BaseRouteHandler(Generic[T]):
         "_resolved_type_encoders",
         "dependencies",
         "exception_handlers",
-        "fn",
         "guards",
         "middleware",
         "name",
@@ -114,11 +113,25 @@ def __init__(
 
     def __call__(self, fn: AsyncAnyCallable) -> Self:
         """Replace a function with itself."""
-        self.fn = Ref["MaybePartial[AsyncAnyCallable]"](fn)
+        self._fn = Ref["MaybePartial[AsyncAnyCallable]"](fn)
         self.signature = Signature.from_callable(fn)
         self._validate_handler_function()
         return self
 
+    @property
+    def fn(self) -> Ref[MaybePartial[AsyncAnyCallable]]:
+        """Get the handler function.
+
+        Raises:
+            ImproperlyConfiguredException: if handler fn is not set.
+
+        Returns:
+            Handler function
+        """
+        if not hasattr(self, "_fn"):
+            raise ImproperlyConfiguredException("Handler has not decorated a function")
+        return self._fn
+
     @property
     def handler_name(self) -> str:
         """Get the name of the handler function.
@@ -129,9 +142,6 @@ def handler_name(self) -> str:
         Returns:
             Name of the handler function
         """
-        fn = getattr(self, "fn", None)
-        if not fn:
-            raise ImproperlyConfiguredException("cannot access handler name before setting the handler function")
         return get_name(unwrap_partial(self.fn.value))
 
     @property
@@ -279,8 +289,6 @@ def _validate_dependency_is_unique(dependencies: dict[str, Provide], key: str, p
 
     def _validate_handler_function(self) -> None:
         """Validate the route handler function once set by inspecting its return annotations."""
-        if not getattr(self, "fn", None):
-            raise ImproperlyConfiguredException("Cannot call _validate_handler_function without first setting self.fn")
 
     def __str__(self) -> str:
         """Return a unique identifier for the route handler.
@@ -288,6 +296,7 @@ def __str__(self) -> str:
         Returns:
             A string
         """
+        target: type[AsyncAnyCallable] | AsyncAnyCallable
         target = unwrap_partial(self.fn.value)
         if not hasattr(target, "__qualname__"):
             target = type(target)


Test patch:
diff --git a/tests/handlers/base/test_validations.py b/tests/handlers/base/test_validations.py
--- a/tests/handlers/base/test_validations.py
+++ b/tests/handlers/base/test_validations.py
@@ -8,4 +8,4 @@ def test_raise_no_fn_validation() -> None:
     handler = BaseRouteHandler[BaseRouteHandler](path="/")
 
     with pytest.raises(ImproperlyConfiguredException):
-        handler._validate_handler_function()
+        handler.fn