Name | DToolslib JSON |
Version |
0.0.1.4
JSON |
| download |
home_page | None |
Summary | A simple and complex tool library containing multiple tool scripts 一个简单且杂的工具库, 包含多个工具脚本 |
upload_time | 2025-02-14 06:47:48 |
maintainer | None |
docs_url | None |
author | Jf-JIN |
requires_python | >=3.11 |
license | MIT License
Copyright (c) 2025 Jf-JIN
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
|
keywords |
signal
logger
logging
enum
|
VCS |
 |
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# DToolslib
A simple and complex tool library containing multiple tool scripts
一个简单且杂的工具库, 包含多个工具脚本
### StaticEnum
An enumeration library, supported
一个枚举类库, 支持:
- Unique variables (not repetitively named)
唯一变量(不可重复命名)
- Value cannot be modified
值不可修改
- Custom properties
自定义属性
- Keep the original type (except None, Boolean), you can use `isinstance` to judge
保留原类型(None, Boolean 除外), 可以使用 `isinstance` 判断
- It can be read directly, and there is no need to use its `value` property. Of course, it can also use `value`
可以直接读取, 不需要使用其 `value` 属性, 当然也可以使用 `value`
###### How to use | 使用方法
```python
class TestEnum(StaticEnum):
# __allow_new_attr__ = True # Allow new attributes to be added outside the class | 允许类外部添加新属性
A = '#ff0000'
A.color_name = 'Red'
A.ansi_font = 31
A.ansi_background = 41
print(TestEnum.A) # output: #ff0000
print(TestEnum.A.name) # output: A
print(TestEnum.A.color_name) # output: Red
print(TestEnum.A.ansi_font) # output: 31
print(type(TestEnum.A)) # output: <class '__main__.SEString'>
print('#ff0000' in TestEnum) # output: True
print(isinstance(TestEnum.A, str)) # output: True
```
### EventSignal
Imitating the mechanism of Qt's signal and slot, custom signals, this signal can be used out of the Qt framework. There is currently no thread locking and asynchronous mechanism, which supports:
模仿于 Qt 的信号和槽的机制, 自定义的信号, 该信号可以脱离 Qt 框架使用, 目前没有线程锁和异步的机制, 支持:
- Instance signal (default)
实例信号(默认)
- Class signals
类信号
- Attribute protection, the signal cannot be assigned
属性保护, 信号不可被赋值
###### How to use | 使用方法
```python
class Test:
signal_instance_a = EventSignal(str) # Instance Signal
signal_instance_b = EventSignal(str, int) # Instance Signal
signal_class = EventSignal(str, int, signal_scope='class') # Class Signal
a = Test()
b = Test()
b.signal_instance_a.connect(print)
a.signal_instance_b.connect(b.signal_instance_a)
b.signal_instance_a.emit('This is a test message')
a.signal_instance_a.disconnect(b.signal_instance_a)
# output: This is a test message
print(a.signal_class is b.signal_class) # output: True
print(a.signal_instance_a is b.signal_instance_a) # output: False
print(type(a.signal_class)) # output: <class '__main__.EventSignal'>
print(a.__signals__) # output: {...} a dict with 2 keys, the values are signal instances. You can also see the slots of the signal.
print(a.__class_signals__) # output: {...} a dict with 1 keys, the values are signal instances. You can also see the slots of the signal.
```
### Logger
Logger, see docstring for details, support:
日志器, 详见 docstring, 支持:
- Clean old logs before startup to define the total number of retained
启动前清理旧日志, 可定义保留总数
- Size splitting
大小分割
- Days segmentation
天数分割
- Function traceability exclusion, class traceability exclusion, module traceability exclusion, for example: Exclude func1 function under ClassA class (assuming the relationship chain is: ClassA->func3->func2->func1), then log positioning will be located to func2
函数追溯排除, 类追溯排除, 模块追溯排除, 例如: 排除 `ClassA` 类下的 `func1` 函数(假设关系链为: `ClassA->func3->func2->func1` ), 则日志定位将定位到`func2`
- Output highlight styles and terminal color styles. After setting, you can obtain HTML style information through the signal.
输出高亮样式, 终端彩色样式. 设置后, 可以通过信号获取 HTML 样式的信息
- Can track logging output
可跟踪 logging 输出
- Can be output with a signal
可通过信号针对性输出
###### How to use | 使用方法
```python
Log = Logger('test', os.path.dirname(__file__), log_level='info', size_limit=1024, doSplitByDay=True)
Log.signal_debug_message.connect(print)
logging.debug('hello world from logging debug') # logging tracking example
Log.trace('This is a trace message.')
Log.debug('This is a debug message.')
Log.info('This is a info message.')
Log.warning('This is a warning message.')
Log.error('This is a error message.')
Log.critical('This is a critical message.')
```
### LoggerGroup
Logger group, see docstring for details, support
日志器组, 详见 docstring, 支持
- Size splitting
大小分割
- Days segmentation
天数分割
- All Logger information is automatically collected by default, and it can also be manually changed to specify a few Loggers.
默认自动收集所有 Logger 信息, 也可以手动更改为指定某几个 Logger
- Output highlight style, same Logger
输出高亮样式, 同 Logger
- Can be output with a signal
可通过信号针对性输出
- Singleton mode
单例模式
###### How to use | 使用方法
```python
Log = Logger('test', os.path.dirname(__file__), log_level='info', size_limit=1024, doSplitByDay=True)
Log_1 = Logger('tests', os.path.dirname(__file__), log_sub_folder_name='test_folder', log_level='trace', size_limit=1024, doSplitByDay=True)
Logger_group = LoggerGroup(os.path.dirname(__file__))
Log.info('This is a info message.')
Log_1.warning('This is a warning message.')
Log.error('This is a error message.')
Log_1.critical('This is a critical message.')
```
### SingletonMeta
Singleton pattern metaclass
单例模式元类
###### How to use | 使用方法
```python
class Test(metaclass=SingletonMeta):
...
a = Test()
b = Test()
print(a is b) # output: True
```
### Inner_Decorators
Interior Decorators
内部装饰器
- `try_except_log`: Capture errors and output them to logs. The function needs to be improved and is not recommended
捕捉报错并输出给日志, 功能有待完善, 不推荐使用
- `boundary_check`: Function/method boundary check, not tested
函数/方法边界检查, 未测试
- `time_counter`: Calculate the function/method run time and print it
计算函数/方法运行时间, 并打印
- `who_called_me`: Get the call tree
获取调用树
# 版本信息 Version Info
#### v0.0.1.4
* The new logger supports the exclusion of combined function names (such as `ClassA.func1`). Currently, only first-level combinations are supported, that is, the most recent class to which the method belongs must be consistent with the current class at the time of call.
新增日志器支持对组合函数名(如 `ClassA.func1`)的排除. 目前仅支持一级组合, 即方法所属的最近一级类必须与调用时的当前类一致.
* Fixed the issue that StaticEnum could add new properties outside, as well as the bug in data type errors in multi-layer nested classes inside.
修复 StaticEnum 可在外部新增属性的问题, 以及内部多层嵌套类的数据类型错误的 bug.
* Changed the way data types are converted in the StaticEnum metaclass, changed from the previous eval to created with the class.
更改了 StaticEnum 元类中转换数据类型的方式, 从之前的eval更改为用类创建.
Raw data
{
"_id": null,
"home_page": null,
"name": "DToolslib",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.11",
"maintainer_email": null,
"keywords": "signal, logger, logging, enum",
"author": "Jf-JIN",
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/ae/0e/dd1759c5025dd6a34b123f75e985ce970a3fe1a0083472bd051f298fcdd0/dtoolslib-0.0.1.4.tar.gz",
"platform": null,
"description": "# DToolslib\n\nA simple and complex tool library containing multiple tool scripts\n\u4e00\u4e2a\u7b80\u5355\u4e14\u6742\u7684\u5de5\u5177\u5e93, \u5305\u542b\u591a\u4e2a\u5de5\u5177\u811a\u672c\n\n### StaticEnum\n\nAn enumeration library, supported\n\u4e00\u4e2a\u679a\u4e3e\u7c7b\u5e93, \u652f\u6301:\n\n- Unique variables (not repetitively named)\n \u552f\u4e00\u53d8\u91cf(\u4e0d\u53ef\u91cd\u590d\u547d\u540d)\n- Value cannot be modified\n \u503c\u4e0d\u53ef\u4fee\u6539\n- Custom properties\n \u81ea\u5b9a\u4e49\u5c5e\u6027\n- Keep the original type (except None, Boolean), you can use `isinstance` to judge\n \u4fdd\u7559\u539f\u7c7b\u578b(None, Boolean \u9664\u5916), \u53ef\u4ee5\u4f7f\u7528 `isinstance` \u5224\u65ad\n- It can be read directly, and there is no need to use its `value` property. Of course, it can also use `value`\n \u53ef\u4ee5\u76f4\u63a5\u8bfb\u53d6, \u4e0d\u9700\u8981\u4f7f\u7528\u5176 `value` \u5c5e\u6027, \u5f53\u7136\u4e5f\u53ef\u4ee5\u4f7f\u7528 `value`\n\n###### How to use | \u4f7f\u7528\u65b9\u6cd5\n\n```python\nclass TestEnum(StaticEnum):\n # __allow_new_attr__ = True # Allow new attributes to be added outside the class | \u5141\u8bb8\u7c7b\u5916\u90e8\u6dfb\u52a0\u65b0\u5c5e\u6027\n A = '#ff0000'\n A.color_name = 'Red'\n A.ansi_font = 31\n A.ansi_background = 41\n\nprint(TestEnum.A) # output: #ff0000\nprint(TestEnum.A.name) # output: A\nprint(TestEnum.A.color_name) # output: Red\nprint(TestEnum.A.ansi_font) # output: 31\nprint(type(TestEnum.A)) # output: <class '__main__.SEString'>\nprint('#ff0000' in TestEnum) # output: True\nprint(isinstance(TestEnum.A, str)) # output: True\n```\n\n### EventSignal\n\nImitating the mechanism of Qt's signal and slot, custom signals, this signal can be used out of the Qt framework. There is currently no thread locking and asynchronous mechanism, which supports:\n\u6a21\u4eff\u4e8e Qt \u7684\u4fe1\u53f7\u548c\u69fd\u7684\u673a\u5236, \u81ea\u5b9a\u4e49\u7684\u4fe1\u53f7, \u8be5\u4fe1\u53f7\u53ef\u4ee5\u8131\u79bb Qt \u6846\u67b6\u4f7f\u7528, \u76ee\u524d\u6ca1\u6709\u7ebf\u7a0b\u9501\u548c\u5f02\u6b65\u7684\u673a\u5236, \u652f\u6301:\n\n- Instance signal (default) \n \u5b9e\u4f8b\u4fe1\u53f7(\u9ed8\u8ba4)\n- Class signals\n \u7c7b\u4fe1\u53f7\n- Attribute protection, the signal cannot be assigned\n \u5c5e\u6027\u4fdd\u62a4, \u4fe1\u53f7\u4e0d\u53ef\u88ab\u8d4b\u503c\n\n###### How to use | \u4f7f\u7528\u65b9\u6cd5\n\n```python\nclass Test:\n signal_instance_a = EventSignal(str) # Instance Signal\n signal_instance_b = EventSignal(str, int) # Instance Signal\n signal_class = EventSignal(str, int, signal_scope='class') # Class Signal\na = Test()\nb = Test()\nb.signal_instance_a.connect(print)\na.signal_instance_b.connect(b.signal_instance_a)\nb.signal_instance_a.emit('This is a test message')\na.signal_instance_a.disconnect(b.signal_instance_a)\n# output: This is a test message\nprint(a.signal_class is b.signal_class) # output: True\nprint(a.signal_instance_a is b.signal_instance_a) # output: False\nprint(type(a.signal_class)) # output: <class '__main__.EventSignal'>\nprint(a.__signals__) # output: {...} a dict with 2 keys, the values are signal instances. You can also see the slots of the signal.\nprint(a.__class_signals__) # output: {...} a dict with 1 keys, the values are signal instances. You can also see the slots of the signal.\n```\n\n### Logger\n\nLogger, see docstring for details, support:\n\u65e5\u5fd7\u5668, \u8be6\u89c1 docstring, \u652f\u6301:\n\n- Clean old logs before startup to define the total number of retained\n \u542f\u52a8\u524d\u6e05\u7406\u65e7\u65e5\u5fd7, \u53ef\u5b9a\u4e49\u4fdd\u7559\u603b\u6570\n \n- Size splitting\n \u5927\u5c0f\u5206\u5272\n \n- Days segmentation\n \u5929\u6570\u5206\u5272\n \n- Function traceability exclusion, class traceability exclusion, module traceability exclusion, for example: Exclude func1 function under ClassA class (assuming the relationship chain is: ClassA->func3->func2->func1), then log positioning will be located to func2\n \n \n \n \u51fd\u6570\u8ffd\u6eaf\u6392\u9664, \u7c7b\u8ffd\u6eaf\u6392\u9664, \u6a21\u5757\u8ffd\u6eaf\u6392\u9664, \u4f8b\u5982: \u6392\u9664 `ClassA` \u7c7b\u4e0b\u7684 `func1` \u51fd\u6570(\u5047\u8bbe\u5173\u7cfb\u94fe\u4e3a: `ClassA->func3->func2->func1` ), \u5219\u65e5\u5fd7\u5b9a\u4f4d\u5c06\u5b9a\u4f4d\u5230`func2`\n \n- Output highlight styles and terminal color styles. After setting, you can obtain HTML style information through the signal.\n \u8f93\u51fa\u9ad8\u4eae\u6837\u5f0f, \u7ec8\u7aef\u5f69\u8272\u6837\u5f0f. \u8bbe\u7f6e\u540e, \u53ef\u4ee5\u901a\u8fc7\u4fe1\u53f7\u83b7\u53d6 HTML \u6837\u5f0f\u7684\u4fe1\u606f\n \n- Can track logging output\n \u53ef\u8ddf\u8e2a logging \u8f93\u51fa\n \n- Can be output with a signal\n \u53ef\u901a\u8fc7\u4fe1\u53f7\u9488\u5bf9\u6027\u8f93\u51fa\n\n###### How to use | \u4f7f\u7528\u65b9\u6cd5\n\n```python\nLog = Logger('test', os.path.dirname(__file__), log_level='info', size_limit=1024, doSplitByDay=True)\nLog.signal_debug_message.connect(print)\nlogging.debug('hello world from logging debug') # logging tracking example\nLog.trace('This is a trace message.')\nLog.debug('This is a debug message.')\nLog.info('This is a info message.')\nLog.warning('This is a warning message.')\nLog.error('This is a error message.')\nLog.critical('This is a critical message.')\n```\n\n### LoggerGroup\n\nLogger group, see docstring for details, support\n\u65e5\u5fd7\u5668\u7ec4, \u8be6\u89c1 docstring, \u652f\u6301\n\n- Size splitting\n \u5927\u5c0f\u5206\u5272\n- Days segmentation\n \u5929\u6570\u5206\u5272\n- All Logger information is automatically collected by default, and it can also be manually changed to specify a few Loggers.\n \u9ed8\u8ba4\u81ea\u52a8\u6536\u96c6\u6240\u6709 Logger \u4fe1\u606f, \u4e5f\u53ef\u4ee5\u624b\u52a8\u66f4\u6539\u4e3a\u6307\u5b9a\u67d0\u51e0\u4e2a Logger\n- Output highlight style, same Logger\n \u8f93\u51fa\u9ad8\u4eae\u6837\u5f0f, \u540c Logger\n- Can be output with a signal\n \u53ef\u901a\u8fc7\u4fe1\u53f7\u9488\u5bf9\u6027\u8f93\u51fa\n- Singleton mode\n \u5355\u4f8b\u6a21\u5f0f\n\n###### How to use | \u4f7f\u7528\u65b9\u6cd5\n\n```python\nLog = Logger('test', os.path.dirname(__file__), log_level='info', size_limit=1024, doSplitByDay=True)\nLog_1 = Logger('tests', os.path.dirname(__file__), log_sub_folder_name='test_folder', log_level='trace', size_limit=1024, doSplitByDay=True)\nLogger_group = LoggerGroup(os.path.dirname(__file__))\nLog.info('This is a info message.')\nLog_1.warning('This is a warning message.')\nLog.error('This is a error message.')\nLog_1.critical('This is a critical message.')\n```\n\n### SingletonMeta\n\nSingleton pattern metaclass\n\u5355\u4f8b\u6a21\u5f0f\u5143\u7c7b\n\n###### How to use | \u4f7f\u7528\u65b9\u6cd5\n\n```python\nclass Test(metaclass=SingletonMeta):\n\t...\na = Test()\nb = Test()\nprint(a is b) # output: True\n```\n\n### Inner_Decorators\n\nInterior Decorators\n\u5185\u90e8\u88c5\u9970\u5668\n\n- `try_except_log`: Capture errors and output them to logs. The function needs to be improved and is not recommended\n \u6355\u6349\u62a5\u9519\u5e76\u8f93\u51fa\u7ed9\u65e5\u5fd7, \u529f\u80fd\u6709\u5f85\u5b8c\u5584, \u4e0d\u63a8\u8350\u4f7f\u7528\n- `boundary_check`: Function/method boundary check, not tested\n \u51fd\u6570/\u65b9\u6cd5\u8fb9\u754c\u68c0\u67e5, \u672a\u6d4b\u8bd5\n- `time_counter`: Calculate the function/method run time and print it\n \u8ba1\u7b97\u51fd\u6570/\u65b9\u6cd5\u8fd0\u884c\u65f6\u95f4, \u5e76\u6253\u5370\n- `who_called_me`: Get the call tree\n \u83b7\u53d6\u8c03\u7528\u6811\n\n# \u7248\u672c\u4fe1\u606f Version Info\n\n#### v0.0.1.4\n\n* The new logger supports the exclusion of combined function names (such as `ClassA.func1`). Currently, only first-level combinations are supported, that is, the most recent class to which the method belongs must be consistent with the current class at the time of call.\n \u65b0\u589e\u65e5\u5fd7\u5668\u652f\u6301\u5bf9\u7ec4\u5408\u51fd\u6570\u540d(\u5982 `ClassA.func1`)\u7684\u6392\u9664. \u76ee\u524d\u4ec5\u652f\u6301\u4e00\u7ea7\u7ec4\u5408, \u5373\u65b9\u6cd5\u6240\u5c5e\u7684\u6700\u8fd1\u4e00\u7ea7\u7c7b\u5fc5\u987b\u4e0e\u8c03\u7528\u65f6\u7684\u5f53\u524d\u7c7b\u4e00\u81f4. \n* Fixed the issue that StaticEnum could add new properties outside, as well as the bug in data type errors in multi-layer nested classes inside.\n \u4fee\u590d StaticEnum \u53ef\u5728\u5916\u90e8\u65b0\u589e\u5c5e\u6027\u7684\u95ee\u9898, \u4ee5\u53ca\u5185\u90e8\u591a\u5c42\u5d4c\u5957\u7c7b\u7684\u6570\u636e\u7c7b\u578b\u9519\u8bef\u7684 bug. \n* Changed the way data types are converted in the StaticEnum metaclass, changed from the previous eval to created with the class.\n \u66f4\u6539\u4e86 StaticEnum \u5143\u7c7b\u4e2d\u8f6c\u6362\u6570\u636e\u7c7b\u578b\u7684\u65b9\u5f0f, \u4ece\u4e4b\u524d\u7684eval\u66f4\u6539\u4e3a\u7528\u7c7b\u521b\u5efa. \n\n",
"bugtrack_url": null,
"license": "MIT License\n \n Copyright (c) 2025 Jf-JIN\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\n \n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n \n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n \n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n SOFTWARE.\n ",
"summary": "A simple and complex tool library containing multiple tool scripts \u4e00\u4e2a\u7b80\u5355\u4e14\u6742\u7684\u5de5\u5177\u5e93, \u5305\u542b\u591a\u4e2a\u5de5\u5177\u811a\u672c",
"version": "0.0.1.4",
"project_urls": {
"Homepage": "https://github.com/Jf-JIN/DToolslib",
"Repository": "https://github.com/Jf-JIN/DToolslib"
},
"split_keywords": [
"signal",
" logger",
" logging",
" enum"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "7d4cd98a4eff86a5ba2006d5fc384b456d9f0f11a68dd32c3a8fd18b897bf518",
"md5": "dcc7706f6d07ab61e6fb7fda2ad26a6d",
"sha256": "a48fddf1afa7ce062852d0d12fc4218f661d8906ee1182896cad03927830db2e"
},
"downloads": -1,
"filename": "DToolslib-0.0.1.4-py3-none-any.whl",
"has_sig": false,
"md5_digest": "dcc7706f6d07ab61e6fb7fda2ad26a6d",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.11",
"size": 27630,
"upload_time": "2025-02-14T06:47:45",
"upload_time_iso_8601": "2025-02-14T06:47:45.807008Z",
"url": "https://files.pythonhosted.org/packages/7d/4c/d98a4eff86a5ba2006d5fc384b456d9f0f11a68dd32c3a8fd18b897bf518/DToolslib-0.0.1.4-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "ae0edd1759c5025dd6a34b123f75e985ce970a3fe1a0083472bd051f298fcdd0",
"md5": "0c26c79e895d6424f9b3e9aed5793a16",
"sha256": "ab26041173354ade8dbf0c37502be7d3fd754eb91625d0fa9705687df110a3f7"
},
"downloads": -1,
"filename": "dtoolslib-0.0.1.4.tar.gz",
"has_sig": false,
"md5_digest": "0c26c79e895d6424f9b3e9aed5793a16",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.11",
"size": 24087,
"upload_time": "2025-02-14T06:47:48",
"upload_time_iso_8601": "2025-02-14T06:47:48.293930Z",
"url": "https://files.pythonhosted.org/packages/ae/0e/dd1759c5025dd6a34b123f75e985ce970a3fe1a0083472bd051f298fcdd0/dtoolslib-0.0.1.4.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-02-14 06:47:48",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "Jf-JIN",
"github_project": "DToolslib",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "dtoolslib"
}