beeware / toga

A Python native, OS native GUI toolkit.
https://toga.readthedocs.io/en/latest/
BSD 3-Clause "New" or "Revised" License
4.35k stars 672 forks source link

Process for managing build requirements versioning #2202

Closed rmartin16 closed 1 year ago

rmartin16 commented 1 year ago

Describe the bug

Hello...local quibbler here :) I noticed #1675 pinned Toga's build requirements in pyproject.toml.

As I pointed as recently in beeware/briefcase#1527, this can be problematic for projects dependent on Toga (although, that would require them to package Toga themselves for whatever reason). More importantly, though, we've set up processes to manage versioning for all other dependencies (AFAIK)....but these have been overlooked. So, if these requirements should remain pinned, what's the process to maintain them over time?

(On a related note, pyproject.toml does not contain a tool.setuptools_scm section....wasn't sure if that was intentional)

Steps to reproduce

https://github.com/beeware/toga/blob/69fc00cb59d56c25516d2c9900b140cab26fde9c/core/pyproject.toml#L2

Expected behavior

These dependencies are maintained over time such that we over avoid finding they have to be bumped because of an issue...but then bumping them creates problems of its own.

Screenshots

No response

Environment

Logs

No response

Additional context

No response

freakboy3742 commented 1 year ago

As I pointed as recently in beeware/briefcase#1527, this can be problematic for projects dependent on Toga (although, that would require them to package Toga themselves for whatever reason). More importantly, though, we've set up processes to manage versioning for all other dependencies (AFAIK)....but these have been overlooked. So, if these requirements should remain pinned, what's the process to maintain them over time?

I don't know that there is a process, other than "update them when they break".

We've leant towards strict pinning any version that is part of our build/test infrastructure because of repeatability - the build system should produce the same output from the same input. We rely on the weekly dependabot update to bump the dev dependencies; but I'm not aware of a dependabot setting that will bump PEP517 build requirements.

I'm not sure I 100% follow the argument about pinning causing problems downstream, though. The point of PEP517 is to allow for isolated builds. The thread you've linked does make the point that isolated builds aren't 100% reproducible because there's lots of things outside the Python environment that need to be specified (like C compiler versions) - but within the context of Python tooling and pure Python packaging, an isolated build with pinned versions should produce the same output consistently (AFAIK).

A downstream package using Toga doesn't ever user the build system requirements, unless they're building their own wheel... but even then, they should get the same guaranteed output. And if you're not using isolated builds... why the hell not? The only use case I'm aware of is for cross-platform builds... in which case you are using an isolated build, just not python -m build in isolated mode.

Using a minimum version pin (i..e, >= X) means that it's entirely possible a new version of Setuptools will be released that will break the build. A strict pin will always have the same behavior. That pinned version may not be compatible with new versions of Python... but that's the point at which you do a version update, and fix any problems that arise. Dependabot auto-updates would make these version update issues a little easier to identify, but unlike most dependencies, this is a much narrower footprint.

(On a related note, pyproject.toml does not contain a tool.setuptools_scm section....wasn't sure if that was intentional)

I believe that's because we're still using setup.py. We're not relying on the PEP621 interpretation of the version as a dynamic field - we're explicitly setting the version in setup.py by invoking setuptools_scm.

FWIW - I'd like to get away from the use of setup.py. The only reason we're still using it is because toga-cocoa needs to specify a version dependency on toga-core of the same version, and I'm not aware of a way to do that dynamically. I guess it could be replaced with a runtime check (i.e., in toga-cocoa's factory, check the metadata version of toga-core for compatibility). That would allow us to issue a warning, rather than a hard break, which would open up the option of deliberately running different versions of core and backend. It would avoid the pip warning you get in Briefcase when you have a version in your virtualenv that doesn't match the version that is in your app's pyproject.toml. However, I'm not sure if there are other consequences that I haven't thought of.

rmartin16 commented 1 year ago

That chain had a lot going on in it. Nonetheless, the underlying issue with the pinned build requirements is trying to build dependencies without isolation.

I'm mostly indifferent to whether they are pinned at the end of the day, though....if only mostly because of the larger fiasco that is python packaging.

To the end of reproducibility....setuptools_scm depends on packaging if you want to pin that as well....and I think the toml extra is superfluous at this point.

As for managing build-system.requires, it's interesting; they were initially discussed when broader pyproject.toml support was implemented for dependabot...but then they weren't included... If you're good with the status quo, though, the risk profile certainly seems limited.