absfuyu 4.2.0__py3-none-any.whl → 5.0.1__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 +4 -4
- absfuyu/__main__.py +13 -1
- absfuyu/cli/__init__.py +2 -2
- absfuyu/cli/color.py +9 -2
- absfuyu/cli/config_group.py +2 -2
- absfuyu/cli/do_group.py +2 -37
- absfuyu/cli/game_group.py +2 -2
- absfuyu/cli/tool_group.py +7 -7
- absfuyu/config/__init__.py +17 -34
- absfuyu/core/__init__.py +49 -0
- absfuyu/core/baseclass.py +299 -0
- absfuyu/core/baseclass2.py +165 -0
- absfuyu/core/decorator.py +67 -0
- absfuyu/core/docstring.py +166 -0
- absfuyu/core/dummy_cli.py +67 -0
- absfuyu/core/dummy_func.py +49 -0
- absfuyu/dxt/__init__.py +42 -0
- absfuyu/dxt/dictext.py +201 -0
- absfuyu/dxt/dxt_support.py +79 -0
- absfuyu/dxt/intext.py +586 -0
- absfuyu/dxt/listext.py +508 -0
- absfuyu/dxt/strext.py +530 -0
- absfuyu/extra/__init__.py +12 -0
- absfuyu/extra/beautiful.py +252 -0
- absfuyu/{extensions → extra}/data_analysis.py +51 -82
- absfuyu/fun/__init__.py +110 -135
- absfuyu/fun/tarot.py +11 -19
- absfuyu/game/__init__.py +8 -2
- absfuyu/game/game_stat.py +8 -2
- absfuyu/game/sudoku.py +9 -3
- absfuyu/game/tictactoe.py +14 -7
- absfuyu/game/wordle.py +16 -10
- absfuyu/general/__init__.py +8 -81
- absfuyu/general/content.py +24 -38
- absfuyu/general/human.py +108 -228
- absfuyu/general/shape.py +1334 -0
- absfuyu/logger.py +10 -15
- absfuyu/pkg_data/__init__.py +137 -100
- absfuyu/pkg_data/deprecated.py +133 -0
- absfuyu/sort.py +6 -130
- absfuyu/tools/__init__.py +2 -2
- absfuyu/tools/checksum.py +33 -22
- absfuyu/tools/converter.py +51 -48
- absfuyu/{general → tools}/generator.py +17 -42
- absfuyu/tools/keygen.py +25 -30
- absfuyu/tools/obfuscator.py +246 -112
- absfuyu/tools/passwordlib.py +100 -30
- absfuyu/tools/shutdownizer.py +68 -47
- absfuyu/tools/web.py +4 -11
- absfuyu/util/__init__.py +17 -17
- absfuyu/util/api.py +10 -15
- absfuyu/util/json_method.py +7 -24
- absfuyu/util/lunar.py +5 -11
- absfuyu/util/path.py +22 -27
- absfuyu/util/performance.py +43 -67
- absfuyu/util/shorten_number.py +65 -14
- absfuyu/util/zipped.py +11 -17
- absfuyu/version.py +59 -42
- {absfuyu-4.2.0.dist-info → absfuyu-5.0.1.dist-info}/METADATA +41 -14
- absfuyu-5.0.1.dist-info/RECORD +68 -0
- absfuyu/core.py +0 -57
- absfuyu/everything.py +0 -32
- absfuyu/extensions/__init__.py +0 -12
- absfuyu/extensions/beautiful.py +0 -188
- absfuyu/fun/WGS.py +0 -134
- absfuyu/general/data_extension.py +0 -1796
- absfuyu/tools/stats.py +0 -226
- absfuyu/util/pkl.py +0 -67
- absfuyu-4.2.0.dist-info/RECORD +0 -59
- {absfuyu-4.2.0.dist-info → absfuyu-5.0.1.dist-info}/WHEEL +0 -0
- {absfuyu-4.2.0.dist-info → absfuyu-5.0.1.dist-info}/entry_points.txt +0 -0
- {absfuyu-4.2.0.dist-info → absfuyu-5.0.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Absfuyu: Core
|
|
3
|
+
-------------
|
|
4
|
+
Bases for other features (with library)
|
|
5
|
+
|
|
6
|
+
Version: 5.0.0
|
|
7
|
+
Date updated: 25/02/2025 (dd/mm/yyyy)
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
# Module Package
|
|
11
|
+
# ---------------------------------------------------------------------------
|
|
12
|
+
__all__ = [
|
|
13
|
+
# Class
|
|
14
|
+
"ShowAllMethodsMixinInspectVer",
|
|
15
|
+
# Metaclass
|
|
16
|
+
"PerformanceTrackingMeta",
|
|
17
|
+
# Class decorator
|
|
18
|
+
"positive_class_init_args",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
# Library
|
|
23
|
+
# ---------------------------------------------------------------------------
|
|
24
|
+
import time
|
|
25
|
+
import tracemalloc
|
|
26
|
+
from collections.abc import Callable
|
|
27
|
+
from functools import wraps
|
|
28
|
+
from inspect import getmro, isfunction
|
|
29
|
+
from types import MethodType
|
|
30
|
+
from typing import Any, ParamSpec, TypeVar
|
|
31
|
+
|
|
32
|
+
# Type
|
|
33
|
+
# ---------------------------------------------------------------------------
|
|
34
|
+
P = ParamSpec("P") # Parameter type
|
|
35
|
+
T = TypeVar("T", bound=type) # Type type - Can be any subtype of `type`
|
|
36
|
+
# R = TypeVar("R") # Return type
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
# Class
|
|
40
|
+
# ---------------------------------------------------------------------------
|
|
41
|
+
class ShowAllMethodsMixinInspectVer:
|
|
42
|
+
@classmethod
|
|
43
|
+
def show_all_methods(
|
|
44
|
+
cls,
|
|
45
|
+
include_classmethod: bool = True,
|
|
46
|
+
classmethod_indicator: str = "<classmethod>",
|
|
47
|
+
) -> dict[str, list[str]]:
|
|
48
|
+
result = {}
|
|
49
|
+
for base in getmro(cls)[::-1]:
|
|
50
|
+
methods = []
|
|
51
|
+
# for name, attr in inspect.getmembers(base, predicate=callable):
|
|
52
|
+
for name, attr in base.__dict__.items():
|
|
53
|
+
if name.startswith("__"):
|
|
54
|
+
continue
|
|
55
|
+
if isfunction(attr):
|
|
56
|
+
methods.append(name)
|
|
57
|
+
# if inspect.ismethod(attr):
|
|
58
|
+
if isinstance(attr, (classmethod, MethodType)) and include_classmethod:
|
|
59
|
+
methods.append(f"{name} {classmethod_indicator}")
|
|
60
|
+
if methods:
|
|
61
|
+
result[base.__name__] = sorted(methods)
|
|
62
|
+
return result
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
# Metaclass
|
|
66
|
+
# ---------------------------------------------------------------------------
|
|
67
|
+
class PerformanceTrackingMeta(type):
|
|
68
|
+
"""
|
|
69
|
+
A metaclass that tracks the instantiation time of classes.
|
|
70
|
+
|
|
71
|
+
Usage:
|
|
72
|
+
------
|
|
73
|
+
>>> class Demo(metaclass=PerformanceTrackingMeta):
|
|
74
|
+
... def __init__(self):...
|
|
75
|
+
>>> Demo()
|
|
76
|
+
--------------------------------------
|
|
77
|
+
Class: Demo
|
|
78
|
+
Memory usage: 0.000000 MB
|
|
79
|
+
Peak memory usage: 0.000008 MB
|
|
80
|
+
Time elapsed: 0.000001 s
|
|
81
|
+
--------------------------------------
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
def __new__(mcs, name: str, bases: tuple, attrs: dict[str, Any]):
|
|
85
|
+
"""
|
|
86
|
+
Intercepts class creation to wrap the ``__init__`` method.
|
|
87
|
+
|
|
88
|
+
Parameters
|
|
89
|
+
----------
|
|
90
|
+
mcs
|
|
91
|
+
The metaclass
|
|
92
|
+
|
|
93
|
+
name : str
|
|
94
|
+
The class name
|
|
95
|
+
|
|
96
|
+
bases : tuple
|
|
97
|
+
Tuple of base classes
|
|
98
|
+
|
|
99
|
+
attrs : dict[str, Any]
|
|
100
|
+
Dictionary of attributes
|
|
101
|
+
"""
|
|
102
|
+
if "__init__" in attrs:
|
|
103
|
+
original_init = attrs["__init__"]
|
|
104
|
+
|
|
105
|
+
@wraps(original_init)
|
|
106
|
+
def wrapped_init(self, *args, **kwargs):
|
|
107
|
+
# Performance check
|
|
108
|
+
tracemalloc.start()
|
|
109
|
+
start_time = time.perf_counter()
|
|
110
|
+
|
|
111
|
+
# Run __init__()
|
|
112
|
+
original_init(self, *args, **kwargs)
|
|
113
|
+
|
|
114
|
+
# Performance stop
|
|
115
|
+
current, peak = tracemalloc.get_traced_memory()
|
|
116
|
+
end_time = time.perf_counter()
|
|
117
|
+
tracemalloc.stop()
|
|
118
|
+
creation_time = end_time - start_time
|
|
119
|
+
|
|
120
|
+
# Print output
|
|
121
|
+
print(
|
|
122
|
+
f"{''.ljust(38, '-')}\n"
|
|
123
|
+
f"Class: {name}\n"
|
|
124
|
+
f"Memory usage:\t\t {current / 10**6:,.6f} MB\n"
|
|
125
|
+
f"Peak memory usage:\t {peak / 10**6:,.6f} MB\n"
|
|
126
|
+
f"Time elapsed:\t\t {creation_time:,.6f} s\n"
|
|
127
|
+
f"{''.ljust(38, '-')}"
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
attrs["__init__"] = wrapped_init
|
|
131
|
+
return super().__new__(mcs, name, bases, attrs)
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
# Decorator
|
|
135
|
+
# ---------------------------------------------------------------------------
|
|
136
|
+
def positive_class_init_args(cls: T):
|
|
137
|
+
"""
|
|
138
|
+
A class decorator that ensures all arguments in the ``__init__()`` method are positive.
|
|
139
|
+
"""
|
|
140
|
+
# original_init: Callable[P, None] | None = getattr(cls, "__init__", None)
|
|
141
|
+
# if original_init is None:
|
|
142
|
+
# return cls
|
|
143
|
+
try:
|
|
144
|
+
original_init: Callable[P, None] = cls.__init__ # type: ignore
|
|
145
|
+
except AttributeError:
|
|
146
|
+
return cls
|
|
147
|
+
|
|
148
|
+
@wraps(original_init)
|
|
149
|
+
def new_init(self, *args: P.args, **kwargs: P.kwargs):
|
|
150
|
+
# Check if all positional arguments are positive
|
|
151
|
+
for arg in args:
|
|
152
|
+
if isinstance(arg, (int, float)) and arg < 0:
|
|
153
|
+
raise ValueError(f"Argument {arg} must be positive")
|
|
154
|
+
|
|
155
|
+
# Check if all keyword arguments are positive
|
|
156
|
+
for key, value in kwargs.items():
|
|
157
|
+
if isinstance(value, (int, float)) and value < 0:
|
|
158
|
+
raise ValueError(f"Argument {key}={value} must be positive")
|
|
159
|
+
|
|
160
|
+
# Call the original __init__ method
|
|
161
|
+
original_init(self, *args, **kwargs)
|
|
162
|
+
|
|
163
|
+
# setattr(cls, "__init__", new_init)
|
|
164
|
+
cls.__init__ = new_init # type: ignore
|
|
165
|
+
return cls
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Absfuyu: Core
|
|
3
|
+
-------------
|
|
4
|
+
Decorator
|
|
5
|
+
|
|
6
|
+
Version: 5.0.0
|
|
7
|
+
Date updated: 22/02/2025 (dd/mm/yyyy)
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
# Module Package
|
|
11
|
+
# ---------------------------------------------------------------------------
|
|
12
|
+
__all__ = ["dummy_decorator", "dummy_decorator_with_args"]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
# Library
|
|
16
|
+
# ---------------------------------------------------------------------------
|
|
17
|
+
from collections.abc import Callable
|
|
18
|
+
from functools import wraps
|
|
19
|
+
from typing import ParamSpec, TypeVar, overload
|
|
20
|
+
|
|
21
|
+
# Type
|
|
22
|
+
# ---------------------------------------------------------------------------
|
|
23
|
+
P = ParamSpec("P") # Parameter type
|
|
24
|
+
R = TypeVar("R") # Return type - Can be anything
|
|
25
|
+
T = TypeVar("T", bound=type) # Type type - Can be any subtype of `type`
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
# Decorator
|
|
29
|
+
# ---------------------------------------------------------------------------
|
|
30
|
+
@overload
|
|
31
|
+
def dummy_decorator(obj: T) -> T: ...
|
|
32
|
+
@overload
|
|
33
|
+
def dummy_decorator(obj: Callable[P, R]) -> Callable[P, R]: ...
|
|
34
|
+
def dummy_decorator(obj: Callable[P, R] | T) -> Callable[P, R] | T:
|
|
35
|
+
"""
|
|
36
|
+
This is a decorator that does nothing. Normally used as a placeholder
|
|
37
|
+
"""
|
|
38
|
+
if isinstance(obj, type):
|
|
39
|
+
return obj
|
|
40
|
+
|
|
41
|
+
@wraps(obj)
|
|
42
|
+
def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
|
|
43
|
+
return obj(*args, **kwargs)
|
|
44
|
+
|
|
45
|
+
return wrapper
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def dummy_decorator_with_args(*args, **kwargs):
|
|
49
|
+
"""
|
|
50
|
+
This is a decorator with args and kwargs that does nothing. Normally used as a placeholder
|
|
51
|
+
"""
|
|
52
|
+
|
|
53
|
+
@overload
|
|
54
|
+
def decorator(obj: T) -> T: ...
|
|
55
|
+
@overload
|
|
56
|
+
def decorator(obj: Callable[P, R]) -> Callable[P, R]: ...
|
|
57
|
+
def decorator(obj: Callable[P, R] | T) -> Callable[P, R] | T:
|
|
58
|
+
if isinstance(obj, type):
|
|
59
|
+
return obj
|
|
60
|
+
|
|
61
|
+
@wraps(obj)
|
|
62
|
+
def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
|
|
63
|
+
return obj(*args, **kwargs)
|
|
64
|
+
|
|
65
|
+
return wrapper
|
|
66
|
+
|
|
67
|
+
return decorator
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Absfuyu: Core
|
|
3
|
+
-------------
|
|
4
|
+
Sphinx docstring decorator
|
|
5
|
+
|
|
6
|
+
Version: 5.0.0
|
|
7
|
+
Date updated: 23/02/2025 (dd/mm/yyyy)
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
# Module Package
|
|
11
|
+
# ---------------------------------------------------------------------------
|
|
12
|
+
__all__ = [
|
|
13
|
+
"SphinxDocstring",
|
|
14
|
+
"SphinxDocstringMode",
|
|
15
|
+
"versionadded",
|
|
16
|
+
"versionchanged",
|
|
17
|
+
"deprecated",
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
# Library
|
|
22
|
+
# ---------------------------------------------------------------------------
|
|
23
|
+
from collections.abc import Callable
|
|
24
|
+
from enum import Enum
|
|
25
|
+
from functools import partial, wraps
|
|
26
|
+
from string import Template
|
|
27
|
+
from typing import ClassVar, ParamSpec, TypeVar, overload
|
|
28
|
+
|
|
29
|
+
# Type
|
|
30
|
+
# ---------------------------------------------------------------------------
|
|
31
|
+
_P = ParamSpec("_P") # Parameter type
|
|
32
|
+
_R = TypeVar("_R") # Return type - Can be anything
|
|
33
|
+
_T = TypeVar("_T", bound=type) # Type type - Can be any subtype of `type`
|
|
34
|
+
|
|
35
|
+
_SPHINX_DOCS_TEMPLATE = Template("$line_break*$mode in version $version$reason*")
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
# Class
|
|
39
|
+
# ---------------------------------------------------------------------------
|
|
40
|
+
class SphinxDocstringMode(Enum):
|
|
41
|
+
"""
|
|
42
|
+
Enum representing the mode of the version change
|
|
43
|
+
(added, changed, or deprecated)
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
ADDED = "Added"
|
|
47
|
+
CHANGED = "Changed"
|
|
48
|
+
DEPRECATED = "Deprecated"
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class SphinxDocstring:
|
|
52
|
+
"""
|
|
53
|
+
A class-based decorator to add a 'Version added',
|
|
54
|
+
'Version changed', or 'Deprecated' note to a function's docstring,
|
|
55
|
+
formatted for Sphinx documentation.
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
_LINEBREAK: ClassVar[str] = "\n\n" # Use ClassVar for constant
|
|
59
|
+
|
|
60
|
+
def __init__(
|
|
61
|
+
self,
|
|
62
|
+
version: str,
|
|
63
|
+
reason: str | None = None,
|
|
64
|
+
mode: SphinxDocstringMode = SphinxDocstringMode.ADDED,
|
|
65
|
+
) -> None:
|
|
66
|
+
"""
|
|
67
|
+
Initializes the SphinxDocstring decorator.
|
|
68
|
+
|
|
69
|
+
Parameters
|
|
70
|
+
----------
|
|
71
|
+
version : str
|
|
72
|
+
The version in which the function was added, changed, or deprecated.
|
|
73
|
+
|
|
74
|
+
reason : str | None, optional
|
|
75
|
+
An optional reason or description for the change
|
|
76
|
+
or deprecation, by default ``None``
|
|
77
|
+
|
|
78
|
+
mode : SphinxDocstringMode | int, optional
|
|
79
|
+
Specifies whether the function was 'added', 'changed', or 'deprecated',
|
|
80
|
+
by default SphinxDocstringMode.ADDED
|
|
81
|
+
|
|
82
|
+
Usage
|
|
83
|
+
-----
|
|
84
|
+
Use this as a decorator (``@SphinxDocstring(<parameters>)``)
|
|
85
|
+
"""
|
|
86
|
+
self.version = version
|
|
87
|
+
self.reason = reason
|
|
88
|
+
self.mode = mode
|
|
89
|
+
|
|
90
|
+
@overload
|
|
91
|
+
def __call__(self, obj: _T) -> _T: ... # Class overload
|
|
92
|
+
|
|
93
|
+
@overload
|
|
94
|
+
def __call__(
|
|
95
|
+
self, obj: Callable[_P, _R]
|
|
96
|
+
) -> Callable[_P, _R]: ... # Function overload
|
|
97
|
+
def __call__(self, obj: _T | Callable[_P, _R]) -> _T | Callable[_P, _R]:
|
|
98
|
+
# Class wrapper
|
|
99
|
+
if isinstance(obj, type): # if inspect.isclass(obj):
|
|
100
|
+
obj.__doc__ = (obj.__doc__ or "") + self._generate_version_note(
|
|
101
|
+
num_of_white_spaces=self._calculate_white_space(obj.__doc__)
|
|
102
|
+
)
|
|
103
|
+
return obj
|
|
104
|
+
|
|
105
|
+
# Function wrapper
|
|
106
|
+
@wraps(obj)
|
|
107
|
+
def wrapper(*args: _P.args, **kwargs: _P.kwargs) -> _R:
|
|
108
|
+
return obj(*args, **kwargs)
|
|
109
|
+
|
|
110
|
+
# Add docstring
|
|
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
|
|
122
|
+
|
|
123
|
+
def _calculate_white_space(self, docs: str | None) -> int:
|
|
124
|
+
"""
|
|
125
|
+
Calculates the number of leading white spaces
|
|
126
|
+
in __doc__ of original function
|
|
127
|
+
"""
|
|
128
|
+
|
|
129
|
+
res = 0
|
|
130
|
+
if docs is None:
|
|
131
|
+
return res
|
|
132
|
+
|
|
133
|
+
try:
|
|
134
|
+
# Replace tabs with space and split line
|
|
135
|
+
lines = docs.expandtabs(4).splitlines()
|
|
136
|
+
except UnicodeError:
|
|
137
|
+
return res
|
|
138
|
+
else:
|
|
139
|
+
# Get indentation of each line and unique it
|
|
140
|
+
indent_set = {len(line) - len(line.lstrip()) for line in lines[1:]}
|
|
141
|
+
# Drop 0
|
|
142
|
+
res_list = sorted([x for x in indent_set if x > 0])
|
|
143
|
+
|
|
144
|
+
if res_list:
|
|
145
|
+
return res_list[0]
|
|
146
|
+
return res
|
|
147
|
+
|
|
148
|
+
def _generate_version_note(self, num_of_white_spaces: int) -> str:
|
|
149
|
+
"""
|
|
150
|
+
Generates the version note string based on the mode
|
|
151
|
+
"""
|
|
152
|
+
reason_str = f": {self.reason}" if self.reason else ""
|
|
153
|
+
# return f"{self._LINEBREAK}*{self.mode.value} in version {self.version}{reason_str}*"
|
|
154
|
+
return _SPHINX_DOCS_TEMPLATE.substitute(
|
|
155
|
+
line_break=self._LINEBREAK + " " * num_of_white_spaces,
|
|
156
|
+
mode=self.mode.value,
|
|
157
|
+
version=self.version,
|
|
158
|
+
reason=reason_str,
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
# Partial
|
|
163
|
+
# ---------------------------------------------------------------------------
|
|
164
|
+
versionadded = partial(SphinxDocstring, mode=SphinxDocstringMode.ADDED)
|
|
165
|
+
versionchanged = partial(SphinxDocstring, mode=SphinxDocstringMode.CHANGED)
|
|
166
|
+
deprecated = partial(SphinxDocstring, mode=SphinxDocstringMode.DEPRECATED)
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Absfuyu: Core
|
|
3
|
+
-------------
|
|
4
|
+
Dummy cli
|
|
5
|
+
|
|
6
|
+
Version: 5.0.0
|
|
7
|
+
Date updated: 25/02/2025 (dd/mm/yyyy)
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
# Module Package
|
|
11
|
+
# ---------------------------------------------------------------------------
|
|
12
|
+
__all__ = ["cli"]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
# Library
|
|
16
|
+
# ---------------------------------------------------------------------------
|
|
17
|
+
import sys
|
|
18
|
+
from argparse import ArgumentDefaultsHelpFormatter, ArgumentParser
|
|
19
|
+
|
|
20
|
+
from absfuyu import __title__, __version__
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
# Function
|
|
24
|
+
# ---------------------------------------------------------------------------
|
|
25
|
+
def get_parser(
|
|
26
|
+
name: str | None = None,
|
|
27
|
+
description: str | None = None,
|
|
28
|
+
epilog: str | None = None,
|
|
29
|
+
*,
|
|
30
|
+
version: str = "",
|
|
31
|
+
add_help: bool = True,
|
|
32
|
+
add_logging: bool = True,
|
|
33
|
+
) -> ArgumentParser:
|
|
34
|
+
arg_parser = ArgumentParser(
|
|
35
|
+
prog=name,
|
|
36
|
+
description=description,
|
|
37
|
+
epilog=epilog,
|
|
38
|
+
add_help=add_help,
|
|
39
|
+
formatter_class=ArgumentDefaultsHelpFormatter,
|
|
40
|
+
# allow_abbrev=False, # Disable long options recognize
|
|
41
|
+
# exit_on_error=True
|
|
42
|
+
)
|
|
43
|
+
arg_parser.add_argument(
|
|
44
|
+
"--version", action="version", version=f"%(prog)s {version}"
|
|
45
|
+
)
|
|
46
|
+
if add_logging:
|
|
47
|
+
_ll_val = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
|
|
48
|
+
arg_parser.add_argument(
|
|
49
|
+
"--log-level",
|
|
50
|
+
metavar="LOG_LEVEL",
|
|
51
|
+
dest="log_level",
|
|
52
|
+
choices=_ll_val,
|
|
53
|
+
default="INFO",
|
|
54
|
+
help=f"Log level: {_ll_val}",
|
|
55
|
+
)
|
|
56
|
+
return arg_parser
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def cli() -> None:
|
|
60
|
+
desc = "This is a dummy cli, please install <click> and <colorama> package to use this feature"
|
|
61
|
+
arg_parser = get_parser(
|
|
62
|
+
name=__title__,
|
|
63
|
+
description=desc,
|
|
64
|
+
version=__version__,
|
|
65
|
+
add_logging=False,
|
|
66
|
+
)
|
|
67
|
+
args = arg_parser.parse_args(args=None if sys.argv[1:] else ["--help"]) # noqa
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Absfuyu: Core
|
|
3
|
+
-------------
|
|
4
|
+
Dummy functions when other libraries are unvailable
|
|
5
|
+
|
|
6
|
+
Version: 5.0.0
|
|
7
|
+
Date updated: 22/02/2025 (dd/mm/yyyy)
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
# Module Package
|
|
11
|
+
# ---------------------------------------------------------------------------
|
|
12
|
+
__all__ = [
|
|
13
|
+
"tqdm",
|
|
14
|
+
"unidecode",
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# Library
|
|
19
|
+
# ---------------------------------------------------------------------------
|
|
20
|
+
from importlib import import_module
|
|
21
|
+
|
|
22
|
+
# Wrapper
|
|
23
|
+
# ---------------------------------------------------------------------------
|
|
24
|
+
# tqdm wrapper
|
|
25
|
+
try:
|
|
26
|
+
_tqdm = import_module("tqdm")
|
|
27
|
+
tqdm = getattr(_tqdm, "tqdm") # noqa
|
|
28
|
+
except (ModuleNotFoundError, AttributeError):
|
|
29
|
+
|
|
30
|
+
def tqdm(iterable, *args, **kwargs):
|
|
31
|
+
"""
|
|
32
|
+
Dummy tqdm function,
|
|
33
|
+
install package ``tqdm`` to fully use this feature
|
|
34
|
+
"""
|
|
35
|
+
return iterable
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
# unidecode wrapper
|
|
39
|
+
try:
|
|
40
|
+
_unidecode = import_module("unidecode")
|
|
41
|
+
unidecode = getattr(_unidecode, "unidecode") # noqa
|
|
42
|
+
except (ModuleNotFoundError, AttributeError):
|
|
43
|
+
|
|
44
|
+
def unidecode(*args, **kwargs):
|
|
45
|
+
"""
|
|
46
|
+
Dummy unidecode function,
|
|
47
|
+
install package ``unidecode`` to fully use this feature
|
|
48
|
+
"""
|
|
49
|
+
return args[0]
|
absfuyu/dxt/__init__.py
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Absfuyu: Data Extension
|
|
3
|
+
-----------------------
|
|
4
|
+
Extension for data type such as ``list``, ``str``, ``dict``, ...
|
|
5
|
+
|
|
6
|
+
Version: 5.0.0
|
|
7
|
+
Date updated: 22/02/2025 (dd/mm/yyyy)
|
|
8
|
+
|
|
9
|
+
Features:
|
|
10
|
+
---------
|
|
11
|
+
- DictExt
|
|
12
|
+
- IntExt
|
|
13
|
+
- ListExt
|
|
14
|
+
- Text
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
# Module Package
|
|
18
|
+
# ---------------------------------------------------------------------------
|
|
19
|
+
__all__ = [
|
|
20
|
+
# Main
|
|
21
|
+
"DictExt",
|
|
22
|
+
"IntExt",
|
|
23
|
+
"ListExt",
|
|
24
|
+
"Text",
|
|
25
|
+
# Support
|
|
26
|
+
"DictAnalyzeResult",
|
|
27
|
+
"DictBoolFalse",
|
|
28
|
+
"DictBoolTrue",
|
|
29
|
+
"ListNoDunder",
|
|
30
|
+
"ListREPR",
|
|
31
|
+
"Pow",
|
|
32
|
+
"TextAnalyzeDictFormat",
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
# Library
|
|
37
|
+
# ---------------------------------------------------------------------------
|
|
38
|
+
from absfuyu.dxt.dictext import DictAnalyzeResult, DictExt
|
|
39
|
+
from absfuyu.dxt.dxt_support import DictBoolFalse, DictBoolTrue, ListNoDunder, ListREPR
|
|
40
|
+
from absfuyu.dxt.intext import IntExt, Pow
|
|
41
|
+
from absfuyu.dxt.listext import ListExt
|
|
42
|
+
from absfuyu.dxt.strext import Text, TextAnalyzeDictFormat
|