Repository navigation
Description
Description of improvement
- Move the
plasmapy/directory to becomesrc/plasmapy - Move tests into a separate
testsdirectory outside ofsrc
The directory structure would become more like:
├── README.md
├── tox.ini
├── pyproject.toml
├── ...
├── src/
│ └── plasmapy/
│ ├── __init__.py
│ ├── formulary/
│ └── ...
├── tests/
└── tools/ ← if we decide there's a need for it?
└── ...
(I adapted this from the Python packaging guide.)
This PR should wait until we had sufficient time to discuss this.
Motivation
The src layout is now recommended in the Python packaging guide, in the pyOpenSci packaging guide, and by the scientific Python packaging guide.
The Python Packaging Guide notes that there are real consequences of a flat layout:
The
srclayout requires installation of the project to be able to run its code, and the flat layout does not.This means that the
srclayout involves an additional step in the development workflow of a project (typically, an editable installation is used for development and a regular installation is used for testing).The
srclayout 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
srclayout 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
srclayout helps enforce that an editable installation 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 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.
If others look to PlasmaPy as an example for Python packaging, having an src layout would set a good example of currently recommended practices.
Packaging the tests outside of src might have the advantage of making it easier to include tests in source distributions (sdists) but not include tests in wheels (I'm not 100% of this, though). Having wheels be small is advantageous because large package sizes can be a barrier for running on the cloud (see astropy/astropy#16152).
Some disadvantages are:
- Switching may take between a few hours (if we're lucky) and a few days (if there are any difficult-to-fix problems that arise).
- The new directory structure will take some time to get used to.
- The change may disrupt all current pull requests (though if we do
git mv plasmapy src/, the magic ofgitmay handle things for us) - The change may disrupt current setups and shortcuts. (I'll have some editing to do in my
.bashrcfile, that's for sure.) - PlasmaPy's package structure will differ from Astropy, SunPy & most Python in Heliophysics Community packages, NumPy, Scipy, xarray, etc. There is some discussion to switch, though (like in Move astropy to
srcdirectory astropy/astropy#13678).
Implementation strategy
We would need to update pyproject.toml and MANIFEST.in for sure, which would probably be fairly straightforward. We'll probably also need to update tox.ini, mypy.ini, .pre-commit-config, and .pre-commit-search-and-replace. We might need to update some of the files in .github/workflows and docs too, though I'm not sure where.
We'll need to update the contributor guide in a bunch of places. (We could probably grep for plasmapy or plasmapy/, and possibly the :file: reStructuredText role.)
We should plan to perform a pre-release ahead of the next release to make sure everything is being handled correctly.
We should pick a time when there are relatively few PRs happening, and we would want to get this in quickly to reduce the chances of merge conflicts (though if we use git mv then we may not need to worry about this). If we decide to go this route, I'd suggest doing this sooner rather than later.
Afterwards, we'll want to update .git-blame-ignore-revs so that doing git blame will ignore these changes. (There are a bunch of other PRs we should add to this file too.)
Additional context
Related issue: #1877.
Activity
pheuer commentedon Mar 14, 2024
Seems like a script could be written to move the files and make the relevant import statement adjustments?
That's true, but doesn't sound that bad to me
This sounds like the most serious issue. I don't know about the git solution: if that works, we'd need good instructions on doing that. For PRs that only touch a few files, it might be easiest to copy the changed contents into another document, restart the branch from main, then copy back in the proposed changes? That would effectively disrupt the chain of commits prior to that point. Sounds like a headache!
I'm unsophisticated enough that I run the tests manually most of the time, so this wouldn't bother me :P
Sounds fine if we are following updated guidelines. At the same time, it might be prudent to wait for some of these other packages to switch prior to following along?
namurphy commentedon Mar 14, 2024
Thank you for the feedback!
If
git mvworks its wonders, it could be that a singlegit pull upstream mainwould handle this. Otherwise...yes, we would definitely need instructions.Since there's ongoing discussion (and apprehension) in Astropy about switching to an
srclayout (or at least a layout with a separatetestsdirectory), I was thinking that PlasmaPy could serve as a "prototype" for making these changes. It was actually the discussion in Astropy that sparked me to raise this issue (though I've been thinking it for a while).namurphy commentedon Mar 14, 2024
I'm finding it interesting to read through the issue on PyPA about whether to recommend the
srclayout in their Python Packaging Guide (pypa/packaging.python.org#320). There were a lot of very interesting perspectives raised there. Overall it sounds like it isn't so much that there's a single overarching reason to use ansrclayout, but rather that there are a bunch of smaller compelling reasons whysrclayouts are helpful for preventing subtle packaging and testing problems.One thing to note is that an
srclayout would require us to do an editable installation of PlasmaPy before running tests directly with pytest. I've seen this noted as both a pro and a con ofsrclayouts. It's more work to run pytest, but this makes it certain that the tests are being run against the installed version of PlasmaPy (i.e., there is parity with how users use PlasmaPy). [Then again, tox is only a few seconds longer than pytest if it doesn't have to recreate the environment, so maybe we should start recommending tox as the preferred way to run tests...but that's for another issue.]namurphy commentedon Mar 21, 2024
I just did an experiment where I entered a branch for an existing PR, and then did:
Because this worked very smoothly, I suspect that a switch to an
srclayout will not cause any major disruptions to ongoing pull requests. The disruption will probably be limited to requiring agit pull upstream mainand for any open files to be closed and reopened at the new location.