[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