Author: Ronan Lamy <ronan.l...@gmail.com> Branch: py3.5 Changeset: r89800:9b9d04aef631 Date: 2017-01-27 16:06 +0000 http://bitbucket.org/pypy/pypy/changeset/9b9d04aef631/
Log: hg merge default diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py --- a/pypy/interpreter/error.py +++ b/pypy/interpreter/error.py @@ -80,7 +80,8 @@ def errorstr(self, space, use_repr=False): "The exception class and value, as a string." - self.normalize_exception(space) + if not use_repr: # see write_unraisable() + self.normalize_exception(space) w_value = self.get_w_value(space) if space is None: # this part NOT_RPYTHON @@ -276,6 +277,11 @@ first_line = 'Exception ignored in: %s%s\n' % ( where, objrepr) else: + # Note that like CPython, we don't normalize the + # exception here. So from `'foo'.index('bar')` you get + # "Exception ValueError: 'substring not found' in x ignored" + # but from `raise ValueError('foo')` you get + # "Exception ValueError: ValueError('foo',) in x ignored" first_line = '' space.appexec([space.wrap(first_line), space.wrap(extra_line), diff --git a/pypy/interpreter/test/test_appinterp.py b/pypy/interpreter/test/test_appinterp.py --- a/pypy/interpreter/test/test_appinterp.py +++ b/pypy/interpreter/test/test_appinterp.py @@ -23,7 +23,9 @@ (): y y """) - assert str(excinfo.value.errorstr(space)).find('y y') != -1 + # NOTE: the following test only works because excinfo.value is not + # normalized so far + assert str(excinfo.value.get_w_value(space)).find('y y') != -1 def test_simple_applevel(space): app = appdef("""app(x,y): 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,4 +1,5 @@ from collections import OrderedDict +from itertools import izip from . import cmodel as model from .commontypes import COMMON_TYPES, resolve_common_type from .error import FFIError, CDefError @@ -103,7 +104,7 @@ class Parser(object): def __init__(self): - self._declarations = {} + self._declarations = OrderedDict() self._included_declarations = set() self._anonymous_counter = 0 self._structnode2type = weakref.WeakKeyDictionary() @@ -699,8 +700,7 @@ self.headers = headers if headers is not None else ['sys/types.h'] self.parsed_headers = [] self.sources = [] - self._Config = type('Config', (object,), {}) - self._TYPES = {} + self._config_entries = OrderedDict() self.includes = [] self.struct_typedefs = {} self._handled = set() @@ -758,10 +758,8 @@ def realize_struct(self, struct): type_name = struct.get_type_name() - configname = type_name.replace(' ', '__') - setattr(self._Config, configname, - rffi_platform.Struct(type_name, struct.fields)) - self._TYPES[configname] = struct.TYPE + entry = rffi_platform.Struct(type_name, struct.fields) + self._config_entries[entry] = struct.TYPE return struct.TYPE def build_eci(self): @@ -795,13 +793,15 @@ elif name.startswith('macro '): name = name[6:] self.add_macro(name, obj) - self._Config._compilation_info_ = self.build_eci() - for name, TYPE in rffi_platform.configure(self._Config).iteritems(): + if not self._config_entries: + return + eci = self.build_eci() + result = rffi_platform.configure_entries(list(self._config_entries), eci) + for entry, TYPE in izip(self._config_entries, result): # hack: prevent the source from being pasted into common_header.h del TYPE._hints['eci'] - if name in self._TYPES: - self._TYPES[name].become(TYPE) - del self._TYPES[name] + self._config_entries[entry].become(TYPE) + self._config_entries.clear() def convert_type(self, obj, quals=0): if isinstance(obj, model.DefinedType): diff --git a/pypy/module/cpyext/parse/cpyext_object.h b/pypy/module/cpyext/parse/cpyext_object.h --- a/pypy/module/cpyext/parse/cpyext_object.h +++ b/pypy/module/cpyext/parse/cpyext_object.h @@ -280,3 +280,12 @@ destructor tp_finalize; } PyTypeObject; + +typedef struct { + PyTypeObject ht_type; + PyNumberMethods as_number; + PyMappingMethods as_mapping; + PySequenceMethods as_sequence; + PyBufferProcs as_buffer; + PyObject *ht_name, *ht_slots; +} PyHeapTypeObject; diff --git a/pypy/module/cpyext/parse/cpyext_typeobject.h b/pypy/module/cpyext/parse/cpyext_typeobject.h deleted file mode 100644 --- a/pypy/module/cpyext/parse/cpyext_typeobject.h +++ /dev/null @@ -1,9 +0,0 @@ -typedef struct { - PyTypeObject ht_type; - PyNumberMethods as_number; - PyMappingMethods as_mapping; - PySequenceMethods as_sequence; - PyBufferProcs as_buffer; - PyObject *ht_name, *ht_slots; -} PyHeapTypeObject; - 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 @@ -142,6 +142,20 @@ assert isinstance(Object, lltype.Struct) hash(Object) +def test_nested_struct(): + cdef = """ + typedef struct { + int x; + } foo; + typedef struct { + foo y; + } bar; + """ + cts = parse_source(cdef) + bar = cts.gettype('bar') + assert isinstance(bar, lltype.Struct) + hash(bar) # bar is hashable + def test_const(): cdef = """ typedef struct { diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py --- a/pypy/module/cpyext/typeobject.py +++ b/pypy/module/cpyext/typeobject.py @@ -40,7 +40,6 @@ PyType_Check, PyType_CheckExact = build_type_checkers("Type", "w_type") -cts.parse_header(parse_dir / 'cpyext_typeobject.h') PyHeapTypeObject = cts.gettype('PyHeapTypeObject *') diff --git a/rpython/rlib/rsiphash.py b/rpython/rlib/rsiphash.py --- a/rpython/rlib/rsiphash.py +++ b/rpython/rlib/rsiphash.py @@ -21,6 +21,9 @@ # that as easily because many details may rely on getting the same hash # value before and after translation. We can, however, pick a random # seed once per translation, which should already be quite good. +# +# XXX no, it is not: e.g. all Ubuntu installations of the same Ubuntu +# would get the same seed. That's not good enough. @not_rpython def select_random_seed(): diff --git a/rpython/rtyper/tool/rffi_platform.py b/rpython/rtyper/tool/rffi_platform.py --- a/rpython/rtyper/tool/rffi_platform.py +++ b/rpython/rtyper/tool/rffi_platform.py @@ -131,38 +131,32 @@ # General interface class ConfigResult: - def __init__(self, CConfig, info, entries): - self.CConfig = CConfig + def __init__(self, eci, info): + self.eci = eci + self.info = info self.result = {} - self.info = info - self.entries = entries def get_entry_result(self, entry): try: return self.result[entry] except KeyError: pass - name = self.entries[entry] - info = self.info[name] + info = self.info[entry] self.result[entry] = entry.build_result(info, self) return self.result[entry] - def get_result(self): - return dict([(name, self.result[entry]) - for entry, name in self.entries.iteritems()]) class _CWriter(object): """ A simple class which aggregates config parts """ - def __init__(self, CConfig): + def __init__(self, eci): self.path = uniquefilepath() self.f = self.path.open("w") - self.config = CConfig + self.eci = eci def write_header(self): f = self.f - CConfig = self.config - CConfig._compilation_info_.write_c_header(f) + self.eci.write_c_header(f) print >> f, C_HEADER print >> f @@ -194,8 +188,7 @@ self.start_main() self.f.write(question + "\n") self.close() - eci = self.config._compilation_info_ - try_compile_cache([self.path], eci) + try_compile_cache([self.path], self.eci) def configure(CConfig, ignore_errors=False): """Examine the local system by running the C compiler. @@ -208,50 +201,53 @@ assert not hasattr(CConfig, attr), \ "Found legacy attribute %s on CConfig" % attr - entries = [] + eci = CConfig._compilation_info_ + entries = {} for key in dir(CConfig): value = getattr(CConfig, key) if isinstance(value, CConfigEntry): - entries.append((key, value)) + entries[key] = value + res = {} if entries: # can be empty if there are only CConfigSingleEntries - writer = _CWriter(CConfig) - writer.write_header() - for key, entry in entries: - writer.write_entry(key, entry) - - writer.start_main() - for key, entry in entries: - writer.write_entry_main(key) - writer.close() - - eci = CConfig._compilation_info_ - infolist = list(run_example_code(writer.path, eci, - ignore_errors=ignore_errors)) - assert len(infolist) == len(entries) - - resultinfo = {} - resultentries = {} - for info, (key, entry) in zip(infolist, entries): - resultinfo[key] = info - resultentries[entry] = key - - result = ConfigResult(CConfig, resultinfo, resultentries) - for name, entry in entries: - result.get_entry_result(entry) - res = result.get_result() - else: - res = {} + results = configure_entries( + entries.values(), eci, ignore_errors=ignore_errors) + for name, result in zip(entries, results): + res[name] = result for key in dir(CConfig): value = getattr(CConfig, key) if isinstance(value, CConfigSingleEntry): - writer = _CWriter(CConfig) + writer = _CWriter(eci) writer.write_header() res[key] = value.question(writer.ask_gcc) return res + +def configure_entries(entries, eci, ignore_errors=False): + writer = _CWriter(eci) + writer.write_header() + for i, entry in enumerate(entries): + writer.write_entry(str(i), entry) + + writer.start_main() + for i, entry in enumerate(entries): + writer.write_entry_main(str(i)) + writer.close() + + infolist = list(run_example_code( + writer.path, eci, ignore_errors=ignore_errors)) + assert len(infolist) == len(entries) + + resultinfo = {} + for info, entry in zip(infolist, entries): + resultinfo[entry] = info + + result = ConfigResult(eci, resultinfo) + for entry in entries: + yield result.get_entry_result(entry) + # ____________________________________________________________ @@ -344,7 +340,7 @@ allfields = tuple(['c_' + name for name, _ in fields]) padfields = tuple(padfields) name = self.name - eci = config_result.CConfig._compilation_info_ + eci = config_result.eci padding_drop = PaddingDrop(name, allfields, padfields, eci) hints = {'align': info['align'], 'size': info['size'], _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit