Python自作モジュールのパッケージ化手順

python

 自分で書いたコードをpipでインストールできるようにするためにはパッケージ化する必要があります。その作成手順をまとめてみました。

 *.whl形式のファイルを作る。これさえあれば

pip install xxxx.whl

 これでインストールできます。これを作ります。

新しい仮想環境を作る

 必ずしも必要な手順ではありませんが、自作ライブラリの依存関係をはっきりさせるために、新規の環境を作成しそこで作業します。

python -m venv "なにがしか"

 これで空っぽの”なにがしか”という名前の環境ができます。その環境で作業します。

/Script/activate

 これでアクティベートされます。

ライブラリを入れる

 パッケージ作成に必要な3つのライブラリを入れます。

pip install hatch ←パッケージ作成用
pip install black ←コードフォーマッタ
pip install ruff  ←静的解析ツール

 blackとruffは必須ではないですが、コードスタイルを強制するために入れとくことにします。詳細はググってください。

 以降コマンドプロンプトでhatchを使った作業になります。

プロジェクトを作成する

 activateしたコマンドプロンプト上での作業になります。任意の名前のプロジェクトを作ります。

hatch new "プロジェクト名"

 これがそのままライブラリの名前になるので慎重に決めましょう。またパッケージのネーミングにも一定のルールがあります。

以下が命名ルールになります。

  • すべて小文字
  • モジュール名・パッケージ名には “-” を使用しない
  • パッケージ名に区切り文字は禁止
  • モジュール名(ファイル名)の区切り文字は “_” を使用する(ただこれも非推奨)

 cubeという名前でプロジェクトを作ると、

└─cube
    │  LICENSE.txt
    │  pyproject.toml
    │  README.md
    │
    ├─src
    │  │
    │  └─cube
    │      │  __about__.py
    │      │  __init__.py
    │
    └─tests
            __init__.py

 こんな感じのディレクトリツリーができます。

pyproject.tomlを編集する

 pyproject.tomlの記述をいろいろいじって諸々設定します。ひとまず以下としました。

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[project]
name = "cube"
dynamic = ["version"]
description = 'equirectangular / cube 360 map'
readme = "README.md"
requires-python = ">=3.8"
license = "MIT"
keywords = []
authors = [
  { name = "camping engineer", email = "camping.engineer@campkougaku.com" },
]
dependencies = ["opencv-python >= 4.8.0"]

[project.urls]
Documentation = "https://campkougaku.com"
Source = "https://campkougaku.com"

[tool.hatch.version]
path = "src/cube/__about__.py"

[tool.hatch.build]
eclude = ["src/cube_test.py", "src/*.tif", "src/*.jpg"]

[tool.hatch.envs.lint]
detached = true
dependencies = [
  "black>=23.1.0",
  "ruff>=0.0.243",
]
[tool.hatch.envs.lint.scripts]
style = [
  "ruff {args:.}",
  "black --check --diff {args:.}",
]
fmt = [
  "black {args:.}",
  "ruff --fix {args:.}",
  "style",
]

 DocumentationとSourceはGitのアドレスがあればそちらを指定するのがよさそうです。

 Readmeはマークダウンで記述。今回はPyPIへのアップロードをしないのでそのあたりもごっそり消しました。

 __about__.pyにはバージョンを記載します。適当にバージョンを記載します。whlを作り直す場合には必ずインクリメントします。

 blackやruffはソースコードをとあるルールに従って整形してくれるので、リリース前には通すことにしておきます。

 VSCodeでは保存時に自動実行できるような設定も可能なようです。

 ココへ記述する項目の詳細は

pyproject.toml を書く - Python Packaging User Guide

 とか、

 とか。

ソースコードを配置する

 src以下、プロジェクト名と同名の__about__.pyがあるフォルダに対してモジュールを配置します。(この例だとcube_map.py)

 動作確認用のコードはその上のsrcフォルダに置いておくことにします。(この例だとcube_test.py)このファイルはパッケージには含めないためexcludeします。

└─cube
    │  LICENSE.txt
    │  pyproject.toml
    │  README.md
    │
    ├─src
    │  │  cube_test.py   ←こいつが動作確認用のコード excludeする
    │  │
    │  └─cube
    │      │  cube_map.py   ←こいつが処理モジュール
    │      │  __about__.py
    │      │  __init__.py
    │
    └─tests
            __init__.py

 この状態でコーディングとデバッグをすることとします。いらんファイルはexcludeしときます。

eclude = ["src/cube_test.py", "src/*.tif", "src/*.jpg"]

 冒頭で作った空っぽの環境スタートなので、必要なライブラリはがつがつ追加していきます。必要なライブラリはpyproject.tomlファイルのdependenciesにも追記します。今回の例ではopencvを依存関係に追加しました。

dependencies = ["opencv-python >= 4.8.0"]

 こんな感じ。pip listと打つと今の環境に入っているライブラリの一覧が取れます。必要なものをピックアップします。

__init__.pyを編集する

 この__init__.pyですが空っぽでもいいのですが、ライブラリとして仕立てる以上import cubeとして、cube.hoge()で関数アクセスできるようにしたいので、編集します。

 あと合わせて、内部で使っているだけの関数は隠蔽して、ライブラリとして公開すべき関数だけ公開します。

from cube.cube_map import equirectangular_to_cube  # 公開する関数
from cube.cube_map import cube_to_equirectangular  # 公開する関数

__all__ = [
    'equirectangular_to_cube',
    'cube_to_equirectangular',
]

 こんな感じで、

from ライブラリ名.ファイル名 import 関数名

 importした後で__all__にその関数名を追加する。これで使う時には普通のライブラリのごとくimportして公開された関数を使うことができるようになります。

Lintを実行する

 blackというライブラリでコードを書き換えてもらって、コードスタイルを強制的にあるルールに従わせます。今回はオプションもとりあえずなしのデフォルトで。

 ruffというライブラリを使って静的解析してもらって、怪しいところをアラートしてもらいます。

 今回のpyproject.tomlでは

 書き換えない(チェックするだけ、後で自分で書き換える)
hatch run lint:style

 書き換える(バックアップもなく上書きされる)
hatch run lint:fmt

 いろいろ指摘されてしまいます。

buildする

htach build

 srcディレクトリと並列にdistディレクトリができ、そこに*.whlと*.tar.gzができます。

 このwhlファイルはwheelと呼ばれるファイルで、こいつを使ってpipインストールを行います。

動作確認する

 再度まっさらな仮想環境を作ります。コマンドプロンプト上でどこか環境を作る場所へ移動します。

python -m venv testenv
/testenv/Script/activate

 その環境下で先ほど作ったwhlをインストールします。

pip install xxx.whl

 依存関係があるライブラリも同時にインストールされます。これが入った環境でサンプルコードを書いて動けばOK。

pythonメモ
スポンサーリンク
キャンプ工学

コメント

タイトルとURLをコピーしました