class_docstr: Core :py:class:`.PluginManager` class which manages registration
  of plugin objects and 1:N hook calling.
  
  You can register new hooks by calling :py:meth:`add_hookspecs(module_or_class)
  <.PluginManager.add_hookspecs>`.
  You can register plugin objects (which contain hooks) by calling
  :py:meth:`register(plugin) <.PluginManager.register>`.  The :py:class:`.PluginManager`
  is initialized with a prefix that is searched for in the names of the dict
  of registered plugin objects.
  
  For debugging purposes you can call :py:meth:`.PluginManager.enable_tracing`
  which will subsequently send debug information to the trace helper.
docstr: Register a plugin and return its canonical name or ``None`` if the name
  is blocked from registering.  Raise a :py:class:`ValueError` if the plugin
  is already registered. 
docstr_tok: ["Register","a","plugin","and","return","its","canonical","name","or","``","None","``","if","the","name","is","blocked","from","registering",".","Raise","a",":","py",":","class",":","`","ValueError","`","if","the","plugin","is","already","registered","."]
code: def register(self, plugin, name=None):
      """Register a plugin and return its canonical name or ``None`` if the name
      is blocked from registering.  Raise a :py:class:`ValueError` if the plugin
      is already registered."""
      plugin_name = name or self.get_canonical_name(plugin)
  
      if (
          plugin_name in self._name2plugin
          or plugin in self._plugin2hookcallers
      ):
          if self._name2plugin.get(plugin_name, -1) is None:
              return  # blocked plugin, return None to indicate no registration
          raise ValueError(
              "Plugin already registered: %s=%s\n%s"
              % (plugin_name, plugin, self._name2plugin)
          )
  
      # XXX if an error happens we should make sure no state has been
      # changed at point of return
      self._name2plugin[plugin_name] = plugin
  
      # register matching hook implementations of the plugin
      self._plugin2hookcallers[plugin] = hookcallers = []
      for name in dir(plugin):
          hookimpl_opts = self.parse_hookimpl_opts(plugin, name)
          if hookimpl_opts is not None:
              normalize_hookimpl_opts(hookimpl_opts)
              method = getattr(plugin, name)
              hookimpl = HookImpl(
                  plugin, plugin_name, method, hookimpl_opts
              )
              hook = getattr(self.hook, name, None)
              if hook is None:
                  hook = _HookCaller(name, self._hookexec)
                  setattr(self.hook, name, hook)
              elif hook.has_spec():
                  self._verify_hook(hook, hookimpl)
                  hook._maybe_apply_history(hookimpl)
              hook._add_hookimpl(hookimpl)
              hookcallers.append(hook)
      return plugin_name
  
imports: import inspect
  import sys
  from .None import _tracing
  from .callers import _Result
  from .hooks import HookImpl, _HookRelay, _HookCaller, normalize_hookimpl_opts
  import warnings
label_desc: Use image node_id 3 for calling the PluginManager obj's underlying member method code with example usage: obj.register(plugin, name) and returns: plugin_name