HPInc / HP-Digital-Microfluidics

HP Digital Microfluidics Software Platform and Libraries
MIT License
2 stars 0 forks source link

Add support for deprecated cmd-line arguments #267

Closed EvanKirshenbaum closed 5 months ago

EvanKirshenbaum commented 5 months ago

When designing support for Joey 1.5 boards (#266), it became clear that the command-line arguments I have for specifying the Opendrop version and Wombat version as bare numbers (e.g., --4.0 for Opendrop version and --v2 for Wombat layout version) are confusing and the wrong way to do it. What I want instead are regular arguments like --opendrop-version and --wombat-layout and --joey-layout. Since people are currently using the old parameters, I don't want to get rid of them, but I do want to make it so that they are deprecated and print a warning, while still working and passing their values on to the new arguments.

I have no idea if this link will work for anybody else but ChatGPT helpfully provided me a starting point for this:

import argparse
import warnings

class DeprecatedAction(argparse.Action):
    def __init__(self, alternative, munge_func=None, help=None, **kwargs):
        self.alternative = alternative
        self.munge_func = munge_func
        super().__init__(help=help, **kwargs)

    def __call__(self, parser, namespace, values, option_string=None):
        warnings.warn(
            f"The argument '{option_string}' is deprecated. Use '{self.alternative}' instead.",
            DeprecationWarning
        )
        if self.munge_func:
            values = self.munge_func(values)

        # Find the new argument's action and set its value
        for action in parser._actions:
            if action.option_strings == [self.alternative]:
                setattr(namespace, action.dest, values)
                break

def main():
    def munge_old_arg(value):
        # Transform the value of the deprecated argument as needed
        return value * 2

    parser = argparse.ArgumentParser()
    parser.add_argument("--old-arg", action=DeprecatedAction, alternative="--new-arg",
                        munge_func=munge_old_arg,
                        help="This argument is deprecated. Use --new-arg instead.")
    parser.add_argument("--new-arg", type=int, help="This is the new argument.")

    args = parser.parse_args()
    print(args)

if __name__ == "__main__":
    main()
Migrated from internal repository. Originally created by @EvanKirshenbaum on Apr 29, 2023 at 2:47 PM PDT. Closed on May 16, 2023 at 12:08 PM PDT.
EvanKirshenbaum commented 5 months ago

I forgot to tag this, but I implemented it as part of the implementation of ConfigParam.add_arg_to() (and its sibling methods) in #123, specifically in commit 9204d29.

I particular, if you say

cp.add_arg_to(group, '--foo', deprecated=True)

the string 'THIS ARGUMENT IS DEPRECATED.' will be added to the help string, and --foo IS DEPRECATED. will be logged as a warning if the argument is used.

If you say

cp.add_arg_to(group, '--foo', deprecated='Please don't use it.')

the warning will be 'THIS ARGUMENT IS DEPRECATED. Please don't use it.'

As a shortcut,

cp.add_arg_to(group, '--foo', deprecated=ConfigParam.use_instead('--bar'))

is equivalent to

cp.add_arg_to(group, '--foo', deprecated='Use --bar instead.')

In addition, if the the parameter ignored is True, 'AND WILL BE IGNORED' will be added. This may be used with or without a deprecated parameter.

Migrated from internal repository. Originally created by @EvanKirshenbaum on May 16, 2023 at 12:08 PM PDT.