Skip to content

Commit 28c8f42

Browse files
committed
fixes #1439
1 parent f59fd2d commit 28c8f42

20 files changed

+242
-236
lines changed

nbdev/clean.py

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# %% auto 0
44
__all__ = ['nbdev_trust', 'clean_nb', 'process_write', 'nbdev_clean', 'clean_jupyter', 'nbdev_install_hooks']
55

6-
# %% ../nbs/api/11_clean.ipynb 2
6+
# %% ../nbs/api/11_clean.ipynb
77
import ast,warnings,stat
88
from astunparse import unparse
99
from textwrap import indent
@@ -18,7 +18,7 @@
1818
from .sync import *
1919
from .process import first_code_ln
2020

21-
# %% ../nbs/api/11_clean.ipynb 6
21+
# %% ../nbs/api/11_clean.ipynb
2222
@call_parse
2323
def nbdev_trust(
2424
fname:str=None, # A notebook name or glob to trust
@@ -45,7 +45,7 @@ def nbdev_trust(
4545
if not NotebookNotary().check_signature(nb): NotebookNotary().sign(nb)
4646
check_fname.touch(exist_ok=True)
4747

48-
# %% ../nbs/api/11_clean.ipynb 9
48+
# %% ../nbs/api/11_clean.ipynb
4949
_repr_id_re = re.compile('(<.*?)( at 0x[0-9a-fA-F]+)(>)')
5050

5151
_sub = partial(_repr_id_re.sub, r'\1\3')
@@ -55,7 +55,7 @@ def _skip_or_sub(x): return _sub(x) if "at 0x" in x else x
5555
def _clean_cell_output_id(lines):
5656
return _skip_or_sub(lines) if isinstance(lines,str) else [_skip_or_sub(o) for o in lines]
5757

58-
# %% ../nbs/api/11_clean.ipynb 11
58+
# %% ../nbs/api/11_clean.ipynb
5959
def _clean_cell_output(cell, clean_ids):
6060
"Remove `cell` output execution count and optionally ids from text reprs"
6161
outputs = cell.get('outputs', [])
@@ -69,7 +69,7 @@ def _clean_cell_output(cell, clean_ids):
6969
if 'text' in o and clean_ids: o['text'] = _clean_cell_output_id(o['text'])
7070
o.get('metadata', {}).pop('tags', None)
7171

72-
# %% ../nbs/api/11_clean.ipynb 12
72+
# %% ../nbs/api/11_clean.ipynb
7373
def _clean_cell(cell, clear_all, allowed_metadata_keys, clean_ids):
7474
"Clean `cell` by removing superfluous metadata or everything except the input if `clear_all`"
7575
if 'execution_count' in cell: cell['execution_count'] = None
@@ -80,7 +80,7 @@ def _clean_cell(cell, clear_all, allowed_metadata_keys, clean_ids):
8080
cell['metadata'] = {} if clear_all else {
8181
k:v for k,v in cell['metadata'].items() if k in allowed_metadata_keys}
8282

83-
# %% ../nbs/api/11_clean.ipynb 13
83+
# %% ../nbs/api/11_clean.ipynb
8484
def clean_nb(
8585
nb, # The notebook to clean
8686
clear_all=False, # Remove all cell metadata and cell outputs?
@@ -98,12 +98,12 @@ def clean_nb(
9898
nb['metadata']['kernelspec']['display_name'] = nb["metadata"]["kernelspec"]["name"]
9999
nb['metadata'] = {k:v for k,v in nb['metadata'].items() if k in metadata_keys}
100100

101-
# %% ../nbs/api/11_clean.ipynb 26
101+
# %% ../nbs/api/11_clean.ipynb
102102
def _reconfigure(*strms):
103103
for s in strms:
104104
if hasattr(s,'reconfigure'): s.reconfigure(encoding='utf-8')
105105

106-
# %% ../nbs/api/11_clean.ipynb 27
106+
# %% ../nbs/api/11_clean.ipynb
107107
def process_write(warn_msg, proc_nb, f_in, f_out=None, disp=False):
108108
if not f_out: f_out = f_in
109109
if isinstance(f_in, (str,Path)): f_in = Path(f_in).open(encoding="utf-8")
@@ -116,7 +116,7 @@ def process_write(warn_msg, proc_nb, f_in, f_out=None, disp=False):
116116
warn(f'{warn_msg}')
117117
warn(e)
118118

119-
# %% ../nbs/api/11_clean.ipynb 28
119+
# %% ../nbs/api/11_clean.ipynb
120120
def _nbdev_clean(nb, path=None, clear_all=None):
121121
cfg = get_config(path=path)
122122
clear_all = clear_all or cfg.clear_all
@@ -125,7 +125,7 @@ def _nbdev_clean(nb, path=None, clear_all=None):
125125
clean_nb(nb, clear_all, allowed_metadata_keys, allowed_cell_metadata_keys, cfg.clean_ids)
126126
if path: nbdev_trust.__wrapped__(path)
127127

128-
# %% ../nbs/api/11_clean.ipynb 29
128+
# %% ../nbs/api/11_clean.ipynb
129129
@call_parse
130130
def nbdev_clean(
131131
fname:str=None, # A notebook name or glob to clean
@@ -141,15 +141,15 @@ def nbdev_clean(
141141
if fname is None: fname = get_config().nbs_path
142142
for f in globtastic(fname, file_glob='*.ipynb', skip_folder_re='^[_.]'): _write(f_in=f, disp=disp)
143143

144-
# %% ../nbs/api/11_clean.ipynb 32
144+
# %% ../nbs/api/11_clean.ipynb
145145
def clean_jupyter(path, model, **kwargs):
146146
"Clean Jupyter `model` pre save to `path`"
147147
if not (model['type']=='notebook' and model['content']['nbformat']==4): return
148148
get_config.cache_clear() # Allow config changes without restarting Jupyter
149149
jupyter_hooks = get_config(path=path).jupyter_hooks
150150
if jupyter_hooks: _nbdev_clean(model['content'], path=path)
151151

152-
# %% ../nbs/api/11_clean.ipynb 35
152+
# %% ../nbs/api/11_clean.ipynb
153153
_pre_save_hook_src = '''
154154
def nbdev_clean_jupyter(**kwargs):
155155
try: from nbdev.clean import clean_jupyter
@@ -159,7 +159,7 @@ def nbdev_clean_jupyter(**kwargs):
159159
c.ContentsManager.pre_save_hook = nbdev_clean_jupyter'''.strip()
160160
_pre_save_hook_re = re.compile(r'c\.(File)?ContentsManager\.pre_save_hook')
161161

162-
# %% ../nbs/api/11_clean.ipynb 36
162+
# %% ../nbs/api/11_clean.ipynb
163163
def _add_jupyter_hooks(src, path):
164164
if _pre_save_hook_src in src: return
165165
mod = ast.parse(src)
@@ -177,12 +177,12 @@ def _add_jupyter_hooks(src, path):
177177
if src: src+='\n\n'
178178
return src+_pre_save_hook_src
179179

180-
# %% ../nbs/api/11_clean.ipynb 40
180+
# %% ../nbs/api/11_clean.ipynb
181181
def _git_root():
182182
try: return Path(run('git rev-parse --show-toplevel'))
183183
except OSError: return None
184184

185-
# %% ../nbs/api/11_clean.ipynb 43
185+
# %% ../nbs/api/11_clean.ipynb
186186
@call_parse
187187
def nbdev_install_hooks():
188188
"Install Jupyter and git hooks to automatically clean, trust, and fix merge conflicts in notebooks"

nbdev/cli.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
# %% auto 0
2828
__all__ = ['mapping', 'nbdev_filter', 'extract_tgz', 'nbdev_new', 'nbdev_update_license', 'chelp']
2929

30-
# %% ../nbs/api/13_cli.ipynb 5
30+
# %% ../nbs/api/13_cli.ipynb
3131
@call_parse
3232
def nbdev_filter(
3333
nb_txt:str=None, # Notebook text (uses stdin if not provided)
@@ -50,20 +50,20 @@ def nbdev_filter(
5050
if printit: print(res, flush=True)
5151
else: return res
5252

53-
# %% ../nbs/api/13_cli.ipynb 8
53+
# %% ../nbs/api/13_cli.ipynb
5454
def extract_tgz(url, dest='.'):
5555
from fastcore.net import urlopen
5656
with urlopen(url) as u: tarfile.open(mode='r:gz', fileobj=u).extractall(dest)
5757

58-
# %% ../nbs/api/13_cli.ipynb 9
58+
# %% ../nbs/api/13_cli.ipynb
5959
def _render_nb(fn, cfg):
6060
"Render templated values like `{{lib_name}}` in notebook at `fn` from `cfg`"
6161
txt = fn.read_text()
6262
txt = txt.replace('from your_lib.core', f'from {cfg.lib_path}.core') # for compatibility with old templates
6363
for k,v in cfg.d.items(): txt = txt.replace('{{'+k+'}}', v)
6464
fn.write_text(txt)
6565

66-
# %% ../nbs/api/13_cli.ipynb 10
66+
# %% ../nbs/api/13_cli.ipynb
6767
def _update_repo_meta(cfg):
6868
"Enable gh pages and update the homepage and description in your GitHub repo."
6969
token=os.getenv('GITHUB_TOKEN')
@@ -74,7 +74,7 @@ def _update_repo_meta(cfg):
7474
except HTTPError:print(f"Could not update the description & URL on the repo: {cfg.user}/{cfg.repo} using $GITHUB_TOKEN.\n"
7575
"Use a token with the correction permissions or perform these steps manually.")
7676

77-
# %% ../nbs/api/13_cli.ipynb 11
77+
# %% ../nbs/api/13_cli.ipynb
7878
@call_parse
7979
@delegates(nbdev_create_config)
8080
def nbdev_new(**kwargs):
@@ -123,7 +123,7 @@ def nbdev_new(**kwargs):
123123
nbdev_export.__wrapped__()
124124
nbdev_readme.__wrapped__()
125125

126-
# %% ../nbs/api/13_cli.ipynb 13
126+
# %% ../nbs/api/13_cli.ipynb
127127
mapping = {
128128
'mit': 'mit',
129129
'apache2': 'apache-2.0',
@@ -132,7 +132,7 @@ def nbdev_new(**kwargs):
132132
'bsd3': 'bsd-3-clause'
133133
}
134134

135-
# %% ../nbs/api/13_cli.ipynb 14
135+
# %% ../nbs/api/13_cli.ipynb
136136
@call_parse
137137
def nbdev_update_license(
138138
to: str=None, # update license to
@@ -163,7 +163,7 @@ def nbdev_update_license(
163163
lic.write(body)
164164
print(f"License updated from {curr_lic} to {to}")
165165

166-
# %% ../nbs/api/13_cli.ipynb 17
166+
# %% ../nbs/api/13_cli.ipynb
167167
@call_parse
168168
def chelp():
169169
"Show help for all console scripts"

nbdev/config.py

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77
__all__ = ['nbdev_create_config', 'get_config', 'config_key', 'create_output', 'show_src', 'update_version', 'add_init',
88
'write_cells']
99

10-
# %% ../nbs/api/01_config.ipynb 2
10+
# %% ../nbs/api/01_config.ipynb
1111
_doc_ = """Read and write nbdev's `settings.ini` file.
1212
`get_config` is the main function for reading settings."""
1313

14-
# %% ../nbs/api/01_config.ipynb 3
14+
# %% ../nbs/api/01_config.ipynb
1515
from datetime import datetime
1616
from fastcore.docments import *
1717
from fastcore.utils import *
@@ -25,16 +25,16 @@
2525
from execnb.nbio import read_nb,NbCell
2626
from urllib.error import HTTPError
2727

28-
# %% ../nbs/api/01_config.ipynb 8
28+
# %% ../nbs/api/01_config.ipynb
2929
_nbdev_home_dir = 'nbdev' # sub-directory of xdg base dir
3030
_nbdev_cfg_name = 'settings.ini'
3131

32-
# %% ../nbs/api/01_config.ipynb 9
32+
# %% ../nbs/api/01_config.ipynb
3333
def _git_repo():
3434
try: return repo_details(run('git config --get remote.origin.url'))[1]
3535
except OSError: return
3636

37-
# %% ../nbs/api/01_config.ipynb 11
37+
# %% ../nbs/api/01_config.ipynb
3838
# When adding a named default to the list below, be sure that that name
3939
# is also added to one of the sections in `_nbdev_cfg_sections` as well,
4040
# or it won't get written by `nbdev_create_config`:
@@ -82,7 +82,7 @@ def _apply_defaults(
8282
cfg[k] = v
8383
return cfg
8484

85-
# %% ../nbs/api/01_config.ipynb 12
85+
# %% ../nbs/api/01_config.ipynb
8686
def _get_info(owner, repo, default_branch='main', default_kw='nbdev'):
8787
from ghapi.all import GhApi
8888
api = GhApi(owner=owner, repo=repo, token=os.getenv('GITHUB_TOKEN'))
@@ -98,7 +98,7 @@ def _get_info(owner, repo, default_branch='main', default_kw='nbdev'):
9898

9999
return r.default_branch, default_kw if not getattr(r, 'topics', []) else ' '.join(r.topics), r.description
100100

101-
# %% ../nbs/api/01_config.ipynb 14
101+
# %% ../nbs/api/01_config.ipynb
102102
def _fetch_from_git(raise_err=False):
103103
"Get information for settings.ini from the user."
104104
res={}
@@ -114,7 +114,7 @@ def _fetch_from_git(raise_err=False):
114114
else: res['lib_name'] = res['repo'].replace('-','_')
115115
return res
116116

117-
# %% ../nbs/api/01_config.ipynb 16
117+
# %% ../nbs/api/01_config.ipynb
118118
def _prompt_user(cfg, inferred):
119119
"Let user input values not in `cfg` or `inferred`."
120120
res = cfg.copy()
@@ -128,7 +128,7 @@ def _prompt_user(cfg, inferred):
128128
print(msg+res[k]+' # Automatically inferred from git')
129129
return res
130130

131-
# %% ../nbs/api/01_config.ipynb 18
131+
# %% ../nbs/api/01_config.ipynb
132132
def _cfg2txt(cfg, head, sections, tail=''):
133133
"Render `cfg` with commented sections."
134134
nm = cfg.d.name
@@ -140,7 +140,7 @@ def _cfg2txt(cfg, head, sections, tail=''):
140140
res += tail
141141
return res.strip()
142142

143-
# %% ../nbs/api/01_config.ipynb 20
143+
# %% ../nbs/api/01_config.ipynb
144144
_nbdev_cfg_head = '''# All sections below are required unless otherwise specified.
145145
# See https://github.com/fastai/nbdev/blob/master/settings.ini for examples.
146146
@@ -157,7 +157,7 @@ def _cfg2txt(cfg, head, sections, tail=''):
157157
# package_data =
158158
'''
159159

160-
# %% ../nbs/api/01_config.ipynb 21
160+
# %% ../nbs/api/01_config.ipynb
161161
@call_parse
162162
@delegates(_apply_defaults, but='cfg')
163163
def nbdev_create_config(
@@ -183,19 +183,19 @@ def nbdev_create_config(
183183
cfg_fn = Path(path)/cfg_name
184184
print(f'{cfg_fn} created.')
185185

186-
# %% ../nbs/api/01_config.ipynb 24
186+
# %% ../nbs/api/01_config.ipynb
187187
def _nbdev_config_file(cfg_name=_nbdev_cfg_name, path=None):
188188
cfg_path = path = Path.cwd() if path is None else Path(path)
189189
while cfg_path != cfg_path.parent and not (cfg_path/cfg_name).exists(): cfg_path = cfg_path.parent
190190
if not (cfg_path/cfg_name).exists(): cfg_path = path
191191
return cfg_path/cfg_name
192192

193-
# %% ../nbs/api/01_config.ipynb 26
193+
# %% ../nbs/api/01_config.ipynb
194194
def _xdg_config_paths(cfg_name=_nbdev_cfg_name):
195195
xdg_config_paths = reversed([xdg_config_home()]+xdg_config_dirs())
196196
return [o/_nbdev_home_dir/cfg_name for o in xdg_config_paths]
197197

198-
# %% ../nbs/api/01_config.ipynb 27
198+
# %% ../nbs/api/01_config.ipynb
199199
def _type(t): return bool if t==bool_arg else t
200200
_types = {k:_type(v['anno']) for k,v in docments(_apply_defaults,full=True,returns=False).items() if k != 'cfg'}
201201

@@ -207,22 +207,22 @@ def get_config(cfg_name=_nbdev_cfg_name, path=None):
207207
cfg = Config(cfg_file.parent, cfg_file.name, extra_files=extra_files, types=_types)
208208
return _apply_defaults(cfg)
209209

210-
# %% ../nbs/api/01_config.ipynb 42
210+
# %% ../nbs/api/01_config.ipynb
211211
def config_key(c, default=None, path=True, missing_ok=None):
212212
"Deprecated: use `get_config().get` or `get_config().path` instead."
213213
warn("`config_key` is deprecated. Use `get_config().get` or `get_config().path` instead.", DeprecationWarning)
214214
return get_config().path(c, default) if path else get_config().get(c, default)
215215

216-
# %% ../nbs/api/01_config.ipynb 44
216+
# %% ../nbs/api/01_config.ipynb
217217
def create_output(txt, mime):
218218
"Add a cell output containing `txt` of the `mime` text MIME sub-type"
219219
return [{"data": { f"text/{mime}": str(txt).splitlines(True) },
220220
"execution_count": 1, "metadata": {}, "output_type": "execute_result"}]
221221

222-
# %% ../nbs/api/01_config.ipynb 45
222+
# %% ../nbs/api/01_config.ipynb
223223
def show_src(src, lang='python'): return Markdown(f'```{lang}\n{src}\n```')
224224

225-
# %% ../nbs/api/01_config.ipynb 48
225+
# %% ../nbs/api/01_config.ipynb
226226
_re_version = re.compile(r'^__version__\s*=.*$', re.MULTILINE)
227227
_init = '__init__.py'
228228

@@ -251,15 +251,15 @@ def add_init(path=None):
251251
if _has_py(fs) or any(filter(_has_py, subds)) and not (r/_init).exists(): (r/_init).touch()
252252
if get_config().get('put_version_in_init', True): update_version(path)
253253

254-
# %% ../nbs/api/01_config.ipynb 51
254+
# %% ../nbs/api/01_config.ipynb
255255
def write_cells(cells, hdr, file, offset=0, cell_number=True):
256256
"Write `cells` to `file` along with header `hdr` starting at index `offset` (mainly for nbdev internal use)."
257257
for cell in cells:
258258
if cell.source.strip():
259259
idx = f" {cell.idx_+offset}" if cell_number else ""
260260
file.write(f'\n\n{hdr}{idx}\n{cell.source}')
261261

262-
# %% ../nbs/api/01_config.ipynb 52
262+
# %% ../nbs/api/01_config.ipynb
263263
def _basic_export_nb(fname, name, dest=None):
264264
"Basic exporter to bootstrap nbdev."
265265
if dest is None: dest = get_config().lib_path

0 commit comments

Comments
 (0)