nodes: 0, module; 1, function_definition; 2, function_name:parse_int_string; 3, parameters; 4, type; 5, block; 6, typed_parameter; 7, generic_type; 8, expression_statement; 9, expression_statement; 10, expression_statement; 11, expression_statement; 12, expression_statement; 13, expression_statement; 14, for_statement; 15, return_statement; 16, identifier:int_string; 17, type; 18, identifier:List; 19, type_parameter; 20, comment:"""
      Given a string like "1 23 4-8 32 1", return a unique list of those integers in the string and
      the integers in the ranges in the string.
      Non-numbers ignored. Not necessarily sorted
      """; 21, assignment; 22, assignment; 23, assignment; 24, assignment; 25, assignment; 26, identifier:token; 27, identifier:tokens; 28, block; 29, call; 30, identifier:str; 31, type; 32, identifier:cleaned; 33, call; 34, identifier:cleaned; 35, call; 36, identifier:cleaned; 37, call; 38, identifier:tokens; 39, call; 40, identifier:indices; 41, type; 42, call; 43, if_statement; 44, identifier:list; 45, argument_list; 46, identifier:int; 47, attribute; 48, argument_list; 49, attribute; 50, argument_list; 51, attribute; 52, argument_list; 53, attribute; 54, argument_list; 55, generic_type; 56, identifier:set; 57, argument_list; 58, comparison_operator:"-" in token; 59, block; 60, else_clause; 61, identifier:indices; 62, string:" "; 63, identifier:join; 64, call; 65, identifier:cleaned; 66, identifier:replace; 67, string:" - "; 68, string:"-"; 69, identifier:cleaned; 70, identifier:replace; 71, string:","; 72, string:" "; 73, identifier:cleaned; 74, identifier:split; 75, string:" "; 76, identifier:Set; 77, type_parameter; 78, string:"-"; 79, identifier:token; 80, expression_statement; 81, if_statement; 82, expression_statement; 83, expression_statement; 84, expression_statement; 85, block; 86, attribute; 87, argument_list; 88, type; 89, assignment; 90, comparison_operator:len(endpoints) != 2; 91, block; 92, assignment; 93, assignment; 94, assignment; 95, try_statement; 96, call; 97, identifier:split; 98, identifier:int; 99, identifier:endpoints; 100, call; 101, call; 102, integer:2; 103, expression_statement; 104, continue_statement; 105, identifier:start; 106, call; 107, identifier:end; 108, binary_operator:int(endpoints[1]) + 1; 109, identifier:indices; 110, call; 111, block; 112, except_clause; 113, attribute; 114, argument_list; 115, attribute; 116, argument_list; 117, identifier:len; 118, argument_list; 119, call; 120, identifier:int; 121, argument_list; 122, call; 123, integer:1; 124, attribute; 125, argument_list; 126, expression_statement; 127, identifier:ValueError; 128, block; 129, identifier:int_string; 130, identifier:strip; 131, identifier:token; 132, identifier:split; 133, string:"-"; 134, identifier:endpoints; 135, attribute; 136, argument_list; 137, subscript; 138, identifier:int; 139, argument_list; 140, identifier:indices; 141, identifier:union; 142, identifier:indices; 143, call; 144, call; 145, expression_statement; 146, identifier:LOG; 147, identifier:info; 148, string:f"Dropping '{token}' as invalid - weird range."; 149, identifier:endpoints; 150, integer:0; 151, subscript; 152, identifier:set; 153, argument_list; 154, attribute; 155, argument_list; 156, call; 157, identifier:endpoints; 158, integer:1; 159, call; 160, identifier:indices; 161, identifier:add; 162, call; 163, attribute; 164, argument_list; 165, identifier:range; 166, argument_list; 167, identifier:int; 168, argument_list; 169, identifier:LOG; 170, identifier:info; 171, string:f"Dropping '{token}' as invalid - not an int."; 172, identifier:start; 173, identifier:end; 174, identifier:token
code: def parse_int_string(int_string: str) -> List[int]:
      """
      Given a string like "1 23 4-8 32 1", return a unique list of those integers in the string and
      the integers in the ranges in the string.
      Non-numbers ignored. Not necessarily sorted
      """
      cleaned = " ".join(int_string.strip().split())
      cleaned = cleaned.replace(" - ", "-")
      cleaned = cleaned.replace(",", " ")
  
      tokens = cleaned.split(" ")
      indices: Set[int] = set()
      for token in tokens:
          if "-" in token:
              endpoints = token.split("-")
              if len(endpoints) != 2:
                  LOG.info(f"Dropping '{token}' as invalid - weird range.")
                  continue
  
              start = int(endpoints[0])
              end = int(endpoints[1]) + 1
  
              indices = indices.union(indices, set(range(start, end)))
  
          else:
              try:
                  indices.add(int(token))
              except ValueError:
                  LOG.info(f"Dropping '{token}' as invalid - not an int.")
  
      return list(indices)