こんにちは。takapy(@takapy0210)です。
自作パッケージをPyPIにアップロードしようとしたところ簡易的なミスで数時間溶かしたので、その備忘です。
エラー内容
$ twine upload -r testpypi dist/* Uploading distributions to https://test.pypi.org/legacy/ Enter your password: Uploading nlplot-1.0.0-py3-none-any.whl 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 948k/948k [00:02<00:00, 443kB/s] NOTE: Try --verbose to see response content. HTTPError: 400 Client Error: The description failed to render in the default format of reStructuredText. See https://test.pypi.org/help/#description-content-type for more information. for url: https://test.pypi.org/legacy/
エラー発生時のsetup.pyの内容
import os, sys from setuptools import setup, find_packages with open('README.md', 'r', encoding='utf-8') as f: long_description = f.read() with open('LICENSE.txt', 'r', encoding='utf-8') as f: license = f.read() def read_requirements(): """Parse requirements from requirements.txt.""" reqs_path = os.path.join('.', 'requirements.txt') with open(reqs_path, 'r') as f: requirements = [line.rstrip() for line in f] return requirements setup( name='nlplot', version='1.0.0', description='Visualization Module for Natural Language Processing', long_description=long_description, long_description_content_type='text/markdown', author='Takanobu Nozawa', author_email='takanobu.030210@gmail.com', url='https://github.com/takapy0210/nlplot', license=license, install_requires=read_requirements(), packages=find_packages(exclude=('tests')), package_data={'nlplot':['data/*']}, python_requires='~=3.6' )
この状態で twine check
を実施すると下記のようなエラーが発生し、twine upload
しても冒頭のエラーが発生します。
エラー内容をみるにlong_description_content_type
がうまく機能していない(?)ように見えます。
$ twine check dist/* Checking dist/nlplot-1.0.0-py3-none-any.whl: FAILED `long_description` has syntax errors in markup and would not be rendered on PyPI. line 3: Error: Unexpected indentation. warning: `long_description_content_type` missing. defaulting to `text/x-rst`. Checking dist/nlplot-1.0.0.tar.gz: FAILED `long_description` has syntax errors in markup and would not be rendered on PyPI. line 3: Error: Unexpected indentation. warning: `long_description_content_type` missing. defaulting to `text/x-rst`.
解決方法
license
を外部ファイルから読み込むのではなく、文字列をハードコーディングしました。
(上記エラーの「long_description has syntax errors in markup and would not be rendered on PyPI」とはいったい...)
これだけ見るとなんでこんなことに数時間も気づかなかったのか・・・という感じです。
そもそもこのlicense
を外部ファイルから読み込もうとしていたのがダメだったようです。
下記が修正後のsetup.py
です。
import os from setuptools import setup, find_packages with open('README.md', 'r', encoding='utf-8') as f: long_description = f.read() def read_requirements(): """Parse requirements from requirements.txt.""" reqs_path = os.path.join('.', 'requirements.txt') with open(reqs_path, 'r') as f: requirements = [line.rstrip() for line in f] return requirements setup( name='nlplot', version='1.0.1', description='Visualization Module for Natural Language Processing', long_description=long_description, long_description_content_type='text/markdown', author='Takanobu Nozawa', author_email='takanobu.030210@gmail.com', url='https://github.com/takapy0210/nlplot', # license=license, license='MIT License', install_requires=read_requirements(), packages=find_packages(exclude=('tests')), package_data={'nlplot':['data/*']}, python_requires='~=3.6' )
testpypiへのアップロードも上手くいきました。
twine upload -r testpypi dist/* Uploading distributions to https://test.pypi.org/legacy/ Enter your password: Uploading nlplot-1.0.1-py3-none-any.whl 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 947k/947k [00:02<00:00, 358kB/s] Uploading nlplot-1.0.1.tar.gz 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 945k/945k [00:01<00:00, 705kB/s] View at: https://test.pypi.org/project/nlplot/1.0.1/
後述していますが、LICENSEファイルを作り方はGithub公式ドキュメントがあるので、こちらを参考に作るのが良さそうです。
以下、試行錯誤の履歴です。
やったこと
基本的には下記手順でチェックしました。
$ python setup.py sdist $ python setup.py bdist_wheel $ twine check dist/*
都度twine upload -r testpypi dist/*
コマンドでtestpypiへアップロードできるかどうかチェックしても良いですが、twine check
を使ってアップロード前に確認すると、無駄にversionをインクリメントする必要もないので、オススメです。
各種パッケージのアップデート
やりましたが、うまくいかず。
pip install --upgrade setuptools wheel twine
公式の書き方をもう一度確認
description
周りの書き方をコピーしてみましたが、上手くいかず。
long_descriptionをコメントアウト
... setup( name='nlplot', version='1.0.0', description='Visualization Module for Natural Language Processing', # long_description=long_description, # long_description_content_type='text/markdown', author='Takanobu Nozawa', author_email='takanobu.030210@gmail.com', url='https://github.com/takapy0210/nlplot', license=license, install_requires=read_requirements(), packages=find_packages(exclude=('tests')), package_data={'nlplot':['data/*']}, python_requires='~=3.6' ) ...
twine check
でwarning
は出るものの、Error
は無くなった。
twine check dist/* Checking dist/nlplot-1.0.0-py3-none-any.whl: PASSED, with warnings warning: `long_description_content_type` missing. defaulting to `text/x-rst`. Checking dist/nlplot-1.0.0.tar.gz: PASSED, with warnings warning: `long_description_content_type` missing. defaulting to `text/x-rst`.
ここでアップロードしてみると、無事に終了した。
twine upload -r testpypi dist/* Uploading distributions to https://test.pypi.org/legacy/ Enter your password: Uploading nlplot-1.0.0-py3-none-any.whl 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 947k/947k [00:03<00:00, 278kB/s] Uploading nlplot-1.0.0.tar.gz 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 945k/945k [00:01<00:00, 583kB/s] View at: https://test.pypi.org/project/nlplot/1.0.0/
test PyPIでみてみると、なんかおかしい。
最後の希望Twitterへ
PyPIへのアップロード、https://t.co/NUUYlDjJ3Gのlong_descriptionにREADMEをうまく設定できないので、long_descriptionの設定は一旦諦めるか・・・😢
— takapy | たかぱい (@takapy0210) 2020年5月10日
すると、u++さんからjapanize-matplotlib
を参考にしてみては?との助言を頂きました。
(u++さんありがとうございます。)
ん〜・・・long_description
周りの記述は悪くなさそうだな...
license
の書き方がちょっと違うから、念のためここを変更して確認してみることに。
... setup( name='nlplot', version='1.0.0', description='Visualization Module for Natural Language Processing', long_description=long_description, long_description_content_type='text/markdown', author='Takanobu Nozawa', author_email='takanobu.030210@gmail.com', url='https://github.com/takapy0210/nlplot', # license=license, license='MIT License', install_requires=read_requirements(), packages=find_packages(exclude=('tests')), package_data={'nlplot':['data/*']}, python_requires='~=3.6' ) ...
twine check
をしてみると、warningもErrorも出ない。
twine check dist/* Checking dist/nlplot-1.0.0-py3-none-any.whl: PASSED Checking dist/nlplot-1.0.0.tar.gz: PASSED
ちなみに元々読み込んでいたLICENSE.txt
の中身はこちら。
MIT License Copyright (c) 2020, Takanobu Nozawa
こちらが悪さをしていた様子。(このファイルを1行だけにすると上手くいきました)
検索してみると、Githubの公式にこのLICENSEファイルの作り方がありました。
そもそも setup()
のlicense
のこのファイルの内容を設定しようしていたのがダメだったようです。
最後に
同じようなことで数時間溶かす人がいなくなりますように。