doclinks

从模块生成文档索引

创建模块索引


source

patch_name

 patch_name (o)

如果 opatchpatch_to 修饰,则返回其类前缀名称

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()

导出 notebook


source

nbglob

 nbglob (path=None, skip_folder_re='^[_.]', file_glob='*.ipynb',
         skip_file_re='^[_.]', key='nbs_path', as_path=False,
         recursive:bool=True, symlinks:bool=True, file_re:str=None,
         folder_re:str=None, skip_file_glob:str=None,
         func:callable=<function join>, ret_folders:bool=False)

根据配置键查找目录中匹配特定扩展名的所有文件。

类型 默认值 详情
path pathlib.Path | str 开始搜索的路径
skip_folder_re str None 跳过匹配正则表达式的文件夹,
file_glob str None 仅包含匹配 glob 的文件
skip_file_re str None 跳过匹配正则表达式的文件
key str nbs_path
as_path bool False
recursive bool True 搜索子文件夹
symlinks bool True 跟随软链接?
file_re str None 仅包含匹配正则表达式的文件
folder_re str None 仅进入匹配正则表达式的文件夹
skip_file_glob str None 跳过匹配 glob 的文件
func callable join 应用于每个匹配文件的函数
ret_folders bool False 返回文件夹,而非仅文件
返回值 L 匹配文件的路径

source

nbglob_cli

 nbglob_cli (path:str=None, symlinks:bool=False, file_glob:str='*.ipynb',
             file_re:str=None, folder_re:str=None,
             skip_file_glob:str=None, skip_file_re:str='^[_.]',
             skip_folder_re:str='^[_.]')

根据配置键查找目录中匹配特定扩展名的所有文件。

类型 默认值 详情
path str None notebook 路径
symlinks bool False 跟随软链接?
file_glob str *.ipynb 仅包含匹配 glob 的文件
file_re str None 仅包含匹配正则表达式的文件
folder_re str None 仅进入匹配正则表达式的文件夹
skip_file_glob str None 跳过匹配 glob 的文件
skip_file_re str ^[_.] 跳过匹配正则表达式的文件
skip_folder_re str ^[_.] 跳过匹配正则表达式的文件夹

source

nbdev_export

 nbdev_export (path:str=None,
               procs:<tokensnamingtheexportprocessorstouse.>='black_format
               ', symlinks:bool=False, file_glob:str='*.ipynb',
               file_re:str=None, folder_re:str=None,
               skip_file_glob:str=None, skip_file_re:str='^[_.]',
               skip_folder_re:str='^[_.]')

path 中的 notebook 导出为 Python 模块

类型 默认值 详情
path str None 路径或文件名
procs <用于命名要使用的导出处理器的标记。> black_format
symlinks bool False 跟随软链接?
file_glob str *.ipynb 仅包含匹配 glob 的文件
file_re str None 仅包含匹配正则表达式的文件
folder_re str None 仅进入匹配正则表达式的文件夹
skip_file_glob str None 跳过匹配 glob 的文件
skip_file_re str ^[_.] 跳过匹配正则表达式的文件
skip_folder_re str ^[_.] 跳过匹配正则表达式的文件夹

procs 指定了您希望在 notebook 导出单元格上运行的可选处理器。

注意:black_format 处理器默认会被传入。但它是一个空操作(no-op),除非在您的 settings.ini 配置中将 black_formatting 设置为 True。您可以通过在命令行上传递 --procs 参数来从 nbdev_export 中省略它。

构造索引


source

create_index

 create_index (url, pre=None)

从位于 url 的 sphinx 清单文件创建文档索引,带可选前缀 pre

url = 'https://docs.pythonlang.cn/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.pythonlang.cn/3/library/functions.html#bool',
 'builtins.bytearray': 'https://docs.pythonlang.cn/3/library/stdtypes.html#bytearray',
 'builtins.bytes': 'https://docs.pythonlang.cn/3/library/stdtypes.html#bytes',
 'builtins.complex': 'https://docs.pythonlang.cn/3/library/functions.html#complex',
 'builtins.dict': 'https://docs.pythonlang.cn/3/library/stdtypes.html#dict',
 'builtins.float': 'https://docs.pythonlang.cn/3/library/functions.html#float',
 'builtins.frozenset': 'https://docs.pythonlang.cn/3/library/stdtypes.html#frozenset',
 'builtins.int': 'https://docs.pythonlang.cn/3/library/functions.html#int',
 'builtins.list': 'https://docs.pythonlang.cn/3/library/stdtypes.html#list',
 'builtins.memoryview': 'https://docs.pythonlang.cn/3/library/stdtypes.html#memoryview'}

查询模块索引

让我们测试一下当其中一个入口点抛出错误时的错误处理。

# Create mock entry points
class BadEntryPoint:
    name = 'bad_entry'
    dist = type('Dist', (), {'key': 'bad_lib'})()
    def resolve(self): raise AttributeError("Simulated error")

class GoodEntryPoint:
    name = 'good_entry'
    dist = type('Dist', (), {'key': 'good_lib'})()
    def resolve(self): return {'syms': {}, 'settings': {}}
# Clear the cache before testing
_build_lookup_table.cache_clear()

# Patch iter_entry_points
with xpatch('pkg_resources.iter_entry_points', return_value=[BadEntryPoint(), GoodEntryPoint()]):
    entries, py_syms = _build_lookup_table()
    
    # Should only contain the good entry
    assert 'bad_entry' not in entries
    assert 'good_entry' in entries
    assert len(entries) == 1
entries
{'good_entry': {'syms': {}, 'settings': {}}}

source

NbdevLookup

 NbdevLookup (strip_libs=None, incl_libs=None, skip_mods=None, ns=None)

从符号名称到文档和源代码 URL 的映射

索引返回符号文档的链接,以及源代码文件的名称(如果源代码 URL 可用的话)。

c = NbdevLookup()
c['nbdev.doclinks.NbdevLookup']
('https://nbdev.fastai.net.cn/api/doclinks.html#nbdevlookup',
 'nbdev/doclinks.py',
 'https://github.com/AnswerDotAI/nbdev/blob/master/nbdev/doclinks.py')

source

NbdevLookup.doc

 NbdevLookup.doc (sym)

sym 的文档链接

这是一个验证错误处理行为的测试套件

c.doc('nbdev.doclinks.NbdevLookup')
'https://nbdev.fastai.net.cn/api/doclinks.html#nbdevlookup'

符号名称取自使用 'nbdev' 入口点注册的库。默认情况下,会搜索所有使用此入口点的库,但需要完整的符号名称(包括模块前缀)。

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

传入 strip_libs 以列出无需模块前缀即可使用的库。

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

source

NbdevLookup.code

 NbdevLookup.code (sym)

sym 的源代码链接

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

source

NbdevLookup.linkify

 NbdevLookup.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.com.cn/doc/stable/reference/generated/numpy.array.html#numpy.array) and to `array()` and to [`get_config()`](https://nbdev.fastai.net.cn/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.pythonlang.cn/3/library/stdtypes.html#str.split)'
# ... now with stripping
md = "`str.split` and `str`"
NbdevLookup('nbdev_stdlib').linkify(md)
'[`str.split`](https://docs.pythonlang.cn/3/library/stdtypes.html#str.split) and [`str`](https://docs.pythonlang.cn/3/library/stdtypes.html#str)'

当存在冲突时,链接化将按照去前缀库的顺序,然后按字母顺序应用。例如,enumerate 既是内置函数,也是 threading 模块中的一个函数。然而,由于内置函数按字母顺序排在前面,它将优先。

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

我们也可以将 find() 函数作为另一个例子,它既存在于标准库中,也存在于 numpy 中。因此,取决于我们传入的去前缀库的顺序,find() 将链接到 numpy 或标准库。

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

您还可以使用 NbdevLookup,并使用如下所示的导入别名

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.com.cn/doc/stable/reference/generated/numpy.array.html#numpy.array)'