code: def dir2zip(in_dir, zip_fname):
      
      z = zipfile.ZipFile(zip_fname, 'w',
                          compression=zipfile.ZIP_DEFLATED)
      for root, dirs, files in os.walk(in_dir):
          for file in files:
              in_fname = pjoin(root, file)
              in_stat = os.stat(in_fname)
              # Preserve file permissions, but allow copy
              info = zipfile.ZipInfo(in_fname)
              info.filename = relpath(in_fname, in_dir)
              if os.path.sep == '\\':
                  # Make the path unix friendly on windows.
                  # PyPI won't accept wheels with windows path separators
                  info.filename = relpath(in_fname, in_dir).replace('\\', '/')
              # Set time from modification time
              info.date_time = time.localtime(in_stat.st_mtime)
              # See https://stackoverflow.com/questions/434641/how-do-i-set-permissions-attributes-on-a-file-in-a-zip-file-using-pythons-zip/48435482#48435482
              # Also set regular file permissions
              perms = stat.S_IMODE(in_stat.st_mode) | stat.S_IFREG
              info.external_attr = perms << 16
              with open_readable(in_fname, 'rb') as fobj:
                  contents = fobj.read()
              z.writestr(info, contents, zipfile.ZIP_DEFLATED)
      z.close()
docs: Make a zip file `zip_fname` with contents of directory `in_dir`
  
      The recorded filenames are relative to `in_dir`, so doing a standard zip
      unpack of the resulting `zip_fname` in an empty directory will result in
      the original directory contents.
  
      Parameters
      ----------
      in_dir : str
          Directory path containing files to go in the zip archive
      zip_fname : str
          Filename of zip archive to write