「Python パッケージガイドライン」の版間の差分

提供: ArchWiki
ナビゲーションに移動 検索に移動
(チェックを翻訳して追加)
(ヒントとテクニックを翻訳して追加)
181行目: 181行目:
 
}}
 
}}
   
  +
== ヒントとテクニック ==
   
  +
=== PyPI で分離された PGP 署名を検出する ===
== ファイルの配置場所 ==
 
   
  +
特定の Python sdist tarball の分離された PGP 署名が存在する場合、それらを tarball の検証に使用する必要があります。ただし、署名ファイルは、pypi.org の特定のプロジェクトのファイルダウンロードセクションには直接表示されません。sdist tarball とその潜在的な署名ファイルを検出するには、このサービスを使用してプロジェクトごとの概要を取得できます: https://pypi.debian.net/
ほとんどの Python パッケージは '''setup.py''' による [http://docs.python.org/library/distutils.html distutils] システムでインストールされます。ファイルは {{Ic|/usr/lib/python''<python version>''/site-packages/''pkgname''}} ディレクトリにインストールされます。
 
   
  +
{{Pkg|python-requests}} の場合、これは https://pypi.debian.net/requests になります。
* {{Ic|1=--optimize=1}} パラメータは {{Ic|.pyo}} ファイルをコンパイルして [[pacman]] から追跡することができます。
 
   
  +
=== python バージョンを使用する ===
もし [https://pip.pypa.io/en/stable/ pip] (wheels などのインストールで必要であり、最近 Python コミュニティから一般に推奨されています) を使う場合は、次のフラグを忘れずに渡してください:
 
   
  +
準備、構築、テスト、またはインストール中に、システムの Python のメジャーバージョンとマイナーバージョンを参照する必要がある場合があります。これをハードコードせず (例: {{ic|3.9}} や {{ic|3.10}})、代わりに Python インタープリターへの呼び出しを使用して情報を取得し、ローカル変数に保存します。
PIP_CONFIG_FILE=/dev/null pip install --isolated --root="$pkgdir" --ignore-installed --no-deps *.whl
 
   
  +
{{bc|1=
* {{ic|PIP_CONFIG_FILE&#61;/dev/null}} は '''pip''' にフラグを追加するかもしれない {{ic|{/etc,~/.config}/pip.conf}} を無視します。
 
  +
check(){
* {{ic|--isolated}} は '''pip''' にフラグを追加するかもしれない環境変数 (それと {{ic|{/etc,~/.config}/pip/pip.conf}}) を無視します。
 
  +
local python_version=$(python -c 'import sys; print(".".join(map(str, sys.version_info[:2])))')
* {{ic|--ignore-installed}} は https://github.com/pypa/pip/issues/3063 が解決されるまで必要です (フラグを指定しないと先に {{ic|--user}} でインストールされていた場合でも '''pip''' はインストールをスキップしてしまいます)。
 
  +
...
* {{ic|--no-deps}} はメインパッケージと一緒に依存関係がパッケージされないことを保証します。
 
  +
}
  +
}}
   
== ノート ==
+
=== サイパッケージの使用 ===
   
  +
構築、テスト、またはインストール中に、システムの {{ic|site-packages}} ディレクトリを参照する必要がある場合があります。このディレクトリをハードコードせず、代わりに Python インタープリタへの呼び出しを使用してパスを取得し、ローカル変数に保存します。
基本的に Python パッケージはアーキテクチャに依存しないので {{Ic|arch}} には {{Ic|any}} を指定します。
 
   
  +
{{bc|1=
{{Ic|tests}} という名前のディレクトリをインストールしてはいけません。他の Python パッケージと衝突する可能性があります (例: {{Ic|/usr/lib/python2.7/site-packages/tests/}})。
 
  +
check(){
  +
local site_packages=$(python -c "import site; print(site.getsitepackages()[0])")
  +
...
  +
}
  +
}}
   
  +
=== サイトパッケージ内のテストディレクトリ ===
== サンプル ==
 
   
  +
{{ic|tests}} という名前のディレクトリを {{ic|site-packages}} にインストールしないように注意してください (つまり、{{ic|/usr/lib/pythonX.Y/site-packages/tests/}}) setuptools を使用する Python パッケージプロジェクトは、テストを含むディレクトリをトップレベルの Python パッケージとして含めるように誤って設定されることがあります。これに遭遇した場合は、パッケージプロジェクトに問題を提出して修正を依頼することができます (例: [https://github.com/Lightning-AI/lightning/issues/10335 like this])
サンプル PKGBUILD は [https://projects.archlinux.org/abs.git/tree/prototypes/PKGBUILD-python.proto こちら] を見るか、{{Pkg|abs}}{{Broken package link|パッケージが存在しません}} パッケージに入っている {{Ic|/usr/share/pacman/PKGBUILD-python.proto}} ファイルを見て下さい。
 

2023年6月28日 (水) 17:28時点における版

このドキュメントでは Python ソフトウェアの PKGBUILD を書くときの決まり事とガイドラインを提供します。

パッケージの命名規則

Python 3 ライブラリモジュールの場合は、python-modulename を使用します。パッケージが Python エコシステムに強く結合されたプログラムを提供する場合にも、接頭辞を使用します (例: pip または tox) 他のアプリケーションの場合は、プログラム名のみを使用します。

ノート: パッケージ名はすべて小文字にする必要があります。

アーキテクチャ

PKGBUILD#arch を参照してください。

C 拡張機能を含む Python パッケージはアーキテクチャに依存します。それ以外の場合は、アーキテクチャに依存しない可能性が高くなります。

[1] を使用してビルドされたパッケージは、setup.pyext_modules キーワードを使用して C 拡張機能を定義します。

ソース

PyPI Web サイトからリンクされているダウンロード URL には、パッケージを更新する必要があるたびに PyPI Web サイトから取得する必要がある予測不可能なハッシュが含まれています。このため、PKGBUILD での使用には適していません。PyPI が提供 代替の安定したスキーム: PKGBUILD#source source=() 配列次の URL テンプレートを使用する必要があります。

ソースパッケージ
https://files.pythonhosted.org/packages/source/${_name::1}/$_name/$_name-$pkgver.tar.gz
純粋な Python wheel パッケージ
https://files.pythonhosted.org/packages/py2.py3/${_name::1}/$_name/${_name//-/_}-$pkgver-py2.py3-none-any.whl (バイリンガル – Python 2 および Python 3 互換)
https://files.pythonhosted.org/packages/py3/${_name::1}/$_name/${_name//-/_}-$pkgver-py3-none-any.whl (Python 3 のみ)
ディストリビューション名にはダッシュを含めることができますが、wheel ファイル名での表現にはダッシュを含めることができないことに注意してください (ダッシュはアンダースコアに変換されます)

アーキテクチャ固有の wheel パッケージ

source_x86_64=('...') のように、アンダースコアとアーキテクチャ名を追加することで、アーキテクチャ固有の配列を追加できます。また、_py=cp310 を使用して、Python バージョンを繰り返さないようにすることもできます。
https://files.pythonhosted.org/packages/$_py/${_name::1}/$_name/${_name//-/_}-$pkgver-$_py-${_py}m-manylinux1_x86_64.whl

Python パッケージには通常、python- という接頭辞が付けられるため、pkgname の代わりにカスタムの _name 変数が使用されることに注意してください。この変数は一般に次のように定義できます。

_name=${pkgname#python-}

インストール方法

Python パッケージは通常、pip などの言語固有のパッケージ マネージャーを使用してインストールされます。このマネージャーは、オンラインリポジトリ (通常は PyPI) からパッケージを取得します。 Package Index) を作成し、関連ファイルを追跡します。

ただし、PKGBUILD 内から Python パッケージを管理するには、Python パッケージを一時的な場所 $pkgdir/usr/lib/python<Python) に インストール する必要があります。バージョン>/site-packages/$pkgname

standard metadata を使って pyproject.toml でビルドバックエンドを指定している Python パッケージでは、python-buildpython-installer を使うのが最も簡単です。

古いパッケージでは、setuptools を使用することを指定できず、手動で呼び出す必要がある setup.py のみが提供される場合があります。

ノート: パッケージのメタデータからの依存関係は、depends 配列で定義する必要があります。定義しないとインストールされません。

標準ベース (PEP 517)

標準ベースのワークフローは簡単です。python-build を使用して wheel をビルドし、python-installer を使用してそれを $pkgdir にインストールします。

makedepends=(python-build python-installer python-wheel)

build() {
    cd "$_name-$pkgver"
    python -m build --wheel --no-isolation
}

package() {
    cd "$_name-$pkgver"
    python -m installer --destdir="$pkgdir" dist/*.whl
}

場所

  • --wheel では、wheel ファイルのみがビルドされ、ソースは配布されません。
  • --no-isolation は、システムにインストールされているもの (depends で指定したパッケージを含む) を使用してパッケージがビルドされることを意味します。デフォルトでは、ツールは分離された仮想環境にアクセスし、そこでビルドを実行します。
  • --destdir="$pkgdir" により、パッケージファイル内ではなくホストシステムに直接インストールしようとすることが防止されます。これにより、権限エラーが発生します。
  • --compile-bytecode=... または --no-compile-bytecodeinstaller に渡すことができますが、デフォルトは賢明に選択されているため、これは必要ありません。
警告: build をスキップして、source 配列に .whl ファイルを配置することは、ソースからビルドすることを優先するため推奨されません。後者が適切でない場合にのみ使用してください。実行可能なオプション (たとえば、wheel ソースのみが付属しているため、ソースからビルドできないパッケージ)
警告: あなたのパッケージが VCSパッケージ (python-...-git) の場合、git -C "${srcdir}/${pkgname}" clean -dfx コマンドを prepare 関数に含めてください。これにより、他のビルド成果物とともに古くなったホイールが削除され、後々の問題を防ぐことができます。https://github.com/pypa/setuptools/issues/1347 setuptools] および Poetry に関するアップストリームの課題も参照してください。

setuptools または distutils

pyproject.toml が見つからない場合、または [build-system] テーブルが含まれていない場合は、プロジェクトが セットアップ を使用する古いレガシー形式を使用していることを意味します。 setuptools または distutils を呼び出す .py ファイル。distutils は Python の standardlib に含まれていますが、setuptools がインストールされているということは、パッチ適用されたバージョンの distutils を使用することを意味することに注意してください。

makedepends=('python-setuptools')  # unless it only requires distutils

build() {
    cd "$_name-$pkgver"
    python setup.py build
}

package() {
    cd "$_name-$pkgver"
    python setup.py install --root="$pkgdir" --optimize=1
}

場所:

  • --root="$pkgdir" は上記の --destdir と同様に機能します
  • --optimize=1 は、最適化されたバイトコードファイル (.opt-1.pyc) をコンパイルします。これにより、ファイルはホストシステム上で作成されるのではなく、pacman から要求、追跡できるようになります。
  • --skip-build を追加すると、build() 関数で既に実行されているビルド ステップを再実行する不要な試行が最適化されます (該当する場合)

結果のパッケージに 非推奨の pkg_resources モジュールをインポートする 実行可能ファイルが含まれている場合は、setuptools を追加で指定する必要があります。分割された package_*() 関数の depends。 あるいは、PKGBUILD が Python の単一バージョンの Python パッケージのみをインストールする場合は、setuptoolsmakedepends から depends に移動する必要があります。

一部のパッケージは setuptools を使用しようとし、setuptools をインポートできない場合は distutils にフォールバックします。この場合、得られる Python メタデータがより適切になるように、setuptools を makedepends として追加する必要があります。

実行可能ファイル (distutils ではサポートされていない) が含まれているためにパッケージに setuptools をビルドする必要があるが、distutils のみをインポートする場合、ビルドすると警告が表示され、結果のパッケージは次のようになります。壊れている可能性があります (実行可能ファイルは含まれません):

/usr/lib/python3.8/distutils/dist.py:274: UserWarning: Unknown distribution option: 'entry_points'
  warnings.warn(msg)

アップストリームのバグは報告する必要があります。この問題を回避するには、文書化されていない setuptools 機能を使用できます。

# fails because of distutils
python setup.py build

# works by using a setuptools shim
python -m setuptools.launch setup.py build

パッケージで python-setuptools-scm を使用する場合、パッケージはビルドされず、次のようなエラーが発生する可能性があります。

LookupError: setuptools-scm was unable to detect version for /build/python-jsonschema/src/jsonschema-3.2.0.

Make sure you're either building from a fully intact git repository or PyPI tarballs. Most other sources (such as GitHub's tarballs, a git checkout without the .git folder) don't contain the necessary metadata and will not work.

SETUPTOOLS_SCM_PRETEND_VERSION をビルドするには、$pkgver を値として環境変数としてエクスポートする必要があります。

export SETUPTOOLS_SCM_PRETEND_VERSION=$pkgver

チェック

警告: tox は、tox の実行中にPyPIからダウンロードされた繰り返し可能な設定をテストするために明示的に設計されており、パッケージによってインストールされるバージョンをテストしません。これでは check 機能を持つ意味がありません。

テストスイートを提供するほとんどの Python プロジェクトは、nosetests または pytest を使用して、テストスイートを含むファイルまたはディレクトリの名前に test を含むテストを実行します。一般に、テストスイートを実行するには、nosetests または pytest を実行するだけで十分です。

check(){
    cd "$srcdir/foo-$pkgver"

    # For nosetests
    nosetests

    # For pytest
    pytest
}

コンパイルされた C 拡張機能がある場合は、それを見つけてロードするために、Python の現在のメジャーバージョンとマイナーバージョンを反映する $PYTHONPATH を使用してテストを実行する必要があります。

check(){
  cd "$pkgname-$pkgver"
  local python_version=$(python -c 'import sys; print("".join(map(str, sys.version_info[:2])))')
  # For nosetests
  PYTHONPATH="$PWD/build/lib.linux-$CARCH-cpython-${python_version}" nosetests

  # For pytest
  PYTHONPATH="$PWD/build/lib.linux-$CARCH-cpython-${python_version}" pytest
}

一部のプロジェクトでは、テストを実行するための setup.py エントリポイントが提供されています。これは、pytestnosetests の両方で機能します。

check(){
    cd "$srcdir/foo-$pkgver"

    # For nosetests
    python setup.py nosetests

    # For pytest - needs python-pytest-runner
    python setup.py pytest
}

ヒントとテクニック

PyPI で分離された PGP 署名を検出する

特定の Python sdist tarball の分離された PGP 署名が存在する場合、それらを tarball の検証に使用する必要があります。ただし、署名ファイルは、pypi.org の特定のプロジェクトのファイルダウンロードセクションには直接表示されません。sdist tarball とその潜在的な署名ファイルを検出するには、このサービスを使用してプロジェクトごとの概要を取得できます: https://pypi.debian.net/

python-requests の場合、これは https://pypi.debian.net/requests になります。

python バージョンを使用する

準備、構築、テスト、またはインストール中に、システムの Python のメジャーバージョンとマイナーバージョンを参照する必要がある場合があります。これをハードコードせず (例: 3.93.10)、代わりに Python インタープリターへの呼び出しを使用して情報を取得し、ローカル変数に保存します。

check(){
  local python_version=$(python -c 'import sys; print(".".join(map(str, sys.version_info[:2])))')
  ...
}

サイトパッケージの使用

構築、テスト、またはインストール中に、システムの site-packages ディレクトリを参照する必要がある場合があります。このディレクトリをハードコードせず、代わりに Python インタープリタへの呼び出しを使用してパスを取得し、ローカル変数に保存します。

check(){
  local site_packages=$(python -c "import site; print(site.getsitepackages()[0])")
  ...
}

サイトパッケージ内のテストディレクトリ

tests という名前のディレクトリを site-packages にインストールしないように注意してください (つまり、/usr/lib/pythonX.Y/site-packages/tests/) setuptools を使用する Python パッケージプロジェクトは、テストを含むディレクトリをトップレベルの Python パッケージとして含めるように誤って設定されることがあります。これに遭遇した場合は、パッケージプロジェクトに問題を提出して修正を依頼することができます (例: like this)