docstr: Apply a function on publicly exposed API components.
  
  Recursively iterates over the members of the passed object. It omits
  any '_' prefixed and thirdparty (non pyarrow) symbols.
  
  Parameters
  ----------
  fn : callable
      A function to apply on all traversed objects.
  obj : Any
      The object to start from.
  from_package : string
      Predicate to only consider objects from this package.
docstr_tok: ["Apply","a","function","on","publicly","exposed","API","components",".","Recursively","iterates","over","the","members","of","the","passed","object",".","It","omits","any","'","_","'","prefixed","and","thirdparty","(","non","pyarrow",")","symbols",".","Parameters","--","--","--","--","--","fn",":","callable","A","function","to","apply","on","all","traversed","objects",".","obj",":","Any","The","object","to","start","from",".","from_package",":","string","Predicate","to","only","consider","objects","from","this","package","."]
code: def traverse(self, fn, obj, from_package):
      """Apply a function on publicly exposed API components.
  
      Recursively iterates over the members of the passed object. It omits
      any '_' prefixed and thirdparty (non pyarrow) symbols.
  
      Parameters
      ----------
      fn : callable
          A function to apply on all traversed objects.
      obj : Any
          The object to start from.
      from_package : string
          Predicate to only consider objects from this package.
      """
      todo = [obj]
      seen = set()
  
      while todo:
          obj = todo.pop()
          if obj in seen:
              continue
          else:
              seen.add(obj)
  
          fn(obj)
  
          for name in dir(obj):
              if name.startswith("_"):
                  continue
  
              member = getattr(obj, name)
              module = _get_module(member)
              if module is None or not module.startswith(from_package):
                  continue
              # Is it a Cython-generated method? If so, try to detect
              # whether it only has a implicitly-generated docstring,
              # and no user-defined docstring following it.
              # The generated docstring would lack description of method
              # parameters and therefore fail Numpydoc validation.
              if hasattr(member, "__objclass__"):
                  doc = getattr(member, "__doc__", None)
                  # The Cython-generated docstring would be a one-liner,
                  # such as "ReadOptions.equals(self, ReadOptions other)".
                  if doc and "\n" not in doc and f".{name}(" in doc:
                      continue
              todo.append(member)
  
imports: from contextlib import contextmanager
  from enum import EnumMeta
  import inspect
  import tokenize
  from ..compat import _get_module
  from ..utils.logger import logger
  from ..utils.command import Command, capture_stdout, default_bin
label_desc: Use image node_id 2 for calling the NumpyDoc obj's underlying member method code with example usage: obj.traverse(fn, obj, from_package) without return types