Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion nbdev/export.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def _export_(self, cell, exp_to=None):
def __call__(self, cell):
src = cell.source
if not src: return
if cell.cell_type=='markdown' and src.startswith('# '): self.modules['#'].append(cell)
if cell.cell_type=='markdown' and (src.startswith('# ') or 'export' in cell.directives_): self._exporti_(cell)
_exports_=_export_

# %% ../nbs/api/04_export.ipynb #76717e36
Expand Down
7 changes: 4 additions & 3 deletions nbdev/maker.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,14 +175,15 @@ def _import2relative(cells, lib_path=None):

# %% ../nbs/api/02_maker.ipynb #5bff9d71
def _retr_mdoc(cells):
"Search for md meta quote lines, used to create module docstring"
"Search for markdown cells used to create module docstring"
md1 = first(o for o in cells if o.cell_type=='markdown' and o.source.startswith('# '))
if not md1: return ''
lines = dropwhile(lambda l: not l.startswith('> '), md1.source.splitlines())
lines = list(takewhile(lambda l: l.startswith('> '), lines))
if not lines: return ''
summ = '\n'.join(l.lstrip('> ').strip() for l in lines)
return f'"""{summ}"""\n\n' if summ else ''
docs = L(o.source.rstrip() for o in cells if o.cell_type=='markdown' and 'export' in getattr(o,'directives_',{}))
mdoc = '\n\n'.join(L(summ)+docs).strip()
return f'"""{mdoc}\n"""\n\n' if mdoc else ''

# %% ../nbs/api/02_maker.ipynb #cdd205d6
@patch
Expand Down
5 changes: 3 additions & 2 deletions nbdev/processors.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,9 @@ def rm_header_dash(cell):
_hide_dirs = {'export','exporti', 'hide','default_exp'}

def rm_export(cell):
"Remove cells that are exported or hidden"
if cell.directives_ and (cell.directives_.keys() & _hide_dirs): del(cell['source'])
"Remove code cells that are exported or hidden"
if cell.cell_type=='code' and cell.directives_ and (cell.directives_.keys() & _hide_dirs): del(cell['source'])


# %% ../nbs/api/10_processors.ipynb #2d9a0a30
_re_showdoc = re.compile(r'^show_doc', re.MULTILINE)
Expand Down
122 changes: 100 additions & 22 deletions nbs/api/02_maker.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -491,14 +491,15 @@
"source": [
"#| export\n",
"def _retr_mdoc(cells):\n",
" \"Search for md meta quote lines, used to create module docstring\"\n",
" \"Search for markdown cells used to create module docstring\"\n",
" md1 = first(o for o in cells if o.cell_type=='markdown' and o.source.startswith('# '))\n",
" if not md1: return ''\n",
" lines = dropwhile(lambda l: not l.startswith('> '), md1.source.splitlines())\n",
" lines = list(takewhile(lambda l: l.startswith('> '), lines))\n",
" if not lines: return ''\n",
" summ = '\\n'.join(l.lstrip('> ').strip() for l in lines)\n",
" return f'\"\"\"{summ}\"\"\"\\n\\n' if summ else ''"
" docs = L(o.source.rstrip() for o in cells if o.cell_type=='markdown' and 'export' in getattr(o,'directives_',{}))\n",
" mdoc = '\\n\\n'.join(L(summ)+docs).strip()\n",
" return f'\"\"\"{mdoc}\\n\"\"\"\\n\\n' if mdoc else ''"
]
},
{
Expand All @@ -510,7 +511,10 @@
"source": [
"#| hide\n",
"nb = read_nb('02_maker.ipynb')\n",
"test_eq(_retr_mdoc(nb.cells), '\"\"\"Create one or more modules from selected notebook cells\"\"\"\\n\\n')"
"test_eq(_retr_mdoc(nb.cells), '\"\"\"Create one or more modules from selected notebook cells\"\"\"\\n\\n')\n",
"nb.cells.append(mk_cell('Extra module docs', 'markdown'))\n",
"nb.cells[-1].directives_ = {'export': ''}\n",
"test_eq(_retr_mdoc(nb.cells), '\"\"\"Create one or more modules from selected notebook cells\\n\\nExtra module docs\"\"\"\\n\\n')\n"
]
},
{
Expand Down Expand Up @@ -557,26 +561,46 @@
{
"data": {
"text/markdown": [
"<div class=\"prose\" markdown=\"1\">\n",
"\n",
"```python\n",
"# AUTOGENERATED! DO NOT EDIT! File to edit: ../../04_export.ipynb.\n",
"\n",
"# %% ../../04_export.ipynb #73b66309\n",
"# %% ../../04_export.ipynb #dec4cd88\n",
"from __future__ import print_function\n",
"\n",
"# %% auto #0\n",
"__all__ = ['b']\n",
"\n",
"# %% ../../04_export.ipynb #c168485a\n",
"# %% ../../04_export.ipynb #b2a73a89\n",
"#| export\n",
"def a(): ...\n",
"\n",
"# %% ../../04_export.ipynb #94c4db18\n",
"# %% ../../04_export.ipynb #470e0aea\n",
"def b(): ...\n",
"\n",
"```"
"```\n",
"\n",
"</div>"
],
"text/plain": [
"<IPython.core.display.Markdown object>"
"Markdown(```python\n",
"# AUTOGENERATED! DO NOT EDIT! File to edit: ../../04_export.ipynb.\n",
"\n",
"# %% ../../04_export.ipynb #dec4cd88\n",
"from __future__ import print_function\n",
"\n",
"# %% auto #0\n",
"__all__ = ['b']\n",
"\n",
"# %% ../../04_export.ipynb #b2a73a89\n",
"#| export\n",
"def a(): ...\n",
"\n",
"# %% ../../04_export.ipynb #470e0aea\n",
"def b(): ...\n",
"\n",
"```)"
]
},
"execution_count": null,
Expand Down Expand Up @@ -637,24 +661,42 @@
{
"data": {
"text/markdown": [
"<div class=\"prose\" markdown=\"1\">\n",
"\n",
"```python\n",
"# AUTOGENERATED! DO NOT EDIT! File to edit: ../../01_export.ipynb.\n",
"\n",
"# %% ../../01_export.ipynb #cfd87ddf\n",
"# %% ../../01_export.ipynb #65e15f2e\n",
"from __future__ import print_function\n",
"\n",
"# %% ../../01_export.ipynb #23244dea\n",
"# %% ../../01_export.ipynb #1e9ea7e8\n",
"#| export\n",
"def a(): ...\n",
"\n",
"# %% ../../01_export.ipynb #c710d552\n",
"# %% ../../01_export.ipynb #d73c328f\n",
"#| export\n",
"class A:\n",
"\n",
"```"
"```\n",
"\n",
"</div>"
],
"text/plain": [
"<IPython.core.display.Markdown object>"
"Markdown(```python\n",
"# AUTOGENERATED! DO NOT EDIT! File to edit: ../../01_export.ipynb.\n",
"\n",
"# %% ../../01_export.ipynb #65e15f2e\n",
"from __future__ import print_function\n",
"\n",
"# %% ../../01_export.ipynb #1e9ea7e8\n",
"#| export\n",
"def a(): ...\n",
"\n",
"# %% ../../01_export.ipynb #d73c328f\n",
"#| export\n",
"class A:\n",
"\n",
"```)"
]
},
"execution_count": null,
Expand Down Expand Up @@ -717,31 +759,56 @@
{
"data": {
"text/markdown": [
"<div class=\"prose\" markdown=\"1\">\n",
"\n",
"```python\n",
"# AUTOGENERATED! DO NOT EDIT! File to edit: ../../04_export.ipynb.\n",
"\n",
"# %% ../../04_export.ipynb #73b66309\n",
"# %% ../../04_export.ipynb #dec4cd88\n",
"from __future__ import print_function\n",
"\n",
"# %% auto #0\n",
"__all__ = ['b', 'c', 'd']\n",
"\n",
"# %% ../../04_export.ipynb #c168485a\n",
"# %% ../../04_export.ipynb #b2a73a89\n",
"#| export\n",
"def a(): ...\n",
"\n",
"# %% ../../04_export.ipynb #94c4db18\n",
"# %% ../../04_export.ipynb #470e0aea\n",
"def b(): ...\n",
"\n",
"# %% ../../04_export.ipynb #e53b62a7\n",
"# %% ../../04_export.ipynb #4e1e1d2e\n",
"def c(): ...\n",
"\n",
"# %% ../../04_export.ipynb #90b96fb2\n",
"# %% ../../04_export.ipynb #7199ab8d\n",
"def d(): ...\n",
"```"
"```\n",
"\n",
"</div>"
],
"text/plain": [
"<IPython.core.display.Markdown object>"
"Markdown(```python\n",
"# AUTOGENERATED! DO NOT EDIT! File to edit: ../../04_export.ipynb.\n",
"\n",
"# %% ../../04_export.ipynb #dec4cd88\n",
"from __future__ import print_function\n",
"\n",
"# %% auto #0\n",
"__all__ = ['b', 'c', 'd']\n",
"\n",
"# %% ../../04_export.ipynb #b2a73a89\n",
"#| export\n",
"def a(): ...\n",
"\n",
"# %% ../../04_export.ipynb #470e0aea\n",
"def b(): ...\n",
"\n",
"# %% ../../04_export.ipynb #4e1e1d2e\n",
"def c(): ...\n",
"\n",
"# %% ../../04_export.ipynb #7199ab8d\n",
"def d(): ...\n",
"```)"
]
},
"execution_count": null,
Expand All @@ -761,7 +828,9 @@
"outputs": [],
"source": [
"try:\n",
" sys.path.append('')\n",
" g = exec_import('tmp.test.testing', '*')\n",
" sys.path.pop()\n",
" for s in \"b c d\".split(): assert s in g, s\n",
" assert 'a' not in g\n",
" assert g['b']() is None\n",
Expand Down Expand Up @@ -816,7 +885,16 @@
]
}
],
"metadata": {},
"metadata": {
"solveit": {
"default_code": true,
"mode": "learning",
"use_fence": false,
"use_thinking": true,
"use_tools": true,
"ver": 2
}
},
"nbformat": 4,
"nbformat_minor": 5
}
56 changes: 44 additions & 12 deletions nbs/api/04_export.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
"from pdb import set_trace\n",
"from importlib import reload\n",
"from fastcore import shutil\n",
"from fastcore.nbio import read_nb"
"from fastcore.nbio import *"
]
},
{
Expand All @@ -76,7 +76,7 @@
" def __call__(self, cell):\n",
" src = cell.source\n",
" if not src: return\n",
" if cell.cell_type=='markdown' and src.startswith('# '): self.modules['#'].append(cell)\n",
" if cell.cell_type=='markdown' and (src.startswith('# ') or 'export' in cell.directives_): self._exporti_(cell)\n",
" _exports_=_export_"
]
},
Expand Down Expand Up @@ -107,6 +107,33 @@
"assert 'h_n' in exp.in_all['some.thing'][0].source"
]
},
{
"cell_type": "markdown",
"id": "9e635bb9",
"metadata": {},
"source": [
"Markdown title cells and `#| export` markdown cells are collected into the module so `ModuleMaker` can build the module docstring.\n",
"They must not be added to `in_all`, since `__all__` generation only applies to Python symbols from code cells."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ddb7e224",
"metadata": {},
"outputs": [],
"source": [
"nb = dict2nb({'cells':[\n",
" mk_cell('#| default_exp tmp_doc'),\n",
" mk_cell('# Test module\\n> Short summary', 'markdown'),\n",
" mk_cell('#| export\\nExtra docs', 'markdown'),\n",
" mk_cell('#| export\\ndef f(): return 1')]})\n",
"exp = ExportModuleProc(); NBProcessor(nb=nb, procs=exp).process()\n",
"test_eq([(c.cell_type, c.source.splitlines()[0]) for c in exp.modules['#']], \n",
" [('markdown', '# Test module'), ('markdown', 'Extra docs'), ('code', 'def f(): return 1')])\n",
"test_eq([c.cell_type for c in exp.in_all['#']], ['code'])"
]
},
{
"cell_type": "markdown",
"id": "94eb949b",
Expand Down Expand Up @@ -168,9 +195,13 @@
"shutil.rmtree('tmp', ignore_errors=True)\n",
"nb_export('../../tests/00_some.thing.ipynb', 'tmp')\n",
"\n",
"sys.path.append('')\n",
"g = exec_new('import tmp.some.thing')\n",
"sys.path.pop()\n",
"test_eq(g['tmp'].some.thing.__all__, ['a'])\n",
"test_eq(g['tmp'].some.thing.a, 1)"
"test_eq(g['tmp'].some.thing.a, 1)\n",
"test_eq(g['tmp'].some.thing.__doc__, \n",
"\"Test module some.thing\\n\\nThis notebook is used to demonstrate exporting to an existing module. See the notebooks in `nbs` for how it's used.\")\n"
]
},
{
Expand Down Expand Up @@ -242,17 +273,18 @@
"g = exec_new('import nbdev.export')\n",
"assert hasattr(g['nbdev'].export, 'nb_export')"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "184b448f",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {},
"metadata": {
"solveit": {
"default_code": false,
"mode": "learning",
"use_fence": false,
"use_thinking": false,
"use_tools": false,
"ver": 2
}
},
"nbformat": 4,
"nbformat_minor": 5
}
4 changes: 2 additions & 2 deletions nbs/api/10_processors.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -633,8 +633,8 @@
"_hide_dirs = {'export','exporti', 'hide','default_exp'}\n",
"\n",
"def rm_export(cell):\n",
" \"Remove cells that are exported or hidden\"\n",
" if cell.directives_ and (cell.directives_.keys() & _hide_dirs): del(cell['source'])"
" \"Remove code cells that are exported or hidden\"\n",
" if cell.cell_type=='code' and cell.directives_ and (cell.directives_.keys() & _hide_dirs): del(cell['source'])\n"
]
},
{
Expand Down
Loading
Loading