nodes: 0, module; 1, function_definition; 2, function_name:build_key; 3, parameters; 4, type; 5, block; 6, identifier:self; 7, generic_type; 8, expression_statement; 9, if_statement; 10, return_statement; 11, identifier:Tuple; 12, type_parameter; 13, comment:"""A Key to sort the rules by weight for building.
  
          The key leads to ordering:
  
           - By routes with defaults first, as these must be evaulated
             for building before ones without.
           - Then the more complex routes (most converted parts).
          """; 14, comparison_operator:self.map is None; 15, block; 16, tuple; 17, type; 18, type; 19, attribute; 20, None; 21, raise_statement; 22, not_operator; 23, unary_operator; 24, identifier:bool; 25, identifier:int; 26, identifier:self; 27, identifier:map; 28, call; 29, call; 30, call; 31, identifier:RuntimeError; 32, argument_list; 33, identifier:bool; 34, argument_list; 35, identifier:sum; 36, generator_expression; 37, string:f"{self!r} is not bound to a Map"; 38, attribute; 39, integer:1; 40, for_in_clause; 41, if_clause; 42, identifier:self; 43, identifier:defaults; 44, identifier:weight; 45, attribute; 46, attribute; 47, identifier:self; 48, identifier:_weights; 49, identifier:weight; 50, identifier:converter
code: def build_key(self) -> Tuple[bool, int]:
          """A Key to sort the rules by weight for building.
  
          The key leads to ordering:
  
           - By routes with defaults first, as these must be evaulated
             for building before ones without.
           - Then the more complex routes (most converted parts).
          """
          if self.map is None:
              raise RuntimeError(f"{self!r} is not bound to a Map")
          return (not bool(self.defaults), -sum(1 for weight in self._weights if weight.converter))