1
0
Эх сурвалжийг харах

enable N rules for naming conventions (#4666)

* enable N rules for naming conventions

* fix pyi

* address comments

* remove unneeded code
Thomas Brandého 3 сар өмнө
parent
commit
7f1aee6dc8

+ 1 - 1
benchmarks/benchmark_package_size.py

@@ -21,7 +21,7 @@ def get_package_size(venv_path: Path, os_name):
         ValueError: when venv does not exist or python version is None.
     """
     python_version = get_python_version(venv_path, os_name)
-    print("Python version:", python_version)  # noqa: T201
+    print("Python version:", python_version)
     if python_version is None:
         raise ValueError("Error: Failed to determine Python version.")
 

+ 6 - 3
pyproject.toml

@@ -85,15 +85,18 @@ build-backend = "poetry.core.masonry.api"
 target-version = "py39"
 output-format = "concise"
 lint.isort.split-on-trailing-comma = false
-lint.select = ["B", "C4", "D", "E", "ERA", "F", "FURB", "I", "PERF", "PTH", "RUF", "SIM", "T", "TRY", "W"]
+lint.select = ["B", "C4", "D", "E", "ERA", "F", "FURB", "I", "N", "PERF", "PTH", "RUF", "SIM", "T", "TRY", "W"]
 lint.ignore = ["B008", "D205", "E501", "F403", "SIM115", "RUF006", "RUF012", "TRY0"]
 lint.pydocstyle.convention = "google"
 
 [tool.ruff.lint.per-file-ignores]
 "__init__.py" = ["F401"]
-"tests/*.py" = ["D100", "D103", "D104", "B018", "PERF", "T"]
+"tests/*.py" = ["D100", "D103", "D104", "B018", "PERF", "T", "N"]
+"benchmarks/*.py" = ["D100", "D103", "D104", "B018", "PERF", "T", "N"]
 "reflex/.templates/*.py" = ["D100", "D103", "D104"]
-"*.pyi" = ["D301", "D415", "D417", "D418", "E742"]
+"*.pyi" = ["D301", "D415", "D417", "D418", "E742", "N"]
+"pyi_generator.py" = ["N802"]
+"reflex/constants/*.py" = ["N"]
 "*/blank.py" = ["I001"]
 
 [tool.pytest.ini_options]

+ 4 - 4
reflex/app.py

@@ -1197,11 +1197,11 @@ class App(MiddlewareMixin, LifespanMixin):
             ValueError: If the custom exception handlers are invalid.
 
         """
-        FRONTEND_ARG_SPEC = {
+        frontend_arg_spec = {
             "exception": Exception,
         }
 
-        BACKEND_ARG_SPEC = {
+        backend_arg_spec = {
             "exception": Exception,
         }
 
@@ -1209,8 +1209,8 @@ class App(MiddlewareMixin, LifespanMixin):
             ["frontend", "backend"],
             [self.frontend_exception_handler, self.backend_exception_handler],
             [
-                FRONTEND_ARG_SPEC,
-                BACKEND_ARG_SPEC,
+                frontend_arg_spec,
+                backend_arg_spec,
             ],
         ):
             if hasattr(handler_fn, "__name__"):

+ 3 - 3
reflex/app_mixins/lifespan.py

@@ -12,7 +12,7 @@ from typing import Callable, Coroutine, Set, Union
 from fastapi import FastAPI
 
 from reflex.utils import console
-from reflex.utils.exceptions import InvalidLifespanTaskType
+from reflex.utils.exceptions import InvalidLifespanTaskTypeError
 
 from .mixin import AppMixin
 
@@ -64,10 +64,10 @@ class LifespanMixin(AppMixin):
             task_kwargs: The kwargs of the task.
 
         Raises:
-            InvalidLifespanTaskType: If the task is a generator function.
+            InvalidLifespanTaskTypeError: If the task is a generator function.
         """
         if inspect.isgeneratorfunction(task) or inspect.isasyncgenfunction(task):
-            raise InvalidLifespanTaskType(
+            raise InvalidLifespanTaskTypeError(
                 f"Task {task.__name__} of type generator must be decorated with contextlib.asynccontextmanager."
             )
 

+ 1 - 1
reflex/components/core/html.py

@@ -14,7 +14,7 @@ class Html(Div):
     """
 
     # The HTML to render.
-    dangerouslySetInnerHTML: Var[Dict[str, str]]
+    dangerouslySetInnerHTML: Var[Dict[str, str]]  # noqa: N815
 
     @classmethod
     def create(cls, *children, **props):

+ 5 - 3
reflex/components/dynamic.py

@@ -4,7 +4,7 @@ from typing import TYPE_CHECKING, Union
 
 from reflex import constants
 from reflex.utils import imports
-from reflex.utils.exceptions import DynamicComponentMissingLibrary
+from reflex.utils.exceptions import DynamicComponentMissingLibraryError
 from reflex.utils.format import format_library_name
 from reflex.utils.serializers import serializer
 from reflex.vars import Var, get_unique_variable_name
@@ -36,13 +36,15 @@ def bundle_library(component: Union["Component", str]):
         component: The component to bundle the library with.
 
     Raises:
-        DynamicComponentMissingLibrary: Raised when a dynamic component is missing a library.
+        DynamicComponentMissingLibraryError: Raised when a dynamic component is missing a library.
     """
     if isinstance(component, str):
         bundled_libraries.add(component)
         return
     if component.library is None:
-        raise DynamicComponentMissingLibrary("Component must have a library to bundle.")
+        raise DynamicComponentMissingLibraryError(
+            "Component must have a library to bundle."
+        )
     bundled_libraries.add(format_library_name(component.library))
 
 

+ 13 - 3
reflex/components/next/image.py

@@ -3,11 +3,13 @@
 from typing import Any, Literal, Optional, Union
 
 from reflex.event import EventHandler, no_args_event_spec
-from reflex.utils import types
+from reflex.utils import console, types
 from reflex.vars.base import Var
 
 from .base import NextComponent
 
+DEFAULT_W_H = "100%"
+
 
 class Image(NextComponent):
     """Display an image."""
@@ -53,7 +55,7 @@ class Image(NextComponent):
     loading: Var[Literal["lazy", "eager"]]
 
     # A Data URL to be used as a placeholder image before the src image successfully loads. Only takes effect when combined with placeholder="blur".
-    blurDataURL: Var[str]
+    blur_data_url: Var[str]
 
     # Fires when the image has loaded.
     on_load: EventHandler[no_args_event_spec]
@@ -80,8 +82,16 @@ class Image(NextComponent):
         Returns:
             _type_: _description_
         """
+        if "blurDataURL" in props:
+            console.deprecate(
+                feature_name="blurDataURL",
+                reason="Use blur_data_url instead",
+                deprecation_version="0.7.0",
+                removal_version="0.8.0",
+            )
+            props["blur_data_url"] = props.pop("blurDataURL")
+
         style = props.get("style", {})
-        DEFAULT_W_H = "100%"
 
         def check_prop_type(prop_name, prop_value):
             if types.check_prop_in_allowed_types(prop_value, allowed_types=[int]):

+ 4 - 2
reflex/components/next/image.pyi

@@ -11,6 +11,8 @@ from reflex.vars.base import Var
 
 from .base import NextComponent
 
+DEFAULT_W_H = "100%"
+
 class Image(NextComponent):
     @overload
     @classmethod
@@ -30,7 +32,7 @@ class Image(NextComponent):
         loading: Optional[
             Union[Literal["eager", "lazy"], Var[Literal["eager", "lazy"]]]
         ] = None,
-        blurDataURL: Optional[Union[Var[str], str]] = None,
+        blur_data_url: Optional[Union[Var[str], str]] = None,
         style: Optional[Style] = None,
         key: Optional[Any] = None,
         id: Optional[Any] = None,
@@ -71,7 +73,7 @@ class Image(NextComponent):
             priority: When true, the image will be considered high priority and preload. Lazy loading is automatically disabled for images using priority.
             placeholder: A placeholder to use while the image is loading. Possible values are blur, empty, or data:image/.... Defaults to empty.
             loading: The loading behavior of the image. Defaults to lazy. Can hurt performance, recommended to use `priority` instead.
-            blurDataURL: A Data URL to be used as a placeholder image before the src image successfully loads. Only takes effect when combined with placeholder="blur".
+            blur_data_url: A Data URL to be used as a placeholder image before the src image successfully loads. Only takes effect when combined with placeholder="blur".
             on_load: Fires when the image has loaded.
             on_error: Fires when the image has an error.
             style: The style of the component.

+ 4 - 4
reflex/components/radix/primitives/accordion.py

@@ -485,11 +485,11 @@ to {
         Returns:
             The style of the component.
         """
-        slideDown = LiteralVar.create(
+        slide_down = LiteralVar.create(
             "${slideDown} var(--animation-duration) var(--animation-easing)",
         )
 
-        slideUp = LiteralVar.create(
+        slide_up = LiteralVar.create(
             "${slideUp} var(--animation-duration) var(--animation-easing)",
         )
 
@@ -503,8 +503,8 @@ to {
                 "display": "block",
                 "height": "var(--space-3)",
             },
-            "&[data-state='open']": {"animation": slideDown},
-            "&[data-state='closed']": {"animation": slideUp},
+            "&[data-state='open']": {"animation": slide_down},
+            "&[data-state='closed']": {"animation": slide_up},
             _inherited_variant_selector("classic"): {
                 "color": "var(--accent-contrast)",
             },

+ 1 - 1
reflex/components/radix/primitives/drawer.py

@@ -66,7 +66,7 @@ class DrawerRoot(DrawerComponent):
     scroll_lock_timeout: Var[int]
 
     # When `True`, it prevents scroll restoration. Defaults to `True`.
-    preventScrollRestoration: Var[bool]
+    prevent_scroll_restoration: Var[bool]
 
     # Enable background scaling, it requires container element with `vaul-drawer-wrapper` attribute to scale its background.
     should_scale_background: Var[bool]

+ 4 - 4
reflex/components/radix/primitives/drawer.pyi

@@ -81,7 +81,7 @@ class DrawerRoot(DrawerComponent):
         snap_points: Optional[List[Union[float, str]]] = None,
         fade_from_index: Optional[Union[Var[int], int]] = None,
         scroll_lock_timeout: Optional[Union[Var[int], int]] = None,
-        preventScrollRestoration: Optional[Union[Var[bool], bool]] = None,
+        prevent_scroll_restoration: Optional[Union[Var[bool], bool]] = None,
         should_scale_background: Optional[Union[Var[bool], bool]] = None,
         close_threshold: Optional[Union[Var[float], float]] = None,
         as_child: Optional[Union[Var[bool], bool]] = None,
@@ -129,7 +129,7 @@ class DrawerRoot(DrawerComponent):
             snap_points: Array of numbers from 0 to 100 that corresponds to % of the screen a given snap point should take up. Should go from least visible. Also Accept px values, which doesn't take screen height into account.
             fade_from_index: Index of a snapPoint from which the overlay fade should be applied. Defaults to the last snap point.
             scroll_lock_timeout: Duration for which the drawer is not draggable after scrolling content inside of the drawer. Defaults to 500ms
-            preventScrollRestoration: When `True`, it prevents scroll restoration. Defaults to `True`.
+            prevent_scroll_restoration: When `True`, it prevents scroll restoration. Defaults to `True`.
             should_scale_background: Enable background scaling, it requires container element with `vaul-drawer-wrapper` attribute to scale its background.
             close_threshold: Number between 0 and 1 that determines when the drawer should be closed.
             as_child: Change the default rendered element for the one passed as a child.
@@ -567,7 +567,7 @@ class Drawer(ComponentNamespace):
         snap_points: Optional[List[Union[float, str]]] = None,
         fade_from_index: Optional[Union[Var[int], int]] = None,
         scroll_lock_timeout: Optional[Union[Var[int], int]] = None,
-        preventScrollRestoration: Optional[Union[Var[bool], bool]] = None,
+        prevent_scroll_restoration: Optional[Union[Var[bool], bool]] = None,
         should_scale_background: Optional[Union[Var[bool], bool]] = None,
         close_threshold: Optional[Union[Var[float], float]] = None,
         as_child: Optional[Union[Var[bool], bool]] = None,
@@ -615,7 +615,7 @@ class Drawer(ComponentNamespace):
             snap_points: Array of numbers from 0 to 100 that corresponds to % of the screen a given snap point should take up. Should go from least visible. Also Accept px values, which doesn't take screen height into account.
             fade_from_index: Index of a snapPoint from which the overlay fade should be applied. Defaults to the last snap point.
             scroll_lock_timeout: Duration for which the drawer is not draggable after scrolling content inside of the drawer. Defaults to 500ms
-            preventScrollRestoration: When `True`, it prevents scroll restoration. Defaults to `True`.
+            prevent_scroll_restoration: When `True`, it prevents scroll restoration. Defaults to `True`.
             should_scale_background: Enable background scaling, it requires container element with `vaul-drawer-wrapper` attribute to scale its background.
             close_threshold: Number between 0 and 1 that determines when the drawer should be closed.
             as_child: Change the default rendered element for the one passed as a child.

+ 2 - 2
reflex/components/radix/themes/components/icon_button.py

@@ -22,6 +22,8 @@ from ..base import (
 
 LiteralButtonSize = Literal["1", "2", "3", "4"]
 
+RADIX_TO_LUCIDE_SIZE = {"1": 12, "2": 24, "3": 36, "4": 48}
+
 
 class IconButton(elements.Button, RadixLoadingProp, RadixThemesComponent):
     """A button designed specifically for usage with a single icon."""
@@ -72,8 +74,6 @@ class IconButton(elements.Button, RadixLoadingProp, RadixThemesComponent):
                 "IconButton requires a child icon. Pass a string as the first child or a rx.icon."
             )
         if "size" in props:
-            RADIX_TO_LUCIDE_SIZE = {"1": 12, "2": 24, "3": 36, "4": 48}
-
             if isinstance(props["size"], str):
                 children[0].size = RADIX_TO_LUCIDE_SIZE[props["size"]]
             else:

+ 1 - 0
reflex/components/radix/themes/components/icon_button.pyi

@@ -14,6 +14,7 @@ from reflex.vars.base import Var
 from ..base import RadixLoadingProp, RadixThemesComponent
 
 LiteralButtonSize = Literal["1", "2", "3", "4"]
+RADIX_TO_LUCIDE_SIZE = {"1": 12, "2": 24, "3": 36, "4": 48}
 
 class IconButton(elements.Button, RadixLoadingProp, RadixThemesComponent):
     @overload

+ 3 - 1
reflex/components/radix/themes/components/tooltip.py

@@ -28,6 +28,9 @@ LiteralStickyType = Literal[
 ]
 
 
+ARIA_LABEL_KEY = "aria_label"
+
+
 # The Tooltip inherits props from the Tooltip.Root, Tooltip.Portal, Tooltip.Content
 class Tooltip(RadixThemesComponent):
     """Floating element that provides a control with contextual information via pointer or focus."""
@@ -104,7 +107,6 @@ class Tooltip(RadixThemesComponent):
         Returns:
             The created component.
         """
-        ARIA_LABEL_KEY = "aria_label"
         if props.get(ARIA_LABEL_KEY) is not None:
             props[format.to_kebab_case(ARIA_LABEL_KEY)] = props.pop(ARIA_LABEL_KEY)
 

+ 1 - 0
reflex/components/radix/themes/components/tooltip.pyi

@@ -14,6 +14,7 @@ from ..base import RadixThemesComponent
 LiteralSideType = Literal["top", "right", "bottom", "left"]
 LiteralAlignType = Literal["start", "center", "end"]
 LiteralStickyType = Literal["partial", "always"]
+ARIA_LABEL_KEY = "aria_label"
 
 class Tooltip(RadixThemesComponent):
     @overload

+ 1 - 1
reflex/components/recharts/polar.py

@@ -73,7 +73,7 @@ class Pie(Recharts):
     data: Var[List[Dict[str, Any]]]
 
     # Valid children components
-    _valid_children: List[str] = ["Cell", "LabelList"]
+    _valid_children: List[str] = ["Cell", "LabelList", "Bare"]
 
     # Stoke color. Default: rx.color("accent", 9)
     stroke: Var[Union[str, Color]] = LiteralVar.create(Color("accent", 9))

+ 2 - 2
reflex/components/recharts/recharts.py

@@ -1,6 +1,6 @@
 """A component that wraps a recharts lib."""
 
-from typing import Dict, Literal
+from typing import Literal
 
 from reflex.components.component import Component, MemoizationLeaf, NoSSRComponent
 
@@ -10,7 +10,7 @@ class Recharts(Component):
 
     library = "recharts@2.15.0"
 
-    def _get_style(self) -> Dict:
+    def _get_style(self) -> dict:
         return {"wrapperStyle": self.style}
 
 

+ 4 - 4
reflex/config.py

@@ -390,7 +390,7 @@ class EnvVar(Generic[T]):
             os.environ[self.name] = str(value)
 
 
-class env_var:  # type: ignore
+class env_var:  # type: ignore # noqa: N801
     """Descriptor for environment variables."""
 
     name: str
@@ -823,16 +823,16 @@ class Config(Base):
         if "api_url" not in self._non_default_attributes:
             # If running in Github Codespaces, override API_URL
             codespace_name = os.getenv("CODESPACE_NAME")
-            GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN = os.getenv(
+            github_codespaces_port_forwarding_domain = os.getenv(
                 "GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN"
             )
             # If running on Replit.com interactively, override API_URL to ensure we maintain the backend_port
             replit_dev_domain = os.getenv("REPLIT_DEV_DOMAIN")
             backend_port = kwargs.get("backend_port", self.backend_port)
-            if codespace_name and GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN:
+            if codespace_name and github_codespaces_port_forwarding_domain:
                 self.api_url = (
                     f"https://{codespace_name}-{kwargs.get('backend_port', self.backend_port)}"
-                    f".{GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN}"
+                    f".{github_codespaces_port_forwarding_domain}"
                 )
             elif replit_dev_domain and backend_port:
                 self.api_url = f"https://{replit_dev_domain}:{backend_port}"

+ 4 - 4
reflex/event.py

@@ -534,10 +534,10 @@ class JavasciptKeyboardEvent:
     """Interface for a Javascript KeyboardEvent https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent."""
 
     key: str = ""
-    altKey: bool = False
-    ctrlKey: bool = False
-    metaKey: bool = False
-    shiftKey: bool = False
+    altKey: bool = False  # noqa: N815
+    ctrlKey: bool = False  # noqa: N815
+    metaKey: bool = False  # noqa: N815
+    shiftKey: bool = False  # noqa: N815
 
 
 def input_event(e: Var[JavascriptInputEvent]) -> Tuple[Var[str]]:

+ 4 - 4
reflex/experimental/hooks.py

@@ -26,7 +26,7 @@ def const(name, value) -> Var:
     return Var(_js_expr=f"const {name} = {value}")
 
 
-def useCallback(func, deps) -> Var:
+def useCallback(func, deps) -> Var:  # noqa: N802
     """Create a useCallback hook with a function and dependencies.
 
     Args:
@@ -42,7 +42,7 @@ def useCallback(func, deps) -> Var:
     )
 
 
-def useContext(context) -> Var:
+def useContext(context) -> Var:  # noqa: N802
     """Create a useContext hook with a context.
 
     Args:
@@ -57,7 +57,7 @@ def useContext(context) -> Var:
     )
 
 
-def useRef(default) -> Var:
+def useRef(default) -> Var:  # noqa: N802
     """Create a useRef hook with a default value.
 
     Args:
@@ -72,7 +72,7 @@ def useRef(default) -> Var:
     )
 
 
-def useState(var_name, default=None) -> Var:
+def useState(var_name, default=None) -> Var:  # noqa: N802
     """Create a useState hook with a variable name and setter name.
 
     Args:

+ 1 - 1
reflex/experimental/layout.pyi

@@ -109,7 +109,7 @@ class DrawerSidebar(DrawerRoot):
         snap_points: Optional[List[Union[float, str]]] = None,
         fade_from_index: Optional[Union[Var[int], int]] = None,
         scroll_lock_timeout: Optional[Union[Var[int], int]] = None,
-        preventScrollRestoration: Optional[Union[Var[bool], bool]] = None,
+        prevent_scroll_restoration: Optional[Union[Var[bool], bool]] = None,
         should_scale_background: Optional[Union[Var[bool], bool]] = None,
         close_threshold: Optional[Union[Var[float], float]] = None,
         as_child: Optional[Union[Var[bool], bool]] = None,

+ 23 - 24
reflex/state.py

@@ -93,14 +93,14 @@ from reflex.event import (
 )
 from reflex.utils import console, format, path_ops, prerequisites, types
 from reflex.utils.exceptions import (
-    ComputedVarShadowsBaseVars,
-    ComputedVarShadowsStateVar,
-    DynamicComponentInvalidSignature,
-    DynamicRouteArgShadowsStateVar,
-    EventHandlerShadowsBuiltInStateMethod,
+    ComputedVarShadowsBaseVarsError,
+    ComputedVarShadowsStateVarError,
+    DynamicComponentInvalidSignatureError,
+    DynamicRouteArgShadowsStateVarError,
+    EventHandlerShadowsBuiltInStateMethodError,
     ImmutableStateError,
     InvalidLockWarningThresholdError,
-    InvalidStateManagerMode,
+    InvalidStateManagerModeError,
     LockExpiredError,
     ReflexRuntimeError,
     SetUndefinedStateVarError,
@@ -815,7 +815,7 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
         """Check for shadow methods and raise error if any.
 
         Raises:
-            EventHandlerShadowsBuiltInStateMethod: When an event handler shadows an inbuilt state method.
+            EventHandlerShadowsBuiltInStateMethodError: When an event handler shadows an inbuilt state method.
         """
         overridden_methods = set()
         state_base_functions = cls._get_base_functions()
@@ -829,7 +829,7 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
                 overridden_methods.add(method.__name__)
 
         for method_name in overridden_methods:
-            raise EventHandlerShadowsBuiltInStateMethod(
+            raise EventHandlerShadowsBuiltInStateMethodError(
                 f"The event handler name `{method_name}` shadows a builtin State method; use a different name instead"
             )
 
@@ -838,11 +838,11 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
         """Check for shadow base vars and raise error if any.
 
         Raises:
-            ComputedVarShadowsBaseVars: When a computed var shadows a base var.
+            ComputedVarShadowsBaseVarsError: When a computed var shadows a base var.
         """
         for computed_var_ in cls._get_computed_vars():
             if computed_var_._js_expr in cls.__annotations__:
-                raise ComputedVarShadowsBaseVars(
+                raise ComputedVarShadowsBaseVarsError(
                     f"The computed var name `{computed_var_._js_expr}` shadows a base var in {cls.__module__}.{cls.__name__}; use a different name instead"
                 )
 
@@ -851,14 +851,14 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
         """Check for shadow computed vars and raise error if any.
 
         Raises:
-            ComputedVarShadowsStateVar: When a computed var shadows another.
+            ComputedVarShadowsStateVarError: When a computed var shadows another.
         """
         for name, cv in cls.__dict__.items():
             if not is_computed_var(cv):
                 continue
             name = cv._js_expr
             if name in cls.inherited_vars or name in cls.inherited_backend_vars:
-                raise ComputedVarShadowsStateVar(
+                raise ComputedVarShadowsStateVarError(
                     f"The computed var name `{cv._js_expr}` shadows a var in {cls.__module__}.{cls.__name__}; use a different name instead"
                 )
 
@@ -1218,14 +1218,14 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
             args: a dict of args
 
         Raises:
-            DynamicRouteArgShadowsStateVar: If a dynamic arg is shadowing an existing var.
+            DynamicRouteArgShadowsStateVarError: If a dynamic arg is shadowing an existing var.
         """
         for arg in args:
             if (
                 arg in cls.computed_vars
                 and not isinstance(cls.computed_vars[arg], DynamicRouteVar)
             ) or arg in cls.base_vars:
-                raise DynamicRouteArgShadowsStateVar(
+                raise DynamicRouteArgShadowsStateVarError(
                     f"Dynamic route arg '{arg}' is shadowing an existing var in {cls.__module__}.{cls.__name__}"
                 )
         for substate in cls.get_substates():
@@ -2353,8 +2353,7 @@ def dynamic(func: Callable[[T], Component]):
         The dynamically generated component.
 
     Raises:
-        DynamicComponentInvalidSignature: If the function does not have exactly one parameter.
-        DynamicComponentInvalidSignature: If the function does not have a type hint for the state class.
+        DynamicComponentInvalidSignatureError: If the function does not have exactly one parameter or a type hint for the state class.
     """
     number_of_parameters = len(inspect.signature(func).parameters)
 
@@ -2366,12 +2365,12 @@ def dynamic(func: Callable[[T], Component]):
     values = list(func_signature.values())
 
     if number_of_parameters != 1:
-        raise DynamicComponentInvalidSignature(
+        raise DynamicComponentInvalidSignatureError(
             "The function must have exactly one parameter, which is the state class."
         )
 
     if len(values) != 1:
-        raise DynamicComponentInvalidSignature(
+        raise DynamicComponentInvalidSignatureError(
             "You must provide a type hint for the state class in the function."
         )
 
@@ -2875,7 +2874,7 @@ class StateManager(Base, ABC):
             state: The state class to use.
 
         Raises:
-            InvalidStateManagerMode: If the state manager mode is invalid.
+            InvalidStateManagerModeError: If the state manager mode is invalid.
 
         Returns:
             The state manager (either disk, memory or redis).
@@ -2898,7 +2897,7 @@ class StateManager(Base, ABC):
                     lock_expiration=config.redis_lock_expiration,
                     lock_warning_threshold=config.redis_lock_warning_threshold,
                 )
-        raise InvalidStateManagerMode(
+        raise InvalidStateManagerModeError(
             f"Expected one of: DISK, MEMORY, REDIS, got {config.state_manager_mode}"
         )
 
@@ -4056,10 +4055,10 @@ def serialize_mutable_proxy(mp: MutableProxy):
     return mp.__wrapped__
 
 
-_orig_json_JSONEncoder_default = json.JSONEncoder.default
+_orig_json_encoder_default = json.JSONEncoder.default
 
 
-def _json_JSONEncoder_default_wrapper(self: json.JSONEncoder, o: Any) -> Any:
+def _json_encoder_default_wrapper(self: json.JSONEncoder, o: Any) -> Any:
     """Wrap JSONEncoder.default to handle MutableProxy objects.
 
     Args:
@@ -4073,10 +4072,10 @@ def _json_JSONEncoder_default_wrapper(self: json.JSONEncoder, o: Any) -> Any:
         return o.__wrapped__
     except AttributeError:
         pass
-    return _orig_json_JSONEncoder_default(self, o)
+    return _orig_json_encoder_default(self, o)
 
 
-json.JSONEncoder.default = _json_JSONEncoder_default_wrapper
+json.JSONEncoder.default = _json_encoder_default_wrapper
 
 
 class ImmutableMutableProxy(MutableProxy):

+ 1 - 1
reflex/testing.py

@@ -87,7 +87,7 @@ else:
 
 
 # borrowed from py3.11
-class chdir(contextlib.AbstractContextManager):
+class chdir(contextlib.AbstractContextManager):  # noqa: N801
     """Non thread-safe context manager to change the current working directory."""
 
     def __init__(self, path):

+ 1 - 4
reflex/utils/codespaces.py

@@ -42,10 +42,7 @@ def codespaces_port_forwarding_domain() -> str | None:
     Returns:
         The domain for port forwarding in Github Codespaces, or None if not running in Codespaces.
     """
-    GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN = os.getenv(
-        "GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN"
-    )
-    return GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN
+    return os.getenv("GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN")
 
 
 def is_running_in_codespaces() -> bool:

+ 10 - 10
reflex/utils/exceptions.py

@@ -11,7 +11,7 @@ class ConfigError(ReflexError):
     """Custom exception for config related errors."""
 
 
-class InvalidStateManagerMode(ReflexError, ValueError):
+class InvalidStateManagerModeError(ReflexError, ValueError):
     """Raised when an invalid state manager mode is provided."""
 
 
@@ -143,35 +143,35 @@ class EventFnArgMismatchError(ReflexError, TypeError):
     """Raised when the number of args required by an event handler is more than provided by the event trigger."""
 
 
-class DynamicRouteArgShadowsStateVar(ReflexError, NameError):
+class DynamicRouteArgShadowsStateVarError(ReflexError, NameError):
     """Raised when a dynamic route arg shadows a state var."""
 
 
-class ComputedVarShadowsStateVar(ReflexError, NameError):
+class ComputedVarShadowsStateVarError(ReflexError, NameError):
     """Raised when a computed var shadows a state var."""
 
 
-class ComputedVarShadowsBaseVars(ReflexError, NameError):
+class ComputedVarShadowsBaseVarsError(ReflexError, NameError):
     """Raised when a computed var shadows a base var."""
 
 
-class EventHandlerShadowsBuiltInStateMethod(ReflexError, NameError):
+class EventHandlerShadowsBuiltInStateMethodError(ReflexError, NameError):
     """Raised when an event handler shadows a built-in state method."""
 
 
-class GeneratedCodeHasNoFunctionDefs(ReflexError):
+class GeneratedCodeHasNoFunctionDefsError(ReflexError):
     """Raised when refactored code generated with flexgen has no functions defined."""
 
 
-class PrimitiveUnserializableToJSON(ReflexError, ValueError):
+class PrimitiveUnserializableToJSONError(ReflexError, ValueError):
     """Raised when a primitive type is unserializable to JSON. Usually with NaN and Infinity."""
 
 
-class InvalidLifespanTaskType(ReflexError, TypeError):
+class InvalidLifespanTaskTypeError(ReflexError, TypeError):
     """Raised when an invalid task type is registered as a lifespan task."""
 
 
-class DynamicComponentMissingLibrary(ReflexError, ValueError):
+class DynamicComponentMissingLibraryError(ReflexError, ValueError):
     """Raised when a dynamic component is missing a library."""
 
 
@@ -187,7 +187,7 @@ class EnvironmentVarValueError(ReflexError, ValueError):
     """Raised when an environment variable is set to an invalid value."""
 
 
-class DynamicComponentInvalidSignature(ReflexError, TypeError):
+class DynamicComponentInvalidSignatureError(ReflexError, TypeError):
     """Raised when a dynamic component has an invalid signature."""
 
 

+ 4 - 4
reflex/utils/exec.py

@@ -364,11 +364,11 @@ def run_uvicorn_backend_prod(host, port, loglevel):
 
     app_module = get_app_module()
 
-    RUN_BACKEND_PROD = f"gunicorn --worker-class {config.gunicorn_worker_class} --max-requests {config.gunicorn_max_requests} --max-requests-jitter {config.gunicorn_max_requests_jitter} --preload --timeout {config.timeout} --log-level critical".split()
-    RUN_BACKEND_PROD_WINDOWS = f"uvicorn --limit-max-requests {config.gunicorn_max_requests} --timeout-keep-alive {config.timeout}".split()
+    run_backend_prod = f"gunicorn --worker-class {config.gunicorn_worker_class} --max-requests {config.gunicorn_max_requests} --max-requests-jitter {config.gunicorn_max_requests_jitter} --preload --timeout {config.timeout} --log-level critical".split()
+    run_backend_prod_windows = f"uvicorn --limit-max-requests {config.gunicorn_max_requests} --timeout-keep-alive {config.timeout}".split()
     command = (
         [
-            *RUN_BACKEND_PROD_WINDOWS,
+            *run_backend_prod_windows,
             "--host",
             host,
             "--port",
@@ -377,7 +377,7 @@ def run_uvicorn_backend_prod(host, port, loglevel):
         ]
         if constants.IS_WINDOWS
         else [
-            *RUN_BACKEND_PROD,
+            *run_backend_prod,
             "--bind",
             f"{host}:{port}",
             "--threads",

+ 3 - 3
reflex/utils/prerequisites.py

@@ -38,7 +38,7 @@ from reflex.compiler import templates
 from reflex.config import Config, environment, get_config
 from reflex.utils import console, net, path_ops, processes, redir
 from reflex.utils.exceptions import (
-    GeneratedCodeHasNoFunctionDefs,
+    GeneratedCodeHasNoFunctionDefsError,
     SystemPackageMissingError,
 )
 from reflex.utils.format import format_library_name
@@ -1816,7 +1816,7 @@ def initialize_main_module_index_from_generation(app_name: str, generation_hash:
         generation_hash: The generation hash from reflex.build.
 
     Raises:
-        GeneratedCodeHasNoFunctionDefs: If the fetched code has no function definitions
+        GeneratedCodeHasNoFunctionDefsError: If the fetched code has no function definitions
             (the refactored reflex code is expected to have at least one root function defined).
     """
     # Download the reflex code for the generation.
@@ -1833,7 +1833,7 @@ def initialize_main_module_index_from_generation(app_name: str, generation_hash:
     # Determine the name of the last function, which renders the generated code.
     defined_funcs = re.findall(r"def ([a-zA-Z_]+)\(", resp.text)
     if not defined_funcs:
-        raise GeneratedCodeHasNoFunctionDefs(
+        raise GeneratedCodeHasNoFunctionDefsError(
             f"No function definitions found in generated code from {url!r}."
         )
     render_func_name = defined_funcs[-1]

+ 1 - 1
reflex/vars/base.py

@@ -1555,7 +1555,7 @@ def figure_out_type(value: Any) -> types.GenericType:
     return type(value)
 
 
-class cached_property_no_lock(functools.cached_property):
+class cached_property_no_lock(functools.cached_property):  # noqa: N801
     """A special version of functools.cached_property that does not use a lock."""
 
     def __init__(self, func):

+ 3 - 3
reflex/vars/number.py

@@ -18,7 +18,7 @@ from typing import (
 )
 
 from reflex.constants.base import Dirs
-from reflex.utils.exceptions import PrimitiveUnserializableToJSON, VarTypeError
+from reflex.utils.exceptions import PrimitiveUnserializableToJSONError, VarTypeError
 from reflex.utils.imports import ImportDict, ImportVar
 
 from .base import (
@@ -987,10 +987,10 @@ class LiteralNumberVar(LiteralVar, NumberVar):
             The JSON representation of the var.
 
         Raises:
-            PrimitiveUnserializableToJSON: If the var is unserializable to JSON.
+            PrimitiveUnserializableToJSONError: If the var is unserializable to JSON.
         """
         if math.isinf(self._var_value) or math.isnan(self._var_value):
-            raise PrimitiveUnserializableToJSON(
+            raise PrimitiveUnserializableToJSONError(
                 f"No valid JSON representation for {self}"
             )
         return json.dumps(self._var_value)

+ 1 - 30
tests/units/conftest.py

@@ -1,11 +1,8 @@
 """Test fixtures."""
 
 import asyncio
-import contextlib
-import os
 import platform
 import uuid
-from pathlib import Path
 from typing import Dict, Generator, Type
 from unittest import mock
 
@@ -14,6 +11,7 @@ import pytest
 from reflex.app import App
 from reflex.event import EventSpec
 from reflex.model import ModelRegistry
+from reflex.testing import chdir
 from reflex.utils import prerequisites
 
 from .states import (
@@ -191,33 +189,6 @@ def router_data(router_data_headers) -> Dict[str, str]:
     }
 
 
-# borrowed from py3.11
-class chdir(contextlib.AbstractContextManager):
-    """Non thread-safe context manager to change the current working directory."""
-
-    def __init__(self, path):
-        """Prepare contextmanager.
-
-        Args:
-            path: the path to change to
-        """
-        self.path = path
-        self._old_cwd = []
-
-    def __enter__(self):
-        """Save current directory and perform chdir."""
-        self._old_cwd.append(Path.cwd())
-        os.chdir(self.path)
-
-    def __exit__(self, *excinfo):
-        """Change back to previous directory on stack.
-
-        Args:
-            excinfo: sys.exc_info captured in the context block
-        """
-        os.chdir(self._old_cwd.pop())
-
-
 @pytest.fixture
 def tmp_working_dir(tmp_path):
     """Create a temporary directory and chdir to it.

+ 2 - 2
tests/units/test_var.py

@@ -12,7 +12,7 @@ from reflex.base import Base
 from reflex.constants.base import REFLEX_VAR_CLOSING_TAG, REFLEX_VAR_OPENING_TAG
 from reflex.state import BaseState
 from reflex.utils.exceptions import (
-    PrimitiveUnserializableToJSON,
+    PrimitiveUnserializableToJSONError,
     UntypedComputedVarError,
 )
 from reflex.utils.imports import ImportVar
@@ -1061,7 +1061,7 @@ def test_inf_and_nan(var, expected_js):
     assert str(var) == expected_js
     assert isinstance(var, NumberVar)
     assert isinstance(var, LiteralVar)
-    with pytest.raises(PrimitiveUnserializableToJSON):
+    with pytest.raises(PrimitiveUnserializableToJSONError):
         var.json()