Skip to content

Add initial draft of src vs flat layout discussion #1150

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions source/discussions/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ specific topic. If you're just trying to get stuff done, see
pip-vs-easy-install
install-requires-vs-requirements
wheel-vs-egg
src-layout-vs-flat-layout
79 changes: 79 additions & 0 deletions source/discussions/src-layout-vs-flat-layout.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
=========================
src layout vs flat layout
=========================

The "flat layout" refers to organising a project's files in a folder or
repository, such that the various configuration files and
:term:`import packages <Import Package>` are all in the top-level directory.

::

.
├── README.md
├── noxfile.py
├── pyproject.toml
├── setup.py
├── awesome_package/
│ ├── __init__.py
│ └── module.py
└── tools/
├── generate_awesomeness.py
└── decrease_world_suck.py

The "src layout" deviates from the flat layout by moving the code that is
intended to be importable (i.e. ``import awesome_package``, also known as
:term:`import packages <Import Package>`) into a subdirectory. This
subdirectory is typically named ``src/``, hence "src layout".

::

.
├── README.md
├── noxfile.py
├── pyproject.toml
├── setup.py
├── src/
│ └── awesome_package/
│ ├── __init__.py
│ └── module.py
└── tools/
├── generate_awesomeness.py
└── decrease_world_suck.py

Here's a breakdown of the important behaviour differences between the src
layout and the flat layout:

* The src layout requires installation of the project to be able to run its
code, and the flat layout does not.

This means that the src layout involves an additional step in the
development workflow of a project (typically, an
:doc:`editable installation <setuptools:userguide/development_mode>`
is used for development and a regular installation is used for testing).

* The src layout helps prevent accidental usage of the in-development copy of
the code.

This is relevant since the Python interpreter includes the current working
directory as the first item on the import path. This means that if an import
package exists in the current working directory with the same name as an
installed import package, the variant from the current working directory will
be used. This can lead to subtle misconfiguration of the project's packaging
tooling, which could result in files not being included in a distribution.

The src layout helps avoid this by keeping import packages in a directory
separate from the root directory of the project, ensuring that the installed
copy is used.

* The src layout helps enforce that an
:doc:`editable installation <setuptools:userguide/development_mode>` is only
able to import files that were meant to be importable.

This is especially relevant when the editable installation is implemented
using a `path configuration file <https://docs.python.org/3/library/site.html#index-2>`_
that adds the directory to the import path.

The flat layout would add the other project files (eg: ``README.md``,
``tox.ini``) and packaging/tooling configuration files (eg: ``setup.py``,
``noxfile.py``) on the import path. This would make certain imports work
in editable installations but not regular installations.