# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
"""
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

# pylint: disable-all

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]
