我的第一个README在pypi.python.org上没有格式

47
5个回答

26

事实证明,@sigmavirus 关于链接的回答很接近。我在 distutils 邮件列表上开始了一次讨论,并发现在页内链接(即 #minimum-cash)是不被 pypi reStructuredText 解析器允许的,这将使整个文档无效。

看起来,pypi 使用一个白名单来过滤链接协议(http vs ftp vs gopher),并将 '#' 视为无效协议。这似乎很容易在他们的端解决,但在那之前,我将删除我的页内锚点链接。


4
PyPI的reStructuredText渲染器对相对链接也存在问题,即使它们不是锚点。我不得不用完整路径(以“https://”开头)替换相对链接,但现在它可以工作了。 https://github.com/chbrown/filesequence/commit/728ac3db4bf2ae2c640d48e065fb3aed0e937acc - chbrown
你可以使用我上面的过滤代码来消除我所知道的所有PyPi无效结构。 - ankostis

22
  • 您可以使用collective.checkdocs软件包来检测无效结构:

    pip install collective.checkdocs python setup.py checkdocs

  • 然后,您可以使用以下Python函数来过滤掉sphinx-only结构(可能需要添加更多的正则表达式,以匹配您的内容):

#!/usr/bin/python3
"""
Cleans-up Sphinx-only constructs (ie from README.rst),
so that *PyPi* can format it properly.

To check for remaining errors, install ``sphinx`` and run::

        python setup.py --long-description | sed -file 'this_file.sed' | rst2html.py  --halt=warning

"""

import re
import sys, io


def yield_sphinx_only_markup(lines):
    """
    :param file_inp:     a `filename` or ``sys.stdin``?
    :param file_out:     a `filename` or ``sys.stdout`?`

    """
    substs = [
        ## Selected Sphinx-only Roles.
        #
        (r':abbr:`([^`]+)`',        r'\1'),
        (r':ref:`([^`]+)`',         r'`\1`_'),
        (r':term:`([^`]+)`',        r'**\1**'),
        (r':dfn:`([^`]+)`',         r'**\1**'),
        (r':(samp|guilabel|menuselection):`([^`]+)`',        r'``\2``'),


        ## Sphinx-only roles:
        #        :foo:`bar`   --> foo(``bar``)
        #        :a:foo:`bar` XXX afoo(``bar``)
        #
        #(r'(:(\w+))?:(\w+):`([^`]*)`', r'\2\3(``\4``)'),
        (r':(\w+):`([^`]*)`', r'\1(``\2``)'),


        ## Sphinx-only Directives.
        #
        (r'\.\. doctest',           r'code-block'),
        (r'\.\. plot::',            r'.. '),
        (r'\.\. seealso',           r'info'),
        (r'\.\. glossary',          r'rubric'),
        (r'\.\. figure::',          r'.. '),


        ## Other
        #
        (r'\|version\|',              r'x.x.x'),
    ]

    regex_subs = [ (re.compile(regex, re.IGNORECASE), sub) for (regex, sub) in substs ]

    def clean_line(line):
        try:
            for (regex, sub) in regex_subs:
                line = regex.sub(sub, line)
        except Exception as ex:
            print("ERROR: %s, (line(%s)"%(regex, sub))
            raise ex

        return line

    for line in lines:
        yield clean_line(line)

如果您想在setup.py文件中使用and/or, 您可以像这样设置:

def read_text_lines(fname):
    with io.open(os.path.join(mydir, fname)) as fd:
        return fd.readlines()

readme_lines = read_text_lines('README.rst')
long_desc = ''.join(yield_sphinx_only_markup(readme_lines)),

或者您可以使用 sed Unix 工具处理此文件:

## Sed-file to clean-up README.rst from Sphinx-only constructs,
##   so that *PyPi* can format it properly.
##   To check for remaining errors, install ``sphinx`` and run:
##
##          sed -f "this_file.txt" README.rst | rst2html.py  --halt=warning
##

## Selected Sphinx-only Roles.
#
s/:abbr:`\([^`]*\)`/\1/gi
s/:ref:`\([^`]*\)`/`\1`_/gi
s/:term:`\([^`]*\)`/**\1**/gi
s/:dfn:`\([^`]*\)`/**\1**/gi
s/:\(samp\|guilabel\|menuselection\):`\([^`]*\)`/``\1``/gi


## Sphinx-only roles:
#        :foo:`bar` --> foo(``bar``)
#
s/:\([a-z]*\):`\([^`]*\)`/\1(``\2``)/gi


## Sphinx-only Directives.
#
s/\.\. +doctest/code-block/i
s/\.\. +plot/raw/i
s/\.\. +seealso/info/i
s/\.\. +glossary/rubric/i
s/\.\. +figure::/../i


## Other
#
s/|version|/x.x.x/gi

checkdocs的好技巧就是在python setup.py check --restructuredtext没有发现错误时,它可以找到破坏我的自述文件的错误。 - Anentropic
不过如果没有 setup.py 文件,使用起来会相当困难:from setuptools import Distribution; from collective.checkdocs import checkdocs; checkdocs(Distribution(dict(long_description=open("README.rst").read()))).run() - flying sheep

14

编辑: 您可以使用以下内容查找RST中的错误,这些错误将显示在PyPI上:

twine check

你需要安装版本为1.12.0或更高的twine。如果没有,请使用以下命令进行安装或更新:

pip install --upgrade twine

源代码


已过时的答案:

python setup.py check --restructuredtext

源地址


1
对我来说,只有在执行了pip install readme之后才能正常工作。然而,这时它显示了其他检查器没有捕获到的问题。 - m00am
2
这似乎已经被弃用了:“警告:检查:此命令已被弃用。请改用 twine check:https://packaging.python.org/guides/making-a-pypi-friendly-readme#validating-restructuredtext-markup”,并引用了 https://packaging.python.org/guides/making-a-pypi-friendly-readme/#validating-restructuredtext-markup。 - kuropan
twine check需要一个或多个以构建的分发文件形式的参数。如果事先检查生成的分发文件是否会正确显示,当然不是很有用。 (为我的一个C扩展程序构建这些分发文件需要超过一小时的时间,如果您运行twine check dist/*并发现您需要重新开始,则会浪费这些时间) - Anthon

8

在我快速浏览后,首先注意到的是,在您的高级筛选器部分,您在链接后使用了两个下划线,例如:

`Link text <http://example.com>`__

它应该在哪里

`Link text <http://example.com>`_

很奇怪reStructuredText检查器没有发现这个问题。如果您已经安装了docutils,您可以运行rst2html.py README.rst,它会输出HTML。如果出现错误,它将失败并告诉您错误的位置。

另外,警告一下,列表应该没有前导空格,也就是说,您的写法有误。

 - foo
 - bar

与其

- foo
- bar

(为了更加直观清晰)

- foo # correct
 - one too many for a regular list, it will show up as a quoted list

此外,相对链接并不像这样工作:要链接的文本 <#链接>_。如果您想链接到另一个部分,您需要执行以下操作:

Here's my `link <section_name>`_ to the other section.

.. Other stuff here ...

.. _section_name:

Min/Max Investment Opportunities and Other Foo Biz Baz
------------------------------------------------------

5

当我上传我的Python模块到pypi时,我遇到了同样的问题

后来我使用rst-lint检查了 README.rst文件中的错误,发现我的自述文件没有问题。

我发现问题不在自述文件中,而是在 setup.py 中。

编写 README 和 setup.py 时,请遵循以下要点:

  • 不要为描述、摘要或任何进入 setup() 参数的内容编写多行 Python 字符串。
  • 不要在 README 文件中使用相对链接(如./path1/path2)。
  • 确保 rst 语法正确,可以使用 rst-lint 这样的检查工具检查。
  • 如果你有一个 markdown 文件,你可以使用 pandoc 轻松地将其转换为 Restructured text 格式。

在我的情况下,的确是用于描述的多行字符串(甚至不是长描述!)。真是疯狂……您的答案为我节省了好几个小时,非常感谢! - marsl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接