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!!