Skip to content

Commit e68f7e0

Browse files
committed
Merge branch 'main' into pythongh-115999-refactor-load-global
2 parents d00adef + 447a151 commit e68f7e0

File tree

94 files changed

+7000
-4401
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

94 files changed

+7000
-4401
lines changed

Doc/c-api/tuple.rst

+2-1
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,8 @@ type.
167167
168168
.. c:member:: const char *name
169169
170-
Name of the struct sequence type.
170+
Fully qualified name of the type; null-terminated UTF-8 encoded.
171+
The name must contain the module name.
171172
172173
.. c:member:: const char *doc
173174

Doc/c-api/unicode.rst

+25
Original file line numberDiff line numberDiff line change
@@ -1438,6 +1438,31 @@ They all return ``NULL`` or ``-1`` if an exception occurs.
14381438
This function returns ``-1`` upon failure, so one should call
14391439
:c:func:`PyErr_Occurred` to check for errors.
14401440
1441+
.. seealso::
1442+
1443+
The :c:func:`PyUnicode_Equal` function.
1444+
1445+
1446+
.. c:function:: int PyUnicode_Equal(PyObject *a, PyObject *b)
1447+
1448+
Test if two strings are equal:
1449+
1450+
* Return ``1`` if *a* is equal to *b*.
1451+
* Return ``0`` if *a* is not equal to *b*.
1452+
* Set a :exc:`TypeError` exception and return ``-1`` if *a* or *b* is not a
1453+
:class:`str` object.
1454+
1455+
The function always succeeds if *a* and *b* are :class:`str` objects.
1456+
1457+
The function works for :class:`str` subclasses, but does not honor custom
1458+
``__eq__()`` method.
1459+
1460+
.. seealso::
1461+
1462+
The :c:func:`PyUnicode_Compare` function.
1463+
1464+
.. versionadded:: 3.14
1465+
14411466
14421467
.. c:function:: int PyUnicode_EqualToUTF8AndSize(PyObject *unicode, const char *string, Py_ssize_t size)
14431468

Doc/data/stable_abi.dat

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Doc/glossary.rst

+5-9
Original file line numberDiff line numberDiff line change
@@ -1160,16 +1160,12 @@ Glossary
11601160
(subscript) notation uses :class:`slice` objects internally.
11611161

11621162
soft deprecated
1163-
A soft deprecation can be used when using an API which should no longer
1164-
be used to write new code, but it remains safe to continue using it in
1165-
existing code. The API remains documented and tested, but will not be
1166-
developed further (no enhancement).
1163+
A soft deprecated API should not be used in new code,
1164+
but it is safe for already existing code to use it.
1165+
The API remains documented and tested, but will not be enhanced further.
11671166

1168-
The main difference between a "soft" and a (regular) "hard" deprecation
1169-
is that the soft deprecation does not imply scheduling the removal of the
1170-
deprecated API.
1171-
1172-
Another difference is that a soft deprecation does not issue a warning.
1167+
Soft deprecation, unlike normal deprecation, does not plan on removing the API
1168+
and will not emit warnings.
11731169

11741170
See `PEP 387: Soft Deprecation
11751171
<https://peps.python.org/pep-0387/#soft-deprecation>`_.

Doc/library/_thread.rst

+2-7
Original file line numberDiff line numberDiff line change
@@ -213,9 +213,8 @@ In addition to these methods, lock objects can also be used via the
213213

214214
.. index:: pair: module; signal
215215

216-
* Threads interact strangely with interrupts: the :exc:`KeyboardInterrupt`
217-
exception will be received by an arbitrary thread. (When the :mod:`signal`
218-
module is available, interrupts always go to the main thread.)
216+
* Interrupts always go to the main thread (the :exc:`KeyboardInterrupt`
217+
exception will be received by that thread.)
219218

220219
* Calling :func:`sys.exit` or raising the :exc:`SystemExit` exception is
221220
equivalent to calling :func:`_thread.exit`.
@@ -229,7 +228,3 @@ In addition to these methods, lock objects can also be used via the
229228
:keyword:`try` ... :keyword:`finally` clauses or executing object
230229
destructors.
231230

232-
* When the main thread exits, it does not do any of its usual cleanup (except
233-
that :keyword:`try` ... :keyword:`finally` clauses are honored), and the
234-
standard I/O files are not flushed.
235-

Doc/library/importlib.metadata.rst

+144-44
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,13 @@ You can also get a :ref:`distribution's version number <version>`, list its
100100
:ref:`requirements`.
101101

102102

103+
.. exception:: PackageNotFoundError
104+
105+
Subclass of :class:`ModuleNotFoundError` raised by several functions in this
106+
module when queried for a distribution package which is not installed in the
107+
current Python environment.
108+
109+
103110
Functional API
104111
==============
105112

@@ -111,31 +118,53 @@ This package provides the following functionality via its public API.
111118
Entry points
112119
------------
113120

114-
The ``entry_points()`` function returns a collection of entry points.
115-
Entry points are represented by ``EntryPoint`` instances;
116-
each ``EntryPoint`` has a ``.name``, ``.group``, and ``.value`` attributes and
117-
a ``.load()`` method to resolve the value. There are also ``.module``,
118-
``.attr``, and ``.extras`` attributes for getting the components of the
119-
``.value`` attribute.
121+
.. function:: entry_points(**select_params)
122+
123+
Returns a :class:`EntryPoints` instance describing entry points for the
124+
current environment. Any given keyword parameters are passed to the
125+
:meth:`!select` method for comparison to the attributes of
126+
the individual entry point definitions.
127+
128+
Note: it is not currently possible to query for entry points based on
129+
their :attr:`!EntryPoint.dist` attribute (as different :class:`!Distribution`
130+
instances do not currently compare equal, even if they have the same attributes)
131+
132+
.. class:: EntryPoints
133+
134+
Details of a collection of installed entry points.
135+
136+
Also provides a ``.groups`` attribute that reports all identifed entry
137+
point groups, and a ``.names`` attribute that reports all identified entry
138+
point names.
139+
140+
.. class:: EntryPoint
141+
142+
Details of an installed entry point.
143+
144+
Each :class:`!EntryPoint` instance has ``.name``, ``.group``, and ``.value``
145+
attributes and a ``.load()`` method to resolve the value. There are also
146+
``.module``, ``.attr``, and ``.extras`` attributes for getting the
147+
components of the ``.value`` attribute, and ``.dist`` for obtaining
148+
information regarding the distribution package that provides the entry point.
120149

121150
Query all entry points::
122151

123152
>>> eps = entry_points() # doctest: +SKIP
124153

125-
The ``entry_points()`` function returns an ``EntryPoints`` object,
126-
a collection of all ``EntryPoint`` objects with ``names`` and ``groups``
154+
The :func:`!entry_points` function returns a :class:`!EntryPoints` object,
155+
a collection of all :class:`!EntryPoint` objects with ``names`` and ``groups``
127156
attributes for convenience::
128157

129158
>>> sorted(eps.groups) # doctest: +SKIP
130159
['console_scripts', 'distutils.commands', 'distutils.setup_keywords', 'egg_info.writers', 'setuptools.installation']
131160

132-
``EntryPoints`` has a ``select`` method to select entry points
161+
:class:`!EntryPoints` has a :meth:`!select` method to select entry points
133162
matching specific properties. Select entry points in the
134163
``console_scripts`` group::
135164

136165
>>> scripts = eps.select(group='console_scripts') # doctest: +SKIP
137166

138-
Equivalently, since ``entry_points`` passes keyword arguments
167+
Equivalently, since :func:`!entry_points` passes keyword arguments
139168
through to select::
140169

141170
>>> scripts = entry_points(group='console_scripts') # doctest: +SKIP
@@ -189,31 +218,41 @@ for more information on entry points, their definition, and usage.
189218
Distribution metadata
190219
---------------------
191220

192-
Every `Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package>`_ includes some metadata,
193-
which you can extract using the
194-
``metadata()`` function::
221+
.. function:: metadata(distribution_name)
222+
223+
Return the distribution metadata corresponding to the named
224+
distribution package as a :class:`PackageMetadata` instance.
225+
226+
Raises :exc:`PackageNotFoundError` if the named distribution
227+
package is not installed in the current Python environment.
228+
229+
.. class:: PackageMetadata
230+
231+
A concrete implementation of the
232+
`PackageMetadata protocol <https://importlib-metadata.readthedocs.io/en/latest/api.html#importlib_metadata.PackageMetadata>`_.
233+
234+
In addition to providing the defined protocol methods and attributes, subscripting
235+
the instance is equivalent to calling the :meth:`!get` method.
236+
237+
Every `Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package>`_
238+
includes some metadata, which you can extract using the :func:`!metadata` function::
195239

196240
>>> wheel_metadata = metadata('wheel') # doctest: +SKIP
197241

198-
The keys of the returned data structure, a ``PackageMetadata``,
199-
name the metadata keywords, and
242+
The keys of the returned data structure name the metadata keywords, and
200243
the values are returned unparsed from the distribution metadata::
201244

202245
>>> wheel_metadata['Requires-Python'] # doctest: +SKIP
203246
'>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*'
204247

205-
``PackageMetadata`` also presents a ``json`` attribute that returns
248+
:class:`PackageMetadata` also presents a :attr:`!json` attribute that returns
206249
all the metadata in a JSON-compatible form per :PEP:`566`::
207250

208251
>>> wheel_metadata.json['requires_python']
209252
'>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*'
210253

211-
.. note::
212-
213-
The actual type of the object returned by ``metadata()`` is an
214-
implementation detail and should be accessed only through the interface
215-
described by the
216-
`PackageMetadata protocol <https://importlib-metadata.readthedocs.io/en/latest/api.html#importlib_metadata.PackageMetadata>`_.
254+
The full set of available metadata is not described here.
255+
See the PyPA `Core metadata specification <https://packaging.python.org/en/latest/specifications/core-metadata/#core-metadata>`_ for additional details.
217256

218257
.. versionchanged:: 3.10
219258
The ``Description`` is now included in the metadata when presented
@@ -227,7 +266,15 @@ all the metadata in a JSON-compatible form per :PEP:`566`::
227266
Distribution versions
228267
---------------------
229268

230-
The ``version()`` function is the quickest way to get a
269+
.. function:: version(distribution_name)
270+
271+
Return the installed distribution package version for the named
272+
distribution package.
273+
274+
Raises :exc:`PackageNotFoundError` if the named distribution
275+
package is not installed in the current Python environment.
276+
277+
The :func:`!version` function is the quickest way to get a
231278
`Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package>`_'s version
232279
number, as a string::
233280

@@ -240,12 +287,28 @@ number, as a string::
240287
Distribution files
241288
------------------
242289

243-
You can also get the full set of files contained within a distribution. The
244-
``files()`` function takes a `Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package>`_ name
245-
and returns all of the
246-
files installed by this distribution. Each file object returned is a
247-
``PackagePath``, a :class:`pathlib.PurePath` derived object with additional ``dist``,
248-
``size``, and ``hash`` properties as indicated by the metadata. For example::
290+
.. function:: files(distribution_name)
291+
292+
Return the full set of files contained within the named
293+
distribution package.
294+
295+
Raises :exc:`PackageNotFoundError` if the named distribution
296+
package is not installed in the current Python environment.
297+
298+
Returns :const:`None` if the distribution is found but the installation
299+
database records reporting the files associated with the distribuion package
300+
are missing.
301+
302+
.. class:: PackagePath
303+
304+
A :class:`pathlib.PurePath` derived object with additional ``dist``,
305+
``size``, and ``hash`` properties corresponding to the distribution
306+
package's installation metadata for that file.
307+
308+
The :func:`!files` function takes a
309+
`Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package>`_
310+
name and returns all of the files installed by this distribution. Each file is reported
311+
as a :class:`PackagePath` instance. For example::
249312

250313
>>> util = [p for p in files('wheel') if 'util.py' in str(p)][0] # doctest: +SKIP
251314
>>> util # doctest: +SKIP
@@ -268,16 +331,16 @@ Once you have the file, you can also read its contents::
268331
return s.encode('utf-8')
269332
return s
270333

271-
You can also use the ``locate`` method to get a the absolute path to the
272-
file::
334+
You can also use the :meth:`!locate` method to get the absolute
335+
path to the file::
273336

274337
>>> util.locate() # doctest: +SKIP
275338
PosixPath('/home/gustav/example/lib/site-packages/wheel/util.py')
276339

277340
In the case where the metadata file listing files
278-
(RECORD or SOURCES.txt) is missing, ``files()`` will
279-
return ``None``. The caller may wish to wrap calls to
280-
``files()`` in `always_iterable
341+
(``RECORD`` or ``SOURCES.txt``) is missing, :func:`!files` will
342+
return :const:`None`. The caller may wish to wrap calls to
343+
:func:`!files` in `always_iterable
281344
<https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.always_iterable>`_
282345
or otherwise guard against this condition if the target
283346
distribution is not known to have the metadata present.
@@ -287,8 +350,16 @@ distribution is not known to have the metadata present.
287350
Distribution requirements
288351
-------------------------
289352

353+
.. function:: requires(distribution_name)
354+
355+
Return the declared dependency specifiers for the named
356+
distribution package.
357+
358+
Raises :exc:`PackageNotFoundError` if the named distribution
359+
package is not installed in the current Python environment.
360+
290361
To get the full set of requirements for a `Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package>`_,
291-
use the ``requires()``
362+
use the :func:`!requires`
292363
function::
293364

294365
>>> requires('wheel') # doctest: +SKIP
@@ -301,6 +372,16 @@ function::
301372
Mapping import to distribution packages
302373
---------------------------------------
303374

375+
.. function:: packages_distributions()
376+
377+
Return a mapping from the top level module and import package
378+
names found via :attr:`sys.meta_path` to the names of the distribution
379+
packages (if any) that provide the corresponding files.
380+
381+
To allow for namespace packages (which may have members provided by
382+
multiple distribution packages), each top level import name maps to a
383+
list of distribution names rather than mapping directly to a single name.
384+
304385
A convenience method to resolve the `Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package>`_
305386
name (or names, in the case of a namespace package)
306387
that provide each importable top-level
@@ -320,23 +401,42 @@ function is not reliable with such installs.
320401
Distributions
321402
=============
322403

323-
While the above API is the most common and convenient usage, you can get all
324-
of that information from the ``Distribution`` class. A ``Distribution`` is an
325-
abstract object that represents the metadata for
326-
a Python `Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package>`_. You can
327-
get the ``Distribution`` instance::
404+
.. function:: distribution(distribution_name)
405+
406+
Return a :class:`Distribution` instance describing the named
407+
distribution package.
408+
409+
Raises :exc:`PackageNotFoundError` if the named distribution
410+
package is not installed in the current Python environment.
411+
412+
.. class:: Distribution
413+
414+
Details of an installed distribution package.
415+
416+
Note: different :class:`!Distribution` instances do not currently compare
417+
equal, even if they relate to the same installed distribution and
418+
accordingly have the same attributes.
419+
420+
While the module level API described above is the most common and convenient usage,
421+
you can get all of that information from the :class:`!Distribution` class.
422+
:class:`!Distribution` is an abstract object that represents the metadata for
423+
a Python `Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package>`_.
424+
You can get the concreate :class:`!Distribution` subclass instance for an installed
425+
distribution package by calling the :func:`distribution` function::
328426

329427
>>> from importlib.metadata import distribution # doctest: +SKIP
330428
>>> dist = distribution('wheel') # doctest: +SKIP
429+
>>> type(dist) # doctest: +SKIP
430+
<class 'importlib.metadata.PathDistribution'>
331431

332432
Thus, an alternative way to get the version number is through the
333-
``Distribution`` instance::
433+
:class:`!Distribution` instance::
334434

335435
>>> dist.version # doctest: +SKIP
336436
'0.32.3'
337437

338-
There are all kinds of additional metadata available on the ``Distribution``
339-
instance::
438+
There are all kinds of additional metadata available on :class:`!Distribution`
439+
instances::
340440

341441
>>> dist.metadata['Requires-Python'] # doctest: +SKIP
342442
'>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*'
@@ -350,7 +450,7 @@ metadata::
350450
'file:///path/to/wheel-0.32.3.editable-py3-none-any.whl'
351451

352452
The full set of available metadata is not described here.
353-
See the `Core metadata specifications <https://packaging.python.org/en/latest/specifications/core-metadata/#core-metadata>`_ for additional details.
453+
See the PyPA `Core metadata specification <https://packaging.python.org/en/latest/specifications/core-metadata/#core-metadata>`_ for additional details.
354454

355455
.. versionadded:: 3.13
356456
The ``.origin`` property was added.

0 commit comments

Comments
 (0)