nbdev 3.1.0__tar.gz → 3.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.
- {nbdev-3.1.0/nbdev.egg-info → nbdev-3.2.0}/PKG-INFO +6 -3
- {nbdev-3.1.0 → nbdev-3.2.0}/README.md +4 -1
- {nbdev-3.1.0 → nbdev-3.2.0}/nbdev/__init__.py +1 -1
- {nbdev-3.1.0 → nbdev-3.2.0}/nbdev/_modidx.py +2 -0
- {nbdev-3.1.0 → nbdev-3.2.0}/nbdev/cli.py +10 -7
- {nbdev-3.1.0 → nbdev-3.2.0}/nbdev/config.py +3 -2
- {nbdev-3.1.0 → nbdev-3.2.0}/nbdev/export.py +9 -8
- {nbdev-3.1.0 → nbdev-3.2.0}/nbdev/merge.py +7 -5
- {nbdev-3.1.0 → nbdev-3.2.0}/nbdev/migrate.py +9 -7
- {nbdev-3.1.0 → nbdev-3.2.0}/nbdev/processors.py +10 -4
- {nbdev-3.1.0 → nbdev-3.2.0}/nbdev/qmd.py +34 -24
- {nbdev-3.1.0 → nbdev-3.2.0}/nbdev/quarto.py +15 -8
- {nbdev-3.1.0 → nbdev-3.2.0}/nbdev/showdoc.py +6 -4
- {nbdev-3.1.0 → nbdev-3.2.0}/nbdev/test.py +17 -13
- {nbdev-3.1.0 → nbdev-3.2.0/nbdev.egg-info}/PKG-INFO +6 -3
- {nbdev-3.1.0 → nbdev-3.2.0}/nbdev.egg-info/requires.txt +1 -1
- {nbdev-3.1.0 → nbdev-3.2.0}/pyproject.toml +1 -1
- {nbdev-3.1.0 → nbdev-3.2.0}/CONTRIBUTING.md +0 -0
- {nbdev-3.1.0 → nbdev-3.2.0}/LICENSE +0 -0
- {nbdev-3.1.0 → nbdev-3.2.0}/MANIFEST.in +0 -0
- {nbdev-3.1.0 → nbdev-3.2.0}/nbdev/clean.py +0 -0
- {nbdev-3.1.0 → nbdev-3.2.0}/nbdev/diff.py +0 -0
- {nbdev-3.1.0 → nbdev-3.2.0}/nbdev/doclinks.py +0 -0
- {nbdev-3.1.0 → nbdev-3.2.0}/nbdev/extract_attachments.py +0 -0
- {nbdev-3.1.0 → nbdev-3.2.0}/nbdev/frontmatter.py +0 -0
- {nbdev-3.1.0 → nbdev-3.2.0}/nbdev/imports.py +0 -0
- {nbdev-3.1.0 → nbdev-3.2.0}/nbdev/maker.py +0 -0
- {nbdev-3.1.0 → nbdev-3.2.0}/nbdev/process.py +0 -0
- {nbdev-3.1.0 → nbdev-3.2.0}/nbdev/release.py +0 -0
- {nbdev-3.1.0 → nbdev-3.2.0}/nbdev/scrubmagics.py +0 -0
- {nbdev-3.1.0 → nbdev-3.2.0}/nbdev/serve.py +0 -0
- {nbdev-3.1.0 → nbdev-3.2.0}/nbdev/serve_drv.py +0 -0
- {nbdev-3.1.0 → nbdev-3.2.0}/nbdev/sync.py +0 -0
- {nbdev-3.1.0 → nbdev-3.2.0}/nbdev.egg-info/SOURCES.txt +0 -0
- {nbdev-3.1.0 → nbdev-3.2.0}/nbdev.egg-info/dependency_links.txt +0 -0
- {nbdev-3.1.0 → nbdev-3.2.0}/nbdev.egg-info/entry_points.txt +0 -0
- {nbdev-3.1.0 → nbdev-3.2.0}/nbdev.egg-info/top_level.txt +0 -0
- {nbdev-3.1.0 → nbdev-3.2.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nbdev
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.2.0
|
|
4
4
|
Summary: Create delightful software with Jupyter Notebooks
|
|
5
5
|
Author-email: "Jeremy Howard and the fast.ai community" <j@fast.ai>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -16,7 +16,7 @@ Classifier: License :: OSI Approved :: Apache Software License
|
|
|
16
16
|
Requires-Python: >=3.9
|
|
17
17
|
Description-Content-Type: text/markdown
|
|
18
18
|
License-File: LICENSE
|
|
19
|
-
Requires-Dist: fastcore>=1.14.
|
|
19
|
+
Requires-Dist: fastcore>=1.14.6
|
|
20
20
|
Requires-Dist: execnb>=0.2.4
|
|
21
21
|
Requires-Dist: astunparse
|
|
22
22
|
Requires-Dist: ghapi>=2.0.0
|
|
@@ -158,7 +158,7 @@ available commands:
|
|
|
158
158
|
nbdev-pypi Create and upload Python package to PyPI
|
|
159
159
|
nbdev-readme Create README.md from readme_nb (index.ipynb by default)
|
|
160
160
|
nbdev-release-both Release both conda and PyPI packages
|
|
161
|
-
nbdev-release-gh Calls `
|
|
161
|
+
nbdev-release-gh Calls `nbdev-changelog`, lets you edit the result, then pushes to git and calls `nbdev-release-git`
|
|
162
162
|
nbdev-release-git Tag and create a release in GitHub for the current version
|
|
163
163
|
nbdev-requirements Writes a `requirements.txt` file to `directory` based on pyproject.toml.
|
|
164
164
|
nbdev-sidebar Create sidebar.yml
|
|
@@ -184,6 +184,9 @@ some_module.something()
|
|
|
184
184
|
Instead, split this into two cells, one which does `import some_module`,
|
|
185
185
|
and the other which does `some_module.something()`.
|
|
186
186
|
|
|
187
|
+
Only top-level statements count: `try: import` blocks and imports inside
|
|
188
|
+
function definitions are fine.
|
|
189
|
+
|
|
187
190
|
The reason for this is that when we create your documentation website,
|
|
188
191
|
we ensure that all of the signatures for functions you document are up
|
|
189
192
|
to date, by running the imports, exported cells, and
|
|
@@ -114,7 +114,7 @@ available commands:
|
|
|
114
114
|
nbdev-pypi Create and upload Python package to PyPI
|
|
115
115
|
nbdev-readme Create README.md from readme_nb (index.ipynb by default)
|
|
116
116
|
nbdev-release-both Release both conda and PyPI packages
|
|
117
|
-
nbdev-release-gh Calls `
|
|
117
|
+
nbdev-release-gh Calls `nbdev-changelog`, lets you edit the result, then pushes to git and calls `nbdev-release-git`
|
|
118
118
|
nbdev-release-git Tag and create a release in GitHub for the current version
|
|
119
119
|
nbdev-requirements Writes a `requirements.txt` file to `directory` based on pyproject.toml.
|
|
120
120
|
nbdev-sidebar Create sidebar.yml
|
|
@@ -140,6 +140,9 @@ some_module.something()
|
|
|
140
140
|
Instead, split this into two cells, one which does `import some_module`,
|
|
141
141
|
and the other which does `some_module.something()`.
|
|
142
142
|
|
|
143
|
+
Only top-level statements count: `try: import` blocks and imports inside
|
|
144
|
+
function definitions are fine.
|
|
145
|
+
|
|
143
146
|
The reason for this is that when we create your documentation website,
|
|
144
147
|
we ensure that all of the signatures for functions you document are up
|
|
145
148
|
to date, by running the imports, exported cells, and
|
|
@@ -225,6 +225,7 @@ d = { 'settings': { 'branch': 'main',
|
|
|
225
225
|
'nbdev.processors._is_showdoc': ('api/processors.html#_is_showdoc', 'nbdev/processors.py'),
|
|
226
226
|
'nbdev.processors._re_hideline': ('api/processors.html#_re_hideline', 'nbdev/processors.py'),
|
|
227
227
|
'nbdev.processors._show_docs': ('api/processors.html#_show_docs', 'nbdev/processors.py'),
|
|
228
|
+
'nbdev.processors._tl_contains': ('api/processors.html#_tl_contains', 'nbdev/processors.py'),
|
|
228
229
|
'nbdev.processors._want_doc': ('api/processors.html#_want_doc', 'nbdev/processors.py'),
|
|
229
230
|
'nbdev.processors.add_fold': ('api/processors.html#add_fold', 'nbdev/processors.py'),
|
|
230
231
|
'nbdev.processors.add_links': ('api/processors.html#add_links', 'nbdev/processors.py'),
|
|
@@ -287,6 +288,7 @@ d = { 'settings': { 'branch': 'main',
|
|
|
287
288
|
'nbdev.quarto._nbglob_docs': ('api/quarto.html#_nbglob_docs', 'nbdev/quarto.py'),
|
|
288
289
|
'nbdev.quarto._pre': ('api/quarto.html#_pre', 'nbdev/quarto.py'),
|
|
289
290
|
'nbdev.quarto._pre_docs': ('api/quarto.html#_pre_docs', 'nbdev/quarto.py'),
|
|
291
|
+
'nbdev.quarto._readme_cands': ('api/quarto.html#_readme_cands', 'nbdev/quarto.py'),
|
|
290
292
|
'nbdev.quarto._recursive_parser': ('api/quarto.html#_recursive_parser', 'nbdev/quarto.py'),
|
|
291
293
|
'nbdev.quarto._save_cached_contributing': ('api/quarto.html#_save_cached_contributing', 'nbdev/quarto.py'),
|
|
292
294
|
'nbdev.quarto._save_cached_readme': ('api/quarto.html#_save_cached_readme', 'nbdev/quarto.py'),
|
|
@@ -169,18 +169,21 @@ async def nbdev_update_license(
|
|
|
169
169
|
# %% ../nbs/api/13_cli.ipynb #412b4cd2
|
|
170
170
|
@call_parse
|
|
171
171
|
@delegates(nb_export, but=['procs', 'mod_maker'])
|
|
172
|
-
def nb_export_cli(
|
|
173
|
-
|
|
174
|
-
|
|
172
|
+
def nb_export_cli(
|
|
173
|
+
nbname,
|
|
174
|
+
debug:store_true=False, # Debug flag
|
|
175
|
+
**kwargs
|
|
176
|
+
):
|
|
175
177
|
"Export a single nbdev notebook to a python script."
|
|
176
178
|
return nb_export(nbname=nbname, debug=debug, **kwargs)
|
|
177
179
|
|
|
178
180
|
# %% ../nbs/api/13_cli.ipynb #aaa472e7
|
|
179
181
|
@call_parse
|
|
180
|
-
def watch_export(
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
182
|
+
def watch_export(
|
|
183
|
+
nbs:str=None, # Nb directory to watch for changes
|
|
184
|
+
lib:str=None, # Export directory to write py files to
|
|
185
|
+
force:bool=False # Ignore nbdev config if in nbdev project
|
|
186
|
+
):
|
|
184
187
|
'''Use `nb_export` on ipynb files in `nbs` directory on changes using nbdev config if available'''
|
|
185
188
|
cfg = get_config() if is_nbdev() else None
|
|
186
189
|
nbs = nbs or (cfg.nbs_path if cfg else '.')
|
|
@@ -236,7 +236,7 @@ def get_config(path=None, also_settings=False):
|
|
|
236
236
|
nbdev = {**user, **d.get('tool', {}).get('nbdev', {})}
|
|
237
237
|
return ConfigToml(nbdev, d.get('project', {}), cfg_file)
|
|
238
238
|
if also_settings:
|
|
239
|
-
from fastcore.
|
|
239
|
+
from fastcore.xtras import Config
|
|
240
240
|
cfg = Config.find('settings.ini', path)
|
|
241
241
|
if cfg: return cfg
|
|
242
242
|
cfg_path = Path(path or Path.cwd()).expanduser().absolute()
|
|
@@ -265,7 +265,8 @@ def nbpath2docurl(nb_path):
|
|
|
265
265
|
"Hosted docs URL (with `.md` suffix) for notebook `nb_path`, or '' if no `doc_host`"
|
|
266
266
|
cfg = get_config()
|
|
267
267
|
if not cfg.doc_host: return ''
|
|
268
|
-
p = Path(nb_path).resolve().relative_to(cfg.path('nbs_path'))
|
|
268
|
+
try: p = Path(nb_path).resolve().relative_to(cfg.path('nbs_path'))
|
|
269
|
+
except ValueError: return ""
|
|
269
270
|
return f"{cfg.doc_host.rstrip('/')}{cfg.doc_baseurl.rstrip('/')}/{nbpath2html(p).as_posix()}.md"
|
|
270
271
|
|
|
271
272
|
# %% ../nbs/api/01_config.ipynb #163177f2
|
|
@@ -36,14 +36,15 @@ class ExportModuleProc:
|
|
|
36
36
|
_exports_=_export_
|
|
37
37
|
|
|
38
38
|
# %% ../nbs/api/04_export.ipynb #76717e36
|
|
39
|
-
def nb_export(
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
39
|
+
def nb_export(
|
|
40
|
+
nbname:str, # Filename of notebook
|
|
41
|
+
lib_path:str=None, # Path to destination library. If not in a nbdev project, defaults to current directory.
|
|
42
|
+
procs=None, # Processors to use
|
|
43
|
+
name:str=None, # Name of python script {name}.py to create.
|
|
44
|
+
mod_maker=ModuleMaker,
|
|
45
|
+
debug:bool=False, # Debug mode
|
|
46
|
+
solo_nb:bool=False # Export single notebook outside of an nbdev project.
|
|
47
|
+
):
|
|
47
48
|
"Create module(s) from notebook"
|
|
48
49
|
if lib_path is None: lib_path = get_config().lib_path if is_nbdev() else '.'
|
|
49
50
|
exp = ExportModuleProc()
|
|
@@ -60,11 +60,13 @@ def _merge_cells(a, b, brancha, branchb, theirs):
|
|
|
60
60
|
|
|
61
61
|
# %% ../nbs/api/07_merge.ipynb #cc492d30
|
|
62
62
|
@call_parse
|
|
63
|
-
def nbdev_fix(
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
63
|
+
def nbdev_fix(
|
|
64
|
+
nbname:str, # Notebook filename to fix
|
|
65
|
+
outname:str=None, # Filename of output notebook (defaults to `nbname`)
|
|
66
|
+
nobackup:bool_arg=True, # Do not backup `nbname` to `nbname`.bak if `outname` not provided
|
|
67
|
+
theirs:bool=False, # Use their outputs and metadata instead of ours
|
|
68
|
+
noprint:bool=False # Do not print info about whether conflicts are found
|
|
69
|
+
):
|
|
68
70
|
"Create working notebook from conflicted notebook `nbname`"
|
|
69
71
|
nbname = Path(nbname)
|
|
70
72
|
if not nobackup and not outname: shutil.copy(nbname, nbname.with_suffix('.ipynb.bak'))
|
|
@@ -32,11 +32,12 @@ def _file_slug(fname):
|
|
|
32
32
|
return dt + p.stem[11:]
|
|
33
33
|
|
|
34
34
|
# %% ../nbs/api/16_migrate.ipynb #689bf354
|
|
35
|
-
def _replace_fm(
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
def _replace_fm(
|
|
36
|
+
d:dict, # dictionary you wish to conditionally change
|
|
37
|
+
k:str, # key to check
|
|
38
|
+
val:str,# value to check if d[k] == v
|
|
39
|
+
repl_dict:dict #dictionary that will be used as a replacement
|
|
40
|
+
):
|
|
40
41
|
"replace key `k` in dict `d` if d[k] == val with `repl_dict`"
|
|
41
42
|
if str(d.get(k, '')).lower().strip() == str(val.lower()).strip():
|
|
42
43
|
d.pop(k)
|
|
@@ -191,8 +192,9 @@ def _migrate_workflows(path):
|
|
|
191
192
|
wf_path = Path(path) / '.github/workflows'
|
|
192
193
|
if not wf_path.exists(): return
|
|
193
194
|
replacements = [
|
|
194
|
-
('fastai/workflows/quarto-ghp@', '
|
|
195
|
-
('fastai/workflows/nbdev-ci@', '
|
|
195
|
+
('fastai/workflows/quarto-ghp@', 'AnswerDotAI/workflows/quarto-ghp3@'),
|
|
196
|
+
('fastai/workflows/nbdev-ci@', 'AnswerDotAI/workflows/nbdev3-ci@'),
|
|
197
|
+
('fastai/workflows/', 'AnswerDotAI/workflows/'),
|
|
196
198
|
]
|
|
197
199
|
for f in (*wf_path.glob('*.yml'), *wf_path.glob('*.yaml')):
|
|
198
200
|
txt = f.read_text()
|
|
@@ -182,11 +182,15 @@ def ai_magics(cell):
|
|
|
182
182
|
cell.source = '\n'.join(cell.source.splitlines()[1:])
|
|
183
183
|
|
|
184
184
|
# %% ../nbs/api/10_processors.ipynb #5a9c8fd4
|
|
185
|
-
|
|
185
|
+
_def_strip_magics = '%load_ext %autoreload %reload_ext %matplotlib %config'
|
|
186
186
|
|
|
187
187
|
def clean_magics(cell):
|
|
188
|
-
"
|
|
189
|
-
|
|
188
|
+
"Remove housekeeping magics: those named in the `strip_magics` config (space-separated, default `_def_strip_magics`)"
|
|
189
|
+
mm = str(get_config().get('strip_magics', _def_strip_magics)).split()
|
|
190
|
+
if not mm or cell.cell_type != 'code': return
|
|
191
|
+
pat = re.compile(rf"^\s*({'|'.join(re.escape(m) for m in mm)})\b.*", re.MULTILINE)
|
|
192
|
+
cell.source = pat.sub('', cell.source).strip()
|
|
193
|
+
|
|
190
194
|
|
|
191
195
|
# %% ../nbs/api/10_processors.ipynb #93e27a52
|
|
192
196
|
_re_hdr_dash = re.compile(r'^#+\s+.*\s+-\s*$', re.MULTILINE)
|
|
@@ -223,6 +227,8 @@ def _ast_contains(trees, types):
|
|
|
223
227
|
for node in ast.walk(tree):
|
|
224
228
|
if isinstance(node, types): return True
|
|
225
229
|
|
|
230
|
+
def _tl_contains(trees, types): return any(isinstance(t, types) for t in trees)
|
|
231
|
+
|
|
226
232
|
def _do_eval(cell):
|
|
227
233
|
if cell_lang(cell) != 'python': return
|
|
228
234
|
if not cell.source or 'nbdev_export'+'()' in cell.source: return
|
|
@@ -233,7 +239,7 @@ def _do_eval(cell):
|
|
|
233
239
|
_show_dirs = {'export','exports','exporti','exec_doc'}
|
|
234
240
|
if cell.directives_.keys() & _show_dirs: return True
|
|
235
241
|
if _ast_contains(trees, (ast.Import, ast.ImportFrom)):
|
|
236
|
-
if
|
|
242
|
+
if _tl_contains(trees, (ast.Import, ast.ImportFrom)) and _tl_contains(trees, (ast.Expr, ast.Assign)):
|
|
237
243
|
warn(f'Found cells containing imports and other code. See FAQ.\n---\n{cell.source}\n---\n')
|
|
238
244
|
return True
|
|
239
245
|
if _show_docs(trees): return True
|
|
@@ -14,10 +14,12 @@ from fastcore.utils import *
|
|
|
14
14
|
from fastcore.meta import delegates
|
|
15
15
|
|
|
16
16
|
# %% ../nbs/api/15_qmd.ipynb #5a64f1f4
|
|
17
|
-
def meta(
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
def meta(
|
|
18
|
+
md, # Markdown to add meta to
|
|
19
|
+
classes=None, # List of CSS classes to add
|
|
20
|
+
style=None, # Dict of CSS styles to add
|
|
21
|
+
**kwargs # Additional attributes to add to meta
|
|
22
|
+
):
|
|
21
23
|
"A metadata section for qmd div in `{}`"
|
|
22
24
|
if style: kwargs['style'] = "; ".join(f'{k}: {v}' for k,v in style.items())
|
|
23
25
|
props = ' '.join(f'{k}="{v}"' for k,v in kwargs.items())
|
|
@@ -29,21 +31,25 @@ def meta(md, # Markdown to add meta to
|
|
|
29
31
|
return md + ("{" + meta + "}" if meta else "")
|
|
30
32
|
|
|
31
33
|
# %% ../nbs/api/15_qmd.ipynb #52637a70
|
|
32
|
-
def div(
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
def div(
|
|
35
|
+
txt, # Markdown to add meta to
|
|
36
|
+
classes=None, # List of CSS classes to add
|
|
37
|
+
style=None, # Dict of CSS styles to add
|
|
38
|
+
**kwargs
|
|
39
|
+
):
|
|
36
40
|
"A qmd div with optional metadata section"
|
|
37
41
|
return meta("::: ", classes=classes, style=style, **kwargs) + f"\n\n{txt}\n\n:::\n\n"
|
|
38
42
|
|
|
39
43
|
# %% ../nbs/api/15_qmd.ipynb #f9f499f4
|
|
40
|
-
def img(
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
def img(
|
|
45
|
+
fname, # Image to link to
|
|
46
|
+
classes=None, # List of CSS classes to add
|
|
47
|
+
style=None, # Dict of CSS styles to add
|
|
48
|
+
height=None, # Height attribute
|
|
49
|
+
relative=None, # Tuple of (position,px)
|
|
50
|
+
link=False, # Hyperlink to this image
|
|
51
|
+
**kwargs
|
|
52
|
+
):
|
|
47
53
|
"A qmd image"
|
|
48
54
|
kwargs,style = kwargs or {}, style or {}
|
|
49
55
|
if height: kwargs["height"]= f"{height}px"
|
|
@@ -55,23 +61,27 @@ def img(fname, # Image to link to
|
|
|
55
61
|
return f'[{res}]({fname})' if link else res
|
|
56
62
|
|
|
57
63
|
# %% ../nbs/api/15_qmd.ipynb #16d7aa5f
|
|
58
|
-
def btn(
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
64
|
+
def btn(
|
|
65
|
+
txt, # Button text
|
|
66
|
+
link, # Button link URL
|
|
67
|
+
classes=None, # List of CSS classes to add
|
|
68
|
+
style=None, # Dict of CSS styles to add
|
|
69
|
+
**kwargs
|
|
70
|
+
):
|
|
63
71
|
"A qmd button"
|
|
64
72
|
return meta(f'[{txt}]({link})', classes=classes, style=style, role="button")
|
|
65
73
|
|
|
66
74
|
# %% ../nbs/api/15_qmd.ipynb #e414ed33
|
|
67
|
-
def tbl_row(
|
|
68
|
-
|
|
75
|
+
def tbl_row(
|
|
76
|
+
cols:list, # Auto-stringified columns to show in the row
|
|
77
|
+
):
|
|
69
78
|
"Create a markdown table row from `cols`"
|
|
70
79
|
return '|' + '|'.join(str(c or '') for c in cols) + '|'
|
|
71
80
|
|
|
72
81
|
# %% ../nbs/api/15_qmd.ipynb #38f0641b
|
|
73
|
-
def tbl_sep(
|
|
74
|
-
|
|
82
|
+
def tbl_sep(
|
|
83
|
+
sizes:int|list=3 # List of column sizes, or single `int` if all sizes the same
|
|
84
|
+
):
|
|
75
85
|
"Create a markdown table separator with relative column size `sizes`"
|
|
76
86
|
if isinstance(sizes,int): sizes = [3]*sizes
|
|
77
87
|
return tbl_row('-'*s for s in sizes)
|
|
@@ -249,15 +249,20 @@ def _copytree(a,b):
|
|
|
249
249
|
copy_tree(a, b)
|
|
250
250
|
|
|
251
251
|
# %% ../nbs/api/14_quarto.ipynb #caeaa153
|
|
252
|
+
def _readme_cands(cache, cfg):
|
|
253
|
+
"Locations where `quarto render -o README.md` may put its output, which differs by quarto version"
|
|
254
|
+
return cache/cfg.doc_path.name/'README.md', cache/'README.md'
|
|
255
|
+
|
|
252
256
|
def _save_cached_readme(cache, cfg):
|
|
253
|
-
|
|
254
|
-
readme =
|
|
255
|
-
if readme.
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
257
|
+
cands = _readme_cands(cache, cfg)
|
|
258
|
+
readme = next((f for f in cands if f.exists()), None)
|
|
259
|
+
if not readme: raise FileNotFoundError(f"quarto render did not produce a README.md in any of: {cands}")
|
|
260
|
+
readme_path = cfg.config_path/'README.md'
|
|
261
|
+
if readme_path.exists(): readme_path.unlink() # py37 doesn't have `missing_ok`
|
|
262
|
+
move(readme, cfg.config_path)
|
|
263
|
+
_rdmi = readme.parent/((cache/cfg.readme_nb).stem + '_files') # Supporting files for README
|
|
264
|
+
if _rdmi.exists(): _copytree(_rdmi, cfg.config_path/_rdmi.name)
|
|
265
|
+
|
|
261
266
|
|
|
262
267
|
# %% ../nbs/api/14_quarto.ipynb #45d6bb5d
|
|
263
268
|
@call_parse
|
|
@@ -272,6 +277,8 @@ def nbdev_readme(
|
|
|
272
277
|
|
|
273
278
|
with _SidebarYmlRemoved(path): # to avoid rendering whole website
|
|
274
279
|
cache = proc_nbs(path)
|
|
280
|
+
for f in _readme_cands(cache, cfg):
|
|
281
|
+
if f.exists(): f.unlink() # remove stale renders from either quarto layout
|
|
275
282
|
_sprun(f'cd "{cache}" && quarto render "{cache/cfg.readme_nb}" -o README.md -t gfm --no-execute')
|
|
276
283
|
|
|
277
284
|
_save_cached_readme(cache, cfg)
|
|
@@ -34,10 +34,12 @@ class BasicMarkdownRenderer(MarkdownRenderer):
|
|
|
34
34
|
return doc+super()._repr_markdown_()
|
|
35
35
|
|
|
36
36
|
# %% ../nbs/api/08_showdoc.ipynb #1256ef79
|
|
37
|
-
def show_doc(
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
37
|
+
def show_doc(
|
|
38
|
+
sym, # Symbol to document
|
|
39
|
+
renderer=None, # Optional renderer (defaults to markdown)
|
|
40
|
+
name:str|None=None, # Optionally override displayed name of `sym`
|
|
41
|
+
title_level:int=3 # Heading level to use for symbol name
|
|
42
|
+
):
|
|
41
43
|
"Show signature and docstring for `sym`"
|
|
42
44
|
if renderer is None: renderer = get_config().get('renderer', None)
|
|
43
45
|
if renderer is None: renderer=BasicMarkdownRenderer
|
|
@@ -25,15 +25,17 @@ from fastcore.nbio import *
|
|
|
25
25
|
from execnb.shell import *
|
|
26
26
|
|
|
27
27
|
# %% ../nbs/api/12_test.ipynb #3f4fa1ad
|
|
28
|
-
def test_nb(
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
28
|
+
def test_nb(
|
|
29
|
+
fn, # file name of notebook to test
|
|
30
|
+
skip_flags=None, # list of flags marking cells to skip
|
|
31
|
+
force_flags=None, # list of flags marking cells to always run
|
|
32
|
+
do_print=False, # print completion?
|
|
33
|
+
showerr=True, # print errors to stderr?
|
|
34
|
+
basepath=None, # path to add to sys.path
|
|
35
|
+
verbose=False, # stream stdout/stderr from cells to console?
|
|
36
|
+
save=False, # write outputs back to notebook on success?
|
|
37
|
+
profile:bool=None # load the IPython profile, as `ipykernel` does? (default: `exec_profile` config key)
|
|
38
|
+
):
|
|
37
39
|
"Execute tests in notebook in `fn` except those with `skip_flags`"
|
|
38
40
|
faulthandler.register(signal.SIGINT, file=sys.__stderr__, all_threads=True, chain=True)
|
|
39
41
|
fn = Path(fn)
|
|
@@ -73,9 +75,10 @@ def test_nb(fn, # file name of notebook to test
|
|
|
73
75
|
|
|
74
76
|
|
|
75
77
|
# %% ../nbs/api/12_test.ipynb #d8bf1f1b-935d-4b69-ba96-827c5d7213f0
|
|
76
|
-
def _keep_file(
|
|
77
|
-
|
|
78
|
-
|
|
78
|
+
def _keep_file(
|
|
79
|
+
p:Path, # filename for which to check for `indicator_fname`
|
|
80
|
+
ignore_fname:str # filename that will result in siblings being ignored
|
|
81
|
+
) -> bool:
|
|
79
82
|
"Returns False if `indicator_fname` is a sibling to `fname` else True"
|
|
80
83
|
if p.exists(): return not bool(p.parent.ls().attrgot('name').filter(lambda x: x == ignore_fname))
|
|
81
84
|
else: True
|
|
@@ -93,7 +96,8 @@ def nbdev_test(
|
|
|
93
96
|
ignore_fname:str='.notest', # Filename that will result in siblings being ignored
|
|
94
97
|
verbose:bool=False, # Print stdout/stderr from notebook cells?
|
|
95
98
|
save:bool=False, # Write outputs back to notebooks on success?
|
|
96
|
-
**kwargs
|
|
99
|
+
**kwargs
|
|
100
|
+
):
|
|
97
101
|
"Test in parallel notebooks matching `path`, passing along `flags`"
|
|
98
102
|
cfg = get_config(Path(path).resolve() if path else None)
|
|
99
103
|
skip_flags = cfg.tst_flags
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nbdev
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.2.0
|
|
4
4
|
Summary: Create delightful software with Jupyter Notebooks
|
|
5
5
|
Author-email: "Jeremy Howard and the fast.ai community" <j@fast.ai>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -16,7 +16,7 @@ Classifier: License :: OSI Approved :: Apache Software License
|
|
|
16
16
|
Requires-Python: >=3.9
|
|
17
17
|
Description-Content-Type: text/markdown
|
|
18
18
|
License-File: LICENSE
|
|
19
|
-
Requires-Dist: fastcore>=1.14.
|
|
19
|
+
Requires-Dist: fastcore>=1.14.6
|
|
20
20
|
Requires-Dist: execnb>=0.2.4
|
|
21
21
|
Requires-Dist: astunparse
|
|
22
22
|
Requires-Dist: ghapi>=2.0.0
|
|
@@ -158,7 +158,7 @@ available commands:
|
|
|
158
158
|
nbdev-pypi Create and upload Python package to PyPI
|
|
159
159
|
nbdev-readme Create README.md from readme_nb (index.ipynb by default)
|
|
160
160
|
nbdev-release-both Release both conda and PyPI packages
|
|
161
|
-
nbdev-release-gh Calls `
|
|
161
|
+
nbdev-release-gh Calls `nbdev-changelog`, lets you edit the result, then pushes to git and calls `nbdev-release-git`
|
|
162
162
|
nbdev-release-git Tag and create a release in GitHub for the current version
|
|
163
163
|
nbdev-requirements Writes a `requirements.txt` file to `directory` based on pyproject.toml.
|
|
164
164
|
nbdev-sidebar Create sidebar.yml
|
|
@@ -184,6 +184,9 @@ some_module.something()
|
|
|
184
184
|
Instead, split this into two cells, one which does `import some_module`,
|
|
185
185
|
and the other which does `some_module.something()`.
|
|
186
186
|
|
|
187
|
+
Only top-level statements count: `try: import` blocks and imports inside
|
|
188
|
+
function definitions are fine.
|
|
189
|
+
|
|
187
190
|
The reason for this is that when we create your documentation website,
|
|
188
191
|
we ensure that all of the signatures for functions you document are up
|
|
189
192
|
to date, by running the imports, exported cells, and
|
|
@@ -19,7 +19,7 @@ classifiers = [
|
|
|
19
19
|
"License :: OSI Approved :: Apache Software License",
|
|
20
20
|
]
|
|
21
21
|
dynamic = ["version"]
|
|
22
|
-
dependencies = [ "fastcore>=1.14.
|
|
22
|
+
dependencies = [ "fastcore>=1.14.6", "execnb>=0.2.4", "astunparse", "ghapi>=2.0.0", "watchdog", "asttokens",
|
|
23
23
|
"setuptools", "build", "fastgit", "pyyaml", "tomli; python_version < '3.11'", ]
|
|
24
24
|
|
|
25
25
|
[project.optional-dependencies]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|