Python Package Structure & Layout#

Pythonのパッケージングエコシステムでよく見られるレイアウトは2種類あります。: srcとフラットレイアウどちらのレイアウトも、異なるメンテナグループにとって利点があります。

Python パッケージの作成には src/ レイアウト (後述) を使うことを強く推奨しますが、必須ではありません。 このレイアウトは、 PyPA packaging guide tutorial でも推奨されています。

pyOpenSciは査読のために特定のパッケージ構造を要求することはありません

新しいレイアウトに移行することは、既存のメンテナンス担当者にとって重要な労力となることは理解しています。

このページの概要では、これから Python のパッケージングを始める人や、パッケージがシンプルなビルドで、より失敗のないアプローチに移行することに前向きな人に最適だと思われる推奨事項を紹介します。

他のリソースもチェックできます:

Hatch のようなツールを使って、最新の Python パッケージ構造を素早く作成することができます。 クイックスタートチュートリアルをご覧ください:

パッケージを構築するための仕組み作りを学びたいですか? こちらをクリックしてください。

Pythonパッケージのソースレイアウトとは何ですか?#

src/package のレイアウト構造の例を以下に示します。

myPackageRepoName
├── CHANGELOG.md               ┐
├── CODE_OF_CONDUCT.md         │
├── CONTRIBUTING.md            │
├── docs                        Package documentation
│   └── index.md
│   └── ...                    │
├── LICENSE                    │
├── README.md                  ┘
├── pyproject.toml             ] Package metadata and build configuration
├── src                        ┐
│   └── myPackage              │
│       ├── __init__.py         Package source code
│       ├── moduleA.py         │
│       └── moduleB.py         ┘
└── tests                         └── ...                      Package tests

上の例では、以下のディレクトリの位置に注意してください:

  • docs/: docsの章で説明したように、このディレクトリにはユーザー向けのドキュメントサイトが含まれます。 src/ レイアウトでは、通常 docs/ は src/ フォルダの同じディレクトリレベルに含まれます。

  • tests/ このディレクトリには、プロジェクトコードのテストが含まれます。 src/ レイアウトでは、テストは通常 src/ フォルダの同じディレクトリレベルに含まれます。

  • src/package/: これはPythonプロジェクトのコードを含むディレクトリです。 "Package" は通常プロジェクトの名前です。

また、上記の例では、pyOpenSciが必要とするすべてのコアドキュメントファイルがプロジェクトディレクトリのルートにあることに注意してください。 これらのファイルには以下が含まれています:

  • CHANGELOG.md

  • CODE_OF_CONDUCT.md

  • CONTRIBUTING.md

  • LICENSE.txt

  • README.md

パッケージング文書の要件については、ここをクリックしてください。

Example scientific packages that use src/package layout

ソースのレイアウトとテスト#

src/package レイアウトを使用する利点は、パッケージの作業ディレクトリ内のファイルではなく、インストールされているバージョンのパッケージに対してテストが確実に実行されることです。インストールされたバージョンのパッケージではなく、ファイルに対してテストを実行すると、パッケージのインストール時にユーザーが遭遇する問題が見逃される可能性があります。

tests/src/package ディレクトリの外にある場合、それらはパッケージの wheel には含まれません。これにより、パッケージのサイズがわずかに小さくなり、PyPI にかかるストレージの負担が軽減され、フェッチが速くなります。

Python がモジュールのインポートを検出して優先順位を付ける方法

デフォルトでは、Python は現在の作業ディレクトリ内のモジュールを Python モジュール検索パスの先頭に追加します。

これは、フラット レイアウト /package/module.py を使用してパッケージの作業ディレクトリでテストを実行すると、Python はインストールされたパッケージを検出する前に package/module.py ファイルを検出することを意味します。

ただし、パッケージが src/ ディレクトリ構造 src/package に存在する場合、デフォルトでは Python パスに追加されません。これは、パッケージをインポートすると、Python はアクティブな環境 (パッケージがインストールされている環境) を強制的に検索することを意味します。

注: Python バージョン 3.11 以降には、インストールされたパッケージを優先的に使用するように調整できるパス設定があります (例: 「PYTHONSAFEPATH」)。

Don't include tests in your package wheel#

パッケージに tests を記述することは重要です。ただし、デフォルトで パッケージ ホイール の一部としてテストを含めることはお勧めしません。ただし、パッケージの配布にテストを含めないと、自分以外の人がパッケージが自分のシステムで適切に動作するかどうかをテストすることが難しくなります。小規模なテスト スイート (Python ファイル + データ) があり、ユーザーがシステム上でローカルにテストを実行したいと考えている場合は、tests/ ディレクトリを src/package ディレクトリに移動することでテストを含めることができます (以下の例を参照)。

src/
  package/
    tests/
docs/

src/package ディレクトリに tests/ ディレクトリをインクルードすることで、パッケージの wheel にテストが含まれるようになります。

パッケージ配布にテストを含める方法については、 pytest documentation for more about including tests in your package distribution を必ず読んでください。

パッケージwheelにテストとデータを含める際の課題

テストは、特にテストデータを伴う場合、以下のような小さな課題を生み出す可能性があります:

  • PyPI上のストレージスペースとして時間の経過とともに蓄積される、ディストリビューション内のスペースを占有します。

  • ファイルサイズが大きいと、パッケージのインストールも遅くなります。

しかし、場合によっては、特に科学的なPythonのエコシステムでは、テストを含める必要があるかもしれません。

テストスイートのデータセットをパッケージに含めないでください#

テストをパッケージ配布に含める場合、テストスイートディレクトリにデータを含めることは強くお勧めしません。 そうではなく、FigshareやZenodoのようなリポジトリでテストデータをホストします。 Pooch のようなツールを使用して、あなた(またはユーザー)がテストを実行する際にデータにアクセスします。

Python パッケージテストの詳細については、 ガイドの tests のセクション を参照してください。

  • src/package レイアウトの方が意味的に明確である。 コードは常に src/package ディレクトリにあり、 tests/docs/ はルートディレクトリにあります。

重要

パッケージのテストにデータが必要な場合は、そのデータをパッケージ構造に含めないでください。 パッケージ構造にデータをインクルードすると、配布ファイルのサイズが大きくなります。 これは PyPI や Anaconda.org のような何千ものパッケージのアップロードに対応しなければならないリポジトリにメンテナンスの負担をかけます。

Pythonパッケージ作成のクイックスタートチュートリアルはこちらです。

フラットなPythonパッケージレイアウトとは何ですか?#

多くの科学的パッケージは flat-layout を使用しています:

  • このレイアウトは、NumPy、SciPy、Matplotlibのような多くの科学的Pythonパッケージで使用されています。

  • 多くのPythonツールは、他の言語のツールや、コンパイルステップを含む複雑なビルドに依存しています。 多くのメンテナーは、より複雑なビルドのためにフラットレイアウトの機能を好みます。

上述した src/package レイアウトを使用することを推奨しますが、特にこのレイアウトを使用するパッケージに貢献する予定がある場合は、フラットレイアウトも理解することが重要です。

Why most scientific Python packages do not use src/ layout

Migrating larger scientific packages that already use a flat layout would consume significant time and resources.

しかし、初心者にとってsrc/packageレイアウトを使う利点は大きいです。そのため、新しいパッケージを作成する場合は、 src/package レイアウトを使用することをお勧めします。

エコシステムの中で数多くのパッケージが src/package レイアウトに移行しなければなりませんでした。

フラットレイアウトの構造はどのようなものですか?#

フラットレイアウトの主な特徴は以下の通りです:

  • パッケージのソースコードは、ディレクトリのルートにあるパッケージ名のディレクトリに格納されます

  • 多くの場合、 tests/ ディレクトリも同じ package ディレクトリの中にあります。

以下に、フラットレイアウトを使った科学的Pythonパッケージの推奨構造を示します。

myPackage/
├── CHANGELOG.md             ┐
├── CODE_OF_CONDUCT.md       │
├── CONTRIBUTING.md          │
├── docs/                     Package documentation
│   └── ...                  │
├── LICENSE                  │
├── README.md                ┘
├── pyproject.toml           ] Package metadata and build configuration
|   myPackage/               ┐
│     ├── __init__.py         Package source code
│     ├── moduleA.py         │
│     └── moduleB.py               tests/                         └── test-file1.py    | Package tests
        └── ....             

Pythonパッケージでフラットレイアウトを使うメリット#

フラットレイアウトを採用することは、科学コミュニティにとってもメリットがあります。

  • この構造は歴史的にエコシステム全体で使われてきたものであり、これを使うパッケージが変わることはないでしょう。

  • ルートディレクトリからパッケージを直接インポートすることができます。これがそれぞれのワークフローに組み込まれている人もいるでしょう。しかし、初心者がこの方法をとる危険性は、インストールされたバージョンのパッケージに対して開発やテストを行っていないことにあります。 むしろ、フラットファイルを直接扱うことになります。

フラットレイアウトを使用する科学的Pythonのコアパッケージ

これらのパッケージをすべて別のレイアウトに移行するのは、かなりのメンテナンスコストと負担になるでしょう。 これらのツールのソースレイアウトの潜在的な利点は、メンテナンスの投資に見合うものではありません。

src/ フォルダー内の複数のパッケージ

より高度なケースでは、src/ ディレクトリに複数のパッケージが存在する場合があります。この例については、Black の GitHub リポジトリ を参照してください。ただし、ほとんどの初心者の場合、src/ フォルダー内にサブディレクトリは 1 つしかないでしょう。