enable N rules for naming conventions

This commit is contained in:
Lendemor 2025-01-20 23:09:07 +01:00
parent 4da32a122b
commit e56d7702cd
31 changed files with 151 additions and 169 deletions

View File

@ -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.")

View File

@ -86,15 +86,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", "W"]
lint.select = ["B", "C4", "D", "E", "ERA", "F", "FURB", "I", "N", "PERF", "PTH", "RUF", "SIM", "T", "W"]
lint.ignore = ["B008", "D205", "E501", "F403", "SIM115", "RUF006", "RUF012"]
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]

View File

@ -1164,11 +1164,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,
}
@ -1176,8 +1176,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__"):

View File

@ -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."
)

View File

@ -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):

View File

@ -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))

View File

@ -8,6 +8,8 @@ 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]
@ -81,7 +83,6 @@ class Image(NextComponent):
_type_: _description_
"""
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]):

View File

@ -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.

View File

@ -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)",
},

View File

@ -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]

View File

@ -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.

View File

@ -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:

View File

@ -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

View File

@ -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)

View File

@ -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
@ -89,36 +90,36 @@ class Tooltip(RadixThemesComponent):
Run some additional handling on the props.
Args:
*children: The positional arguments
content: The content of the tooltip.
default_open: The open state of the tooltip when it is initially rendered. Use when you do not need to control its open state.
open: The controlled open state of the tooltip. Must be used in conjunction with `on_open_change`.
side: The preferred side of the trigger to render against when open. Will be reversed when collisions occur and `avoid_collisions` is enabled.The position of the tooltip. Defaults to "top".
side_offset: The distance in pixels from the trigger. Defaults to 0.
align: The preferred alignment against the trigger. May change when collisions occur. Defaults to "center".
align_offset: An offset in pixels from the "start" or "end" alignment options.
avoid_collisions: When true, overrides the side and align preferences to prevent collisions with boundary edges. Defaults to True.
collision_padding: The distance in pixels from the boundary edges where collision detection should occur. Accepts a number (same for all sides), or a partial padding object, for example: { "top": 20, "left": 20 }. Defaults to 0.
arrow_padding: The padding between the arrow and the edges of the content. If your content has border-radius, this will prevent it from overflowing the corners. Defaults to 0.
sticky: The sticky behavior on the align axis. "partial" will keep the content in the boundary as long as the trigger is at least partially in the boundary whilst "always" will keep the content in the boundary regardless. Defaults to "partial".
hide_when_detached: Whether to hide the content when the trigger becomes fully occluded. Defaults to False.
delay_duration: Override the duration in milliseconds to customize the open delay for a specific tooltip. Default is 700.
disable_hoverable_content: Prevents Tooltip content from remaining open when hovering.
force_mount: Used to force mounting when more control is needed. Useful when controlling animation with React animation libraries.
aria_label: By default, screenreaders will announce the content inside the component. If this is not descriptive enough, or you have content that cannot be announced, use aria-label as a more descriptive label.
on_open_change: Fired when the open state changes.
on_escape_key_down: Fired when the escape key is pressed.
on_pointer_down_outside: Fired when the pointer is down outside the tooltip.
style: The style of the component.
key: A unique key for the component.
id: The id for the component.
class_name: The class name for the component.
autofocus: Whether the component should take the focus once the page is loaded
custom_attrs: custom attribute
**props: The keyword arguments
*children: The positional arguments
content: The content of the tooltip.
default_open: The open state of the tooltip when it is initially rendered. Use when you do not need to control its open state.
open: The controlled open state of the tooltip. Must be used in conjunction with `on_open_change`.
side: The preferred side of the trigger to render against when open. Will be reversed when collisions occur and `avoid_collisions` is enabled.The position of the tooltip. Defaults to "top".
side_offset: The distance in pixels from the trigger. Defaults to 0.
align: The preferred alignment against the trigger. May change when collisions occur. Defaults to "center".
align_offset: An offset in pixels from the "start" or "end" alignment options.
avoid_collisions: When true, overrides the side and align preferences to prevent collisions with boundary edges. Defaults to True.
collision_padding: The distance in pixels from the boundary edges where collision detection should occur. Accepts a number (same for all sides), or a partial padding object, for example: { "top": 20, "left": 20 }. Defaults to 0.
arrow_padding: The padding between the arrow and the edges of the content. If your content has border-radius, this will prevent it from overflowing the corners. Defaults to 0.
sticky: The sticky behavior on the align axis. "partial" will keep the content in the boundary as long as the trigger is at least partially in the boundary whilst "always" will keep the content in the boundary regardless. Defaults to "partial".
hide_when_detached: Whether to hide the content when the trigger becomes fully occluded. Defaults to False.
delay_duration: Override the duration in milliseconds to customize the open delay for a specific tooltip. Default is 700.
disable_hoverable_content: Prevents Tooltip content from remaining open when hovering.
force_mount: Used to force mounting when more control is needed. Useful when controlling animation with React animation libraries.
aria_label: By default, screenreaders will announce the content inside the component. If this is not descriptive enough, or you have content that cannot be announced, use aria-label as a more descriptive label.
on_open_change: Fired when the open state changes.
on_escape_key_down: Fired when the escape key is pressed.
on_pointer_down_outside: Fired when the pointer is down outside the tooltip.
style: The style of the component.
key: A unique key for the component.
id: The id for the component.
class_name: The class name for the component.
autofocus: Whether the component should take the focus once the page is loaded
custom_attrs: custom attribute
**props: The keyword arguments
Returns:
The created component.
The created component.
"""
...

View File

@ -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))

View File

@ -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.13.0"
def _get_style(self) -> Dict:
def _get_style(self) -> dict:
return {"wrapperStyle": self.style}

View File

@ -389,7 +389,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
@ -807,16 +807,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}"

View File

@ -40,7 +40,10 @@ from typing_extensions import (
from reflex import constants
from reflex.constants.state import FRONTEND_EVENT_STATE
from reflex.utils import console, format
from reflex.utils.exceptions import EventFnArgMismatch, EventHandlerArgTypeMismatch
from reflex.utils.exceptions import (
EventFnArgMismatchError,
EventHandlerArgTypeMismatchError,
)
from reflex.utils.types import ArgsSpec, GenericType, typehint_issubclass
from reflex.vars import VarData
from reflex.vars.base import LiteralVar, Var
@ -557,10 +560,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
alt_key: bool = False
ctrl_key: bool = False
meta_key: bool = False
shift_key: bool = False
def input_event(e: Var[JavascriptInputEvent]) -> Tuple[Var[str]]:
@ -1364,7 +1367,7 @@ def call_event_handler(
if compare_result:
continue
else:
failure = EventHandlerArgTypeMismatch(
failure = EventHandlerArgTypeMismatchError(
f"Event handler {key} expects {args_types_without_vars[i]} for argument {arg} but got {type_hints_of_provided_callback[arg]} as annotated in {event_callback.fn.__qualname__} instead."
)
failures.append(failure)
@ -1477,7 +1480,7 @@ def check_fn_match_arg_spec(
func_name: str | None = None,
):
"""Ensures that the function signature matches the passed argument specification
or raises an EventFnArgMismatch if they do not.
or raises an EventFnArgMismatchError if they do not.
Args:
user_func: The function to be validated.
@ -1487,7 +1490,7 @@ def check_fn_match_arg_spec(
func_name: The name of the function to be validated.
Raises:
EventFnArgMismatch: Raised if the number of mandatory arguments do not match
EventFnArgMismatchError: Raised if the number of mandatory arguments do not match
"""
user_args = inspect.getfullargspec(user_func).args
# Drop the first argument if it's a bound method
@ -1503,7 +1506,7 @@ def check_fn_match_arg_spec(
number_of_event_args = len(parsed_event_args)
if number_of_user_args - number_of_user_default_args > number_of_event_args:
raise EventFnArgMismatch(
raise EventFnArgMismatchError(
f"Event {key} only provides {number_of_event_args} arguments, but "
f"{func_name or user_func} requires at least {number_of_user_args - number_of_user_default_args} "
"arguments to be passed to the event handler.\n"

View File

@ -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:

View File

@ -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():
@ -2356,8 +2356,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)
@ -2369,12 +2368,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."
)
@ -2876,7 +2875,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).
@ -2899,7 +2898,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}"
)
@ -4058,10 +4057,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:
@ -4075,10 +4074,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):

View File

@ -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):

View File

@ -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:

View File

@ -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."""
@ -95,43 +95,43 @@ class MatchTypeError(ReflexError, TypeError):
"""Raised when the return types of match cases are different."""
class EventHandlerArgTypeMismatch(ReflexError, TypeError):
class EventHandlerArgTypeMismatchError(ReflexError, TypeError):
"""Raised when the annotations of args accepted by an EventHandler differs from the spec of the event trigger."""
class EventFnArgMismatch(ReflexError, TypeError):
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."""
@ -147,7 +147,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."""

View File

@ -339,11 +339,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",
@ -352,7 +352,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",

View File

@ -36,7 +36,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,
raise_system_package_missing_error,
)
from reflex.utils.format import format_library_name
@ -1609,7 +1609,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.
@ -1626,7 +1626,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]

View File

@ -1581,7 +1581,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):

View File

@ -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)

View File

@ -27,7 +27,7 @@ from reflex.event import (
from reflex.state import BaseState
from reflex.style import Style
from reflex.utils import imports
from reflex.utils.exceptions import EventFnArgMismatch
from reflex.utils.exceptions import EventFnArgMismatchError
from reflex.utils.imports import ImportDict, ImportVar, ParsedImportDict, parse_imports
from reflex.vars import VarData
from reflex.vars.base import LiteralVar, Var
@ -905,11 +905,11 @@ def test_invalid_event_handler_args(component2, test_state):
test_state: A test state.
"""
# EventHandler args must match
with pytest.raises(EventFnArgMismatch):
with pytest.raises(EventFnArgMismatchError):
component2.create(on_click=test_state.do_something_arg)
# Multiple EventHandler args: all must match
with pytest.raises(EventFnArgMismatch):
with pytest.raises(EventFnArgMismatchError):
component2.create(
on_click=[test_state.do_something_arg, test_state.do_something]
)
@ -941,15 +941,15 @@ def test_invalid_event_handler_args(component2, test_state):
)
# lambda signature must match event trigger.
with pytest.raises(EventFnArgMismatch):
with pytest.raises(EventFnArgMismatchError):
component2.create(on_click=lambda _: test_state.do_something_arg(1))
# lambda returning EventHandler must match spec
with pytest.raises(EventFnArgMismatch):
with pytest.raises(EventFnArgMismatchError):
component2.create(on_click=lambda: test_state.do_something_arg)
# Mixed EventSpec and EventHandler must match spec.
with pytest.raises(EventFnArgMismatch):
with pytest.raises(EventFnArgMismatchError):
component2.create(
on_click=lambda: [
test_state.do_something_arg(1),

View File

@ -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.

View File

@ -11,7 +11,7 @@ import reflex as rx
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
from reflex.utils.exceptions import PrimitiveUnserializableToJSONError
from reflex.utils.imports import ImportVar
from reflex.vars import VarData
from reflex.vars.base import (
@ -1058,7 +1058,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()