Functions to show the doc cells in notebooks
IN_NOTEBOOK
True

All the automatic documentation of functions and classes are generated with the show_doc function. It displays the name, arguments, docstring along with a link to the source code on GitHub.

Gather the information

The inspect module lets us know quickly if an object is a function or a class but it doesn't distinguish classes and enums.

is_enum[source]

is_enum()

Check if cls is an enum or another type of class

e = enum.Enum('e', 'a b')
assert is_enum(e)
assert not is_enum(e.__class__)
assert not is_enum(int)

is_lib_module[source]

is_lib_module(name)

Test if name is a library module.

assert is_lib_module('export')
assert not is_lib_module('transform')

try_external_doc_link(name, packages)

Try to find a doc link for name in packages

This function will only work for other packages built with nbdev.

test_eq(try_external_doc_link('TfmdDL', ['fastai2']), 'https://dev.fast.ai/data.core#TfmdDL')
test_eq(try_external_doc_link('Learner', ['fastai2']), 'https://dev.fast.ai/learner#Learner')
#Only works for packages built with nbdev right now
assert try_external_doc_link('Tensor', ['torch']) is None

doc_link(name, include_bt=True)

Create link to documentation for name.

This function will generate link for a module (pointing to the html conversion of the notebook that created it) and functions (pointing to the hmtl conversion of the notebook they were defined, with the first anchor found before). If the function/module is not part of the library you are writing, it will call the function custom_doc_links generated in _nbdev (you can customize it to your needs) and just return the name between backticks if that function returns None.

For instance, fastai2 has the following custom_doc_links that tries to find a doc link for name in fastcore then nbdev (in this order):

def custom_doc_links(name): 
    from nbdev.showdoc import try_external_doc_link
    return try_external_doc_link(name, ['fastcore', 'nbdev'])
test_eq(doc_link('export'), f'[`export`](/export)')
test_eq(doc_link('DocsTestClass'), f'[`DocsTestClass`](/export#DocsTestClass)')
test_eq(doc_link('DocsTestClass.test'), f'[`DocsTestClass.test`](/export#DocsTestClass.test)')
test_eq(doc_link('Tenso'),'`Tenso`')
test_eq(doc_link('_nbdev'), f'`_nbdev`')
test_eq(doc_link('__main__'), f'`__main__`')

add_doc_links(text)

Search for doc links for any item between backticks in text and isnter them

This function not only add links to backtick keywords, it also update the links that are already in the text (in case they have changed).

tst = add_doc_links('This is an example of `DocsTestClass`')
test_eq(tst, "This is an example of [`DocsTestClass`](/export#DocsTestClass)")
tst = add_doc_links('This is an example of [`DocsTestClass`](old_link.html)')
test_eq(tst, "This is an example of [`DocsTestClass`](/export#DocsTestClass)")

get_source_link(func)

Return link to func in source code

Be sure to properly set the git_url in setting.ini (derived from lib_name and branch on top of the prefix you will need to adapt) so that those links are correct.

As important as the source code, we want to quickly jump to where the function is defined when we are in a development notebook.

get_nb_source_link(func, local=False, is_name=None)

Return a link to the notebook where func is defined.

test_eq(get_nb_source_link(DocsTestClass.test), get_nb_source_link(DocsTestClass))
test_eq(get_nb_source_link('DocsTestClass'), get_nb_source_link(DocsTestClass))

NB_SOURCE_URL = Config().git_url.replace('github.com', 'nbviewer.jupyter.org/github')+ Config().nbs_path.name+'/'
test_eq(get_nb_source_link(check_re), f'{NB_SOURCE_URL}00_export.ipynb#Finding-patterns')
test_eq(get_nb_source_link(check_re, local=True), f'00_export.ipynb#Finding-patterns')

You can either pass an object or its name (by default is_name will look if func is a string or not to decide if it's True or False, but you can override if there is some inconsistent behavior). local will return a local link, otherwise it will point to a the notebook on github wrapped in nbviewer.

nb_source_link(func, is_name=None, disp=True)

Show a relative link to the notebook where func is defined

This function assumes you are in one notebook in the development folder, otherwise you can use disp=False to get the relative link. You can either pass an object or its name (by default is_name will look if func is a string or not to decide if it's True or False, but you can override if there is some inconsistent behavior).

test_eq(nb_source_link(check_re, disp=False), f'00_export.ipynb#Finding-patterns')
test_eq(nb_source_link('check_re', disp=False), f'00_export.ipynb#Finding-patterns')

Show documentation

type_repr[source]

type_repr(t)

Representation of type t (in a type annotation)

The representation tries to find doc links if possible.

tst = type_repr(Optional[DocsTestClass])
test_eq(tst, '`Optional`\\[[`DocsTestClass`](/export#DocsTestClass)\\]')
tst = type_repr(Union[int, float])
test_eq(tst, '`Union`\\[`int`, `float`\\]')
test_eq(type_repr(Param("description")), '"description"')

format_param[source]

format_param(p)

Formats function param to param:Type=val with font weights: param=bold, val=italic

sig = inspect.signature(notebook2script)
params = [format_param(p) for _,p in sig.parameters.items()]
test_eq(params, ['**`fname`**=*`None`*', '**`silent`**=*`False`*', '**`to_dict`**=*`False`*'])

show_doc[source]

show_doc(elt, doc_string=True, name=None, title_level=None, disp=True, default_cls_level=2)

Show documentation for element elt. Supported types: class, function, and enum.

doc_string determines if we show the docstring of the function or not. name can be used to provide an alternative to the name automatically found. title_level determines the level of the anchor (default 3 for classes and 4 for functions). If disp is False, the function returns the markdown code instead of displaying it. If doc_string is True and monospace_docstrings is set to True in settings.ini, the docstring of the function is formatted in a code block to preserve whitespace.

For instance

show_doc(notebook2script)

will display

notebook2script[source]

notebook2script(fname=None, silent=False, to_dict=False)

Convert notebooks matching fname to modules

Show doc magic flag

parse_nbdev_show_doc[source]

parse_nbdev_show_doc(line, namespace=None)

Return a tuple of names, wild_names and kwargs found in a show doc line

Wild names directly preceed a *

This function can be used to:

  • Statically parse a line (if namespace is not provided)
    • In which case wild names will not be inspected
    • So you might assume that docs will have been shown for all members of everything in wild_names
  • Dynamically parse a line
    • Where we create and inpect "live" objects of wild names using the namespace provided
for line, expected in [
    ['', ([],[],{})],
    ['a', (['a'],[],{})],
    ['a b', (['a', 'b'],[],{})],
    ['a,b', (['a', 'b'],[],{})],
    ['A.a', (['A.a'],[],{})],
    ['A.a b', (['A.a', 'b'],[],{})],
    [',A.a, A.b,,,', (['A.a', 'A.b'],[],{})],
    ['A . a', (['A', 'A.a'],[],{})],
    ['A . a,b', (['A', 'A.a', 'A.b'],[],{})],
    ['A . a b', (['A', 'A.a', 'A.b'],[],{})],
    ['A . a B . a', (['A', 'A.a', 'A.B', 'B.a'],[],{})], # using multiple dots is not recommend
    ['A *', (['A'],['A'],{})],
    ['A * a B *', (['A', 'a', 'B'],['A', 'B'],{})],
    ['  A  a B  *  ', (['A', 'a', 'B'],['B'],{})],
    ['A *. _a', (['A', 'A._a'],['A'],{})],
    ['A.a._a *', (['A.a._a'],['A.a._a'],{})],
    ['arg=2', (['arg=2'],[],{})], # this would be a mistake
    ['title_level=2 default_cls_level=1', ([],[],dict(title_level=2,default_cls_level=1))],
    ['default_cls_lvl=2, title_level=1', ([],[],dict(title_level=1,default_cls_level=2))],
    ['default_class_level=55', ([],[],dict(default_cls_level=55))],
    ['A.a title_level=2 default_cls_level=1', (['A.a'],[],dict(title_level=2,default_cls_level=1))],
    ['A * title_level=2 default_cls_level=1', (['A'],['A'],dict(title_level=2,default_cls_level=1))]]:
    test_eq(parse_nbdev_show_doc(line), expected)
    if not '*' in line: 
        # dynamic parse only makes a difference when using wildcard
        test_eq(parse_nbdev_show_doc(line, globals()), expected)
try: parse_nbdev_show_doc('A *', globals()); call_failed=False
except: call_failed=True
assert call_failed, 'dynamic parse should fail because A does not exist'

for line, expected in [
    ['', ([],[],{})],
    [',A.a, A.b,,,', (['A.a', 'A.b'],[],{})],
    ['A . a', (['A', 'A.a'],[],{})],
    ['ReTstFlags . findall search', (['ReTstFlags', 'ReTstFlags.findall', 'ReTstFlags.search'],[],{})],
    ['ReTstFlags * ', (['ReTstFlags', 'ReTstFlags.__init__', 'ReTstFlags.findall', 'ReTstFlags.search'],['ReTstFlags'],{})],
    ['ReTstFlags * a', (['ReTstFlags', 'ReTstFlags.__init__', 'ReTstFlags.findall', 'ReTstFlags.search', 'a'],['ReTstFlags'],{})],
    ['ReTstFlags *. a', (['ReTstFlags', 'ReTstFlags.__init__', 'ReTstFlags.findall', 'ReTstFlags.search', 'ReTstFlags.a'],['ReTstFlags'],{})],
    ['DocsTestClass * a', (['DocsTestClass', 'DocsTestClass.test', 'a'],['DocsTestClass'],{})]]:
    test_eq(parse_nbdev_show_doc(line, globals()), expected)

nbdev_show_doc[source]

nbdev_show_doc(line, local_ns)

Show documentation for one or more elements. Supported types: class, function, and enum. To show doc for multiple elements and specify title level: %nbdev_show_doc name_1, name_2, title_level=3. To show doc for a class and some of its members and specify class level: %nbdev_show_doc MyClass . __init__, my_method, default_cls_level=3 To show doc for a class and all of its "public" members: %nbdev_show_doc MyClass *

  • List of names can be space and/or comma separated.
  • Arguments cannot contain spaces. i.e. title_level = 3 won't work
    • default_cls_lvl and default_class_level are aliases for default_cls_level.
  • The * wildcard will show doc for
    • everything in _docs if possible, or
    • all members that
      • are part of the class (i.e. methods defined in parent classes will not be shown),
      • are classes, functions or properties and
      • have names that do not start with _.

If you want to show doc for a class and some of its members, the dot is important:

Without a dot, %nbdev_show_doc will look for a thing called "test"

test="i am not a method"
%nbdev_show_doc DocsTestClass test

class DocsTestClass[source]

DocsTestClass()

test[source]

str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.str() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to 'strict'.

With a dot, %nbdev_show_doc will look for an attribute of DocsTestClass called "test"

%nbdev_show_doc DocsTestClass . test

class DocsTestClass[source]

DocsTestClass()

DocsTestClass.test[source]

DocsTestClass.test()

Using *. together allows you to show doc for a class, all of its "public" members and methods defined by a parent class etc

%nbdev_show_doc DocsTestClass *. __init__ default_cls_level=3

class DocsTestClass[source]

DocsTestClass()

DocsTestClass.test[source]

DocsTestClass.test()

DocsTestClass.__init__[source]

DocsTestClass.__init__(*args, **kwargs)

Initialize self. See help(type(self)) for accurate signature.

The doc command

md2html[source]

md2html(md)

Convert markdown md to HTML code

get_doc_link(func)

test_eq(get_doc_link(notebook2script), 'https://nbdev.fast.ai/export#notebook2script')
from fastai2.data.core import TfmdDL
test_eq(get_doc_link(TfmdDL), 'https://dev.fast.ai/data.core#TfmdDL')

doc[source]

doc(elt)

Show show_doc info in preview window when used in a notebook