absfuyu 5.0.0__py3-none-any.whl → 5.1.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.
Potentially problematic release.
This version of absfuyu might be problematic. Click here for more details.
- absfuyu/__init__.py +1 -1
- absfuyu/__main__.py +2 -2
- absfuyu/cli/__init__.py +2 -2
- absfuyu/cli/color.py +30 -14
- absfuyu/cli/config_group.py +9 -2
- absfuyu/cli/do_group.py +13 -6
- absfuyu/cli/game_group.py +9 -2
- absfuyu/cli/tool_group.py +16 -9
- absfuyu/config/__init__.py +2 -2
- absfuyu/core/__init__.py +2 -2
- absfuyu/core/baseclass.py +449 -80
- absfuyu/core/baseclass2.py +2 -2
- absfuyu/core/decorator.py +69 -3
- absfuyu/core/docstring.py +25 -22
- absfuyu/core/dummy_cli.py +2 -2
- absfuyu/core/dummy_func.py +19 -6
- absfuyu/core/typings.py +40 -0
- absfuyu/dxt/__init__.py +2 -2
- absfuyu/dxt/dictext.py +2 -2
- absfuyu/dxt/dxt_support.py +2 -2
- absfuyu/dxt/intext.py +31 -3
- absfuyu/dxt/listext.py +28 -3
- absfuyu/dxt/strext.py +3 -3
- absfuyu/extra/__init__.py +2 -2
- absfuyu/extra/beautiful.py +3 -2
- absfuyu/extra/da/__init__.py +36 -0
- absfuyu/extra/da/dadf.py +1138 -0
- absfuyu/extra/da/dadf_base.py +186 -0
- absfuyu/extra/da/df_func.py +97 -0
- absfuyu/extra/da/mplt.py +219 -0
- absfuyu/extra/data_analysis.py +10 -1067
- absfuyu/fun/__init__.py +2 -2
- absfuyu/fun/tarot.py +2 -2
- absfuyu/game/__init__.py +2 -2
- absfuyu/game/game_stat.py +2 -2
- absfuyu/game/sudoku.py +2 -2
- absfuyu/game/tictactoe.py +2 -2
- absfuyu/game/wordle.py +2 -2
- absfuyu/general/__init__.py +4 -4
- absfuyu/general/content.py +2 -2
- absfuyu/general/human.py +2 -2
- absfuyu/general/shape.py +2 -2
- absfuyu/logger.py +2 -2
- absfuyu/pkg_data/__init__.py +2 -2
- absfuyu/pkg_data/deprecated.py +2 -2
- absfuyu/sort.py +2 -2
- absfuyu/tools/__init__.py +25 -2
- absfuyu/tools/checksum.py +27 -7
- absfuyu/tools/converter.py +93 -28
- absfuyu/{general → tools}/generator.py +2 -2
- absfuyu/tools/inspector.py +433 -0
- absfuyu/tools/keygen.py +2 -2
- absfuyu/tools/obfuscator.py +46 -8
- absfuyu/tools/passwordlib.py +88 -23
- absfuyu/tools/shutdownizer.py +2 -2
- absfuyu/tools/web.py +2 -2
- absfuyu/util/__init__.py +2 -2
- absfuyu/util/api.py +2 -2
- absfuyu/util/json_method.py +2 -2
- absfuyu/util/lunar.py +2 -2
- absfuyu/util/path.py +190 -82
- absfuyu/util/performance.py +4 -4
- absfuyu/util/shorten_number.py +40 -10
- absfuyu/util/text_table.py +272 -0
- absfuyu/util/zipped.py +6 -6
- absfuyu/version.py +59 -42
- {absfuyu-5.0.0.dist-info → absfuyu-5.1.0.dist-info}/METADATA +10 -3
- absfuyu-5.1.0.dist-info/RECORD +76 -0
- absfuyu-5.0.0.dist-info/RECORD +0 -68
- {absfuyu-5.0.0.dist-info → absfuyu-5.1.0.dist-info}/WHEEL +0 -0
- {absfuyu-5.0.0.dist-info → absfuyu-5.1.0.dist-info}/entry_points.txt +0 -0
- {absfuyu-5.0.0.dist-info → absfuyu-5.1.0.dist-info}/licenses/LICENSE +0 -0
absfuyu/core/baseclass.py
CHANGED
|
@@ -3,8 +3,8 @@ Absfuyu: Core
|
|
|
3
3
|
-------------
|
|
4
4
|
Bases for other features
|
|
5
5
|
|
|
6
|
-
Version: 5.
|
|
7
|
-
Date updated:
|
|
6
|
+
Version: 5.1.0
|
|
7
|
+
Date updated: 10/03/2025 (dd/mm/yyyy)
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
# Module Package
|
|
@@ -12,6 +12,9 @@ Date updated: 12/02/2025 (dd/mm/yyyy)
|
|
|
12
12
|
__all__ = [
|
|
13
13
|
# Color
|
|
14
14
|
"CLITextColor",
|
|
15
|
+
# Support
|
|
16
|
+
"MethodNPropertyList",
|
|
17
|
+
"MethodNPropertyResult",
|
|
15
18
|
# Mixins
|
|
16
19
|
"ShowAllMethodsMixin",
|
|
17
20
|
"AutoREPRMixin",
|
|
@@ -21,6 +24,10 @@ __all__ = [
|
|
|
21
24
|
"PositiveInitArgsMeta",
|
|
22
25
|
]
|
|
23
26
|
|
|
27
|
+
# Library
|
|
28
|
+
# ---------------------------------------------------------------------------
|
|
29
|
+
from typing import ClassVar, Literal, NamedTuple, Self
|
|
30
|
+
|
|
24
31
|
|
|
25
32
|
# Color
|
|
26
33
|
# ---------------------------------------------------------------------------
|
|
@@ -41,29 +48,194 @@ class CLITextColor:
|
|
|
41
48
|
|
|
42
49
|
# Mixins
|
|
43
50
|
# ---------------------------------------------------------------------------
|
|
44
|
-
|
|
51
|
+
# @versionadded("5.1.0")
|
|
52
|
+
class MethodNPropertyList(NamedTuple):
|
|
45
53
|
"""
|
|
46
|
-
|
|
54
|
+
Contains lists of methods, classmethods, staticmethods, and properties of a class.
|
|
47
55
|
|
|
48
|
-
|
|
56
|
+
Parameters
|
|
57
|
+
----------
|
|
58
|
+
methods : list[str]
|
|
59
|
+
List contains method names of a class.
|
|
60
|
+
|
|
61
|
+
classmethods : list[str]
|
|
62
|
+
List contains classmethod names of a class.
|
|
63
|
+
|
|
64
|
+
staticmethods : list[str]
|
|
65
|
+
List contains staticmethod names of a class.
|
|
66
|
+
|
|
67
|
+
properties : list[str]
|
|
68
|
+
List contains property names of a class.
|
|
49
69
|
"""
|
|
50
70
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
71
|
+
methods: list[str]
|
|
72
|
+
classmethods: list[str]
|
|
73
|
+
staticmethods: list[str]
|
|
74
|
+
properties: list[str]
|
|
75
|
+
|
|
76
|
+
def __repr__(self) -> str:
|
|
77
|
+
"""
|
|
78
|
+
Only shows list with items in repr
|
|
79
|
+
|
|
80
|
+
*This overwrites ``NamedTuple.__repr__()``*
|
|
81
|
+
"""
|
|
82
|
+
# return super().__repr__()
|
|
83
|
+
cls_name = self.__class__.__name__
|
|
84
|
+
out = []
|
|
85
|
+
sep = ", "
|
|
86
|
+
for x in self._fields:
|
|
87
|
+
if len(getattr(self, x)) > 0:
|
|
88
|
+
out.append(f"{x}={repr(getattr(self, x))}")
|
|
89
|
+
return f"{cls_name}({sep.join(out)})"
|
|
90
|
+
|
|
91
|
+
def is_empty(self) -> bool:
|
|
92
|
+
"""
|
|
93
|
+
Checks if all lists (methods, classmethods, staticmethods, properties) are empty.
|
|
94
|
+
"""
|
|
95
|
+
# for x in self:
|
|
96
|
+
# if len(x) > 0:
|
|
97
|
+
# return False
|
|
98
|
+
# return True
|
|
99
|
+
return all(len(getattr(self, x)) == 0 for x in self._fields)
|
|
100
|
+
|
|
101
|
+
def pack(
|
|
102
|
+
self,
|
|
103
|
+
include_method: bool = True,
|
|
54
104
|
include_classmethod: bool = True,
|
|
55
105
|
classmethod_indicator: str = "<classmethod>",
|
|
56
106
|
include_staticmethod: bool = True,
|
|
57
107
|
staticmethod_indicator: str = "<staticmethod>",
|
|
58
|
-
|
|
59
|
-
print_result: bool = False,
|
|
60
|
-
) -> dict[str, list[str]]:
|
|
108
|
+
) -> Self:
|
|
61
109
|
"""
|
|
62
|
-
|
|
63
|
-
|
|
110
|
+
Combines methods, classmethods, and staticmethods into one list.
|
|
111
|
+
|
|
112
|
+
Parameters
|
|
113
|
+
----------
|
|
114
|
+
include_method : bool, optional
|
|
115
|
+
Whether to include methods in the output, by default ``True``
|
|
116
|
+
|
|
117
|
+
include_classmethod : bool, optional
|
|
118
|
+
Whether to include classmethods in the output, by default ``True``
|
|
119
|
+
|
|
120
|
+
classmethod_indicator : str, optional
|
|
121
|
+
A string used to mark classmethod in the output. This string is appended
|
|
122
|
+
to the name of each classmethod to visually differentiate it from regular
|
|
123
|
+
instance methods, by default ``"<classmethod>"``
|
|
124
|
+
|
|
125
|
+
include_staticmethod : bool, optional
|
|
126
|
+
Whether to include staticmethods in the output, by default ``True``
|
|
127
|
+
|
|
128
|
+
staticmethod_indicator : str, optional
|
|
129
|
+
A string used to mark staticmethod in the output. This string is appended
|
|
130
|
+
to the name of each staticmethod to visually differentiate it from regular
|
|
131
|
+
instance methods, by default ``"<staticmethod>"``
|
|
132
|
+
|
|
133
|
+
Returns
|
|
134
|
+
-------
|
|
135
|
+
Self
|
|
136
|
+
MethodNPropertyList (combined methods lists)
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
Example:
|
|
140
|
+
--------
|
|
141
|
+
>>> test = MethodNPropertyList(["a"], ["b"], ["c"], ["d"])
|
|
142
|
+
>>> test.pack()
|
|
143
|
+
MethodNPropertyList(methods=['a', 'b <classmethod>', 'c <staticmethod>'], properties=['d'])
|
|
144
|
+
"""
|
|
145
|
+
new_methods_list = []
|
|
146
|
+
|
|
147
|
+
# Method
|
|
148
|
+
if include_method:
|
|
149
|
+
new_methods_list.extend(self.methods)
|
|
150
|
+
|
|
151
|
+
# Classmethod
|
|
152
|
+
if include_classmethod:
|
|
153
|
+
new_methods_list.extend(
|
|
154
|
+
[f"{x} {classmethod_indicator}".strip() for x in self.classmethods]
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
# Staticmethod
|
|
158
|
+
if include_staticmethod:
|
|
159
|
+
new_methods_list.extend(
|
|
160
|
+
[f"{x} {staticmethod_indicator}".strip() for x in self.staticmethods]
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
return self.__class__(new_methods_list, [], [], self.properties)
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
# @versionadded("5.1.0")
|
|
167
|
+
class MethodNPropertyResult(dict[str, MethodNPropertyList]):
|
|
168
|
+
"""
|
|
169
|
+
All methods and properties of a class and its parent classes.
|
|
170
|
+
|
|
171
|
+
Sorted in ascending order.
|
|
172
|
+
"""
|
|
173
|
+
|
|
174
|
+
_LINELENGTH: ClassVar[int] = 88
|
|
175
|
+
|
|
176
|
+
def _merge_value(
|
|
177
|
+
self,
|
|
178
|
+
value_name: Literal["methods", "classmethods", "staticmethods", "properties"],
|
|
179
|
+
) -> list[str]:
|
|
180
|
+
"""
|
|
181
|
+
Merge all specified values from the dictionary.
|
|
182
|
+
|
|
183
|
+
Parameters
|
|
184
|
+
----------
|
|
185
|
+
value_name : Literal["methods", "classmethods", "staticmethods", "properties"]
|
|
186
|
+
The type of value to merge.
|
|
187
|
+
|
|
188
|
+
Returns
|
|
189
|
+
-------
|
|
190
|
+
list[str]
|
|
191
|
+
A list of merged values.
|
|
192
|
+
"""
|
|
193
|
+
merged = []
|
|
194
|
+
for _, methods_n_properties in self.items():
|
|
195
|
+
if value_name in methods_n_properties._fields:
|
|
196
|
+
merged.extend(getattr(methods_n_properties, value_name))
|
|
197
|
+
return merged
|
|
198
|
+
|
|
199
|
+
def flatten_value(self) -> MethodNPropertyList:
|
|
200
|
+
"""
|
|
201
|
+
Merge all attributes of ``dict``'s values into one ``MethodNPropertyList``.
|
|
202
|
+
|
|
203
|
+
Returns
|
|
204
|
+
-------
|
|
205
|
+
MethodNPropertyList
|
|
206
|
+
Flattened value
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
Example:
|
|
210
|
+
--------
|
|
211
|
+
>>> test = MethodNPropertyResult(
|
|
212
|
+
... ABC=MethodNPropertyList(["a"], ["b"], ["c"], ["d"]),
|
|
213
|
+
... DEF=MethodNPropertyList(["e"], ["f"], ["g"], ["h"]),
|
|
214
|
+
... )
|
|
215
|
+
>>> test.flatten_value()
|
|
216
|
+
MethodNPropertyList(methods=["a", "e"], classmethods=["b", "f"], staticmethods=["c", "g"], properties=["d", "h"])
|
|
217
|
+
"""
|
|
218
|
+
res = []
|
|
219
|
+
for x in ["methods", "classmethods", "staticmethods", "properties"]:
|
|
220
|
+
res.append(self._merge_value(x)) # type: ignore
|
|
221
|
+
return MethodNPropertyList._make(res)
|
|
222
|
+
|
|
223
|
+
def pack_value(
|
|
224
|
+
self,
|
|
225
|
+
include_method: bool = True,
|
|
226
|
+
include_classmethod: bool = True,
|
|
227
|
+
classmethod_indicator: str = "<classmethod>",
|
|
228
|
+
include_staticmethod: bool = True,
|
|
229
|
+
staticmethod_indicator: str = "<staticmethod>",
|
|
230
|
+
) -> Self:
|
|
231
|
+
"""
|
|
232
|
+
Join method, classmethod, staticmethod into one list for each value.
|
|
64
233
|
|
|
65
234
|
Parameters
|
|
66
235
|
----------
|
|
236
|
+
include_method : bool, optional
|
|
237
|
+
Whether to include method in the output, by default ``True``
|
|
238
|
+
|
|
67
239
|
include_classmethod : bool, optional
|
|
68
240
|
Whether to include classmethod in the output, by default ``True``
|
|
69
241
|
|
|
@@ -80,52 +252,242 @@ class ShowAllMethodsMixin:
|
|
|
80
252
|
to the name of each staticmethod to visually differentiate it from regular
|
|
81
253
|
instance methods, by default ``"<staticmethod>"``
|
|
82
254
|
|
|
83
|
-
|
|
84
|
-
|
|
255
|
+
Returns
|
|
256
|
+
-------
|
|
257
|
+
Self
|
|
258
|
+
MethodNPropertyResult with packed value.
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
Example:
|
|
262
|
+
--------
|
|
263
|
+
>>> test = MethodNPropertyResult(
|
|
264
|
+
... ABC=MethodNPropertyList(["a"], ["b"], ["c"], ["d"]),
|
|
265
|
+
... DEF=MethodNPropertyList(["e"], ["f"], ["g"], ["h"]),
|
|
266
|
+
... )
|
|
267
|
+
>>> test.pack_value()
|
|
268
|
+
{
|
|
269
|
+
"ABC": MethodNPropertyList(
|
|
270
|
+
methods=["a", "b <classmethod>", "c <staticmethod>"], properties=["d"]
|
|
271
|
+
),
|
|
272
|
+
"DEF": MethodNPropertyList(
|
|
273
|
+
methods=["e", "f <classmethod>", "g <staticmethod>"], properties=["h"]
|
|
274
|
+
),
|
|
275
|
+
}
|
|
276
|
+
"""
|
|
277
|
+
for class_name, method_prop_list in self.items():
|
|
278
|
+
self[class_name] = method_prop_list.pack(
|
|
279
|
+
include_method=include_method,
|
|
280
|
+
include_classmethod=include_classmethod,
|
|
281
|
+
classmethod_indicator=classmethod_indicator,
|
|
282
|
+
include_staticmethod=include_staticmethod,
|
|
283
|
+
staticmethod_indicator=staticmethod_indicator,
|
|
284
|
+
)
|
|
285
|
+
return self
|
|
286
|
+
|
|
287
|
+
def prioritize_value(
|
|
288
|
+
self,
|
|
289
|
+
value_name: Literal[
|
|
290
|
+
"methods", "classmethods", "staticmethods", "properties"
|
|
291
|
+
] = "methods",
|
|
292
|
+
) -> dict[str, list[str]]:
|
|
293
|
+
"""
|
|
294
|
+
Prioritize which field of value to show.
|
|
85
295
|
|
|
86
|
-
|
|
87
|
-
|
|
296
|
+
Parameters
|
|
297
|
+
----------
|
|
298
|
+
value_name : Literal["methods", "classmethods", "staticmethods", "properties"], optional
|
|
299
|
+
The type of value to prioritize, by default ``"methods"``
|
|
88
300
|
|
|
89
301
|
Returns
|
|
90
302
|
-------
|
|
91
303
|
dict[str, list[str]]
|
|
92
|
-
A dictionary
|
|
304
|
+
A dictionary with prioritized values.
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
Example:
|
|
308
|
+
--------
|
|
309
|
+
>>> test = MethodNPropertyResult(
|
|
310
|
+
... ABC=MethodNPropertyList(["a"], ["b"], ["c"], ["d"]),
|
|
311
|
+
... DEF=MethodNPropertyList(["e"], ["f"], ["g"], ["h"]),
|
|
312
|
+
... )
|
|
313
|
+
>>> test.prioritize_value("methods")
|
|
314
|
+
{'ABC': ['a'], 'DEF': ['e']}
|
|
315
|
+
>>> test.prioritize_value("classmethods")
|
|
316
|
+
{'ABC': ['b'], 'DEF': ['f']}
|
|
317
|
+
>>> test.prioritize_value("staticmethods")
|
|
318
|
+
{'ABC': ['c'], 'DEF': ['g']}
|
|
319
|
+
>>> test.prioritize_value("properties")
|
|
320
|
+
{'ABC': ['d'], 'DEF': ['h']}
|
|
321
|
+
"""
|
|
322
|
+
result = {}
|
|
323
|
+
for k, v in self.items():
|
|
324
|
+
result[k] = getattr(v, value_name, v.methods)
|
|
325
|
+
return result
|
|
326
|
+
|
|
327
|
+
def print_output(
|
|
328
|
+
self,
|
|
329
|
+
where_to_print: Literal["methods", "properties"] = "methods",
|
|
330
|
+
print_in_one_column: bool = False,
|
|
331
|
+
) -> None:
|
|
332
|
+
"""
|
|
333
|
+
Beautifully print the result.
|
|
334
|
+
|
|
335
|
+
Parameters
|
|
336
|
+
----------
|
|
337
|
+
where_to_print : Literal["methods", "properties"], optional
|
|
338
|
+
Whether to print ``self.methods`` or ``self.properties``, by default ``"methods"``
|
|
339
|
+
|
|
340
|
+
print_in_one_column : bool, optional
|
|
341
|
+
Whether to print in one column, by default ``False``
|
|
342
|
+
"""
|
|
343
|
+
|
|
344
|
+
print_func = print # Can be extended with function parameter
|
|
345
|
+
|
|
346
|
+
# Loop through each class base
|
|
347
|
+
for order, (class_base, methods_n_properties) in enumerate(
|
|
348
|
+
self.items(), start=1
|
|
349
|
+
):
|
|
350
|
+
methods: list[str] = getattr(
|
|
351
|
+
methods_n_properties, where_to_print, methods_n_properties.methods
|
|
352
|
+
)
|
|
353
|
+
mlen = len(methods) # How many methods in that class
|
|
354
|
+
if mlen == 0:
|
|
355
|
+
continue
|
|
356
|
+
print_func(f"{order:02}. <{class_base}> | len: {mlen:02}")
|
|
357
|
+
|
|
358
|
+
# Modify methods list
|
|
359
|
+
max_method_name_len = max([len(x) for x in methods])
|
|
360
|
+
if mlen % 2 == 0:
|
|
361
|
+
p1, p2 = methods[: int(mlen / 2)], methods[int(mlen / 2) :]
|
|
362
|
+
else:
|
|
363
|
+
p1, p2 = methods[: int(mlen / 2) + 1], methods[int(mlen / 2) + 1 :]
|
|
364
|
+
p2.append("")
|
|
365
|
+
new_methods = list(zip(p1, p2))
|
|
366
|
+
|
|
367
|
+
# print
|
|
368
|
+
if print_in_one_column:
|
|
369
|
+
# This print 1 method in one line
|
|
370
|
+
for name in methods:
|
|
371
|
+
print(f" - {name.ljust(max_method_name_len)}")
|
|
372
|
+
else:
|
|
373
|
+
# This print 2 methods in 1 line
|
|
374
|
+
for x1, x2 in new_methods:
|
|
375
|
+
if x2 == "":
|
|
376
|
+
print_func(f" - {x1.ljust(max_method_name_len)}")
|
|
377
|
+
else:
|
|
378
|
+
print_func(
|
|
379
|
+
f" - {x1.ljust(max_method_name_len)} - {x2.ljust(max_method_name_len)}"
|
|
380
|
+
)
|
|
381
|
+
|
|
382
|
+
print_func("".ljust(self._LINELENGTH, "-"))
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
class ShowAllMethodsMixin:
|
|
386
|
+
"""
|
|
387
|
+
Show all methods of the class and its parent class minus ``object`` class
|
|
388
|
+
|
|
389
|
+
*This class is meant to be used with other class*
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
Example:
|
|
393
|
+
--------
|
|
394
|
+
>>> class TestClass(ShowAllMethodsMixin):
|
|
395
|
+
... def method1(self): ...
|
|
396
|
+
>>> TestClass._get_methods_and_properties()
|
|
397
|
+
{
|
|
398
|
+
"ShowAllMethodsMixin": MethodNPropertyList(
|
|
399
|
+
classmethods=[
|
|
400
|
+
"_get_methods_and_properties",
|
|
401
|
+
"show_all_methods",
|
|
402
|
+
"show_all_properties",
|
|
403
|
+
]
|
|
404
|
+
),
|
|
405
|
+
"TestClass": MethodNPropertyList(
|
|
406
|
+
methods=["method1"]
|
|
407
|
+
),
|
|
408
|
+
}
|
|
409
|
+
"""
|
|
410
|
+
|
|
411
|
+
# @versionadded("5.1.0")
|
|
412
|
+
@classmethod
|
|
413
|
+
def _get_methods_and_properties(
|
|
414
|
+
cls,
|
|
415
|
+
skip_private_attribute: bool = True,
|
|
416
|
+
include_private_method: bool = False,
|
|
417
|
+
) -> MethodNPropertyResult:
|
|
418
|
+
"""
|
|
419
|
+
Class method to get all methods and properties of the class and its parent classes
|
|
420
|
+
|
|
421
|
+
Parameters
|
|
422
|
+
----------
|
|
423
|
+
skip_private_attribute : bool, optional
|
|
424
|
+
Whether to include attribute with ``__`` (dunder) in the output, by default ``True``
|
|
425
|
+
|
|
426
|
+
include_private_method : bool, optional
|
|
427
|
+
Whether to include private method in the output, by default ``False``
|
|
428
|
+
|
|
429
|
+
Returns
|
|
430
|
+
-------
|
|
431
|
+
MethodNPropertyResult
|
|
432
|
+
A dictionary where keys are class names and values are tuples of method names and properties.
|
|
93
433
|
"""
|
|
94
|
-
|
|
434
|
+
|
|
435
|
+
# MRO in reverse order
|
|
436
|
+
classes = cls.__mro__[::-1]
|
|
95
437
|
result = {}
|
|
438
|
+
|
|
439
|
+
# For each class base in classes
|
|
96
440
|
for base in classes:
|
|
97
441
|
methods = []
|
|
442
|
+
classmethods = []
|
|
443
|
+
staticmethods = []
|
|
444
|
+
properties = []
|
|
445
|
+
|
|
446
|
+
# Dict items of base
|
|
98
447
|
for name, attr in base.__dict__.items():
|
|
99
448
|
# Skip private attribute
|
|
100
|
-
if name.startswith("__"):
|
|
449
|
+
if name.startswith("__") and skip_private_attribute:
|
|
101
450
|
continue
|
|
102
451
|
|
|
103
452
|
# Skip private Callable
|
|
104
453
|
if base.__name__ in name and not include_private_method:
|
|
105
454
|
continue
|
|
106
455
|
|
|
107
|
-
#
|
|
456
|
+
# Methods
|
|
108
457
|
if callable(attr):
|
|
109
458
|
if isinstance(attr, staticmethod):
|
|
110
|
-
|
|
111
|
-
methods.append(f"{name} {staticmethod_indicator}")
|
|
459
|
+
staticmethods.append(name)
|
|
112
460
|
else:
|
|
113
461
|
methods.append(name)
|
|
114
|
-
if isinstance(attr, classmethod)
|
|
115
|
-
|
|
462
|
+
if isinstance(attr, classmethod):
|
|
463
|
+
classmethods.append(name)
|
|
116
464
|
|
|
117
|
-
|
|
118
|
-
|
|
465
|
+
# Property
|
|
466
|
+
if isinstance(attr, property):
|
|
467
|
+
properties.append(name)
|
|
119
468
|
|
|
120
|
-
|
|
121
|
-
|
|
469
|
+
# Save to result
|
|
470
|
+
result[base.__name__] = MethodNPropertyList(
|
|
471
|
+
methods=sorted(methods),
|
|
472
|
+
classmethods=sorted(classmethods),
|
|
473
|
+
staticmethods=sorted(staticmethods),
|
|
474
|
+
properties=sorted(properties),
|
|
475
|
+
)
|
|
122
476
|
|
|
123
|
-
return result
|
|
477
|
+
return MethodNPropertyResult(result)
|
|
124
478
|
|
|
125
479
|
@classmethod
|
|
126
|
-
def
|
|
480
|
+
def show_all_methods(
|
|
481
|
+
cls,
|
|
482
|
+
print_result: bool = False,
|
|
483
|
+
include_classmethod: bool = True,
|
|
484
|
+
classmethod_indicator: str = "<classmethod>",
|
|
485
|
+
include_staticmethod: bool = True,
|
|
486
|
+
staticmethod_indicator: str = "<staticmethod>",
|
|
487
|
+
include_private_method: bool = False,
|
|
488
|
+
) -> dict[str, list[str]]:
|
|
127
489
|
"""
|
|
128
|
-
Class method to display all
|
|
490
|
+
Class method to display all methods of the class and its parent classes,
|
|
129
491
|
including the class in which they are defined in alphabetical order.
|
|
130
492
|
|
|
131
493
|
Parameters
|
|
@@ -133,71 +495,78 @@ class ShowAllMethodsMixin:
|
|
|
133
495
|
print_result : bool, optional
|
|
134
496
|
Beautifully print the output, by default ``False``
|
|
135
497
|
|
|
498
|
+
include_classmethod : bool, optional
|
|
499
|
+
Whether to include classmethod in the output, by default ``True``
|
|
500
|
+
|
|
501
|
+
classmethod_indicator : str, optional
|
|
502
|
+
A string used to mark classmethod in the output. This string is appended
|
|
503
|
+
to the name of each classmethod to visually differentiate it from regular
|
|
504
|
+
instance methods, by default ``"<classmethod>"``
|
|
505
|
+
|
|
506
|
+
include_staticmethod : bool, optional
|
|
507
|
+
Whether to include staticmethod in the output, by default ``True``
|
|
508
|
+
|
|
509
|
+
staticmethod_indicator : str, optional
|
|
510
|
+
A string used to mark staticmethod in the output. This string is appended
|
|
511
|
+
to the name of each staticmethod to visually differentiate it from regular
|
|
512
|
+
instance methods, by default ``"<staticmethod>"``
|
|
513
|
+
|
|
514
|
+
include_private_method : bool, optional
|
|
515
|
+
Whether to include private method in the output, by default ``False``
|
|
516
|
+
|
|
136
517
|
Returns
|
|
137
518
|
-------
|
|
138
519
|
dict[str, list[str]]
|
|
139
|
-
A dictionary where keys are class names and values are lists of
|
|
520
|
+
A dictionary where keys are class names and values are lists of method names.
|
|
140
521
|
"""
|
|
141
|
-
classes = cls.__mro__[::-1][1:] # MRO in reverse order
|
|
142
|
-
result = {}
|
|
143
|
-
for base in classes:
|
|
144
|
-
properties = []
|
|
145
|
-
for name, attr in base.__dict__.items():
|
|
146
|
-
# Skip private attribute
|
|
147
|
-
if name.startswith("__"):
|
|
148
|
-
continue
|
|
149
|
-
|
|
150
|
-
if isinstance(attr, property):
|
|
151
|
-
properties.append(name)
|
|
152
522
|
|
|
153
|
-
|
|
154
|
-
|
|
523
|
+
result = cls._get_methods_and_properties(
|
|
524
|
+
include_private_method=include_private_method
|
|
525
|
+
).pack_value(
|
|
526
|
+
include_classmethod=include_classmethod,
|
|
527
|
+
classmethod_indicator=classmethod_indicator,
|
|
528
|
+
include_staticmethod=include_staticmethod,
|
|
529
|
+
staticmethod_indicator=staticmethod_indicator,
|
|
530
|
+
)
|
|
155
531
|
|
|
156
532
|
if print_result:
|
|
157
|
-
|
|
533
|
+
result.print_output("methods")
|
|
158
534
|
|
|
159
|
-
return result
|
|
535
|
+
return result.prioritize_value("methods")
|
|
160
536
|
|
|
161
|
-
@
|
|
162
|
-
def
|
|
537
|
+
@classmethod
|
|
538
|
+
def show_all_properties(cls, print_result: bool = False) -> dict[str, list[str]]:
|
|
163
539
|
"""
|
|
164
|
-
|
|
540
|
+
Class method to display all properties of the class and its parent classes,
|
|
541
|
+
including the class in which they are defined in alphabetical order.
|
|
165
542
|
|
|
166
543
|
Parameters
|
|
167
544
|
----------
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
"""
|
|
171
|
-
print_func = print # Can be extended with function parameter
|
|
172
|
-
|
|
173
|
-
# Loop through each class base
|
|
174
|
-
for order, (class_base, methods) in enumerate(result.items(), start=1):
|
|
175
|
-
mlen = len(methods) # How many methods in that class
|
|
176
|
-
print_func(f"{order:02}. <{class_base}> | len: {mlen:02}")
|
|
545
|
+
print_result : bool, optional
|
|
546
|
+
Beautifully print the output, by default ``False``
|
|
177
547
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
p1, p2 = methods[: int(mlen / 2) + 1], methods[int(mlen / 2) + 1 :]
|
|
184
|
-
p2.append("")
|
|
185
|
-
new_methods = list(zip(p1, p2))
|
|
548
|
+
Returns
|
|
549
|
+
-------
|
|
550
|
+
dict[str, list[str]]
|
|
551
|
+
A dictionary where keys are class names and values are lists of property names.
|
|
552
|
+
"""
|
|
186
553
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
)
|
|
554
|
+
# result = cls.get_methods_and_properties().prioritize_value("properties")
|
|
555
|
+
result = MethodNPropertyResult(
|
|
556
|
+
{
|
|
557
|
+
cls.__name__: MethodNPropertyList(
|
|
558
|
+
[],
|
|
559
|
+
[],
|
|
560
|
+
[],
|
|
561
|
+
cls._get_methods_and_properties().flatten_value().properties,
|
|
562
|
+
)
|
|
563
|
+
}
|
|
564
|
+
)
|
|
195
565
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
# print(f" - {name.ljust(max_method_name_len)}")
|
|
566
|
+
if print_result:
|
|
567
|
+
result.print_output("properties")
|
|
199
568
|
|
|
200
|
-
|
|
569
|
+
return result.prioritize_value("properties")
|
|
201
570
|
|
|
202
571
|
|
|
203
572
|
class AutoREPRMixin:
|