Skip to content

bug: UnboundLocalError in Litestar provider _BeforeAfterFilterProvider due to MyPyC compiler bug #475

@cofin

Description

@cofin

Describe the bug

When importing or initializing any Litestar Controller utilizing create_filter_dependencies() or _build_before_after_provider on SQLSpec 0.47.0, the module crashes with:

UnboundLocalError: local variable "before_annotation" referenced before assignment

This regression occurs inside sqlspec/extensions/litestar/providers.py during instantiation of _BeforeAfterFilterProvider.

Cause / Analysis

The regression is caused by an optimization pass in MyPyC when compiling _BeforeAfterFilterProvider.__init__.

Under a pure-python fallback (e.g. removing the compiled .so module), _BeforeAfterFilterProvider instantiates perfectly. However, once compiled with MyPyC, the presence of two local variables ending in the same suffix _annotation (before_annotation and after_annotation) inside the constructor triggers a compiler/optimizer bug that loses local variable tracking, raising the UnboundLocalError at runtime.

Solution / Workaround

Renaming the variables to avoid the suffix clash resolves the MyPyC compilation bug completely:

-        before_annotation = Annotated[DTorNone, QueryParameter(name=before_alias, required=False)]
-        after_annotation = Annotated[DTorNone, QueryParameter(name=after_alias, required=False)]
+        before_ann = Annotated[DTorNone, QueryParameter(name=before_alias, required=False)]
+        after_ann = Annotated[DTorNone, QueryParameter(name=after_alias, required=False)]
         self.signature = inspect.Signature(
             parameters=[
                 inspect.Parameter(
-                    self.before_param, kind=inspect.Parameter.KEYWORD_ONLY, default=None, annotation=before_annotation
+                    self.before_param, kind=inspect.Parameter.KEYWORD_ONLY, default=None, annotation=before_ann
                 ),
                 inspect.Parameter(
-                    self.after_param, kind=inspect.Parameter.KEYWORD_ONLY, default=None, annotation=after_annotation
+                    self.after_param, kind=inspect.Parameter.KEYWORD_ONLY, default=None, annotation=after_ann
                 ),
             ],
             return_annotation=BeforeAfterFilter,
         )
         self.annotations = {
-            self.before_param: before_annotation,
-            self.after_param: after_annotation,
+            self.before_param: before_ann,
+            self.after_param: after_ann,
             "return": BeforeAfterFilter,
         }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions