docs: def generate(declaration, headers=None, has_iterators=False):
      """Compile and load the reflection dictionary for a type.
  
      If the requested dictionary has already been cached, then load that instead.
  
      Parameters
      ----------
      declaration : str
          A type declaration (for example "vector<int>")
      headers : str or list of str
          A header file or list of header files required to compile the dictionary
          for this type.
      has_iterators : bool
          If True, then include iterators in the dictionary generation.
      """
      global NEW_DICTS
      # FIXME: _rootpy_dictionary_already_exists returns false positives
      # if a third-party module provides "incomplete" dictionaries.
      #if compiled._rootpy_dictionary_already_exists(declaration):
      #    log.debug("generate({0}) => already available".format(declaration))
      #    return
      log.debug("requesting dictionary for {0}".format(declaration))
      if headers:
          if isinstance(headers, string_types):
              headers = sorted(headers.split(';'))
          log.debug("using the headers {0}".format(', '.join(headers)))
          unique_name = ';'.join([declaration] + headers)
      else:
          unique_name = declaration
      unique_name = unique_name.replace(' ', '')
  
      # If the library is already loaded, do nothing
      if unique_name in LOADED_DICTS:
          log.debug("dictionary for {0} is already loaded".format(declaration))
          return
  
      if sys.version_info[0] < 3:
          libname = hashlib.sha512(unique_name).hexdigest()[:16]
      else:
          libname = hashlib.sha512(unique_name.encode('utf-8')).hexdigest()[:16]
      libnameso = libname + ".so"
  
      if ROOT.gROOT.GetVersionInt() < 53403:
          # check for this class in the global TClass list and remove it
          # fixes infinite recursion in ROOT < 5.34.03
          # (exact ROOT versions where this is required is unknown)
          cls = ROOT.gROOT.GetClass(declaration)
          if cls and not cls.IsLoaded():
              log.debug("removing {0} from gROOT.GetListOfClasses()".format(
                  declaration))
              ROOT.gROOT.GetListOfClasses().Remove(cls)
  
      # If a .so already exists for this class, use it.
      if exists(pjoin(DICTS_PATH, libnameso)):
          log.debug("loading previously generated dictionary for {0}"
                      .format(declaration))
          if (ROOT.gInterpreter.Load(pjoin(DICTS_PATH, libnameso))
                  not in (0, 1)):
              raise RuntimeError(
                  "failed to load the library for '{0}' @ {1}".format(
                      declaration, libname))
          LOADED_DICTS[unique_name] = None
          return
  
      with lock(pjoin(DICTS_PATH, "lock"), poll_interval=5, max_age=60):
          # This dict was not previously generated so we must create it now
          log.info("generating dictionary for {0} ...".format(declaration))
          includes = ''
          if headers is not None:
              for header in headers:
                  if re.match('^<.+>$', header):
                      includes += '#include {0}\n'.format(header)
                  else:
                      includes += '#include "{0}"\n'.format(header)
          source = LINKDEF % locals()
          sourcepath = os.path.join(DICTS_PATH, '{0}.C'.format(libname))
          log.debug("source path: {0}".format(sourcepath))
          with open(sourcepath, 'w') as sourcefile:
              sourcefile.write(source)
          log.debug("include path: {0}".format(
              ROOT.gSystem.GetIncludePath()))
          if (ROOT.gSystem.CompileMacro(
                  sourcepath, 'k-', libname, DICTS_PATH) != 1):
              raise RuntimeError(
                  "failed to compile the library for '{0}'".format(
                      sourcepath))
  
      LOADED_DICTS[unique_name] = None
      NEW_DICTS = True