[pypy-commit] pypy py3.6: merge py3.5 into py3.6
mattip
pypy.commits at gmail.com
Sat Jun 30 22:48:27 EDT 2018
Author: Matti Picus <matti.picus at gmail.com>
Branch: py3.6
Changeset: r94790:a43321e72438
Date: 2018-06-30 19:47 -0700
http://bitbucket.org/pypy/pypy/changeset/a43321e72438/
Log: merge py3.5 into py3.6
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/generator.py b/pypy/interpreter/generator.py
--- a/pypy/interpreter/generator.py
+++ b/pypy/interpreter/generator.py
@@ -288,7 +288,7 @@
if self.frame is None:
return # nothing to do in this case
space = self.space
- operr = get_generator_exit(space)
+ operr = None
# note: w_yielded_from is always None if 'self.running'
w_yf = self.w_yielded_from
if w_yf is not None:
@@ -296,6 +296,8 @@
self._gen_close_iter(space)
except OperationError as e:
operr = e
+ if operr is None:
+ operr = OperationError(space.w_GeneratorExit, space.w_None)
try:
self.send_error(operr)
except OperationError as e:
@@ -471,11 +473,6 @@
space.call_function(space.w_StopIteration, w_value))
- at specialize.memo()
-def get_generator_exit(space):
- return OperationError(space.w_GeneratorExit,
- space.call_function(space.w_GeneratorExit))
-
def gen_close_iter(space, w_yf):
# This helper function is used by close() and throw() to
# close a subiterator being delegated to by yield-from.
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
@@ -170,6 +170,7 @@
h = get_h()
raises(ValueError, "f.__code__ = h.__code__")
+ @pytest.mark.skipif("config.option.runappdirect")
def test_write_code_builtin_forbidden(self):
def f(*args):
return 42
@@ -339,7 +340,6 @@
assert meth() == obj
def test_none_get_interaction(self):
- skip("XXX issue #2083")
assert type(None).__repr__(None) == 'None'
def test_none_get_interaction_2(self):
@@ -544,7 +544,9 @@
pass
r = repr(ClsB().f)
assert "ClsA.f of <" in r
- assert "ClsB object at " in r
+ assert repr(type(ClsA.f)) == "<class 'function'>"
+ assert repr(type(ClsA().f)) == "<class 'method'>"
+
def test_method_call(self):
class C(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)
@@ -138,7 +138,7 @@
return space.newtext(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)
@@ -146,12 +146,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):
@@ -342,7 +342,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
@@ -378,10 +378,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
@@ -658,7 +658,7 @@
'PyType_FromSpec',
'Py_IncRef', 'Py_DecRef', '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',
'PyTuple_New', '_Py_Dealloc',
]
@@ -789,6 +789,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
@@ -372,6 +372,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.interpreter.error import OperationError, oefmt
from rpython.rlib.rbigint import rbigint, InvalidSignednessError
@@ -120,7 +120,7 @@
num = space.bigint_w(w_long)
return num.ulonglongmask()
- at cpython_api([PyObject, rffi.CArrayPtr(rffi.INT_real)], lltype.Signed,
+ at cpython_api([PyObject, INTP_real], lltype.Signed,
error=-1)
def PyLong_AsLongAndOverflow(space, w_long, overflow_ptr):
"""
@@ -141,7 +141,7 @@
overflow_ptr[0] = rffi.cast(rffi.INT_real, -1)
return -1
- at cpython_api([PyObject, rffi.CArrayPtr(rffi.INT_real)], rffi.LONGLONG,
+ at cpython_api([PyObject, INTP_real], rffi.LONGLONG,
error=-1)
def PyLong_AsLongLongAndOverflow(space, w_long, overflow_ptr):
"""
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')
- at cpython_api([rffi.DOUBLE, lltype.Char, rffi.INT_real, rffi.INT_real, rffi.INTP], rffi.CCHARP)
+ at 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
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,
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,8 @@
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, Py_CLEANUP_SUPPORTED
+from pypy.module.cpyext.api import (PyObjectP, PyObject,
+ Py_CLEANUP_SUPPORTED, INTP_real)
from pypy.module.cpyext.pyobject import decref, from_ref
from rpython.rtyper.lltypesystem import rffi, lltype
import sys, py
@@ -726,7 +727,7 @@
value = 1
else:
value = 0
- pendian = lltype.malloc(INT_realP.TO, 1, flavor='raw')
+ pendian = lltype.malloc(INTP_real.TO, 1, flavor='raw')
pendian[0] = rffi.cast(rffi.INT_real, value)
else:
pendian = None
@@ -739,7 +740,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)
@@ -762,7 +763,7 @@
value = 1
else:
value = 0
- pendian = lltype.malloc(INT_realP.TO, 1, flavor='raw')
+ 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
@@ -6,7 +6,7 @@
from pypy.module.unicodedata import unicodedb
from pypy.module.cpyext.api import (
CANNOT_FAIL, Py_ssize_t, build_type_checkers, cpython_api,
- bootstrap_function, CONST_STRING,
+ bootstrap_function, CONST_STRING, INTP_real,
CONST_WSTRING, Py_CLEANUP_SUPPORTED, slot_function, cts, parse_dir)
from pypy.module.cpyext.pyerrors import PyErr_BadArgument
from pypy.module.cpyext.pyobject import (
@@ -768,7 +768,7 @@
if sys.platform == 'win32':
make_conversion_functions('MBCS', 'mbcs')
- at cpython_api([CONST_STRING, Py_ssize_t, CONST_STRING, INT_realP], PyObject)
+ at 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
@@ -822,7 +822,7 @@
return space.newunicode(result)
- at cpython_api([CONST_STRING, Py_ssize_t, CONST_STRING, INT_realP], PyObject)
+ at 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)
diff --git a/pypy/module/exceptions/interp_exceptions.py b/pypy/module/exceptions/interp_exceptions.py
--- a/pypy/module/exceptions/interp_exceptions.py
+++ b/pypy/module/exceptions/interp_exceptions.py
@@ -235,6 +235,13 @@
self.descr_settraceback(space, w_traceback)
return self
+ def _cleanup_(self):
+ raise Exception("Prebuilt instances of (subclasses of) BaseException "
+ "must be avoided in Python 3.x. They have mutable "
+ "attributes related to tracebacks, so whenever they "
+ "are raised in the actual program they will "
+ "accumulate more frames and never free them.")
+
def _new(cls, basecls=None):
if basecls is None:
basecls = cls
More information about the pypy-commit
mailing list