[Python]自作パッケージのインストール

Python

このページでは、自作パッケージをインストールする方法をまとめます。

pyproject.toml」と「pip」を使います。

個人やその周りで利用する場合を想定していて、PyPIなど不特定多数に公開するための作法は考慮していません。

参考ページ
Python のプロジェクトをパッケージングする — Python Packaging User Guide

使用した環境
WSL2 Ubuntu - 20.04
Python 3.10.0
pip 22.3

 Androidアプリを作成しました。
 感情用のメモ帳です。

スポンサーリンク
スポンサーリンク

setup.pyとpyproject.toml

パッケージのインストールにはビルドをする必要があり、検索をかけると、主に、

  • setup.py(+ setup.cfg)
  • pyproject.toml

の二つのやり方が出てくると思います。

現時点では、PEP 518によって「pyproject.toml」を使う方が標準的な方法です。

ざっくりとした経緯は(私なりの理解ですが)、

  • setup.pyを使った方法では依存関係が把握しづらかった。
  • pipでsetup.pyを実行するにはsetuptoolsが必要だと仮定するようになった。
    これでは他のビルドツールが盛り上がってきても貢献が難しく、他のツールの普及を妨げることになっている。
  • それなら「pyproject.toml」でビルドツールを選択できるようにし、依存関係を書くようにしよう。

となっています。

ビルドツール

複数のビルドツールがあります。

各プロジェクト概要 — Python Packaging User Guide

最初「setuptools」を使うつもりだったのですが、今の段階(2022年10月)では「setuptools」での「pyproject.toml」による設定方法はベータ版の書き方もあり、簡単なパッケージ作成なら「hatch」が一番良さそうだったので、このページではこちらを使います。

実際にはhatchそのものではなく、そのバックエンドツールを使用します。
pyproject.tomlでの設定は大枠では共通していて、各ツールごとに使える機能は異なります。tomlの書き方を覚えておけば別のバックエンドツールに変更できます。

ビルドツール自体をインストールし、その手順に従ってビルドする方法もあります。

自作パッケージの用意

説明にあたって簡単なパッケージを作りました。

$ tree greeting
greeting
├── goodbye.py
├── hello.py
├── __init__.py
├── text1.txt
└── text2.txt

0 directories, 5 files

greeting」が自作パッケージ。

hello.py」と「goodbye.py」は、コード中に外部パッケージの「termcolor」をインポートしています。

from termcolor import cprint


def say():
    cprint('Hello', 'red')
from termcolor import cprint


def say():
    cprint('Goodbye', 'blue')

それぞれ色を付けてアイサツを表示する関数を定義しています。

__init__.py」、「text1.txt」、「text2.txtの中身は空です。

そのうち「text2.txt」はインストール対象から除外するつもりです。

pyproject.toml

パッケージと同じ場所に「pyproject.toml」を作成します。

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

[project]
name = "greeting"
version = "1.0.0"
dependencies = ["termcolor"]

[tool.hatch.build]
exclude = ["text2.txt"]

[build-system]
requires――使うツールの名前を書きます。
上記ではhatchのバックエンドツールである”hatchling"を指定。

build-backend――バックエンドに使用するPythonオブジェクトの名前を書きます。
使いたいツールのWebページなどで確認。

[project]
name――パッケージに付ける名前。
パッケージをインポートするときの名前ではありません。

dependencies――必要な外部パッケージをここに書いておくと、インストール時に合わせて追加されます。

Pythonのパッケージシステムに準拠しているツールなら、[build-system]や[project]などのテーブルが設定できるようになっています。

[tool.hatch.build]
exclude――除外したいファイルを指定します。

Build - Hatch

他のビルドツールにも似た機能はあるかもしれませんが、項目や設定方法が異なります。

$ tree mypkg
mypkg
├── greeting
│   ├── goodbye.py
│   ├── hello.py
│   ├── __init__.py
│   ├── text1.txt
│   └── text2.txt
└── pyproject.toml

1 directory, 6 files

mypkg」というディレクトリのなかに、パッケージとtomlファイルが入っています。

これ以降の項目は仮想環境を作成してから行っています。
環境を汚したくないならおすすめです。

配布物の作成

念のため、pipをアップグレードしてください。

pip install --upgrade pip

配布物にしておくと、持ち運びがしやすくなり、ディレクトリごとコピーして渡すより余計なものが入りこまなくて便利です。

配布物が必要ないならインストールの項目に進んでください。

つぎに外部パッケージ「build」をインストールします。

pip install build

$ pip list
Package    Version
---------- -------
build      0.8.0
packaging  21.3
pep517     0.13.0
pip        22.3
pyparsing  3.0.9
setuptools 57.4.0
tomli      2.0.1

バックエンドツール(今回の場合は”hatchling”)はpipなどのフロントエンドツールが一時的に仮想環境を作って自動でインストールしてくれるため、追加する必要はありません。

以下のコマンドを「pyproject.toml」があるディレクトリで実行すると、ビルドして配布物を作成します。

python -m build

mypkg$ python -m build
* Creating venv isolated environment...
* Installing packages in isolated environment... (hatchling)
* Getting dependencies for sdist...
* Building sdist...
* Building wheel from sdist
* Creating venv isolated environment...
* Installing packages in isolated environment... (hatchling)
* Getting dependencies for wheel...
* Building wheel...
Successfully built greeting-1.0.0.tar.gz and greeting-1.0.0-py2.py3-none-any.whl

dist」というディレクトリのなかに、以下のファイルが作成されました。

  • greeting-1.0.0.tar.gz
  • greeting-1.0.0-py2.py3-none-any.whl

インストール

手元のパッケージ

手元にパッケージ(未ビルド)があるなら、tomlとパッケージの入っているディレクトリを指定して、インストールします。

pip install ディレクトリのパス」を実行します。

$ pip install mypkg/
Processing ./mypkg
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Preparing metadata (pyproject.toml) ... done
省略
Successfully installed greeting-1.0.0
$ pip list
Package    Version
---------- -------
greeting   1.0.0
pip        22.3
setuptools 57.4.0
termcolor  2.0.1

greeting」と「termcolor」がインストールされました。

ビルド済み配布物

whl」と「tar.gz」形式、どちらでも構いません。
pip install ファイルパス」で指定して実行します。

$ pip install dist/greeting-1.0.0-py2.py3-none-any.whl 
Processing ./dist/greeting-1.0.0-py2.py3-none-any.whl
Requirement already satisfied: termcolor in /home/fujino/venv/lib/python3.10/site-packages (from greeting==1.0.0) (2.0.1)
Installing collected packages: greeting
Successfully installed greeting-1.0.0
$ pip list
Package    Version
---------- -------
greeting   1.0.0
pip        22.3
setuptools 57.4.0
termcolor  2.0.1

こちらも「greeting」と必要な「termcolor」が追加されました。

検証

自作のパッケージがどこにインストールされたか確認してみましょう。

$ pip show greeting
Name: greeting
Version: 1.0.0
Summary: 
Home-page: 
Author: 
Author-email: 
License: 
Location: /home/fujino/venv/lib/python3.10/site-packages
Requires: termcolor
Required-by: 

環境によって異なると思いますが「site-packages」でした。

その「site-packages」内には「greeting」があり、中を確認すると、

site-packages$ tree greeting
greeting
├── goodbye.py
├── hello.py
├── __init__.py
├── __pycache__
│   ├── goodbye.cpython-310.pyc
│   ├── hello.cpython-310.pyc
│   └── __init__.cpython-310.pyc
└── text1.txt

1 directory, 7 files

「text2.txt」は入っていません。
「pyproject.toml」内で除外していたため、ですね。

今度はパッケージ内のモジュールが呼べるか確かめます。
まったく別のディレクトリに移動し、Pythonを対話モードで起動します。

$ cd
$ pwd
/home/fujino
$ python
Python 3.10.0 (default, Oct 12 2021, 16:02:08) [GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from greeting import hello, goodbye
>>> hello.say()
Hello
>>> goodbye.say()
Goodbye

helloモジュール、goodbyeモジュール、ともにインポートできました。

どこからでも呼べるようになり、これで利便性が上がりました。

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