def take_action(action, argument_strings, option_string=None): seen_actions.add(action) argument_values = self._get_values(action, argument_strings) # error if this argument is not allowed with other previously # seen arguments, assuming that actions that use the default # value don't really count as "present" if argument_values is not action.default: seen_non_default_actions.add(action) for conflict_action in action_conflicts.get(action, []): if conflict_action in seen_non_default_actions: msg = _('not allowed with argument %s') action_name = _get_action_name(conflict_action) raise ArgumentError(action, msg % action_name) # take the action if we didn't receive a SUPPRESS value # (e.g. from a default) if argument_values is not SUPPRESS \ or isinstance(action, _SubParsersAction): try: action(self, namespace, argument_values, option_string) except BaseException: # Begin added by argcomplete # When a subparser action is taken and fails due to incomplete arguments, it does not merge the # contents of its parsed namespace into the parent namespace. Do that here to allow completers to # access the partially parsed arguments for the subparser. if isinstance(action, _SubParsersAction): subnamespace = action._name_parser_map[ argument_values[0]]._argcomplete_namespace for key, value in vars(subnamespace).items(): setattr(namespace, key, value) # End added by argcomplete raise
def _check_value(self, action, value): # Override to customize the error message when a argument is not among the available choices # converted value must be one of the choices (if specified) import difflib import sys if action.choices is not None and value not in action.choices: if action.dest in ["_command", "_subcommand"]: # Command error_msg = "{prog}: '{value}' is not in the '{prog}' command group. See '{prog} --help'.".format( prog=self.prog, value=value) logger.error(error_msg) # Show suggestions candidates = difflib.get_close_matches(value, action.choices, cutoff=0.7) if candidates: suggestion_msg = "\nThe most similar choices to '{value}':\n".format(value=value) suggestion_msg += '\n'.join(['\t' + candidate for candidate in candidates]) print(suggestion_msg, file=sys.stderr) else: # Argument error_msg = "{prog}: '{value}' is not a valid value for '{name}'.".format( prog=self.prog, value=value, name=argparse._get_action_name(action)) # pylint: disable=protected-access logger.error(error_msg) # Show all allowed values suggestion_msg = "Allowed values: " + ', '.join(action.choices) print(suggestion_msg, file=sys.stderr) self.exit(2)
def take_action(action, argument_strings, option_string=None): seen_actions.add(action) argument_values = self._get_values(action, argument_strings) # error if this argument is not allowed with other previously # seen arguments, assuming that actions that use the default # value don't really count as "present" if argument_values is not action.default: seen_non_default_actions.add(action) for conflict_action in action_conflicts.get(action, []): if conflict_action in seen_non_default_actions: msg = _('not allowed with argument %s') action_name = _get_action_name(conflict_action) raise ArgumentError(action, msg % action_name) # take the action if we didn't receive a SUPPRESS value # (e.g. from a default) if argument_values is not SUPPRESS \ or isinstance(action, _SubParsersAction): try: action(self, namespace, argument_values, option_string) except: # Begin added by argcomplete # When a subparser action is taken and fails due to incomplete arguments, it does not merge the # contents of its parsed namespace into the parent namespace. Do that here to allow completers to # access the partially parsed arguments for the subparser. if isinstance(action, _SubParsersAction): subnamespace = action._name_parser_map[argument_values[0]]._argcomplete_namespace for key, value in vars(subnamespace).items(): setattr(namespace, key, value) # End added by argcomplete raise
def update_mutex_groups(arg_action: argparse.Action) -> bool: """ Check if an argument belongs to a mutually exclusive group and either mark that group as complete or print an error if the group has already been completed :param arg_action: the action of the argument :return: False if the group has already been completed and there is a conflict, otherwise True """ # Check if this action is in a mutually exclusive group for group in self._parser._mutually_exclusive_groups: if arg_action in group._group_actions: # Check if the group this action belongs to has already been completed if group in completed_mutex_groups: # If this is the action that completed the group, then there is no error # since it's allowed to appear on the command line more than once. completer_action = completed_mutex_groups[group] if arg_action == completer_action: return True error = ansi.style_error( "\nError: argument {}: not allowed with argument {}\n" .format( argparse._get_action_name(arg_action), argparse._get_action_name(completer_action))) self._print_message(error) return False # Mark that this action completed the group completed_mutex_groups[group] = arg_action # Don't tab complete any of the other args in the group for group_action in group._group_actions: if group_action == arg_action: continue elif group_action in self._flag_to_action.values(): matched_flags.extend(group_action.option_strings) elif group_action in remaining_positionals: remaining_positionals.remove(group_action) # Arg can only be in one group, so we are done break return True
def __init__(self, flag_arg_state: _ArgumentState) -> None: """ CompletionError which occurs when the user has not finished the current flag :param flag_arg_state: information about the unfinished flag action """ error = "Error: argument {}: {} ({} entered)".\ format(argparse._get_action_name(flag_arg_state.action), generate_range_error(flag_arg_state.min, flag_arg_state.max), flag_arg_state.count) super().__init__(error)
def _print_unfinished_flag_error(self, flag_arg_state: _ArgumentState) -> None: """ Print an error during tab completion when the user has not finished the current flag :param flag_arg_state: information about the unfinished flag action """ error = "\nError: argument {}: {} ({} entered)\n".\ format(argparse._get_action_name(flag_arg_state.action), generate_range_error(flag_arg_state.min, flag_arg_state.max), flag_arg_state.count) self._print_message(ansi.style_error('{}'.format(error)))
def _enforce_required(self, namespace): empty_required_actions = [ _ap._get_action_name(action) for action in self._actions if getattr(action, 'required', False) and isinstance(action, self._REQUIRED_IS_NONEMPTY_ACTIONS) and not getattr(namespace, action.dest, None) ] if empty_required_actions: self.error( _ap._('the following arguments are required: %s') % ', '.join(empty_required_actions) )
def _print_completion_error(self, arg_action: argparse.Action, completion_error: CompletionError) -> None: """ Print a CompletionError to the user :param arg_action: action being tab completed :param completion_error: error that occurred """ # Indent all lines of completion_error indented_error = textwrap.indent(str(completion_error), ' ') error = ("\nError tab completing {}:\n" "{}\n".format(argparse._get_action_name(arg_action), indented_error)) self._print_message(ansi.style_error('{}'.format(error)))
def parse_args(self, *args, **kwargs): namespace = super().parse_args(*args, **kwargs) # Mounting config config = {k: v or os.environ.get(k.upper(), '') for k, v in vars(namespace).items()} # Verifying required arguments missing_args = [argparse._get_action_name(a) for a in self._required_actions if not config[a.dest]] if missing_args: self.error("missing arguments: " + ", ".join(missing_args)) return config
def main(): # Configuring log logging.basicConfig( level=logging.INFO, format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p' ) # Configuring bot parameters logging.info("Configurando parâmetros") parser = argparse.ArgumentParser(description='Bot do GDG Aracaju') parser.add_argument('-t', '--telegram_token', help='Token da API do Telegram', required=True) parser.add_argument('-m', '--meetup_key', help='Key da API do Meetup', required=True) parser.add_argument('-g', '--group_name', help='Grupo do Meetup', required=True) parser.add_argument('--url_shortener_key', help='Key da API do URL Shortener') parser.add_argument('-d', '--dev', help='Indicador de Debug/Dev mode', action='store_true') parser.add_argument('--no-dev', help=argparse.SUPPRESS, dest='dev', action='store_false') # Get required arguments to check after parsed required_actions = [] for action in parser._actions: if action.required: required_actions.append(action) action.required = False # Parse command line args namespace = parser.parse_args() # Mounting config _config = {k: v or os.environ.get(k.upper(), '') for k, v in vars(namespace).items()} # Verifying required arguments missing_args = [argparse._get_action_name(a) for a in required_actions if not _config[a.dest]] if missing_args: parser.error("missing arguments: " + ", ".join(missing_args)) # Starting bot logging.info("Iniciando bot") bot = telebot.TeleBot(_config['telegram_token']) if _config["dev"]: logging.info("Dev mode activated.") logging.info("Usando @%s", bot.get_me().username) logging.info("Usando telegram_token=%(telegram_token)s", _config) logging.info("Usando meetup_key=%(meetup_key)s", _config) resources = Resources(_config) gdgbot = GDGAjuBot(bot, resources, _config) gdgbot.start()
def __call__(self, parser, namespace, values, option_string=None): positional_values = filter(lambda v: v.selector is None, values) positional_values = map( lambda v: ThreadAffinity(PositionalThreadSelector(v[0]), v[1]. affinity), enumerate(positional_values)) values = filter(lambda v: v.selector is not None, values) values = list(itertools.chain(values, positional_values)) # counter over selectors selectors = Counter(filter(None, map(lambda v: v.selector, values))) # prevent duplicate tids if len(list(filter(lambda c: c > 1, selectors.values()))) > 0: parser.error('argument %s: duplicate affinity value.' % argparse._get_action_name(self)) setattr(namespace, self.dest, dict(values))
def parse_args(self, *args, **kwargs): namespace = super().parse_args(*args, **kwargs) # Mounting config config_dict = { k: v or os.environ.get(k.upper(), '') for k, v in vars(namespace).items() } # Verifying required arguments missing_args = [ argparse._get_action_name(a) for a in self._required_actions if not config_dict[a.dest] ] if missing_args: self.error("missing arguments: " + ", ".join(missing_args)) return BotConfig(**config_dict)
def __call__(self, parser, namespace, values, option_string=None): super().__call__(parser, namespace, values, option_string) # the user has invoked an "exclusive step" subcommand -- we'll: # # 1. inform (the pipeline) of the specially-satisfied # requirements associated with this case (s.t. it may update # itself) # # 2. based on those steps the pipeline reports ejected: # # 2a. mark the arguments of ejected steps not required # 2b. raise conflict errors for *any* of these arguments # that are supplied # # in so doing we'll both dynamically customize the pipeline and # the CLI based on the invocation of this subcommand. # argparse keeps nice track of what it's seen and what it hasn't # from within _parse_known_args (and which is ostensibly the # caller of this method); however, short of reaching into there, # we can do s'thing simple & robust here to check for conflicts. # # when checking for conflicts, argparse itself treats an # argument holding its default value as having not been supplied # -- even though these situations merely result in equivalent # argumentation (i.e. the user may have supplied the argument # with its default). nonetheless, we'll do the same. subcommand = getattr(namespace, self.dest) satisfied = self._name_satisfies_map[subcommand] resolver = getattr(namespace, self._resolver) for removed_group in resolver(*satisfied): actions = removed_group._group_actions if removed_group else () for action in actions: if (action.default is not argparse.SUPPRESS and getattr( namespace, action.dest) is not action.default): action_name = argparse._get_action_name(action) raise argparse.ArgumentError( None, f'argument {subcommand}: ' f'not allowed with argument {action_name}') action.required = False
def take_action(action, argument_strings, option_string=None): seen_actions.add(action) argument_values = self._get_values(action, argument_strings) # error if this argument is not allowed with other previously # seen arguments, assuming that actions that use the default # value don't really count as "present" if argument_values is not action.default: seen_non_default_actions.add(action) for conflict_action in action_conflicts.get(action, []): if conflict_action in seen_non_default_actions: msg = _('not allowed with argument %s') action_name = _get_action_name(conflict_action) raise ArgumentError(action, msg % action_name) # take the action if we didn't receive a SUPPRESS value # (e.g. from a default) if argument_values is not SUPPRESS: action(self, namespace, argument_values, option_string)
def take_action(action, argument_strings, option_string=None): seen_actions.add(action) argument_values = self._get_values(action, argument_strings) # error if this argument is not allowed with other previously # seen arguments, assuming that actions that use the default # value don't really count as "present" if argument_values is not action.default: seen_non_default_actions.add(action) for conflict_action in action_conflicts.get(action, []): if conflict_action in seen_non_default_actions: msg = _("not allowed with argument %s") action_name = _get_action_name(conflict_action) raise ArgumentError(action, msg % action_name) # take the action if we didn't receive a SUPPRESS value # (e.g. from a default) # argcomplete: we should walk through sub-commands. if argument_values is not SUPPRESS or isinstance(action, _SubParsersAction): action(self, namespace, argument_values, option_string)
def update_event(self, inp=-1): self.set_output_val(0, argparse._get_action_name(self.input(0)))
def _find_action_from_parser(self, parser, *option): s = "/".join(option) for action in parser._actions: if "--access-token" == argparse._get_action_name(action): return action return None
def _parse_known_args(self, arg_strings, namespace): self.active_actions = [] # Added by argcomplete # replace arg strings that are file references if self.fromfile_prefix_chars is not None: arg_strings = self._read_args_from_files(arg_strings) # map all mutually exclusive arguments to the other arguments # they can't occur with action_conflicts = {} for mutex_group in self._mutually_exclusive_groups: group_actions = mutex_group._group_actions for i, mutex_action in enumerate(mutex_group._group_actions): conflicts = action_conflicts.setdefault(mutex_action, []) conflicts.extend(group_actions[:i]) conflicts.extend(group_actions[i + 1:]) # find all option indices, and determine the arg_string_pattern # which has an 'O' if there is an option at an index, # an 'A' if there is an argument, or a '-' if there is a '--' option_string_indices = {} arg_string_pattern_parts = [] arg_strings_iter = iter(arg_strings) for i, arg_string in enumerate(arg_strings_iter): # all args after -- are non-options if arg_string == '--': arg_string_pattern_parts.append('-') for arg_string in arg_strings_iter: arg_string_pattern_parts.append('A') # otherwise, add the arg to the arg strings # and note the index if it was an option else: option_tuple = self._parse_optional(arg_string) if option_tuple is None: pattern = 'A' else: option_string_indices[i] = option_tuple pattern = 'O' arg_string_pattern_parts.append(pattern) # join the pieces together to form the pattern arg_strings_pattern = ''.join(arg_string_pattern_parts) # converts arg strings to the appropriate and then takes the action seen_actions = set() seen_non_default_actions = set() def take_action(action, argument_strings, option_string=None): seen_actions.add(action) argument_values = self._get_values(action, argument_strings) # error if this argument is not allowed with other previously # seen arguments, assuming that actions that use the default # value don't really count as "present" if argument_values is not action.default: seen_non_default_actions.add(action) for conflict_action in action_conflicts.get(action, []): if conflict_action in seen_non_default_actions: msg = _('not allowed with argument %s') action_name = _get_action_name(conflict_action) raise ArgumentError(action, msg % action_name) # take the action if we didn't receive a SUPPRESS value # (e.g. from a default) if argument_values is not SUPPRESS: action(self, namespace, argument_values, option_string) # function to convert arg_strings into an optional action def consume_optional(start_index): # get the optional identified at this index option_tuple = option_string_indices[start_index] action, option_string, explicit_arg = option_tuple # identify additional optionals in the same arg string # (e.g. -xyz is the same as -x -y -z if no args are required) match_argument = self._match_argument action_tuples = [] while True: # if we found no optional action, skip it if action is None: extras.append(arg_strings[start_index]) return start_index + 1 # if there is an explicit argument, try to match the # optional's string arguments to only this if explicit_arg is not None: arg_count = match_argument(action, 'A') # if the action is a single-dash option and takes no # arguments, try to parse more single-dash options out # of the tail of the option string chars = self.prefix_chars if arg_count == 0 and option_string[1] not in chars: action_tuples.append((action, [], option_string)) char = option_string[0] option_string = char + explicit_arg[0] new_explicit_arg = explicit_arg[1:] or None optionals_map = self._option_string_actions if option_string in optionals_map: action = optionals_map[option_string] explicit_arg = new_explicit_arg else: msg = _('ignored explicit argument %r') raise ArgumentError(action, msg % explicit_arg) # if the action expect exactly one argument, we've # successfully matched the option; exit the loop elif arg_count == 1: stop = start_index + 1 args = [explicit_arg] action_tuples.append((action, args, option_string)) break # error if a double-dash option did not use the # explicit argument else: msg = _('ignored explicit argument %r') raise ArgumentError(action, msg % explicit_arg) # if there is no explicit argument, try to match the # optional's string arguments with the following strings # if successful, exit the loop else: start = start_index + 1 selected_patterns = arg_strings_pattern[start:] self.active_actions = [action] # Added by argcomplete action.num_consumed_args = 0 # Added by argcomplete arg_count = match_argument(action, selected_patterns) stop = start + arg_count args = arg_strings[start:stop] # Begin added by argcomplete # If the pattern is not open (e.g. no + at the end), remove the action from active actions (since # it wouldn't be able to consume any more args) if not action_is_open(action): self.active_actions.remove(action) elif action.nargs == OPTIONAL and len(args) == 1: self.active_actions.remove(action) action.num_consumed_args = len(args) # End added by argcomplete action_tuples.append((action, args, option_string)) break # add the Optional to the list and return the index at which # the Optional's string args stopped assert action_tuples for action, args, option_string in action_tuples: take_action(action, args, option_string) return stop # the list of Positionals left to be parsed; this is modified # by consume_positionals() positionals = self._get_positional_actions() # function to convert arg_strings into positional actions def consume_positionals(start_index): # match as many Positionals as possible match_partial = self._match_arguments_partial selected_pattern = arg_strings_pattern[start_index:] arg_counts = match_partial(positionals, selected_pattern) # slice off the appropriate arg strings for each Positional # and add the Positional and its args to the list for action, arg_count in zip(positionals, arg_counts): if arg_count > 0: # Added by argcomplete self.active_actions = [action] # Added by argcomplete else: # Added by argcomplete self.active_actions.append(action) # Added by argcomplete args = arg_strings[start_index: start_index + arg_count] start_index += arg_count action.num_consumed_args = len(args) take_action(action, args) # slice off the Positionals that we just parsed and return the # index at which the Positionals' string args stopped positionals[:] = positionals[len(arg_counts):] return start_index # consume Positionals and Optionals alternately, until we have # passed the last option string extras = [] start_index = 0 if option_string_indices: max_option_string_index = max(option_string_indices) else: max_option_string_index = -1 while start_index <= max_option_string_index: # consume any Positionals preceding the next option next_option_string_index = min([ index for index in option_string_indices if index >= start_index]) if start_index != next_option_string_index: positionals_end_index = consume_positionals(start_index) # only try to parse the next optional if we didn't consume # the option string during the positionals parsing if positionals_end_index > start_index: start_index = positionals_end_index continue else: start_index = positionals_end_index # if we consumed all the positionals we could and we're not # at the index of an option string, there were extra arguments if start_index not in option_string_indices: strings = arg_strings[start_index:next_option_string_index] extras.extend(strings) start_index = next_option_string_index # consume the next optional and any arguments for it start_index = consume_optional(start_index) # consume any positionals following the last Optional stop_index = consume_positionals(start_index) # if we didn't consume all the argument strings, there were extras extras.extend(arg_strings[stop_index:]) # if we didn't use all the Positional objects, there were too few # arg strings supplied. if positionals: self.active_actions.append(positionals[0]) # Added by argcomplete self.error(_('too few arguments')) # make sure all required actions were present for action in self._actions: if action.required: if action not in seen_actions: name = _get_action_name(action) self.error(_('argument %s is required') % name) # make sure all required groups had one option present for group in self._mutually_exclusive_groups: if group.required: for action in group._group_actions: if action in seen_non_default_actions: break # if no actions were used, report the error else: names = [_get_action_name(action) for action in group._group_actions if action.help is not SUPPRESS] msg = _('one of the arguments %s is required') self.error(msg % ' '.join(names)) # return the updated namespace and the extra arguments return namespace, extras
def _parse_known_args(self, arg_strings, namespace): self.active_actions = [] # Added by argcomplete # replace arg strings that are file references if self.fromfile_prefix_chars is not None: arg_strings = self._read_args_from_files(arg_strings) # map all mutually exclusive arguments to the other arguments # they can't occur with action_conflicts = {} for mutex_group in self._mutually_exclusive_groups: group_actions = mutex_group._group_actions for i, mutex_action in enumerate(mutex_group._group_actions): conflicts = action_conflicts.setdefault(mutex_action, []) conflicts.extend(group_actions[:i]) conflicts.extend(group_actions[i + 1:]) # find all option indices, and determine the arg_string_pattern # which has an 'O' if there is an option at an index, # an 'A' if there is an argument, or a '-' if there is a '--' option_string_indices = {} arg_string_pattern_parts = [] arg_strings_iter = iter(arg_strings) for i, arg_string in enumerate(arg_strings_iter): # all args after -- are non-options if arg_string == '--': arg_string_pattern_parts.append('-') for arg_string in arg_strings_iter: arg_string_pattern_parts.append('A') # otherwise, add the arg to the arg strings # and note the index if it was an option else: option_tuple = self._parse_optional(arg_string) if option_tuple is None: pattern = 'A' else: option_string_indices[i] = option_tuple pattern = 'O' arg_string_pattern_parts.append(pattern) # join the pieces together to form the pattern arg_strings_pattern = ''.join(arg_string_pattern_parts) # converts arg strings to the appropriate and then takes the action seen_actions = set() seen_non_default_actions = set() def take_action(action, argument_strings, option_string=None): seen_actions.add(action) argument_values = self._get_values(action, argument_strings) # error if this argument is not allowed with other previously # seen arguments, assuming that actions that use the default # value don't really count as "present" if argument_values is not action.default: seen_non_default_actions.add(action) for conflict_action in action_conflicts.get(action, []): if conflict_action in seen_non_default_actions: msg = _('not allowed with argument %s') action_name = _get_action_name(conflict_action) raise ArgumentError(action, msg % action_name) # take the action if we didn't receive a SUPPRESS value # (e.g. from a default) if argument_values is not SUPPRESS: action(self, namespace, argument_values, option_string) # function to convert arg_strings into an optional action def consume_optional(start_index): # get the optional identified at this index option_tuple = option_string_indices[start_index] action, option_string, explicit_arg = option_tuple # identify additional optionals in the same arg string # (e.g. -xyz is the same as -x -y -z if no args are required) match_argument = self._match_argument action_tuples = [] while True: # if we found no optional action, skip it if action is None: extras.append(arg_strings[start_index]) return start_index + 1 # if there is an explicit argument, try to match the # optional's string arguments to only this if explicit_arg is not None: arg_count = match_argument(action, 'A') # if the action is a single-dash option and takes no # arguments, try to parse more single-dash options out # of the tail of the option string chars = self.prefix_chars if arg_count == 0 and option_string[1] not in chars: action_tuples.append((action, [], option_string)) char = option_string[0] option_string = char + explicit_arg[0] new_explicit_arg = explicit_arg[1:] or None optionals_map = self._option_string_actions if option_string in optionals_map: action = optionals_map[option_string] explicit_arg = new_explicit_arg else: msg = _('ignored explicit argument %r') raise ArgumentError(action, msg % explicit_arg) # if the action expect exactly one argument, we've # successfully matched the option; exit the loop elif arg_count == 1: stop = start_index + 1 args = [explicit_arg] action_tuples.append((action, args, option_string)) break # error if a double-dash option did not use the # explicit argument else: msg = _('ignored explicit argument %r') raise ArgumentError(action, msg % explicit_arg) # if there is no explicit argument, try to match the # optional's string arguments with the following strings # if successful, exit the loop else: start = start_index + 1 selected_patterns = arg_strings_pattern[start:] self.active_actions = [action] # Added by argcomplete action.num_consumed_args = 0 # Added by argcomplete arg_count = match_argument(action, selected_patterns) stop = start + arg_count args = arg_strings[start:stop] # Begin added by argcomplete # If the pattern is not open (e.g. no + at the end), remove the action from active actions (since # it wouldn't be able to consume any more args) if action.nargs not in [ ZERO_OR_MORE, ONE_OR_MORE, PARSER, REMAINDER ]: self.active_actions.remove(action) elif action.nargs == OPTIONAL and len(args) == 1: self.active_actions.remove(action) action.num_consumed_args = len(args) # End added by argcomplete action_tuples.append((action, args, option_string)) break # add the Optional to the list and return the index at which # the Optional's string args stopped assert action_tuples for action, args, option_string in action_tuples: take_action(action, args, option_string) return stop # the list of Positionals left to be parsed; this is modified # by consume_positionals() positionals = self._get_positional_actions() # function to convert arg_strings into positional actions def consume_positionals(start_index): # match as many Positionals as possible match_partial = self._match_arguments_partial selected_pattern = arg_strings_pattern[start_index:] arg_counts = match_partial(positionals, selected_pattern) # slice off the appropriate arg strings for each Positional # and add the Positional and its args to the list for action, arg_count in zip(positionals, arg_counts): if arg_count > 0: # Added by argcomplete self.active_actions = [action] # Added by argcomplete else: # Added by argcomplete self.active_actions.append(action) # Added by argcomplete args = arg_strings[start_index:start_index + arg_count] start_index += arg_count take_action(action, args) # slice off the Positionals that we just parsed and return the # index at which the Positionals' string args stopped positionals[:] = positionals[len(arg_counts):] return start_index # consume Positionals and Optionals alternately, until we have # passed the last option string extras = [] start_index = 0 if option_string_indices: max_option_string_index = max(option_string_indices) else: max_option_string_index = -1 while start_index <= max_option_string_index: # consume any Positionals preceding the next option next_option_string_index = min([ index for index in option_string_indices if index >= start_index ]) if start_index != next_option_string_index: positionals_end_index = consume_positionals(start_index) # only try to parse the next optional if we didn't consume # the option string during the positionals parsing if positionals_end_index > start_index: start_index = positionals_end_index continue else: start_index = positionals_end_index # if we consumed all the positionals we could and we're not # at the index of an option string, there were extra arguments if start_index not in option_string_indices: strings = arg_strings[start_index:next_option_string_index] extras.extend(strings) start_index = next_option_string_index # consume the next optional and any arguments for it start_index = consume_optional(start_index) # consume any positionals following the last Optional stop_index = consume_positionals(start_index) # if we didn't consume all the argument strings, there were extras extras.extend(arg_strings[stop_index:]) # if we didn't use all the Positional objects, there were too few # arg strings supplied. if positionals: self.active_actions.append(positionals[0]) # Added by argcomplete self.error(_('too few arguments')) # make sure all required actions were present for action in self._actions: if action.required: if action not in seen_actions: name = _get_action_name(action) self.error(_('argument %s is required') % name) # make sure all required groups had one option present for group in self._mutually_exclusive_groups: if group.required: for action in group._group_actions: if action in seen_non_default_actions: break # if no actions were used, report the error else: names = [ _get_action_name(action) for action in group._group_actions if action.help is not SUPPRESS ] msg = _('one of the arguments %s is required') self.error(msg % ' '.join(names)) # return the updated namespace and the extra arguments return namespace, extras
def _parse_known_args(self, arg_strings, namespace): # map all mutually exclusive arguments to the other arguments # they can't occur with action_conflicts = {} # find all option indices, and determine the arg_string_pattern # which has an 'O' if there is an option at an index, # an 'A' if there is an argument, or a '-' if there is a '--' option_string_indices = {} arg_string_pattern_parts = [] arg_strings_iter = iter(arg_strings) for i, arg_string in enumerate(arg_strings_iter): # all args after -- are non-options if arg_string == '--': arg_string_pattern_parts.append('-') for arg_string in arg_strings_iter: arg_string_pattern_parts.append('A') # otherwise, add the arg to the arg strings # and note the index if it was an option else: option_tuple = self._parse_optional(arg_string) if option_tuple is None: pattern = 'A' else: option_string_indices[i] = option_tuple pattern = 'O' arg_string_pattern_parts.append(pattern) # join the pieces together to form the pattern arg_strings_pattern = ''.join(arg_string_pattern_parts) # converts arg strings to the appropriate and then takes the action seen_actions = set() seen_non_default_actions = set() def take_action(action, argument_strings, option_string=None): seen_actions.add(action) argument_values = self._get_values(action, argument_strings) # error if this argument is not allowed with other previously # seen arguments, assuming that actions that use the default # value don't really count as "present" if argument_values is not action.default: seen_non_default_actions.add(action) # take the action if we didn't receive a SUPPRESS value # (e.g. from a default) if argument_values is not argparse.SUPPRESS: action(self, namespace, argument_values, option_string) # function to convert arg_strings into an optional action def consume_optional(start_index): # get the optional identified at this index option_tuple = option_string_indices[start_index] action, option_string, explicit_arg = option_tuple # identify additional optionals in the same arg string # (e.g. -xyz is the same as -x -y -z if no args are required) match_argument = self._match_argument action_tuples = [] while True: # if we found no optional action, skip it if action is None: extras.append(arg_strings[start_index]) return start_index + 1 # if there is an explicit argument, try to match the # optional's string arguments to only this if explicit_arg is not None: arg_count = match_argument(action, 'A') # if the action is a single-dash option and takes no # arguments, try to parse more single-dash options out # of the tail of the option string chars = self.prefix_chars if arg_count == 0 and option_string[1] not in chars: action_tuples.append((action, [], option_string)) char = option_string[0] option_string = char + explicit_arg[0] new_explicit_arg = explicit_arg[1:] or None optionals_map = self._option_string_actions if option_string in optionals_map: action = optionals_map[option_string] explicit_arg = new_explicit_arg # if the action expect exactly one argument, we've # successfully matched the option; exit the loop elif arg_count == 1: stop = start_index + 1 args = [explicit_arg] action_tuples.append((action, args, option_string)) break # if there is no explicit argument, try to match the # optional's string arguments with the following strings # if successful, exit the loop else: start = start_index + 1 selected_patterns = arg_strings_pattern[start:] arg_count = match_argument(action, selected_patterns) stop = start + arg_count args = arg_strings[start:stop] action_tuples.append((action, args, option_string)) break # add the Optional to the list and return the index at which # the Optional's string args stopped assert action_tuples for action, args, option_string in action_tuples: take_action(action, args, option_string) return stop # the list of Positionals left to be parsed; this is modified # by consume_positionals() positionals = self._get_positional_actions() # function to convert arg_strings into positional actions def consume_positionals(start_index): # match as many Positionals as possible match_partial = self._match_arguments_partial selected_pattern = arg_strings_pattern[start_index:] arg_counts = match_partial(positionals, selected_pattern) # slice off the appropriate arg strings for each Positional # and add the Positional and its args to the list for action, arg_count in zip(positionals, arg_counts): args = arg_strings[start_index:start_index + arg_count] start_index += arg_count take_action(action, args) # slice off the Positionals that we just parsed and return the # index at which the Positionals' string args stopped positionals[:] = positionals[len(arg_counts):] return start_index # consume Positionals and Optionals alternately, until we have # passed the last option string extras = [] start_index = 0 if option_string_indices: max_option_string_index = max(option_string_indices) else: max_option_string_index = -1 while start_index <= max_option_string_index: # consume any Positionals preceding the next option next_option_string_index = min([ index for index in option_string_indices if index >= start_index ]) if start_index != next_option_string_index: positionals_end_index = consume_positionals(start_index) # only try to parse the next optional if we didn't consume # the option string during the positionals parsing if positionals_end_index > start_index: start_index = positionals_end_index continue else: start_index = positionals_end_index # if we consumed all the positionals we could and we're not # at the index of an option string, there were extra arguments if start_index not in option_string_indices: strings = arg_strings[start_index:next_option_string_index] extras.extend(strings) start_index = next_option_string_index # consume the next optional and any arguments for it start_index = consume_optional(start_index) # consume any positionals following the last Optional stop_index = consume_positionals(start_index) # if we didn't consume all the argument strings, there were extras extras.extend(arg_strings[stop_index:]) # make sure all required actions were present and also convert # action defaults which were not given as arguments required_actions = [] for action in self._actions: if action not in seen_actions: if action.required: required_actions.append(argparse._get_action_name(action)) else: # Convert action default now instead of doing it before # parsing arguments to avoid calling convert functions # twice (which may fail) if the argument was given, but # only if it was defined already in the namespace if (action.default is not None and isinstance(action.default, str) and hasattr(namespace, action.dest) and action.default is getattr(namespace, action.dest)): setattr(namespace, action.dest, self._get_value(action, action.default)) # make sure all required groups had one option present for group in self._mutually_exclusive_groups: if group.required: for action in group._group_actions: if action in seen_non_default_actions: break # return the updated namespace and the extra arguments return namespace, extras
def main(): # Configuring log logging.basicConfig(level=logging.INFO, format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p') # Configuring bot parameters logging.info("Configurando parâmetros") parser = argparse.ArgumentParser(description='Bot do GDG Aracaju') parser.add_argument('-t', '--telegram_token', help='Token da API do Telegram', required=True) parser.add_argument('-m', '--meetup_key', help='Key da API do Meetup', required=True) parser.add_argument('-g', '--group_name', help='Grupo do Meetup', required=True) parser.add_argument('--url_shortener_key', help='Key da API do URL Shortener') parser.add_argument('-d', '--dev', help='Indicador de Debug/Dev mode', action='store_true') parser.add_argument('--no-dev', help=argparse.SUPPRESS, dest='dev', action='store_false') # Get required arguments to check after parsed required_actions = [] for action in parser._actions: if action.required: required_actions.append(action) action.required = False # Parse command line args namespace = parser.parse_args() # Mounting config _config = { k: v or os.environ.get(k.upper(), '') for k, v in vars(namespace).items() } # Verifying required arguments missing_args = [ argparse._get_action_name(a) for a in required_actions if not _config[a.dest] ] if missing_args: parser.error("missing arguments: " + ", ".join(missing_args)) # Starting bot logging.info("Iniciando bot") bot = telebot.TeleBot(_config['telegram_token']) if _config["dev"]: logging.info("Dev mode activated.") logging.info("Usando @%s", bot.get_me().username) logging.info("Usando telegram_token=%(telegram_token)s", _config) logging.info("Usando meetup_key=%(meetup_key)s", _config) resources = Resources(_config) gdgbot = GDGAjuBot(bot, resources, _config) gdgbot.start()
def main(): parser = argparse.ArgumentParser( description='Set QEMU thread affinity', formatter_class=argparse.RawDescriptionHelpFormatter, epilog=""" THREAD_AFFINITY can be one of: <affinity-spec> <selector>:<affinity-spec> Where <affinity-spec> is: a CPU number, a range (inclusive) of CPU numbers separated by a dash (-), or a comma-delimited (,) list of CPU numbers or ranges. for example: 0\t\tspecifies CPU 0 0,1,2,3\t\tspecifies CPU 0, 1, 2 and 3 0-3\t\tsame as above 0,2-4,6\t\tspecifies CPU 0, 2, 3, 4 and 6 Where <selector> is: *\t\t\tall threads (for -k, -i, -w, -t) <partial-name>\t\tfor -k ('CPU <partial-name>/KVM') \t\tand -i ('IO <partial-name>') <name>\t\t\tfor -t The first variant selects threads based on argument position. e.g., -k 0,4 1,5 2,6 3,7 pins the first KVM thread to CPUs 0 and 4, the second KVM thread to CPUs 1 and 5, and so on. The second variant selects threads by <selector>, which is a partial name or wildcard. KVM threads have numeric names ('0', '1', '2', etc). IO threads have user-supplied names (`-object iothread,id=<name>`). e.g., -k 2:2,6 -i myiothread:7 *:0 pins KVM thread 2 to CPUs 2 and 6, IO thread 'myiothread' to CPU 7, and all remaining IO threads to CPU 0. The two variants can be combined. e.g., -k 0,4 *:2,6 pins the first KVM thread to CPUs 0 and 4, and all remaining KVM threads to CPUs 2 and 6. """) parser.add_argument('qemu_proc', type=qemu_proc, metavar='[--] qemu-system-pid', help='PID of the qemu-system process') parser.add_argument( '--dry-run', action='store_true', help='don\'t modify thread affinity values (useful with -v)') parser.add_argument( '-v', '--verbose', action='store_true', help= 'be verbose (always output current thread affinity values and modifications)' ) parser.add_argument( '-p', '--process-affinity', nargs='?', type=affinity, metavar='AFFINITY', help= 'set \'qemu-system\' process affinity (and default for new threads)') parser.add_argument( '-q', '--qemu-affinity', nargs='+', action=ThreadAffinityAction, type=ThreadAffinityType(allow_thread_names=False), metavar='AFFINITY', help= 'set \'qemu-system\' thread affinity (partial name selectors not allowed)' ) parser.add_argument('-k', '--kvm-affinity', nargs='+', action=ThreadAffinityAction, type=ThreadAffinityType(), metavar='THREAD_AFFINITY', help='set KVM (\'CPU <n>/KVM\') thread affinity') parser.add_argument('-i', '--io-affinity', nargs='+', action=ThreadAffinityAction, type=ThreadAffinityType(), metavar='THREAD_AFFINITY', help='set IO object (\'IO <name>\') thread affinity') parser.add_argument( '-w', '--worker-affinity', nargs='+', action=ThreadAffinityAction, type=ThreadAffinityType(allow_thread_names=False), metavar='THREAD_AFFINITY', help= 'set qemu worker (\'worker\') thread affinity (partial name selectors not allowed)' ) parser.add_argument('-t', '--thread-affinity', nargs='+', action=ThreadAffinityAction, type=ThreadAffinityType(), metavar='THREAD_AFFINITY', help='set arbitary (\'<name>\') thread affinity') def get_argument(name): # yuck, why isn't this public return parser._option_string_actions[name] args = parser.parse_args() def cores_affinityspec(cores): # [(k, [(0, x), (1, y) (2, z)]), (j, [(0, a), (1, b) (2, c)])] spec_groups = itertools.groupby(enumerate(cores), lambda e: e[0] - e[1]) spec_groups = [list(map(itemgetter(1), g)) for k, g in spec_groups] spec_groups = ','.join([ '%s-%s' % (g[0], g[-1]) if len(g) > 1 else str(g[0]) for g in spec_groups ]) return spec_groups classes = [ # [argument, thread name regex, thread name format] ['--qemu-affinity', re.compile('^qemu-system-.*$'), None], [ '--kvm-affinity', re.compile('^CPU (?P<name>\d+)/KVM$'), 'CPU %s/KVM' ], ['--io-affinity', re.compile('^IO (?P<name>.+)$'), 'IO %s'], ['--worker-affinity', re.compile('^worker$'), None], ['--thread-affinity', re.compile('^(?P<name>.+)$'), '%s'] ] thread_affinities = OrderedDict() if args.process_affinity is not None: thread_affinities[args.qemu_proc.main_thread] = args.process_affinity for (arg, thread_name_re, thread_name_fmt) in classes: arg = get_argument(arg) affinities = vars(args)[arg.dest] if affinities is None: continue spec_count = len(affinities) # [thread] -> [(thread, match)] threads = map(lambda t: (t, thread_name_re.match(t.name)), args.qemu_proc.threads.values()) threads = filter(lambda v: v[1] is not None, threads) for (i, (thread, match)) in enumerate(threads): default_affinity = affinities.get(ALL_THREADS) positional_affinity = affinities.pop(PositionalThreadSelector(i), None) named_affinity = affinities.pop(match.groupdict().get('name'), None) aff = named_affinity or positional_affinity or default_affinity if aff is None: continue thread_affinities[thread] = aff affinities.pop(ALL_THREADS, None) if len(affinities) != 0: selector = affinities.popitem()[0] if isinstance(selector, PositionalThreadSelector): parser.error( 'argument %s: too many positional affinity specifications (%d threads, %d provided).' % (argparse._get_action_name(arg), len(threads), spec_count)) tname = thread_name_fmt % selector parser.error('argument %s: thread id {%s} not found.' % (argparse._get_action_name(arg), tname)) if len(thread_affinities) == 0 or args.verbose: print('%s(%d) threads:' % (args.qemu_proc.exe.name, args.qemu_proc.pid)) for thread in args.qemu_proc.threads.values(): print('\t{%s}(%d): %s' % (thread.name, thread.tid, cores_affinityspec(os.sched_getaffinity(thread.tid)))) if len(thread_affinities) == 0: parser.exit(-1) if args.verbose or args.dry_run: print('%s %s(%d) thread affinities to:' % ('Would set' if args.dry_run else 'Setting', args.qemu_proc.exe.name, args.qemu_proc.pid)) for (thread, aff) in thread_affinities.items(): print('\t{%s}(%d): %s' % (thread.name, thread.tid, cores_affinityspec(aff))) if args.dry_run: exit(-1) for (thread, aff) in thread_affinities.items(): os.sched_setaffinity(thread.tid, aff)
def _aname(action) -> str: """Converts argument name to string to be consistent with argparse.""" return argparse._get_action_name(action)