orionis 0.644.0__py3-none-any.whl → 0.645.0__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.
- orionis/console/contracts/console.py +51 -0
- orionis/console/contracts/dumper.py +92 -0
- orionis/console/debug/dumper.py +149 -0
- orionis/console/output/console.py +136 -4
- orionis/foundation/providers/dumper_provider.py +13 -13
- orionis/metadata/framework.py +1 -1
- orionis/support/facades/dumper.pyi +1 -1
- orionis/test/output/dumper.py +80 -82
- {orionis-0.644.0.dist-info → orionis-0.645.0.dist-info}/METADATA +1 -1
- {orionis-0.644.0.dist-info → orionis-0.645.0.dist-info}/RECORD +14 -14
- orionis/console/contracts/debug.py +0 -34
- orionis/console/dumper/debug.py +0 -627
- /orionis/console/{dumper → debug}/__init__.py +0 -0
- {orionis-0.644.0.dist-info → orionis-0.645.0.dist-info}/WHEEL +0 -0
- {orionis-0.644.0.dist-info → orionis-0.645.0.dist-info}/licenses/LICENCE +0 -0
- {orionis-0.644.0.dist-info → orionis-0.645.0.dist-info}/top_level.txt +0 -0
orionis/console/dumper/debug.py
DELETED
|
@@ -1,627 +0,0 @@
|
|
|
1
|
-
import inspect
|
|
2
|
-
import json
|
|
3
|
-
import os
|
|
4
|
-
from dataclasses import is_dataclass
|
|
5
|
-
from datetime import datetime
|
|
6
|
-
from typing import Any
|
|
7
|
-
from rich.console import Console
|
|
8
|
-
from rich.panel import Panel
|
|
9
|
-
from rich.syntax import Syntax
|
|
10
|
-
from rich.table import Table
|
|
11
|
-
from rich.traceback import install
|
|
12
|
-
from orionis.console.contracts.debug import IDebug
|
|
13
|
-
|
|
14
|
-
class Debug(IDebug):
|
|
15
|
-
|
|
16
|
-
def __init__(self, line:str = None) -> None:
|
|
17
|
-
"""
|
|
18
|
-
Initializes the dump class.
|
|
19
|
-
|
|
20
|
-
Parameters
|
|
21
|
-
----------
|
|
22
|
-
line : str, optional
|
|
23
|
-
The line text callback to use for output, default is None
|
|
24
|
-
Returns
|
|
25
|
-
-------
|
|
26
|
-
None
|
|
27
|
-
Notes
|
|
28
|
-
-----
|
|
29
|
-
This constructor performs the following setup:
|
|
30
|
-
- Installs required dependencies via `install()`
|
|
31
|
-
- Initializes a console instance for output handling
|
|
32
|
-
- Sets the default indentation size to 4 spaces
|
|
33
|
-
- Creates a set to prevent recursion during operations
|
|
34
|
-
- Stores the provided line callback if specified
|
|
35
|
-
"""
|
|
36
|
-
install()
|
|
37
|
-
self.console = Console()
|
|
38
|
-
self.indent_size = 4
|
|
39
|
-
self._recursion_guard = set()
|
|
40
|
-
self.line_tcbk = line
|
|
41
|
-
|
|
42
|
-
def dd(self, *args: Any) -> None:
|
|
43
|
-
"""
|
|
44
|
-
Dumps the provided arguments to the output and exits the program.
|
|
45
|
-
|
|
46
|
-
Parameters
|
|
47
|
-
----------
|
|
48
|
-
*args : Any
|
|
49
|
-
Variable length argument list to be processed and output.
|
|
50
|
-
Returns
|
|
51
|
-
-------
|
|
52
|
-
Notes
|
|
53
|
-
-----
|
|
54
|
-
This method will terminate the program execution after dumping the arguments.
|
|
55
|
-
"""
|
|
56
|
-
self.__processOutput(*args, exit_after=True)
|
|
57
|
-
|
|
58
|
-
def dump(self, *args: Any) -> None:
|
|
59
|
-
"""
|
|
60
|
-
Dumps the provided arguments to the output without exiting the program.
|
|
61
|
-
|
|
62
|
-
Parameters
|
|
63
|
-
----------
|
|
64
|
-
*args : Any
|
|
65
|
-
Variable length argument list to be processed and output.
|
|
66
|
-
|
|
67
|
-
Returns
|
|
68
|
-
-------
|
|
69
|
-
None
|
|
70
|
-
|
|
71
|
-
Notes
|
|
72
|
-
-----
|
|
73
|
-
This method displays the arguments in an appropriate format based on their type
|
|
74
|
-
but allows the program execution to continue.
|
|
75
|
-
"""
|
|
76
|
-
self.__processOutput(*args, exit_after=False)
|
|
77
|
-
|
|
78
|
-
def __processOutput(self, *args: Any, exit_after: bool) -> None:
|
|
79
|
-
"""
|
|
80
|
-
Processes the output based on the provided arguments and determines the appropriate
|
|
81
|
-
format for displaying the data.
|
|
82
|
-
|
|
83
|
-
Parameters
|
|
84
|
-
----------
|
|
85
|
-
*args : Any
|
|
86
|
-
Variable-length arguments representing the data to be processed.
|
|
87
|
-
exit_after : bool
|
|
88
|
-
If True, the program will exit after processing the output.
|
|
89
|
-
|
|
90
|
-
Raises
|
|
91
|
-
------
|
|
92
|
-
Exception
|
|
93
|
-
Catches and logs any exception that occurs during processing.
|
|
94
|
-
|
|
95
|
-
Notes
|
|
96
|
-
-----
|
|
97
|
-
If `exit_after` is True, the program will terminate with an exit code of 1.
|
|
98
|
-
Determines whether to display data as a table, JSON, or raw dump based on its structure.
|
|
99
|
-
"""
|
|
100
|
-
|
|
101
|
-
# Try to process the output and handle any exceptions that may occur
|
|
102
|
-
try:
|
|
103
|
-
|
|
104
|
-
# Check if any arguments were provided
|
|
105
|
-
if not args:
|
|
106
|
-
raise ValueError("No arguments were provided, or the arguments are null or invalid")
|
|
107
|
-
|
|
108
|
-
# If only one argument is provided, determine its type and print accordingly
|
|
109
|
-
elif len(args) == 1:
|
|
110
|
-
arg = args[0]
|
|
111
|
-
if self.__isJsonSerializable(arg) and self.__isTabular(arg) and isinstance(arg, (list)):
|
|
112
|
-
self.__printTable(arg)
|
|
113
|
-
elif self.__isJsonSerializable(arg):
|
|
114
|
-
self.__printJson(arg)
|
|
115
|
-
else:
|
|
116
|
-
self.__printDump(args)
|
|
117
|
-
|
|
118
|
-
# If multiple arguments are provided, determine the type of each and print accordingly
|
|
119
|
-
else:
|
|
120
|
-
self.__printDump(args)
|
|
121
|
-
|
|
122
|
-
except Exception as e:
|
|
123
|
-
|
|
124
|
-
# If an error occurs, print the error message in a standard panel format
|
|
125
|
-
self.__printStandardPanel(
|
|
126
|
-
f"[bold red]An error occurred while processing the debug output: {str(e)}[/]",
|
|
127
|
-
border_style="red",
|
|
128
|
-
)
|
|
129
|
-
finally:
|
|
130
|
-
|
|
131
|
-
# If exit_after is True, exit the program with a non-zero status code
|
|
132
|
-
if exit_after:
|
|
133
|
-
os._exit(1)
|
|
134
|
-
|
|
135
|
-
def __printDump(self, args: tuple) -> None:
|
|
136
|
-
"""
|
|
137
|
-
Prints a formatted dump of the provided arguments to the console.
|
|
138
|
-
|
|
139
|
-
Parameters
|
|
140
|
-
----------
|
|
141
|
-
args : tuple
|
|
142
|
-
A tuple containing the objects to be dumped and displayed.
|
|
143
|
-
|
|
144
|
-
Returns
|
|
145
|
-
-------
|
|
146
|
-
This method doesn't return anything.
|
|
147
|
-
|
|
148
|
-
Notes
|
|
149
|
-
-----
|
|
150
|
-
This method processes each argument in the tuple, clears the recursion guard
|
|
151
|
-
for each iteration, renders the argument using the __render method, and then
|
|
152
|
-
prints all rendered content in a formatted panel with syntax highlighting.
|
|
153
|
-
"""
|
|
154
|
-
|
|
155
|
-
# Clear the recursion guard before processing the arguments
|
|
156
|
-
content = []
|
|
157
|
-
for arg in args:
|
|
158
|
-
self._recursion_guard.clear()
|
|
159
|
-
content.append(self.__render(arg))
|
|
160
|
-
|
|
161
|
-
# Print the rendered content in a standard panel with syntax highlighting
|
|
162
|
-
self.__printStandardPanel(
|
|
163
|
-
Syntax(
|
|
164
|
-
"\n".join(content),
|
|
165
|
-
"python",
|
|
166
|
-
line_numbers=False,
|
|
167
|
-
background_color="default",
|
|
168
|
-
word_wrap=True
|
|
169
|
-
),
|
|
170
|
-
border_style="cyan bold",
|
|
171
|
-
)
|
|
172
|
-
|
|
173
|
-
def __printJson(self, data: Any) -> None:
|
|
174
|
-
"""
|
|
175
|
-
Print a JSON representation of the given data to the console using a styled panel.
|
|
176
|
-
|
|
177
|
-
Parameters
|
|
178
|
-
----------
|
|
179
|
-
data : Any
|
|
180
|
-
The data to be serialized and displayed as JSON.
|
|
181
|
-
Must be a dictionary or list for proper JSON serialization.
|
|
182
|
-
|
|
183
|
-
Returns
|
|
184
|
-
-------
|
|
185
|
-
None
|
|
186
|
-
|
|
187
|
-
Raises
|
|
188
|
-
------
|
|
189
|
-
TypeError
|
|
190
|
-
If the data cannot be serialized to JSON, falls back to a generic dump method.
|
|
191
|
-
|
|
192
|
-
Notes
|
|
193
|
-
-----
|
|
194
|
-
Uses the `rich` library to format and display the JSON output with syntax highlighting.
|
|
195
|
-
Retrieves and displays the caller's line information for context.
|
|
196
|
-
Handles non-serializable objects using a custom JSON serializer.
|
|
197
|
-
If serialization fails, falls back to the `__printDump` method.
|
|
198
|
-
"""
|
|
199
|
-
try:
|
|
200
|
-
|
|
201
|
-
# Check if the data is JSON serializable
|
|
202
|
-
if not isinstance(data, (dict, list)):
|
|
203
|
-
raise TypeError("Data must be a dictionary or a list for JSON serialization.")
|
|
204
|
-
|
|
205
|
-
# Serialize the data to JSON format with custom serializer
|
|
206
|
-
json_str = json.dumps(
|
|
207
|
-
data,
|
|
208
|
-
ensure_ascii=False,
|
|
209
|
-
indent=2,
|
|
210
|
-
default=self.__jsonSerializer
|
|
211
|
-
)
|
|
212
|
-
|
|
213
|
-
# Print the JSON string in a standard panel with syntax highlighting
|
|
214
|
-
self.__printStandardPanel(
|
|
215
|
-
Syntax(
|
|
216
|
-
json_str,
|
|
217
|
-
"json",
|
|
218
|
-
line_numbers=True,
|
|
219
|
-
background_color="default",
|
|
220
|
-
word_wrap=True
|
|
221
|
-
),
|
|
222
|
-
border_style="green",
|
|
223
|
-
)
|
|
224
|
-
|
|
225
|
-
except TypeError:
|
|
226
|
-
|
|
227
|
-
# If serialization fails, print a dump of the data instead
|
|
228
|
-
self.__printDump((data,))
|
|
229
|
-
|
|
230
|
-
def __printTable(self, data: Any) -> None:
|
|
231
|
-
"""
|
|
232
|
-
Prints a formatted table representation of the given data.
|
|
233
|
-
|
|
234
|
-
Parameters
|
|
235
|
-
----------
|
|
236
|
-
data : Any
|
|
237
|
-
The data to be displayed in a tabular format.
|
|
238
|
-
Can be a list of dictionaries, list of objects, or a dictionary.
|
|
239
|
-
|
|
240
|
-
Returns
|
|
241
|
-
-------
|
|
242
|
-
None
|
|
243
|
-
This method doesn't return anything, it prints output to the console.
|
|
244
|
-
|
|
245
|
-
Notes
|
|
246
|
-
-----
|
|
247
|
-
- For lists of dictionaries: Uses dictionary keys as column headers
|
|
248
|
-
- For lists of objects: Uses object attribute names as column headers
|
|
249
|
-
- For simple lists: Shows index and value columns
|
|
250
|
-
- For dictionaries: Shows key-value pairs as two columns
|
|
251
|
-
- Falls back to __printDump if table rendering fails
|
|
252
|
-
"""
|
|
253
|
-
try:
|
|
254
|
-
|
|
255
|
-
# Create a table with specified styles and minimum width
|
|
256
|
-
table = Table(
|
|
257
|
-
show_header=True,
|
|
258
|
-
header_style="bold white on blue",
|
|
259
|
-
min_width=(self.console.width // 4) * 3
|
|
260
|
-
)
|
|
261
|
-
|
|
262
|
-
# Check if the data is in a tabular format (list or dict)
|
|
263
|
-
if isinstance(data, list):
|
|
264
|
-
|
|
265
|
-
# If the list is empty, print a message and return
|
|
266
|
-
if not data:
|
|
267
|
-
self.console.print("[yellow]Empty list[/]")
|
|
268
|
-
return
|
|
269
|
-
|
|
270
|
-
# Determine the columns based on the first item in the list
|
|
271
|
-
first = data[0]
|
|
272
|
-
if isinstance(first, dict):
|
|
273
|
-
columns = list(first.keys())
|
|
274
|
-
elif hasattr(first, '__dict__'):
|
|
275
|
-
columns = list(vars(first).keys())
|
|
276
|
-
else:
|
|
277
|
-
columns = ["Index", "Value"]
|
|
278
|
-
|
|
279
|
-
# Add columns to the table
|
|
280
|
-
for col in columns:
|
|
281
|
-
table.add_column(str(col))
|
|
282
|
-
|
|
283
|
-
# Populate the table with data
|
|
284
|
-
for i, item in enumerate(data):
|
|
285
|
-
if isinstance(item, dict):
|
|
286
|
-
table.add_row(*[str(item.get(col, '')) for col in columns])
|
|
287
|
-
elif hasattr(item, '__dict__'):
|
|
288
|
-
item_dict = vars(item)
|
|
289
|
-
table.add_row(*[str(item_dict.get(col, '')) for col in columns])
|
|
290
|
-
else:
|
|
291
|
-
table.add_row(str(i), str(item))
|
|
292
|
-
|
|
293
|
-
# If the data is a dictionary, create a key-value table
|
|
294
|
-
elif isinstance(data, dict):
|
|
295
|
-
table.add_column("Key", style="magenta")
|
|
296
|
-
table.add_column("Value")
|
|
297
|
-
|
|
298
|
-
for k, v in data.items():
|
|
299
|
-
table.add_row(str(k), str(v))
|
|
300
|
-
|
|
301
|
-
# If the data is not in a recognized format, print a dump
|
|
302
|
-
self.__printStandardPanel(
|
|
303
|
-
table,
|
|
304
|
-
border_style="blue",
|
|
305
|
-
)
|
|
306
|
-
|
|
307
|
-
except Exception:
|
|
308
|
-
|
|
309
|
-
# If an error occurs while creating the table, print a dump of the data
|
|
310
|
-
self.__printDump((data,))
|
|
311
|
-
|
|
312
|
-
def __printStandardPanel(self, renderable, border_style: str, padding=(0, 1)) -> None:
|
|
313
|
-
"""
|
|
314
|
-
Renders a standard panel with the given content and styling options.
|
|
315
|
-
|
|
316
|
-
Parameters
|
|
317
|
-
----------
|
|
318
|
-
renderable : Any
|
|
319
|
-
The content to be displayed inside the panel. This can be any renderable object
|
|
320
|
-
supported by the Rich library.
|
|
321
|
-
border_style : str
|
|
322
|
-
The style of the border for the panel (e.g., "green", "red bold").
|
|
323
|
-
padding : tuple, optional
|
|
324
|
-
A tuple specifying the padding inside the panel as (vertical, horizontal).
|
|
325
|
-
Default is (0, 1).
|
|
326
|
-
|
|
327
|
-
Returns
|
|
328
|
-
-------
|
|
329
|
-
None
|
|
330
|
-
This method prints to the console but does not return a value.
|
|
331
|
-
|
|
332
|
-
Notes
|
|
333
|
-
-----
|
|
334
|
-
This method uses the Rich library to create and display a panel with the specified
|
|
335
|
-
content and styling. It includes line information from the call stack and a timestamp.
|
|
336
|
-
"""
|
|
337
|
-
|
|
338
|
-
# Get the line information from the call stack or use the provided callback
|
|
339
|
-
if self.line_tcbk is None:
|
|
340
|
-
frame = inspect.currentframe()
|
|
341
|
-
caller_frame = frame.f_back.f_back.f_back.f_back if frame else None
|
|
342
|
-
line_info = f"[blue underline]{self.__getLineInfo(caller_frame) if caller_frame else 'Unknown location'}[/]"
|
|
343
|
-
|
|
344
|
-
# If a line callback is provided, use it to get the line information
|
|
345
|
-
else:
|
|
346
|
-
line_info = f"[blue underline]{self.line_tcbk}[/]"
|
|
347
|
-
|
|
348
|
-
# Get the current timestamp for the subtitle
|
|
349
|
-
subtitle = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
350
|
-
|
|
351
|
-
# Print a blank line before the panel for better readability
|
|
352
|
-
self.console.print()
|
|
353
|
-
self.console.print(Panel(
|
|
354
|
-
renderable,
|
|
355
|
-
title=f"Debugger - {line_info}",
|
|
356
|
-
title_align='left',
|
|
357
|
-
subtitle=subtitle,
|
|
358
|
-
subtitle_align='right',
|
|
359
|
-
border_style=border_style,
|
|
360
|
-
highlight=True,
|
|
361
|
-
padding=padding,
|
|
362
|
-
width=(self.console.width // 4) * 3,
|
|
363
|
-
))
|
|
364
|
-
self.console.print()
|
|
365
|
-
|
|
366
|
-
def __isTabular(self, data: Any) -> bool:
|
|
367
|
-
"""
|
|
368
|
-
Determines if the given data is in a tabular format.
|
|
369
|
-
|
|
370
|
-
Parameters
|
|
371
|
-
----------
|
|
372
|
-
data : Any
|
|
373
|
-
The data to be checked for tabular structure.
|
|
374
|
-
|
|
375
|
-
Returns
|
|
376
|
-
-------
|
|
377
|
-
bool
|
|
378
|
-
True if the data is in a tabular format, False otherwise.
|
|
379
|
-
|
|
380
|
-
Notes
|
|
381
|
-
-----
|
|
382
|
-
A data structure is considered tabular if it is:
|
|
383
|
-
- A list of dictionaries with identical keys
|
|
384
|
-
- A list of objects with attributes
|
|
385
|
-
- A dictionary
|
|
386
|
-
"""
|
|
387
|
-
|
|
388
|
-
# Check if the data is a list or a dictionary
|
|
389
|
-
if isinstance(data, list):
|
|
390
|
-
|
|
391
|
-
# If the list is empty, it is not considered tabular
|
|
392
|
-
if all(isinstance(item, dict) for item in data):
|
|
393
|
-
keys = set(data[0].keys())
|
|
394
|
-
return all(set(item.keys()) == keys for item in data)
|
|
395
|
-
|
|
396
|
-
# If the list contains objects, check if they have a __dict__ attribute
|
|
397
|
-
if len(data) > 0 and hasattr(data[0], '__dict__'):
|
|
398
|
-
return True
|
|
399
|
-
|
|
400
|
-
# If the data is a tuple, set, or any other iterable, it is not considered tabular
|
|
401
|
-
elif isinstance(data, dict):
|
|
402
|
-
return True
|
|
403
|
-
|
|
404
|
-
# If the data is not a list or dictionary, it is not considered tabular
|
|
405
|
-
return False
|
|
406
|
-
|
|
407
|
-
def __isJsonSerializable(self, data: Any) -> bool:
|
|
408
|
-
"""
|
|
409
|
-
Determines if the given data is JSON serializable.
|
|
410
|
-
|
|
411
|
-
Parameters
|
|
412
|
-
----------
|
|
413
|
-
data : Any
|
|
414
|
-
The data to check for JSON serializability.
|
|
415
|
-
|
|
416
|
-
Returns
|
|
417
|
-
-------
|
|
418
|
-
bool
|
|
419
|
-
True if the data is JSON serializable, False otherwise.
|
|
420
|
-
|
|
421
|
-
Notes
|
|
422
|
-
-----
|
|
423
|
-
This method attempts to serialize the provided data into a JSON string
|
|
424
|
-
using a custom serializer. If the serialization succeeds, the data is
|
|
425
|
-
considered JSON serializable.
|
|
426
|
-
"""
|
|
427
|
-
try:
|
|
428
|
-
|
|
429
|
-
# Attempt to serialize the data to JSON format
|
|
430
|
-
json.dumps(
|
|
431
|
-
data,
|
|
432
|
-
default=self.__jsonSerializer
|
|
433
|
-
)
|
|
434
|
-
|
|
435
|
-
# If serialization succeeds, return True
|
|
436
|
-
return True
|
|
437
|
-
|
|
438
|
-
except (TypeError, OverflowError):
|
|
439
|
-
|
|
440
|
-
# If serialization fails due to unsupported types or overflow,
|
|
441
|
-
# return False indicating the data is not JSON serializable
|
|
442
|
-
return False
|
|
443
|
-
|
|
444
|
-
def __render(self, value: Any, indent: int = 0, key: Any = None, depth: int = 0) -> str:
|
|
445
|
-
"""
|
|
446
|
-
Recursively renders a string representation of a given value.
|
|
447
|
-
|
|
448
|
-
Parameters
|
|
449
|
-
----------
|
|
450
|
-
value : Any
|
|
451
|
-
The value to render. Can be of any type, including dict, list, tuple, set,
|
|
452
|
-
dataclass, or objects with a `__dict__` attribute.
|
|
453
|
-
indent : int, optional
|
|
454
|
-
The current indentation level. Default is 0.
|
|
455
|
-
key : Any, optional
|
|
456
|
-
The key or index associated with the value, if applicable. Default is None.
|
|
457
|
-
depth : int, optional
|
|
458
|
-
The current recursion depth. Default is 0.
|
|
459
|
-
|
|
460
|
-
Returns
|
|
461
|
-
-------
|
|
462
|
-
str
|
|
463
|
-
A string representation of the value, formatted with indentation and type information.
|
|
464
|
-
|
|
465
|
-
Notes
|
|
466
|
-
-----
|
|
467
|
-
- Limits recursion depth to 10 to prevent infinite loops.
|
|
468
|
-
- Detects and handles recursive references to avoid infinite recursion.
|
|
469
|
-
- Supports rendering of common Python data structures, dataclasses, and objects with attributes.
|
|
470
|
-
- Formats datetime objects and callable objects with additional details.
|
|
471
|
-
"""
|
|
472
|
-
|
|
473
|
-
# Check for maximum recursion depth to prevent infinite loops
|
|
474
|
-
if depth > 10:
|
|
475
|
-
return "... (max depth)"
|
|
476
|
-
|
|
477
|
-
# Check for recursion guard to prevent infinite recursion
|
|
478
|
-
obj_id = id(value)
|
|
479
|
-
|
|
480
|
-
# If the object ID is already in the recursion guard, return a placeholder
|
|
481
|
-
if obj_id in self._recursion_guard:
|
|
482
|
-
return "... (recursive)"
|
|
483
|
-
|
|
484
|
-
# Add the object ID to the recursion guard to track it
|
|
485
|
-
self._recursion_guard.add(obj_id)
|
|
486
|
-
|
|
487
|
-
# Prepare the prefix for the rendered output
|
|
488
|
-
space = ' ' * indent
|
|
489
|
-
prefix = f"{space}"
|
|
490
|
-
|
|
491
|
-
# If a key is provided, format it and add it to the prefix
|
|
492
|
-
if key is not None:
|
|
493
|
-
prefix += f"{self.__formatKey(key)} => "
|
|
494
|
-
|
|
495
|
-
# If the value is None, return a formatted string indicating None
|
|
496
|
-
if value is None:
|
|
497
|
-
result = f"{prefix}None"
|
|
498
|
-
|
|
499
|
-
# Handle different types of values and format them accordingly
|
|
500
|
-
elif isinstance(value, dict):
|
|
501
|
-
result = f"{prefix}dict({len(value)})"
|
|
502
|
-
for k, v in value.items():
|
|
503
|
-
result += "\n" + self.__render(v, indent + self.indent_size, k, depth + 1)
|
|
504
|
-
|
|
505
|
-
# If the value is a list, tuple, or set, format it with its type and length
|
|
506
|
-
elif isinstance(value, (list, tuple, set)):
|
|
507
|
-
type_name = type(value).__name__
|
|
508
|
-
result = f"{prefix}{type_name}({len(value)})"
|
|
509
|
-
for i, item in enumerate(value):
|
|
510
|
-
result += "\n" + self.__render(
|
|
511
|
-
item,
|
|
512
|
-
indent + self.indent_size,
|
|
513
|
-
i if isinstance(value, (list, tuple)) else None,
|
|
514
|
-
depth + 1
|
|
515
|
-
)
|
|
516
|
-
|
|
517
|
-
# If the value is a string, format it with its type and length
|
|
518
|
-
elif is_dataclass(value):
|
|
519
|
-
result = f"{prefix}{value.__class__.__name__}"
|
|
520
|
-
for k, v in vars(value).items():
|
|
521
|
-
result += "\n" + self.__render(v, indent + self.indent_size, k, depth + 1)
|
|
522
|
-
|
|
523
|
-
# If the value is an object with a __dict__ attribute, format it with its class name
|
|
524
|
-
elif hasattr(value, "__dict__"):
|
|
525
|
-
result = f"{prefix}{value.__class__.__name__}"
|
|
526
|
-
for k, v in vars(value).items():
|
|
527
|
-
result += "\n" + self.__render(v, indent + self.indent_size, k, depth + 1)
|
|
528
|
-
|
|
529
|
-
# If the value is a datetime object, format it with its ISO 8601 string representation
|
|
530
|
-
elif isinstance(value, datetime):
|
|
531
|
-
result = f"{prefix}datetime({value.isoformat()})"
|
|
532
|
-
|
|
533
|
-
# If the value is a callable (function or method), format it with its name
|
|
534
|
-
elif callable(value):
|
|
535
|
-
result = f"{prefix}callable({value.__name__ if hasattr(value, '__name__') else repr(value)})"
|
|
536
|
-
|
|
537
|
-
# If the value is a simple type (int, float, str, etc.), format it with its type and value
|
|
538
|
-
else:
|
|
539
|
-
result = f"{prefix}{type(value).__name__}({repr(value)})"
|
|
540
|
-
|
|
541
|
-
# Remove the object ID from the recursion guard after processing
|
|
542
|
-
self._recursion_guard.discard(obj_id)
|
|
543
|
-
|
|
544
|
-
# Return the formatted result
|
|
545
|
-
return result
|
|
546
|
-
|
|
547
|
-
@staticmethod
|
|
548
|
-
def __jsonSerializer(obj):
|
|
549
|
-
"""
|
|
550
|
-
Serialize an object into a JSON-compatible format.
|
|
551
|
-
|
|
552
|
-
Parameters
|
|
553
|
-
----------
|
|
554
|
-
obj : object
|
|
555
|
-
The object to serialize. Supported types include:
|
|
556
|
-
|
|
557
|
-
Returns
|
|
558
|
-
-------
|
|
559
|
-
object
|
|
560
|
-
|
|
561
|
-
Raises
|
|
562
|
-
------
|
|
563
|
-
TypeError
|
|
564
|
-
If the object type is not supported for JSON serialization.
|
|
565
|
-
"""
|
|
566
|
-
|
|
567
|
-
# Check if the object is a datetime instance and return its ISO format
|
|
568
|
-
if isinstance(obj, datetime):
|
|
569
|
-
return obj.isoformat()
|
|
570
|
-
|
|
571
|
-
# Check if the object is a dataclass and return its dictionary representation
|
|
572
|
-
elif hasattr(obj, '__dict__'):
|
|
573
|
-
return vars(obj)
|
|
574
|
-
|
|
575
|
-
# Check if the object is a dataclass instance and return its dictionary representation
|
|
576
|
-
elif isinstance(obj, (set, tuple)):
|
|
577
|
-
return list(obj)
|
|
578
|
-
|
|
579
|
-
# If the object is a list, convert it to a list of JSON-serializable items
|
|
580
|
-
raise TypeError(f"Object of type {obj.__class__.__name__} is not JSON serializable")
|
|
581
|
-
|
|
582
|
-
@staticmethod
|
|
583
|
-
def __formatKey(key: Any) -> str:
|
|
584
|
-
"""
|
|
585
|
-
Formats a given key into a string representation.
|
|
586
|
-
|
|
587
|
-
Parameters
|
|
588
|
-
----------
|
|
589
|
-
key : Any
|
|
590
|
-
The key to be formatted. It can be of any type.
|
|
591
|
-
Returns
|
|
592
|
-
-------
|
|
593
|
-
str
|
|
594
|
-
A string representation of the key. If the key is a string, it is
|
|
595
|
-
"""
|
|
596
|
-
|
|
597
|
-
# If the key is a string, return it wrapped in quotes; otherwise, convert it to a string
|
|
598
|
-
if isinstance(key, str):
|
|
599
|
-
return f'"{key}"'
|
|
600
|
-
|
|
601
|
-
# If the key is not a string, convert it to a string representation
|
|
602
|
-
return str(key)
|
|
603
|
-
|
|
604
|
-
@staticmethod
|
|
605
|
-
def __getLineInfo(frame: inspect.FrameInfo) -> str:
|
|
606
|
-
"""
|
|
607
|
-
Extracts and formats line information from a given frame.
|
|
608
|
-
|
|
609
|
-
Parameters
|
|
610
|
-
----------
|
|
611
|
-
frame : inspect.FrameInfo
|
|
612
|
-
The frame object containing code context.
|
|
613
|
-
|
|
614
|
-
Returns
|
|
615
|
-
-------
|
|
616
|
-
str
|
|
617
|
-
A string in the format "filename:line_no", where `filename` is the
|
|
618
|
-
name of the file (excluding the path) and `line_no` is the line number
|
|
619
|
-
in the file where the frame is located.
|
|
620
|
-
"""
|
|
621
|
-
|
|
622
|
-
# Extract the filename and line number from the frame
|
|
623
|
-
filename = frame.f_code.co_filename.split('/')[-1]
|
|
624
|
-
line_no = frame.f_lineno
|
|
625
|
-
|
|
626
|
-
# Return the formatted string with filename and line number
|
|
627
|
-
return f"{filename}:{line_no}"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|