docs: def _split_object(pobj, package, resplit=False, packincl=None, skipext=False):
      """Splits the specified object into its modules, classes, methods and
      functions so that it can be decorated more easily. For extension
      modules/classes that can't have attributes set, the object's dictionary is
      modified to point to a derived-type version.
  
      Args:
          pobj: object instance returned from the import.
          package (str): name of the package (used for filtering all the loaded
            packages and methods inside the package object).
          resplit (bool): if True, re-processes the object, even if has been done
            before.
          packincl (list): of package names that should be considered relevant when
            deciding how to filter the members of this object. If a member belongs
            to one of these packages, they will be included in the split for the
            object.
          skipext (bool): when True, the list of split objects is only returned;
            no attempts are made to extend any objects for decoration.
      """
      import inspect
      result = {
          "classes": [],
          "functions": [],
          "methods": [],
          "modules": [],
          "builtins": [],
          "descriptors": [],
          "unknowns": []
          }
  
      global _split_objects
      if pobj in _split_objects and not resplit:
          return result
      
      tests = {
          "classes": inspect.isclass,
          "functions": inspect.isfunction,
          "methods": inspect.ismethod,
          "modules": inspect.ismodule,
          "builtins": inspect.isbuiltin,
          "descriptors": inspect.ismethoddescriptor
          }
  
      from functools import partial
      prepack = "{}.".format(package)
      pms = []
      pmodule = pobj if inspect.ismodule(pobj) or inspect.isclass(pobj) else None
      for n, o in _get_members(pobj):
          if isinstance(o, (dict, list, set, float, int, str, complex, bool)):
              #We are looking for functions, modules and packages; sometimes
              #constants are declared that we just ignore.
              continue
          else:
              omod = _safe_getmodule(o)
              if omod is None:
                  #This may be an instance method of an object-class. In that
                  #case, we still want to decorate it.
                  if hasattr(o,"__objclass__") and o.__objclass__ is not type:
                      omod = _safe_getmodule(o.__objclass__)
                  elif hasattr(o, "__class__") and o.__class__ is not type:
                      omod = _safe_getmodule(o.__class__)
                  else:
                      omod = pmodule
  
                  #Catch the last outlier case: C-extension built-in descriptors
                  #methods for "built-in" objects.
                  if omod is None and inspect.ismethoddescriptor(o):
                      omod = pmodule
                      
          #Some packages define special types with __class__ = type. These are
          #indistinguishable from the built-in types like `float` or `str`. So we
          #force the developers to configure these manually.
          packok = False
          confok = False
          pincl = False        
          if omod is not None:
              if packincl is not None and len(packincl) > 0:
                  #We want to sometimes return all the objects available at the
                  #top-level of a package, even if they were imported from a
                  #different package. This doesn't get called in normal decoration
                  #mode, except for certain special packages.
                  fqdn_ = _fqdn(o, False, pmodule=pmodule)
                  if fqdn_ is not None:
                      pincl = any(p in fqdn_ for p in packincl)
  
              omodname = (omod.__name__ if inspect.ismodule(omod)
                          else _fqdn(omod, False))
              packok = (prepack in omodname or omodname == package or pincl)
              if not packok and hasattr(o, "__class__") and o.__class__ is type:
                  fqdn_ = _fqdn(o, False, pmodule=pmodule)
                  incl = filter_name(fqdn_, package, explicit=True)
                  if incl: # pragma: no cover
                      filesrc = inspect.getabsfile(pobj)
                      confok = "/{}/".format(package) in filesrc
                  
          if packok or confok:
              pms.append((n, o, confok))                    
  
      global _decor_count
      def oappend(n, o, t, result, confok):
          """Appends the specified object to `results` if it can be extended.
  
          Args:
              confok (bool): when True, the code has already determined previously
                that this object should be decorated no matter what (the user said
                so). In that case, we bypass the regular name checks.
          """
          fqdn = _fqdn(o, False, pmodule=pmodule)
          if fqdn is None:
              #The object was probably of type unknown and doesn't have a __name__
              #attribute, so we just skip it.
              return
  
          package = fqdn.split('.')[0]
          if confok or (filter_name(n, package) and filter_name(fqdn, package)):
              xobj = _extend_object(pobj, n, o, t, fqdn)
              if xobj is not None:
                  result[t].append((n, xobj))
              else: # pragma: no cover
                  msg.warn("Couldn't extend {} ({}).".format(o, t), 2)
          else:
              skipmsg = "Skipping {}: {} because of filter rules."
              msg.info(skipmsg.format(n, fqdn), 4)
              if package in _decor_count:
                  _decor_count[package][1] += 1
          
      for n, o, confok in pms:
          for t, f in tests.items():
              if f(o):
                  if skipext:
                      result[t].append((n, o))
                  else:
                      oappend(n, o, t, result, confok)
                  break
          else:
              #With some class instances (which end up being members of
              #objects), an error is raised because they implement their own
              #__getattr__ routine that wasn't designed to work with acorn. We
              #just ignore these. We don't want to decorate object instances
              #anyway, except that numpy.ufunc instances are actually
              #functions that don't match any of the inspect.is* methods, and
              #so we have this catch-all over here.
              cancall = _safe_hasattr(o, "__call__")
              if cancall:
                  if skipext: # pragma: no cover
                      result["unknowns"].append((n, o))
                  else:
                      oappend(n, o, "unknowns", result, confok)
  
      _split_objects.append(pobj)
      return result