[pypy-commit] pypy rffi-parser: Expand the pseudo-header in api.py, handle forward refs and pointers
Author: Ronan Lamy Branch: rffi-parser Changeset: r89106:cb24068cdac0 Date: 2016-12-17 04:10 + http://bitbucket.org/pypy/pypy/changeset/cb24068cdac0/ Log:Expand the pseudo-header in api.py, handle forward refs and pointers 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 @@ -602,8 +602,28 @@ % (cpyname, )) build_exported_objects() -# update these for other platforms -h = parse_source("typedef ssize_t Py_ssize_t;") +h = parse_source(""" +typedef ssize_t Py_ssize_t; + +#define PyObject_HEAD \ +Py_ssize_t ob_refcnt;\ +Py_ssize_t ob_pypy_link; \ +struct _typeobject *ob_type; + +#define PyObject_VAR_HEAD \ + PyObject_HEAD \ + Py_ssize_t ob_size; /* Number of items in variable part */ + +typedef struct _object { +PyObject_HEAD +} PyObject; + +typedef struct { + PyObject_VAR_HEAD +} PyVarObject; + +typedef struct _typeobject PyTypeObject; +""") Py_ssize_t = h.definitions['Py_ssize_t'] Py_ssize_tP = rffi.CArrayPtr(Py_ssize_t) @@ -613,16 +633,15 @@ # Note: as a special case, "PyObject" is the pointer type in RPython, # corresponding to "PyObject *" in C. We do that only for PyObject. # For example, "PyTypeObject" is the struct type even in RPython. -PyTypeObject = lltype.ForwardReference() +PyTypeObject = h.definitions['PyTypeObject'].OF PyTypeObjectPtr = lltype.Ptr(PyTypeObject) -PyObjectStruct = lltype.ForwardReference() +PyObjectStruct = h.definitions['PyObject'].OF PyObject = lltype.Ptr(PyObjectStruct) PyObjectFields = (("ob_refcnt", lltype.Signed), ("ob_pypy_link", lltype.Signed), ("ob_type", PyTypeObjectPtr)) PyVarObjectFields = PyObjectFields + (("ob_size", Py_ssize_t), ) -cpython_struct('PyObject', PyObjectFields, PyObjectStruct) -PyVarObjectStruct = cpython_struct("PyVarObject", PyVarObjectFields) +PyVarObjectStruct = h.definitions['PyVarObject'].OF PyVarObject = lltype.Ptr(PyVarObjectStruct) Py_buffer = cpython_struct( diff --git a/pypy/module/cpyext/cparser.py b/pypy/module/cpyext/cparser.py --- a/pypy/module/cpyext/cparser.py +++ b/pypy/module/cpyext/cparser.py @@ -1,3 +1,4 @@ +from collections import OrderedDict from cffi import api, model from cffi.commontypes import COMMON_TYPES, resolve_common_type import pycparser @@ -30,7 +31,7 @@ # should not contain any string literal! csource = _r_comment.sub(' ', csource) # Remove the "#define FOO x" lines -macros = {} +macros = OrderedDict() for match in _r_define.finditer(csource): macroname, macrovalue = match.groups() macrovalue = macrovalue.replace('\\\n', '').strip() @@ -695,12 +696,19 @@ from pypy.module.cpyext.api import cpython_struct if obj in self.structs: return self.structs[obj] -fields = zip( -obj.fldnames, -[self.convert_type(field) for field in obj.fldtypes]) -result = DelayedStruct(obj.name, fields) +if obj.fldtypes is None: +result = lltype.ForwardReference() +else: +fields = zip( +obj.fldnames, +[self.convert_type(field) for field in obj.fldtypes]) +result = DelayedStruct(obj.name, fields) self.structs[obj] = result return result +elif isinstance(obj, model.PointerType): +return lltype.Ptr(self.convert_type(obj.totype)) +else: +raise NotImplementedError def parse_source(source): ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy rffi-parser: Begin using parse_source() in pypy.module.cpyext.api
Author: Ronan Lamy Branch: rffi-parser Changeset: r89105:91730b67d4d6 Date: 2016-12-17 03:00 + http://bitbucket.org/pypy/pypy/changeset/91730b67d4d6/ Log:Begin using parse_source() in pypy.module.cpyext.api 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 @@ -41,15 +41,10 @@ from rpython.rlib import rawrefcount from rpython.rlib import rthread from rpython.rlib.debug import fatalerror_notb +from pypy.module.cpyext.cparser import parse_source DEBUG_WRAPPER = True -# update these for other platforms -Py_ssize_t = lltype.Typedef(rffi.SSIZE_T, 'Py_ssize_t') -Py_ssize_tP = rffi.CArrayPtr(Py_ssize_t) -size_t = rffi.ULONG -ADDR = lltype.Signed - pypydir = py.path.local(pypydir) include_dir = pypydir / 'module' / 'cpyext' / 'include' source_dir = pypydir / 'module' / 'cpyext' / 'src' @@ -119,6 +114,9 @@ return is_valid_fd(c_fileno(fp)) pypy_decl = 'pypy_decl.h' +udir.join(pypy_decl).write("/* Will be filled later */\n") +udir.join('pypy_structmember_decl.h').write("/* Will be filled later */\n") +udir.join('pypy_macros.h').write("/* Will be filled later */\n") constant_names = """ Py_TPFLAGS_READY Py_TPFLAGS_READYING Py_TPFLAGS_HAVE_GETCHARBUFFER @@ -129,9 +127,6 @@ """.split() for name in constant_names: setattr(CConfig_constants, name, rffi_platform.ConstantInteger(name)) -udir.join(pypy_decl).write("/* Will be filled later */\n") -udir.join('pypy_structmember_decl.h').write("/* Will be filled later */\n") -udir.join('pypy_macros.h').write("/* Will be filled later */\n") globals().update(rffi_platform.configure(CConfig_constants)) def _copy_header_files(headers, dstdir): @@ -607,6 +602,14 @@ % (cpyname, )) build_exported_objects() +# update these for other platforms +h = parse_source("typedef ssize_t Py_ssize_t;") + +Py_ssize_t = h.definitions['Py_ssize_t'] +Py_ssize_tP = rffi.CArrayPtr(Py_ssize_t) +size_t = rffi.ULONG +ADDR = lltype.Signed + # Note: as a special case, "PyObject" is the pointer type in RPython, # corresponding to "PyObject *" in C. We do that only for PyObject. # For example, "PyTypeObject" is the struct type even in RPython. diff --git a/pypy/module/cpyext/cparser.py b/pypy/module/cpyext/cparser.py --- a/pypy/module/cpyext/cparser.py +++ b/pypy/module/cpyext/cparser.py @@ -2,7 +2,7 @@ from cffi.commontypes import COMMON_TYPES, resolve_common_type import pycparser import weakref, re -from rpython.rtyper.lltypesystem import rffi +from rpython.rtyper.lltypesystem import rffi, lltype from rpython.rtyper.tool import rfficache _r_comment = re.compile(r"/\*.*?\*/|//([^\n\\]|\\.)*?$", @@ -682,17 +682,17 @@ if isinstance(tp, DelayedStruct): tp = tp.realize(name) self.structs[obj] = tp -self.definitions[name] = tp +self.definitions[name] = lltype.Typedef(tp, name) def add_macro(self, name, value): assert name not in self.macros self.macros[name] = value def convert_type(self, obj): -from pypy.module.cpyext.api import cpython_struct if isinstance(obj, model.PrimitiveType): return cname_to_lltype(obj.name) elif isinstance(obj, model.StructType): +from pypy.module.cpyext.api import cpython_struct if obj in self.structs: return self.structs[obj] fields = zip( ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy rffi-parser: Remove unused function
Author: Ronan Lamy Branch: rffi-parser Changeset: r89103:faa4070df377 Date: 2016-12-16 16:38 + http://bitbucket.org/pypy/pypy/changeset/faa4070df377/ Log:Remove unused function 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 @@ -607,14 +607,6 @@ % (cpyname, )) build_exported_objects() -def get_structtype_for_ctype(ctype): -from pypy.module.cpyext.typeobjectdefs import PyTypeObjectPtr -from pypy.module.cpyext.cdatetime import PyDateTime_CAPI -from pypy.module.cpyext.intobject import PyIntObject -return {"PyObject*": PyObject, "PyTypeObject*": PyTypeObjectPtr, -"PyIntObject*": PyIntObject, -"PyDateTime_CAPI*": lltype.Ptr(PyDateTime_CAPI)}[ctype] - # Note: as a special case, "PyObject" is the pointer type in RPython, # corresponding to "PyObject *" in C. We do that only for PyObject. # For example, "PyTypeObject" is the struct type even in RPython. ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy rffi-parser: progress?
Author: Ronan Lamy Branch: rffi-parser Changeset: r89104:f6bc1fb871de Date: 2016-12-17 02:24 + http://bitbucket.org/pypy/pypy/changeset/f6bc1fb871de/ Log:progress? diff --git a/pypy/module/cpyext/cparser.py b/pypy/module/cpyext/cparser.py --- a/pypy/module/cpyext/cparser.py +++ b/pypy/module/cpyext/cparser.py @@ -656,36 +656,62 @@ def cname_to_lltype(name): return CNAME_TO_LLTYPE[name] +class DelayedStruct(object): +def __init__(self, name, fields): +self.struct_name = name +self.fields = fields + +def realize(self, type_name): +from pypy.module.cpyext.api import cpython_struct +return cpython_struct(type_name, self.fields) + +def __repr__(self): +return "".format(vars(self)) + + class ParsedSource(object): -def __init__(self, source, definitions, macros): +def __init__(self, source, definitions=None, macros=None): self.source = source -self.definitions = definitions -self.macros = macros +self.definitions = definitions if definitions is not None else {} +self.macros = macros if macros is not None else {} +self.structs = {} -def cffi_to_lltype(obj): -from pypy.module.cpyext.api import cpython_struct -if isinstance(obj, model.PrimitiveType): -return cname_to_lltype(obj.name) -elif isinstance(obj, model.StructType): -fields = zip( -obj.fldnames, -[cffi_to_lltype(field) for field in obj.fldtypes]) -return cpython_struct(obj.name, fields) +def add_typedef(self, name, obj): +assert name not in self.definitions +tp = self.convert_type(obj) +if isinstance(tp, DelayedStruct): +tp = tp.realize(name) +self.structs[obj] = tp +self.definitions[name] = tp + +def add_macro(self, name, value): +assert name not in self.macros +self.macros[name] = value + +def convert_type(self, obj): +from pypy.module.cpyext.api import cpython_struct +if isinstance(obj, model.PrimitiveType): +return cname_to_lltype(obj.name) +elif isinstance(obj, model.StructType): +if obj in self.structs: +return self.structs[obj] +fields = zip( +obj.fldnames, +[self.convert_type(field) for field in obj.fldtypes]) +result = DelayedStruct(obj.name, fields) +self.structs[obj] = result +return result def parse_source(source): ctx = Parser() ctx.parse(source) -defs = {} -macros = {} +src = ParsedSource(source) for name, (obj, quals) in ctx._declarations.iteritems(): if name.startswith('typedef '): name = name[8:] -assert name not in defs -defs[name] = cffi_to_lltype(obj) +src.add_typedef(name, obj) elif name.startswith('macro '): name = name[6:] -assert name not in macros -macros[name] = obj - -return ParsedSource(source, defs, macros) +src.add_macro(name, obj) +return src ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy rffi-parser: Deal with parameterless macros
Author: Ronan Lamy Branch: rffi-parser Changeset: r89102:11a2deff4a3d Date: 2016-12-16 16:31 + http://bitbucket.org/pypy/pypy/changeset/11a2deff4a3d/ Log:Deal with parameterless macros diff --git a/pypy/module/cpyext/cparser.py b/pypy/module/cpyext/cparser.py --- a/pypy/module/cpyext/cparser.py +++ b/pypy/module/cpyext/cparser.py @@ -45,6 +45,10 @@ csource = _r_stdcall2.sub(' volatile volatile const(', csource) csource = _r_stdcall1.sub(' volatile volatile const ', csource) csource = _r_cdecl.sub(' ', csource) + +for name, value in reversed(macros.items()): +csource = re.sub(r'\b%s\b' % name, value, csource) + return csource, macros def _common_type_names(csource): @@ -219,17 +223,8 @@ value = value.strip() if _r_int_literal.match(value): self._add_integer_constant(key, value) -elif value == '...': +else: self._declare('macro ' + key, value) -else: -raise api.CDefError( -'only supports one of the following syntax:\n' -' #define %s ... (literally dot-dot-dot)\n' -' #define %s NUMBER (with NUMBER an integer' -' constant, decimal/hex/octal)\n' -'got:\n' -' #define %s %s' -% (key, key, key, value)) def _declare_function(self, tp, quals, decl): tp = self._get_type_pointer(tp, quals) @@ -662,9 +657,10 @@ return CNAME_TO_LLTYPE[name] class ParsedSource(object): -def __init__(self, source, definitions): +def __init__(self, source, definitions, macros): self.source = source self.definitions = definitions +self.macros = macros def cffi_to_lltype(obj): from pypy.module.cpyext.api import cpython_struct @@ -681,10 +677,15 @@ ctx = Parser() ctx.parse(source) defs = {} +macros = {} for name, (obj, quals) in ctx._declarations.iteritems(): -if not name.startswith('typedef '): -continue -name = name[8:] -assert name not in defs -defs[name] = cffi_to_lltype(obj) -return ParsedSource(source, defs) +if name.startswith('typedef '): +name = name[8:] +assert name not in defs +defs[name] = cffi_to_lltype(obj) +elif name.startswith('macro '): +name = name[6:] +assert name not in macros +macros[name] = obj + +return ParsedSource(source, defs, macros) diff --git a/pypy/module/cpyext/test/test_cparser.py b/pypy/module/cpyext/test/test_cparser.py --- a/pypy/module/cpyext/test/test_cparser.py +++ b/pypy/module/cpyext/test/test_cparser.py @@ -22,3 +22,20 @@ decl = "typedef ssize_t Py_ssize_t;" hdr = parse_source(decl) assert hdr.definitions == {'Py_ssize_t': rffi.SSIZE_T} + +def test_macro(): +decl = """ +typedef ssize_t Py_ssize_t; + +#define PyObject_HEAD \ +Py_ssize_t ob_refcnt;\ +Py_ssize_t ob_pypy_link; \ + +typedef struct { +PyObject_HEAD +double ob_fval; +} PyFloatObject; +""" +hdr = parse_source(decl) +assert 'PyFloatObject' in hdr.definitions +assert 'PyObject_HEAD' in hdr.macros ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy space-newtext: gave up finding the root cause of this translation problem, and instead enforce
Author: Carl Friedrich Bolz Branch: space-newtext Changeset: r89101:4d6b02c8898d Date: 2016-12-16 16:53 +0100 http://bitbucket.org/pypy/pypy/changeset/4d6b02c8898d/ Log:gave up finding the root cause of this translation problem, and instead enforce some W_Root types in gateway.py. (why things have to be None is another sad story) diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -27,6 +27,9 @@ from rpython.rlib.rarithmetic import r_longlong, r_int, r_ulonglong, r_uint from rpython.tool.sourcetools import func_with_new_name, compile2 +from rpython.rlib.signature import signature, finishsigs +from rpython.rlib import types as sigtypes + # internal non-translatable parts: class SignatureBuilder(object): @@ -795,11 +798,17 @@ w_result = space.w_None return w_result +w_root_or_none = sigtypes.instance(W_Root, can_be_None=True) +@finishsigs class BuiltinCode1(BuiltinCode): _immutable_ = True fast_natural_arity = 1 +@signature(sigtypes.self(), sigtypes.any(), + w_root_or_none, + w_root_or_none, + returns=w_root_or_none) def fastcall_1(self, space, w_func, w1): try: w_result = self.fastfunc_1(space, w1) @@ -816,10 +825,16 @@ return w_result +@finishsigs class BuiltinCode2(BuiltinCode): _immutable_ = True fast_natural_arity = 2 +@signature(sigtypes.self(), sigtypes.any(), + w_root_or_none, + w_root_or_none, + w_root_or_none, + returns=w_root_or_none) def fastcall_2(self, space, w_func, w1, w2): try: w_result = self.fastfunc_2(space, w1, w2) @@ -836,10 +851,17 @@ return w_result +@finishsigs class BuiltinCode3(BuiltinCode): _immutable_ = True fast_natural_arity = 3 +@signature(sigtypes.self(), sigtypes.any(), + w_root_or_none, + w_root_or_none, + w_root_or_none, + w_root_or_none, + returns=w_root_or_none) def fastcall_3(self, space, func, w1, w2, w3): try: w_result = self.fastfunc_3(space, w1, w2, w3) @@ -855,12 +877,20 @@ w_result = space.w_None return w_result - +@finishsigs class BuiltinCode4(BuiltinCode): _immutable_ = True fast_natural_arity = 4 +@signature(sigtypes.self(), sigtypes.any(), + w_root_or_none, + w_root_or_none, + w_root_or_none, + w_root_or_none, + w_root_or_none, + returns=w_root_or_none) def fastcall_4(self, space, func, w1, w2, w3, w4): +from rpython.rlib.debug import check_annotation try: w_result = self.fastfunc_4(space, w1, w2, w3, w4) except DescrMismatch: diff --git a/rpython/rlib/test/test_signature.py b/rpython/rlib/test/test_signature.py --- a/rpython/rlib/test/test_signature.py +++ b/rpython/rlib/test/test_signature.py @@ -221,6 +221,36 @@ @check_annotator_fails def bad_for_body(): f(C1()) +@check_annotator_fails +def ok_for_body(): +f(None) + +def test_instance_or_none(): +class C1(object): +pass +class C2(C1): +pass +class C3(C2): +pass +@signature(types.instance(C3, can_be_None=True), returns=types.instance(C2, can_be_None=True)) +def f(x): +assert isinstance(x, C2) or x is None +return x +argtype, rettype = getsig(f) +assert isinstance(argtype, model.SomeInstance) +assert argtype.classdef.classdesc.pyobj == C3 +assert argtype.can_be_None +assert isinstance(rettype, model.SomeInstance) +assert rettype.classdef.classdesc.pyobj == C2 +assert rettype.can_be_None + +@check_annotator_fails +def ok_for_body(): +f(C2()) +@check_annotator_fails +def bad_for_body(): +f(C1()) + def test_self(): @finishsigs diff --git a/rpython/rlib/types.py b/rpython/rlib/types.py --- a/rpython/rlib/types.py +++ b/rpython/rlib/types.py @@ -76,8 +76,8 @@ return model.SomeDict(dictdef) -def instance(cls): -return lambda bookkeeper: model.SomeInstance(bookkeeper.getuniqueclassdef(cls)) +def instance(cls, can_be_None=False): +return lambda bookkeeper: model.SomeInstance(bookkeeper.getuniqueclassdef(cls), can_be_None=can_be_None) class SelfTypeMarker(object): ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy space-newtext: fix some wrong newbytes in baseobjspace.py. thanks armin
Author: Carl Friedrich Bolz Branch: space-newtext Changeset: r89100:d77161178f39 Date: 2016-12-16 15:12 +0100 http://bitbucket.org/pypy/pypy/changeset/d77161178f39/ Log:fix some wrong newbytes in baseobjspace.py. thanks armin diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1193,7 +1193,7 @@ return w_res def call_method(self, w_obj, methname, *arg_w): -w_meth = self.getattr(w_obj, self.newbytes(methname)) +w_meth = self.getattr(w_obj, self.newtext(methname)) return self.call_function(w_meth, *arg_w) def raise_key_error(self, w_key): @@ -1202,7 +1202,7 @@ def lookup(self, w_obj, name): w_type = self.type(w_obj) -w_mro = self.getattr(w_type, self.newbytes("__mro__")) +w_mro = self.getattr(w_type, self.newtext("__mro__")) for w_supertype in self.fixedview(w_mro): w_value = w_supertype.getdictvalue(self, name) if w_value is not None: @@ -1223,7 +1223,7 @@ if self.is_oldstyle_instance(w_obj): # ugly old style class special treatment, but well ... try: -self.getattr(w_obj, self.newbytes("__call__")) +self.getattr(w_obj, self.newtext("__call__")) return self.w_True except OperationError as e: if not e.match(self, self.w_AttributeError): @@ -1235,7 +1235,7 @@ def issequence_w(self, w_obj): if self.is_oldstyle_instance(w_obj): -return (self.findattr(w_obj, self.newbytes('__getitem__')) is not None) +return (self.findattr(w_obj, self.newtext('__getitem__')) is not None) flag = self.type(w_obj).flag_map_or_seq if flag == 'M': return False @@ -1246,7 +1246,7 @@ def ismapping_w(self, w_obj): if self.is_oldstyle_instance(w_obj): -return (self.findattr(w_obj, self.newbytes('__getitem__')) is not None) +return (self.findattr(w_obj, self.newtext('__getitem__')) is not None) flag = self.type(w_obj).flag_map_or_seq if flag == 'M': return True @@ -1327,7 +1327,7 @@ hidden_applevel=hidden_applevel) if not isinstance(statement, PyCode): raise TypeError('space.exec_(): expected a string, code or PyCode object') -w_key = self.newbytes('__builtins__') +w_key = self.newtext('__builtins__') if not self.contains_w(w_globals, w_key): self.setitem(w_globals, w_key, self.builtin) return statement.exec_code(self, w_globals, w_locals) @@ -1808,7 +1808,7 @@ if (not self.isinstance_w(w_fd, self.w_int) and not self.isinstance_w(w_fd, self.w_long)): try: -w_fileno = self.getattr(w_fd, self.newbytes("fileno")) +w_fileno = self.getattr(w_fd, self.newtext("fileno")) except OperationError as e: if e.match(self, self.w_AttributeError): raise oefmt(self.w_TypeError, ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3.5-newtext: Replace identifier_w() with text_w() in some places where we don't really
Author: Armin Rigo Branch: py3.5-newtext Changeset: r89099:cda3e3f5f13e Date: 2016-12-16 15:00 +0100 http://bitbucket.org/pypy/pypy/changeset/cda3e3f5f13e/ Log:Replace identifier_w() with text_w() in some places where we don't really want the "there-are-no-surrogates" check diff --git a/pypy/interpreter/argument.py b/pypy/interpreter/argument.py --- a/pypy/interpreter/argument.py +++ b/pypy/interpreter/argument.py @@ -404,7 +404,7 @@ i = 0 for w_key in keys_w: try: -key = space.identifier_w(w_key) +key = space.text_w(w_key) except OperationError as e: if e.match(space, space.w_TypeError): raise oefmt(space.w_TypeError, @@ -595,7 +595,7 @@ except IndexError: name = '?' else: -name = space.identifier_w(w_name) +name = space.text_w(w_name) break self.kwd_name = name diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1522,7 +1522,7 @@ if self.isinstance_w(w_obj, self.w_str): return StringBuffer(w_obj.bytes_w(self)) if self.isinstance_w(w_obj, self.w_unicode): -return StringBuffer(w_obj.identifier_w(self)) +return StringBuffer(w_obj.identifier_w(self)) # no surrogates try: return w_obj.buffer_w(self, self.BUF_SIMPLE) except BufferInterfaceNotFound: @@ -1531,7 +1531,7 @@ if self.isinstance_w(w_obj, self.w_str): return w_obj.bytes_w(self) if self.isinstance_w(w_obj, self.w_unicode): -return w_obj.identifier_w(self) +return w_obj.identifier_w(self)# no surrogates (forbidden) try: return w_obj.buffer_w(self, self.BUF_SIMPLE).as_str() except BufferInterfaceNotFound: @@ -1681,6 +1681,7 @@ This differs from space.text_w() because it raises an app-level UnicodeEncodeError if the unicode string contains surrogates. This corresponds exactly to 'str.encode(obj, "utf-8")' at app-level. +(XXX check what occurs on narrow builds or kill narrow builds!) """ return w_obj.identifier_w(self) diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py --- a/pypy/interpreter/pyopcode.py +++ b/pypy/interpreter/pyopcode.py @@ -465,7 +465,7 @@ return self.getcode().co_consts_w[index] def getname_u(self, index): -return self.space.identifier_w(self.getname_w(index)) +return self.space.text_w(self.getname_w(index)) def getname_w(self, index): return self.getcode().co_names_w[index] @@ -899,7 +899,7 @@ def LOAD_NAME(self, nameindex, next_instr): w_varname = self.getname_w(nameindex) -varname = self.space.identifier_w(w_varname) +varname = self.space.text_w(w_varname) if self.getorcreatedebug().w_locals is not self.get_w_globals(): w_value = self.space.finditem_str(self.getorcreatedebug().w_locals, varname) @@ -929,7 +929,7 @@ @always_inline def LOAD_GLOBAL(self, nameindex, next_instr): w_varname = self.getname_w(nameindex) -w_value = self._load_global(self.space.identifier_w(w_varname)) +w_value = self._load_global(self.space.text_w(w_varname)) if w_value is None: self._load_global_failed(w_varname) self.pushvalue(w_value) @@ -1257,7 +1257,7 @@ break w_value = self.popvalue() w_key = self.popvalue() -key = self.space.identifier_w(w_key) +key = self.space.text_w(w_key) keywords[n_keywords] = key keywords_w[n_keywords] = w_value else: ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3.5-newtext: Start
Author: Armin Rigo Branch: py3.5-newtext Changeset: r89098:e5f85b6b5bbf Date: 2016-12-16 14:51 +0100 http://bitbucket.org/pypy/pypy/changeset/e5f85b6b5bbf/ Log:Start diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -6,7 +6,7 @@ from rpython.rlib.buffer import StringBuffer from rpython.rlib.debug import make_sure_not_resized from rpython.rlib.objectmodel import (we_are_translated, newlist_hint, - compute_unique_id, specialize) + compute_unique_id, specialize, not_rpython) from rpython.rlib.signature import signature from rpython.rlib.rarithmetic import r_uint, SHRT_MIN, SHRT_MAX, \ INT_MIN, INT_MAX, UINT_MAX, USHRT_MAX @@ -255,6 +255,9 @@ def identifier_w(self, space): self._typed_unwrap_error(space, "string") +def text_w(self, space): +self._typed_unwrap_error(space, "string") + def bytearray_list_of_chars_w(self, space): self._typed_unwrap_error(space, "bytearray") @@ -1570,18 +1573,20 @@ return None if self.is_none(w_obj) else self.str_w(w_obj) def text_or_None_w(self, w_obj): -return None if self.is_none(w_obj) else self.identifier_w(w_obj) +return None if self.is_none(w_obj) else self.text_w(w_obj) +@not_rpython def str_w(self, w_obj): """ -if w_obj is unicode, call identifier_w() (i.e., return the UTF-8 +if w_obj is unicode, call text_w() (i.e., return the UTF-8-nosg encoded string). Else, call bytes_w(). -Maybe we should kill str_w completely and manually substitute it with -identifier_w/bytes_w at all call sites? +We should kill str_w completely and manually substitute it with +text_w/identifier_w/bytes_w at all call sites. It remains for +now for tests only. """ if self.isinstance_w(w_obj, self.w_unicode): -return w_obj.identifier_w(self) +return w_obj.text_w(self) else: return w_obj.bytes_w(self) @@ -1660,11 +1665,22 @@ raise oefmt(self.w_TypeError, "argument must be a unicode") return self.unicode_w(w_obj) +def text_w(self, w_obj): +""" +Unwrap a unicode object and return a 'utf-8-nosg' byte string +('no surrogate'). This encoding always works and is in one-to- +one correspondance with the unicode. +""" +return w_obj.text_w(self) + def identifier_w(self, w_obj): """ Unwrap an object which is used as an identifier (i.e. names of variables, methdods, functions, classes etc.). In py3k, identifiers are unicode strings and are unwrapped as UTF-8 encoded byte strings. +This differs from space.text_w() because it raises an app-level +UnicodeEncodeError if the unicode string contains surrogates. +This corresponds exactly to 'str.encode(obj, "utf-8")' at app-level. """ return w_obj.identifier_w(self) diff --git a/pypy/module/__pypy__/interp_stderrprinter.py b/pypy/module/__pypy__/interp_stderrprinter.py --- a/pypy/module/__pypy__/interp_stderrprinter.py +++ b/pypy/module/__pypy__/interp_stderrprinter.py @@ -34,8 +34,8 @@ return space.wrap(res) def descr_write(self, space, w_data): -# Encode to UTF-8. -data = space.identifier_w(w_data) +# Encode to UTF-8-nosg. +data = space.text_w(w_data) try: n = os.write(self.fd, data) diff --git a/pypy/objspace/std/test/test_unicodeobject.py b/pypy/objspace/std/test/test_unicodeobject.py --- a/pypy/objspace/std/test/test_unicodeobject.py +++ b/pypy/objspace/std/test/test_unicodeobject.py @@ -30,6 +30,16 @@ space.w_unicode, "__new__", space.w_unicode, w_uni) assert w_new is w_uni +def test_identifier_or_text_w(self): +space = self.space +w_uni = space.wrap(u'abcd') +assert space.identifier_w(w_uni) == 'abcd' +assert space.text_w(w_uni) == 'abcd' +w_uni = space.wrap(unichr(0xd921) + unichr(0x)) +space.raises_w(space.w_UnicodeEncodeError, space.identifier_w, w_uni) +assert space.text_w(w_uni) == '\xed\xa4\xa1\xed\xb7\x9d' +# ^^^ and not the 4-bytes combined character + class AppTestUnicodeStringStdOnly: def test_compares(self): diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py --- a/pypy/objspace/std/typeobject.py +++ b/pypy/objspace/std/typeobject.py @@ -1073,7 +1073,7 @@ "__slots__ items must be strings, not '%T'", w_name) if not _isidentifier(space.unicode_w(w_name)): raise oefmt(space.w_TypeError, "__slots__ must be identifiers") -return w_name.identifier_w(space) +return w_name.text_w(space) def create_all_slots(w_self, hasoldstylebase, w_bestbase, force_new_layout): fro
[pypy-commit] pypy py3.5-newtext: A branch to track space-newtext in the py3.5 world
Author: Armin Rigo Branch: py3.5-newtext Changeset: r89097:58d1d9b712b7 Date: 2016-12-16 14:51 +0100 http://bitbucket.org/pypy/pypy/changeset/58d1d9b712b7/ Log:A branch to track space-newtext in the py3.5 world ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: Flow space: "raise x" now explicitly asserts that x is not a None
Author: Armin Rigo Branch: Changeset: r89096:2fbea2e90463 Date: 2016-12-16 13:40 +0100 http://bitbucket.org/pypy/pypy/changeset/2fbea2e90463/ Log:Flow space: "raise x" now explicitly asserts that x is not a None diff --git a/rpython/annotator/annrpython.py b/rpython/annotator/annrpython.py --- a/rpython/annotator/annrpython.py +++ b/rpython/annotator/annrpython.py @@ -231,6 +231,12 @@ v = graph.getreturnvar() if v.annotation is None: self.setbinding(v, s_ImpossibleValue) +v = graph.exceptblock.inputargs[1] +if v.annotation is not None and v.annotation.can_be_none(): +raise annmodel.AnnotatorError( +"%r is found by annotation to possibly raise None, " +"but the None was not suppressed by the flow space" % +(graph,)) def validate(self): """Check that the annotation results are valid""" diff --git a/rpython/annotator/model.py b/rpython/annotator/model.py --- a/rpython/annotator/model.py +++ b/rpython/annotator/model.py @@ -484,6 +484,9 @@ def __init__(self, classdefs): self.classdefs = classdefs +def can_be_none(self): +return False + def as_SomeInstance(self): return unionof(*[SomeInstance(cdef) for cdef in self.classdefs]) diff --git a/rpython/annotator/test/test_annrpython.py b/rpython/annotator/test/test_annrpython.py --- a/rpython/annotator/test/test_annrpython.py +++ b/rpython/annotator/test/test_annrpython.py @@ -4652,6 +4652,17 @@ assert ('string formatting requires a constant string/unicode' in str(e.value)) +def test_cannot_raise_none(self): +def f(x): +s = None +if x > 5: +s = ValueError() +raise s +a = self.RPythonAnnotator() +a.build_types(f, [int]) +s_exc = a.binding(graphof(a, f).exceptblock.inputargs[1]) +assert not s_exc.can_be_none() + def g(n): return [0, 1, 2, n] diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py --- a/rpython/flowspace/flowcontext.py +++ b/rpython/flowspace/flowcontext.py @@ -597,6 +597,8 @@ Returns an FSException object whose w_value is an instance of w_type. """ +from rpython.rlib.debug import ll_assert_not_none + w_is_type = op.isinstance(w_arg1, const(type)).eval(self) if self.guessbool(w_is_type): # this is for all cases of the form (Class, something) @@ -618,6 +620,7 @@ "separate value") raise Raise(const(exc)) w_value = w_arg1 +w_value = op.simple_call(const(ll_assert_not_none), w_value).eval(self) w_type = op.type(w_value).eval(self) return FSException(w_type, w_value) diff --git a/rpython/rlib/debug.py b/rpython/rlib/debug.py --- a/rpython/rlib/debug.py +++ b/rpython/rlib/debug.py @@ -11,7 +11,8 @@ # Expose these here (public interface) from rpython.rtyper.debug import ( -ll_assert, FatalError, fatalerror, fatalerror_notb, debug_print_traceback) +ll_assert, FatalError, fatalerror, fatalerror_notb, debug_print_traceback, +ll_assert_not_none) class DebugLog(list): diff --git a/rpython/rtyper/debug.py b/rpython/rtyper/debug.py --- a/rpython/rtyper/debug.py +++ b/rpython/rtyper/debug.py @@ -20,6 +20,26 @@ hop.exception_cannot_occur() hop.genop('debug_assert', vlist) +def ll_assert_not_none(x): +"""assert x is not None""" +assert x, "ll_assert_not_none(%r)" % (x,) +return x + +class Entry(ExtRegistryEntry): +_about_ = ll_assert_not_none + +def compute_result_annotation(self, s_x): +return s_x.nonnoneify() + +def specialize_call(self, hop): +[v0] = hop.inputargs(hop.args_r[0]) +assert isinstance(v0.concretetype, lltype.Ptr) +v1 = hop.genop('ptr_nonzero', [v0], resulttype=lltype.Bool) +hop.exception_cannot_occur() +cmsg = hop.inputconst(lltype.Void, "ll_assert_not_none failed") +hop.genop('debug_assert', [v1, cmsg]) +return v0 + class FatalError(Exception): pass ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3.5: fix for tests
Author: Armin Rigo Branch: py3.5 Changeset: r89095:31775eeb3581 Date: 2016-12-16 12:54 +0100 http://bitbucket.org/pypy/pypy/changeset/31775eeb3581/ Log:fix for tests diff --git a/pypy/objspace/fake/objspace.py b/pypy/objspace/fake/objspace.py --- a/pypy/objspace/fake/objspace.py +++ b/pypy/objspace/fake/objspace.py @@ -349,6 +349,9 @@ def is_generator(self, w_obj): return NonConstant(False) +def is_iterable(self, w_obj): +return NonConstant(False) + def lookup_in_type(self, w_type, name): return w_some_obj() ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3.5: test and fix for bytes.__rmod__
Author: Armin Rigo Branch: py3.5 Changeset: r89094:96366ab75bb6 Date: 2016-12-16 12:35 +0100 http://bitbucket.org/pypy/pypy/changeset/96366ab75bb6/ Log:test and fix for bytes.__rmod__ diff --git a/pypy/objspace/std/bytesobject.py b/pypy/objspace/std/bytesobject.py --- a/pypy/objspace/std/bytesobject.py +++ b/pypy/objspace/std/bytesobject.py @@ -684,6 +684,8 @@ return mod_format(space, self, w_values, fmt_type=FORMAT_BYTES) def descr_rmod(self, space, w_values): +if not isinstance(w_values, W_AbstractBytesObject): +return space.w_NotImplemented return mod_format(space, w_values, self, fmt_type=FORMAT_BYTES) @staticmethod diff --git a/pypy/objspace/std/test/test_bytesobject.py b/pypy/objspace/std/test/test_bytesobject.py --- a/pypy/objspace/std/test/test_bytesobject.py +++ b/pypy/objspace/std/test/test_bytesobject.py @@ -170,6 +170,8 @@ expected2 = int_format + ' format: an integer is required, not str' assert str(exc_info.value) in (expected1, expected2) raises(TypeError, "None % 'abc'") # __rmod__ +assert b'abc'.__rmod__('-%b-') is NotImplemented +assert b'abc'.__rmod__(b'-%b-') == b'-abc-' def test_format_bytes(self): assert b'<%s>' % b'abc' == b'' ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy space-newtext: merge default
Author: Carl Friedrich Bolz Branch: space-newtext Changeset: r89093:b799e1db856f Date: 2016-12-16 11:39 +0100 http://bitbucket.org/pypy/pypy/changeset/b799e1db856f/ Log:merge default diff --git a/pypy/doc/contributor.rst b/pypy/doc/contributor.rst --- a/pypy/doc/contributor.rst +++ b/pypy/doc/contributor.rst @@ -1,3 +1,9 @@ +#encoding utf-8 + +Contributors + +:: + Armin Rigo Maciej Fijalkowski Carl Friedrich Bolz @@ -307,7 +313,7 @@ Mads Kiilerich Antony Lee Jason Madden - Daniel Neuh�user + Daniel Neuhäuser reub...@gmail.com Yaroslav Fedevych Jim Hunziker diff --git a/pypy/doc/cppyy.rst b/pypy/doc/cppyy.rst --- a/pypy/doc/cppyy.rst +++ b/pypy/doc/cppyy.rst @@ -3,16 +3,17 @@ The cppyy module delivers dynamic Python-C++ bindings. It is designed for automation, high performance, scale, interactivity, and -handling all of modern C++. +handling all of modern C++ (11, 14, etc.). It is based on `Cling`_ which, through `LLVM`_/`clang`_, provides C++ reflection and interactivity. Reflection information is extracted from C++ header files. Cppyy itself is built into PyPy (an alternative exists for CPython), but -it requires a backend, installable through pip, to interface with Cling. +it requires a `backend`_, installable through pip, to interface with Cling. .. _Cling: https://root.cern.ch/cling .. _LLVM: http://llvm.org/ .. _clang: http://clang.llvm.org/ +.. _backend: https://pypi.python.org/pypi/PyPy-cppyy-backend Installation @@ -22,25 +23,39 @@ module, which is no longer supported. Both the tooling and user-facing Python codes are very backwards compatible, however. -Further dependencies are cmake (for general build) and Python2.7 (for LLVM). +Further dependencies are cmake (for general build), Python2.7 (for LLVM), and +a modern C++ compiler (one that supports at least C++11). Assuming you have a recent enough version of PyPy installed, use pip to complete the installation of cppyy:: - $ pypy-c -m pip install PyPy-cppyy-backend + $ MAKE_NPROCS=4 pypy-c -m pip install --verbose PyPy-cppyy-backend +Set the number of parallel builds ('4' in this example, through the MAKE_NPROCS +environment variable) to a number appropriate for your machine. The building process may take quite some time as it includes a customized -version of LLVM as part of Cling. +version of LLVM as part of Cling, which is why --verbose is recommended so that +you can see the build progress. + +The default installation will be under +$PYTHONHOME/site-packages/cppyy_backend/lib, +which needs to be added to your dynamic loader path (LD_LIBRARY_PATH). +If you need the dictionary and class map generation tools (used in the examples +below), you need to add $PYTHONHOME/site-packages/cppyy_backend/bin to your +executable path (PATH). Basic bindings example -- -Now test with a trivial example whether all packages are properly installed -and functional. -First, create a C++ header file with some class in it (note that all functions -are made inline for convenience; a real-world example would of course have a -corresponding source file):: +These examples assume that cppyy_backend is pointed to by the environment +variable CPPYYHOME, and that CPPYYHOME/lib is added to LD_LIBRARY_PATH and +CPPYYHOME/bin to PATH. + +Let's first test with a trivial example whether all packages are properly +installed and functional. +Create a C++ header file with some class in it (all functions are made inline +for convenience; if you have out-of-line code, link with it as appropriate):: $ cat MyClass.h class MyClass { @@ -54,11 +69,11 @@ int m_myint; }; -Then, generate the bindings using ``genreflex`` (part of ROOT), and compile the -code:: +Then, generate the bindings using ``genreflex`` (installed under +cppyy_backend/bin in site_packages), and compile the code:: $ genreflex MyClass.h -$ g++ -fPIC -rdynamic -O2 -shared -I$REFLEXHOME/include MyClass_rflx.cpp -o libMyClassDict.so -L$REFLEXHOME/lib -lReflex +$ g++ -std=c++11 -fPIC -rdynamic -O2 -shared -I$CPPYYHOME/include MyClass_rflx.cpp -o libMyClassDict.so -L$CPPYYHOME/lib -lCling Next, make sure that the library can be found through the dynamic lookup path (the ``LD_LIBRARY_PATH`` environment variable on Linux, ``PATH`` on Windows), @@ -110,7 +125,7 @@ For example:: $ genreflex MyClass.h --rootmap=libMyClassDict.rootmap --rootmap-lib=libMyClassDict.so -$ g++ -fPIC -rdynamic -O2 -shared -I$REFLEXHOME/include MyClass_rflx.cpp -o libMyClassDict.so -L$REFLEXHOME/lib -lReflex +$ g++ -std=c++11 -fPIC -rdynamic -O2 -shared -I$CPPYYHOME/include MyClass_rflx.cpp -o libMyClassDict.so -L$CPPYYHOME/lib -lCling where the first option (``--rootmap``) specifies the output file name, and the second option (``--rootmap-lib``) the name of the reflection library where @@ -212,7 +227,7 @@ Now the reflection info can be generated and compiled:: $ genreflex
[pypy-commit] pypy space-newtext: remove some new wraps
Author: Carl Friedrich Bolz Branch: space-newtext Changeset: r89092:342d364c012a Date: 2016-12-16 11:39 +0100 http://bitbucket.org/pypy/pypy/changeset/342d364c012a/ Log:remove some new wraps diff --git a/pypy/module/cppyy/capi/loadable_capi.py b/pypy/module/cppyy/capi/loadable_capi.py --- a/pypy/module/cppyy/capi/loadable_capi.py +++ b/pypy/module/cppyy/capi/loadable_capi.py @@ -601,7 +601,7 @@ from pypy.module.cppyy import interp_cppyy cppstr = space.interp_w(interp_cppyy.W_CPPInstance, w_self, can_be_None=False) -return space.wrap(c_stdstring2charp(space, cppstr._rawobject)) +return space.newtext(c_stdstring2charp(space, cppstr._rawobject)) # setup pythonizations for later use at run-time _pythonizations = {} @@ -616,14 +616,14 @@ ] for f in allfuncs: -_pythonizations[f.__name__] = space.wrap(interp2app(f)) +_pythonizations[f.__name__] = interp2app(f).spacebind(space) def _method_alias(space, w_pycppclass, m1, m2): -space.setattr(w_pycppclass, space.wrap(m1), - space.getattr(w_pycppclass, space.wrap(m2))) +space.setattr(w_pycppclass, space.newtext(m1), + space.getattr(w_pycppclass, space.newtext(m2))) def pythonize(space, name, w_pycppclass): if name == "string": -space.setattr(w_pycppclass, space.wrap("c_str"), _pythonizations["stdstring_c_str"]) +space.setattr(w_pycppclass, space.newtext("c_str"), _pythonizations["stdstring_c_str"]) _method_alias(space, w_pycppclass, "_cppyy_as_builtin", "c_str") _method_alias(space, w_pycppclass, "__str__", "c_str") ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3.5: A more proper fix than 7d75f981d293: introduce and use the unwrap_spec
Author: Armin Rigo Branch: py3.5 Changeset: r89091:98017da1387f Date: 2016-12-16 11:18 +0100 http://bitbucket.org/pypy/pypy/changeset/98017da1387f/ Log:A more proper fix than 7d75f981d293: introduce and use the unwrap_spec 'text_or_None' (doesn't break randomly other things for now) diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1567,7 +1567,9 @@ return self.buffer_w(w_obj, flags).as_str() def str_or_None_w(self, w_obj): -# FIXME: XXX for now, inconsistent with str_w() +return None if self.is_none(w_obj) else self.str_w(w_obj) + +def text_or_None_w(self, w_obj): return None if self.is_none(w_obj) else self.identifier_w(w_obj) def str_w(self, w_obj): diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -156,6 +156,9 @@ def visit_str_or_None(self, el, app_sig): self.checked_space_method(el, app_sig) +def visit_text_or_None(self, el, app_sig): +self.checked_space_method(el, app_sig) + def visit_str0(self, el, app_sig): self.checked_space_method(el, app_sig) @@ -296,6 +299,9 @@ def visit_str_or_None(self, typ): self.run_args.append("space.str_or_None_w(%s)" % (self.scopenext(),)) +def visit_text_or_None(self, typ): +self.run_args.append("space.text_or_None_w(%s)" % (self.scopenext(),)) + def visit_str0(self, typ): self.run_args.append("space.str0_w(%s)" % (self.scopenext(),)) @@ -455,6 +461,9 @@ def visit_str_or_None(self, typ): self.unwrap.append("space.str_or_None_w(%s)" % (self.nextarg(),)) +def visit_text_or_None(self, typ): +self.unwrap.append("space.text_or_None_w(%s)" % (self.nextarg(),)) + def visit_str0(self, typ): self.unwrap.append("space.str0_w(%s)" % (self.nextarg(),)) diff --git a/pypy/objspace/std/bytearrayobject.py b/pypy/objspace/std/bytearrayobject.py --- a/pypy/objspace/std/bytearrayobject.py +++ b/pypy/objspace/std/bytearrayobject.py @@ -206,7 +206,7 @@ # we ignore w_type and always return a bytearray return new_bytearray(space, space.w_bytearray, data) -@unwrap_spec(encoding='str_or_None', errors='str_or_None') +@unwrap_spec(encoding='text_or_None', errors='text_or_None') def descr_init(self, space, w_source=None, encoding=None, errors=None): assert isinstance(self, W_BytearrayObject) data = [c for c in newbytesdata_w(space, w_source, encoding, errors)] diff --git a/pypy/objspace/std/bytesobject.py b/pypy/objspace/std/bytesobject.py --- a/pypy/objspace/std/bytesobject.py +++ b/pypy/objspace/std/bytesobject.py @@ -526,7 +526,7 @@ return space.newlist_bytes(lst) @staticmethod -@unwrap_spec(encoding='str_or_None', errors='str_or_None') +@unwrap_spec(encoding='text_or_None', errors='text_or_None') def descr_new(space, w_stringtype, w_source=None, encoding=None, errors=None): if (w_source and space.is_w(w_stringtype, space.w_bytes) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3.5: hg merge default
Author: Armin Rigo Branch: py3.5 Changeset: r89090:97c916c45ec7 Date: 2016-12-16 10:44 +0100 http://bitbucket.org/pypy/pypy/changeset/97c916c45ec7/ Log:hg merge default diff --git a/pypy/doc/contributor.rst b/pypy/doc/contributor.rst --- a/pypy/doc/contributor.rst +++ b/pypy/doc/contributor.rst @@ -1,3 +1,9 @@ +#encoding utf-8 + +Contributors + +:: + Armin Rigo Maciej Fijalkowski Carl Friedrich Bolz @@ -307,7 +313,7 @@ Mads Kiilerich Antony Lee Jason Madden - Daniel Neuh�user + Daniel Neuhäuser reub...@gmail.com Yaroslav Fedevych Jim Hunziker diff --git a/pypy/doc/cppyy.rst b/pypy/doc/cppyy.rst --- a/pypy/doc/cppyy.rst +++ b/pypy/doc/cppyy.rst @@ -3,16 +3,17 @@ The cppyy module delivers dynamic Python-C++ bindings. It is designed for automation, high performance, scale, interactivity, and -handling all of modern C++. +handling all of modern C++ (11, 14, etc.). It is based on `Cling`_ which, through `LLVM`_/`clang`_, provides C++ reflection and interactivity. Reflection information is extracted from C++ header files. Cppyy itself is built into PyPy (an alternative exists for CPython), but -it requires a backend, installable through pip, to interface with Cling. +it requires a `backend`_, installable through pip, to interface with Cling. .. _Cling: https://root.cern.ch/cling .. _LLVM: http://llvm.org/ .. _clang: http://clang.llvm.org/ +.. _backend: https://pypi.python.org/pypi/PyPy-cppyy-backend Installation @@ -22,25 +23,39 @@ module, which is no longer supported. Both the tooling and user-facing Python codes are very backwards compatible, however. -Further dependencies are cmake (for general build) and Python2.7 (for LLVM). +Further dependencies are cmake (for general build), Python2.7 (for LLVM), and +a modern C++ compiler (one that supports at least C++11). Assuming you have a recent enough version of PyPy installed, use pip to complete the installation of cppyy:: - $ pypy-c -m pip install PyPy-cppyy-backend + $ MAKE_NPROCS=4 pypy-c -m pip install --verbose PyPy-cppyy-backend +Set the number of parallel builds ('4' in this example, through the MAKE_NPROCS +environment variable) to a number appropriate for your machine. The building process may take quite some time as it includes a customized -version of LLVM as part of Cling. +version of LLVM as part of Cling, which is why --verbose is recommended so that +you can see the build progress. + +The default installation will be under +$PYTHONHOME/site-packages/cppyy_backend/lib, +which needs to be added to your dynamic loader path (LD_LIBRARY_PATH). +If you need the dictionary and class map generation tools (used in the examples +below), you need to add $PYTHONHOME/site-packages/cppyy_backend/bin to your +executable path (PATH). Basic bindings example -- -Now test with a trivial example whether all packages are properly installed -and functional. -First, create a C++ header file with some class in it (note that all functions -are made inline for convenience; a real-world example would of course have a -corresponding source file):: +These examples assume that cppyy_backend is pointed to by the environment +variable CPPYYHOME, and that CPPYYHOME/lib is added to LD_LIBRARY_PATH and +CPPYYHOME/bin to PATH. + +Let's first test with a trivial example whether all packages are properly +installed and functional. +Create a C++ header file with some class in it (all functions are made inline +for convenience; if you have out-of-line code, link with it as appropriate):: $ cat MyClass.h class MyClass { @@ -54,11 +69,11 @@ int m_myint; }; -Then, generate the bindings using ``genreflex`` (part of ROOT), and compile the -code:: +Then, generate the bindings using ``genreflex`` (installed under +cppyy_backend/bin in site_packages), and compile the code:: $ genreflex MyClass.h -$ g++ -fPIC -rdynamic -O2 -shared -I$REFLEXHOME/include MyClass_rflx.cpp -o libMyClassDict.so -L$REFLEXHOME/lib -lReflex +$ g++ -std=c++11 -fPIC -rdynamic -O2 -shared -I$CPPYYHOME/include MyClass_rflx.cpp -o libMyClassDict.so -L$CPPYYHOME/lib -lCling Next, make sure that the library can be found through the dynamic lookup path (the ``LD_LIBRARY_PATH`` environment variable on Linux, ``PATH`` on Windows), @@ -110,7 +125,7 @@ For example:: $ genreflex MyClass.h --rootmap=libMyClassDict.rootmap --rootmap-lib=libMyClassDict.so -$ g++ -fPIC -rdynamic -O2 -shared -I$REFLEXHOME/include MyClass_rflx.cpp -o libMyClassDict.so -L$REFLEXHOME/lib -lReflex +$ g++ -std=c++11 -fPIC -rdynamic -O2 -shared -I$CPPYYHOME/include MyClass_rflx.cpp -o libMyClassDict.so -L$CPPYYHOME/lib -lCling where the first option (``--rootmap``) specifies the output file name, and the second option (``--rootmap-lib``) the name of the reflection library where @@ -212,7 +227,7 @@ Now the reflection info can be generated and compiled:: $ genreflex MyAdvanced.h -
[pypy-commit] pypy default: Linux: try to implement os.urandom() on top of the syscall getrandom()
Author: Armin Rigo Branch: Changeset: r89089:82ef21124af8 Date: 2016-12-16 10:42 +0100 http://bitbucket.org/pypy/pypy/changeset/82ef21124af8/ Log:Linux: try to implement os.urandom() on top of the syscall getrandom() diff --git a/pypy/module/posix/interp_posix.py b/pypy/module/posix/interp_posix.py --- a/pypy/module/posix/interp_posix.py +++ b/pypy/module/posix/interp_posix.py @@ -1331,8 +1331,9 @@ Return a string of n random bytes suitable for cryptographic use. """ context = get(space).random_context +signal_checker = space.getexecutioncontext().checksignals try: -return space.wrap(rurandom.urandom(context, n)) +return space.wrap(rurandom.urandom(context, n, signal_checker)) except OSError as e: raise wrap_oserror(space, e) diff --git a/rpython/rlib/rurandom.py b/rpython/rlib/rurandom.py --- a/rpython/rlib/rurandom.py +++ b/rpython/rlib/rurandom.py @@ -7,12 +7,12 @@ from rpython.rtyper.lltypesystem import lltype, rffi from rpython.rlib.objectmodel import not_rpython +from rpython.translator.tool.cbuild import ExternalCompilationInfo +from rpython.rtyper.tool import rffi_platform if sys.platform == 'win32': from rpython.rlib import rwin32 -from rpython.translator.tool.cbuild import ExternalCompilationInfo -from rpython.rtyper.tool import rffi_platform eci = ExternalCompilationInfo( includes = ['windows.h', 'wincrypt.h'], @@ -56,7 +56,7 @@ return lltype.malloc(rffi.CArray(HCRYPTPROV), 1, immortal=True, zero=True) -def urandom(context, n): +def urandom(context, n, signal_checker=None): provider = context[0] if not provider: # This handle is never explicitly released. The operating @@ -80,11 +80,71 @@ def init_urandom(): return None -def urandom(context, n): +SYS_getrandom = None + +if sys.platform.startswith('linux'): +eci = ExternalCompilationInfo(includes=['sys/syscall.h']) +class CConfig: +_compilation_info_ = eci +SYS_getrandom = rffi_platform.DefinedConstantInteger( +'SYS_getrandom') +globals().update(rffi_platform.configure(CConfig)) + +if SYS_getrandom is not None: +from rpython.rlib.rposix import get_saved_errno, handle_posix_error +import errno + +eci = eci.merge(ExternalCompilationInfo(includes=['linux/random.h'])) +class CConfig: +_compilation_info_ = eci +GRND_NONBLOCK = rffi_platform.ConstantInteger('GRND_NONBLOCK') +globals().update(rffi_platform.configure(CConfig)) + +# On Linux, use the syscall() function because the GNU libc doesn't +# expose the Linux getrandom() syscall yet. +syscall = rffi.llexternal( +'syscall', +[lltype.Signed, rffi.CCHARP, rffi.LONG, rffi.INT], +lltype.Signed, +compilation_info=eci, +save_err=rffi.RFFI_SAVE_ERRNO) + +class Works: +status = True +getrandom_works = Works() + +def _getrandom(n, result, signal_checker): +if not getrandom_works.status: +return n +while n > 0: +with rffi.scoped_alloc_buffer(n) as buf: +got = syscall(SYS_getrandom, buf.raw, n, GRND_NONBLOCK) +if got >= 0: +s = buf.str(got) +result.append(s) +n -= len(s) +continue +err = get_saved_errno() +if (err == errno.ENOSYS or err == errno.EPERM or +err == errno.EAGAIN): # see CPython 3.5 +getrandom_works.status = False +return n +if err == errno.EINTR: +if signal_checker is not None: +signal_checker() +continue +handle_posix_error("getrandom", got) +raise AssertionError("unreachable") +return n + +def urandom(context, n, signal_checker=None): "Read n bytes from /dev/urandom." -result = '' -if n == 0: -return result +result = [] +if SYS_getrandom is not None: +n = _getrandom(n, result, signal_checker) +if n <= 0: +return ''.join(result) + # XXX should somehow cache the file descriptor. It's a mess. # CPython has a 99% solution and hopes for the remaining 1% # not to occur. For now, we just don't cache the file @@ -98,8 +158,8 @@ if e.errno != errno.EINTR: raise data = '' -result += data +result.append(data) n -= len(data) finally: os.close(fd) -return result +return ''
[pypy-commit] pypy default: utf-8
Author: Armin Rigo Branch: Changeset: r89088:58b122a955e6 Date: 2016-12-16 09:51 +0100 http://bitbucket.org/pypy/pypy/changeset/58b122a955e6/ Log:utf-8 diff --git a/pypy/doc/contributor.rst b/pypy/doc/contributor.rst --- a/pypy/doc/contributor.rst +++ b/pypy/doc/contributor.rst @@ -313,7 +313,7 @@ Mads Kiilerich Antony Lee Jason Madden - Daniel Neuh�user + Daniel Neuhäuser reub...@gmail.com Yaroslav Fedevych Jim Hunziker ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy.org extradoc: update the values
Author: Armin Rigo Branch: extradoc Changeset: r834:33beccdd20eb Date: 2016-12-16 09:29 +0100 http://bitbucket.org/pypy/pypy.org/changeset/33beccdd20eb/ Log:update the values diff --git a/don1.html b/don1.html --- a/don1.html +++ b/don1.html @@ -15,7 +15,7 @@ - $66436 of $105000 (63.3%) + $66464 of $105000 (63.3%) @@ -23,7 +23,7 @@ This donation goes towards supporting Python 3 in PyPy. Current status: -we have $2280 left +we have $2305 left in the account. Read proposal ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit