nodes: 0, module; 1, function_definition; 2, function_name:get_loc; 3, parameters; 4, block; 5, identifier:self; 6, identifier:key; 7, default_parameter; 8, expression_statement; 9, if_statement; 10, function_definition; 11, if_statement; 12, expression_statement; 13, if_statement; 14, if_statement; 15, comment:# -- partial selection or non-unique index; 16, comment:# break the key into 2 parts based on the lexsort_depth of the index;; 17, comment:# the first part returns a continuous slice of the index; the 2nd part; 18, comment:# needs linear search within the slice; 19, expression_statement; 20, expression_statement; 21, expression_statement; 22, if_statement; 23, if_statement; 24, expression_statement; 25, expression_statement; 26, for_statement; 27, return_statement; 28, identifier:method; 29, None; 30, comment:"""
          Get location for a label or a tuple of labels as an integer, slice or
          boolean mask.
  
          Parameters
          ----------
          key : label or tuple of labels (one for each level)
          method : None
  
          Returns
          -------
          loc : int, slice object or boolean mask
              If the key is past the lexsort depth, the return may be a
              boolean mask array, otherwise it is always a slice or int.
  
          Examples
          ---------
          >>> mi = pd.MultiIndex.from_arrays([list('abb'), list('def')])
  
          >>> mi.get_loc('b')
          slice(1, 3, None)
  
          >>> mi.get_loc(('b', 'e'))
          1
  
          Notes
          ------
          The key cannot be a slice, list of same-level labels, a boolean mask,
          or a sequence of such. If you want to use those, use
          :meth:`MultiIndex.get_locs` instead.
  
          See Also
          --------
          Index.get_loc : The get_loc method for (single-level) index.
          MultiIndex.slice_locs : Get slice location given start label(s) and
                                  end label(s).
          MultiIndex.get_locs : Get location for a label/slice/list/mask or a
                                sequence of such.
          """; 31, comparison_operator:method is not None; 32, block; 33, function_name:_maybe_to_slice; 34, parameters; 35, block; 36, not_operator; 37, block; 38, assignment; 39, comparison_operator:self.nlevels < keylen; 40, block; 41, boolean_operator; 42, block; 43, assignment; 44, assignment; 45, assignment; 46, comparison_operator:start == stop; 47, block; 48, not_operator; 49, block; 50, call; 51, assignment; 52, pattern_list; 53, call; 54, block; 55, parenthesized_expression; 56, identifier:method; 57, None; 58, raise_statement; 59, identifier:loc; 60, expression_statement; 61, if_statement; 62, expression_statement; 63, if_statement; 64, expression_statement; 65, expression_statement; 66, expression_statement; 67, return_statement; 68, call; 69, expression_statement; 70, return_statement; 71, identifier:keylen; 72, call; 73, attribute; 74, identifier:keylen; 75, raise_statement; 76, comparison_operator:keylen == self.nlevels; 77, attribute; 78, return_statement; 79, identifier:i; 80, attribute; 81, pattern_list; 82, expression_list; 83, pattern_list; 84, parenthesized_expression; 85, identifier:start; 86, identifier:stop; 87, raise_statement; 88, identifier:follow_key; 89, return_statement; 90, attribute; 91, argument_list; 92, identifier:loc; 93, call; 94, identifier:i; 95, identifier:k; 96, identifier:enumerate; 97, argument_list; 98, expression_statement; 99, if_statement; 100, if_statement; 101, conditional_expression:_maybe_to_slice(loc) if len(loc) != stop - start else
                  slice(start, stop); 102, call; 103, comment:"""convert integer indexer to boolean mask or slice if possible"""; 104, boolean_operator; 105, block; 106, assignment; 107, call; 108, block; 109, assignment; 110, call; 111, assignment; 112, identifier:mask; 113, identifier:isinstance; 114, argument_list; 115, assignment; 116, call; 117, identifier:len; 118, argument_list; 119, identifier:self; 120, identifier:nlevels; 121, call; 122, identifier:keylen; 123, attribute; 124, identifier:self; 125, identifier:is_unique; 126, call; 127, identifier:self; 128, identifier:lexsort_depth; 129, identifier:lead_key; 130, identifier:follow_key; 131, subscript; 132, subscript; 133, identifier:start; 134, identifier:stop; 135, conditional_expression:self.slice_locs(lead_key, lead_key)
                         if lead_key else (0, len(self)); 136, call; 137, call; 138, identifier:warnings; 139, identifier:warn; 140, string; 141, identifier:PerformanceWarning; 142, keyword_argument; 143, attribute; 144, argument_list; 145, identifier:follow_key; 146, call; 147, assignment; 148, not_operator; 149, block; 150, not_operator; 151, block; 152, call; 153, comparison_operator:len(loc) != stop - start; 154, call; 155, identifier:NotImplementedError; 156, argument_list; 157, not_operator; 158, comparison_operator:loc.dtype != 'int64'; 159, return_statement; 160, identifier:loc; 161, call; 162, identifier:isinstance; 163, argument_list; 164, return_statement; 165, identifier:mask; 166, call; 167, attribute; 168, argument_list; 169, subscript; 170, True; 171, identifier:key; 172, identifier:tuple; 173, identifier:loc; 174, call; 175, identifier:_maybe_to_slice; 176, argument_list; 177, identifier:key; 178, identifier:KeyError; 179, argument_list; 180, identifier:self; 181, identifier:nlevels; 182, attribute; 183, argument_list; 184, identifier:key; 185, slice; 186, identifier:key; 187, slice; 188, call; 189, identifier:lead_key; 190, tuple; 191, identifier:KeyError; 192, argument_list; 193, identifier:slice; 194, argument_list; 195, string_content:indexing past lexsort depth may impact performance.; 196, identifier:stacklevel; 197, integer:10; 198, identifier:np; 199, identifier:arange; 200, identifier:start; 201, identifier:stop; 202, keyword_argument; 203, identifier:len; 204, argument_list; 205, identifier:mask; 206, comparison_operator:self.codes[i][loc] == self.levels[i].get_loc(k); 207, call; 208, expression_statement; 209, call; 210, raise_statement; 211, identifier:_maybe_to_slice; 212, argument_list; 213, call; 214, binary_operator:stop - start; 215, identifier:slice; 216, argument_list; 217, concatenated_string; 218, call; 219, attribute; 220, string; 221, identifier:loc; 222, attribute; 223, argument_list; 224, identifier:loc; 225, identifier:slice; 226, identifier:loc; 227, attribute; 228, argument_list; 229, identifier:mask; 230, identifier:fill; 231, False; 232, identifier:mask; 233, identifier:loc; 234, attribute; 235, argument_list; 236, identifier:loc; 237, call; 238, attribute; 239, identifier:get_loc; 240, identifier:key; 241, identifier:i; 242, identifier:i; 243, attribute; 244, argument_list; 245, integer:0; 246, call; 247, identifier:key; 248, identifier:start; 249, identifier:stop; 250, identifier:dtype; 251, string; 252, identifier:lead_key; 253, subscript; 254, call; 255, attribute; 256, argument_list; 257, assignment; 258, identifier:len; 259, argument_list; 260, call; 261, identifier:loc; 262, identifier:len; 263, argument_list; 264, identifier:stop; 265, identifier:start; 266, identifier:start; 267, identifier:stop; 268, string; 269, string; 270, identifier:isinstance; 271, argument_list; 272, identifier:loc; 273, identifier:dtype; 274, string_content:int64; 275, identifier:lib; 276, identifier:maybe_indices_to_slice; 277, identifier:loc; 278, call; 279, identifier:np; 280, identifier:empty; 281, call; 282, keyword_argument; 283, identifier:self; 284, identifier:_get_level_indexer; 285, identifier:key; 286, keyword_argument; 287, attribute; 288, argument_list; 289, identifier:self; 290, identifier:_engine; 291, identifier:self; 292, identifier:slice_locs; 293, identifier:lead_key; 294, identifier:lead_key; 295, identifier:len; 296, argument_list; 297, string_content:int64; 298, subscript; 299, identifier:loc; 300, attribute; 301, argument_list; 302, identifier:mask; 303, identifier:all; 304, identifier:loc; 305, subscript; 306, identifier:loc; 307, identifier:KeyError; 308, argument_list; 309, identifier:loc; 310, string_content:only the default get_loc method is; 311, string_content:currently supported for MultiIndex; 312, identifier:loc; 313, attribute; 314, identifier:len; 315, argument_list; 316, identifier:len; 317, argument_list; 318, identifier:dtype; 319, string; 320, identifier:level; 321, integer:0; 322, concatenated_string; 323, identifier:format; 324, identifier:keylen; 325, attribute; 326, identifier:self; 327, attribute; 328, identifier:i; 329, subscript; 330, identifier:get_loc; 331, identifier:k; 332, identifier:loc; 333, identifier:mask; 334, identifier:key; 335, identifier:np; 336, identifier:ndarray; 337, identifier:self; 338, identifier:self; 339, string_content:bool; 340, string; 341, string; 342, identifier:self; 343, identifier:nlevels; 344, identifier:self; 345, identifier:codes; 346, attribute; 347, identifier:i; 348, string_content:Key length ({0}) exceeds index depth ({1}); 349, identifier:self; 350, identifier:levels
code: def get_loc(self, key, method=None):
          """
          Get location for a label or a tuple of labels as an integer, slice or
          boolean mask.
  
          Parameters
          ----------
          key : label or tuple of labels (one for each level)
          method : None
  
          Returns
          -------
          loc : int, slice object or boolean mask
              If the key is past the lexsort depth, the return may be a
              boolean mask array, otherwise it is always a slice or int.
  
          Examples
          ---------
          >>> mi = pd.MultiIndex.from_arrays([list('abb'), list('def')])
  
          >>> mi.get_loc('b')
          slice(1, 3, None)
  
          >>> mi.get_loc(('b', 'e'))
          1
  
          Notes
          ------
          The key cannot be a slice, list of same-level labels, a boolean mask,
          or a sequence of such. If you want to use those, use
          :meth:`MultiIndex.get_locs` instead.
  
          See Also
          --------
          Index.get_loc : The get_loc method for (single-level) index.
          MultiIndex.slice_locs : Get slice location given start label(s) and
                                  end label(s).
          MultiIndex.get_locs : Get location for a label/slice/list/mask or a
                                sequence of such.
          """
          if method is not None:
              raise NotImplementedError('only the default get_loc method is '
                                        'currently supported for MultiIndex')
  
          def _maybe_to_slice(loc):
              """convert integer indexer to boolean mask or slice if possible"""
              if not isinstance(loc, np.ndarray) or loc.dtype != 'int64':
                  return loc
  
              loc = lib.maybe_indices_to_slice(loc, len(self))
              if isinstance(loc, slice):
                  return loc
  
              mask = np.empty(len(self), dtype='bool')
              mask.fill(False)
              mask[loc] = True
              return mask
  
          if not isinstance(key, tuple):
              loc = self._get_level_indexer(key, level=0)
              return _maybe_to_slice(loc)
  
          keylen = len(key)
          if self.nlevels < keylen:
              raise KeyError('Key length ({0}) exceeds index depth ({1})'
                             ''.format(keylen, self.nlevels))
  
          if keylen == self.nlevels and self.is_unique:
              return self._engine.get_loc(key)
  
          # -- partial selection or non-unique index
          # break the key into 2 parts based on the lexsort_depth of the index;
          # the first part returns a continuous slice of the index; the 2nd part
          # needs linear search within the slice
          i = self.lexsort_depth
          lead_key, follow_key = key[:i], key[i:]
          start, stop = (self.slice_locs(lead_key, lead_key)
                         if lead_key else (0, len(self)))
  
          if start == stop:
              raise KeyError(key)
  
          if not follow_key:
              return slice(start, stop)
  
          warnings.warn('indexing past lexsort depth may impact performance.',
                        PerformanceWarning, stacklevel=10)
  
          loc = np.arange(start, stop, dtype='int64')
  
          for i, k in enumerate(follow_key, len(lead_key)):
              mask = self.codes[i][loc] == self.levels[i].get_loc(k)
              if not mask.all():
                  loc = loc[mask]
              if not len(loc):
                  raise KeyError(key)
  
          return (_maybe_to_slice(loc) if len(loc) != stop - start else
                  slice(start, stop))