def str2dict(strdict, required_keys=None, optional_keys=None):
result = {}<EOL>if strdict:<EOL><INDENT>for kv in strdict.split('<STR_LIT:U+002C>'):<EOL><INDENT>key, sep, value = kv.partition('<STR_LIT:=>')<EOL>if not sep:<EOL><INDENT>msg = _("<STR_LIT>")<EOL>raise argparse.ArgumentTypeError(msg % kv)<EOL><DEDENT>result[key] = value<EOL><DEDENT><DEDENT>valid_keys = set(required_keys or []) | set(optional_keys or [])<EOL>if valid_keys:<EOL><INDENT>invalid_keys = [k for k in result if k not in valid_keys]<EOL>if invalid_keys:<EOL><INDENT>msg = _("<STR_LIT>"<EOL>"<STR_LIT>")<EOL>raise argparse.ArgumentTypeError(<EOL>msg % {'<STR_LIT>': '<STR_LIT:U+002CU+0020>'.join(sorted(invalid_keys)),<EOL>'<STR_LIT>': '<STR_LIT:U+002CU+0020>'.join(sorted(valid_keys))})<EOL><DEDENT><DEDENT>if required_keys:<EOL><INDENT>not_found_keys = [k for k in required_keys if k not in result]<EOL>if not_found_keys:<EOL><INDENT>msg = _("<STR_LIT>")<EOL>raise argparse.ArgumentTypeError(msg % '<STR_LIT:U+002CU+0020>'.join(not_found_keys))<EOL><DEDENT><DEDENT>return result<EOL>
Convert key1=value1,key2=value2,... string into dictionary.

    :param strdict: string in the form of key1=value1,key2=value2
    :param required_keys: list of required keys. All keys in this list must be
                       specified. Otherwise ArgumentTypeError will be raised.
                       If this parameter is unspecified, no required key check
                       will be done.
    :param optional_keys: list of optional keys.
                       This parameter is used for valid key check.
                       When at least one of required_keys and optional_keys,
                       a key must be a member of either of required_keys or
                       optional_keys. Otherwise, ArgumentTypeError will be
                       raised. When both required_keys and optional_keys are
                       unspecified, no valid key check will be done.