[pypy-svn] pypy default: Change the definition of "_immutable_ = True" to be explicitly
arigo
commits-noreply at bitbucket.org
Wed Feb 23 22:54:43 CET 2011
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r42247:72ff127c6643
Date: 2011-02-23 22:52 +0100
http://bitbucket.org/pypy/pypy/changeset/72ff127c6643/
Log: Change the definition of "_immutable_ = True" to be explicitly
required on all subclasses when we put it on a class. Previously, we
got this effect implicitly. However, it made an obscure bug that
took me three days to locate: app-level subclasses of the immutable
built-in types, like 'long', have their fields flagged as immutable
too, including the 'storage' from the mapdict, which is nonsense.
diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py
--- a/pypy/objspace/std/unicodeobject.py
+++ b/pypy/objspace/std/unicodeobject.py
@@ -21,7 +21,7 @@
class W_UnicodeObject(W_Object):
from pypy.objspace.std.unicodetype import unicode_typedef as typedef
- _immutable_ = True
+ _immutable_fields_ = ['_value']
def __init__(w_self, unistr):
assert isinstance(unistr, unicode)
diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py
--- a/pypy/interpreter/function.py
+++ b/pypy/interpreter/function.py
@@ -563,7 +563,7 @@
class StaticMethod(Wrappable):
"""The staticmethod objects."""
- _immutable_ = True
+ _immutable_fields_ = ['w_function']
def __init__(self, w_function):
self.w_function = w_function
@@ -577,7 +577,7 @@
class ClassMethod(Wrappable):
"""The classmethod objects."""
- _immutable_ = True
+ _immutable_fields_ = ['w_function']
def __init__(self, w_function):
self.w_function = w_function
diff --git a/pypy/objspace/std/intobject.py b/pypy/objspace/std/intobject.py
--- a/pypy/objspace/std/intobject.py
+++ b/pypy/objspace/std/intobject.py
@@ -17,9 +17,8 @@
class W_IntObject(W_Object):
__slots__ = 'intval'
+ _immutable_fields_ = ['intval']
- _immutable_ = True
-
from pypy.objspace.std.inttype import int_typedef as typedef
def __init__(w_self, intval):
diff --git a/pypy/objspace/std/complexobject.py b/pypy/objspace/std/complexobject.py
--- a/pypy/objspace/std/complexobject.py
+++ b/pypy/objspace/std/complexobject.py
@@ -14,7 +14,7 @@
"""This is a reimplementation of the CPython "PyComplexObject"
"""
from pypy.objspace.std.complextype import complex_typedef as typedef
- _immutable_ = True
+ _immutable_fields_ = ['realval', 'imagval']
def __init__(w_self, realval=0.0, imgval=0.0):
w_self.realval = float(realval)
diff --git a/pypy/objspace/std/smalllongobject.py b/pypy/objspace/std/smalllongobject.py
--- a/pypy/objspace/std/smalllongobject.py
+++ b/pypy/objspace/std/smalllongobject.py
@@ -19,7 +19,7 @@
class W_SmallLongObject(W_Object):
from pypy.objspace.std.longtype import long_typedef as typedef
- _immutable_ = True
+ _immutable_fields_ = ['longlong']
def __init__(w_self, value):
assert isinstance(value, r_longlong)
diff --git a/pypy/objspace/std/ropeunicodeobject.py b/pypy/objspace/std/ropeunicodeobject.py
--- a/pypy/objspace/std/ropeunicodeobject.py
+++ b/pypy/objspace/std/ropeunicodeobject.py
@@ -78,7 +78,7 @@
class W_RopeUnicodeObject(W_Object):
from pypy.objspace.std.unicodetype import unicode_typedef as typedef
- _immutable_ = True
+ _immutable_fields_ = ['_node']
def __init__(w_self, node):
w_self._node = node
diff --git a/pypy/objspace/std/longobject.py b/pypy/objspace/std/longobject.py
--- a/pypy/objspace/std/longobject.py
+++ b/pypy/objspace/std/longobject.py
@@ -11,7 +11,7 @@
class W_LongObject(W_Object):
"""This is a wrapper of rbigint."""
from pypy.objspace.std.longtype import long_typedef as typedef
- _immutable_ = True
+ _immutable_fields_ = ['num']
def __init__(w_self, l):
w_self.num = l # instance of rbigint
diff --git a/pypy/rpython/rclass.py b/pypy/rpython/rclass.py
--- a/pypy/rpython/rclass.py
+++ b/pypy/rpython/rclass.py
@@ -158,7 +158,13 @@
pass
def _check_for_immutable_hints(self, hints):
- if self.classdef.classdesc.lookup('_immutable_') is not None:
+ loc = self.classdef.classdesc.lookup('_immutable_')
+ if loc is not None:
+ if loc is not self.classdef.classdesc:
+ raise ImmutableConflictError(
+ "class %r inherits from its parent _immutable_=True, "
+ "so it should also declare _immutable_=True" % (
+ self.classdef,))
hints = hints.copy()
hints['immutable'] = True
self.immutable_field_list = [] # unless overwritten below
diff --git a/pypy/objspace/std/ropeobject.py b/pypy/objspace/std/ropeobject.py
--- a/pypy/objspace/std/ropeobject.py
+++ b/pypy/objspace/std/ropeobject.py
@@ -21,7 +21,7 @@
class W_RopeObject(W_Object):
from pypy.objspace.std.stringtype import str_typedef as typedef
- _immutable_ = True
+ _immutable_fields_ = ['_node']
def __init__(w_self, node):
if not we_are_translated():
diff --git a/pypy/objspace/std/stringobject.py b/pypy/objspace/std/stringobject.py
--- a/pypy/objspace/std/stringobject.py
+++ b/pypy/objspace/std/stringobject.py
@@ -21,7 +21,7 @@
class W_StringObject(W_Object):
from pypy.objspace.std.stringtype import str_typedef as typedef
- _immutable_ = True
+ _immutable_fields_ = ['_value']
def __init__(w_self, str):
w_self._value = str
diff --git a/pypy/rpython/test/test_rclass.py b/pypy/rpython/test/test_rclass.py
--- a/pypy/rpython/test/test_rclass.py
+++ b/pypy/rpython/test/test_rclass.py
@@ -853,17 +853,17 @@
accessor.fields == {"ov" : ""} # for ootype
def test_immutable_subclass_1(self):
+ from pypy.rpython.rclass import ImmutableConflictError
from pypy.jit.metainterp.typesystem import deref
class A(object):
_immutable_ = True
class B(A):
pass
def f():
+ A()
B().v = 123
return B()
- t, typer, graph = self.gengraph(f, [])
- B_TYPE = deref(graph.getreturnvar().concretetype)
- assert B_TYPE._hints["immutable"] # inherited from A
+ py.test.raises(ImmutableConflictError, self.gengraph, f, [])
def test_immutable_subclass_2(self):
from pypy.jit.metainterp.typesystem import deref
@@ -872,6 +872,7 @@
class B(A):
_immutable_ = True
def f():
+ A()
B().v = 123
return B()
t, typer, graph = self.gengraph(f, [])
diff --git a/pypy/objspace/std/floatobject.py b/pypy/objspace/std/floatobject.py
--- a/pypy/objspace/std/floatobject.py
+++ b/pypy/objspace/std/floatobject.py
@@ -25,7 +25,7 @@
it is assumed that the constructor takes a real Python float as
an argument"""
from pypy.objspace.std.floattype import float_typedef as typedef
- _immutable_ = True
+ _immutable_fields_ = ['floatval']
def __init__(w_self, floatval):
w_self.floatval = floatval
diff --git a/pypy/objspace/std/sliceobject.py b/pypy/objspace/std/sliceobject.py
--- a/pypy/objspace/std/sliceobject.py
+++ b/pypy/objspace/std/sliceobject.py
@@ -8,7 +8,7 @@
class W_SliceObject(W_Object):
from pypy.objspace.std.slicetype import slice_typedef as typedef
- _immutable_ = True
+ _immutable_fields_ = ['w_start', 'w_stop', 'w_step']
def __init__(w_self, w_start, w_stop, w_step):
assert w_start is not None
More information about the Pypy-commit
mailing list