[pypy-commit] pypy py3.5: Implement PyUnicode_InternInPlace (port PyString_InternInPlace from default)

rlamy pypy.commits at gmail.com
Tue Feb 21 10:36:25 EST 2017


Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: py3.5
Changeset: r90272:033d9de18f47
Date: 2017-02-21 15:35 +0000
http://bitbucket.org/pypy/pypy/changeset/033d9de18f47/

Log:	Implement PyUnicode_InternInPlace (port PyString_InternInPlace from
	default)

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
@@ -1858,28 +1858,6 @@
     there was an error."""
     raise NotImplementedError
 
- at cpython_api([PyObjectP], lltype.Void)
-def PyUnicode_InternInPlace(space, string):
-    """Intern the argument *string in place.  The argument must be the address of a
-    pointer variable pointing to a Python unicode 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.)"""
-    raise NotImplementedError
-
-
- at cpython_api([rffi.CCHARP], PyObject)
-def PyUnicode_InternFromString(space, v):
-    """A combination of PyUnicode_FromString() and
-    PyUnicode_InternInPlace(), returning either a new unicode string object
-    that has been interned, or a new ("owned") reference to an earlier interned
-    string object with the same value."""
-    raise NotImplementedError
-
 
 @cpython_api([rffi.INT_real, CWCHARPP], rffi.INT_real, error=1)
 def Py_Main(space, argc, argv):
diff --git a/pypy/module/cpyext/test/test_unicodeobject.py b/pypy/module/cpyext/test/test_unicodeobject.py
--- a/pypy/module/cpyext/test/test_unicodeobject.py
+++ b/pypy/module/cpyext/test/test_unicodeobject.py
@@ -78,6 +78,20 @@
         print(module.strlen(True))
         assert module.strlen(True) == 4
 
+    def test_intern_inplace(self):
+        module = self.import_extension('foo', [
+            ("test_intern_inplace", "METH_O",
+             '''
+                 PyObject *s = args;
+                 Py_INCREF(s);
+                 PyUnicode_InternInPlace(&s);
+                 return s;
+             '''
+             )])
+        # This does not test much, but at least the refcounts are checked.
+        assert module.test_intern_inplace('s') == 's'
+
+
     def test_unicode_buffer_init(self):
         module = self.import_extension('foo', [
             ("getunicode", "METH_NOARGS",
diff --git a/pypy/module/cpyext/unicodeobject.py b/pypy/module/cpyext/unicodeobject.py
--- a/pypy/module/cpyext/unicodeobject.py
+++ b/pypy/module/cpyext/unicodeobject.py
@@ -587,6 +587,23 @@
     w_str = space.newbytes(rffi.charp2str(s))
     return space.call_method(w_str, 'decode', space.newtext("utf-8"))
 
+ at cpython_api([PyObjectP], lltype.Void)
+def PyUnicode_InternInPlace(space, string):
+    """Intern the argument *string in place.  The argument must be the address
+    of a pointer variable pointing to a Python unicode 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.)"""
+    w_str = from_ref(space, string[0])
+    w_str = space.new_interned_w_str(w_str)
+    Py_DecRef(space, string[0])
+    string[0] = make_ref(space, w_str)
+
+
 @cpython_api([CONST_STRING], PyObject)
 def PyUnicode_InternFromString(space, s):
     """A combination of PyUnicode_FromString() and


More information about the pypy-commit mailing list