Skip to content

gh-136140: Add update(**kwargs) method to types.SimpleNamespace #136142

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

Closed
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
19 changes: 19 additions & 0 deletions Lib/test/test_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import unittest.mock
import weakref
import typing
from types import SimpleNamespace


c_types = import_fresh_module('types', fresh=['_types'])
py_types = import_fresh_module('types', blocked=['_types'])
Expand Down Expand Up @@ -2128,6 +2130,23 @@ class FakeSimpleNamespace(str):
types.SimpleNamespace() > FakeSimpleNamespace()
with self.assertRaises(TypeError):
types.SimpleNamespace() >= FakeSimpleNamespace()

def test_update_method(self):
ns = SimpleNamespace(a=1)
self.assertEqual(ns.a, 1)

ns.update(b=2, c=3)
self.assertEqual(ns.b, 2)
self.assertEqual(ns.c, 3)

# Overwriting existing key
ns.update(a=42)
self.assertEqual(ns.a, 42)

# No update with no kwargs
ns.update()
self.assertEqual(vars(ns), {'a': 42, 'b': 2, 'c': 3})



class CoroutineTests(unittest.TestCase):
Expand Down
46 changes: 45 additions & 1 deletion Objects/namespaceobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,14 +245,53 @@
return result;
}

static PyObject *namespace_update(PyObject *self, PyObject *args, PyObject *kwds);
static PyObject *
namespace_update(PyObject *self, PyObject *args, PyObject *kwargs)
{
PyObject *update_obj = NULL;

if (!PyArg_UnpackTuple(args, "update", 0, 1, &update_obj)) {
return NULL;
}

_PyNamespaceObject *ns = (_PyNamespaceObject *)self;
PyObject *dict = ns->ns_dict;
Py_INCREF(dict);

if (update_obj != NULL) {
if (PyDict_Update(dict, update_obj) < 0) {
Py_DECREF(dict);
return NULL;
}
}

if (kwargs && PyDict_Update(dict, kwargs) < 0) {
Py_DECREF(dict);
return NULL;
}

Py_DECREF(dict);
Py_RETURN_NONE;
}



static PyMethodDef namespace_methods[] = {
{"__reduce__", namespace_reduce, METH_NOARGS,
namespace_reduce__doc__},
{"__replace__", _PyCFunction_CAST(namespace_replace), METH_VARARGS|METH_KEYWORDS,
PyDoc_STR("__replace__($self, /, **changes)\n--\n\n"
"Return a copy of the namespace object with new values for the specified attributes.")},
{NULL, NULL} // sentinel

{"update", (PyCFunction)(PyCFunctionWithKeywords)namespace_update, METH_VARARGS | METH_KEYWORDS,

Check warning on line 287 in Objects/namespaceobject.c

View workflow job for this annotation

GitHub Actions / Hypothesis tests on Ubuntu

cast between incompatible function types from ‘PyObject * (*)(PyObject *, PyObject *, PyObject *)’ {aka ‘struct _object * (*)(struct _object *, struct _object *, struct _object *)’} to ‘PyObject * (*)(PyObject *, PyObject *)’ {aka ‘struct _object * (*)(struct _object *, struct _object *)’} [-Wcast-function-type]

Check warning on line 287 in Objects/namespaceobject.c

View workflow job for this annotation

GitHub Actions / Address sanitizer (ubuntu-24.04)

cast between incompatible function types from ‘PyObject * (*)(PyObject *, PyObject *, PyObject *)’ {aka ‘struct _object * (*)(struct _object *, struct _object *, struct _object *)’} to ‘PyObject * (*)(PyObject *, PyObject *)’ {aka ‘struct _object * (*)(struct _object *, struct _object *)’} [-Wcast-function-type]

Check warning on line 287 in Objects/namespaceobject.c

View workflow job for this annotation

GitHub Actions / Cross build Linux

cast between incompatible function types from ‘PyObject * (*)(PyObject *, PyObject *, PyObject *)’ {aka ‘struct _object * (*)(struct _object *, struct _object *, struct _object *)’} to ‘PyObject * (*)(PyObject *, PyObject *)’ {aka ‘struct _object * (*)(struct _object *, struct _object *)’} [-Wcast-function-type]

Check warning on line 287 in Objects/namespaceobject.c

View workflow job for this annotation

GitHub Actions / Ubuntu / build and test (ubuntu-24.04)

cast between incompatible function types from ‘PyObject * (*)(PyObject *, PyObject *, PyObject *)’ {aka ‘struct _object * (*)(struct _object *, struct _object *, struct _object *)’} to ‘PyObject * (*)(PyObject *, PyObject *)’ {aka ‘struct _object * (*)(struct _object *, struct _object *)’} [-Wcast-function-type]

Check warning on line 287 in Objects/namespaceobject.c

View workflow job for this annotation

GitHub Actions / Ubuntu / build and test (ubuntu-24.04-arm)

cast between incompatible function types from ‘PyObject * (*)(PyObject *, PyObject *, PyObject *)’ {aka ‘struct _object * (*)(struct _object *, struct _object *, struct _object *)’} to ‘PyObject * (*)(PyObject *, PyObject *)’ {aka ‘struct _object * (*)(struct _object *, struct _object *)’} [-Wcast-function-type]

Check warning on line 287 in Objects/namespaceobject.c

View workflow job for this annotation

GitHub Actions / Ubuntu (free-threading) / build and test (ubuntu-24.04)

cast between incompatible function types from ‘PyObject * (*)(PyObject *, PyObject *, PyObject *)’ {aka ‘struct _object * (*)(struct _object *, struct _object *, struct _object *)’} to ‘PyObject * (*)(PyObject *, PyObject *)’ {aka ‘struct _object * (*)(struct _object *, struct _object *)’} [-Wcast-function-type]

Check warning on line 287 in Objects/namespaceobject.c

View workflow job for this annotation

GitHub Actions / Ubuntu (free-threading) / build and test (ubuntu-24.04-arm)

cast between incompatible function types from ‘PyObject * (*)(PyObject *, PyObject *, PyObject *)’ {aka ‘struct _object * (*)(struct _object *, struct _object *, struct _object *)’} to ‘PyObject * (*)(PyObject *, PyObject *)’ {aka ‘struct _object * (*)(struct _object *, struct _object *)’} [-Wcast-function-type]

Check warning on line 287 in Objects/namespaceobject.c

View workflow job for this annotation

GitHub Actions / Ubuntu (bolt) / build and test (ubuntu-24.04)

cast between incompatible function types from ‘PyObject * (*)(PyObject *, PyObject *, PyObject *)’ {aka ‘struct _object * (*)(struct _object *, struct _object *, struct _object *)’} to ‘PyObject * (*)(PyObject *, PyObject *)’ {aka ‘struct _object * (*)(struct _object *, struct _object *)’} [-Wcast-function-type]
PyDoc_STR("update(self, mapping=(), /, **kwargs)\n--\n\n"
"Update the namespace with the given keyword arguments.")},

{NULL, NULL} /* sentinel */



};


Expand Down Expand Up @@ -321,3 +360,8 @@

return (PyObject *)ns;
}





Loading