code: def extract_func_data(self, func):
          
          code = func.__code__
  
          # extract all global ref's
          func_global_refs = self.extract_code_globals(code)
  
          # process all variables referenced by global environment
          f_globals = {}
          for var in func_global_refs:
              if var in func.__globals__:
                  f_globals[var] = func.__globals__[var]
  
          # defaults requires no processing
          defaults = func.__defaults__
  
          # process closure
          closure = (
              list(map(_get_cell_contents, func.__closure__))
              if func.__closure__ is not None
              else None
          )
  
          # save the dict
          dct = func.__dict__
  
          base_globals = self.globals_ref.get(id(func.__globals__), None)
          if base_globals is None:
              # For functions defined in a well behaved module use
              # vars(func.__module__) for base_globals. This is necessary to
              # share the global variables across multiple pickled functions from
              # this module.
              if hasattr(func, '__module__') and func.__module__ is not None:
                  base_globals = func.__module__
              else:
                  base_globals = {}
          self.globals_ref[id(func.__globals__)] = base_globals
  
          return (code, f_globals, defaults, closure, dct, base_globals)
docs: Turn the function into a tuple of data necessary to recreate it:
              code, globals, defaults, closure_values, dict