enable RUF rules for linting (#4465)

This commit is contained in:
Thomas Brandého 2024-12-10 09:11:50 -08:00 committed by GitHub
parent a68eef23aa
commit 4ecb0b81ce
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
46 changed files with 156 additions and 150 deletions

View File

@ -93,8 +93,8 @@ build-backend = "poetry.core.masonry.api"
[tool.ruff]
target-version = "py39"
lint.isort.split-on-trailing-comma = false
lint.select = ["B", "D", "E", "F", "I", "SIM", "W"]
lint.ignore = ["B008", "D205", "E501", "F403", "SIM115"]
lint.select = ["B", "D", "E", "F", "I", "SIM", "W", "RUF"]
lint.ignore = ["B008", "D205", "E501", "F403", "SIM115", "RUF006", "RUF012"]
lint.pydocstyle.convention = "google"
[tool.ruff.lint.per-file-ignores]

View File

@ -103,8 +103,8 @@ class Bare(Component):
def _render(self) -> Tag:
if isinstance(self.contents, Var):
if isinstance(self.contents, (BooleanVar, ObjectVar)):
return Tagless(contents=f"{{{str(self.contents.to_string())}}}")
return Tagless(contents=f"{{{str(self.contents)}}}")
return Tagless(contents=f"{{{self.contents.to_string()!s}}}")
return Tagless(contents=f"{{{self.contents!s}}}")
return Tagless(contents=str(self.contents))
def _get_vars(self, include_children: bool = False) -> Iterator[Var]:

View File

@ -583,7 +583,7 @@ class Component(BaseComponent, ABC):
return self._create_event_chain(args_spec, value.guess_type(), key=key)
else:
raise ValueError(
f"Invalid event chain: {str(value)} of type {value._var_type}"
f"Invalid event chain: {value!s} of type {value._var_type}"
)
elif isinstance(value, EventChain):
# Trust that the caller knows what they're doing passing an EventChain directly
@ -1111,7 +1111,7 @@ class Component(BaseComponent, ABC):
vars.append(prop_var)
# Style keeps track of its own VarData instance, so embed in a temp Var that is yielded.
if isinstance(self.style, dict) and self.style or isinstance(self.style, Var):
if (isinstance(self.style, dict) and self.style) or isinstance(self.style, Var):
vars.append(
Var(
_js_expr="style",
@ -1466,7 +1466,9 @@ class Component(BaseComponent, ABC):
"""
ref = self.get_ref()
if ref is not None:
return f"const {ref} = useRef(null); {str(Var(_js_expr=ref)._as_ref())} = {ref};"
return (
f"const {ref} = useRef(null); {Var(_js_expr=ref)._as_ref()!s} = {ref};"
)
def _get_vars_hooks(self) -> dict[str, None]:
"""Get the hooks required by vars referenced in this component.

View File

@ -109,7 +109,7 @@ class ConnectionToaster(Toaster):
)
individual_hooks = [
f"const toast_props = {str(LiteralVar.create(props))};",
f"const toast_props = {LiteralVar.create(props)!s};",
"const [userDismissed, setUserDismissed] = useState(false);",
FunctionStringVar(
"useEffect",
@ -124,7 +124,7 @@ class ConnectionToaster(Toaster):
Var(
_js_expr=f"""
() => {{
if ({str(has_too_many_connection_errors)}) {{
if ({has_too_many_connection_errors!s}) {{
if (!userDismissed) {{
toast.error(
`Cannot connect to server: ${{{connection_error}}}.`,

View File

@ -51,7 +51,7 @@ class Clipboard(Fragment):
return super().create(*children, **props)
def _exclude_props(self) -> list[str]:
return super()._exclude_props() + ["on_paste", "on_paste_event_actions"]
return [*super()._exclude_props(), "on_paste", "on_paste_event_actions"]
def _render(self) -> Tag:
tag = super()._render()

View File

@ -94,7 +94,7 @@ class Cond(MemoizationLeaf):
).set(
props=tag.format_props(),
),
cond_state=f"isTrue({str(self.cond)})",
cond_state=f"isTrue({self.cond!s})",
)
def add_imports(self) -> ImportDict:

View File

@ -54,7 +54,7 @@ class Foreach(Component):
iterable = LiteralVar.create(iterable)
if iterable._var_type == Any:
raise ForeachVarError(
f"Could not foreach over var `{str(iterable)}` of type Any. "
f"Could not foreach over var `{iterable!s}` of type Any. "
"(If you are trying to foreach over a state var, add a type annotation to the var). "
"See https://reflex.dev/docs/library/dynamic-rendering/foreach/"
)

View File

@ -61,7 +61,7 @@ def upload_file(id_: str = DEFAULT_UPLOAD_ID) -> Var:
id_var = LiteralStringVar.create(id_)
var_name = f"""e => setFilesById(filesById => {{
const updatedFilesById = Object.assign({{}}, filesById);
updatedFilesById[{str(id_var)}] = e;
updatedFilesById[{id_var!s}] = e;
return updatedFilesById;
}})
"""
@ -87,7 +87,7 @@ def selected_files(id_: str = DEFAULT_UPLOAD_ID) -> Var:
"""
id_var = LiteralStringVar.create(id_)
return Var(
_js_expr=f"(filesById[{str(id_var)}] ? filesById[{str(id_var)}].map((f) => (f.path || f.name)) : [])",
_js_expr=f"(filesById[{id_var!s}] ? filesById[{id_var!s}].map((f) => (f.path || f.name)) : [])",
_var_type=List[str],
_var_data=VarData.merge(
upload_files_context_var_data, id_var._get_all_var_data()
@ -120,9 +120,7 @@ def cancel_upload(upload_id: str) -> EventSpec:
Returns:
An event spec that cancels the upload when triggered.
"""
return run_script(
f"upload_controllers[{str(LiteralVar.create(upload_id))}]?.abort()"
)
return run_script(f"upload_controllers[{LiteralVar.create(upload_id)!s}]?.abort()")
def get_upload_dir() -> Path:
@ -301,7 +299,7 @@ class Upload(MemoizationLeaf):
)
left_side = f"const {{getRootProps: {root_props_unique_name}, getInputProps: {input_props_unique_name}}} "
right_side = f"useDropzone({str(use_dropzone_arguments)})"
right_side = f"useDropzone({use_dropzone_arguments!s})"
var_data = VarData.merge(
VarData(

View File

@ -519,13 +519,13 @@ class CodeBlock(Component, MarkdownComponentMap):
The hook to register the language.
"""
return f"""
if ({str(_LANGUAGE)}) {{
if ({_LANGUAGE!s}) {{
(async () => {{
try {{
const module = await import(`react-syntax-highlighter/dist/cjs/languages/prism/${{{str(_LANGUAGE)}}}`);
SyntaxHighlighter.registerLanguage({str(_LANGUAGE)}, module.default);
const module = await import(`react-syntax-highlighter/dist/cjs/languages/prism/${{{_LANGUAGE!s}}}`);
SyntaxHighlighter.registerLanguage({_LANGUAGE!s}, module.default);
}} catch (error) {{
console.error(`Error importing language module for ${{{str(_LANGUAGE)}}}:`, error);
console.error(`Error importing language module for ${{{_LANGUAGE!s}}}:`, error);
}}
}})();
}}
@ -547,7 +547,7 @@ class CodeBlock(Component, MarkdownComponentMap):
The hooks for the component.
"""
return [
f"const {str(_LANGUAGE)} = {str(self.language)}",
f"const {_LANGUAGE!s} = {self.language!s}",
self._get_language_registration_hook(),
]

View File

@ -406,10 +406,8 @@ class DataEditor(NoSSRComponent):
props["rows"] = data.length() if isinstance(data, Var) else len(data)
if not isinstance(columns, Var) and len(columns):
if (
types.is_dataframe(type(data))
or isinstance(data, Var)
and types.is_dataframe(data._var_type)
if types.is_dataframe(type(data)) or (
isinstance(data, Var) and types.is_dataframe(data._var_type)
):
raise ValueError(
"Cannot pass in both a pandas dataframe and columns to the data_editor component."

View File

@ -173,7 +173,7 @@ def load_dynamic_serializer():
f"const [{unique_var_name}, set_{unique_var_name}] = useState(null);": None,
"useEffect(() => {"
"let isMounted = true;"
f"evalReactComponent({str(js_string)})"
f"evalReactComponent({js_string!s})"
".then((component) => {"
"if (isMounted) {"
f"set_{unique_var_name}(component);"
@ -183,7 +183,7 @@ def load_dynamic_serializer():
"isMounted = false;"
"};"
"}"
f", [{str(js_string)}]);": None,
f", [{js_string!s}]);": None,
},
),
),

View File

@ -241,13 +241,13 @@ class Form(BaseHTML):
if ref.startswith("refs_"):
ref_var = Var(_js_expr=ref[:-3])._as_ref()
form_refs[ref[len("refs_") : -3]] = Var(
_js_expr=f"getRefValues({str(ref_var)})",
_js_expr=f"getRefValues({ref_var!s})",
_var_data=VarData.merge(ref_var._get_all_var_data()),
)
else:
ref_var = Var(_js_expr=ref)._as_ref()
form_refs[ref[4:]] = Var(
_js_expr=f"getRefValue({str(ref_var)})",
_js_expr=f"getRefValue({ref_var!s})",
_var_data=VarData.merge(ref_var._get_all_var_data()),
)
# print(repr(form_refs))
@ -258,7 +258,8 @@ class Form(BaseHTML):
yield from self._get_form_refs().values()
def _exclude_props(self) -> list[str]:
return super()._exclude_props() + [
return [
*super()._exclude_props(),
"reset_on_submit",
"handle_submit_unique_name",
]
@ -652,19 +653,20 @@ class Textarea(BaseHTML):
"Cannot combine `enter_key_submit` with `on_key_down`.",
)
custom_attrs["on_key_down"] = Var(
_js_expr=f"(e) => enterKeySubmitOnKeyDown(e, {str(enter_key_submit)})",
_js_expr=f"(e) => enterKeySubmitOnKeyDown(e, {enter_key_submit!s})",
_var_data=VarData.merge(enter_key_submit._get_all_var_data()),
)
if auto_height is not None:
auto_height = Var.create(auto_height)
custom_attrs["on_input"] = Var(
_js_expr=f"(e) => autoHeightOnInput(e, {str(auto_height)})",
_js_expr=f"(e) => autoHeightOnInput(e, {auto_height!s})",
_var_data=VarData.merge(auto_height._get_all_var_data()),
)
return super().create(*children, **props)
def _exclude_props(self) -> list[str]:
return super()._exclude_props() + [
return [
*super()._exclude_props(),
"auto_height",
"enter_key_submit",
]

View File

@ -8,7 +8,7 @@ from reflex.vars.base import Var
from .base import BaseHTML
class Base(BaseHTML): # noqa: E742
class Base(BaseHTML):
"""Display the base element."""
tag = "base"
@ -18,13 +18,13 @@ class Base(BaseHTML): # noqa: E742
target: Var[Union[str, int, bool]]
class Head(BaseHTML): # noqa: E742
class Head(BaseHTML):
"""Display the head element."""
tag = "head"
class Link(BaseHTML): # noqa: E742
class Link(BaseHTML):
"""Display the link element."""
tag = "link"
@ -75,14 +75,14 @@ class Meta(BaseHTML): # Inherits common attributes from BaseHTML
name: Var[Union[str, int, bool]]
class Title(Element): # noqa: E742
class Title(Element):
"""Display the title element."""
tag = "title"
# Had to be named with an underscore so it doesnt conflict with reflex.style Style in pyi
class StyleEl(Element): # noqa: E742
class StyleEl(Element):
"""Display the style element."""
tag = "style"

View File

@ -3,91 +3,91 @@
from .base import BaseHTML
class Body(BaseHTML): # noqa: E742
class Body(BaseHTML):
"""Display the body element."""
tag = "body"
class Address(BaseHTML): # noqa: E742
class Address(BaseHTML):
"""Display the address element."""
tag = "address"
class Article(BaseHTML): # noqa: E742
class Article(BaseHTML):
"""Display the article element."""
tag = "article"
class Aside(BaseHTML): # noqa: E742
class Aside(BaseHTML):
"""Display the aside element."""
tag = "aside"
class Footer(BaseHTML): # noqa: E742
class Footer(BaseHTML):
"""Display the footer element."""
tag = "footer"
class Header(BaseHTML): # noqa: E742
class Header(BaseHTML):
"""Display the header element."""
tag = "header"
class H1(BaseHTML): # noqa: E742
class H1(BaseHTML):
"""Display the h1 element."""
tag = "h1"
class H2(BaseHTML): # noqa: E742
class H2(BaseHTML):
"""Display the h1 element."""
tag = "h2"
class H3(BaseHTML): # noqa: E742
class H3(BaseHTML):
"""Display the h1 element."""
tag = "h3"
class H4(BaseHTML): # noqa: E742
class H4(BaseHTML):
"""Display the h1 element."""
tag = "h4"
class H5(BaseHTML): # noqa: E742
class H5(BaseHTML):
"""Display the h1 element."""
tag = "h5"
class H6(BaseHTML): # noqa: E742
class H6(BaseHTML):
"""Display the h1 element."""
tag = "h6"
class Main(BaseHTML): # noqa: E742
class Main(BaseHTML):
"""Display the main element."""
tag = "main"
class Nav(BaseHTML): # noqa: E742
class Nav(BaseHTML):
"""Display the nav element."""
tag = "nav"
class Section(BaseHTML): # noqa: E742
class Section(BaseHTML):
"""Display the section element."""
tag = "section"

View File

@ -283,7 +283,7 @@ class Markdown(Component):
# Format the code to handle inline and block code.
formatted_code = f"""
const match = (className || '').match(/language-(?<lang>.*)/);
const {str(_LANGUAGE)} = match ? match[1] : '';
const {_LANGUAGE!s} = match ? match[1] : '';
{codeblock_custom_code};
return inline ? (
{self.format_component("code")}
@ -340,7 +340,7 @@ const {str(_LANGUAGE)} = match ? match[1] : '';
# If the children are set as a prop, don't pass them as children.
children_prop = props.pop("children", None)
if children_prop is not None:
special_props.append(Var(_js_expr=f"children={{{str(children_prop)}}}"))
special_props.append(Var(_js_expr=f"children={{{children_prop!s}}}"))
children = []
# Get the component.
component = self.component_map[tag](*children, **props).set(
@ -429,7 +429,7 @@ const {str(_LANGUAGE)} = match ? match[1] : '';
function {self._get_component_map_name()} () {{
{formatted_hooks}
return (
{str(LiteralVar.create(self.format_component_map()))}
{LiteralVar.create(self.format_component_map())!s}
)
}}
"""

View File

@ -270,11 +270,11 @@ const extractPoints = (points) => {
tag.special_props.append(
# Merge all dictionaries and spread the result over props.
Var(
_js_expr=f"{{...mergician({str(figure)},"
_js_expr=f"{{...mergician({figure!s},"
f"{','.join(str(md) for md in merge_dicts)})}}",
),
)
else:
# Spread the figure dict over props, nothing to merge.
tag.special_props.append(Var(_js_expr=f"{{...{str(figure)}}}"))
tag.special_props.append(Var(_js_expr=f"{{...{figure!s}}}"))
return tag

View File

@ -129,7 +129,8 @@ class AccordionRoot(AccordionComponent):
on_value_change: EventHandler[on_value_change]
def _exclude_props(self) -> list[str]:
return super()._exclude_props() + [
return [
*super()._exclude_props(),
"radius",
"duration",
"easing",

View File

@ -140,10 +140,8 @@ class HighLevelRadioGroup(RadixThemesComponent):
color_scheme = props.pop("color_scheme", None)
default_value = props.pop("default_value", "")
if (
not isinstance(items, (list, Var))
or isinstance(items, Var)
and not types._issubclass(items._var_type, list)
if not isinstance(items, (list, Var)) or (
isinstance(items, Var) and not types._issubclass(items._var_type, list)
):
items_type = type(items) if not isinstance(items, Var) else items._var_type
raise TypeError(

View File

@ -64,7 +64,7 @@ def _toast_callback_signature(toast: Var) -> list[Var]:
"""
return [
Var(
_js_expr=f"(() => {{let {{action, cancel, onDismiss, onAutoClose, ...rest}} = {str(toast)}; return rest}})()"
_js_expr=f"(() => {{let {{action, cancel, onDismiss, onAutoClose, ...rest}} = {toast!s}; return rest}})()"
)
]
@ -338,7 +338,7 @@ class Toaster(Component):
dismiss_var_data = None
if isinstance(id, Var):
dismiss = f"{toast_ref}.dismiss({str(id)})"
dismiss = f"{toast_ref}.dismiss({id!s})"
dismiss_var_data = id._get_all_var_data()
elif isinstance(id, str):
dismiss = f"{toast_ref}.dismiss('{id}')"

View File

@ -447,7 +447,7 @@ class JavascriptHTMLInputElement:
class JavascriptInputEvent:
"""Interface for a Javascript InputEvent https://developer.mozilla.org/en-US/docs/Web/API/InputEvent."""
target: JavascriptHTMLInputElement = JavascriptHTMLInputElement()
target: JavascriptHTMLInputElement = JavascriptHTMLInputElement() # noqa: RUF009
@dataclasses.dataclass(

View File

@ -106,7 +106,7 @@ class ClientStateVar(Var):
default_var = default
setter_name = f"set{var_name.capitalize()}"
hooks = {
f"const [{var_name}, {setter_name}] = useState({str(default_var)})": None,
f"const [{var_name}, {setter_name}] = useState({default_var!s})": None,
}
imports = {
"react": [ImportVar(tag="useState")],

View File

@ -436,7 +436,7 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
"""
return [
v
for mixin in cls._mixins() + [cls]
for mixin in [*cls._mixins(), cls]
for name, v in mixin.__dict__.items()
if is_computed_var(v) and name not in cls.inherited_vars
]

View File

@ -74,7 +74,7 @@ def set_color_mode(
new_color_mode = LiteralVar.create(new_color_mode)
return Var(
f"() => {str(base_setter)}({str(new_color_mode)})",
f"() => {base_setter!s}({new_color_mode!s})",
_var_data=VarData.merge(
base_setter._get_all_var_data(), new_color_mode._get_all_var_data()
),

View File

@ -879,7 +879,7 @@ class Subdir404TCPServer(socketserver.TCPServer):
Args:
request: the requesting socket
client_address: (host, port) referring to the clients address.
client_address: (host, port) referring to the client's address.
"""
self.RequestHandlerClass(
request,

View File

@ -206,7 +206,9 @@ def get_granian_target():
app_module_path = Path(reflex.__file__).parent / "app_module_for_backend.py"
return f"{str(app_module_path)}:{constants.CompileVars.APP}.{constants.CompileVars.API}"
return (
f"{app_module_path!s}:{constants.CompileVars.APP}.{constants.CompileVars.API}"
)
def run_backend(
@ -440,10 +442,8 @@ def output_system_info():
system = platform.system()
if (
system != "Windows"
or system == "Windows"
and prerequisites.is_windows_bun_supported()
if system != "Windows" or (
system == "Windows" and prerequisites.is_windows_bun_supported()
):
dependencies.extend(
[

View File

@ -329,12 +329,12 @@ def format_match(
return_value = case[-1]
case_conditions = " ".join(
[f"case JSON.stringify({str(condition)}):" for condition in conditions]
[f"case JSON.stringify({condition!s}):" for condition in conditions]
)
case_code = f"{case_conditions} return ({str(return_value)}); break;"
case_code = f"{case_conditions} return ({return_value!s}); break;"
switch_code += case_code
switch_code += f"default: return ({str(default)}); break;"
switch_code += f"default: return ({default!s}); break;"
switch_code += "};})()"
return switch_code
@ -413,7 +413,7 @@ def format_props(*single_props, **key_value_props) -> list[str]:
)
for name, prop in sorted(key_value_props.items())
if prop is not None
] + [(f"{str(LiteralVar.create(prop))}") for prop in single_props]
] + [(f"{LiteralVar.create(prop)!s}") for prop in single_props]
def get_event_handler_parts(handler: EventHandler) -> tuple[str, str]:
@ -713,7 +713,7 @@ def format_array_ref(refs: str, idx: Var | None) -> str:
clean_ref = re.sub(r"[^\w]+", "_", refs)
if idx is not None:
# idx._var_is_local = True
return f"refs_{clean_ref}[{str(idx)}]"
return f"refs_{clean_ref}[{idx!s}]"
return f"refs_{clean_ref}"

View File

@ -219,9 +219,8 @@ def get_install_package_manager(on_failure_return_none: bool = False) -> str | N
Returns:
The path to the package manager.
"""
if (
constants.IS_WINDOWS
and not is_windows_bun_supported()
if constants.IS_WINDOWS and (
not is_windows_bun_supported()
or windows_check_onedrive_in_path()
or windows_npm_escape_hatch()
):
@ -834,7 +833,7 @@ def install_bun():
"""Install bun onto the user's system."""
win_supported = is_windows_bun_supported()
one_drive_in_path = windows_check_onedrive_in_path()
if constants.IS_WINDOWS and not win_supported or one_drive_in_path:
if constants.IS_WINDOWS and (not win_supported or one_drive_in_path):
if not win_supported:
console.warn(
"Bun for Windows is currently only available for x86 64-bit Windows. Installation will fall back on npm."
@ -926,7 +925,7 @@ def cached_procedure(cache_file: str, payload_fn: Callable[..., str]):
@cached_procedure(
cache_file=str(get_web_dir() / "reflex.install_frontend_packages.cached"),
payload_fn=lambda p, c: f"{repr(sorted(list(p)))},{c.json()}",
payload_fn=lambda p, c: f"{sorted(list(p))!r},{c.json()}",
)
def install_frontend_packages(packages: set[str], config: Config):
"""Installs the base and custom frontend packages.
@ -946,9 +945,12 @@ def install_frontend_packages(packages: set[str], config: Config):
get_package_manager(on_failure_return_none=True)
if (
not constants.IS_WINDOWS
or constants.IS_WINDOWS
and is_windows_bun_supported()
and not windows_check_onedrive_in_path()
or (
constants.IS_WINDOWS
and (
is_windows_bun_supported() and not windows_check_onedrive_in_path()
)
)
)
else None
)

View File

@ -364,7 +364,7 @@ def get_command_with_loglevel(command: list[str]) -> list[str]:
npm_path = str(Path(npm_path).resolve()) if npm_path else npm_path
if command[0] == npm_path:
return command + ["--loglevel", "silly"]
return [*command, "--loglevel", "silly"]
return command

View File

@ -835,7 +835,7 @@ class StubGenerator(ast.NodeTransformer):
self.inserted_imports = True
default_imports = _generate_imports(self.typing_imports)
self.import_statements.extend(ast.unparse(i) for i in default_imports)
return default_imports + [node]
return [*default_imports, node]
return node
def visit_ImportFrom(

View File

@ -783,7 +783,7 @@ def validate_literal(key: str, value: Any, expected_type: Type, comp_name: str):
)
value_str = f"'{value}'" if isinstance(value, str) else value
raise ValueError(
f"prop value for {str(key)} of the `{comp_name}` component should be one of the following: {allowed_value_str}. Got {value_str} instead"
f"prop value for {key!s} of the `{comp_name}` component should be one of the following: {allowed_value_str}. Got {value_str} instead"
)

View File

@ -1057,7 +1057,7 @@ class Var(Generic[VAR_TYPE]):
if self._var_type is Any:
raise TypeError(
f"You must provide an annotation for the state var `{str(self)}`. Annotation cannot be `{self._var_type}`."
f"You must provide an annotation for the state var `{self!s}`. Annotation cannot be `{self._var_type}`."
)
if name in REPLACED_NAMES:
@ -2117,7 +2117,7 @@ class ComputedVar(Var[RETURN_TYPE]):
ref_obj = None
if instruction.argval in invalid_names:
raise VarValueError(
f"Cached var {str(self)} cannot access arbitrary state via `{instruction.argval}`."
f"Cached var {self!s} cannot access arbitrary state via `{instruction.argval}`."
)
if callable(ref_obj):
# recurse into callable attributes
@ -2492,7 +2492,7 @@ class StateOperation(CachedVarOperation, Var):
Returns:
The cached var name.
"""
return f"{str(self._state_name)}.{str(self._field)}"
return f"{self._state_name!s}.{self._field!s}"
def __getattr__(self, name: str) -> Any:
"""Get an attribute of the var.
@ -2804,9 +2804,9 @@ def dispatch(
if result_origin_var_type in dispatchers:
fn = dispatchers[result_origin_var_type]
fn_first_arg_type = list(inspect.signature(fn).parameters.values())[
0
].annotation
fn_first_arg_type = next(
iter(inspect.signature(fn).parameters.values())
).annotation
fn_return = inspect.signature(fn).return_annotation

View File

@ -240,7 +240,7 @@ class VarOperationCall(Generic[P, R], CachedVarOperation, Var[R]):
Returns:
The name of the var.
"""
return f"({str(self._func)}({', '.join([str(LiteralVar.create(arg)) for arg in self._args])}))"
return f"({self._func!s}({', '.join([str(LiteralVar.create(arg)) for arg in self._args])}))"
@cached_property_no_lock
def _cached_get_all_var_data(self) -> VarData | None:

View File

@ -272,7 +272,7 @@ class ObjectVar(Var[OBJECT_TYPE], python_types=dict):
attribute_type = get_attribute_access_type(var_type, name)
if attribute_type is None:
raise VarAttributeError(
f"The State var `{str(self)}` has no attribute '{name}' or may have been annotated "
f"The State var `{self!s}` has no attribute '{name}' or may have been annotated "
f"wrongly."
)
return ObjectItemOperation.create(self, name, attribute_type).guess_type()
@ -332,7 +332,7 @@ class LiteralObjectVar(CachedVarOperation, ObjectVar[OBJECT_TYPE], LiteralVar):
"({ "
+ ", ".join(
[
f"[{str(LiteralVar.create(key))}] : {str(LiteralVar.create(value))}"
f"[{LiteralVar.create(key)!s}] : {LiteralVar.create(value)!s}"
for key, value in self._var_value.items()
]
)
@ -494,8 +494,8 @@ class ObjectItemOperation(CachedVarOperation, Var):
The name of the operation.
"""
if types.is_optional(self._object._var_type):
return f"{str(self._object)}?.[{str(self._key)}]"
return f"{str(self._object)}[{str(self._key)}]"
return f"{self._object!s}?.[{self._key!s}]"
return f"{self._object!s}[{self._key!s}]"
@classmethod
def create(

View File

@ -1349,7 +1349,7 @@ class ArraySliceOperation(CachedVarOperation, ArrayVar):
LiteralVar.create(end) if end is not None else Var(_js_expr="undefined")
)
if step is None:
return f"{str(self._array)}.slice({str(normalized_start)}, {str(normalized_end)})"
return f"{self._array!s}.slice({normalized_start!s}, {normalized_end!s})"
if not isinstance(step, Var):
if step < 0:
actual_start = end + 1 if end is not None else 0
@ -1357,12 +1357,12 @@ class ArraySliceOperation(CachedVarOperation, ArrayVar):
return str(self._array[actual_start:actual_end].reverse()[::-step])
if step == 0:
raise ValueError("slice step cannot be zero")
return f"{str(self._array)}.slice({str(normalized_start)}, {str(normalized_end)}).filter((_, i) => i % {str(step)} === 0)"
return f"{self._array!s}.slice({normalized_start!s}, {normalized_end!s}).filter((_, i) => i % {step!s} === 0)"
actual_start_reverse = end + 1 if end is not None else 0
actual_end_reverse = start + 1 if start is not None else self._array.length()
return f"{str(self.step)} > 0 ? {str(self._array)}.slice({str(normalized_start)}, {str(normalized_end)}).filter((_, i) => i % {str(step)} === 0) : {str(self._array)}.slice({str(actual_start_reverse)}, {str(actual_end_reverse)}).reverse().filter((_, i) => i % {str(-step)} === 0)"
return f"{self.step!s} > 0 ? {self._array!s}.slice({normalized_start!s}, {normalized_end!s}).filter((_, i) => i % {step!s} === 0) : {self._array!s}.slice({actual_start_reverse!s}, {actual_end_reverse!s}).reverse().filter((_, i) => i % {-step!s} === 0)"
@classmethod
def create(
@ -1535,7 +1535,7 @@ def array_item_operation(array: ArrayVar, index: NumberVar | int):
element_type = unionize(*args)
return var_operation_return(
js_expression=f"{str(array)}.at({str(index)})",
js_expression=f"{array!s}.at({index!s})",
var_type=element_type,
)
@ -1555,7 +1555,7 @@ def array_range_operation(
The range of numbers.
"""
return var_operation_return(
js_expression=f"Array.from({{ length: ({str(stop)} - {str(start)}) / {str(step)} }}, (_, i) => {str(start)} + i * {str(step)})",
js_expression=f"Array.from({{ length: ({stop!s} - {start!s}) / {step!s} }}, (_, i) => {start!s} + i * {step!s})",
var_type=List[int],
)

View File

@ -160,7 +160,7 @@ def CallScript():
@rx.event
def call_with_var_str_cast(self):
return rx.call_script(
f"{str(rx.Var('inline_counter'))} + {str(rx.Var('external_counter'))}",
f"{rx.Var('inline_counter')!s} + {rx.Var('external_counter')!s}",
callback=CallScriptState.set_last_result, # type: ignore
)
@ -175,7 +175,7 @@ def CallScript():
def call_with_var_str_cast_wrapped(self):
return rx.call_script(
rx.Var(
f"{str(rx.Var('inline_counter'))} + {str(rx.Var('external_counter'))}"
f"{rx.Var('inline_counter')!s} + {rx.Var('external_counter')!s}"
),
callback=CallScriptState.set_last_result, # type: ignore
)
@ -315,7 +315,7 @@ def CallScript():
rx.button(
"call_with_var_str_cast_inline",
on_click=rx.call_script(
f"{str(rx.Var('inline_counter'))} + {str(rx.Var('external_counter'))}",
f"{rx.Var('inline_counter')!s} + {rx.Var('external_counter')!s}",
callback=CallScriptState.set_last_result, # type: ignore
),
id="call_with_var_str_cast_inline",
@ -334,7 +334,7 @@ def CallScript():
"call_with_var_str_cast_wrapped_inline",
on_click=rx.call_script(
rx.Var(
f"{str(rx.Var('inline_counter'))} + {str(rx.Var('external_counter'))}"
f"{rx.Var('inline_counter')!s} + {rx.Var('external_counter')!s}"
),
callback=CallScriptState.set_last_result, # type: ignore
),

View File

@ -97,4 +97,5 @@ def test_table(page: Page, table_app: AppHarness):
# Check cells
rows = table.get_by_role("cell").all_inner_texts()
for i, expected_row in enumerate(expected_cells_data):
assert [rows[idx := i * 2], rows[idx + 1]] == expected_row
idx = i * 2
assert [rows[idx], rows[idx + 1]] == expected_row

View File

@ -32,38 +32,38 @@ def create_color_var(color):
(create_color_var(rx.color("mint", 3, True)), '"var(--mint-a3)"', Color),
(
create_color_var(rx.color(ColorState.color, ColorState.shade)), # type: ignore
f'("var(--"+{str(color_state_name)}.color+"-"+(((__to_string) => __to_string.toString())({str(color_state_name)}.shade))+")")',
f'("var(--"+{color_state_name!s}.color+"-"+(((__to_string) => __to_string.toString())({color_state_name!s}.shade))+")")',
Color,
),
(
create_color_var(
rx.color(ColorState.color, ColorState.shade, ColorState.alpha) # type: ignore
),
f'("var(--"+{str(color_state_name)}.color+"-"+({str(color_state_name)}.alpha ? "a" : "")+(((__to_string) => __to_string.toString())({str(color_state_name)}.shade))+")")',
f'("var(--"+{color_state_name!s}.color+"-"+({color_state_name!s}.alpha ? "a" : "")+(((__to_string) => __to_string.toString())({color_state_name!s}.shade))+")")',
Color,
),
(
create_color_var(rx.color(f"{ColorState.color}", f"{ColorState.shade}")), # type: ignore
f'("var(--"+{str(color_state_name)}.color+"-"+{str(color_state_name)}.shade+")")',
f'("var(--"+{color_state_name!s}.color+"-"+{color_state_name!s}.shade+")")',
Color,
),
(
create_color_var(
rx.color(f"{ColorState.color_part}ato", f"{ColorState.shade}") # type: ignore
),
f'("var(--"+({str(color_state_name)}.color_part+"ato")+"-"+{str(color_state_name)}.shade+")")',
f'("var(--"+({color_state_name!s}.color_part+"ato")+"-"+{color_state_name!s}.shade+")")',
Color,
),
(
create_color_var(f'{rx.color(ColorState.color, f"{ColorState.shade}")}'), # type: ignore
f'("var(--"+{str(color_state_name)}.color+"-"+{str(color_state_name)}.shade+")")',
f'("var(--"+{color_state_name!s}.color+"-"+{color_state_name!s}.shade+")")',
str,
),
(
create_color_var(
f'{rx.color(f"{ColorState.color}", f"{ColorState.shade}")}' # type: ignore
),
f'("var(--"+{str(color_state_name)}.color+"-"+{str(color_state_name)}.shade+")")',
f'("var(--"+{color_state_name!s}.color+"-"+{color_state_name!s}.shade+")")',
str,
),
],
@ -82,7 +82,7 @@ def test_color(color, expected, expected_type: Union[Type[str], Type[Color]]):
),
(
rx.cond(True, rx.color(ColorState.color), rx.color(ColorState.color, 5)), # type: ignore
f'(true ? ("var(--"+{str(color_state_name)}.color+"-7)") : ("var(--"+{str(color_state_name)}.color+"-5)"))',
f'(true ? ("var(--"+{color_state_name!s}.color+"-7)") : ("var(--"+{color_state_name!s}.color+"-5)"))',
),
(
rx.match(
@ -93,7 +93,7 @@ def test_color(color, expected, expected_type: Union[Type[str], Type[Color]]):
),
'(() => { switch (JSON.stringify("condition")) {case JSON.stringify("first"): return ("var(--mint-7)");'
' break;case JSON.stringify("second"): return ("var(--tomato-5)"); break;default: '
f'return (("var(--"+{str(color_state_name)}.color+"-2)")); break;}};}})()',
f'return (("var(--"+{color_state_name!s}.color+"-2)")); break;}};}})()',
),
(
rx.match(
@ -103,9 +103,9 @@ def test_color(color, expected, expected_type: Union[Type[str], Type[Color]]):
rx.color(ColorState.color, 2), # type: ignore
),
'(() => { switch (JSON.stringify("condition")) {case JSON.stringify("first"): '
f'return (("var(--"+{str(color_state_name)}.color+"-7)")); break;case JSON.stringify("second"): '
f'return (("var(--"+{str(color_state_name)}.color+"-5)")); break;default: '
f'return (("var(--"+{str(color_state_name)}.color+"-2)")); break;}};}})()',
f'return (("var(--"+{color_state_name!s}.color+"-7)")); break;case JSON.stringify("second"): '
f'return (("var(--"+{color_state_name!s}.color+"-5)")); break;default: '
f'return (("var(--"+{color_state_name!s}.color+"-2)")); break;}};}})()',
),
],
)

View File

@ -96,7 +96,7 @@ def test_prop_cond(c1: Any, c2: Any):
c1 = json.dumps(c1)
if not isinstance(c2, Var):
c2 = json.dumps(c2)
assert str(prop_cond) == f"(true ? {str(c1)} : {str(c2)})"
assert str(prop_cond) == f"(true ? {c1!s} : {c2!s})"
def test_cond_no_mix():

View File

@ -108,7 +108,7 @@ def test_render_with_special_props():
)
)._render()
assert len(tag.special_props) == 1
assert list(tag.special_props)[0].equals(special_prop)
assert next(iter(tag.special_props)).equals(special_prop)
def test_event_triggers():

View File

@ -33,9 +33,9 @@ def test_html_fstring_create():
assert (
str(html.dangerouslySetInnerHTML) # type: ignore
== f'({{ ["__html"] : ("<p>Hello "+{str(TestState.myvar)}+"!</p>") }})'
== f'({{ ["__html"] : ("<p>Hello "+{TestState.myvar!s}+"!</p>") }})'
)
assert (
str(html)
== f'<div className={{"rx-Html"}} dangerouslySetInnerHTML={{{str(html.dangerouslySetInnerHTML)}}}/>' # type: ignore
== f'<div className={{"rx-Html"}} dangerouslySetInnerHTML={{{html.dangerouslySetInnerHTML!s}}}/>' # type: ignore
)

View File

@ -810,7 +810,8 @@ def test_component_create_unpack_tuple_child(test_component, element, expected):
comp = test_component.create(element)
assert len(comp.children) == 1
assert isinstance((fragment_wrapper := comp.children[0]), Fragment)
fragment_wrapper = comp.children[0]
assert isinstance(fragment_wrapper, Fragment)
assert fragment_wrapper.render() == expected

View File

@ -1479,17 +1479,20 @@ def test_add_page_component_returning_tuple():
app._compile_page("index")
app._compile_page("page2")
assert isinstance((fragment_wrapper := app.pages["index"].children[0]), Fragment)
assert isinstance((first_text := fragment_wrapper.children[0]), Text)
fragment_wrapper = app.pages["index"].children[0]
assert isinstance(fragment_wrapper, Fragment)
first_text = fragment_wrapper.children[0]
assert isinstance(first_text, Text)
assert str(first_text.children[0].contents) == '"first"' # type: ignore
assert isinstance((second_text := fragment_wrapper.children[1]), Text)
second_text = fragment_wrapper.children[1]
assert isinstance(second_text, Text)
assert str(second_text.children[0].contents) == '"second"' # type: ignore
# Test page with trailing comma.
assert isinstance(
(page2_fragment_wrapper := app.pages["page2"].children[0]), Fragment
)
assert isinstance((third_text := page2_fragment_wrapper.children[0]), Text)
page2_fragment_wrapper = app.pages["page2"].children[0]
assert isinstance(page2_fragment_wrapper, Fragment)
third_text = page2_fragment_wrapper.children[0]
assert isinstance(third_text, Text)
assert str(third_text.children[0].contents) == '"third"' # type: ignore

View File

@ -319,7 +319,7 @@ def test_remove_cookie_with_options():
assert spec.args[1][1].equals(LiteralVar.create(options))
assert (
format.format_event(spec)
== f'Event("_remove_cookie", {{key:"testkey",options:{str(LiteralVar.create(options))}}})'
== f'Event("_remove_cookie", {{key:"testkey",options:{LiteralVar.create(options)!s}}})'
)

View File

@ -2552,7 +2552,7 @@ def test_duplicate_substate_class(mocker):
class TestState(BaseState):
pass
class ChildTestState(TestState): # type: ignore # noqa
class ChildTestState(TestState): # type: ignore
pass
class ChildTestState(TestState): # type: ignore # noqa
@ -2669,23 +2669,23 @@ def test_state_union_optional():
c3r: Custom3 = Custom3(c2r=Custom2(c1r=Custom1(foo="")))
custom_union: Union[Custom1, Custom2, Custom3] = Custom1(foo="")
assert str(UnionState.c3.c2) == f'{str(UnionState.c3)}?.["c2"]' # type: ignore
assert str(UnionState.c3.c2.c1) == f'{str(UnionState.c3)}?.["c2"]?.["c1"]' # type: ignore
assert str(UnionState.c3.c2) == f'{UnionState.c3!s}?.["c2"]' # type: ignore
assert str(UnionState.c3.c2.c1) == f'{UnionState.c3!s}?.["c2"]?.["c1"]' # type: ignore
assert (
str(UnionState.c3.c2.c1.foo) == f'{str(UnionState.c3)}?.["c2"]?.["c1"]?.["foo"]' # type: ignore
str(UnionState.c3.c2.c1.foo) == f'{UnionState.c3!s}?.["c2"]?.["c1"]?.["foo"]' # type: ignore
)
assert (
str(UnionState.c3.c2.c1r.foo) == f'{str(UnionState.c3)}?.["c2"]?.["c1r"]["foo"]' # type: ignore
str(UnionState.c3.c2.c1r.foo) == f'{UnionState.c3!s}?.["c2"]?.["c1r"]["foo"]' # type: ignore
)
assert str(UnionState.c3.c2r.c1) == f'{str(UnionState.c3)}?.["c2r"]["c1"]' # type: ignore
assert str(UnionState.c3.c2r.c1) == f'{UnionState.c3!s}?.["c2r"]["c1"]' # type: ignore
assert (
str(UnionState.c3.c2r.c1.foo) == f'{str(UnionState.c3)}?.["c2r"]["c1"]?.["foo"]' # type: ignore
str(UnionState.c3.c2r.c1.foo) == f'{UnionState.c3!s}?.["c2r"]["c1"]?.["foo"]' # type: ignore
)
assert (
str(UnionState.c3.c2r.c1r.foo) == f'{str(UnionState.c3)}?.["c2r"]["c1r"]["foo"]' # type: ignore
str(UnionState.c3.c2r.c1r.foo) == f'{UnionState.c3!s}?.["c2r"]["c1r"]["foo"]' # type: ignore
)
assert str(UnionState.c3i.c2) == f'{str(UnionState.c3i)}["c2"]' # type: ignore
assert str(UnionState.c3r.c2) == f'{str(UnionState.c3r)}["c2"]' # type: ignore
assert str(UnionState.c3i.c2) == f'{UnionState.c3i!s}["c2"]' # type: ignore
assert str(UnionState.c3r.c2) == f'{UnionState.c3r!s}["c2"]' # type: ignore
assert UnionState.custom_union.foo is not None # type: ignore
assert UnionState.custom_union.c1 is not None # type: ignore
assert UnionState.custom_union.c1r is not None # type: ignore

View File

@ -1770,7 +1770,7 @@ def test_valid_var_operations(operand1_var: Var, operand2_var, operators: List[s
)
def test_invalid_var_operations(operand1_var: Var, operand2_var, operators: List[str]):
for operator in operators:
print(f"testing {operator} on {str(operand1_var)} and {str(operand2_var)}")
print(f"testing {operator} on {operand1_var!s} and {operand2_var!s}")
with pytest.raises(TypeError):
print(eval(f"operand1_var {operator} operand2_var"))
# operand1_var.operation(op=operator, other=operand2_var)

View File

@ -17,7 +17,7 @@ def test_validate_literal_error_msg(params, allowed_value_str, value_str):
types.validate_literal(*params)
assert (
err.value.args[0] == f"prop value for {str(params[0])} of the `{params[-1]}` "
err.value.args[0] == f"prop value for {params[0]!s} of the `{params[-1]}` "
f"component should be one of the following: {allowed_value_str}. Got {value_str} instead"
)