self.assertEqual(ns, ns_roundtrip, pname)
+ def test_replace(self):
+ ns = types.SimpleNamespace(x=11, y=22)
+
+ ns2 = copy.replace(ns)
+ self.assertEqual(ns2, ns)
+ self.assertIsNot(ns2, ns)
+ self.assertIs(type(ns2), types.SimpleNamespace)
+ self.assertEqual(vars(ns2), {'x': 11, 'y': 22})
+ ns2.x = 3
+ self.assertEqual(ns.x, 11)
+ ns.x = 4
+ self.assertEqual(ns2.x, 3)
+
+ self.assertEqual(vars(copy.replace(ns, x=1)), {'x': 1, 'y': 22})
+ self.assertEqual(vars(copy.replace(ns, y=2)), {'x': 4, 'y': 2})
+ self.assertEqual(vars(copy.replace(ns, x=1, y=2)), {'x': 1, 'y': 2})
+
+ def test_replace_subclass(self):
+ class Spam(types.SimpleNamespace):
+ pass
+
+ spam = Spam(ham=8, eggs=9)
+ spam2 = copy.replace(spam, ham=5)
+
+ self.assertIs(type(spam2), Spam)
+ self.assertEqual(vars(spam2), {'ham': 5, 'eggs': 9})
+
def test_fake_namespace_compare(self):
# Issue #24257: Incorrect use of PyObject_IsInstance() caused
# SystemError.
}
+static PyObject *
+namespace_replace(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ if (!_PyArg_NoPositional("__replace__", args)) {
+ return NULL;
+ }
+
+ PyObject *result = PyObject_CallNoArgs((PyObject *)Py_TYPE(self));
+ if (!result) {
+ return NULL;
+ }
+ if (PyDict_Update(((_PyNamespaceObject*)result)->ns_dict,
+ ((_PyNamespaceObject*)self)->ns_dict) < 0)
+ {
+ Py_DECREF(result);
+ return NULL;
+ }
+ if (kwargs) {
+ if (PyDict_Update(((_PyNamespaceObject*)result)->ns_dict, kwargs) < 0) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ }
+ return result;
+}
+
+
static PyMethodDef namespace_methods[] = {
{"__reduce__", (PyCFunction)namespace_reduce, METH_NOARGS,
namespace_reduce__doc__},
+ {"__replace__", _PyCFunction_CAST(namespace_replace), METH_VARARGS|METH_KEYWORDS, NULL},
{NULL, NULL} // sentinel
};