docs: def get_object_nbytes(obj, fallback_type=None, follow_pointers=False, exclude_modules=True, listoverhead=False):
      """
      CommandLine:
          python -m utool.util_dev --test-get_object_nbytes
          python -m utool.util_dev --test-get_object_nbytes:1
  
      Example:
          >>> # ENABLE_DOCTEST
          >>> from utool.util_dev import *  # NOQA
          >>> import numpy as np
          >>> import utool as ut
          >>> obj = [np.empty(1, dtype=np.uint8) for _ in range(8)]
          >>> nBytes = ut.get_object_nbytes(obj)
          >>> result = ('nBytes = %s' % (nBytes,))
          >>> print(result)
          nBytes = 8
  
      Example:
          >>> # DISABLE_DOCTEST
          >>> # UNSTABLE_DOCTEST
          >>> from utool.util_dev import *  # NOQA
          >>> import ibeis
          >>> import utool as ut
          >>> species = ibeis.const.TEST_SPECIES.ZEB_PLAIN
          >>> ibs = ibeis.opendb(defaultdb='testdb1')
          >>> qaids = ibs.get_valid_aids(species=species)
          >>> daids = ibs.get_valid_aids(species=species)
          >>> qreq_ = ibs.new_query_request(qaids, daids, verbose=True)
          >>> nBytes = ut.get_object_nbytes(qreq_)
          >>> result = (ut.byte_str2(nBytes))
          >>> print('result = %r' % (result,))
  
      Ignore:
          import sys
          sizedict = {key: sys.getsizeof(key()) for key in [dict, list, set, tuple, int, float]}
          ut.print_dict(sizedict)
          sizedict = {
              <type 'tuple'>: 56,
              <type 'set'>: 232,
              <type 'list'>: 72,
              <type 'float'>: 24,
              <type 'int'>: 24,
              <type 'dict'>: 280,
          }
      """
      import utool as ut
      import types
      seen = set([])
      def _object_nbytes(obj):
          object_id = id(obj)
          if object_id in seen:
              return 0
          if (obj is None or isinstance(obj, (int, bool, float))):
              return sys.getsizeof(obj)
          elif isinstance(obj, six.string_types):
              return sys.getsizeof(obj)
          seen.add(object_id)
  
          if listoverhead:
              totalsize = sys.getsizeof(obj)
          else:
              totalsize = 0
          try:
              if isinstance(obj, (ut.DynStruct, ut.Pref)):
                  # dont deal with dynstruct shenanigans
                  return
              elif exclude_modules and isinstance(obj, types.ModuleType):
                  return 0
              elif isinstance(obj, np.ndarray):
                  if not obj.flags['OWNDATA']:
                      # somebody else owns the data, returned size may be smaller than sobj.nbytes
                      # because sys.getsizeof will return the container size.
                      # if owndata is true sys.getsizeof returns the actual size
                      if follow_pointers:
                          totalsize += obj.nbytes
                      pass
                  # TODO: check if a view or is memmapped
                  # Does sys.getsizeof do the right thing ?
                  totalsize = obj.nbytes
              elif (isinstance(obj, (tuple, list, set, frozenset))):
                  for item in obj:
                      totalsize += _object_nbytes(item)
              elif isinstance(obj, dict):
                  try:
                      for key, val in six.iteritems(obj):
                          totalsize += _object_nbytes(key)
                          totalsize += _object_nbytes(val)
                  except RuntimeError as dictex:
                      ut.printex(dictex, 'RuntimeError in parsing dict nbytes',
                                 keys=['key', (type, 'obj')], iswarning=True)
                      raise
              elif isinstance(obj, object) and hasattr(obj, '__dict__'):
                  if hasattr(obj, 'used_memory') and not isinstance(obj, type):
                      # hack for flann objects
                      totalsize += obj.used_memory()
                  totalsize += _object_nbytes(obj.__dict__)
                  return totalsize
              elif isinstance(obj, type):
                  # use zero for class definitions
                  return 0
              elif isinstance(obj, np.int32):
                  return obj.nbytes
              else:
                  print('Unknown type %r for parsing size' % (type(obj),))
                  return 0
          #except TypeError as ex:
          except Exception as ex:
              ut.printex(ex, 'may be an error in _object_nbytes',
                         keys=[(type, 'obj')], iswarning=True, tb=True)
              pass
              #import utool as ut
              #print('obj = %r' % (obj,))
              #ut.printex(ex)
              #ut.embed()
              #raise RuntimeError(str(ex))  # from ex
          return totalsize
      return _object_nbytes(obj)