smartasync 0.2.0__tar.gz

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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 GenroPy
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,254 @@
1
+ Metadata-Version: 2.4
2
+ Name: smartasync
3
+ Version: 0.2.0
4
+ Summary: Unified sync/async API decorator with automatic context detection
5
+ Author-email: Giovanni Porcari <softwell@softwell.it>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/genropy/smartasync
8
+ Project-URL: Documentation, https://smartasync.readthedocs.io
9
+ Project-URL: Repository, https://github.com/genropy/smartasync
10
+ Project-URL: Bug Tracker, https://github.com/genropy/smartasync/issues
11
+ Keywords: async,sync,decorator,asyncio,context-detection,unified-api
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
19
+ Classifier: Framework :: AsyncIO
20
+ Classifier: Typing :: Typed
21
+ Requires-Python: >=3.10
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Provides-Extra: dev
25
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
26
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
27
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
28
+ Requires-Dist: black>=23.0.0; extra == "dev"
29
+ Requires-Dist: ruff>=0.1.0; extra == "dev"
30
+ Requires-Dist: mypy>=1.0.0; extra == "dev"
31
+ Provides-Extra: docs
32
+ Requires-Dist: sphinx>=8.0.0; extra == "docs"
33
+ Requires-Dist: sphinx-rtd-theme>=3.0.0; extra == "docs"
34
+ Requires-Dist: sphinx-autodoc-typehints>=3.0.0; extra == "docs"
35
+ Requires-Dist: myst-parser>=4.0.0; extra == "docs"
36
+ Requires-Dist: sphinxcontrib-mermaid>=1.0.0; extra == "docs"
37
+ Provides-Extra: all
38
+ Requires-Dist: pytest>=7.0.0; extra == "all"
39
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == "all"
40
+ Requires-Dist: pytest-cov>=4.0.0; extra == "all"
41
+ Requires-Dist: black>=23.0.0; extra == "all"
42
+ Requires-Dist: ruff>=0.1.0; extra == "all"
43
+ Requires-Dist: mypy>=1.0.0; extra == "all"
44
+ Requires-Dist: sphinx>=8.0.0; extra == "all"
45
+ Requires-Dist: sphinx-rtd-theme>=3.0.0; extra == "all"
46
+ Requires-Dist: sphinx-autodoc-typehints>=3.0.0; extra == "all"
47
+ Requires-Dist: myst-parser>=4.0.0; extra == "all"
48
+ Requires-Dist: sphinxcontrib-mermaid>=1.0.0; extra == "all"
49
+ Dynamic: license-file
50
+
51
+ # SmartAsync
52
+
53
+ **Unified sync/async API decorator with automatic context detection**
54
+
55
+ [![PyPI version](https://img.shields.io/pypi/v/smartasync.svg)](https://pypi.org/project/smartasync/)
56
+ [![Tests](https://github.com/genropy/smartasync/actions/workflows/test.yml/badge.svg)](https://github.com/genropy/smartasync/actions/workflows/test.yml)
57
+ [![codecov](https://codecov.io/gh/genropy/smartasync/branch/main/graph/badge.svg)](https://codecov.io/gh/genropy/smartasync)
58
+ [![Documentation Status](https://readthedocs.org/projects/smartasync/badge/?version=latest)](https://smartasync.readthedocs.io/en/latest/?badge=latest)
59
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
60
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
61
+ [![Part of Genro-Libs](https://img.shields.io/badge/Part%20of-Genro--Libs-blue)](https://github.com/softwell/genro-libs)
62
+ [![LLM Docs](https://img.shields.io/badge/LLM-Docs-purple)](llm-docs/)
63
+
64
+ SmartAsync allows you to write async methods once and call them in both sync and async contexts without modification. It automatically detects the execution context and adapts accordingly.
65
+
66
+ ## Features
67
+
68
+ - ✅ **Automatic context detection**: Detects sync vs async execution context at runtime
69
+ - ✅ **Zero configuration**: Just apply the `@smartasync` decorator
70
+ - ✅ **Asymmetric caching**: Smart caching strategy for optimal performance
71
+ - ✅ **Compatible with `__slots__`**: Works with memory-optimized classes
72
+ - ✅ **Pure Python**: No dependencies beyond standard library
73
+
74
+ ## Installation
75
+
76
+ ```bash
77
+ pip install smartasync
78
+ ```
79
+
80
+ ## Quick Start
81
+
82
+ ```python
83
+ from smartasync import smartasync
84
+ import asyncio
85
+
86
+ class DataManager:
87
+ @smartasync
88
+ async def fetch_data(self, url: str):
89
+ """Fetch data - works in both sync and async contexts!"""
90
+ async with httpx.AsyncClient() as client:
91
+ response = await client.get(url)
92
+ return response.json()
93
+
94
+ # Sync context - no await needed
95
+ manager = DataManager()
96
+ data = manager.fetch_data("https://api.example.com/data")
97
+
98
+ # Async context - use await
99
+ async def main():
100
+ manager = DataManager()
101
+ data = await manager.fetch_data("https://api.example.com/data")
102
+
103
+ asyncio.run(main())
104
+ ```
105
+
106
+ ## How It Works
107
+
108
+ SmartAsync uses `asyncio.get_running_loop()` to detect the execution context:
109
+
110
+ - **Sync context** (no event loop): Executes with `asyncio.run()`
111
+ - **Async context** (event loop running): Returns coroutine to be awaited
112
+
113
+ ### Asymmetric Caching
114
+
115
+ SmartAsync uses an intelligent caching strategy:
116
+ - ✅ **Async context detected**: Cached forever (can't transition from async to sync)
117
+ - ⚠️ **Sync context**: Always rechecked (can transition from sync to async)
118
+
119
+ This ensures correct behavior while optimizing for the most common case (async contexts in web frameworks).
120
+
121
+ ## Use Cases
122
+
123
+ ### 1. CLI + HTTP API
124
+
125
+ ```python
126
+ from smartasync import smartasync
127
+ from smpub import PublishedClass, ApiSwitcher
128
+
129
+ class DataHandler(PublishedClass):
130
+ api = ApiSwitcher()
131
+
132
+ @api
133
+ @smartasync
134
+ async def process_data(self, input_file: str):
135
+ """Process data file."""
136
+ async with aiofiles.open(input_file) as f:
137
+ data = await f.read()
138
+ return process(data)
139
+
140
+ # CLI usage (sync)
141
+ handler = DataHandler()
142
+ result = handler.process_data("data.csv")
143
+
144
+ # HTTP usage (async via FastAPI)
145
+ # Automatically works without modification!
146
+ ```
147
+
148
+ ### 2. Testing
149
+
150
+ ```python
151
+ @smartasync
152
+ async def database_query(query: str):
153
+ async with database.connect() as conn:
154
+ return await conn.execute(query)
155
+
156
+ # Sync tests
157
+ def test_query():
158
+ result = database_query("SELECT * FROM users")
159
+ assert len(result) > 0
160
+
161
+ # Async tests
162
+ async def test_query_async():
163
+ result = await database_query("SELECT * FROM users")
164
+ assert len(result) > 0
165
+ ```
166
+
167
+ ### 3. Mixed Codebases
168
+
169
+ Perfect for gradually migrating sync code to async without breaking existing callers.
170
+
171
+ ## Performance
172
+
173
+ - **Decoration time**: ~3-4 microseconds (one-time cost)
174
+ - **Sync context**: ~102 microseconds (dominated by `asyncio.run()` overhead)
175
+ - **Async context (first call)**: ~2.3 microseconds
176
+ - **Async context (cached)**: ~1.3 microseconds
177
+
178
+ For typical CLI tools and web APIs, this overhead is negligible compared to network latency (10-200ms).
179
+
180
+ ## Advanced Usage
181
+
182
+ ### With `__slots__`
183
+
184
+ SmartAsync works seamlessly with `__slots__` classes:
185
+
186
+ ```python
187
+ from smartasync import smartasync
188
+
189
+ class OptimizedManager:
190
+ __slots__ = ('data',)
191
+
192
+ def __init__(self):
193
+ self.data = []
194
+
195
+ @smartasync
196
+ async def add_item(self, item):
197
+ await asyncio.sleep(0.01) # Simulate I/O
198
+ self.data.append(item)
199
+ ```
200
+
201
+ ### Cache Reset for Testing
202
+
203
+ ```python
204
+ @smartasync
205
+ async def my_method():
206
+ pass
207
+
208
+ # Reset cache between tests
209
+ my_method._smartasync_reset_cache()
210
+ ```
211
+
212
+ ## Limitations
213
+
214
+ - ⚠️ **Cannot transition from async to sync**: Once in async context, cannot move back to sync (this is correct behavior)
215
+ - ⚠️ **Sync overhead**: Always rechecks context in sync mode (~2 microseconds per call)
216
+
217
+ ## Thread Safety
218
+
219
+ SmartAsync is **safe for all common use cases**:
220
+
221
+ ✅ **Safe scenarios** (covers 99% of real-world usage):
222
+ - Single-threaded applications (CLI tools, scripts)
223
+ - Async event loops (inherently single-threaded)
224
+ - Web servers with request isolation (new instance per request)
225
+ - Thread pools with instance-per-thread pattern
226
+
227
+ ⚠️ **Theoretical concern** (anti-pattern, not recommended):
228
+ - Sharing a single instance across multiple threads in a thread pool
229
+
230
+ **Why this isn't a real issue:**
231
+ The anti-pattern scenario defeats SmartAsync's purpose. If you're using thread pools with shared instances, you should use async workers instead for better performance and natural concurrency.
232
+
233
+ **Recommendation:** Create instances per thread/request, or better yet, use async patterns natively.
234
+
235
+ ## Related Projects
236
+
237
+ SmartAsync is part of the **Genro-Libs toolkit**:
238
+
239
+ - [smartswitch](https://github.com/genropy/smartswitch) - Rule-based function dispatch
240
+ - [smpub](https://github.com/genropy/smpub) - CLI/API framework (uses SmartAsync for async handlers)
241
+ - [gtext](https://github.com/genropy/gtext) - Text transformation and templates
242
+
243
+ ## Contributing
244
+
245
+ Contributions welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
246
+
247
+ ## License
248
+
249
+ MIT License - see [LICENSE](LICENSE) file for details.
250
+
251
+ ## Credits
252
+
253
+ **Author**: Giovanni Porcari (Genropy Team)
254
+ **Part of**: [Genro-Libs](https://github.com/softwell/genro-libs) developer toolkit
@@ -0,0 +1,204 @@
1
+ # SmartAsync
2
+
3
+ **Unified sync/async API decorator with automatic context detection**
4
+
5
+ [![PyPI version](https://img.shields.io/pypi/v/smartasync.svg)](https://pypi.org/project/smartasync/)
6
+ [![Tests](https://github.com/genropy/smartasync/actions/workflows/test.yml/badge.svg)](https://github.com/genropy/smartasync/actions/workflows/test.yml)
7
+ [![codecov](https://codecov.io/gh/genropy/smartasync/branch/main/graph/badge.svg)](https://codecov.io/gh/genropy/smartasync)
8
+ [![Documentation Status](https://readthedocs.org/projects/smartasync/badge/?version=latest)](https://smartasync.readthedocs.io/en/latest/?badge=latest)
9
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
10
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
11
+ [![Part of Genro-Libs](https://img.shields.io/badge/Part%20of-Genro--Libs-blue)](https://github.com/softwell/genro-libs)
12
+ [![LLM Docs](https://img.shields.io/badge/LLM-Docs-purple)](llm-docs/)
13
+
14
+ SmartAsync allows you to write async methods once and call them in both sync and async contexts without modification. It automatically detects the execution context and adapts accordingly.
15
+
16
+ ## Features
17
+
18
+ - ✅ **Automatic context detection**: Detects sync vs async execution context at runtime
19
+ - ✅ **Zero configuration**: Just apply the `@smartasync` decorator
20
+ - ✅ **Asymmetric caching**: Smart caching strategy for optimal performance
21
+ - ✅ **Compatible with `__slots__`**: Works with memory-optimized classes
22
+ - ✅ **Pure Python**: No dependencies beyond standard library
23
+
24
+ ## Installation
25
+
26
+ ```bash
27
+ pip install smartasync
28
+ ```
29
+
30
+ ## Quick Start
31
+
32
+ ```python
33
+ from smartasync import smartasync
34
+ import asyncio
35
+
36
+ class DataManager:
37
+ @smartasync
38
+ async def fetch_data(self, url: str):
39
+ """Fetch data - works in both sync and async contexts!"""
40
+ async with httpx.AsyncClient() as client:
41
+ response = await client.get(url)
42
+ return response.json()
43
+
44
+ # Sync context - no await needed
45
+ manager = DataManager()
46
+ data = manager.fetch_data("https://api.example.com/data")
47
+
48
+ # Async context - use await
49
+ async def main():
50
+ manager = DataManager()
51
+ data = await manager.fetch_data("https://api.example.com/data")
52
+
53
+ asyncio.run(main())
54
+ ```
55
+
56
+ ## How It Works
57
+
58
+ SmartAsync uses `asyncio.get_running_loop()` to detect the execution context:
59
+
60
+ - **Sync context** (no event loop): Executes with `asyncio.run()`
61
+ - **Async context** (event loop running): Returns coroutine to be awaited
62
+
63
+ ### Asymmetric Caching
64
+
65
+ SmartAsync uses an intelligent caching strategy:
66
+ - ✅ **Async context detected**: Cached forever (can't transition from async to sync)
67
+ - ⚠️ **Sync context**: Always rechecked (can transition from sync to async)
68
+
69
+ This ensures correct behavior while optimizing for the most common case (async contexts in web frameworks).
70
+
71
+ ## Use Cases
72
+
73
+ ### 1. CLI + HTTP API
74
+
75
+ ```python
76
+ from smartasync import smartasync
77
+ from smpub import PublishedClass, ApiSwitcher
78
+
79
+ class DataHandler(PublishedClass):
80
+ api = ApiSwitcher()
81
+
82
+ @api
83
+ @smartasync
84
+ async def process_data(self, input_file: str):
85
+ """Process data file."""
86
+ async with aiofiles.open(input_file) as f:
87
+ data = await f.read()
88
+ return process(data)
89
+
90
+ # CLI usage (sync)
91
+ handler = DataHandler()
92
+ result = handler.process_data("data.csv")
93
+
94
+ # HTTP usage (async via FastAPI)
95
+ # Automatically works without modification!
96
+ ```
97
+
98
+ ### 2. Testing
99
+
100
+ ```python
101
+ @smartasync
102
+ async def database_query(query: str):
103
+ async with database.connect() as conn:
104
+ return await conn.execute(query)
105
+
106
+ # Sync tests
107
+ def test_query():
108
+ result = database_query("SELECT * FROM users")
109
+ assert len(result) > 0
110
+
111
+ # Async tests
112
+ async def test_query_async():
113
+ result = await database_query("SELECT * FROM users")
114
+ assert len(result) > 0
115
+ ```
116
+
117
+ ### 3. Mixed Codebases
118
+
119
+ Perfect for gradually migrating sync code to async without breaking existing callers.
120
+
121
+ ## Performance
122
+
123
+ - **Decoration time**: ~3-4 microseconds (one-time cost)
124
+ - **Sync context**: ~102 microseconds (dominated by `asyncio.run()` overhead)
125
+ - **Async context (first call)**: ~2.3 microseconds
126
+ - **Async context (cached)**: ~1.3 microseconds
127
+
128
+ For typical CLI tools and web APIs, this overhead is negligible compared to network latency (10-200ms).
129
+
130
+ ## Advanced Usage
131
+
132
+ ### With `__slots__`
133
+
134
+ SmartAsync works seamlessly with `__slots__` classes:
135
+
136
+ ```python
137
+ from smartasync import smartasync
138
+
139
+ class OptimizedManager:
140
+ __slots__ = ('data',)
141
+
142
+ def __init__(self):
143
+ self.data = []
144
+
145
+ @smartasync
146
+ async def add_item(self, item):
147
+ await asyncio.sleep(0.01) # Simulate I/O
148
+ self.data.append(item)
149
+ ```
150
+
151
+ ### Cache Reset for Testing
152
+
153
+ ```python
154
+ @smartasync
155
+ async def my_method():
156
+ pass
157
+
158
+ # Reset cache between tests
159
+ my_method._smartasync_reset_cache()
160
+ ```
161
+
162
+ ## Limitations
163
+
164
+ - ⚠️ **Cannot transition from async to sync**: Once in async context, cannot move back to sync (this is correct behavior)
165
+ - ⚠️ **Sync overhead**: Always rechecks context in sync mode (~2 microseconds per call)
166
+
167
+ ## Thread Safety
168
+
169
+ SmartAsync is **safe for all common use cases**:
170
+
171
+ ✅ **Safe scenarios** (covers 99% of real-world usage):
172
+ - Single-threaded applications (CLI tools, scripts)
173
+ - Async event loops (inherently single-threaded)
174
+ - Web servers with request isolation (new instance per request)
175
+ - Thread pools with instance-per-thread pattern
176
+
177
+ ⚠️ **Theoretical concern** (anti-pattern, not recommended):
178
+ - Sharing a single instance across multiple threads in a thread pool
179
+
180
+ **Why this isn't a real issue:**
181
+ The anti-pattern scenario defeats SmartAsync's purpose. If you're using thread pools with shared instances, you should use async workers instead for better performance and natural concurrency.
182
+
183
+ **Recommendation:** Create instances per thread/request, or better yet, use async patterns natively.
184
+
185
+ ## Related Projects
186
+
187
+ SmartAsync is part of the **Genro-Libs toolkit**:
188
+
189
+ - [smartswitch](https://github.com/genropy/smartswitch) - Rule-based function dispatch
190
+ - [smpub](https://github.com/genropy/smpub) - CLI/API framework (uses SmartAsync for async handlers)
191
+ - [gtext](https://github.com/genropy/gtext) - Text transformation and templates
192
+
193
+ ## Contributing
194
+
195
+ Contributions welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
196
+
197
+ ## License
198
+
199
+ MIT License - see [LICENSE](LICENSE) file for details.
200
+
201
+ ## Credits
202
+
203
+ **Author**: Giovanni Porcari (Genropy Team)
204
+ **Part of**: [Genro-Libs](https://github.com/softwell/genro-libs) developer toolkit
@@ -0,0 +1,93 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "smartasync"
7
+ version = "0.2.0"
8
+ description = "Unified sync/async API decorator with automatic context detection"
9
+ authors = [
10
+ {name = "Giovanni Porcari", email = "softwell@softwell.it"},
11
+ ]
12
+ readme = "README.md"
13
+ license = {text = "MIT"}
14
+ requires-python = ">=3.10"
15
+ classifiers = [
16
+ "Development Status :: 4 - Beta",
17
+ "Intended Audience :: Developers",
18
+ "Programming Language :: Python :: 3",
19
+ "Programming Language :: Python :: 3.10",
20
+ "Programming Language :: Python :: 3.11",
21
+ "Programming Language :: Python :: 3.12",
22
+ "Topic :: Software Development :: Libraries :: Python Modules",
23
+ "Framework :: AsyncIO",
24
+ "Typing :: Typed",
25
+ ]
26
+ keywords = ["async", "sync", "decorator", "asyncio", "context-detection", "unified-api"]
27
+
28
+ [project.optional-dependencies]
29
+ dev = [
30
+ "pytest>=7.0.0",
31
+ "pytest-asyncio>=0.21.0",
32
+ "pytest-cov>=4.0.0",
33
+ "black>=23.0.0",
34
+ "ruff>=0.1.0",
35
+ "mypy>=1.0.0",
36
+ ]
37
+ docs = [
38
+ "sphinx>=8.0.0",
39
+ "sphinx-rtd-theme>=3.0.0",
40
+ "sphinx-autodoc-typehints>=3.0.0",
41
+ "myst-parser>=4.0.0",
42
+ "sphinxcontrib-mermaid>=1.0.0",
43
+ ]
44
+ all = [
45
+ "pytest>=7.0.0",
46
+ "pytest-asyncio>=0.21.0",
47
+ "pytest-cov>=4.0.0",
48
+ "black>=23.0.0",
49
+ "ruff>=0.1.0",
50
+ "mypy>=1.0.0",
51
+ "sphinx>=8.0.0",
52
+ "sphinx-rtd-theme>=3.0.0",
53
+ "sphinx-autodoc-typehints>=3.0.0",
54
+ "myst-parser>=4.0.0",
55
+ "sphinxcontrib-mermaid>=1.0.0",
56
+ ]
57
+
58
+ [project.urls]
59
+ Homepage = "https://github.com/genropy/smartasync"
60
+ Documentation = "https://smartasync.readthedocs.io"
61
+ Repository = "https://github.com/genropy/smartasync"
62
+ "Bug Tracker" = "https://github.com/genropy/smartasync/issues"
63
+
64
+ [tool.setuptools.packages.find]
65
+ where = ["src"]
66
+ include = ["smartasync*"]
67
+
68
+ [tool.pytest.ini_options]
69
+ testpaths = ["tests"]
70
+ python_files = ["test_*.py"]
71
+ python_classes = ["Test*"]
72
+ python_functions = ["test_*"]
73
+ addopts = "-v --cov=smartasync --cov-report=term-missing --cov-report=html --cov-report=xml"
74
+ asyncio_mode = "auto"
75
+
76
+ [tool.black]
77
+ line-length = 100
78
+ target-version = ['py310', 'py311', 'py312']
79
+
80
+ [tool.ruff]
81
+ line-length = 100
82
+ target-version = "py310"
83
+ src = ["src"]
84
+
85
+ [tool.ruff.lint]
86
+ select = ["E", "F", "W", "I", "N"]
87
+
88
+ [tool.mypy]
89
+ python_version = "3.10"
90
+ warn_return_any = true
91
+ warn_unused_configs = true
92
+ disallow_untyped_defs = false
93
+ files = ["src/smartasync"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,9 @@
1
+ """SmartAsync - Unified sync/async API decorator.
2
+
3
+ Provides transparent sync/async method calling with automatic context detection.
4
+ """
5
+
6
+ from .core import smartasync
7
+
8
+ __version__ = "0.1.0"
9
+ __all__ = ["smartasync"]