-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Update StringVar to match Python str behavior (#5417)
#6596
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| `StringVar` now includes `lstrip` and `rstrip` methods. The `strip` method now accepts an optional `chars` argument for consistency with Python’s str API. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -674,6 +674,20 @@ def lower(self) -> StringVar: | |
| """ | ||
| return string_lower_operation(self) | ||
|
|
||
| def lstrip(self, chars: StringVar | str | None = None) -> StringVar: | ||
| """Left strip the string. | ||
|
|
||
| Args: | ||
| chars: Characters to remove from the left side. If None, strip whitespace. | ||
|
|
||
| Returns: | ||
| The string lstrip operation. | ||
| """ | ||
| if chars is not None and not isinstance(chars, (StringVar, str)): | ||
| raise_unsupported_operand_types("lstrip", (type(self), type(chars))) | ||
|
|
||
| return string_lstrip_operation(self, chars) | ||
|
|
||
| def upper(self) -> StringVar: | ||
| """Convert the string to uppercase. | ||
|
|
||
|
|
@@ -698,13 +712,19 @@ def capitalize(self) -> StringVar: | |
| """ | ||
| return string_capitalize_operation(self) | ||
|
|
||
| def strip(self) -> StringVar: | ||
| def strip(self, chars: StringVar | str | None = None) -> StringVar: | ||
| """Strip the string. | ||
|
|
||
| Args: | ||
| chars: Characters to remove from both ends. If None, strip whitespace. | ||
|
|
||
| Returns: | ||
| The string strip operation. | ||
| """ | ||
| return string_strip_operation(self) | ||
| if chars is not None and not isinstance(chars, (StringVar, str)): | ||
| raise_unsupported_operand_types("strip", (type(self), type(chars))) | ||
|
|
||
| return string_strip_operation(self, chars) | ||
|
|
||
| def reversed(self) -> StringVar: | ||
| """Reverse the string. | ||
|
|
@@ -714,6 +734,20 @@ def reversed(self) -> StringVar: | |
| """ | ||
| return self.split().reverse().join() | ||
|
|
||
| def rstrip(self, chars: StringVar | str | None = None) -> StringVar: | ||
| """Right strip the string. | ||
|
|
||
| Args: | ||
| chars: Characters to remove from the right side. If None, strip whitespace. | ||
|
|
||
| Returns: | ||
| The string rstrip operation. | ||
| """ | ||
| if chars is not None and not isinstance(chars, (StringVar, str)): | ||
| raise_unsupported_operand_types("rstrip", (type(self), type(chars))) | ||
|
|
||
| return string_rstrip_operation(self, chars) | ||
|
|
||
| def contains( | ||
| self, other: StringVar | str, field: StringVar | str | None = None | ||
| ) -> BooleanVar: | ||
|
|
@@ -972,16 +1006,48 @@ def string_capitalize_operation(string: StringVar[Any]): | |
|
|
||
|
|
||
| @var_operation | ||
| def string_strip_operation(string: StringVar[Any]): | ||
| """Strip a string. | ||
| def string_strip_operation( | ||
| string: StringVar[Any], | ||
| chars: StringVar[Any] | str | None = None, | ||
| ): | ||
| """Strip a string.""" | ||
| if str(chars) == "null": | ||
| return var_operation_return(js_expression=f"{string}.trim()", var_type=str) | ||
|
|
||
| Args: | ||
| string: The string to strip. | ||
| return var_operation_return( | ||
| js_expression=f"{string}.replace(/^[{chars}]+|[{chars}]+$/g, '')", | ||
| var_type=str, | ||
| ) | ||
|
Comment on lines
+1017
to
+1020
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Characters such as |
||
|
|
||
| Returns: | ||
| The stripped string. | ||
| """ | ||
| return var_operation_return(js_expression=f"{string}.trim()", var_type=str) | ||
|
|
||
| @var_operation | ||
| def string_lstrip_operation( | ||
| string: StringVar[Any], | ||
| chars: StringVar[Any] | str | None = None, | ||
| ): | ||
| """Left strip a string.""" | ||
| if str(chars) == "null": | ||
| return var_operation_return(js_expression=f"{string}.trimStart()", var_type=str) | ||
|
|
||
| return var_operation_return( | ||
| js_expression=f"{string}.replace(/^[{chars}]+/, '')", | ||
| var_type=str, | ||
| ) | ||
|
|
||
|
|
||
| @var_operation | ||
| def string_rstrip_operation( | ||
| string: StringVar[Any], | ||
| chars: StringVar[Any] | str | None = None, | ||
| ): | ||
| """Right strip a string.""" | ||
| if str(chars) == "null": | ||
| return var_operation_return(js_expression=f"{string}.trimEnd()", var_type=str) | ||
|
|
||
| return var_operation_return( | ||
| js_expression=f"{string}.replace(/[{chars}]+$/, '')", | ||
| var_type=str, | ||
| ) | ||
|
|
||
|
|
||
| @var_operation | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When
charsis a plain Pythonstr(e.g.,"abc"), the@var_operationwrapper converts it toLiteralVar.create("abc"), whose JavaScript serialization is"abc"(with quotes). Interpolating that into the regex literal produces/^["abc"]+.../— the double-quote characters become literal members of the character class, so.strip("abc")would also strip"from the string.For a
StringVarstate-variable, the JS variable expression (e.g.,state.chars) is embedded verbatim inside the literal regex/.../, which is static syntax — it does not reference the variable at runtime and instead treats the characters of the expression name as the set to strip. The same problem exists identically instring_lstrip_operationandstring_rstrip_operation.