absfuyu 5.4.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.

Files changed (73) hide show
  1. absfuyu/__init__.py +1 -1
  2. absfuyu/__main__.py +2 -2
  3. absfuyu/cli/__init__.py +2 -2
  4. absfuyu/cli/color.py +2 -2
  5. absfuyu/cli/config_group.py +2 -2
  6. absfuyu/cli/do_group.py +2 -2
  7. absfuyu/cli/game_group.py +2 -2
  8. absfuyu/cli/tool_group.py +2 -2
  9. absfuyu/config/__init__.py +2 -2
  10. absfuyu/core/__init__.py +4 -4
  11. absfuyu/core/baseclass.py +511 -153
  12. absfuyu/core/baseclass2.py +3 -3
  13. absfuyu/core/decorator.py +2 -2
  14. absfuyu/core/docstring.py +2 -2
  15. absfuyu/core/dummy_cli.py +2 -2
  16. absfuyu/core/dummy_func.py +2 -2
  17. absfuyu/dxt/__init__.py +2 -2
  18. absfuyu/dxt/dictext.py +5 -11
  19. absfuyu/dxt/dxt_support.py +2 -2
  20. absfuyu/dxt/intext.py +4 -4
  21. absfuyu/dxt/listext.py +69 -14
  22. absfuyu/dxt/strext.py +4 -4
  23. absfuyu/extra/__init__.py +2 -2
  24. absfuyu/extra/beautiful.py +2 -2
  25. absfuyu/extra/da/__init__.py +2 -2
  26. absfuyu/extra/da/dadf.py +4 -4
  27. absfuyu/extra/da/dadf_base.py +2 -2
  28. absfuyu/extra/da/df_func.py +2 -2
  29. absfuyu/extra/da/mplt.py +2 -2
  30. absfuyu/extra/data_analysis.py +2 -2
  31. absfuyu/fun/__init__.py +2 -2
  32. absfuyu/fun/rubik.py +2 -2
  33. absfuyu/fun/tarot.py +2 -2
  34. absfuyu/game/__init__.py +2 -2
  35. absfuyu/game/game_stat.py +2 -2
  36. absfuyu/game/sudoku.py +2 -2
  37. absfuyu/game/tictactoe.py +2 -2
  38. absfuyu/game/wordle.py +2 -2
  39. absfuyu/general/__init__.py +2 -2
  40. absfuyu/general/content.py +4 -4
  41. absfuyu/general/human.py +2 -2
  42. absfuyu/general/shape.py +2 -2
  43. absfuyu/logger.py +2 -2
  44. absfuyu/pkg_data/__init__.py +2 -2
  45. absfuyu/pkg_data/deprecated.py +2 -2
  46. absfuyu/sort.py +2 -2
  47. absfuyu/tools/__init__.py +2 -2
  48. absfuyu/tools/checksum.py +2 -2
  49. absfuyu/tools/converter.py +2 -2
  50. absfuyu/tools/generator.py +4 -4
  51. absfuyu/tools/inspector.py +325 -69
  52. absfuyu/tools/keygen.py +2 -2
  53. absfuyu/tools/obfuscator.py +4 -4
  54. absfuyu/tools/passwordlib.py +2 -2
  55. absfuyu/tools/shutdownizer.py +2 -2
  56. absfuyu/tools/web.py +2 -2
  57. absfuyu/typings.py +2 -2
  58. absfuyu/util/__init__.py +2 -2
  59. absfuyu/util/api.py +2 -2
  60. absfuyu/util/json_method.py +2 -2
  61. absfuyu/util/lunar.py +2 -2
  62. absfuyu/util/path.py +17 -4
  63. absfuyu/util/performance.py +2 -2
  64. absfuyu/util/shorten_number.py +2 -2
  65. absfuyu/util/text_table.py +33 -14
  66. absfuyu/util/zipped.py +2 -2
  67. absfuyu/version.py +3 -3
  68. {absfuyu-5.4.0.dist-info → absfuyu-5.5.0.dist-info}/METADATA +2 -2
  69. absfuyu-5.5.0.dist-info/RECORD +77 -0
  70. absfuyu-5.4.0.dist-info/RECORD +0 -77
  71. {absfuyu-5.4.0.dist-info → absfuyu-5.5.0.dist-info}/WHEEL +0 -0
  72. {absfuyu-5.4.0.dist-info → absfuyu-5.5.0.dist-info}/entry_points.txt +0 -0
  73. {absfuyu-5.4.0.dist-info → absfuyu-5.5.0.dist-info}/licenses/LICENSE +0 -0
absfuyu/tools/__init__.py CHANGED
@@ -3,8 +3,8 @@ Absfuyu: Tools
3
3
  --------------
4
4
  Some useful tools
5
5
 
6
- Version: 5.4.0
7
- Date updated: 21/03/2025 (dd/mm/yyyy)
6
+ Version: 5.5.0
7
+ Date updated: 23/04/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
10
10
  # Module Package
absfuyu/tools/checksum.py CHANGED
@@ -3,8 +3,8 @@ Absufyu: Checksum
3
3
  -----------------
4
4
  Check MD5, SHA256, ...
5
5
 
6
- Version: 5.4.0
7
- Date updated: 21/03/2025 (dd/mm/yyyy)
6
+ Version: 5.5.0
7
+ Date updated: 23/04/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
10
10
  # Module level
@@ -3,8 +3,8 @@ Absufyu: Converter
3
3
  ------------------
4
4
  Convert stuff
5
5
 
6
- Version: 5.4.0
7
- Date updated: 21/03/2025 (dd/mm/yyyy)
6
+ Version: 5.5.0
7
+ Date updated: 23/04/2025 (dd/mm/yyyy)
8
8
 
9
9
  Feature:
10
10
  --------
@@ -3,8 +3,8 @@ Absfuyu: Generator
3
3
  ------------------
4
4
  This generate stuff (Not python's ``generator``)
5
5
 
6
- Version: 5.4.0
7
- Date updated: 21/03/2025 (dd/mm/yyyy)
6
+ Version: 5.5.0
7
+ Date updated: 23/04/2025 (dd/mm/yyyy)
8
8
 
9
9
  Features:
10
10
  ---------
@@ -27,7 +27,7 @@ from itertools import chain, combinations
27
27
  from random import choice
28
28
  from typing import TypeVar, cast, overload
29
29
 
30
- from absfuyu.core.baseclass import ShowAllMethodsMixin
30
+ from absfuyu.core.baseclass import GetClassMembersMixin
31
31
  from absfuyu.core.docstring import deprecated
32
32
  from absfuyu.util import set_min_max
33
33
 
@@ -65,7 +65,7 @@ class Charset:
65
65
  return f"{clsname}({', '.join(charset)})"
66
66
 
67
67
 
68
- class Generator(ShowAllMethodsMixin):
68
+ class Generator(GetClassMembersMixin):
69
69
  """
70
70
  Generator that generate stuffs
71
71
 
@@ -3,8 +3,8 @@ Absfuyu: Inspector
3
3
  ------------------
4
4
  Inspector
5
5
 
6
- Version: 5.4.0
7
- Date updated: 21/03/2025 (dd/mm/yyyy)
6
+ Version: 5.5.0
7
+ Date updated: 23/04/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
10
10
  # Module level
@@ -17,24 +17,179 @@ __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
- MethodNPropertyResult,
28
- ShowAllMethodsMixin,
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
+ @overload
187
+ def make_output(self, *args, **kwargs) -> list[str]: ...
188
+ def make_output(self, *args, **kwargs) -> list[str]: ...
33
189
 
34
190
 
35
191
  # Class
36
192
  # ---------------------------------------------------------------------------
37
- # TODO: rewrite with each class for docs, method, property, attr, param, title
38
193
  class Inspector(AutoREPRMixin):
39
194
  """
40
195
  Inspect an object.
@@ -74,7 +229,7 @@ class Inspector(AutoREPRMixin):
74
229
  Maximum lines for the output's header (class, signature, repr).
75
230
  Must be >= 1, by default ``8``
76
231
 
77
- style : Literal["normal", "bold", "dashed", "double", "rounded"], optional
232
+ style : BoxStyle, optional
78
233
  Style for the table, by default ``"normal"``
79
234
 
80
235
 
@@ -102,7 +257,7 @@ class Inspector(AutoREPRMixin):
102
257
  include_attribute: bool = True,
103
258
  include_private: bool = False,
104
259
  max_textwrap_lines: int = 8,
105
- style: Literal["normal", "bold", "dashed", "double", "rounded"] = "normal",
260
+ style: BoxStyle = "normal",
106
261
  ) -> None: ...
107
262
 
108
263
  def __init__(
@@ -119,10 +274,11 @@ class Inspector(AutoREPRMixin):
119
274
  include_method: bool = False,
120
275
  include_property: bool = False,
121
276
  include_attribute: bool = True,
277
+ include_dunder: bool = False,
122
278
  include_private: bool = False,
123
279
  include_all: bool = False,
124
280
  # Style
125
- style: Literal["normal", "bold", "dashed", "double", "rounded"] = "normal",
281
+ style: BoxStyle = "normal",
126
282
  ) -> None:
127
283
  """
128
284
  Inspect an object.
@@ -162,7 +318,7 @@ class Inspector(AutoREPRMixin):
162
318
  Maximum lines for the output's header (class, signature, repr).
163
319
  Must be >= 1, by default ``8``
164
320
 
165
- style : Literal["normal", "bold", "dashed", "double", "rounded"], optional
321
+ style : BoxStyle | Literal["normal", "bold", "dashed", "double", "rounded", ...], optional
166
322
  Style for the table, by default ``"normal"``
167
323
 
168
324
 
@@ -177,6 +333,7 @@ class Inspector(AutoREPRMixin):
177
333
  self.include_property = include_property
178
334
  self.include_attribute = include_attribute
179
335
  self.include_private = include_private
336
+ self.include_dunder = include_dunder
180
337
  self._style = style
181
338
 
182
339
  if include_all:
@@ -212,21 +369,20 @@ class Inspector(AutoREPRMixin):
212
369
  self._inspect_output = self._make_output()
213
370
 
214
371
  def __str__(self) -> str:
215
- return self.detail_str()
372
+ return self._inspect_output.make_table()
216
373
 
217
- # Support
374
+ # 00. Support
375
+ # -----------------------------------------------------------
376
+ # @deprecated
218
377
  def _long_list_terminal_size(self, long_list: list) -> list:
219
378
  ll = ListExt(long_list).wrap_to_column(
220
379
  self._linelength, margin=4, transpose=True
221
380
  )
222
381
  return list(ll)
223
382
 
224
- # Signature
383
+ # 01. Signature
384
+ # -----------------------------------------------------------
225
385
  def _make_title(self) -> str:
226
- """
227
- Inspector's workflow:
228
- 01. Make title
229
- """
230
386
  title_str = (
231
387
  str(self.obj)
232
388
  if (
@@ -248,6 +404,7 @@ class Inspector(AutoREPRMixin):
248
404
  return "def"
249
405
  return ""
250
406
 
407
+ # @deprecated
251
408
  def get_parameters(self) -> list[str] | None:
252
409
  try:
253
410
  sig = _inspect.signature(self.obj)
@@ -266,11 +423,8 @@ class Inspector(AutoREPRMixin):
266
423
  for x in overloads
267
424
  ]
268
425
 
426
+ # @deprecated
269
427
  def _make_signature(self) -> list[str]:
270
- """
271
- Inspector's workflow:
272
- 02. Make signature
273
- """
274
428
  try:
275
429
  # if isinstance(self.obj, Callable):
276
430
  if _inspect.isfunction(self.obj):
@@ -286,15 +440,93 @@ class Inspector(AutoREPRMixin):
286
440
  except (ValueError, AttributeError, TypeError):
287
441
  return self._text_wrapper.wrap(repr(self.obj))
288
442
 
289
- # Method and property
290
- def _get_method_property(self) -> MethodNPropertyResult:
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:
291
523
  # if _inspect.isclass(self.obj) or inspect.ismodule(self.obj):
292
524
  if _inspect.isclass(self.obj):
293
525
  tmpcls = type(
294
526
  "tmpcls",
295
527
  (
296
528
  self.obj,
297
- ShowAllMethodsMixin,
529
+ GetClassMembersMixin,
298
530
  ),
299
531
  {},
300
532
  )
@@ -303,46 +535,38 @@ class Inspector(AutoREPRMixin):
303
535
  "tmpcls",
304
536
  (
305
537
  type(self.obj),
306
- ShowAllMethodsMixin,
538
+ GetClassMembersMixin,
307
539
  ),
308
540
  {},
309
541
  )
310
- med_prop = tmpcls._get_methods_and_properties( # type: ignore
311
- include_private_method=self.include_private
542
+ med_prop = tmpcls._get_members( # type: ignore
543
+ dunder=False, private=self.include_private
312
544
  )
313
545
 
314
546
  try:
315
- # If self.obj is a subclass of ShowAllMethodsMixin
547
+ # If self.obj is a subclass of GetClassMembersMixin
316
548
  _mro = getattr(
317
549
  self.obj, "__mro__", getattr(type(self.obj), "__mro__", None)
318
550
  )
319
- if ShowAllMethodsMixin in _mro: # type: ignore
551
+ if GetClassMembersMixin in _mro: # type: ignore
320
552
  return med_prop # type: ignore
321
553
  except AttributeError: # Not a class
322
554
  pass
323
- med_prop.__delitem__(ShowAllMethodsMixin.__name__)
555
+ med_prop.__delitem__(GetClassMembersMixin.__name__)
324
556
  return med_prop # type: ignore
325
557
 
326
- # Docstring
327
- def _get_docs(self) -> str:
328
- """
329
- Inspector's workflow:
330
- 03. Get docstring and strip
331
- """
332
- docs: str | None = _inspect.getdoc(self.obj)
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())
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())
344
566
 
345
- return text_shorten(" ".join(doc_lines), width=self._linelength - 4, tabsize=4)
567
+ # @deprecated
568
+ def _get_method_property(self) -> ClassMembersResult:
569
+ return self._get_obj_member()
346
570
 
347
571
  # Attribute
348
572
  @staticmethod
@@ -406,24 +630,9 @@ class Inspector(AutoREPRMixin):
406
630
  text_shorten(f"- {x[0]} = {x[1]}", self._linelength - 4) for x in attr_list
407
631
  ]
408
632
 
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
633
  # Output
634
+ # -----------------------------------------------------------
635
+ # @deprecated
427
636
  def _make_output(self) -> OneColumnTableMaker:
428
637
  table = OneColumnTableMaker(self._linelength, style=self._style)
429
638
  body: list[str] = []
@@ -489,8 +698,55 @@ class Inspector(AutoREPRMixin):
489
698
 
490
699
  return table
491
700
 
492
- def detail_str(self) -> str:
493
- return self._inspect_output.make_table()
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
494
750
 
495
751
 
496
752
  # Partial
absfuyu/tools/keygen.py CHANGED
@@ -5,8 +5,8 @@ Mod7 product key generator (90's)
5
5
 
6
6
  This is for educational and informative purposes only.
7
7
 
8
- Version: 5.4.0
9
- Date updated: 21/03/2025 (dd/mm/yyyy)
8
+ Version: 5.5.0
9
+ Date updated: 23/04/2025 (dd/mm/yyyy)
10
10
  """
11
11
 
12
12
  # Module level
@@ -3,8 +3,8 @@ Absfuyu: Obfuscator
3
3
  -------------------
4
4
  Obfuscate code
5
5
 
6
- Version: 5.4.0
7
- Date updated: 21/03/2025 (dd/mm/yyyy)
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, ShowAllMethodsMixin
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(ShowAllMethodsMixin):
113
+ class Obfuscator(GetClassMembersMixin):
114
114
  """
115
115
  Obfuscate code
116
116
 
@@ -3,8 +3,8 @@ Absfuyu: Passwordlib
3
3
  --------------------
4
4
  Password library
5
5
 
6
- Version: 5.4.0
7
- Date updated: 21/03/2025 (dd/mm/yyyy)
6
+ Version: 5.5.0
7
+ Date updated: 23/04/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
10
10
  # Module level
@@ -3,8 +3,8 @@ Absfuyu: Shutdownizer
3
3
  ---------------------
4
4
  This shutdowns
5
5
 
6
- Version: 5.4.0
7
- Date updated: 21/03/2025 (dd/mm/yyyy)
6
+ Version: 5.5.0
7
+ Date updated: 23/04/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
10
10
  # Module level
absfuyu/tools/web.py CHANGED
@@ -3,8 +3,8 @@ Absfuyu: Web
3
3
  ------------
4
4
  Web, ``request``, ``BeautifulSoup`` stuff
5
5
 
6
- Version: 5.4.0
7
- Date updated: 21/03/2025 (dd/mm/yyyy)
6
+ Version: 5.5.0
7
+ Date updated: 23/04/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
10
10
  # Library
absfuyu/typings.py CHANGED
@@ -3,8 +3,8 @@ Absfuyu: Core
3
3
  -------------
4
4
  Pre-defined typing
5
5
 
6
- Version: 5.4.0
7
- Date updated: 21/03/2025 (dd/mm/yyyy)
6
+ Version: 5.5.0
7
+ Date updated: 23/04/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
10
10
  # Module Package