Allow pyproject.toml to reference a requirements file
- Dominant language
- Python
- Stars
- 3.3k
- Forks
- 549
- Avg merge
- 1d 4h
- Merged PRs (30d)
- 40
Description
In the context of the `requires_lock` feature added by #1209, we had the following conversation:
----
@mhsmith
How about generalizing this to `requires_file`, so it can be used for any requirements file, not just lock files? See #1270 for an example of where this would be useful.
----
@freakboy3742
Agreed that it would be nice to support requirements files in general, as an alternative to pyproject.toml `requires` definitions. However, I think this is a supplement to, rather than a replacement for `requires_lock`.
The choice to introduce `requires_lock` was to allow a project to define loose requirements based on core functionality, but then lock a specific solution to the full package set required at runtime. This makes the maintenance task as an author simpler - just define the high level packages you need, and then periodically generate a new lock of the full solution so that builds are reproducible.
Before we introduced `requires_lock`, one ideas I had was to allow `requires` to be either a list or a string; if it's a list, it's a list of packages; if it's a string, it's a path to a file. I can't see any reason we couldn't still do this - `requires` accepts both list and str forms, and `requires_lock` defines a locking file. This would allow for `requires` to continue to be an additive setting (so you can define global, macOS and Windows requirements files) but `requires_lock` is a complete solution file.
An alternative to having 2 type alternatives for `requires` would be to add `requires_file`; however, I'm not 100% about the ergonomics of having 1 setting with 2 possible types, vs having 2 settings and then needing to document and implement error handling (or at least a resolution order) around projects that define both.
----
@mhsmith
I think it's better to have two separate settings. Not only would that be more explicit and less error-prone, it could also be useful to define both requirements files and explicit requirements, especially when adding a BeeWare app to an established project. Such projects might also find it useful if the `requires_file` setting accepted a list of multiple files.
But I agree it's better for this PR to only deal with the locking issue: I misunderstood the title and thought it had a larger scope.
----
@freakboy3742
To clarify - are you suggestion that we support both settings, and the final list of installed packages is the union of `requires` *and* `requires_file`, merged across all levels (app, platform, format etc)? I was originally thinking it would require picking one to have primacy (or, alternatively, raise an error if both are defined); supporting both is an interesting option I hadn't considered.
----
@mhsmith
Yes, and I'm basing this on the experience I had developing the Android app for Electron Cash. That project has a core Python library with its own requirements file, and three apps using the library (PyQt, iOS and Android). So the app needs to use the library's requirements file, and then add some requirements of its own, either directly or via a [second requirements file](https://github.com/Electron-Cash/Electron-Cash/blob/4.2.14/android/app/build.gradle#L46). I think this would be a fairly common scenario.
Contributor guide
Research direction
Start by reviewing the requires_lock feature from #1209 and the example in #1270, then trace how pyproject.toml requirements are currently read. Resolve whether requirements files use a new requires_file setting or a string form of requires, and define how multiple files combine with explicit requirements across app and platform levels. Done means the chosen behavior is implemented, validated for conflicts and merging, and documented.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- build-system
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100