class_docstr: Decorator helper class for marking functions as hook specifications.
  
  You can instantiate it with a project_name to get a decorator.
  Calling :py:meth:`.PluginManager.add_hookspecs` later will discover all marked functions
  if the :py:class:`.PluginManager` uses the same project_name.
docstr: if passed a function, directly sets attributes on the function
  which will make it discoverable to :py:meth:`.PluginManager.add_hookspecs`.
  If passed no function, returns a decorator which can be applied to a function
  later using the attributes supplied.
  
  If ``firstresult`` is ``True`` the 1:N hook call (N being the number of registered
  hook implementation functions) will stop at I<=N when the I'th function
  returns a non-``None`` result.
  
  If ``historic`` is ``True`` calls to a hook will be memorized and replayed
  on later registered plugins.
docstr_tok: ["if","passed","a","function",",","directly","sets","attributes","on","the","function","which","will","make","it","discoverable","to",":","py",":","meth",":","`",".PluginManager.add_hookspecs","`",".","If","passed","no","function",",","returns","a","decorator","which","can","be","applied","to","a","function","later","using","the","attributes","supplied",".","If","``","firstresult","``","is","``","True","``","the","1",":","N","hook","call","(","N","being","the","number","of","registered","hook","implementation","functions",")","will","stop","at","I","<","=N","when","the","I'th","function","returns","a","non-","``","None","``","result",".","If","``","historic","``","is","``","True","``","calls","to","a","hook","will","be","memorized","and","replayed","on","later","registered","plugins","."]
code: def __call__(
      self,
      function=None,
      firstresult=False,
      historic=False,
      warn_on_impl=None,
  ):
      """if passed a function, directly sets attributes on the function
      which will make it discoverable to :py:meth:`.PluginManager.add_hookspecs`.
      If passed no function, returns a decorator which can be applied to a function
      later using the attributes supplied.
  
      If ``firstresult`` is ``True`` the 1:N hook call (N being the number of registered
      hook implementation functions) will stop at I<=N when the I'th function
      returns a non-``None`` result.
  
      If ``historic`` is ``True`` calls to a hook will be memorized and replayed
      on later registered plugins.
  
      """
  
      def setattr_hookspec_opts(func):
          if historic and firstresult:
              raise ValueError(
                  "cannot have a historic firstresult hook"
              )
          setattr(
              func,
              self.project_name + "_spec",
              dict(
                  firstresult=firstresult,
                  historic=historic,
                  warn_on_impl=warn_on_impl,
              ),
          )
          return func
  
      if function is not None:
          return setattr_hookspec_opts(function)
      else:
          return setattr_hookspec_opts
  
imports: import inspect
  import sys
  import warnings
  from .callers import _legacymulticall, _multicall
label_desc: Use image node_id 2 for calling the HookspecMarker obj's underlying member method code with example usage: obj.__call__(function, firstresult, historic, warn_on_impl) and returns: func, setattr_hookspec_opts, setattr_hookspec_opts