code: def import_string(import_name, silent=False):
      
      #XXX: py3 review needed
      assert isinstance(import_name, string_types)
      # force the import name to automatically convert to strings
      import_name = str(import_name)
      try:
          if ':' in import_name:
              module, obj = import_name.split(':', 1)
          elif '.' in import_name:
              module, obj = import_name.rsplit('.', 1)
          else:
              return __import__(import_name)
          # __import__ is not able to handle unicode strings in the fromlist
          # if the module is a package
          if PY2 and isinstance(obj, unicode):
              obj = obj.encode('utf-8')
          try:
              return getattr(__import__(module, None, None, [obj]), obj)
          except (ImportError, AttributeError):
              # support importing modules not yet set up by the parent module
              # (or package for that matter)
              modname = module + '.' + obj
              __import__(modname)
              return sys.modules[modname]
      except ImportError as e:
          if not silent:
              reraise(
                  ImportStringError,
                  ImportStringError(import_name, e),
                  sys.exc_info()[2])
docs: Imports an object based on a string.  This is useful if you want to
      use import paths as endpoints or something similar.  An import path can
      be specified either in dotted notation (``xml.sax.saxutils.escape``)
      or with a colon as object delimiter (``xml.sax.saxutils:escape``).
  
      If `silent` is True the return value will be `None` if the import fails.
  
      :param import_name: the dotted name for the object to import.
      :param silent: if set to `True` import errors are ignored and
                     `None` is returned instead.
      :return: imported object