パッケージングとプロジェクトの配布#

この節では、 setuptools を使ったPythonパッケージの設定・パッケージング・配布方法について、 :doc:`/tutorials/packaging-projects`_ の入門的なチュートリアルでは触れていないような追加的な詳細を説明します。あなたが既に パッケージをインストールする ページの内容については慣れ親しんでいるものと仮定して進めます。

この節は、Pythonプロジェクトの開発についての全体的なベストプラクティスを説明しているわけではありません。例えば、バージョン管理や文書化、あるいは試験について、手引きとなったりツールを推奨するようなことはありません。

より詳しい参考文献としては、Setuptools の説明文書の中の パッケージのビルドと配布 を挙げておきますが、推奨事項のいくつかはもはや古くなっているかもしれません。喰い違いがあった場合には、Python パッケージングユーザガイドの推奨事項を優先してください。

パッケージングと配布に対する要求事項#

  1. 最初に、あなたが既に パッケージをインストールする際の要求事項 を満たしていることを確実にしてください。

  2. "twine"をインストールする [1]:

    python3 -m pip install twine
    
    py -m pip install twine
    

あなたのプロジェクトの 配布物PyPI にアップロードする( 後述 )ためにこれが必要になるでしょう。

あなたのプロジェクトを設定する#

最初に必要なファイル群#

setup.py#

最重要のファイルは、あなたのプロジェクトのディレクトリの一番上(ルート)にある setup.py です。PyPA サンプルプロジェクトsetup.py に具体例があります。

setup.py はふたつの主要な機能を提供します。

  1. まず、あなたのプロジェクトをさまざまな角度から設定するためのファイルです。 setup.py の主要な機能は、グローバルな setup() 関数を含んでいることです。この関数にキーワード引数を渡すことで、あなたのプロジェクトの特定の細部を定義することができます。適切な引数のほとんどについて 次節 で説明します。

  2. それは、パッケージングする上での作業項目に関連したさまざまなコマンドを走らせるためのコマンドラインインタフェイスです。使用可能なコマンドを一覧するには、 python setup.py --help-commands を実行してください。

setup.cfg#

setup.cfgsetup.py のコマンド群に対するオプションの既定値を含む初期化ファイルです。 PyPA サンプルプロジェクト の中の setup.cfg に使用例が出ています。

README.rstとREADME.md#

すべてのプロジェクトは、プロジェクトのゴールを記したreadmeファイルを備えるべきです。一番良くあるフォーマットは拡張子が "rst" の reStructuredText ですが、これは(訳註、必須の)要求事項というわけではありません。他にも複数の種類の マークダウン フォーマットがサポートされています(setup()long_description_content_type 引数を見てください)。

PyPA sample project の中の README.md に例が出ています。

注釈

setuptools`の0.6.27およびそれ以降のバージョンを使っているプロジェクトでは、標準のreadmeファイル(:file:`README.rstREADME.txt、または README)がデフォルトでソースコード配布物に含まれるようになっています。標準ライブラリの distutils では、Python 3.7からこの動作を採用しました。さらに、Setuptools の36.4.0およびそれ以降のバージョンでは、もし見つかれば README.md を含めるようになっています。もしあなたがsetuptoolsを使っているのであれば、あなたはreadmeファイルを MANIFEST.in に明記する必要はありません。そうでないなら、明示的に書いてください。

MANIFEST.in#

自動的に追加されるファイル以外のファイルをソースコード配布物に追加したい場合には、 MANIFEST.in が必要になります。 どんなファイルがデフォルトで自動的に追加されるのかも含めて、 MANIFEST.in の書き方の詳細については「 MANIFEST.in の使い方」を見てください。

しかしながら、あなたは必ずしも MANIFEST.in を使わなくても構いません。一つの例として`PyPA サンプルプロジェクト <https://github.com/pypa/sampleproject>`_ では、必要なファイルがすべて 43.0.0およびこれ以降の:ref:`setuptools`に含まれているので、マニフェストファイルを削除しています。

注釈

MANIFEST.in は、wheelなどのバイナリ配布物には影響を与えません。

LICENSE.txt#

各パッケージは、配布の条件を指定するライセンスファイルを含んでいるべきです。多くの司法管轄区域(訳註、大雑把にいうと「多くの国」)では、明示的なライセンス条項がないと、著作権保持者でなければ誰も適法にパッケージを使用したり配布したりすることができません。どのライセンスを選択すればよいか分からない場合には、GitHubの「オープンソースライセンスを選ぶには」 などのリソースを見ることも、弁護士に相談することもできます。

PyPAサンプルプロジェクトLICENSE.txt に例がでています。

<あなたのパッケージ>#

必ずそうしなければならないというわけではありませんが、あなたのプロジェクトと同じか非常に近い 名前 の単一のプロジェクトをPythonのモジュールやパッケージのトップレベルに配置するということが共通の慣習になっています。

PyPAサンプルプロジェクト に含まれる サンプル パッケージに例が出ています。

setup() の引数#

上述の通り、setup.py の第一の機能は、グローバルスコープの setup() 関数を含むことです。この関数に与えるキーワード引数は、あなたのプロジェクトの特定の細部がどのように定義されているかを示すものです。

もっともよく使われる引数についてこの後解説します。ほとんどのソースコード断片(スニペット)は、PyPA サンプルプロジェクト の中の setup.py から取られたものです。

名称#

name='sample',

これは、あなたのプロジェクトが PyPI でどこに並べられるかを決めるプロジェクトの名前です。 PEP 508 に従えば、正当なプロジェクト名は以下の条件を満たさなければなりません:

  • ASCII文字・数字・アンダースコア(_)・ハイフン(-)・ピリオド(.)だけを含むこと、かつ、

  • 先頭と最後の文字がASCII文字ないし数字であること。

プロジェクト名の比較では、大文字小文字を区別せず、また、アンダースコア・ハイフン・ピリオドは何文字連続していても同じものとして扱います。例えば、あなたが cool-stuff という名前のプロジェクトを登録したなら、利用者がダウンロードしたり依存関係を宣言したりするのに、次に挙げる綴りのどれでも使うことができます:

Cool-Stuff
cool.stuff
COOL_STUFF
CoOl__-.-__sTuFF

version#

version='1.2.0',

これはあなたのプロジェクトの現在のバージョンで、これがあることであなたのプロジェクトのユーザたちが自分が最新版を使っているのかどうかを判断したり、彼ら自身のソフトウェアと組み合わせて試験を行ったバージョンがどれなのかを示したりすることができるようになります。

バージョンは、あなたが自分のプロジェクトをリリースする度に PyPI 上に表示されます。

あなたのユーザへ互換性情報を伝える方法としてバージョン番号を使うやり方については、 バージョンをつける規則を選択するには をご覧ください。

プログラムが動作している間に自分自身のバージョンを知る必要があるのであれば、バージョン番号を setup.py とあなたのソースコードの両方に格納しておくのがもっとも単純な方法です。値を複数箇所に書きたくないのであれば、やり方が2,3種類あります。「 バージョンを一箇所で管理するには 」の「高度な話題」の節を見て下さい。

説明#

description='A sample Python project',
long_description=long_description,
long_description_content_type='text/x-rst',

あなたのプロジェクトについて、短い説明と長い説明を与えて下さい。

これらの値は、あなたのプロジェクトを公開したときに PyPI に表示されます。 pypi.org のユーザインタフェイスでは、灰色のバナーに description を表示し、「プロジェクトの説明」と名付けられたセクションに long_description を表示します。

description は、プロジェクト一覧にも表示されます。例えば、https://pypi.org/search/?q=jupyter のような検索結果のページや、フロントページの流行プロジェクトや新規リリースプロジェクトの一覧や、あなたのアカウントのプロファイルページ(例えば https://pypi.org/user/jaraco/)の中のあなたがメンテナンスしているプロジェクトの一覧に表示されるということです。

long_description_content_type 引数に特に整形しない text/plainreStructuredText (reST) として解釈される text/x-rstMarkdown の中でもGitHub方言のものとして解釈される text/markdown のうちのいずれかを与えることで、コンテンツタイプ を指定することができます。

url#

url='https://github.com/pypa/sampleproject',

あなたのプロジェクトのホームページのURLを与えてください。

author#

author='A. Random Developer',
author_email='author@example.com',

著者について詳しい情報を提供してください。

ライセンス#

license='MIT',

license 引数には、あなたのパッケージがどのライセンスの下で公開されたかを示すこともできますが、これは必須ではなくオプションです。あなたが一般的でよく知られたライセンスを採用するのであれば、 分類詞 <classifiers> を指定するだけで済ませることができると同時に済ませるべきです。メジャーなオープンソースライセンスであればどれでも、それを指し示す分類詞が用意されています。

license 引数は、よく知られたライセンスとの違いを示すために使われたり、あなた自身の独自のライセンスを取り込むために使われたりすることの方がより典型的です。混乱を避けるために、また、組織によってはそのライセンスが認可されていないためにソフトウェアの使用を避けることがあるので、一般論としては、一般的なよく知られたライセンスを採用することは良い考えです。

分類詞 <classifiers>#

classifiers=[
    # How mature is this project? Common values are
    #   3 - Alpha
    #   4 - Beta
    #   5 - Production/Stable
    'Development Status :: 3 - Alpha',

    # Indicate who your project is intended for
    'Intended Audience :: Developers',
    'Topic :: Software Development :: Build Tools',

    # Pick your license as you wish (should match "license" above)
    'License :: OSI Approved :: MIT License',

    # Specify the Python versions you support here. In particular, ensure
    # that you indicate whether you support Python 2, Python 3 or both.
    'Programming Language :: Python :: 2',
    'Programming Language :: Python :: 2.7',
    'Programming Language :: Python :: 3',
    'Programming Language :: Python :: 3.6',
    'Programming Language :: Python :: 3.7',
    'Programming Language :: Python :: 3.8',
    'Programming Language :: Python :: 3.9',
],

あなたのプロジェクトを特徴付ける分類詞(classifier)を設定してください。https://pypi.org/classifiers に全部の一覧が出ています。

そのプロジェクトがどのPythonバージョンをサポートしているのかを分類詞リスト(classifiers)で告知することが往々にしてあるのですが、この欄はPyPIでプロジェクトを検索・閲覧する時に使われるためにだけ用意されているのであって、プロジェクトをインストールする時のためのものではありません。本当にPythonのバージョンに制約を付けたい場合には、 :ref:`python_requires`引数を使ってください。

パッケージが (誤って) PyPI にアップロードされるのを防ぐには、 'Private :: Do Not Upload' 分類子を使いましょう。"Private ::' で始まる分類子を付けられたパッケージを PyPI は常に拒否します。

keywords#

keywords='sample setuptools development',

あなたのプロジェクトを説明するキーワードを列挙してください。

project_urls#

project_urls={
    'Documentation': 'https://packaging.python.org/tutorials/distributing-packages/',
    'Funding': 'https://donate.pypi.org',
    'Say Thanks!': 'http://saythanks.io/to/example',
    'Source': 'https://github.com/pypa/sampleproject/',
    'Tracker': 'https://github.com/pypa/sampleproject/issues',
},

あなたのプロジェクトに関係する追加的なURLを列挙してください。これは、バグ追跡システムやソースコードリポジトリ、あるいは、パッケージ開発をサポートする場所などをリンクするための場所です。キー文字列をそのままテキストとしてPyPI上に表示されます。

packages#

packages=find_packages(include=['sample', 'sample.*']),

packages には、あなたのプロジェクトにある パッケージ を子パッケージや孫パッケージなども含めてすべて列挙してください。パッケージは手動で列挙することもできますが、 setuptools.find_packages() を使えば自動で列挙することができます。 include キーワード引数を使うと、ここに与えられた特定のパッケージだけを探索することができます。 exclude キーワード引数を使うと、公開したりインストールしたりする意図のないパッケージを除外することができます。

py_modules#

py_modules=["six"],

あなたのプロジェクトに、プロジェクトの一部ではない単一ファイルのPythonモジュールがあるなら、 Setuptools に知らせるために、そのようなモジュールの(拡張子``.py``を削除した)名前を py_modules に列挙してください。

install_requires#

install_requires=['peppercorn'],

install_requires は、プロジェクトが動作するために最低限必要な依存関係を指定するのに使われます。プロジェクトが pip でインストールされる場合には、この指定を見て依存関係(訳註、にある他パッケージ)をインストールするために用いられます。

さらなる install_requires の使い方については install_requires対Requirementsファイル を参照してください。

python_requires#

あなたのプロジェクトが特定のバージョンのPythonでないと動作しないのであれば、適切な PEP 440 バージョン特定文字列で python_requires 引数を設定しておくことで pip が他のバージョンの Python なのに当該プロジェクトをインストールしてしまうことがなくなります。例えば、あなたのパッケージが Python 3+ 向けのものであれば、このように書いてください:

python_requires='>=3',

Python 2.6と2.7、そして3.3以上のPython 3用であればこのように書きます:

python_requires='>=2.6, !=3.0.*, !=3.1.*, !=3.2.*',

等々。

注釈

この機能がサポートされたのは比較的最近のことです。 python_requires 引数が認識されて適切なメタデータが生成されるためには、あなたのプロジェクトのソースコード配布物やwheels (あなたのプロジェクトをパッケージする 参照)を24.2.0かそれ以降のバージョンの Setuptools でビルドしなければなりません。

さらに、 pip のバージョン9.0.0かそれ以降のものでなければ python_requires のメタデータを認識しません。これより前のバージョンのpipを使っている場合は、 python_requires の設定に関わりなくどんなバージョンのPythonを使っていてもダウンロードやインストールが可能です。

package_data#

package_data={
    'sample': ['package_data.dat'],
},

追加のファイルを パッケージ にインストールする必要がある、というのはよくあることです。このようなファイルは、しばしば、そのパッケージの実装に深く関係していたり、パッケージを利用するプログラマの利益になるような説明を含んだテキストファイルであったりします。このようなファイルは「パッケージデータ」と呼ばれます。

この引数に渡す値は、パッケージ名から、そのパッケージ内にコピーされるべきファイルの相対パス名を列挙したもののマッピングになっていなければなりません。パス名はパッケージを含むディレクトリからの相対パスとして解釈されます。

詳しくは、 setuptools説明文書 の中の データファイルを追加するには を見てください。

data_files#

data_files=[('my_data', ['data/data_file'])],

パッケージデータ を設定すればほとんどの需要に応えられますが、あなたの パッケージ外側 にデータファイルを置きたいこともあるでしょう。 data_files ディレクティブでそれができます。大抵は、Pythonのパッケージを認識しないような他のプログラムから利用するファイルをインストールする必要がある時に、これが役に立つでしょう。

設定値の中の (ディレクトリ, ファイル) の組は、それぞれインストール先のディレクトリとそこにインストールされるべきファイル(群)を指定しています。 ディレクトリ <directory> は相対パスでなければならず (これは将来変更されるかもしれません。 wheel Issue #92 を見てください)、インストール先プレフィクス(デフォルトではPythonの sys.prefix、ないし、ユーザインストールでは site.USER_BASE )に対する相対パスとして解釈されます。 files 内のファイル名は、プロジェクトのソースコード配布物の最上位にある setup.py スクリプトに対する相対パスとして解釈されます。

さらに詳しくは、 追加的なファイルをインストールするには の中のdistutilsの節を見てください。

注釈

パッケージをeggとしてインストールする時には、 data_files はサポートされていません。だから、もしあなたのプロジェクトで Setuptools を使っているならば pip でインストールしなければなりません。あるいは、 --old-and-unmanageable オプション付きの python setup.py を使わなければなりません。

scripts#

setup() はあらかじめ作成されたスクリプトをインストールするために scripts キーワードをサポートしていますが、異機種間の互換性を取るためのアプローチとして推奨されるのは console_scripts エントリーポイント(後述)を使うことです。

entry_points#

entry_points={
  ...
},

あなたのプロジェクト内か依存先のプロジェクトで定義された名前付きのエントリーポイントをあなたのプロジェクトが提供しているようなプラグインがあればこのキーワード引数を使って指定してください。

詳しくは、setup tools 文書の 広報する動作 の節を見てください。

よくあるエントリーポイントとしては、"console_scipts" (後述)が挙げられます。

console_scripts#
entry_points={
    'console_scripts': [
        'sample=sample:main',
    ],
},

console_script エントリーポイント は、スクリプトインターフェイスを登録するために使ってください。そうすれば、ツールチェーンがそのようなインターフェイスを実際のスクリプトに変換する作業を肩代わりしてくれます[2]_ 。あなたの 配布物 をインストールする途中でスクリプトが生成されます。

詳しくは、 setuptools 説明文書 の中の エントリポイント を見てください。

バージョン体系を選択する#

相互互換性のための標準的な取り決め#

相異なるPythonプロジェクトがそれぞれの事情に合わせて異なるバージョン体系を採用することは構いませんが、しかし、いずれにしても、pipsetuptools のようなツールやライブラリにサポートされるためには、PEP 440 で指定された 公式のバージョン体系 の自由度の高い規定に合致していなければなりません。

規定に合致したバージョン番号の例を次に示す:

1.2.0.dev1  # Development release
1.2.0a1     # Alpha Release
1.2.0b1     # Beta Release
1.2.0rc1    # Release Candidate
1.2.0       # Final Release
1.2.0.post1 # Post Release
15.10       # Date based release
23          # Serial release

過去の様々なバージョン番号付与方法を規定内に包含するために、 PEP 440 は様々なバージョン番号の変種的書き方を網羅する バージョンの正規化 のテクニックも定義しています。

方法論の選択#

意味を伴ったバージョン付与 (推奨)#

新しいプロジェクトには、 意味あるバージョン付与方法 に従うことが推奨されていますが、リリース前やビルド時のメタデータとしては異なるやり方を採用しても良いでしょう。

意味あるバージョン付与方法の真髄は、MAJOR.MINOR.MAINTENANCE の3段階のバージョン付与方法で、プロジェクトの作者は以下のように各段階の数字を増やします:

  1. APIの変更で互換性を失う時には MAJOR 番号、

  2. 後方互換性を保ったままで新機能を追加する場合には MINOR を、そして

  3. 後方互換性を維持したままのバグ修正の場合には MAINTENANCE を増加させます。

プロジェクトの作者としてこのやり方を採用すれば、ユーザが 互換性のあるリリース の指定、つまり、name ~= X.Y と指定してあるなら少なくともリリース X.Y が必要だが同じMAJORバージョンを持つならその後のリリースでも構わないという書き方を利用することができるようになります。

セマンティックバージョニングを採用しているPythonプロジェクトでは、 セマンティックバージョニング 2.0.0 仕様書 の第1節から第8節までに従うべきです。

日付ベースのバージョン付与#

セマンティックバージョニングはすべてのプロジェクト向きと言うわけではなく、例えば定期的なリリースサイクルに従う場合や、ある機能を削除する前に何世代にもわたるリリースで非推奨(deprecation)の警告を出すような場合には適していないかもしれません。

日付ベースのバージョン付与の最大の利点は、バージョン番号を見ただけで基盤になっている機能セットがどれほど古いのかが直截にわかることです。

日付ベースのバージョン番号は、YEAR.MONTHの形(例えば 12.04``や``15.10)をとるのが普通です。

一連番号によるバージョン付与#

これは最も単純なバージョン付与方法で、リリースのたびに増加する単一の番号で構成します。

一連番号によるバージョン付与は開発者にとってはとても管理しやすい反面、一連番号によるバージョン番号を見てもAPIの後方互換性に関する情報がほとんど又は全くわからないので、ユーザにとっては追跡するのが最も困難です。

混成型の方法#

上に述べた方式を組み合わせて用いることもできます。例えば、日付ベースのバージョン付与と一連番号によるバージョン付与を組み合わせて YEAR.SERIAL型のバージョン番号付与方式を作り出して、バージョン番号がリリース年を示すけれどもその年の中のどのリリースサイクルかを特定することについてはあまり気にしていないというプロジェクトもあるでしょう。

リリース前のバージョン付与方式#

どのバージョン付与方式を採用するとしても、ある特定の最終的なリリースの前のリリースが次のような形で公開されることもあるでしょう:

  • 零またはそれ以上の dev リリース (".devN"という拡張子をつけて表示)

  • 零またはそれ以上のalphaリリース (".aN"という拡張子をつけて表示)

  • 零またはそれ以上のbetaリリース (".bN"という拡張子をつけて表示)

  • 零またはそれ以上のリリース候補 (".rcN"という拡張子をつけて表示)

``pip``や最近のPythonパッケージインストーラでは、依存関係にあるパッケージをインストールする際にリリース前のものを無視して含めないのが規定の動作です。

ローカルのバージョン指定子#

公的バージョン識別子は、 PyPI を通じた配布をサポートするように設計されています。Pythonのソフトウェア配布ツール群は、ローカルでの開発でビルドごとの識別子や再配布者が維持管理している変種のリリースの識別子として用いるような 局所的バージョン識別子 の考え方もサポートします。

ローカルバージョン識別子は、 <公的バージョン識別子>+<ローカルバージョンラベル> の形を取ります。例えば:

1.2.0.dev1+hg.5.b11e5e6f0b0b  # 5th VCS commit since 1.2.0.dev1 release
1.2.1+fedora.4                # Package with downstream Fedora patches applied

開発モードで作業する#

あなたがまだ作業している途中なら、プロジェクトを「編集可能」または「開発」モードでインストールすることができます。編集可能な状態でインストールされると、再インストールしなくてもプロジェクトをその場で編集することができます: 編集可能状態でインストールされたプロジェクトのPythonソースコードに変更を加えると、次にインタープリターのプロセスが開始された時に反映されます。

Pythonのパッケージを「編集可能」/「開発」モードでインストールするには、そのプロジェクトのルートディレクトリへ移動して、次のコマンドを走らせてください:

python3 -m pip install -e .

pip のコマンドラインオプションの -e--editable の省略形で、 . は現在作業をしているディレクトリのことですので、まとめると「現在のディレクトリ(つまりあなたのプロジェクト)に編集可能モードでインストールせよ」ということになります。また、このコマンドによって install_requires に宣言された依存先のパッケージや console_scripts に書かれたスクリプトもインストールされます。

依存先のプロジェクトも同様に編集可能モードでインストールしたい時があるかもしれません。例えば、あなたのプロジェクトが "foo" と "bar" というパッケージを要求していて、 "bar" についてはVCS (バージョンコントロールシステム) から編集可能モードでインストールしたい場合には、requirements ファイルを次のように構成すれば良いでしょう:

-e .
-e bar @ git+https://somerepo/bar.git

最初の行ではあなたのプロジェクトとその依存先をインストールするように指示しています。2行目で、 "bar" についてPyPIではなくVCSから充当するようにと依存関係を上書きしています。

そうではなくて、 "bar" をローカルディレクトリから編集可能モードでインストールしたい場合には、 requirements ファイルの先頭にローカルのディレクトリパスを置いて次のようになるでしょう:

-e /path/to/project/bar
-e .

さもなければ requirements ファイルに書かれた順にインストールされてしまうので、依存先のパッケージが PyPI から充当されてしまいます。 requirements ファイルについてさらに詳しく知りたい場合は、 pipの解説文書の Requirements ファイル の節を見てください。VCSからのインストールについては、同書の VCSサポート の節を見てください。

最後に、もし依存先パッケージは何もインストールしたくないのであれば、このようにします:

python3 -m pip install -e . --no-deps

さらに詳しいことを知りたい場合は、 Setuptools 文書の 開発モード の 節を見てください。

プロジェクトをパッケージングする#

あなたのプロジェクトを PyPI のような パッケージインデックス からインストールできるようにするには、 配布物 (:term:`パッケージ <Distribution Package>`の名前でも知られる) を作成しなければならないでしょう。

あなたのプロジェクトでwheelsやsdistsをビルドする前に、 build パッケージをインストールする必要があります。

python3 -m pip install build
py -m pip install build

ソースコード配布物#

少なくとも、 ソースコード配布物 を作成するべきです:

python3 -m build --sdist
py -m build --sdist

ソースコード配布物はビルドされていない (すなわち、 ビルド済み配布物 ではない) ので、pip でインストールする際にビルドする段階が必要になります。配布物が純Python (つまり (訳注、多言語で書かれた) 拡張を含まない) であったとしても、 setup.pysetup.cfg からインストール用メタデータを取り出してビルドする段階を必要とするのです。

Wheels#

あなたのプロジェクトでは、wheelも作成するべきです。wheel は、インストールするのにビルド処理を行う必要がない ビルド済み配布物 です。wheelを使えば、ソースコード配布物からのインストールに比べてエンドユーザにとって相当素早くインストールすることができます。

あなたのプロジェクトが純Pythonなら、きっとあなたは:ref:`"純PythonのWheel" (後述) <Pure Python Wheels>`を作成することになるでしょう。

もしあなたのプロジェクトにコンパイル済の拡張が含まれているなら、 *プラットフォーム Wheel* (後述) を作成することになるでしょう。

注釈

あなたのプロジェクトが Python 2をさぽーとしていて、かつ、C言語拡張を含むのであれば、次のものをあなたの setup.cfg ファイルに追加して ユニバーサル Wheel と呼ばれるものを作成するべきです:

[bdist_wheel]
universal=1

あなたのプロジェクトにC言語拡張がなく、かつ、Python 2 および3をサポートしている場合に限って、この設定を使ってください。

純Python Wheels#

純Python Wheels は、コンパイル済拡張を含んでおらず、従って単独のPython wheelを要求するだけです。

wheelをビルドするには:

python3 -m build --wheel
py -m build --wheel

wheel パッケージは、ソースコードが純Pythonであることを検出して、Python 3 へのインストールであればどこでも使えるのでそのように名付けられたwheelをビルドします。wheelファイルの名称について詳しいことは PEP 425 を見てください。

--wheel--sdist を付けずに build を実行すると、両方のファイルが作成されます; 複数のwheelファイルにしたくないときにはこれが便利です。

プラットフォームWheels#

プラットフォームWheels は、LinuxやmacOSあるいはWindowsのような特定のプラットフォーム向けのwheelで、大抵の場合は(訳注、特定のプラットフォーム向けにコンパイルされた)コンパイル済み拡張を含むためです。

wheelをビルドするには:

python3 -m build --wheel
py -m build --wheel

wheel パッケージは、ソースコードが純Pythonで書かれていないと判断すると、ビルドされたプラットフォーム上でのみ利用可能であるように命名されたwheelを作成します。wheelファイルの命名規則については、 PEP 425 を見てください。

注釈

現在、 PyPI は、Windows向けとmacOS向け、そして複数のLinuxディストリビューションに対応した manylinux* のABI向けのプラットフォームWheelsをアップロードすることに対応しています。

プロジェクトをPyPIにアップロードする#

配布物を作成するコマンドを走らせると、あなたのプロジェクトのルートディレクトリに dist/ という新しいディレクトリが作成されます。ここに配布物のファイル(群)が置かれます。

注釈

これらのファイルは、配布物作成のコマンドを走らせたときにだけ作成されます。ということは、プロジェクトのソースコードや setup.py の中の設定を変更したときにはいつでも、PyPIへ送る前に配布物のファイルを再作成する必要があるということです。

注釈

PyPIの主リポジトリでリリースをする前に、半定期的に消去される PyPI 試験サイト で練習する方が良いかもしれません。どのように設定すれば試験サイトを使えるかについては、 TestPyPI を使う を見てください。

警告

他のリソースでは、 python setup.py registerpython setup.py upload に遭遇するかもしれません。これらのメソッドはパッケージを登録ないしアップロードするものですが、 いくつかのバージョンのPythonで使うと平文のHTTPか検証しないHTTPSを用いるのであなたのユーザ名とパスワードが 通信経路上で横取りされる恐れがあって 強く非推奨 の状態になっています。

Tip

PyPIで使っている reStructuredText パーサは Sphinx ではありません! その上、全ユーザの安全を確保するためにある種の URL やディレクティブ(例えば .. raw:: ディレクティブ)は禁止されていたり削除されたりしています。あなたの配布物をアップロードしてみる 前に setup.py の中の brief/long description が文法的に妥当かどうかを確かめるべきです。あなたのパッケージのファイル群に対して twine check を走らせれば、それを確かめることができます。

twine check dist/*

アカウントを作成する#

まず、 PyPI のユーザアカウントが必要です。 PyPIウェブサイトにあるフォームを使えば アカウントを作成することができます。

次に PyPI の API トークン を作成して、プロジェクトを安全にアップロードできるようにしましょう。

https://pypi.org/manage/account/#api-tokens and create へ行って、新しい API トークン を作成してください; これから新しいプロジェクトを作成するわけですから、スコープを特定のプロジェクトに限定しないようにしてください。

トークンをコピーして保存するまではページを閉じないでください -- トークンは二度と表示されることがありません。

注釈

$HOME/.pypirc ファイルを作っておくことで、アップロードするたびにトークンをコピー・ペーストする手間を省くことができます。

[pypi]
username = __token__
password = <the token value, including the `pypi-` prefix>

このファイルにはトークンが平文で保存されていることに注意してください。

.pypirc についてさらに詳しく知りたい場合は specification を見てください。

配布物をアップロードする#

アカウントが入手できれば、 twine を使ってあなたの配布物を PyPI へアップロードすることができます。

リリースをアップロードする手続きは、そのプロジェクトがPyPIに既に存在していても存在していなくても同じです - もしまだ存在していなければ、最初にリリースがアップロードされたときに自動的に作成されます。

2回目やそれ以降のリリースで PyPI が要求するのは、新しいリリースのバージョン番号が先行するすべてのリリースとは異なるものであることだけです。

twine upload dist/*

sampleproject のところをアップロードしているプロジェクトの名前に置き換えるとして、 https://pypi.org/project/<sampleproject> に誘導されれば、あなたのパッケージのアップロードは成功です。あなたのプロジェクトがサイト上に表示されるまでには1,2分の時間がかかるかもしれません。