"""
This class is defined to override standard pickle functionality
The goals of it follow:
-Serialize lambdas and nested functions to compiled byte code
-Deal with main module correctly
-Deal with other non-serializable objects
It does not include an unpickler, as standard python unpickling suffices.
This module was extracted from the `cloud` package, developed by `PiCloud, Inc.
<http://www.picloud.com>`_.
Copyright (c) 2012, Regents of the University of California.
Copyright (c) 2009 `PiCloud, Inc. <http://www.picloud.com>`_.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
  * Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.
  * Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.
  * Neither the name of the University of California, Berkeley nor the
    names of its contributors may be used to endorse or promote
    products derived from this software without specific prior written
    permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
from __future__ import print_function

import operator
import opcode
import os
import io
import pickle
import struct
import sys
import types
from functools import partial
import itertools
import dis
import traceback
import weakref

if sys.version < '3':
  from pickle import Pickler # pylint: disable=ungrouped-imports
  try:
    from cStringIO import StringIO
  except ImportError:
    from StringIO import StringIO
  PY3 = False
else:
  types.ClassType = type
  from pickle import _Pickler as Pickler # pylint: disable=ungrouped-imports
  from io import BytesIO as StringIO # pylint: disable=ungrouped-imports
  PY3 = True

#relevant opcodes
STORE_GLOBAL = opcode.opmap['STORE_GLOBAL']
DELETE_GLOBAL = opcode.opmap['DELETE_GLOBAL']
LOAD_GLOBAL = opcode.opmap['LOAD_GLOBAL']
GLOBAL_OPS = (STORE_GLOBAL, DELETE_GLOBAL, LOAD_GLOBAL)
HAVE_ARGUMENT = dis.HAVE_ARGUMENT
EXTENDED_ARG = dis.EXTENDED_ARG


def islambda(func):
  return getattr(func, '__name__') == '<lambda>'


_BUILTIN_TYPE_NAMES = {}
for k1, v1 in types.__dict__.items():
  if type(v1) is type: # pylint: disable=unidiomatic-typecheck
    _BUILTIN_TYPE_NAMES[v1] = k1


def _builtin_type(name):
  return getattr(types, name)


if sys.version_info < (3, 4):
  def _walk_global_ops(code):
    """
    Yield (opcode, argument number) tuples for all
    global-referencing instructions in *code*.
    """
    code = getattr(code, 'co_code', b'')
    if not PY3:
      code = map(ord, code)

    n = len(code)
    i = 0
    extended_arg = 0
    while i < n:
      op = code[i]
      i += 1
      if op >= HAVE_ARGUMENT:
        oparg = code[i] + code[i + 1] * 256 + extended_arg
        extended_arg = 0
        i += 2
        if op == EXTENDED_ARG:
          extended_arg = oparg * 65536
        if op in GLOBAL_OPS:
          yield op, oparg

else:
  def _walk_global_ops(code):
    """
    Yield (opcode, argument number) tuples for all
    global-referencing instructions in *code*.
    """
    for instr in dis.get_instructions(code): # pylint: disable=no-member
      op = instr.opcode
      if op in GLOBAL_OPS:
        yield op, instr.arg


class CloudPickler(Pickler): # pylint: disable=too-many-public-methods
  """
  CloudPickler class
  """
  dispatch = Pickler.dispatch.copy()

  def __init__(self, filen, protocol=None):
    Pickler.__init__(self, filen, protocol)
    # set of modules to unpickle
    self.modules = set()
    # map ids to dictionary. used to ensure that functions can share global env
    self.globals_ref = {}

  def dump(self, obj):
    self.inject_addons()
    try:
      return Pickler.dump(self, obj)
    except RuntimeError as e:
      if 'recursion' in e.args[0]:
        msg = """Could not pickle object as excessively deep recursion required."""
        raise pickle.PicklingError(msg)
    except pickle.PickleError:
      raise
    except Exception as e:
      print_exec(sys.stderr)
      raise pickle.PicklingError(str(e))

  def save_memoryview(self, obj):
    """Fallback to save_string"""
    Pickler.save_string(self, str(obj))

  def save_buffer(self, obj):
    """Fallback to save_string"""
    Pickler.save_string(self, str(obj))
  if PY3:
    dispatch[memoryview] = save_memoryview
  else:
    dispatch[buffer] = save_buffer

  def save_unsupported(self, obj): # pylint: disable=no-self-use
    raise pickle.PicklingError("Cannot pickle objects of type %s" % type(obj))
  dispatch[types.GeneratorType] = save_unsupported

  # itertools objects do not pickle!
  for v in itertools.__dict__.values():
    if type(v) is type: # pylint: disable=unidiomatic-typecheck
      dispatch[v] = save_unsupported

  def save_module(self, obj):
    """
    Save a module as an import
    """
    self.modules.add(obj)
    self.save_reduce(subimport, (obj.__name__,), obj=obj)
  dispatch[types.ModuleType] = save_module

  def save_codeobject(self, obj):
    """
    Save a code object
    """
    if PY3:
      args = (
          obj.co_argcount, obj.co_kwonlyargcount, obj.co_nlocals, obj.co_stacksize,
          obj.co_flags, obj.co_code, obj.co_consts, obj.co_names, obj.co_varnames,
          obj.co_filename, obj.co_name, obj.co_firstlineno, obj.co_lnotab, obj.co_freevars,
          obj.co_cellvars
      )
    else:
      args = (
          obj.co_argcount, obj.co_nlocals, obj.co_stacksize, obj.co_flags, obj.co_code,
          obj.co_consts, obj.co_names, obj.co_varnames, obj.co_filename, obj.co_name,
          obj.co_firstlineno, obj.co_lnotab, obj.co_freevars, obj.co_cellvars
      )
    self.save_reduce(types.CodeType, args, obj=obj)
  dispatch[types.CodeType] = save_codeobject

  def save_function(self, obj, name=None):
    """ Registered with the dispatch to handle all function types.
    Determines what kind of function obj is (e.g. lambda, defined at
    interactive prompt, etc) and handles the pickling appropriately.
    """
    write = self.write

    if name is None:
      name = obj.__name__
    try:
      # whichmodule() could fail, see
      # https://bitbucket.org/gutworth/six/issues/63/importing-six-breaks-pickling
      modname = pickle.whichmodule(obj, name)
    except Exception:
      modname = None
    # print('which gives %s %s %s' % (modname, obj, name))
    try:
      themodule = sys.modules[modname]
    except KeyError:
      # eval'd items such as namedtuple give invalid items for their function __module__
      modname = '__main__'

    if modname == '__main__':
      themodule = None

    if themodule:
      self.modules.add(themodule)
      if getattr(themodule, name, None) is obj:
        return self.save_global(obj, name)

    # if func is lambda, def'ed at prompt, is in main, or is nested, then
    # we'll pickle the actual function object rather than simply saving a
    # reference (as is done in default pickler), via save_function_tuple.
    if islambda(obj) or obj.__code__.co_filename == '<stdin>' or themodule is None:
      #print("save global", islambda(obj), obj.__code__.co_filename, modname, themodule)
      self.save_function_tuple(obj)
      return
    else:
      # func is nested
      klass = getattr(themodule, name, None)
      if klass is None or klass is not obj:
        self.save_function_tuple(obj)
        return

    if obj.__dict__:
      # essentially save_reduce, but workaround needed to avoid recursion
      self.save(_restore_attr)
      write(pickle.MARK + pickle.GLOBAL + modname + '\n' + name + '\n')
      self.memoize(obj)
      self.save(obj.__dict__)
      write(pickle.TUPLE + pickle.REDUCE)
    else:
      write(pickle.GLOBAL + modname + '\n' + name + '\n')
      self.memoize(obj)
  dispatch[types.FunctionType] = save_function

  def save_function_tuple(self, func):
    """  Pickles an actual func object.
    A func comprises: code, globals, defaults, closure, and dict.  We
    extract and save these, injecting reducing functions at certain points
    to recreate the func object.  Keep in mind that some of these pieces
    can contain a ref to the func itself.  Thus, a naive save on these
    pieces could trigger an infinite loop of save's.  To get around that,
    we first create a skeleton func object using just the code (this is
    safe, since this won't contain a ref to the func), and memoize it as
    soon as it's created.  The other stuff can then be filled in later.
    """
    save = self.save
    write = self.write

    code, f_globals, defaults, closure, dct, base_globals = self.extract_func_data(func)

    save(_fill_function)  # skeleton function updater
    write(pickle.MARK)    # beginning of tuple that _fill_function expects

    # create a skeleton function object and memoize it
    save(_make_skel_func)
    save((code, closure, base_globals))
    write(pickle.REDUCE)
    self.memoize(func)

    # save the rest of the func data needed by _fill_function
    save(f_globals)
    save(defaults)
    save(dct)
    save(func.__module__)
    write(pickle.TUPLE)
    write(pickle.REDUCE)  # applies _fill_function on the tuple

  _extract_code_globals_cache = (
      weakref.WeakKeyDictionary()
      if sys.version_info >= (2, 7) and not hasattr(sys, "pypy_version_info")
      else {}
  )

  @classmethod
  def extract_code_globals(cls, co):
    """
    Find all globals names read or written to by codeblock co
    """
    out_names = cls._extract_code_globals_cache.get(co)
    if out_names is None:
      try:
        names = co.co_names
      except AttributeError:
        # PyPy "builtin-code" object
        out_names = set()
      else:
        out_names = set(names[oparg]
                        for op, oparg in _walk_global_ops(co))

        # see if nested function have any global refs
        if co.co_consts:
          for const in co.co_consts:
            if type(const) is types.CodeType: # pylint: disable=unidiomatic-typecheck
              out_names |= cls.extract_code_globals(const)

      cls._extract_code_globals_cache[co] = out_names

    return out_names

  def extract_func_data(self, func):
    """
    Turn the function into a tuple of data necessary to recreate it:
      code, globals, defaults, closure, dict
    """
    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 = [c.cell_contents for c in func.__closure__] if func.__closure__ else []

    # save the dict
    dct = func.__dict__

    base_globals = self.globals_ref.get(id(func.__globals__), {})
    self.globals_ref[id(func.__globals__)] = base_globals

    return (code, f_globals, defaults, closure, dct, base_globals)

  def save_builtin_function(self, obj):
    if obj.__module__ is "__builtin__":
      return self.save_global(obj)
    return self.save_function(obj)
  dispatch[types.BuiltinFunctionType] = save_builtin_function

  def save_global(self, obj, name=None, pack=struct.pack): # pylint: disable=too-many-branches
    if obj.__module__ == "__builtin__" or obj.__module__ == "builtins":
      if obj in _BUILTIN_TYPE_NAMES:
        return self.save_reduce(_builtin_type, (_BUILTIN_TYPE_NAMES[obj],), obj=obj)

    if name is None:
      name = obj.__name__

    modname = getattr(obj, "__module__", None)
    if modname is None:
      try:
        # whichmodule() could fail, see
        # https://bitbucket.org/gutworth/six/issues/63/importing-six-breaks-pickling
        modname = pickle.whichmodule(obj, name)
      except Exception:
        modname = '__main__'

    if modname == '__main__':
      themodule = None
    else:
      __import__(modname)
      themodule = sys.modules[modname]
      self.modules.add(themodule)

    if hasattr(themodule, name) and getattr(themodule, name) is obj:
      return Pickler.save_global(self, obj, name)

    typ = type(obj)
    if typ is not obj and isinstance(obj, (type, types.ClassType)):
      d = dict(obj.__dict__)  # copy dict proxy to a dict
      if not isinstance(d.get('__dict__', None), property):
        # don't extract dict that are properties
        d.pop('__dict__', None)
      d.pop('__weakref__', None)

      # hack as __new__ is stored differently in the __dict__
      new_override = d.get('__new__', None)
      if new_override:
        d['__new__'] = obj.__new__

      # workaround for namedtuple (hijacked by PySpark)
      if getattr(obj, '_is_namedtuple_', False):
        self.save_reduce(_load_namedtuple, (obj.__name__, obj._fields))
        return

      self.save(_load_class)
      self.save_reduce(typ, (obj.__name__, obj.__bases__, {"__doc__": obj.__doc__}), obj=obj)
      d.pop('__doc__', None)
      # handle property and staticmethod
      dd = {}
      for k, v in d.items():
        if isinstance(v, property):
          k = ('property', k)
          v = (v.fget, v.fset, v.fdel, v.__doc__)
        elif isinstance(v, staticmethod) and hasattr(v, '__func__'):
          k = ('staticmethod', k)
          v = v.__func__
        elif isinstance(v, classmethod) and hasattr(v, '__func__'):
          k = ('classmethod', k)
          v = v.__func__
        dd[k] = v
      self.save(dd)
      self.write(pickle.TUPLE2)
      self.write(pickle.REDUCE)

    else:
      raise pickle.PicklingError("Can't pickle %r" % obj)

  dispatch[type] = save_global
  dispatch[types.ClassType] = save_global

  def save_instancemethod(self, obj):
    # Memoization rarely is ever useful due to python bounding
    if PY3:
      self.save_reduce(types.MethodType, (obj.__func__, obj.__self__), obj=obj)
    else:
      self.save_reduce(
          types.MethodType, (obj.__func__, obj.__self__, obj.__self__.__class__),
          obj=obj)
  dispatch[types.MethodType] = save_instancemethod

  def save_inst(self, obj):
    """Inner logic to save instance. Based off pickle.save_inst
    Supports __transient__"""
    cls = obj.__class__

    memo = self.memo
    write = self.write
    save = self.save

    if hasattr(obj, '__getinitargs__'):
      args = obj.__getinitargs__()
      len(args)  # assert it's a sequence
      pickle._keep_alive(args, memo) # pylint: disable=protected-access
    else:
      args = ()

    write(pickle.MARK)

    if self.bin:
      save(cls)
      for arg in args:
        save(arg)
      write(pickle.OBJ)
    else:
      for arg in args:
        save(arg)
      write(pickle.INST + cls.__module__ + '\n' + cls.__name__ + '\n')

    self.memoize(obj)

    try:
      getstate = obj.__getstate__
    except AttributeError:
      stuff = obj.__dict__
      #remove items if transient
      if hasattr(obj, '__transient__'):
        transient = obj.__transient__
        stuff = stuff.copy()
        for k in list(stuff.keys()):
          if k in transient:
            del stuff[k]
    else:
      stuff = getstate()
      pickle._keep_alive(stuff, memo) # pylint: disable=protected-access
    save(stuff)
    write(pickle.BUILD)

  if not PY3:
    dispatch[types.InstanceType] = save_inst

  def save_property(self, obj):
    # properties not correctly saved in python
    self.save_reduce(property, (obj.fget, obj.fset, obj.fdel, obj.__doc__), obj=obj)
  dispatch[property] = save_property

  def save_itemgetter(self, obj):
    """itemgetter serializer (needed for namedtuple support)"""
    class Dummy: # pylint: disable=old-style-class
      def __init__(self):
        pass
      def __getitem__(self, item):
        return item
    items = obj(Dummy())
    if not isinstance(items, tuple):
      items = (items, )
    return self.save_reduce(operator.itemgetter, items)

  if type(operator.itemgetter) is type: # pylint: disable=unidiomatic-typecheck
    dispatch[operator.itemgetter] = save_itemgetter

  def save_attrgetter(self, obj):
    """attrgetter serializer"""
    class Dummy(object):
      def __init__(self, attrs, index=None):
        self.attrs = attrs
        self.index = index
      def __getattribute__(self, item):
        attrs = object.__getattribute__(self, "attrs")
        index = object.__getattribute__(self, "index")
        if index is None:
          index = len(attrs)
          attrs.append(item)
        else:
          attrs[index] = ".".join([attrs[index], item])
        return type(self)(attrs, index)
    attrs = []
    obj(Dummy(attrs))
    return self.save_reduce(operator.attrgetter, tuple(attrs))

  if type(operator.attrgetter) is type: # pylint: disable=unidiomatic-typecheck
    dispatch[operator.attrgetter] = save_attrgetter

  def save_reduce(self, func, args, state=None, # pylint: disable=too-many-branches
                  listitems=None, dictitems=None, obj=None):
    """Modified to support __transient__ on new objects
    Change only affects protocol level 2 (which is always used by PiCloud"""
    # Assert that args is a tuple or None
    if not isinstance(args, tuple):
      raise pickle.PicklingError("args from reduce() should be a tuple")

    # Assert that func is callable
    if not hasattr(func, '__call__'):
      raise pickle.PicklingError("func from reduce should be callable")

    save = self.save
    write = self.write

    # Protocol 2 special case: if func's name is __newobj__, use NEWOBJ
    if self.proto >= 2 and getattr(func, "__name__", "") == "__newobj__":
      #Added fix to allow transient
      cls = args[0]
      if not hasattr(cls, "__new__"):
        raise pickle.PicklingError(
            "args[0] from __newobj__ args has no __new__")
      if obj is not None and cls is not obj.__class__:
        raise pickle.PicklingError(
            "args[0] from __newobj__ args has the wrong class")
      args = args[1:]
      save(cls)

      #Don't pickle transient entries
      if hasattr(obj, '__transient__'):
        transient = obj.__transient__
        state = state.copy()

        for k in list(state.keys()):
          if k in transient:
            del state[k]

      save(args)
      write(pickle.NEWOBJ)
    else:
      save(func)
      save(args)
      write(pickle.REDUCE)

    if obj is not None:
      self.memoize(obj)

    # More new special cases (that work with older protocols as
    # well): when __reduce__ returns a tuple with 4 or 5 items,
    # the 4th and 5th item should be iterators that provide list
    # items and dict items (as (key, value) tuples), or None.

    if listitems is not None:
      self._batch_appends(listitems)

    if dictitems is not None:
      self._batch_setitems(dictitems)

    if state is not None:
      save(state)
      write(pickle.BUILD)

  def save_partial(self, obj):
    """Partial objects do not serialize correctly in python2.x -- this fixes the bugs"""
    self.save_reduce(_genpartial, (obj.func, obj.args, obj.keywords))

  if sys.version_info < (2, 7):  # 2.7 supports partial pickling
    dispatch[partial] = save_partial


  def save_file(self, obj): # pylint: disable=too-many-branches
    """Save a file"""
    try:
      import StringIO as pystringIO #we can't use cStringIO as it lacks the name attribute
    except ImportError:
      import io as pystringIO # pylint: disable=reimported

    if not hasattr(obj, 'name') or  not hasattr(obj, 'mode'):
      raise pickle.PicklingError("Cannot pickle files that do not map to an actual file")
    if obj is sys.stdout:
      return self.save_reduce(getattr, (sys, 'stdout'), obj=obj)
    if obj is sys.stderr:
      return self.save_reduce(getattr, (sys, 'stderr'), obj=obj)
    if obj is sys.stdin:
      raise pickle.PicklingError("Cannot pickle standard input")
    if  hasattr(obj, 'isatty') and obj.isatty():
      raise pickle.PicklingError("Cannot pickle files that map to tty objects")
    if 'r' not in obj.mode:
      raise pickle.PicklingError("Cannot pickle files that are not opened for reading")
    name = obj.name
    try:
      fsize = os.stat(name).st_size
    except OSError:
      raise pickle.PicklingError("Cannot pickle file %s as it cannot be stat" % name)

    if obj.closed:
      #create an empty closed string io
      retval = pystringIO.StringIO("")
      retval.close()
    elif not fsize: #empty file
      retval = pystringIO.StringIO("")
      try:
        tmpfile = file(name)
        tst = tmpfile.read(1)
      except IOError:
        raise pickle.PicklingError("Cannot pickle file %s as it cannot be read" % name)
      tmpfile.close()
      if tst != '':
        raise pickle.PicklingError(
            "Cannot pickle file %s as it does not appear to map to a physical, real file" % name)
    else:
      try:
        tmpfile = file(name)
        contents = tmpfile.read()
        tmpfile.close()
      except IOError:
        raise pickle.PicklingError("Cannot pickle file %s as it cannot be read" % name)
      retval = pystringIO.StringIO(contents)
      curloc = obj.tell()
      retval.seek(curloc)

    retval.name = name
    self.save(retval)
    self.memoize(obj)

  if PY3:
    dispatch[io.TextIOWrapper] = save_file
  else:
    dispatch[file] = save_file

  # Special functions for Add-on libraries

  def inject_numpy(self):
    numpy = sys.modules.get('numpy')
    if not numpy or not hasattr(numpy, 'ufunc'):
      return
    self.dispatch[numpy.ufunc] = self.__class__.save_ufunc

  def save_ufunc(self, obj):
    """Hack function for saving numpy ufunc objects"""
    name = obj.__name__
    numpy_tst_mods = ['numpy', 'scipy.special']
    for tst_mod_name in numpy_tst_mods:
      tst_mod = sys.modules.get(tst_mod_name, None)
      if tst_mod and name in tst_mod.__dict__:
        return self.save_reduce(_getobject, (tst_mod_name, name))
    raise pickle.PicklingError(
        'cannot save %s. Cannot resolve what module it is defined in' % str(obj))

  def inject_addons(self):
    """Plug in system. Register additional pickling functions if modules already loaded"""
    self.inject_numpy()


# Shorthands for legacy support

def dump(obj, filen, protocol=2):
  CloudPickler(filen, protocol).dump(obj)


def dumps(obj, protocol=2):
  filen = StringIO()

  cp = CloudPickler(filen, protocol)
  cp.dump(obj)

  return filen.getvalue()


#hack for __import__ not working as desired
def subimport(name):
  __import__(name)
  return sys.modules[name]


# restores function attributes
def _restore_attr(obj, attr):
  for key, val in attr.items():
    setattr(obj, key, val)
  return obj


def _get_module_builtins():
  return pickle.__builtins__ # pylint: disable=no-member


def print_exec(stream):
  ei = sys.exc_info()
  traceback.print_exception(ei[0], ei[1], ei[2], None, stream)


def _modules_to_main(modList):
  """Force every module in modList to be placed into main"""
  if not modList:
    return

  main = sys.modules['__main__']
  for modname in modList:
    if isinstance(modname, str):
      try:
        mod = __import__(modname)
      except Exception:
        sys.stderr.write(
            'warning: could not import %s\n.  '
            'Your function may unexpectedly error due to this import failing;'
            'A version mismatch is likely.  Specific error was:\n' % modname)
        print_exec(sys.stderr)
      else:
        setattr(main, mod.__name__, mod)


#object generators:
def _genpartial(func, args, kwds):
  if not args:
    args = ()
  if not kwds:
    kwds = {}
  return partial(func, *args, **kwds)


def _fill_function(func, globalsn, defaults, dictn, module):
  """ Fills in the rest of function data into the skeleton function object
    that were created via _make_skel_func().
     """
  func.__globals__.update(globalsn)
  func.__defaults__ = defaults
  func.__dict__ = dictn
  func.__module__ = module

  return func


def _make_cell(value):
  return (lambda: value).__closure__[0]


def _reconstruct_closure(values):
  return tuple([_make_cell(v) for v in values])


def _make_skel_func(code, closures, base_globals=None):
  """ Creates a skeleton function object that contains just the provided
    code and the correct number of cells in func_closure.  All other
    func attributes (e.g. func_globals) are empty.
  """
  closure = _reconstruct_closure(closures) if closures else None

  if base_globals is None:
    base_globals = {}
  base_globals['__builtins__'] = __builtins__

  return types.FunctionType(code, base_globals, None, None, closure)


def _load_class(cls, d):
  """
  Loads additional properties into class `cls`.
  """
  for k, v in d.items():
    if isinstance(k, tuple):
      typ, k = k
      if typ == 'property':
        v = property(*v)
      elif typ == 'staticmethod':
        v = staticmethod(v) # pylint: disable=redefined-variable-type
      elif typ == 'classmethod':
        v = classmethod(v)
    setattr(cls, k, v)
  return cls


def _load_namedtuple(name, fields):
  """
  Loads a class generated by namedtuple
  """
  from collections import namedtuple
  return namedtuple(name, fields)


# Constructors for 3rd party libraries
# Note: These can never be renamed due to client compatibility issues

def _getobject(modname, attribute):
  mod = __import__(modname, fromlist=[attribute])
  return mod.__dict__[attribute]
