[pypy-svn] r69554 - in pypy/trunk/pypy: annotation doc doc/config interpreter interpreter/pyparser interpreter/test lib lib/app_test module/__builtin__ module/_file module/exceptions module/exceptions/test module/pypyjit module/pypyjit/test objspace/std objspace/std/test rlib tool
arigo at codespeak.net
arigo at codespeak.net
Mon Nov 23 16:42:02 CET 2009
Author: arigo
Date: Mon Nov 23 16:42:00 2009
New Revision: 69554
Added:
pypy/trunk/pypy/doc/config/objspace.usemodules.exceptions.txt
- copied unchanged from r69545, pypy/branch/faster-raise-2/pypy/doc/config/objspace.usemodules.exceptions.txt
pypy/trunk/pypy/module/exceptions/ (props changed)
- copied from r69545, pypy/branch/faster-raise-2/pypy/module/exceptions/
Removed:
pypy/trunk/pypy/lib/_exceptions.py
pypy/trunk/pypy/tool/_enum_exceptions_broken.py
Modified:
pypy/trunk/pypy/annotation/description.py
pypy/trunk/pypy/doc/geninterp.txt
pypy/trunk/pypy/interpreter/baseobjspace.py
pypy/trunk/pypy/interpreter/error.py
pypy/trunk/pypy/interpreter/pyframe.py
pypy/trunk/pypy/interpreter/pyopcode.py
pypy/trunk/pypy/interpreter/pyparser/error.py
pypy/trunk/pypy/interpreter/pytraceback.py
pypy/trunk/pypy/interpreter/test/test_module.py
pypy/trunk/pypy/interpreter/test/test_pyframe.py
pypy/trunk/pypy/interpreter/test/test_raise.py
pypy/trunk/pypy/interpreter/typedef.py
pypy/trunk/pypy/lib/app_test/test_exception_extra.py
pypy/trunk/pypy/module/__builtin__/__init__.py
pypy/trunk/pypy/module/__builtin__/abstractinst.py
pypy/trunk/pypy/module/_file/interp_file.py
pypy/trunk/pypy/module/exceptions/test/ (props changed)
pypy/trunk/pypy/module/pypyjit/interp_jit.py
pypy/trunk/pypy/module/pypyjit/policy.py
pypy/trunk/pypy/module/pypyjit/test/test_policy.py
pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py
pypy/trunk/pypy/objspace/std/objspace.py
pypy/trunk/pypy/objspace/std/stdtypedef.py
pypy/trunk/pypy/objspace/std/test/test_proxy_internals.py
pypy/trunk/pypy/objspace/std/transparent.py
pypy/trunk/pypy/objspace/std/typeobject.py
pypy/trunk/pypy/rlib/rwin32.py
pypy/trunk/pypy/tool/sourcetools.py
Log:
Merge the branch/faster-raise-2:
* move exceptions to interp-level.
* add helpers space.exception_getclass() & co.
* other similar small fixes all over the place.
Modified: pypy/trunk/pypy/annotation/description.py
==============================================================================
--- pypy/trunk/pypy/annotation/description.py (original)
+++ pypy/trunk/pypy/annotation/description.py Mon Nov 23 16:42:00 2009
@@ -453,7 +453,7 @@
# is of type FunctionType. But bookkeeper.immutablevalue()
# will do the right thing in s_get_value().
- if type(value) is MemberDescriptorType:
+ if type(value) in MemberDescriptorTypes:
# skip __slots__, showing up in the class as 'member' objects
return
if name == '__init__' and self.is_builtin_exception_class():
@@ -896,5 +896,9 @@
class Sample(object):
__slots__ = 'x'
-MemberDescriptorType = type(Sample.x)
+MemberDescriptorTypes = [type(Sample.x)]
del Sample
+try:
+ MemberDescriptorTypes.append(type(OSError.errno))
+except AttributeError: # on CPython <= 2.4
+ pass
Modified: pypy/trunk/pypy/doc/geninterp.txt
==============================================================================
--- pypy/trunk/pypy/doc/geninterp.txt (original)
+++ pypy/trunk/pypy/doc/geninterp.txt Mon Nov 23 16:42:00 2009
@@ -18,20 +18,15 @@
any longer to execute this code.
.. _`application-level`: coding-guide.html#app-preferable
-.. _exceptions: ../../pypy/lib/_exceptions.py
-An example is exceptions_. They are
-needed in a very early phase of bootstrapping StdObjspace, but
-for simplicity, they are written as RPythonic application
-level code. This implies that the interpreter must be quite
-completely initialized to execute this code, which is
-impossible in the early phase, where we have neither
-exceptions implemented nor classes available.
+Bootstrap issue
++++++++++++++++
-Solution
-++++++++
+One issue we had so far was of bootstrapping: some pieces of the
+interpreter (e.g. exceptions) were written in geninterped code.
+It is unclear how much of it is left, thought.
-This bootstrap issue is solved by invoking a new bytecode interpreter
+That bootstrap issue is (was?) solved by invoking a new bytecode interpreter
which runs on FlowObjspace. FlowObjspace is complete without
complicated initialization. It is able to do abstract interpretation
of any Rpythonic code, without actually implementing anything. It just
@@ -176,10 +171,8 @@
Interplevel Snippets in the Sources
+++++++++++++++++++++++++++++++++++
-.. _`_exceptions.py`: ../../pypy/lib/_exceptions.py
-
Code written in application space can consist of complete files
-to be translated (e.g. `_exceptions.py`_), or they
+to be translated, or they
can be tiny snippets scattered all over a source file, similar
to our example from above.
Modified: pypy/trunk/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/trunk/pypy/interpreter/baseobjspace.py (original)
+++ pypy/trunk/pypy/interpreter/baseobjspace.py Mon Nov 23 16:42:00 2009
@@ -9,7 +9,7 @@
from pypy.rlib.objectmodel import we_are_translated
from pypy.rlib.debug import make_sure_not_resized
from pypy.rlib.timer import DummyTimer, Timer
-from pypy.rlib.jit import we_are_jitted, dont_look_inside
+from pypy.rlib.jit import we_are_jitted, dont_look_inside, unroll_safe
import os, sys
__all__ = ['ObjSpace', 'OperationError', 'Wrappable', 'W_Root']
@@ -389,12 +389,19 @@
def make_builtins(self):
"NOT_RPYTHON: only for initializing the space."
+ from pypy.module.exceptions import Module
+ w_name_exceptions = self.wrap('exceptions')
+ self.exceptions_module = Module(self, w_name_exceptions)
+
from pypy.module.sys import Module
w_name = self.wrap('sys')
self.sys = Module(self, w_name)
w_modules = self.sys.get('modules')
self.setitem(w_modules, w_name, self.wrap(self.sys))
+ self.setitem(w_modules, w_name_exceptions,
+ self.wrap(self.exceptions_module))
+
from pypy.module.__builtin__ import Module
w_name = self.wrap('__builtin__')
self.builtin = Module(self, w_name)
@@ -405,6 +412,8 @@
bootstrap_modules = ['sys', '__builtin__', 'exceptions']
installed_builtin_modules = bootstrap_modules[:]
+ self.export_builtin_exceptions()
+
# initialize with "bootstrap types" from objspace (e.g. w_None)
for name, value in self.__dict__.items():
if name.startswith('w_') and not name.endswith('Type'):
@@ -430,6 +439,18 @@
self.setitem(self.sys.w_dict, self.wrap('builtin_module_names'),
w_builtin_module_names)
+ def export_builtin_exceptions(self):
+ """NOT_RPYTHON"""
+ w_dic = self.exceptions_module.getdict()
+ names_w = self.unpackiterable(self.call_function(self.getattr(w_dic, self.wrap("keys"))))
+
+ for w_name in names_w:
+ name = self.str_w(w_name)
+ if not name.startswith('__'):
+ excname = name
+ w_exc = self.getitem(w_dic, w_name)
+ setattr(self, "w_"+excname, w_exc)
+
def install_mixedmodule(self, mixedname, installed_builtin_modules):
"""NOT_RPYTHON"""
modname = self.setbuiltinmodule(mixedname)
@@ -679,12 +700,19 @@
"""
return self.unpackiterable(w_iterable, expected_length)
+ @unroll_safe
def exception_match(self, w_exc_type, w_check_class):
"""Checks if the given exception type matches 'w_check_class'."""
if self.is_w(w_exc_type, w_check_class):
return True # fast path (also here to handle string exceptions)
try:
- return self.abstract_issubclass_w(w_exc_type, w_check_class)
+ if self.is_true(self.isinstance(w_check_class, self.w_tuple)):
+ for w_t in self.fixedview(w_check_class):
+ if self.exception_match(w_exc_type, w_t):
+ return True
+ else:
+ return False
+ return self.exception_issubclass_w(w_exc_type, w_check_class)
except OperationError, e:
if e.match(self, self.w_TypeError): # string exceptions maybe
return False
@@ -806,34 +834,52 @@
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_obj_as_class_w(self, w_obj):
+ if not self.is_true(self.isinstance(w_obj, self.w_type)):
+ return False
+ if not self.full_exceptions:
+ return True
+ return self.is_true(self.issubtype(w_obj, self.w_BaseException))
+
+ def exception_is_valid_class_w(self, w_cls):
+ if not self.full_exceptions:
+ return True
+ return self.is_true(self.issubtype(w_cls, 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
@@ -991,6 +1037,21 @@
buffer = self.buffer_w(w_obj)
return buffer.as_str()
+ def realstr_w(self, w_obj):
+ # Like str_w, but only works if w_obj is really of type 'str'.
+ if not self.is_true(self.isinstance(w_obj, self.w_str)):
+ raise OperationError(self.w_TypeError,
+ self.wrap('argument must be a string'))
+ return self.str_w(w_obj)
+
+ def realunicode_w(self, w_obj):
+ # Like unicode_w, but only works if w_obj is really of type
+ # 'unicode'.
+ if not self.is_true(self.isinstance(w_obj, self.w_unicode)):
+ raise OperationError(self.w_TypeError,
+ self.wrap('argument must be a unicode'))
+ return self.unicode_w(w_obj)
+
def bool_w(self, w_obj):
# Unwraps a bool, also accepting an int for compatibility.
# This is here mostly just for gateway.int_unwrapping_space_method().
Modified: pypy/trunk/pypy/interpreter/error.py
==============================================================================
--- pypy/trunk/pypy/interpreter/error.py (original)
+++ pypy/trunk/pypy/interpreter/error.py Mon Nov 23 16:42:00 2009
@@ -73,13 +73,6 @@
else:
return '%s: %s' % (exc_typename, exc_value)
- def getframe(self):
- "The frame this exception was raised in, or None."
- if self.application_traceback:
- return self.application_traceback.frame
- else:
- return None
-
def record_interpreter_traceback(self):
"""Records the current traceback inside the interpreter.
This traceback is only useful to debug the interpreter, not the
@@ -102,7 +95,7 @@
print >> file, "Traceback (application-level):"
while tb is not None:
co = tb.frame.pycode
- lineno = tb.lineno
+ lineno = tb.get_lineno()
fname = co.co_filename
if fname.startswith('<inline>\n'):
lines = fname.split('\n')
@@ -177,16 +170,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_obj_as_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 +190,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 +200,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 +232,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/trunk/pypy/interpreter/pyframe.py
==============================================================================
--- pypy/trunk/pypy/interpreter/pyframe.py (original)
+++ pypy/trunk/pypy/interpreter/pyframe.py Mon Nov 23 16:42:00 2009
@@ -56,7 +56,6 @@
self.valuestack_w = [None] * code.co_stacksize
self.valuestackdepth = 0
self.lastblock = None
- self.blockcount = 0
if space.config.objspace.honor__builtins__:
self.builtin = space.builtin.pick_builtin(w_globals)
# regular functions always have CO_OPTIMIZED and CO_NEWLOCALS.
@@ -70,31 +69,29 @@
def append_block(self, block):
block.previous = self.lastblock
self.lastblock = block
- self.blockcount += 1
def pop_block(self):
block = self.lastblock
self.lastblock = block.previous
- self.blockcount -= 1
return block
+ def blockstack_non_empty(self):
+ return self.lastblock is not None
+
def get_blocklist(self):
"""Returns a list containing all the blocks in the frame"""
- lst = [None] * self.blockcount
+ lst = []
block = self.lastblock
- i = 0
while block is not None:
- lst[i] = block
- i += 1
+ lst.append(block)
block = block.previous
return lst
def set_blocklist(self, lst):
self.lastblock = None
- self.blockcount = 0
- i = len(lst)
- while i > 0:
- block = lst[i-1]
+ i = len(lst) - 1
+ while i >= 0:
+ block = lst[i]
i -= 1
self.append_block(block)
@@ -162,9 +159,6 @@
raise
if not we_are_jitted():
executioncontext.return_trace(self, w_exitvalue)
- # on exit, we try to release self.last_exception -- breaks an
- # obvious reference cycle, so it helps refcounting implementations
- self.last_exception = None
finally:
executioncontext.leave(self)
return w_exitvalue
@@ -464,7 +458,7 @@
if self.w_f_trace is None:
raise OperationError(space.w_ValueError,
- space.wrap("f_lineo can only be set by a trace function."))
+ space.wrap("f_lineno can only be set by a trace function."))
if new_lineno < self.pycode.co_firstlineno:
raise OperationError(space.w_ValueError,
@@ -559,7 +553,11 @@
else:
addr += 1
- f_iblock = self.blockcount
+ f_iblock = 0
+ block = self.lastblock
+ while block:
+ f_iblock += 1
+ block = block.previous
min_iblock = f_iblock + min_delta_iblock
if new_lasti > self.last_instr:
new_iblock = f_iblock + delta_iblock
Modified: pypy/trunk/pypy/interpreter/pyopcode.py
==============================================================================
--- pypy/trunk/pypy/interpreter/pyopcode.py (original)
+++ pypy/trunk/pypy/interpreter/pyopcode.py Mon Nov 23 16:42:00 2009
@@ -274,11 +274,8 @@
@jit.unroll_safe
def unrollstack(self, unroller_kind):
- n = self.blockcount
- n = jit.hint(n, promote=True)
- while n > 0:
+ while self.blockstack_non_empty():
block = self.pop_block()
- n -= 1
if (block.handling_mask & unroller_kind) != 0:
return block
block.cleanupstack(self)
Modified: pypy/trunk/pypy/interpreter/pyparser/error.py
==============================================================================
--- pypy/trunk/pypy/interpreter/pyparser/error.py (original)
+++ pypy/trunk/pypy/interpreter/pyparser/error.py Mon Nov 23 16:42:00 2009
@@ -8,7 +8,6 @@
self.offset = offset
self.text = text
self.filename = filename
- self.print_file_and_line = False
def wrap_info(self, space):
return space.newtuple([space.wrap(self.msg),
Modified: pypy/trunk/pypy/interpreter/pytraceback.py
==============================================================================
--- pypy/trunk/pypy/interpreter/pytraceback.py (original)
+++ pypy/trunk/pypy/interpreter/pytraceback.py Mon Nov 23 16:42:00 2009
@@ -5,20 +5,25 @@
class PyTraceback(baseobjspace.Wrappable):
"""Traceback object
- Public fields:
+ Public app-level fields:
* 'tb_frame'
* 'tb_lasti'
* 'tb_lineno'
* 'tb_next'
"""
- def __init__(self, space, frame, lasti, lineno, next):
+ def __init__(self, space, frame, lasti, next):
self.space = space
self.frame = frame
self.lasti = lasti
- self.lineno = lineno
self.next = next
+ def get_lineno(self):
+ return offset2lineno(self.frame.pycode, self.lasti)
+
+ def descr_tb_lineno(space, self):
+ return space.wrap(self.get_lineno())
+
def descr__reduce__(self, space):
from pypy.interpreter.mixedmodule import MixedModule
w_mod = space.getbuiltinmodule('_pickle_support')
@@ -30,7 +35,6 @@
tup_state = [
w(self.frame),
w(self.lasti),
- w(self.lineno),
w(self.next),
]
nt = space.newtuple
@@ -39,19 +43,17 @@
def descr__setstate__(self, space, w_args):
from pypy.interpreter.pyframe import PyFrame
args_w = space.unpackiterable(w_args)
- w_frame, w_lasti, w_lineno, w_next = args_w
+ w_frame, w_lasti, w_next = args_w
self.frame = space.interp_w(PyFrame, w_frame)
self.lasti = space.int_w(w_lasti)
- self.lineno = space.int_w(w_lineno)
self.next = space.interp_w(PyTraceback, w_next, can_be_None=True)
def record_application_traceback(space, operror, frame, last_instruction):
frame.force_f_back()
if frame.pycode.hidden_applevel:
return
- lineno = offset2lineno(frame.pycode, last_instruction)
tb = operror.application_traceback
- tb = PyTraceback(space, frame, last_instruction, lineno, tb)
+ tb = PyTraceback(space, frame, last_instruction, tb)
operror.application_traceback = tb
def offset2lineno(c, stopat):
Modified: pypy/trunk/pypy/interpreter/test/test_module.py
==============================================================================
--- pypy/trunk/pypy/interpreter/test/test_module.py (original)
+++ pypy/trunk/pypy/interpreter/test/test_module.py Mon Nov 23 16:42:00 2009
@@ -54,13 +54,13 @@
r = repr(sys)
assert r == "<module 'sys' (built-in)>"
- import _exceptions # known to be in pypy/lib
- r = repr(_exceptions)
- assert r.startswith("<module '_exceptions' from ") and \
- 'pypy/lib/_exceptions.py' in r and \
+ import _pypy_interact # known to be in pypy/lib
+ r = repr(_pypy_interact)
+ assert r.startswith("<module '_pypy_interact' from ") and \
+ 'pypy/lib/_pypy_interact.py' in r and \
r.endswith('>')
- nofile = type(_exceptions)('nofile', 'foo')
+ nofile = type(_pypy_interact)('nofile', 'foo')
assert repr(nofile) == "<module 'nofile' from ?>"
- m = type(_exceptions).__new__(type(_exceptions))
+ m = type(_pypy_interact).__new__(type(_pypy_interact))
assert repr(m).startswith("<module '?'")
Modified: pypy/trunk/pypy/interpreter/test/test_pyframe.py
==============================================================================
--- pypy/trunk/pypy/interpreter/test/test_pyframe.py (original)
+++ pypy/trunk/pypy/interpreter/test/test_pyframe.py Mon Nov 23 16:42:00 2009
@@ -42,6 +42,25 @@
origin = g.func_code.co_firstlineno
assert g() == [origin+3, origin+4, origin+5]
+ def test_f_lineno_set(self):
+ def tracer(f, *args):
+ def x(f, *args):
+ if f.f_lineno == origin + 1:
+ f.f_lineno = origin + 2
+ return x
+
+ def function():
+ xyz
+ return 3
+
+ def g():
+ import sys
+ sys.settrace(tracer)
+ function()
+ sys.settrace(None)
+ origin = function.func_code.co_firstlineno
+ g() # assert did not crash
+
def test_f_back(self):
import sys
def f():
Modified: pypy/trunk/pypy/interpreter/test/test_raise.py
==============================================================================
--- pypy/trunk/pypy/interpreter/test/test_raise.py (original)
+++ pypy/trunk/pypy/interpreter/test/test_raise.py Mon Nov 23 16:42:00 2009
@@ -244,3 +244,50 @@
assert 0
except KeyError:
pass
+
+ def test_catch_tuple(self):
+ class A:
+ pass
+
+ try:
+ raise ValueError
+ except (ValueError, A):
+ pass
+ else:
+ fail("Did not raise")
+
+ try:
+ raise A()
+ except (ValueError, A):
+ pass
+ else:
+ fail("Did not raise")
+
+ def test_obscure_bases(self):
+ # this test checks bug-to-bug cpython compatibility
+ e = ValueError()
+ e.__bases__ = (5,)
+ try:
+ raise e
+ except ValueError:
+ pass
+
+ # explodes on CPython and py.test, not sure why
+
+ flag = False
+ class A(BaseException):
+ class __metaclass__(type):
+ def __getattribute__(self, name):
+ if flag and name == '__bases__':
+ fail("someone read bases attr")
+ else:
+ return type.__getattribute__(self, name)
+
+ try:
+ a = A()
+ flag = True
+ raise a
+ except 42:
+ pass
+ except A:
+ pass
Modified: pypy/trunk/pypy/interpreter/typedef.py
==============================================================================
--- pypy/trunk/pypy/interpreter/typedef.py (original)
+++ pypy/trunk/pypy/interpreter/typedef.py Mon Nov 23 16:42:00 2009
@@ -24,6 +24,7 @@
self.weakrefable |= __base.weakrefable
self.rawdict = {}
self.acceptable_as_base_class = True
+ self.applevel_subclasses_base = None
# xxx used by faking
self.fakedcpytype = None
self.add_entries(**rawdict)
@@ -561,6 +562,9 @@
def descr_set_dict(space, w_obj, w_dict):
w_obj.setdict(space, w_dict)
+def descr_del_dict(space, w_obj): # blame CPython for the existence of this one
+ w_obj.setdict(space, space.newdict())
+
def descr_get_weakref(space, w_obj):
lifeline = w_obj.getweakref()
if lifeline is None:
@@ -825,7 +829,7 @@
unwrap_spec=['self', ObjSpace, W_Root]),
tb_frame = interp_attrproperty('frame', cls=PyTraceback),
tb_lasti = interp_attrproperty('lasti', cls=PyTraceback),
- tb_lineno = interp_attrproperty('lineno', cls=PyTraceback),
+ tb_lineno = GetSetProperty(PyTraceback.descr_tb_lineno),
tb_next = interp_attrproperty('next', cls=PyTraceback),
)
PyTraceback.typedef.acceptable_as_base_class = False
Modified: pypy/trunk/pypy/lib/app_test/test_exception_extra.py
==============================================================================
--- pypy/trunk/pypy/lib/app_test/test_exception_extra.py (original)
+++ pypy/trunk/pypy/lib/app_test/test_exception_extra.py Mon Nov 23 16:42:00 2009
@@ -6,7 +6,7 @@
e = ex.EnvironmentError(1, "hello")
assert str(e) == "[Errno 1] hello"
e = ex.EnvironmentError(1, "hello", "world")
- assert str(e) == "[Errno 1] hello: world"
+ assert str(e) == "[Errno 1] hello: 'world'"
def app_test_import():
import exceptions
Modified: pypy/trunk/pypy/module/__builtin__/__init__.py
==============================================================================
--- pypy/trunk/pypy/module/__builtin__/__init__.py (original)
+++ pypy/trunk/pypy/module/__builtin__/__init__.py Mon Nov 23 16:42:00 2009
@@ -148,6 +148,10 @@
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_is_valid_obj_as_class_w = ab.exception_is_valid_obj_as_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/trunk/pypy/module/__builtin__/abstractinst.py
==============================================================================
--- pypy/trunk/pypy/module/__builtin__/abstractinst.py (original)
+++ pypy/trunk/pypy/module/__builtin__/abstractinst.py Mon Nov 23 16:42:00 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,37 @@
" or tuple of classes and types")
return _issubclass_recurse(space, w_derived, w_klass_or_tuple)
+# ------------------------------------------------------------
+# Exception helpers
+
+def exception_is_valid_obj_as_class_w(space, w_obj):
+ obj = space.interpclass_w(w_obj)
+ if isinstance(obj, W_ClassObject):
+ return True
+ return BaseObjSpace.exception_is_valid_obj_as_class_w(space, w_obj)
+
+def exception_is_valid_class_w(space, w_cls):
+ cls = space.interpclass_w(w_cls)
+ if isinstance(cls, W_ClassObject):
+ return True
+ return BaseObjSpace.exception_is_valid_class_w(space, w_cls)
+
+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
Modified: pypy/trunk/pypy/module/_file/interp_file.py
==============================================================================
--- pypy/trunk/pypy/module/_file/interp_file.py (original)
+++ pypy/trunk/pypy/module/_file/interp_file.py Mon Nov 23 16:42:00 2009
@@ -387,7 +387,8 @@
head = "closed"
else:
head = "open"
- if self.space.abstract_isinstance_w(self.w_name, self.space.w_str):
+ if self.space.is_true(self.space.isinstance(self.w_name,
+ self.space.w_str)):
info = "%s file '%s', mode '%s'" % (
head,
self.space.str_w(self.w_name),
Modified: pypy/trunk/pypy/module/pypyjit/interp_jit.py
==============================================================================
--- pypy/trunk/pypy/module/pypyjit/interp_jit.py (original)
+++ pypy/trunk/pypy/module/pypyjit/interp_jit.py Mon Nov 23 16:42:00 2009
@@ -22,6 +22,7 @@
PyFrame._virtualizable2_ = ['last_instr', 'pycode',
'valuestackdepth', 'valuestack_w[*]',
'fastlocals_w[*]', 'f_forward',
+ 'last_exception',
]
JUMP_ABSOLUTE = opmap['JUMP_ABSOLUTE']
Modified: pypy/trunk/pypy/module/pypyjit/policy.py
==============================================================================
--- pypy/trunk/pypy/module/pypyjit/policy.py (original)
+++ pypy/trunk/pypy/module/pypyjit/policy.py Mon Nov 23 16:42:00 2009
@@ -8,7 +8,7 @@
if '.' in modname:
modname, _ = modname.split('.', 1)
- if modname in ['pypyjit', 'signal', 'micronumpy', 'math']:
+ if modname in ['pypyjit', 'signal', 'micronumpy', 'math', 'exceptions']:
return True
return False
Modified: pypy/trunk/pypy/module/pypyjit/test/test_policy.py
==============================================================================
--- pypy/trunk/pypy/module/pypyjit/test/test_policy.py (original)
+++ pypy/trunk/pypy/module/pypyjit/test/test_policy.py Mon Nov 23 16:42:00 2009
@@ -30,6 +30,7 @@
assert not pypypolicy.look_inside_pypy_module('posix.interp_expat')
assert pypypolicy.look_inside_pypy_module('__builtin__.operation')
assert pypypolicy.look_inside_pypy_module('__builtin__.abstractinst')
+ assert pypypolicy.look_inside_pypy_module('exceptions.interp_exceptions')
for modname in 'pypyjit', 'signal', 'micronumpy', 'math':
assert pypypolicy.look_inside_pypy_module(modname)
assert pypypolicy.look_inside_pypy_module(modname + '.foo')
Modified: pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py
==============================================================================
--- pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py (original)
+++ pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py Mon Nov 23 16:42:00 2009
@@ -373,6 +373,51 @@
assert len(bytecode.get_opnames("call")) == 1 # the call to append
assert len(bytecode.get_opnames("guard")) == 1 # guard_no_exception after the call
+ def test_exception_inside_loop_1(self):
+ py.test.skip("exceptions: in-progress")
+ self.run_source('''
+ def main(n):
+ while n:
+ try:
+ raise ValueError
+ except ValueError:
+ pass
+ n -= 1
+ return n
+ ''',
+ ([30], 0))
+
+ bytecode, = self.get_by_bytecode("SETUP_EXCEPT")
+ #assert not bytecode.get_opnames("new") -- currently, we have
+ # new_with_vtable(pypy.interpreter.pyopcode.ExceptBlock)
+ bytecode, = self.get_by_bytecode("RAISE_VARARGS")
+ assert not bytecode.get_opnames("new")
+ bytecode, = self.get_by_bytecode("COMPARE_OP")
+ assert not bytecode.get_opnames()
+
+ def test_exception_inside_loop_2(self):
+ py.test.skip("exceptions: in-progress")
+ self.run_source('''
+ def g(n):
+ raise ValueError(n)
+ def f(n):
+ g(n)
+ def main(n):
+ while n:
+ try:
+ f(n)
+ except ValueError:
+ pass
+ n -= 1
+ return n
+ ''',
+ ([30], 0))
+
+ bytecode, = self.get_by_bytecode("RAISE_VARARGS")
+ assert not bytecode.get_opnames("new")
+ bytecode, = self.get_by_bytecode("COMPARE_OP")
+ assert len(bytecode.get_opnames()) <= 2 # oois, guard_true
+
class AppTestJIT(PyPyCJITTests):
def setup_class(cls):
Modified: pypy/trunk/pypy/objspace/std/objspace.py
==============================================================================
--- pypy/trunk/pypy/objspace/std/objspace.py (original)
+++ pypy/trunk/pypy/objspace/std/objspace.py Mon Nov 23 16:42:00 2009
@@ -322,9 +322,7 @@
setattr(self, 'w_' + typedef.name, w_type)
# exceptions & builtins
- w_mod = self.setup_exceptions()
self.make_builtins()
- self.sys.setmodule(w_mod)
# the type of old-style classes
self.w_classobj = self.builtin.get('__metaclass__')
@@ -358,61 +356,6 @@
self.setattr(w___pypy__, self.wrap('get_tproxy_controller'),
self.wrap(app_proxy_controller))
- def create_builtin_module(self, pyname, publicname):
- """NOT_RPYTHON
- helper function which returns the wrapped module and its dict.
- """
- # generate on-the-fly
- class Fake: pass
- fake = Fake()
- from pypy import lib
- fname = os.path.join(os.path.split(lib.__file__)[0], pyname)
- fake.filename = fname
- fake.code = compile(file(fname).read(), fname, "exec")
- fake.modname = publicname
- w_dic = PyPyCacheDir.build_applevelinterp_dict(fake, self)
- from pypy.interpreter.module import Module
- mod = Module(self, self.wrap(publicname), w_dic)
- w_mod = self.wrap(mod)
- return w_mod, w_dic
-
- def setup_exceptions(self):
- """NOT_RPYTHON"""
- ## hacking things in
- def call(w_type, w_args):
- space = self
- # too early for unpackiterable as well :-(
- name = space.unwrap(space.getitem(w_args, space.wrap(0)))
- bases = space.fixedview(space.getitem(w_args, space.wrap(1)))
- dic = space.unwrap(space.getitem(w_args, space.wrap(2)))
- dic = dict([(key,space.wrap(value)) for (key, value) in dic.items()])
- bases = list(bases)
- if not bases:
- bases = [space.w_object]
- res = W_TypeObject(space, name, bases, dic)
- res.ready()
- return res
- try:
- # note that we hide the real call method by an instance variable!
- self.call = call
- mod, w_dic = self.create_builtin_module('_exceptions.py', 'exceptions')
-
- self.w_IndexError = self.getitem(w_dic, self.wrap("IndexError"))
- self.w_StopIteration = self.getitem(w_dic, self.wrap("StopIteration"))
- finally:
- del self.call # revert
-
- names_w = self.unpackiterable(self.call_function(self.getattr(w_dic, self.wrap("keys"))))
-
- for w_name in names_w:
- name = self.str_w(w_name)
- if not name.startswith('__'):
- excname = name
- w_exc = self.getitem(w_dic, w_name)
- setattr(self, "w_"+excname, w_exc)
-
- return mod
-
def createexecutioncontext(self):
# add space specific fields to execution context
# note that this method must not call space methods that might need an
@@ -615,16 +558,18 @@
# the purpose of the above check is to avoid the code below
# to be annotated at all for 'cls' if it is not necessary
w_subtype = w_type.check_user_subclass(w_subtype)
+ if cls.typedef.applevel_subclasses_base is not None:
+ cls = cls.typedef.applevel_subclasses_base
subcls = get_unique_interplevel_subclass(
self.config, cls, w_subtype.hasdict, w_subtype.nslots != 0,
w_subtype.needsdel, w_subtype.weakrefable)
instance = instantiate(subcls)
+ assert isinstance(instance, cls)
instance.user_setup(self, w_subtype)
else:
raise OperationError(self.w_TypeError,
self.wrap("%s.__new__(%s): only for the type %s" % (
w_type.name, w_subtype.getname(self, '?'), w_type.name)))
- assert isinstance(instance, cls)
return instance
allocate_instance._annspecialcase_ = "specialize:arg(1)"
Modified: pypy/trunk/pypy/objspace/std/stdtypedef.py
==============================================================================
--- pypy/trunk/pypy/objspace/std/stdtypedef.py (original)
+++ pypy/trunk/pypy/objspace/std/stdtypedef.py Mon Nov 23 16:42:00 2009
@@ -2,7 +2,7 @@
from pypy.interpreter.error import OperationError
from pypy.interpreter.typedef import TypeDef, GetSetProperty, Member
from pypy.interpreter.typedef import descr_get_dict, descr_set_dict
-from pypy.interpreter.typedef import no_hash_descr
+from pypy.interpreter.typedef import no_hash_descr, descr_del_dict
from pypy.interpreter.baseobjspace import SpaceCache
from pypy.objspace.std.model import StdObjSpaceMultiMethod
from pypy.objspace.std.multimethod import FailedToImplement
@@ -39,9 +39,6 @@
a = a.base
return True
-def descr_del_dict(space, w_obj): # blame CPython for the existence of this one
- w_obj.setdict(space, space.newdict())
-
std_dict_descr = GetSetProperty(descr_get_dict, descr_set_dict, descr_del_dict)
std_dict_descr.name = '__dict__'
@@ -91,8 +88,12 @@
for descrname, descrvalue in rawdict.items():
dict_w[descrname] = w(descrvalue)
+ if typedef.applevel_subclasses_base is not None:
+ overridetypedef = typedef.applevel_subclasses_base.typedef
+ else:
+ overridetypedef = typedef
w_type = W_TypeObject(space, typedef.name, bases_w, dict_w,
- overridetypedef=typedef)
+ overridetypedef=overridetypedef)
w_type.lazyloaders = lazyloaders
return w_type
Modified: pypy/trunk/pypy/objspace/std/test/test_proxy_internals.py
==============================================================================
--- pypy/trunk/pypy/objspace/std/test/test_proxy_internals.py (original)
+++ pypy/trunk/pypy/objspace/std/test/test_proxy_internals.py Mon Nov 23 16:42:00 2009
@@ -1,7 +1,8 @@
""" test proxy internals like code, traceback, frame
"""
-from pypy.conftest import gettestobjspace
+import py
+from pypy.conftest import gettestobjspace, option
class AppProxy(object):
def setup_class(cls):
@@ -21,6 +22,28 @@
return get_proxy
""")
+class AppTestProxyInterpOnly(AppProxy):
+ def setup_class(cls):
+ if option.runappdirect:
+ py.test.skip("interp only test")
+ from pypy.interpreter.typedef import TypeDef, interp2app
+ from pypy.interpreter.baseobjspace import Wrappable
+
+ class W_Stuff(Wrappable):
+ pass
+
+ def descr_new(space, w_subtype):
+ return W_Stuff()
+
+ W_Stuff.typedef = TypeDef(
+ 'Stuff',
+ __new__ = interp2app(descr_new),
+ )
+ cls.w_Stuff = cls.space.gettypefor(W_Stuff)
+
+ def test_unproxyable(self):
+ raises(TypeError, self.get_proxy, self.Stuff())
+
class AppTestProxyInternals(AppProxy):
def test_traceback_basic(self):
try:
@@ -31,7 +54,7 @@
tb = self.get_proxy(e[2])
assert tb.tb_frame is e[2].tb_frame
-
+
def test_traceback_catch(self):
try:
try:
Modified: pypy/trunk/pypy/objspace/std/transparent.py
==============================================================================
--- pypy/trunk/pypy/objspace/std/transparent.py (original)
+++ pypy/trunk/pypy/objspace/std/transparent.py Mon Nov 23 16:42:00 2009
@@ -26,7 +26,6 @@
completely controlled by the controller."""
from pypy.interpreter.typedef import Function, PyTraceback, PyFrame, \
PyCode, GeneratorIterator
-
if not space.is_true(space.callable(w_controller)):
raise OperationError(space.w_TypeError, space.wrap("controller should be function"))
@@ -49,14 +48,12 @@
return W_Transparent(space, w_type, w_controller)
else:
raise OperationError(space.w_TypeError, space.wrap("type expected as first argument"))
- try:
- w_lookup = w_type or w_type.w_besttype
- for k, v in type_cache.cache:
- if w_lookup == k:
- return v(space, w_type, w_controller)
- except KeyError:
- raise OperationError(space.w_TypeError, space.wrap("Object type %s could not "\
- "be wrapped (YET)" % w_type.getname(space, "?")))
+ w_lookup = w_type
+ for k, v in type_cache.cache:
+ if w_lookup == k:
+ return v(space, w_type, w_controller)
+ raise OperationError(space.w_TypeError, space.wrap("Object type %s could not "\
+ "be wrapped (YET)" % w_type.getname(space, "?")))
def register_proxyable(space, cls):
tpdef = cls.typedef
Modified: pypy/trunk/pypy/objspace/std/typeobject.py
==============================================================================
--- pypy/trunk/pypy/objspace/std/typeobject.py (original)
+++ pypy/trunk/pypy/objspace/std/typeobject.py Mon Nov 23 16:42:00 2009
@@ -80,7 +80,6 @@
w_self.hasdict = False
w_self.needsdel = False
w_self.weakrefable = False
- w_self.w_same_layout_as = None
w_self.weak_subclasses = []
w_self.__flags__ = 0 # or _HEAPTYPE
w_self.instancetypedef = overridetypedef
@@ -91,6 +90,7 @@
else:
setup_user_defined_type(w_self)
custom_metaclass = not space.is_w(space.type(w_self), space.w_type)
+ w_self.w_same_layout_as = get_parent_layout(w_self)
if space.config.objspace.std.withtypeversion:
if w_self.instancetypedef.hasdict or custom_metaclass:
@@ -548,7 +548,6 @@
hasoldstylebase = copy_flags_from_bases(w_self, w_bestbase)
create_all_slots(w_self, hasoldstylebase)
- w_self.w_same_layout_as = get_parent_layout(w_self)
ensure_common_attributes(w_self)
def setup_builtin_type(w_self):
Modified: pypy/trunk/pypy/rlib/rwin32.py
==============================================================================
--- pypy/trunk/pypy/rlib/rwin32.py (original)
+++ pypy/trunk/pypy/rlib/rwin32.py Mon Nov 23 16:42:00 2009
@@ -6,7 +6,7 @@
from pypy.translator.tool.cbuild import ExternalCompilationInfo
from pypy.rpython.lltypesystem import lltype, rffi
from pypy.rlib.rarithmetic import intmask
-import os, sys
+import os, sys, errno
# This module can be imported on any platform,
# but most symbols are not usable...
@@ -14,8 +14,13 @@
if WIN32:
eci = ExternalCompilationInfo(
- includes = ['windows.h'],
+ includes = ['windows.h', 'errno.h'],
libraries = ['kernel32'],
+ separate_module_sources = ["""
+ long WINAPI pypy_dosmaperr(long winerror)
+ { _dosmaperr(winerror); return errno; }
+ """],
+ export_symbols = ["pypy_dosmaperr"],
)
else:
eci = ExternalCompilationInfo()
@@ -60,7 +65,6 @@
""".split():
locals()[name] = rffi_platform.ConstantInteger(name)
-
for k, v in rffi_platform.configure(CConfig).items():
globals()[k] = v
@@ -93,6 +97,20 @@
_get_osfhandle = rffi.llexternal('_get_osfhandle', [rffi.INT], HANDLE)
+ dosmaperr = winexternal('pypy_dosmaperr', [rffi.LONG], rffi.LONG)
+
+
+ def build_winerror_to_errno():
+ """Build a dictionary mapping windows error numbers to POSIX errno.
+ The function returns the dict, and the default value for codes not
+ in the dict."""
+ default = errno.EINVAL
+ errors = {}
+ for i in range(1, 65000):
+ error = dosmaperr(i)
+ if error != default:
+ errors[i] = error
+ return errors, default
# A bit like strerror...
def FormatError(code):
Modified: pypy/trunk/pypy/tool/sourcetools.py
==============================================================================
--- pypy/trunk/pypy/tool/sourcetools.py (original)
+++ pypy/trunk/pypy/tool/sourcetools.py Mon Nov 23 16:42:00 2009
@@ -236,12 +236,13 @@
'a' <= chr(i) <= 'z' or
'A' <= chr(i) <= 'Z') and chr(i) or '_')
for i in range(256)])
+PY_IDENTIFIER_MAX = 120
def valid_identifier(stuff):
stuff = str(stuff).translate(PY_IDENTIFIER)
if not stuff or ('0' <= stuff[0] <= '9'):
stuff = '_' + stuff
- return stuff
+ return stuff[:PY_IDENTIFIER_MAX]
CO_VARARGS = 0x0004
CO_VARKEYWORDS = 0x0008
More information about the Pypy-commit
mailing list