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/tools/inspector.py
CHANGED
|
@@ -3,35 +3,193 @@ Absfuyu: Inspector
|
|
|
3
3
|
------------------
|
|
4
4
|
Inspector
|
|
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 level
|
|
11
11
|
# ---------------------------------------------------------------------------
|
|
12
12
|
__all__ = ["Inspector", "inspect_all"]
|
|
13
13
|
|
|
14
|
+
|
|
14
15
|
# Library
|
|
15
16
|
# ---------------------------------------------------------------------------
|
|
16
17
|
import inspect as _inspect
|
|
17
18
|
import os
|
|
19
|
+
from collections.abc import Callable
|
|
20
|
+
from dataclasses import dataclass
|
|
18
21
|
from functools import partial
|
|
19
22
|
from textwrap import TextWrapper
|
|
20
23
|
from textwrap import shorten as text_shorten
|
|
21
|
-
from typing import Any, Literal, overload
|
|
24
|
+
from typing import Any, Literal, Protocol, get_overloads, overload
|
|
22
25
|
|
|
23
26
|
from absfuyu.core.baseclass import (
|
|
24
27
|
AutoREPRMixin,
|
|
25
|
-
|
|
26
|
-
|
|
28
|
+
BaseDataclass,
|
|
29
|
+
ClassMembers,
|
|
30
|
+
ClassMembersResult,
|
|
31
|
+
GetClassMembersMixin,
|
|
27
32
|
)
|
|
28
33
|
from absfuyu.dxt.listext import ListExt
|
|
29
|
-
from absfuyu.
|
|
34
|
+
from absfuyu.typings import P, R
|
|
35
|
+
from absfuyu.util.text_table import BoxStyle, OneColumnTableMaker
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
# TODO: rewrite with each class for docs, method, property, attr, param, title
|
|
39
|
+
# Dataclass
|
|
40
|
+
# ---------------------------------------------------------------------------
|
|
41
|
+
@dataclass
|
|
42
|
+
class BaseDCInspect(BaseDataclass):
|
|
43
|
+
def _make_repr(self) -> str | None:
|
|
44
|
+
fields = self._get_fields()
|
|
45
|
+
if 0 < len(fields) < 2:
|
|
46
|
+
return repr(getattr(self, fields[0]))
|
|
47
|
+
return None
|
|
48
|
+
|
|
49
|
+
def _long_list_terminal_size(
|
|
50
|
+
self, long_list: list[str], width: int = 80, /
|
|
51
|
+
) -> list[str]:
|
|
52
|
+
ll = ListExt(long_list).wrap_to_column(width, margin=4, transpose=True)
|
|
53
|
+
return list(ll)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@dataclass
|
|
57
|
+
class _TitleSignature:
|
|
58
|
+
"""
|
|
59
|
+
Inspector:
|
|
60
|
+
Object's title and signature
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
title: str
|
|
64
|
+
signature: list[str]
|
|
65
|
+
|
|
66
|
+
def make_output(self):
|
|
67
|
+
pass
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
@dataclass
|
|
71
|
+
class _Docstring(BaseDCInspect):
|
|
72
|
+
"""
|
|
73
|
+
Inspector:
|
|
74
|
+
Object's docstring
|
|
75
|
+
"""
|
|
76
|
+
|
|
77
|
+
docs: str
|
|
78
|
+
|
|
79
|
+
def __repr__(self) -> str:
|
|
80
|
+
r = self._make_repr()
|
|
81
|
+
if r is not None:
|
|
82
|
+
return r
|
|
83
|
+
return super().__repr__()
|
|
84
|
+
|
|
85
|
+
def _get_first_paragraph(self) -> str:
|
|
86
|
+
# Get docs and get first paragraph
|
|
87
|
+
doc_lines = []
|
|
88
|
+
for line in self.docs.splitlines():
|
|
89
|
+
if len(line) < 1:
|
|
90
|
+
break
|
|
91
|
+
doc_lines.append(line.strip())
|
|
92
|
+
return " ".join(doc_lines)
|
|
93
|
+
|
|
94
|
+
def make_output(self) -> list[str]:
|
|
95
|
+
if len(self._get_first_paragraph()) > 0:
|
|
96
|
+
return ["Docstring:", self._get_first_paragraph()]
|
|
97
|
+
return [""]
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
@dataclass
|
|
101
|
+
class _MRO(BaseDCInspect):
|
|
102
|
+
"""
|
|
103
|
+
Inspector:
|
|
104
|
+
Object's MRO, bases
|
|
105
|
+
"""
|
|
106
|
+
|
|
107
|
+
mro: tuple[type, ...]
|
|
108
|
+
|
|
109
|
+
def __repr__(self) -> str:
|
|
110
|
+
r = self._make_repr()
|
|
111
|
+
if r is not None:
|
|
112
|
+
return r
|
|
113
|
+
return super().__repr__()
|
|
114
|
+
|
|
115
|
+
def _make_output(self) -> list[str]:
|
|
116
|
+
out = [
|
|
117
|
+
f"- {i:02}. {x.__module__}.{x.__name__}"
|
|
118
|
+
for i, x in enumerate(self.mro[1:], start=1)
|
|
119
|
+
]
|
|
120
|
+
# ListExt.wrap_to_column
|
|
121
|
+
return out
|
|
122
|
+
|
|
123
|
+
def make_output(self, *, width: int = 80) -> list[str]:
|
|
124
|
+
out = self._make_output()
|
|
125
|
+
if len(out) > 0:
|
|
126
|
+
out_ = self._long_list_terminal_size(out, width)
|
|
127
|
+
return ["", f"Bases (Len: {len(out)}):", *out_]
|
|
128
|
+
return [""]
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
@dataclass
|
|
132
|
+
class _Member(BaseDCInspect):
|
|
133
|
+
"""
|
|
134
|
+
Inspector:
|
|
135
|
+
Object's member
|
|
136
|
+
"""
|
|
137
|
+
|
|
138
|
+
member: ClassMembers
|
|
139
|
+
|
|
140
|
+
def __repr__(self) -> str:
|
|
141
|
+
r = self._make_repr()
|
|
142
|
+
if r is not None:
|
|
143
|
+
return r
|
|
144
|
+
return super().__repr__()
|
|
145
|
+
|
|
146
|
+
def make_output(
|
|
147
|
+
self,
|
|
148
|
+
*,
|
|
149
|
+
width: int = 80,
|
|
150
|
+
obj,
|
|
151
|
+
include_method: bool = True,
|
|
152
|
+
include_property: bool = True,
|
|
153
|
+
) -> list[str]:
|
|
154
|
+
mems = self.member.pack().sort()
|
|
155
|
+
body: list[str] = []
|
|
156
|
+
|
|
157
|
+
if include_method:
|
|
158
|
+
ml = [text_shorten(f"- {x}", width - 4) for x in mems.methods]
|
|
159
|
+
if len(ml) > 0:
|
|
160
|
+
head = ["", f"Methods (Len: {len(ml)}):"]
|
|
161
|
+
head.extend(self._long_list_terminal_size(ml, width))
|
|
162
|
+
body.extend(head)
|
|
163
|
+
|
|
164
|
+
if include_property:
|
|
165
|
+
pl = [
|
|
166
|
+
text_shorten(f"- {x} = {getattr(obj, x, None)}", width - 4)
|
|
167
|
+
for x in mems.properties
|
|
168
|
+
]
|
|
169
|
+
if len(pl) > 0:
|
|
170
|
+
head = ["", f"Properties (Len: {len(pl)}):"]
|
|
171
|
+
head.extend(self._long_list_terminal_size(pl, width))
|
|
172
|
+
body.extend(head)
|
|
173
|
+
|
|
174
|
+
if len(body) > 0:
|
|
175
|
+
return body
|
|
176
|
+
return [""]
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
class InspectComponents(Protocol):
|
|
180
|
+
"""Supports make_output() -> list[str]"""
|
|
181
|
+
|
|
182
|
+
@overload
|
|
183
|
+
def make_output(self) -> list[str]: ...
|
|
184
|
+
@overload
|
|
185
|
+
def make_output(self, *, width: int = ...) -> list[str]: ...
|
|
186
|
+
@overload
|
|
187
|
+
def make_output(self, *args, **kwargs) -> list[str]: ...
|
|
188
|
+
def make_output(self, *args, **kwargs) -> list[str]: ...
|
|
30
189
|
|
|
31
190
|
|
|
32
191
|
# Class
|
|
33
192
|
# ---------------------------------------------------------------------------
|
|
34
|
-
# TODO: rewrite with each class for docs, method, property, attr, param, title
|
|
35
193
|
class Inspector(AutoREPRMixin):
|
|
36
194
|
"""
|
|
37
195
|
Inspect an object.
|
|
@@ -71,7 +229,7 @@ class Inspector(AutoREPRMixin):
|
|
|
71
229
|
Maximum lines for the output's header (class, signature, repr).
|
|
72
230
|
Must be >= 1, by default ``8``
|
|
73
231
|
|
|
74
|
-
style :
|
|
232
|
+
style : BoxStyle, optional
|
|
75
233
|
Style for the table, by default ``"normal"``
|
|
76
234
|
|
|
77
235
|
|
|
@@ -99,7 +257,7 @@ class Inspector(AutoREPRMixin):
|
|
|
99
257
|
include_attribute: bool = True,
|
|
100
258
|
include_private: bool = False,
|
|
101
259
|
max_textwrap_lines: int = 8,
|
|
102
|
-
style:
|
|
260
|
+
style: BoxStyle = "normal",
|
|
103
261
|
) -> None: ...
|
|
104
262
|
|
|
105
263
|
def __init__(
|
|
@@ -116,10 +274,11 @@ class Inspector(AutoREPRMixin):
|
|
|
116
274
|
include_method: bool = False,
|
|
117
275
|
include_property: bool = False,
|
|
118
276
|
include_attribute: bool = True,
|
|
277
|
+
include_dunder: bool = False,
|
|
119
278
|
include_private: bool = False,
|
|
120
279
|
include_all: bool = False,
|
|
121
280
|
# Style
|
|
122
|
-
style:
|
|
281
|
+
style: BoxStyle = "normal",
|
|
123
282
|
) -> None:
|
|
124
283
|
"""
|
|
125
284
|
Inspect an object.
|
|
@@ -159,7 +318,7 @@ class Inspector(AutoREPRMixin):
|
|
|
159
318
|
Maximum lines for the output's header (class, signature, repr).
|
|
160
319
|
Must be >= 1, by default ``8``
|
|
161
320
|
|
|
162
|
-
style : Literal["normal", "bold", "dashed", "double", "rounded"], optional
|
|
321
|
+
style : BoxStyle | Literal["normal", "bold", "dashed", "double", "rounded", ...], optional
|
|
163
322
|
Style for the table, by default ``"normal"``
|
|
164
323
|
|
|
165
324
|
|
|
@@ -174,6 +333,7 @@ class Inspector(AutoREPRMixin):
|
|
|
174
333
|
self.include_property = include_property
|
|
175
334
|
self.include_attribute = include_attribute
|
|
176
335
|
self.include_private = include_private
|
|
336
|
+
self.include_dunder = include_dunder
|
|
177
337
|
self._style = style
|
|
178
338
|
|
|
179
339
|
if include_all:
|
|
@@ -209,21 +369,20 @@ class Inspector(AutoREPRMixin):
|
|
|
209
369
|
self._inspect_output = self._make_output()
|
|
210
370
|
|
|
211
371
|
def __str__(self) -> str:
|
|
212
|
-
return self.
|
|
372
|
+
return self._inspect_output.make_table()
|
|
213
373
|
|
|
214
|
-
# Support
|
|
374
|
+
# 00. Support
|
|
375
|
+
# -----------------------------------------------------------
|
|
376
|
+
# @deprecated
|
|
215
377
|
def _long_list_terminal_size(self, long_list: list) -> list:
|
|
216
378
|
ll = ListExt(long_list).wrap_to_column(
|
|
217
379
|
self._linelength, margin=4, transpose=True
|
|
218
380
|
)
|
|
219
381
|
return list(ll)
|
|
220
382
|
|
|
221
|
-
# Signature
|
|
383
|
+
# 01. Signature
|
|
384
|
+
# -----------------------------------------------------------
|
|
222
385
|
def _make_title(self) -> str:
|
|
223
|
-
"""
|
|
224
|
-
Inspector's workflow:
|
|
225
|
-
01. Make title
|
|
226
|
-
"""
|
|
227
386
|
title_str = (
|
|
228
387
|
str(self.obj)
|
|
229
388
|
if (
|
|
@@ -245,6 +404,7 @@ class Inspector(AutoREPRMixin):
|
|
|
245
404
|
return "def"
|
|
246
405
|
return ""
|
|
247
406
|
|
|
407
|
+
# @deprecated
|
|
248
408
|
def get_parameters(self) -> list[str] | None:
|
|
249
409
|
try:
|
|
250
410
|
sig = _inspect.signature(self.obj)
|
|
@@ -252,12 +412,27 @@ class Inspector(AutoREPRMixin):
|
|
|
252
412
|
return None
|
|
253
413
|
return [str(x) for x in sig.parameters.values()]
|
|
254
414
|
|
|
415
|
+
def _get_func_signature(self, func: Callable[P, R]) -> list[str]:
|
|
416
|
+
overloads = list(get_overloads(func))
|
|
417
|
+
if len(overloads) < 1:
|
|
418
|
+
return [
|
|
419
|
+
f"{self._get_signature_prefix()} {func.__name__}{_inspect.signature(func)}"
|
|
420
|
+
]
|
|
421
|
+
return [
|
|
422
|
+
f"{self._get_signature_prefix()} {x.__name__}{_inspect.signature(x)}"
|
|
423
|
+
for x in overloads
|
|
424
|
+
]
|
|
425
|
+
|
|
426
|
+
# @deprecated
|
|
255
427
|
def _make_signature(self) -> list[str]:
|
|
256
|
-
"""
|
|
257
|
-
Inspector's workflow:
|
|
258
|
-
02. Make signature
|
|
259
|
-
"""
|
|
260
428
|
try:
|
|
429
|
+
# if isinstance(self.obj, Callable):
|
|
430
|
+
if _inspect.isfunction(self.obj):
|
|
431
|
+
funcs = [
|
|
432
|
+
self._text_wrapper.wrap(x)
|
|
433
|
+
for x in self._get_func_signature(self.obj)
|
|
434
|
+
]
|
|
435
|
+
return ListExt(funcs).flatten()
|
|
261
436
|
return self._text_wrapper.wrap(
|
|
262
437
|
f"{self._get_signature_prefix()} {self.obj.__name__}{_inspect.signature(self.obj)}"
|
|
263
438
|
)
|
|
@@ -265,15 +440,93 @@ class Inspector(AutoREPRMixin):
|
|
|
265
440
|
except (ValueError, AttributeError, TypeError):
|
|
266
441
|
return self._text_wrapper.wrap(repr(self.obj))
|
|
267
442
|
|
|
268
|
-
|
|
269
|
-
def
|
|
443
|
+
@property
|
|
444
|
+
def obj_signature(self) -> _TitleSignature:
|
|
445
|
+
"""Object's title and signature"""
|
|
446
|
+
title: str = self._make_title()
|
|
447
|
+
sig: list[str] = []
|
|
448
|
+
try:
|
|
449
|
+
if _inspect.isfunction(self.obj):
|
|
450
|
+
sig.extend(self._get_func_signature(self.obj))
|
|
451
|
+
sig.append(
|
|
452
|
+
f"{self._get_signature_prefix()} {self.obj.__name__}{_inspect.signature(self.obj)}"
|
|
453
|
+
)
|
|
454
|
+
# not class, func | not type | is module
|
|
455
|
+
except (ValueError, AttributeError, TypeError):
|
|
456
|
+
sig.append(repr(self.obj))
|
|
457
|
+
|
|
458
|
+
return _TitleSignature(title=title, signature=sig)
|
|
459
|
+
|
|
460
|
+
# 02. Docstring
|
|
461
|
+
# -----------------------------------------------------------
|
|
462
|
+
@property
|
|
463
|
+
def obj_docs(self) -> _Docstring:
|
|
464
|
+
"""Object's docstring"""
|
|
465
|
+
docs: str | None = _inspect.getdoc(self.obj)
|
|
466
|
+
|
|
467
|
+
if docs is None:
|
|
468
|
+
return _Docstring("")
|
|
469
|
+
return _Docstring(docs=docs)
|
|
470
|
+
|
|
471
|
+
# @deprecated
|
|
472
|
+
def _get_docs(self) -> str:
|
|
473
|
+
docs: str | None = _inspect.getdoc(self.obj)
|
|
474
|
+
|
|
475
|
+
if docs is None:
|
|
476
|
+
return ""
|
|
477
|
+
|
|
478
|
+
# Get docs and get first paragraph
|
|
479
|
+
# doc_lines: list[str] = [x.strip() for x in docs.splitlines()]
|
|
480
|
+
doc_lines = []
|
|
481
|
+
for line in docs.splitlines():
|
|
482
|
+
if len(line) < 1:
|
|
483
|
+
break
|
|
484
|
+
doc_lines.append(line.strip())
|
|
485
|
+
|
|
486
|
+
return text_shorten(" ".join(doc_lines), width=self._linelength - 4, tabsize=4)
|
|
487
|
+
|
|
488
|
+
# 03. MRO/Bases
|
|
489
|
+
# -----------------------------------------------------------
|
|
490
|
+
@property
|
|
491
|
+
def obj_mro(self) -> _MRO:
|
|
492
|
+
"""Object's MRO, bases"""
|
|
493
|
+
if isinstance(self.obj, type):
|
|
494
|
+
return _MRO(mro=self.obj.__mro__[::-1])
|
|
495
|
+
return _MRO(mro=type(self.obj).__mro__[::-1])
|
|
496
|
+
|
|
497
|
+
@property
|
|
498
|
+
def obj_bases(self) -> _MRO:
|
|
499
|
+
"""Object's MRO, bases"""
|
|
500
|
+
return self.obj_mro
|
|
501
|
+
|
|
502
|
+
# @deprecated
|
|
503
|
+
def _get_mro(self) -> tuple[type, ...]:
|
|
504
|
+
"""Get MRO in reverse and subtract <class 'object'>"""
|
|
505
|
+
if isinstance(self.obj, type):
|
|
506
|
+
return self.obj.__mro__[::-1][1:]
|
|
507
|
+
return type(self.obj).__mro__[::-1][1:]
|
|
508
|
+
|
|
509
|
+
# @deprecated
|
|
510
|
+
def _make_mro_data(self) -> list[str]:
|
|
511
|
+
mro = [
|
|
512
|
+
f"- {i:02}. {x.__module__}.{x.__name__}"
|
|
513
|
+
for i, x in enumerate(self._get_mro(), start=1)
|
|
514
|
+
]
|
|
515
|
+
mod_chunk = self._long_list_terminal_size(mro)
|
|
516
|
+
|
|
517
|
+
# return [text_shorten(x, self._linelength - 4) for x in mod_chunk]
|
|
518
|
+
return mod_chunk
|
|
519
|
+
|
|
520
|
+
# 04. Class's members
|
|
521
|
+
# -----------------------------------------------------------
|
|
522
|
+
def _get_obj_member(self) -> ClassMembersResult:
|
|
270
523
|
# if _inspect.isclass(self.obj) or inspect.ismodule(self.obj):
|
|
271
524
|
if _inspect.isclass(self.obj):
|
|
272
525
|
tmpcls = type(
|
|
273
526
|
"tmpcls",
|
|
274
527
|
(
|
|
275
528
|
self.obj,
|
|
276
|
-
|
|
529
|
+
GetClassMembersMixin,
|
|
277
530
|
),
|
|
278
531
|
{},
|
|
279
532
|
)
|
|
@@ -282,46 +535,38 @@ class Inspector(AutoREPRMixin):
|
|
|
282
535
|
"tmpcls",
|
|
283
536
|
(
|
|
284
537
|
type(self.obj),
|
|
285
|
-
|
|
538
|
+
GetClassMembersMixin,
|
|
286
539
|
),
|
|
287
540
|
{},
|
|
288
541
|
)
|
|
289
|
-
med_prop = tmpcls.
|
|
290
|
-
|
|
542
|
+
med_prop = tmpcls._get_members( # type: ignore
|
|
543
|
+
dunder=False, private=self.include_private
|
|
291
544
|
)
|
|
292
545
|
|
|
293
546
|
try:
|
|
294
|
-
# If self.obj is a subclass of
|
|
547
|
+
# If self.obj is a subclass of GetClassMembersMixin
|
|
295
548
|
_mro = getattr(
|
|
296
549
|
self.obj, "__mro__", getattr(type(self.obj), "__mro__", None)
|
|
297
550
|
)
|
|
298
|
-
if
|
|
551
|
+
if GetClassMembersMixin in _mro: # type: ignore
|
|
299
552
|
return med_prop # type: ignore
|
|
300
553
|
except AttributeError: # Not a class
|
|
301
554
|
pass
|
|
302
|
-
med_prop.__delitem__(
|
|
555
|
+
med_prop.__delitem__(GetClassMembersMixin.__name__)
|
|
303
556
|
return med_prop # type: ignore
|
|
304
557
|
|
|
305
|
-
|
|
306
|
-
def
|
|
307
|
-
"""
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
if docs is None:
|
|
314
|
-
return ""
|
|
315
|
-
|
|
316
|
-
# Get docs and get first paragraph
|
|
317
|
-
# doc_lines: list[str] = [x.strip() for x in docs.splitlines()]
|
|
318
|
-
doc_lines = []
|
|
319
|
-
for line in docs.splitlines():
|
|
320
|
-
if len(line) < 1:
|
|
321
|
-
break
|
|
322
|
-
doc_lines.append(line.strip())
|
|
558
|
+
@property
|
|
559
|
+
def obj_member(self) -> _Member:
|
|
560
|
+
"""Object's members"""
|
|
561
|
+
try:
|
|
562
|
+
mem = self._get_obj_member()
|
|
563
|
+
return _Member(mem.flatten_value())
|
|
564
|
+
except (TypeError, AttributeError):
|
|
565
|
+
return _Member(ClassMembers())
|
|
323
566
|
|
|
324
|
-
|
|
567
|
+
# @deprecated
|
|
568
|
+
def _get_method_property(self) -> ClassMembersResult:
|
|
569
|
+
return self._get_obj_member()
|
|
325
570
|
|
|
326
571
|
# Attribute
|
|
327
572
|
@staticmethod
|
|
@@ -385,24 +630,9 @@ class Inspector(AutoREPRMixin):
|
|
|
385
630
|
text_shorten(f"- {x[0]} = {x[1]}", self._linelength - 4) for x in attr_list
|
|
386
631
|
]
|
|
387
632
|
|
|
388
|
-
# Get MRO
|
|
389
|
-
def _get_mro(self) -> tuple[type, ...]:
|
|
390
|
-
"""Get MRO in reverse and subtract <class 'object'>"""
|
|
391
|
-
if isinstance(self.obj, type):
|
|
392
|
-
return self.obj.__mro__[::-1][1:]
|
|
393
|
-
return type(self.obj).__mro__[::-1][1:]
|
|
394
|
-
|
|
395
|
-
def _make_mro_data(self) -> list[str]:
|
|
396
|
-
mro = [
|
|
397
|
-
f"- {i:02}. {x.__module__}.{x.__name__}"
|
|
398
|
-
for i, x in enumerate(self._get_mro(), start=1)
|
|
399
|
-
]
|
|
400
|
-
mod_chunk = self._long_list_terminal_size(mro)
|
|
401
|
-
|
|
402
|
-
# return [text_shorten(x, self._linelength - 4) for x in mod_chunk]
|
|
403
|
-
return mod_chunk
|
|
404
|
-
|
|
405
633
|
# Output
|
|
634
|
+
# -----------------------------------------------------------
|
|
635
|
+
# @deprecated
|
|
406
636
|
def _make_output(self) -> OneColumnTableMaker:
|
|
407
637
|
table = OneColumnTableMaker(self._linelength, style=self._style)
|
|
408
638
|
body: list[str] = []
|
|
@@ -468,8 +698,55 @@ class Inspector(AutoREPRMixin):
|
|
|
468
698
|
|
|
469
699
|
return table
|
|
470
700
|
|
|
471
|
-
def
|
|
472
|
-
|
|
701
|
+
def _make_output_2(self) -> OneColumnTableMaker:
|
|
702
|
+
# Prep
|
|
703
|
+
# components: list[InspectComponents] = [
|
|
704
|
+
# self.obj_signature,
|
|
705
|
+
# self.obj_docs,
|
|
706
|
+
# self.obj_mro,
|
|
707
|
+
# self.obj_member,
|
|
708
|
+
# ]
|
|
709
|
+
table = OneColumnTableMaker(self._linelength, style=self._style)
|
|
710
|
+
body: list[str] = []
|
|
711
|
+
|
|
712
|
+
# Signature
|
|
713
|
+
title = self.obj_signature.title
|
|
714
|
+
table.add_title(title)
|
|
715
|
+
if table._title == "": # Title too long
|
|
716
|
+
_title = [title]
|
|
717
|
+
_title.extend(self.obj_signature.signature)
|
|
718
|
+
table.add_paragraph(_title)
|
|
719
|
+
else:
|
|
720
|
+
table.add_paragraph(self.obj_signature.signature)
|
|
721
|
+
|
|
722
|
+
# Docstring
|
|
723
|
+
if self.include_docs:
|
|
724
|
+
body.extend(self.obj_docs.make_output())
|
|
725
|
+
|
|
726
|
+
# Class bases
|
|
727
|
+
if self.include_mro:
|
|
728
|
+
body.extend(self.obj_mro.make_output(width=self._linelength))
|
|
729
|
+
|
|
730
|
+
# Method & Property
|
|
731
|
+
body.extend(
|
|
732
|
+
self.obj_member.make_output(
|
|
733
|
+
width=self._linelength,
|
|
734
|
+
obj=self.obj,
|
|
735
|
+
include_method=self.include_method,
|
|
736
|
+
include_property=self.include_property,
|
|
737
|
+
)
|
|
738
|
+
)
|
|
739
|
+
|
|
740
|
+
# Attribute
|
|
741
|
+
attrs = self._get_attributes()
|
|
742
|
+
if len(attrs) > 0 and self.include_attribute:
|
|
743
|
+
body.extend(["", f"Attributes (Len: {len(attrs)}):"])
|
|
744
|
+
body.extend(self._handle_attributes_for_output(attr_list=attrs))
|
|
745
|
+
|
|
746
|
+
# Add to table
|
|
747
|
+
table.add_paragraph(body)
|
|
748
|
+
|
|
749
|
+
return table
|
|
473
750
|
|
|
474
751
|
|
|
475
752
|
# Partial
|
absfuyu/tools/keygen.py
CHANGED
absfuyu/tools/obfuscator.py
CHANGED
|
@@ -3,8 +3,8 @@ Absfuyu: Obfuscator
|
|
|
3
3
|
-------------------
|
|
4
4
|
Obfuscate code
|
|
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 level
|
|
@@ -22,7 +22,7 @@ from collections import deque
|
|
|
22
22
|
from string import Template
|
|
23
23
|
from typing import ClassVar
|
|
24
24
|
|
|
25
|
-
from absfuyu.core.baseclass import BaseClass,
|
|
25
|
+
from absfuyu.core.baseclass import BaseClass, GetClassMembersMixin
|
|
26
26
|
from absfuyu.core.docstring import versionadded
|
|
27
27
|
from absfuyu.dxt import Text
|
|
28
28
|
from absfuyu.logger import logger
|
|
@@ -110,7 +110,7 @@ class StrShifter(BaseClass):
|
|
|
110
110
|
return self._use_convert_table(self._make_convert_table())
|
|
111
111
|
|
|
112
112
|
|
|
113
|
-
class Obfuscator(
|
|
113
|
+
class Obfuscator(GetClassMembersMixin):
|
|
114
114
|
"""
|
|
115
115
|
Obfuscate code
|
|
116
116
|
|
absfuyu/tools/passwordlib.py
CHANGED
absfuyu/tools/shutdownizer.py
CHANGED
absfuyu/tools/web.py
CHANGED
absfuyu/typings.py
CHANGED
|
@@ -3,8 +3,8 @@ Absfuyu: Core
|
|
|
3
3
|
-------------
|
|
4
4
|
Pre-defined typing
|
|
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
|
|
@@ -14,6 +14,8 @@ __all__ = [
|
|
|
14
14
|
"T",
|
|
15
15
|
"T_co",
|
|
16
16
|
"T_contra",
|
|
17
|
+
"KT",
|
|
18
|
+
"VT",
|
|
17
19
|
"P",
|
|
18
20
|
"R",
|
|
19
21
|
"_CALLABLE",
|
|
@@ -48,6 +50,9 @@ T_co = TypeVar("T_co", covariant=True) # Type covariant
|
|
|
48
50
|
# with a more general type without causing errors
|
|
49
51
|
T_contra = TypeVar("T_contra", contravariant=True) # Type contravariant
|
|
50
52
|
|
|
53
|
+
KT = TypeVar("KT")
|
|
54
|
+
VT = TypeVar("VT")
|
|
55
|
+
|
|
51
56
|
# Callable
|
|
52
57
|
P = ParamSpec("P") # Parameter type
|
|
53
58
|
R = TypeVar("R") # Return type - Can be anything
|