put an item into the queue

        .. note::

            if the queue was created with a `maxsize` and it is currently
            :meth:`full`, this method will block the calling coroutine until
            another coroutine :meth:`get`\ s an item.

        :param item: the object to put into the queue, can be any type
        :param block:
            whether to block if the queue is already :meth:`full` (default
            ``True``)
        :type block: bool
        :param timeout:
            the maximum time in seconds to block waiting. with the default of
            ``None``, it can wait indefinitely. this is unused if `block` is
            ``False``.
        :type timeout: int, float or None

        :raises:
            :class:`Full` if the queue is :meth:`full` and `block` is
            ``False``, or if `timeout` expires.

def put(self, item, block=True, timeout=None):
        """put an item into the queue

        .. note::

            if the queue was created with a `maxsize` and it is currently
            :meth:`full`, this method will block the calling coroutine until
            another coroutine :meth:`get`\ s an item.

        :param item: the object to put into the queue, can be any type
        :param block:
            whether to block if the queue is already :meth:`full` (default
            ``True``)
        :type block: bool
        :param timeout:
            the maximum time in seconds to block waiting. with the default of
            ``None``, it can wait indefinitely. this is unused if `block` is
            ``False``.
        :type timeout: int, float or None

        :raises:
            :class:`Full` if the queue is :meth:`full` and `block` is
            ``False``, or if `timeout` expires.
        """
        if self.full():
            if not block:
                raise Full()

            current = compat.getcurrent()

            waketime = None if timeout is None else time.time() + timeout
            if timeout is not None:
                scheduler.schedule_at(waketime, current)
            self._waiters.append((current, waketime))

            scheduler.state.mainloop.switch()

            if timeout is not None:
                if not scheduler._remove_timer(waketime, current):
                    self._waiters.remove((current, waketime))
                    raise Full()

        if self._waiters and not self.full():
            scheduler.schedule(self._waiters.popleft()[0])

        if not self._open_tasks:
            self._jobs_done.clear()
        self._open_tasks += 1

        self._put(item)