Add the typedef to this engine if it is compatible.

        After registering a :class:`~TypeDefinition`, it will not be bound
        until :meth:`~TypeEngine.bind` is next called.

        Nothing will happen when register is called with a typedef that is
        pending binding or already bound.  Otherwise, the engine will ensure it
        is compatible with the type using :meth:`~TypeEngine.is_compatible`
        before adding it to the set of unbound types.

        Parameters
        ----------
        typedef : :class:`~TypeDefinition`
            The typedef to register with this engine

        Raises
        ------
        exc : :class:`ValueError`
            If :meth:`~TypeEngine.is_compatible` is falsey

def register(self, typedef):
        """
        Add the typedef to this engine if it is compatible.

        After registering a :class:`~TypeDefinition`, it will not be bound
        until :meth:`~TypeEngine.bind` is next called.

        Nothing will happen when register is called with a typedef that is
        pending binding or already bound.  Otherwise, the engine will ensure it
        is compatible with the type using :meth:`~TypeEngine.is_compatible`
        before adding it to the set of unbound types.

        Parameters
        ----------
        typedef : :class:`~TypeDefinition`
            The typedef to register with this engine

        Raises
        ------
        exc : :class:`ValueError`
            If :meth:`~TypeEngine.is_compatible` is falsey

        """
        if typedef in self.bound_types:
            return
        if not self.is_compatible(typedef):
            raise ValueError("Incompatible type {} for engine {}".format(
                typedef, self))
        if typedef not in self.unbound_types:
            self.unbound_types.add(typedef)
            typedef._register(self)