Commit 21b75ed0 authored by Michael Arntzenius's avatar Michael Arntzenius

Add & update tests for with blocks handling exceptions

- exceptions_test: exceptions_test now succeeds, unless we're JITting.
  It fails due to a bug in llvm codegen having to do with definedness
  analysis; see comment in emitBBs in irgen.cpp.

- with_{class,functiondef}, try_{class,def}: Expose the same JIT bug
  that occurs in exceptions_test.

- try_return_finally: We used to flip an internal assert in
  compareKeyset when JITting this test, but it's fixed now.

- file_closed: Files have a `closed' attribute in Python, but not yet in
  Pyston.

- finally_except: Our CFG pass had some corner case bugs when nesting a
  try/finally inside a try/except. This checks they're fixed.

- try_continue: The CFG pass has a bug in its syntax error reporting.

- with_continue, try_continue: Checks that `with'/`try'/`finally' handle
  syntax errors properly.

- with_ctxclass_instance_attrs: Checks that we're accessing
  context-manager attributes on the context-manager's class, not the
  instance, when we run a `with'. As it turns out, our AST interpreter
  has a bug in ClsAttribute (I think) which means that we don't. Our JIT
  works ok, though.

- with_ctxclass_order_of_access: Checks that we're accessing
  context-manager attributes in the right order when we run a `with',
  which we are.

- with_file: Our `file' object runtime previously didn't support `with'
  properly. This checks that files work with `with'.
parent 4216e6a6
# expected: fail
# - with statements
# fail-if: '-n' in EXTRA_JIT_ARGS or '-O' in EXTRA_JIT_ARGS
# we have an llvm codegen bug that this file triggers when we JIT
class TestException(Exception):
pass
......@@ -361,7 +360,11 @@ def f12():
except Exception as l[0]:
print "shouldnt get here"
except Exception as e2:
print e2
# print it to stderr, so that our tester's error message substituter can
# deal with differences between error messages between different Python
# versions.
import traceback
traceback.print_exc()
l = []
try:
......
# expected: fail
import sys
print sys.stdout.closed
# these may seem pointless, but they exercise a family of corner cases in our
# CFG generation pass (cfg.cpp).
def returner():
try:
try:
print '2 + 2'
return
finally:
print 'finally'
except:
print 'exception'
returner()
def continuer():
for x in [1]:
try:
try:
print '2 + 2'
continue
finally:
print 'finally'
except:
print 'exception'
continuer()
def breaker():
for x in [1]:
try:
try:
print '2 + 2'
break
finally:
print 'finally'
except:
print 'exception'
breaker()
def raiser():
try:
try:
print '2 + 2'
raise Exception('blaaargh')
finally:
print 'finally'
except:
print 'exception'
raiser()
def alltogethernow():
for x in [1,2,3,4]:
try:
try:
print '2 + 2'
if x == 1: break
if x == 2: continue
if x == 3: raise Exception('blaargh')
if x == 4: return
finally:
print 'finally'
except:
print 'exception'
alltogethernow()
# we have one test at global scope, another at local.
# they behave differently in codegen; there have been points at which either was bugged when the other was not.
try:
class C(object):
print 'here'
finally:
print 'finally'
def f():
try:
class C(object):
print 'here'
finally:
print 'finally'
f()
try:
class D(object):
print 'here'
except:
print 'impossible'
raise
def f2():
try:
class D(object):
print 'here'
except:
print 'impossible'
raise
f2()
# expected: fail
# Syntax error to have a continue outside a loop.
def foo():
try: continue
finally: pass
def f():
try:
def foo(): return 0
except:
print 'except'
finally:
print 'finally'
f()
def f2():
try:
def foo(): return 0
except:
print 'except'
f2()
def f3():
try:
def foo(): return 0
finally:
print 'finally'
f3()
def f():
try:
# Looks like this returns from the function, but it needs to go to the finally block
return
finally:
pass
f()
def f():
# originally this exposed a bug in our irgen phase, so even `with None`
# failed here; the bug happened before actual execution. Just to test more
# things, though, we use an actual contextmanager here.
with open('/dev/null'):
class C(object):
print 'hello'
f()
# expected: fail
def f():
C = 23
try:
class C(object): pass
except:
print 'except: C = %s' % C
raise
finally:
print 'finally: C = %s' % C
print 'end: C = %s' % C
f()
# should_error
class Mgr(object):
def __enter__(self):
print 'entered!'
def __exit__(self, *args):
print 'exited!'
with Mgr() as m:
continue
# fail-if: '-n' not in EXTRA_JIT_ARGS and '-O' not in EXTRA_JIT_ARGS
# the interpreter has a bug in handling ClsAttribute. succeeds on JIT path.
class Mgr(object):
def __init__(self): self.__enter__ = 'sucks to be you'
def __enter__(self): pass
def __exit__(self, typ, val, tback): pass
with Mgr() as m:
print 'boom boom boom boom'
class Mgr2(object):
def __init__(self): self.__exit__ = 'screwed!'
def __enter__(self): pass
def __exit__(self, typ, val, tback): pass
with Mgr2() as m:
print 'bang bang bang bang'
class Mgr(object):
def __init__(self): print 'Mgr.__init__()'
@property
def __enter__(self):
print 'Mgr.__enter__ accessed'
def enterer(*args):
print 'Mgr.__enter__%r called' % (args,)
return 23
return enterer
@property
def __exit__(self):
print 'Mgr.__exit__ accessed'
def exiter(*args):
print 'Mgr.__exit__%r called' % (args,)
return False
return exiter
with Mgr() as m:
print 'hello I am a with block'
print 'm: %s' % m
try:
with Mgr() as m:
1/0
print "you can't get there from here"
except ZeroDivisionError, e:
print e
f = open('/dev/null')
try:
with f:
1/0
except ZeroDivisionError as e:
print e
try:
f.readline()
except ValueError as e:
print e
def f():
# originally this exposed a bug in our irgen phase, so even `with None`
# failed here; the bug happened before actual execution. Just to test more
# things, though, we use an actual contextmanager here.
with open('/dev/null'):
def foo():
# raises a syntaxerror
pass
f()
......@@ -111,6 +111,7 @@ def canonicalize_stderr(stderr):
("NameError: global name '", "NameError: name '"),
("AttributeError: '(\w+)' object attribute '(\w+)' is read-only", "AttributeError: \\2"),
(r"TypeError: object.__new__\(\) takes no parameters", "TypeError: object() takes no parameters"),
("IndexError: list assignment index out of range", "IndexError: list index out of range"),
]
for pattern, subst_with in substitutions:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment