code: def _encoding_wrapper(fileobj, mode, encoding=None, errors=None):
      
      logger.debug('encoding_wrapper: %r', locals())
  
      #
      # If the mode is binary, but the user specified an encoding, assume they
      # want text.  If we don't make this assumption, ignore the encoding and
      # return bytes, smart_open behavior will diverge from the built-in open:
      #
      #   open(filename, encoding='utf-8') returns a text stream in Py3
      #   smart_open(filename, encoding='utf-8') would return a byte stream
      #       without our assumption, because the default mode is rb.
      #
      if 'b' in mode and encoding is None:
          return fileobj
  
      if encoding is None:
          encoding = SYSTEM_ENCODING
  
      kw = {'errors': errors} if errors else {}
      if mode[0] == 'r' or mode.endswith('+'):
          fileobj = codecs.getreader(encoding)(fileobj, **kw)
      if mode[0] in ('w', 'a') or mode.endswith('+'):
          fileobj = codecs.getwriter(encoding)(fileobj, **kw)
      return fileobj
docs: Decode bytes into text, if necessary.
  
      If mode specifies binary access, does nothing, unless the encoding is
      specified.  A non-null encoding implies text mode.
  
      :arg fileobj: must quack like a filehandle object.
      :arg str mode: is the mode which was originally requested by the user.
      :arg str encoding: The text encoding to use.  If mode is binary, overrides mode.
      :arg str errors: The method to use when handling encoding/decoding errors.
      :returns: a file object