Python 斯芬克斯:ivar标签寻找交叉引用
我想用Sphinx记录Python对象属性。我知道我应该使用Python 斯芬克斯:ivar标签寻找交叉引用,python,python-sphinx,Python,Python Sphinx,我想用Sphinx记录Python对象属性。我知道我应该使用 :ivar varname: description :ivar type varname: description 然而,我看到了一种奇怪的行为,那就是Sphinx在我的项目中搜索变量名并试图创建符号链接。 例如,该代码: class A(object): """ :ivar x: some description """ def __init__(self, x): self.x
:ivar varname: description
:ivar type varname: description
然而,我看到了一种奇怪的行为,那就是Sphinx在我的项目中搜索变量名并试图创建符号链接。
例如,该代码:
class A(object):
"""
:ivar x: some description
"""
def __init__(self, x):
self.x = x
class B(object):
def x(self):
return 1
class C(object):
def x(self):
return 2
将导致此错误:
module1.py:mylibrary.module1.A的docstring:None:警告:找到多个交叉引用u'x的目标:mylibrary.module1.C.x,mylibrary.module1.B.x
我是否错误地理解了:ivar的用途或用法?因为mzjn提到了一个。在该线程中,也已经有一个针对发布问题的解决方案。总之,您使用内联注释
:
而不是docstring
查看用户引用的提交中的python.py
文件。删除了docstring条目(红线),并在构造函数中添加了内联注释(绿线)
我一直在寻找这方面的文档,但找不到它。
例如:
(...)
def __init__(self, function, fixtureinfo, config, cls=None, module=None):
#: access to the :class:`_pytest.config.Config` object for the test session
self.config = config
(...)
正如尼克·巴斯汀(Nick Bastin)所指出的,这项工作与:ivar:
完全不同。没有类型支持,它总是呈现默认值。这里有一个猴子补丁(基于Sphinx 1.5.1),它禁用了ivar
交叉引用。我不知道最好的解决方案是什么,所以考虑补丁是一个实验性的建议。要进行尝试,请将下面的代码添加到conf.py
from docutils import nodes
from sphinx.util.docfields import TypedField
from sphinx import addnodes
def patched_make_field(self, types, domain, items):
# type: (List, unicode, Tuple) -> nodes.field
def handle_item(fieldarg, content):
par = nodes.paragraph()
par += addnodes.literal_strong('', fieldarg) # Patch: this line added
#par.extend(self.make_xrefs(self.rolename, domain, fieldarg,
# addnodes.literal_strong))
if fieldarg in types:
par += nodes.Text(' (')
# NOTE: using .pop() here to prevent a single type node to be
# inserted twice into the doctree, which leads to
# inconsistencies later when references are resolved
fieldtype = types.pop(fieldarg)
if len(fieldtype) == 1 and isinstance(fieldtype[0], nodes.Text):
typename = u''.join(n.astext() for n in fieldtype)
par.extend(self.make_xrefs(self.typerolename, domain, typename,
addnodes.literal_emphasis))
else:
par += fieldtype
par += nodes.Text(')')
par += nodes.Text(' -- ')
par += content
return par
fieldname = nodes.field_name('', self.label)
if len(items) == 1 and self.can_collapse:
fieldarg, content = items[0]
bodynode = handle_item(fieldarg, content)
else:
bodynode = self.list_type()
for fieldarg, content in items:
bodynode += nodes.list_item('', handle_item(fieldarg, content))
fieldbody = nodes.field_body('', bodynode)
return nodes.field('', fieldname, fieldbody)
TypedField.make_field = patched_make_field
原始的
TypedField.make\u field方法如下:。还有一种具有其他优点的替代方法。只需在类范围内定义成员变量,并用普通docstring记录它们。稍后,您可以使用角色引用它们。它更具可读性,自我记录(是的,我知道这是在,但无论如何)和内省友好的方法
模块.py
自述文件
conf.py
像PYTHONPATH=一样构建。斯芬克斯建造。html
以下是github上的@acrisci
提供的一种解决方法:在变量名前面加上~。
。例如,替换
:ivar float bandwidth: blah
为此:
:ivar float ~.bandwidth: blah
资料来源:这最终在2021年4月12日发布的《狮身人面像4.0.0》中得到了修正 Sphinx的下一个稳定版本将是4.0或4.1
< P>(问题:PR:修正了:4的beta 1:)如果你删除<代码>:IVAR X:一些描述< /代码>,错误消失了。是的,错误是由IVAR引起的,如果我删除C类,那么我就不会出错,但是在HTML中,我得到一个从A.x到B.Xi的不想要的链接也有同样的问题。这并非适用于所有:ivar,仅在实例变量的名称被其他类/模块使用的情况下才会发生。令人担忧的是:ivar(据我所知)根本不应该创建一个被报告为bug的交叉引用:问题是
:
的呈现方式与:ivar:
(及其类似内容)完全不同。没有类型支持,它总是呈现默认值,并且没有那么紧凑。我感觉到了,它不是一个解决方案,只是一个变通方法。我只是在这里添加了信息来完成这个线程,因为这个问题源于这里。我还将添加您的注释。这从根本上改变了代码类属性与实例属性完全不同的功能。另外,您可以只使用:py:attr:
,而不这样做,但它也不是以相同的方式呈现的(作为类或实例属性)。@NickBastin我看不到以这种方式“定义”其成员的类有任何“根本性更改”。我只看到好处。你能详细解释一下你的意思吗?最简单的例子是,你的更改允许A.x
有一个值,而在正确的代码中,只有A().x
有一个值(尝试访问A.x
会给你一个异常)。这很容易导致细微的错误,甚至更糟。无论如何,文档不应该要求更改实际代码的行为。@NickBastin在我的示例中,尽管我想讨论类成员的更高级别抽象,但类属性得到了None
值。初始化器中的对象属性重新绑定它们。我无法想象编写良好的代码会因此而崩溃。或者它是一个已经损坏的代码,错误地将类而不是实例传递到某个地方。或者它是一个写得很差的代码,它根据属性的存在(在\uuuu dict\uuuu
中)而不是属性的值来做出决定。所以我再次认为你的观点是没有根据的…@NickBastin…好吧,除了一个人显然不需要重写他们的类,因为var
在Sphinx中不能正常工作。从这个问题的意义上说,这是一个解决办法。但就我个人而言,我总是以这种方式编写类,从来没有遇到过这样的问题。您还可以在一些已知的包(如cherrypy、sqlalchemy和其他可能的包)中看到这种模式。这是一种编写类本身的方法。一种声明类范围(类的第一缩进级别)中所有成员的方法,以便更容易对其状态和功能进行推理。这确实有效!当然,这感觉有点不对劲,我不知道它在RTD上是否有效,但授予赏金是因为它满足了请求的参数(希望有人能在某个时候修复斯芬克斯票据,但这同时会起作用);一行代码代替另一行代码。顺便说一句,该补丁也可以应用于Sphinx的早期版本。不过,它抱怨的理由不匹配。只需将另一个可选参数作为patched\u make\u字段(self、type、domain、items、env=None)
@SauravSahu:是的,猴子补丁可能很脆弱。在我发布答案后,docfields.py已经做了一些更改。相关错误报告仍处于打开状态:。显然已被Sphinx 3.4.0破坏:不工作:警告:未找到py:obj参考目标:。带宽
extensions = ['sphinx.ext.autodoc']
source_suffix = '.txt'
master_doc = 'README'
project = 'Test'
pygments_style = 'sphinx'
html_theme = 'alabaster'
html_use_index = False
html_show_sourcelink = False
html_show_copyright = False
html_sidebars = {'**': ['localtoc.html']}
:ivar float bandwidth: blah
:ivar float ~.bandwidth: blah