
Hey, I don't think there's any helper to deprecate an argument in argparse Let's say you have a --foo option in your CLI and want to deprecate it in the next release before you completely remove it later. My first though on how to do this by adding a new "deprecated" option to https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser.add_... "deprecated" would be a callable that is called after the argument has been parsed by argparse, so the developer can decide if they want to issue a deprecation warning, use the parsed value or override it etc. Another interesting approach suggest by Doug Hellman, which I like as much, is a set of higher level options that provide a deprecation workflow for arguments, see https://github.com/openstack/oslo.config/blob/master/oslo_config/cfg.py#L441 What do you think? Cheers Tarek -- Tarek Ziadé | coding: https://ziade.org | running: https://foule.es | twitter: @tarek_ziade

+1, but I would make "deprecated" either a warning, an exception or a callable. This way to create a simple deprecation, you just provide DeprecationWarning('This will be gone in the next release'), or ValueError('This has been removed in 2.X, use "stuff instead"') if you decide it's gone for good. But if you need a custom behavior, you pass in a callable. Le 09/08/2017 à 09:56, Tarek Ziadé a écrit :

On 8/9/17 3:56 AM, Tarek Ziadé wrote:
I don't see why this is something that argparse has to do. The semantics of options is handled by the rest of the program. Why would the parser be issuing these warnings? Let argparse parse the options, then let other code deal with what they *mean*. --Ned.

Argparse is not just about parsing, it's about providing convenient tooling associated with parsing. Otherwise you would not have automatically generated a "usage" message or a "--help" command. Following your definition, those are not parsing. But there are here, because we all end up coding them anyway. Le 09/08/2017 à 11:50, Ned Batchelder a écrit :

OK, then on a more pragmatic note: why is it easier to write a callback than to write a simple if statement after the parsing? Generating help is complex, and a common task that is closely tied to the syntax of the options, so it makes sense for argparse to do it. Deprecation is neither complex, common, nor closely tied to the syntax of the options. Another note about the proposal: calling it "deprecated" seems odd, since the proposal is really just a general-purpose callback. argparse isn't generating the warning, your callback function would be doing it. Why name it "deprecated"? How is this different than the "action" keyword argument that argparse already provides? --Ned. On 8/9/17 5:54 AM, Michel Desmoulin wrote:

Le 09/08/2017 à 12:59, Ned Batchelder a écrit :
I imagine something like: def _(warn, forbid): warn('This is deprecated') # for forbid to just put an error parser.add_option(on_deprecated=deprecationCallback) This does: - provide an easy way to warn, or transition to forbid - allow introspection to list the deprecated options - deprecated options can be marked as such in the generated --help - create a complex dynamic deprecation message, or just pass a short lambda But indeed I'd like it to be able to do: parser.add_option(on_deprecated=DeprecationWarning('meh')) parser.add_option(on_deprecated=ValueError('meh')) As a shortcut for simple use cases. I still don't know how to make the distinction between deprecated and removed from the introspection point of view. All in all, I think it's an interesting proposal, but I'm not going to fight over it. If it never happens, I can fit a bunch of "if" like you said.

That sounds right. Maybe a better implementation would be to implement a custom action by inheriting from argparse.Action https://docs.python.org/3/library/argparse.html#action and do all the warning/deprecation job there. I'll experiment with this idea on my side to see how it goes :) Cheers Tarek

+1, but I would make "deprecated" either a warning, an exception or a callable. This way to create a simple deprecation, you just provide DeprecationWarning('This will be gone in the next release'), or ValueError('This has been removed in 2.X, use "stuff instead"') if you decide it's gone for good. But if you need a custom behavior, you pass in a callable. Le 09/08/2017 à 09:56, Tarek Ziadé a écrit :

On 8/9/17 3:56 AM, Tarek Ziadé wrote:
I don't see why this is something that argparse has to do. The semantics of options is handled by the rest of the program. Why would the parser be issuing these warnings? Let argparse parse the options, then let other code deal with what they *mean*. --Ned.

Argparse is not just about parsing, it's about providing convenient tooling associated with parsing. Otherwise you would not have automatically generated a "usage" message or a "--help" command. Following your definition, those are not parsing. But there are here, because we all end up coding them anyway. Le 09/08/2017 à 11:50, Ned Batchelder a écrit :

OK, then on a more pragmatic note: why is it easier to write a callback than to write a simple if statement after the parsing? Generating help is complex, and a common task that is closely tied to the syntax of the options, so it makes sense for argparse to do it. Deprecation is neither complex, common, nor closely tied to the syntax of the options. Another note about the proposal: calling it "deprecated" seems odd, since the proposal is really just a general-purpose callback. argparse isn't generating the warning, your callback function would be doing it. Why name it "deprecated"? How is this different than the "action" keyword argument that argparse already provides? --Ned. On 8/9/17 5:54 AM, Michel Desmoulin wrote:

Le 09/08/2017 à 12:59, Ned Batchelder a écrit :
I imagine something like: def _(warn, forbid): warn('This is deprecated') # for forbid to just put an error parser.add_option(on_deprecated=deprecationCallback) This does: - provide an easy way to warn, or transition to forbid - allow introspection to list the deprecated options - deprecated options can be marked as such in the generated --help - create a complex dynamic deprecation message, or just pass a short lambda But indeed I'd like it to be able to do: parser.add_option(on_deprecated=DeprecationWarning('meh')) parser.add_option(on_deprecated=ValueError('meh')) As a shortcut for simple use cases. I still don't know how to make the distinction between deprecated and removed from the introspection point of view. All in all, I think it's an interesting proposal, but I'm not going to fight over it. If it never happens, I can fit a bunch of "if" like you said.

That sounds right. Maybe a better implementation would be to implement a custom action by inheriting from argparse.Action https://docs.python.org/3/library/argparse.html#action and do all the warning/deprecation job there. I'll experiment with this idea on my side to see how it goes :) Cheers Tarek
participants (3)
-
Michel Desmoulin
-
Ned Batchelder
-
Tarek Ziadé