Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r91057:1cbb46d0ce7a
Date: 2017-04-15 16:52 +0200
http://bitbucket.org/pypy/pypy/changeset/1cbb46d0ce7a/

Log:    Complain clearly when we rtype ``_immutable_fields_=['foo[*]']'' and
        ``.foo'' is not actually a list

diff --git a/rpython/rtyper/rclass.py b/rpython/rtyper/rclass.py
--- a/rpython/rtyper/rclass.py
+++ b/rpython/rtyper/rclass.py
@@ -621,7 +621,8 @@
 
     def _parse_field_list(self, fields, accessor, hints):
         ranking = {}
-        for name in fields:
+        for fullname in fields:
+            name = fullname
             quasi = False
             if name.endswith('?[*]'):   # a quasi-immutable field pointing to
                 name = name[:-4]        # an immutable array
@@ -644,6 +645,12 @@
                 raise TyperError(
                     "can't have _immutable_ = True and a quasi-immutable field 
"
                     "%s in class %s" % (name, self.classdef))
+            if rank in (IR_QUASIIMMUTABLE_ARRAY, IR_IMMUTABLE_ARRAY):
+                from rpython.rtyper.rlist import AbstractBaseListRepr
+                if not isinstance(r, AbstractBaseListRepr):
+                    raise TyperError(
+                        "_immutable_fields_ = [%r] in %r, but %r is not a list 
"
+                        "(got %r)" % (fullname, self, name, r))
             ranking[mangled_name] = rank
         accessor.initialize(self.object_type, ranking)
         return ranking
diff --git a/rpython/rtyper/test/test_rclass.py 
b/rpython/rtyper/test/test_rclass.py
--- a/rpython/rtyper/test/test_rclass.py
+++ b/rpython/rtyper/test/test_rclass.py
@@ -963,6 +963,41 @@
                 found.append(op.args[1].value)
         assert found == ['mutate_c']
 
+    def test_bad_type_for_immutable_field_1(self):
+        class A:
+            _immutable_fields_ = ['lst[*]']
+        def f(n):
+            a = A()
+            a.lst = n
+            return a.lst
+
+        with py.test.raises(TyperError):
+            self.gengraph(f, [int])
+
+    def test_bad_type_for_immutable_field_2(self):
+        from rpython.rtyper.lltypesystem import lltype
+        class A:
+            _immutable_fields_ = ['lst[*]']
+        ARRAY = lltype.GcArray(lltype.Signed)
+        def f(n):
+            a = A()
+            a.lst = lltype.malloc(ARRAY, n)
+            return a.lst
+
+        with py.test.raises(TyperError):
+            self.gengraph(f, [int])
+
+    def test_bad_type_for_immutable_field_3(self):
+        class A:
+            _immutable_fields_ = ['lst?[*]']
+        def f(n):
+            a = A()
+            a.lst = n
+            return a.lst
+
+        with py.test.raises(TyperError):
+            self.gengraph(f, [int])
+
     def test_calling_object_init(self):
         class A(object):
             pass
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to