Re: Deprecating positional arguments for functions whose signatures are being already

Evgeni Burovski <[email protected]> Mon, 23 Oct 2023 15:04:51 +0300
Newsgroups gmane.comp.python.scientific.devel
Message-ID <CAMRo0ivs3PsAadftNrON+Bsna8qm302xoE+WSrkP+fwfUzh=8g@mail.gmail.com>
FWIW, I'd think
- this is a good idea overall, and it's great to have momentum
- this sounds to me like a SciPy 2.0 event. I know we don't have any
specific plans for scipy 2.0; maybe this codebase-wide change could seed
working out in more details of what is scipy 2.0 and when.

My two cents,

Evgeni




On Mon, Oct 23, 2023 at 1:59 PM h.vetinari--- via SciPy-Dev <
[email protected]> wrote:

> Dear all,
>
> In the context of maintaining our APIs, previous discussions recognized
> the advantages of using keyword-only arguments where appropriate, but it
> was decided that a "big bang" change of all our APIs is not desired, and so
> the current policy [1] states that this should only be done where APIs are
> already being changed _anyway_, for example because a certain argument in
> the signature is being removed (which would make positional-only use of all
> following arguments invalid).
>
> In the context of the ongoing deprecation work, we (meaning mainly myself
> and @j-bowhay) have taken this to mean "introduce the keyword-only cut-off
> at the _natural_ point in the signature". Obviously there is some degree of
> subjectivity in that, but I consider it strictly worse than doing nothing
> to introduce the cut-off between positional-or-keyword and keyword-only at
> exactly the point where a given deprecated argument gets removed. To me it
> is a binary choice "whether to make a function keyword-only at its natural
> point or not".
>
> To illustrate this distinction, let's imagine a function
>
> def func(x, y, z, option_A=..., option_B=..., option_C=...): ...
>
> Let's assume that option_B has become obsolete, or gets renamed, then -
> strictly speaking - only option_C would need to become keyword-only, and
> not option_A. However, I would argue that the only reasonable point to make
> this function keyword only is as follows:
>
> def func(x, y, z, *, option_A=..., option_C=...): ...
>
> This results in a "net additional deprecation" of positional usage of
> option_A vis-à-vis the most minimal deprecation to keep things working as
> before that would look as follows:
>
> def func(x, y, z, option_A=..., *, option_C=...): ...
>
> This is worse IMO because it creates an inconsistency in how conceptually
> equivalent arguments are treated in the API (one can be used positionally,
> one cannot), and risks having to _again_ deprecate something in the
> function if anything about option_A changes in the future.
>
> Obviously, not all examples are as clear-cut, and more than that,
> sometimes a given deprecation only affects a subset of functions that
> belong to an interrelated family, where the API should be consistent
> overall. More context and discussion about this can be found in [2].
>
> For 1.12, we have taken all the functions being touched by deprecations
> and handled them accordingly (in accordance with their respective owners,
> in case the question about where to place the cut-off wasn't self-evident),
> which happened early in 1.12 development. Currently, the affected functions
> are (see also release notes):
> * linalg.{eigh, eigvalsh, pinv}
> * integrate.simpson
> * signal.{firls, firwin, firwin2, remez}
> * sparse.linalg.{bicg, bicgstab, cg, cgs, gcrotmk, gmres, lgmres, minres,
> qmr, tfqmr}
> * special.comb
> * stats.kendalltau
>
> It's worth noting that in some cases we delayed signature changes already
> announced for 1.12 or 1.13 to 1.14, in order to give people time to _also_
> react to the fact that they now need to change away from positional usage
> of some keyword arguments in those functions.
>
> There was some discussion in [2] about these additional deprecations (e.g.
> the option_A case in the example above), resp. whether we should revisit
> the choice about doing a wholesale change of our APIs like e.g.
> scikit-learn did with SLEP009 [3].
>
> I agreed to bring up this topic on the mailing list - please let us know
> your thoughts. The three broad choices (as far as I can tell) are:
> 1. wholesale change à la SLEP009 (this will need more discussion and a
> concrete plan of action IMO)
> 2. keep doing incremental changes as currently present in main (but
> changing over individual functions wholesale and not piecemeal w.r.t. their
> signature)
> 3. revert the change to keyword-only arguments for the above-mentioned
> functions
>
> Option 2. represents the status quo of both the current documented policy
> and the state of the repo on main.
>
> Best regards
> H.
>
> [1]
> https://docs.scipy.org/doc/scipy/dev/missing-bits.html#required-keyword-names
> [2] https://github.com/scipy/scipy/issues/18703
> [3] https://github.com/scikit-learn/scikit-learn/issues/15005
> _______________________________________________
> SciPy-Dev mailing list -- [email protected]
> To unsubscribe send an email to [email protected]
> https://mail.python.org/mailman3/lists/scipy-dev.python.org/
> Member address: [email protected]
>

_______________________________________________
SciPy-Dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/scipy-dev.python.org/
Member address: [email protected]