https://github.com/python/cpython/commit/66b940c2f1fcb219bc2277ad5a2af04a0b…
commit: 66b940c2f1fcb219bc2277ad5a2af04a0b40abd1
branch: 3.13
author: Senthil Kumaran <senthil(a)python.org>
committer: orsenthil <senthil(a)python.org>
date: 2026-05-31T12:57:53-07:00
summary:
[3.13] gh-141444:fix broken URLs and examples in urllib.request.rst (GH-144863) (#150647)
* Doc: fix broken URLs and examples in urllib.request.rst (gh-141444)
* Doc: update urllib.request examples to handle gzip compression
---------
(cherry picked from commit 0f1f7c7889873deb7c2e2c3f18695bf636e7752c)
Co-authored-by: Paper Moon <tangyuan0821(a)email.cn>
files:
M Doc/library/urllib.request.rst
diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst
index 04f5466c1a2c51..945c96892f592a 100644
--- a/Doc/library/urllib.request.rst
+++ b/Doc/library/urllib.request.rst
@@ -1007,7 +1007,7 @@ AbstractBasicAuthHandler Objects
*headers* should be the error headers.
*host* is either an authority (e.g. ``"python.org"``) or a URL containing an
- authority component (e.g. ``"http://python.org/"``). In either case, the
+ authority component (e.g. ``"https://python.org/"``). In either case, the
authority must not contain a userinfo component (so, ``"python.org"`` and
``"python.org:80"`` are fine, ``"joe:password@python.org"`` is not).
@@ -1203,10 +1203,14 @@ This example gets the python.org main page and displays the first 300 bytes of
it::
>>> import urllib.request
- >>> with urllib.request.urlopen('http://www.python.org/') as f:
- ... print(f.read(300))
- ...
- b'<!doctype html>\n<!--[if lt IE 7]> <html class="no-js ie6 lt-ie7 lt-ie8 lt-ie9"> <![endif]-->\n<!--[if IE 7]> <html class="no-js ie7 lt-ie8 lt-ie9"> <![endif]-->\n<!--[if IE 8]> <html class="no-js ie8 lt-ie9">
+ >>> with urllib.request.urlopen('https://www.python.org/') as f:
+ ... # The response may be compressed (for example, 'gzip').
+ ... print(f.headers.get('Content-Encoding'))
+ ... data = f.read()
+ ... if f.headers.get('Content-Encoding') == 'gzip':
+ ... import gzip
+ ... data = gzip.decompress(data)
+ ... print(data[:300].decode('utf-8', errors='replace'))
Note that urlopen returns a bytes object. This is because there is no way
for urlopen to automatically determine the encoding of the byte stream
@@ -1223,26 +1227,30 @@ For additional information, see the W3C document: https://www.w3.org/Internation
As the python.org website uses *utf-8* encoding as specified in its meta tag, we
will use the same for decoding the bytes object::
- >>> with urllib.request.urlopen('http://www.python.org/') as f:
- ... print(f.read(100).decode('utf-8'))
+ >>> with urllib.request.urlopen('https://www.python.org/') as f:
+ ... # Check for compression and decode appropriately.
+ ... enc = f.headers.get('Content-Encoding')
+ ... data = f.read()
+ ... if enc == 'gzip':
+ ... import gzip
+ ... data = gzip.decompress(data)
+ ... print(data[:100].decode('utf-8', errors='replace'))
...
- <!doctype html>
- <!--[if lt IE 7]> <html class="no-js ie6 lt-ie7 lt-ie8 lt-ie9"> <![endif]-->
- <!-
It is also possible to achieve the same result without using the
:term:`context manager` approach::
>>> import urllib.request
- >>> f = urllib.request.urlopen('http://www.python.org/')
+ >>> f = urllib.request.urlopen('https://www.python.org/')
>>> try:
- ... print(f.read(100).decode('utf-8'))
+ ... enc = f.headers.get('Content-Encoding')
+ ... data = f.read()
+ ... if enc == 'gzip':
+ ... import gzip
+ ... data = gzip.decompress(data)
+ ... print(data[:100].decode('utf-8', errors='replace'))
... finally:
... f.close()
- ...
- <!doctype html>
- <!--[if lt IE 7]> <html class="no-js ie6 lt-ie7 lt-ie8 lt-ie9"> <![endif]-->
- <!--
In the following example, we are sending a data-stream to the stdin of a CGI
and reading the data it returns to us. Note that this example will only work
@@ -1313,7 +1321,7 @@ Use the *headers* argument to the :class:`Request` constructor, or::
import urllib.request
req = urllib.request.Request('http://www.example.com/')
- req.add_header('Referer', 'http://www.python.org/')
+ req.add_header('Referer', 'https://www.python.org/')
# Customize the default User-Agent header value:
req.add_header('User-Agent', 'urllib-example/0.1 (Contact: . . .)')
with urllib.request.urlopen(req) as f:
@@ -1342,7 +1350,7 @@ containing parameters::
>>> import urllib.request
>>> import urllib.parse
>>> params = urllib.parse.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
- >>> url = "http://www.musi-cal.com/cgi-bin/query?%s" % params
+ >>> url = "https://www.python.org/?%s" % params
>>> with urllib.request.urlopen(url) as f:
... print(f.read().decode('utf-8'))
...
@@ -1354,7 +1362,7 @@ from urlencode is encoded to bytes before it is sent to urlopen as data::
>>> import urllib.parse
>>> data = urllib.parse.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
>>> data = data.encode('ascii')
- >>> with urllib.request.urlopen("http://requestb.in/xrbl82xr", data) as f:
+ >>> with urllib.request.urlopen("https://httpbin.org/post", data) as f:
... print(f.read().decode('utf-8'))
...
@@ -1363,16 +1371,16 @@ environment settings::
>>> import urllib.request
>>> proxies = {'http': 'http://proxy.example.com:8080/'}
- >>> opener = urllib.request.FancyURLopener(proxies)
- >>> with opener.open("http://www.python.org") as f:
+ >>> opener = urllib.request.build_opener(urllib.request.ProxyHandler(proxies))
+ >>> with opener.open("https://www.python.org") as f:
... f.read().decode('utf-8')
...
The following example uses no proxies at all, overriding environment settings::
>>> import urllib.request
- >>> opener = urllib.request.FancyURLopener({})
- >>> with opener.open("http://www.python.org/") as f:
+ >>> opener = urllib.request.build_opener(urllib.request.ProxyHandler({}))
+ >>> with opener.open("https://www.python.org/") as f:
... f.read().decode('utf-8')
...
@@ -1405,7 +1413,7 @@ some point in the future.
The following example illustrates the most common usage scenario::
>>> import urllib.request
- >>> local_filename, headers = urllib.request.urlretrieve('http://python.org/')
+ >>> local_filename, headers = urllib.request.urlretrieve('https://python.org/')
>>> html = open(local_filename)
>>> html.close()
https://github.com/python/cpython/commit/fed5c744dfff9a4cae04becf6cc33228f3…
commit: fed5c744dfff9a4cae04becf6cc33228f31793c6
branch: 3.15
author: Miss Islington (bot) <31488909+miss-islington(a)users.noreply.github.com>
committer: StanFromIreland <stan(a)python.org>
date: 2026-05-31T20:21:08+01:00
summary:
[3.15] gh-140553: Mark `*gettext` parameters as positionaly only in documentation (GH-140598)
(cherry picked from commit 1837c17bc78b8169cd6c1c5799dcf6a71c3eac83)
Co-authored-by: Stan Ulbrych <stan(a)python.org>
files:
M Doc/library/gettext.rst
diff --git a/Doc/library/gettext.rst b/Doc/library/gettext.rst
index 2de16fe40362b3..2ab7ba7df19cf1 100644
--- a/Doc/library/gettext.rst
+++ b/Doc/library/gettext.rst
@@ -51,19 +51,19 @@ class-based API instead.
.. index:: single: _ (underscore); gettext
-.. function:: gettext(message)
+.. function:: gettext(message, /)
Return the localized translation of *message*, based on the current global
domain, language, and locale directory. This function is usually aliased as
:func:`!_` in the local namespace (see examples below).
-.. function:: dgettext(domain, message)
+.. function:: dgettext(domain, message, /)
Like :func:`.gettext`, but look the message up in the specified *domain*.
-.. function:: ngettext(singular, plural, n)
+.. function:: ngettext(singular, plural, n, /)
Like :func:`.gettext`, but consider plural forms. If a translation is found,
apply the plural formula to *n*, and return the resulting message (some
@@ -78,15 +78,15 @@ class-based API instead.
formulas for a variety of languages.
-.. function:: dngettext(domain, singular, plural, n)
+.. function:: dngettext(domain, singular, plural, n, /)
Like :func:`ngettext`, but look the message up in the specified *domain*.
-.. function:: pgettext(context, message)
-.. function:: dpgettext(domain, context, message)
-.. function:: npgettext(context, singular, plural, n)
-.. function:: dnpgettext(domain, context, singular, plural, n)
+.. function:: pgettext(context, message, /)
+.. function:: dpgettext(domain, context, message, /)
+.. function:: npgettext(context, singular, plural, n, /)
+.. function:: dnpgettext(domain, context, singular, plural, n, /)
Similar to the corresponding functions without the ``p`` in the prefix (that
is, :func:`gettext`, :func:`dgettext`, :func:`ngettext`, :func:`dngettext`),
@@ -223,20 +223,20 @@ are the methods of :class:`!NullTranslations`:
translation for a given message.
- .. method:: gettext(message)
+ .. method:: gettext(message, /)
If a fallback has been set, forward :meth:`!gettext` to the fallback.
Otherwise, return *message*. Overridden in derived classes.
- .. method:: ngettext(singular, plural, n)
+ .. method:: ngettext(singular, plural, n, /)
If a fallback has been set, forward :meth:`!ngettext` to the fallback.
Otherwise, return *singular* if *n* is 1; return *plural* otherwise.
Overridden in derived classes.
- .. method:: pgettext(context, message)
+ .. method:: pgettext(context, message, /)
If a fallback has been set, forward :meth:`pgettext` to the fallback.
Otherwise, return the translated message. Overridden in derived classes.
@@ -244,7 +244,7 @@ are the methods of :class:`!NullTranslations`:
.. versionadded:: 3.8
- .. method:: npgettext(context, singular, plural, n)
+ .. method:: npgettext(context, singular, plural, n, /)
If a fallback has been set, forward :meth:`npgettext` to the fallback.
Otherwise, return the translated message. Overridden in derived classes.
@@ -322,7 +322,7 @@ unexpected, or if other problems occur while reading the file, instantiating a
The following methods are overridden from the base class implementation:
- .. method:: gettext(message)
+ .. method:: gettext(message, /)
Look up the *message* id in the catalog and return the corresponding message
string, as a Unicode string. If there is no entry in the catalog for the
@@ -331,7 +331,7 @@ unexpected, or if other problems occur while reading the file, instantiating a
*message* id is returned.
- .. method:: ngettext(singular, plural, n)
+ .. method:: ngettext(singular, plural, n, /)
Do a plural-forms lookup of a message id. *singular* is used as the message id
for purposes of lookup in the catalog, while *n* is used to determine which
@@ -352,7 +352,7 @@ unexpected, or if other problems occur while reading the file, instantiating a
n) % {'num': n}
- .. method:: pgettext(context, message)
+ .. method:: pgettext(context, message, /)
Look up the *context* and *message* id in the catalog and return the
corresponding message string, as a Unicode string. If there is no
@@ -363,7 +363,7 @@ unexpected, or if other problems occur while reading the file, instantiating a
.. versionadded:: 3.8
- .. method:: npgettext(context, singular, plural, n)
+ .. method:: npgettext(context, singular, plural, n, /)
Do a plural-forms lookup of a message id. *singular* is used as the
message id for purposes of lookup in the catalog, while *n* is used to
https://github.com/python/cpython/commit/ea58c352b717c8ea06a43c76bf99985bd4…
commit: ea58c352b717c8ea06a43c76bf99985bd42c288b
branch: 3.15
author: Miss Islington (bot) <31488909+miss-islington(a)users.noreply.github.com>
committer: serhiy-storchaka <storchaka(a)gmail.com>
date: 2026-05-31T12:19:43Z
summary:
[3.15] Clarify docs for scheduler.run(blocking=False) (GH-129575) (GH-150668)
(cherry picked from commit 2f8f569ba911ab3cff1356a15a3e688adc4ae917)
Co-authored-by: M. Greyson Christoforo <grey(a)christoforo.net>
files:
M Doc/library/sched.rst
diff --git a/Doc/library/sched.rst b/Doc/library/sched.rst
index 70541c5f3cb367..037e27f031d0c8 100644
--- a/Doc/library/sched.rst
+++ b/Doc/library/sched.rst
@@ -117,9 +117,11 @@ Scheduler Objects
function passed to the constructor) for the next event, then execute it and so
on until there are no more scheduled events.
- If *blocking* is false executes the scheduled events due to expire soonest
- (if any) and then return the deadline of the next scheduled call in the
- scheduler (if any).
+ If *blocking* is false, immediately executes all events in the queue which have
+ a time value less than or equal to the current *timefunc* value (if any) and
+ returns the difference between the current *timefunc* value and the time value
+ of the next scheduled event in the scheduler's event queue. If the queue is
+ empty, returns ``None``.
Either *action* or *delayfunc* can raise an exception. In either case, the
scheduler will maintain a consistent state and propagate the exception. If an
https://github.com/python/cpython/commit/27051b7ce151b15607cc63ad1c57c72b18…
commit: 27051b7ce151b15607cc63ad1c57c72b181cd1be
branch: 3.14
author: Miss Islington (bot) <31488909+miss-islington(a)users.noreply.github.com>
committer: serhiy-storchaka <storchaka(a)gmail.com>
date: 2026-05-31T12:18:57Z
summary:
[3.14] Clarify docs for scheduler.run(blocking=False) (GH-129575) (GH-150669)
(cherry picked from commit 2f8f569ba911ab3cff1356a15a3e688adc4ae917)
Co-authored-by: M. Greyson Christoforo <grey(a)christoforo.net>
files:
M Doc/library/sched.rst
diff --git a/Doc/library/sched.rst b/Doc/library/sched.rst
index 5560478ce15e28..302231d95f8979 100644
--- a/Doc/library/sched.rst
+++ b/Doc/library/sched.rst
@@ -119,9 +119,11 @@ Scheduler Objects
function passed to the constructor) for the next event, then execute it and so
on until there are no more scheduled events.
- If *blocking* is false executes the scheduled events due to expire soonest
- (if any) and then return the deadline of the next scheduled call in the
- scheduler (if any).
+ If *blocking* is false, immediately executes all events in the queue which have
+ a time value less than or equal to the current *timefunc* value (if any) and
+ returns the difference between the current *timefunc* value and the time value
+ of the next scheduled event in the scheduler's event queue. If the queue is
+ empty, returns ``None``.
Either *action* or *delayfunc* can raise an exception. In either case, the
scheduler will maintain a consistent state and propagate the exception. If an
https://github.com/python/cpython/commit/ca2fdca9482a8b2da10b0bc99bcc1346f5…
commit: ca2fdca9482a8b2da10b0bc99bcc1346f5b51121
branch: 3.13
author: Miss Islington (bot) <31488909+miss-islington(a)users.noreply.github.com>
committer: serhiy-storchaka <storchaka(a)gmail.com>
date: 2026-05-31T12:18:09Z
summary:
[3.13] Clarify docs for scheduler.run(blocking=False) (GH-129575) (GH-150670)
(cherry picked from commit 2f8f569ba911ab3cff1356a15a3e688adc4ae917)
Co-authored-by: M. Greyson Christoforo <grey(a)christoforo.net>
files:
M Doc/library/sched.rst
diff --git a/Doc/library/sched.rst b/Doc/library/sched.rst
index 517dbe8c321898..44858c2c98782a 100644
--- a/Doc/library/sched.rst
+++ b/Doc/library/sched.rst
@@ -119,9 +119,11 @@ Scheduler Objects
function passed to the constructor) for the next event, then execute it and so
on until there are no more scheduled events.
- If *blocking* is false executes the scheduled events due to expire soonest
- (if any) and then return the deadline of the next scheduled call in the
- scheduler (if any).
+ If *blocking* is false, immediately executes all events in the queue which have
+ a time value less than or equal to the current *timefunc* value (if any) and
+ returns the difference between the current *timefunc* value and the time value
+ of the next scheduled event in the scheduler's event queue. If the queue is
+ empty, returns ``None``.
Either *action* or *delayfunc* can raise an exception. In either case, the
scheduler will maintain a consistent state and propagate the exception. If an
https://github.com/python/cpython/commit/2fb2a23cbd41b640afda105ed767778ab1…
commit: 2fb2a23cbd41b640afda105ed767778ab191cbee
branch: 3.15
author: Miss Islington (bot) <31488909+miss-islington(a)users.noreply.github.com>
committer: serhiy-storchaka <storchaka(a)gmail.com>
date: 2026-05-31T12:16:58Z
summary:
[3.15] gh-150636: Clarify difference between copy.copy() and the copy() methods (GH-150637) (GH-150665)
(cherry picked from commit 1de909b32411fc1c4d4c42b4f8221b86096c6353)
Co-authored-by: Serhiy Storchaka <storchaka(a)gmail.com>
Co-authored-by: Pieter Eendebak <pieter.eendebak(a)gmail.com>
Co-authored-by: Stan Ulbrych <stan(a)python.org>
files:
M Doc/library/copy.rst
diff --git a/Doc/library/copy.rst b/Doc/library/copy.rst
index 121c44a16ad43b..39fc7800d03a91 100644
--- a/Doc/library/copy.rst
+++ b/Doc/library/copy.rst
@@ -72,9 +72,13 @@ file, socket, window, or any similar types. It does "copy" functions and
classes (shallow and deeply), by returning the original object unchanged; this
is compatible with the way these are treated by the :mod:`pickle` module.
-Shallow copies of dictionaries can be made using :meth:`dict.copy`, and
-of lists by assigning a slice of the entire list, for example,
-``copied_list = original_list[:]``.
+Shallow copies of many collections can be made using the corresponding
+:meth:`!copy` method (such as :meth:`list.copy`, :meth:`dict.copy` or
+:meth:`set.copy`), and of sequences (such as lists or bytearrays) by making
+a slice of the entire sequence (``sequence[:]``).
+However, these methods and slicing can create an instance of the base type
+when copying an instance of a subclass, whereas :func:`copy.copy` normally
+returns an instance of the same type.
.. index:: pair: module; pickle