stubpy 0.1.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.
stubpy-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Josue N Rivera
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.
stubpy-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,274 @@
1
+ Metadata-Version: 2.4
2
+ Name: stubpy
3
+ Version: 0.1.0
4
+ Summary: Generate .pyi stub files with full **kwargs / *args MRO backtracing
5
+ Author-email: Josue N Rivera <josue.n.rivera@outlook.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/wzjoriv/stubpy
8
+ Project-URL: Repository, https://github.com/wzjoriv/stubpy
9
+ Project-URL: Documentation, https://wzjoriv.github.io/stubpy
10
+ Project-URL: Bug Tracker, https://github.com/wzjoriv/stubpy/issues
11
+ Project-URL: Changelog, https://github.com/wzjoriv/stubpy/blob/main/docs/changelog.rst
12
+ Keywords: stubs,type hints,pyi,static analysis,mypy,pyright
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Topic :: Software Development :: Code Generators
22
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
+ Classifier: Typing :: Typed
24
+ Requires-Python: >=3.10
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Provides-Extra: dev
28
+ Requires-Dist: pytest>=7.0; extra == "dev"
29
+ Requires-Dist: pytest-cov; extra == "dev"
30
+ Provides-Extra: docs
31
+ Requires-Dist: sphinx>=7.0; extra == "docs"
32
+ Requires-Dist: furo>=2024.1.29; extra == "docs"
33
+ Requires-Dist: myst-parser>=2.0; extra == "docs"
34
+ Requires-Dist: sphinx-autobuild; extra == "docs"
35
+ Dynamic: license-file
36
+
37
+ # stubpy
38
+
39
+ Generate `.pyi` stub files for Python modules with full `**kwargs` / `*args` MRO backtracing, type-alias preservation, and cross-file import resolution.
40
+
41
+ [![PyPI](https://img.shields.io/pypi/v/stubpy)](https://pypi.org/project/stubpy/)
42
+ [![Python](https://img.shields.io/pypi/pyversions/stubpy)](https://pypi.org/project/stubpy/)
43
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
44
+
45
+ ## Features
46
+
47
+ - **`**kwargs` backtracing** — walks the entire MRO to expand `**kwargs` into concrete, named parameters at every inheritance level.
48
+ - **`cls()` detection** — `@classmethod` methods that forward `**kwargs` into `cls(...)` are resolved against `cls.__init__`, not MRO siblings.
49
+ - **Typed `*args` preserved** — explicitly annotated `*args` (e.g. `*elements: Element`) always survive the resolution chain.
50
+ - **Type-alias preservation** — `types.Length` stays `types.Length` rather than expanding to `str | float | int`.
51
+ - **Cross-file imports** — base classes and annotation types from other local modules are re-emitted in the `.pyi` header automatically.
52
+ - **Zero runtime dependencies** — stdlib only.
53
+
54
+ ---
55
+
56
+ ## Environment setup
57
+
58
+ > Requires **Python 3.10+**. The steps below use the Windows Python Launcher (`py`).
59
+ > On macOS / Linux replace `py -3.10` with `python3.11`.
60
+
61
+ ```bash
62
+ # 1. Clone the repository
63
+ git clone https://github.com/wzjoriv/stubpy.git
64
+ cd stubpy
65
+
66
+ # 2. Create a virtual environment with Python 3.11
67
+ py -3.11 -m venv .venv
68
+
69
+ # 3. Activate the environment
70
+ .venv\Scripts\activate # Windows CMD / PowerShell
71
+ # source .venv/bin/activate # macOS / Linux
72
+
73
+ # 4. Install in editable mode with development dependencies
74
+ pip install -e ".[dev]"
75
+
76
+ # 5. Verify — run the full test suite
77
+ pytest
78
+ ```
79
+
80
+ #
81
+ ## How it works
82
+
83
+ stubpy is a pipeline of six focused stages, each in its own module:
84
+
85
+ ```
86
+ generate_stub(filepath)
87
+
88
+ ├─ 1. loader load_module() load source as a live module
89
+ ├─ 2. imports scan_import_statements() parse AST → {name: import_stmt}
90
+ ├─ 3. aliases build_alias_registry() discover type-alias sub-modules
91
+ ├─ 4. generator collect_classes() gather classes in source order
92
+ │ └─ for each class:
93
+ │ emitter generate_class_stub()
94
+ │ └─ for each method:
95
+ │ resolver resolve_params() ← MRO backtracing
96
+ │ emitter generate_method_stub()
97
+ └─ 5. generator assemble header + body → write .pyi
98
+ ```
99
+
100
+ **`resolve_params` uses three strategies in order:**
101
+
102
+ 1. **No variadics** — if the method has neither `*args` nor `**kwargs`, return its own parameters unchanged.
103
+ 2. **`cls()` detection** — if a `@classmethod` body contains `cls(..., **kwargs)`, the `**kwargs` is resolved against `cls.__init__` via AST analysis. Parameters hardcoded in the call are excluded.
104
+ 3. **MRO walk** — walk ancestor classes that define the same method, collecting concrete parameters until all variadics are fully resolved.
105
+
106
+ **`StubContext`** carries all mutable state for one run (alias registry, used imports). A fresh instance is created per `generate_stub()` call, making the generator fully re-entrant.
107
+
108
+ ---
109
+ ## Documentation (optional)
110
+
111
+ ```bash
112
+ # Install documentation dependencies
113
+ pip install -e ".[docs]"
114
+
115
+ # Build the HTML site
116
+ cd docs && make html
117
+ # → open docs/_build/html/index.html in a browser
118
+
119
+ # Live-reloading dev server (auto-rebuilds on file changes)
120
+ make livehtml
121
+ ```
122
+
123
+ ---
124
+
125
+ ## Installation (end users)
126
+
127
+ ```bash
128
+ pip install stubpy
129
+ # or
130
+ uv add stubpy
131
+ ```
132
+
133
+ ---
134
+
135
+ ## Usage
136
+
137
+ ### CLI
138
+
139
+ ```bash
140
+ stubpy path/to/module.py # writes module.pyi alongside source
141
+ stubpy path/to/module.py -o out/module.pyi # custom output path
142
+ stubpy path/to/module.py --print # also print to stdout
143
+ ```
144
+
145
+ ### Python API
146
+
147
+ ```python
148
+ from stubpy import generate_stub
149
+
150
+ content = generate_stub("path/to/module.py")
151
+ content = generate_stub("path/to/module.py", "out/module.pyi")
152
+ ```
153
+
154
+ ---
155
+
156
+ ## Example
157
+
158
+ ```python
159
+ # shapes.py
160
+ class Shape:
161
+ def __init__(self, color: str = "black", opacity: float = 1.0) -> None: ...
162
+
163
+ class Circle(Shape):
164
+ def __init__(self, radius: float, **kwargs) -> None:
165
+ super().__init__(**kwargs)
166
+
167
+ @classmethod
168
+ def unit(cls, **kwargs) -> "Circle":
169
+ return cls(radius=1.0, **kwargs)
170
+ ```
171
+
172
+ ```bash
173
+ stubpy shapes.py --print
174
+ ```
175
+
176
+ ```python
177
+ # shapes.pyi (generated)
178
+ from __future__ import annotations
179
+
180
+ class Shape:
181
+ def __init__(self, color: str = 'black', opacity: float = 1.0) -> None: ...
182
+
183
+ class Circle(Shape):
184
+ def __init__(
185
+ self,
186
+ radius: float,
187
+ color: str = 'black',
188
+ opacity: float = 1.0,
189
+ ) -> None: ...
190
+ @classmethod
191
+ def unit(cls, color: str = 'black', opacity: float = 1.0) -> Circle: ...
192
+ ```
193
+
194
+ `**kwargs` in `Circle.__init__` resolves to `color` and `opacity` from `Shape.__init__`. `Circle.unit` detects `cls(radius=1.0, **kwargs)` via AST — `radius` is hardcoded so it's excluded; the remaining `Shape` params appear.
195
+
196
+ ---
197
+
198
+
199
+ ## How it works
200
+
201
+ stubpy is a pipeline of six focused stages, each in its own module:
202
+
203
+ ```
204
+ generate_stub(filepath)
205
+
206
+ ├─ 1. loader load_module() load source as a live module
207
+ ├─ 2. imports scan_import_statements() parse AST → {name: import_stmt}
208
+ ├─ 3. aliases build_alias_registry() discover type-alias sub-modules
209
+ ├─ 4. generator collect_classes() gather classes in source order
210
+ │ └─ for each class:
211
+ │ emitter generate_class_stub()
212
+ │ └─ for each method:
213
+ │ resolver resolve_params() ← MRO backtracing
214
+ │ emitter generate_method_stub()
215
+ └─ 5. generator assemble header + body → write .pyi
216
+ ```
217
+
218
+ **`resolve_params` uses three strategies in order:**
219
+
220
+ 1. **No variadics** — if the method has neither `*args` nor `**kwargs`, return its own parameters unchanged.
221
+ 2. **`cls()` detection** — if a `@classmethod` body contains `cls(..., **kwargs)`, the `**kwargs` is resolved against `cls.__init__` via AST analysis. Parameters hardcoded in the call are excluded.
222
+ 3. **MRO walk** — walk ancestor classes that define the same method, collecting concrete parameters until all variadics are fully resolved.
223
+
224
+ **`StubContext`** carries all mutable state for one run (alias registry, used imports). A fresh instance is created per `generate_stub()` call, making the generator fully re-entrant.
225
+
226
+ ---
227
+ ## Documentation
228
+
229
+ Full documentation at **[wzjoriv.github.io/stubpy](https://wzjoriv.github.io/stubpy)** including:
230
+
231
+ - [Getting Started](https://wzjoriv.github.io/stubpy/guides/quickstart.html)
232
+ - [How It Works](https://wzjoriv.github.io/stubpy/guides/how_it_works.html)
233
+ - [API Reference](https://wzjoriv.github.io/stubpy/api/index.html)
234
+
235
+ ---
236
+
237
+ ## Project layout
238
+
239
+ ```
240
+ stubpy/
241
+ ├── stubpy/ ← package (stdlib only, no runtime deps)
242
+ │ ├── context.py StubContext, AliasEntry
243
+ │ ├── loader.py load_module
244
+ │ ├── aliases.py build_alias_registry
245
+ │ ├── imports.py scan / collect imports
246
+ │ ├── annotations.py dispatch-table annotation_to_str
247
+ │ ├── resolver.py resolve_params (3 strategies)
248
+ │ ├── emitter.py generate_class / method stub
249
+ │ └── generator.py generate_stub orchestrator
250
+ ├── demo/ demo package used for integration tests
251
+ ├── tests/ pytest suite (~162 tests)
252
+ ├── docs/ Sphinx + Furo documentation
253
+ ├── LICENSE
254
+ └── pyproject.toml
255
+ ```
256
+
257
+ ---
258
+
259
+ ## Contributing
260
+
261
+ ```bash
262
+ git clone https://github.com/wzjoriv/stubpy.git
263
+ cd stubpy
264
+ py -3.11 -m venv .venv
265
+ .venv\Scripts\activate
266
+ pip install -e ".[dev]"
267
+ pytest
268
+ ```
269
+
270
+ ---
271
+
272
+ ## License
273
+
274
+ [MIT](LICENSE) © 2024 [Josue N Rivera](https://github.com/wzjoriv)
stubpy-0.1.0/README.md ADDED
@@ -0,0 +1,238 @@
1
+ # stubpy
2
+
3
+ Generate `.pyi` stub files for Python modules with full `**kwargs` / `*args` MRO backtracing, type-alias preservation, and cross-file import resolution.
4
+
5
+ [![PyPI](https://img.shields.io/pypi/v/stubpy)](https://pypi.org/project/stubpy/)
6
+ [![Python](https://img.shields.io/pypi/pyversions/stubpy)](https://pypi.org/project/stubpy/)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
8
+
9
+ ## Features
10
+
11
+ - **`**kwargs` backtracing** — walks the entire MRO to expand `**kwargs` into concrete, named parameters at every inheritance level.
12
+ - **`cls()` detection** — `@classmethod` methods that forward `**kwargs` into `cls(...)` are resolved against `cls.__init__`, not MRO siblings.
13
+ - **Typed `*args` preserved** — explicitly annotated `*args` (e.g. `*elements: Element`) always survive the resolution chain.
14
+ - **Type-alias preservation** — `types.Length` stays `types.Length` rather than expanding to `str | float | int`.
15
+ - **Cross-file imports** — base classes and annotation types from other local modules are re-emitted in the `.pyi` header automatically.
16
+ - **Zero runtime dependencies** — stdlib only.
17
+
18
+ ---
19
+
20
+ ## Environment setup
21
+
22
+ > Requires **Python 3.10+**. The steps below use the Windows Python Launcher (`py`).
23
+ > On macOS / Linux replace `py -3.10` with `python3.11`.
24
+
25
+ ```bash
26
+ # 1. Clone the repository
27
+ git clone https://github.com/wzjoriv/stubpy.git
28
+ cd stubpy
29
+
30
+ # 2. Create a virtual environment with Python 3.11
31
+ py -3.11 -m venv .venv
32
+
33
+ # 3. Activate the environment
34
+ .venv\Scripts\activate # Windows CMD / PowerShell
35
+ # source .venv/bin/activate # macOS / Linux
36
+
37
+ # 4. Install in editable mode with development dependencies
38
+ pip install -e ".[dev]"
39
+
40
+ # 5. Verify — run the full test suite
41
+ pytest
42
+ ```
43
+
44
+ #
45
+ ## How it works
46
+
47
+ stubpy is a pipeline of six focused stages, each in its own module:
48
+
49
+ ```
50
+ generate_stub(filepath)
51
+
52
+ ├─ 1. loader load_module() load source as a live module
53
+ ├─ 2. imports scan_import_statements() parse AST → {name: import_stmt}
54
+ ├─ 3. aliases build_alias_registry() discover type-alias sub-modules
55
+ ├─ 4. generator collect_classes() gather classes in source order
56
+ │ └─ for each class:
57
+ │ emitter generate_class_stub()
58
+ │ └─ for each method:
59
+ │ resolver resolve_params() ← MRO backtracing
60
+ │ emitter generate_method_stub()
61
+ └─ 5. generator assemble header + body → write .pyi
62
+ ```
63
+
64
+ **`resolve_params` uses three strategies in order:**
65
+
66
+ 1. **No variadics** — if the method has neither `*args` nor `**kwargs`, return its own parameters unchanged.
67
+ 2. **`cls()` detection** — if a `@classmethod` body contains `cls(..., **kwargs)`, the `**kwargs` is resolved against `cls.__init__` via AST analysis. Parameters hardcoded in the call are excluded.
68
+ 3. **MRO walk** — walk ancestor classes that define the same method, collecting concrete parameters until all variadics are fully resolved.
69
+
70
+ **`StubContext`** carries all mutable state for one run (alias registry, used imports). A fresh instance is created per `generate_stub()` call, making the generator fully re-entrant.
71
+
72
+ ---
73
+ ## Documentation (optional)
74
+
75
+ ```bash
76
+ # Install documentation dependencies
77
+ pip install -e ".[docs]"
78
+
79
+ # Build the HTML site
80
+ cd docs && make html
81
+ # → open docs/_build/html/index.html in a browser
82
+
83
+ # Live-reloading dev server (auto-rebuilds on file changes)
84
+ make livehtml
85
+ ```
86
+
87
+ ---
88
+
89
+ ## Installation (end users)
90
+
91
+ ```bash
92
+ pip install stubpy
93
+ # or
94
+ uv add stubpy
95
+ ```
96
+
97
+ ---
98
+
99
+ ## Usage
100
+
101
+ ### CLI
102
+
103
+ ```bash
104
+ stubpy path/to/module.py # writes module.pyi alongside source
105
+ stubpy path/to/module.py -o out/module.pyi # custom output path
106
+ stubpy path/to/module.py --print # also print to stdout
107
+ ```
108
+
109
+ ### Python API
110
+
111
+ ```python
112
+ from stubpy import generate_stub
113
+
114
+ content = generate_stub("path/to/module.py")
115
+ content = generate_stub("path/to/module.py", "out/module.pyi")
116
+ ```
117
+
118
+ ---
119
+
120
+ ## Example
121
+
122
+ ```python
123
+ # shapes.py
124
+ class Shape:
125
+ def __init__(self, color: str = "black", opacity: float = 1.0) -> None: ...
126
+
127
+ class Circle(Shape):
128
+ def __init__(self, radius: float, **kwargs) -> None:
129
+ super().__init__(**kwargs)
130
+
131
+ @classmethod
132
+ def unit(cls, **kwargs) -> "Circle":
133
+ return cls(radius=1.0, **kwargs)
134
+ ```
135
+
136
+ ```bash
137
+ stubpy shapes.py --print
138
+ ```
139
+
140
+ ```python
141
+ # shapes.pyi (generated)
142
+ from __future__ import annotations
143
+
144
+ class Shape:
145
+ def __init__(self, color: str = 'black', opacity: float = 1.0) -> None: ...
146
+
147
+ class Circle(Shape):
148
+ def __init__(
149
+ self,
150
+ radius: float,
151
+ color: str = 'black',
152
+ opacity: float = 1.0,
153
+ ) -> None: ...
154
+ @classmethod
155
+ def unit(cls, color: str = 'black', opacity: float = 1.0) -> Circle: ...
156
+ ```
157
+
158
+ `**kwargs` in `Circle.__init__` resolves to `color` and `opacity` from `Shape.__init__`. `Circle.unit` detects `cls(radius=1.0, **kwargs)` via AST — `radius` is hardcoded so it's excluded; the remaining `Shape` params appear.
159
+
160
+ ---
161
+
162
+
163
+ ## How it works
164
+
165
+ stubpy is a pipeline of six focused stages, each in its own module:
166
+
167
+ ```
168
+ generate_stub(filepath)
169
+
170
+ ├─ 1. loader load_module() load source as a live module
171
+ ├─ 2. imports scan_import_statements() parse AST → {name: import_stmt}
172
+ ├─ 3. aliases build_alias_registry() discover type-alias sub-modules
173
+ ├─ 4. generator collect_classes() gather classes in source order
174
+ │ └─ for each class:
175
+ │ emitter generate_class_stub()
176
+ │ └─ for each method:
177
+ │ resolver resolve_params() ← MRO backtracing
178
+ │ emitter generate_method_stub()
179
+ └─ 5. generator assemble header + body → write .pyi
180
+ ```
181
+
182
+ **`resolve_params` uses three strategies in order:**
183
+
184
+ 1. **No variadics** — if the method has neither `*args` nor `**kwargs`, return its own parameters unchanged.
185
+ 2. **`cls()` detection** — if a `@classmethod` body contains `cls(..., **kwargs)`, the `**kwargs` is resolved against `cls.__init__` via AST analysis. Parameters hardcoded in the call are excluded.
186
+ 3. **MRO walk** — walk ancestor classes that define the same method, collecting concrete parameters until all variadics are fully resolved.
187
+
188
+ **`StubContext`** carries all mutable state for one run (alias registry, used imports). A fresh instance is created per `generate_stub()` call, making the generator fully re-entrant.
189
+
190
+ ---
191
+ ## Documentation
192
+
193
+ Full documentation at **[wzjoriv.github.io/stubpy](https://wzjoriv.github.io/stubpy)** including:
194
+
195
+ - [Getting Started](https://wzjoriv.github.io/stubpy/guides/quickstart.html)
196
+ - [How It Works](https://wzjoriv.github.io/stubpy/guides/how_it_works.html)
197
+ - [API Reference](https://wzjoriv.github.io/stubpy/api/index.html)
198
+
199
+ ---
200
+
201
+ ## Project layout
202
+
203
+ ```
204
+ stubpy/
205
+ ├── stubpy/ ← package (stdlib only, no runtime deps)
206
+ │ ├── context.py StubContext, AliasEntry
207
+ │ ├── loader.py load_module
208
+ │ ├── aliases.py build_alias_registry
209
+ │ ├── imports.py scan / collect imports
210
+ │ ├── annotations.py dispatch-table annotation_to_str
211
+ │ ├── resolver.py resolve_params (3 strategies)
212
+ │ ├── emitter.py generate_class / method stub
213
+ │ └── generator.py generate_stub orchestrator
214
+ ├── demo/ demo package used for integration tests
215
+ ├── tests/ pytest suite (~162 tests)
216
+ ├── docs/ Sphinx + Furo documentation
217
+ ├── LICENSE
218
+ └── pyproject.toml
219
+ ```
220
+
221
+ ---
222
+
223
+ ## Contributing
224
+
225
+ ```bash
226
+ git clone https://github.com/wzjoriv/stubpy.git
227
+ cd stubpy
228
+ py -3.11 -m venv .venv
229
+ .venv\Scripts\activate
230
+ pip install -e ".[dev]"
231
+ pytest
232
+ ```
233
+
234
+ ---
235
+
236
+ ## License
237
+
238
+ [MIT](LICENSE) © 2024 [Josue N Rivera](https://github.com/wzjoriv)
@@ -0,0 +1,74 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "stubpy"
7
+ version = "0.1.0"
8
+ description = "Generate .pyi stub files with full **kwargs / *args MRO backtracing"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = { text = "MIT" }
12
+ authors = [
13
+ { name = "Josue N Rivera", email = "josue.n.rivera@outlook.com" },
14
+ ]
15
+ keywords = ["stubs", "type hints", "pyi", "static analysis", "mypy", "pyright"]
16
+ classifiers = [
17
+ "Development Status :: 3 - Alpha",
18
+ "Intended Audience :: Developers",
19
+ "License :: OSI Approved :: MIT License",
20
+ "Operating System :: OS Independent",
21
+ "Programming Language :: Python :: 3",
22
+ "Programming Language :: Python :: 3.10",
23
+ "Programming Language :: Python :: 3.11",
24
+ "Programming Language :: Python :: 3.12",
25
+ "Topic :: Software Development :: Code Generators",
26
+ "Topic :: Software Development :: Libraries :: Python Modules",
27
+ "Typing :: Typed",
28
+ ]
29
+ # No runtime dependencies — stdlib only.
30
+ dependencies = []
31
+
32
+ [project.urls]
33
+ Homepage = "https://github.com/wzjoriv/stubpy"
34
+ Repository = "https://github.com/wzjoriv/stubpy"
35
+ Documentation = "https://wzjoriv.github.io/stubpy"
36
+ "Bug Tracker" = "https://github.com/wzjoriv/stubpy/issues"
37
+ Changelog = "https://github.com/wzjoriv/stubpy/blob/main/docs/changelog.rst"
38
+
39
+ [project.optional-dependencies]
40
+ dev = [
41
+ "pytest>=7.0",
42
+ "pytest-cov",
43
+ ]
44
+ docs = [
45
+ "sphinx>=7.0",
46
+ "furo>=2024.1.29",
47
+ "myst-parser>=2.0",
48
+ "sphinx-autobuild",
49
+ ]
50
+
51
+ [project.scripts]
52
+ stubpy = "stubpy.__main__:main"
53
+
54
+ [tool.setuptools.packages.find]
55
+ where = ["."]
56
+ include = ["stubpy*"]
57
+
58
+ # ---------------------------------------------------------------------------
59
+ # pytest
60
+ # ---------------------------------------------------------------------------
61
+ [tool.pytest.ini_options]
62
+ testpaths = ["tests"]
63
+ addopts = "-v --tb=short"
64
+
65
+ # ---------------------------------------------------------------------------
66
+ # coverage
67
+ # ---------------------------------------------------------------------------
68
+ [tool.coverage.run]
69
+ source = ["stubpy"]
70
+ omit = ["tests/*", "demo/*"]
71
+
72
+ [tool.coverage.report]
73
+ show_missing = true
74
+ skip_covered = false
stubpy-0.1.0/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,38 @@
1
+ """
2
+ stubpy
3
+ ======
4
+
5
+ Generate ``.pyi`` stub files for Python modules with full ``**kwargs``
6
+ and ``*args`` MRO backtracing.
7
+
8
+ Quickstart::
9
+
10
+ from stubpy import generate_stub
11
+
12
+ # Write stub alongside the source and return its content
13
+ content = generate_stub("path/to/module.py")
14
+
15
+ # Write to a custom path
16
+ content = generate_stub("path/to/module.py", "out/module.pyi")
17
+
18
+ CLI::
19
+
20
+ stubpy path/to/module.py
21
+ stubpy path/to/module.py -o out/module.pyi --print
22
+
23
+ Public API
24
+ ----------
25
+
26
+ .. currentmodule:: stubpy
27
+
28
+ .. autosummary::
29
+
30
+ generate_stub
31
+ StubContext
32
+ AliasEntry
33
+ """
34
+ from .context import AliasEntry, StubContext
35
+ from .generator import generate_stub
36
+
37
+ __all__ = ["generate_stub", "StubContext", "AliasEntry"]
38
+ __version__ = "0.1.0"