Skip to content

Document the correct way to subclass asyncio.Queue #146366

@jonathandung

Description

@jonathandung

Feature or enhancement

Proposal:

In Lib/asyncio/queues.py:

    # These three are overridable in subclasses.

    def _init(self, maxsize):
        self._queue = collections.deque()

    def _get(self):
        return self._queue.popleft()

    def _put(self, item):
        self._queue.append(item)

    # End of the overridable methods.

The _queue attribute is used to store the items, and the behaviour of getting and putting can apparently be easily customized in subclasses of asyncio.Queue by overriding _init, _get and _put with these exact signatures. However, nowhere in the docs is this mentioned. It would be suboptimal that a developer has to read the source code just to figure this out.

Besides, since the _init method can be overridden, it appears that the attribute name under which the items are stored (_queue) can be changed. However, this is simply not true, due to the following:

The _format method (line 87) used to compute the string representation of the queue object q assumes that q._queue points to an iterable or does not exist, in which case the representation will not expose the items:

    def _format(self):
        result = f'maxsize={self._maxsize!r}'
        if getattr(self, '_queue', None):
            result += f' _queue={list(self._queue)!r}'
        if self._getters:
            result += f' _getters[{len(self._getters)}]'
        if self._putters:
            result += f' _putters[{len(self._putters)}]'
        if self._unfinished_tasks:
            result += f' tasks={self._unfinished_tasks}'
        if self._is_shutdown:
            result += ' shutdown'
        return result

The qsize method (line 101) expects q._queue to be sized:

    def qsize(self):
        """Number of items in the queue."""
        return len(self._queue)

The empty method (line 110) expects the truth value of q._queue to correspond to whether any items are in the queue:

    def empty(self):
        """Return True if the queue is empty, False otherwise."""
        return not self._queue

These methods are said not to be overridable; see the comment below _put.

This is all in all an obtrusive hole in documentation, and there is no more suitable place to put it than in the asyncio.Queue docs page (source).

If needed, I will open a PR to fix this.

Has this already been discussed elsewhere?

No response given

Links to previous discussion of this feature:

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    docsDocumentation in the Doc dirpendingThe issue will be closed if no feedback is providedtopic-asynciotype-featureA feature request or enhancement

    Projects

    Status

    Todo

    Status

    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions