pypiにpackageをuploadするときに、HTTPError: 400 Client Error: The description failed to render in the default format of reStructuredText.が出た話。
pypiにuploadした時に以下のようなエラーが出た。
$ python setup.py sdist bdist_wheel $ twine upload dist/<package> ... HTTPError: 400 Client Error: The description failed to render in the default format of reStructuredText. See https://pypi.org/help/#description-content-type for more information. for url: https://upload.pypi.org/legacy/
一応verboseオプション付きでメッセージを表示してみる。
$ twine upload --verbose dist/<package> ... Content received from server: <html> <head> <title>400 The description failed to render in the default format of reStructuredText. See https://pypi.org/help/#description-content-type for more information.</title> </head> <body> <h1>400 The description failed to render in the default format of reStructuredText. See https://pypi.org/help/#description-content-type for more information.</h1> The server could not comply with the request since it is either malformed or otherwise incorrect.<br/><br/> The description failed to render in the default format of reStructuredText. See https://pypi.org/help/#description-content-type for more information. </body> </html> HTTPError: 400 Client Error: The description failed to render in the default format of reStructuredText. See https://pypi.org/help/#description-content-type for more information. for url: https://upload.pypi.org/legacy/
このときのパッケージのsetup.pyに description-content-type
を指定していなかった(結構前からtext/markdownを指定するとreadmeをmarkdownで書ける様になっている。デフォルトはReST)。
ただし今回に限って言うと、エラーメッセージがほとんどかけらも役に立たない。唯一役に立つのはrenderに失敗しているということがわかるだけ。なので、ヘルプメッセージの指すリンク先をみてdescription-content-type
を指定しても意味がない。
(追記: 以下の文が役に立つ。一応。)
PyPI will reject uploads if the description fails to render. To check a description locally for validity, you may use readme_renderer, which is the same description renderer used by PyPI.
(追記おしまい)
ちなみに、text/x-rst
に変えた場合のメッセージは以下の様に変わる。
HTTPError: 400 Client Error: The description failed to render for 'text/x-rst'. See https://pypi.org/help/#description-content-type for more information. for url: https://upload.pypi.org/legacy/
readme_renderer
解決にはこのPRが参考になった。
何やら以下の様な感じらしい。
- readmeのrenderingにはreadme_renderer パッケージを利用している
- 少しのwarningであってもfailed扱いになる
実際試してみたら以下のようなwarningが出ていた。これだけのwarningでもだめ。
$ python -m readme_renderer README.rst <string>:417: (WARNING/2) Title underline too short. available info (extensions and additional modules) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
このときの環境
$ pip freeze | grep -i readme readme-renderer==24.0
追記
twine checkを教えてもらった。たしかに存在する。便利そう。
$ twine -h usage: twine [-h] [--version] {check,register,upload} positional arguments: {check,register,upload} optional arguments: -h, --help show this help message and exit --version show program's version number and exit $ twine check dist/<package> Checking distribution dist/<package>-py2.py3-none-any.whl: Passed