Skip to content

Commit

Permalink
Merge branch 'main' into remove-imp
Browse files Browse the repository at this point in the history
  • Loading branch information
warsaw committed Apr 23, 2023
2 parents c45ba31 + e38bebb commit eee4ae6
Show file tree
Hide file tree
Showing 114 changed files with 8,679 additions and 4,508 deletions.
18 changes: 18 additions & 0 deletions Doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,24 @@
r'https://github.com/python/cpython/tree/.*': 'https://github.com/python/cpython/blob/.*'
}

linkcheck_anchors_ignore = [
# ignore anchors that start with a '/', e.g. Wikipedia media files:
# https://en.wikipedia.org/wiki/Walrus#/media/File:Pacific_Walrus_-_Bull_(8247646168).jpg
r'\/.*',
]

linkcheck_ignore = [
# The crawler gets "Anchor not found"
r'https://developer.apple.com/documentation/.+?#.*',
r'https://devguide.python.org.+?/#.*',
r'https://github.com.+?#.*',
# Robot crawlers not allowed: "403 Client Error: Forbidden"
r'https://support.enthought.com/hc/.*',
# SSLError CertificateError, even though it is valid
r'https://unix.org/version2/whatsnew/lp64_wp.html',
]


# Options for extensions
# ----------------------

Expand Down
12 changes: 4 additions & 8 deletions Doc/distributing/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -129,14 +129,10 @@ involved in creating and publishing a project:
* `Uploading the project to the Python Package Index`_
* `The .pypirc file`_

.. _Project structure: \
https://packaging.python.org/tutorials/packaging-projects/#packaging-python-projects
.. _Building and packaging the project: \
https://packaging.python.org/tutorials/packaging-projects/#creating-the-package-files
.. _Uploading the project to the Python Package Index: \
https://packaging.python.org/tutorials/packaging-projects/#uploading-the-distribution-archives
.. _The .pypirc file: \
https://packaging.python.org/specifications/pypirc/
.. _Project structure: https://packaging.python.org/tutorials/packaging-projects/#packaging-python-projects
.. _Building and packaging the project: https://packaging.python.org/tutorials/packaging-projects/#creating-the-package-files
.. _Uploading the project to the Python Package Index: https://packaging.python.org/tutorials/packaging-projects/#uploading-the-distribution-archives
.. _The .pypirc file: https://packaging.python.org/specifications/pypirc/


How do I...?
Expand Down
2 changes: 1 addition & 1 deletion Doc/faq/library.rst
Original file line number Diff line number Diff line change
Expand Up @@ -780,7 +780,7 @@ socket to :meth:`select.select` to check if it's writable.
The :mod:`asyncio` module provides a general purpose single-threaded and
concurrent asynchronous library, which can be used for writing non-blocking
network code.
The third-party `Twisted <https://twistedmatrix.com/trac/>`_ library is
The third-party `Twisted <https://twisted.org/>`_ library is
a popular and feature-rich alternative.
Expand Down
98 changes: 90 additions & 8 deletions Doc/howto/descriptor.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1273,37 +1273,86 @@ Using the non-data descriptor protocol, a pure Python version of

.. testcode::

import functools

class StaticMethod:
"Emulate PyStaticMethod_Type() in Objects/funcobject.c"

def __init__(self, f):
self.f = f
functools.update_wrapper(self, f)

def __get__(self, obj, objtype=None):
return self.f

def __call__(self, *args, **kwds):
return self.f(*args, **kwds)
The :func:`functools.update_wrapper` call adds a ``__wrapped__`` attribute
that refers to the underlying function. Also it carries forward
the attributes necessary to make the wrapper look like the wrapped
function: ``__name__``, ``__qualname__``, ``__doc__``, and ``__annotations__``.

.. testcode::
:hide:

class E_sim:
@StaticMethod
def f(x):
return x * 10
def f(x: int) -> str:
"Simple function example"
return "!" * x

wrapped_ord = StaticMethod(ord)

.. doctest::
:hide:

>>> E_sim.f(3)
30
'!!!'
>>> E_sim().f(3)
30
'!!!'

>>> sm = vars(E_sim)['f']
>>> type(sm).__name__
'StaticMethod'
>>> f = E_sim.f
>>> type(f).__name__
'function'
>>> sm.__name__
'f'
>>> f.__name__
'f'
>>> sm.__qualname__
'E_sim.f'
>>> f.__qualname__
'E_sim.f'
>>> sm.__doc__
'Simple function example'
>>> f.__doc__
'Simple function example'
>>> sm.__annotations__
{'x': <class 'int'>, 'return': <class 'str'>}
>>> f.__annotations__
{'x': <class 'int'>, 'return': <class 'str'>}
>>> sm.__module__ == f.__module__
True
>>> sm(3)
'!!!'
>>> f(3)
'!!!'

>>> wrapped_ord('A')
65
>>> wrapped_ord.__module__ == ord.__module__
True
>>> wrapped_ord.__wrapped__ == ord
True
>>> wrapped_ord.__name__ == ord.__name__
True
>>> wrapped_ord.__qualname__ == ord.__qualname__
True
>>> wrapped_ord.__doc__ == ord.__doc__
True


Class methods
Expand Down Expand Up @@ -1359,11 +1408,14 @@ Using the non-data descriptor protocol, a pure Python version of

.. testcode::

import functools

class ClassMethod:
"Emulate PyClassMethod_Type() in Objects/funcobject.c"

def __init__(self, f):
self.f = f
functools.update_wrapper(self, f)

def __get__(self, obj, cls=None):
if cls is None:
Expand All @@ -1380,8 +1432,9 @@ Using the non-data descriptor protocol, a pure Python version of
# Verify the emulation works
class T:
@ClassMethod
def cm(cls, x, y):
return (cls, x, y)
def cm(cls, x: int, y: str) -> tuple[str, int, str]:
"Class method that returns a tuple"
return (cls.__name__, x, y)

@ClassMethod
@property
Expand All @@ -1393,17 +1446,40 @@ Using the non-data descriptor protocol, a pure Python version of
:hide:

>>> T.cm(11, 22)
(<class 'T'>, 11, 22)
('T', 11, 22)

# Also call it from an instance
>>> t = T()
>>> t.cm(11, 22)
(<class 'T'>, 11, 22)
('T', 11, 22)

# Check the alternate path for chained descriptors
>>> T.__doc__
"A doc for 'T'"

# Verify that T uses our emulation
>>> type(vars(T)['cm']).__name__
'ClassMethod'

# Verify that update_wrapper() correctly copied attributes
>>> T.cm.__name__
'cm'
>>> T.cm.__qualname__
'T.cm'
>>> T.cm.__doc__
'Class method that returns a tuple'
>>> T.cm.__annotations__
{'x': <class 'int'>, 'y': <class 'str'>, 'return': tuple[str, int, str]}

# Verify that __wrapped__ was added and works correctly
>>> f = vars(T)['cm'].__wrapped__
>>> type(f).__name__
'function'
>>> f.__name__
'cm'
>>> f(T, 11, 22)
('T', 11, 22)


The code path for ``hasattr(type(self.f), '__get__')`` was added in
Python 3.9 and makes it possible for :func:`classmethod` to support
Expand All @@ -1423,6 +1499,12 @@ chained together. In Python 3.11, this functionality was deprecated.
>>> G.__doc__
"A doc for 'G'"

The :func:`functools.update_wrapper` call in ``ClassMethod`` adds a
``__wrapped__`` attribute that refers to the underlying function. Also
it carries forward the attributes necessary to make the wrapper look
like the wrapped function: ``__name__``, ``__qualname__``, ``__doc__``,
and ``__annotations__``.


Member objects and __slots__
----------------------------
Expand Down
4 changes: 2 additions & 2 deletions Doc/howto/functional.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1208,8 +1208,8 @@ General
-------

**Structure and Interpretation of Computer Programs**, by Harold Abelson and
Gerald Jay Sussman with Julie Sussman. Full text at
https://mitpress.mit.edu/sicp/. In this classic textbook of computer science,
Gerald Jay Sussman with Julie Sussman. The book can be found at
https://mitpress.mit.edu/sicp. In this classic textbook of computer science,
chapters 2 and 3 discuss the use of sequences and streams to organize the data
flow inside a program. The book uses Scheme for its examples, but many of the
design approaches described in these chapters are applicable to functional-style
Expand Down
4 changes: 2 additions & 2 deletions Doc/howto/urllib2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ response::

import urllib.request

req = urllib.request.Request('http://www.voidspace.org.uk')
req = urllib.request.Request('http://python.org/')
with urllib.request.urlopen(req) as response:
the_page = response.read()

Expand Down Expand Up @@ -458,7 +458,7 @@ To illustrate creating and installing a handler we will use the
``HTTPBasicAuthHandler``. For a more detailed discussion of this subject --
including an explanation of how Basic Authentication works - see the `Basic
Authentication Tutorial
<http://www.voidspace.org.uk/python/articles/authentication.shtml>`_.
<https://web.archive.org/web/20201215133350/http://www.voidspace.org.uk/python/articles/authentication.shtml>`__.

When authentication is required, the server sends a header (as well as the 401
error code) requesting authentication. This specifies the authentication scheme
Expand Down
15 changes: 10 additions & 5 deletions Doc/library/asyncio-task.rst
Original file line number Diff line number Diff line change
Expand Up @@ -256,8 +256,9 @@ Creating Tasks

.. note::

:meth:`asyncio.TaskGroup.create_task` is a newer alternative
that allows for convenient waiting for a group of related tasks.
:meth:`asyncio.TaskGroup.create_task` is a new alternative
leveraging structural concurrency; it allows for waiting
for a group of related tasks with strong safety guarantees.

.. important::

Expand Down Expand Up @@ -340,7 +341,7 @@ Example::
async with asyncio.TaskGroup() as tg:
task1 = tg.create_task(some_coro(...))
task2 = tg.create_task(another_coro(...))
print("Both tasks have completed now.")
print(f"Both tasks have completed now: {task1.result()}, {task2.result()}")

The ``async with`` statement will wait for all tasks in the group to finish.
While waiting, new tasks may still be added to the group
Expand Down Expand Up @@ -459,8 +460,12 @@ Running Tasks Concurrently
Tasks/Futures to be cancelled.

.. note::
A more modern way to create and run tasks concurrently and
wait for their completion is :class:`asyncio.TaskGroup`.
A new alternative to create and run tasks concurrently and
wait for their completion is :class:`asyncio.TaskGroup`. *TaskGroup*
provides stronger safety guarantees than *gather* for scheduling a nesting of subtasks:
if a task (or a subtask, a task scheduled by a task)
raises an exception, *TaskGroup* will, while *gather* will not,
cancel the remaining scheduled tasks).

.. _asyncio_example_gather:

Expand Down
23 changes: 16 additions & 7 deletions Doc/library/functools.rst
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,13 @@ The :mod:`functools` module defines the following functions:
>>> factorial(12) # makes two new recursive calls, the other 10 are cached
479001600

The cache is threadsafe so the wrapped function can be used in multiple
threads.
The cache is threadsafe so that the wrapped function can be used in
multiple threads. This means that the underlying data structure will
remain coherent during concurrent updates.

It is possible for the wrapped function to be called more than once if
another thread makes an additional call before the initial call has been
completed and cached.

.. versionadded:: 3.9

Expand Down Expand Up @@ -118,6 +123,7 @@ The :mod:`functools` module defines the following functions:
def stdev(self):
return statistics.stdev(self._data)

.. versionadded:: 3.8

.. versionchanged:: 3.12
Prior to Python 3.12, ``cached_property`` included an undocumented lock to
Expand All @@ -126,8 +132,6 @@ The :mod:`functools` module defines the following functions:
per-instance, which could result in unacceptably high lock contention. In
Python 3.12+ this locking is removed.

.. versionadded:: 3.8


.. function:: cmp_to_key(func)

Expand Down Expand Up @@ -159,8 +163,13 @@ The :mod:`functools` module defines the following functions:
*maxsize* most recent calls. It can save time when an expensive or I/O bound
function is periodically called with the same arguments.

The cache is threadsafe so the wrapped function can be used in multiple
threads.
The cache is threadsafe so that the wrapped function can be used in
multiple threads. This means that the underlying data structure will
remain coherent during concurrent updates.

It is possible for the wrapped function to be called more than once if
another thread makes an additional call before the initial call has been
completed and cached.

Since a dictionary is used to cache results, the positional and keyword
arguments to the function must be :term:`hashable`.
Expand Down Expand Up @@ -233,7 +242,7 @@ The :mod:`functools` module defines the following functions:
@lru_cache(maxsize=32)
def get_pep(num):
'Retrieve text of a Python Enhancement Proposal'
resource = 'https://peps.python.org/pep-%04d/' % num
resource = f'https://peps.python.org/pep-{num:04d}'
try:
with urllib.request.urlopen(resource) as s:
return s.read()
Expand Down
4 changes: 4 additions & 0 deletions Doc/library/importlib.metadata.rst
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,10 @@ Python module or `Import Package <https://packaging.python.org/en/latest/glossar
>>> packages_distributions()
{'importlib_metadata': ['importlib-metadata'], 'yaml': ['PyYAML'], 'jaraco': ['jaraco.classes', 'jaraco.functools'], ...}

Some editable installs, `do not supply top-level names
<https://github.com/pypa/packaging-problems/issues/609>`_, and thus this
function is not reliable with such installs.

.. versionadded:: 3.10

.. _distributions:
Expand Down
4 changes: 1 addition & 3 deletions Doc/library/multiprocessing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -452,9 +452,7 @@ process which created it.
importable by the children. This is covered in :ref:`multiprocessing-programming`
however it is worth pointing out here. This means that some examples, such
as the :class:`multiprocessing.pool.Pool` examples will not work in the
interactive interpreter. For example:

.. code-block:: text
interactive interpreter. For example::

>>> from multiprocessing import Pool
>>> p = Pool(5)
Expand Down
6 changes: 3 additions & 3 deletions Doc/library/pkgutil.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ support.
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)

This will add to the package's ``__path__`` all subdirectories of directories
on :data:`sys.path` named after the package. This is useful if one wants to
distribute different parts of a single logical package as multiple
For each directory on :data:`sys.path` that has a subdirectory that matches the
package name, add the subdirectory to the package's :attr:`__path__`. This is useful
if one wants to distribute different parts of a single logical package as multiple
directories.

It also looks for :file:`\*.pkg` files beginning where ``*`` matches the
Expand Down
2 changes: 1 addition & 1 deletion Doc/library/readline.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ function.

Readline keybindings may be configured via an initialization file, typically
``.inputrc`` in your home directory. See `Readline Init File
<https://tiswww.cwru.edu/php/chet/readline/rluserman.html#SEC9>`_
<https://tiswww.cwru.edu/php/chet/readline/rluserman.html#Readline-Init-File>`_
in the GNU Readline manual for information about the format and
allowable constructs of that file, and the capabilities of the
Readline library in general.
Expand Down

0 comments on commit eee4ae6

Please sign in to comment.