nikkie-ftnextの日記

イベントレポートや読書メモを発信

Pythonでリソースファイルと一緒にパッケージをインストールするための設定値(📣MANIFEST.inが必要です)

はじめに

みんなの中に私はいない😢1 nikkieです。

Pythonのパッケージに.py以外のファイルを含めたいことってありますよね。
これに必要な設定についてのアウトプットです。
なお、.py以外のファイルを指して、タイトルで「リソースファイル」と書きました。

目次

install_package_dataの指定とMANIFEST.inの2点が必要と知っていた

パッケージングについて今の私が決定版と思っている資料が、みんなのPython勉強会(2022年1月)のaodagさん発表「パッケージングしよう」2
リソースファイルについては以下のスライドで解説されています(スライド中の文言はpackage data

2箇所あるので気をつけましょう
- MANIFEST.in で sdist に含める
- setup.cfg で options.include_package_data を True にする

この知識の利用シーンがこのたび訪れたのです。

MANIFEST.inの設定値ってどう書く? このドキュメントに助けられた!

「よっしゃー!2箇所書くぞ」と意気込んで立ち向かったものの、すぐ直面したのが「MANIFEST.inってどう書けばいいんだ?」というもの。
いくつかのドキュメントの中を探し回って見つけたのが、こちら!

setuptoolsのUser Guide、「Data Files Support」です。

これを元に以下のような設定値にしました。

パッケージ構造

project_root_directory
├── setup.py
├── MANIFEST.in
└── mypkg
    ├── __init__.py
    ├── data1.rst
    ├── data2.rst
    ├── data1.txt
    └── data2.txt

setup.py3

from setuptools import setup, find_packages
setup(
    # ...,
    packages=find_packages(),
    include_package_data=True
)

MANIFEST.in4

include mypkg/*.txt
include mypkg/*.rst

リポジトリのルート(MANIFEST.in)がある位置からの相対パスと理解しました。

OSSプロジェクトの例:Django

「MANIFEST.inの設定例はOSSのコードにもあるんじゃないかな」と知名度のあるプロジェクトをいくつか見てみました。
Djangoの例がこちら:

https://github.com/django/django/blob/4.2/setup.cfg#L39

[options]
packages = find:
include_package_data = true

https://github.com/django/django/blob/4.2/MANIFEST.in

include LICENSE
include *.rst

(MANIFEST.inからは一部だけ抜粋しました)

Pythonプロフェッショナルプログラミング第3版』で解説されてる!

「このあたり、まとまった書籍はないのかな」と考えて思い出したのがpypro3
3章の「03-03-03 setup.pyとMANIFEST.in: パッケージ情報と同梱するファイルの設定」はまさしくです!

setuptoolsのsetup関数の解説では、include_package_data引数にも言及されます。

ただし、この設定だけでパッケージリソースが配布パッケージに同梱されるわけではありません。(p.71)

(そうなんですよ。このフラグだけじゃ足りないんですよ > 過去の自分)

MANIFEST.inはincludeやrecursive-includeが紹介されます。

インストール先の環境に同梱したファイルを置きたい場合は、前述のinstall_package_data=Trueも指定する必要があります。(p.72)

終わりに

Pythonのパッケージに.py以外のファイル(リソースファイル)を含める設定についてのアウトプットでした。
以下の2点が必要です。

  1. setup関数でinclude_package_data=Trueを指定
  2. MANIFEST.inにリソースファイルのincludeを指定する

オススメリソースはこれらです:

P.S. リソースファイルがインストールされるかはbuildのログで確認

上で紹介したaodagさんの発表で知ったbuild。

python -m build .のログにリソースファイルが入ってくるかを見ながら、検証を進めました。
ビルドされたwheelにリソースファイルが入っていれば、wheelからインストールした後もsite-packages以下にリソースファイルが置かれるという理解です!


  1. なにかの作品で聞いた覚えがあって、今回含まれてないつながりで選びました。ニジガク1期11話の歩夢🎀ちゃん、なのかな?
  2. アーカイブあります
  3. setuptoolsのドキュメントがすごいのは、setup.cfgやpyproject.tomlの設定値も掲載されていて、見比べられることです!
  4. These files are included via the MANIFEST.in file(これらのファイルはMANIFEST.inを通して含められる)とあります。MANIFEST.inも必要なんだ!