https://github.com/python/cpython/commit/245671555b7e33112ae1efd0c26071d7a0e27b3a
commit: 245671555b7e33112ae1efd0c26071d7a0e27b3a
branch: main
author: Raymond Hettinger <rhettin...@users.noreply.github.com>
committer: rhettinger <rhettin...@users.noreply.github.com>
date: 2025-07-24T11:23:03-06:00
summary:

Fix docs for Queue.shutdown (gh-137028)

files:
M Doc/library/asyncio-queue.rst
M Doc/library/queue.rst
M Lib/asyncio/queues.py
M Lib/queue.py

diff --git a/Doc/library/asyncio-queue.rst b/Doc/library/asyncio-queue.rst
index d99213aa81d53e..963bc1fb82c12f 100644
--- a/Doc/library/asyncio-queue.rst
+++ b/Doc/library/asyncio-queue.rst
@@ -102,17 +102,33 @@ Queue
 
    .. method:: shutdown(immediate=False)
 
-      Shut down the queue, making :meth:`~Queue.get` and :meth:`~Queue.put`
+      Put a :class:`Queue` instance into a shutdown mode.
+
+      The queue can no longer grow.
+      Future calls to :meth:`~Queue.put` raise :exc:`QueueShutDown`.
+      Currently blocked callers of :meth:`~Queue.put` will be unblocked
+      and will raise :exc:`QueueShutDown` in the formerly blocked thread.
+
+      If *immediate* is false (the default), the queue can be wound
+      down normally with :meth:`~Queue.get` calls to extract tasks
+      that have already been loaded.
+
+      And if :meth:`~Queue.task_done` is called for each remaining task, a
+      pending :meth:`~Queue.join` will be unblocked normally.
+
+      Once the queue is empty, future calls to :meth:`~Queue.get` will
       raise :exc:`QueueShutDown`.
 
-      By default, :meth:`~Queue.get` on a shut down queue will only
-      raise once the queue is empty. Set *immediate* to true to make
-      :meth:`~Queue.get` raise immediately instead.
+      If *immediate* is true, the queue is terminated immediately.
+      The queue is drained to be completely empty.  All callers of
+      :meth:`~Queue.join` are unblocked regardless of the number
+      of unfinished tasks.  Blocked callers of :meth:`~Queue.get`
+      are unblocked and will raise :exc:`QueueShutDown` because the
+      queue is empty.
 
-      All blocked callers of :meth:`~Queue.put` and :meth:`~Queue.get`
-      will be unblocked. If *immediate* is true, a task will be marked
-      as done for each remaining item in the queue, which may unblock
-      callers of :meth:`~Queue.join`.
+      Use caution when using :meth:`~Queue.join` with *immediate* set
+      to true. This unblocks the join even when no work has been done
+      on the tasks, violating the usual invariant for joining a queue.
 
       .. versionadded:: 3.13
 
@@ -129,9 +145,6 @@ Queue
       call was received for every item that had been :meth:`~Queue.put`
       into the queue).
 
-      ``shutdown(immediate=True)`` calls :meth:`task_done` for each
-      remaining item in the queue.
-
       Raises :exc:`ValueError` if called more times than there were
       items placed in the queue.
 
diff --git a/Doc/library/queue.rst b/Doc/library/queue.rst
index fbbebcf4ed8f92..6dcf06aab00295 100644
--- a/Doc/library/queue.rst
+++ b/Doc/library/queue.rst
@@ -187,9 +187,6 @@ fully processed by daemon consumer threads.
    processed (meaning that a :meth:`task_done` call was received for every item
    that had been :meth:`put` into the queue).
 
-   ``shutdown(immediate=True)`` calls :meth:`task_done` for each remaining item
-   in the queue.
-
    Raises a :exc:`ValueError` if called more times than there were items 
placed in
    the queue.
 
@@ -204,6 +201,9 @@ fully processed by daemon consumer threads.
    count of unfinished tasks drops to zero, :meth:`join` unblocks.
 
 
+Waiting for task completion
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
 Example of how to wait for enqueued tasks to be completed::
 
     import threading
@@ -233,22 +233,38 @@ Example of how to wait for enqueued tasks to be 
completed::
 Terminating queues
 ^^^^^^^^^^^^^^^^^^
 
-:class:`Queue` objects can be made to prevent further interaction by shutting
-them down.
+When no longer needed, :class:`Queue` objects can be wound down
+until empty or terminated immediately with a hard shutdown.
 
 .. method:: Queue.shutdown(immediate=False)
 
-   Shut down the queue, making :meth:`~Queue.get` and :meth:`~Queue.put` raise
-   :exc:`ShutDown`.
+   Put a :class:`Queue` instance into a shutdown mode.
+
+   The queue can no longer grow.
+   Future calls to :meth:`~Queue.put` raise :exc:`ShutDown`.
+   Currently blocked callers of :meth:`~Queue.put` will be unblocked
+   and will raise :exc:`ShutDown` in the formerly blocked thread.
+
+   If *immediate* is false (the default), the queue can be wound
+   down normally with :meth:`~Queue.get` calls to extract tasks
+   that have already been loaded.
+
+   And if :meth:`~Queue.task_done` is called for each remaining task, a
+   pending :meth:`~Queue.join` will be unblocked normally.
+
+   Once the queue is empty, future calls to :meth:`~Queue.get` will
+   raise :exc:`ShutDown`.
 
-   By default, :meth:`~Queue.get` on a shut down queue will only raise once the
-   queue is empty. Set *immediate* to true to make :meth:`~Queue.get` raise
-   immediately instead.
+   If *immediate* is true, the queue is terminated immediately.
+   The queue is drained to be completely empty.  All callers of
+   :meth:`~Queue.join` are unblocked regardless of the number
+   of unfinished tasks.  Blocked callers of :meth:`~Queue.get`
+   are unblocked and will raise :exc:`ShutDown` because the
+   queue is empty.
 
-   All blocked callers of :meth:`~Queue.put` and :meth:`~Queue.get` will be
-   unblocked. If *immediate* is true, a task will be marked as done for each
-   remaining item in the queue, which may unblock callers of
-   :meth:`~Queue.join`.
+   Use caution when using :meth:`~Queue.join` with *immediate* set
+   to true. This unblocks the join even when no work has been done
+   on the tasks, violating the usual invariant for joining a queue.
 
    .. versionadded:: 3.13
 
diff --git a/Lib/asyncio/queues.py b/Lib/asyncio/queues.py
index 2f3865114a84f9..e5d6f2e4b61e17 100644
--- a/Lib/asyncio/queues.py
+++ b/Lib/asyncio/queues.py
@@ -227,9 +227,6 @@ def task_done(self):
         been processed (meaning that a task_done() call was received for every
         item that had been put() into the queue).
 
-        shutdown(immediate=True) calls task_done() for each remaining item in
-        the queue.
-
         Raises ValueError if called more times than there were items placed in
         the queue.
         """
@@ -257,8 +254,8 @@ def shutdown(self, immediate=False):
         'immediate' to True to make gets raise immediately instead.
 
         All blocked callers of put() and get() will be unblocked. If
-        'immediate', a task is marked as done for each item remaining in
-        the queue, which may unblock callers of join().
+        'immediate', unblock callers of join() regardless of the
+        number of unfinished tasks.
         """
         self._is_shutdown = True
         if immediate:
diff --git a/Lib/queue.py b/Lib/queue.py
index 25beb46e30d6bd..c90de8edc76c34 100644
--- a/Lib/queue.py
+++ b/Lib/queue.py
@@ -80,9 +80,6 @@ def task_done(self):
         have been processed (meaning that a task_done() call was received
         for every item that had been put() into the queue).
 
-        shutdown(immediate=True) calls task_done() for each remaining item in
-        the queue.
-
         Raises a ValueError if called more times than there were items
         placed in the queue.
         '''
@@ -240,8 +237,8 @@ def shutdown(self, immediate=False):
         'immediate' to True to make gets raise immediately instead.
 
         All blocked callers of put() and get() will be unblocked. If
-        'immediate', a task is marked as done for each item remaining in
-        the queue, which may unblock callers of join().
+        'immediate', callers of join() are unblocked regardless of
+        the number of unfinished tasks.
         '''
         with self.mutex:
             self.is_shutdown = True

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: arch...@mail-archive.com

Reply via email to