def METHOD_NAME(mdstr: str) -> GenericMetadata:
    """The metadata string is a comma separated list of name-value pairs
    The names match the attributes of the internal metadata struct (for now)
    The caret is the special "escape character", since it's not common in
    natural language text
    example = "series=Kickers^, Inc. ,issue=1, year=1986"
    """
    escaped_comma = "^,"
    escaped_equals = "^="
    replacement_token = "<_~_>"
    md = GenericMetadata()
    # First, replace escaped commas with with a unique token (to be changed back later)
    mdstr = mdstr.replace(escaped_comma, replacement_token)
    tmp_list = utils.split(mdstr, ",")
    md_list = []
    for item in tmp_list:
        item = item.replace(replacement_token, ",")
        md_list.append(item)
    # Now build a nice dict from the list
    md_dict = {}
    for item in md_list:
        # Make sure to fix any escaped equal signs
        i = item.replace(escaped_equals, replacement_token)
        key, value = utils.split(i, "=")
        value = value.replace(replacement_token, "=").strip()
        key = key.strip()
        if key.casefold() == "credit":
            cred_attribs = utils.split(value, ":")
            role = cred_attribs[0]
            person = cred_attribs[1] if len(cred_attribs) > 1 else ""
            primary = len(cred_attribs) > 2
            md.add_credit(person.strip(), role.strip(), primary)
        else:
            md_dict[key] = value
    # Map the dict to the metadata object
    for key, value in md_dict.items():
        if not hasattr(md, key):
            raise argparse.ArgumentTypeError(f"'{key}' is not a valid tag name")
        else:
            md.is_empty = False
            setattr(md, key, value)
    return md