Author: Matti Picus <matti.pi...@gmail.com> Branch: py3.6 Changeset: r97911:87d2c3bfeef2 Date: 2019-10-31 18:36 +0200 http://bitbucket.org/pypy/pypy/changeset/87d2c3bfeef2/
Log: merge default into py3.6 diff --git a/lib_pypy/_curses_build.py b/lib_pypy/_curses_build.py --- a/lib_pypy/_curses_build.py +++ b/lib_pypy/_curses_build.py @@ -1,26 +1,27 @@ +from cffi import FFI import os -from cffi import FFI, VerificationError - -def find_curses_library(): - for curses_library in ['ncursesw', 'ncurses']: +def find_library(options): + for library in options: ffi = FFI() - ffi.set_source("_curses_cffi_check", "", libraries=[curses_library]) + ffi.set_source("_curses_cffi_check", "", libraries=[library]) try: ffi.compile() except VerificationError as e: e_last = e continue else: - return curses_library + return library - # If none of the libraries is available, present the user a meaningful + # If none of the options is available, present the user a meaningful # error message raise e_last def find_curses_include_dirs(): + if os.path.exists('/usr/include/ncurses'): + return ['/usr/include/ncurses'] if os.path.exists('/usr/include/ncursesw'): - return ['/usr/include/ncursesw'] + return ['/usr/include/ncursesw'] return [] @@ -72,7 +73,8 @@ void _m_getsyx(int *yx) { getsyx(yx[0], yx[1]); } -""", libraries=[find_curses_library(), 'panel'], +""", libraries=[find_library(['ncurses', 'ncursesw']), + find_library(['panel', 'panelw'])], include_dirs=find_curses_include_dirs()) 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 @@ -278,13 +278,14 @@ py_dict = rffi.cast(PyDictObject, py_obj) if pos == 0: # Store the current keys in the PyDictObject. - decref(space, py_dict.c__tmpkeys) w_keyview = space.call_method(space.w_dict, "keys", w_dict) # w_keys must use the object strategy in order to keep the keys alive w_keys = space.newlist(space.listview(w_keyview)) w_keys.switch_to_object_strategy() + oldkeys = py_dict.c__tmpkeys py_dict.c__tmpkeys = create_ref(space, w_keys) incref(space, py_dict.c__tmpkeys) + decref(space, oldkeys) else: if not py_dict.c__tmpkeys: # pos should have been 0, cannot fail so return 0 diff --git a/pypy/module/cpyext/include/Python.h b/pypy/module/cpyext/include/Python.h --- a/pypy/module/cpyext/include/Python.h +++ b/pypy/module/cpyext/include/Python.h @@ -109,6 +109,7 @@ #include "tupleobject.h" #include "dictobject.h" #include "longobject.h" +#include "setobject.h" #include "listobject.h" #include "longobject.h" #include "unicodeobject.h" diff --git a/pypy/module/cpyext/include/setobject.h b/pypy/module/cpyext/include/setobject.h new file mode 100644 --- /dev/null +++ b/pypy/module/cpyext/include/setobject.h @@ -0,0 +1,19 @@ + +/* set object interface */ + +#ifndef Py_SETOBJECT_H +#define Py_SETOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PyObject_HEAD + PyObject *_tmplist; /* a private place to put values during _PySet_Next */ +} PySetObject; + +#ifdef __cplusplus +} +#endif +#endif /* !Py_SETOBJECT_H */ + diff --git a/pypy/module/cpyext/object.py b/pypy/module/cpyext/object.py --- a/pypy/module/cpyext/object.py +++ b/pypy/module/cpyext/object.py @@ -362,11 +362,11 @@ """ Compute and return the hash value of an object o. On failure, return -1. This is the equivalent of the Python expression hash(o).""" - return space.int_w(space.hash(w_obj)) + return space.hash_w(w_obj) @cpython_api([rffi.DOUBLE], rffi.LONG, error=-1) def _Py_HashDouble(space, v): - return space.int_w(space.hash(space.newfloat(v))) + return space.hash_w(space.newfloat(v)) @cpython_api([PyObject], lltype.Signed, error=-1) def PyObject_HashNotImplemented(space, o): diff --git a/pypy/module/cpyext/setobject.py b/pypy/module/cpyext/setobject.py --- a/pypy/module/cpyext/setobject.py +++ b/pypy/module/cpyext/setobject.py @@ -1,12 +1,45 @@ from pypy.interpreter.error import OperationError, oefmt from rpython.rtyper.lltypesystem import rffi, lltype -from pypy.module.cpyext.api import (cpython_api, Py_ssize_t, CANNOT_FAIL, - build_type_checkers) +from pypy.module.cpyext.api import ( + cpython_api, Py_ssize_t, Py_ssize_tP, CANNOT_FAIL, build_type_checkers, + PyObjectFields, cpython_struct, bootstrap_function, slot_function) from pypy.module.cpyext.pyobject import (PyObject, PyObjectP, - make_ref, from_ref) + make_ref, from_ref, as_pyobj, create_ref, make_typedescr, incref, decref) +from pypy.module.cpyext.object import _dealloc from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall from pypy.objspace.std.setobject import W_SetObject, W_FrozensetObject, newset +PySetObjectStruct = lltype.ForwardReference() +PySetObject = lltype.Ptr(PySetObjectStruct) +PySetObjectFields = PyObjectFields + \ + (("_tmplist", PyObject),) +cpython_struct("PySetObject", PySetObjectFields, PySetObjectStruct) + +@bootstrap_function +def init_setobject(space): + "Type description of PySetObject" + make_typedescr(space.w_set.layout.typedef, + basestruct=PySetObject.TO, + attach=set_attach, + dealloc=set_dealloc) + make_typedescr(space.w_frozenset.layout.typedef, # same as 'set' + basestruct=PySetObject.TO, + attach=set_attach, + dealloc=set_dealloc) + +def set_attach(space, py_obj, w_obj, w_userdata=None): + """ + Fills a newly allocated PySetObject with the given set object. + """ + py_set = rffi.cast(PySetObject, py_obj) + py_set.c__tmplist = lltype.nullptr(PyObject.TO) + +@slot_function([PyObject], lltype.Void) +def set_dealloc(space, py_obj): + py_set = rffi.cast(PySetObject, py_obj) + decref(space, py_set.c__tmplist) + py_set.c__tmplist = lltype.nullptr(PyObject.TO) + _dealloc(space, py_obj) PySet_Check, PySet_CheckExact = build_type_checkers("Set") PyFrozenSet_Check, PyFrozenSet_CheckExact = build_type_checkers("FrozenSet") @@ -23,7 +56,7 @@ """Return true if obj is a set object or a frozenset object but not an instance of a subtype.""" w_obj_type = space.type(w_obj) - return (space.is_w(w_obj_type, space.gettypefor(W_SetObject)) or + return (space.is_w(w_obj_type, space.gettypefor(W_SetObject)) or space.is_w(w_obj_type, space.gettypefor(W_FrozensetObject))) @cpython_api([PyObject], PyObject) @@ -126,4 +159,43 @@ else: return space.call_function(space.w_frozenset, w_iterable) +@cpython_api([PyObject, Py_ssize_tP, PyObjectP, Py_ssize_tP], rffi.INT_real, error=-1) +def _PySet_NextEntry(space, w_set, ppos, pkey, phash): + if w_set is None or not PyAnySet_Check(space, w_set): + PyErr_BadInternalCall(space) + return -1 + if not pkey: + PyErr_BadInternalCall(space) + return -1 + pos = ppos[0] + py_obj = as_pyobj(space, w_set) + py_set = rffi.cast(PySetObject, py_obj) + if pos == 0: + # Store the current item list in the PySetObject. + # w_keys must use the object strategy in order to keep the keys alive + w_keys = space.newlist(space.listview(w_set)) + w_keys.switch_to_object_strategy() + oldlist = py_set.c__tmplist + py_set.c__tmplist = create_ref(space, w_keys) + incref(space, py_set.c__tmplist) + decref(space, oldlist) + else: + if not py_set.c__tmplist: + # pos should have been 0, cannot fail so return 0 + return 0; + w_keys = from_ref(space, py_set.c__tmplist) + ppos[0] += 1 + if pos >= space.len_w(w_keys): + decref(space, py_set.c__tmplist) + py_set.c__tmplist = lltype.nullptr(PyObject.TO) + return 0 + w_key = space.listview(w_keys)[pos] + pkey[0] = as_pyobj(space, w_key) + if phash: + phash[0] = space.hash_w(w_key) + return 1 +@cpython_api([PyObject, Py_ssize_tP, PyObjectP], rffi.INT_real, error=-1) +def _PySet_Next(space, w_set, ppos, pkey): + null = lltype.nullptr(Py_ssize_tP.TO) + return _PySet_NextEntry(space, w_set, ppos, pkey, null) diff --git a/pypy/module/cpyext/test/test_setobject.py b/pypy/module/cpyext/test/test_setobject.py --- a/pypy/module/cpyext/test/test_setobject.py +++ b/pypy/module/cpyext/test/test_setobject.py @@ -1,8 +1,11 @@ +from rpython.rtyper.lltypesystem import lltype from pypy.module.cpyext.test.test_api import BaseApiTest, raises_w from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase from pypy.module.cpyext.setobject import ( PySet_Check, PyFrozenSet_Check, PyFrozenSet_CheckExact, PySet_Add, PySet_Size, PySet_GET_SIZE) +from pypy.module.cpyext.api import Py_ssize_tP, PyObjectP +from pypy.module.cpyext.pyobject import from_ref class TestTupleObject(BaseApiTest): @@ -62,6 +65,42 @@ """) assert api.PyAnySet_Check(w_instance) + def test_pyset_next(self, space, api): + w_set = space.call_function(space.w_set, space.newtext("ab")) + with lltype.scoped_alloc(Py_ssize_tP.TO, 1) as pos_p: + with lltype.scoped_alloc(PyObjectP.TO, 1) as result_p: + pos_p[0] = 0 + res = api._PySet_Next(w_set, pos_p, result_p) + assert res == 1 + letter1 = space.text_w(from_ref(space, result_p[0])) + res = api._PySet_Next(w_set, pos_p, result_p) + assert res == 1 + letter2 = space.text_w(from_ref(space, result_p[0])) + res = api._PySet_Next(w_set, pos_p, result_p) + assert res == 0 + assert set([letter1, letter2]) == set("ab") + + def test_pyset_nextentry(self, space, api): + w_set = space.call_function(space.w_set, space.newtext("ab")) + with lltype.scoped_alloc(Py_ssize_tP.TO, 1) as pos_p: + with lltype.scoped_alloc(PyObjectP.TO, 1) as result_p: + with lltype.scoped_alloc(Py_ssize_tP.TO, 1) as hash_p: + pos_p[0] = 0 + res = api._PySet_NextEntry(w_set, pos_p, result_p, hash_p) + assert res == 1 + w_obj = from_ref(space, result_p[0]) + letter1 = space.text_w(w_obj) + assert hash_p[0] == space.hash_w(w_obj) + res = api._PySet_NextEntry(w_set, pos_p, result_p, hash_p) + assert res == 1 + w_obj = from_ref(space, result_p[0]) + letter2 = space.text_w(w_obj) + assert hash_p[0] == space.hash_w(w_obj) + res = api._PySet_NextEntry(w_set, pos_p, result_p, hash_p) + assert res == 0 + assert set([letter1, letter2]) == set("ab") + + class AppTestSetObject(AppTestCpythonExtensionBase): def test_set_macro_cast(self): module = self.import_extension('foo', [ diff --git a/pypy/module/cpyext/userslot.py b/pypy/module/cpyext/userslot.py --- a/pypy/module/cpyext/userslot.py +++ b/pypy/module/cpyext/userslot.py @@ -22,7 +22,7 @@ @slot_function([PyObject], lltype.Signed, error=-1) def slot_tp_hash(space, w_obj): - return space.int_w(space.hash(w_obj)) + return space.hash_w(w_obj) @slot_function([PyObject, Py_ssize_t], PyObject) def slot_sq_item(space, w_obj, index): _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit