Thanks to visit codestin.com
Credit goes to github.com

Skip to content

gh-116437: Use new C API PyDict_Pop() to simplify the code #116438

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 7, 2024
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
28 changes: 14 additions & 14 deletions Modules/_asynciomodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -2045,12 +2045,22 @@ static PyObject *
swap_current_task(asyncio_state *state, PyObject *loop, PyObject *task)
{
PyObject *prev_task;

if (task == Py_None) {
if (PyDict_Pop(state->current_tasks, loop, &prev_task) < 0) {
return NULL;
}
if (prev_task == NULL) {
Py_RETURN_NONE;
}
return prev_task;
}
Comment on lines 2045 to +2057
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It took me a minute to make sense of your changes in this file, but now I get it. 👍

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here. I blocked here for 5 minutes :-D


Py_hash_t hash;
hash = PyObject_Hash(loop);
if (hash == -1) {
return NULL;
}

prev_task = _PyDict_GetItem_KnownHash(state->current_tasks, loop, hash);
if (prev_task == NULL) {
if (PyErr_Occurred()) {
Expand All @@ -2059,22 +2069,12 @@ swap_current_task(asyncio_state *state, PyObject *loop, PyObject *task)
prev_task = Py_None;
}
Py_INCREF(prev_task);

if (task == Py_None) {
if (_PyDict_DelItem_KnownHash(state->current_tasks, loop, hash) == -1) {
goto error;
}
} else {
if (_PyDict_SetItem_KnownHash(state->current_tasks, loop, task, hash) == -1) {
goto error;
}
if (_PyDict_SetItem_KnownHash(state->current_tasks, loop, task, hash) == -1) {
Py_DECREF(prev_task);
return NULL;
}

return prev_task;

error:
Py_DECREF(prev_task);
return NULL;
}

/* ----- Task */
Expand Down
10 changes: 6 additions & 4 deletions Modules/_csv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1606,10 +1606,12 @@ _csv_unregister_dialect_impl(PyObject *module, PyObject *name)
/*[clinic end generated code: output=0813ebca6c058df4 input=6b5c1557bf60c7e7]*/
{
_csvstate *module_state = get_csv_state(module);
if (PyDict_DelItem(module_state->dialects, name) < 0) {
if (PyErr_ExceptionMatches(PyExc_KeyError)) {
PyErr_Format(module_state->error_obj, "unknown dialect");
}
int rc = PyDict_Pop(module_state->dialects, name, NULL);
if (rc < 0) {
return NULL;
}
if (rc == 0) {
PyErr_Format(module_state->error_obj, "unknown dialect");
return NULL;
}
Py_RETURN_NONE;
Expand Down
16 changes: 5 additions & 11 deletions Modules/_elementtree.c
Original file line number Diff line number Diff line change
Expand Up @@ -372,33 +372,27 @@ element_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
static PyObject*
get_attrib_from_keywords(PyObject *kwds)
{
PyObject *attrib_str = PyUnicode_FromString("attrib");
if (attrib_str == NULL) {
PyObject *attrib;
if (PyDict_PopString(kwds, "attrib", &attrib) < 0) {
return NULL;
}
PyObject *attrib = PyDict_GetItemWithError(kwds, attrib_str);

if (attrib) {
/* If attrib was found in kwds, copy its value and remove it from
* kwds
*/
if (!PyDict_Check(attrib)) {
Py_DECREF(attrib_str);
PyErr_Format(PyExc_TypeError, "attrib must be dict, not %.100s",
Py_TYPE(attrib)->tp_name);
Py_DECREF(attrib);
return NULL;
}
attrib = PyDict_Copy(attrib);
if (attrib && PyDict_DelItem(kwds, attrib_str) < 0) {
Py_SETREF(attrib, NULL);
}
Py_SETREF(attrib, PyDict_Copy(attrib));
}
else if (!PyErr_Occurred()) {
else {
attrib = PyDict_New();
}

Py_DECREF(attrib_str);

if (attrib != NULL && PyDict_Update(attrib, kwds) < 0) {
Py_DECREF(attrib);
return NULL;
Expand Down
8 changes: 2 additions & 6 deletions Modules/_threadmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -1262,13 +1262,9 @@ _localdummy_destroyed(PyObject *localweakref, PyObject *dummyweakref)
/* If the thread-local object is still alive and not being cleared,
remove the corresponding local dict */
if (self->dummies != NULL) {
PyObject *ldict;
ldict = PyDict_GetItemWithError(self->dummies, dummyweakref);
if (ldict != NULL) {
PyDict_DelItem(self->dummies, dummyweakref);
}
if (PyErr_Occurred())
if (PyDict_Pop(self->dummies, dummyweakref, NULL) < 0) {
PyErr_WriteUnraisable((PyObject*)self);
}
}
Py_DECREF(self);
Py_RETURN_NONE;
Expand Down
8 changes: 4 additions & 4 deletions Modules/posixmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -17556,11 +17556,11 @@ posixmodule_exec(PyObject *m)
return -1;
}

if (PyDict_DelItemString(dct, "pwritev") == -1) {
PyErr_Clear();
if (PyDict_PopString(dct, "pwritev", NULL) < 0) {
return -1;
}
if (PyDict_DelItemString(dct, "preadv") == -1) {
PyErr_Clear();
if (PyDict_PopString(dct, "preadv", NULL) < 0) {
return -1;
Comment on lines -17559 to +17563
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is slightly different behavior, isn't it? Before, we tried removing each item and ignored all errors. Now we fail at the first error. Is that okay? (Maybe @ronaldoussoren has some thoughts on this?) Was this intentional?

(The same applies to the changes in Modules/timemodule.c.)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not ignoring errors is always a good thing.

}
}
#endif
Expand Down
28 changes: 14 additions & 14 deletions Modules/timemodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -1928,20 +1928,20 @@ time_exec(PyObject *module)
return -1;
}

if (PyDict_DelItemString(dct, "clock_gettime") == -1) {
PyErr_Clear();
if (PyDict_PopString(dct, "clock_gettime", NULL) < 0) {
return -1;
}
if (PyDict_DelItemString(dct, "clock_gettime_ns") == -1) {
PyErr_Clear();
if (PyDict_PopString(dct, "clock_gettime_ns", NULL) < 0) {
return -1;
}
if (PyDict_DelItemString(dct, "clock_settime") == -1) {
PyErr_Clear();
if (PyDict_PopString(dct, "clock_settime", NULL) < 0) {
return -1;
}
if (PyDict_DelItemString(dct, "clock_settime_ns") == -1) {
PyErr_Clear();
if (PyDict_PopString(dct, "clock_settime_ns", NULL) < 0) {
return -1;
}
if (PyDict_DelItemString(dct, "clock_getres") == -1) {
PyErr_Clear();
if (PyDict_PopString(dct, "clock_getres", NULL) < 0) {
return -1;
}
}
#endif
Expand All @@ -1951,11 +1951,11 @@ time_exec(PyObject *module)
} else {
PyObject* dct = PyModule_GetDict(module);

if (PyDict_DelItemString(dct, "thread_time") == -1) {
PyErr_Clear();
if (PyDict_PopString(dct, "thread_time", NULL) < 0) {
return -1;
}
if (PyDict_DelItemString(dct, "thread_time_ns") == -1) {
PyErr_Clear();
if (PyDict_PopString(dct, "thread_time_ns", NULL) < 0) {
return -1;
}
}
#endif
Expand Down
10 changes: 7 additions & 3 deletions Objects/moduleobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -1004,9 +1004,13 @@ module_set_annotations(PyModuleObject *m, PyObject *value, void *Py_UNUSED(ignor
}
else {
/* delete */
ret = PyDict_DelItem(dict, &_Py_ID(__annotations__));
if (ret < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) {
PyErr_SetString(PyExc_AttributeError, "__annotations__");
ret = PyDict_Pop(dict, &_Py_ID(__annotations__), NULL);
if (ret == 0) {
PyErr_SetObject(PyExc_AttributeError, &_Py_ID(__annotations__));
ret = -1;
}
else if (ret > 0) {
ret = 0;
}
}

Expand Down
34 changes: 19 additions & 15 deletions Objects/typeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -1236,20 +1236,22 @@ type_set_abstractmethods(PyTypeObject *type, PyObject *value, void *context)
}
else {
abstract = 0;
res = PyDict_DelItem(dict, &_Py_ID(__abstractmethods__));
if (res && PyErr_ExceptionMatches(PyExc_KeyError)) {
res = PyDict_Pop(dict, &_Py_ID(__abstractmethods__), NULL);
if (res == 0) {
PyErr_SetObject(PyExc_AttributeError, &_Py_ID(__abstractmethods__));
return -1;
}
}
if (res == 0) {
PyType_Modified(type);
if (abstract)
type->tp_flags |= Py_TPFLAGS_IS_ABSTRACT;
else
type->tp_flags &= ~Py_TPFLAGS_IS_ABSTRACT;
if (res < 0) {
return -1;
}
return res;

PyType_Modified(type);
if (abstract)
type->tp_flags |= Py_TPFLAGS_IS_ABSTRACT;
else
type->tp_flags &= ~Py_TPFLAGS_IS_ABSTRACT;
return 0;
}

static PyObject *
Expand Down Expand Up @@ -1606,16 +1608,18 @@ type_set_annotations(PyTypeObject *type, PyObject *value, void *context)
result = PyDict_SetItem(dict, &_Py_ID(__annotations__), value);
} else {
/* delete */
result = PyDict_DelItem(dict, &_Py_ID(__annotations__));
if (result < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) {
result = PyDict_Pop(dict, &_Py_ID(__annotations__), NULL);
if (result == 0) {
PyErr_SetString(PyExc_AttributeError, "__annotations__");
return -1;
}
}

if (result == 0) {
PyType_Modified(type);
if (result < 0) {
return -1;
}
return result;

PyType_Modified(type);
return 0;
}

static PyObject *
Expand Down
18 changes: 9 additions & 9 deletions Parser/asdl_c.py
Original file line number Diff line number Diff line change
Expand Up @@ -1077,20 +1077,20 @@ def visitModule(self, mod):
if (!name) {
goto cleanup;
}
PyObject *value = PyDict_GetItemWithError(remaining_dict, name);
PyObject *value;
int rc = PyDict_Pop(remaining_dict, name, &value);
Py_DECREF(name);
if (rc < 0) {
goto cleanup;
}
if (!value) {
if (PyErr_Occurred()) {
goto cleanup;
}
break;
}
if (PyList_Append(positional_args, value) < 0) {
rc = PyList_Append(positional_args, value);
Py_DECREF(value);
if (rc < 0) {
goto cleanup;
}
if (PyDict_DelItem(remaining_dict, name) < 0) {
goto cleanup;
}
Py_DECREF(name);
Comment on lines +1081 to -1093
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch about fixing the decrefs.

}
PyObject *args_tuple = PyList_AsTuple(positional_args);
if (!args_tuple) {
Expand Down
18 changes: 9 additions & 9 deletions Python/Python-ast.c

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 1 addition & 4 deletions Python/bltinmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,13 +140,10 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs,
goto error;
}

if (PyDict_GetItemRef(mkw, &_Py_ID(metaclass), &meta) < 0) {
if (PyDict_Pop(mkw, &_Py_ID(metaclass), &meta) < 0) {
goto error;
}
if (meta != NULL) {
if (PyDict_DelItem(mkw, &_Py_ID(metaclass)) < 0) {
goto error;
}
/* metaclass is explicitly given, check if it's indeed a class */
isclass = PyType_Check(meta);
}
Expand Down
14 changes: 7 additions & 7 deletions Python/bytecodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -1307,14 +1307,14 @@ dummy_func(

inst(DELETE_GLOBAL, (--)) {
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg);
int err;
err = PyDict_DelItem(GLOBALS(), name);
int err = PyDict_Pop(GLOBALS(), name, NULL);
// Can't use ERROR_IF here.
if (err != 0) {
if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
_PyEval_FormatExcCheckArg(tstate, PyExc_NameError,
NAME_ERROR_MSG, name);
}
if (err < 0) {
GOTO_ERROR(error);
}
if (err == 0) {
_PyEval_FormatExcCheckArg(tstate, PyExc_NameError,
NAME_ERROR_MSG, name);
GOTO_ERROR(error);
}
}
Expand Down
14 changes: 7 additions & 7 deletions Python/executor_cases.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 7 additions & 7 deletions Python/generated_cases.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading