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.

Files changed (75) 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 +518 -154
  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 +5 -5
  23. absfuyu/extra/__init__.py +2 -2
  24. absfuyu/extra/beautiful.py +2 -2
  25. absfuyu/extra/da/__init__.py +3 -3
  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/extra/pdf.py +89 -0
  32. absfuyu/fun/__init__.py +2 -2
  33. absfuyu/fun/rubik.py +2 -2
  34. absfuyu/fun/tarot.py +2 -2
  35. absfuyu/game/__init__.py +2 -2
  36. absfuyu/game/game_stat.py +2 -2
  37. absfuyu/game/sudoku.py +2 -2
  38. absfuyu/game/tictactoe.py +2 -2
  39. absfuyu/game/wordle.py +2 -2
  40. absfuyu/general/__init__.py +2 -2
  41. absfuyu/general/content.py +4 -4
  42. absfuyu/general/human.py +2 -2
  43. absfuyu/general/shape.py +2 -2
  44. absfuyu/logger.py +2 -2
  45. absfuyu/pkg_data/__init__.py +2 -2
  46. absfuyu/pkg_data/deprecated.py +2 -2
  47. absfuyu/sort.py +2 -2
  48. absfuyu/tools/__init__.py +2 -2
  49. absfuyu/tools/checksum.py +2 -2
  50. absfuyu/tools/converter.py +2 -2
  51. absfuyu/tools/generator.py +4 -4
  52. absfuyu/tools/inspector.py +325 -71
  53. absfuyu/tools/keygen.py +2 -2
  54. absfuyu/tools/obfuscator.py +4 -4
  55. absfuyu/tools/passwordlib.py +2 -2
  56. absfuyu/tools/shutdownizer.py +2 -2
  57. absfuyu/tools/sw.py +514 -0
  58. absfuyu/tools/web.py +2 -2
  59. absfuyu/typings.py +2 -2
  60. absfuyu/util/__init__.py +14 -3
  61. absfuyu/util/api.py +2 -2
  62. absfuyu/util/json_method.py +2 -2
  63. absfuyu/util/lunar.py +2 -2
  64. absfuyu/util/path.py +53 -4
  65. absfuyu/util/performance.py +2 -2
  66. absfuyu/util/shorten_number.py +2 -2
  67. absfuyu/util/text_table.py +33 -14
  68. absfuyu/util/zipped.py +2 -2
  69. absfuyu/version.py +3 -3
  70. {absfuyu-5.4.0.dist-info → absfuyu-5.6.0.dist-info}/METADATA +7 -2
  71. absfuyu-5.6.0.dist-info/RECORD +79 -0
  72. absfuyu-5.4.0.dist-info/RECORD +0 -77
  73. {absfuyu-5.4.0.dist-info → absfuyu-5.6.0.dist-info}/WHEEL +0 -0
  74. {absfuyu-5.4.0.dist-info → absfuyu-5.6.0.dist-info}/entry_points.txt +0 -0
  75. {absfuyu-5.4.0.dist-info → absfuyu-5.6.0.dist-info}/licenses/LICENSE +0 -0
@@ -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.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
- 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
+ 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 : Literal["normal", "bold", "dashed", "double", "rounded"], optional
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: Literal["normal", "bold", "dashed", "double", "rounded"] = "normal",
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: Literal["normal", "bold", "dashed", "double", "rounded"] = "normal",
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.detail_str()
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
- # Method and property
290
- def _get_method_property(self) -> MethodNPropertyResult:
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
- ShowAllMethodsMixin,
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
- ShowAllMethodsMixin,
536
+ GetClassMembersMixin,
307
537
  ),
308
538
  {},
309
539
  )
310
- med_prop = tmpcls._get_methods_and_properties( # type: ignore
311
- include_private_method=self.include_private
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 ShowAllMethodsMixin
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 ShowAllMethodsMixin in _mro: # type: ignore
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__(ShowAllMethodsMixin.__name__)
553
+ med_prop.__delitem__(GetClassMembersMixin.__name__)
324
554
  return med_prop # type: ignore
325
555
 
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())
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
- return text_shorten(" ".join(doc_lines), width=self._linelength - 4, tabsize=4)
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 detail_str(self) -> str:
493
- return self._inspect_output.make_table()
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
@@ -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.6.0
9
+ Date updated: 12/09/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.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, 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.6.0
7
+ Date updated: 12/09/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.6.0
7
+ Date updated: 12/09/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
10
10
  # Module level