doclinks

Generating a documentation index from a module

Create the module index


source

patch_name


def patch_name(
    o
):

If o is decorated with patch or patch_to, return its class-prefix name

def _test_patch(code): return patch_name(ast.parse(code).body[0])
s = "@patch\ndef _f(self:_T): ..."
test_eq('_T._f', _test_patch(s))
s = "@patch_to(_T)\ndef _g(self): ..."
test_eq('_T._g', _test_patch(s))
# Get all patched classes when patching with a union
s = "@patch\ndef _f(self:_T|_U|_V): ..."
test_eq(_test_patch(s), ['_T._f', '_U._f', '_V._f'])
# _build_modidx()

Export a notebook


source

nbglob


def nbglob(
    path:NoneType=None, # path to start searching
    skip_folder_re:str='^[_.]', # Skip folders matching regex,
    file_glob:str='*.ipynb', # Only include files matching glob
    skip_file_re:str='^[_.]', # Skip files matching regex
    key:str='nbs_path', as_path:bool=False, recursive:bool=True, # search subfolders
    symlinks:bool=True, # follow symlinks?
    file_re:str=None, # Only include files matching regex
    folder_re:str=None, # Only enter folders matching regex
    skip_file_glob:str=None, # Skip files matching glob
    func:callable=<function join at 0x7f549ed72e60>, # function to apply to each matched file
    ret_folders:bool=False, # return folders, not just files
    sort:bool=True, # sort files by name within each folder
    types:str \| list=None, # list or comma-separated str of ext types from: py, js, java, c, cpp, rb, r, ex, sh, web, doc, cfg
    exts:str \| list=None, # list or comma-separated str of exts to include
): # Paths to matched files

Find all files in a directory matching an extension given a config key.


source

nbglob_cli


def nbglob_cli(
    path:str=None, # Path to notebooks
    symlinks:bool=False, # Follow symlinks?
    file_glob:str='*.ipynb', # Only include files matching glob
    file_re:str=None, # Only include files matching regex
    folder_re:str=None, # Only enter folders matching regex
    skip_file_glob:str=None, # Skip files matching glob
    skip_file_re:str='^[_.]', # Skip files matching regex
    skip_folder_re:str='^[_.]', # Skip folders matching regex
):

Find all files in a directory matching an extension given a config key.


source

nbdev_export


def nbdev_export(
    path:str=None, # Path or filename
    procs:<tokens naming the export processors to use.>='black_format', symlinks:bool=False, # Follow symlinks?
    file_glob:str='*.ipynb', # Only include files matching glob
    file_re:str=None, # Only include files matching regex
    folder_re:str=None, # Only enter folders matching regex
    skip_file_glob:str=None, # Skip files matching glob
    skip_file_re:str='^[_.]', # Skip files matching regex
    skip_folder_re:str='^[_.]', # Skip folders matching regex
):

Export notebooks in path to Python modules

procs names the optional processors you wish to run on the exported cells of your notebook.

N.B.: the black_format processor is passed in by default. But it is a no-op, unless black_formatting=True is set in your settings.ini configuration. You can omit it from nbdev_export on the command line by passing in --procs.

Construct Index


source

create_index


def create_index(
    url, pre:NoneType=None
):

Create a documentation index from a sphinx inventory file at url, with optional prefix pre

url = 'https://docs.python.org/3'
syms = create_index(url)

for b in syms['builtins']:
    b = b.split('.')
    if len(b) != 2: continue
    b = b[1]
    assert b in bset

dict(list(syms['builtins'].items())[:10])
{'builtins.bool': 'https://docs.python.org/3/library/functions.html#bool',
 'builtins.bytearray': 'https://docs.python.org/3/library/stdtypes.html#bytearray',
 'builtins.bytes': 'https://docs.python.org/3/library/stdtypes.html#bytes',
 'builtins.complex': 'https://docs.python.org/3/library/functions.html#complex',
 'builtins.dict': 'https://docs.python.org/3/library/stdtypes.html#dict',
 'builtins.float': 'https://docs.python.org/3/library/functions.html#float',
 'builtins.frozenset': 'https://docs.python.org/3/library/stdtypes.html#frozenset',
 'builtins.int': 'https://docs.python.org/3/library/functions.html#int',
 'builtins.list': 'https://docs.python.org/3/library/stdtypes.html#list',
 'builtins.memoryview': 'https://docs.python.org/3/library/stdtypes.html#memoryview'}

Query the module index


source

NbdevLookup


def NbdevLookup(
    strip_libs:NoneType=None, incl_libs:NoneType=None, skip_mods:NoneType=None, ns:NoneType=None
):

Mapping from symbol names to docs and source URLs

Indexing returns a link to the symbol’s docs, along with the name of the source file the source URL if available.

c = NbdevLookup()
c['nbdev.doclinks.NbdevLookup']
('https://nbdev.fast.ai/api/doclinks.html#nbdevlookup',
 'nbdev/doclinks.py',
 'https://github.com/AnswerDotAI/nbdev/blob/main/nbdev/doclinks.py')

source

NbdevLookup.doc


def doc(
    sym
):

Link to docs for sym

c.doc('nbdev.doclinks.NbdevLookup')
'https://nbdev.fast.ai/api/doclinks.html#nbdevlookup'

Symbol names are taken from libraries registered using the ‘nbdev’ entry point. By default, all libraries with this entry point are searched, but full symbol names (including module prefix) are required.

assert c.doc('numpy.array').startswith('http')
assert not c.doc('numpy.Array')
assert c.doc('NbdevLookup').endswith('#nbdevlookup')
assert not c.doc('array')

Pass strip_libs to list libraries which should be available without requiring a module prefix.

c = NbdevLookup(strip_libs=('nbdev', 'nbdev_numpy'))
assert c.doc('array').startswith('http')

source

NbdevLookup.code


def code(
    sym
):

Link to source code for sym

NbdevLookup().code('fastcore.net.urlsend')
'https://github.com/AnswerDotAI/fastcore/blob/main/fastcore/net.py#LNone'

source

NbdevLookup.linkify


def linkify(
    md
):
md = """This is a link to `numpy.array` and to `array()` and to `get_config()` but not a link to `foobar`.
And not a link to <code>dict2nb</code>.

    This is not a link to `get_config`

```
This isn't a link to `get_config` either
```"""
print(NbdevLookup(('nbdev','numpy')).linkify(md))
This is a link to [`numpy.array`](https://numpy.org/doc/stable/reference/generated/numpy.array.html#numpy.array) and to `array()` and to [`get_config()`](https://nbdev.fast.ai/api/config.html#get_config) but not a link to `foobar`.
And not a link to <code>dict2nb</code>.

    This is not a link to `get_config`

```
This isn't a link to `get_config` either
```
# Test code blocks
md = """```python
def foo():
    return `bar`
```"""
assert NbdevLookup().linkify(md) == md
# Test builtins
md = "`builtins.str.split`"
NbdevLookup().linkify(md)
'[`builtins.str.split`](https://docs.python.org/3/library/stdtypes.html#str.split)'
# ... now with stripping
md = "`str.split` and `str`"
NbdevLookup('nbdev_stdlib').linkify(md)
'[`str.split`](https://docs.python.org/3/library/stdtypes.html#str.split) and [`str`](https://docs.python.org/3/library/stdtypes.html#str)'

When there is a conflict, the linkification will apply in the order of the stripped libraries and then by alphabetical order. For example, enumerate is both a builtin and a function in the threading module. However, since builtins comes first alphabetically, it will take priority

md = "`enumerate`, `builtins.enumerate` and `threading.enumerate`"
NbdevLookup(('nbdev_stdlib')).linkify(md)
'[`enumerate`](https://docs.python.org/3/library/functions.html#enumerate), [`builtins.enumerate`](https://docs.python.org/3/library/functions.html#enumerate) and [`threading.enumerate`](https://docs.python.org/3/library/threading.html#threading.enumerate)'

We can also take the find() function as another instance, it exists as a standard library and in numpy. Therefore, depending on the order of stripped libraries we pass, find() will link to either numpy or standard library.

md = "`find()`"
NbdevLookup(('nbdev_numpy','nbdev_stdlib')).linkify(md)
'[`find()`](https://numpy.org/doc/stable/reference/generated/numpy.char.find.html#numpy.char.find)'
md = "`find()`"
NbdevLookup(('nbdev_stdlib','nbdev_numpy')).linkify(md)
'[`find()`](https://docs.python.org/3/library/gettext.html#gettext.find)'

You can also use NbdevLookup with import aliases like the following:

import numpy as np
NbdevLookup(ns=globals()).linkify('this is an aliased import link `np.array`')
'this is an aliased import link [`np.array`](https://numpy.org/doc/stable/reference/generated/numpy.array.html#numpy.array)'