On Mon, Mar 23, 2026 at 12:48 PM Michael J Gruber <[email protected]>
wrote:

> Hi there
>
> Charalampos Stratakis via python-devel venit, vidit, dixit 2026-03-21
> 02:11:36:
> > More and more packages move to pyproject macros that make use of upstream
> > metadata. Upstream Python projects frequently pin or constrain dependency
> > versions (e.g. numpy<2.0, attrs==25.3). When Fedora ships a different
> > version, packagers currently resort to sed/patch in %prep to modify
> > pyproject.toml, requirements.txt, setup.cfg etc. This is quite fragile
> and
> > honestly a pain point every time as it breaks on upstream reformatting,
> > varies across build systems and pollutes the spec. And I'm not the
> biggest
> > fan of deciphering regexes.
>
> It's good to have a uniform solution.
>
> > The reasoning for only one override per macro call is that each override
> > should be verified and possibly commented on why it's needed, instead of
> > blindly removing dependencies. Also having one per line will keep the
> spec
> > readable. More than one argument in the macro call will make it error
> out.
>
> Yes!
>
> > *Available actions*
> >
> >    - drop_upper: remove upper-bound constraints (<, <=, ==, ~=)
> >    - drop_lower: remove lower-bound constraints (>, >=, ==, ~=)
> >    - drop_constraints: remove all version constraints
>
> Maybe drop_any? Because "constraints" applies to all macros and is not
> specific.
>
>
Reasonable naming concern, but I think drop_constraints is actually
clearer. The other actions specify which constraints (upper/lower), whereas
this one drops all of them. drop_any could be misread as "drop any single
constraint" or "drop all" so I'd consider it more ambiguous. Maybe drop_all
would be less ambiguous than drop_any? What do you think?


> >    - set_upper: replace the upper bound with < VALUE
> >    - set_lower: replace the lower bound with >= VALUE
>
> I'm surprised by those two - both by the asummetry as well as the
> choice.
>
> Typically, the upper bound is the last known good version, so I'd expect
> "<=" instead of "<". In particular, you may not even know what the next
> version beyond the good one will be so that you don't know the value
> "next(good)".
>
>
In my experience, at least as long as I've been working with python
projects, the upper bound is most of the time some arbitrary api breaking
version. e.g. a project would have click >=8,<9 just because it's expecting
some breakage. In many cases, this doesn't happen so it's mostly like
an insurance.
Overall, that's the convention here.


> For lower, it's not as clear cut. Here, you typically know the lowest
> version which works (">=") as well as the one before which breaks things
> (">") so that packagers could live with both ways to specify things. I'd
> do it symmetrically.
>
>
For lower bounds, the convention is also specific. Upstreams know which
version introduced the feature they need/want (>=1.5), not the last version
that broke (>1.4). So >= is the natural choice and consistent with the same
convention.


> >    - ignore: remove the dependency entirely
> >
> > Note: == and ~= act as both upper and lower bounds, so either drop_upper
> or
> > drop_lower will remove them. Exclusions (!=) are always preserved.
>
> If drop_{upper,lower} both include "=" then applying them to an "=="
> should transform the "==" into ">=" resp. "<=", shouldn't it? That would
> be both logical as well as practical - you can always
> "drop_contstraints" if you really mean it.
>
>
You are right here, drop_upper should drop only the upper bound. For "~=",
PEP 440 explicitly defines "~= V.N" as ">= V.N, == V.*", so decomposing it
is the consistent behavior. For "==",  there is no specific PEP 440
decomposition but it's mathematically ">=V AND <=V", so the same logic can
apply. I'll implement this: drop_upper on "==V" and "~=V" becomes ">=V".
For drop_lower: "==V" becomes "<=V". On "~=V" it will be removed entirely
as computing the effective upper bound from the prefix match is complex and
unlikely to be needed. "===" stays as atomic removal since it has no
meaningful decomposition.



> Exclusions should not be preserved with "drop_any/constraints", should
> they?
>
>
That's a good catch, it works properly but the initial RFC could be
clearer. drop_constraints removes everything including exclusions.
Exclusions are only preserved by drop_upper/drop_lower (since != is neither
an upper nor lower bound).


> Logically speaking, "!= v" is "( < v OR > v )" so one could say
> drop_upper" should turn this into "> v" and "drop" should remove it.
>
>
"!= v" would mean "any version except v" and is almost always a workaround
for a specific buggy release. Transforming "!= V" into ">V" via drop_upper
would be surprising and would silently exclude all older versions, which is
not the intention of this operation. Preserving "!=" as is with
drop_upper/drop_lower is the least surprising behavior here.


> Finally, the spec says that "~= V.N" is rougly equivalent to
> ">= V.N, == V.*" which is the obvious lower bound plus an effective
> upper bound, so that I would expect drop_{lower,upper} to tranform "~="
> accordingly.
>
>
Addressed above: drop_upper on "~=V" will become ">=V". For drop_lower on
"~=V", it will be removed entirely (computing the effective upper bound
from the prefix match is complex and the use case is unlikely).


> ... just following the principle of least surprise :)
>
>
Thank you for taking the time to check out each part and provide feedback
here! Hope I addressed your points one way or another and I'll be happy to
revisit and debate more on it :)


> Cheers
> Michael
>
>

-- 
Regards,

Charalampos Stratakis
Senior Software Engineer
Python Maintenance Team, Red Hat
-- 
_______________________________________________
python-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]
Fedora Code of Conduct: 
https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: 
https://lists.fedoraproject.org/archives/list/[email protected]
Do not reply to spam, report it: 
https://forge.fedoraproject.org/infra/tickets/issues/new

Reply via email to