[pypy-commit] pypy default: cpyext: implement PyString_InternInPlace()
amauryfa
noreply at buildbot.pypy.org
Tue Feb 14 22:41:51 CET 2012
Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch:
Changeset: r52488:a5bb40bcb46b
Date: 2012-02-14 22:34 +0100
http://bitbucket.org/pypy/pypy/changeset/a5bb40bcb46b/
Log: cpyext: implement PyString_InternInPlace()
diff --git a/pypy/module/cpyext/stringobject.py b/pypy/module/cpyext/stringobject.py
--- a/pypy/module/cpyext/stringobject.py
+++ b/pypy/module/cpyext/stringobject.py
@@ -250,6 +250,25 @@
s = rffi.charp2str(string)
return space.new_interned_str(s)
+ at cpython_api([PyObjectP], lltype.Void)
+def PyString_InternInPlace(space, string):
+ """Intern the argument *string in place. The argument must be the
+ address of a pointer variable pointing to a Python string object.
+ If there is an existing interned string that is the same as
+ *string, it sets *string to it (decrementing the reference count
+ of the old string object and incrementing the reference count of
+ the interned string object), otherwise it leaves *string alone and
+ interns it (incrementing its reference count). (Clarification:
+ even though there is a lot of talk about reference counts, think
+ of this function as reference-count-neutral; you own the object
+ after the call if and only if you owned it before the call.)
+
+ This function is not available in 3.x and does not have a PyBytes
+ alias."""
+ w_str = from_ref(space, string[0])
+ w_str = space.new_interned_w_str(w_str)
+ string[0] = make_ref(space, w_str)
+
@cpython_api([PyObject, rffi.CCHARP, rffi.CCHARP], PyObject)
def PyString_AsEncodedObject(space, w_str, encoding, errors):
"""Encode a string object using the codec registered for encoding and return
diff --git a/pypy/module/cpyext/stubs.py b/pypy/module/cpyext/stubs.py
--- a/pypy/module/cpyext/stubs.py
+++ b/pypy/module/cpyext/stubs.py
@@ -1768,21 +1768,6 @@
"""Empty an existing set of all elements."""
raise NotImplementedError
- at cpython_api([PyObjectP], lltype.Void)
-def PyString_InternInPlace(space, string):
- """Intern the argument *string in place. The argument must be the address of a
- pointer variable pointing to a Python string object. If there is an existing
- interned string that is the same as *string, it sets *string to it
- (decrementing the reference count of the old string object and incrementing the
- reference count of the interned string object), otherwise it leaves *string
- alone and interns it (incrementing its reference count). (Clarification: even
- though there is a lot of talk about reference counts, think of this function as
- reference-count-neutral; you own the object after the call if and only if you
- owned it before the call.)
-
- This function is not available in 3.x and does not have a PyBytes alias."""
- raise NotImplementedError
-
@cpython_api([rffi.CCHARP, Py_ssize_t, rffi.CCHARP, rffi.CCHARP], PyObject)
def PyString_Decode(space, s, size, encoding, errors):
"""Create an object by decoding size bytes of the encoded buffer s using the
diff --git a/pypy/module/cpyext/test/test_stringobject.py b/pypy/module/cpyext/test/test_stringobject.py
--- a/pypy/module/cpyext/test/test_stringobject.py
+++ b/pypy/module/cpyext/test/test_stringobject.py
@@ -166,6 +166,20 @@
res = module.test_string_format(1, "xyz")
assert res == "bla 1 ble xyz\n"
+ def test_intern_inplace(self):
+ module = self.import_extension('foo', [
+ ("test_intern_inplace", "METH_O",
+ '''
+ PyObject *s = args;
+ Py_INCREF(s);
+ PyString_InternInPlace(&s);
+ return s;
+ '''
+ )
+ ])
+ # This does not test much, but at least the refcounts are checked.
+ assert module.test_intern_inplace('s') == 's'
+
class TestString(BaseApiTest):
def test_string_resize(self, space, api):
py_str = new_empty_str(space, 10)
More information about the pypy-commit
mailing list