stouputils 1.2.19__tar.gz → 1.2.20__tar.gz
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.
- {stouputils-1.2.19 → stouputils-1.2.20}/PKG-INFO +1 -1
- {stouputils-1.2.19 → stouputils-1.2.20}/pyproject.toml +1 -1
- {stouputils-1.2.19 → stouputils-1.2.20}/stouputils/ctx.py +1 -48
- {stouputils-1.2.19 → stouputils-1.2.20}/stouputils/parallel.py +4 -4
- {stouputils-1.2.19 → stouputils-1.2.20}/stouputils/print.py +67 -1
- {stouputils-1.2.19 → stouputils-1.2.20}/.gitignore +0 -0
- {stouputils-1.2.19 → stouputils-1.2.20}/LICENSE +0 -0
- {stouputils-1.2.19 → stouputils-1.2.20}/README.md +0 -0
- {stouputils-1.2.19 → stouputils-1.2.20}/stouputils/__init__.py +0 -0
- {stouputils-1.2.19 → stouputils-1.2.20}/stouputils/all_doctests.py +0 -0
- {stouputils-1.2.19 → stouputils-1.2.20}/stouputils/applications/__init__.py +0 -0
- {stouputils-1.2.19 → stouputils-1.2.20}/stouputils/applications/automatic_docs.py +0 -0
- {stouputils-1.2.19 → stouputils-1.2.20}/stouputils/archive.py +0 -0
- {stouputils-1.2.19 → stouputils-1.2.20}/stouputils/backup.py +0 -0
- {stouputils-1.2.19 → stouputils-1.2.20}/stouputils/collections.py +0 -0
- {stouputils-1.2.19 → stouputils-1.2.20}/stouputils/continuous_delivery/__init__.py +0 -0
- {stouputils-1.2.19 → stouputils-1.2.20}/stouputils/continuous_delivery/cd_utils.py +0 -0
- {stouputils-1.2.19 → stouputils-1.2.20}/stouputils/continuous_delivery/github.py +0 -0
- {stouputils-1.2.19 → stouputils-1.2.20}/stouputils/continuous_delivery/pypi.py +0 -0
- {stouputils-1.2.19 → stouputils-1.2.20}/stouputils/continuous_delivery/pyproject.py +0 -0
- {stouputils-1.2.19 → stouputils-1.2.20}/stouputils/decorators.py +0 -0
- {stouputils-1.2.19 → stouputils-1.2.20}/stouputils/dont_look/zip_file_override.py +0 -0
- {stouputils-1.2.19 → stouputils-1.2.20}/stouputils/image.py +0 -0
- {stouputils-1.2.19 → stouputils-1.2.20}/stouputils/io.py +0 -0
- {stouputils-1.2.19 → stouputils-1.2.20}/stouputils/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: stouputils
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.20
|
|
4
4
|
Summary: Stouputils is a collection of utility modules designed to simplify and enhance the development process. It includes a range of tools for tasks such as execution of doctests, display utilities, decorators, as well as context managers, and many more.
|
|
5
5
|
Project-URL: Homepage, https://github.com/Stoupy51/stouputils
|
|
6
6
|
Project-URL: Issues, https://github.com/Stoupy51/stouputils/issues
|
|
@@ -5,7 +5,7 @@ build-backend = "hatchling.build"
|
|
|
5
5
|
|
|
6
6
|
[project]
|
|
7
7
|
name = "stouputils"
|
|
8
|
-
version = "1.2.
|
|
8
|
+
version = "1.2.20"
|
|
9
9
|
description = "Stouputils is a collection of utility modules designed to simplify and enhance the development process. It includes a range of tools for tasks such as execution of doctests, display utilities, decorators, as well as context managers, and many more."
|
|
10
10
|
readme = "README.md"
|
|
11
11
|
requires-python = ">=3.10"
|
|
@@ -12,7 +12,7 @@ This module provides context managers for temporarily silencing output.
|
|
|
12
12
|
import os
|
|
13
13
|
import sys
|
|
14
14
|
from typing import IO, TextIO, Callable, Any
|
|
15
|
-
from .print import
|
|
15
|
+
from .print import TeeMultiOutput
|
|
16
16
|
from .io import super_open
|
|
17
17
|
|
|
18
18
|
|
|
@@ -55,53 +55,6 @@ class Muffle:
|
|
|
55
55
|
sys.stderr = self.original_stderr
|
|
56
56
|
|
|
57
57
|
|
|
58
|
-
# TeeMultiOutput class to duplicate output to multiple file-like objects
|
|
59
|
-
class TeeMultiOutput(object):
|
|
60
|
-
""" File-like object that duplicates output to multiple file objects.
|
|
61
|
-
|
|
62
|
-
Args:
|
|
63
|
-
*files (IO[Any]): One or more file-like objects that have write and flush methods
|
|
64
|
-
strip_colors (bool): Whether to strip ANSI color codes from output sent to non-stdout/stderr files
|
|
65
|
-
|
|
66
|
-
Examples:
|
|
67
|
-
>>> f = open("logfile.txt", "w")
|
|
68
|
-
>>> original_stdout = sys.stdout
|
|
69
|
-
>>> sys.stdout = TeeMultiOutput(sys.stdout, f)
|
|
70
|
-
>>> print("Hello World") # Output goes to both console and file
|
|
71
|
-
>>> sys.stdout = original_stdout
|
|
72
|
-
>>> f.close()
|
|
73
|
-
"""
|
|
74
|
-
def __init__(self, *files: IO[Any], strip_colors: bool = True) -> None:
|
|
75
|
-
self.files: tuple[IO[Any], ...] = files
|
|
76
|
-
""" File-like objects to write to """
|
|
77
|
-
self.strip_colors: bool = strip_colors
|
|
78
|
-
""" Whether to strip ANSI color codes from output sent to non-stdout/stderr files """
|
|
79
|
-
|
|
80
|
-
def write(self, obj: str) -> None:
|
|
81
|
-
""" Write the object to all files while stripping colors if needed.
|
|
82
|
-
|
|
83
|
-
Args:
|
|
84
|
-
obj (str): String to write
|
|
85
|
-
"""
|
|
86
|
-
for i, f in enumerate(self.files):
|
|
87
|
-
if self.strip_colors and i != 0:
|
|
88
|
-
f.write(remove_colors(obj))
|
|
89
|
-
else:
|
|
90
|
-
f.write(obj)
|
|
91
|
-
|
|
92
|
-
def flush(self) -> None:
|
|
93
|
-
""" Flush all files. """
|
|
94
|
-
for f in self.files:
|
|
95
|
-
f.flush()
|
|
96
|
-
|
|
97
|
-
# Add other methods that might be expected from a file-like object
|
|
98
|
-
def isatty(self) -> bool:
|
|
99
|
-
""" Return whether the first file is connected to a tty-like device. """
|
|
100
|
-
return hasattr(self.files[0], 'isatty') and self.files[0].isatty()
|
|
101
|
-
|
|
102
|
-
def fileno(self) -> int:
|
|
103
|
-
""" Return the file descriptor of the first file. """
|
|
104
|
-
return self.files[0].fileno()
|
|
105
58
|
|
|
106
59
|
# Context manager to log to a file
|
|
107
60
|
class LogToFile:
|
|
@@ -123,7 +123,7 @@ def multiprocessing(func: Callable[[T], R], args: list[T], use_starmap: bool = F
|
|
|
123
123
|
# Do multiprocessing only if there is more than 1 argument and more than 1 CPU
|
|
124
124
|
if max_workers > 1 and len(args) > 1:
|
|
125
125
|
if verbose > 0:
|
|
126
|
-
return list(process_map(func, args, max_workers=max_workers, chunksize=chunksize, desc=desc, bar_format=BAR_FORMAT)) # type: ignore
|
|
126
|
+
return list(process_map(func, args, max_workers=max_workers, chunksize=chunksize, desc=desc, bar_format=BAR_FORMAT, ascii=False)) # type: ignore
|
|
127
127
|
else:
|
|
128
128
|
with Pool(max_workers) as pool:
|
|
129
129
|
return list(pool.map(func, args, chunksize=chunksize)) # type: ignore
|
|
@@ -131,7 +131,7 @@ def multiprocessing(func: Callable[[T], R], args: list[T], use_starmap: bool = F
|
|
|
131
131
|
# Single process execution
|
|
132
132
|
else:
|
|
133
133
|
if verbose > 0:
|
|
134
|
-
return [func(arg) for arg in tqdm(args, total=len(args), desc=desc, bar_format=BAR_FORMAT)]
|
|
134
|
+
return [func(arg) for arg in tqdm(args, total=len(args), desc=desc, bar_format=BAR_FORMAT, ascii=False)]
|
|
135
135
|
else:
|
|
136
136
|
return [func(arg) for arg in args]
|
|
137
137
|
|
|
@@ -176,7 +176,7 @@ def multithreading(func: Callable[[T], R], args: list[T], use_starmap: bool = Fa
|
|
|
176
176
|
if max_workers > 1 and len(args) > 1:
|
|
177
177
|
if verbose > 0:
|
|
178
178
|
with ThreadPoolExecutor(max_workers) as executor:
|
|
179
|
-
return list(tqdm(executor.map(func, args), total=len(args), desc=desc, bar_format=BAR_FORMAT))
|
|
179
|
+
return list(tqdm(executor.map(func, args), total=len(args), desc=desc, bar_format=BAR_FORMAT, ascii=False))
|
|
180
180
|
else:
|
|
181
181
|
with ThreadPoolExecutor(max_workers) as executor:
|
|
182
182
|
return list(executor.map(func, args))
|
|
@@ -184,7 +184,7 @@ def multithreading(func: Callable[[T], R], args: list[T], use_starmap: bool = Fa
|
|
|
184
184
|
# Single process execution
|
|
185
185
|
else:
|
|
186
186
|
if verbose > 0:
|
|
187
|
-
return [func(arg) for arg in tqdm(args, total=len(args), desc=desc, bar_format=BAR_FORMAT)]
|
|
187
|
+
return [func(arg) for arg in tqdm(args, total=len(args), desc=desc, bar_format=BAR_FORMAT, ascii=False)]
|
|
188
188
|
else:
|
|
189
189
|
return [func(arg) for arg in args]
|
|
190
190
|
|
|
@@ -10,7 +10,7 @@ If a message is printed multiple times, it will be displayed as "(xN) message" w
|
|
|
10
10
|
# Imports
|
|
11
11
|
import sys
|
|
12
12
|
import time
|
|
13
|
-
from typing import Callable, TextIO, Any
|
|
13
|
+
from typing import Callable, IO, TextIO, Any
|
|
14
14
|
|
|
15
15
|
# Colors constants
|
|
16
16
|
RESET: str = "\033[0m"
|
|
@@ -224,7 +224,73 @@ def breakpoint(*values: Any, print_function: Callable[..., None] = warning, **pr
|
|
|
224
224
|
sys.exit(1)
|
|
225
225
|
|
|
226
226
|
|
|
227
|
+
# TeeMultiOutput class to duplicate output to multiple file-like objects
|
|
228
|
+
class TeeMultiOutput(object):
|
|
229
|
+
""" File-like object that duplicates output to multiple file objects.
|
|
227
230
|
|
|
231
|
+
Args:
|
|
232
|
+
*files (IO[Any]): One or more file-like objects that have write and flush methods
|
|
233
|
+
strip_colors (bool): Whether to strip ANSI color codes from output sent to non-stdout/stderr files
|
|
234
|
+
force_tty (bool): Whether to force reporting as a TTY device (helps with tqdm)
|
|
235
|
+
ascii_only (bool): Whether to replace non-ASCII characters with their ASCII equivalents for non-stdout/stderr files
|
|
236
|
+
|
|
237
|
+
Examples:
|
|
238
|
+
>>> f = open("logfile.txt", "w")
|
|
239
|
+
>>> original_stdout = sys.stdout
|
|
240
|
+
>>> sys.stdout = TeeMultiOutput(sys.stdout, f)
|
|
241
|
+
>>> print("Hello World") # Output goes to both console and file
|
|
242
|
+
>>> sys.stdout = original_stdout
|
|
243
|
+
>>> f.close()
|
|
244
|
+
"""
|
|
245
|
+
def __init__(self, *files: IO[Any], strip_colors: bool = True, ascii_only: bool = True) -> None:
|
|
246
|
+
self.files: tuple[IO[Any], ...] = files
|
|
247
|
+
""" File-like objects to write to """
|
|
248
|
+
self.strip_colors: bool = strip_colors
|
|
249
|
+
""" Whether to strip ANSI color codes from output sent to non-stdout/stderr files """
|
|
250
|
+
self.ascii_only: bool = ascii_only
|
|
251
|
+
""" Whether to replace non-ASCII characters with their ASCII equivalents for non-stdout/stderr files """
|
|
252
|
+
|
|
253
|
+
def write(self, obj: str) -> None:
|
|
254
|
+
""" Write the object to all files while stripping colors if needed.
|
|
255
|
+
|
|
256
|
+
Args:
|
|
257
|
+
obj (str): String to write
|
|
258
|
+
"""
|
|
259
|
+
for i, f in enumerate(self.files):
|
|
260
|
+
try:
|
|
261
|
+
content = obj
|
|
262
|
+
if i != 0:
|
|
263
|
+
# First file (i = 0) (often stdout/stderr) gets the original content
|
|
264
|
+
# Other files (i != 0) get processed content
|
|
265
|
+
|
|
266
|
+
# Strip colors if needed
|
|
267
|
+
if self.strip_colors:
|
|
268
|
+
content = remove_colors(content)
|
|
269
|
+
|
|
270
|
+
# Replace Unicode block characters with ASCII equivalents
|
|
271
|
+
# Replace other problematic Unicode characters as needed
|
|
272
|
+
if self.ascii_only:
|
|
273
|
+
content = content.replace('█', '#')
|
|
274
|
+
content = ''.join(c if ord(c) < 128 else '?' for c in content)
|
|
275
|
+
|
|
276
|
+
# Write content to file
|
|
277
|
+
f.write(content)
|
|
278
|
+
|
|
279
|
+
except Exception:
|
|
280
|
+
pass
|
|
281
|
+
|
|
282
|
+
def flush(self) -> None:
|
|
283
|
+
""" Flush all files. """
|
|
284
|
+
for f in self.files:
|
|
285
|
+
if hasattr(f, 'flush'):
|
|
286
|
+
try:
|
|
287
|
+
f.flush()
|
|
288
|
+
except Exception:
|
|
289
|
+
pass
|
|
290
|
+
|
|
291
|
+
def fileno(self) -> int:
|
|
292
|
+
""" Return the file descriptor of the first file. """
|
|
293
|
+
return self.files[0].fileno() if hasattr(self.files[0], "fileno") else 0
|
|
228
294
|
|
|
229
295
|
|
|
230
296
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|