Skip to content

Commit 2b7d1fa

Browse files
authored
Merge branch 'main' into make-resource-tracker-reentrant-safe
2 parents 8e8f9f7 + 51d2459 commit 2b7d1fa

File tree

78 files changed

+1946
-657
lines changed

Some content is hidden

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

78 files changed

+1946
-657
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ Include/internal/pycore_time.h @pganssle @abalkin
188188

189189
# AST
190190
Python/ast.c @isidentical @JelleZijlstra @eclips4
191-
Python/ast_opt.c @isidentical @eclips4
191+
Python/ast_preprocess.c @isidentical @eclips4
192192
Parser/asdl.py @isidentical @JelleZijlstra @eclips4
193193
Parser/asdl_c.py @isidentical @JelleZijlstra @eclips4
194194
Lib/ast.py @isidentical @JelleZijlstra @eclips4

Doc/library/annotationlib.rst

Lines changed: 91 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ The :func:`get_annotations` function is the main entry point for
4040
retrieving annotations. Given a function, class, or module, it returns
4141
an annotations dictionary in the requested format. This module also provides
4242
functionality for working directly with the :term:`annotate function`
43-
that is used to evaluate annotations, such as :func:`get_annotate_function`
43+
that is used to evaluate annotations, such as :func:`get_annotate_from_class_namespace`
4444
and :func:`call_annotate_function`, as well as the
4545
:func:`call_evaluate_function` function for working with
4646
:term:`evaluate functions <evaluate function>`.
@@ -132,7 +132,7 @@ Classes
132132

133133
Values are real annotation values (as per :attr:`Format.VALUE` format)
134134
for defined values, and :class:`ForwardRef` proxies for undefined
135-
values. Real objects may contain references to, :class:`ForwardRef`
135+
values. Real objects may contain references to :class:`ForwardRef`
136136
proxy objects.
137137

138138
.. attribute:: STRING
@@ -172,14 +172,21 @@ Classes
172172
:class:`~ForwardRef`. The string may not be exactly equivalent
173173
to the original source.
174174

175-
.. method:: evaluate(*, owner=None, globals=None, locals=None, type_params=None)
175+
.. method:: evaluate(*, owner=None, globals=None, locals=None, type_params=None, format=Format.VALUE)
176176

177177
Evaluate the forward reference, returning its value.
178178

179-
This may throw an exception, such as :exc:`NameError`, if the forward
179+
If the *format* argument is :attr:`~Format.VALUE` (the default),
180+
this method may throw an exception, such as :exc:`NameError`, if the forward
180181
reference refers to a name that cannot be resolved. The arguments to this
181182
method can be used to provide bindings for names that would otherwise
182-
be undefined.
183+
be undefined. If the *format* argument is :attr:`~Format.FORWARDREF`,
184+
the method will never throw an exception, but may return a :class:`~ForwardRef`
185+
instance. For example, if the forward reference object contains the code
186+
``list[undefined]``, where ``undefined`` is a name that is not defined,
187+
evaluating it with the :attr:`~Format.FORWARDREF` format will return
188+
``list[ForwardRef('undefined')]``. If the *format* argument is
189+
:attr:`~Format.STRING`, the method will return :attr:`~ForwardRef.__forward_arg__`.
183190

184191
The *owner* parameter provides the preferred mechanism for passing scope
185192
information to this method. The owner of a :class:`~ForwardRef` is the
@@ -300,15 +307,13 @@ Functions
300307

301308
.. versionadded:: 3.14
302309

303-
.. function:: get_annotate_function(obj)
310+
.. function:: get_annotate_from_class_namespace(namespace)
304311

305-
Retrieve the :term:`annotate function` for *obj*. Return :const:`!None`
306-
if *obj* does not have an annotate function. *obj* may be a class, function,
307-
module, or a namespace dictionary for a class. The last case is useful during
308-
class creation, e.g. in the ``__new__`` method of a metaclass.
309-
310-
This is usually equivalent to accessing the :attr:`~object.__annotate__`
311-
attribute of *obj*, but access through this public function is preferred.
312+
Retrieve the :term:`annotate function` from a class namespace dictionary *namespace*.
313+
Return :const:`!None` if the namespace does not contain an annotate function.
314+
This is primarily useful before the class has been fully created (e.g., in a metaclass);
315+
after the class exists, the annotate function can be retrieved with ``cls.__annotate__``.
316+
See :ref:`below <annotationlib-metaclass>` for an example using this function in a metaclass.
312317

313318
.. versionadded:: 3.14
314319

@@ -407,3 +412,76 @@ Functions
407412

408413
.. versionadded:: 3.14
409414

415+
416+
Recipes
417+
-------
418+
419+
.. _annotationlib-metaclass:
420+
421+
Using annotations in a metaclass
422+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
423+
424+
A :ref:`metaclass <metaclasses>` may want to inspect or even modify the annotations
425+
in a class body during class creation. Doing so requires retrieving annotations
426+
from the class namespace dictionary. For classes created with
427+
``from __future__ import annotations``, the annotations will be in the ``__annotations__``
428+
key of the dictionary. For other classes with annotations,
429+
:func:`get_annotate_from_class_namespace` can be used to get the
430+
annotate function, and :func:`call_annotate_function` can be used to call it and
431+
retrieve the annotations. Using the :attr:`~Format.FORWARDREF` format will usually
432+
be best, because this allows the annotations to refer to names that cannot yet be
433+
resolved when the class is created.
434+
435+
To modify the annotations, it is best to create a wrapper annotate function
436+
that calls the original annotate function, makes any necessary adjustments, and
437+
returns the result.
438+
439+
Below is an example of a metaclass that filters out all :class:`typing.ClassVar`
440+
annotations from the class and puts them in a separate attribute:
441+
442+
.. code-block:: python
443+
444+
import annotationlib
445+
import typing
446+
447+
class ClassVarSeparator(type):
448+
def __new__(mcls, name, bases, ns):
449+
if "__annotations__" in ns: # from __future__ import annotations
450+
annotations = ns["__annotations__"]
451+
classvar_keys = {
452+
key for key, value in annotations.items()
453+
# Use string comparison for simplicity; a more robust solution
454+
# could use annotationlib.ForwardRef.evaluate
455+
if value.startswith("ClassVar")
456+
}
457+
classvars = {key: annotations[key] for key in classvar_keys}
458+
ns["__annotations__"] = {
459+
key: value for key, value in annotations.items()
460+
if key not in classvar_keys
461+
}
462+
wrapped_annotate = None
463+
elif annotate := annotationlib.get_annotate_from_class_namespace(ns):
464+
annotations = annotationlib.call_annotate_function(
465+
annotate, format=annotationlib.Format.FORWARDREF
466+
)
467+
classvar_keys = {
468+
key for key, value in annotations.items()
469+
if typing.get_origin(value) is typing.ClassVar
470+
}
471+
classvars = {key: annotations[key] for key in classvar_keys}
472+
473+
def wrapped_annotate(format):
474+
annos = annotationlib.call_annotate_function(annotate, format, owner=typ)
475+
return {key: value for key, value in annos.items() if key not in classvar_keys}
476+
477+
else: # no annotations
478+
classvars = {}
479+
wrapped_annotate = None
480+
typ = super().__new__(mcls, name, bases, ns)
481+
482+
if wrapped_annotate is not None:
483+
# Wrap the original __annotate__ with a wrapper that removes ClassVars
484+
typ.__annotate__ = wrapped_annotate
485+
typ.classvars = classvars # Store the ClassVars in a separate attribute
486+
return typ
487+

Doc/library/os.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2338,6 +2338,7 @@ features:
23382338
This function can support specifying *src_dir_fd* and/or *dst_dir_fd* to
23392339
supply :ref:`paths relative to directory descriptors <dir_fd>`, and :ref:`not
23402340
following symlinks <follow_symlinks>`.
2341+
The default value of *follow_symlinks* is ``False`` on Windows.
23412342

23422343
.. audit-event:: os.link src,dst,src_dir_fd,dst_dir_fd os.link
23432344

Doc/reference/datamodel.rst

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1228,15 +1228,9 @@ Special attributes
12281228
:attr:`__annotations__ attributes <object.__annotations__>`.
12291229

12301230
For best practices on working with :attr:`~object.__annotations__`,
1231-
please see :mod:`annotationlib`.
1232-
1233-
.. caution::
1234-
1235-
Accessing the :attr:`!__annotations__` attribute of a class
1236-
object directly may yield incorrect results in the presence of
1237-
metaclasses. In addition, the attribute may not exist for
1238-
some classes. Use :func:`annotationlib.get_annotations` to
1239-
retrieve class annotations safely.
1231+
please see :mod:`annotationlib`. Where possible, use
1232+
:func:`annotationlib.get_annotations` instead of accessing this
1233+
attribute directly.
12401234

12411235
.. versionchanged:: 3.14
12421236
Annotations are now :ref:`lazily evaluated <lazy-evaluation>`.
@@ -1247,13 +1241,6 @@ Special attributes
12471241
if the class has no annotations.
12481242
See also: :attr:`__annotate__ attributes <object.__annotate__>`.
12491243

1250-
.. caution::
1251-
1252-
Accessing the :attr:`!__annotate__` attribute of a class
1253-
object directly may yield incorrect results in the presence of
1254-
metaclasses. Use :func:`annotationlib.get_annotate_function` to
1255-
retrieve the annotate function safely.
1256-
12571244
.. versionadded:: 3.14
12581245

12591246
* - .. attribute:: type.__type_params__

Doc/whatsnew/3.14.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2213,6 +2213,12 @@ Others
22132213
integer must implement either :meth:`~object.__int__` or
22142214
:meth:`~object.__index__`. (Contributed by Mark Dickinson in :gh:`119743`.)
22152215

2216+
* The default :term:`interactive` shell now supports import autocompletion.
2217+
This means that typing ``import foo`` and pressing ``<tab>`` will suggest
2218+
modules starting with ``foo``. Similarly, typing ``from foo import b`` will
2219+
suggest submodules of ``foo`` starting with ``b``. Note that autocompletion
2220+
of module attributes is not currently supported.
2221+
(Contributed by Tomas Roun in :gh:`69605`.)
22162222

22172223
CPython Bytecode Changes
22182224
========================

Include/cpython/pystate.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ struct _ts {
194194
/* The thread's exception stack entry. (Always the last entry.) */
195195
_PyErr_StackItem exc_state;
196196

197-
PyObject *previous_executor;
197+
PyObject *current_executor;
198198

199199
uint64_t dict_global_version;
200200

Include/internal/pycore_compile.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,16 @@ PyAPI_FUNC(PyCodeObject*) _PyAST_Compile(
3434
int optimize,
3535
struct _arena *arena);
3636

37-
/* AST optimizations */
38-
extern int _PyCompile_AstOptimize(
37+
/* AST preprocessing */
38+
extern int _PyCompile_AstPreprocess(
3939
struct _mod *mod,
4040
PyObject *filename,
4141
PyCompilerFlags *flags,
4242
int optimize,
4343
struct _arena *arena,
4444
int syntax_check_only);
4545

46-
extern int _PyAST_Optimize(
46+
extern int _PyAST_Preprocess(
4747
struct _mod *,
4848
struct _arena *arena,
4949
PyObject *filename,

Include/internal/pycore_interp_structs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -923,6 +923,8 @@ struct _is {
923923
PyObject *common_consts[NUM_COMMON_CONSTANTS];
924924
bool jit;
925925
struct _PyExecutorObject *executor_list_head;
926+
struct _PyExecutorObject *executor_deletion_list_head;
927+
int executor_deletion_list_remaining_capacity;
926928
size_t trace_run_counter;
927929
_rare_events rare_events;
928930
PyDict_WatchCallback builtins_dict_watcher;

Include/internal/pycore_opcode_metadata.h

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_optimizer.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ typedef struct {
6969
typedef struct {
7070
uint32_t target;
7171
_Py_BackoffCounter temperature;
72-
const struct _PyExecutorObject *executor;
72+
struct _PyExecutorObject *executor;
7373
} _PyExitData;
7474

7575
typedef struct _PyExecutorObject {
@@ -84,6 +84,10 @@ typedef struct _PyExecutorObject {
8484
_PyExitData exits[1];
8585
} _PyExecutorObject;
8686

87+
/* If pending deletion list gets large enough, then scan,
88+
* and free any executors that aren't executing
89+
* i.e. any that aren't a thread's current_executor. */
90+
#define EXECUTOR_DELETE_LIST_MAX 100
8791

8892
// Export for '_opcode' shared extension (JIT compiler).
8993
PyAPI_FUNC(_PyExecutorObject*) _Py_GetExecutor(PyCodeObject *code, int offset);
@@ -304,6 +308,9 @@ static inline int is_terminator(const _PyUOpInstruction *uop)
304308
}
305309

306310
PyAPI_FUNC(int) _PyDumpExecutors(FILE *out);
311+
#ifdef _Py_TIER2
312+
extern void _Py_ClearExecutorDeletionList(PyInterpreterState *interp);
313+
#endif
307314

308315
#ifdef __cplusplus
309316
}

0 commit comments

Comments
 (0)