Commit 400cbc3a authored by Tim Peters's avatar Tim Peters

Set EOL style to native.

parent 85b1052e
"Usage: unparse.py <path to source file>" "Usage: unparse.py <path to source file>"
import sys import sys
class Unparser: class Unparser:
"""Methods in this class recursively traverse an AST and """Methods in this class recursively traverse an AST and
output source code for the abstract syntax; original formatting output source code for the abstract syntax; original formatting
is disregarged. """ is disregarged. """
def __init__(self, tree, file = sys.stdout): def __init__(self, tree, file = sys.stdout):
"""Unparser(tree, file=sys.stdout) -> None. """Unparser(tree, file=sys.stdout) -> None.
Print the source for tree to file.""" Print the source for tree to file."""
self.f = file self.f = file
self._indent = 0 self._indent = 0
self.dispatch(tree) self.dispatch(tree)
self.f.flush() self.f.flush()
def fill(self, text = ""): def fill(self, text = ""):
"Indent a piece of text, according to the current indentation level" "Indent a piece of text, according to the current indentation level"
self.f.write("\n"+" "*self._indent + text) self.f.write("\n"+" "*self._indent + text)
def write(self, text): def write(self, text):
"Append a piece of text to the current line." "Append a piece of text to the current line."
self.f.write(text) self.f.write(text)
def enter(self): def enter(self):
"Print ':', and increase the indentation." "Print ':', and increase the indentation."
self.write(":") self.write(":")
self._indent += 1 self._indent += 1
def leave(self): def leave(self):
"Decrease the indentation level." "Decrease the indentation level."
self._indent -= 1 self._indent -= 1
def dispatch(self, tree): def dispatch(self, tree):
"Dispatcher function, dispatching tree type T to method _T." "Dispatcher function, dispatching tree type T to method _T."
if isinstance(tree, list): if isinstance(tree, list):
for t in tree: for t in tree:
self.dispatch(t) self.dispatch(t)
return return
meth = getattr(self, "_"+tree.__class__.__name__) meth = getattr(self, "_"+tree.__class__.__name__)
meth(tree) meth(tree)
############### Unparsing methods ###################### ############### Unparsing methods ######################
# There should be one method per concrete grammar type # # There should be one method per concrete grammar type #
# Constructors should be grouped by sum type. Ideally, # # Constructors should be grouped by sum type. Ideally, #
# this would follow the order in the grammar, but # # this would follow the order in the grammar, but #
# currently doesn't. # # currently doesn't. #
######################################################## ########################################################
def _Module(self, tree): def _Module(self, tree):
for stmt in tree.body: for stmt in tree.body:
self.dispatch(stmt) self.dispatch(stmt)
# stmt # stmt
def _Expr(self, tree): def _Expr(self, tree):
self.fill() self.fill()
self.dispatch(tree.value) self.dispatch(tree.value)
def _Import(self, t): def _Import(self, t):
self.fill("import ") self.fill("import ")
first = True first = True
for a in t.names: for a in t.names:
if first: if first:
first = False first = False
else: else:
self.write(", ") self.write(", ")
self.write(a.name) self.write(a.name)
if a.asname: if a.asname:
self.write(" as "+a.asname) self.write(" as "+a.asname)
def _Assign(self, t): def _Assign(self, t):
self.fill() self.fill()
for target in t.targets: for target in t.targets:
self.dispatch(target) self.dispatch(target)
self.write(" = ") self.write(" = ")
self.dispatch(t.value) self.dispatch(t.value)
def _ClassDef(self, t): def _ClassDef(self, t):
self.write("\n") self.write("\n")
self.fill("class "+t.name) self.fill("class "+t.name)
if t.bases: if t.bases:
self.write("(") self.write("(")
for a in t.bases: for a in t.bases:
self.dispatch(a) self.dispatch(a)
self.write(", ") self.write(", ")
self.write(")") self.write(")")
self.enter() self.enter()
self.dispatch(t.body) self.dispatch(t.body)
self.leave() self.leave()
def _FunctionDef(self, t): def _FunctionDef(self, t):
self.write("\n") self.write("\n")
self.fill("def "+t.name + "(") self.fill("def "+t.name + "(")
self.dispatch(t.args) self.dispatch(t.args)
self.enter() self.enter()
self.dispatch(t.body) self.dispatch(t.body)
self.leave() self.leave()
def _If(self, t): def _If(self, t):
self.fill("if ") self.fill("if ")
self.dispatch(t.test) self.dispatch(t.test)
self.enter() self.enter()
# XXX elif? # XXX elif?
self.dispatch(t.body) self.dispatch(t.body)
self.leave() self.leave()
if t.orelse: if t.orelse:
self.fill("else") self.fill("else")
self.enter() self.enter()
self.dispatch(t.orelse) self.dispatch(t.orelse)
self.leave() self.leave()
# expr # expr
def _Str(self, tree): def _Str(self, tree):
self.write(repr(tree.s)) self.write(repr(tree.s))
def _Name(self, t): def _Name(self, t):
self.write(t.id) self.write(t.id)
def _List(self, t): def _List(self, t):
self.write("[") self.write("[")
for e in t.elts: for e in t.elts:
self.dispatch(e) self.dispatch(e)
self.write(", ") self.write(", ")
self.write("]") self.write("]")
unop = {"Invert":"~", "Not": "not", "UAdd":"+", "USub":"-"} unop = {"Invert":"~", "Not": "not", "UAdd":"+", "USub":"-"}
def _UnaryOp(self, t): def _UnaryOp(self, t):
self.write(self.unop[t.op.__class__.__name__]) self.write(self.unop[t.op.__class__.__name__])
self.write("(") self.write("(")
self.dispatch(t.operand) self.dispatch(t.operand)
self.write(")") self.write(")")
# others # others
def _arguments(self, t): def _arguments(self, t):
first = True first = True
# XXX t.defaults # XXX t.defaults
for a in t.args: for a in t.args:
if first:first = False if first:first = False
else: self.write(", ") else: self.write(", ")
self.dispatch(a) self.dispatch(a)
if t.vararg: if t.vararg:
if first:first = False if first:first = False
else: self.write(", ") else: self.write(", ")
self.write("*"+t.vararg) self.write("*"+t.vararg)
if t.kwarg: if t.kwarg:
if first:first = False if first:first = False
else: self.write(", ") else: self.write(", ")
self.write("**"+self.kwarg) self.write("**"+self.kwarg)
self.write(")") self.write(")")
def roundtrip(filename): def roundtrip(filename):
source = open(filename).read() source = open(filename).read()
tree = compile(source, filename, "exec", 0x400) tree = compile(source, filename, "exec", 0x400)
Unparser(tree) Unparser(tree)
if __name__=='__main__': if __name__=='__main__':
roundtrip(sys.argv[1]) roundtrip(sys.argv[1])
class GeneratorContextManager(object): class GeneratorContextManager(object):
def __init__(self, gen): def __init__(self, gen):
self.gen = gen self.gen = gen
def __context__(self): def __context__(self):
return self return self
def __enter__(self): def __enter__(self):
try: try:
return self.gen.next() return self.gen.next()
except StopIteration: except StopIteration:
raise RuntimeError("generator didn't yield") raise RuntimeError("generator didn't yield")
def __exit__(self, type, value, traceback): def __exit__(self, type, value, traceback):
if type is None: if type is None:
try: try:
self.gen.next() self.gen.next()
except StopIteration: except StopIteration:
return return
else: else:
raise RuntimeError("generator didn't stop") raise RuntimeError("generator didn't stop")
else: else:
try: try:
self.gen.throw(type, value, traceback) self.gen.throw(type, value, traceback)
except (type, StopIteration): except (type, StopIteration):
return return
else: else:
raise RuntimeError("generator caught exception") raise RuntimeError("generator caught exception")
def contextmanager(func): def contextmanager(func):
def helper(*args, **kwds): def helper(*args, **kwds):
return GeneratorContextManager(func(*args, **kwds)) return GeneratorContextManager(func(*args, **kwds))
return helper return helper
import sys import sys
from collections import deque from collections import deque
class nested(object): class nested(object):
def __init__(self, *contexts): def __init__(self, *contexts):
self.contexts = contexts self.contexts = contexts
self.entered = None self.entered = None
def __context__(self): def __context__(self):
return self return self
def __enter__(self): def __enter__(self):
if self.entered is not None: if self.entered is not None:
raise RuntimeError("Context is not reentrant") raise RuntimeError("Context is not reentrant")
self.entered = deque() self.entered = deque()
vars = [] vars = []
try: try:
for context in self.contexts: for context in self.contexts:
mgr = context.__context__() mgr = context.__context__()
vars.append(mgr.__enter__()) vars.append(mgr.__enter__())
self.entered.appendleft(mgr) self.entered.appendleft(mgr)
except: except:
self.__exit__(*sys.exc_info()) self.__exit__(*sys.exc_info())
raise raise
return vars return vars
def __exit__(self, *exc_info): def __exit__(self, *exc_info):
# Behave like nested with statements # Behave like nested with statements
# first in, last out # first in, last out
# New exceptions override old ones # New exceptions override old ones
ex = exc_info ex = exc_info
for mgr in self.entered: for mgr in self.entered:
try: try:
mgr.__exit__(*ex) mgr.__exit__(*ex)
except: except:
ex = sys.exc_info() ex = sys.exc_info()
self.entered = None self.entered = None
if ex is not exc_info: if ex is not exc_info:
raise ex[0], ex[1], ex[2] raise ex[0], ex[1], ex[2]
import sys, itertools import sys, itertools
def to_tuple(t): def to_tuple(t):
if t is None or isinstance(t, (basestring, int, long, complex)): if t is None or isinstance(t, (basestring, int, long, complex)):
return t return t
elif isinstance(t, list): elif isinstance(t, list):
return [to_tuple(e) for e in t] return [to_tuple(e) for e in t]
result = [t.__class__.__name__] result = [t.__class__.__name__]
if t._fields is None: if t._fields is None:
return tuple(result) return tuple(result)
for f in t._fields: for f in t._fields:
result.append(to_tuple(getattr(t, f))) result.append(to_tuple(getattr(t, f)))
return tuple(result) return tuple(result)
# These tests are compiled through "exec" # These tests are compiled through "exec"
# There should be atleast one test per statement # There should be atleast one test per statement
exec_tests = [ exec_tests = [
# FunctionDef # FunctionDef
"def f(): pass", "def f(): pass",
# ClassDef # ClassDef
"class C:pass", "class C:pass",
# Return # Return
"def f():return 1", "def f():return 1",
# Delete # Delete
"del v", "del v",
# Assign # Assign
"v = 1", "v = 1",
# AugAssign # AugAssign
"v += 1", "v += 1",
# Print # Print
"print >>f, 1, ", "print >>f, 1, ",
# For # For
"for v in v:pass", "for v in v:pass",
# While # While
"while v:pass", "while v:pass",
# If # If
"if v:pass", "if v:pass",
# Raise # Raise
"raise Exception, 'string'", "raise Exception, 'string'",
# TryExcept # TryExcept
"try:\n pass\nexcept Exception:\n pass", "try:\n pass\nexcept Exception:\n pass",
# TryFinally # TryFinally
"try:\n pass\nfinally:\n pass", "try:\n pass\nfinally:\n pass",
# Assert # Assert
"assert v", "assert v",
# Import # Import
"import sys", "import sys",
# ImportFrom # ImportFrom
"from sys import v", "from sys import v",
# Exec # Exec
"exec 'v'", "exec 'v'",
# Global # Global
"global v", "global v",
# Expr # Expr
"1", "1",
# Pass, # Pass,
"pass", "pass",
# Break # Break
"break", "break",
# Continue # Continue
"continue", "continue",
] ]
# These are compiled through "single" # These are compiled through "single"
# because of overlap with "eval", it just tests what # because of overlap with "eval", it just tests what
# can't be tested with "eval" # can't be tested with "eval"
single_tests = [ single_tests = [
"1+2" "1+2"
] ]
# These are compiled through "eval" # These are compiled through "eval"
# It should test all expressions # It should test all expressions
eval_tests = [ eval_tests = [
# BoolOp # BoolOp
"a and b", "a and b",
# BinOp # BinOp
"a + b", "a + b",
# UnaryOp # UnaryOp
"not v", "not v",
# Lambda # Lambda
"lambda:None", "lambda:None",
# Dict # Dict
"{ 1:2 }", "{ 1:2 }",
# ListComp # ListComp
"[a for b in c if d]", "[a for b in c if d]",
# GeneratorExp # GeneratorExp
"(a for b in c if d)", "(a for b in c if d)",
# Yield - yield expressions can't work outside a function # Yield - yield expressions can't work outside a function
# #
# Compare # Compare
"1 < 2 < 3", "1 < 2 < 3",
# Call # Call
"f(1,2,c=3,*d,**e)", "f(1,2,c=3,*d,**e)",
# Repr # Repr
"`v`", "`v`",
# Num # Num
"10L", "10L",
# Str # Str
"'string'", "'string'",
# Attribute # Attribute
"a.b", "a.b",
# Subscript # Subscript
"a[b:c]", "a[b:c]",
# Name # Name
"v", "v",
# List # List
"[1,2,3]", "[1,2,3]",
# Tuple # Tuple
"1,2,3" "1,2,3"
] ]
# TODO: expr_context, slice, boolop, operator, unaryop, cmpop, comprehension # TODO: expr_context, slice, boolop, operator, unaryop, cmpop, comprehension
# excepthandler, arguments, keywords, alias # excepthandler, arguments, keywords, alias
if __name__=='__main__' and sys.argv[1:] == ['-g']: if __name__=='__main__' and sys.argv[1:] == ['-g']:
for statements, kind in ((exec_tests, "exec"), (single_tests, "single"), (eval_tests, "eval")): for statements, kind in ((exec_tests, "exec"), (single_tests, "single"), (eval_tests, "eval")):
print kind+"_results = [" print kind+"_results = ["
for s in statements: for s in statements:
print repr(to_tuple(compile(s, "?", kind, 0x400)))+"," print repr(to_tuple(compile(s, "?", kind, 0x400)))+","
print "]" print "]"
print "run_tests()" print "run_tests()"
raise SystemExit raise SystemExit
def run_tests(): def run_tests():
for input, output, kind in ((exec_tests, exec_results, "exec"), for input, output, kind in ((exec_tests, exec_results, "exec"),
(single_tests, single_results, "single"), (single_tests, single_results, "single"),
(eval_tests, eval_results, "eval")): (eval_tests, eval_results, "eval")):
for i, o in itertools.izip(input, output): for i, o in itertools.izip(input, output):
assert to_tuple(compile(i, "?", kind, 0x400)) == o assert to_tuple(compile(i, "?", kind, 0x400)) == o
#### EVERYTHING BELOW IS GENERATED ##### #### EVERYTHING BELOW IS GENERATED #####
exec_results = [ exec_results = [
('Module', [('FunctionDef', 'f', ('arguments', [], None, None, []), [('Pass',)], [])]), ('Module', [('FunctionDef', 'f', ('arguments', [], None, None, []), [('Pass',)], [])]),
('Module', [('ClassDef', 'C', [], [('Pass',)])]), ('Module', [('ClassDef', 'C', [], [('Pass',)])]),
('Module', [('FunctionDef', 'f', ('arguments', [], None, None, []), [('Return', ('Num', 1))], [])]), ('Module', [('FunctionDef', 'f', ('arguments', [], None, None, []), [('Return', ('Num', 1))], [])]),
('Module', [('Delete', [('Name', 'v', ('Del',))])]), ('Module', [('Delete', [('Name', 'v', ('Del',))])]),
('Module', [('Assign', [('Name', 'v', ('Store',))], ('Num', 1))]), ('Module', [('Assign', [('Name', 'v', ('Store',))], ('Num', 1))]),
('Module', [('AugAssign', ('Name', 'v', ('Load',)), ('Add',), ('Num', 1))]), ('Module', [('AugAssign', ('Name', 'v', ('Load',)), ('Add',), ('Num', 1))]),
('Module', [('Print', ('Name', 'f', ('Load',)), [('Num', 1)], False)]), ('Module', [('Print', ('Name', 'f', ('Load',)), [('Num', 1)], False)]),
('Module', [('For', ('Name', 'v', ('Store',)), ('Name', 'v', ('Load',)), [('Pass',)], [])]), ('Module', [('For', ('Name', 'v', ('Store',)), ('Name', 'v', ('Load',)), [('Pass',)], [])]),
('Module', [('While', ('Name', 'v', ('Load',)), [('Pass',)], [])]), ('Module', [('While', ('Name', 'v', ('Load',)), [('Pass',)], [])]),
('Module', [('If', ('Name', 'v', ('Load',)), [('Pass',)], [])]), ('Module', [('If', ('Name', 'v', ('Load',)), [('Pass',)], [])]),
('Module', [('Raise', ('Name', 'Exception', ('Load',)), ('Str', 'string'), None)]), ('Module', [('Raise', ('Name', 'Exception', ('Load',)), ('Str', 'string'), None)]),
('Module', [('TryExcept', [('Pass',)], [('excepthandler', ('Name', 'Exception', ('Load',)), None, [('Pass',)])], [])]), ('Module', [('TryExcept', [('Pass',)], [('excepthandler', ('Name', 'Exception', ('Load',)), None, [('Pass',)])], [])]),
('Module', [('TryFinally', [('Pass',)], [('Pass',)])]), ('Module', [('TryFinally', [('Pass',)], [('Pass',)])]),
('Module', [('Assert', ('Name', 'v', ('Load',)), None)]), ('Module', [('Assert', ('Name', 'v', ('Load',)), None)]),
('Module', [('Import', [('alias', 'sys', None)])]), ('Module', [('Import', [('alias', 'sys', None)])]),
('Module', [('ImportFrom', 'sys', [('alias', 'v', None)], 0)]), ('Module', [('ImportFrom', 'sys', [('alias', 'v', None)], 0)]),
('Module', [('Exec', ('Str', 'v'), None, None)]), ('Module', [('Exec', ('Str', 'v'), None, None)]),
('Module', [('Global', ['v'])]), ('Module', [('Global', ['v'])]),
('Module', [('Expr', ('Num', 1))]), ('Module', [('Expr', ('Num', 1))]),
('Module', [('Pass',)]), ('Module', [('Pass',)]),
('Module', [('Break',)]), ('Module', [('Break',)]),
('Module', [('Continue',)]), ('Module', [('Continue',)]),
] ]
single_results = [ single_results = [
('Interactive', [('Expr', ('BinOp', ('Num', 1), ('Add',), ('Num', 2)))]), ('Interactive', [('Expr', ('BinOp', ('Num', 1), ('Add',), ('Num', 2)))]),
] ]
eval_results = [ eval_results = [
('Expression', ('BoolOp', ('And',), [('Name', 'a', ('Load',)), ('Name', 'b', ('Load',))])), ('Expression', ('BoolOp', ('And',), [('Name', 'a', ('Load',)), ('Name', 'b', ('Load',))])),
('Expression', ('BinOp', ('Name', 'a', ('Load',)), ('Add',), ('Name', 'b', ('Load',)))), ('Expression', ('BinOp', ('Name', 'a', ('Load',)), ('Add',), ('Name', 'b', ('Load',)))),
('Expression', ('UnaryOp', ('Not',), ('Name', 'v', ('Load',)))), ('Expression', ('UnaryOp', ('Not',), ('Name', 'v', ('Load',)))),
('Expression', ('Lambda', ('arguments', [], None, None, []), ('Name', 'None', ('Load',)))), ('Expression', ('Lambda', ('arguments', [], None, None, []), ('Name', 'None', ('Load',)))),
('Expression', ('Dict', [('Num', 1)], [('Num', 2)])), ('Expression', ('Dict', [('Num', 1)], [('Num', 2)])),
('Expression', ('ListComp', ('Name', 'a', ('Load',)), [('comprehension', ('Name', 'b', ('Store',)), ('Name', 'c', ('Load',)), [('Name', 'd', ('Load',))])])), ('Expression', ('ListComp', ('Name', 'a', ('Load',)), [('comprehension', ('Name', 'b', ('Store',)), ('Name', 'c', ('Load',)), [('Name', 'd', ('Load',))])])),
('Expression', ('GeneratorExp', ('Name', 'a', ('Load',)), [('comprehension', ('Name', 'b', ('Store',)), ('Name', 'c', ('Load',)), [('Name', 'd', ('Load',))])])), ('Expression', ('GeneratorExp', ('Name', 'a', ('Load',)), [('comprehension', ('Name', 'b', ('Store',)), ('Name', 'c', ('Load',)), [('Name', 'd', ('Load',))])])),
('Expression', ('Compare', ('Num', 1), [('Lt',), ('Lt',)], [('Num', 2), ('Num', 3)])), ('Expression', ('Compare', ('Num', 1), [('Lt',), ('Lt',)], [('Num', 2), ('Num', 3)])),
('Expression', ('Call', ('Name', 'f', ('Load',)), [('Num', 1), ('Num', 2)], [('keyword', 'c', ('Num', 3))], ('Name', 'd', ('Load',)), ('Name', 'e', ('Load',)))), ('Expression', ('Call', ('Name', 'f', ('Load',)), [('Num', 1), ('Num', 2)], [('keyword', 'c', ('Num', 3))], ('Name', 'd', ('Load',)), ('Name', 'e', ('Load',)))),
('Expression', ('Repr', ('Name', 'v', ('Load',)))), ('Expression', ('Repr', ('Name', 'v', ('Load',)))),
('Expression', ('Num', 10L)), ('Expression', ('Num', 10L)),
('Expression', ('Str', 'string')), ('Expression', ('Str', 'string')),
('Expression', ('Attribute', ('Name', 'a', ('Load',)), 'b', ('Load',))), ('Expression', ('Attribute', ('Name', 'a', ('Load',)), 'b', ('Load',))),
('Expression', ('Subscript', ('Name', 'a', ('Load',)), ('Slice', ('Name', 'b', ('Load',)), ('Name', 'c', ('Load',)), None), ('Load',))), ('Expression', ('Subscript', ('Name', 'a', ('Load',)), ('Slice', ('Name', 'b', ('Load',)), ('Name', 'c', ('Load',)), None), ('Load',))),
('Expression', ('Name', 'v', ('Load',))), ('Expression', ('Name', 'v', ('Load',))),
('Expression', ('List', [('Num', 1), ('Num', 2), ('Num', 3)], ('Load',))), ('Expression', ('List', [('Num', 1), ('Num', 2), ('Num', 3)], ('Load',))),
('Expression', ('Tuple', [('Num', 1), ('Num', 2), ('Num', 3)], ('Load',))), ('Expression', ('Tuple', [('Num', 1), ('Num', 2), ('Num', 3)], ('Load',))),
] ]
run_tests() run_tests()
#!/usr/bin/env python #!/usr/bin/env python
"""Unit tests for the with statement specified in PEP 343.""" """Unit tests for the with statement specified in PEP 343."""
__author__ = "Mike Bland" __author__ = "Mike Bland"
__email__ = "mbland at acm dot org" __email__ = "mbland at acm dot org"
import unittest import unittest
from test.contextmanager import GeneratorContextManager from test.contextmanager import GeneratorContextManager
from test.nested import nested from test.nested import nested
from test.test_support import run_unittest from test.test_support import run_unittest
class MockContextManager(GeneratorContextManager): class MockContextManager(GeneratorContextManager):
def __init__(self, gen): def __init__(self, gen):
GeneratorContextManager.__init__(self, gen) GeneratorContextManager.__init__(self, gen)
self.context_called = False self.context_called = False
self.enter_called = False self.enter_called = False
self.exit_called = False self.exit_called = False
self.exit_args = None self.exit_args = None
def __context__(self): def __context__(self):
self.context_called = True self.context_called = True
return GeneratorContextManager.__context__(self) return GeneratorContextManager.__context__(self)
def __enter__(self): def __enter__(self):
self.enter_called = True self.enter_called = True
return GeneratorContextManager.__enter__(self) return GeneratorContextManager.__enter__(self)
def __exit__(self, type, value, traceback): def __exit__(self, type, value, traceback):
self.exit_called = True self.exit_called = True
self.exit_args = (type, value, traceback) self.exit_args = (type, value, traceback)
return GeneratorContextManager.__exit__(self, type, value, traceback) return GeneratorContextManager.__exit__(self, type, value, traceback)
def mock_contextmanager(func): def mock_contextmanager(func):
def helper(*args, **kwds): def helper(*args, **kwds):
return MockContextManager(func(*args, **kwds)) return MockContextManager(func(*args, **kwds))
return helper return helper
class MockResource(object): class MockResource(object):
def __init__(self): def __init__(self):
self.yielded = False self.yielded = False
self.stopped = False self.stopped = False
@mock_contextmanager @mock_contextmanager
def mock_contextmanager_generator(): def mock_contextmanager_generator():
mock = MockResource() mock = MockResource()
try: try:
mock.yielded = True mock.yielded = True
yield mock yield mock
finally: finally:
mock.stopped = True mock.stopped = True
class MockNested(nested): class MockNested(nested):
def __init__(self, *contexts): def __init__(self, *contexts):
nested.__init__(self, *contexts) nested.__init__(self, *contexts)
self.context_called = False self.context_called = False
self.enter_called = False self.enter_called = False
self.exit_called = False self.exit_called = False
self.exit_args = None self.exit_args = None
def __context__(self): def __context__(self):
self.context_called = True self.context_called = True
return nested.__context__(self) return nested.__context__(self)
def __enter__(self): def __enter__(self):
self.enter_called = True self.enter_called = True
return nested.__enter__(self) return nested.__enter__(self)
def __exit__(self, *exc_info): def __exit__(self, *exc_info):
self.exit_called = True self.exit_called = True
self.exit_args = exc_info self.exit_args = exc_info
return nested.__exit__(self, *exc_info) return nested.__exit__(self, *exc_info)
class FailureTestCase(unittest.TestCase): class FailureTestCase(unittest.TestCase):
def testNameError(self): def testNameError(self):
def fooNotDeclared(): def fooNotDeclared():
with foo: pass with foo: pass
self.assertRaises(NameError, fooNotDeclared) self.assertRaises(NameError, fooNotDeclared)
def testContextAttributeError(self): def testContextAttributeError(self):
class LacksContext(object): class LacksContext(object):
def __enter__(self): def __enter__(self):
pass pass
def __exit__(self, type, value, traceback): def __exit__(self, type, value, traceback):
pass pass
def fooLacksContext(): def fooLacksContext():
foo = LacksContext() foo = LacksContext()
with foo: pass with foo: pass
self.assertRaises(AttributeError, fooLacksContext) self.assertRaises(AttributeError, fooLacksContext)
def testEnterAttributeError(self): def testEnterAttributeError(self):
class LacksEnter(object): class LacksEnter(object):
def __context__(self): def __context__(self):
pass pass
def __exit__(self, type, value, traceback): def __exit__(self, type, value, traceback):
pass pass
def fooLacksEnter(): def fooLacksEnter():
foo = LacksEnter() foo = LacksEnter()
with foo: pass with foo: pass
self.assertRaises(AttributeError, fooLacksEnter) self.assertRaises(AttributeError, fooLacksEnter)
def testExitAttributeError(self): def testExitAttributeError(self):
class LacksExit(object): class LacksExit(object):
def __context__(self): def __context__(self):
pass pass
def __enter__(self): def __enter__(self):
pass pass
def fooLacksExit(): def fooLacksExit():
foo = LacksExit() foo = LacksExit()
with foo: pass with foo: pass
self.assertRaises(AttributeError, fooLacksExit) self.assertRaises(AttributeError, fooLacksExit)
def assertRaisesSyntaxError(self, codestr): def assertRaisesSyntaxError(self, codestr):
def shouldRaiseSyntaxError(s): def shouldRaiseSyntaxError(s):
compile(s, '', 'single') compile(s, '', 'single')
self.assertRaises(SyntaxError, shouldRaiseSyntaxError, codestr) self.assertRaises(SyntaxError, shouldRaiseSyntaxError, codestr)
def testAssignmentToNoneError(self): def testAssignmentToNoneError(self):
self.assertRaisesSyntaxError('with mock as None:\n pass') self.assertRaisesSyntaxError('with mock as None:\n pass')
self.assertRaisesSyntaxError( self.assertRaisesSyntaxError(
'with mock as (None):\n' 'with mock as (None):\n'
' pass') ' pass')
def testAssignmentToEmptyTupleError(self): def testAssignmentToEmptyTupleError(self):
self.assertRaisesSyntaxError( self.assertRaisesSyntaxError(
'with mock as ():\n' 'with mock as ():\n'
' pass') ' pass')
def testAssignmentToTupleOnlyContainingNoneError(self): def testAssignmentToTupleOnlyContainingNoneError(self):
self.assertRaisesSyntaxError('with mock as None,:\n pass') self.assertRaisesSyntaxError('with mock as None,:\n pass')
self.assertRaisesSyntaxError( self.assertRaisesSyntaxError(
'with mock as (None,):\n' 'with mock as (None,):\n'
' pass') ' pass')
def testAssignmentToTupleContainingNoneError(self): def testAssignmentToTupleContainingNoneError(self):
self.assertRaisesSyntaxError( self.assertRaisesSyntaxError(
'with mock as (foo, None, bar):\n' 'with mock as (foo, None, bar):\n'
' pass') ' pass')
def testContextThrows(self): def testContextThrows(self):
class ContextThrows(object): class ContextThrows(object):
def __context__(self): def __context__(self):
raise RuntimeError("Context threw") raise RuntimeError("Context threw")
def shouldThrow(): def shouldThrow():
ct = ContextThrows() ct = ContextThrows()
self.foo = None self.foo = None
with ct as self.foo: with ct as self.foo:
pass pass
self.assertRaises(RuntimeError, shouldThrow) self.assertRaises(RuntimeError, shouldThrow)
self.assertEqual(self.foo, None) self.assertEqual(self.foo, None)
def testEnterThrows(self): def testEnterThrows(self):
class EnterThrows(object): class EnterThrows(object):
def __context__(self): def __context__(self):
return self return self
def __enter__(self): def __enter__(self):
raise RuntimeError("Context threw") raise RuntimeError("Context threw")
def __exit__(self, *args): def __exit__(self, *args):
pass pass
def shouldThrow(): def shouldThrow():
ct = EnterThrows() ct = EnterThrows()
self.foo = None self.foo = None
with ct as self.foo: with ct as self.foo:
pass pass
self.assertRaises(RuntimeError, shouldThrow) self.assertRaises(RuntimeError, shouldThrow)
self.assertEqual(self.foo, None) self.assertEqual(self.foo, None)
def testExitThrows(self): def testExitThrows(self):
class ExitThrows(object): class ExitThrows(object):
def __context__(self): def __context__(self):
return self return self
def __enter__(self): def __enter__(self):
return return
def __exit__(self, *args): def __exit__(self, *args):
raise RuntimeError(42) raise RuntimeError(42)
def shouldThrow(): def shouldThrow():
with ExitThrows(): with ExitThrows():
pass pass
self.assertRaises(RuntimeError, shouldThrow) self.assertRaises(RuntimeError, shouldThrow)
class ContextmanagerAssertionMixin(object): class ContextmanagerAssertionMixin(object):
TEST_EXCEPTION = RuntimeError("test exception") TEST_EXCEPTION = RuntimeError("test exception")
def assertInWithManagerInvariants(self, mock_manager): def assertInWithManagerInvariants(self, mock_manager):
self.assertTrue(mock_manager.context_called) self.assertTrue(mock_manager.context_called)
self.assertTrue(mock_manager.enter_called) self.assertTrue(mock_manager.enter_called)
self.assertFalse(mock_manager.exit_called) self.assertFalse(mock_manager.exit_called)
self.assertEqual(mock_manager.exit_args, None) self.assertEqual(mock_manager.exit_args, None)
def assertAfterWithManagerInvariants(self, mock_manager, exit_args): def assertAfterWithManagerInvariants(self, mock_manager, exit_args):
self.assertTrue(mock_manager.context_called) self.assertTrue(mock_manager.context_called)
self.assertTrue(mock_manager.enter_called) self.assertTrue(mock_manager.enter_called)
self.assertTrue(mock_manager.exit_called) self.assertTrue(mock_manager.exit_called)
self.assertEqual(mock_manager.exit_args, exit_args) self.assertEqual(mock_manager.exit_args, exit_args)
def assertAfterWithManagerInvariantsNoError(self, mock_manager): def assertAfterWithManagerInvariantsNoError(self, mock_manager):
self.assertAfterWithManagerInvariants(mock_manager, self.assertAfterWithManagerInvariants(mock_manager,
(None, None, None)) (None, None, None))
def assertInWithGeneratorInvariants(self, mock_generator): def assertInWithGeneratorInvariants(self, mock_generator):
self.assertTrue(mock_generator.yielded) self.assertTrue(mock_generator.yielded)
self.assertFalse(mock_generator.stopped) self.assertFalse(mock_generator.stopped)
def assertAfterWithGeneratorInvariantsNoError(self, mock_generator): def assertAfterWithGeneratorInvariantsNoError(self, mock_generator):
self.assertTrue(mock_generator.yielded) self.assertTrue(mock_generator.yielded)
self.assertTrue(mock_generator.stopped) self.assertTrue(mock_generator.stopped)
def raiseTestException(self): def raiseTestException(self):
raise self.TEST_EXCEPTION raise self.TEST_EXCEPTION
def assertAfterWithManagerInvariantsWithError(self, mock_manager): def assertAfterWithManagerInvariantsWithError(self, mock_manager):
self.assertTrue(mock_manager.context_called) self.assertTrue(mock_manager.context_called)
self.assertTrue(mock_manager.enter_called) self.assertTrue(mock_manager.enter_called)
self.assertTrue(mock_manager.exit_called) self.assertTrue(mock_manager.exit_called)
self.assertEqual(mock_manager.exit_args[0], RuntimeError) self.assertEqual(mock_manager.exit_args[0], RuntimeError)
self.assertEqual(mock_manager.exit_args[1], self.TEST_EXCEPTION) self.assertEqual(mock_manager.exit_args[1], self.TEST_EXCEPTION)
def assertAfterWithGeneratorInvariantsWithError(self, mock_generator): def assertAfterWithGeneratorInvariantsWithError(self, mock_generator):
self.assertTrue(mock_generator.yielded) self.assertTrue(mock_generator.yielded)
self.assertTrue(mock_generator.stopped) self.assertTrue(mock_generator.stopped)
class NonexceptionalTestCase(unittest.TestCase, ContextmanagerAssertionMixin): class NonexceptionalTestCase(unittest.TestCase, ContextmanagerAssertionMixin):
def testInlineGeneratorSyntax(self): def testInlineGeneratorSyntax(self):
with mock_contextmanager_generator(): with mock_contextmanager_generator():
pass pass
def testUnboundGenerator(self): def testUnboundGenerator(self):
mock = mock_contextmanager_generator() mock = mock_contextmanager_generator()
with mock: with mock:
pass pass
self.assertAfterWithManagerInvariantsNoError(mock) self.assertAfterWithManagerInvariantsNoError(mock)
def testInlineGeneratorBoundSyntax(self): def testInlineGeneratorBoundSyntax(self):
with mock_contextmanager_generator() as foo: with mock_contextmanager_generator() as foo:
self.assertInWithGeneratorInvariants(foo) self.assertInWithGeneratorInvariants(foo)
# FIXME: In the future, we'll try to keep the bound names from leaking # FIXME: In the future, we'll try to keep the bound names from leaking
self.assertAfterWithGeneratorInvariantsNoError(foo) self.assertAfterWithGeneratorInvariantsNoError(foo)
def testInlineGeneratorBoundToExistingVariable(self): def testInlineGeneratorBoundToExistingVariable(self):
foo = None foo = None
with mock_contextmanager_generator() as foo: with mock_contextmanager_generator() as foo:
self.assertInWithGeneratorInvariants(foo) self.assertInWithGeneratorInvariants(foo)
self.assertAfterWithGeneratorInvariantsNoError(foo) self.assertAfterWithGeneratorInvariantsNoError(foo)
def testInlineGeneratorBoundToDottedVariable(self): def testInlineGeneratorBoundToDottedVariable(self):
with mock_contextmanager_generator() as self.foo: with mock_contextmanager_generator() as self.foo:
self.assertInWithGeneratorInvariants(self.foo) self.assertInWithGeneratorInvariants(self.foo)
self.assertAfterWithGeneratorInvariantsNoError(self.foo) self.assertAfterWithGeneratorInvariantsNoError(self.foo)
def testBoundGenerator(self): def testBoundGenerator(self):
mock = mock_contextmanager_generator() mock = mock_contextmanager_generator()
with mock as foo: with mock as foo:
self.assertInWithGeneratorInvariants(foo) self.assertInWithGeneratorInvariants(foo)
self.assertInWithManagerInvariants(mock) self.assertInWithManagerInvariants(mock)
self.assertAfterWithGeneratorInvariantsNoError(foo) self.assertAfterWithGeneratorInvariantsNoError(foo)
self.assertAfterWithManagerInvariantsNoError(mock) self.assertAfterWithManagerInvariantsNoError(mock)
def testNestedSingleStatements(self): def testNestedSingleStatements(self):
mock_a = mock_contextmanager_generator() mock_a = mock_contextmanager_generator()
with mock_a as foo: with mock_a as foo:
mock_b = mock_contextmanager_generator() mock_b = mock_contextmanager_generator()
with mock_b as bar: with mock_b as bar:
self.assertInWithManagerInvariants(mock_a) self.assertInWithManagerInvariants(mock_a)
self.assertInWithManagerInvariants(mock_b) self.assertInWithManagerInvariants(mock_b)
self.assertInWithGeneratorInvariants(foo) self.assertInWithGeneratorInvariants(foo)
self.assertInWithGeneratorInvariants(bar) self.assertInWithGeneratorInvariants(bar)
self.assertAfterWithManagerInvariantsNoError(mock_b) self.assertAfterWithManagerInvariantsNoError(mock_b)
self.assertAfterWithGeneratorInvariantsNoError(bar) self.assertAfterWithGeneratorInvariantsNoError(bar)
self.assertInWithManagerInvariants(mock_a) self.assertInWithManagerInvariants(mock_a)
self.assertInWithGeneratorInvariants(foo) self.assertInWithGeneratorInvariants(foo)
self.assertAfterWithManagerInvariantsNoError(mock_a) self.assertAfterWithManagerInvariantsNoError(mock_a)
self.assertAfterWithGeneratorInvariantsNoError(foo) self.assertAfterWithGeneratorInvariantsNoError(foo)
class NestedNonexceptionalTestCase(unittest.TestCase, class NestedNonexceptionalTestCase(unittest.TestCase,
ContextmanagerAssertionMixin): ContextmanagerAssertionMixin):
def testSingleArgInlineGeneratorSyntax(self): def testSingleArgInlineGeneratorSyntax(self):
with nested(mock_contextmanager_generator()): with nested(mock_contextmanager_generator()):
pass pass
def testSingleArgUnbound(self): def testSingleArgUnbound(self):
mock_contextmanager = mock_contextmanager_generator() mock_contextmanager = mock_contextmanager_generator()
mock_nested = MockNested(mock_contextmanager) mock_nested = MockNested(mock_contextmanager)
with mock_nested: with mock_nested:
self.assertInWithManagerInvariants(mock_contextmanager) self.assertInWithManagerInvariants(mock_contextmanager)
self.assertInWithManagerInvariants(mock_nested) self.assertInWithManagerInvariants(mock_nested)
self.assertAfterWithManagerInvariantsNoError(mock_contextmanager) self.assertAfterWithManagerInvariantsNoError(mock_contextmanager)
self.assertAfterWithManagerInvariantsNoError(mock_nested) self.assertAfterWithManagerInvariantsNoError(mock_nested)
def testSingleArgBoundToNonTuple(self): def testSingleArgBoundToNonTuple(self):
m = mock_contextmanager_generator() m = mock_contextmanager_generator()
# This will bind all the arguments to nested() into a single list # This will bind all the arguments to nested() into a single list
# assigned to foo. # assigned to foo.
with nested(m) as foo: with nested(m) as foo:
self.assertInWithManagerInvariants(m) self.assertInWithManagerInvariants(m)
self.assertAfterWithManagerInvariantsNoError(m) self.assertAfterWithManagerInvariantsNoError(m)
def testSingleArgBoundToSingleElementParenthesizedList(self): def testSingleArgBoundToSingleElementParenthesizedList(self):
m = mock_contextmanager_generator() m = mock_contextmanager_generator()
# This will bind all the arguments to nested() into a single list # This will bind all the arguments to nested() into a single list
# assigned to foo. # assigned to foo.
# FIXME: what should this do: with nested(m) as (foo,): # FIXME: what should this do: with nested(m) as (foo,):
with nested(m) as (foo): with nested(m) as (foo):
self.assertInWithManagerInvariants(m) self.assertInWithManagerInvariants(m)
self.assertAfterWithManagerInvariantsNoError(m) self.assertAfterWithManagerInvariantsNoError(m)
def testSingleArgBoundToMultipleElementTupleError(self): def testSingleArgBoundToMultipleElementTupleError(self):
def shouldThrowValueError(): def shouldThrowValueError():
with nested(mock_contextmanager_generator()) as (foo, bar): with nested(mock_contextmanager_generator()) as (foo, bar):
pass pass
self.assertRaises(ValueError, shouldThrowValueError) self.assertRaises(ValueError, shouldThrowValueError)
def testSingleArgUnbound(self): def testSingleArgUnbound(self):
mock_contextmanager = mock_contextmanager_generator() mock_contextmanager = mock_contextmanager_generator()
mock_nested = MockNested(mock_contextmanager) mock_nested = MockNested(mock_contextmanager)
with mock_nested: with mock_nested:
self.assertInWithManagerInvariants(mock_contextmanager) self.assertInWithManagerInvariants(mock_contextmanager)
self.assertInWithManagerInvariants(mock_nested) self.assertInWithManagerInvariants(mock_nested)
self.assertAfterWithManagerInvariantsNoError(mock_contextmanager) self.assertAfterWithManagerInvariantsNoError(mock_contextmanager)
self.assertAfterWithManagerInvariantsNoError(mock_nested) self.assertAfterWithManagerInvariantsNoError(mock_nested)
def testMultipleArgUnbound(self): def testMultipleArgUnbound(self):
m = mock_contextmanager_generator() m = mock_contextmanager_generator()
n = mock_contextmanager_generator() n = mock_contextmanager_generator()
o = mock_contextmanager_generator() o = mock_contextmanager_generator()
mock_nested = MockNested(m, n, o) mock_nested = MockNested(m, n, o)
with mock_nested: with mock_nested:
self.assertInWithManagerInvariants(m) self.assertInWithManagerInvariants(m)
self.assertInWithManagerInvariants(n) self.assertInWithManagerInvariants(n)
self.assertInWithManagerInvariants(o) self.assertInWithManagerInvariants(o)
self.assertInWithManagerInvariants(mock_nested) self.assertInWithManagerInvariants(mock_nested)
self.assertAfterWithManagerInvariantsNoError(m) self.assertAfterWithManagerInvariantsNoError(m)
self.assertAfterWithManagerInvariantsNoError(n) self.assertAfterWithManagerInvariantsNoError(n)
self.assertAfterWithManagerInvariantsNoError(o) self.assertAfterWithManagerInvariantsNoError(o)
self.assertAfterWithManagerInvariantsNoError(mock_nested) self.assertAfterWithManagerInvariantsNoError(mock_nested)
def testMultipleArgBound(self): def testMultipleArgBound(self):
mock_nested = MockNested(mock_contextmanager_generator(), mock_nested = MockNested(mock_contextmanager_generator(),
mock_contextmanager_generator(), mock_contextmanager_generator()) mock_contextmanager_generator(), mock_contextmanager_generator())
with mock_nested as (m, n, o): with mock_nested as (m, n, o):
self.assertInWithGeneratorInvariants(m) self.assertInWithGeneratorInvariants(m)
self.assertInWithGeneratorInvariants(n) self.assertInWithGeneratorInvariants(n)
self.assertInWithGeneratorInvariants(o) self.assertInWithGeneratorInvariants(o)
self.assertInWithManagerInvariants(mock_nested) self.assertInWithManagerInvariants(mock_nested)
self.assertAfterWithGeneratorInvariantsNoError(m) self.assertAfterWithGeneratorInvariantsNoError(m)
self.assertAfterWithGeneratorInvariantsNoError(n) self.assertAfterWithGeneratorInvariantsNoError(n)
self.assertAfterWithGeneratorInvariantsNoError(o) self.assertAfterWithGeneratorInvariantsNoError(o)
self.assertAfterWithManagerInvariantsNoError(mock_nested) self.assertAfterWithManagerInvariantsNoError(mock_nested)
class ExceptionalTestCase(unittest.TestCase, ContextmanagerAssertionMixin): class ExceptionalTestCase(unittest.TestCase, ContextmanagerAssertionMixin):
def testSingleResource(self): def testSingleResource(self):
cm = mock_contextmanager_generator() cm = mock_contextmanager_generator()
def shouldThrow(): def shouldThrow():
with cm as self.resource: with cm as self.resource:
self.assertInWithManagerInvariants(cm) self.assertInWithManagerInvariants(cm)
self.assertInWithGeneratorInvariants(self.resource) self.assertInWithGeneratorInvariants(self.resource)
self.raiseTestException() self.raiseTestException()
self.assertRaises(RuntimeError, shouldThrow) self.assertRaises(RuntimeError, shouldThrow)
self.assertAfterWithManagerInvariantsWithError(cm) self.assertAfterWithManagerInvariantsWithError(cm)
self.assertAfterWithGeneratorInvariantsWithError(self.resource) self.assertAfterWithGeneratorInvariantsWithError(self.resource)
def testNestedSingleStatements(self): def testNestedSingleStatements(self):
mock_a = mock_contextmanager_generator() mock_a = mock_contextmanager_generator()
mock_b = mock_contextmanager_generator() mock_b = mock_contextmanager_generator()
def shouldThrow(): def shouldThrow():
with mock_a as self.foo: with mock_a as self.foo:
with mock_b as self.bar: with mock_b as self.bar:
self.assertInWithManagerInvariants(mock_a) self.assertInWithManagerInvariants(mock_a)
self.assertInWithManagerInvariants(mock_b) self.assertInWithManagerInvariants(mock_b)
self.assertInWithGeneratorInvariants(self.foo) self.assertInWithGeneratorInvariants(self.foo)
self.assertInWithGeneratorInvariants(self.bar) self.assertInWithGeneratorInvariants(self.bar)
self.raiseTestException() self.raiseTestException()
self.assertRaises(RuntimeError, shouldThrow) self.assertRaises(RuntimeError, shouldThrow)
self.assertAfterWithManagerInvariantsWithError(mock_a) self.assertAfterWithManagerInvariantsWithError(mock_a)
self.assertAfterWithManagerInvariantsWithError(mock_b) self.assertAfterWithManagerInvariantsWithError(mock_b)
self.assertAfterWithGeneratorInvariantsWithError(self.foo) self.assertAfterWithGeneratorInvariantsWithError(self.foo)
self.assertAfterWithGeneratorInvariantsWithError(self.bar) self.assertAfterWithGeneratorInvariantsWithError(self.bar)
def testMultipleResourcesInSingleStatement(self): def testMultipleResourcesInSingleStatement(self):
cm_a = mock_contextmanager_generator() cm_a = mock_contextmanager_generator()
cm_b = mock_contextmanager_generator() cm_b = mock_contextmanager_generator()
mock_nested = MockNested(cm_a, cm_b) mock_nested = MockNested(cm_a, cm_b)
def shouldThrow(): def shouldThrow():
with mock_nested as (self.resource_a, self.resource_b): with mock_nested as (self.resource_a, self.resource_b):
self.assertInWithManagerInvariants(cm_a) self.assertInWithManagerInvariants(cm_a)
self.assertInWithManagerInvariants(cm_b) self.assertInWithManagerInvariants(cm_b)
self.assertInWithManagerInvariants(mock_nested) self.assertInWithManagerInvariants(mock_nested)
self.assertInWithGeneratorInvariants(self.resource_a) self.assertInWithGeneratorInvariants(self.resource_a)
self.assertInWithGeneratorInvariants(self.resource_b) self.assertInWithGeneratorInvariants(self.resource_b)
self.raiseTestException() self.raiseTestException()
self.assertRaises(RuntimeError, shouldThrow) self.assertRaises(RuntimeError, shouldThrow)
self.assertAfterWithManagerInvariantsWithError(cm_a) self.assertAfterWithManagerInvariantsWithError(cm_a)
self.assertAfterWithManagerInvariantsWithError(cm_b) self.assertAfterWithManagerInvariantsWithError(cm_b)
self.assertAfterWithManagerInvariantsWithError(mock_nested) self.assertAfterWithManagerInvariantsWithError(mock_nested)
self.assertAfterWithGeneratorInvariantsWithError(self.resource_a) self.assertAfterWithGeneratorInvariantsWithError(self.resource_a)
self.assertAfterWithGeneratorInvariantsWithError(self.resource_b) self.assertAfterWithGeneratorInvariantsWithError(self.resource_b)
def testNestedExceptionBeforeInnerStatement(self): def testNestedExceptionBeforeInnerStatement(self):
mock_a = mock_contextmanager_generator() mock_a = mock_contextmanager_generator()
mock_b = mock_contextmanager_generator() mock_b = mock_contextmanager_generator()
self.bar = None self.bar = None
def shouldThrow(): def shouldThrow():
with mock_a as self.foo: with mock_a as self.foo:
self.assertInWithManagerInvariants(mock_a) self.assertInWithManagerInvariants(mock_a)
self.assertInWithGeneratorInvariants(self.foo) self.assertInWithGeneratorInvariants(self.foo)
self.raiseTestException() self.raiseTestException()
with mock_b as self.bar: with mock_b as self.bar:
pass pass
self.assertRaises(RuntimeError, shouldThrow) self.assertRaises(RuntimeError, shouldThrow)
self.assertAfterWithManagerInvariantsWithError(mock_a) self.assertAfterWithManagerInvariantsWithError(mock_a)
self.assertAfterWithGeneratorInvariantsWithError(self.foo) self.assertAfterWithGeneratorInvariantsWithError(self.foo)
# The inner statement stuff should never have been touched # The inner statement stuff should never have been touched
self.assertEqual(self.bar, None) self.assertEqual(self.bar, None)
self.assertFalse(mock_b.context_called) self.assertFalse(mock_b.context_called)
self.assertFalse(mock_b.enter_called) self.assertFalse(mock_b.enter_called)
self.assertFalse(mock_b.exit_called) self.assertFalse(mock_b.exit_called)
self.assertEqual(mock_b.exit_args, None) self.assertEqual(mock_b.exit_args, None)
def testNestedExceptionAfterInnerStatement(self): def testNestedExceptionAfterInnerStatement(self):
mock_a = mock_contextmanager_generator() mock_a = mock_contextmanager_generator()
mock_b = mock_contextmanager_generator() mock_b = mock_contextmanager_generator()
def shouldThrow(): def shouldThrow():
with mock_a as self.foo: with mock_a as self.foo:
with mock_b as self.bar: with mock_b as self.bar:
self.assertInWithManagerInvariants(mock_a) self.assertInWithManagerInvariants(mock_a)
self.assertInWithManagerInvariants(mock_b) self.assertInWithManagerInvariants(mock_b)
self.assertInWithGeneratorInvariants(self.foo) self.assertInWithGeneratorInvariants(self.foo)
self.assertInWithGeneratorInvariants(self.bar) self.assertInWithGeneratorInvariants(self.bar)
self.raiseTestException() self.raiseTestException()
self.assertRaises(RuntimeError, shouldThrow) self.assertRaises(RuntimeError, shouldThrow)
self.assertAfterWithManagerInvariantsWithError(mock_a) self.assertAfterWithManagerInvariantsWithError(mock_a)
self.assertAfterWithManagerInvariantsNoError(mock_b) self.assertAfterWithManagerInvariantsNoError(mock_b)
self.assertAfterWithGeneratorInvariantsWithError(self.foo) self.assertAfterWithGeneratorInvariantsWithError(self.foo)
self.assertAfterWithGeneratorInvariantsNoError(self.bar) self.assertAfterWithGeneratorInvariantsNoError(self.bar)
class NonLocalFlowControlTestCase(unittest.TestCase): class NonLocalFlowControlTestCase(unittest.TestCase):
def testWithBreak(self): def testWithBreak(self):
counter = 0 counter = 0
while True: while True:
counter += 1 counter += 1
with mock_contextmanager_generator(): with mock_contextmanager_generator():
counter += 10 counter += 10
break break
counter += 100 # Not reached counter += 100 # Not reached
self.assertEqual(counter, 11) self.assertEqual(counter, 11)
def testWithContinue(self): def testWithContinue(self):
counter = 0 counter = 0
while True: while True:
counter += 1 counter += 1
if counter > 2: if counter > 2:
break break
with mock_contextmanager_generator(): with mock_contextmanager_generator():
counter += 10 counter += 10
continue continue
counter += 100 # Not reached counter += 100 # Not reached
self.assertEqual(counter, 12) self.assertEqual(counter, 12)
def testWithReturn(self): def testWithReturn(self):
def foo(): def foo():
counter = 0 counter = 0
while True: while True:
counter += 1 counter += 1
with mock_contextmanager_generator(): with mock_contextmanager_generator():
counter += 10 counter += 10
return counter return counter
counter += 100 # Not reached counter += 100 # Not reached
self.assertEqual(foo(), 11) self.assertEqual(foo(), 11)
def testWithYield(self): def testWithYield(self):
def gen(): def gen():
with mock_contextmanager_generator(): with mock_contextmanager_generator():
yield 12 yield 12
yield 13 yield 13
x = list(gen()) x = list(gen())
self.assertEqual(x, [12, 13]) self.assertEqual(x, [12, 13])
def testWithRaise(self): def testWithRaise(self):
counter = 0 counter = 0
try: try:
counter += 1 counter += 1
with mock_contextmanager_generator(): with mock_contextmanager_generator():
counter += 10 counter += 10
raise RuntimeError raise RuntimeError
counter += 100 # Not reached counter += 100 # Not reached
except RuntimeError: except RuntimeError:
self.assertEqual(counter, 11) self.assertEqual(counter, 11)
else: else:
self.fail("Didn't raise RuntimeError") self.fail("Didn't raise RuntimeError")
class AssignmentTargetTestCase(unittest.TestCase): class AssignmentTargetTestCase(unittest.TestCase):
def testSingleComplexTarget(self): def testSingleComplexTarget(self):
targets = {1: [0, 1, 2]} targets = {1: [0, 1, 2]}
with mock_contextmanager_generator() as targets[1][0]: with mock_contextmanager_generator() as targets[1][0]:
self.assertEqual(targets.keys(), [1]) self.assertEqual(targets.keys(), [1])
self.assertEqual(targets[1][0].__class__, MockResource) self.assertEqual(targets[1][0].__class__, MockResource)
with mock_contextmanager_generator() as targets.values()[0][1]: with mock_contextmanager_generator() as targets.values()[0][1]:
self.assertEqual(targets.keys(), [1]) self.assertEqual(targets.keys(), [1])
self.assertEqual(targets[1][1].__class__, MockResource) self.assertEqual(targets[1][1].__class__, MockResource)
with mock_contextmanager_generator() as targets[2]: with mock_contextmanager_generator() as targets[2]:
keys = targets.keys() keys = targets.keys()
keys.sort() keys.sort()
self.assertEqual(keys, [1, 2]) self.assertEqual(keys, [1, 2])
class C: pass class C: pass
blah = C() blah = C()
with mock_contextmanager_generator() as blah.foo: with mock_contextmanager_generator() as blah.foo:
self.assertEqual(hasattr(blah, "foo"), True) self.assertEqual(hasattr(blah, "foo"), True)
def testMultipleComplexTargets(self): def testMultipleComplexTargets(self):
class C: class C:
def __context__(self): return self def __context__(self): return self
def __enter__(self): return 1, 2, 3 def __enter__(self): return 1, 2, 3
def __exit__(self, *a): pass def __exit__(self, *a): pass
targets = {1: [0, 1, 2]} targets = {1: [0, 1, 2]}
with C() as (targets[1][0], targets[1][1], targets[1][2]): with C() as (targets[1][0], targets[1][1], targets[1][2]):
self.assertEqual(targets, {1: [1, 2, 3]}) self.assertEqual(targets, {1: [1, 2, 3]})
with C() as (targets.values()[0][2], targets.values()[0][1], targets.values()[0][0]): with C() as (targets.values()[0][2], targets.values()[0][1], targets.values()[0][0]):
self.assertEqual(targets, {1: [3, 2, 1]}) self.assertEqual(targets, {1: [3, 2, 1]})
with C() as (targets[1], targets[2], targets[3]): with C() as (targets[1], targets[2], targets[3]):
self.assertEqual(targets, {1: 1, 2: 2, 3: 3}) self.assertEqual(targets, {1: 1, 2: 2, 3: 3})
class B: pass class B: pass
blah = B() blah = B()
with C() as (blah.one, blah.two, blah.three): with C() as (blah.one, blah.two, blah.three):
self.assertEqual(blah.one, 1) self.assertEqual(blah.one, 1)
self.assertEqual(blah.two, 2) self.assertEqual(blah.two, 2)
self.assertEqual(blah.three, 3) self.assertEqual(blah.three, 3)
def test_main(): def test_main():
run_unittest(FailureTestCase, NonexceptionalTestCase, run_unittest(FailureTestCase, NonexceptionalTestCase,
NestedNonexceptionalTestCase, ExceptionalTestCase, NestedNonexceptionalTestCase, ExceptionalTestCase,
NonLocalFlowControlTestCase, NonLocalFlowControlTestCase,
AssignmentTargetTestCase) AssignmentTargetTestCase)
if __name__ == '__main__': if __name__ == '__main__':
test_main() test_main()
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