Skip to content

Strings

Utility Helpers Module

STR_BOOL_MAP = {'1': True, 'y': True, 't': True, 'on': True, 'yes': True, 'true': True, '0': False, 'n': False, 'f': False, 'no': False, 'off': False, 'false': False} module-attribute

  • Util classes

StrEnum

Bases: str, Enum

Enum where the value is always a string.

Source code in src/utils/strings.py
39
40
41
42
43
44
45
46
47
48
49
50
51
class StrEnum(str, Enum, metaclass=StrEnumMeta):
    """Enum where the value is always a string."""

    def __str__(self) -> str:
        return self.value

    @cached_property
    def value(self) -> str:
        return str(self._value_)

    @cached_property
    def Default(self) -> str:
        return "default"

StrEnumMeta

Bases: EnumMeta

Metaclass for StrEnum.

Source code in src/utils/strings.py
32
33
34
35
36
class StrEnumMeta(EnumMeta):
    """Metaclass for StrEnum."""

    def __contains__(cls, item: str):
        return item in cls._value2member_map_

get_bullet_points(text, char='•')

Turns a list of strings into a joined string bullet point list. @param text: List of strings. @param char: Character to use as bullet. @return: Joined string with bullet points and newlines.

Source code in src/utils/strings.py
228
229
230
231
232
233
234
235
236
237
238
def get_bullet_points(text: list[str], char: str = '•') -> str:
    """
    Turns a list of strings into a joined string bullet point list.
    @param text: List of strings.
    @param char: Character to use as bullet.
    @return: Joined string with bullet points and newlines.
    """
    if not text:
        return ""
    bullet = f"\n{char} "
    return str(bullet + bullet.join(text))

get_line(text, i, sep='\n')

Get line by index from a multiline string.
@param text: Multiline string.
@param i: Index of the line.
@param sep: Newline separator to use for split, defaults to '

'. @return: Isolated line.

Source code in src/utils/strings.py
100
101
102
103
104
105
106
107
108
109
110
def get_line(text: str, i: int, sep: str = '\n') -> str:
    """
    Get line by index from a multiline string.
    @param text: Multiline string.
    @param i: Index of the line.
    @param sep: Newline separator to use for split, defaults to '\n'.
    @return: Isolated line.
    """
    if abs(i) > text.count('\n'):
        raise IndexError(f"Not enough lines in multiline string. Index of {i} is invalid.")
    return text.split(sep)[i]

get_lines(text, num, sep='\n')

Separate a number of lines from a multiline string.
@param text: Multiline string.
@param num: Number of lines to separate and return, negative integer for trailing lines.
@param sep: Newline separator to use for split, defaults to '

'. @return: Isolated lines.

Source code in src/utils/strings.py
113
114
115
116
117
118
119
120
121
122
123
124
125
def get_lines(text: str, num: int, sep: str = '\n') -> str:
    """
    Separate a number of lines from a multiline string.
    @param text: Multiline string.
    @param num: Number of lines to separate and return, negative integer for trailing lines.
    @param sep: Newline separator to use for split, defaults to '\n'.
    @return: Isolated lines.
    """
    if num == 0 or abs(num) > text.count('\n') + 1:
        return text
    if num < 0:
        return '\n'.join(text.split(sep)[num:])
    return '\n'.join(text.split(sep)[:num])

is_multiline(text)

Check if text or list of texts given contains multiline text (a newline character). @param text: String to check or list of strings to check. @return: True/False or list of True/False values.

Source code in src/utils/strings.py
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
def is_multiline(text: Union[str, list[str]]) -> Union[bool, list[bool]]:
    """
    Check if text or list of texts given contains multiline text (a newline character).
    @param text: String to check or list of strings to check.
    @return: True/False or list of True/False values.
    """
    # String Given
    if isinstance(text, str):
        if '\n' in text or '\r' in text:
            return True
        return False
    # List Given
    if isinstance(text, list):
        return [bool('\n' in t or '\r' in t) for t in text]
    # Invalid data type provided
    raise Exception("Invalid type passed to 'is_multiline', can only accept a string or list of strings.\n"
                    f"Received the value: {text}")

msg_bold(msg)

Wraps a console string with a bold tag. @param msg: Message to wrap. @return: Wrapped message.

Source code in src/utils/strings.py
170
171
172
173
174
175
176
def msg_bold(msg: str) -> str:
    """
    Wraps a console string with a bold tag.
    @param msg: Message to wrap.
    @return: Wrapped message.
    """
    return f"[b]{msg}[/b]"

msg_error(msg, reason=None)

Adds unified error color tag to Proxyshop console message. @param msg: String to add tag to. @param reason: Reason for the error, if needed. @return: Formatted string.

Source code in src/utils/strings.py
188
189
190
191
192
193
194
195
196
def msg_error(msg: str, reason: Optional[str] = None) -> str:
    """
    Adds unified error color tag to Proxyshop console message.
    @param msg: String to add tag to.
    @param reason: Reason for the error, if needed.
    @return: Formatted string.
    """
    msg = f'[color={ConsoleMessages.error}]{msg}[/color]'
    return f"{msg_bold(msg)} - {msg_italics(reason)}" if reason else msg

msg_info(msg)

Adds unified info color tag to Proxyshop console message. @param msg: String to add tag to. @return: Formatted string.

Source code in src/utils/strings.py
219
220
221
222
223
224
225
def msg_info(msg: str) -> str:
    """
    Adds unified info color tag to Proxyshop console message.
    @param msg: String to add tag to.
    @return: Formatted string.
    """
    return f'[color={ConsoleMessages.info}]{msg}[/color]'

msg_italics(msg)

Wraps a console string with an italics tag. @param msg: Message to wrap. @return: Wrapped message.

Source code in src/utils/strings.py
179
180
181
182
183
184
185
def msg_italics(msg: str) -> str:
    """
    Wraps a console string with an italics tag.
    @param msg: Message to wrap.
    @return: Wrapped message.
    """
    return f"[i]{msg}[/i]"

msg_success(msg)

Adds unified success color tag to Proxyshop console message. @param msg: String to add tag to. @return: Formatted string.

Source code in src/utils/strings.py
210
211
212
213
214
215
216
def msg_success(msg: str) -> str:
    """
    Adds unified success color tag to Proxyshop console message.
    @param msg: String to add tag to.
    @return: Formatted string.
    """
    return f'[color={ConsoleMessages.success}]{msg}[/color]'

msg_warn(msg, reason=None)

Adds unified warning color tag to Proxyshop console message. @param msg: String to add tag to. @param reason: Reason for the warning, if needed. @return: Formatted string.

Source code in src/utils/strings.py
199
200
201
202
203
204
205
206
207
def msg_warn(msg: str, reason: Optional[str] = None) -> str:
    """
    Adds unified warning color tag to Proxyshop console message.
    @param msg: String to add tag to.
    @param reason: Reason for the warning, if needed.
    @return: Formatted string.
    """
    msg = f'[color={ConsoleMessages.warning}]{msg}[/color]'
    return f"{msg_bold(msg)} - {msg_italics(reason)}" if reason else msg

normalize_str(st, no_space=False)

Normalizes a string for safe comparison. @param st: String to normalize. @param no_space: Remove spaces. @return: Normalized string.

Source code in src/utils/strings.py
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
def normalize_str(st: str, no_space: bool = False) -> str:
    """
    Normalizes a string for safe comparison.
    @param st: String to normalize.
    @param no_space: Remove spaces.
    @return: Normalized string.
    """
    # Ignore accents and unusual characters, all lowercase
    st = unicodedata.normalize("NFD", st).encode("ascii", "ignore").decode("utf8").lower()

    # Remove spaces?
    if no_space:
        st = st.replace(' ', '')

    # Remove punctuation
    return st.translate(str.maketrans("", "", string.punctuation))

str_to_bool(st)

Converts a truthy string value to a bool. Conversion is case-insensitive. @param st: True values are y, yes, t, true, on and 1. False values are n, no, f, false, off and 0. @return: Adjacent boolean value. @raise: ValueError if string provided isn't a recognized truthy expression.

Source code in src/utils/strings.py
151
152
153
154
155
156
157
158
159
160
161
162
def str_to_bool(st: str) -> bool:
    """
    Converts a truthy string value to a bool. Conversion is case-insensitive.
    @param st: True values are y, yes, t, true, on and 1.
    False values are n, no, f, false, off and 0.
    @return: Adjacent boolean value.
    @raise: ValueError if string provided isn't a recognized truthy expression.
    """
    try:
        return STR_BOOL_MAP[st.lower()]
    except KeyError:
        raise ValueError(f"Couldn't discern boolean value of string '{st}'!")

strip_lines(text, num, sep='\n')

Removes a number of leading or trailing lines from a multiline string.
@param text: Multiline string.
@param num: Positive integer for number leading lines, negative integer for number of trailing lines.
@param sep: Newline separator to use for split, defaults to '

'. @return: String with lines stripped.

Source code in src/utils/strings.py
85
86
87
88
89
90
91
92
93
94
95
96
97
def strip_lines(text: str, num: int, sep: str = '\n') -> str:
    """
    Removes a number of leading or trailing lines from a multiline string.
    @param text: Multiline string.
    @param num: Positive integer for number leading lines, negative integer for number of trailing lines.
    @param sep: Newline separator to use for split, defaults to '\n'.
    @return: String with lines stripped.
    """
    if num == 0:
        return text
    if num < 0:
        return '\n'.join(text.split(sep)[:num])
    return '\n'.join(text.split(sep)[num:])