absfuyu 5.4.0__py3-none-any.whl → 5.6.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 +518 -154
- 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 +5 -11
- absfuyu/dxt/dxt_support.py +2 -2
- absfuyu/dxt/intext.py +4 -4
- absfuyu/dxt/listext.py +69 -14
- absfuyu/dxt/strext.py +5 -5
- absfuyu/extra/__init__.py +2 -2
- absfuyu/extra/beautiful.py +2 -2
- absfuyu/extra/da/__init__.py +3 -3
- absfuyu/extra/da/dadf.py +4 -4
- 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/extra/pdf.py +89 -0
- absfuyu/fun/__init__.py +2 -2
- absfuyu/fun/rubik.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 +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 +325 -71
- 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/sw.py +514 -0
- absfuyu/tools/web.py +2 -2
- absfuyu/typings.py +2 -2
- absfuyu/util/__init__.py +14 -3
- absfuyu/util/api.py +2 -2
- absfuyu/util/json_method.py +2 -2
- absfuyu/util/lunar.py +2 -2
- absfuyu/util/path.py +53 -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.4.0.dist-info → absfuyu-5.6.0.dist-info}/METADATA +7 -2
- absfuyu-5.6.0.dist-info/RECORD +79 -0
- absfuyu-5.4.0.dist-info/RECORD +0 -77
- {absfuyu-5.4.0.dist-info → absfuyu-5.6.0.dist-info}/WHEEL +0 -0
- {absfuyu-5.4.0.dist-info → absfuyu-5.6.0.dist-info}/entry_points.txt +0 -0
- {absfuyu-5.4.0.dist-info → absfuyu-5.6.0.dist-info}/licenses/LICENSE +0 -0
absfuyu/tools/inspector.py
CHANGED
|
@@ -3,8 +3,8 @@ Absfuyu: Inspector
|
|
|
3
3
|
------------------
|
|
4
4
|
Inspector
|
|
5
5
|
|
|
6
|
-
Version: 5.
|
|
7
|
-
Date updated:
|
|
6
|
+
Version: 5.6.0
|
|
7
|
+
Date updated: 12/09/2025 (dd/mm/yyyy)
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
# Module level
|
|
@@ -17,24 +17,177 @@ __all__ = ["Inspector", "inspect_all"]
|
|
|
17
17
|
import inspect as _inspect
|
|
18
18
|
import os
|
|
19
19
|
from collections.abc import Callable
|
|
20
|
+
from dataclasses import dataclass
|
|
20
21
|
from functools import partial
|
|
21
22
|
from textwrap import TextWrapper
|
|
22
23
|
from textwrap import shorten as text_shorten
|
|
23
|
-
from typing import Any, Literal, get_overloads, overload
|
|
24
|
+
from typing import Any, Literal, Protocol, get_overloads, overload
|
|
24
25
|
|
|
25
26
|
from absfuyu.core.baseclass import (
|
|
26
27
|
AutoREPRMixin,
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
BaseDataclass,
|
|
29
|
+
ClassMembers,
|
|
30
|
+
ClassMembersResult,
|
|
31
|
+
GetClassMembersMixin,
|
|
29
32
|
)
|
|
30
33
|
from absfuyu.dxt.listext import ListExt
|
|
31
34
|
from absfuyu.typings import P, R
|
|
32
|
-
from absfuyu.util.text_table import OneColumnTableMaker
|
|
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
|
+
def make_output(self, *args, **kwargs) -> list[str]: ...
|
|
33
187
|
|
|
34
188
|
|
|
35
189
|
# Class
|
|
36
190
|
# ---------------------------------------------------------------------------
|
|
37
|
-
# TODO: rewrite with each class for docs, method, property, attr, param, title
|
|
38
191
|
class Inspector(AutoREPRMixin):
|
|
39
192
|
"""
|
|
40
193
|
Inspect an object.
|
|
@@ -74,7 +227,7 @@ class Inspector(AutoREPRMixin):
|
|
|
74
227
|
Maximum lines for the output's header (class, signature, repr).
|
|
75
228
|
Must be >= 1, by default ``8``
|
|
76
229
|
|
|
77
|
-
style :
|
|
230
|
+
style : BoxStyle, optional
|
|
78
231
|
Style for the table, by default ``"normal"``
|
|
79
232
|
|
|
80
233
|
|
|
@@ -102,7 +255,7 @@ class Inspector(AutoREPRMixin):
|
|
|
102
255
|
include_attribute: bool = True,
|
|
103
256
|
include_private: bool = False,
|
|
104
257
|
max_textwrap_lines: int = 8,
|
|
105
|
-
style:
|
|
258
|
+
style: BoxStyle = "normal",
|
|
106
259
|
) -> None: ...
|
|
107
260
|
|
|
108
261
|
def __init__(
|
|
@@ -119,10 +272,11 @@ class Inspector(AutoREPRMixin):
|
|
|
119
272
|
include_method: bool = False,
|
|
120
273
|
include_property: bool = False,
|
|
121
274
|
include_attribute: bool = True,
|
|
275
|
+
include_dunder: bool = False,
|
|
122
276
|
include_private: bool = False,
|
|
123
277
|
include_all: bool = False,
|
|
124
278
|
# Style
|
|
125
|
-
style:
|
|
279
|
+
style: BoxStyle = "normal",
|
|
126
280
|
) -> None:
|
|
127
281
|
"""
|
|
128
282
|
Inspect an object.
|
|
@@ -162,7 +316,7 @@ class Inspector(AutoREPRMixin):
|
|
|
162
316
|
Maximum lines for the output's header (class, signature, repr).
|
|
163
317
|
Must be >= 1, by default ``8``
|
|
164
318
|
|
|
165
|
-
style : Literal["normal", "bold", "dashed", "double", "rounded"], optional
|
|
319
|
+
style : BoxStyle | Literal["normal", "bold", "dashed", "double", "rounded", ...], optional
|
|
166
320
|
Style for the table, by default ``"normal"``
|
|
167
321
|
|
|
168
322
|
|
|
@@ -177,6 +331,7 @@ class Inspector(AutoREPRMixin):
|
|
|
177
331
|
self.include_property = include_property
|
|
178
332
|
self.include_attribute = include_attribute
|
|
179
333
|
self.include_private = include_private
|
|
334
|
+
self.include_dunder = include_dunder
|
|
180
335
|
self._style = style
|
|
181
336
|
|
|
182
337
|
if include_all:
|
|
@@ -212,21 +367,20 @@ class Inspector(AutoREPRMixin):
|
|
|
212
367
|
self._inspect_output = self._make_output()
|
|
213
368
|
|
|
214
369
|
def __str__(self) -> str:
|
|
215
|
-
return self.
|
|
370
|
+
return self._inspect_output.make_table()
|
|
216
371
|
|
|
217
|
-
# Support
|
|
372
|
+
# 00. Support
|
|
373
|
+
# -----------------------------------------------------------
|
|
374
|
+
# @deprecated
|
|
218
375
|
def _long_list_terminal_size(self, long_list: list) -> list:
|
|
219
376
|
ll = ListExt(long_list).wrap_to_column(
|
|
220
377
|
self._linelength, margin=4, transpose=True
|
|
221
378
|
)
|
|
222
379
|
return list(ll)
|
|
223
380
|
|
|
224
|
-
# Signature
|
|
381
|
+
# 01. Signature
|
|
382
|
+
# -----------------------------------------------------------
|
|
225
383
|
def _make_title(self) -> str:
|
|
226
|
-
"""
|
|
227
|
-
Inspector's workflow:
|
|
228
|
-
01. Make title
|
|
229
|
-
"""
|
|
230
384
|
title_str = (
|
|
231
385
|
str(self.obj)
|
|
232
386
|
if (
|
|
@@ -248,6 +402,7 @@ class Inspector(AutoREPRMixin):
|
|
|
248
402
|
return "def"
|
|
249
403
|
return ""
|
|
250
404
|
|
|
405
|
+
# @deprecated
|
|
251
406
|
def get_parameters(self) -> list[str] | None:
|
|
252
407
|
try:
|
|
253
408
|
sig = _inspect.signature(self.obj)
|
|
@@ -266,11 +421,8 @@ class Inspector(AutoREPRMixin):
|
|
|
266
421
|
for x in overloads
|
|
267
422
|
]
|
|
268
423
|
|
|
424
|
+
# @deprecated
|
|
269
425
|
def _make_signature(self) -> list[str]:
|
|
270
|
-
"""
|
|
271
|
-
Inspector's workflow:
|
|
272
|
-
02. Make signature
|
|
273
|
-
"""
|
|
274
426
|
try:
|
|
275
427
|
# if isinstance(self.obj, Callable):
|
|
276
428
|
if _inspect.isfunction(self.obj):
|
|
@@ -286,15 +438,93 @@ class Inspector(AutoREPRMixin):
|
|
|
286
438
|
except (ValueError, AttributeError, TypeError):
|
|
287
439
|
return self._text_wrapper.wrap(repr(self.obj))
|
|
288
440
|
|
|
289
|
-
|
|
290
|
-
def
|
|
441
|
+
@property
|
|
442
|
+
def obj_signature(self) -> _TitleSignature:
|
|
443
|
+
"""Object's title and signature"""
|
|
444
|
+
title: str = self._make_title()
|
|
445
|
+
sig: list[str] = []
|
|
446
|
+
try:
|
|
447
|
+
if _inspect.isfunction(self.obj):
|
|
448
|
+
sig.extend(self._get_func_signature(self.obj))
|
|
449
|
+
sig.append(
|
|
450
|
+
f"{self._get_signature_prefix()} {self.obj.__name__}{_inspect.signature(self.obj)}"
|
|
451
|
+
)
|
|
452
|
+
# not class, func | not type | is module
|
|
453
|
+
except (ValueError, AttributeError, TypeError):
|
|
454
|
+
sig.append(repr(self.obj))
|
|
455
|
+
|
|
456
|
+
return _TitleSignature(title=title, signature=sig)
|
|
457
|
+
|
|
458
|
+
# 02. Docstring
|
|
459
|
+
# -----------------------------------------------------------
|
|
460
|
+
@property
|
|
461
|
+
def obj_docs(self) -> _Docstring:
|
|
462
|
+
"""Object's docstring"""
|
|
463
|
+
docs: str | None = _inspect.getdoc(self.obj)
|
|
464
|
+
|
|
465
|
+
if docs is None:
|
|
466
|
+
return _Docstring("")
|
|
467
|
+
return _Docstring(docs=docs)
|
|
468
|
+
|
|
469
|
+
# @deprecated
|
|
470
|
+
def _get_docs(self) -> str:
|
|
471
|
+
docs: str | None = _inspect.getdoc(self.obj)
|
|
472
|
+
|
|
473
|
+
if docs is None:
|
|
474
|
+
return ""
|
|
475
|
+
|
|
476
|
+
# Get docs and get first paragraph
|
|
477
|
+
# doc_lines: list[str] = [x.strip() for x in docs.splitlines()]
|
|
478
|
+
doc_lines = []
|
|
479
|
+
for line in docs.splitlines():
|
|
480
|
+
if len(line) < 1:
|
|
481
|
+
break
|
|
482
|
+
doc_lines.append(line.strip())
|
|
483
|
+
|
|
484
|
+
return text_shorten(" ".join(doc_lines), width=self._linelength - 4, tabsize=4)
|
|
485
|
+
|
|
486
|
+
# 03. MRO/Bases
|
|
487
|
+
# -----------------------------------------------------------
|
|
488
|
+
@property
|
|
489
|
+
def obj_mro(self) -> _MRO:
|
|
490
|
+
"""Object's MRO, bases"""
|
|
491
|
+
if isinstance(self.obj, type):
|
|
492
|
+
return _MRO(mro=self.obj.__mro__[::-1])
|
|
493
|
+
return _MRO(mro=type(self.obj).__mro__[::-1])
|
|
494
|
+
|
|
495
|
+
@property
|
|
496
|
+
def obj_bases(self) -> _MRO:
|
|
497
|
+
"""Object's MRO, bases"""
|
|
498
|
+
return self.obj_mro
|
|
499
|
+
|
|
500
|
+
# @deprecated
|
|
501
|
+
def _get_mro(self) -> tuple[type, ...]:
|
|
502
|
+
"""Get MRO in reverse and subtract <class 'object'>"""
|
|
503
|
+
if isinstance(self.obj, type):
|
|
504
|
+
return self.obj.__mro__[::-1][1:]
|
|
505
|
+
return type(self.obj).__mro__[::-1][1:]
|
|
506
|
+
|
|
507
|
+
# @deprecated
|
|
508
|
+
def _make_mro_data(self) -> list[str]:
|
|
509
|
+
mro = [
|
|
510
|
+
f"- {i:02}. {x.__module__}.{x.__name__}"
|
|
511
|
+
for i, x in enumerate(self._get_mro(), start=1)
|
|
512
|
+
]
|
|
513
|
+
mod_chunk = self._long_list_terminal_size(mro)
|
|
514
|
+
|
|
515
|
+
# return [text_shorten(x, self._linelength - 4) for x in mod_chunk]
|
|
516
|
+
return mod_chunk
|
|
517
|
+
|
|
518
|
+
# 04. Class's members
|
|
519
|
+
# -----------------------------------------------------------
|
|
520
|
+
def _get_obj_member(self) -> ClassMembersResult:
|
|
291
521
|
# if _inspect.isclass(self.obj) or inspect.ismodule(self.obj):
|
|
292
522
|
if _inspect.isclass(self.obj):
|
|
293
523
|
tmpcls = type(
|
|
294
524
|
"tmpcls",
|
|
295
525
|
(
|
|
296
526
|
self.obj,
|
|
297
|
-
|
|
527
|
+
GetClassMembersMixin,
|
|
298
528
|
),
|
|
299
529
|
{},
|
|
300
530
|
)
|
|
@@ -303,46 +533,38 @@ class Inspector(AutoREPRMixin):
|
|
|
303
533
|
"tmpcls",
|
|
304
534
|
(
|
|
305
535
|
type(self.obj),
|
|
306
|
-
|
|
536
|
+
GetClassMembersMixin,
|
|
307
537
|
),
|
|
308
538
|
{},
|
|
309
539
|
)
|
|
310
|
-
med_prop = tmpcls.
|
|
311
|
-
|
|
540
|
+
med_prop = tmpcls._get_members( # type: ignore
|
|
541
|
+
dunder=False, private=self.include_private
|
|
312
542
|
)
|
|
313
543
|
|
|
314
544
|
try:
|
|
315
|
-
# If self.obj is a subclass of
|
|
545
|
+
# If self.obj is a subclass of GetClassMembersMixin
|
|
316
546
|
_mro = getattr(
|
|
317
547
|
self.obj, "__mro__", getattr(type(self.obj), "__mro__", None)
|
|
318
548
|
)
|
|
319
|
-
if
|
|
549
|
+
if GetClassMembersMixin in _mro: # type: ignore
|
|
320
550
|
return med_prop # type: ignore
|
|
321
551
|
except AttributeError: # Not a class
|
|
322
552
|
pass
|
|
323
|
-
med_prop.__delitem__(
|
|
553
|
+
med_prop.__delitem__(GetClassMembersMixin.__name__)
|
|
324
554
|
return med_prop # type: ignore
|
|
325
555
|
|
|
326
|
-
|
|
327
|
-
def
|
|
328
|
-
"""
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
if docs is None:
|
|
335
|
-
return ""
|
|
336
|
-
|
|
337
|
-
# Get docs and get first paragraph
|
|
338
|
-
# doc_lines: list[str] = [x.strip() for x in docs.splitlines()]
|
|
339
|
-
doc_lines = []
|
|
340
|
-
for line in docs.splitlines():
|
|
341
|
-
if len(line) < 1:
|
|
342
|
-
break
|
|
343
|
-
doc_lines.append(line.strip())
|
|
556
|
+
@property
|
|
557
|
+
def obj_member(self) -> _Member:
|
|
558
|
+
"""Object's members"""
|
|
559
|
+
try:
|
|
560
|
+
mem = self._get_obj_member()
|
|
561
|
+
return _Member(mem.flatten_value())
|
|
562
|
+
except (TypeError, AttributeError):
|
|
563
|
+
return _Member(ClassMembers())
|
|
344
564
|
|
|
345
|
-
|
|
565
|
+
# @deprecated
|
|
566
|
+
def _get_method_property(self) -> ClassMembersResult:
|
|
567
|
+
return self._get_obj_member()
|
|
346
568
|
|
|
347
569
|
# Attribute
|
|
348
570
|
@staticmethod
|
|
@@ -406,26 +628,11 @@ class Inspector(AutoREPRMixin):
|
|
|
406
628
|
text_shorten(f"- {x[0]} = {x[1]}", self._linelength - 4) for x in attr_list
|
|
407
629
|
]
|
|
408
630
|
|
|
409
|
-
# Get MRO
|
|
410
|
-
def _get_mro(self) -> tuple[type, ...]:
|
|
411
|
-
"""Get MRO in reverse and subtract <class 'object'>"""
|
|
412
|
-
if isinstance(self.obj, type):
|
|
413
|
-
return self.obj.__mro__[::-1][1:]
|
|
414
|
-
return type(self.obj).__mro__[::-1][1:]
|
|
415
|
-
|
|
416
|
-
def _make_mro_data(self) -> list[str]:
|
|
417
|
-
mro = [
|
|
418
|
-
f"- {i:02}. {x.__module__}.{x.__name__}"
|
|
419
|
-
for i, x in enumerate(self._get_mro(), start=1)
|
|
420
|
-
]
|
|
421
|
-
mod_chunk = self._long_list_terminal_size(mro)
|
|
422
|
-
|
|
423
|
-
# return [text_shorten(x, self._linelength - 4) for x in mod_chunk]
|
|
424
|
-
return mod_chunk
|
|
425
|
-
|
|
426
631
|
# Output
|
|
632
|
+
# -----------------------------------------------------------
|
|
633
|
+
# @deprecated
|
|
427
634
|
def _make_output(self) -> OneColumnTableMaker:
|
|
428
|
-
table = OneColumnTableMaker(self._linelength, style=self._style)
|
|
635
|
+
table = OneColumnTableMaker(self._linelength, style=self._style) # type: ignore
|
|
429
636
|
body: list[str] = []
|
|
430
637
|
|
|
431
638
|
# Signature
|
|
@@ -489,10 +696,57 @@ class Inspector(AutoREPRMixin):
|
|
|
489
696
|
|
|
490
697
|
return table
|
|
491
698
|
|
|
492
|
-
def
|
|
493
|
-
|
|
699
|
+
def _make_output_2(self) -> OneColumnTableMaker:
|
|
700
|
+
# Prep
|
|
701
|
+
# components: list[InspectComponents] = [
|
|
702
|
+
# self.obj_signature,
|
|
703
|
+
# self.obj_docs,
|
|
704
|
+
# self.obj_mro,
|
|
705
|
+
# self.obj_member,
|
|
706
|
+
# ]
|
|
707
|
+
table = OneColumnTableMaker(self._linelength, style=self._style) # type: ignore
|
|
708
|
+
body: list[str] = []
|
|
709
|
+
|
|
710
|
+
# Signature
|
|
711
|
+
title = self.obj_signature.title
|
|
712
|
+
table.add_title(title)
|
|
713
|
+
if table._title == "": # Title too long
|
|
714
|
+
_title = [title]
|
|
715
|
+
_title.extend(self.obj_signature.signature)
|
|
716
|
+
table.add_paragraph(_title)
|
|
717
|
+
else:
|
|
718
|
+
table.add_paragraph(self.obj_signature.signature)
|
|
719
|
+
|
|
720
|
+
# Docstring
|
|
721
|
+
if self.include_docs:
|
|
722
|
+
body.extend(self.obj_docs.make_output())
|
|
723
|
+
|
|
724
|
+
# Class bases
|
|
725
|
+
if self.include_mro:
|
|
726
|
+
body.extend(self.obj_mro.make_output(width=self._linelength))
|
|
727
|
+
|
|
728
|
+
# Method & Property
|
|
729
|
+
body.extend(
|
|
730
|
+
self.obj_member.make_output(
|
|
731
|
+
width=self._linelength,
|
|
732
|
+
obj=self.obj,
|
|
733
|
+
include_method=self.include_method,
|
|
734
|
+
include_property=self.include_property,
|
|
735
|
+
)
|
|
736
|
+
)
|
|
737
|
+
|
|
738
|
+
# Attribute
|
|
739
|
+
attrs = self._get_attributes()
|
|
740
|
+
if len(attrs) > 0 and self.include_attribute:
|
|
741
|
+
body.extend(["", f"Attributes (Len: {len(attrs)}):"])
|
|
742
|
+
body.extend(self._handle_attributes_for_output(attr_list=attrs))
|
|
743
|
+
|
|
744
|
+
# Add to table
|
|
745
|
+
table.add_paragraph(body)
|
|
746
|
+
|
|
747
|
+
return table
|
|
494
748
|
|
|
495
749
|
|
|
496
750
|
# Partial
|
|
497
751
|
# ---------------------------------------------------------------------------
|
|
498
|
-
inspect_all = partial(Inspector, line_length=None, include_all=True)
|
|
752
|
+
inspect_all = partial(Inspector, line_length=None, include_all=True) # type: ignore
|
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.6.0
|
|
7
|
+
Date updated: 12/09/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