class_docstr: The number of neighbors to sample in a homogeneous or heterogeneous
  graph. In heterogeneous graphs, may also take in a dictionary denoting
  the amount of neighbors to sample for individual edge types.
  
  Args:
      values (List[int] or Dict[Tuple[str, str, str], List[int]]): The
          number of neighbors to sample.
          If an entry is set to :obj:`-1`, all neighbors will be included.
          In heterogeneous graphs, may also take in a dictionary denoting
          the amount of neighbors to sample for individual edge types.
      default (List[int], optional): The default number of neighbors for edge
          types not specified in :obj:`values`. (default: :obj:`None`)
docstr: Returns the number of hops.
docstr_tok: ["Returns","the","number","of","hops","."]
code: def num_hops(self) -> int:
      r"""Returns the number of hops."""
      if "_num_hops" in self.__dict__:
          return self.__dict__["_num_hops"]
  
      if isinstance(self.values, (tuple, list)):
          num_hops = max(len(self.values), len(self.default or []))
      else:  # isinstance(self.values, dict):
          num_hops = max([0] + [len(v) for v in self.values.values()])
          num_hops = max(num_hops, len(self.default or []))
  
      self.__dict__["_num_hops"] = num_hops
      return num_hops
  
imports: import copy
  import math
  import warnings
  from abc import ABC
  from collections import defaultdict
  from dataclasses import dataclass
  from enum import Enum
  from typing import Any, Dict, List, Optional, Union
  import torch
  from torch import Tensor
  from torch_geometric.data import Data, FeatureStore, GraphStore, HeteroData
  from torch_geometric.sampler.utils import to_bidirectional
  from torch_geometric.typing import EdgeType, EdgeTypeStr, NodeType, OptTensor
  from torch_geometric.utils.mixin import CastMixin
label_desc: Use image node_id 5 for calling the NumNeighbors obj's underlying member method code with example usage: obj.num_hops() and returns: num_hops, self