absfuyu 5.3.0__py3-none-any.whl → 5.5.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 +2 -2
- absfuyu/cli/config_group.py +2 -2
- absfuyu/cli/do_group.py +2 -2
- absfuyu/cli/game_group.py +2 -2
- absfuyu/cli/tool_group.py +2 -2
- absfuyu/config/__init__.py +2 -2
- absfuyu/core/__init__.py +4 -4
- absfuyu/core/baseclass.py +511 -153
- absfuyu/core/baseclass2.py +3 -3
- absfuyu/core/decorator.py +2 -2
- absfuyu/core/docstring.py +2 -2
- absfuyu/core/dummy_cli.py +2 -2
- absfuyu/core/dummy_func.py +2 -2
- absfuyu/dxt/__init__.py +2 -2
- absfuyu/dxt/dictext.py +17 -14
- absfuyu/dxt/dxt_support.py +2 -2
- absfuyu/dxt/intext.py +52 -34
- absfuyu/dxt/listext.py +81 -14
- absfuyu/dxt/strext.py +4 -4
- absfuyu/extra/__init__.py +2 -2
- absfuyu/extra/beautiful.py +2 -2
- absfuyu/extra/da/__init__.py +2 -2
- absfuyu/extra/da/dadf.py +59 -56
- absfuyu/extra/da/dadf_base.py +2 -2
- absfuyu/extra/da/df_func.py +2 -2
- absfuyu/extra/da/mplt.py +2 -2
- absfuyu/extra/data_analysis.py +2 -2
- absfuyu/fun/__init__.py +7 -2
- absfuyu/fun/rubik.py +442 -0
- 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 +2 -2
- absfuyu/general/content.py +4 -4
- 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 +2 -2
- absfuyu/tools/checksum.py +2 -2
- absfuyu/tools/converter.py +2 -2
- absfuyu/tools/generator.py +4 -4
- absfuyu/tools/inspector.py +346 -69
- absfuyu/tools/keygen.py +2 -2
- absfuyu/tools/obfuscator.py +4 -4
- absfuyu/tools/passwordlib.py +2 -2
- absfuyu/tools/shutdownizer.py +2 -2
- absfuyu/tools/web.py +2 -2
- absfuyu/typings.py +7 -2
- absfuyu/util/__init__.py +57 -3
- absfuyu/util/api.py +2 -2
- absfuyu/util/json_method.py +2 -2
- absfuyu/util/lunar.py +2 -2
- absfuyu/util/path.py +17 -4
- absfuyu/util/performance.py +2 -2
- absfuyu/util/shorten_number.py +2 -2
- absfuyu/util/text_table.py +33 -14
- absfuyu/util/zipped.py +2 -2
- absfuyu/version.py +3 -3
- {absfuyu-5.3.0.dist-info → absfuyu-5.5.0.dist-info}/METADATA +2 -2
- absfuyu-5.5.0.dist-info/RECORD +77 -0
- absfuyu-5.3.0.dist-info/RECORD +0 -76
- {absfuyu-5.3.0.dist-info → absfuyu-5.5.0.dist-info}/WHEEL +0 -0
- {absfuyu-5.3.0.dist-info → absfuyu-5.5.0.dist-info}/entry_points.txt +0 -0
- {absfuyu-5.3.0.dist-info → absfuyu-5.5.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.5.0
|
|
7
|
+
Date updated: 23/04/2025 (dd/mm/yyyy)
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
# Module Package
|
|
@@ -13,20 +13,22 @@ __all__ = [
|
|
|
13
13
|
# Color
|
|
14
14
|
"CLITextColor",
|
|
15
15
|
# Support
|
|
16
|
-
"
|
|
17
|
-
"
|
|
16
|
+
"ClassMembers",
|
|
17
|
+
"ClassMembersResult",
|
|
18
18
|
# Mixins
|
|
19
|
-
"
|
|
19
|
+
"GetClassMembersMixin",
|
|
20
20
|
"AutoREPRMixin",
|
|
21
21
|
# Class
|
|
22
22
|
"BaseClass",
|
|
23
|
+
"BaseDataclass",
|
|
23
24
|
# Metaclass
|
|
24
25
|
"PositiveInitArgsMeta",
|
|
25
26
|
]
|
|
26
27
|
|
|
27
28
|
# Library
|
|
28
29
|
# ---------------------------------------------------------------------------
|
|
29
|
-
from
|
|
30
|
+
from dataclasses import dataclass, field
|
|
31
|
+
from typing import Any, ClassVar, Literal, Self
|
|
30
32
|
|
|
31
33
|
|
|
32
34
|
# Color
|
|
@@ -46,68 +48,145 @@ class CLITextColor:
|
|
|
46
48
|
RESET = "\x1b[39m"
|
|
47
49
|
|
|
48
50
|
|
|
49
|
-
#
|
|
51
|
+
# Dataclass
|
|
52
|
+
# ---------------------------------------------------------------------------
|
|
53
|
+
# @versionadded("5.5.0")
|
|
54
|
+
@dataclass
|
|
55
|
+
class BaseDataclass:
|
|
56
|
+
"""
|
|
57
|
+
Base dataclass.
|
|
58
|
+
|
|
59
|
+
Contains util methods:
|
|
60
|
+
- Get fields
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
@classmethod
|
|
64
|
+
def _get_fields(cls) -> tuple[str, ...]:
|
|
65
|
+
"""
|
|
66
|
+
Get dataclass's fields.
|
|
67
|
+
|
|
68
|
+
Returns
|
|
69
|
+
-------
|
|
70
|
+
tuple[str, ...]
|
|
71
|
+
Dataclass's fields.
|
|
72
|
+
"""
|
|
73
|
+
_fields = getattr(cls, "__dataclass_fields__", ())
|
|
74
|
+
return tuple(_fields)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
# Support
|
|
50
78
|
# ---------------------------------------------------------------------------
|
|
51
|
-
# @versionadded("5.
|
|
52
|
-
|
|
79
|
+
# @versionadded("5.5.0")
|
|
80
|
+
@dataclass
|
|
81
|
+
class ClassMembers(BaseDataclass):
|
|
53
82
|
"""
|
|
54
|
-
Contains lists of methods, classmethods, staticmethods,
|
|
83
|
+
Contains lists of methods, classmethods, staticmethods,
|
|
84
|
+
properties, and attributes of a class.
|
|
55
85
|
|
|
56
86
|
Parameters
|
|
57
87
|
----------
|
|
58
|
-
methods : list[str]
|
|
88
|
+
methods : list[str], optional
|
|
59
89
|
List contains method names of a class.
|
|
90
|
+
By default inits an empty list.
|
|
60
91
|
|
|
61
|
-
classmethods : list[str]
|
|
92
|
+
classmethods : list[str], optional
|
|
62
93
|
List contains classmethod names of a class.
|
|
94
|
+
By default inits an empty list.
|
|
63
95
|
|
|
64
|
-
staticmethods : list[str]
|
|
96
|
+
staticmethods : list[str], optional
|
|
65
97
|
List contains staticmethod names of a class.
|
|
98
|
+
By default inits an empty list.
|
|
66
99
|
|
|
67
|
-
properties : list[str]
|
|
100
|
+
properties : list[str], optional
|
|
68
101
|
List contains property names of a class.
|
|
102
|
+
By default inits an empty list.
|
|
103
|
+
|
|
104
|
+
attributes : list[str], optional
|
|
105
|
+
List contains attributes of a class instance.
|
|
106
|
+
By default inits an empty list.
|
|
107
|
+
|
|
108
|
+
classattributes : list[str], optional
|
|
109
|
+
List contains attributes of a class.
|
|
110
|
+
By default inits an empty list.
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
Available formats
|
|
114
|
+
-----------------
|
|
115
|
+
Alternative format to use with: ``format(<obj>, <format_spec>)``
|
|
116
|
+
- ``s``/``short`` (This hides attributes with empty value)
|
|
69
117
|
"""
|
|
70
118
|
|
|
71
|
-
methods: list[str]
|
|
72
|
-
classmethods: list[str]
|
|
73
|
-
staticmethods: list[str]
|
|
74
|
-
properties: list[str]
|
|
119
|
+
methods: list[str] = field(default_factory=list)
|
|
120
|
+
classmethods: list[str] = field(default_factory=list)
|
|
121
|
+
staticmethods: list[str] = field(default_factory=list)
|
|
122
|
+
properties: list[str] = field(default_factory=list)
|
|
123
|
+
attributes: list[str] = field(default_factory=list)
|
|
124
|
+
classattributes: list[str] = field(default_factory=list)
|
|
75
125
|
|
|
76
|
-
def
|
|
126
|
+
def __format__(self, format_spec: str) -> str:
|
|
77
127
|
"""
|
|
78
|
-
|
|
128
|
+
Available format:
|
|
129
|
+
- ``s``/``short`` (This hides attributes with empty value)
|
|
130
|
+
|
|
131
|
+
Parameters
|
|
132
|
+
----------
|
|
133
|
+
format_spec : str
|
|
134
|
+
Format spec
|
|
79
135
|
|
|
80
|
-
|
|
136
|
+
Returns
|
|
137
|
+
-------
|
|
138
|
+
str
|
|
139
|
+
Alternative text representation of this class.
|
|
81
140
|
"""
|
|
82
|
-
|
|
141
|
+
|
|
142
|
+
fmt = format_spec.lower().strip()
|
|
83
143
|
cls_name = self.__class__.__name__
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
144
|
+
|
|
145
|
+
if fmt == "short" or fmt == "s":
|
|
146
|
+
out = []
|
|
147
|
+
sep = ", "
|
|
148
|
+
for x in self._get_fields():
|
|
149
|
+
if len(getattr(self, x)) > 0:
|
|
150
|
+
out.append(f"{x}={repr(getattr(self, x))}")
|
|
151
|
+
return f"{cls_name}({sep.join(out)})"
|
|
152
|
+
|
|
153
|
+
return self.__repr__()
|
|
90
154
|
|
|
91
155
|
def is_empty(self) -> bool:
|
|
92
156
|
"""
|
|
93
|
-
Checks if all
|
|
157
|
+
Checks if all fields are empty.
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
Example:
|
|
161
|
+
--------
|
|
162
|
+
>>> ClassMembers().is_empty()
|
|
163
|
+
True
|
|
164
|
+
|
|
165
|
+
>>> ClassMembers(["a"]).is_empty()
|
|
166
|
+
False
|
|
94
167
|
"""
|
|
95
|
-
|
|
96
|
-
#
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
168
|
+
|
|
169
|
+
# return all(len(getattr(self, x)) == 0 for x in self._get_fields())
|
|
170
|
+
for x in self._get_fields():
|
|
171
|
+
if len(getattr(self, x)) > 0:
|
|
172
|
+
return False
|
|
173
|
+
return True
|
|
100
174
|
|
|
101
175
|
def pack(
|
|
102
176
|
self,
|
|
103
177
|
include_method: bool = True,
|
|
104
178
|
include_classmethod: bool = True,
|
|
105
|
-
classmethod_indicator: str = "<
|
|
179
|
+
classmethod_indicator: str = "<cls>",
|
|
106
180
|
include_staticmethod: bool = True,
|
|
107
|
-
staticmethod_indicator: str = "<
|
|
181
|
+
staticmethod_indicator: str = "<stc>",
|
|
182
|
+
include_attribute: bool = True,
|
|
183
|
+
include_classattribute: bool = True,
|
|
184
|
+
classattribute_indicator: str = "<cls>",
|
|
108
185
|
) -> Self:
|
|
109
186
|
"""
|
|
110
|
-
Combines
|
|
187
|
+
Combines the following into one list:
|
|
188
|
+
- methods, classmethods, and staticmethods
|
|
189
|
+
- attributes and class attributes
|
|
111
190
|
|
|
112
191
|
Parameters
|
|
113
192
|
----------
|
|
@@ -120,7 +199,7 @@ class MethodNPropertyList(NamedTuple):
|
|
|
120
199
|
classmethod_indicator : str, optional
|
|
121
200
|
A string used to mark classmethod in the output. This string is appended
|
|
122
201
|
to the name of each classmethod to visually differentiate it from regular
|
|
123
|
-
instance methods, by default ``"<
|
|
202
|
+
instance methods, by default ``"<cls>"``
|
|
124
203
|
|
|
125
204
|
include_staticmethod : bool, optional
|
|
126
205
|
Whether to include staticmethods in the output, by default ``True``
|
|
@@ -128,21 +207,32 @@ class MethodNPropertyList(NamedTuple):
|
|
|
128
207
|
staticmethod_indicator : str, optional
|
|
129
208
|
A string used to mark staticmethod in the output. This string is appended
|
|
130
209
|
to the name of each staticmethod to visually differentiate it from regular
|
|
131
|
-
instance methods, by default ``"<
|
|
210
|
+
instance methods, by default ``"<stc>"``
|
|
211
|
+
|
|
212
|
+
include_attribute : bool, optional
|
|
213
|
+
Whether to include attributes in the output, by default ``True``
|
|
214
|
+
|
|
215
|
+
include_classattribute : bool, optional
|
|
216
|
+
Whether to include class attributes in the output, by default ``True``
|
|
217
|
+
|
|
218
|
+
classattribute_indicator : str, optional
|
|
219
|
+
A string used to mark class attribute in the output. This string is appended
|
|
220
|
+
to the name of each class attribute to visually differentiate it from regular
|
|
221
|
+
instance attributes, by default ``"<cls>"``
|
|
132
222
|
|
|
133
223
|
Returns
|
|
134
224
|
-------
|
|
135
225
|
Self
|
|
136
|
-
|
|
226
|
+
ClassMembers (combined methods)
|
|
137
227
|
|
|
138
228
|
|
|
139
229
|
Example:
|
|
140
230
|
--------
|
|
141
|
-
>>>
|
|
142
|
-
|
|
143
|
-
MethodNPropertyList(methods=['a', 'b <classmethod>', 'c <staticmethod>'], properties=['d'])
|
|
231
|
+
>>> ClassMembers(["a"], ["b"], ["c"], ["d"], ["e"], ["f"]).pack().__format__("short")
|
|
232
|
+
ClassMembers(methods=['a', 'b <cls>', 'c <stc>'], properties=['d'], attributes=['e', 'f <cls>'])
|
|
144
233
|
"""
|
|
145
|
-
|
|
234
|
+
|
|
235
|
+
new_methods_list: list[str] = []
|
|
146
236
|
|
|
147
237
|
# Method
|
|
148
238
|
if include_method:
|
|
@@ -160,7 +250,27 @@ class MethodNPropertyList(NamedTuple):
|
|
|
160
250
|
[f"{x} {staticmethod_indicator}".strip() for x in self.staticmethods]
|
|
161
251
|
)
|
|
162
252
|
|
|
163
|
-
|
|
253
|
+
new_attributes_list: list[str] = []
|
|
254
|
+
|
|
255
|
+
# Attribute
|
|
256
|
+
if include_attribute:
|
|
257
|
+
new_attributes_list.extend(self.attributes)
|
|
258
|
+
|
|
259
|
+
# Class attribute
|
|
260
|
+
if include_classattribute:
|
|
261
|
+
new_attributes_list.extend(
|
|
262
|
+
[
|
|
263
|
+
f"{x} {classattribute_indicator}".strip()
|
|
264
|
+
for x in self.classattributes
|
|
265
|
+
]
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
# return self.__class__(new_methods_list, [], [], self.properties, [])
|
|
269
|
+
return self.__class__(
|
|
270
|
+
methods=new_methods_list,
|
|
271
|
+
properties=self.properties,
|
|
272
|
+
attributes=new_attributes_list,
|
|
273
|
+
)
|
|
164
274
|
|
|
165
275
|
def sort(self, reverse: bool = False) -> Self:
|
|
166
276
|
"""
|
|
@@ -174,45 +284,96 @@ class MethodNPropertyList(NamedTuple):
|
|
|
174
284
|
Returns
|
|
175
285
|
-------
|
|
176
286
|
Self
|
|
177
|
-
|
|
287
|
+
Self with sorted values.
|
|
178
288
|
|
|
179
289
|
|
|
180
290
|
Example:
|
|
181
291
|
--------
|
|
182
|
-
>>>
|
|
183
|
-
|
|
184
|
-
MethodNPropertyList(methods=['a', 'b'], classmethods=['c', 'd'], staticmethods=['e', 'f'], properties=['g', 'h'])
|
|
292
|
+
>>> ClassMembers(["b", "a"], ["d", "c"], ["f", "e"]).sort().__format__("short")
|
|
293
|
+
ClassMembers(methods=['a', 'b'], classmethods=['c', 'd'], staticmethods=['e', 'f'])
|
|
185
294
|
|
|
186
|
-
>>>
|
|
187
|
-
|
|
295
|
+
>>> ClassMembers(["b", "a"], ["d", "c"], ["f", "e"]).pack().sort().__format__("short")
|
|
296
|
+
ClassMembers(methods=['a', 'b', 'c <cls>', 'd <cls>', 'e <stc>', 'f <stc>'])
|
|
188
297
|
"""
|
|
189
|
-
|
|
190
|
-
|
|
298
|
+
|
|
299
|
+
sorted_vals: list[list[str]] = [
|
|
300
|
+
sorted(getattr(self, field), reverse=reverse)
|
|
301
|
+
for field in self._get_fields()
|
|
191
302
|
]
|
|
192
|
-
|
|
303
|
+
|
|
193
304
|
return self.__class__(*sorted_vals)
|
|
194
305
|
|
|
195
306
|
|
|
196
|
-
# @versionadded("5.
|
|
197
|
-
class
|
|
307
|
+
# @versionadded("5.5.0")
|
|
308
|
+
class ClassMembersResult(dict[str, ClassMembers]):
|
|
198
309
|
"""
|
|
199
|
-
All
|
|
200
|
-
|
|
201
|
-
Sorted in ascending order.
|
|
310
|
+
All members of a class and its parent classes.
|
|
202
311
|
"""
|
|
203
312
|
|
|
204
313
|
_LINELENGTH: ClassVar[int] = 88
|
|
205
314
|
|
|
315
|
+
def __format__(self, format_spec: str) -> str:
|
|
316
|
+
"""
|
|
317
|
+
Available format:
|
|
318
|
+
- ``s``/``short`` (This hides attributes with empty value)
|
|
319
|
+
|
|
320
|
+
Parameters
|
|
321
|
+
----------
|
|
322
|
+
format_spec : str
|
|
323
|
+
Format spec
|
|
324
|
+
|
|
325
|
+
Returns
|
|
326
|
+
-------
|
|
327
|
+
str
|
|
328
|
+
Alternative text representation of this class.
|
|
329
|
+
"""
|
|
330
|
+
|
|
331
|
+
fmt = format_spec.lower().strip()
|
|
332
|
+
|
|
333
|
+
if fmt == "short" or fmt == "s":
|
|
334
|
+
# out = {}
|
|
335
|
+
# for name, member in self.items():
|
|
336
|
+
# out[name] = format(member, fmt)
|
|
337
|
+
# return repr(out)
|
|
338
|
+
out = []
|
|
339
|
+
sep = ", "
|
|
340
|
+
for idx, (name, member) in enumerate(self.items()):
|
|
341
|
+
mem = format(member, fmt)
|
|
342
|
+
base = f"{repr(name)}: {mem}"
|
|
343
|
+
|
|
344
|
+
# if idx == 0:
|
|
345
|
+
# out.append("{" + base)
|
|
346
|
+
# elif idx + 1 == len(self.items()):
|
|
347
|
+
# out.append(base + "}")
|
|
348
|
+
# else:
|
|
349
|
+
# out.append(base)
|
|
350
|
+
out.append(
|
|
351
|
+
("{" if idx == 0 else "")
|
|
352
|
+
+ base
|
|
353
|
+
+ ("}" if idx + 1 == len(self.items()) else "")
|
|
354
|
+
)
|
|
355
|
+
|
|
356
|
+
return sep.join(out)
|
|
357
|
+
|
|
358
|
+
return self.__repr__()
|
|
359
|
+
|
|
206
360
|
def _merge_value(
|
|
207
361
|
self,
|
|
208
|
-
value_name: Literal[
|
|
362
|
+
value_name: Literal[
|
|
363
|
+
"methods",
|
|
364
|
+
"classmethods",
|
|
365
|
+
"staticmethods",
|
|
366
|
+
"properties",
|
|
367
|
+
"attributes",
|
|
368
|
+
"classattributes",
|
|
369
|
+
],
|
|
209
370
|
) -> list[str]:
|
|
210
371
|
"""
|
|
211
372
|
Merge all specified values from the dictionary.
|
|
212
373
|
|
|
213
374
|
Parameters
|
|
214
375
|
----------
|
|
215
|
-
value_name : Literal["methods", "classmethods", "staticmethods", "properties"]
|
|
376
|
+
value_name : Literal["methods", "classmethods", "staticmethods", "properties", "attributes", "classattributes"]
|
|
216
377
|
The type of value to merge.
|
|
217
378
|
|
|
218
379
|
Returns
|
|
@@ -220,35 +381,57 @@ class MethodNPropertyResult(dict[str, MethodNPropertyList]):
|
|
|
220
381
|
list[str]
|
|
221
382
|
A list of merged values.
|
|
222
383
|
"""
|
|
384
|
+
|
|
223
385
|
merged = []
|
|
224
|
-
for _,
|
|
225
|
-
if value_name in
|
|
226
|
-
merged.extend(getattr(
|
|
386
|
+
for _, member in self.items():
|
|
387
|
+
if value_name in member._get_fields():
|
|
388
|
+
merged.extend(getattr(member, value_name))
|
|
227
389
|
return merged
|
|
228
390
|
|
|
229
|
-
def flatten_value(self) ->
|
|
391
|
+
def flatten_value(self, sort: bool = True) -> ClassMembers:
|
|
230
392
|
"""
|
|
231
|
-
Merge all attributes of ``dict``'s values into one ``
|
|
393
|
+
Merge all attributes of ``dict``'s values into one ``ClassMembers``.
|
|
394
|
+
|
|
395
|
+
Parameters
|
|
396
|
+
----------
|
|
397
|
+
sort : bool
|
|
398
|
+
Sort value in ascending order after flatten, by default ``True``
|
|
232
399
|
|
|
233
400
|
Returns
|
|
234
401
|
-------
|
|
235
|
-
|
|
236
|
-
Flattened value
|
|
402
|
+
ClassMembers
|
|
403
|
+
Flattened value.
|
|
237
404
|
|
|
238
405
|
|
|
239
406
|
Example:
|
|
240
407
|
--------
|
|
241
|
-
>>> test =
|
|
242
|
-
... ABC=
|
|
243
|
-
... DEF=
|
|
408
|
+
>>> test = ClassMembersResult(
|
|
409
|
+
... ABC=ClassMembers(["a"], ["b"], ["c"], ["d"], ["y"], ["x"]),
|
|
410
|
+
... DEF=ClassMembers(["e"], ["f"], ["g"], ["h"], ["w"], ["z"]),
|
|
244
411
|
... )
|
|
245
412
|
>>> test.flatten_value()
|
|
246
|
-
|
|
413
|
+
ClassMembers(
|
|
414
|
+
methods=["a", "e"],
|
|
415
|
+
classmethods=["b", "f"],
|
|
416
|
+
staticmethods=["c", "g"],
|
|
417
|
+
properties=["d", "h"],
|
|
418
|
+
attributes=["w", "y"],
|
|
419
|
+
classattributes=["x", "z"],
|
|
420
|
+
)
|
|
247
421
|
"""
|
|
248
|
-
|
|
249
|
-
|
|
422
|
+
|
|
423
|
+
res: list[list[str]] = []
|
|
424
|
+
# for x in [
|
|
425
|
+
# "methods",
|
|
426
|
+
# "classmethods",
|
|
427
|
+
# "staticmethods",
|
|
428
|
+
# "properties",
|
|
429
|
+
# "attributes",
|
|
430
|
+
# "classattributes",
|
|
431
|
+
# ]:
|
|
432
|
+
for x in ClassMembers._get_fields():
|
|
250
433
|
res.append(self._merge_value(x)) # type: ignore
|
|
251
|
-
return
|
|
434
|
+
return ClassMembers(*res).sort() if sort else ClassMembers(*res)
|
|
252
435
|
|
|
253
436
|
def pack_value(
|
|
254
437
|
self,
|
|
@@ -257,9 +440,12 @@ class MethodNPropertyResult(dict[str, MethodNPropertyList]):
|
|
|
257
440
|
classmethod_indicator: str = "<classmethod>",
|
|
258
441
|
include_staticmethod: bool = True,
|
|
259
442
|
staticmethod_indicator: str = "<staticmethod>",
|
|
443
|
+
include_attribute: bool = True,
|
|
444
|
+
include_classattribute: bool = True,
|
|
445
|
+
classattribute_indicator: str = "<cls>",
|
|
260
446
|
) -> Self:
|
|
261
447
|
"""
|
|
262
|
-
Join
|
|
448
|
+
Join members into one list for each value.
|
|
263
449
|
|
|
264
450
|
Parameters
|
|
265
451
|
----------
|
|
@@ -282,42 +468,72 @@ class MethodNPropertyResult(dict[str, MethodNPropertyList]):
|
|
|
282
468
|
to the name of each staticmethod to visually differentiate it from regular
|
|
283
469
|
instance methods, by default ``"<staticmethod>"``
|
|
284
470
|
|
|
471
|
+
include_attribute : bool, optional
|
|
472
|
+
Whether to include attributes in the output, by default ``True``
|
|
473
|
+
|
|
474
|
+
include_classattribute : bool, optional
|
|
475
|
+
Whether to include class attributes in the output, by default ``True``
|
|
476
|
+
|
|
477
|
+
classattribute_indicator : str, optional
|
|
478
|
+
A string used to mark class attribute in the output. This string is appended
|
|
479
|
+
to the name of each class attribute to visually differentiate it from regular
|
|
480
|
+
instance attributes, by default ``"<cls>"``
|
|
481
|
+
|
|
285
482
|
Returns
|
|
286
483
|
-------
|
|
287
484
|
Self
|
|
288
|
-
|
|
485
|
+
ClassMembersResult with packed value.
|
|
289
486
|
|
|
290
487
|
|
|
291
488
|
Example:
|
|
292
489
|
--------
|
|
293
|
-
>>> test =
|
|
294
|
-
... ABC=
|
|
295
|
-
... DEF=
|
|
490
|
+
>>> test = ClassMembersResult(
|
|
491
|
+
... ABC=ClassMembers(["a"], ["b"], ["c"], ["d"], ["y"], ["x"]),
|
|
492
|
+
... DEF=ClassMembers(["e"], ["f"], ["g"], ["h"], ["w"], ["z"]),
|
|
296
493
|
... )
|
|
297
494
|
>>> test.pack_value()
|
|
298
495
|
{
|
|
299
|
-
"ABC":
|
|
300
|
-
methods=["a", "b <classmethod>", "c <staticmethod>"],
|
|
496
|
+
"ABC": ClassMembers(
|
|
497
|
+
methods=["a", "b <classmethod>", "c <staticmethod>"],
|
|
498
|
+
classmethods=[],
|
|
499
|
+
staticmethods=[],
|
|
500
|
+
properties=["d"],
|
|
501
|
+
attributes=["y", "x <cls>"],
|
|
502
|
+
classattributes=[],
|
|
301
503
|
),
|
|
302
|
-
"DEF":
|
|
303
|
-
methods=["e", "f <classmethod>", "g <staticmethod>"],
|
|
504
|
+
"DEF": ClassMembers(
|
|
505
|
+
methods=["e", "f <classmethod>", "g <staticmethod>"],
|
|
506
|
+
classmethods=[],
|
|
507
|
+
staticmethods=[],
|
|
508
|
+
properties=["h"],
|
|
509
|
+
attributes=["w", "z <cls>"],
|
|
510
|
+
classattributes=[],
|
|
304
511
|
),
|
|
305
512
|
}
|
|
306
513
|
"""
|
|
307
|
-
|
|
308
|
-
|
|
514
|
+
|
|
515
|
+
for class_name, members in self.items():
|
|
516
|
+
self[class_name] = members.pack(
|
|
309
517
|
include_method=include_method,
|
|
310
518
|
include_classmethod=include_classmethod,
|
|
311
519
|
classmethod_indicator=classmethod_indicator,
|
|
312
520
|
include_staticmethod=include_staticmethod,
|
|
313
521
|
staticmethod_indicator=staticmethod_indicator,
|
|
522
|
+
include_attribute=include_attribute,
|
|
523
|
+
include_classattribute=include_classattribute,
|
|
524
|
+
classattribute_indicator=classattribute_indicator,
|
|
314
525
|
)
|
|
315
526
|
return self
|
|
316
527
|
|
|
317
528
|
def prioritize_value(
|
|
318
529
|
self,
|
|
319
530
|
value_name: Literal[
|
|
320
|
-
"methods",
|
|
531
|
+
"methods",
|
|
532
|
+
"classmethods",
|
|
533
|
+
"staticmethods",
|
|
534
|
+
"properties",
|
|
535
|
+
"attributes",
|
|
536
|
+
"classattributes",
|
|
321
537
|
] = "methods",
|
|
322
538
|
) -> dict[str, list[str]]:
|
|
323
539
|
"""
|
|
@@ -325,7 +541,7 @@ class MethodNPropertyResult(dict[str, MethodNPropertyList]):
|
|
|
325
541
|
|
|
326
542
|
Parameters
|
|
327
543
|
----------
|
|
328
|
-
value_name : Literal["methods", "classmethods", "staticmethods", "properties"], optional
|
|
544
|
+
value_name : Literal["methods", "classmethods", "staticmethods", "properties", "attributes", "classattributes"], optional
|
|
329
545
|
The type of value to prioritize, by default ``"methods"``
|
|
330
546
|
|
|
331
547
|
Returns
|
|
@@ -336,9 +552,9 @@ class MethodNPropertyResult(dict[str, MethodNPropertyList]):
|
|
|
336
552
|
|
|
337
553
|
Example:
|
|
338
554
|
--------
|
|
339
|
-
>>> test =
|
|
340
|
-
... ABC=
|
|
341
|
-
... DEF=
|
|
555
|
+
>>> test = ClassMembersResult(
|
|
556
|
+
... ABC=ClassMembers(["a"], ["b"], ["c"], ["d"]),
|
|
557
|
+
... DEF=ClassMembers(["e"], ["f"], ["g"], ["h"]),
|
|
342
558
|
... )
|
|
343
559
|
>>> test.prioritize_value("methods")
|
|
344
560
|
{'ABC': ['a'], 'DEF': ['e']}
|
|
@@ -349,23 +565,26 @@ class MethodNPropertyResult(dict[str, MethodNPropertyList]):
|
|
|
349
565
|
>>> test.prioritize_value("properties")
|
|
350
566
|
{'ABC': ['d'], 'DEF': ['h']}
|
|
351
567
|
"""
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
568
|
+
|
|
569
|
+
result: dict[str, list[str]] = {}
|
|
570
|
+
for name, member in self.items():
|
|
571
|
+
result[name] = getattr(member, value_name, member.methods)
|
|
355
572
|
return result
|
|
356
573
|
|
|
357
574
|
def print_output(
|
|
358
575
|
self,
|
|
359
|
-
where_to_print: Literal["methods", "properties"] = "methods",
|
|
576
|
+
where_to_print: Literal["methods", "properties", "attributes"] = "methods",
|
|
360
577
|
print_in_one_column: bool = False,
|
|
361
578
|
) -> None:
|
|
362
579
|
"""
|
|
363
580
|
Beautifully print the result.
|
|
364
581
|
|
|
582
|
+
*This method is deprecated.*
|
|
583
|
+
|
|
365
584
|
Parameters
|
|
366
585
|
----------
|
|
367
|
-
where_to_print : Literal["methods", "properties"], optional
|
|
368
|
-
Whether to print ``
|
|
586
|
+
where_to_print : Literal["methods", "properties", "attributes"], optional
|
|
587
|
+
Whether to print ``methods`` or ``properties``, by default ``"methods"``
|
|
369
588
|
|
|
370
589
|
print_in_one_column : bool, optional
|
|
371
590
|
Whether to print in one column, by default ``False``
|
|
@@ -374,12 +593,8 @@ class MethodNPropertyResult(dict[str, MethodNPropertyList]):
|
|
|
374
593
|
print_func = print # Can be extended with function parameter
|
|
375
594
|
|
|
376
595
|
# Loop through each class base
|
|
377
|
-
for order, (class_base,
|
|
378
|
-
|
|
379
|
-
):
|
|
380
|
-
methods: list[str] = getattr(
|
|
381
|
-
methods_n_properties, where_to_print, methods_n_properties.methods
|
|
382
|
-
)
|
|
596
|
+
for order, (class_base, member) in enumerate(self.items(), start=1):
|
|
597
|
+
methods: list[str] = getattr(member, where_to_print, member.methods)
|
|
383
598
|
mlen = len(methods) # How many methods in that class
|
|
384
599
|
if mlen == 0:
|
|
385
600
|
continue
|
|
@@ -412,7 +627,9 @@ class MethodNPropertyResult(dict[str, MethodNPropertyList]):
|
|
|
412
627
|
print_func("".ljust(self._LINELENGTH, "-"))
|
|
413
628
|
|
|
414
629
|
|
|
415
|
-
|
|
630
|
+
# Mixins
|
|
631
|
+
# ---------------------------------------------------------------------------
|
|
632
|
+
class GetClassMembersMixin:
|
|
416
633
|
"""
|
|
417
634
|
Show all methods of the class and its parent class minus ``object`` class
|
|
418
635
|
|
|
@@ -421,66 +638,91 @@ class ShowAllMethodsMixin:
|
|
|
421
638
|
|
|
422
639
|
Example:
|
|
423
640
|
--------
|
|
424
|
-
>>> class TestClass(
|
|
641
|
+
>>> class TestClass(GetClassMembersMixin):
|
|
425
642
|
... def method1(self): ...
|
|
426
|
-
>>> TestClass.
|
|
643
|
+
>>> TestClass._get_members(dunder=False)
|
|
427
644
|
{
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
]
|
|
434
|
-
|
|
435
|
-
"TestClass": MethodNPropertyList(
|
|
436
|
-
methods=["method1"]
|
|
645
|
+
'GetClassMembersMixin': ClassMembers(
|
|
646
|
+
methods=[],
|
|
647
|
+
classmethods=['_get_members', ..., 'show_all_methods', 'show_all_properties'],
|
|
648
|
+
staticmethods=[],
|
|
649
|
+
properties=[],
|
|
650
|
+
attributes=[],
|
|
651
|
+
classattributes=[]
|
|
437
652
|
),
|
|
653
|
+
'TestClass': ClassMembers(
|
|
654
|
+
methods=['method1'],
|
|
655
|
+
classmethods=[],
|
|
656
|
+
staticmethods=[],
|
|
657
|
+
properties=[],
|
|
658
|
+
attributes=[],
|
|
659
|
+
classattributes=[]
|
|
660
|
+
)
|
|
438
661
|
}
|
|
439
662
|
"""
|
|
440
663
|
|
|
441
|
-
# @versionadded("5.
|
|
664
|
+
# @versionadded("5.5.0")
|
|
442
665
|
@classmethod
|
|
443
|
-
def
|
|
666
|
+
def _get_members(
|
|
444
667
|
cls,
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
668
|
+
dunder: bool = True,
|
|
669
|
+
underscore: bool = True,
|
|
670
|
+
private: bool = True,
|
|
671
|
+
) -> ClassMembersResult:
|
|
448
672
|
"""
|
|
449
|
-
Class method to get all methods
|
|
673
|
+
Class method to get all methods, properties, and attributes
|
|
674
|
+
of the class and its parent classes.
|
|
450
675
|
|
|
451
676
|
Parameters
|
|
452
677
|
----------
|
|
453
|
-
|
|
454
|
-
Whether to include attribute with ``__`` (dunder)
|
|
678
|
+
dunder : bool, optional
|
|
679
|
+
Whether to include attribute with ``__`` (dunder)
|
|
680
|
+
in the output, by default ``True``
|
|
455
681
|
|
|
456
|
-
|
|
457
|
-
Whether to include
|
|
682
|
+
underscore : bool, optional
|
|
683
|
+
Whether to include attribute starts with ``_``
|
|
684
|
+
in the output (will also skip dunder), by default ``True``
|
|
685
|
+
|
|
686
|
+
private : bool, optional
|
|
687
|
+
Whether to include private attribute
|
|
688
|
+
(``_<__class__.__name__>__<attribute>``)
|
|
689
|
+
in the output, by default ``True``
|
|
458
690
|
|
|
459
691
|
Returns
|
|
460
692
|
-------
|
|
461
|
-
|
|
462
|
-
A dictionary where keys are class names
|
|
693
|
+
ClassMembersResult
|
|
694
|
+
A dictionary where keys are class names
|
|
695
|
+
and values are tuples of method names and properties.
|
|
463
696
|
"""
|
|
464
697
|
|
|
465
698
|
# MRO in reverse order
|
|
466
699
|
classes = cls.__mro__[::-1]
|
|
467
|
-
result = {}
|
|
700
|
+
result: dict[str, ClassMembers] = {}
|
|
468
701
|
|
|
469
702
|
# For each class base in classes
|
|
470
703
|
for base in classes:
|
|
471
|
-
methods = []
|
|
472
|
-
classmethods = []
|
|
473
|
-
staticmethods = []
|
|
474
|
-
properties = []
|
|
704
|
+
methods: list[str] = []
|
|
705
|
+
classmethods: list[str] = []
|
|
706
|
+
staticmethods: list[str] = []
|
|
707
|
+
properties: list[str] = []
|
|
708
|
+
classattributes: list[str] = []
|
|
475
709
|
|
|
476
710
|
# Dict items of base
|
|
477
711
|
for name, attr in base.__dict__.items():
|
|
712
|
+
# Skip dunder
|
|
713
|
+
if name.startswith("__") and not dunder:
|
|
714
|
+
continue
|
|
715
|
+
|
|
478
716
|
# Skip private attribute
|
|
479
|
-
if
|
|
717
|
+
if base.__name__ in name and not private:
|
|
480
718
|
continue
|
|
481
719
|
|
|
482
|
-
# Skip
|
|
483
|
-
if
|
|
720
|
+
# Skip underscore
|
|
721
|
+
if (
|
|
722
|
+
name.startswith("_")
|
|
723
|
+
and not underscore
|
|
724
|
+
and base.__name__ not in name
|
|
725
|
+
):
|
|
484
726
|
continue
|
|
485
727
|
|
|
486
728
|
# Methods
|
|
@@ -489,22 +731,132 @@ class ShowAllMethodsMixin:
|
|
|
489
731
|
staticmethods.append(name)
|
|
490
732
|
else:
|
|
491
733
|
methods.append(name)
|
|
492
|
-
|
|
734
|
+
elif isinstance(attr, classmethod):
|
|
493
735
|
classmethods.append(name)
|
|
494
736
|
|
|
495
737
|
# Property
|
|
496
|
-
|
|
738
|
+
elif isinstance(attr, property):
|
|
497
739
|
properties.append(name)
|
|
498
740
|
|
|
741
|
+
# Class attribute
|
|
742
|
+
else:
|
|
743
|
+
classattributes.append(name)
|
|
744
|
+
|
|
499
745
|
# Save to result
|
|
500
|
-
result[base.__name__] =
|
|
501
|
-
methods=
|
|
502
|
-
classmethods=
|
|
503
|
-
staticmethods=
|
|
504
|
-
properties=
|
|
505
|
-
|
|
746
|
+
result[base.__name__] = ClassMembers(
|
|
747
|
+
methods=methods,
|
|
748
|
+
classmethods=classmethods,
|
|
749
|
+
staticmethods=staticmethods,
|
|
750
|
+
properties=properties,
|
|
751
|
+
classattributes=classattributes,
|
|
752
|
+
).sort()
|
|
753
|
+
|
|
754
|
+
return ClassMembersResult(result)
|
|
755
|
+
|
|
756
|
+
# @versionadded("5.5.0")
|
|
757
|
+
def _get_attributes(
|
|
758
|
+
self,
|
|
759
|
+
underscore: bool = True,
|
|
760
|
+
private: bool = True,
|
|
761
|
+
) -> list[str]:
|
|
762
|
+
"""
|
|
763
|
+
Get all attributes of the class instance.
|
|
764
|
+
|
|
765
|
+
Parameters
|
|
766
|
+
----------
|
|
767
|
+
underscore : bool, optional
|
|
768
|
+
Whether to include attribute starts with ``_``
|
|
769
|
+
in the output, by default ``True``
|
|
770
|
+
|
|
771
|
+
private : bool, optional
|
|
772
|
+
Whether to include private attribute
|
|
773
|
+
(``_<__class__.__name__>__<attribute>``)
|
|
774
|
+
in the output, by default ``True``
|
|
775
|
+
|
|
776
|
+
Returns
|
|
777
|
+
-------
|
|
778
|
+
list[str]
|
|
779
|
+
A list contains attributes.
|
|
780
|
+
"""
|
|
781
|
+
|
|
782
|
+
# Default output
|
|
783
|
+
out: list[str] = []
|
|
784
|
+
|
|
785
|
+
# Get attributes
|
|
786
|
+
cls_dict: dict[str, Any] | None = getattr(self, "__dict__", None)
|
|
787
|
+
cls_slots: tuple[str, ...] | None = getattr(self, "__slots__", None)
|
|
788
|
+
cls_name: str = self.__class__.__name__
|
|
789
|
+
|
|
790
|
+
def _is_valid(item_name: str) -> bool:
|
|
791
|
+
if not item_name.startswith("_"):
|
|
792
|
+
return True
|
|
793
|
+
if cls_name in item_name and private:
|
|
794
|
+
return True
|
|
795
|
+
if underscore and cls_name not in item_name:
|
|
796
|
+
return True
|
|
797
|
+
return False
|
|
798
|
+
|
|
799
|
+
# Check if __dict__ exist and len(__dict__) > 0
|
|
800
|
+
if cls_dict is not None and len(cls_dict) > 0:
|
|
801
|
+
# out = [x for x in self.__dict__ if _is_valid(x)]
|
|
802
|
+
out.extend(list(cls_dict))
|
|
506
803
|
|
|
507
|
-
|
|
804
|
+
# Check if __slots__ exist and len(__slots__) > 0
|
|
805
|
+
if cls_slots is not None and len(cls_slots) > 0:
|
|
806
|
+
# Convert __<attribute> to _<self.__class__.__name__>__<attribute>
|
|
807
|
+
_slot = [f"_{cls_name}{x}" if x.startswith("__") else x for x in cls_slots]
|
|
808
|
+
out.extend(_slot)
|
|
809
|
+
|
|
810
|
+
return [x for x in out if _is_valid(x)]
|
|
811
|
+
|
|
812
|
+
# @versionadded("5.5.0")
|
|
813
|
+
def get_members(
|
|
814
|
+
self,
|
|
815
|
+
dunder: bool = False,
|
|
816
|
+
underscore: bool = True,
|
|
817
|
+
private: bool = True,
|
|
818
|
+
) -> ClassMembersResult:
|
|
819
|
+
"""
|
|
820
|
+
Get all members of a class instance.
|
|
821
|
+
|
|
822
|
+
Parameters
|
|
823
|
+
----------
|
|
824
|
+
dunder : bool, optional
|
|
825
|
+
Whether to include attribute with ``__`` (dunder)
|
|
826
|
+
in the output, by default ``False``
|
|
827
|
+
|
|
828
|
+
underscore : bool, optional
|
|
829
|
+
Whether to include attribute starts with ``_``
|
|
830
|
+
in the output (will also skip dunder), by default ``True``
|
|
831
|
+
|
|
832
|
+
private : bool, optional
|
|
833
|
+
Whether to include private attribute
|
|
834
|
+
(``_<__class__.__name__>__<attribute>``)
|
|
835
|
+
in the output, by default ``True``
|
|
836
|
+
|
|
837
|
+
Returns
|
|
838
|
+
-------
|
|
839
|
+
ClassMembersResult
|
|
840
|
+
All member of a class instance.
|
|
841
|
+
"""
|
|
842
|
+
mems = self._get_members(dunder=dunder, underscore=underscore, private=private)
|
|
843
|
+
attrs = self._get_attributes(underscore=underscore, private=private)
|
|
844
|
+
mems[self.__class__.__name__].attributes = attrs
|
|
845
|
+
return mems
|
|
846
|
+
|
|
847
|
+
# @remove("6.0.0")
|
|
848
|
+
# @deprecated("5.5.0")
|
|
849
|
+
# @versionadded("5.1.0")
|
|
850
|
+
@classmethod
|
|
851
|
+
def _get_methods_and_properties(
|
|
852
|
+
cls,
|
|
853
|
+
skip_private_attribute: bool = True,
|
|
854
|
+
include_private_method: bool = False,
|
|
855
|
+
) -> ClassMembersResult:
|
|
856
|
+
"""Wrapper of ``cls._get_members``, deprecated"""
|
|
857
|
+
return cls._get_members(
|
|
858
|
+
dunder=skip_private_attribute, private=include_private_method
|
|
859
|
+
)
|
|
508
860
|
|
|
509
861
|
@classmethod
|
|
510
862
|
def show_all_methods(
|
|
@@ -550,8 +902,8 @@ class ShowAllMethodsMixin:
|
|
|
550
902
|
A dictionary where keys are class names and values are lists of method names.
|
|
551
903
|
"""
|
|
552
904
|
|
|
553
|
-
result = cls.
|
|
554
|
-
|
|
905
|
+
result = cls._get_members(
|
|
906
|
+
dunder=False, private=include_private_method
|
|
555
907
|
).pack_value(
|
|
556
908
|
include_classmethod=include_classmethod,
|
|
557
909
|
classmethod_indicator=classmethod_indicator,
|
|
@@ -582,13 +934,12 @@ class ShowAllMethodsMixin:
|
|
|
582
934
|
"""
|
|
583
935
|
|
|
584
936
|
# result = cls.get_methods_and_properties().prioritize_value("properties")
|
|
585
|
-
result =
|
|
937
|
+
result = ClassMembersResult(
|
|
586
938
|
{
|
|
587
|
-
cls.__name__:
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
cls._get_methods_and_properties().flatten_value().properties,
|
|
939
|
+
cls.__name__: ClassMembers(
|
|
940
|
+
properties=cls._get_members(dunder=False)
|
|
941
|
+
.flatten_value()
|
|
942
|
+
.properties,
|
|
592
943
|
)
|
|
593
944
|
}
|
|
594
945
|
)
|
|
@@ -599,6 +950,13 @@ class ShowAllMethodsMixin:
|
|
|
599
950
|
return result.prioritize_value("properties")
|
|
600
951
|
|
|
601
952
|
|
|
953
|
+
# Temp name for backward compability
|
|
954
|
+
# Will be removed at version 6.0.0
|
|
955
|
+
MethodNPropertyList = ClassMembers
|
|
956
|
+
MethodNPropertyResult = ClassMembersResult
|
|
957
|
+
ShowAllMethodsMixin = GetClassMembersMixin
|
|
958
|
+
|
|
959
|
+
|
|
602
960
|
class AutoREPRMixin:
|
|
603
961
|
"""
|
|
604
962
|
Generate ``repr()`` output as ``<class(param1=any, param2=any, ...)>``
|
|
@@ -658,7 +1016,7 @@ class AutoREPRMixin:
|
|
|
658
1016
|
|
|
659
1017
|
# Class
|
|
660
1018
|
# ---------------------------------------------------------------------------
|
|
661
|
-
class BaseClass(
|
|
1019
|
+
class BaseClass(GetClassMembersMixin, AutoREPRMixin):
|
|
662
1020
|
"""Base class"""
|
|
663
1021
|
|
|
664
1022
|
def __str__(self) -> str:
|