docs: def register_exporter(name, base_class):
      """
      Register an exporter to use for a :class:`Part <cqparts.Part>`,
      :class:`Assembly <cqparts.Assembly>`, or both
      (with :class:`Component <cqparts.Component>`).
  
      Registration is necessary to use with
      :meth:`Component.exporter() <cqparts.Component.exporter>`.
  
      :param name: name (or 'key') of exporter
      :type name: :class:`str`
      :param base_class: class of :class:`Component <cqparts.Component>` to export
      :type base_class: :class:`type`
  
      .. doctest::
  
          >>> from cqparts import Part
          >>> from cqparts.codec import Exporter, register_exporter
  
          >>> @register_exporter('my_type', Part)
          ... class MyExporter(Exporter):
          ...     def __call__(self, filename='out.mytype'):
          ...         print("export %r to %s" % (self.obj, filename))
  
          >>> from cqparts_misc.basic.primatives import Sphere
          >>> thing = Sphere(radius=5)
          >>> thing.exporter('my_type')('some-file.mytype')
          export <Sphere: radius=5.0> to some-file.mytype
  
      """
      # Verify params
      if not isinstance(name, str) or (not name):
          raise TypeError("invalid name: %r" % name)
      if not issubclass(base_class, Component):
          raise TypeError("invalid base_class: %r, must be a %r subclass" % (base_class, Component))
  
      def decorator(cls):
          # --- Verify
          # Can only be registered once
          if base_class in exporter_index[name]:
              raise TypeError("'%s' exporter type %r has already been registered" % (
                  name, base_class
              ))
  
          # Verify class hierarchy will not conflict
          # (so you can't have an exporter for a Component, and a Part. must be
          #  an Assembly, and a Part, respectively)
          for key in exporter_index[name].keys():
              if issubclass(key, base_class) or issubclass(base_class, key):
                  raise TypeError("'%s' exporter type %r is in conflict with %r" % (
                      name, base_class, key,
                  ))
  
          # --- Index
          exporter_index[name][base_class] = cls
  
          return cls
      return decorator