absfuyu 5.0.1__py3-none-any.whl → 5.2.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 +3 -3
- absfuyu/cli/__init__.py +2 -2
- absfuyu/cli/color.py +30 -14
- absfuyu/cli/config_group.py +9 -2
- absfuyu/cli/do_group.py +13 -6
- absfuyu/cli/game_group.py +9 -2
- absfuyu/cli/tool_group.py +15 -9
- absfuyu/config/__init__.py +2 -2
- absfuyu/core/__init__.py +2 -2
- absfuyu/core/baseclass.py +448 -79
- absfuyu/core/baseclass2.py +2 -2
- absfuyu/core/decorator.py +70 -4
- absfuyu/core/docstring.py +43 -25
- absfuyu/core/dummy_cli.py +2 -2
- absfuyu/core/dummy_func.py +15 -4
- absfuyu/dxt/__init__.py +2 -2
- absfuyu/dxt/dictext.py +5 -2
- absfuyu/dxt/dxt_support.py +2 -2
- absfuyu/dxt/intext.py +34 -3
- absfuyu/dxt/listext.py +300 -113
- absfuyu/dxt/strext.py +75 -15
- absfuyu/extra/__init__.py +2 -2
- absfuyu/extra/beautiful.py +2 -2
- absfuyu/extra/da/__init__.py +36 -0
- absfuyu/extra/da/dadf.py +1177 -0
- absfuyu/extra/da/dadf_base.py +186 -0
- absfuyu/extra/da/df_func.py +97 -0
- absfuyu/extra/da/mplt.py +219 -0
- absfuyu/extra/data_analysis.py +10 -1067
- absfuyu/fun/__init__.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 -3
- absfuyu/game/wordle.py +2 -2
- absfuyu/general/__init__.py +2 -2
- absfuyu/general/content.py +2 -2
- 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 +28 -2
- absfuyu/tools/checksum.py +27 -7
- absfuyu/tools/converter.py +120 -34
- absfuyu/tools/generator.py +251 -110
- absfuyu/tools/inspector.py +463 -0
- absfuyu/tools/keygen.py +2 -2
- absfuyu/tools/obfuscator.py +45 -7
- absfuyu/tools/passwordlib.py +88 -24
- absfuyu/tools/shutdownizer.py +2 -2
- absfuyu/tools/web.py +2 -2
- absfuyu/typings.py +136 -0
- absfuyu/util/__init__.py +18 -4
- absfuyu/util/api.py +36 -16
- absfuyu/util/json_method.py +43 -14
- absfuyu/util/lunar.py +2 -2
- absfuyu/util/path.py +190 -82
- absfuyu/util/performance.py +122 -7
- absfuyu/util/shorten_number.py +40 -10
- absfuyu/util/text_table.py +306 -0
- absfuyu/util/zipped.py +8 -7
- absfuyu/version.py +2 -2
- {absfuyu-5.0.1.dist-info → absfuyu-5.2.0.dist-info}/METADATA +9 -2
- absfuyu-5.2.0.dist-info/RECORD +76 -0
- absfuyu-5.0.1.dist-info/RECORD +0 -68
- {absfuyu-5.0.1.dist-info → absfuyu-5.2.0.dist-info}/WHEEL +0 -0
- {absfuyu-5.0.1.dist-info → absfuyu-5.2.0.dist-info}/entry_points.txt +0 -0
- {absfuyu-5.0.1.dist-info → absfuyu-5.2.0.dist-info}/licenses/LICENSE +0 -0
absfuyu/core/decorator.py
CHANGED
|
@@ -3,20 +3,24 @@ Absfuyu: Core
|
|
|
3
3
|
-------------
|
|
4
4
|
Decorator
|
|
5
5
|
|
|
6
|
-
Version: 5.
|
|
7
|
-
Date updated:
|
|
6
|
+
Version: 5.2.0
|
|
7
|
+
Date updated: 14/03/2025 (dd/mm/yyyy)
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
# Module Package
|
|
11
11
|
# ---------------------------------------------------------------------------
|
|
12
|
-
__all__ = [
|
|
12
|
+
__all__ = [
|
|
13
|
+
"dummy_decorator",
|
|
14
|
+
"dummy_decorator_with_args",
|
|
15
|
+
"add_subclass_methods_decorator",
|
|
16
|
+
]
|
|
13
17
|
|
|
14
18
|
|
|
15
19
|
# Library
|
|
16
20
|
# ---------------------------------------------------------------------------
|
|
17
21
|
from collections.abc import Callable
|
|
18
22
|
from functools import wraps
|
|
19
|
-
from typing import ParamSpec, TypeVar, overload
|
|
23
|
+
from typing import ParamSpec, TypeVar, cast, overload
|
|
20
24
|
|
|
21
25
|
# Type
|
|
22
26
|
# ---------------------------------------------------------------------------
|
|
@@ -52,8 +56,10 @@ def dummy_decorator_with_args(*args, **kwargs):
|
|
|
52
56
|
|
|
53
57
|
@overload
|
|
54
58
|
def decorator(obj: T) -> T: ...
|
|
59
|
+
|
|
55
60
|
@overload
|
|
56
61
|
def decorator(obj: Callable[P, R]) -> Callable[P, R]: ...
|
|
62
|
+
|
|
57
63
|
def decorator(obj: Callable[P, R] | T) -> Callable[P, R] | T:
|
|
58
64
|
if isinstance(obj, type):
|
|
59
65
|
return obj
|
|
@@ -65,3 +71,63 @@ def dummy_decorator_with_args(*args, **kwargs):
|
|
|
65
71
|
return wrapper
|
|
66
72
|
|
|
67
73
|
return decorator
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def add_subclass_methods_decorator(cls: T) -> T:
|
|
77
|
+
"""
|
|
78
|
+
Class decorator replace the ``__init_subclass__`` method.
|
|
79
|
+
|
|
80
|
+
This method populates a dictionary with subclass names as keys
|
|
81
|
+
and their available methods as values.
|
|
82
|
+
|
|
83
|
+
- Create 2 class attributes: ``_METHOD_INCLUDE`` (bool) and ``SUBCLASS_METHODS`` (dict[str, list[str]])
|
|
84
|
+
- Automatically add subclass methods to class variable: ``SUBCLASS_METHODS``
|
|
85
|
+
- Set class attribute ``_METHOD_INCLUDE`` to ``False`` to exclude from ``SUBCLASS_METHODS``
|
|
86
|
+
|
|
87
|
+
Example:
|
|
88
|
+
--------
|
|
89
|
+
>>> # Normal behavior
|
|
90
|
+
>>> @add_subclass_methods_decorator
|
|
91
|
+
>>> class TestParent: ...
|
|
92
|
+
>>> class TestChild(TestParent):
|
|
93
|
+
... def method1(self): ...
|
|
94
|
+
>>> TestChild.SUBCLASS_METHODS
|
|
95
|
+
{'__main__.TestChild': ['method1']}
|
|
96
|
+
|
|
97
|
+
>>> # Hidden from ``SUBCLASS_METHODS``
|
|
98
|
+
>>> @add_subclass_methods_decorator
|
|
99
|
+
>>> class TestParent: ...
|
|
100
|
+
>>> class TestChildHidden(TestParent):
|
|
101
|
+
... _METHOD_INCLUDE = False
|
|
102
|
+
... def method1(self): ...
|
|
103
|
+
>>> TestChildHidden.SUBCLASS_METHODS
|
|
104
|
+
{}
|
|
105
|
+
"""
|
|
106
|
+
|
|
107
|
+
# Check for class
|
|
108
|
+
if not isinstance(cls, type):
|
|
109
|
+
raise ValueError("Object is not a class")
|
|
110
|
+
|
|
111
|
+
class AutoSubclassMixin:
|
|
112
|
+
_METHOD_INCLUDE: bool = True # Include in SUBCLASS_METHODS
|
|
113
|
+
SUBCLASS_METHODS: dict[str, list[str]] = {}
|
|
114
|
+
|
|
115
|
+
def __init_subclass__(cls, *args, **kwargs) -> None:
|
|
116
|
+
"""
|
|
117
|
+
This create a dictionary with:
|
|
118
|
+
- key (str) : Subclass
|
|
119
|
+
- value (list[str]): List of available methods
|
|
120
|
+
"""
|
|
121
|
+
super().__init_subclass__(*args, **kwargs)
|
|
122
|
+
|
|
123
|
+
if cls._METHOD_INCLUDE and not any(
|
|
124
|
+
[x.endswith(cls.__name__) for x in cls.SUBCLASS_METHODS.keys()]
|
|
125
|
+
):
|
|
126
|
+
methods_list: list[str] = [
|
|
127
|
+
k for k, v in cls.__dict__.items() if callable(v)
|
|
128
|
+
]
|
|
129
|
+
if len(methods_list) > 0:
|
|
130
|
+
name = f"{cls.__module__}.{cls.__name__}"
|
|
131
|
+
cls.SUBCLASS_METHODS.update({name: sorted(methods_list)})
|
|
132
|
+
|
|
133
|
+
return cast(T, type("AutoSubclass", (AutoSubclassMixin, cls), {}))
|
absfuyu/core/docstring.py
CHANGED
|
@@ -3,8 +3,8 @@ Absfuyu: Core
|
|
|
3
3
|
-------------
|
|
4
4
|
Sphinx docstring decorator
|
|
5
5
|
|
|
6
|
-
Version: 5.
|
|
7
|
-
Date updated:
|
|
6
|
+
Version: 5.2.0
|
|
7
|
+
Date updated: 14/03/2025 (dd/mm/yyyy)
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
# Module Package
|
|
@@ -53,6 +53,24 @@ class SphinxDocstring:
|
|
|
53
53
|
A class-based decorator to add a 'Version added',
|
|
54
54
|
'Version changed', or 'Deprecated' note to a function's docstring,
|
|
55
55
|
formatted for Sphinx documentation.
|
|
56
|
+
|
|
57
|
+
Parameters
|
|
58
|
+
----------
|
|
59
|
+
version : str
|
|
60
|
+
The version in which the function was added, changed, or deprecated.
|
|
61
|
+
|
|
62
|
+
reason : str | None, optional
|
|
63
|
+
An optional reason or description for the change
|
|
64
|
+
or deprecation, by default ``None``
|
|
65
|
+
|
|
66
|
+
mode : SphinxDocstringMode, optional
|
|
67
|
+
Specifies whether the function was 'added', 'changed', or 'deprecated',
|
|
68
|
+
by default SphinxDocstringMode.ADDED
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
Usage
|
|
72
|
+
-----
|
|
73
|
+
Use this as a decorator (``@SphinxDocstring(<parameters>)``)
|
|
56
74
|
"""
|
|
57
75
|
|
|
58
76
|
_LINEBREAK: ClassVar[str] = "\n\n" # Use ClassVar for constant
|
|
@@ -75,7 +93,7 @@ class SphinxDocstring:
|
|
|
75
93
|
An optional reason or description for the change
|
|
76
94
|
or deprecation, by default ``None``
|
|
77
95
|
|
|
78
|
-
mode : SphinxDocstringMode
|
|
96
|
+
mode : SphinxDocstringMode, optional
|
|
79
97
|
Specifies whether the function was 'added', 'changed', or 'deprecated',
|
|
80
98
|
by default SphinxDocstringMode.ADDED
|
|
81
99
|
|
|
@@ -87,38 +105,27 @@ class SphinxDocstring:
|
|
|
87
105
|
self.reason = reason
|
|
88
106
|
self.mode = mode
|
|
89
107
|
|
|
90
|
-
@overload
|
|
91
|
-
def __call__(self, obj: _T) -> _T: ...
|
|
108
|
+
@overload # Class overload
|
|
109
|
+
def __call__(self, obj: _T) -> _T: ...
|
|
110
|
+
|
|
111
|
+
@overload # Function overload
|
|
112
|
+
def __call__(self, obj: Callable[_P, _R]) -> Callable[_P, _R]: ...
|
|
92
113
|
|
|
93
|
-
@overload
|
|
94
|
-
def __call__(
|
|
95
|
-
self, obj: Callable[_P, _R]
|
|
96
|
-
) -> Callable[_P, _R]: ... # Function overload
|
|
97
114
|
def __call__(self, obj: _T | Callable[_P, _R]) -> _T | Callable[_P, _R]:
|
|
115
|
+
"""
|
|
116
|
+
Decorator for class and callable
|
|
117
|
+
"""
|
|
118
|
+
|
|
98
119
|
# Class wrapper
|
|
99
120
|
if isinstance(obj, type): # if inspect.isclass(obj):
|
|
100
|
-
|
|
101
|
-
num_of_white_spaces=self._calculate_white_space(obj.__doc__)
|
|
102
|
-
)
|
|
103
|
-
return obj
|
|
121
|
+
return self._update_doc(obj)
|
|
104
122
|
|
|
105
123
|
# Function wrapper
|
|
106
124
|
@wraps(obj)
|
|
107
125
|
def wrapper(*args: _P.args, **kwargs: _P.kwargs) -> _R:
|
|
108
126
|
return obj(*args, **kwargs)
|
|
109
127
|
|
|
110
|
-
|
|
111
|
-
# version_note = self._generate_version_note()
|
|
112
|
-
# if wrapper.__doc__ is None:
|
|
113
|
-
# wrapper.__doc__ = version_note
|
|
114
|
-
# else:
|
|
115
|
-
# wrapper.__doc__ += version_note
|
|
116
|
-
|
|
117
|
-
wrapper.__doc__ = (wrapper.__doc__ or "") + self._generate_version_note(
|
|
118
|
-
num_of_white_spaces=self._calculate_white_space(wrapper.__doc__)
|
|
119
|
-
)
|
|
120
|
-
|
|
121
|
-
return wrapper
|
|
128
|
+
return self._update_doc(wrapper)
|
|
122
129
|
|
|
123
130
|
def _calculate_white_space(self, docs: str | None) -> int:
|
|
124
131
|
"""
|
|
@@ -158,6 +165,17 @@ class SphinxDocstring:
|
|
|
158
165
|
reason=reason_str,
|
|
159
166
|
)
|
|
160
167
|
|
|
168
|
+
@overload
|
|
169
|
+
def _update_doc(self, obj: _T) -> _T: ...
|
|
170
|
+
@overload
|
|
171
|
+
def _update_doc(self, obj: Callable[_P, _R]) -> Callable[_P, _R]: ...
|
|
172
|
+
def _update_doc(self, obj: _T | Callable[_P, _R]) -> _T | Callable[_P, _R]:
|
|
173
|
+
"""Update docstring for an object"""
|
|
174
|
+
obj.__doc__ = (obj.__doc__ or "") + self._generate_version_note(
|
|
175
|
+
num_of_white_spaces=self._calculate_white_space(obj.__doc__)
|
|
176
|
+
)
|
|
177
|
+
return obj
|
|
178
|
+
|
|
161
179
|
|
|
162
180
|
# Partial
|
|
163
181
|
# ---------------------------------------------------------------------------
|
absfuyu/core/dummy_cli.py
CHANGED
absfuyu/core/dummy_func.py
CHANGED
|
@@ -3,8 +3,8 @@ Absfuyu: Core
|
|
|
3
3
|
-------------
|
|
4
4
|
Dummy functions when other libraries are unvailable
|
|
5
5
|
|
|
6
|
-
Version: 5.
|
|
7
|
-
Date updated:
|
|
6
|
+
Version: 5.2.0
|
|
7
|
+
Date updated: 13/03/2025 (dd/mm/yyyy)
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
# Module Package
|
|
@@ -12,6 +12,7 @@ Date updated: 22/02/2025 (dd/mm/yyyy)
|
|
|
12
12
|
__all__ = [
|
|
13
13
|
"tqdm",
|
|
14
14
|
"unidecode",
|
|
15
|
+
"dummy_function",
|
|
15
16
|
]
|
|
16
17
|
|
|
17
18
|
|
|
@@ -25,7 +26,7 @@ from importlib import import_module
|
|
|
25
26
|
try:
|
|
26
27
|
_tqdm = import_module("tqdm")
|
|
27
28
|
tqdm = getattr(_tqdm, "tqdm") # noqa
|
|
28
|
-
except (
|
|
29
|
+
except (ImportError, AttributeError):
|
|
29
30
|
|
|
30
31
|
def tqdm(iterable, *args, **kwargs):
|
|
31
32
|
"""
|
|
@@ -39,7 +40,7 @@ except (ModuleNotFoundError, AttributeError):
|
|
|
39
40
|
try:
|
|
40
41
|
_unidecode = import_module("unidecode")
|
|
41
42
|
unidecode = getattr(_unidecode, "unidecode") # noqa
|
|
42
|
-
except (
|
|
43
|
+
except (ImportError, AttributeError):
|
|
43
44
|
|
|
44
45
|
def unidecode(*args, **kwargs):
|
|
45
46
|
"""
|
|
@@ -47,3 +48,13 @@ except (ModuleNotFoundError, AttributeError):
|
|
|
47
48
|
install package ``unidecode`` to fully use this feature
|
|
48
49
|
"""
|
|
49
50
|
return args[0]
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
# dummy
|
|
54
|
+
def dummy_function(*args, **kwargs):
|
|
55
|
+
"""This is a dummy function"""
|
|
56
|
+
if args:
|
|
57
|
+
return args[0]
|
|
58
|
+
if kwargs:
|
|
59
|
+
return kwargs[list(kwargs)[0]]
|
|
60
|
+
return None
|
absfuyu/dxt/__init__.py
CHANGED
absfuyu/dxt/dictext.py
CHANGED
|
@@ -3,8 +3,8 @@ Absfuyu: Data Extension
|
|
|
3
3
|
-----------------------
|
|
4
4
|
dict extension
|
|
5
5
|
|
|
6
|
-
Version: 5.
|
|
7
|
-
Date updated:
|
|
6
|
+
Version: 5.2.0
|
|
7
|
+
Date updated: 12/03/2025 (dd/mm/yyyy)
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
# Module Package
|
|
@@ -37,6 +37,9 @@ class DictAnalyzeResult(NamedTuple):
|
|
|
37
37
|
class DictExt(ShowAllMethodsMixin, dict):
|
|
38
38
|
"""
|
|
39
39
|
``dict`` extension
|
|
40
|
+
|
|
41
|
+
>>> # For a list of new methods
|
|
42
|
+
>>> DictExt.show_all_methods()
|
|
40
43
|
"""
|
|
41
44
|
|
|
42
45
|
@versionchanged("3.3.0", reason="Updated return type")
|
absfuyu/dxt/dxt_support.py
CHANGED
absfuyu/dxt/intext.py
CHANGED
|
@@ -3,8 +3,8 @@ Absfuyu: Data Extension
|
|
|
3
3
|
-----------------------
|
|
4
4
|
int extension
|
|
5
5
|
|
|
6
|
-
Version: 5.
|
|
7
|
-
Date updated:
|
|
6
|
+
Version: 5.2.0
|
|
7
|
+
Date updated: 12/03/2025 (dd/mm/yyyy)
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
# Module Package
|
|
@@ -18,7 +18,7 @@ import math
|
|
|
18
18
|
from collections import Counter
|
|
19
19
|
from typing import Any, Self
|
|
20
20
|
|
|
21
|
-
from absfuyu.core import ShowAllMethodsMixin, versionchanged
|
|
21
|
+
from absfuyu.core import ShowAllMethodsMixin, versionadded, versionchanged
|
|
22
22
|
from absfuyu.dxt.dxt_support import DictBoolTrue
|
|
23
23
|
|
|
24
24
|
|
|
@@ -62,6 +62,9 @@ class Pow:
|
|
|
62
62
|
class IntExt(ShowAllMethodsMixin, int):
|
|
63
63
|
"""
|
|
64
64
|
``int`` extension
|
|
65
|
+
|
|
66
|
+
>>> # For a list of new methods
|
|
67
|
+
>>> IntExt.show_all_methods()
|
|
65
68
|
"""
|
|
66
69
|
|
|
67
70
|
# convert stuff
|
|
@@ -584,3 +587,31 @@ class IntExt(ShowAllMethodsMixin, int):
|
|
|
584
587
|
|
|
585
588
|
output["characteristic"] = characteristic
|
|
586
589
|
return output # type: ignore
|
|
590
|
+
|
|
591
|
+
@versionadded("5.1.0")
|
|
592
|
+
def split(self, parts: int) -> list[int]:
|
|
593
|
+
"""
|
|
594
|
+
Evenly split the number into ``parts`` parts
|
|
595
|
+
|
|
596
|
+
Parameters
|
|
597
|
+
----------
|
|
598
|
+
parts : int
|
|
599
|
+
Split by how many parts
|
|
600
|
+
|
|
601
|
+
Returns
|
|
602
|
+
-------
|
|
603
|
+
list[int]
|
|
604
|
+
List of evenly splitted numbers
|
|
605
|
+
|
|
606
|
+
|
|
607
|
+
Example:
|
|
608
|
+
--------
|
|
609
|
+
>>> IntExt(10).split(4)
|
|
610
|
+
[2, 2, 3, 3]
|
|
611
|
+
"""
|
|
612
|
+
p = max(1, parts)
|
|
613
|
+
if p == 1:
|
|
614
|
+
return [int(self)]
|
|
615
|
+
|
|
616
|
+
quotient, remainder = divmod(self, p)
|
|
617
|
+
return [quotient + (i >= (p - remainder)) for i in range(p)]
|