| Name | xtwraps JSON |
| Version |
0.2.1
JSON |
| download |
| home_page | None |
| Summary | 功能强大的Python装饰器工具库,提供各种实用的装饰器和工具函数 |
| upload_time | 2025-10-19 09:41:30 |
| maintainer | None |
| docs_url | None |
| author | None |
| requires_python | >=3.13 |
| license | MIT License
Copyright (c) 2025 sandorn
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 |
python
decorators
tools
utilities
singleton
cache
retry
timer
logging
|
| VCS |
 |
| bugtrack_url |
|
| requirements |
six
websocket-client
xtlog
pytest
pytest-asyncio
pytest-cov
aiohttp
tenacity
requests
|
| Travis-CI |
No Travis.
|
| coveralls test coverage |
No coveralls.
|
# XTWraps
[](https://www.python.org/downloads/)
[](https://opensource.org/licenses/MIT)
[](https://pypi.org/project/xtwraps/)
## 项目简介
XTWraps 是一个功能强大的 Python 装饰器工具库,提供一系列实用的装饰器和工具函数,用于简化日常开发工作。
## 功能特性
### 核心功能
- **统一装饰器接口**:简化同步/异步函数的装饰器实现
- **日志记录装饰器**:提供函数调用的详细日志
- **函数执行计时器**:监控同步/异步函数的执行时间
- **自动重试机制**:优化网络请求和不稳定操作的成功率
- **线程池执行器包装器**:简化异步执行同步函数,函数命名优化为更直观的名称
- **单例模式实现**:提供多种单例装饰器和混入类
- **缓存装饰器**:提供函数结果缓存功能
- **类型检查和验证装饰器**:确保函数参数和返回值类型正确
### 设计特点
- **统一的 API 设计**:简化装饰器使用体验
- **自动识别并适配**:同步和异步函数无缝切换
- **完整的异常捕获和处理机制**:提高代码健壮性
- **符合现代 Python 类型注解规范**:增强代码可读性和 IDE 支持
- **支持多种组合使用场景**:灵活应对不同需求
- **线程安全的单例实现**:确保多线程环境下的安全性
- **完整的类型提示支持**:提高开发效率和代码质量
## 安装方法
### 从 PyPI 安装(推荐)
```bash
pip install xtwraps
```
### 从源码安装
```bash
git clone https://github.com/sandorn/xtwraps.git
cd xtwraps
pip install -e .
```
### 开发环境安装
```bash
git clone https://github.com/sandorn/xtwraps.git
cd xtwraps
pip install -e ".[test]"
```
## 使用示例
### 1. 日志装饰器
```python
from xtwraps import log_wraps
@log_wraps
def add_numbers(a: int, b: int) -> int:
return a + b
# 调用函数,会自动记录函数调用信息
result = add_numbers(5, 3)
```
### 2. 计时装饰器
```python
from xtwraps import timer_wraps
@timer_wraps
def slow_function():
import time
time.sleep(1) # 模拟耗时操作
return "完成"
# 调用函数,会自动记录执行时间
result = slow_function()
```
### 3. 异常处理装饰器
```python
from xtwraps import exc_wraps
@exc_wraps(re_raise=False, default_return=0)
def divide(a: int, b: int) -> float:
return a / b
# 安全调用,即使除零也不会崩溃
result = divide(10, 0) # 返回 0
```
### 4. 重试装饰器
```python
from xtwraps import retry_wraps
@retry_wraps(max_retries=3, delay=1)
def unstable_operation():
# 模拟不稳定操作,可能会失败
import random
if random.random() < 0.7:
raise ConnectionError("连接失败")
return "操作成功"
# 调用函数,会自动重试失败的操作
result = unstable_operation()
```
### 5. 单例模式
```python
from xtwraps import singleton
@singleton
def get_database_connection():
# 模拟数据库连接初始化
print("初始化数据库连接...")
return {"connection": "active"}
# 多次调用返回相同实例
conn1 = get_database_connection()
conn2 = get_database_connection()
assert conn1 is conn2
```
### 6. 缓存装饰器
```python
from xtwraps import cache_wrapper
@cache_wrapper(ttl=60) # 缓存60秒
def expensive_computation(x: int, y: int) -> int:
# 模拟耗时计算
print(f"执行计算: {x} + {y}")
return x + y
# 首次调用会执行计算并缓存结果
result1 = expensive_computation(10, 20)
# 再次调用会直接返回缓存结果,不执行计算
result2 = expensive_computation(10, 20)
```
## 更多示例
请查看 [examples](examples/) 目录下的示例文件,了解更多使用方法:
## 功能变化
### 版本 0.2.0 更新内容
- **异常处理优化**:改进了 retry 模块中异常处理的逻辑,确保异常捕获和处理更加健壮
- **爬虫专用重试装饰器**:新增了 spider_retry 装饰器,专为爬虫场景设计,支持更灵活的异常处理
- **代码复用优化**:优化了装饰器实现,减少冗余代码,提高维护性
- **JSON 响应处理**:修复了 JSON 响应处理中的错误,确保结果处理更加稳定
- **参数检查增强**:增强了函数参数的类型检查,提高代码健壮性
### 版本 0.1.1 更新内容
- **枚举类优化**:优化 BaseEnum 和 StrEnum 的使用方式和文档说明
- **最佳实践更新**:提供异常处理和类型使用的最佳实践指南
- **代码结构优化**:进一步优化模块组织,提高代码可读性和可维护性
- **文档完善**:更新功能说明和使用注意事项
### 版本 0.1.0 更新内容
- **API 稳定性提升**:所有核心 API 已稳定,适合生产环境使用
- **代码质量优化**:全面通过 ruff 和 basedPyright 检查,代码风格统一
- **文档完善**:更新使用示例和 API 说明,提高用户体验
- **性能改进**:优化内部实现,提高装饰器执行效率
- **依赖管理优化**:更新依赖版本,提高兼容性
### 版本 0.0.9 更新内容
- **函数命名优化**:重构 executor 模块,将复杂的函数名改为更直观的名称
- `executor_wraps` → `async_executor`:异步执行器装饰器,更明确地表达其异步执行功能
- `run_executor_wraps` → `syncify`:同步化装饰器,将异步函数转换为同步函数
- `future_wraps` → `to_future`:将普通函数返回值包装为 Future 对象
- `future_wraps_result` → `await_future_with_timeout`:带超时的 Future 等待函数
- **代码结构优化**:移除冗余类定义,将功能转换为独立函数,提高代码可读性
- **文档更新**:完善函数文档和类型注解,符合现代 Python 编码规范
## 版本更新日志
### v0.2.1 (2025-10-19)
**新功能:**
- 整合所有依赖到 `pyproject.toml` 中,简化依赖管理
- 移除 `wrapped.py` 模块,相关功能已整合到其他模块
- 优化类型注解,提升 IDE 支持
**改进:**
- 更新所有示例代码,移除对已删除模块的依赖
- 完善项目文档和安装说明
- 修复 Python 3.14 兼容性问题
**依赖更新:**
- 添加 `aiohttp>=3.10.0` 支持异步 HTTP 请求
- 添加 `tenacity>=8.2.0` 增强重试机制
- 添加 `requests>=2.32.3` 支持同步 HTTP 请求
### v0.2.0 (2025-10-01)
**重大更新:**
- 项目重命名:`nswrapslite` → `xtwraps`
- 更新 GitHub 仓库地址
- 完善所有模块的文档和示例
## 开发要求
- Python 3.13+
- 依赖项已整合到 `pyproject.toml` 中
## 贡献指南
欢迎提交问题和改进建议!如果您想为项目贡献代码,请遵循以下步骤:
1. Fork 项目仓库
2. 创建您的特性分支 (`git checkout -b feature/AmazingFeature`)
3. 提交您的更改 (`git commit -m 'Add some AmazingFeature'`)
4. 推送到分支 (`git push origin feature/AmazingFeature`)
5. 开启 Pull Request
## 许可证
本项目采用 MIT 许可证 - 详见 [LICENSE](LICENSE) 文件
## 作者
**sandorn**
- GitHub: [@sandorn](https://github.com/sandorn)
- Email: sandorn@live.cn
Raw data
{
"_id": null,
"home_page": null,
"name": "xtwraps",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.13",
"maintainer_email": null,
"keywords": "python, decorators, tools, utilities, singleton, cache, retry, timer, logging",
"author": null,
"author_email": "sandorn <sandorn@live.cn>",
"download_url": "https://files.pythonhosted.org/packages/3b/1c/6bd5bc8e2ad6aaf224535b48916e68e915a4dae7c65fbb7ab164933f7ca3/xtwraps-0.2.1.tar.gz",
"platform": null,
"description": "# XTWraps\r\n\r\n[](https://www.python.org/downloads/)\r\n[](https://opensource.org/licenses/MIT)\r\n[](https://pypi.org/project/xtwraps/)\r\n\r\n## \u9879\u76ee\u7b80\u4ecb\r\n\r\nXTWraps \u662f\u4e00\u4e2a\u529f\u80fd\u5f3a\u5927\u7684 Python \u88c5\u9970\u5668\u5de5\u5177\u5e93\uff0c\u63d0\u4f9b\u4e00\u7cfb\u5217\u5b9e\u7528\u7684\u88c5\u9970\u5668\u548c\u5de5\u5177\u51fd\u6570\uff0c\u7528\u4e8e\u7b80\u5316\u65e5\u5e38\u5f00\u53d1\u5de5\u4f5c\u3002\r\n\r\n## \u529f\u80fd\u7279\u6027\r\n\r\n### \u6838\u5fc3\u529f\u80fd\r\n\r\n- **\u7edf\u4e00\u88c5\u9970\u5668\u63a5\u53e3**\uff1a\u7b80\u5316\u540c\u6b65/\u5f02\u6b65\u51fd\u6570\u7684\u88c5\u9970\u5668\u5b9e\u73b0\r\n- **\u65e5\u5fd7\u8bb0\u5f55\u88c5\u9970\u5668**\uff1a\u63d0\u4f9b\u51fd\u6570\u8c03\u7528\u7684\u8be6\u7ec6\u65e5\u5fd7\r\n- **\u51fd\u6570\u6267\u884c\u8ba1\u65f6\u5668**\uff1a\u76d1\u63a7\u540c\u6b65/\u5f02\u6b65\u51fd\u6570\u7684\u6267\u884c\u65f6\u95f4\r\n- **\u81ea\u52a8\u91cd\u8bd5\u673a\u5236**\uff1a\u4f18\u5316\u7f51\u7edc\u8bf7\u6c42\u548c\u4e0d\u7a33\u5b9a\u64cd\u4f5c\u7684\u6210\u529f\u7387\r\n- **\u7ebf\u7a0b\u6c60\u6267\u884c\u5668\u5305\u88c5\u5668**\uff1a\u7b80\u5316\u5f02\u6b65\u6267\u884c\u540c\u6b65\u51fd\u6570\uff0c\u51fd\u6570\u547d\u540d\u4f18\u5316\u4e3a\u66f4\u76f4\u89c2\u7684\u540d\u79f0\r\n- **\u5355\u4f8b\u6a21\u5f0f\u5b9e\u73b0**\uff1a\u63d0\u4f9b\u591a\u79cd\u5355\u4f8b\u88c5\u9970\u5668\u548c\u6df7\u5165\u7c7b\r\n- **\u7f13\u5b58\u88c5\u9970\u5668**\uff1a\u63d0\u4f9b\u51fd\u6570\u7ed3\u679c\u7f13\u5b58\u529f\u80fd\r\n- **\u7c7b\u578b\u68c0\u67e5\u548c\u9a8c\u8bc1\u88c5\u9970\u5668**\uff1a\u786e\u4fdd\u51fd\u6570\u53c2\u6570\u548c\u8fd4\u56de\u503c\u7c7b\u578b\u6b63\u786e\r\n\r\n### \u8bbe\u8ba1\u7279\u70b9\r\n\r\n- **\u7edf\u4e00\u7684 API \u8bbe\u8ba1**\uff1a\u7b80\u5316\u88c5\u9970\u5668\u4f7f\u7528\u4f53\u9a8c\r\n- **\u81ea\u52a8\u8bc6\u522b\u5e76\u9002\u914d**\uff1a\u540c\u6b65\u548c\u5f02\u6b65\u51fd\u6570\u65e0\u7f1d\u5207\u6362\r\n- **\u5b8c\u6574\u7684\u5f02\u5e38\u6355\u83b7\u548c\u5904\u7406\u673a\u5236**\uff1a\u63d0\u9ad8\u4ee3\u7801\u5065\u58ee\u6027\r\n- **\u7b26\u5408\u73b0\u4ee3 Python \u7c7b\u578b\u6ce8\u89e3\u89c4\u8303**\uff1a\u589e\u5f3a\u4ee3\u7801\u53ef\u8bfb\u6027\u548c IDE \u652f\u6301\r\n- **\u652f\u6301\u591a\u79cd\u7ec4\u5408\u4f7f\u7528\u573a\u666f**\uff1a\u7075\u6d3b\u5e94\u5bf9\u4e0d\u540c\u9700\u6c42\r\n- **\u7ebf\u7a0b\u5b89\u5168\u7684\u5355\u4f8b\u5b9e\u73b0**\uff1a\u786e\u4fdd\u591a\u7ebf\u7a0b\u73af\u5883\u4e0b\u7684\u5b89\u5168\u6027\r\n- **\u5b8c\u6574\u7684\u7c7b\u578b\u63d0\u793a\u652f\u6301**\uff1a\u63d0\u9ad8\u5f00\u53d1\u6548\u7387\u548c\u4ee3\u7801\u8d28\u91cf\r\n\r\n## \u5b89\u88c5\u65b9\u6cd5\r\n\r\n### \u4ece PyPI \u5b89\u88c5\uff08\u63a8\u8350\uff09\r\n\r\n```bash\r\npip install xtwraps\r\n```\r\n\r\n### \u4ece\u6e90\u7801\u5b89\u88c5\r\n\r\n```bash\r\ngit clone https://github.com/sandorn/xtwraps.git\r\ncd xtwraps\r\npip install -e .\r\n```\r\n\r\n### \u5f00\u53d1\u73af\u5883\u5b89\u88c5\r\n\r\n```bash\r\ngit clone https://github.com/sandorn/xtwraps.git\r\ncd xtwraps\r\npip install -e \".[test]\"\r\n```\r\n\r\n## \u4f7f\u7528\u793a\u4f8b\r\n\r\n### 1. \u65e5\u5fd7\u88c5\u9970\u5668\r\n\r\n```python\r\nfrom xtwraps import log_wraps\r\n\r\n@log_wraps\r\ndef add_numbers(a: int, b: int) -> int:\r\n return a + b\r\n\r\n# \u8c03\u7528\u51fd\u6570\uff0c\u4f1a\u81ea\u52a8\u8bb0\u5f55\u51fd\u6570\u8c03\u7528\u4fe1\u606f\r\nresult = add_numbers(5, 3)\r\n```\r\n\r\n### 2. \u8ba1\u65f6\u88c5\u9970\u5668\r\n\r\n```python\r\nfrom xtwraps import timer_wraps\r\n\r\n@timer_wraps\r\ndef slow_function():\r\n import time\r\n time.sleep(1) # \u6a21\u62df\u8017\u65f6\u64cd\u4f5c\r\n return \"\u5b8c\u6210\"\r\n\r\n# \u8c03\u7528\u51fd\u6570\uff0c\u4f1a\u81ea\u52a8\u8bb0\u5f55\u6267\u884c\u65f6\u95f4\r\nresult = slow_function()\r\n```\r\n\r\n### 3. \u5f02\u5e38\u5904\u7406\u88c5\u9970\u5668\r\n\r\n```python\r\nfrom xtwraps import exc_wraps\r\n\r\n@exc_wraps(re_raise=False, default_return=0)\r\ndef divide(a: int, b: int) -> float:\r\n return a / b\r\n\r\n# \u5b89\u5168\u8c03\u7528\uff0c\u5373\u4f7f\u9664\u96f6\u4e5f\u4e0d\u4f1a\u5d29\u6e83\r\nresult = divide(10, 0) # \u8fd4\u56de 0\r\n```\r\n\r\n### 4. \u91cd\u8bd5\u88c5\u9970\u5668\r\n\r\n```python\r\nfrom xtwraps import retry_wraps\r\n\r\n@retry_wraps(max_retries=3, delay=1)\r\ndef unstable_operation():\r\n # \u6a21\u62df\u4e0d\u7a33\u5b9a\u64cd\u4f5c\uff0c\u53ef\u80fd\u4f1a\u5931\u8d25\r\n import random\r\n if random.random() < 0.7:\r\n raise ConnectionError(\"\u8fde\u63a5\u5931\u8d25\")\r\n return \"\u64cd\u4f5c\u6210\u529f\"\r\n\r\n# \u8c03\u7528\u51fd\u6570\uff0c\u4f1a\u81ea\u52a8\u91cd\u8bd5\u5931\u8d25\u7684\u64cd\u4f5c\r\nresult = unstable_operation()\r\n```\r\n\r\n### 5. \u5355\u4f8b\u6a21\u5f0f\r\n\r\n```python\r\nfrom xtwraps import singleton\r\n\r\n@singleton\r\ndef get_database_connection():\r\n # \u6a21\u62df\u6570\u636e\u5e93\u8fde\u63a5\u521d\u59cb\u5316\r\n print(\"\u521d\u59cb\u5316\u6570\u636e\u5e93\u8fde\u63a5...\")\r\n return {\"connection\": \"active\"}\r\n\r\n# \u591a\u6b21\u8c03\u7528\u8fd4\u56de\u76f8\u540c\u5b9e\u4f8b\r\nconn1 = get_database_connection()\r\nconn2 = get_database_connection()\r\nassert conn1 is conn2\r\n```\r\n\r\n### 6. \u7f13\u5b58\u88c5\u9970\u5668\r\n\r\n```python\r\nfrom xtwraps import cache_wrapper\r\n\r\n@cache_wrapper(ttl=60) # \u7f13\u5b5860\u79d2\r\ndef expensive_computation(x: int, y: int) -> int:\r\n # \u6a21\u62df\u8017\u65f6\u8ba1\u7b97\r\n print(f\"\u6267\u884c\u8ba1\u7b97: {x} + {y}\")\r\n return x + y\r\n\r\n# \u9996\u6b21\u8c03\u7528\u4f1a\u6267\u884c\u8ba1\u7b97\u5e76\u7f13\u5b58\u7ed3\u679c\r\nresult1 = expensive_computation(10, 20)\r\n# \u518d\u6b21\u8c03\u7528\u4f1a\u76f4\u63a5\u8fd4\u56de\u7f13\u5b58\u7ed3\u679c\uff0c\u4e0d\u6267\u884c\u8ba1\u7b97\r\nresult2 = expensive_computation(10, 20)\r\n```\r\n\r\n## \u66f4\u591a\u793a\u4f8b\r\n\r\n\u8bf7\u67e5\u770b [examples](examples/) \u76ee\u5f55\u4e0b\u7684\u793a\u4f8b\u6587\u4ef6\uff0c\u4e86\u89e3\u66f4\u591a\u4f7f\u7528\u65b9\u6cd5\uff1a\r\n\r\n## \u529f\u80fd\u53d8\u5316\r\n\r\n### \u7248\u672c 0.2.0 \u66f4\u65b0\u5185\u5bb9\r\n\r\n- **\u5f02\u5e38\u5904\u7406\u4f18\u5316**\uff1a\u6539\u8fdb\u4e86 retry \u6a21\u5757\u4e2d\u5f02\u5e38\u5904\u7406\u7684\u903b\u8f91\uff0c\u786e\u4fdd\u5f02\u5e38\u6355\u83b7\u548c\u5904\u7406\u66f4\u52a0\u5065\u58ee\r\n- **\u722c\u866b\u4e13\u7528\u91cd\u8bd5\u88c5\u9970\u5668**\uff1a\u65b0\u589e\u4e86 spider_retry \u88c5\u9970\u5668\uff0c\u4e13\u4e3a\u722c\u866b\u573a\u666f\u8bbe\u8ba1\uff0c\u652f\u6301\u66f4\u7075\u6d3b\u7684\u5f02\u5e38\u5904\u7406\r\n- **\u4ee3\u7801\u590d\u7528\u4f18\u5316**\uff1a\u4f18\u5316\u4e86\u88c5\u9970\u5668\u5b9e\u73b0\uff0c\u51cf\u5c11\u5197\u4f59\u4ee3\u7801\uff0c\u63d0\u9ad8\u7ef4\u62a4\u6027\r\n- **JSON \u54cd\u5e94\u5904\u7406**\uff1a\u4fee\u590d\u4e86 JSON \u54cd\u5e94\u5904\u7406\u4e2d\u7684\u9519\u8bef\uff0c\u786e\u4fdd\u7ed3\u679c\u5904\u7406\u66f4\u52a0\u7a33\u5b9a\r\n- **\u53c2\u6570\u68c0\u67e5\u589e\u5f3a**\uff1a\u589e\u5f3a\u4e86\u51fd\u6570\u53c2\u6570\u7684\u7c7b\u578b\u68c0\u67e5\uff0c\u63d0\u9ad8\u4ee3\u7801\u5065\u58ee\u6027\r\n\r\n### \u7248\u672c 0.1.1 \u66f4\u65b0\u5185\u5bb9\r\n\r\n- **\u679a\u4e3e\u7c7b\u4f18\u5316**\uff1a\u4f18\u5316 BaseEnum \u548c StrEnum \u7684\u4f7f\u7528\u65b9\u5f0f\u548c\u6587\u6863\u8bf4\u660e\r\n- **\u6700\u4f73\u5b9e\u8df5\u66f4\u65b0**\uff1a\u63d0\u4f9b\u5f02\u5e38\u5904\u7406\u548c\u7c7b\u578b\u4f7f\u7528\u7684\u6700\u4f73\u5b9e\u8df5\u6307\u5357\r\n- **\u4ee3\u7801\u7ed3\u6784\u4f18\u5316**\uff1a\u8fdb\u4e00\u6b65\u4f18\u5316\u6a21\u5757\u7ec4\u7ec7\uff0c\u63d0\u9ad8\u4ee3\u7801\u53ef\u8bfb\u6027\u548c\u53ef\u7ef4\u62a4\u6027\r\n- **\u6587\u6863\u5b8c\u5584**\uff1a\u66f4\u65b0\u529f\u80fd\u8bf4\u660e\u548c\u4f7f\u7528\u6ce8\u610f\u4e8b\u9879\r\n\r\n### \u7248\u672c 0.1.0 \u66f4\u65b0\u5185\u5bb9\r\n\r\n- **API \u7a33\u5b9a\u6027\u63d0\u5347**\uff1a\u6240\u6709\u6838\u5fc3 API \u5df2\u7a33\u5b9a\uff0c\u9002\u5408\u751f\u4ea7\u73af\u5883\u4f7f\u7528\r\n- **\u4ee3\u7801\u8d28\u91cf\u4f18\u5316**\uff1a\u5168\u9762\u901a\u8fc7 ruff \u548c basedPyright \u68c0\u67e5\uff0c\u4ee3\u7801\u98ce\u683c\u7edf\u4e00\r\n- **\u6587\u6863\u5b8c\u5584**\uff1a\u66f4\u65b0\u4f7f\u7528\u793a\u4f8b\u548c API \u8bf4\u660e\uff0c\u63d0\u9ad8\u7528\u6237\u4f53\u9a8c\r\n- **\u6027\u80fd\u6539\u8fdb**\uff1a\u4f18\u5316\u5185\u90e8\u5b9e\u73b0\uff0c\u63d0\u9ad8\u88c5\u9970\u5668\u6267\u884c\u6548\u7387\r\n- **\u4f9d\u8d56\u7ba1\u7406\u4f18\u5316**\uff1a\u66f4\u65b0\u4f9d\u8d56\u7248\u672c\uff0c\u63d0\u9ad8\u517c\u5bb9\u6027\r\n\r\n### \u7248\u672c 0.0.9 \u66f4\u65b0\u5185\u5bb9\r\n\r\n- **\u51fd\u6570\u547d\u540d\u4f18\u5316**\uff1a\u91cd\u6784 executor \u6a21\u5757\uff0c\u5c06\u590d\u6742\u7684\u51fd\u6570\u540d\u6539\u4e3a\u66f4\u76f4\u89c2\u7684\u540d\u79f0\r\n - `executor_wraps` \u2192 `async_executor`\uff1a\u5f02\u6b65\u6267\u884c\u5668\u88c5\u9970\u5668\uff0c\u66f4\u660e\u786e\u5730\u8868\u8fbe\u5176\u5f02\u6b65\u6267\u884c\u529f\u80fd\r\n - `run_executor_wraps` \u2192 `syncify`\uff1a\u540c\u6b65\u5316\u88c5\u9970\u5668\uff0c\u5c06\u5f02\u6b65\u51fd\u6570\u8f6c\u6362\u4e3a\u540c\u6b65\u51fd\u6570\r\n - `future_wraps` \u2192 `to_future`\uff1a\u5c06\u666e\u901a\u51fd\u6570\u8fd4\u56de\u503c\u5305\u88c5\u4e3a Future \u5bf9\u8c61\r\n - `future_wraps_result` \u2192 `await_future_with_timeout`\uff1a\u5e26\u8d85\u65f6\u7684 Future \u7b49\u5f85\u51fd\u6570\r\n- **\u4ee3\u7801\u7ed3\u6784\u4f18\u5316**\uff1a\u79fb\u9664\u5197\u4f59\u7c7b\u5b9a\u4e49\uff0c\u5c06\u529f\u80fd\u8f6c\u6362\u4e3a\u72ec\u7acb\u51fd\u6570\uff0c\u63d0\u9ad8\u4ee3\u7801\u53ef\u8bfb\u6027\r\n- **\u6587\u6863\u66f4\u65b0**\uff1a\u5b8c\u5584\u51fd\u6570\u6587\u6863\u548c\u7c7b\u578b\u6ce8\u89e3\uff0c\u7b26\u5408\u73b0\u4ee3 Python \u7f16\u7801\u89c4\u8303\r\n\r\n## \u7248\u672c\u66f4\u65b0\u65e5\u5fd7\r\n\r\n### v0.2.1 (2025-10-19)\r\n\r\n**\u65b0\u529f\u80fd\uff1a**\r\n\r\n- \u6574\u5408\u6240\u6709\u4f9d\u8d56\u5230 `pyproject.toml` \u4e2d\uff0c\u7b80\u5316\u4f9d\u8d56\u7ba1\u7406\r\n- \u79fb\u9664 `wrapped.py` \u6a21\u5757\uff0c\u76f8\u5173\u529f\u80fd\u5df2\u6574\u5408\u5230\u5176\u4ed6\u6a21\u5757\r\n- \u4f18\u5316\u7c7b\u578b\u6ce8\u89e3\uff0c\u63d0\u5347 IDE \u652f\u6301\r\n\r\n**\u6539\u8fdb\uff1a**\r\n\r\n- \u66f4\u65b0\u6240\u6709\u793a\u4f8b\u4ee3\u7801\uff0c\u79fb\u9664\u5bf9\u5df2\u5220\u9664\u6a21\u5757\u7684\u4f9d\u8d56\r\n- \u5b8c\u5584\u9879\u76ee\u6587\u6863\u548c\u5b89\u88c5\u8bf4\u660e\r\n- \u4fee\u590d Python 3.14 \u517c\u5bb9\u6027\u95ee\u9898\r\n\r\n**\u4f9d\u8d56\u66f4\u65b0\uff1a**\r\n\r\n- \u6dfb\u52a0 `aiohttp>=3.10.0` \u652f\u6301\u5f02\u6b65 HTTP \u8bf7\u6c42\r\n- \u6dfb\u52a0 `tenacity>=8.2.0` \u589e\u5f3a\u91cd\u8bd5\u673a\u5236\r\n- \u6dfb\u52a0 `requests>=2.32.3` \u652f\u6301\u540c\u6b65 HTTP \u8bf7\u6c42\r\n\r\n### v0.2.0 (2025-10-01)\r\n\r\n**\u91cd\u5927\u66f4\u65b0\uff1a**\r\n\r\n- \u9879\u76ee\u91cd\u547d\u540d\uff1a`nswrapslite` \u2192 `xtwraps`\r\n- \u66f4\u65b0 GitHub \u4ed3\u5e93\u5730\u5740\r\n- \u5b8c\u5584\u6240\u6709\u6a21\u5757\u7684\u6587\u6863\u548c\u793a\u4f8b\r\n\r\n## \u5f00\u53d1\u8981\u6c42\r\n\r\n- Python 3.13+\r\n- \u4f9d\u8d56\u9879\u5df2\u6574\u5408\u5230 `pyproject.toml` \u4e2d\r\n\r\n## \u8d21\u732e\u6307\u5357\r\n\r\n\u6b22\u8fce\u63d0\u4ea4\u95ee\u9898\u548c\u6539\u8fdb\u5efa\u8bae\uff01\u5982\u679c\u60a8\u60f3\u4e3a\u9879\u76ee\u8d21\u732e\u4ee3\u7801\uff0c\u8bf7\u9075\u5faa\u4ee5\u4e0b\u6b65\u9aa4\uff1a\r\n\r\n1. Fork \u9879\u76ee\u4ed3\u5e93\r\n2. \u521b\u5efa\u60a8\u7684\u7279\u6027\u5206\u652f (`git checkout -b feature/AmazingFeature`)\r\n3. \u63d0\u4ea4\u60a8\u7684\u66f4\u6539 (`git commit -m 'Add some AmazingFeature'`)\r\n4. \u63a8\u9001\u5230\u5206\u652f (`git push origin feature/AmazingFeature`)\r\n5. \u5f00\u542f Pull Request\r\n\r\n## \u8bb8\u53ef\u8bc1\r\n\r\n\u672c\u9879\u76ee\u91c7\u7528 MIT \u8bb8\u53ef\u8bc1 - \u8be6\u89c1 [LICENSE](LICENSE) \u6587\u4ef6\r\n\r\n## \u4f5c\u8005\r\n\r\n**sandorn**\r\n\r\n- GitHub: [@sandorn](https://github.com/sandorn)\r\n- Email: sandorn@live.cn\r\n",
"bugtrack_url": null,
"license": "MIT License\r\n \r\n Copyright (c) 2025 sandorn\r\n \r\n Permission is hereby granted, free of charge, to any person obtaining a copy\r\n of this software and associated documentation files (the \"Software\"), to deal\r\n in the Software without restriction, including without limitation the rights\r\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n copies of the Software, and to permit persons to whom the Software is\r\n furnished to do so, subject to the following conditions:\r\n \r\n The above copyright notice and this permission notice shall be included in all\r\n copies or substantial portions of the Software.\r\n \r\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n SOFTWARE.",
"summary": "\u529f\u80fd\u5f3a\u5927\u7684Python\u88c5\u9970\u5668\u5de5\u5177\u5e93\uff0c\u63d0\u4f9b\u5404\u79cd\u5b9e\u7528\u7684\u88c5\u9970\u5668\u548c\u5de5\u5177\u51fd\u6570",
"version": "0.2.1",
"project_urls": {
"documentation": "https://github.com/sandorn/xtwraps/wiki",
"homepage": "https://github.com/sandorn/xtwraps",
"repository": "https://github.com/sandorn/xtwraps"
},
"split_keywords": [
"python",
" decorators",
" tools",
" utilities",
" singleton",
" cache",
" retry",
" timer",
" logging"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "a41558448db0dc5c81c687ab0b0965f11cc28ba2edad3b65d64b4a7737f5475e",
"md5": "7a0bc7622e28ed3458feddd8df75f990",
"sha256": "af85fbf64adca62a18ed95d5f3215eab649e91c5f250edb1ea56e87ae8e5820a"
},
"downloads": -1,
"filename": "xtwraps-0.2.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "7a0bc7622e28ed3458feddd8df75f990",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.13",
"size": 42846,
"upload_time": "2025-10-19T09:41:19",
"upload_time_iso_8601": "2025-10-19T09:41:19.734597Z",
"url": "https://files.pythonhosted.org/packages/a4/15/58448db0dc5c81c687ab0b0965f11cc28ba2edad3b65d64b4a7737f5475e/xtwraps-0.2.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "3b1c6bd5bc8e2ad6aaf224535b48916e68e915a4dae7c65fbb7ab164933f7ca3",
"md5": "20212bc2ddbb277c2b1d4d7ef899be27",
"sha256": "f51522008f3346136bad300edcd9ea87d680c079eed5eea92630fc53885f62e4"
},
"downloads": -1,
"filename": "xtwraps-0.2.1.tar.gz",
"has_sig": false,
"md5_digest": "20212bc2ddbb277c2b1d4d7ef899be27",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.13",
"size": 37317,
"upload_time": "2025-10-19T09:41:30",
"upload_time_iso_8601": "2025-10-19T09:41:30.405128Z",
"url": "https://files.pythonhosted.org/packages/3b/1c/6bd5bc8e2ad6aaf224535b48916e68e915a4dae7c65fbb7ab164933f7ca3/xtwraps-0.2.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-19 09:41:30",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "sandorn",
"github_project": "xtwraps",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"requirements": [
{
"name": "six",
"specs": [
[
">=",
"1.16.0"
]
]
},
{
"name": "websocket-client",
"specs": [
[
">=",
"1.5.1"
]
]
},
{
"name": "xtlog",
"specs": [
[
">=",
"0.1.7"
]
]
},
{
"name": "pytest",
"specs": [
[
">=",
"7.3.0"
]
]
},
{
"name": "pytest-asyncio",
"specs": [
[
">=",
"0.21.0"
]
]
},
{
"name": "pytest-cov",
"specs": [
[
">=",
"4.1.0"
]
]
},
{
"name": "aiohttp",
"specs": [
[
">=",
"3.10.0"
]
]
},
{
"name": "tenacity",
"specs": [
[
">=",
"8.2.0"
]
]
},
{
"name": "requests",
"specs": [
[
">=",
"2.32.3"
]
]
}
],
"lcname": "xtwraps"
}