[pypy-svn] r37312 - in pypy/dist/pypy: annotation annotation/test jit/timeshifter
pedronis at codespeak.net
pedronis at codespeak.net
Thu Jan 25 03:56:04 CET 2007
Author: pedronis
Date: Thu Jan 25 03:56:00 2007
New Revision: 37312
Modified:
pypy/dist/pypy/annotation/classdef.py
pypy/dist/pypy/annotation/description.py
pypy/dist/pypy/annotation/test/test_annrpython.py
pypy/dist/pypy/annotation/unaryop.py
pypy/dist/pypy/jit/timeshifter/rcontainer.py
pypy/dist/pypy/jit/timeshifter/rvalue.py
pypy/dist/pypy/jit/timeshifter/rvirtualizable.py
pypy/dist/pypy/jit/timeshifter/vdict.py
Log:
introduce _atts_ as a way to enforce attrs without the special side-effects of __slots__,
use _attrs_ instead of slots for the various jit runtime helpers. As much as possible that is using __slots__
should move to use _attrs_.
Modified: pypy/dist/pypy/annotation/classdef.py
==============================================================================
--- pypy/dist/pypy/annotation/classdef.py (original)
+++ pypy/dist/pypy/annotation/classdef.py Thu Jan 25 03:56:00 2007
@@ -72,7 +72,7 @@
self.bookkeeper = bookkeeper
self.s_value = s_ImpossibleValue
self.readonly = True
- self.slot_allowed = True
+ self.attr_allowed = True
self.read_locations = {}
def add_constant_source(self, classdef, source):
@@ -121,17 +121,17 @@
(self.name, homedef))
break
- # check for attributes forbidden by slots
- if homedef.classdesc.allslots is not None:
- if self.name not in homedef.classdesc.allslots:
- self.slot_allowed = False
+ # check for attributes forbidden by slots or _attrs_
+ if homedef.classdesc.all_enforced_attrs is not None:
+ if self.name not in homedef.classdesc.all_enforced_attrs:
+ self.attr_allowed = False
if not self.readonly:
- raise NoSuchSlotError(homedef, self.name)
+ raise NoSuchAttrError(homedef, self.name)
def modified(self, classdef='?'):
self.readonly = False
- if not self.slot_allowed:
- raise NoSuchSlotError(classdef, self.name)
+ if not self.attr_allowed:
+ raise NoSuchAttrError(classdef, self.name)
class ClassDef:
@@ -419,8 +419,8 @@
try:
v = getattr(self.obj, name)
except AttributeError:
- allslots = classdef.classdesc.allslots
- if allslots and name in allslots:
+ all_enforced_attrs = classdef.classdesc.all_enforced_attrs
+ if all_enforced_attrs and name in all_enforced_attrs:
return s_ImpossibleValue
raise
s_value = self.bookkeeper.immutablevalue(v)
@@ -439,8 +439,9 @@
result.extend(slots)
return result
-class NoSuchSlotError(Exception):
- "Raised when an attribute is found on a class where __slots__ forbits it."
+class NoSuchAttrError(Exception):
+ """Raised when an attribute is found on a class where __slots__
+ or _attrs_ forbits it."""
# ____________________________________________________________
Modified: pypy/dist/pypy/annotation/description.py
==============================================================================
--- pypy/dist/pypy/annotation/description.py (original)
+++ pypy/dist/pypy/annotation/description.py Thu Jan 25 03:56:00 2007
@@ -350,7 +350,7 @@
class ClassDesc(Desc):
knowntype = type
instance_level = False
- allslots = None # or a set
+ all_enforced_attrs = None # or a set
def __init__(self, bookkeeper, pyobj=None,
name=None, basedesc=None, classdict=None,
@@ -400,17 +400,21 @@
if base is not object:
self.basedesc = bookkeeper.getdesc(base)
- if '__slots__' in cls.__dict__:
- slots = cls.__dict__['__slots__']
- if isinstance(slots, str):
- slots = (slots,)
- slots = dict.fromkeys(slots)
+ if '__slots__' in cls.__dict__ or '_attrs_' in cls.__dict__:
+ attrs = {}
+ for decl in ('__slots__', '_attrs_'):
+ decl = cls.__dict__.get(decl, [])
+ if isinstance(decl, str):
+ decl = (decl,)
+ decl = dict.fromkeys(decl)
+ attrs.update(decl)
if self.basedesc is not None:
- if self.basedesc.allslots is None:
- raise Exception("%r has slots, but not its base class"
+ if self.basedesc.all_enforced_attrs is None:
+ raise Exception("%r has slots or _attrs_, "
+ "but not its base class"
% (pyobj,))
- slots.update(self.basedesc.allslots)
- self.allslots = slots
+ attrs.update(self.basedesc.all_enforced_attrs)
+ self.all_enforced_attrs = attrs
def add_source_attribute(self, name, value, mixin=False):
if isinstance(value, types.FunctionType):
Modified: pypy/dist/pypy/annotation/test/test_annrpython.py
==============================================================================
--- pypy/dist/pypy/annotation/test/test_annrpython.py (original)
+++ pypy/dist/pypy/annotation/test/test_annrpython.py Thu Jan 25 03:56:00 2007
@@ -2420,8 +2420,8 @@
if works:
a.build_types(fun, [int])
else:
- from pypy.annotation.classdef import NoSuchSlotError
- py.test.raises(NoSuchSlotError, a.build_types, fun, [int])
+ from pypy.annotation.classdef import NoSuchAttrError
+ py.test.raises(NoSuchAttrError, a.build_types, fun, [int])
def test_slots_enforce_attrs(self):
class Superbase(object):
@@ -2445,6 +2445,56 @@
s = a.build_types(fun, [str])
assert s == annmodel.s_ImpossibleValue # but not blocked blocks
+ def test_enforced_attrs_check(self):
+ class Base(object):
+ _attrs_ = 'x'
+ class A(Base):
+ _attrs_ = 'y'
+ def m(self):
+ return 65
+ class C(Base):
+ _attrs_ = 'z'
+ def m(self):
+ return 67
+ for attrname, works in [('x', True),
+ ('y', False),
+ ('z', False),
+ ('t', False)]:
+ def fun(n):
+ if n: o = A()
+ else: o = C()
+ setattr(o, attrname, 12)
+ return o.m()
+ a = self.RPythonAnnotator()
+ if works:
+ a.build_types(fun, [int])
+ else:
+ from pypy.annotation.classdef import NoSuchAttrError
+ py.test.raises(NoSuchAttrError, a.build_types, fun, [int])
+
+ def test_attrs_enforce_attrs(self):
+ class Superbase(object):
+ _attrs_ = 'x'
+ class Base(Superbase):
+ pass
+ class A(Base):
+ pass
+ class B(Base):
+ pass
+ def fun(s):
+ if s is None: # known not to be None in this test
+ o = B()
+ o.x = 12
+ elif len(s) > 5:
+ o = A()
+ else:
+ o = Base()
+ return o.x
+ a = self.RPythonAnnotator()
+ s = a.build_types(fun, [str])
+ assert s == annmodel.s_ImpossibleValue # but not blocked blocks
+
+
def test_pbc_enforce_attrs(self):
class F(object):
_attrs_ = ['foo',]
Modified: pypy/dist/pypy/annotation/unaryop.py
==============================================================================
--- pypy/dist/pypy/annotation/unaryop.py (original)
+++ pypy/dist/pypy/annotation/unaryop.py Thu Jan 25 03:56:00 2007
@@ -529,9 +529,9 @@
# blocking is harmless if the attribute is explicitly listed
# in the class or a parent class.
for basedef in ins.classdef.getmro():
- if basedef.classdesc.allslots is not None:
- if attr in basedef.classdesc.allslots:
- raise HarmlesslyBlocked("getattr on a slot")
+ if basedef.classdesc.all_enforced_attrs is not None:
+ if attr in basedef.classdesc.all_enforced_attrs:
+ raise HarmlesslyBlocked("get enforced attr")
return s_result
return SomeObject()
getattr.can_only_throw = []
Modified: pypy/dist/pypy/jit/timeshifter/rcontainer.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rcontainer.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rcontainer.py Thu Jan 25 03:56:00 2007
@@ -12,7 +12,7 @@
debug_pdb = lloperation.llop.debug_pdb
class AbstractContainer(object):
- __slots__ = []
+ _attrs_ = []
def op_getfield(self, jitstate, fielddesc):
raise NotImplementedError
@@ -25,11 +25,11 @@
class VirtualContainer(AbstractContainer):
- __slots__ = []
+ _attrs_ = []
class FrozenContainer(AbstractContainer):
- __slots__ = []
+ _attrs_ = []
def exactmatch(self, vstruct, outgoingvarboxes, memo):
raise NotImplementedError
@@ -44,7 +44,7 @@
VirtualStructCls = None # patched later with VirtualStruct
- __slots__ = """TYPE PTRTYPE
+ _attrs_ = """TYPE PTRTYPE
firstsubstructdesc arrayfielddesc
innermostdesc
ptrkind
@@ -59,9 +59,8 @@
gv_vrti_get_global_shape_ptr
vrti_read_forced_token
gv_vrti_read_forced_ptr
- __dict__
- """.split() # XXX remove rpython abuse of __slots__
- # use our own _attrs_ instead
+ """.split()
+
firstsubstructdesc = None
materialize = None
@@ -188,7 +187,7 @@
VirtualStructCls = None # patched later with VirtualizableStruct
- __slots__ = """redirected_fielddescs
+ _attrs_ = """redirected_fielddescs
base_desc rti_desc access_desc
gv_access
gv_access_is_null_ptr access_is_null_token
@@ -498,7 +497,7 @@
class VirtualStruct(VirtualContainer):
- __slots__ = "typedesc content_boxes ownbox".split()
+ _attrs_ = "typedesc content_boxes ownbox".split()
def __init__(self, typedesc):
self.typedesc = typedesc
Modified: pypy/dist/pypy/jit/timeshifter/rvalue.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rvalue.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rvalue.py Thu Jan 25 03:56:00 2007
@@ -32,7 +32,7 @@
pass
class RedBox(object):
- __slots__ = ['kind', 'genvar']
+ _attrs_ = ['kind', 'genvar']
def __init__(self, kind, genvar=None):
self.kind = kind
Modified: pypy/dist/pypy/jit/timeshifter/rvirtualizable.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rvirtualizable.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rvirtualizable.py Thu Jan 25 03:56:00 2007
@@ -3,7 +3,8 @@
from pypy.rpython.annlowlevel import cast_instance_to_base_ptr
class VirtualRTI(object):
- __slots__ = 'rgenop varindexes vrtis bitmask'.split()
+ _attrs_ = 'rgenop varindexes vrtis bitmask'.split()
+
def __init__(self, rgenop, bitmask):
self.rgenop = rgenop
self.varindexes = []
@@ -39,7 +40,7 @@
get_forced._annspecialcase_ = "specialize:arg(2)"
class VirtualizableRTI(VirtualRTI):
- __slots__ = "frameinfo vable_getset_rtis".split()
+ _attrs_ = "frameinfo vable_getset_rtis".split()
def get_global_shape(self):
return 0
@@ -64,7 +65,7 @@
return state
class WithForcedStateVirtualizableRTI(VirtualizableRTI):
- __slots__ = "state".split()
+ _attrs_ = "state"
def __init__(self, vablerti, state):
self.rgenop = vablerti.rgenop
Modified: pypy/dist/pypy/jit/timeshifter/vdict.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/vdict.py (original)
+++ pypy/dist/pypy/jit/timeshifter/vdict.py Thu Jan 25 03:56:00 2007
@@ -142,7 +142,7 @@
class AbstractFrozenVirtualDict(FrozenContainer):
- __slots__ = ('typedesc',)
+ _attrs_ = ('typedesc',)
def __init__(self, typedesc):
self.typedesc = typedesc
@@ -183,7 +183,7 @@
class AbstractVirtualDict(VirtualContainer):
- __slots__ = ('typedesc', 'ownbox') # and no item_boxes
+ _attrs_ = ('typedesc', 'ownbox') # and no item_boxes
FrozenVirtualDict = AbstractFrozenVirtualDict # overridden in subclasses
More information about the Pypy-commit
mailing list