quartopydoc 0.12.0__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.
- quartodoc/__init__.py +30 -0
- quartodoc/__main__.py +283 -0
- quartodoc/_griffe_compat/__init__.py +11 -0
- quartodoc/_griffe_compat/_generate_stubs.py +71 -0
- quartodoc/_griffe_compat/dataclasses.py +35 -0
- quartodoc/_griffe_compat/docstrings.py +38 -0
- quartodoc/_griffe_compat/expressions.py +48 -0
- quartodoc/_pydantic_compat.py +18 -0
- quartodoc/ast.py +391 -0
- quartodoc/autosummary.py +911 -0
- quartodoc/builder/__init__.py +0 -0
- quartodoc/builder/_node.py +17 -0
- quartodoc/builder/blueprint.py +589 -0
- quartodoc/builder/collect.py +86 -0
- quartodoc/builder/utils.py +120 -0
- quartodoc/builder/write.py +17 -0
- quartodoc/interlinks.py +431 -0
- quartodoc/inventory.py +174 -0
- quartodoc/layout.py +522 -0
- quartodoc/pandoc/__init__.py +7 -0
- quartodoc/pandoc/blocks.py +421 -0
- quartodoc/pandoc/components.py +76 -0
- quartodoc/pandoc/inlines.py +261 -0
- quartodoc/parsers.py +8 -0
- quartodoc/py.typed +0 -0
- quartodoc/qpyd/README.md +78 -0
- quartodoc/qpyd/__init__.py +16 -0
- quartodoc/qpyd/__main__.py +6 -0
- quartodoc/qpyd/clean.py +91 -0
- quartodoc/qpyd/cli.py +89 -0
- quartodoc/qpyd/config.py +206 -0
- quartodoc/qpyd/convert.py +273 -0
- quartodoc/qpyd/execute.py +274 -0
- quartodoc/qpyd/nb.py +93 -0
- quartodoc/qpyd/prerender.py +141 -0
- quartodoc/qpyd/quarto_utils.py +351 -0
- quartodoc/qpyd/render.py +85 -0
- quartodoc/qpyd/scaffold.py +133 -0
- quartodoc/qpyd/tests/__init__.py +0 -0
- quartodoc/qpyd/tests/conftest.py +15 -0
- quartodoc/qpyd/tests/data/nb_fail.qmd +9 -0
- quartodoc/qpyd/tests/data/nb_ok.qmd +11 -0
- quartodoc/qpyd/tests/data/prose.qmd +5 -0
- quartodoc/qpyd/tests/test_cli.py +78 -0
- quartodoc/qpyd/tests/test_config.py +39 -0
- quartodoc/qpyd/tests/test_convert.py +69 -0
- quartodoc/qpyd/tests/test_execute.py +47 -0
- quartodoc/qpyd/tests/test_safety.py +163 -0
- quartodoc/qpyd/tests/test_variables.py +34 -0
- quartodoc/qpyd/variables.py +90 -0
- quartodoc/renderers/__init__.py +4 -0
- quartodoc/renderers/base.py +119 -0
- quartodoc/renderers/md_renderer.py +966 -0
- quartodoc/static/styles.css +15 -0
- quartodoc/tests/__init__.py +0 -0
- quartodoc/tests/__snapshots__/test_builder.ambr +47 -0
- quartodoc/tests/__snapshots__/test_renderers.ambr +1306 -0
- quartodoc/tests/__snapshots__/test_validation.ambr +39 -0
- quartodoc/tests/example.py +26 -0
- quartodoc/tests/example_alias_target.py +13 -0
- quartodoc/tests/example_alias_target__nested.py +21 -0
- quartodoc/tests/example_attribute.py +7 -0
- quartodoc/tests/example_class.py +63 -0
- quartodoc/tests/example_docstring_full.py +68 -0
- quartodoc/tests/example_docstring_styles.py +81 -0
- quartodoc/tests/example_dynamic.py +51 -0
- quartodoc/tests/example_interlinks/.gitignore +2 -0
- quartodoc/tests/example_interlinks/README.md +3 -0
- quartodoc/tests/example_interlinks/_inv/other_objects.json +1 -0
- quartodoc/tests/example_interlinks/_quarto.yml +10 -0
- quartodoc/tests/example_interlinks/interlinks.lua +411 -0
- quartodoc/tests/example_interlinks/objects.json +1 -0
- quartodoc/tests/example_interlinks/spec.yml +107 -0
- quartodoc/tests/example_interlinks/test.md +176 -0
- quartodoc/tests/example_interlinks/test.qmd +266 -0
- quartodoc/tests/example_signature.py +44 -0
- quartodoc/tests/example_star_imports.py +1 -0
- quartodoc/tests/example_stubs.py +2 -0
- quartodoc/tests/example_stubs.pyi +2 -0
- quartodoc/tests/pandoc/test_blocks.py +430 -0
- quartodoc/tests/pandoc/test_inlines.py +121 -0
- quartodoc/tests/test_ast.py +110 -0
- quartodoc/tests/test_basic.py +225 -0
- quartodoc/tests/test_builder.py +227 -0
- quartodoc/tests/test_builder_blueprint.py +435 -0
- quartodoc/tests/test_cli.py +29 -0
- quartodoc/tests/test_interlinks.py +117 -0
- quartodoc/tests/test_layout.py +59 -0
- quartodoc/tests/test_qpyd.py +20 -0
- quartodoc/tests/test_renderers.py +500 -0
- quartodoc/tests/test_validation.py +57 -0
- quartodoc/validation.py +88 -0
- quartopydoc-0.12.0.dist-info/METADATA +215 -0
- quartopydoc-0.12.0.dist-info/RECORD +98 -0
- quartopydoc-0.12.0.dist-info/WHEEL +5 -0
- quartopydoc-0.12.0.dist-info/entry_points.txt +4 -0
- quartopydoc-0.12.0.dist-info/licenses/LICENSE +21 -0
- quartopydoc-0.12.0.dist-info/top_level.txt +1 -0
quartodoc/__init__.py
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""
|
|
2
|
+
quartopydoc is a package for building delightful python API documentation.
|
|
3
|
+
|
|
4
|
+
It is a fork of quartodoc by Michael Chow, with formatting customizations and
|
|
5
|
+
extra utilities for working with notebooks.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
# flake8: noqa
|
|
9
|
+
|
|
10
|
+
from .autosummary import get_function, get_object, Builder
|
|
11
|
+
from .renderers import MdRenderer
|
|
12
|
+
from .inventory import convert_inventory, create_inventory
|
|
13
|
+
from .ast import preview
|
|
14
|
+
from .builder.blueprint import blueprint
|
|
15
|
+
from .builder.collect import collect
|
|
16
|
+
from .layout import Auto
|
|
17
|
+
|
|
18
|
+
__all__ = (
|
|
19
|
+
"Auto",
|
|
20
|
+
"blueprint",
|
|
21
|
+
"collect",
|
|
22
|
+
"convert_inventory",
|
|
23
|
+
"create_inventory",
|
|
24
|
+
"get_object",
|
|
25
|
+
"preview",
|
|
26
|
+
"Builder",
|
|
27
|
+
"BuilderPkgdown",
|
|
28
|
+
"BuilderSinglePage",
|
|
29
|
+
"MdRenderer",
|
|
30
|
+
)
|
quartodoc/__main__.py
ADDED
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import click
|
|
2
|
+
import contextlib
|
|
3
|
+
import os
|
|
4
|
+
import sys
|
|
5
|
+
import time
|
|
6
|
+
import sphobjinv as soi
|
|
7
|
+
import yaml
|
|
8
|
+
import importlib
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from watchdog.observers import Observer
|
|
11
|
+
from functools import partial
|
|
12
|
+
from watchdog.events import PatternMatchingEventHandler
|
|
13
|
+
from quartodoc import Builder, convert_inventory
|
|
14
|
+
from ._pydantic_compat import BaseModel
|
|
15
|
+
from .interlinks import inventory_from_url
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def get_package_path(package_name):
|
|
19
|
+
"""
|
|
20
|
+
Get the path to a package installed in the current environment.
|
|
21
|
+
"""
|
|
22
|
+
try:
|
|
23
|
+
lib = importlib.import_module(package_name)
|
|
24
|
+
return lib.__path__[0]
|
|
25
|
+
except ModuleNotFoundError:
|
|
26
|
+
raise ModuleNotFoundError(
|
|
27
|
+
f"Package {package_name} not found. Please install it in your environment."
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class FileInfo(BaseModel):
|
|
32
|
+
size: int
|
|
33
|
+
mtime: float
|
|
34
|
+
name: str = ""
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class QuartoDocFileChangeHandler(PatternMatchingEventHandler):
|
|
38
|
+
"""
|
|
39
|
+
A handler for file changes.
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
# Ignore patterns for the file watcher that are not relevant to the docs
|
|
43
|
+
py_ignore_patterns = [
|
|
44
|
+
"*/__pycache__/*", # These are the compiled python code files which are automatically generated by Python
|
|
45
|
+
"*/.ipynb_checkpoints/*", # This directory is created by Jupyter Notebook for auto-saving notebooks
|
|
46
|
+
"*/.vscode/*", # If you're using Visual Studio Code, it creates this directory to store settings specific to that project.
|
|
47
|
+
"*/.idea/*", # Similar to .vscode/, but for JetBrains IDEs like PyCharm.
|
|
48
|
+
"*/.git/*", # i This directory is created by Git. It's not relevant to the docs.
|
|
49
|
+
"*/venv/*",
|
|
50
|
+
"*/env/*",
|
|
51
|
+
"*/.env/*", # Common names for directories containing a Python virtual environment.
|
|
52
|
+
"*/.pytest_cache/*", # This directory is created when you run Pytest.
|
|
53
|
+
"*/.eggs/*",
|
|
54
|
+
"*/dist/*",
|
|
55
|
+
"*/build/*",
|
|
56
|
+
"*/*.egg-info/*", # These are typically created when building Python packages with setuptools.
|
|
57
|
+
"*.pyo", # These are optimized .pyc files, created when Python is run with the -O flag.
|
|
58
|
+
"*.pyd", # This is the equivalent of a .pyc file, but for C extensions on Windows.
|
|
59
|
+
"*/.mypy_cache/*", # This directory is created when you run mypy.
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
def __init__(self, callback):
|
|
63
|
+
super().__init__(
|
|
64
|
+
ignore_patterns=self.py_ignore_patterns, ignore_directories=True
|
|
65
|
+
)
|
|
66
|
+
self.callback = callback
|
|
67
|
+
self.old_file_info = FileInfo(size=-1, mtime=-1, name="")
|
|
68
|
+
|
|
69
|
+
def get_file_info(self, path: str) -> FileInfo:
|
|
70
|
+
"""
|
|
71
|
+
Get the file size and modification time.
|
|
72
|
+
"""
|
|
73
|
+
return FileInfo(
|
|
74
|
+
size=os.stat(path).st_size, mtime=os.stat(path).st_mtime, name=path
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
def is_diff(self, old: FileInfo, new: FileInfo) -> bool:
|
|
78
|
+
"""
|
|
79
|
+
Check if a file has changed. Prevents duplicate events from being triggered.
|
|
80
|
+
"""
|
|
81
|
+
same_nm = old.name == new.name
|
|
82
|
+
diff_sz = old.size != new.size
|
|
83
|
+
diff_tm = new.mtime - old.mtime # wait 1/4 second before triggering
|
|
84
|
+
|
|
85
|
+
if (
|
|
86
|
+
diff_tm < 0.25
|
|
87
|
+
): # if consequetive events are less than 1/4th of a second apart, ignore
|
|
88
|
+
return False
|
|
89
|
+
elif same_nm:
|
|
90
|
+
if diff_sz or diff_tm >= 0.25:
|
|
91
|
+
return True
|
|
92
|
+
else:
|
|
93
|
+
return False
|
|
94
|
+
else:
|
|
95
|
+
return True
|
|
96
|
+
|
|
97
|
+
def callback_if_diff(self, event):
|
|
98
|
+
"""
|
|
99
|
+
Call the callback if the file has changed.
|
|
100
|
+
"""
|
|
101
|
+
new_file_info = self.get_file_info(event.src_path)
|
|
102
|
+
if self.is_diff(self.old_file_info, new_file_info):
|
|
103
|
+
self.print_event(event)
|
|
104
|
+
self.callback()
|
|
105
|
+
self.old_file_info = new_file_info
|
|
106
|
+
|
|
107
|
+
@classmethod
|
|
108
|
+
def print_event(cls, event):
|
|
109
|
+
print(f"Rebuilding docs. Detected: {event.event_type} path : {event.src_path}")
|
|
110
|
+
|
|
111
|
+
def on_modified(self, event):
|
|
112
|
+
self.callback_if_diff(event)
|
|
113
|
+
|
|
114
|
+
def on_created(self, event):
|
|
115
|
+
self.callback_if_diff(event)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def _enable_logs():
|
|
119
|
+
import logging
|
|
120
|
+
|
|
121
|
+
root = logging.getLogger("quartodoc")
|
|
122
|
+
root.setLevel(logging.INFO)
|
|
123
|
+
|
|
124
|
+
handler = logging.StreamHandler(sys.stdout)
|
|
125
|
+
handler.setLevel(logging.DEBUG)
|
|
126
|
+
formatter = logging.Formatter(
|
|
127
|
+
"%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
|
128
|
+
)
|
|
129
|
+
handler.setFormatter(formatter)
|
|
130
|
+
root.addHandler(handler)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
@contextlib.contextmanager
|
|
134
|
+
def chdir(new_dir):
|
|
135
|
+
prev = os.getcwd()
|
|
136
|
+
os.chdir(new_dir)
|
|
137
|
+
try:
|
|
138
|
+
yield new_dir
|
|
139
|
+
finally:
|
|
140
|
+
os.chdir(prev)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
@click.group()
|
|
144
|
+
def cli():
|
|
145
|
+
pass
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
@click.command()
|
|
149
|
+
@click.option(
|
|
150
|
+
"--config",
|
|
151
|
+
default="_quarto.yml",
|
|
152
|
+
help="Change the path to the configuration file. The default is `./_quarto.yml`",
|
|
153
|
+
)
|
|
154
|
+
@click.option(
|
|
155
|
+
"--filter",
|
|
156
|
+
nargs=1,
|
|
157
|
+
default="*",
|
|
158
|
+
help="Specify the filter to select specific files. The default is '*' which selects all files.",
|
|
159
|
+
)
|
|
160
|
+
@click.option(
|
|
161
|
+
"--dry-run",
|
|
162
|
+
is_flag=True,
|
|
163
|
+
default=False,
|
|
164
|
+
help="If set, prevents new documents from being generated.",
|
|
165
|
+
)
|
|
166
|
+
@click.option(
|
|
167
|
+
"--watch",
|
|
168
|
+
is_flag=True,
|
|
169
|
+
default=False,
|
|
170
|
+
help="If set, the command will keep running and watch for changes in the package directory.",
|
|
171
|
+
)
|
|
172
|
+
@click.option("--verbose", is_flag=True, default=False, help="Enable verbose logging.")
|
|
173
|
+
def build(config, filter, dry_run, watch, verbose):
|
|
174
|
+
"""
|
|
175
|
+
Generate API docs based on the given configuration file (`./_quarto.yml` by default).
|
|
176
|
+
"""
|
|
177
|
+
|
|
178
|
+
cfg_path = Path(config).absolute()
|
|
179
|
+
if not cfg_path.exists():
|
|
180
|
+
raise FileNotFoundError(
|
|
181
|
+
f"Configuration file {cfg_path} not found. Please create one."
|
|
182
|
+
)
|
|
183
|
+
if verbose:
|
|
184
|
+
_enable_logs()
|
|
185
|
+
|
|
186
|
+
# allow users to include files like _renderer.py in their quarto docs folder
|
|
187
|
+
if config != "_quarto.yml":
|
|
188
|
+
sys.path.append(str(Path(config).parent.absolute()))
|
|
189
|
+
|
|
190
|
+
builder = Builder.from_quarto_config(config)
|
|
191
|
+
doc_build = partial(builder.build, filter=filter)
|
|
192
|
+
|
|
193
|
+
if dry_run:
|
|
194
|
+
pass
|
|
195
|
+
else:
|
|
196
|
+
# add current directory to path, and then temporarily switch directories.
|
|
197
|
+
# this supports the case where a user is depending on the current directory
|
|
198
|
+
# for imports
|
|
199
|
+
sys.path.append(os.getcwd())
|
|
200
|
+
with chdir(Path(config).parent):
|
|
201
|
+
if watch:
|
|
202
|
+
pkg_path = get_package_path(builder.package)
|
|
203
|
+
print(f"Watching {pkg_path} for changes...")
|
|
204
|
+
observer = Observer()
|
|
205
|
+
observer._event_queue.maxsize = 1 # the default is 0 which is infinite, and there isn't a way to set this in the constructor
|
|
206
|
+
event_handler = QuartoDocFileChangeHandler(callback=doc_build)
|
|
207
|
+
observer.schedule(event_handler, pkg_path, recursive=True)
|
|
208
|
+
observer.schedule(event_handler, cfg_path, recursive=True)
|
|
209
|
+
observer.start()
|
|
210
|
+
try:
|
|
211
|
+
while True:
|
|
212
|
+
time.sleep(1)
|
|
213
|
+
except KeyboardInterrupt:
|
|
214
|
+
pass
|
|
215
|
+
finally:
|
|
216
|
+
observer.stop()
|
|
217
|
+
observer.join()
|
|
218
|
+
else:
|
|
219
|
+
doc_build()
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
@click.command(
|
|
223
|
+
short_help="Generate inventory files that the Quarto "
|
|
224
|
+
"`interlink` extension can use to auto-link to other docs."
|
|
225
|
+
)
|
|
226
|
+
@click.argument("config", default="_quarto.yml")
|
|
227
|
+
@click.option("--dry-run", is_flag=True, default=False)
|
|
228
|
+
@click.option("--fast", is_flag=True, default=False)
|
|
229
|
+
def interlinks(config, dry_run, fast):
|
|
230
|
+
"""
|
|
231
|
+
Generate inventory files that the Quarto `interlink` extension can use to
|
|
232
|
+
auto-link to other docs.
|
|
233
|
+
|
|
234
|
+
The files are stored in a cache directory, which defaults to _inv.
|
|
235
|
+
The Quarto extension `interlinks` will look for these files in the cache
|
|
236
|
+
and add links to your docs accordingly.
|
|
237
|
+
"""
|
|
238
|
+
|
|
239
|
+
# config loading ----
|
|
240
|
+
cfg = yaml.safe_load(open(config))
|
|
241
|
+
interlinks = cfg.get("interlinks", {})
|
|
242
|
+
|
|
243
|
+
p_root = Path(config).parent
|
|
244
|
+
|
|
245
|
+
if not interlinks:
|
|
246
|
+
print("No interlinks field found in your quarto config. Quitting.")
|
|
247
|
+
return
|
|
248
|
+
|
|
249
|
+
# interlinks config settings ----
|
|
250
|
+
cache = p_root / "_inv"
|
|
251
|
+
cfg_fast = interlinks.get("fast", False)
|
|
252
|
+
|
|
253
|
+
fast = cfg_fast or fast
|
|
254
|
+
|
|
255
|
+
for k, v in interlinks["sources"].items():
|
|
256
|
+
# don't include user's own docs (users don't need to specify their own docs in
|
|
257
|
+
# the interlinks config anymore, so this is for backwards compat).
|
|
258
|
+
if v["url"] == "/":
|
|
259
|
+
continue
|
|
260
|
+
|
|
261
|
+
url = v["url"] + v.get("inv", "objects.inv")
|
|
262
|
+
|
|
263
|
+
inv = inventory_from_url(url)
|
|
264
|
+
|
|
265
|
+
p_dst = p_root / cache / f"{k}_objects"
|
|
266
|
+
p_dst.parent.mkdir(exist_ok=True, parents=True)
|
|
267
|
+
|
|
268
|
+
if fast:
|
|
269
|
+
# use sphobjinv to dump inv in txt format
|
|
270
|
+
df = inv.data_file()
|
|
271
|
+
soi.writebytes(p_dst.with_suffix(".txt"), df)
|
|
272
|
+
|
|
273
|
+
else:
|
|
274
|
+
# old behavior of converting to custom json format
|
|
275
|
+
convert_inventory(inv, p_dst.with_suffix(".json"))
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
cli.add_command(build)
|
|
279
|
+
cli.add_command(interlinks)
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
if __name__ == "__main__":
|
|
283
|
+
cli()
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# flake8: noqa
|
|
2
|
+
|
|
3
|
+
from griffe import GriffeLoader
|
|
4
|
+
from griffe import ModulesCollection, LinesCollection
|
|
5
|
+
|
|
6
|
+
from . import dataclasses
|
|
7
|
+
from . import docstrings
|
|
8
|
+
from . import expressions
|
|
9
|
+
|
|
10
|
+
from griffe import Parser, parse, parse_numpy
|
|
11
|
+
from griffe import AliasResolutionError
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"""Generate the submodules which import parts of griffe (e.g. dataclasses.py)
|
|
2
|
+
|
|
3
|
+
This process balances having to import specific objects from griffe, against
|
|
4
|
+
importing everything via the top-level griffe module. It does this by generating
|
|
5
|
+
modules for objects commonly used together in quartodoc.
|
|
6
|
+
|
|
7
|
+
* dataclasses: represent python objects
|
|
8
|
+
* docstrings: represent python docstrings
|
|
9
|
+
* expressions: represent annotation expressions
|
|
10
|
+
|
|
11
|
+
Run using: python -m quartodoc._griffe_compat._generate_stubs
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import ast
|
|
15
|
+
import black
|
|
16
|
+
import copy
|
|
17
|
+
import griffe
|
|
18
|
+
import inspect
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def fetch_submodule(ast_body, submodule: str):
|
|
23
|
+
ast_imports = [
|
|
24
|
+
obj
|
|
25
|
+
for obj in ast_body
|
|
26
|
+
if isinstance(obj, ast.ImportFrom) and obj.module == submodule
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
if len(ast_imports) > 1:
|
|
30
|
+
raise Exception(f"Found {len(ast_imports)} imports for {submodule}")
|
|
31
|
+
elif not ast_imports:
|
|
32
|
+
raise Exception(f"Could not find import for {submodule}")
|
|
33
|
+
|
|
34
|
+
return ast_imports[0]
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def code_for_imports(mod_code: str, submodules: list[str]) -> str:
|
|
38
|
+
res = []
|
|
39
|
+
mod = ast.parse(mod_code)
|
|
40
|
+
for submod in submodules:
|
|
41
|
+
expr = fetch_submodule(mod.body, submod)
|
|
42
|
+
expr.module = "griffe"
|
|
43
|
+
new_expr = copy.copy(expr)
|
|
44
|
+
new_expr.module = "griffe"
|
|
45
|
+
res.append(ast.unparse(new_expr))
|
|
46
|
+
|
|
47
|
+
return black.format_str(
|
|
48
|
+
"# flake8: noqa\n\n" + "\n".join(res), mode=black.FileMode()
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def generate_griffe_stub(out_path: Path, mod, submodules: list[str]):
|
|
53
|
+
res = code_for_imports(inspect.getsource(mod), submodules)
|
|
54
|
+
out_path.write_text(res)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
MAPPINGS = {
|
|
58
|
+
"dataclasses": [
|
|
59
|
+
"griffe._internal.models",
|
|
60
|
+
"griffe._internal.mixins",
|
|
61
|
+
"griffe._internal.enumerations",
|
|
62
|
+
],
|
|
63
|
+
"docstrings": ["griffe._internal.docstrings.models"],
|
|
64
|
+
"expressions": ["griffe._internal.expressions"],
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if __name__ == "__main__":
|
|
68
|
+
for out_name, submodules in MAPPINGS.items():
|
|
69
|
+
generate_griffe_stub(
|
|
70
|
+
Path(__file__).parent / f"{out_name}.py", griffe, submodules
|
|
71
|
+
)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# flake8: noqa
|
|
2
|
+
|
|
3
|
+
from griffe import (
|
|
4
|
+
Alias,
|
|
5
|
+
Attribute,
|
|
6
|
+
Class,
|
|
7
|
+
Decorator,
|
|
8
|
+
Docstring,
|
|
9
|
+
Function,
|
|
10
|
+
Module,
|
|
11
|
+
Object,
|
|
12
|
+
Parameter,
|
|
13
|
+
Parameters,
|
|
14
|
+
TypeAlias,
|
|
15
|
+
TypeParameter,
|
|
16
|
+
TypeParameters,
|
|
17
|
+
)
|
|
18
|
+
from griffe import (
|
|
19
|
+
DelMembersMixin,
|
|
20
|
+
GetMembersMixin,
|
|
21
|
+
ObjectAliasMixin,
|
|
22
|
+
SerializationMixin,
|
|
23
|
+
SetMembersMixin,
|
|
24
|
+
)
|
|
25
|
+
from griffe import (
|
|
26
|
+
BreakageKind,
|
|
27
|
+
DocstringSectionKind,
|
|
28
|
+
ExplanationStyle,
|
|
29
|
+
Kind,
|
|
30
|
+
LogLevel,
|
|
31
|
+
ObjectKind,
|
|
32
|
+
ParameterKind,
|
|
33
|
+
Parser,
|
|
34
|
+
TypeParameterKind,
|
|
35
|
+
)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# flake8: noqa
|
|
2
|
+
|
|
3
|
+
from griffe import (
|
|
4
|
+
DocstringAdmonition,
|
|
5
|
+
DocstringAttribute,
|
|
6
|
+
DocstringClass,
|
|
7
|
+
DocstringDeprecated,
|
|
8
|
+
DocstringElement,
|
|
9
|
+
DocstringFunction,
|
|
10
|
+
DocstringModule,
|
|
11
|
+
DocstringNamedElement,
|
|
12
|
+
DocstringParameter,
|
|
13
|
+
DocstringRaise,
|
|
14
|
+
DocstringReceive,
|
|
15
|
+
DocstringReturn,
|
|
16
|
+
DocstringSection,
|
|
17
|
+
DocstringSectionAdmonition,
|
|
18
|
+
DocstringSectionAttributes,
|
|
19
|
+
DocstringSectionClasses,
|
|
20
|
+
DocstringSectionDeprecated,
|
|
21
|
+
DocstringSectionExamples,
|
|
22
|
+
DocstringSectionFunctions,
|
|
23
|
+
DocstringSectionModules,
|
|
24
|
+
DocstringSectionOtherParameters,
|
|
25
|
+
DocstringSectionParameters,
|
|
26
|
+
DocstringSectionRaises,
|
|
27
|
+
DocstringSectionReceives,
|
|
28
|
+
DocstringSectionReturns,
|
|
29
|
+
DocstringSectionText,
|
|
30
|
+
DocstringSectionTypeAliases,
|
|
31
|
+
DocstringSectionTypeParameters,
|
|
32
|
+
DocstringSectionWarns,
|
|
33
|
+
DocstringSectionYields,
|
|
34
|
+
DocstringTypeAlias,
|
|
35
|
+
DocstringTypeParameter,
|
|
36
|
+
DocstringWarn,
|
|
37
|
+
DocstringYield,
|
|
38
|
+
)
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# flake8: noqa
|
|
2
|
+
|
|
3
|
+
from griffe import (
|
|
4
|
+
Expr,
|
|
5
|
+
ExprAttribute,
|
|
6
|
+
ExprBinOp,
|
|
7
|
+
ExprBoolOp,
|
|
8
|
+
ExprCall,
|
|
9
|
+
ExprCompare,
|
|
10
|
+
ExprComprehension,
|
|
11
|
+
ExprConstant,
|
|
12
|
+
ExprDict,
|
|
13
|
+
ExprDictComp,
|
|
14
|
+
ExprExtSlice,
|
|
15
|
+
ExprFormatted,
|
|
16
|
+
ExprGeneratorExp,
|
|
17
|
+
ExprIfExp,
|
|
18
|
+
ExprInterpolation,
|
|
19
|
+
ExprJoinedStr,
|
|
20
|
+
ExprKeyword,
|
|
21
|
+
ExprLambda,
|
|
22
|
+
ExprList,
|
|
23
|
+
ExprListComp,
|
|
24
|
+
ExprName,
|
|
25
|
+
ExprNamedExpr,
|
|
26
|
+
ExprParameter,
|
|
27
|
+
ExprSet,
|
|
28
|
+
ExprSetComp,
|
|
29
|
+
ExprSlice,
|
|
30
|
+
ExprSubscript,
|
|
31
|
+
ExprTemplateStr,
|
|
32
|
+
ExprTuple,
|
|
33
|
+
ExprUnaryOp,
|
|
34
|
+
ExprVarKeyword,
|
|
35
|
+
ExprVarPositional,
|
|
36
|
+
ExprYield,
|
|
37
|
+
ExprYieldFrom,
|
|
38
|
+
get_annotation,
|
|
39
|
+
get_base_class,
|
|
40
|
+
get_class_keyword,
|
|
41
|
+
get_condition,
|
|
42
|
+
get_expression,
|
|
43
|
+
safe_get_annotation,
|
|
44
|
+
safe_get_base_class,
|
|
45
|
+
safe_get_class_keyword,
|
|
46
|
+
safe_get_condition,
|
|
47
|
+
safe_get_expression,
|
|
48
|
+
)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
try:
|
|
2
|
+
from pydantic.v1 import (
|
|
3
|
+
BaseModel,
|
|
4
|
+
Field,
|
|
5
|
+
Extra,
|
|
6
|
+
PrivateAttr,
|
|
7
|
+
ValidationError,
|
|
8
|
+
validator,
|
|
9
|
+
) # noqa
|
|
10
|
+
except ImportError:
|
|
11
|
+
from pydantic import ( # noqa
|
|
12
|
+
BaseModel,
|
|
13
|
+
Field,
|
|
14
|
+
Extra,
|
|
15
|
+
PrivateAttr,
|
|
16
|
+
ValidationError,
|
|
17
|
+
validator,
|
|
18
|
+
)
|