3

I am a relatively new maintainer of a burgeoning Python library that is used by several dozen users. We have a function with a positional argument that needs to be deprecated. For example, our function is something like:

def foo(x, y, z, a, b = None, c = None, d = 1):
    ...

and we are looking to depreciate and ultimately remove y, while not immediately breaking code compatibility. What is the best/most pythonic way to do this? The best idea that I have at the moment is to move z and a to keyword arguments and change the definition to:

def foo(*args, **kwargs):
    if len(args)>=2 or 'a' not in kwargs:
        warnings.warn("y is deprecated, pass in z and a as keyword arguments")

However, this obviously makes the call more annoying for documentation and accounting purposes (e.g., what are the possible kwargs). Is there a better way to depreciate a positional argument?

I should add that it would be best to not break any current code for a bit and to warn users if we are going to break their code.

William Pursell
  • 204,365
  • 48
  • 270
  • 300
Laxsnor
  • 857
  • 1
  • 12
  • 21
  • 1
    Are you able to tell if something is supposed to be `y` or `z` based on its type or value? – matszwecja May 12 '22 at 13:47
  • @matszwecja, yes. `y` will be array-like and `z` and `a` should be number-like. – Laxsnor May 12 '22 at 13:48
  • 10
    I'd opt for a completely new function. If something as important as the second argument of a four argument function changes, it's basically a new function, or not? I'd leave the old function the way it is, but let it emit a deprecation warning "please use foo2, in the future foo might vanish and foo2 renamed to foo". – Jan Christoph Terasa May 12 '22 at 13:48
  • 1
    Related: https://stackoverflow.com/questions/2536307/decorators-in-the-python-standard-lib-deprecated-specifically – jarmod May 12 '22 at 13:48
  • @JanChristophTerasa We have debated that as well. The function in no way uses `y`, so functionality doesn't change. I'm not sure why the argument was left in the original release; the function has never used this positional argument. – Laxsnor May 12 '22 at 13:50
  • 1
    Seconding new function altogether. This way can make a simple switch to new interface and you don't need to worry whether the parameters are in the old format and should trigger a warning of user updated and everything is fine. It is possible, but I don't see much benefits in doing so. And if you finally decide to remove support for old signature, all you need to do is to remove this function and everyone using your lib should be informed at the point of static code checking. – matszwecja May 12 '22 at 14:02
  • This question seems more appropriate for [softwareengineering.se] – Barmar May 12 '22 at 14:49

0 Answers0