[pypy-commit] pypy py3.5: hg merge default
rlamy
pypy.commits at gmail.com
Fri Jan 27 11:07:29 EST 2017
Author: Ronan Lamy <ronan.lamy at 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'],
More information about the pypy-commit
mailing list