Python Package Structure & Layout#
Pythonのパッケージングエコシステムでよく見られるレイアウトは2種類あります。: srcとフラットレイアウどちらのレイアウトも、異なるメンテナグループにとって利点があります。
Python パッケージの作成には src/ レイアウト (後述) を使うことを強く推奨しますが、必須ではありません。 このレイアウトは、 PyPA packaging guide tutorial でも推奨されています。
pyOpenSciは査読のために特定のパッケージ構造を要求することはありません
新しいレイアウトに移行することは、既存のメンテナンス担当者にとって重要な労力となることは理解しています。
このページの概要では、これから Python のパッケージングを始める人や、パッケージがシンプルなビルドで、より失敗のないアプローチに移行することに前向きな人に最適だと思われる推奨事項を紹介します。
他のリソースもチェックできます:
Hatch のようなツールを使って、最新の Python パッケージ構造を素早く作成することができます。 クイックスタートチュートリアルをご覧ください:
パッケージを構築するための仕組み作りを学びたいですか? こちらをクリックしてください。
Pythonパッケージのソースレイアウトとは何ですか?#
src/package のレイアウト構造の例を以下に示します。
上の例では、以下のディレクトリの位置に注意してください:
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
Click here to read about our packaging documentation requirements.
:::
:::{admonition} Example scientific packages that use src/package layout
* Sourmash
* bokeh
* openscm
* awkward
* poliastro
:::
(src-layout-test)=
## The src/ layout and testing
The benefit of using the src/package layout is that it ensures tests are run against the
installed version of your package rather than the files in your package
working directory. If you run your tests on your files rather than the
installed version of your package, you may be missing issues that users encounter when
your package is installed.
If tests/ are outside the src/package directory, they aren't included in the package's wheel. This makes your package size slightly smaller, which places a smaller storage burden on PyPI, and makes them faster to fetch.
- Read more about reasons to use the src/package layout
:::{admonition} How Python discovers and prioritizes importing modules
By default, Python adds a module in your current working directory to the front of the Python module search path.
This means that if you run your tests in your package's working directory, using a flat layout, /package/module.py, Python will discover package/module.py file before it discovers the installed package.
However, if your package lives in a src/ directory structure src/package, then it won't be added to the Python path by default. This means that when you import your package, Python will be forced to search the active environment (which has your package installed).
Note: Python versions 3.11 and above have a path setting that can be adjusted to ensure the priority is to use installed packages first (e.g., PYTHONSAFEPATH).
:::
### Don't include tests in your package wheel
Writing tests for your package is important; however, we do not recommend including tests as part of your package wheel by default. However, not including tests in your package distribution will make it harder for people other than yourself to test whether your package runs properly on their system. If you have a small test suite (Python files + data), and think your users may want to run tests locally on their systems, you can include tests by moving the tests/ directory into the src/package directory (see example below).
```bash
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のコアパッケージ
これらのパッケージをすべて別のレイアウトに移行するのは、かなりのメンテナンスコストと負担になるでしょう。 これらのツールのソースレイアウトの潜在的な利点は、メンテナンスの投資に見合うものではありません。
Multiple packages in a src/ folder
In some more advanced cases, you may have more than one package in your src/ directory. See Black's GitHub repo for an example of this. However, for most beginners you will likely only have one sub-directory in your src/ folder.