nodes: 0, module; 1, function_definition; 2, function_name:sort; 3, parameters; 4, block; 5, identifier:self; 6, expression_statement; 7, if_statement; 8, function_definition; 9, expression_statement; 10, expression_statement; 11, comment:"""Sort variants from most correct to consume, to least.
  
          Sort rules:
  
          version_priority:
          - sort by highest versions of packages shared with request;
          - THEN least number of additional packages added to solve;
          - THEN highest versions of additional packages;
          - THEN alphabetical on name of additional packages;
          - THEN variant index.
  
          intersection_priority:
          - sort by highest number of packages shared with request;
          - THEN sort according to version_priority
  
          Note:
              In theory 'variant.index' should never factor into the sort unless
              two variants are identical (which shouldn't happen) - this is just
              here as a safety measure so that sorting is guaranteed repeatable
              regardless.
          """; 12, attribute; 13, block; 14, function_name:key; 15, parameters; 16, block; 17, call; 18, assignment; 19, identifier:self; 20, identifier:sorted; 21, return_statement; 22, identifier:variant; 23, expression_statement; 24, expression_statement; 25, for_statement; 26, expression_statement; 27, for_statement; 28, if_statement; 29, return_statement; 30, attribute; 31, argument_list; 32, attribute; 33, True; 34, assignment; 35, assignment; 36, pattern_list; 37, call; 38, block; 39, assignment; 40, identifier:request; 41, attribute; 42, block; 43, parenthesized_expression; 44, block; 45, else_clause; 46, identifier:k; 47, attribute; 48, identifier:sort; 49, keyword_argument; 50, keyword_argument; 51, identifier:self; 52, identifier:sorted; 53, identifier:requested_key; 54, list; 55, identifier:names; 56, call; 57, identifier:i; 58, identifier:request; 59, identifier:enumerate; 60, argument_list; 61, if_statement; 62, identifier:additional_key; 63, list; 64, identifier:variant; 65, identifier:requires_list; 66, if_statement; 67, comparison_operator:VariantSelectMode[config.variant_select_mode] ==
                      VariantSelectMode.version_priority; 68, expression_statement; 69, comment:# VariantSelectMode.intersection_priority; 70, block; 71, identifier:self; 72, identifier:variants; 73, identifier:key; 74, identifier:key; 75, identifier:reverse; 76, True; 77, identifier:set; 78, argument_list; 79, attribute; 80, not_operator; 81, block; 82, boolean_operator; 83, block; 84, subscript; 85, attribute; 86, assignment; 87, expression_statement; 88, attribute; 89, identifier:request_list; 90, attribute; 91, expression_statement; 92, if_statement; 93, not_operator; 94, comparison_operator:request.name not in names; 95, expression_statement; 96, identifier:VariantSelectMode; 97, attribute; 98, identifier:VariantSelectMode; 99, identifier:version_priority; 100, identifier:k; 101, tuple; 102, assignment; 103, identifier:self; 104, identifier:solver; 105, identifier:request; 106, identifier:conflict; 107, assignment; 108, comparison_operator:req is not None; 109, block; 110, attribute; 111, attribute; 112, identifier:names; 113, call; 114, identifier:config; 115, identifier:variant_select_mode; 116, identifier:requested_key; 117, unary_operator; 118, identifier:additional_key; 119, attribute; 120, identifier:k; 121, tuple; 122, identifier:req; 123, call; 124, identifier:req; 125, None; 126, expression_statement; 127, expression_statement; 128, identifier:request; 129, identifier:conflict; 130, identifier:request; 131, identifier:name; 132, attribute; 133, argument_list; 134, call; 135, identifier:variant; 136, identifier:index; 137, call; 138, identifier:requested_key; 139, unary_operator; 140, identifier:additional_key; 141, attribute; 142, attribute; 143, argument_list; 144, call; 145, call; 146, identifier:additional_key; 147, identifier:append; 148, tuple; 149, identifier:len; 150, argument_list; 151, identifier:len; 152, argument_list; 153, call; 154, identifier:variant; 155, identifier:index; 156, attribute; 157, identifier:get; 158, attribute; 159, attribute; 160, argument_list; 161, attribute; 162, argument_list; 163, attribute; 164, attribute; 165, identifier:additional_key; 166, identifier:requested_key; 167, identifier:len; 168, argument_list; 169, identifier:variant; 170, identifier:requires_list; 171, identifier:request; 172, identifier:name; 173, identifier:requested_key; 174, identifier:append; 175, tuple; 176, identifier:names; 177, identifier:add; 178, attribute; 179, identifier:request; 180, identifier:range; 181, identifier:request; 182, identifier:name; 183, identifier:additional_key; 184, unary_operator; 185, attribute; 186, identifier:req; 187, identifier:name; 188, identifier:i; 189, identifier:req; 190, identifier:range
code: def sort(self):
          """Sort variants from most correct to consume, to least.
  
          Sort rules:
  
          version_priority:
          - sort by highest versions of packages shared with request;
          - THEN least number of additional packages added to solve;
          - THEN highest versions of additional packages;
          - THEN alphabetical on name of additional packages;
          - THEN variant index.
  
          intersection_priority:
          - sort by highest number of packages shared with request;
          - THEN sort according to version_priority
  
          Note:
              In theory 'variant.index' should never factor into the sort unless
              two variants are identical (which shouldn't happen) - this is just
              here as a safety measure so that sorting is guaranteed repeatable
              regardless.
          """
          if self.sorted:
              return
  
          def key(variant):
              requested_key = []
              names = set()
  
              for i, request in enumerate(self.solver.request_list):
                  if not request.conflict:
                      req = variant.requires_list.get(request.name)
                      if req is not None:
                          requested_key.append((-i, req.range))
                          names.add(req.name)
  
              additional_key = []
              for request in variant.requires_list:
                  if not request.conflict and request.name not in names:
                      additional_key.append((request.range, request.name))
  
              if (VariantSelectMode[config.variant_select_mode] ==
                      VariantSelectMode.version_priority):
                  k = (requested_key,
                       -len(additional_key),
                       additional_key,
                       variant.index)
              else:  # VariantSelectMode.intersection_priority
                  k = (len(requested_key),
                       requested_key,
                       -len(additional_key),
                       additional_key,
                       variant.index)
  
              return k
  
          self.variants.sort(key=key, reverse=True)
          self.sorted = True