nbdev 2.3.27__tar.gz → 2.3.29__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-2.3.27/nbdev.egg-info → nbdev-2.3.29}/PKG-INFO +3 -2
- {nbdev-2.3.27 → nbdev-2.3.29}/nbdev/__init__.py +1 -1
- {nbdev-2.3.27 → nbdev-2.3.29}/nbdev/_modidx.py +2 -0
- {nbdev-2.3.27 → nbdev-2.3.29}/nbdev/clean.py +17 -15
- {nbdev-2.3.27 → nbdev-2.3.29}/nbdev/cli.py +14 -19
- {nbdev-2.3.27 → nbdev-2.3.29}/nbdev/config.py +21 -26
- {nbdev-2.3.27 → nbdev-2.3.29}/nbdev/doclinks.py +16 -14
- {nbdev-2.3.27 → nbdev-2.3.29}/nbdev/export.py +22 -15
- {nbdev-2.3.27 → nbdev-2.3.29}/nbdev/frontmatter.py +5 -3
- {nbdev-2.3.27 → nbdev-2.3.29}/nbdev/maker.py +28 -26
- {nbdev-2.3.27 → nbdev-2.3.29}/nbdev/merge.py +11 -9
- {nbdev-2.3.27 → nbdev-2.3.29}/nbdev/migrate.py +19 -17
- {nbdev-2.3.27 → nbdev-2.3.29}/nbdev/process.py +16 -14
- {nbdev-2.3.27 → nbdev-2.3.29}/nbdev/processors.py +39 -27
- {nbdev-2.3.27 → nbdev-2.3.29}/nbdev/qmd.py +9 -7
- {nbdev-2.3.27 → nbdev-2.3.29}/nbdev/quarto.py +25 -21
- {nbdev-2.3.27 → nbdev-2.3.29}/nbdev/release.py +30 -28
- {nbdev-2.3.27 → nbdev-2.3.29}/nbdev/serve.py +6 -4
- {nbdev-2.3.27 → nbdev-2.3.29}/nbdev/showdoc.py +17 -15
- {nbdev-2.3.27 → nbdev-2.3.29}/nbdev/sync.py +10 -8
- {nbdev-2.3.27 → nbdev-2.3.29}/nbdev/test.py +6 -4
- {nbdev-2.3.27 → nbdev-2.3.29/nbdev.egg-info}/PKG-INFO +3 -2
- {nbdev-2.3.27 → nbdev-2.3.29}/settings.ini +2 -2
- {nbdev-2.3.27 → nbdev-2.3.29}/setup.py +1 -1
- {nbdev-2.3.27 → nbdev-2.3.29}/CONTRIBUTING.md +0 -0
- {nbdev-2.3.27 → nbdev-2.3.29}/LICENSE +0 -0
- {nbdev-2.3.27 → nbdev-2.3.29}/MANIFEST.in +0 -0
- {nbdev-2.3.27 → nbdev-2.3.29}/README.md +0 -0
- {nbdev-2.3.27 → nbdev-2.3.29}/nbdev/extract_attachments.py +0 -0
- {nbdev-2.3.27 → nbdev-2.3.29}/nbdev/imports.py +0 -0
- {nbdev-2.3.27 → nbdev-2.3.29}/nbdev/serve_drv.py +0 -0
- {nbdev-2.3.27 → nbdev-2.3.29}/nbdev.egg-info/SOURCES.txt +0 -0
- {nbdev-2.3.27 → nbdev-2.3.29}/nbdev.egg-info/dependency_links.txt +0 -0
- {nbdev-2.3.27 → nbdev-2.3.29}/nbdev.egg-info/entry_points.txt +0 -0
- {nbdev-2.3.27 → nbdev-2.3.29}/nbdev.egg-info/not-zip-safe +0 -0
- {nbdev-2.3.27 → nbdev-2.3.29}/nbdev.egg-info/requires.txt +0 -0
- {nbdev-2.3.27 → nbdev-2.3.29}/nbdev.egg-info/top_level.txt +0 -0
- {nbdev-2.3.27 → nbdev-2.3.29}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: nbdev
|
|
3
|
-
Version: 2.3.
|
|
3
|
+
Version: 2.3.29
|
|
4
4
|
Summary: Create delightful software with Jupyter Notebooks
|
|
5
5
|
Home-page: https://github.com/fastai/nbdev
|
|
6
6
|
Author: Jeremy Howard and Hamel Husain
|
|
@@ -15,7 +15,8 @@ Classifier: Programming Language :: Python :: 3.7
|
|
|
15
15
|
Classifier: Programming Language :: Python :: 3.8
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.9
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
20
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
20
21
|
Requires-Python: >=3.7
|
|
21
22
|
Description-Content-Type: text/markdown
|
|
@@ -71,6 +71,7 @@ d = { 'settings': { 'branch': 'master',
|
|
|
71
71
|
'nbdev.doclinks.nbglob_cli': ('api/doclinks.html#nbglob_cli', 'nbdev/doclinks.py'),
|
|
72
72
|
'nbdev.doclinks.patch_name': ('api/doclinks.html#patch_name', 'nbdev/doclinks.py')},
|
|
73
73
|
'nbdev.export': { 'nbdev.export.ExportModuleProc': ('api/export.html#exportmoduleproc', 'nbdev/export.py'),
|
|
74
|
+
'nbdev.export.ExportModuleProc.__call__': ('api/export.html#exportmoduleproc.__call__', 'nbdev/export.py'),
|
|
74
75
|
'nbdev.export.ExportModuleProc._default_exp_': ( 'api/export.html#exportmoduleproc._default_exp_',
|
|
75
76
|
'nbdev/export.py'),
|
|
76
77
|
'nbdev.export.ExportModuleProc._export_': ('api/export.html#exportmoduleproc._export_', 'nbdev/export.py'),
|
|
@@ -203,6 +204,7 @@ d = { 'settings': { 'branch': 'master',
|
|
|
203
204
|
'nbdev.processors.add_show_docs': ('api/processors.html#add_show_docs', 'nbdev/processors.py'),
|
|
204
205
|
'nbdev.processors.add_show_docs.begin': ( 'api/processors.html#add_show_docs.begin',
|
|
205
206
|
'nbdev/processors.py'),
|
|
207
|
+
'nbdev.processors.ai_magics': ('api/processors.html#ai_magics', 'nbdev/processors.py'),
|
|
206
208
|
'nbdev.processors.boxify': ('api/processors.html#boxify', 'nbdev/processors.py'),
|
|
207
209
|
'nbdev.processors.cell_lang': ('api/processors.html#cell_lang', 'nbdev/processors.py'),
|
|
208
210
|
'nbdev.processors.clean_magics': ('api/processors.html#clean_magics', 'nbdev/processors.py'),
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
"""Strip superfluous metadata from notebooks"""
|
|
2
|
+
|
|
1
3
|
# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/api/11_clean.ipynb.
|
|
2
4
|
|
|
3
5
|
# %% auto 0
|
|
4
6
|
__all__ = ['nbdev_trust', 'clean_nb', 'process_write', 'nbdev_clean', 'clean_jupyter', 'nbdev_install_hooks']
|
|
5
7
|
|
|
6
|
-
# %% ../nbs/api/11_clean.ipynb
|
|
8
|
+
# %% ../nbs/api/11_clean.ipynb
|
|
7
9
|
import ast,warnings,stat
|
|
8
10
|
from astunparse import unparse
|
|
9
11
|
from textwrap import indent
|
|
@@ -18,7 +20,7 @@ from .config import *
|
|
|
18
20
|
from .sync import *
|
|
19
21
|
from .process import first_code_ln
|
|
20
22
|
|
|
21
|
-
# %% ../nbs/api/11_clean.ipynb
|
|
23
|
+
# %% ../nbs/api/11_clean.ipynb
|
|
22
24
|
@call_parse
|
|
23
25
|
def nbdev_trust(
|
|
24
26
|
fname:str=None, # A notebook name or glob to trust
|
|
@@ -45,7 +47,7 @@ def nbdev_trust(
|
|
|
45
47
|
if not NotebookNotary().check_signature(nb): NotebookNotary().sign(nb)
|
|
46
48
|
check_fname.touch(exist_ok=True)
|
|
47
49
|
|
|
48
|
-
# %% ../nbs/api/11_clean.ipynb
|
|
50
|
+
# %% ../nbs/api/11_clean.ipynb
|
|
49
51
|
_repr_id_re = re.compile('(<.*?)( at 0x[0-9a-fA-F]+)(>)')
|
|
50
52
|
|
|
51
53
|
_sub = partial(_repr_id_re.sub, r'\1\3')
|
|
@@ -55,7 +57,7 @@ def _skip_or_sub(x): return _sub(x) if "at 0x" in x else x
|
|
|
55
57
|
def _clean_cell_output_id(lines):
|
|
56
58
|
return _skip_or_sub(lines) if isinstance(lines,str) else [_skip_or_sub(o) for o in lines]
|
|
57
59
|
|
|
58
|
-
# %% ../nbs/api/11_clean.ipynb
|
|
60
|
+
# %% ../nbs/api/11_clean.ipynb
|
|
59
61
|
def _clean_cell_output(cell, clean_ids):
|
|
60
62
|
"Remove `cell` output execution count and optionally ids from text reprs"
|
|
61
63
|
outputs = cell.get('outputs', [])
|
|
@@ -69,7 +71,7 @@ def _clean_cell_output(cell, clean_ids):
|
|
|
69
71
|
if 'text' in o and clean_ids: o['text'] = _clean_cell_output_id(o['text'])
|
|
70
72
|
o.get('metadata', {}).pop('tags', None)
|
|
71
73
|
|
|
72
|
-
# %% ../nbs/api/11_clean.ipynb
|
|
74
|
+
# %% ../nbs/api/11_clean.ipynb
|
|
73
75
|
def _clean_cell(cell, clear_all, allowed_metadata_keys, clean_ids):
|
|
74
76
|
"Clean `cell` by removing superfluous metadata or everything except the input if `clear_all`"
|
|
75
77
|
if 'execution_count' in cell: cell['execution_count'] = None
|
|
@@ -80,7 +82,7 @@ def _clean_cell(cell, clear_all, allowed_metadata_keys, clean_ids):
|
|
|
80
82
|
cell['metadata'] = {} if clear_all else {
|
|
81
83
|
k:v for k,v in cell['metadata'].items() if k in allowed_metadata_keys}
|
|
82
84
|
|
|
83
|
-
# %% ../nbs/api/11_clean.ipynb
|
|
85
|
+
# %% ../nbs/api/11_clean.ipynb
|
|
84
86
|
def clean_nb(
|
|
85
87
|
nb, # The notebook to clean
|
|
86
88
|
clear_all=False, # Remove all cell metadata and cell outputs?
|
|
@@ -98,12 +100,12 @@ def clean_nb(
|
|
|
98
100
|
nb['metadata']['kernelspec']['display_name'] = nb["metadata"]["kernelspec"]["name"]
|
|
99
101
|
nb['metadata'] = {k:v for k,v in nb['metadata'].items() if k in metadata_keys}
|
|
100
102
|
|
|
101
|
-
# %% ../nbs/api/11_clean.ipynb
|
|
103
|
+
# %% ../nbs/api/11_clean.ipynb
|
|
102
104
|
def _reconfigure(*strms):
|
|
103
105
|
for s in strms:
|
|
104
106
|
if hasattr(s,'reconfigure'): s.reconfigure(encoding='utf-8')
|
|
105
107
|
|
|
106
|
-
# %% ../nbs/api/11_clean.ipynb
|
|
108
|
+
# %% ../nbs/api/11_clean.ipynb
|
|
107
109
|
def process_write(warn_msg, proc_nb, f_in, f_out=None, disp=False):
|
|
108
110
|
if not f_out: f_out = f_in
|
|
109
111
|
if isinstance(f_in, (str,Path)): f_in = Path(f_in).open(encoding="utf-8")
|
|
@@ -116,7 +118,7 @@ def process_write(warn_msg, proc_nb, f_in, f_out=None, disp=False):
|
|
|
116
118
|
warn(f'{warn_msg}')
|
|
117
119
|
warn(e)
|
|
118
120
|
|
|
119
|
-
# %% ../nbs/api/11_clean.ipynb
|
|
121
|
+
# %% ../nbs/api/11_clean.ipynb
|
|
120
122
|
def _nbdev_clean(nb, path=None, clear_all=None):
|
|
121
123
|
cfg = get_config(path=path)
|
|
122
124
|
clear_all = clear_all or cfg.clear_all
|
|
@@ -125,7 +127,7 @@ def _nbdev_clean(nb, path=None, clear_all=None):
|
|
|
125
127
|
clean_nb(nb, clear_all, allowed_metadata_keys, allowed_cell_metadata_keys, cfg.clean_ids)
|
|
126
128
|
if path: nbdev_trust.__wrapped__(path)
|
|
127
129
|
|
|
128
|
-
# %% ../nbs/api/11_clean.ipynb
|
|
130
|
+
# %% ../nbs/api/11_clean.ipynb
|
|
129
131
|
@call_parse
|
|
130
132
|
def nbdev_clean(
|
|
131
133
|
fname:str=None, # A notebook name or glob to clean
|
|
@@ -141,7 +143,7 @@ def nbdev_clean(
|
|
|
141
143
|
if fname is None: fname = get_config().nbs_path
|
|
142
144
|
for f in globtastic(fname, file_glob='*.ipynb', skip_folder_re='^[_.]'): _write(f_in=f, disp=disp)
|
|
143
145
|
|
|
144
|
-
# %% ../nbs/api/11_clean.ipynb
|
|
146
|
+
# %% ../nbs/api/11_clean.ipynb
|
|
145
147
|
def clean_jupyter(path, model, **kwargs):
|
|
146
148
|
"Clean Jupyter `model` pre save to `path`"
|
|
147
149
|
if not (model['type']=='notebook' and model['content']['nbformat']==4): return
|
|
@@ -149,7 +151,7 @@ def clean_jupyter(path, model, **kwargs):
|
|
|
149
151
|
jupyter_hooks = get_config(path=path).jupyter_hooks
|
|
150
152
|
if jupyter_hooks: _nbdev_clean(model['content'], path=path)
|
|
151
153
|
|
|
152
|
-
# %% ../nbs/api/11_clean.ipynb
|
|
154
|
+
# %% ../nbs/api/11_clean.ipynb
|
|
153
155
|
_pre_save_hook_src = '''
|
|
154
156
|
def nbdev_clean_jupyter(**kwargs):
|
|
155
157
|
try: from nbdev.clean import clean_jupyter
|
|
@@ -159,7 +161,7 @@ def nbdev_clean_jupyter(**kwargs):
|
|
|
159
161
|
c.ContentsManager.pre_save_hook = nbdev_clean_jupyter'''.strip()
|
|
160
162
|
_pre_save_hook_re = re.compile(r'c\.(File)?ContentsManager\.pre_save_hook')
|
|
161
163
|
|
|
162
|
-
# %% ../nbs/api/11_clean.ipynb
|
|
164
|
+
# %% ../nbs/api/11_clean.ipynb
|
|
163
165
|
def _add_jupyter_hooks(src, path):
|
|
164
166
|
if _pre_save_hook_src in src: return
|
|
165
167
|
mod = ast.parse(src)
|
|
@@ -177,12 +179,12 @@ def _add_jupyter_hooks(src, path):
|
|
|
177
179
|
if src: src+='\n\n'
|
|
178
180
|
return src+_pre_save_hook_src
|
|
179
181
|
|
|
180
|
-
# %% ../nbs/api/11_clean.ipynb
|
|
182
|
+
# %% ../nbs/api/11_clean.ipynb
|
|
181
183
|
def _git_root():
|
|
182
184
|
try: return Path(run('git rev-parse --show-toplevel'))
|
|
183
185
|
except OSError: return None
|
|
184
186
|
|
|
185
|
-
# %% ../nbs/api/11_clean.ipynb
|
|
187
|
+
# %% ../nbs/api/11_clean.ipynb
|
|
186
188
|
@call_parse
|
|
187
189
|
def nbdev_install_hooks():
|
|
188
190
|
"Install Jupyter and git hooks to automatically clean, trust, and fix merge conflicts in notebooks"
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"""CLI commands"""
|
|
2
|
+
|
|
1
3
|
# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/api/13_cli.ipynb.
|
|
2
4
|
|
|
3
5
|
# %% ../nbs/api/13_cli.ipynb 2
|
|
@@ -27,7 +29,7 @@ import os, tarfile, sys
|
|
|
27
29
|
# %% auto 0
|
|
28
30
|
__all__ = ['mapping', 'nbdev_filter', 'extract_tgz', 'nbdev_new', 'nbdev_update_license', 'chelp']
|
|
29
31
|
|
|
30
|
-
# %% ../nbs/api/13_cli.ipynb
|
|
32
|
+
# %% ../nbs/api/13_cli.ipynb
|
|
31
33
|
@call_parse
|
|
32
34
|
def nbdev_filter(
|
|
33
35
|
nb_txt:str=None, # Notebook text (uses stdin if not provided)
|
|
@@ -50,12 +52,12 @@ def nbdev_filter(
|
|
|
50
52
|
if printit: print(res, flush=True)
|
|
51
53
|
else: return res
|
|
52
54
|
|
|
53
|
-
# %% ../nbs/api/13_cli.ipynb
|
|
55
|
+
# %% ../nbs/api/13_cli.ipynb
|
|
54
56
|
def extract_tgz(url, dest='.'):
|
|
55
57
|
from fastcore.net import urlopen
|
|
56
58
|
with urlopen(url) as u: tarfile.open(mode='r:gz', fileobj=u).extractall(dest)
|
|
57
59
|
|
|
58
|
-
# %% ../nbs/api/13_cli.ipynb
|
|
60
|
+
# %% ../nbs/api/13_cli.ipynb
|
|
59
61
|
def _render_nb(fn, cfg):
|
|
60
62
|
"Render templated values like `{{lib_name}}` in notebook at `fn` from `cfg`"
|
|
61
63
|
txt = fn.read_text()
|
|
@@ -63,7 +65,7 @@ def _render_nb(fn, cfg):
|
|
|
63
65
|
for k,v in cfg.d.items(): txt = txt.replace('{{'+k+'}}', v)
|
|
64
66
|
fn.write_text(txt)
|
|
65
67
|
|
|
66
|
-
# %% ../nbs/api/13_cli.ipynb
|
|
68
|
+
# %% ../nbs/api/13_cli.ipynb
|
|
67
69
|
def _update_repo_meta(cfg):
|
|
68
70
|
"Enable gh pages and update the homepage and description in your GitHub repo."
|
|
69
71
|
token=os.getenv('GITHUB_TOKEN')
|
|
@@ -74,7 +76,7 @@ def _update_repo_meta(cfg):
|
|
|
74
76
|
except HTTPError:print(f"Could not update the description & URL on the repo: {cfg.user}/{cfg.repo} using $GITHUB_TOKEN.\n"
|
|
75
77
|
"Use a token with the correction permissions or perform these steps manually.")
|
|
76
78
|
|
|
77
|
-
# %% ../nbs/api/13_cli.ipynb
|
|
79
|
+
# %% ../nbs/api/13_cli.ipynb
|
|
78
80
|
@call_parse
|
|
79
81
|
@delegates(nbdev_create_config)
|
|
80
82
|
def nbdev_new(**kwargs):
|
|
@@ -83,30 +85,24 @@ def nbdev_new(**kwargs):
|
|
|
83
85
|
nbdev_create_config.__wrapped__(**kwargs)
|
|
84
86
|
cfg = get_config()
|
|
85
87
|
_update_repo_meta(cfg)
|
|
86
|
-
|
|
87
88
|
path = Path()
|
|
88
89
|
|
|
89
|
-
_ORG_OR_USR = 'fastai'
|
|
90
|
-
_REPOSITORY = 'nbdev-template'
|
|
90
|
+
_ORG_OR_USR,_REPOSITORY = 'fastai','nbdev-template'
|
|
91
91
|
_TEMPLATE = f'{_ORG_OR_USR}/{_REPOSITORY}'
|
|
92
92
|
template = kwargs.get('template', _TEMPLATE)
|
|
93
|
-
try:
|
|
94
|
-
|
|
95
|
-
except ValueError:
|
|
96
|
-
org_or_usr, repo = _ORG_OR_USR, _REPOSITORY
|
|
97
|
-
|
|
93
|
+
try: org_or_usr, repo = template.split('/')
|
|
94
|
+
except ValueError: org_or_usr, repo = _ORG_OR_USR, _REPOSITORY
|
|
98
95
|
|
|
99
96
|
tag = kwargs.get('tag', None)
|
|
100
97
|
if tag is None:
|
|
101
98
|
with warnings.catch_warnings():
|
|
102
99
|
warnings.simplefilter('ignore', UserWarning)
|
|
103
|
-
|
|
104
100
|
tag = GhApi(gh_host='https://api.github.com', authenticate=False).repos.get_latest_release(org_or_usr, repo).tag_name
|
|
105
101
|
|
|
106
102
|
url = f"https://github.com/{org_or_usr}/{repo}/archive/{tag}.tar.gz"
|
|
107
103
|
extract_tgz(url)
|
|
108
104
|
tmpl_path = path/f'{repo}-{tag}'
|
|
109
|
-
|
|
105
|
+
|
|
110
106
|
cfg.nbs_path.mkdir(exist_ok=True)
|
|
111
107
|
nbexists = bool(first(cfg.nbs_path.glob('*.ipynb')))
|
|
112
108
|
_nbs_path_sufs = ('.ipynb','.css')
|
|
@@ -119,11 +115,10 @@ def nbdev_new(**kwargs):
|
|
|
119
115
|
rmtree(tmpl_path)
|
|
120
116
|
|
|
121
117
|
refresh_quarto_yml()
|
|
122
|
-
|
|
123
118
|
nbdev_export.__wrapped__()
|
|
124
119
|
nbdev_readme.__wrapped__()
|
|
125
120
|
|
|
126
|
-
# %% ../nbs/api/13_cli.ipynb
|
|
121
|
+
# %% ../nbs/api/13_cli.ipynb
|
|
127
122
|
mapping = {
|
|
128
123
|
'mit': 'mit',
|
|
129
124
|
'apache2': 'apache-2.0',
|
|
@@ -132,7 +127,7 @@ mapping = {
|
|
|
132
127
|
'bsd3': 'bsd-3-clause'
|
|
133
128
|
}
|
|
134
129
|
|
|
135
|
-
# %% ../nbs/api/13_cli.ipynb
|
|
130
|
+
# %% ../nbs/api/13_cli.ipynb
|
|
136
131
|
@call_parse
|
|
137
132
|
def nbdev_update_license(
|
|
138
133
|
to: str=None, # update license to
|
|
@@ -163,7 +158,7 @@ def nbdev_update_license(
|
|
|
163
158
|
lic.write(body)
|
|
164
159
|
print(f"License updated from {curr_lic} to {to}")
|
|
165
160
|
|
|
166
|
-
# %% ../nbs/api/13_cli.ipynb
|
|
161
|
+
# %% ../nbs/api/13_cli.ipynb
|
|
167
162
|
@call_parse
|
|
168
163
|
def chelp():
|
|
169
164
|
"Show help for all console scripts"
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
"""
|
|
2
|
-
`get_config` is the main function for reading settings."""
|
|
1
|
+
"""Configuring nbdev and bootstrapping notebook export"""
|
|
3
2
|
|
|
4
3
|
# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/api/01_config.ipynb.
|
|
5
4
|
|
|
@@ -7,11 +6,7 @@
|
|
|
7
6
|
__all__ = ['nbdev_create_config', 'get_config', 'config_key', 'create_output', 'show_src', 'update_version', 'add_init',
|
|
8
7
|
'write_cells']
|
|
9
8
|
|
|
10
|
-
# %% ../nbs/api/01_config.ipynb
|
|
11
|
-
_doc_ = """Read and write nbdev's `settings.ini` file.
|
|
12
|
-
`get_config` is the main function for reading settings."""
|
|
13
|
-
|
|
14
|
-
# %% ../nbs/api/01_config.ipynb 3
|
|
9
|
+
# %% ../nbs/api/01_config.ipynb
|
|
15
10
|
from datetime import datetime
|
|
16
11
|
from fastcore.docments import *
|
|
17
12
|
from fastcore.utils import *
|
|
@@ -25,16 +20,16 @@ from IPython.display import Markdown
|
|
|
25
20
|
from execnb.nbio import read_nb,NbCell
|
|
26
21
|
from urllib.error import HTTPError
|
|
27
22
|
|
|
28
|
-
# %% ../nbs/api/01_config.ipynb
|
|
23
|
+
# %% ../nbs/api/01_config.ipynb
|
|
29
24
|
_nbdev_home_dir = 'nbdev' # sub-directory of xdg base dir
|
|
30
25
|
_nbdev_cfg_name = 'settings.ini'
|
|
31
26
|
|
|
32
|
-
# %% ../nbs/api/01_config.ipynb
|
|
27
|
+
# %% ../nbs/api/01_config.ipynb
|
|
33
28
|
def _git_repo():
|
|
34
29
|
try: return repo_details(run('git config --get remote.origin.url'))[1]
|
|
35
30
|
except OSError: return
|
|
36
31
|
|
|
37
|
-
# %% ../nbs/api/01_config.ipynb
|
|
32
|
+
# %% ../nbs/api/01_config.ipynb
|
|
38
33
|
# When adding a named default to the list below, be sure that that name
|
|
39
34
|
# is also added to one of the sections in `_nbdev_cfg_sections` as well,
|
|
40
35
|
# or it won't get written by `nbdev_create_config`:
|
|
@@ -82,7 +77,7 @@ def _apply_defaults(
|
|
|
82
77
|
cfg[k] = v
|
|
83
78
|
return cfg
|
|
84
79
|
|
|
85
|
-
# %% ../nbs/api/01_config.ipynb
|
|
80
|
+
# %% ../nbs/api/01_config.ipynb
|
|
86
81
|
def _get_info(owner, repo, default_branch='main', default_kw='nbdev'):
|
|
87
82
|
from ghapi.all import GhApi
|
|
88
83
|
api = GhApi(owner=owner, repo=repo, token=os.getenv('GITHUB_TOKEN'))
|
|
@@ -98,7 +93,7 @@ https://nbdev.fast.ai/api/release.html#setup"""]
|
|
|
98
93
|
|
|
99
94
|
return r.default_branch, default_kw if not getattr(r, 'topics', []) else ' '.join(r.topics), r.description
|
|
100
95
|
|
|
101
|
-
# %% ../nbs/api/01_config.ipynb
|
|
96
|
+
# %% ../nbs/api/01_config.ipynb
|
|
102
97
|
def _fetch_from_git(raise_err=False):
|
|
103
98
|
"Get information for settings.ini from the user."
|
|
104
99
|
res={}
|
|
@@ -114,7 +109,7 @@ def _fetch_from_git(raise_err=False):
|
|
|
114
109
|
else: res['lib_name'] = res['repo'].replace('-','_')
|
|
115
110
|
return res
|
|
116
111
|
|
|
117
|
-
# %% ../nbs/api/01_config.ipynb
|
|
112
|
+
# %% ../nbs/api/01_config.ipynb
|
|
118
113
|
def _prompt_user(cfg, inferred):
|
|
119
114
|
"Let user input values not in `cfg` or `inferred`."
|
|
120
115
|
res = cfg.copy()
|
|
@@ -128,7 +123,7 @@ def _prompt_user(cfg, inferred):
|
|
|
128
123
|
print(msg+res[k]+' # Automatically inferred from git')
|
|
129
124
|
return res
|
|
130
125
|
|
|
131
|
-
# %% ../nbs/api/01_config.ipynb
|
|
126
|
+
# %% ../nbs/api/01_config.ipynb
|
|
132
127
|
def _cfg2txt(cfg, head, sections, tail=''):
|
|
133
128
|
"Render `cfg` with commented sections."
|
|
134
129
|
nm = cfg.d.name
|
|
@@ -140,7 +135,7 @@ def _cfg2txt(cfg, head, sections, tail=''):
|
|
|
140
135
|
res += tail
|
|
141
136
|
return res.strip()
|
|
142
137
|
|
|
143
|
-
# %% ../nbs/api/01_config.ipynb
|
|
138
|
+
# %% ../nbs/api/01_config.ipynb
|
|
144
139
|
_nbdev_cfg_head = '''# All sections below are required unless otherwise specified.
|
|
145
140
|
# See https://github.com/fastai/nbdev/blob/master/settings.ini for examples.
|
|
146
141
|
|
|
@@ -157,7 +152,7 @@ _nbdev_cfg_tail = '''### Optional ###
|
|
|
157
152
|
# package_data =
|
|
158
153
|
'''
|
|
159
154
|
|
|
160
|
-
# %% ../nbs/api/01_config.ipynb
|
|
155
|
+
# %% ../nbs/api/01_config.ipynb
|
|
161
156
|
@call_parse
|
|
162
157
|
@delegates(_apply_defaults, but='cfg')
|
|
163
158
|
def nbdev_create_config(
|
|
@@ -183,19 +178,19 @@ def nbdev_create_config(
|
|
|
183
178
|
cfg_fn = Path(path)/cfg_name
|
|
184
179
|
print(f'{cfg_fn} created.')
|
|
185
180
|
|
|
186
|
-
# %% ../nbs/api/01_config.ipynb
|
|
181
|
+
# %% ../nbs/api/01_config.ipynb
|
|
187
182
|
def _nbdev_config_file(cfg_name=_nbdev_cfg_name, path=None):
|
|
188
183
|
cfg_path = path = Path.cwd() if path is None else Path(path)
|
|
189
184
|
while cfg_path != cfg_path.parent and not (cfg_path/cfg_name).exists(): cfg_path = cfg_path.parent
|
|
190
185
|
if not (cfg_path/cfg_name).exists(): cfg_path = path
|
|
191
186
|
return cfg_path/cfg_name
|
|
192
187
|
|
|
193
|
-
# %% ../nbs/api/01_config.ipynb
|
|
188
|
+
# %% ../nbs/api/01_config.ipynb
|
|
194
189
|
def _xdg_config_paths(cfg_name=_nbdev_cfg_name):
|
|
195
190
|
xdg_config_paths = reversed([xdg_config_home()]+xdg_config_dirs())
|
|
196
191
|
return [o/_nbdev_home_dir/cfg_name for o in xdg_config_paths]
|
|
197
192
|
|
|
198
|
-
# %% ../nbs/api/01_config.ipynb
|
|
193
|
+
# %% ../nbs/api/01_config.ipynb
|
|
199
194
|
def _type(t): return bool if t==bool_arg else t
|
|
200
195
|
_types = {k:_type(v['anno']) for k,v in docments(_apply_defaults,full=True,returns=False).items() if k != 'cfg'}
|
|
201
196
|
|
|
@@ -207,22 +202,22 @@ def get_config(cfg_name=_nbdev_cfg_name, path=None):
|
|
|
207
202
|
cfg = Config(cfg_file.parent, cfg_file.name, extra_files=extra_files, types=_types)
|
|
208
203
|
return _apply_defaults(cfg)
|
|
209
204
|
|
|
210
|
-
# %% ../nbs/api/01_config.ipynb
|
|
205
|
+
# %% ../nbs/api/01_config.ipynb
|
|
211
206
|
def config_key(c, default=None, path=True, missing_ok=None):
|
|
212
207
|
"Deprecated: use `get_config().get` or `get_config().path` instead."
|
|
213
208
|
warn("`config_key` is deprecated. Use `get_config().get` or `get_config().path` instead.", DeprecationWarning)
|
|
214
209
|
return get_config().path(c, default) if path else get_config().get(c, default)
|
|
215
210
|
|
|
216
|
-
# %% ../nbs/api/01_config.ipynb
|
|
211
|
+
# %% ../nbs/api/01_config.ipynb
|
|
217
212
|
def create_output(txt, mime):
|
|
218
213
|
"Add a cell output containing `txt` of the `mime` text MIME sub-type"
|
|
219
214
|
return [{"data": { f"text/{mime}": str(txt).splitlines(True) },
|
|
220
215
|
"execution_count": 1, "metadata": {}, "output_type": "execute_result"}]
|
|
221
216
|
|
|
222
|
-
# %% ../nbs/api/01_config.ipynb
|
|
217
|
+
# %% ../nbs/api/01_config.ipynb
|
|
223
218
|
def show_src(src, lang='python'): return Markdown(f'```{lang}\n{src}\n```')
|
|
224
219
|
|
|
225
|
-
# %% ../nbs/api/01_config.ipynb
|
|
220
|
+
# %% ../nbs/api/01_config.ipynb
|
|
226
221
|
_re_version = re.compile(r'^__version__\s*=.*$', re.MULTILINE)
|
|
227
222
|
_init = '__init__.py'
|
|
228
223
|
|
|
@@ -251,15 +246,15 @@ def add_init(path=None):
|
|
|
251
246
|
if _has_py(fs) or any(filter(_has_py, subds)) and not (r/_init).exists(): (r/_init).touch()
|
|
252
247
|
if get_config().get('put_version_in_init', True): update_version(path)
|
|
253
248
|
|
|
254
|
-
# %% ../nbs/api/01_config.ipynb
|
|
249
|
+
# %% ../nbs/api/01_config.ipynb
|
|
255
250
|
def write_cells(cells, hdr, file, offset=0, cell_number=True):
|
|
256
251
|
"Write `cells` to `file` along with header `hdr` starting at index `offset` (mainly for nbdev internal use)."
|
|
257
252
|
for cell in cells:
|
|
258
|
-
if cell.source.strip():
|
|
253
|
+
if cell.cell_type=='code' and cell.source.strip():
|
|
259
254
|
idx = f" {cell.idx_+offset}" if cell_number else ""
|
|
260
255
|
file.write(f'\n\n{hdr}{idx}\n{cell.source}')
|
|
261
256
|
|
|
262
|
-
# %% ../nbs/api/01_config.ipynb
|
|
257
|
+
# %% ../nbs/api/01_config.ipynb
|
|
263
258
|
def _basic_export_nb(fname, name, dest=None):
|
|
264
259
|
"Basic exporter to bootstrap nbdev."
|
|
265
260
|
if dest is None: dest = get_config().lib_path
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
"""Generating a documentation index from a module"""
|
|
2
|
+
|
|
1
3
|
# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/api/05_doclinks.ipynb.
|
|
2
4
|
|
|
3
5
|
# %% auto 0
|
|
4
6
|
__all__ = ['patch_name', 'nbglob', 'nbglob_cli', 'nbdev_export', 'NbdevLookup']
|
|
5
7
|
|
|
6
|
-
# %% ../nbs/api/05_doclinks.ipynb
|
|
8
|
+
# %% ../nbs/api/05_doclinks.ipynb
|
|
7
9
|
from .config import *
|
|
8
10
|
from .maker import *
|
|
9
11
|
from .export import *
|
|
@@ -21,7 +23,7 @@ from pprint import pformat
|
|
|
21
23
|
from urllib.parse import urljoin
|
|
22
24
|
from functools import lru_cache
|
|
23
25
|
|
|
24
|
-
# %% ../nbs/api/05_doclinks.ipynb
|
|
26
|
+
# %% ../nbs/api/05_doclinks.ipynb
|
|
25
27
|
def _sym_nm(klas, sym): return f'{unparse(klas).strip()}.{sym.name}'
|
|
26
28
|
|
|
27
29
|
def _binop_leafs(bo, o):
|
|
@@ -42,7 +44,7 @@ def patch_name(o):
|
|
|
42
44
|
else: return o.name
|
|
43
45
|
return _sym_nm(a,o)
|
|
44
46
|
|
|
45
|
-
# %% ../nbs/api/05_doclinks.ipynb
|
|
47
|
+
# %% ../nbs/api/05_doclinks.ipynb
|
|
46
48
|
def _iter_py_cells(p):
|
|
47
49
|
"Yield cells from an exported Python file."
|
|
48
50
|
p = Path(p)
|
|
@@ -64,10 +66,10 @@ def _iter_py_cells(p):
|
|
|
64
66
|
if code.endswith('\n'): code=code[:-1]
|
|
65
67
|
yield AttrDict(nb=nb, idx=idx, code=code, nb_path=nb_path, py_path=p.resolve())
|
|
66
68
|
|
|
67
|
-
# %% ../nbs/api/05_doclinks.ipynb
|
|
69
|
+
# %% ../nbs/api/05_doclinks.ipynb
|
|
68
70
|
def _nbpath2html(p): return p.with_name(re.sub(r'^\d+[a-zA-Z0-9]*_', '', p.name.lower())).with_suffix('.html')
|
|
69
71
|
|
|
70
|
-
# %% ../nbs/api/05_doclinks.ipynb
|
|
72
|
+
# %% ../nbs/api/05_doclinks.ipynb
|
|
71
73
|
def _get_modidx(py_path, code_root, nbs_path):
|
|
72
74
|
"Get module symbol index for a Python source file"
|
|
73
75
|
cfg = get_config()
|
|
@@ -89,7 +91,7 @@ def _get_modidx(py_path, code_root, nbs_path):
|
|
|
89
91
|
if isinstance(t2, _def_types): _stor(f'{tree.name}.{t2.name}')
|
|
90
92
|
return {mod_name: d}
|
|
91
93
|
|
|
92
|
-
# %% ../nbs/api/05_doclinks.ipynb
|
|
94
|
+
# %% ../nbs/api/05_doclinks.ipynb
|
|
93
95
|
def _build_modidx(dest=None, nbs_path=None, skip_exists=False):
|
|
94
96
|
"Create _modidx.py"
|
|
95
97
|
if dest is None: dest = get_config().lib_path
|
|
@@ -108,7 +110,7 @@ def _build_modidx(dest=None, nbs_path=None, skip_exists=False):
|
|
|
108
110
|
res['syms'].update(_get_modidx((dest.parent/file).resolve(), code_root, nbs_path=nbs_path))
|
|
109
111
|
idxfile.write_text("# Autogenerated by nbdev\n\nd = "+pformat(res, width=140, indent=2, compact=True)+'\n')
|
|
110
112
|
|
|
111
|
-
# %% ../nbs/api/05_doclinks.ipynb
|
|
113
|
+
# %% ../nbs/api/05_doclinks.ipynb
|
|
112
114
|
@delegates(globtastic)
|
|
113
115
|
def nbglob(path=None, skip_folder_re = '^[_.]', file_glob='*.ipynb', skip_file_re='^[_.]', key='nbs_path', as_path=False, **kwargs):
|
|
114
116
|
"Find all files in a directory matching an extension given a config key."
|
|
@@ -118,7 +120,7 @@ def nbglob(path=None, skip_folder_re = '^[_.]', file_glob='*.ipynb', skip_file_r
|
|
|
118
120
|
skip_file_re=skip_file_re, recursive=recursive, **kwargs)
|
|
119
121
|
return res.map(Path) if as_path else res
|
|
120
122
|
|
|
121
|
-
# %% ../nbs/api/05_doclinks.ipynb
|
|
123
|
+
# %% ../nbs/api/05_doclinks.ipynb
|
|
122
124
|
def nbglob_cli(
|
|
123
125
|
path:str=None, # Path to notebooks
|
|
124
126
|
symlinks:bool=False, # Follow symlinks?
|
|
@@ -132,7 +134,7 @@ def nbglob_cli(
|
|
|
132
134
|
return nbglob(path, symlinks=symlinks, file_glob=file_glob, file_re=file_re, folder_re=folder_re,
|
|
133
135
|
skip_file_glob=skip_file_glob, skip_file_re=skip_file_re, skip_folder_re=skip_folder_re)
|
|
134
136
|
|
|
135
|
-
# %% ../nbs/api/05_doclinks.ipynb
|
|
137
|
+
# %% ../nbs/api/05_doclinks.ipynb
|
|
136
138
|
@call_parse
|
|
137
139
|
@delegates(nbglob_cli)
|
|
138
140
|
def nbdev_export(
|
|
@@ -149,11 +151,11 @@ def nbdev_export(
|
|
|
149
151
|
add_init(get_config().lib_path)
|
|
150
152
|
_build_modidx()
|
|
151
153
|
|
|
152
|
-
# %% ../nbs/api/05_doclinks.ipynb
|
|
154
|
+
# %% ../nbs/api/05_doclinks.ipynb
|
|
153
155
|
import importlib,ast
|
|
154
156
|
from functools import lru_cache
|
|
155
157
|
|
|
156
|
-
# %% ../nbs/api/05_doclinks.ipynb
|
|
158
|
+
# %% ../nbs/api/05_doclinks.ipynb
|
|
157
159
|
def _find_mod(mod):
|
|
158
160
|
mp,_,mr = mod.partition('/')
|
|
159
161
|
spec = importlib.util.find_spec(mp)
|
|
@@ -176,7 +178,7 @@ def _get_exps(mod):
|
|
|
176
178
|
|
|
177
179
|
def _lineno(sym, fname): return _get_exps(fname).get(sym, None) if fname else None
|
|
178
180
|
|
|
179
|
-
# %% ../nbs/api/05_doclinks.ipynb
|
|
181
|
+
# %% ../nbs/api/05_doclinks.ipynb
|
|
180
182
|
def _qual_sym(s, settings):
|
|
181
183
|
if not isinstance(s,tuple): return s
|
|
182
184
|
nb,py = s
|
|
@@ -191,10 +193,10 @@ def _qual_syms(entries):
|
|
|
191
193
|
if 'doc_host' not in settings: return entries
|
|
192
194
|
return {'syms': {mod:_qual_mod(d, settings) for mod,d in entries['syms'].items()}, 'settings':settings}
|
|
193
195
|
|
|
194
|
-
# %% ../nbs/api/05_doclinks.ipynb
|
|
196
|
+
# %% ../nbs/api/05_doclinks.ipynb
|
|
195
197
|
_re_backticks = re.compile(r'`([^`\s]+)`')
|
|
196
198
|
|
|
197
|
-
# %% ../nbs/api/05_doclinks.ipynb
|
|
199
|
+
# %% ../nbs/api/05_doclinks.ipynb
|
|
198
200
|
@lru_cache(None)
|
|
199
201
|
class NbdevLookup:
|
|
200
202
|
"Mapping from symbol names to docs and source URLs"
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
"""Exporting a notebook to a library"""
|
|
2
|
+
|
|
1
3
|
# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/api/04_export.ipynb.
|
|
2
4
|
|
|
3
5
|
# %% auto 0
|
|
4
6
|
__all__ = ['ExportModuleProc', 'black_format', 'scrub_magics', 'optional_procs', 'nb_export']
|
|
5
7
|
|
|
6
|
-
# %% ../nbs/api/04_export.ipynb
|
|
8
|
+
# %% ../nbs/api/04_export.ipynb
|
|
7
9
|
from .config import *
|
|
8
10
|
from .maker import *
|
|
9
11
|
from .imports import *
|
|
@@ -15,7 +17,7 @@ from fastcore.imports import *
|
|
|
15
17
|
|
|
16
18
|
from collections import defaultdict
|
|
17
19
|
|
|
18
|
-
# %% ../nbs/api/04_export.ipynb
|
|
20
|
+
# %% ../nbs/api/04_export.ipynb
|
|
19
21
|
class ExportModuleProc:
|
|
20
22
|
"A processor which exports code to a module"
|
|
21
23
|
def begin(self): self.modules,self.in_all = defaultdict(L),defaultdict(L)
|
|
@@ -24,9 +26,13 @@ class ExportModuleProc:
|
|
|
24
26
|
def _export_(self, cell, exp_to=None):
|
|
25
27
|
self._exporti_(cell, exp_to)
|
|
26
28
|
self.in_all[ifnone(exp_to, '#')].append(cell)
|
|
29
|
+
def __call__(self, cell):
|
|
30
|
+
src = cell.source
|
|
31
|
+
if not src: return
|
|
32
|
+
if cell.cell_type=='markdown' and src.startswith('# '): self.modules['#'].append(cell)
|
|
27
33
|
_exports_=_export_
|
|
28
34
|
|
|
29
|
-
# %% ../nbs/api/04_export.ipynb
|
|
35
|
+
# %% ../nbs/api/04_export.ipynb
|
|
30
36
|
def black_format(cell, # Cell to format
|
|
31
37
|
force=False): # Turn black formatting on regardless of settings.ini
|
|
32
38
|
"Processor to format code with `black`"
|
|
@@ -40,7 +46,7 @@ def black_format(cell, # Cell to format
|
|
|
40
46
|
try: cell.source = _format_str(cell.source).strip()
|
|
41
47
|
except: pass
|
|
42
48
|
|
|
43
|
-
# %% ../nbs/api/04_export.ipynb
|
|
49
|
+
# %% ../nbs/api/04_export.ipynb
|
|
44
50
|
# includes the newline, because calling .strip() would affect all cells.
|
|
45
51
|
_magics_pattern = re.compile(r'^\s*(%%|%).*\n?', re.MULTILINE)
|
|
46
52
|
|
|
@@ -52,14 +58,14 @@ def scrub_magics(cell): # Cell to format
|
|
|
52
58
|
try: cell.source = _magics_pattern.sub('', cell.source)
|
|
53
59
|
except: pass
|
|
54
60
|
|
|
55
|
-
# %% ../nbs/api/04_export.ipynb
|
|
61
|
+
# %% ../nbs/api/04_export.ipynb
|
|
56
62
|
import nbdev.export
|
|
57
63
|
def optional_procs():
|
|
58
64
|
"An explicit list of processors that could be used by `nb_export`"
|
|
59
65
|
return L([p for p in nbdev.export.__all__
|
|
60
66
|
if p not in ["nb_export", "ExportModuleProc", "optional_procs"]])
|
|
61
67
|
|
|
62
|
-
# %% ../nbs/api/04_export.ipynb
|
|
68
|
+
# %% ../nbs/api/04_export.ipynb
|
|
63
69
|
def nb_export(nbname, lib_path=None, procs=None, debug=False, mod_maker=ModuleMaker, name=None):
|
|
64
70
|
"Create module(s) from notebook"
|
|
65
71
|
if lib_path is None: lib_path = get_config().lib_path
|
|
@@ -67,12 +73,13 @@ def nb_export(nbname, lib_path=None, procs=None, debug=False, mod_maker=ModuleMa
|
|
|
67
73
|
nb = NBProcessor(nbname, [exp]+L(procs), debug=debug)
|
|
68
74
|
nb.process()
|
|
69
75
|
for mod,cells in exp.modules.items():
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
76
|
+
if first(1 for o in cells if o.cell_type=='code'):
|
|
77
|
+
all_cells = exp.in_all[mod]
|
|
78
|
+
nm = ifnone(name, getattr(exp, 'default_exp', None) if mod=='#' else mod)
|
|
79
|
+
if not nm:
|
|
80
|
+
warn(f"Notebook '{nbname}' uses `#|export` without `#|default_exp` cell.\n"
|
|
81
|
+
"Note nbdev2 no longer supports nbdev1 syntax. Run `nbdev_migrate` to upgrade.\n"
|
|
82
|
+
"See https://nbdev.fast.ai/getting_started.html for more information.")
|
|
83
|
+
return
|
|
84
|
+
mm = mod_maker(dest=lib_path, name=nm, nb_path=nbname, is_new=bool(name) or mod=='#')
|
|
85
|
+
mm.make(cells, all_cells, lib_path=lib_path)
|