nodes: 0, module; 1, function_definition; 2, function_name:parse_commit_message; 3, parameters; 4, type; 5, block; 6, typed_parameter; 7, generic_type; 8, expression_statement; 9, expression_statement; 10, if_statement; 11, expression_statement; 12, if_statement; 13, if_statement; 14, expression_statement; 15, return_statement; 16, identifier:message; 17, type; 18, identifier:Tuple; 19, type_parameter; 20, comment:"""
      Parses a commit message according to the 1.0 version of python-semantic-release. It expects
      a tag of some sort in the commit message and will use the rest of the first line as changelog
      content.
  
      :param message: A string of a commit message.
      :raises UnknownCommitMessageStyleError: If it does not recognise the commit style
      :return: A tuple of (level to bump, type of change, scope of change, a tuple with descriptions)
      """; 21, assignment; 22, not_operator; 23, block; 24, assignment; 25, comparison_operator:config.get('semantic_release', 'minor_tag') in message; 26, block; 27, elif_clause; 28, else_clause; 29, boolean_operator; 30, block; 31, assignment; 32, expression_list; 33, identifier:str; 34, type; 35, type; 36, type; 37, type; 38, identifier:parsed; 39, call; 40, identifier:parsed; 41, raise_statement; 42, identifier:subject; 43, call; 44, call; 45, identifier:message; 46, expression_statement; 47, expression_statement; 48, if_statement; 49, comparison_operator:config.get('semantic_release', 'fix_tag') in message; 50, block; 51, block; 52, call; 53, comparison_operator:'BREAKING CHANGE' in parsed.group('text'); 54, expression_statement; 55, expression_statement; 56, pattern_list; 57, call; 58, identifier:level_bump; 59, identifier:level; 60, None; 61, tuple; 62, identifier:int; 63, identifier:str; 64, generic_type; 65, generic_type; 66, attribute; 67, argument_list; 68, call; 69, attribute; 70, argument_list; 71, attribute; 72, argument_list; 73, assignment; 74, assignment; 75, identifier:subject; 76, block; 77, call; 78, identifier:message; 79, expression_statement; 80, expression_statement; 81, if_statement; 82, raise_statement; 83, attribute; 84, argument_list; 85, string; 86, call; 87, assignment; 88, assignment; 89, identifier:body; 90, identifier:footer; 91, identifier:parse_text_block; 92, argument_list; 93, call; 94, call; 95, call; 96, identifier:Optional; 97, type_parameter; 98, identifier:Tuple; 99, type_parameter; 100, identifier:re_parser; 101, identifier:match; 102, identifier:message; 103, identifier:UnknownCommitMessageStyleError; 104, argument_list; 105, identifier:parsed; 106, identifier:group; 107, string; 108, identifier:config; 109, identifier:get; 110, string; 111, string; 112, identifier:level; 113, string; 114, identifier:level_bump; 115, integer:2; 116, expression_statement; 117, attribute; 118, argument_list; 119, assignment; 120, assignment; 121, identifier:subject; 122, block; 123, call; 124, identifier:parsed; 125, identifier:group; 126, string; 127, string_content:BREAKING CHANGE; 128, attribute; 129, argument_list; 130, identifier:level; 131, string; 132, identifier:level_bump; 133, integer:3; 134, call; 135, attribute; 136, argument_list; 137, attribute; 138, argument_list; 139, attribute; 140, argument_list; 141, type; 142, type; 143, type; 144, type; 145, call; 146, string_content:subject; 147, string_content:semantic_release; 148, string_content:minor_tag; 149, string_content:feature; 150, assignment; 151, identifier:config; 152, identifier:get; 153, string; 154, string; 155, identifier:level; 156, string; 157, identifier:level_bump; 158, integer:1; 159, expression_statement; 160, identifier:UnknownCommitMessageStyleError; 161, argument_list; 162, string_content:text; 163, identifier:parsed; 164, identifier:group; 165, string; 166, string_content:breaking; 167, attribute; 168, argument_list; 169, identifier:subject; 170, identifier:strip; 171, identifier:body; 172, identifier:strip; 173, identifier:footer; 174, identifier:strip; 175, identifier:str; 176, identifier:str; 177, identifier:str; 178, identifier:str; 179, attribute; 180, argument_list; 181, identifier:subject; 182, call; 183, string_content:semantic_release; 184, string_content:fix_tag; 185, string_content:fix; 186, assignment; 187, call; 188, string_content:text; 189, identifier:parsed; 190, identifier:group; 191, string; 192, string; 193, identifier:format; 194, identifier:message; 195, attribute; 196, argument_list; 197, identifier:subject; 198, call; 199, attribute; 200, argument_list; 201, string_content:text; 202, string_content:Unable to parse the given commit message: {0}; 203, identifier:subject; 204, identifier:replace; 205, call; 206, string; 207, attribute; 208, argument_list; 209, string; 210, identifier:format; 211, identifier:message; 212, attribute; 213, argument_list; 214, identifier:subject; 215, identifier:replace; 216, call; 217, string; 218, string_content:Unable to parse the given commit message: {0}; 219, identifier:config; 220, identifier:get; 221, string; 222, call; 223, attribute; 224, argument_list; 225, string_content:semantic_release; 226, attribute; 227, argument_list; 228, identifier:config; 229, identifier:get; 230, string; 231, call; 232, string; 233, identifier:format; 234, identifier:level; 235, string_content:semantic_release; 236, attribute; 237, argument_list; 238, string_content:minor_tag; 239, string; 240, identifier:format; 241, identifier:level; 242, string_content:fix_tag
code: def parse_commit_message(message: str) -> Tuple[int, str, Optional[str], Tuple[str, str, str]]:
      """
      Parses a commit message according to the 1.0 version of python-semantic-release. It expects
      a tag of some sort in the commit message and will use the rest of the first line as changelog
      content.
  
      :param message: A string of a commit message.
      :raises UnknownCommitMessageStyleError: If it does not recognise the commit style
      :return: A tuple of (level to bump, type of change, scope of change, a tuple with descriptions)
      """
  
      parsed = re_parser.match(message)
  
      if not parsed:
          raise UnknownCommitMessageStyleError(
              'Unable to parse the given commit message: {0}'.format(message)
          )
  
      subject = parsed.group('subject')
  
      if config.get('semantic_release', 'minor_tag') in message:
          level = 'feature'
          level_bump = 2
          if subject:
              subject = subject.replace(config.get('semantic_release', 'minor_tag'.format(level)), '')
  
      elif config.get('semantic_release', 'fix_tag') in message:
          level = 'fix'
          level_bump = 1
          if subject:
              subject = subject.replace(config.get('semantic_release', 'fix_tag'.format(level)), '')
  
      else:
          raise UnknownCommitMessageStyleError(
              'Unable to parse the given commit message: {0}'.format(message)
          )
  
      if parsed.group('text') and 'BREAKING CHANGE' in parsed.group('text'):
          level = 'breaking'
          level_bump = 3
  
      body, footer = parse_text_block(parsed.group('text'))
  
      return level_bump, level, None, (subject.strip(), body.strip(), footer.strip())