Author: Matti Picus <matti.pi...@gmail.com> Branch: unicode-utf8 Changeset: r94801:f32c591c9e7f Date: 2018-07-01 22:45 -0500 http://bitbucket.org/pypy/pypy/changeset/f32c591c9e7f/
Log: merged default into branch diff --git a/pypy/doc/sandbox.rst b/pypy/doc/sandbox.rst --- a/pypy/doc/sandbox.rst +++ b/pypy/doc/sandbox.rst @@ -3,6 +3,11 @@ PyPy's sandboxing features ========================== +.. warning:: This is not actively maintained. You will likely have to fix + some issues yourself, or otherwise play around on your own. We provide + this documentation for historical reasions, it will not translate or + run on the latest PyPy code base. + Introduction ------------ diff --git a/pypy/interpreter/pyparser/automata.py b/pypy/interpreter/pyparser/automata.py --- a/pypy/interpreter/pyparser/automata.py +++ b/pypy/interpreter/pyparser/automata.py @@ -23,6 +23,10 @@ ERROR_STATE = chr(255) +# NB: all non-ascii bytes (>= 128) will be turned into 128 +NON_ASCII = chr(128) + + class DFA: # ____________________________________________________________ def __init__(self, states, accepts, start = 0): @@ -36,7 +40,10 @@ for key in state: if key == DEFAULT: continue - maximum = max(ord(key), maximum) + ordkey = ord(key) + if ordkey > 128: + raise ValueError("DFA does not support matching of specific non-ASCII character %r. Use NON_ASCII instead" % key) + maximum = max(ordkey, maximum) self.max_char = maximum + 1 defaults = [] @@ -72,6 +79,8 @@ i = pos for i in range(pos, len(inVec)): item = inVec[i] + if ord(item) > 0x80: + item = NON_ASCII accept = self.accepts[crntState] crntState = self._next_state(item, crntState) if crntState != ERROR_STATE: @@ -103,6 +112,8 @@ i = pos for i in range(pos, len(inVec)): item = inVec[i] + if ord(item) > 0x80: + item = NON_ASCII accept = self.accepts[crntState] if accept: return i diff --git a/pypy/interpreter/pyparser/test/test_automata.py b/pypy/interpreter/pyparser/test/test_automata.py --- a/pypy/interpreter/pyparser/test/test_automata.py +++ b/pypy/interpreter/pyparser/test/test_automata.py @@ -1,4 +1,7 @@ -from pypy.interpreter.pyparser.automata import DFA, NonGreedyDFA, DEFAULT +# coding: utf-8 +import pytest + +from pypy.interpreter.pyparser.automata import DFA, NonGreedyDFA, DEFAULT, NON_ASCII def test_states(): d = DFA([{"\x00": 1}, {"\x01": 0}], [False, True]) @@ -27,3 +30,18 @@ d = NonGreedyDFA([{"a": 1}, {DEFAULT: 0}], [False, True]) assert d.recognize("a,a?ab") == 1 assert d.recognize("c") == -1 + +def test_nonascii(): + d = DFA([{"a": 1}, {NON_ASCII: 1}], [False, True]) + input = u"aüüüü".encode("utf-8") + assert d.recognize(input) == len(input) + assert d.recognize("c") == -1 + assert d.recognize("ü") == -1 + + d = NonGreedyDFA([{NON_ASCII: 0, "b": 1}, {"b": 0}], [False, True]) + input = u"üübbbb".encode("utf-8") + assert d.recognize(input) == len(u"üüb".encode("utf-8")) + assert d.recognize("c") == -1 + + pytest.raises(ValueError, DFA, [{"\x81": 2}], [True]) + diff --git a/pypy/interpreter/test/test_function.py b/pypy/interpreter/test/test_function.py --- a/pypy/interpreter/test/test_function.py +++ b/pypy/interpreter/test/test_function.py @@ -455,6 +455,8 @@ assert repr(B().f).startswith("<bound method B.f of <") assert repr(A().f).endswith(">>") + assert repr(type(A.f)) == repr(type(A().f)) == "<type 'instancemethod'>" + def test_method_call(self): class C(object): diff --git a/pypy/interpreter/test/test_raise.py b/pypy/interpreter/test/test_raise.py --- a/pypy/interpreter/test/test_raise.py +++ b/pypy/interpreter/test/test_raise.py @@ -280,3 +280,15 @@ def __new__(cls, *args): return object() raises(TypeError, "raise MyException") + + def test_with_exit_True(self): + class X: + def __enter__(self): + pass + def __exit__(self, *args): + return True + def g(): + with X(): + return 42 + assert False, "unreachable" + assert g() == 42 diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py --- a/pypy/interpreter/typedef.py +++ b/pypy/interpreter/typedef.py @@ -688,7 +688,7 @@ Function.typedef.acceptable_as_base_class = False Method.typedef = TypeDef( - "method", + "instancemethod", __doc__ = """instancemethod(function, instance, class) Create an instance method object.""", diff --git a/pypy/module/_cppyy/converter.py b/pypy/module/_cppyy/converter.py --- a/pypy/module/_cppyy/converter.py +++ b/pypy/module/_cppyy/converter.py @@ -706,7 +706,7 @@ "no overload found matching %s", self.signature) -class SmartPointerConverter(TypeConverter): +class SmartPtrConverter(TypeConverter): _immutable_fields = ['typecode', 'smartdecl', 'rawdecl', 'deref'] typecode = 'V' @@ -753,7 +753,7 @@ return interp_cppyy.wrap_cppinstance(space, address, self.rawdecl, smartdecl=self.smartdecl, deref=self.deref, do_cast=False) -class SmartPointerPtrConverter(SmartPointerConverter): +class SmartPtrPtrConverter(SmartPtrConverter): typecode = 'o' def from_memory(self, space, w_obj, w_pycppclass, offset): @@ -763,7 +763,7 @@ self._is_abstract(space) -class SmartPointerRefConverter(SmartPointerPtrConverter): +class SmartPtrRefConverter(SmartPtrPtrConverter): typecode = 'V' @@ -804,6 +804,12 @@ compound = helper.compound(name) clean_name = capi.c_resolve_name(space, helper.clean_type(name)) try: + return _converters[clean_name+compound](space, default) + except KeyError: + pass + + # arrays + try: # array_index may be negative to indicate no size or no size found array_size = helper.array_size(_name) # uses original arg # TODO: using clean_name here drops const (e.g. const char[] will @@ -823,11 +829,11 @@ check_smart = capi.c_smartptr_info(space, clean_name) if check_smart[0]: if compound == '': - return SmartPointerConverter(space, clsdecl, check_smart[1], check_smart[2]) + return SmartPtrConverter(space, clsdecl, check_smart[1], check_smart[2]) elif compound == '*': - return SmartPointerPtrConverter(space, clsdecl, check_smart[1], check_smart[2]) + return SmartPtrPtrConverter(space, clsdecl, check_smart[1], check_smart[2]) elif compound == '&': - return SmartPointerRefConverter(space, clsdecl, check_smart[1], check_smart[2]) + return SmartPtrRefConverter(space, clsdecl, check_smart[1], check_smart[2]) # fall through: can still return smart pointer in non-smart way # type check for the benefit of the annotator diff --git a/pypy/module/_cppyy/executor.py b/pypy/module/_cppyy/executor.py --- a/pypy/module/_cppyy/executor.py +++ b/pypy/module/_cppyy/executor.py @@ -26,7 +26,7 @@ NULL = lltype.nullptr(jit_libffi.FFI_TYPE_P.TO) -class FunctionExecutor(object): +class Executor(object): def __init__(self, space, extra): pass @@ -43,7 +43,7 @@ raise FastCallNotPossible -class PtrTypeExecutor(FunctionExecutor): +class PtrTypeExecutor(Executor): _immutable_fields_ = ['typecode'] typecode = 'P' @@ -63,7 +63,7 @@ return W_ArrayInstance(space, shape, sys.maxint/shape.size, ptrval) -class VoidExecutor(FunctionExecutor): +class VoidExecutor(Executor): def cffi_type(self, space): state = space.fromcache(ffitypes.State) return state.c_void @@ -96,7 +96,7 @@ _mixin_ = True def __init__(self, space, extra): - FunctionExecutor.__init__(self, space, extra) + Executor.__init__(self, space, extra) self.do_assign = False self.item = rffi.cast(self.c_type, 0) @@ -124,7 +124,7 @@ rffi.cast(self.c_ptrtype, rffi.cast(rffi.VOIDPP, result)[0])) -class CStringExecutor(FunctionExecutor): +class CStringExecutor(Executor): def execute(self, space, cppmethod, cppthis, num_args, args): lresult = capi.c_call_l(space, cppmethod, cppthis, num_args, args) ccpresult = rffi.cast(rffi.CCHARP, lresult) @@ -134,7 +134,7 @@ return space.newbytes(result) -class ConstructorExecutor(FunctionExecutor): +class ConstructorExecutor(Executor): def execute(self, space, cppmethod, cpptype, num_args, args): from pypy.module._cppyy import interp_cppyy newthis = capi.c_constructor(space, cppmethod, cpptype, num_args, args) @@ -142,12 +142,12 @@ return space.newlong(rffi.cast(rffi.LONG, newthis)) # really want ptrdiff_t here -class InstanceExecutor(FunctionExecutor): +class InstanceExecutor(Executor): # For return of a C++ instance by pointer: MyClass* func() _immutable_fields_ = ['clsdecl'] def __init__(self, space, clsdecl): - FunctionExecutor.__init__(self, space, clsdecl) + Executor.__init__(self, space, clsdecl) self.clsdecl = clsdecl def _wrap_result(self, space, obj): @@ -338,7 +338,7 @@ return _executors['void*'](space, None) # allow at least passing of the pointer # currently used until proper lazy instantiation available in interp_cppyy - return FunctionExecutor(space, None) + return Executor(space, None) _executors["void"] = VoidExecutor @@ -374,10 +374,10 @@ ) for c_type, stub, names in type_info: - class BasicExecutor(ffitypes.typeid(c_type), NumericExecutorMixin, FunctionExecutor): + class BasicExecutor(ffitypes.typeid(c_type), NumericExecutorMixin, Executor): _immutable_ = True c_stubcall = staticmethod(stub) - class BasicRefExecutor(ffitypes.typeid(c_type), NumericRefExecutorMixin, FunctionExecutor): + class BasicRefExecutor(ffitypes.typeid(c_type), NumericRefExecutorMixin, Executor): def cffi_type(self, space): state = space.fromcache(ffitypes.State) return state.c_voidp diff --git a/pypy/module/_cppyy/ffitypes.py b/pypy/module/_cppyy/ffitypes.py --- a/pypy/module/_cppyy/ffitypes.py +++ b/pypy/module/_cppyy/ffitypes.py @@ -119,7 +119,7 @@ value = space.bytes_w(w_value) if len(value) != 1: raise oefmt(space.w_ValueError, - "usigned char expected, got string of size %d", len(value)) + "unsigned char expected, got string of size %d", len(value)) value = rffi.cast(rffi.CHAR, value[0]) return value # turn it into a "char" to the annotator diff --git a/pypy/module/_cppyy/interp_cppyy.py b/pypy/module/_cppyy/interp_cppyy.py --- a/pypy/module/_cppyy/interp_cppyy.py +++ b/pypy/module/_cppyy/interp_cppyy.py @@ -672,24 +672,33 @@ _mixin_ = True - def construct_template_args(self, w_args): + def construct_template_args(self, w_tpArgs, args_w = None): space = self.space tmpl_args = '' - for i in range(space.len_w(w_args)): - w_obj = space.getitem(w_args, space.newint(i)) - if space.isinstance_w(w_obj, space.w_text): - s = space.text_w(w_obj) # string describing type - elif space.isinstance_w(w_obj, space.w_type): + for i in range(space.len_w(w_tpArgs)): + w_tp = space.getitem(w_tpArgs, space.newint(i)) + if space.isinstance_w(w_tp, space.w_text): + s = space.text_w(w_tp) # string describing type + elif space.isinstance_w(w_tp, space.w_type): try: # cppyy bound types - name = space.getattr(w_obj, space.newtext('__cppname__')) + s = space.text_w(space.getattr(w_tp, space.newtext('__cppname__'))) + if args_w: + # try to specialize the type match for the given object + cppinstance = self.space.interp_w(W_CPPInstance, args_w[i]) + if cppinstance.flags & INSTANCE_FLAGS_IS_RVALUE: + sugar = "&&" + elif cppinstance.flags & INSTANCE_FLAGS_IS_REF: + sugar = "*" + else: + sugar = "&" + s += sugar except OperationError: # generic python types - name = space.getattr(w_obj, space.newtext('__name__')) - s = space.text_w(name) + s = space.text_w(space.getattr(w_tp, space.newtext('__name__'))) else: # builtin types etc. - s = space.text_w(space.str(w_obj)) + s = space.text_w(space.str(w_tp)) # map python types -> C++ types if s == 'str': s = 'std::string' if i != 0: tmpl_args += ', ' @@ -712,23 +721,31 @@ cppol = W_CPPOverload(space, self.scope, funcs[:], self.flags) return cppol - def instantiation_from_args(self, name, args_w): + def instantiate_and_call(self, name, args_w): # try to match with run-time instantiations for cppol in self.master.overloads.values(): try: - cppol.descr_get(self.w_this, []).call(args_w) + return cppol.descr_get(self.w_this, []).call(args_w) except Exception: pass # completely ignore for now; have to see whether errors become confusing # if all failed, then try to deduce from argument types w_types = self.space.newtuple([self.space.type(obj_w) for obj_w in args_w]) - proto = self.construct_template_args(w_types) + proto = self.construct_template_args(w_types, args_w) method = self.find_method_template(name, proto) # only cache result if the name retains the full template - if len(method.functions) == 1: - fullname = capi.c_method_full_name(self.space, method.functions[0].cppmethod) - if 0 <= fullname.rfind('>'): + fullname = capi.c_method_full_name(self.space, method.functions[0].cppmethod) + if 0 <= fullname.rfind('>'): + try: + existing = self.master.overloads[fullname] + allf = existing.functions + method.functions + if isinstance(existing, W_CPPStaticOverload): + cppol = W_CPPStaticOverload(self.space, self.scope, allf, self.flags) + else: + cppol = W_CPPOverload(self.space, self.scope, allf, self.flags) + self.master.overloads[fullname] = cppol + except KeyError: self.master.overloads[fullname] = method return method.descr_get(self.w_this, []).call(args_w) @@ -747,9 +764,12 @@ method = self.master.overloads[fullname] except KeyError: method = self.find_method_template(fullname) - - # cache result (name is always full templated name) - self.master.overloads[fullname] = method + # cache result (name is always full templated name) + self.master.overloads[fullname] = method + # also cache on "official" name (may include default template arguments) + c_fullname = capi.c_method_full_name(self.space, method.functions[0].cppmethod) + if c_fullname != fullname: + self.master.overloads[c_fullname] = method return method.descr_get(self.w_this, []) @@ -774,6 +794,7 @@ return self # unbound, so no new instance needed cppol = W_CPPTemplateOverload(self.space, self.name, self.scope, self.functions, self.flags) cppol.w_this = w_cppinstance + cppol.master = self.master return cppol # bound @unwrap_spec(args_w='args_w') @@ -787,7 +808,7 @@ except Exception: pass - return self.instantiation_from_args(self.name, args_w) + return self.instantiate_and_call(self.name, args_w) @unwrap_spec(args_w='args_w') def getitem(self, args_w): @@ -842,7 +863,7 @@ pass # try new instantiation - return self.instantiation_from_args(self.name, args_w) + return self.instantiate_and_call(self.name, args_w) @unwrap_spec(args_w='args_w') def getitem(self, args_w): diff --git a/pypy/module/_cppyy/pythonify.py b/pypy/module/_cppyy/pythonify.py --- a/pypy/module/_cppyy/pythonify.py +++ b/pypy/module/_cppyy/pythonify.py @@ -408,16 +408,22 @@ # map push_back -> __iadd__ (generally true for STL) if 'push_back' in pyclass.__dict__ and not '__iadd__' in pyclass.__dict__: - def __iadd__(self, ll): - [self.push_back(x) for x in ll] - return self - pyclass.__iadd__ = __iadd__ + if 'reserve' in pyclass.__dict__: + def iadd(self, ll): + self.reserve(len(ll)) + for x in ll: self.push_back(x) + return self + else: + def iadd(self, ll): + for x in ll: self.push_back(x) + return self + pyclass.__iadd__ = iadd # map begin()/end() protocol to iter protocol on STL(-like) classes, but # not on vector, which is pythonized in the capi (interp-level; there is # also the fallback on the indexed __getitem__, but that is slower) - if not 'vector' in name[:11] and \ - ('begin' in pyclass.__dict__ and 'end' in pyclass.__dict__): +# TODO: if not (0 <= name.find('vector') <= 5): + if ('begin' in pyclass.__dict__ and 'end' in pyclass.__dict__): if _cppyy._scope_byname(name+'::iterator') or \ _cppyy._scope_byname(name+'::const_iterator'): def __iter__(self): @@ -430,6 +436,20 @@ pyclass.__iter__ = __iter__ # else: rely on numbered iteration + # add python collection based initializer + if 0 <= name.find('vector') <= 5: + pyclass.__real_init__ = pyclass.__init__ + def vector_init(self, *args): + if len(args) == 1 and isinstance(args[0], (tuple, list)): + ll = args[0] + self.__real_init__() + self.reserve(len(ll)) + for item in ll: + self.push_back(item) + return + return self.__real_init__(*args) + pyclass.__init__ = vector_init + # combine __getitem__ and __len__ to make a pythonized __getitem__ if '__getitem__' in pyclass.__dict__ and '__len__' in pyclass.__dict__: pyclass._getitem__unchecked = pyclass.__getitem__ @@ -470,7 +490,13 @@ for p in pythonizors: p(pyclass, name) +cppyyIsInitialized = False def _post_import_startup(): + # run only once (function is explicitly called in testing) + global cppyyIsInitialized + if cppyyIsInitialized: + return + # _cppyy should not be loaded at the module level, as that will trigger a # call to space.getbuiltinmodule(), which will cause _cppyy to be loaded # at pypy-c startup, rather than on the "import _cppyy" statement @@ -511,6 +537,9 @@ # install nullptr as a unique reference _cppyy.nullptr = _cppyy._get_nullptr() + # done + cppyyIsInitialized = True + # user-defined pythonizations interface _pythonizations = {'' : list()} diff --git a/pypy/module/_cppyy/test/templates.h b/pypy/module/_cppyy/test/templates.h --- a/pypy/module/_cppyy/test/templates.h +++ b/pypy/module/_cppyy/test/templates.h @@ -107,7 +107,7 @@ } inline std::string tuplify(std::ostringstream& out) { - out.seekp(-2, out.cur); out << ')'; + out << "NULL)"; return out.str(); } diff --git a/pypy/module/_cppyy/test/test_templates.py b/pypy/module/_cppyy/test/test_templates.py --- a/pypy/module/_cppyy/test/test_templates.py +++ b/pypy/module/_cppyy/test/test_templates.py @@ -13,7 +13,7 @@ def setup_class(cls): cls.w_test_dct = cls.space.newtext(test_dct) - cls.w_datatypes = cls.space.appexec([], """(): + cls.w_templates = cls.space.appexec([], """(): import ctypes, _cppyy _cppyy._post_import_startup() return ctypes.CDLL(%r, ctypes.RTLD_GLOBAL)""" % (test_dct, )) @@ -84,10 +84,11 @@ import _cppyy - s = _cppyy.gbl.std.ostringstream() - #s << '(' - #_cppyy.gbl.SomeNS.tuplify(s, 1, 4., "aap") - #assert s.str() == '(1, 4, aap) + s = _cppyy.gbl.std.ostringstream('(', _cppyy.gbl.std.ios_base.ate) + # Fails; selects void* overload (?!) + #s << "(" + _cppyy.gbl.SomeNS.tuplify(s, 1, 4., "aap") + assert s.str() == "(1, 4, aap, NULL)" _cppyy.gbl.gInterpreter.Declare(""" template<typename... myTypes> @@ -133,7 +134,7 @@ Obj2 = _cppyy.gbl.AttrTesting.Obj2 select_template_arg = _cppyy.gbl.AttrTesting.select_template_arg - #assert select_template_arg[0, Obj1, Obj2].argument == Obj1 + # assert select_template_arg[0, Obj1, Obj2].argument == Obj1 assert select_template_arg[1, Obj1, Obj2].argument == Obj2 raises(TypeError, select_template_arg.__getitem__, 2, Obj1, Obj2) @@ -169,7 +170,7 @@ # TODO: the ref_value property is inaccessible (offset == -1) - # assert cppyy.gbl.BaseClassWithStatic["size_t"].ref_value == 42 + # assert _cppyy.gbl.BaseClassWithStatic["size_t"].ref_value == 42 b1 = _cppyy.gbl.DerivedClassUsingStatic["size_t"]( 0) b2 = _cppyy.gbl.DerivedClassUsingStatic["size_t"](100) @@ -179,3 +180,62 @@ # assert b2.ref_value == 42 assert b2.m_value == 42 + + +class AppTestBOOSTANY: + spaceconfig = dict(usemodules=['_cppyy', '_rawffi', 'itertools']) + + def setup_class(cls): + cls.w_test_dct = cls.space.newtext(test_dct) + cls.w_templates = cls.space.appexec([], """(): + import ctypes, _cppyy + _cppyy._post_import_startup()""") + + def test01_any_class(self): + """Usage of boost::any""" + + import _cppyy + + if not _cppyy.gbl.gInterpreter.Declare('#include "boost/any.hpp"'): + import warnings + warnings.warn('skipping boost/any testing') + return + + assert _cppyy.gbl.boost + assert _cppyy.gbl.boost.any + + std, boost = _cppyy.gbl.std, _cppyy.gbl.boost + + assert std.list[boost.any] + + val = boost.any() + # test both by-ref and by rvalue + v = std.vector[int]() + val.__assign__(v) + val.__assign__(std.move(std.vector[int](range(100)))) + + _cppyy.gbl.gInterpreter.ProcessLine( + "namespace _cppyy_internal { auto* stdvectid = &typeid(std::vector<int>); }") + + assert val.type() == _cppyy.gbl._cppyy_internal.stdvectid + + extract = boost.any_cast[std.vector[int]](val) + assert type(extract) is std.vector[int] + assert len(extract) == 100 + extract += range(100) + assert len(extract) == 200 + + val.__assign__(std.move(extract)) # move forced + + # TODO: we hit boost::any_cast<int>(boost::any* operand) instead + # of the reference version which raises + boost.any_cast.__useffi__ = False + try: + # raises(Exception, boost.any_cast[int], val) + assert not boost.any_cast[int](val) + except Exception: + # getting here is good, too ... + pass + + extract = boost.any_cast[std.vector[int]](val) + assert len(extract) == 200 diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py --- a/pypy/module/cpyext/api.py +++ b/pypy/module/cpyext/api.py @@ -643,7 +643,7 @@ '_PyTraceMalloc_Track', '_PyTraceMalloc_Untrack', 'PyMem_Malloc', 'PyObject_Free', 'PyObject_GC_Del', 'PyType_GenericAlloc', '_PyObject_New', '_PyObject_NewVar', - '_PyObject_GC_New', '_PyObject_GC_NewVar', + '_PyObject_GC_Malloc', '_PyObject_GC_New', '_PyObject_GC_NewVar', 'PyObject_Init', 'PyObject_InitVar', 'PyInt_FromLong', 'PyTuple_New', '_Py_Dealloc', ] @@ -772,6 +772,9 @@ # a pointer to PyObject PyObjectP = rffi.CArrayPtr(PyObject) +# int * +INTP_real = rffi.CArrayPtr(rffi.INT_real) + def configure_types(): for config in (CConfig, CConfig2): for name, TYPE in rffi_platform.configure(config).iteritems(): diff --git a/pypy/module/cpyext/include/object.h b/pypy/module/cpyext/include/object.h --- a/pypy/module/cpyext/include/object.h +++ b/pypy/module/cpyext/include/object.h @@ -383,6 +383,7 @@ PyAPI_FUNC(PyObject *) _PyObject_New(PyTypeObject *); PyAPI_FUNC(PyVarObject *) _PyObject_NewVar(PyTypeObject *, Py_ssize_t); +PyAPI_FUNC(PyObject *) _PyObject_GC_Malloc(size_t); PyAPI_FUNC(PyObject *) _PyObject_GC_New(PyTypeObject *); PyAPI_FUNC(PyVarObject *) _PyObject_GC_NewVar(PyTypeObject *, Py_ssize_t); diff --git a/pypy/module/cpyext/longobject.py b/pypy/module/cpyext/longobject.py --- a/pypy/module/cpyext/longobject.py +++ b/pypy/module/cpyext/longobject.py @@ -1,7 +1,7 @@ from rpython.rtyper.lltypesystem import lltype, rffi from pypy.module.cpyext.api import ( cpython_api, PyObject, build_type_checkers_flags, Py_ssize_t, - CONST_STRING, ADDR, CANNOT_FAIL) + CONST_STRING, ADDR, CANNOT_FAIL, INTP_real) from pypy.objspace.std.longobject import W_LongObject from pypy.interpreter.error import OperationError, oefmt from pypy.interpreter.unicodehelper import wcharpsize2utf8 @@ -113,7 +113,7 @@ num = space.bigint_w(w_long) return num.ulonglongmask() -@cpython_api([PyObject, rffi.CArrayPtr(rffi.INT_real)], lltype.Signed, +@cpython_api([PyObject, INTP_real], lltype.Signed, error=-1) def PyLong_AsLongAndOverflow(space, w_long, overflow_ptr): """ @@ -134,7 +134,7 @@ overflow_ptr[0] = rffi.cast(rffi.INT_real, -1) return -1 -@cpython_api([PyObject, rffi.CArrayPtr(rffi.INT_real)], rffi.LONGLONG, +@cpython_api([PyObject, INTP_real], rffi.LONGLONG, error=-1) def PyLong_AsLongLongAndOverflow(space, w_long, overflow_ptr): """ 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 @@ -1,7 +1,7 @@ from rpython.rtyper.lltypesystem import rffi, lltype from pypy.module.cpyext.api import ( cpython_api, generic_cpy_call, CANNOT_FAIL, Py_ssize_t, Py_ssize_tP, - PyVarObject, size_t, slot_function, + PyVarObject, size_t, slot_function, INTP_real, Py_TPFLAGS_HEAPTYPE, Py_LT, Py_LE, Py_EQ, Py_NE, Py_GT, Py_GE, CONST_STRING, FILEP, fwrite, c_only) from pypy.module.cpyext.pyobject import ( @@ -221,14 +221,14 @@ expression cmp(o1, o2).""" return space.int_w(space.cmp(w_o1, w_o2)) -@cpython_api([PyObject, PyObject, rffi.INTP], rffi.INT_real, error=-1) +@cpython_api([PyObject, PyObject, INTP_real], rffi.INT_real, error=-1) def PyObject_Cmp(space, w_o1, w_o2, result): """Compare the values of o1 and o2 using a routine provided by o1, if one exists, otherwise with a routine provided by o2. The result of the comparison is returned in result. Returns -1 on failure. This is the equivalent of the Python statement result = cmp(o1, o2).""" res = space.int_w(space.cmp(w_o1, w_o2)) - result[0] = rffi.cast(rffi.INT, res) + result[0] = rffi.cast(rffi.INT_real, res) return 0 @cpython_api([PyObject, PyObject, rffi.INT_real], PyObject) diff --git a/pypy/module/cpyext/pystrtod.py b/pypy/module/cpyext/pystrtod.py --- a/pypy/module/cpyext/pystrtod.py +++ b/pypy/module/cpyext/pystrtod.py @@ -1,6 +1,6 @@ import errno from pypy.interpreter.error import oefmt -from pypy.module.cpyext.api import cpython_api, CONST_STRING +from pypy.module.cpyext.api import cpython_api, CONST_STRING, INTP_real from pypy.module.cpyext.pyobject import PyObject from rpython.rlib import rdtoa from rpython.rlib import rfloat @@ -80,7 +80,7 @@ if not user_endptr: lltype.free(endptr, flavor='raw') -@cpython_api([rffi.DOUBLE, lltype.Char, rffi.INT_real, rffi.INT_real, rffi.INTP], rffi.CCHARP) +@cpython_api([rffi.DOUBLE, lltype.Char, rffi.INT_real, rffi.INT_real, INTP_real], rffi.CCHARP) def PyOS_double_to_string(space, val, format_code, precision, flags, ptype): """Convert a double val to a string using supplied format_code, precision, and flags. @@ -114,7 +114,7 @@ buffer, rtype = rfloat.double_to_string(val, format_code, intmask(precision), intmask(flags)) - if ptype != lltype.nullptr(rffi.INTP.TO): - ptype[0] = rffi.cast(rffi.INT, DOUBLE_TO_STRING_TYPES_MAP[rtype]) + if ptype != lltype.nullptr(INTP_real.TO): + ptype[0] = rffi.cast(rffi.INT_real, DOUBLE_TO_STRING_TYPES_MAP[rtype]) bufp = rffi.str2charp(buffer) return bufp diff --git a/pypy/module/cpyext/src/object.c b/pypy/module/cpyext/src/object.c --- a/pypy/module/cpyext/src/object.c +++ b/pypy/module/cpyext/src/object.c @@ -60,6 +60,11 @@ return (PyObject*)_PyObject_NewVar(type, 0); } +PyObject * _PyObject_GC_Malloc(size_t size) +{ + return (PyObject *)PyObject_Malloc(size); +} + PyObject * _PyObject_GC_New(PyTypeObject *type) { return _PyObject_New(type); diff --git a/pypy/module/cpyext/test/test_object.py b/pypy/module/cpyext/test/test_object.py --- a/pypy/module/cpyext/test/test_object.py +++ b/pypy/module/cpyext/test/test_object.py @@ -5,7 +5,7 @@ from rpython.rtyper.lltypesystem import rffi, lltype from pypy.module.cpyext.pyobject import get_w_obj_and_decref from pypy.module.cpyext.api import ( - Py_LT, Py_LE, Py_NE, Py_EQ, Py_GE, Py_GT) + Py_LT, Py_LE, Py_NE, Py_EQ, Py_GE, Py_GT, INTP_real) from pypy.module.cpyext.object import ( PyObject_IsTrue, PyObject_Not, PyObject_GetAttrString, PyObject_DelAttrString, PyObject_GetAttr, PyObject_DelAttr, @@ -205,7 +205,7 @@ def test_cmp(self, space, api): w = space.wrap - with lltype.scoped_alloc(rffi.INTP.TO, 1) as ptr: + with lltype.scoped_alloc(INTP_real.TO, 1) as ptr: assert api.PyObject_Cmp(w(42), w(72), ptr) == 0 assert ptr[0] == -1 assert api.PyObject_Cmp(w("a"), w("a"), ptr) == 0 diff --git a/pypy/module/cpyext/test/test_pystrtod.py b/pypy/module/cpyext/test/test_pystrtod.py --- a/pypy/module/cpyext/test/test_pystrtod.py +++ b/pypy/module/cpyext/test/test_pystrtod.py @@ -4,7 +4,7 @@ from pypy.module.cpyext.test.test_api import BaseApiTest, raises_w from rpython.rtyper.lltypesystem import rffi from rpython.rtyper.lltypesystem import lltype -from pypy.module.cpyext.pystrtod import PyOS_string_to_double +from pypy.module.cpyext.pystrtod import PyOS_string_to_double, INTP_real class TestPyOS_string_to_double(BaseApiTest): @@ -90,7 +90,7 @@ class TestPyOS_double_to_string(BaseApiTest): def test_format_code(self, api): - ptype = lltype.malloc(rffi.INTP.TO, 1, flavor='raw') + ptype = lltype.malloc(INTP_real.TO, 1, flavor='raw') r = api.PyOS_double_to_string(150.0, 'e', 1, 0, ptype) assert '1.5e+02' == rffi.charp2str(r) type_value = rffi.cast(lltype.Signed, ptype[0]) @@ -99,7 +99,7 @@ lltype.free(ptype, flavor='raw') def test_precision(self, api): - ptype = lltype.malloc(rffi.INTP.TO, 1, flavor='raw') + ptype = lltype.malloc(INTP_real.TO, 1, flavor='raw') r = api.PyOS_double_to_string(3.14159269397, 'g', 5, 0, ptype) assert '3.1416' == rffi.charp2str(r) type_value = rffi.cast(lltype.Signed, ptype[0]) @@ -108,7 +108,7 @@ lltype.free(ptype, flavor='raw') def test_flags_sign(self, api): - ptype = lltype.malloc(rffi.INTP.TO, 1, flavor='raw') + ptype = lltype.malloc(INTP_real.TO, 1, flavor='raw') r = api.PyOS_double_to_string(-3.14, 'g', 3, 1, ptype) assert '-3.14' == rffi.charp2str(r) type_value = rffi.cast(lltype.Signed, ptype[0]) @@ -117,7 +117,7 @@ lltype.free(ptype, flavor='raw') def test_flags_add_dot_0(self, api): - ptype = lltype.malloc(rffi.INTP.TO, 1, flavor='raw') + ptype = lltype.malloc(INTP_real.TO, 1, flavor='raw') r = api.PyOS_double_to_string(3, 'g', 5, 2, ptype) assert '3.0' == rffi.charp2str(r) type_value = rffi.cast(lltype.Signed, ptype[0]) @@ -126,7 +126,7 @@ lltype.free(ptype, flavor='raw') def test_flags_alt(self, api): - ptype = lltype.malloc(rffi.INTP.TO, 1, flavor='raw') + ptype = lltype.malloc(INTP_real.TO, 1, flavor='raw') r = api.PyOS_double_to_string(314., 'g', 3, 4, ptype) assert '314.' == rffi.charp2str(r) type_value = rffi.cast(lltype.Signed, ptype[0]) @@ -135,7 +135,7 @@ lltype.free(ptype, flavor='raw') def test_ptype_nan(self, api): - ptype = lltype.malloc(rffi.INTP.TO, 1, flavor='raw') + ptype = lltype.malloc(INTP_real.TO, 1, flavor='raw') r = api.PyOS_double_to_string(float('nan'), 'g', 3, 4, ptype) assert 'nan' == rffi.charp2str(r) type_value = rffi.cast(lltype.Signed, ptype[0]) @@ -144,7 +144,7 @@ lltype.free(ptype, flavor='raw') def test_ptype_infinity(self, api): - ptype = lltype.malloc(rffi.INTP.TO, 1, flavor='raw') + ptype = lltype.malloc(INTP_real.TO, 1, flavor='raw') r = api.PyOS_double_to_string(1e200 * 1e200, 'g', 0, 0, ptype) assert 'inf' == rffi.charp2str(r) type_value = rffi.cast(lltype.Signed, ptype[0]) @@ -153,8 +153,8 @@ lltype.free(ptype, flavor='raw') def test_ptype_null(self, api): - ptype = lltype.nullptr(rffi.INTP.TO) + ptype = lltype.nullptr(INTP_real.TO) r = api.PyOS_double_to_string(3.14, 'g', 3, 0, ptype) assert '3.14' == rffi.charp2str(r) - assert ptype == lltype.nullptr(rffi.INTP.TO) + assert ptype == lltype.nullptr(INTP_real.TO) rffi.free_charp(r) 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 @@ -4,7 +4,7 @@ from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase from pypy.module.cpyext.unicodeobject import ( Py_UNICODE, PyUnicodeObject, new_empty_unicode) -from pypy.module.cpyext.api import PyObjectP, PyObject +from pypy.module.cpyext.api import PyObjectP, PyObject, INTP_real from pypy.module.cpyext.pyobject import decref, from_ref from rpython.rtyper.lltypesystem import rffi, lltype import sys, py @@ -467,8 +467,8 @@ value = 1 else: value = 0 - pendian = lltype.malloc(rffi.INTP.TO, 1, flavor='raw') - pendian[0] = rffi.cast(rffi.INT, value) + pendian = lltype.malloc(INTP_real.TO, 1, flavor='raw') + pendian[0] = rffi.cast(rffi.INT_real, value) else: pendian = None @@ -480,7 +480,7 @@ rffi.free_charp(strict_charp) if pendian: if realendian is not None: - assert rffi.cast(rffi.INT, realendian) == pendian[0] + assert rffi.cast(rffi.INT_real, realendian) == pendian[0] lltype.free(pendian, flavor='raw') test("\x61\x00\x62\x00\x63\x00\x64\x00", -1) @@ -503,8 +503,8 @@ value = 1 else: value = 0 - pendian = lltype.malloc(rffi.INTP.TO, 1, flavor='raw') - pendian[0] = rffi.cast(rffi.INT, value) + pendian = lltype.malloc(INTP_real.TO, 1, flavor='raw') + pendian[0] = rffi.cast(rffi.INT_real, value) else: pendian = None 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 @@ -9,7 +9,7 @@ from pypy.module.unicodedata import unicodedb from pypy.module.cpyext.api import ( CANNOT_FAIL, Py_ssize_t, build_type_checkers_flags, cpython_api, - bootstrap_function, CONST_STRING, + bootstrap_function, CONST_STRING, INTP_real, CONST_WSTRING, slot_function, cts, parse_dir) from pypy.module.cpyext.pyerrors import PyErr_BadArgument from pypy.module.cpyext.pyobject import ( @@ -532,7 +532,7 @@ if sys.platform == 'win32': make_conversion_functions('MBCS', 'mbcs') -@cpython_api([CONST_STRING, Py_ssize_t, CONST_STRING, rffi.INTP], PyObject) +@cpython_api([CONST_STRING, Py_ssize_t, CONST_STRING, INTP_real], PyObject) def PyUnicode_DecodeUTF16(space, s, size, llerrors, pbyteorder): """Decode length bytes from a UTF-16 encoded buffer string and return the corresponding Unicode object. errors (if non-NULL) defines the error @@ -579,10 +579,10 @@ result, _, length, byteorder = str_decode_utf_16_helper( string, errors, final=True, errorhandler=None, byteorder=byteorder) if pbyteorder is not None: - pbyteorder[0] = rffi.cast(rffi.INT, byteorder) + pbyteorder[0] = rffi.cast(rffi.INT_real, byteorder) return space.newutf8(result, length) -@cpython_api([CONST_STRING, Py_ssize_t, CONST_STRING, rffi.INTP], PyObject) +@cpython_api([CONST_STRING, Py_ssize_t, CONST_STRING, INTP_real], PyObject) def PyUnicode_DecodeUTF32(space, s, size, llerrors, pbyteorder): """Decode length bytes from a UTF-32 encoded buffer string and return the corresponding Unicode object. errors (if non-NULL) @@ -631,7 +631,7 @@ result, _, length, byteorder = unicodehelper.str_decode_utf_32_helper( string, errors, final=True, errorhandler=None, byteorder=byteorder) if pbyteorder is not None: - pbyteorder[0] = rffi.cast(rffi.INT, byteorder) + pbyteorder[0] = rffi.cast(rffi.INT_real, byteorder) return space.newutf8(result, length) @cpython_api([rffi.CWCHARP, Py_ssize_t, rffi.CCHARP, CONST_STRING], _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit