Handle ruff complaints in string module
This commit is contained in:
parent
de70147752
commit
ce26e25923
@ -125,6 +125,8 @@ ignore = [
|
||||
"B011", # assert false. we don't use python -O
|
||||
"B028", # we don't need explicit stacklevel for warnings
|
||||
"D100", "D101", "D102", "D104", "D105", "D107", "D203", "D213", "D401", "D402", "D106", "D205", # docstring stuff
|
||||
"G004", # logging (no f-strings)
|
||||
"RUF012", # disallows mutable class variables unless annotated
|
||||
"DTZ005", # we don't need that
|
||||
"RET505", # sacrifices visual discernability of control flow paths for brevity (regarding return statements)
|
||||
# remaining rules from https://github.com/psf/black/blob/main/.flake8 (except W503)
|
||||
|
@ -1,6 +1,4 @@
|
||||
"""
|
||||
This is a copy of sensai.util.string from sensAI commit d7b4afcc89b4d2e922a816cb07dffde27f297354
|
||||
"""
|
||||
"""Copy of sensai.util.string from sensAI commit d7b4afcc89b4d2e922a816cb07dffde27f297354."""
|
||||
|
||||
|
||||
import functools
|
||||
@ -9,7 +7,10 @@ import re
|
||||
import sys
|
||||
import types
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Union, List, Dict, Any, Sequence, Iterable, Optional, Mapping, Callable
|
||||
from collections.abc import Callable, Iterable, Mapping, Sequence
|
||||
from typing import (
|
||||
Any,
|
||||
)
|
||||
|
||||
reCommaWhitespacePotentiallyBreaks = re.compile(r",\s+")
|
||||
|
||||
@ -17,18 +18,16 @@ log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class StringConverter(ABC):
|
||||
"""
|
||||
Abstraction for a string conversion mechanism
|
||||
"""
|
||||
"""Abstraction for a string conversion mechanism."""
|
||||
|
||||
@abstractmethod
|
||||
def to_string(self, x) -> str:
|
||||
pass
|
||||
|
||||
|
||||
def dict_string(d: Mapping, brackets: Optional[str] = None, converter: StringConverter = None):
|
||||
"""
|
||||
Converts a dictionary to a string of the form "<key>=<value>, <key>=<value>, ...", optionally enclosed
|
||||
by brackets
|
||||
def dict_string(d: Mapping, brackets: str | None = None, converter: StringConverter = None):
|
||||
"""Converts a dictionary to a string of the form "<key>=<value>, <key>=<value>, ...", optionally enclosed
|
||||
by brackets.
|
||||
|
||||
:param d: the dictionary
|
||||
:param brackets: a two-character string containing the opening and closing bracket to use, e.g. ``"{}"``;
|
||||
@ -36,16 +35,20 @@ def dict_string(d: Mapping, brackets: Optional[str] = None, converter: StringCon
|
||||
:param converter: the string converter to use for values
|
||||
:return: the string representation
|
||||
"""
|
||||
s = ', '.join([f'{k}={to_string(v, converter=converter, context=k)}' for k, v in d.items()])
|
||||
s = ", ".join([f"{k}={to_string(v, converter=converter, context=k)}" for k, v in d.items()])
|
||||
if brackets is not None:
|
||||
return brackets[:1] + s + brackets[-1:]
|
||||
else:
|
||||
return s
|
||||
|
||||
|
||||
def list_string(l: Iterable[Any], brackets="[]", quote: Optional[str] = None, converter: StringConverter = None):
|
||||
"""
|
||||
Converts a list or any other iterable to a string of the form "[<value>, <value>, ...]", optionally enclosed
|
||||
def list_string(
|
||||
l: Iterable[Any],
|
||||
brackets="[]",
|
||||
quote: str | None = None,
|
||||
converter: StringConverter = None,
|
||||
):
|
||||
"""Converts a list or any other iterable to a string of the form "[<value>, <value>, ...]", optionally enclosed
|
||||
by different brackets or with the values quoted.
|
||||
|
||||
:param l: the list
|
||||
@ -55,22 +58,28 @@ def list_string(l: Iterable[Any], brackets="[]", quote: Optional[str] = None, co
|
||||
:param converter: the string converter to use for values
|
||||
:return: the string representation
|
||||
"""
|
||||
|
||||
def item(x):
|
||||
x = to_string(x, converter=converter, context="list")
|
||||
if quote is not None:
|
||||
return quote + x + quote
|
||||
else:
|
||||
return x
|
||||
s = ", ".join((item(x) for x in l))
|
||||
|
||||
s = ", ".join(item(x) for x in l)
|
||||
if brackets is not None:
|
||||
return brackets[:1] + s + brackets[-1:]
|
||||
else:
|
||||
return s
|
||||
|
||||
|
||||
def to_string(x, converter: StringConverter = None, apply_converter_to_non_complex_objects=True, context=None):
|
||||
"""
|
||||
Converts the given object to a string, with proper handling of lists, tuples and dictionaries, optionally using a converter.
|
||||
def to_string(
|
||||
x,
|
||||
converter: StringConverter = None,
|
||||
apply_converter_to_non_complex_objects=True,
|
||||
context=None,
|
||||
):
|
||||
"""Converts the given object to a string, with proper handling of lists, tuples and dictionaries, optionally using a converter.
|
||||
The conversion also removes unwanted line breaks (as present, in particular, in sklearn's string representations).
|
||||
|
||||
:param x: the object to convert
|
||||
@ -83,13 +92,13 @@ def to_string(x, converter: StringConverter = None, apply_converter_to_non_compl
|
||||
:return: the string representation
|
||||
"""
|
||||
try:
|
||||
if type(x) == list:
|
||||
if isinstance(x, list):
|
||||
return list_string(x, converter=converter)
|
||||
elif type(x) == tuple:
|
||||
elif isinstance(x, tuple):
|
||||
return list_string(x, brackets="()", converter=converter)
|
||||
elif type(x) == dict:
|
||||
elif isinstance(x, dict):
|
||||
return dict_string(x, brackets="{}", converter=converter)
|
||||
elif type(x) == types.MethodType:
|
||||
elif isinstance(x, types.MethodType):
|
||||
# could be bound method of a ToStringMixin instance (which would print the repr of the instance, which can potentially cause
|
||||
# an infinite recursion)
|
||||
return f"Method[{x.__name__}]"
|
||||
@ -100,16 +109,19 @@ def to_string(x, converter: StringConverter = None, apply_converter_to_non_compl
|
||||
s = str(x)
|
||||
|
||||
# remove any unwanted line breaks and indentation after commas (as generated, for example, by sklearn objects)
|
||||
s = reCommaWhitespacePotentiallyBreaks.sub(", ", s)
|
||||
return reCommaWhitespacePotentiallyBreaks.sub(", ", s)
|
||||
|
||||
return s
|
||||
except RecursionError as e:
|
||||
except RecursionError:
|
||||
log.error(f"Recursion in string conversion detected; context={context}")
|
||||
raise
|
||||
|
||||
|
||||
def object_repr(obj, member_names_or_dict: Union[List[str], Dict[str, Any]]):
|
||||
if type(member_names_or_dict) == dict:
|
||||
def object_repr(obj, member_names_or_dict: list[str] | dict[str, Any]):
|
||||
"""Creates a string representation for the given object based on the given members.
|
||||
|
||||
The string takes the form "ClassName[attr1=value1, attr2=value2, ...]"
|
||||
"""
|
||||
if isinstance(member_names_or_dict, dict):
|
||||
members_dict = member_names_or_dict
|
||||
else:
|
||||
members_dict = {m: to_string(getattr(obj, m)) for m in member_names_or_dict}
|
||||
@ -117,9 +129,7 @@ def object_repr(obj, member_names_or_dict: Union[List[str], Dict[str, Any]]):
|
||||
|
||||
|
||||
def or_regex_group(allowed_names: Sequence[str]):
|
||||
"""
|
||||
|
||||
:param allowed_names: strings to include as literals in the regex
|
||||
""":param allowed_names: strings to include as literals in the regex
|
||||
:return: a regular expression string of the form (<name1>| ...|<nameN>), which any of the given names
|
||||
"""
|
||||
allowed_names = [re.escape(name) for name in allowed_names]
|
||||
@ -127,6 +137,12 @@ def or_regex_group(allowed_names: Sequence[str]):
|
||||
|
||||
|
||||
def function_name(x: Callable) -> str:
|
||||
"""Attempts to retrieve the name of the given function/callable object, taking the possibility
|
||||
of the function being defined via functools.partial into account.
|
||||
|
||||
:param x: a callable object
|
||||
:return: name of the function or str(x) as a fallback
|
||||
"""
|
||||
if isinstance(x, functools.partial):
|
||||
return function_name(x.func)
|
||||
elif hasattr(x, "__name__"):
|
||||
@ -136,8 +152,7 @@ def function_name(x: Callable) -> str:
|
||||
|
||||
|
||||
class ToStringMixin:
|
||||
"""
|
||||
Provides implementations for ``__str__`` and ``__repr__`` which are based on the format ``"<class name>[<object info>]"`` and
|
||||
"""Provides implementations for ``__str__`` and ``__repr__`` which are based on the format ``"<class name>[<object info>]"`` and
|
||||
``"<class name>[id=<object id>, <object info>]"`` respectively, where ``<object info>`` is usually a list of entries of the
|
||||
form ``"<name>=<value>, ..."``.
|
||||
|
||||
@ -174,23 +189,23 @@ class ToStringMixin:
|
||||
.. automethod:: _tostring_additional_entries
|
||||
.. automethod:: _tostring_exclude_private
|
||||
"""
|
||||
|
||||
_TOSTRING_INCLUDE_ALL = "__all__"
|
||||
|
||||
def _tostring_class_name(self):
|
||||
"""
|
||||
:return: the string use for <class name> in the string representation ``"<class name>[<object info]"``
|
||||
"""
|
||||
""":return: the string use for <class name> in the string representation ``"<class name>[<object info]"``"""
|
||||
return type(self).__qualname__
|
||||
|
||||
def _tostring_properties(self,
|
||||
exclude: Optional[Union[str, Iterable[str]]] = None,
|
||||
include: Optional[Union[str, Iterable[str]]] = None,
|
||||
exclude_exceptions: Optional[List[str]] = None,
|
||||
include_forced: Optional[List[str]] = None,
|
||||
additional_entries: Dict[str, Any] = None,
|
||||
converter: StringConverter = None) -> str:
|
||||
"""
|
||||
Creates a string of the class attributes, with optional exclusions/inclusions/additions.
|
||||
def _tostring_properties(
|
||||
self,
|
||||
exclude: str | Iterable[str] | None = None,
|
||||
include: str | Iterable[str] | None = None,
|
||||
exclude_exceptions: list[str] | None = None,
|
||||
include_forced: list[str] | None = None,
|
||||
additional_entries: dict[str, Any] | None = None,
|
||||
converter: StringConverter = None,
|
||||
) -> str:
|
||||
"""Creates a string of the class attributes, with optional exclusions/inclusions/additions.
|
||||
Exclusions take precedence over inclusions.
|
||||
|
||||
:param exclude: attributes to be excluded
|
||||
@ -201,10 +216,11 @@ class ToStringMixin:
|
||||
:param converter: the string converter to use; if None, use default (which avoids infinite recursions)
|
||||
:return: a string containing entry/property names and values
|
||||
"""
|
||||
|
||||
def mklist(x):
|
||||
if x is None:
|
||||
return []
|
||||
if type(x) == str:
|
||||
if isinstance(x, str):
|
||||
return [x]
|
||||
return x
|
||||
|
||||
@ -219,17 +235,21 @@ class ToStringMixin:
|
||||
if k in exclude:
|
||||
return True
|
||||
if self._tostring_exclude_private():
|
||||
is_private = k.startswith("_")
|
||||
return is_private
|
||||
return k.startswith("_")
|
||||
else:
|
||||
return False
|
||||
|
||||
# determine relevant attribute dictionary
|
||||
if len(include) == 1 and include[0] == self._TOSTRING_INCLUDE_ALL: # exclude semantics (include everything by default)
|
||||
if (
|
||||
len(include) == 1 and include[0] == self._TOSTRING_INCLUDE_ALL
|
||||
): # exclude semantics (include everything by default)
|
||||
attribute_dict = self.__dict__
|
||||
else: # include semantics (include only inclusions)
|
||||
attribute_dict = {k: getattr(self, k) for k in set(include + include_forced)
|
||||
if hasattr(self, k) and k != self._TOSTRING_INCLUDE_ALL}
|
||||
attribute_dict = {
|
||||
k: getattr(self, k)
|
||||
for k in set(include + include_forced)
|
||||
if hasattr(self, k) and k != self._TOSTRING_INCLUDE_ALL
|
||||
}
|
||||
|
||||
# apply exclusions and remove underscores from attribute names
|
||||
d = {k.strip("_"): v for k, v in attribute_dict.items() if not is_excluded(k)}
|
||||
@ -242,8 +262,7 @@ class ToStringMixin:
|
||||
return dict_string(d, converter=converter)
|
||||
|
||||
def _tostring_object_info(self) -> str:
|
||||
"""
|
||||
Override this method to use a fully custom definition of the ``<object info>`` part in the full string
|
||||
"""Override this method to use a fully custom definition of the ``<object info>`` part in the full string
|
||||
representation ``"<class name>[<object info>]"`` to be generated.
|
||||
As soon as this method is overridden, any property-based exclusions, inclusions, etc. will have no effect
|
||||
(unless the implementation is specifically designed to make use of them - as is the default
|
||||
@ -253,13 +272,16 @@ class ToStringMixin:
|
||||
|
||||
:return: a string containing the string to use for ``<object info>``
|
||||
"""
|
||||
return self._tostring_properties(exclude=self._tostring_excludes(), include=self._tostring_includes(),
|
||||
exclude_exceptions=self._tostring_exclude_exceptions(), include_forced=self._tostring_includes_forced(),
|
||||
additional_entries=self._tostring_additional_entries())
|
||||
return self._tostring_properties(
|
||||
exclude=self._tostring_excludes(),
|
||||
include=self._tostring_includes(),
|
||||
exclude_exceptions=self._tostring_exclude_exceptions(),
|
||||
include_forced=self._tostring_includes_forced(),
|
||||
additional_entries=self._tostring_additional_entries(),
|
||||
)
|
||||
|
||||
def _tostring_excludes(self) -> List[str]:
|
||||
"""
|
||||
Makes the string representation exclude the returned attributes.
|
||||
def _tostring_excludes(self) -> list[str]:
|
||||
"""Makes the string representation exclude the returned attributes.
|
||||
This method can be conveniently overridden by subclasses which can call super and extend the list returned.
|
||||
|
||||
This method will only have no effect if :meth:`_toStringObjectInfo` is overridden to not use its result.
|
||||
@ -268,9 +290,8 @@ class ToStringMixin:
|
||||
"""
|
||||
return []
|
||||
|
||||
def _tostring_includes(self) -> List[str]:
|
||||
"""
|
||||
Makes the string representation include only the returned attributes (i.e. introduces inclusion semantics);
|
||||
def _tostring_includes(self) -> list[str]:
|
||||
"""Makes the string representation include only the returned attributes (i.e. introduces inclusion semantics);
|
||||
By default, the list contains only a marker element, which is interpreted as "all attributes included".
|
||||
|
||||
This method can be conveniently overridden by sub-classes which can call super and extend the list returned.
|
||||
@ -287,9 +308,8 @@ class ToStringMixin:
|
||||
return [self._TOSTRING_INCLUDE_ALL]
|
||||
|
||||
# noinspection PyMethodMayBeStatic
|
||||
def _tostring_includes_forced(self) -> List[str]:
|
||||
"""
|
||||
Defines a list of attribute names that are required to be present in the string representation, regardless of the
|
||||
def _tostring_includes_forced(self) -> list[str]:
|
||||
"""Defines a list of attribute names that are required to be present in the string representation, regardless of the
|
||||
instance using include semantics or exclude semantics, thus facilitating added inclusions in sub-classes.
|
||||
|
||||
This method will have no effect if :meth:`_toStringObjectInfo` is overridden to not use its result.
|
||||
@ -298,22 +318,18 @@ class ToStringMixin:
|
||||
"""
|
||||
return []
|
||||
|
||||
def _tostring_additional_entries(self) -> Dict[str, Any]:
|
||||
"""
|
||||
:return: a dictionary of entries to be included in the ``<object info>`` part of the string representation
|
||||
"""
|
||||
def _tostring_additional_entries(self) -> dict[str, Any]:
|
||||
""":return: a dictionary of entries to be included in the ``<object info>`` part of the string representation"""
|
||||
return {}
|
||||
|
||||
def _tostring_exclude_private(self) -> bool:
|
||||
"""
|
||||
:return: whether to exclude properties that are private (start with an underscore); explicitly included attributes
|
||||
will still be considered - as will properties exempt from the rule via :meth:`toStringExcludeException`.
|
||||
""":return: whether to exclude properties that are private (start with an underscore); explicitly included attributes
|
||||
will still be considered - as will properties exempt from the rule via :meth:`toStringExcludeException`.
|
||||
"""
|
||||
return False
|
||||
|
||||
def _tostring_exclude_exceptions(self) -> List[str]:
|
||||
"""
|
||||
Defines attribute names which should not be excluded even though other rules (particularly the exclusion of private members
|
||||
def _tostring_exclude_exceptions(self) -> list[str]:
|
||||
"""Defines attribute names which should not be excluded even though other rules (particularly the exclusion of private members
|
||||
via :meth:`_toStringExcludePrivate`) would otherwise exclude them.
|
||||
|
||||
:return: a list of attribute names
|
||||
@ -331,8 +347,7 @@ class ToStringMixin:
|
||||
return f"{self._tostring_class_name()}[{info}]"
|
||||
|
||||
def pprint(self, file=sys.stdout):
|
||||
"""
|
||||
Prints a prettily formatted string representation of the object (with line breaks and indentations)
|
||||
"""Prints a prettily formatted string representation of the object (with line breaks and indentations)
|
||||
to ``stdout`` or the given file.
|
||||
|
||||
:param file: the file to print to
|
||||
@ -340,25 +355,21 @@ class ToStringMixin:
|
||||
print(self.pprints(), file=file)
|
||||
|
||||
def pprints(self) -> str:
|
||||
"""
|
||||
:return: a prettily formatted string representation with line breaks and indentations
|
||||
"""
|
||||
""":return: a prettily formatted string representation with line breaks and indentations"""
|
||||
return pretty_string_repr(self)
|
||||
|
||||
class _StringConverterAvoidToStringMixinRecursion(StringConverter):
|
||||
"""
|
||||
Avoids recursions when converting objects implementing :class:`ToStringMixin` which may contain themselves to strings.
|
||||
"""Avoids recursions when converting objects implementing :class:`ToStringMixin` which may contain themselves to strings.
|
||||
Use of this object prevents infinite recursions caused by a :class:`ToStringMixin` instance recursively containing itself in
|
||||
either a property of another :class:`ToStringMixin`, a list or a tuple.
|
||||
It handles all :class:`ToStringMixin` instances recursively encountered.
|
||||
|
||||
A previously handled instance is converted to a string of the form "<class name>[<<]".
|
||||
"""
|
||||
|
||||
def __init__(self, *handled_objects: "ToStringMixin"):
|
||||
"""
|
||||
:param handled_objects: objects which are initially assumed to have been handled already
|
||||
"""
|
||||
self._handled_to_string_mixin_ids = set([id(o) for o in handled_objects])
|
||||
""":param handled_objects: objects which are initially assumed to have been handled already"""
|
||||
self._handled_to_string_mixin_ids = {id(o) for o in handled_objects}
|
||||
|
||||
def to_string(self, x) -> str:
|
||||
if isinstance(x, ToStringMixin):
|
||||
@ -368,11 +379,15 @@ class ToStringMixin:
|
||||
self._handled_to_string_mixin_ids.add(oid)
|
||||
return str(self._ToStringMixinProxy(x, self))
|
||||
else:
|
||||
return to_string(x, converter=self, apply_converter_to_non_complex_objects=False, context=x.__class__)
|
||||
return to_string(
|
||||
x,
|
||||
converter=self,
|
||||
apply_converter_to_non_complex_objects=False,
|
||||
context=x.__class__,
|
||||
)
|
||||
|
||||
class _ToStringMixinProxy:
|
||||
"""
|
||||
A proxy object which wraps a ToStringMixin to ensure that the converter is applied when creating the properties string.
|
||||
"""A proxy object which wraps a ToStringMixin to ensure that the converter is applied when creating the properties string.
|
||||
The proxy is to achieve that all ToStringMixin methods that aren't explicitly overwritten are bound to this proxy
|
||||
(rather than the original object), such that the transitive call to _toStringProperties will call the new
|
||||
implementation.
|
||||
@ -392,9 +407,15 @@ class ToStringMixin:
|
||||
return self.x._tostring_class_name()
|
||||
|
||||
def __getattr__(self, attr: str):
|
||||
if attr.startswith("_tostring"): # ToStringMixin method which we may bind to use this proxy to ensure correct transitive call
|
||||
if attr.startswith(
|
||||
"_tostring",
|
||||
): # ToStringMixin method which we may bind to use this proxy to ensure correct transitive call
|
||||
method = getattr(self.x.__class__, attr)
|
||||
obj = self if attr in self.TOSTRING_METHODS_TRANSITIVELY_CALLING_TOSTRINGPROPERTIES else self.x
|
||||
obj = (
|
||||
self
|
||||
if attr in self.TOSTRING_METHODS_TRANSITIVELY_CALLING_TOSTRINGPROPERTIES
|
||||
else self.x
|
||||
)
|
||||
return lambda *args, **kwargs: method(obj, *args, **kwargs)
|
||||
else:
|
||||
return getattr(self.x, attr)
|
||||
@ -404,8 +425,7 @@ class ToStringMixin:
|
||||
|
||||
|
||||
def pretty_string_repr(s: Any, initial_indentation_level=0, indentation_string=" "):
|
||||
"""
|
||||
Creates a pretty string representation (using indentations) from the given object/string representation (as generated, for example, via
|
||||
"""Creates a pretty string representation (using indentations) from the given object/string representation (as generated, for example, via
|
||||
ToStringMixin). An indentation level is added for every opening bracket.
|
||||
|
||||
:param s: an object or object string representation
|
||||
@ -413,7 +433,7 @@ def pretty_string_repr(s: Any, initial_indentation_level=0, indentation_string="
|
||||
:param indentation_string: the string which corresponds to a single indentation level
|
||||
:return: a reformatted version of the input string with added indentations and line breaks
|
||||
"""
|
||||
if type(s) != str:
|
||||
if not isinstance(s, str):
|
||||
s = str(s)
|
||||
indent = initial_indentation_level
|
||||
result = indentation_string * indent
|
||||
@ -425,7 +445,7 @@ def pretty_string_repr(s: Any, initial_indentation_level=0, indentation_string="
|
||||
|
||||
def take(cnt=1):
|
||||
nonlocal result, i
|
||||
result += s[i:i+cnt]
|
||||
result += s[i : i + cnt]
|
||||
i += cnt
|
||||
|
||||
def find_matching(j):
|
||||
@ -455,9 +475,11 @@ def pretty_string_repr(s: Any, initial_indentation_level=0, indentation_string="
|
||||
if i_match is not None:
|
||||
k = i_match + 1
|
||||
full_match = s[i:k]
|
||||
take_full_match_without_break = is_quote or not("=" in full_match and "," in full_match)
|
||||
take_full_match_without_break = is_quote or not (
|
||||
"=" in full_match and "," in full_match
|
||||
)
|
||||
if take_full_match_without_break:
|
||||
take(k-i)
|
||||
take(k - i)
|
||||
if not take_full_match_without_break:
|
||||
take(1)
|
||||
indent += 1
|
||||
@ -465,7 +487,7 @@ def pretty_string_repr(s: Any, initial_indentation_level=0, indentation_string="
|
||||
elif s[i] in "])":
|
||||
take(1)
|
||||
indent -= 1
|
||||
elif s[i:i+2] == ", ":
|
||||
elif s[i : i + 2] == ", ":
|
||||
take(2)
|
||||
nl()
|
||||
else:
|
||||
@ -475,12 +497,10 @@ def pretty_string_repr(s: Any, initial_indentation_level=0, indentation_string="
|
||||
|
||||
|
||||
class TagBuilder:
|
||||
"""
|
||||
Assists in building strings made up of components that are joined via a glue string
|
||||
"""
|
||||
"""Assists in building strings made up of components that are joined via a glue string."""
|
||||
|
||||
def __init__(self, *initial_components: str, glue="_"):
|
||||
"""
|
||||
:param initial_components: initial components to always include at the beginning
|
||||
""":param initial_components: initial components to always include at the beginning
|
||||
:param glue: the glue string which joins components
|
||||
"""
|
||||
self.glue = glue
|
||||
@ -490,8 +510,7 @@ class TagBuilder:
|
||||
self.components.append(component)
|
||||
|
||||
def with_conditional(self, cond: bool, component: str):
|
||||
"""
|
||||
Conditionally adds the given component
|
||||
"""Conditionally adds the given component.
|
||||
|
||||
:param cond: the condition
|
||||
:param component: the component to add if the condition holds
|
||||
@ -502,8 +521,7 @@ class TagBuilder:
|
||||
return self
|
||||
|
||||
def with_alternative(self, cond: bool, true_component: str, false_component: str):
|
||||
"""
|
||||
Adds a component depending on a condition
|
||||
"""Adds a component depending on a condition.
|
||||
|
||||
:param cond: the condition
|
||||
:param true_component: the component to add if the condition holds
|
||||
@ -514,7 +532,5 @@ class TagBuilder:
|
||||
return self
|
||||
|
||||
def build(self):
|
||||
"""
|
||||
:return: the string (with all components joined)
|
||||
"""
|
||||
""":return: the string (with all components joined)"""
|
||||
return self.glue.join(self.components)
|
||||
|
Loading…
x
Reference in New Issue
Block a user