[pypy-commit] pypy py3.5: Implement PyDict_SetDefault()
rlamy
pypy.commits at gmail.com
Sat Sep 16 00:16:11 EDT 2017
Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: py3.5
Changeset: r92409:1a05dfedf02e
Date: 2017-09-16 05:15 +0100
http://bitbucket.org/pypy/pypy/changeset/1a05dfedf02e/
Log: Implement PyDict_SetDefault()
diff --git a/pypy/module/cpyext/dictobject.py b/pypy/module/cpyext/dictobject.py
--- a/pypy/module/cpyext/dictobject.py
+++ b/pypy/module/cpyext/dictobject.py
@@ -4,10 +4,10 @@
from pypy.objspace.std.classdict import ClassDictStrategy
from pypy.interpreter.typedef import GetSetProperty
from pypy.module.cpyext.api import (
- cpython_api, CANNOT_FAIL, build_type_checkers_flags, Py_ssize_t,
+ cpython_api, CANNOT_FAIL, build_type_checkers_flags, Py_ssize_t, cts,
Py_ssize_tP, CONST_STRING, PyObjectFields, cpython_struct,
bootstrap_function, slot_function)
-from pypy.module.cpyext.pyobject import (PyObject, PyObjectP, as_pyobj,
+from pypy.module.cpyext.pyobject import (PyObject, PyObjectP, as_pyobj,
make_typedescr, track_reference, create_ref, from_ref, decref,
Py_IncRef)
from pypy.module.cpyext.object import _dealloc
@@ -155,6 +155,15 @@
"""Empty an existing dictionary of all key-value pairs."""
space.call_method(space.w_dict, "clear", w_obj)
+ at cts.decl("""PyObject *
+ PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *defaultobj)""")
+def PyDict_SetDefault(space, w_dict, w_key, w_defaultobj):
+ if not PyDict_Check(space, w_dict):
+ PyErr_BadInternalCall(space)
+ else:
+ return space.call_method(
+ space.w_dict, "setdefault", w_dict, w_key, w_defaultobj)
+
@cpython_api([PyObject], PyObject)
def PyDict_Copy(space, w_obj):
"""Return a new dictionary that contains the same key-value pairs as p.
@@ -258,7 +267,7 @@
if w_dict is None:
return 0
if not space.isinstance_w(w_dict, space.w_dict):
- return 0
+ return 0
pos = ppos[0]
py_obj = as_pyobj(space, w_dict)
py_dict = rffi.cast(PyDictObject, py_obj)
diff --git a/pypy/module/cpyext/test/test_dictobject.py b/pypy/module/cpyext/test/test_dictobject.py
--- a/pypy/module/cpyext/test/test_dictobject.py
+++ b/pypy/module/cpyext/test/test_dictobject.py
@@ -174,6 +174,26 @@
])
assert module.dict_proxy({'a': 1, 'b': 2}) == 2
+ def test_setdefault(self):
+ module = self.import_extension('foo', [
+ ("setdefault", "METH_VARARGS",
+ '''
+ PyObject *d, *key, *defaultobj, *val;
+ if (!PyArg_ParseTuple(args, "OOO", &d, &key, &defaultobj))
+ return NULL;
+ val = PyDict_SetDefault(d, key, defaultobj);
+ Py_XINCREF(val);
+ return val;
+ ''')])
+
+ class Dict(dict):
+ def setdefault(self, key, default):
+ return 42
+
+ d = Dict()
+ assert module.setdefault(d, 'x', 1) == 1
+ assert d['x'] == 1
+
def test_update(self):
module = self.import_extension('foo', [
("update", "METH_VARARGS",
More information about the pypy-commit
mailing list