Skip to content

Commit 8b3b808

Browse files
committed
Merge branch 'main' into gh-114847
2 parents 15199a8 + f341d60 commit 8b3b808

File tree

82 files changed

+4553
-3349
lines changed

Some content is hidden

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

82 files changed

+4553
-3349
lines changed

Doc/library/importlib.resources.abc.rst

+24-2
Original file line numberDiff line numberDiff line change
@@ -109,13 +109,35 @@
109109

110110
Return True if self is a file.
111111

112-
.. abstractmethod:: joinpath(child)
112+
.. abstractmethod:: joinpath(*pathsegments)
113113

114-
Return Traversable child in self.
114+
Traverse directories according to *pathsegments* and return
115+
the result as :class:`!Traversable`.
116+
117+
Each *pathsegments* argument may contain multiple names separated by
118+
forward slashes (``/``, ``posixpath.sep`` ).
119+
For example, the following are equivalent::
120+
121+
files.joinpath('subdir', 'subsuddir', 'file.txt')
122+
files.joinpath('subdir/subsuddir/file.txt')
123+
124+
Note that some :class:`!Traversable` implementations
125+
might not be updated to the latest version of the protocol.
126+
For compatibility with such implementations, provide a single argument
127+
without path separators to each call to ``joinpath``. For example::
128+
129+
files.joinpath('subdir').joinpath('subsubdir').joinpath('file.txt')
130+
131+
.. versionchanged:: 3.11
132+
133+
``joinpath`` accepts multiple *pathsegments*, and these segments
134+
may contain forward slashes as path separators.
135+
Previously, only a single *child* argument was accepted.
115136

116137
.. abstractmethod:: __truediv__(child)
117138

118139
Return Traversable child in self.
140+
Equivalent to ``joinpath(child)``.
119141

120142
.. abstractmethod:: open(mode='r', *args, **kwargs)
121143

Doc/library/subprocess.rst

+8-5
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,12 @@ underlying :class:`Popen` interface can be used directly.
5252

5353
If *capture_output* is true, stdout and stderr will be captured.
5454
When used, the internal :class:`Popen` object is automatically created with
55-
``stdout=PIPE`` and ``stderr=PIPE``. The *stdout* and *stderr* arguments may
56-
not be supplied at the same time as *capture_output*. If you wish to capture
57-
and combine both streams into one, use ``stdout=PIPE`` and ``stderr=STDOUT``
58-
instead of *capture_output*.
55+
*stdout* and *stdin* both set to :data:`~subprocess.PIPE`.
56+
The *stdout* and *stderr* arguments may not be supplied at the same time as *capture_output*.
57+
If you wish to capture and combine both streams into one,
58+
set *stdout* to :data:`~subprocess.PIPE`
59+
and *stderr* to :data:`~subprocess.STDOUT`,
60+
instead of using *capture_output*.
5961

6062
A *timeout* may be specified in seconds, it is internally passed on to
6163
:meth:`Popen.communicate`. If the timeout expires, the child process will be
@@ -69,7 +71,8 @@ underlying :class:`Popen` interface can be used directly.
6971
subprocess's stdin. If used it must be a byte sequence, or a string if
7072
*encoding* or *errors* is specified or *text* is true. When
7173
used, the internal :class:`Popen` object is automatically created with
72-
``stdin=PIPE``, and the *stdin* argument may not be used as well.
74+
*stdin* set to :data:`~subprocess.PIPE`,
75+
and the *stdin* argument may not be used as well.
7376

7477
If *check* is true, and the process exits with a non-zero exit code, a
7578
:exc:`CalledProcessError` exception will be raised. Attributes of that

Doc/library/xml.etree.elementtree.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ and its sub-elements are done on the :class:`Element` level.
4949
Parsing XML
5050
^^^^^^^^^^^
5151

52-
We'll be using the following XML document as the sample data for this section:
52+
We'll be using the fictive :file:`country_data.xml` XML document as the sample data for this section:
5353

5454
.. code-block:: xml
5555

Grammar/python.gram

+4-2
Original file line numberDiff line numberDiff line change
@@ -1013,6 +1013,7 @@ kwargs[asdl_seq*]:
10131013
starred_expression[expr_ty]:
10141014
| invalid_starred_expression
10151015
| '*' a=expression { _PyAST_Starred(a, Load, EXTRA) }
1016+
| '*' { RAISE_SYNTAX_ERROR("Invalid star expression") }
10161017

10171018
kwarg_or_starred[KeywordOrStarred*]:
10181019
| invalid_kwarg
@@ -1133,8 +1134,8 @@ func_type_comment[Token*]:
11331134

11341135
# From here on, there are rules for invalid syntax with specialised error messages
11351136
invalid_arguments:
1136-
| ((','.(starred_expression | ( assignment_expression | expression !':=') !'=')+ ',' kwargs) | kwargs) ',' b='*' {
1137-
RAISE_SYNTAX_ERROR_KNOWN_LOCATION(b, "iterable argument unpacking follows keyword argument unpacking") }
1137+
| ((','.(starred_expression | ( assignment_expression | expression !':=') !'=')+ ',' kwargs) | kwargs) a=',' ','.(starred_expression !'=')+ {
1138+
RAISE_SYNTAX_ERROR_STARTING_FROM(a, "iterable argument unpacking follows keyword argument unpacking") }
11381139
| a=expression b=for_if_clauses ',' [args | expression for_if_clauses] {
11391140
RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, _PyPegen_get_last_comprehension_item(PyPegen_last_item(b, comprehension_ty)), "Generator expression must be parenthesized") }
11401141
| a=NAME b='=' expression for_if_clauses {
@@ -1396,6 +1397,7 @@ invalid_kvpair:
13961397
| expression a=':' &('}'|',') {RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "expression expected after dictionary key and ':'") }
13971398
invalid_starred_expression:
13981399
| a='*' expression '=' b=expression { RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "cannot assign to iterable argument unpacking") }
1400+
13991401
invalid_replacement_field:
14001402
| '{' a='=' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "f-string: valid expression required before '='") }
14011403
| '{' a='!' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "f-string: valid expression required before '!'") }

Include/cpython/compile.h

-20
Original file line numberDiff line numberDiff line change
@@ -32,28 +32,8 @@ typedef struct {
3232
#define _PyCompilerFlags_INIT \
3333
(PyCompilerFlags){.cf_flags = 0, .cf_feature_version = PY_MINOR_VERSION}
3434

35-
/* source location information */
36-
typedef struct {
37-
int lineno;
38-
int end_lineno;
39-
int col_offset;
40-
int end_col_offset;
41-
} _PyCompilerSrcLocation;
42-
43-
#define SRC_LOCATION_FROM_AST(n) \
44-
(_PyCompilerSrcLocation){ \
45-
.lineno = (n)->lineno, \
46-
.end_lineno = (n)->end_lineno, \
47-
.col_offset = (n)->col_offset, \
48-
.end_col_offset = (n)->end_col_offset }
49-
5035
/* Future feature support */
5136

52-
typedef struct {
53-
int ff_features; /* flags set by future statements */
54-
_PyCompilerSrcLocation ff_location; /* location of last future statement */
55-
} PyFutureFeatures;
56-
5737
#define FUTURE_NESTED_SCOPES "nested_scopes"
5838
#define FUTURE_GENERATORS "generators"
5939
#define FUTURE_DIVISION "division"

Include/cpython/pystats.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,11 @@ typedef struct _object_stats {
7777
uint64_t frees;
7878
uint64_t to_freelist;
7979
uint64_t from_freelist;
80-
uint64_t new_values;
80+
uint64_t inline_values;
8181
uint64_t dict_materialized_on_request;
8282
uint64_t dict_materialized_new_key;
8383
uint64_t dict_materialized_too_big;
8484
uint64_t dict_materialized_str_subclass;
85-
uint64_t dict_dematerialized;
8685
uint64_t type_cache_hits;
8786
uint64_t type_cache_misses;
8887
uint64_t type_cache_dunder_hits;

Include/internal/pycore_code.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,10 @@ typedef struct {
7979
typedef struct {
8080
uint16_t counter;
8181
uint16_t type_version[2];
82-
uint16_t keys_version[2];
82+
union {
83+
uint16_t keys_version[2];
84+
uint16_t dict_offset;
85+
};
8386
uint16_t descr[4];
8487
} _PyLoadMethodCache;
8588

Include/internal/pycore_compile.h

+5-3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ extern "C" {
88
# error "this header requires Py_BUILD_CORE define"
99
#endif
1010

11+
#include "pycore_symtable.h" // _Py_SourceLocation
12+
1113
struct _arena; // Type defined in pycore_pyarena.h
1214
struct _mod; // Type defined in pycore_ast.h
1315

@@ -27,7 +29,7 @@ extern int _PyCompile_AstOptimize(
2729
int optimize,
2830
struct _arena *arena);
2931

30-
static const _PyCompilerSrcLocation NO_LOCATION = {-1, -1, -1, -1};
32+
struct _Py_SourceLocation;
3133

3234
extern int _PyAST_Optimize(
3335
struct _mod *,
@@ -44,7 +46,7 @@ typedef struct {
4446
typedef struct {
4547
int i_opcode;
4648
int i_oparg;
47-
_PyCompilerSrcLocation i_loc;
49+
_Py_SourceLocation i_loc;
4850
_PyCompile_ExceptHandlerInfo i_except_handler_info;
4951

5052
/* Used by the assembler */
@@ -65,7 +67,7 @@ typedef struct {
6567
int _PyCompile_InstructionSequence_UseLabel(_PyCompile_InstructionSequence *seq, int lbl);
6668
int _PyCompile_InstructionSequence_Addop(_PyCompile_InstructionSequence *seq,
6769
int opcode, int oparg,
68-
_PyCompilerSrcLocation loc);
70+
_Py_SourceLocation loc);
6971
int _PyCompile_InstructionSequence_ApplyLabelMap(_PyCompile_InstructionSequence *seq);
7072

7173
typedef struct {

Include/internal/pycore_dict.h

+52-12
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ extern "C" {
1111

1212
#include "pycore_freelist.h" // _PyFreeListState
1313
#include "pycore_identifier.h" // _Py_Identifier
14-
#include "pycore_object.h" // PyDictOrValues
14+
#include "pycore_object.h" // PyManagedDictPointer
1515

1616
// Unsafe flavor of PyDict_GetItemWithError(): no error checking
1717
extern PyObject* _PyDict_GetItemWithError(PyObject *dp, PyObject *key);
@@ -181,6 +181,10 @@ struct _dictkeysobject {
181181
* [-1] = prefix size. [-2] = used size. size[-2-n...] = insertion order.
182182
*/
183183
struct _dictvalues {
184+
uint8_t capacity;
185+
uint8_t size;
186+
uint8_t embedded;
187+
uint8_t valid;
184188
PyObject *values[1];
185189
};
186190

@@ -196,6 +200,7 @@ static inline void* _DK_ENTRIES(PyDictKeysObject *dk) {
196200
size_t index = (size_t)1 << dk->dk_log2_index_bytes;
197201
return (&indices[index]);
198202
}
203+
199204
static inline PyDictKeyEntry* DK_ENTRIES(PyDictKeysObject *dk) {
200205
assert(dk->dk_kind == DICT_KEYS_GENERAL);
201206
return (PyDictKeyEntry*)_DK_ENTRIES(dk);
@@ -211,9 +216,6 @@ static inline PyDictUnicodeEntry* DK_UNICODE_ENTRIES(PyDictKeysObject *dk) {
211216
#define DICT_WATCHER_MASK ((1 << DICT_MAX_WATCHERS) - 1)
212217
#define DICT_WATCHER_AND_MODIFICATION_MASK ((1 << (DICT_MAX_WATCHERS + DICT_WATCHED_MUTATION_BITS)) - 1)
213218

214-
#define DICT_VALUES_SIZE(values) ((uint8_t *)values)[-1]
215-
#define DICT_VALUES_USED_SIZE(values) ((uint8_t *)values)[-2]
216-
217219
#ifdef Py_GIL_DISABLED
218220
#define DICT_NEXT_VERSION(INTERP) \
219221
(_Py_atomic_add_uint64(&(INTERP)->dict_state.global_version, DICT_VERSION_INCREMENT) + DICT_VERSION_INCREMENT)
@@ -246,25 +248,63 @@ _PyDict_NotifyEvent(PyInterpreterState *interp,
246248
return DICT_NEXT_VERSION(interp) | (mp->ma_version_tag & DICT_WATCHER_AND_MODIFICATION_MASK);
247249
}
248250

249-
extern PyObject *_PyObject_MakeDictFromInstanceAttributes(PyObject *obj, PyDictValues *values);
250-
PyAPI_FUNC(bool) _PyObject_MakeInstanceAttributesFromDict(PyObject *obj, PyDictOrValues *dorv);
251+
extern PyDictObject *_PyObject_MakeDictFromInstanceAttributes(PyObject *obj);
252+
251253
PyAPI_FUNC(PyObject *)_PyDict_FromItems(
252254
PyObject *const *keys, Py_ssize_t keys_offset,
253255
PyObject *const *values, Py_ssize_t values_offset,
254256
Py_ssize_t length);
255257

258+
static inline uint8_t *
259+
get_insertion_order_array(PyDictValues *values)
260+
{
261+
return (uint8_t *)&values->values[values->capacity];
262+
}
263+
256264
static inline void
257265
_PyDictValues_AddToInsertionOrder(PyDictValues *values, Py_ssize_t ix)
258266
{
259267
assert(ix < SHARED_KEYS_MAX_SIZE);
260-
uint8_t *size_ptr = ((uint8_t *)values)-2;
261-
int size = *size_ptr;
262-
assert(size+2 < DICT_VALUES_SIZE(values));
263-
size++;
264-
size_ptr[-size] = (uint8_t)ix;
265-
*size_ptr = size;
268+
int size = values->size;
269+
uint8_t *array = get_insertion_order_array(values);
270+
assert(size < values->capacity);
271+
assert(((uint8_t)ix) == ix);
272+
array[size] = (uint8_t)ix;
273+
values->size = size+1;
274+
}
275+
276+
static inline size_t
277+
shared_keys_usable_size(PyDictKeysObject *keys)
278+
{
279+
#ifdef Py_GIL_DISABLED
280+
// dk_usable will decrease for each instance that is created and each
281+
// value that is added. dk_nentries will increase for each value that
282+
// is added. We want to always return the right value or larger.
283+
// We therefore increase dk_nentries first and we decrease dk_usable
284+
// second, and conversely here we read dk_usable first and dk_entries
285+
// second (to avoid the case where we read entries before the increment
286+
// and read usable after the decrement)
287+
return (size_t)(_Py_atomic_load_ssize_acquire(&keys->dk_usable) +
288+
_Py_atomic_load_ssize_acquire(&keys->dk_nentries));
289+
#else
290+
return (size_t)keys->dk_nentries + (size_t)keys->dk_usable;
291+
#endif
266292
}
267293

294+
static inline size_t
295+
_PyInlineValuesSize(PyTypeObject *tp)
296+
{
297+
PyDictKeysObject *keys = ((PyHeapTypeObject*)tp)->ht_cached_keys;
298+
assert(keys != NULL);
299+
size_t size = shared_keys_usable_size(keys);
300+
size_t prefix_size = _Py_SIZE_ROUND_UP(size, sizeof(PyObject *));
301+
assert(prefix_size < 256);
302+
return prefix_size + (size + 1) * sizeof(PyObject *);
303+
}
304+
305+
int
306+
_PyDict_DetachFromObject(PyDictObject *dict, PyObject *obj);
307+
268308
#ifdef __cplusplus
269309
}
270310
#endif

Include/internal/pycore_flowgraph.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ typedef struct {
1818
struct _PyCfgBuilder;
1919

2020
int _PyCfgBuilder_UseLabel(struct _PyCfgBuilder *g, _PyCfgJumpTargetLabel lbl);
21-
int _PyCfgBuilder_Addop(struct _PyCfgBuilder *g, int opcode, int oparg, _PyCompilerSrcLocation loc);
21+
int _PyCfgBuilder_Addop(struct _PyCfgBuilder *g, int opcode, int oparg, _Py_SourceLocation loc);
2222

2323
struct _PyCfgBuilder* _PyCfgBuilder_New(void);
2424
void _PyCfgBuilder_Free(struct _PyCfgBuilder *g);

Include/internal/pycore_object.h

+13-35
Original file line numberDiff line numberDiff line change
@@ -265,9 +265,8 @@ _PyObject_Init(PyObject *op, PyTypeObject *typeobj)
265265
{
266266
assert(op != NULL);
267267
Py_SET_TYPE(op, typeobj);
268-
if (_PyType_HasFeature(typeobj, Py_TPFLAGS_HEAPTYPE)) {
269-
Py_INCREF(typeobj);
270-
}
268+
assert(_PyType_HasFeature(typeobj, Py_TPFLAGS_HEAPTYPE) || _Py_IsImmortal(typeobj));
269+
Py_INCREF(typeobj);
271270
_Py_NewReference(op);
272271
}
273272

@@ -611,8 +610,7 @@ extern PyTypeObject* _PyType_CalculateMetaclass(PyTypeObject *, PyObject *);
611610
extern PyObject* _PyType_GetDocFromInternalDoc(const char *, const char *);
612611
extern PyObject* _PyType_GetTextSignatureFromInternalDoc(const char *, const char *, int);
613612

614-
extern int _PyObject_InitializeDict(PyObject *obj);
615-
int _PyObject_InitInlineValues(PyObject *obj, PyTypeObject *tp);
613+
void _PyObject_InitInlineValues(PyObject *obj, PyTypeObject *tp);
616614
extern int _PyObject_StoreInstanceAttribute(PyObject *obj, PyDictValues *values,
617615
PyObject *name, PyObject *value);
618616
PyObject * _PyObject_GetInstanceAttribute(PyObject *obj, PyDictValues *values,
@@ -627,46 +625,26 @@ PyObject * _PyObject_GetInstanceAttribute(PyObject *obj, PyDictValues *values,
627625
#endif
628626

629627
typedef union {
630-
PyObject *dict;
631-
/* Use a char* to generate a warning if directly assigning a PyDictValues */
632-
char *values;
633-
} PyDictOrValues;
628+
PyDictObject *dict;
629+
} PyManagedDictPointer;
634630

635-
static inline PyDictOrValues *
636-
_PyObject_DictOrValuesPointer(PyObject *obj)
631+
static inline PyManagedDictPointer *
632+
_PyObject_ManagedDictPointer(PyObject *obj)
637633
{
638634
assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT);
639-
return (PyDictOrValues *)((char *)obj + MANAGED_DICT_OFFSET);
640-
}
641-
642-
static inline int
643-
_PyDictOrValues_IsValues(PyDictOrValues dorv)
644-
{
645-
return ((uintptr_t)dorv.values) & 1;
635+
return (PyManagedDictPointer *)((char *)obj + MANAGED_DICT_OFFSET);
646636
}
647637

648638
static inline PyDictValues *
649-
_PyDictOrValues_GetValues(PyDictOrValues dorv)
650-
{
651-
assert(_PyDictOrValues_IsValues(dorv));
652-
return (PyDictValues *)(dorv.values + 1);
653-
}
654-
655-
static inline PyObject *
656-
_PyDictOrValues_GetDict(PyDictOrValues dorv)
639+
_PyObject_InlineValues(PyObject *obj)
657640
{
658-
assert(!_PyDictOrValues_IsValues(dorv));
659-
return dorv.dict;
660-
}
661-
662-
static inline void
663-
_PyDictOrValues_SetValues(PyDictOrValues *ptr, PyDictValues *values)
664-
{
665-
ptr->values = ((char *)values) - 1;
641+
assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_INLINE_VALUES);
642+
assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT);
643+
assert(Py_TYPE(obj)->tp_basicsize == sizeof(PyObject));
644+
return (PyDictValues *)((char *)obj + sizeof(PyObject));
666645
}
667646

668647
extern PyObject ** _PyObject_ComputedDictPointer(PyObject *);
669-
extern void _PyObject_FreeInstanceAttributes(PyObject *obj);
670648
extern int _PyObject_IsInstanceDictEmpty(PyObject *);
671649

672650
// Export for 'math' shared extension

0 commit comments

Comments
 (0)