stdl 0.6.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- stdl/__init__.py +2 -0
- stdl/color.py +1505 -0
- stdl/decorators.py +96 -0
- stdl/dt.py +355 -0
- stdl/fs.py +1711 -0
- stdl/import_lazy.py +123 -0
- stdl/log.py +142 -0
- stdl/lst.py +166 -0
- stdl/net.py +80 -0
- stdl/st.py +422 -0
- stdl-0.6.7.dist-info/METADATA +141 -0
- stdl-0.6.7.dist-info/RECORD +14 -0
- stdl-0.6.7.dist-info/WHEEL +4 -0
- stdl-0.6.7.dist-info/licenses/LICENSE +21 -0
stdl/st.py
ADDED
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import re
|
|
3
|
+
import textwrap
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
from platform import system
|
|
6
|
+
from sys import stdout
|
|
7
|
+
from typing import Any, Literal
|
|
8
|
+
|
|
9
|
+
CSI_RESET = "\033["
|
|
10
|
+
NO_COLOR = bool(os.environ.get("NO_COLOR", False))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def ansi_code(n: int) -> str:
|
|
14
|
+
return f"{CSI_RESET}{n}m"
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class ColorANSI:
|
|
18
|
+
# Cancel SGR codes if we don't write to a terminal
|
|
19
|
+
if not stdout.isatty():
|
|
20
|
+
for attr in dir():
|
|
21
|
+
if isinstance(attr, str) and attr[0] != "_":
|
|
22
|
+
locals()[attr] = ""
|
|
23
|
+
else:
|
|
24
|
+
# Enable VT mode on Windows
|
|
25
|
+
if system() == "Windows":
|
|
26
|
+
import ctypes
|
|
27
|
+
|
|
28
|
+
kernel32 = ctypes.windll.kernel32
|
|
29
|
+
handle = kernel32.GetStdHandle(-11)
|
|
30
|
+
if handle:
|
|
31
|
+
kernel32.SetConsoleMode(handle, 7)
|
|
32
|
+
del kernel32
|
|
33
|
+
del handle
|
|
34
|
+
del ctypes
|
|
35
|
+
|
|
36
|
+
@classmethod
|
|
37
|
+
def __class_getitem__(cls, key: str) -> str:
|
|
38
|
+
key = key.upper().replace(" ", "_")
|
|
39
|
+
if key in dir(cls):
|
|
40
|
+
return getattr(cls, key)
|
|
41
|
+
raise KeyError(key)
|
|
42
|
+
|
|
43
|
+
@classmethod
|
|
44
|
+
def dict(cls) -> dict[str, str]:
|
|
45
|
+
ignored = ["dict", "print_all", "get_names"]
|
|
46
|
+
data = {}
|
|
47
|
+
for attr in dir(cls):
|
|
48
|
+
if attr[0] != "_" and attr not in ignored:
|
|
49
|
+
data[attr] = cls[attr]
|
|
50
|
+
return data
|
|
51
|
+
|
|
52
|
+
@classmethod
|
|
53
|
+
def get_names(cls) -> list[str]:
|
|
54
|
+
return [i for i in cls.dict.keys()]
|
|
55
|
+
|
|
56
|
+
@classmethod
|
|
57
|
+
def print_all(cls) -> None:
|
|
58
|
+
for k, v in cls.dict().items():
|
|
59
|
+
if k == "RESET":
|
|
60
|
+
continue
|
|
61
|
+
print(colored(k, v)) # type:ignore
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class FG(ColorANSI):
|
|
65
|
+
"""Foreground Color"""
|
|
66
|
+
|
|
67
|
+
BLACK = ansi_code(30)
|
|
68
|
+
RED = ansi_code(31)
|
|
69
|
+
GREEN = ansi_code(32)
|
|
70
|
+
YELLOW = ansi_code(33)
|
|
71
|
+
BLUE = ansi_code(34)
|
|
72
|
+
MAGENTA = ansi_code(35)
|
|
73
|
+
CYAN = ansi_code(36)
|
|
74
|
+
WHITE = ansi_code(37)
|
|
75
|
+
GRAY = ansi_code(90)
|
|
76
|
+
LIGHT_RED = ansi_code(91)
|
|
77
|
+
LIGHT_GREEN = ansi_code(92)
|
|
78
|
+
LIGHT_YELLOW = ansi_code(93)
|
|
79
|
+
LIGHT_BLUE = ansi_code(94)
|
|
80
|
+
LIGHT_MAGENTA = ansi_code(95)
|
|
81
|
+
LIGHT_CYAN = ansi_code(96)
|
|
82
|
+
LIGHT_WHITE = ansi_code(97)
|
|
83
|
+
BOLD = ansi_code(1)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class BG(ColorANSI):
|
|
87
|
+
"""Background Color"""
|
|
88
|
+
|
|
89
|
+
BLACK = ansi_code(40)
|
|
90
|
+
RED = ansi_code(41)
|
|
91
|
+
GREEN = ansi_code(42)
|
|
92
|
+
YELLOW = ansi_code(43)
|
|
93
|
+
BLUE = ansi_code(44)
|
|
94
|
+
MAGENTA = ansi_code(45)
|
|
95
|
+
CYAN = ansi_code(46)
|
|
96
|
+
WHITE = ansi_code(47)
|
|
97
|
+
GRAY = ansi_code(100)
|
|
98
|
+
LIGHT_RED = ansi_code(101)
|
|
99
|
+
LIGHT_GREEN = ansi_code(102)
|
|
100
|
+
LIGHT_YELLOW = ansi_code(103)
|
|
101
|
+
LIGHT_BLUE = ansi_code(104)
|
|
102
|
+
LIGHT_MAGENTA = ansi_code(105)
|
|
103
|
+
LIGHT_CYAN = ansi_code(106)
|
|
104
|
+
LIGHT_WHITE = ansi_code(107)
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
class ST(ColorANSI):
|
|
108
|
+
"""Style"""
|
|
109
|
+
|
|
110
|
+
RESET = ansi_code(0)
|
|
111
|
+
BOLD = ansi_code(1)
|
|
112
|
+
DIM = ansi_code(2)
|
|
113
|
+
ITALIC = ansi_code(3)
|
|
114
|
+
UNDERLINE = ansi_code(4)
|
|
115
|
+
BLINK = ansi_code(5)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
ForegroundColor = Literal[
|
|
119
|
+
"black",
|
|
120
|
+
"blue",
|
|
121
|
+
"bold",
|
|
122
|
+
"cyan",
|
|
123
|
+
"gray",
|
|
124
|
+
"green",
|
|
125
|
+
"light_blue",
|
|
126
|
+
"light_cyan",
|
|
127
|
+
"light_green",
|
|
128
|
+
"light_magenta",
|
|
129
|
+
"light_red",
|
|
130
|
+
"light_white",
|
|
131
|
+
"light_yellow",
|
|
132
|
+
"magenta",
|
|
133
|
+
"red",
|
|
134
|
+
"white",
|
|
135
|
+
"yellow",
|
|
136
|
+
]
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
BackgroundColor = Literal[
|
|
140
|
+
"black",
|
|
141
|
+
"blue",
|
|
142
|
+
"cyan",
|
|
143
|
+
"gray",
|
|
144
|
+
"green",
|
|
145
|
+
"light_blue",
|
|
146
|
+
"light_cyan",
|
|
147
|
+
"light_green",
|
|
148
|
+
"light_magenta",
|
|
149
|
+
"light_red",
|
|
150
|
+
"light_white",
|
|
151
|
+
"light_yellow",
|
|
152
|
+
"magenta",
|
|
153
|
+
"red",
|
|
154
|
+
"white",
|
|
155
|
+
"yellow",
|
|
156
|
+
]
|
|
157
|
+
|
|
158
|
+
Style = Literal["blink", "bold", "dim", "italic", "reset", "underline"]
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def _get_ansi_value(value: str | None, handler: Any) -> str:
|
|
162
|
+
if not value:
|
|
163
|
+
return ""
|
|
164
|
+
try:
|
|
165
|
+
return handler[value]
|
|
166
|
+
except KeyError:
|
|
167
|
+
return value
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
def colored(
|
|
171
|
+
text: str,
|
|
172
|
+
color: ForegroundColor | str | None = None,
|
|
173
|
+
background: BackgroundColor | str | None = None,
|
|
174
|
+
style: Style | str | None = None,
|
|
175
|
+
) -> str:
|
|
176
|
+
"""
|
|
177
|
+
Returns the text with ansi color, background color and text style codes.
|
|
178
|
+
|
|
179
|
+
Args:
|
|
180
|
+
text (str): The text that should be colorized.
|
|
181
|
+
color (str, optional): The color to use for the text.
|
|
182
|
+
background (str, optional): The color to use for the background.
|
|
183
|
+
style (str, optional): The style to use for the text.
|
|
184
|
+
|
|
185
|
+
Returns:
|
|
186
|
+
str: The colorized text.
|
|
187
|
+
"""
|
|
188
|
+
if NO_COLOR or not stdout.isatty():
|
|
189
|
+
return text
|
|
190
|
+
color = _get_ansi_value(color, FG) # type: ignore
|
|
191
|
+
background = _get_ansi_value(background, BG) # type: ignore
|
|
192
|
+
style = _get_ansi_value(style, ST) # type: ignore
|
|
193
|
+
return f"{color}{background}{style}{text}{ST.RESET}"
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
@dataclass
|
|
197
|
+
class TextStyle:
|
|
198
|
+
color: ForegroundColor | str | None = None
|
|
199
|
+
background: BackgroundColor | str | None = None
|
|
200
|
+
style: Style | str | None = None
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
def with_style(text: str, style: TextStyle) -> str:
|
|
204
|
+
return colored(text, color=style.color, background=style.background, style=style.style)
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def terminal_link(
|
|
208
|
+
uri: str,
|
|
209
|
+
label: str | None = None,
|
|
210
|
+
color: ForegroundColor = "white",
|
|
211
|
+
background: BackgroundColor | None = None,
|
|
212
|
+
style: Style | None = None,
|
|
213
|
+
) -> str:
|
|
214
|
+
"""
|
|
215
|
+
Returns a hyperlink that can be used in terminals.
|
|
216
|
+
|
|
217
|
+
Note:
|
|
218
|
+
Hyperlinks are not supported in all terminals.
|
|
219
|
+
For more information visit
|
|
220
|
+
<https://github.com/Alhadis/OSC8-Adoption/>
|
|
221
|
+
and
|
|
222
|
+
<https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda>
|
|
223
|
+
|
|
224
|
+
Args:
|
|
225
|
+
uri (str): The URI of the link.
|
|
226
|
+
label (str, optional): The label of the link. Defaults to the URI.
|
|
227
|
+
color (str, optional): The color of the link. Defaults to white.
|
|
228
|
+
background (str, optional): The background color of the link.
|
|
229
|
+
style (str, optional): The style of the link.
|
|
230
|
+
|
|
231
|
+
Returns:
|
|
232
|
+
str: The link as a string.
|
|
233
|
+
"""
|
|
234
|
+
if label is None:
|
|
235
|
+
label = uri
|
|
236
|
+
|
|
237
|
+
if stdout.isatty():
|
|
238
|
+
link = f"\033]8;;{uri}\033\\{label}\033]8;;\033\\"
|
|
239
|
+
else:
|
|
240
|
+
link = uri
|
|
241
|
+
link = colored(link, color, background, style)
|
|
242
|
+
return link
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
def remove(s: str, chars: str | set, replace_with: str = "") -> str:
|
|
246
|
+
"""
|
|
247
|
+
Remove or replace characters in a string.
|
|
248
|
+
|
|
249
|
+
Args:
|
|
250
|
+
s (str): Input string.
|
|
251
|
+
chars (str | set): Characters to remove
|
|
252
|
+
replace_with (str, optional): If provided, replace the characters with this value.
|
|
253
|
+
|
|
254
|
+
"""
|
|
255
|
+
string = []
|
|
256
|
+
chars = set(chars)
|
|
257
|
+
for c in s:
|
|
258
|
+
if c not in chars:
|
|
259
|
+
string.append(c)
|
|
260
|
+
else:
|
|
261
|
+
if replace_with:
|
|
262
|
+
string.append(replace_with)
|
|
263
|
+
return "".join(string)
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
def keep(s: str, chars: str | set, replace_with: str = "") -> str:
|
|
267
|
+
"""
|
|
268
|
+
Keep provided characters in a string. Remove or replace others.
|
|
269
|
+
|
|
270
|
+
Args:
|
|
271
|
+
s (str): Input string
|
|
272
|
+
chars (str | set): Characters to keep
|
|
273
|
+
replace_with (str, optional): If provided, replace other characters with this value.
|
|
274
|
+
|
|
275
|
+
"""
|
|
276
|
+
string = []
|
|
277
|
+
chars = set(chars)
|
|
278
|
+
for c in s:
|
|
279
|
+
if c in chars:
|
|
280
|
+
string.append(c)
|
|
281
|
+
else:
|
|
282
|
+
if replace_with:
|
|
283
|
+
string.append(replace_with)
|
|
284
|
+
return "".join(string)
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
ASCII = set("".join(chr(x) for x in range(128)))
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
class sf:
|
|
291
|
+
"""A collection of functions that can be used to filter strings."""
|
|
292
|
+
|
|
293
|
+
@classmethod
|
|
294
|
+
def filename(cls, filename: str, replace_with: str = "") -> str:
|
|
295
|
+
"""Removes or replaces characters that are not allowed to be in a filename."""
|
|
296
|
+
return remove(filename, chars='|?*<>:"\\', replace_with=replace_with)
|
|
297
|
+
|
|
298
|
+
@classmethod
|
|
299
|
+
def filepath(cls, filepath: str, replace_with: str = "") -> str:
|
|
300
|
+
"""Removes or replaces characters that are not allowed to be in a filepath."""
|
|
301
|
+
if not filepath:
|
|
302
|
+
return ""
|
|
303
|
+
dirname, filename = os.path.split(filepath)
|
|
304
|
+
filename = sf.filename(filename, replace_with)
|
|
305
|
+
dirname = remove(dirname, '|?*<>:"')
|
|
306
|
+
return f"{dirname}{os.sep}{filename}"
|
|
307
|
+
|
|
308
|
+
@classmethod
|
|
309
|
+
def ascii(cls, s: str, replace_with: str = "") -> str:
|
|
310
|
+
"""Removes or replaces non-ASCII characters from the string."""
|
|
311
|
+
return keep(s, ASCII, replace_with)
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
def snake_case(s: str) -> str:
|
|
315
|
+
"""Converts a given string to snake_case."""
|
|
316
|
+
return "_".join(
|
|
317
|
+
re.sub(
|
|
318
|
+
"([A-Z][a-z]+)",
|
|
319
|
+
r" \1",
|
|
320
|
+
re.sub("([A-Z]+)", r" \1", s.replace("-", " ")),
|
|
321
|
+
).split()
|
|
322
|
+
).lower()
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
def camel_case(s: str) -> str:
|
|
326
|
+
"""Converts a given string to camelCase."""
|
|
327
|
+
s = re.sub(r"(_|-)+", " ", s).title().replace(" ", "")
|
|
328
|
+
return s[0].lower() + s[1:]
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
def kebab_case(s: str) -> str:
|
|
332
|
+
"""Converts a given string to kebab-case."""
|
|
333
|
+
RE_WORDS = r"[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+"
|
|
334
|
+
RE_SEP = r"(\s|_|-)+"
|
|
335
|
+
return "-".join(
|
|
336
|
+
re.sub(
|
|
337
|
+
RE_SEP,
|
|
338
|
+
" ",
|
|
339
|
+
re.sub(
|
|
340
|
+
RE_WORDS,
|
|
341
|
+
lambda mo: " " + mo.group(0).lower(),
|
|
342
|
+
s,
|
|
343
|
+
),
|
|
344
|
+
).split()
|
|
345
|
+
)
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
def wrapped(text: str, width: int, newline: str = "\n") -> str:
|
|
349
|
+
"""Wraps the given text to a specified width and separates lines with the given newline character."""
|
|
350
|
+
return newline.join(textwrap.wrap(text, width=width))
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
def ansi_len(s: str) -> int:
|
|
354
|
+
"""Returns the length of the string without the ANSI codes."""
|
|
355
|
+
ascii_codes = re.findall(r"\x1b\[[0-9;]*[m]", s)
|
|
356
|
+
codes_len = sum(len(code) for code in ascii_codes)
|
|
357
|
+
return len(s) - codes_len
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
def ansi_ljust(s: str, width: int, fillchar: str = " ") -> str:
|
|
361
|
+
"""
|
|
362
|
+
Ljust function that takes into account the length of the ANSI codes in the string.
|
|
363
|
+
|
|
364
|
+
Args:
|
|
365
|
+
s (str): The string to be left justified.
|
|
366
|
+
width (int): The width of the string.
|
|
367
|
+
fillchar (str, optional): The character to fill the string with. Defaults to " ".
|
|
368
|
+
"""
|
|
369
|
+
ascii_codes = re.findall(r"\x1b\[[0-9;]*[m]", s)
|
|
370
|
+
codes_len = sum(len(code) for code in ascii_codes)
|
|
371
|
+
new_width = width + codes_len
|
|
372
|
+
return s.ljust(new_width, fillchar)
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
def ansi_rjust(s: str, width: int, fillchar: str = " ") -> str:
|
|
376
|
+
"""
|
|
377
|
+
Rjust function that takes into account the length of the ANSI codes in the string.
|
|
378
|
+
|
|
379
|
+
Args:
|
|
380
|
+
s (str): The string to be right justified.
|
|
381
|
+
width (int): The width of the string.
|
|
382
|
+
fillchar (str, optional): The character to fill the string with. Defaults to " ".
|
|
383
|
+
"""
|
|
384
|
+
ascii_codes = re.findall(r"\x1b\[[0-9;]*[m]", s)
|
|
385
|
+
codes_len = sum(len(code) for code in ascii_codes)
|
|
386
|
+
new_width = width + codes_len
|
|
387
|
+
return s.rjust(new_width, fillchar)
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
def ansi_strip(r: str) -> str:
|
|
391
|
+
"""Remove ANSI escape codes from a string."""
|
|
392
|
+
ansi_escape = re.compile(r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])")
|
|
393
|
+
return ansi_escape.sub("", r)
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
if __name__ == "__main__":
|
|
397
|
+
FG.print_all()
|
|
398
|
+
BG.print_all()
|
|
399
|
+
ST.print_all()
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
__all__ = [
|
|
403
|
+
"FG",
|
|
404
|
+
"BG",
|
|
405
|
+
"ST",
|
|
406
|
+
"colored",
|
|
407
|
+
"terminal_link",
|
|
408
|
+
"remove",
|
|
409
|
+
"keep",
|
|
410
|
+
"ASCII",
|
|
411
|
+
"sf",
|
|
412
|
+
"snake_case",
|
|
413
|
+
"camel_case",
|
|
414
|
+
"kebab_case",
|
|
415
|
+
"wrapped",
|
|
416
|
+
"ansi_len",
|
|
417
|
+
"ansi_ljust",
|
|
418
|
+
"ansi_rjust",
|
|
419
|
+
"Style",
|
|
420
|
+
"ForegroundColor",
|
|
421
|
+
"BackgroundColor",
|
|
422
|
+
]
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: stdl
|
|
3
|
+
Version: 0.6.7
|
|
4
|
+
Summary: Extended Python Standard Library
|
|
5
|
+
Project-URL: Repository, https://github.com/zigai/stdl
|
|
6
|
+
Project-URL: Issues, https://github.com/zigai/stdl/issues
|
|
7
|
+
Project-URL: Homepage, https://github.com/zigai/stdl
|
|
8
|
+
Author-email: Žiga Ivanšek <ziga.ivansek@gmail.com>
|
|
9
|
+
License: MIT License
|
|
10
|
+
|
|
11
|
+
Copyright (c) 2022 Žiga Ivanšek
|
|
12
|
+
|
|
13
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
14
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
15
|
+
in the Software without restriction, including without limitation the rights
|
|
16
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
17
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
18
|
+
furnished to do so, subject to the following conditions:
|
|
19
|
+
|
|
20
|
+
The above copyright notice and this permission notice shall be included in all
|
|
21
|
+
copies or substantial portions of the Software.
|
|
22
|
+
|
|
23
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
24
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
25
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
26
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
27
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
28
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
29
|
+
SOFTWARE.
|
|
30
|
+
License-File: LICENSE
|
|
31
|
+
Keywords: ANSI colors,color formats,filesystem,lazy import,list utils,logging configuration,python lazy import,python utilities,standard library,stdl,string utils,terminal links,terminal output
|
|
32
|
+
Classifier: Intended Audience :: Developers
|
|
33
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
34
|
+
Classifier: Operating System :: OS Independent
|
|
35
|
+
Classifier: Programming Language :: Python
|
|
36
|
+
Classifier: Programming Language :: Python :: 3
|
|
37
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
38
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
39
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
40
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
41
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
42
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
43
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
44
|
+
Classifier: Typing :: Typed
|
|
45
|
+
Requires-Python: >=3.10
|
|
46
|
+
Requires-Dist: python-dateutil>=2.8.2
|
|
47
|
+
Requires-Dist: pyyaml>=6.0.2
|
|
48
|
+
Requires-Dist: toml>=0.10.2
|
|
49
|
+
Requires-Dist: typing-extensions>=4.0; python_version < '3.11'
|
|
50
|
+
Provides-Extra: dev
|
|
51
|
+
Requires-Dist: codespell; extra == 'dev'
|
|
52
|
+
Requires-Dist: coverage; extra == 'dev'
|
|
53
|
+
Requires-Dist: mypy; extra == 'dev'
|
|
54
|
+
Requires-Dist: pre-commit; extra == 'dev'
|
|
55
|
+
Requires-Dist: pydantic>=2; extra == 'dev'
|
|
56
|
+
Requires-Dist: pytest; extra == 'dev'
|
|
57
|
+
Requires-Dist: ruff; extra == 'dev'
|
|
58
|
+
Provides-Extra: full
|
|
59
|
+
Requires-Dist: tqdm>=4.67.1; extra == 'full'
|
|
60
|
+
Provides-Extra: test
|
|
61
|
+
Requires-Dist: coverage; extra == 'test'
|
|
62
|
+
Requires-Dist: pydantic>=2; extra == 'test'
|
|
63
|
+
Requires-Dist: pytest; extra == 'test'
|
|
64
|
+
Description-Content-Type: text/markdown
|
|
65
|
+
|
|
66
|
+
# stdl
|
|
67
|
+
|
|
68
|
+
[](https://github.com/zigai/stdl/actions/workflows/test.yml)
|
|
69
|
+
[](https://stdl.readthedocs.io/en/latest/?badge=latest)
|
|
70
|
+
[](https://badge.fury.io/py/stdl)
|
|
71
|
+

|
|
72
|
+
[](https://pepy.tech/project/stdl)
|
|
73
|
+
[](https://github.com/zigai/stdl/blob/master/LICENSE)
|
|
74
|
+
|
|
75
|
+
`stdl` is a collection of Python utilities that complement the standard library.
|
|
76
|
+
|
|
77
|
+
## Features
|
|
78
|
+
|
|
79
|
+
- File and directory operations
|
|
80
|
+
- String manipulation
|
|
81
|
+
- ANSI color support for terminal output
|
|
82
|
+
- Date and time formatting
|
|
83
|
+
- List utils
|
|
84
|
+
- Lazy imports
|
|
85
|
+
- Logging configuration for `logging` and `loguru`
|
|
86
|
+
- [See docs](https://stdl.readthedocs.io/en/latest/?badge=latest)
|
|
87
|
+
|
|
88
|
+
## Installation
|
|
89
|
+
|
|
90
|
+
### Using pip
|
|
91
|
+
|
|
92
|
+
```sh
|
|
93
|
+
pip install stdl
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Using uv
|
|
97
|
+
|
|
98
|
+
```sh
|
|
99
|
+
uv add stdl
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### From source
|
|
103
|
+
|
|
104
|
+
```sh
|
|
105
|
+
pip install git+https://github.com/zigai/stdl.git
|
|
106
|
+
# or
|
|
107
|
+
uv add git+https://github.com/zigai/stdl.git
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Examples
|
|
111
|
+
|
|
112
|
+
### Lazy imports
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
from typing import TYPE_CHECKING
|
|
116
|
+
from stdl.import_lazy import import_lazy
|
|
117
|
+
|
|
118
|
+
if TYPE_CHECKING:
|
|
119
|
+
from os.path import abspath, join
|
|
120
|
+
import numpy as np
|
|
121
|
+
import torch
|
|
122
|
+
else:
|
|
123
|
+
import_lazy("os.path", ["join", "abspath"], verbose=True)
|
|
124
|
+
import_lazy("numpy", alias="np", verbose=True)
|
|
125
|
+
import_lazy("torch", verbose=True)
|
|
126
|
+
|
|
127
|
+
print(np.zeros(4))
|
|
128
|
+
# importing "numpy" took 0.060s
|
|
129
|
+
# [0. 0. 0. 0.]
|
|
130
|
+
print(torch)
|
|
131
|
+
# <LazyImport: torch>
|
|
132
|
+
print(torch.randn(8))
|
|
133
|
+
# importing "torch" took 1.118s
|
|
134
|
+
# tensor([0., 0., 0., 0., 0., 0., 0., 0.])
|
|
135
|
+
print(torch)
|
|
136
|
+
# <module 'torch' from .../torch/__init__.py'
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## License
|
|
140
|
+
|
|
141
|
+
[MIT License](https://github.com/zigai/stdl/blob/master/LICENSE)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
stdl/__init__.py,sha256=XXNSego9YjRnY5QY77ZfWVXGSCfbwosm9Z2MLhECMtI,111
|
|
2
|
+
stdl/color.py,sha256=Vi2MAkF6kPUNDTnctFChT2ldGSHyEKR-Maw-amzfwIQ,45055
|
|
3
|
+
stdl/decorators.py,sha256=vsHGXfzCf9m6pyeT0AiWuVFpwPOQ2FT4xaDOK_MSaFY,3256
|
|
4
|
+
stdl/dt.py,sha256=XmEf0BqkmxM3HMsYwELGjKaVppx3NdbmI6sppCNk-zY,10203
|
|
5
|
+
stdl/fs.py,sha256=vFr4OrWM5hr8qsX_GzREJ-P4xsZh-vP0BiBVUECjbDM,52292
|
|
6
|
+
stdl/import_lazy.py,sha256=xqJU5S4ngYitpLwiGuBwGpeW4d3VYRb1-tN3n3ppqDI,4127
|
|
7
|
+
stdl/log.py,sha256=Bro5Oyeo_RMHzWsi_mcbph6kbPSUvPW1KxmOKqRwqN8,4224
|
|
8
|
+
stdl/lst.py,sha256=xeekFnqpuSpQnPETJCgylWrka5nspQkhyUQIr0D3u6U,4067
|
|
9
|
+
stdl/net.py,sha256=xEaet5wM3Olplvn79E-80C-SPUlI8L-2aqCK1qL87-M,2566
|
|
10
|
+
stdl/st.py,sha256=3bEiDf0Q6xs153aPMCVPAO-MDkvuDW9Z243POJ0mT1s,11061
|
|
11
|
+
stdl-0.6.7.dist-info/METADATA,sha256=XyTEN3jbfRprAZRN-A-bIKMlS95zM1Tq6rPQPX--t94,5086
|
|
12
|
+
stdl-0.6.7.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
13
|
+
stdl-0.6.7.dist-info/licenses/LICENSE,sha256=MwAJrJWzBVMNkmJSjdRctks7VcSbh8yAXezV_uf4yu8,1071
|
|
14
|
+
stdl-0.6.7.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 Žiga Ivanšek
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|