【サイドドアpython 02】setuptoolsでpython whlパッケージを構築する方法


目次
  • 前言
  • 前置準備
  • 一、wheelパッケージの種類
  • 二、wheelパッケージのパッケージングプロセス
  • 2.1 pyproject.toml
  • 2.2 setup.pyの作成
  • 2.2.1基本組成
  • 2.2.2コマンドライン命令
  • 2.2.3条件式依存関係
  • 2.2.4メタデータ
  • 2.3パッケージ/インストール
  • 三、manylinux wheelパッケージ
  • 四、総括
  • 五、参考資料
  • 前言
    ハトは長い間穴を埋めることにしていたが...本編では前編を引き継ぎ、python wheelバッグの作成について話すつもりだ.原則としてカバーしなければならない内容は多いが、紙面に邪魔されて最も関連する部分を抽出するしかない.一般的な開発者がこの部分を使う必要はありませんが、いつオープンソースコミュニティに自分の書いたパッケージを提供したいか、このブログに一定の指導をもたらすことを望んでいるかもしれません.
    事前準備
    pythonのパッケージツールは多く、setuptoolsはデフォルトとは言えませんが、現在最も流行しているものです.まず、自分のシステムにwheelsetuptoolsの2つのモジュールがあることを確認しなければなりません.
    pip install wheel setuptools --user
    
  • setuptoolsはパッケージング動作を完了するための
  • である.
  • wheelsetuptoolsの派生プラグインであり、wheelパケットと対話するためのいくつかのコマンドライン命令
  • を提供する.
    一、wheelパッケージの種類
  • Universal wheel:py2.py3-none-any.whlという名前のパッケージが付いています.python 2やpython 3、オペレーティングシステムなどには要求がなく、互換性が優れています.
  • Pure-python wheel:py3-none-any.whlまたはpy2-none-any.whlという名前のパッケージがあります.universal wheelと比較するとpythonのバージョンでのみ要求されます.
  • Platform wheel:pythonバージョンやオペレーティングシステムなどに要求があります.このタイプのwheelを作成することは、一般に、内部で静的言語で記述されたコード(C++など)が使用されていることを意味します.これらのコードはコンパイル時にプラットフォームに要求されるため、wheelパッケージにもプラットフォーム依存性があります.
  • pip installは実行時に現在の環境と互換性のあるバージョンを探し、互換性のあるバージョンが見つからないが、ソースリリースが見つかった場合、ソースリリースをダウンロードしてローカルでコンパイルインストールする.ソースリリース版も見つからない場合は、インストールが間違っています.
    二、wheelパッケージの梱包過程
    2.1 pyproject.toml pyproject.tomlは、Pythonプロジェクトがどのようなコンパイルツールを使用するかを示すためにPEP 518に導入された.これまで、プログラムがwheelプロセスに必要なコンパイルツールにパッケージ化されるプロジェクトを自動的に知ることはできませんでした.PEP 518に加えて、PEP 517はコンパイルツールを使用してパッケージコンパイルを完了する方法を示し、さらに全体的なプロセスの標準化を実現し、異なるコンパイルツールとプロセスを統一した.もちろん、それらがもたらすメリットはいくつかありますが、ここでは展開しません.setuptoolsユーザーにとって、setuptoolsのバージョンを説明するだけで十分です.
    [build-system]
    requires = ["setuptools >= 40.6.0", "wheel"]
    build-backend = "setuptools.build_meta"
    

    筆者はいくつかの大きなオープンソースプロジェクトを少し閲覧したが,pyproject.tomlの存在は発見されなかった.もちろん、これは統一化の過程にすぎず、未来はもっとよくできるかもしれません.
    2.2 setup.pyの作成
    2.2.1基本構成setup.pyは、パッケージングプロセスのコアファイルです.次のファイル構造を例に挙げます.
    example_project/
    ├── exampleproject/      
    │   ├── __init__.py      
    │   └── example.py    
    └── README.md
    

    これに対応して、最小setup.pyの例は以下の通りである.
    from setuptools import setup, find_packages
    
    setup(
        name='example',
        version='0.1.0',
        packages=find_packages(include=['exampleproject', 'exampleproject.*']),
        install_requires=[
        	'numpy',
        	'matplotlib',
        	'pandas'
        ]
    )
    
  • name:必要なフィールドは、pip検索時のパッケージ名を指定し、プロジェクトフォルダと同名にする必要はありません.
  • version:必要なフィールド、バージョン番号、国際標準のバージョン番号命名方式に従うことが望ましい.
  • packages:必要なフィールドで、すべてのサブモジュールの位置を指定します.
  • install_requires:不要なフィールドで、パッケージが他のライブラリに使用される必要がある場合は、通常のrequirements.txtと一致するように明記できます.

  • 2.2.2命令ライン指令
    一部のPythonパッケージでは、インストールが完了すると自動的にコマンドライン命令が提供され、jupyter-notebook命令のように有名です.これは、setup.pyにフィールドを追加することによって実現される.jupyterプロジェクトのsetup.pyを直接観察することができます.
    ...
    entry_points = {
         
    	'console_scripts': [
    	    'jupyter-notebook = notebook.notebookapp:main',
    	    'jupyter-nbextension = notebook.nbextensions:main',
    	    'jupyter-serverextension = notebook.serverextensions:main',
    	    'jupyter-bundlerextension = notebook.bundler.bundlerextensions:main',
    	]
    }
    ...
    
    entry_pointsは、上記のnameなどのフィールドと同等であり、console_scriptsの文字が追加され、すべてのコマンドライン命令がリストされ、各命令に対応する関数の位置が示されている.文法的には難しくない.
    2.2.3条件式依存関係
    同じパッケージでは、開発時に各モジュールのパフォーマンスを画像で観察する必要があるが、ラインに配置する必要はないなど、異なる依存関係があります.この場合、extras_requireキーワードが必要です(jupyter項目を例にします):
    extras_require = {
         
        'test': ['pytest', 'coverage', 'requests',
                 'nbval', 'selenium', 'pytest', 'pytest-cov'],
        'docs': ['sphinx', 'nbsphinx', 'sphinxcontrib_github_alt',
                 'sphinx_rtd_theme', 'myst-parser'],
        'test:sys_platform != "win32"': ['requests-unixsocket'],
        'json-logging': ['json-logging']
    },
    

    このフィールドを追加すると、通常のpip install jupyterを実行する場合、install_requiresフィールドに要求される依存ライブラリのみがインストールされます.pip install jupyter[test]を実行すると、pytestcoverageなどの7つのパッケージが追加されます.pip install jupyter[docs]を実行すると、sphinxnbsphinxの5つのパッケージが追加されます.
    2.2.4メタデータ
    次のフィールドはメタデータに属します.パッケージをPyPIにパブリッシュするときは、パッケージのメンテナ情報を他のユーザーに知らせるために、これらのフィールドを追加することが望ましいです.
  • author:作者名
  • author_email:作者のメールボックス
  • description:パッケージの一言説明
  • url:パッケージに対応するアイテムのリンク
  • license/license_files:プロジェクトで使用される証明書
  • 2.3パッケージ/インストール
    上記の内容を設定した後、パッケージは一言でいいです.
    python setup.py sdist bdist_wheel
    

    あるいは、システムにbuildパック(pip install build)が入っていれば、
    python -m build
    

    完了すると、プロジェクトのdistディレクトリファイルの下にソース発行パッケージ(.tar.gz)とwheelパッケージ(.whl)が見つかります.
    三、manylinux wheelパッケージ
    これらのプロセスはuniversalタイプのwheelで使用できますが、プラットフォームのターゲットがある場合には適用されません.manylinuxはlinux環境での解決策です.工業的によく用いられる手段は,持続的集積(CI)サーバによるコンパイルである.manylinuxコンパイルをローカルで実行するにはDockerのサポートが必要です.PyPAは開発者に一連のDockerミラーとmanylinuxサンプルrepoを提供してこの方面の仕事をサポートした.この詳細は本稿では展開されず,興味のある開発者はこの2つのリンクをクリックして参照することができる.
    四、まとめ
    この記事では、setuptoolsを使用してpythonパッケージをパッケージ化する簡単な手順について説明します.この過程でjupyterプロジェクトは私に多くのことを学ばせて、それらのsetup.pyはとてもきれいに書いて、強く暇があればちらっと見ることをお勧めします(参考資料を参照)
    しかし、前書きで述べたように、現在の梱包手段はsetuptoolsに限られず、次の編では他の計画がなければpoetryを勉強して何が違うのかを見るつもりです.
    五、参考資料
  • Pythonパッケージングツールの進化史(英語)
  • あっさり!Pythonパッケージ管理ツールの発展史
  • Jupyterプロジェクト
  • PEP518
  • What the heck is pyproject.toml?
  • A practical guide to using setup.py
  • Setuptools quickstart
  • How to Publish an Open-Source Python Package to PyPI