def fire(self, exc=None, data=None):
        """Fire the event

        :param exc: fire the event with an exception
        :param data: fire an event with data
        """
        o = self._self

        if o is not None:
            handlers = self._handlers
            if self._onetime:
                self._handlers = None
                self._self = None

            if handlers:
                if exc is not None:
                    for hnd in handlers:
                        hnd(o, exc=exc)
                elif data is not None:
                    for hnd in handlers:
                        hnd(o, data=data)
                else:
                    for hnd in handlers:
                        hnd(o)

            if self._waiter:
                if exc:
                    self._waiter.set_exception(exc)
                else:
                    self._waiter.set_result(data if data is not None else o)
                self._waiter = None
Fire the event

        :param exc: fire the event with an exception
        :param data: fire an event with data