Skip to content

Commit 57731e8

Browse files
Merge branch 'main' into minor
2 parents 8ab0d13 + a3e8e7b commit 57731e8

98 files changed

Lines changed: 1339 additions & 812 deletions

File tree

Some content is hidden

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

Include/internal/pycore_modsupport.h

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ PyAPI_FUNC(int) _PyArg_ParseStackAndKeywords(
7676
...);
7777

7878
// Export for 'math' shared extension
79-
PyAPI_FUNC(PyObject * const *) _PyArg_UnpackKeywordsEx(
79+
PyAPI_FUNC(PyObject * const *) _PyArg_UnpackKeywords(
8080
PyObject *const *args,
8181
Py_ssize_t nargs,
8282
PyObject *kwargs,
@@ -87,17 +87,12 @@ PyAPI_FUNC(PyObject * const *) _PyArg_UnpackKeywordsEx(
8787
int minkw,
8888
int varpos,
8989
PyObject **buf);
90-
#define _PyArg_UnpackKeywords(args, nargs, kwargs, kwnames, parser, minpos, maxpos, minkw, buf) \
90+
#define _PyArg_UnpackKeywords(args, nargs, kwargs, kwnames, parser, minpos, maxpos, minkw, varpos, buf) \
9191
(((minkw) == 0 && (kwargs) == NULL && (kwnames) == NULL && \
92-
(minpos) <= (nargs) && (nargs) <= (maxpos) && (args) != NULL) ? \
92+
(minpos) <= (nargs) && ((varpos) || (nargs) <= (maxpos)) && (args) != NULL) ? \
9393
(args) : \
94-
_PyArg_UnpackKeywordsEx((args), (nargs), (kwargs), (kwnames), (parser), \
95-
(minpos), (maxpos), (minkw), 0, (buf)))
96-
#define _PyArg_UnpackKeywordsWithVararg(args, nargs, kwargs, kwnames, parser, minpos, maxpos, minkw, buf) \
97-
(((minkw) == 0 && (kwargs) == NULL && (kwnames) == NULL && \
98-
(minpos) <= (nargs) && (args) != NULL) ? (args) : \
99-
_PyArg_UnpackKeywordsEx((args), (nargs), (kwargs), (kwnames), (parser), \
100-
(minpos), (maxpos), (minkw), 1, (buf)))
94+
_PyArg_UnpackKeywords((args), (nargs), (kwargs), (kwnames), (parser), \
95+
(minpos), (maxpos), (minkw), (varpos), (buf)))
10196

10297
#ifdef __cplusplus
10398
}

Lib/test/clinic.test.c

Lines changed: 93 additions & 62 deletions
Large diffs are not rendered by default.

Lib/test/test_call.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ def test_varargs17_kw(self):
168168
print, 0, sep=1, end=2, file=3, flush=4, foo=5)
169169

170170
def test_varargs18_kw(self):
171-
# _PyArg_UnpackKeywordsWithVararg()
171+
# _PyArg_UnpackKeywords() with varpos
172172
msg = r"invalid keyword argument for print\(\)$"
173173
with self.assertRaisesRegex(TypeError, msg):
174174
print(0, 1, **{BadStr('foo'): ','})

Lib/test/test_clinic.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2703,7 +2703,7 @@ def test_cli_force(self):
27032703
# Verify by checking the checksum.
27042704
checksum = (
27052705
"/*[clinic end generated code: "
2706-
"output=0acbef4794cb933e input=9543a8d2da235301]*/\n"
2706+
"output=00512eb783a9b748 input=9543a8d2da235301]*/\n"
27072707
)
27082708
with open(fn, encoding='utf-8') as f:
27092709
generated = f.read()

Modules/_asynciomodule.c

Lines changed: 21 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -136,47 +136,18 @@ typedef struct {
136136
/* Counter for autogenerated Task names */
137137
uint64_t task_name_counter;
138138

139-
/* Linked-list of all tasks which are instances of asyncio.Task or subclasses
139+
/* Circular linked-list of all tasks which are instances of asyncio.Task or subclasses
140140
of it. Third party tasks implementations which don't inherit from
141141
asyncio.Task are tracked separately using the 'non_asyncio_tasks' WeakSet.
142-
`tail` is used as a sentinel to mark the end of the linked-list. It avoids one
142+
`first` is used as a sentinel to mark the end of the linked-list. It avoids one
143143
branch in checking for empty list when adding a new task, the list is
144-
initialized with `head` pointing to `tail` to mark an empty list.
145-
146-
Invariants:
147-
* When the list is empty:
148-
- asyncio_tasks.head == &asyncio_tasks.tail
149-
- asyncio_tasks.head->prev == NULL
150-
- asyncio_tasks.head->next == NULL
151-
152-
* After adding the first task 'task1':
153-
- asyncio_tasks.head == task1
154-
- task1->next == &asyncio_tasks.tail
155-
- task1->prev == NULL
156-
- asyncio_tasks.tail.prev == task1
157-
158-
* After adding a second task 'task2':
159-
- asyncio_tasks.head == task2
160-
- task2->next == task1
161-
- task2->prev == NULL
162-
- task1->prev == task2
163-
- asyncio_tasks.tail.prev == task1
164-
165-
* After removing task 'task1':
166-
- asyncio_tasks.head == task2
167-
- task2->next == &asyncio_tasks.tail
168-
- task2->prev == NULL
169-
- asyncio_tasks.tail.prev == task2
170-
171-
* After removing task 'task2', the list is empty:
172-
- asyncio_tasks.head == &asyncio_tasks.tail
173-
- asyncio_tasks.head->prev == NULL
174-
- asyncio_tasks.tail.prev == NULL
175-
- asyncio_tasks.tail.next == NULL
144+
initialized with `head`, `head->next` and `head->prev` pointing to `first`
145+
to mark an empty list.
146+
176147
*/
177148

178149
struct {
179-
TaskObj tail;
150+
TaskObj first;
180151
TaskObj *head;
181152
} asyncio_tasks;
182153

@@ -1923,7 +1894,7 @@ register_task(asyncio_state *state, TaskObj *task)
19231894
{
19241895
ASYNCIO_STATE_LOCK(state);
19251896
assert(Task_Check(state, task));
1926-
assert(task != &state->asyncio_tasks.tail);
1897+
assert(task != &state->asyncio_tasks.first);
19271898
if (task->next != NULL) {
19281899
// already registered
19291900
goto exit;
@@ -1932,8 +1903,10 @@ register_task(asyncio_state *state, TaskObj *task)
19321903
assert(state->asyncio_tasks.head != NULL);
19331904

19341905
task->next = state->asyncio_tasks.head;
1906+
task->prev = state->asyncio_tasks.head->prev;
1907+
state->asyncio_tasks.head->prev->next = task;
19351908
state->asyncio_tasks.head->prev = task;
1936-
state->asyncio_tasks.head = task;
1909+
19371910
exit:
19381911
ASYNCIO_STATE_UNLOCK(state);
19391912
}
@@ -1949,20 +1922,15 @@ unregister_task(asyncio_state *state, TaskObj *task)
19491922
{
19501923
ASYNCIO_STATE_LOCK(state);
19511924
assert(Task_Check(state, task));
1952-
assert(task != &state->asyncio_tasks.tail);
1925+
assert(task != &state->asyncio_tasks.first);
19531926
if (task->next == NULL) {
19541927
// not registered
19551928
assert(task->prev == NULL);
19561929
assert(state->asyncio_tasks.head != task);
19571930
goto exit;
19581931
}
19591932
task->next->prev = task->prev;
1960-
if (task->prev == NULL) {
1961-
assert(state->asyncio_tasks.head == task);
1962-
state->asyncio_tasks.head = task->next;
1963-
} else {
1964-
task->prev->next = task->next;
1965-
}
1933+
task->prev->next = task->next;
19661934
task->next = NULL;
19671935
task->prev = NULL;
19681936
assert(state->asyncio_tasks.head != task);
@@ -3655,12 +3623,10 @@ _asyncio_all_tasks_impl(PyObject *module, PyObject *loop)
36553623
Py_DECREF(eager_iter);
36563624
int err = 0;
36573625
ASYNCIO_STATE_LOCK(state);
3658-
TaskObj *head = state->asyncio_tasks.head;
3626+
TaskObj *first = &state->asyncio_tasks.first;
3627+
TaskObj *head = state->asyncio_tasks.head->next;
36593628
Py_INCREF(head);
3660-
assert(head != NULL);
3661-
assert(head->prev == NULL);
3662-
TaskObj *tail = &state->asyncio_tasks.tail;
3663-
while (head != tail)
3629+
while (head != first)
36643630
{
36653631
if (add_one_task(state, tasks, (PyObject *)head, loop) < 0) {
36663632
Py_DECREF(tasks);
@@ -3873,9 +3839,12 @@ static int
38733839
module_exec(PyObject *mod)
38743840
{
38753841
asyncio_state *state = get_asyncio_state(mod);
3876-
Py_SET_TYPE(&state->asyncio_tasks.tail, state->TaskType);
3877-
_Py_SetImmortalUntracked((PyObject *)&state->asyncio_tasks.tail);
3878-
state->asyncio_tasks.head = &state->asyncio_tasks.tail;
3842+
3843+
Py_SET_TYPE(&state->asyncio_tasks.first, state->TaskType);
3844+
_Py_SetImmortalUntracked((PyObject *)&state->asyncio_tasks.first);
3845+
state->asyncio_tasks.head = &state->asyncio_tasks.first;
3846+
state->asyncio_tasks.head->next = &state->asyncio_tasks.first;
3847+
state->asyncio_tasks.head->prev = &state->asyncio_tasks.first;
38793848

38803849
#define CREATE_TYPE(m, tp, spec, base) \
38813850
do { \

Modules/_ctypes/clinic/_ctypes.c.h

Lines changed: 23 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Modules/_ctypes/clinic/cfield.c.h

Lines changed: 3 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Modules/_io/clinic/_iomodule.c.h

Lines changed: 5 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)