class_docstr: Provide an opt-producer and CLI argument parser.
  
  Pseudo-extension of ``argparse`` which sets a number of parameters
  for the ParlAI framework. More options can be added specific to other
  modules by passing this object and calling ``add_arg()`` or
  ``add_argument()`` on it.
  
  For an example, see ``parlai.core.dict.DictionaryAgent.add_cmdline_args``.
  
  :param add_parlai_args:
      (default True) initializes the default arguments for ParlAI
      package, including the data download paths and task arguments.
  :param add_model_args:
      (default False) initializes the default arguments for loading
      models, including initializing arguments from that model.
class_docstr_tok: ["Provide","an","opt-producer","and","CLI","argument","parser",".","Pseudo-extension","of","``","argparse","``","which","sets","a","number","of","parameters","for","the","ParlAI","framework",".","More","options","can","be","added","specific","to","other","modules","by","passing","this","object","and","calling","``","add_arg","(",")","``","or","``","add_argument","(",")","``","on","it",".","For","an","example",",","see","``","parlai.core.dict.DictionaryAgent.add_cmdline_args","``",".",":","param","add_parlai_args",":","(","default","True",")","initializes","the","default","arguments","for","ParlAI","package",",","including","the","data","download","paths","and","task","arguments",".",":","param","add_model_args",":","(","default","False",")","initializes","the","default","arguments","for","loading","models",",","including","initializing","arguments","from","that","model","."]
docstr: Attempt to map from python-code kwargs into CLI args.
  
  e.g. model_file -> --model-file.
  
  Works with short options too, like t="convai2".
docstr_tok: ["Attempt","to","map","from","python-code","kwargs","into","CLI","args",".","e.g",".","model_file","-",">","--","model-file",".","Works","with","short","options","too",",","like","t=","''","convai2","''","."]
code: def _kwargs_to_str_args(self, **kwargs):
      """
      Attempt to map from python-code kwargs into CLI args.
  
      e.g. model_file -> --model-file.
  
      Works with short options too, like t="convai2".
      """
  
      # we have to do this large block of repetitive code twice, the first
      # round is basically just to become aware of anything that would have
      # been added by add_extra_args
      kwname_to_action = {}
      for action in self._actions:
          if action.dest == "help":
              # no help allowed
              continue
          for option_string in action.option_strings:
              kwname = option_string.lstrip("-").replace("-", "_")
              assert (kwname not in kwname_to_action) or (
                  kwname_to_action[kwname] is action
              ), f"No duplicate names! ({kwname}, {kwname_to_action[kwname]}, {action})"
              kwname_to_action[kwname] = action
  
      # since we can have options that depend on options, repeat until convergence
      string_args = []
      unparsed_args = set(kwargs.keys())
      while unparsed_args:
          string_args = []
          for kwname, value in kwargs.items():
              if kwname not in kwname_to_action:
                  # best guess, we need to delay it. hopefully this gets added
                  # during add_kw_Args
                  continue
              action = kwname_to_action[kwname]
              last_option_string = action.option_strings[-1]
              if isinstance(action, argparse._StoreTrueAction):
                  if bool(value):
                      string_args.append(last_option_string)
              elif (
                  isinstance(action, argparse._StoreAction)
                  and action.nargs is None
              ):
                  string_args.append(last_option_string)
                  string_args.append(self._value2argstr(value))
              elif (
                  isinstance(action, argparse._StoreAction)
                  and action.nargs in "*+"
              ):
                  string_args.append(last_option_string)
                  string_args.extend(
                      [self._value2argstr(v) for v in value]
                  )
              else:
                  raise TypeError(
                      f"Don't know what to do with {action}"
                  )
  
          # become aware of any extra args that might be specified if the user
          # provides something like model="transformer/generator".
          self.add_extra_args(string_args)
  
          # do it again, this time knowing about ALL args.
          kwname_to_action = {}
          for action in self._actions:
              if action.dest == "help":
                  # no help allowed
                  continue
              for option_string in action.option_strings:
                  kwname = option_string.lstrip("-").replace("-", "_")
                  assert (kwname not in kwname_to_action) or (
                      kwname_to_action[kwname] is action
                  ), f"No duplicate names! ({kwname}, {kwname_to_action[kwname]}, {action})"
                  kwname_to_action[kwname] = action
  
          new_unparsed_args = set()
          string_args = []
          for kwname, value in kwargs.items():
              if kwname not in kwname_to_action:
                  new_unparsed_args.add(kwname)
                  continue
  
              action = kwname_to_action[kwname]
              last_option_string = action.option_strings[-1]
              if isinstance(action, argparse._StoreTrueAction):
                  if bool(value):
                      string_args.append(last_option_string)
              elif (
                  isinstance(action, argparse._StoreAction)
                  and action.nargs is None
              ):
                  string_args.append(last_option_string)
                  string_args.append(self._value2argstr(value))
              elif (
                  isinstance(action, argparse._StoreAction)
                  and action.nargs in "*+"
              ):
                  string_args.append(last_option_string)
                  # Special case: Labels
                  string_args.extend(
                      [self._value2argstr(v) for v in value]
                  )
              else:
                  raise TypeError(
                      f"Don't know what to do with {action}"
                  )
  
          if new_unparsed_args == unparsed_args:
              # if we have converged to a fixed point with no improvements, we
              # truly found some unreachable args
              raise KeyError(
                  f'Failed to parse one or more kwargs: {", ".join(new_unparsed_args)}'
              )
          else:
              # We've seen some improvements on the number of unparsed args,
              # iterate again
              unparsed_args = new_unparsed_args
  
      return string_args
  
imports: import argparse
  import importlib
  import os
  import sys
  import datetime
  import parlai
  import parlai.utils.logging
  from parlai.core.build_data import modelzoo_path
  from parlai.core.loader import load_teacher_module, load_agent_module, load_world_module
  from parlai.tasks.tasks import ids_to_tasks
  from parlai.core.opt import Opt
  from parlai.utils.io import PathManager
  from typing import List, Optional
label_desc: Use image node_id 24 for calling the ParlaiParser obj's underlying member method code with example usage: obj._kwargs_to_str_args() and returns: string_args