Help us understand the problem. What is going on with this article?

PyPIパッケージ定義ファイル作成方法 - __init__.py setup.py MANIFEST.in の書き方

More than 1 year has passed since last update.

はじめに

PyPIパッケージ公開手順 でPyPIに公開するまでの方法を説明しました。
この記事では、パッケージ作成に必要なファイルの作成方法について説明します。

概要

パッケージを作成するために必要なファイルは、3つあります。
MANIFEST.in ファイルは必要な場合だけ、作成してください。

  • __init__.py : パッケージ基本情報を記述します。
  • setup.py : パッケージ作成情報を記述します。
  • MANIFEST.in : 配布物に追加、または除外するファイルを記述します。

ファイル構成の例

以下のファイル構成を例に説明します。

.
├── CHANGELOG.md
├── LICENSE
├── MANIFEST.in
├── README.md
├── README.rst
├── <package>
│   ├── __init__.py
│   └── <module>.py
├── requirements.txt
├── setup.cfg
├── setup.py
├── test
│   ├── __init__.py
│   └── test_foo.py
└── test-requirements.txt

__init__.py : パッケージ基本情報を記述

パッケージの著作権情報や、公開モジュールなどを記述します。

__init__.py
from .<ファイル> import *

__copyright__    = 'Copyright (C) 2018 Your Name'
__version__      = '1.0.0'
__license__      = 'BSD-3-Clause'
__author__       = 'Your Name'
__author_email__ = 'Your@Email'
__url__          = 'http://github.com/account/repository'

__all__ = ['公開モジュール', ...]
定義変数 説明
__copyright__ 著作権
__version__ バージョン番号 ※使える文字は、英数字・ドット(".")です。
__license__ ライセンス情報
__author__ 著作者名
__author_email__ 著作者メールアドレス
__url__ WebサイトURL
__all__ import * したときに公開するモジュールのリスト

setup.py : パッケージ作成情報を記述

パッケージ作成に必要なモジュール配布物を定義するファイルです。

基本的な記述内容

  • from setuptools import setup : パッケージ作成に必要なセットアップモジュールをインポートします。
  • setup( ... ) : setup スクリプトを記述します。

具体的な記述内容

このサンプルで必要な編集箇所は、 package_name, description, keywords, classifiers のみです。
__init__.pyrequirements.txt などの定義ファイルを再利用して、できるだけ同一内容を重複して記述せずに済むように工夫しました。

setup.py サンプル

setup.py
# -*- coding: utf-8 -*-

from setuptools import setup
from codecs import open
from os import path
import re

package_name = "パッケージ名"

root_dir = path.abspath(path.dirname(__file__))

def _requirements():
    return [name.rstrip() for name in open(path.join(root_dir, 'requirements.txt')).readlines()]


def _test_requirements():
    return [name.rstrip() for name in open(path.join(root_dir, 'test-requirements.txt')).readlines()]

with open(path.join(root_dir, package_name, '__init__.py')) as f:
    init_text = f.read()
    version = re.search(r'__version__\s*=\s*[\'\"](.+?)[\'\"]', init_text).group(1)
    license = re.search(r'__license__\s*=\s*[\'\"](.+?)[\'\"]', init_text).group(1)
    author = re.search(r'__author__\s*=\s*[\'\"](.+?)[\'\"]', init_text).group(1)
    author_email = re.search(r'__author_email__\s*=\s*[\'\"](.+?)[\'\"]', init_text).group(1)
    url = re.search(r'__url__\s*=\s*[\'\"](.+?)[\'\"]', init_text).group(1)

assert version
assert license
assert author
assert author_email
assert url

with open('README.rst', encoding='utf-8') as f:
    long_description = f.read()


setup(
    name=package_name,
    packages=[package_name],

    version=version,

    license=license,

    install_requires=_requirements(),
    tests_require=_test_requirements(),

    author=author,
    author_email=author_email,

    url=url,

    description='一言で書けるパッケージ概要',
    long_description=long_description,
    keywords='キーワード1, キーワード2, キーワード3',

    classifiers=[
        'Development Status :: 5 - Production/Stable',
        'License :: OSI Approved :: BSD License',
        'Programming Language :: Python',
        'Programming Language :: Python :: 3',
        'Programming Language :: Python :: 3.4',
        'Programming Language :: Python :: 3.5',
        'Programming Language :: Python :: 3.6',
        'Topic :: Database',
        'Topic :: Software Development :: Libraries :: Python Modules',
    ],
)

setup スクリプト定義項目

setup スクリプトで定義する具体的な項目を説明します。
なお、これがすべてではありません。
他の項目については、Python公式ドキュメントなどを参照してください。

  • name : パッケージ名
  • packages : モジュールリスト
  • version : バージョン番号
  • license : パッケージに適用するライセンス
    'MIT', 'BSD-3-Clause' などを記述します。

  • install_requires : 依存関係のあるパッケージのリスト

  • tests_require : ユニットテスト時に依存関係のあるパッケージのリスト

  • author : 著作者名

  • author_email : 著作者のメールアドレス

  • url : パッケージのWebサイト
    GitHubのリポジトリURLなどを指定します。

  • description : 概要説明

  • long_description : 詳細説明
    一般的には README.rst ファイルの内容をそのまま書き込むことが多いようです。

  • keywords : PyPI検索ヒントキーワード
    PyPIで検索対象にしたいキーワードをスペース区切りで記述します。

  • classifiers : 分類語のリスト
    PyPIの List trove classifiers ページから適切な分類語を選んでください。

MANIFEST.in : 配布物の追加・除外ファイル定義を記述

MANIFEST.in ファイルがなくても、 python setup.py sdist コマンド実行時に最低限必要なソースコード配布物は含まれます。
しかし、LICENSEファイルなど、他にも包含したいことの方が多いのではないでしょうか。
そんなときは、 MANIFEST.in ファイルを作成してください。

  • include <ファイル名> : 追加したいファイルを指定します。
  • exclude <ファイル名> : 除外したいファイルを指定します。
  • recursive-include <ディレクトリ> <ファイル名> : 特定ディレクトリ配下で、追加したいファイルを指定します。
  • recursive-exclude <ディレクトリ> <ファイル名> : 特定ディレクトリ配下で、除外したいファイルを指定します。
  • いずれも、ファイル名にはワイルドカードを使うことができます。
MANIFEST.inの例
include LICENSE
include *.md
exclude README.md
include requirements.txt
include test-requirements.txt
include setup.cfg

関連記事

PyPIパッケージ公開手順

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away