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