[pypy-commit] pypy missing-tp_new: avoid calling tp_hash via hash_w(w_obj) during object attach or realize

mattip pypy.commits at gmail.com
Thu Jan 5 00:18:58 EST 2017


Author: Matti Picus <matti.picus at gmail.com>
Branch: missing-tp_new
Changeset: r89372:7bce3ce5fbce
Date: 2017-01-05 07:17 +0200
http://bitbucket.org/pypy/pypy/changeset/7bce3ce5fbce/

Log:	avoid calling tp_hash via hash_w(w_obj) during object attach or
	realize

diff --git a/pypy/module/cpyext/bytesobject.py b/pypy/module/cpyext/bytesobject.py
--- a/pypy/module/cpyext/bytesobject.py
+++ b/pypy/module/cpyext/bytesobject.py
@@ -88,7 +88,10 @@
     with rffi.scoped_nonmovingbuffer(s) as s_ptr:
         rffi.c_memcpy(py_str.c_ob_sval, s_ptr, len_s)
     py_str.c_ob_sval[len_s] = '\0'
-    py_str.c_ob_shash = space.hash_w(w_obj)
+    # if py_obj has a tp_hash, this will try to call it, but the objects are
+    # not fully linked yet
+    #py_str.c_ob_shash = space.hash_w(w_obj)
+    py_str.c_ob_shash = space.hash_w(space.newbytes(s))
     py_str.c_ob_sstate = rffi.cast(rffi.INT, 1) # SSTATE_INTERNED_MORTAL
 
 def bytes_realize(space, py_obj):
@@ -101,7 +104,9 @@
     w_type = from_ref(space, rffi.cast(PyObject, py_obj.c_ob_type))
     w_obj = space.allocate_instance(W_BytesObject, w_type)
     w_obj.__init__(s)
-    py_str.c_ob_shash = space.hash_w(w_obj)
+    # if py_obj has a tp_hash, this will try to call it but the object is
+    # not realized yet
+    py_str.c_ob_shash = space.hash_w(space.newbytes(s))
     py_str.c_ob_sstate = rffi.cast(rffi.INT, 1) # SSTATE_INTERNED_MORTAL
     track_reference(space, py_obj, w_obj)
     return w_obj
diff --git a/pypy/module/cpyext/test/test_bytesobject.py b/pypy/module/cpyext/test/test_bytesobject.py
--- a/pypy/module/cpyext/test/test_bytesobject.py
+++ b/pypy/module/cpyext/test/test_bytesobject.py
@@ -437,6 +437,7 @@
                 PyStringArrType_Type.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE;
                 PyStringArrType_Type.tp_itemsize = sizeof(char);
                 PyStringArrType_Type.tp_base = &PyString_Type;
+                PyStringArrType_Type.tp_hash = PyString_Type.tp_hash;
                 if (PyType_Ready(&PyStringArrType_Type) < 0) INITERROR;
             ''')
 
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
@@ -65,9 +65,10 @@
 def unicode_attach(space, py_obj, w_obj, w_userdata=None):
     "Fills a newly allocated PyUnicodeObject with a unicode string"
     py_unicode = rffi.cast(PyUnicodeObject, py_obj)
-    py_unicode.c_length = len(space.unicode_w(w_obj))
+    s = space.unicode_w(w_obj)
+    py_unicode.c_length = len(s)
     py_unicode.c_str = lltype.nullptr(rffi.CWCHARP.TO)
-    py_unicode.c_hash = space.hash_w(w_obj)
+    py_unicode.c_hash = space.hash_w(space.newunicode(s))
     py_unicode.c_defenc = lltype.nullptr(PyObject.TO)
 
 def unicode_realize(space, py_obj):
@@ -80,7 +81,7 @@
     w_type = from_ref(space, rffi.cast(PyObject, py_obj.c_ob_type))
     w_obj = space.allocate_instance(unicodeobject.W_UnicodeObject, w_type)
     w_obj.__init__(s)
-    py_uni.c_hash = space.hash_w(w_obj)
+    py_uni.c_hash = space.hash_w(space.newunicode(s))
     track_reference(space, py_obj, w_obj)
     return w_obj
 


More information about the pypy-commit mailing list