Best Python code snippet using avocado_python
for_argparse.py
Source:for_argparse.py  
1# This Source Code Form is subject to the terms of the Mozilla Public2# License, v. 2.0. If a copy of the MPL was not distributed with this3# file, You can obtain one at http://mozilla.org/MPL/2.0/.4"""this module introduces support for argparse as a data definition source5for configman.  Rather than write using configman's data definition language,6programs can instead use the familiar argparse method."""7from __future__ import absolute_import, division, print_function8import argparse9import inspect10from os import environ11from functools import partial12import six13from configman.namespace import Namespace14from configman.config_file_future_proxy import ConfigFileFutureProxy15from configman.dotdict import (16    DotDict,17    iteritems_breadth_first,18    create_key_translating_dot_dict19)20from configman.converters import (21    str_to_instance_of_type_converters,22    str_to_list,23    boolean_converter,24    to_str,25    CannotConvertError26)27#-----------------------------------------------------------------------------28# horrors29# argparse is not very friendly toward extension in this manner.  In order to30# fully exploit argparse, it is necessary to reach inside it to examine some31# of its internal structures that are not intended for external use.  These32# invasive methods are restricted to read-only.33#------------------------------------------------------------------------------34def find_action_name_by_value(registry, target_action_instance):35    """the association of a name of an action class with a human readable36    string is exposed externally only at the time of argument definitions.37    This routine, when given a reference to argparse's internal action38    registry and an action, will find that action and return the name under39    which it was registered.40    """41    target_type = type(target_action_instance)42    for key, value in six.iteritems(registry['action']):43        if value is target_type:44            if key is None:45                return 'store'46            return key47    return None48#------------------------------------------------------------------------------49def get_args_and_values(parser, an_action):50    """this rountine attempts to reconstruct the kwargs that were used in the51    creation of an action object"""52    args = inspect.getargspec(an_action.__class__.__init__).args53    kwargs = dict(54        (an_attr, getattr(an_action, an_attr))55        for an_attr in args56        if (57            an_attr not in ('self', 'required')58            and getattr(an_action, an_attr) is not None59        )60    )61    action_name = find_action_name_by_value(62        parser._optionals._registries,63        an_action64    )65    if 'required' in kwargs:66        del kwargs['required']67    kwargs['action'] = action_name68    if 'option_strings' in kwargs:69        args = tuple(kwargs['option_strings'])70        del kwargs['option_strings']71    else:72        args = ()73    return args, kwargs74#==============================================================================75class SubparserFromStringConverter(object):76    """this class serves as both a repository of namespace sets corresponding77    with subparsers, and a from string converer. It is used in configman as the78    from_string_converter for the Option that corresponds with the subparser79    argparse action.  Once configman as assigned the final value to the80    subparser, it leaves an instance of the SebparserValue class as the default81    for the subparser configman option.  A deriviative of a string, this class82    also contains the configman required config corresponding to the actions83    of the subparsers."""84    #--------------------------------------------------------------------------85    def __init__(self):86        self.namespaces = {}87    #--------------------------------------------------------------------------88    def add_namespace(self, name, a_namespace):89        """as we build up argparse, the actions that define a subparser are90        translated into configman options.  Each of those options must be91        tagged with the value of the subparse to which they correspond."""92        # save a local copy of the namespace93        self.namespaces[name] = a_namespace94        # iterate through the namespace branding each of the options with the95        # name of the subparser to which they belong96        for k in a_namespace.keys_breadth_first():97            an_option = a_namespace[k]98            if not an_option.foreign_data:99                an_option.foreign_data = DotDict()100            an_option.foreign_data['argparse.owning_subparser_name'] = name101    #--------------------------------------------------------------------------102    def __call__(self, subparser_name):103        """As an instance of this class must serve as a from_string_converter,104        it must behave like a function.  This method gives an instance of this105        class function semantics"""106        #======================================================================107        class SubparserValue(str):108            """Instances of this class/closure serve as the value given out as109            the final value of the subparser configman option.  It is a string,110            that also has a 'get_required_config' method that can bring in the111            the arguments defined in the subparser in the local namespace.112            The mechanism works in the same manner that configman normally does113            expansion of dynamically loaded classes."""114            required_config = Namespace()115            try:116                # define the class dynamically, giving it the required_config117                # that corresponds with the confiman options defined for the118                # subparser of the same name.119                required_config = self.namespaces[subparser_name]120            except KeyError:121                raise CannotConvertError(122                    '%s is not a known sub-command' % subparser_name123                )124            #------------------------------------------------------------------125            def __new__(cls):126                """deriving from string is tricky business.  You cannot set the127                value in an __init__ method because strings are immutable and128                __init__ time is too late.  The 'new' method is the only chance129                to properly set the value."""130                obj = str.__new__(cls, subparser_name)131                return obj132            #------------------------------------------------------------------133            def get_required_config(self):134                return self.required_config135            #------------------------------------------------------------------136            def to_str(self):137                return subparser_name138        # instantiate the class and return it.  It will be assigned as the139        # value for the configman option corresponding with the subparser140        return SubparserValue()141#==============================================================================142class ConfigmanSubParsersAction(argparse._SubParsersAction):143    """this is a derivation of the argpares _SubParsersAction action.  We144    require its use over the default _SubParsersAction because we need to145    preserve the original args & kwargs that created it.  They will be used146    in a later phase of configman to perfectly reproduce the object without147    having to resort to a copy."""148    #--------------------------------------------------------------------------149    def __init__(self, *args, **kwargs):150        self.original_args = args151        self.original_kwargs = kwargs152        super(ConfigmanSubParsersAction, self).__init__(*args, **kwargs)153    #--------------------------------------------------------------------------154    def add_parser(self, *args, **kwargs):155        """each time a subparser action is used to create a new parser object156        we must save the original args & kwargs.  In a later phase of157        configman, we'll need to reproduce the subparsers exactly without158        resorting to copying.  We save the args & kwargs in the 'foreign_data'159        section of the configman option that corresponds with the subparser160        action."""161        command_name = args[0]162        new_kwargs = kwargs.copy()163        new_kwargs['configman_subparsers_option'] = self._configman_option164        new_kwargs['subparser_name'] = command_name165        subparsers = self._configman_option.foreign_data.argparse.subparsers166        a_subparser = super(ConfigmanSubParsersAction, self).add_parser(167            *args,168            **new_kwargs169        )170        subparsers[command_name] = DotDict({171            "args": args,172            "kwargs": new_kwargs,173            "subparser": a_subparser174        })175        return a_subparser176    #--------------------------------------------------------------------------177    def add_configman_option(self, an_option):178        self._configman_option = an_option179#==============================================================================180class ArgumentParser(argparse.ArgumentParser):181    """this subclass of the standard argparse parser to be used as a drop in182    replacement for argparse.ArgumentParser.  It hijacks the standard183    parsing methods and hands off to configman.  Configman then calls back184    to the standard argparse base class to actually do the work, intercepting185    the final output do its overlay magic. The final result is not an186    argparse Namespace object, but a configman DotDict.  This means that it187    is functionlly equivalent to the argparse Namespace with the additional188    benefit of being compliant with the collections.Mapping abstract base189    class."""190    #--------------------------------------------------------------------------191    def __init__(self, *args, **kwargs):192        self.original_args = args193        self.original_kwargs = kwargs.copy()194        self.version = kwargs.get("version")  # py3 argparse doesn't define195        kwargs['add_help'] = False  # stop help, reintroduce it later196        self.subparser_name = kwargs.pop('subparser_name', None)197        self.configman_subparsers_option = kwargs.pop(198            'configman_subparsers_option',199            None200        )201        super(ArgumentParser, self).__init__(*args, **kwargs)202        self.value_source_list = [environ, ConfigFileFutureProxy, argparse]203        self.required_config = Namespace()204    #--------------------------------------------------------------------------205    def get_required_config(self):206        """because of the exsistance of subparsers, the configman options207        that correspond with argparse arguments are not a constant.  We need208        to produce a copy of the namespace rather than the actual embedded209        namespace."""210        required_config = Namespace()211        # add current options to a copy of required config212        for k, v in iteritems_breadth_first(self.required_config):213            required_config[k] = v214        # get any option found in any subparsers215        try:216            subparser_namespaces = (217                self.configman_subparsers_option.foreign_data218                .argparse.subprocessor_from_string_converter219            )220            subparsers = (221                self._argparse_subparsers._configman_option.foreign_data222                .argparse.subparsers223            )224            # each subparser needs to have its configman options set up225            # in the subparser's configman option.  This routine copies226            # the required_config of each subparser into the227            # SubparserFromStringConverter defined above.228            for subparser_name, subparser_data in six.iteritems(subparsers):229                subparser_namespaces.add_namespace(230                    subparser_name,231                    subparser_data.subparser.get_required_config()232                )233        except AttributeError:234            # there is no subparser235            pass236        return required_config237    #--------------------------------------------------------------------------238    def add_argument(self, *args, **kwargs):239        """this method overrides the standard in order to create a parallel240        argument system in both the argparse and configman worlds.  Each call241        to this method returns a standard argparse Action object as well as242        adding an equivalent configman Option object to the required_config243        for this object.  The original args & kwargs that defined an argparse244        argument are preserved in the 'foreign_data' section of the245        corresponding configman Option."""246        # pull out each of the argument definition components from the args247        # so that we can deal with them one at a time in a well labeled manner248        # In this section, variables beginning with the prefix "argparse" are249        # values that define Action object.  Variables that begin with250        # "configman" are the arguments to create configman Options.251        argparse_action_name = kwargs.get('action', None)252        argparse_dest = kwargs.get('dest', None)253        argparse_const = kwargs.get('const', None)254        argparse_default = kwargs.get('default', None)255        if argparse_default is argparse.SUPPRESS:256            # we'll be forcing all options to have the attribute of257            # argparse.SUPPRESS later.  It's our way of making sure that258            # argparse returns only values that the user explicitly added to259            # the command line.260            argparse_default = None261        argparse_nargs = kwargs.get('nargs', None)262        argparse_type = kwargs.get('type', None)263        argparse_suppress_help = kwargs.pop('suppress_help', False)264        if argparse_suppress_help:265            configman_doc = kwargs.get('help', '')266            kwargs['help'] = argparse.SUPPRESS267        else:268            argparse_help = kwargs.get('help', '')269            if argparse_help == argparse.SUPPRESS:270                configman_doc = ''271            else:272                configman_doc = argparse_help273        # we need to make sure that all arguments that the user has not274        # explicily set on the command line have this attribute.  This means275        # that when the argparse parser returns the command line values, it276        # will not return values that the user did not mention on the command277        # line.  The defaults that otherwise would have been returned will be278        # handled by configman.279        kwargs['default'] = argparse.SUPPRESS280        # forward all parameters to the underlying base class to create a281        # normal argparse action object.282        an_action = super(ArgumentParser, self).add_argument(283            *args,284            **kwargs285        )286        argparse_option_strings = an_action.option_strings287        # get a human readable string that identifies the type of the argparse288        # action class that was created289        if argparse_action_name is None:290            argparse_action_name = find_action_name_by_value(291                self._optionals._registries,292                an_action293            )294        configman_is_argument = False295        # each of argparse's Action types must be handled separately.296        #--------------------------------------------------------------------297        # STORE298        if argparse_action_name == 'store':299            if argparse_dest is None:300                configman_name, configman_is_argument = self._get_option_name(301                    args302                )303                if not configman_name:304                    configman_name = args[0]305            else:306                configman_name = argparse_dest307                configman_is_argument = not argparse_option_strings308            configman_default = argparse_default309            if argparse_nargs and argparse_nargs in "1?":310                if argparse_type:311                    configman_from_string = argparse_type312                elif argparse_default:313                    configman_from_string = (314                        str_to_instance_of_type_converters.get(315                            type(argparse_default),316                            str317                        )318                    )319                else:320                    configman_from_string = str321            elif argparse_nargs and argparse_type:322                configman_from_string = partial(323                    str_to_list,324                    item_converter=argparse_type,325                    item_separator=' ',326                )327            elif argparse_nargs and argparse_default:328                configman_from_string = partial(329                    str_to_list,330                    item_converter=str_to_instance_of_type_converters.get(331                        type(argparse_default),332                        str333                    ),334                    item_separator=' ',335                )336            elif argparse_nargs:337                configman_from_string = partial(338                    str_to_list,339                    item_converter=str,340                    item_separator=' ',341                )342            elif argparse_type:343                configman_from_string = argparse_type344            elif argparse_default:345                configman_from_string = str_to_instance_of_type_converters.get(346                    type(argparse_default),347                    str348                )349            else:350                configman_from_string = str351            configman_to_string = to_str352        #--------------------------------------------------------------------353        # STORE_CONST354        elif (355            argparse_action_name == 'store_const'356            or argparse_action_name == 'count'357        ):358            if argparse_dest is None:359                configman_name, configman_is_argument = self._get_option_name(360                    args361                )362                if not configman_name:363                    configman_name = args[0]364            else:365                configman_name = argparse_dest366            configman_default = argparse_default367            if argparse_type:368                configman_from_string = argparse_type369            else:370                configman_from_string = str_to_instance_of_type_converters.get(371                    type(argparse_const),372                    str373                )374            configman_to_string = to_str375        #--------------------------------------------------------------------376        # STORE_TRUE /  STORE_FALSE377        elif (378            argparse_action_name == 'store_true'379            or argparse_action_name == 'store_false'380        ):381            if argparse_dest is None:382                configman_name, configman_is_argument = self._get_option_name(383                    args384                )385                if not configman_name:386                    configman_name = args[0]387            else:388                configman_name = argparse_dest389            configman_default = argparse_default390            configman_from_string = boolean_converter391            configman_to_string = to_str392        #--------------------------------------------------------------------393        # APPEND394        elif argparse_action_name == 'append':395            if argparse_dest is None:396                configman_name, configman_is_argument = self._get_option_name(397                    args398                )399                if not configman_name:400                    configman_name = args[0]401            else:402                configman_name = argparse_dest403            configman_default = argparse_default404            if argparse_type:405                configman_from_string = argparse_type406            else:407                configman_from_string = str408            configman_to_string = to_str409        #--------------------------------------------------------------------410        # APPEND_CONST411        elif argparse_action_name == 'append_const':412            if argparse_dest is None:413                configman_name, configman_is_argument = self._get_option_name(414                    args415                )416                if not configman_name:417                    configman_name = args[0]418            else:419                configman_name = argparse_dest420            configman_default = argparse_default421            if argparse_type:422                configman_from_string = argparse_type423            else:424                configman_from_string = str_to_instance_of_type_converters.get(425                    type(argparse_const),426                    str427                )428            configman_to_string = to_str429        #--------------------------------------------------------------------430        # VERSION431        elif argparse_action_name == 'version':432            return an_action433        #--------------------------------------------------------------------434        # OTHER435        else:436            configman_name = argparse_dest437        # configman uses the switch name as the name of the key inwhich to438        # store values.  argparse is able to use different names for each.439        # this means that configman may encounter repeated targets.  Rather440        # than overwriting Options with new ones with the same name, configman441        # renames them by appending the '$' character.442        while configman_name in self.required_config:443            configman_name = "%s$" % configman_name444        configman_not_for_definition = configman_name.endswith('$')445        # it's finally time to create the configman Option object and add it446        # to the required_config.447        self.required_config.add_option(448            name=configman_name,449            default=configman_default,450            doc=configman_doc,451            from_string_converter=configman_from_string,452            to_string_converter=configman_to_string,453            #short_form=configman_short_form,454            is_argument=configman_is_argument,455            not_for_definition=configman_not_for_definition,456            # we're going to save the args & kwargs that created the457            # argparse Action.  This enables us to perfectly reproduce the458            # the original Action object later during the configman overlay459            # process.460            foreign_data=DotDict({461                'argparse.flags.subcommand': False,462                'argparse.args': args,463                'argparse.kwargs': kwargs,464                'argparse.owning_subparser_name': self.subparser_name,465            })466        )467        return an_action468    #--------------------------------------------------------------------------469    def add_subparsers(self, *args, **kwargs):470        """When adding a subparser, we need to ensure that our version of the471        SubparserAction object is returned.  We also need to create the472        corresponding configman Option object for the subparser and pack it's473        foreign data section with the original args & kwargs."""474        kwargs['parser_class'] = self.__class__475        kwargs['action'] = ConfigmanSubParsersAction476        subparser_action = super(ArgumentParser, self).add_subparsers(477            *args,478            **kwargs479        )480        self._argparse_subparsers = subparser_action481        if "dest" not in kwargs or kwargs['dest'] is None:482            kwargs['dest'] = 'subcommand'483        configman_name = kwargs['dest']484        configman_default = None485        configman_doc = kwargs.get('help', '')486        subprocessor_from_string_converter = SubparserFromStringConverter()487        configman_to_string = str488        configman_is_argument = True489        configman_not_for_definition = True490        # it's finally time to create the configman Option object and add it491        # to the required_config.492        self.required_config.add_option(493            name=configman_name,494            default=configman_default,495            doc=configman_doc,496            from_string_converter=subprocessor_from_string_converter,497            to_string_converter=configman_to_string,498            is_argument=configman_is_argument,499            not_for_definition=configman_not_for_definition,500            # we're going to save the input parameters that created the501            # argparse Action.  This enables us to perfectly reproduce the502            # the original Action object later during the configman overlay503            # process.504            foreign_data=DotDict({505                'argparse.flags.subcommand': subparser_action,506                'argparse.args': args,507                'argparse.kwargs': kwargs,508                'argparse.subparsers': DotDict(),509                'argparse.subprocessor_from_string_converter':510                subprocessor_from_string_converter511            })512        )513        self.configman_subparsers_option = self.required_config[configman_name]514        subparser_action.add_configman_option(self.configman_subparsers_option)515        return subparser_action516    #--------------------------------------------------------------------------517    def set_defaults(self, **kwargs):518        """completely take over the 'set_defaults' system of argparse, because519        configman has no equivalent.  These will be added back to the configman520        result at the very end."""521        self.extra_defaults = kwargs522    #--------------------------------------------------------------------------523    def parse_args(self, args=None, namespace=None):524        """this method hijacks the normal argparse Namespace generation,525        shimming configman into the process. The return value will be a526        configman DotDict rather than an argparse Namespace."""527        # load the config_manager within the scope of the method that uses it528        # so that we avoid circular references in the outer scope529        from configman.config_manager import ConfigurationManager530        configuration_manager = ConfigurationManager(531            definition_source=[self.get_required_config()],532            values_source_list=self.value_source_list,533            argv_source=args,534            app_name=self.prog,535            app_version=self.version,536            app_description=self.description,537            use_auto_help=False,538        )539        # it is apparent a common idiom that commandline options may have540        # embedded '-' characters in them.  Configman requires that option541        # follow the Python Identifier rules.  Fortunately, Configman has a542        # class that will perform dynamic translation of keys.  In this543        # code fragment, we fetch the final configuration from configman544        # using a Mapping that will translate keys with '-' into keys with545        # '_' instead.546        conf = configuration_manager.get_config(547            mapping_class=create_key_translating_dot_dict(548                "HyphenUnderscoreDict",549                (('-', '_'),)550            )551        )552        # here is where we add the values given to "set_defaults" method553        # of argparse.554        if self.configman_subparsers_option:555            subparser_name = conf[self.configman_subparsers_option.name]556            try:557                conf.update(558                    self.configman_subparsers_option.foreign_data.argparse559                    .subparsers[subparser_name].subparser560                    .extra_defaults561                )562            except (AttributeError, KeyError):563                # no extra_defaults skip on564                pass565        if hasattr(self, 'extra_defaults'):566            conf.update(self.extra_defaults)567        return conf568    #--------------------------------------------------------------------------569    def parse_known_args(self, args=None, namespace=None):570        """this method hijacks the normal argparse Namespace generation,571        shimming configman into the process. The return value will be a572        configman DotDict rather than an argparse Namespace."""573        # load the config_manager within the scope of the method that uses it574        # so that we avoid circular references in the outer scope575        from configman.config_manager import ConfigurationManager576        configuration_manager = ConfigurationManager(577            definition_source=[self.get_required_config()],578            values_source_list=self.value_source_list,579            argv_source=args,580            app_name=self.prog,581            app_version=self.version,582            app_description=self.description,583            use_auto_help=False,584        )585        conf = configuration_manager.get_config(586            mapping_class=create_key_translating_dot_dict(587                "HyphenUnderscoreDict",588                (('-', '_'),)589            )590        )591        return conf592    #--------------------------------------------------------------------------593    def _get_option_name(self, args):594        # argparse is loose in the manner that it names arguments.  Sometimes595        # it comes in as the 'dest' kwarg, othertimes it is deduced from args596        # as the first "long" style argument in the args.  This method597        short_name = None598        for an_option in args:599            if an_option[0] in self.prefix_chars:600                if an_option[1] in self.prefix_chars:601                    return an_option[2:], False602                if not short_name:603                    short_name = an_option[1:]604            else:605                return an_option, True606        if short_name:607            return short_name, False608        return None609#------------------------------------------------------------------------------610def setup_definitions(source, destination):611    """this method stars the process of configman reading and using an argparse612    instance as a source of configuration definitions."""613    #"""assume that source is of type argparse614    try:615        destination.update(source.get_required_config())616    except AttributeError:617        # looks like the user passed in a real arpgapse parser rather than our618        # bastardized version of one.  No problem, we can work with it,619        # though the translation won't be as perfect.620        our_parser = ArgumentParser()621        for i, an_action in enumerate(source._actions):622            args, kwargs = get_args_and_values(source, an_action)623            dest = kwargs.get('dest', '')624            if dest in ('help', 'version'):625                continue626            our_parser.add_argument(*args, **kwargs)...test_validators.py
Source:test_validators.py  
...69class TestArgparseType(TestCase):70    def test_function_returns_ouptput_data_type(self):71        # GIVEN72        field = FloatField()73        type_func = argparse_type(field)74        # WHEN75        new_value = type_func('123')76        # THEN77        self.assertTrue(type(new_value) is float)78    def test_function_returns_value(self):79        # GIVEN80        field = FloatField()81        type_func = argparse_type(field)82        # WHEN83        new_value = type_func('123')84        # THEN85        self.assertEqual(123.0, new_value)86    def test_function_has_custom_name(self):87        # GIVEN88        field = FloatField()89        # WHEN90        type_func = argparse_type(field, 'custom')91        # THEN92        self.assertEqual('custom', type_func.__name__)93    def test_nonconvertible_input_raises_exception(self):94        # GIVEN95        field = IntegerField()96        type_func = argparse_type(field)97        # THEN98        with self.assertRaises(ValueError):99            type_func('abc')100    def test_function_raises_valueerror_when_validator_fails(self):101        # GIVEN102        field = IntegerField(validators=[MaxValueValidator(10)])103        type_func = argparse_type(field)104        # THEN105        with self.assertRaises(ValueError):...argparse_type.py
Source:argparse_type.py  
1import argparse2parser = argparse.ArgumentParser()3parser.add_argument("-i", type=int)4parser.add_argument("-f", type=float)5parser.add_argument("--file", type=open)6try:7    print(parser.parse_args())8except IOError as msg:9    parser.error(str(msg))10# python argparse_type.py -i 10011# python argparse_type.py -f 10012# python argparse_type.py --file /tmp/a.log...Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
