Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Doc/c-api/concrete.rst
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ Other Objects
picklebuffer.rst
weakref.rst
capsule.rst
sentinel.rst
frame.rst
gen.rst
coro.rst
Expand Down
35 changes: 35 additions & 0 deletions Doc/c-api/sentinel.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
.. highlight:: c

.. _sentinelobjects:

Sentinel objects
----------------

.. c:var:: PyTypeObject PySentinel_Type

This instance of :c:type:`PyTypeObject` represents the Python
:class:`sentinel` type. This is the same object as :class:`sentinel`.

.. versionadded:: next

.. c:function:: int PySentinel_Check(PyObject *o)

Return true if *o* is a :class:`sentinel` object. The :class:`sentinel` type
does not allow subclasses, so this check is exact.

.. versionadded:: next

.. c:function:: PyObject* PySentinel_New(const char *name, const char *module_name)

Return a new :class:`sentinel` object with :attr:`~sentinel.__name__` set to
*name* and :attr:`~sentinel.__module__` set to *module_name*.
*name* must not be ``NULL``. If *module_name* is ``NULL``, :attr:`~sentinel.__module__`
is set to ``None``.
Return ``NULL`` with an exception set on failure.

For pickling to work, *module_name* must be the name of an importable
module, and the sentinel must be accessible from that module under a
path matching *name*. Pickle treats *name* as a global variable name
in *module_name* (see :meth:`object.__reduce__`).

.. versionadded:: next
4 changes: 4 additions & 0 deletions Doc/data/refcounts.dat
Original file line number Diff line number Diff line change
Expand Up @@ -2037,6 +2037,10 @@ PySeqIter_Check:PyObject *:op:0:
PySeqIter_New:PyObject*::+1:
PySeqIter_New:PyObject*:seq:0:

PySentinel_New:PyObject*::+1:
PySentinel_New:const char*:name::
PySentinel_New:const char*:module_name::

PySequence_Check:int:::
PySequence_Check:PyObject*:o:0:

Expand Down
5 changes: 3 additions & 2 deletions Doc/library/ast.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ The abstract grammar is currently defined as follows:
:language: asdl


.. _ast_nodes:

Node classes
------------

Expand Down Expand Up @@ -164,8 +166,7 @@ Node classes
Previous versions of Python allowed the creation of AST nodes that were missing
required fields. Similarly, AST node constructors allowed arbitrary keyword
arguments that were set as attributes of the AST node, even if they did not
match any of the fields of the AST node. This behavior is deprecated and will
be removed in Python 3.15.
match any of the fields of the AST node. These cases now raise a :exc:`TypeError`.

.. note::
The descriptions of the specific node classes displayed here
Expand Down
37 changes: 36 additions & 1 deletion Doc/library/contextlib.rst
Original file line number Diff line number Diff line change
Expand Up @@ -467,12 +467,40 @@ Functions and classes provided:
statements. If this is not the case, then the original construct with the
explicit :keyword:`!with` statement inside the function should be used.

When the decorated callable is a generator function, coroutine function, or
asynchronous generator function, the returned wrapper is of the same kind
and keeps the context manager open for the lifetime of the iteration or
await rather than only for the call that creates the generator or coroutine
object. Wrapped generators and asynchronous generators are explicitly
closed when iteration ends, as if by :func:`closing` or :func:`aclosing`.

.. note::
For asynchronous generators the wrapper re-yields each value with
``async for``; values sent with :meth:`~agen.asend` and exceptions
thrown with :meth:`~agen.athrow` are not forwarded to the wrapped
generator.

.. versionadded:: 3.2

.. versionchanged:: next
Decorating a generator function, coroutine function, or asynchronous
generator function now keeps the context manager open across iteration
or await. Previously the context manager exited as soon as the
generator or coroutine object was created.


.. class:: AsyncContextDecorator

Similar to :class:`ContextDecorator` but only for asynchronous functions.
Similar to :class:`ContextDecorator`, but the context manager is entered
and exited with :keyword:`async with`. Decorate coroutine functions and
asynchronous generator functions with this class; the returned wrapper is
of the same kind.

.. note::
Synchronous functions and generators are accepted, but the wrapper is
always asynchronous, so the decorated callable must then be awaited or
iterated with ``async for``. If that change of calling convention is
not intended, use :class:`ContextDecorator` instead.

Example of ``AsyncContextDecorator``::

Expand Down Expand Up @@ -510,6 +538,13 @@ Functions and classes provided:

.. versionadded:: 3.10

.. versionchanged:: next
Decorating an asynchronous generator function now keeps the context
manager open across iteration. Previously the context manager exited
as soon as the generator object was created. Synchronous functions
and synchronous generator functions are also now accepted, with an
asynchronous wrapper returned.


.. class:: ExitStack()

Expand Down
69 changes: 62 additions & 7 deletions Doc/library/functions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ are always available. They are listed here in alphabetical order.
| | :func:`ascii` | | :func:`filter` | | :func:`map` | | **S** |
| | | | :func:`float` | | :func:`max` | | |func-set|_ |
| | **B** | | :func:`format` | | |func-memoryview|_ | | :func:`setattr` |
| | :func:`bin` | | |func-frozenset|_ | | :func:`min` | | :func:`slice` |
| | :func:`bool` | | | | | | :func:`sorted` |
| | :func:`breakpoint` | | **G** | | **N** | | :func:`staticmethod` |
| | |func-bytearray|_ | | :func:`getattr` | | :func:`next` | | |func-str|_ |
| | |func-bytes|_ | | :func:`globals` | | | | :func:`sum` |
| | | | | | **O** | | :func:`super` |
| | **C** | | **H** | | :func:`object` | | |
| | :func:`bin` | | |func-frozenset|_ | | :func:`min` | | :func:`sentinel` |
| | :func:`bool` | | | | | | :func:`slice` |
| | :func:`breakpoint` | | **G** | | **N** | | :func:`sorted` |
| | |func-bytearray|_ | | :func:`getattr` | | :func:`next` | | :func:`staticmethod` |
| | |func-bytes|_ | | :func:`globals` | | | | |func-str|_ |
| | | | | | **O** | | :func:`sum` |
| | **C** | | **H** | | :func:`object` | | :func:`super` |
| | :func:`callable` | | :func:`hasattr` | | :func:`oct` | | **T** |
| | :func:`chr` | | :func:`hash` | | :func:`open` | | |func-tuple|_ |
| | :func:`classmethod` | | :func:`help` | | :func:`ord` | | :func:`type` |
Expand Down Expand Up @@ -1827,6 +1827,61 @@ are always available. They are listed here in alphabetical order.
:func:`setattr`.


.. class:: sentinel(name, /)

Return a new unique sentinel object. *name* must be a :class:`str`, and is
used as the returned object's representation::

>>> MISSING = sentinel("MISSING")
>>> MISSING
MISSING

Sentinel objects are truthy and compare equal only to themselves. They are
intended to be compared with the :keyword:`is` operator.

Shallow and deep copies of a sentinel object return the object itself.

Sentinels are conventionally assigned to a variable with a matching name.
Sentinels defined in this way can be used in :term:`type hints <type hint>`::

MISSING = sentinel("MISSING")

def next_value(default: int | MISSING = MISSING):
...

Sentinel objects support the :ref:`| <bitwise>` operator for use in type expressions.

:mod:`Pickling <pickle>` is supported for sentinel objects that are
placed in the global scope of a module under a name matching the sentinel's
name, and for sentinels placed in class scopes with a name matching the
:term:`qualified name` of the sentinel. Other sentinels, such as those
defined in a function scope, are not picklable. The identity of the sentinel is preserved
after pickling::

import pickle

PICKLABLE = sentinel("PICKLABLE")

assert pickle.loads(pickle.dumps(PICKLABLE)) is PICKLABLE

class Cls:
PICKLABLE = sentinel("Cls.PICKLABLE")

assert pickle.loads(pickle.dumps(Cls.PICKLABLE)) is Cls.PICKLABLE

Sentinel objects have the following attributes:

.. attribute:: __name__

The sentinel's name.

.. attribute:: __module__

The name of the module where the sentinel was created.

.. versionadded:: next


.. class:: slice(stop, /)
slice(start, stop, step=None, /)

Expand Down
19 changes: 9 additions & 10 deletions Doc/tutorial/stdlib2.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
.. _tut-brieftourtwo:

**********************************************
Brief Tour of the Standard Library --- Part II
Brief tour of the standard library --- part II
**********************************************

This second tour covers more advanced modules that support professional
Expand All @@ -10,7 +10,7 @@ programming needs. These modules rarely occur in small scripts.

.. _tut-output-formatting:

Output Formatting
Output formatting
=================

The :mod:`reprlib` module provides a version of :func:`repr` customized for
Expand Down Expand Up @@ -130,7 +130,7 @@ templates for XML files, plain text reports, and HTML web reports.

.. _tut-binary-formats:

Working with Binary Data Record Layouts
Working with binary data record layouts
=======================================

The :mod:`struct` module provides :func:`~struct.pack` and
Expand Down Expand Up @@ -178,14 +178,13 @@ tasks in background while the main program continues to run::

class AsyncZip(threading.Thread):
def __init__(self, infile, outfile):
threading.Thread.__init__(self)
super().__init__()
self.infile = infile
self.outfile = outfile

def run(self):
f = zipfile.ZipFile(self.outfile, 'w', zipfile.ZIP_DEFLATED)
f.write(self.infile)
f.close()
with zipfile.ZipFile(self.outfile, 'w', zipfile.ZIP_DEFLATED) as f:
f.write(self.infile)
print('Finished background zip of:', self.infile)

background = AsyncZip('mydata.txt', 'myarchive.zip')
Expand Down Expand Up @@ -245,7 +244,7 @@ application.

.. _tut-weak-references:

Weak References
Weak references
===============

Python does automatic memory management (reference counting for most objects and
Expand Down Expand Up @@ -286,7 +285,7 @@ applications include caching objects that are expensive to create::

.. _tut-list-tools:

Tools for Working with Lists
Tools for working with lists
============================

Many data structure needs can be met with the built-in list type. However,
Expand Down Expand Up @@ -352,7 +351,7 @@ not want to run a full list sort::

.. _tut-decimal-fp:

Decimal Floating-Point Arithmetic
Decimal floating-point arithmetic
=================================

The :mod:`decimal` module offers a :class:`~decimal.Decimal` datatype for
Expand Down
35 changes: 35 additions & 0 deletions Doc/whatsnew/3.15.rst
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ Summary -- Release highlights
<whatsnew315-lazy-imports>`
* :pep:`814`: :ref:`Add frozendict built-in type
<whatsnew315-frozendict>`
* :pep:`661`: :ref:`Add sentinel built-in type
<whatsnew315-sentinel>`
* :pep:`799`: :ref:`A dedicated profiling package for organizing Python
profiling tools <whatsnew315-profiling-package>`
* :pep:`799`: :ref:`Tachyon: High frequency statistical sampling profiler
Expand Down Expand Up @@ -247,6 +249,20 @@ to accept also other mapping types such as :class:`~types.MappingProxyType`.
(Contributed by Victor Stinner and Donghee Na in :gh:`141510`.)


.. _whatsnew315-sentinel:

:pep:`661`: Add sentinel built-in type
--------------------------------------

A new :class:`sentinel` type is added to the :mod:`builtins` module for
creating unique sentinel values with a concise representation. Sentinel
objects preserve identity when copied, support use in type expressions with
the ``|`` operator, and can be pickled when they are importable by module and
name.

(PEP by Tal Einat; contributed by Jelle Zijlstra in :gh:`148829`.)


.. _whatsnew315-profiling-package:

:pep:`799`: A dedicated profiling package
Expand Down Expand Up @@ -830,6 +846,15 @@ contextlib
consistency with the :keyword:`with` and :keyword:`async with` statements.
(Contributed by Serhiy Storchaka in :gh:`144386`.)

* :class:`~contextlib.ContextDecorator` and
:class:`~contextlib.AsyncContextDecorator` (and therefore
:func:`~contextlib.contextmanager` and :func:`~contextlib.asynccontextmanager`
used as decorators) now detect generator functions, coroutine functions, and
asynchronous generator functions and keep the context manager open across
iteration or await. Previously the context manager exited as soon as the
generator or coroutine object was created.
(Contributed by Alex Grönholm & Gregory P. Smith in :gh:`125862`.)


dataclasses
-----------
Expand Down Expand Up @@ -1604,6 +1629,16 @@ This was made possible by a refactoring of JIT data structures.
Removed
========

ast
---

* The constructors of :ref:`AST nodes <ast_nodes>` now raise a :exc:`TypeError`
when a required argument is omitted or when a keyword argument that does not
map to a field on the AST node is passed. These cases had previously raised a
:exc:`DeprecationWarning` since Python 3.13.
(Contributed by Brian Schubert and Jelle Zijlstra in :gh:`137600` and :gh:`105858`.)


collections.abc
---------------

Expand Down
1 change: 1 addition & 0 deletions Include/Python.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ __pragma(warning(disable: 4201))
#include "cpython/genobject.h"
#include "descrobject.h"
#include "genericaliasobject.h"
#include "sentinelobject.h"
#include "warnings.h"
#include "weakrefobject.h"
#include "structseq.h"
Expand Down
22 changes: 22 additions & 0 deletions Include/sentinelobject.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/* Sentinel object interface */

#ifndef Py_SENTINELOBJECT_H
#define Py_SENTINELOBJECT_H
#ifdef __cplusplus
extern "C" {
#endif

#ifndef Py_LIMITED_API
PyAPI_DATA(PyTypeObject) PySentinel_Type;

#define PySentinel_Check(op) Py_IS_TYPE((op), &PySentinel_Type)

PyAPI_FUNC(PyObject *) PySentinel_New(
const char *name,
const char *module_name);
#endif

#ifdef __cplusplus
}
#endif
#endif /* !Py_SENTINELOBJECT_H */
Loading
Loading