[pypy-commit] pypy cpyext-unhashable: test, fix for unhashable c-api objects

mattip pypy.commits at gmail.com
Sat May 20 15:41:57 EDT 2017


Author: Matti Picus <matti.picus at gmail.com>
Branch: cpyext-unhashable
Changeset: r91348:552622605578
Date: 2017-05-20 22:30 +0300
http://bitbucket.org/pypy/pypy/changeset/552622605578/

Log:	test, fix for unhashable c-api objects

diff --git a/pypy/module/cpyext/methodobject.py b/pypy/module/cpyext/methodobject.py
--- a/pypy/module/cpyext/methodobject.py
+++ b/pypy/module/cpyext/methodobject.py
@@ -272,6 +272,7 @@
     __objclass__ = interp_attrproperty_w('w_objclass', cls=W_PyCWrapperObject),
     __repr__ = interp2app(W_PyCWrapperObject.descr_method_repr),
     # XXX missing: __getattribute__
+    __hash__ = None
     )
 W_PyCWrapperObject.typedef.acceptable_as_base_class = False
 
diff --git a/pypy/module/cpyext/test/test_arraymodule.py b/pypy/module/cpyext/test/test_arraymodule.py
--- a/pypy/module/cpyext/test/test_arraymodule.py
+++ b/pypy/module/cpyext/test/test_arraymodule.py
@@ -159,3 +159,11 @@
         fd = BytesIO()
         # only test that it works
         fd.write(a)
+
+    def test_hash(self):
+        module = self.import_module(name='array')
+        a = module.array('c')
+        exc = raises(TypeError, hash, a)
+        assert 'unhashable' in str(exc.value)
+        exc = raises(TypeError, hash, a.__mul__)
+        assert 'unhashable' in str(exc.value)
diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py
--- a/pypy/module/cpyext/typeobject.py
+++ b/pypy/module/cpyext/typeobject.py
@@ -338,7 +338,6 @@
                 setattr(struct, slot_names[1], slot_func_helper)
 
 def add_operators(space, dict_w, pto):
-    # XXX support PyObject_HashNotImplemented
     for method_name, slot_names, wrapper_func, wrapper_func_kwds, doc in slotdefs_for_wrappers:
         if method_name in dict_w:
             continue
@@ -365,6 +364,9 @@
             rffi.charp2str(cts.cast('char*', pto.c_tp_doc)))
     if pto.c_tp_new:
         add_tp_new_wrapper(space, dict_w, pto)
+    if not pto.c_tp_hash:
+        dict_w['__hash__'] = space.w_None
+    print 'pto', rffi.charp2str(pto.c_tp_name), 'c_tp_hash', pto.c_tp_hash, dict_w['__hash__']
 
 @slot_function([PyObject, PyObject, PyObject], PyObject)
 def tp_new_wrapper(space, self, w_args, w_kwds):
@@ -943,6 +945,7 @@
     if w_obj.is_cpytype():
         Py_DecRef(space, pto.c_tp_dict)
     w_dict = w_obj.getdict(space)
+
     # pass in the w_obj to convert any values that are
     # unbound GetSetProperty into bound PyGetSetDescrObject
     pto.c_tp_dict = make_ref(space, w_dict, w_obj)


More information about the pypy-commit mailing list