[pypy-svn] r69173 - in pypy/branch/faster-raise/pypy: interpreter interpreter/test module/__builtin__
fijal at codespeak.net
fijal at codespeak.net
Wed Nov 11 15:39:36 CET 2009
Author: fijal
Date: Wed Nov 11 15:39:36 2009
New Revision: 69173
Modified:
pypy/branch/faster-raise/pypy/interpreter/baseobjspace.py
pypy/branch/faster-raise/pypy/interpreter/error.py
pypy/branch/faster-raise/pypy/interpreter/test/test_raise.py
pypy/branch/faster-raise/pypy/module/__builtin__/__init__.py
pypy/branch/faster-raise/pypy/module/__builtin__/abstractinst.py
Log:
(arigo, fijal)
Implement helpers for checking types valid for exeptions.
Change a world a bit.
Modified: pypy/branch/faster-raise/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/branch/faster-raise/pypy/interpreter/baseobjspace.py (original)
+++ pypy/branch/faster-raise/pypy/interpreter/baseobjspace.py Wed Nov 11 15:39:36 2009
@@ -802,34 +802,44 @@
w_objtype = self.type(w_obj)
return self.issubtype(w_objtype, w_type)
+ # The code below only works
+ # for the simple case (new-style instance).
+ # These methods are patched with the full logic by the __builtin__
+ # module when it is loaded
+
def abstract_issubclass_w(self, w_cls1, w_cls2):
- # Equivalent to 'issubclass(cls1, cls2)'. The code below only works
- # for the simple case (new-style class, new-style class).
- # This method is patched with the full logic by the __builtin__
- # module when it is loaded.
+ # Equivalent to 'issubclass(cls1, cls2)'.
return self.is_true(self.issubtype(w_cls1, w_cls2))
def abstract_isinstance_w(self, w_obj, w_cls):
- # Equivalent to 'isinstance(obj, cls)'. The code below only works
- # for the simple case (new-style instance, new-style class).
- # This method is patched with the full logic by the __builtin__
- # module when it is loaded.
+ # Equivalent to 'isinstance(obj, cls)'.
return self.is_true(self.isinstance(w_obj, w_cls))
def abstract_isclass_w(self, w_obj):
- # Equivalent to 'isinstance(obj, type)'. The code below only works
- # for the simple case (new-style instance without special stuff).
- # This method is patched with the full logic by the __builtin__
- # module when it is loaded.
+ # Equivalent to 'isinstance(obj, type)'.
return self.is_true(self.isinstance(w_obj, self.w_type))
def abstract_getclass(self, w_obj):
- # Equivalent to 'obj.__class__'. The code below only works
- # for the simple case (new-style instance without special stuff).
- # This method is patched with the full logic by the __builtin__
- # module when it is loaded.
+ # Equivalent to 'obj.__class__'.
+ return self.type(w_obj)
+
+ # CPython rules allows old style classes or subclasses
+ # of BaseExceptions to be exceptions.
+ # This is slightly less general than the case above, so we prefix
+ # it with exception_
+
+ def exception_is_valid_class_w(self, w_obj):
+ return (self.is_true(self.isinstance(w_obj, self.w_type)) and
+ self.is_true(self.issubtype(w_obj, self.w_BaseException)))
+
+ def exception_getclass(self, w_obj):
return self.type(w_obj)
+ def exception_issubclass_w(self, w_cls1, w_cls2):
+ return self.is_true(self.issubtype(w_cls1, w_cls2))
+
+ # end of special support code
+
def eval(self, expression, w_globals, w_locals, hidden_applevel=False):
"NOT_RPYTHON: For internal debugging."
import types
Modified: pypy/branch/faster-raise/pypy/interpreter/error.py
==============================================================================
--- pypy/branch/faster-raise/pypy/interpreter/error.py (original)
+++ pypy/branch/faster-raise/pypy/interpreter/error.py Wed Nov 11 15:39:36 2009
@@ -177,16 +177,15 @@
while space.is_true(space.isinstance(w_type, space.w_tuple)):
w_type = space.getitem(w_type, space.wrap(0))
- if (space.abstract_isclass_w(w_type) and
- is_valid_exception_class(space, w_type)):
+ if space.exception_is_valid_class_w(w_type):
# this is for all cases of the form (Class, something)
if space.is_w(w_value, space.w_None):
# raise Type: we assume we have to instantiate Type
w_value = space.call_function(w_type)
- w_type = space.abstract_getclass(w_value)
+ w_type = space.exception_getclass(w_value)
else:
- w_valuetype = space.abstract_getclass(w_value)
- if space.abstract_issubclass_w(w_valuetype, w_type):
+ w_valuetype = space.exception_getclass(w_value)
+ if space.exception_issubclass_w(w_valuetype, w_type):
# raise Type, Instance: let etype be the exact type of value
w_type = w_valuetype
else:
@@ -198,7 +197,7 @@
else:
# raise Type, X: assume X is the constructor argument
w_value = space.call_function(w_type, w_value)
- w_type = space.abstract_getclass(w_value)
+ w_type = space.exception_getclass(w_value)
elif space.full_exceptions and space.is_w(space.type(w_type),
space.w_str):
@@ -208,8 +207,8 @@
else:
# the only case left here is (inst, None), from a 'raise inst'.
w_inst = w_type
- w_instclass = space.abstract_getclass(w_inst)
- if not is_valid_exception_class(space, w_instclass):
+ w_instclass = space.exception_getclass(w_inst)
+ if not space.exception_is_valid_class_w(w_instclass):
instclassname = w_instclass.getname(space, '?')
msg = ("exceptions must be classes, or instances,"
"or strings (deprecated) not %s" % (instclassname,))
@@ -240,23 +239,6 @@
except OperationError:
pass # ignored
-
-def is_valid_exception_class(space, w_type):
- """Assuming that 'w_type' is a new-style or old-style class, is it
- correct to use it as the class of an exception? The answer is no
- if it is a new-style class that doesn't inherit from BaseException.
- """
- if not space.full_exceptions:
- return True # always, for the flow space
- try:
- return space.is_true(
- space.issubtype(w_type, space.w_BaseException))
- except OperationError, e:
- if not e.match(space, space.w_TypeError):
- raise
- return True # assuming w_type is an old-style class
-
-
# Utilities
from pypy.tool.ansi_print import ansi_print
Modified: pypy/branch/faster-raise/pypy/interpreter/test/test_raise.py
==============================================================================
--- pypy/branch/faster-raise/pypy/interpreter/test/test_raise.py (original)
+++ pypy/branch/faster-raise/pypy/interpreter/test/test_raise.py Wed Nov 11 15:39:36 2009
@@ -244,3 +244,14 @@
assert 0
except KeyError:
pass
+
+ def test_obscure_bases(self):
+ # this test checks bug-to-bug cpython compatibility
+ e = ValueError()
+ e.__bases__ = (5,)
+ try:
+ raise e
+ except ValueError:
+ pass
+
+
Modified: pypy/branch/faster-raise/pypy/module/__builtin__/__init__.py
==============================================================================
--- pypy/branch/faster-raise/pypy/module/__builtin__/__init__.py (original)
+++ pypy/branch/faster-raise/pypy/module/__builtin__/__init__.py Wed Nov 11 15:39:36 2009
@@ -148,6 +148,9 @@
space.abstract_issubclass_w = ab.abstract_issubclass_w.__get__(space)
space.abstract_isclass_w = ab.abstract_isclass_w.__get__(space)
space.abstract_getclass = ab.abstract_getclass.__get__(space)
+ space.exception_is_valid_class_w = ab.exception_is_valid_class_w.__get__(space)
+ space.exception_getclass = ab.exception_getclass.__get__(space)
+ space.exception_issubclass_w = ab.exception_issubclass_w.__get__(space)
def startup(self, space):
# install zipimport hook if --withmod-zipimport is used
Modified: pypy/branch/faster-raise/pypy/module/__builtin__/abstractinst.py
==============================================================================
--- pypy/branch/faster-raise/pypy/module/__builtin__/abstractinst.py (original)
+++ pypy/branch/faster-raise/pypy/module/__builtin__/abstractinst.py Wed Nov 11 15:39:36 2009
@@ -11,6 +11,7 @@
from pypy.interpreter.error import OperationError
from pypy.module.__builtin__.interp_classobj import W_ClassObject
from pypy.module.__builtin__.interp_classobj import W_InstanceObject
+from pypy.interpreter.baseobjspace import ObjSpace as BaseObjSpace
def _get_bases(space, w_cls):
"""Returns 'cls.__bases__'. Returns None if there is
@@ -152,6 +153,31 @@
" or tuple of classes and types")
return _issubclass_recurse(space, w_derived, w_klass_or_tuple)
+# ------------------------------------------------------------
+# Exception helpers
+
+def exception_is_valid_class_w(space, w_obj):
+ obj = space.interpclass_w(w_obj)
+ if isinstance(obj, W_ClassObject):
+ return True
+ return BaseObjSpace.exception_is_valid_class_w(space, w_obj)
+
+def exception_getclass(space, w_obj):
+ obj = space.interpclass_w(w_obj)
+ if isinstance(obj, W_InstanceObject):
+ return obj.w_class
+ return BaseObjSpace.exception_getclass(space, w_obj)
+
+def exception_issubclass_w(space, w_cls1, w_cls2):
+ cls1 = space.interpclass_w(w_cls1)
+ cls2 = space.interpclass_w(w_cls2)
+ if isinstance(cls1, W_ClassObject):
+ if isinstance(cls2, W_ClassObject):
+ return cls1.is_subclass_of(cls2)
+ return False
+ if isinstance(cls2, W_ClassObject):
+ return False
+ return BaseObjSpace.exception_issubclass_w(space, w_cls1, w_cls2)
# ____________________________________________________________
# App-level interface
More information about the Pypy-commit
mailing list