diff options
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/compiler/ast.py | 6 | ||||
-rw-r--r-- | Lib/test/contextmanager.py | 67 | ||||
-rw-r--r-- | Lib/test/nested.py | 81 | ||||
-rw-r--r-- | Lib/test/test_ast.py | 357 | ||||
-rw-r--r-- | Lib/test/test_importhooks.py | 4 | ||||
-rw-r--r-- | Lib/test/test_with.py | 1120 |
6 files changed, 816 insertions, 819 deletions
diff --git a/Lib/compiler/ast.py b/Lib/compiler/ast.py index e270995..6e3e182 100644 --- a/Lib/compiler/ast.py +++ b/Lib/compiler/ast.py @@ -553,7 +553,7 @@ class Function(Node): self.varargs = 1 if flags & CO_VARKEYWORDS: self.kwargs = 1 - + def getChildren(self): @@ -584,7 +584,7 @@ class GenExpr(Node): self.lineno = lineno self.argnames = ['[outmost-iterable]'] self.varargs = self.kwargs = None - + def getChildren(self): @@ -763,7 +763,7 @@ class Lambda(Node): self.varargs = 1 if flags & CO_VARKEYWORDS: self.kwargs = 1 - + def getChildren(self): diff --git a/Lib/test/contextmanager.py b/Lib/test/contextmanager.py index 0ebf646..e8b0894 100644 --- a/Lib/test/contextmanager.py +++ b/Lib/test/contextmanager.py @@ -1,34 +1,33 @@ -class GeneratorContextManager(object): - def __init__(self, gen): - self.gen = gen - - def __context__(self): - return self - - def __enter__(self): - try: - return self.gen.next() - except StopIteration: - raise RuntimeError("generator didn't yield") - - def __exit__(self, type, value, traceback): - if type is None: - try: - self.gen.next() - except StopIteration: - return - else: - raise RuntimeError("generator didn't stop") - else: - try: - self.gen.throw(type, value, traceback) - except (type, StopIteration): - return - else: - raise RuntimeError("generator caught exception") - -def contextmanager(func): - def helper(*args, **kwds): - return GeneratorContextManager(func(*args, **kwds)) - return helper - +class GeneratorContextManager(object):
+ def __init__(self, gen):
+ self.gen = gen
+
+ def __context__(self):
+ return self
+
+ def __enter__(self):
+ try:
+ return self.gen.next()
+ except StopIteration:
+ raise RuntimeError("generator didn't yield")
+
+ def __exit__(self, type, value, traceback):
+ if type is None:
+ try:
+ self.gen.next()
+ except StopIteration:
+ return
+ else:
+ raise RuntimeError("generator didn't stop")
+ else:
+ try:
+ self.gen.throw(type, value, traceback)
+ except (type, StopIteration):
+ return
+ else:
+ raise RuntimeError("generator caught exception")
+
+def contextmanager(func):
+ def helper(*args, **kwds):
+ return GeneratorContextManager(func(*args, **kwds))
+ return helper
diff --git a/Lib/test/nested.py b/Lib/test/nested.py index bb210d4..a20cf43 100644 --- a/Lib/test/nested.py +++ b/Lib/test/nested.py @@ -1,41 +1,40 @@ -import sys -from collections import deque - - -class nested(object): - def __init__(self, *contexts): - self.contexts = contexts - self.entered = None - - def __context__(self): - return self - - def __enter__(self): - if self.entered is not None: - raise RuntimeError("Context is not reentrant") - self.entered = deque() - vars = [] - try: - for context in self.contexts: - mgr = context.__context__() - vars.append(mgr.__enter__()) - self.entered.appendleft(mgr) - except: - self.__exit__(*sys.exc_info()) - raise - return vars - - def __exit__(self, *exc_info): - # Behave like nested with statements - # first in, last out - # New exceptions override old ones - ex = exc_info - for mgr in self.entered: - try: - mgr.__exit__(*ex) - except: - ex = sys.exc_info() - self.entered = None - if ex is not exc_info: - raise ex[0], ex[1], ex[2] - +import sys
+from collections import deque
+
+
+class nested(object):
+ def __init__(self, *contexts):
+ self.contexts = contexts
+ self.entered = None
+
+ def __context__(self):
+ return self
+
+ def __enter__(self):
+ if self.entered is not None:
+ raise RuntimeError("Context is not reentrant")
+ self.entered = deque()
+ vars = []
+ try:
+ for context in self.contexts:
+ mgr = context.__context__()
+ vars.append(mgr.__enter__())
+ self.entered.appendleft(mgr)
+ except:
+ self.__exit__(*sys.exc_info())
+ raise
+ return vars
+
+ def __exit__(self, *exc_info):
+ # Behave like nested with statements
+ # first in, last out
+ # New exceptions override old ones
+ ex = exc_info
+ for mgr in self.entered:
+ try:
+ mgr.__exit__(*ex)
+ except:
+ ex = sys.exc_info()
+ self.entered = None
+ if ex is not exc_info:
+ raise ex[0], ex[1], ex[2]
diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index 83a1baa..f83dc92 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -1,179 +1,178 @@ -import sys, itertools - -def to_tuple(t): - if t is None or isinstance(t, (basestring, int, long, complex)): - return t - elif isinstance(t, list): - return [to_tuple(e) for e in t] - result = [t.__class__.__name__] - if t._fields is None: - return tuple(result) - for f in t._fields: - result.append(to_tuple(getattr(t, f))) - return tuple(result) - -# These tests are compiled through "exec" -# There should be atleast one test per statement -exec_tests = [ - # FunctionDef - "def f(): pass", - # ClassDef - "class C:pass", - # Return - "def f():return 1", - # Delete - "del v", - # Assign - "v = 1", - # AugAssign - "v += 1", - # Print - "print >>f, 1, ", - # For - "for v in v:pass", - # While - "while v:pass", - # If - "if v:pass", - # Raise - "raise Exception, 'string'", - # TryExcept - "try:\n pass\nexcept Exception:\n pass", - # TryFinally - "try:\n pass\nfinally:\n pass", - # Assert - "assert v", - # Import - "import sys", - # ImportFrom - "from sys import v", - # Exec - "exec 'v'", - # Global - "global v", - # Expr - "1", - # Pass, - "pass", - # Break - "break", - # Continue - "continue", -] - -# These are compiled through "single" -# because of overlap with "eval", it just tests what -# can't be tested with "eval" -single_tests = [ - "1+2" -] - -# These are compiled through "eval" -# It should test all expressions -eval_tests = [ - # BoolOp - "a and b", - # BinOp - "a + b", - # UnaryOp - "not v", - # Lambda - "lambda:None", - # Dict - "{ 1:2 }", - # ListComp - "[a for b in c if d]", - # GeneratorExp - "(a for b in c if d)", - # Yield - yield expressions can't work outside a function - # - # Compare - "1 < 2 < 3", - # Call - "f(1,2,c=3,*d,**e)", - # Repr - "`v`", - # Num - "10L", - # Str - "'string'", - # Attribute - "a.b", - # Subscript - "a[b:c]", - # Name - "v", - # List - "[1,2,3]", - # Tuple - "1,2,3" -] - -# TODO: expr_context, slice, boolop, operator, unaryop, cmpop, comprehension -# excepthandler, arguments, keywords, alias - -if __name__=='__main__' and sys.argv[1:] == ['-g']: - for statements, kind in ((exec_tests, "exec"), (single_tests, "single"), (eval_tests, "eval")): - print kind+"_results = [" - for s in statements: - print repr(to_tuple(compile(s, "?", kind, 0x400)))+"," - print "]" - print "run_tests()" - raise SystemExit - -def run_tests(): - for input, output, kind in ((exec_tests, exec_results, "exec"), - (single_tests, single_results, "single"), - (eval_tests, eval_results, "eval")): - for i, o in itertools.izip(input, output): - assert to_tuple(compile(i, "?", kind, 0x400)) == o - -#### EVERYTHING BELOW IS GENERATED ##### -exec_results = [ -('Module', [('FunctionDef', 'f', ('arguments', [], None, None, []), [('Pass',)], [])]), -('Module', [('ClassDef', 'C', [], [('Pass',)])]), -('Module', [('FunctionDef', 'f', ('arguments', [], None, None, []), [('Return', ('Num', 1))], [])]), -('Module', [('Delete', [('Name', 'v', ('Del',))])]), -('Module', [('Assign', [('Name', 'v', ('Store',))], ('Num', 1))]), -('Module', [('AugAssign', ('Name', 'v', ('Load',)), ('Add',), ('Num', 1))]), -('Module', [('Print', ('Name', 'f', ('Load',)), [('Num', 1)], False)]), -('Module', [('For', ('Name', 'v', ('Store',)), ('Name', 'v', ('Load',)), [('Pass',)], [])]), -('Module', [('While', ('Name', 'v', ('Load',)), [('Pass',)], [])]), -('Module', [('If', ('Name', 'v', ('Load',)), [('Pass',)], [])]), -('Module', [('Raise', ('Name', 'Exception', ('Load',)), ('Str', 'string'), None)]), -('Module', [('TryExcept', [('Pass',)], [('excepthandler', ('Name', 'Exception', ('Load',)), None, [('Pass',)])], [])]), -('Module', [('TryFinally', [('Pass',)], [('Pass',)])]), -('Module', [('Assert', ('Name', 'v', ('Load',)), None)]), -('Module', [('Import', [('alias', 'sys', None)])]), -('Module', [('ImportFrom', 'sys', [('alias', 'v', None)], 0)]), -('Module', [('Exec', ('Str', 'v'), None, None)]), -('Module', [('Global', ['v'])]), -('Module', [('Expr', ('Num', 1))]), -('Module', [('Pass',)]), -('Module', [('Break',)]), -('Module', [('Continue',)]), -] -single_results = [ -('Interactive', [('Expr', ('BinOp', ('Num', 1), ('Add',), ('Num', 2)))]), -] -eval_results = [ -('Expression', ('BoolOp', ('And',), [('Name', 'a', ('Load',)), ('Name', 'b', ('Load',))])), -('Expression', ('BinOp', ('Name', 'a', ('Load',)), ('Add',), ('Name', 'b', ('Load',)))), -('Expression', ('UnaryOp', ('Not',), ('Name', 'v', ('Load',)))), -('Expression', ('Lambda', ('arguments', [], None, None, []), ('Name', 'None', ('Load',)))), -('Expression', ('Dict', [('Num', 1)], [('Num', 2)])), -('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', ('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', ('Repr', ('Name', 'v', ('Load',)))), -('Expression', ('Num', 10L)), -('Expression', ('Str', 'string')), -('Expression', ('Attribute', ('Name', 'a', ('Load',)), 'b', ('Load',))), -('Expression', ('Subscript', ('Name', 'a', ('Load',)), ('Slice', ('Name', 'b', ('Load',)), ('Name', 'c', ('Load',)), None), ('Load',))), -('Expression', ('Name', 'v', ('Load',))), -('Expression', ('List', [('Num', 1), ('Num', 2), ('Num', 3)], ('Load',))), -('Expression', ('Tuple', [('Num', 1), ('Num', 2), ('Num', 3)], ('Load',))), -] -run_tests() - +import sys, itertools
+
+def to_tuple(t):
+ if t is None or isinstance(t, (basestring, int, long, complex)):
+ return t
+ elif isinstance(t, list):
+ return [to_tuple(e) for e in t]
+ result = [t.__class__.__name__]
+ if t._fields is None:
+ return tuple(result)
+ for f in t._fields:
+ result.append(to_tuple(getattr(t, f)))
+ return tuple(result)
+
+# These tests are compiled through "exec"
+# There should be atleast one test per statement
+exec_tests = [
+ # FunctionDef
+ "def f(): pass",
+ # ClassDef
+ "class C:pass",
+ # Return
+ "def f():return 1",
+ # Delete
+ "del v",
+ # Assign
+ "v = 1",
+ # AugAssign
+ "v += 1",
+ # Print
+ "print >>f, 1, ",
+ # For
+ "for v in v:pass",
+ # While
+ "while v:pass",
+ # If
+ "if v:pass",
+ # Raise
+ "raise Exception, 'string'",
+ # TryExcept
+ "try:\n pass\nexcept Exception:\n pass",
+ # TryFinally
+ "try:\n pass\nfinally:\n pass",
+ # Assert
+ "assert v",
+ # Import
+ "import sys",
+ # ImportFrom
+ "from sys import v",
+ # Exec
+ "exec 'v'",
+ # Global
+ "global v",
+ # Expr
+ "1",
+ # Pass,
+ "pass",
+ # Break
+ "break",
+ # Continue
+ "continue",
+]
+
+# These are compiled through "single"
+# because of overlap with "eval", it just tests what
+# can't be tested with "eval"
+single_tests = [
+ "1+2"
+]
+
+# These are compiled through "eval"
+# It should test all expressions
+eval_tests = [
+ # BoolOp
+ "a and b",
+ # BinOp
+ "a + b",
+ # UnaryOp
+ "not v",
+ # Lambda
+ "lambda:None",
+ # Dict
+ "{ 1:2 }",
+ # ListComp
+ "[a for b in c if d]",
+ # GeneratorExp
+ "(a for b in c if d)",
+ # Yield - yield expressions can't work outside a function
+ #
+ # Compare
+ "1 < 2 < 3",
+ # Call
+ "f(1,2,c=3,*d,**e)",
+ # Repr
+ "`v`",
+ # Num
+ "10L",
+ # Str
+ "'string'",
+ # Attribute
+ "a.b",
+ # Subscript
+ "a[b:c]",
+ # Name
+ "v",
+ # List
+ "[1,2,3]",
+ # Tuple
+ "1,2,3"
+]
+
+# TODO: expr_context, slice, boolop, operator, unaryop, cmpop, comprehension
+# excepthandler, arguments, keywords, alias
+
+if __name__=='__main__' and sys.argv[1:] == ['-g']:
+ for statements, kind in ((exec_tests, "exec"), (single_tests, "single"), (eval_tests, "eval")):
+ print kind+"_results = ["
+ for s in statements:
+ print repr(to_tuple(compile(s, "?", kind, 0x400)))+","
+ print "]"
+ print "run_tests()"
+ raise SystemExit
+
+def run_tests():
+ for input, output, kind in ((exec_tests, exec_results, "exec"),
+ (single_tests, single_results, "single"),
+ (eval_tests, eval_results, "eval")):
+ for i, o in itertools.izip(input, output):
+ assert to_tuple(compile(i, "?", kind, 0x400)) == o
+
+#### EVERYTHING BELOW IS GENERATED #####
+exec_results = [
+('Module', [('FunctionDef', 'f', ('arguments', [], None, None, []), [('Pass',)], [])]),
+('Module', [('ClassDef', 'C', [], [('Pass',)])]),
+('Module', [('FunctionDef', 'f', ('arguments', [], None, None, []), [('Return', ('Num', 1))], [])]),
+('Module', [('Delete', [('Name', 'v', ('Del',))])]),
+('Module', [('Assign', [('Name', 'v', ('Store',))], ('Num', 1))]),
+('Module', [('AugAssign', ('Name', 'v', ('Load',)), ('Add',), ('Num', 1))]),
+('Module', [('Print', ('Name', 'f', ('Load',)), [('Num', 1)], False)]),
+('Module', [('For', ('Name', 'v', ('Store',)), ('Name', 'v', ('Load',)), [('Pass',)], [])]),
+('Module', [('While', ('Name', 'v', ('Load',)), [('Pass',)], [])]),
+('Module', [('If', ('Name', 'v', ('Load',)), [('Pass',)], [])]),
+('Module', [('Raise', ('Name', 'Exception', ('Load',)), ('Str', 'string'), None)]),
+('Module', [('TryExcept', [('Pass',)], [('excepthandler', ('Name', 'Exception', ('Load',)), None, [('Pass',)])], [])]),
+('Module', [('TryFinally', [('Pass',)], [('Pass',)])]),
+('Module', [('Assert', ('Name', 'v', ('Load',)), None)]),
+('Module', [('Import', [('alias', 'sys', None)])]),
+('Module', [('ImportFrom', 'sys', [('alias', 'v', None)], 0)]),
+('Module', [('Exec', ('Str', 'v'), None, None)]),
+('Module', [('Global', ['v'])]),
+('Module', [('Expr', ('Num', 1))]),
+('Module', [('Pass',)]),
+('Module', [('Break',)]),
+('Module', [('Continue',)]),
+]
+single_results = [
+('Interactive', [('Expr', ('BinOp', ('Num', 1), ('Add',), ('Num', 2)))]),
+]
+eval_results = [
+('Expression', ('BoolOp', ('And',), [('Name', 'a', ('Load',)), ('Name', 'b', ('Load',))])),
+('Expression', ('BinOp', ('Name', 'a', ('Load',)), ('Add',), ('Name', 'b', ('Load',)))),
+('Expression', ('UnaryOp', ('Not',), ('Name', 'v', ('Load',)))),
+('Expression', ('Lambda', ('arguments', [], None, None, []), ('Name', 'None', ('Load',)))),
+('Expression', ('Dict', [('Num', 1)], [('Num', 2)])),
+('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', ('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', ('Repr', ('Name', 'v', ('Load',)))),
+('Expression', ('Num', 10L)),
+('Expression', ('Str', 'string')),
+('Expression', ('Attribute', ('Name', 'a', ('Load',)), 'b', ('Load',))),
+('Expression', ('Subscript', ('Name', 'a', ('Load',)), ('Slice', ('Name', 'b', ('Load',)), ('Name', 'c', ('Load',)), None), ('Load',))),
+('Expression', ('Name', 'v', ('Load',))),
+('Expression', ('List', [('Num', 1), ('Num', 2), ('Num', 3)], ('Load',))),
+('Expression', ('Tuple', [('Num', 1), ('Num', 2), ('Num', 3)], ('Load',))),
+]
+run_tests()
diff --git a/Lib/test/test_importhooks.py b/Lib/test/test_importhooks.py index c580755..5af7847 100644 --- a/Lib/test/test_importhooks.py +++ b/Lib/test/test_importhooks.py @@ -190,7 +190,7 @@ class ImportHooksTestCase(ImportHooksBaseTestCase): TestImporter.modules['reloadmodule'] = (False, reload_co) reload(reloadmodule) self.failUnless(hasattr(reloadmodule,'reloaded')) - + import hooktestpackage.oldabs self.assertEqual(hooktestpackage.oldabs.get_name(), "hooktestpackage.oldabs") @@ -208,7 +208,7 @@ class ImportHooksTestCase(ImportHooksBaseTestCase): "hooktestpackage.futrel") self.assertEqual(hooktestpackage.futrel.sub, hooktestpackage.sub) - + import sub self.assertEqual(sub.get_name(), "sub") diff --git a/Lib/test/test_with.py b/Lib/test/test_with.py index 9d809ef..3f32830 100644 --- a/Lib/test/test_with.py +++ b/Lib/test/test_with.py @@ -1,560 +1,560 @@ -#!/usr/bin/env python - -"""Unit tests for the with statement specified in PEP 343.""" - -__author__ = "Mike Bland" -__email__ = "mbland at acm dot org" - -import unittest -from test.contextmanager import GeneratorContextManager -from test.nested import nested -from test.test_support import run_unittest - - -class MockContextManager(GeneratorContextManager): - def __init__(self, gen): - GeneratorContextManager.__init__(self, gen) - self.context_called = False - self.enter_called = False - self.exit_called = False - self.exit_args = None - - def __context__(self): - self.context_called = True - return GeneratorContextManager.__context__(self) - - def __enter__(self): - self.enter_called = True - return GeneratorContextManager.__enter__(self) - - def __exit__(self, type, value, traceback): - self.exit_called = True - self.exit_args = (type, value, traceback) - return GeneratorContextManager.__exit__(self, type, value, traceback) - - -def mock_contextmanager(func): - def helper(*args, **kwds): - return MockContextManager(func(*args, **kwds)) - return helper - - -class MockResource(object): - def __init__(self): - self.yielded = False - self.stopped = False - - -@mock_contextmanager -def mock_contextmanager_generator(): - mock = MockResource() - try: - mock.yielded = True - yield mock - finally: - mock.stopped = True - - -class MockNested(nested): - def __init__(self, *contexts): - nested.__init__(self, *contexts) - self.context_called = False - self.enter_called = False - self.exit_called = False - self.exit_args = None - - def __context__(self): - self.context_called = True - return nested.__context__(self) - - def __enter__(self): - self.enter_called = True - return nested.__enter__(self) - - def __exit__(self, *exc_info): - self.exit_called = True - self.exit_args = exc_info - return nested.__exit__(self, *exc_info) - - -class FailureTestCase(unittest.TestCase): - def testNameError(self): - def fooNotDeclared(): - with foo: pass - self.assertRaises(NameError, fooNotDeclared) - - def testContextAttributeError(self): - class LacksContext(object): - def __enter__(self): - pass - - def __exit__(self, type, value, traceback): - pass - - def fooLacksContext(): - foo = LacksContext() - with foo: pass - self.assertRaises(AttributeError, fooLacksContext) - - def testEnterAttributeError(self): - class LacksEnter(object): - def __context__(self): - pass - - def __exit__(self, type, value, traceback): - pass - - def fooLacksEnter(): - foo = LacksEnter() - with foo: pass - self.assertRaises(AttributeError, fooLacksEnter) - - def testExitAttributeError(self): - class LacksExit(object): - def __context__(self): - pass - - def __enter__(self): - pass - - def fooLacksExit(): - foo = LacksExit() - with foo: pass - self.assertRaises(AttributeError, fooLacksExit) - - def assertRaisesSyntaxError(self, codestr): - def shouldRaiseSyntaxError(s): - compile(s, '', 'single') - self.assertRaises(SyntaxError, shouldRaiseSyntaxError, codestr) - - def testAssignmentToNoneError(self): - self.assertRaisesSyntaxError('with mock as None:\n pass') - self.assertRaisesSyntaxError( - 'with mock as (None):\n' - ' pass') - - def testAssignmentToEmptyTupleError(self): - self.assertRaisesSyntaxError( - 'with mock as ():\n' - ' pass') - - def testAssignmentToTupleOnlyContainingNoneError(self): - self.assertRaisesSyntaxError('with mock as None,:\n pass') - self.assertRaisesSyntaxError( - 'with mock as (None,):\n' - ' pass') - - def testAssignmentToTupleContainingNoneError(self): - self.assertRaisesSyntaxError( - 'with mock as (foo, None, bar):\n' - ' pass') - - def testContextThrows(self): - class ContextThrows(object): - def __context__(self): - raise RuntimeError("Context threw") - - def shouldThrow(): - ct = ContextThrows() - self.foo = None - with ct as self.foo: - pass - self.assertRaises(RuntimeError, shouldThrow) - self.assertEqual(self.foo, None) - - def testEnterThrows(self): - class EnterThrows(object): - def __context__(self): - return self - - def __enter__(self): - raise RuntimeError("Context threw") - - def __exit__(self, *args): - pass - - def shouldThrow(): - ct = EnterThrows() - self.foo = None - with ct as self.foo: - pass - self.assertRaises(RuntimeError, shouldThrow) - self.assertEqual(self.foo, None) - - def testExitThrows(self): - class ExitThrows(object): - def __context__(self): - return self - def __enter__(self): - return - def __exit__(self, *args): - raise RuntimeError(42) - def shouldThrow(): - with ExitThrows(): - pass - self.assertRaises(RuntimeError, shouldThrow) - -class ContextmanagerAssertionMixin(object): - TEST_EXCEPTION = RuntimeError("test exception") - - def assertInWithManagerInvariants(self, mock_manager): - self.assertTrue(mock_manager.context_called) - self.assertTrue(mock_manager.enter_called) - self.assertFalse(mock_manager.exit_called) - self.assertEqual(mock_manager.exit_args, None) - - def assertAfterWithManagerInvariants(self, mock_manager, exit_args): - self.assertTrue(mock_manager.context_called) - self.assertTrue(mock_manager.enter_called) - self.assertTrue(mock_manager.exit_called) - self.assertEqual(mock_manager.exit_args, exit_args) - - def assertAfterWithManagerInvariantsNoError(self, mock_manager): - self.assertAfterWithManagerInvariants(mock_manager, - (None, None, None)) - - def assertInWithGeneratorInvariants(self, mock_generator): - self.assertTrue(mock_generator.yielded) - self.assertFalse(mock_generator.stopped) - - def assertAfterWithGeneratorInvariantsNoError(self, mock_generator): - self.assertTrue(mock_generator.yielded) - self.assertTrue(mock_generator.stopped) - - def raiseTestException(self): - raise self.TEST_EXCEPTION - - def assertAfterWithManagerInvariantsWithError(self, mock_manager): - self.assertTrue(mock_manager.context_called) - self.assertTrue(mock_manager.enter_called) - self.assertTrue(mock_manager.exit_called) - self.assertEqual(mock_manager.exit_args[0], RuntimeError) - self.assertEqual(mock_manager.exit_args[1], self.TEST_EXCEPTION) - - def assertAfterWithGeneratorInvariantsWithError(self, mock_generator): - self.assertTrue(mock_generator.yielded) - self.assertTrue(mock_generator.stopped) - - -class NonexceptionalTestCase(unittest.TestCase, ContextmanagerAssertionMixin): - def testInlineGeneratorSyntax(self): - with mock_contextmanager_generator(): - pass - - def testUnboundGenerator(self): - mock = mock_contextmanager_generator() - with mock: - pass - self.assertAfterWithManagerInvariantsNoError(mock) - - def testInlineGeneratorBoundSyntax(self): - with mock_contextmanager_generator() as foo: - self.assertInWithGeneratorInvariants(foo) - # FIXME: In the future, we'll try to keep the bound names from leaking - self.assertAfterWithGeneratorInvariantsNoError(foo) - - def testInlineGeneratorBoundToExistingVariable(self): - foo = None - with mock_contextmanager_generator() as foo: - self.assertInWithGeneratorInvariants(foo) - self.assertAfterWithGeneratorInvariantsNoError(foo) - - def testInlineGeneratorBoundToDottedVariable(self): - with mock_contextmanager_generator() as self.foo: - self.assertInWithGeneratorInvariants(self.foo) - self.assertAfterWithGeneratorInvariantsNoError(self.foo) - - def testBoundGenerator(self): - mock = mock_contextmanager_generator() - with mock as foo: - self.assertInWithGeneratorInvariants(foo) - self.assertInWithManagerInvariants(mock) - self.assertAfterWithGeneratorInvariantsNoError(foo) - self.assertAfterWithManagerInvariantsNoError(mock) - - def testNestedSingleStatements(self): - mock_a = mock_contextmanager_generator() - with mock_a as foo: - mock_b = mock_contextmanager_generator() - with mock_b as bar: - self.assertInWithManagerInvariants(mock_a) - self.assertInWithManagerInvariants(mock_b) - self.assertInWithGeneratorInvariants(foo) - self.assertInWithGeneratorInvariants(bar) - self.assertAfterWithManagerInvariantsNoError(mock_b) - self.assertAfterWithGeneratorInvariantsNoError(bar) - self.assertInWithManagerInvariants(mock_a) - self.assertInWithGeneratorInvariants(foo) - self.assertAfterWithManagerInvariantsNoError(mock_a) - self.assertAfterWithGeneratorInvariantsNoError(foo) - - -class NestedNonexceptionalTestCase(unittest.TestCase, - ContextmanagerAssertionMixin): - def testSingleArgInlineGeneratorSyntax(self): - with nested(mock_contextmanager_generator()): - pass - - def testSingleArgUnbound(self): - mock_contextmanager = mock_contextmanager_generator() - mock_nested = MockNested(mock_contextmanager) - with mock_nested: - self.assertInWithManagerInvariants(mock_contextmanager) - self.assertInWithManagerInvariants(mock_nested) - self.assertAfterWithManagerInvariantsNoError(mock_contextmanager) - self.assertAfterWithManagerInvariantsNoError(mock_nested) - - def testSingleArgBoundToNonTuple(self): - m = mock_contextmanager_generator() - # This will bind all the arguments to nested() into a single list - # assigned to foo. - with nested(m) as foo: - self.assertInWithManagerInvariants(m) - self.assertAfterWithManagerInvariantsNoError(m) - - def testSingleArgBoundToSingleElementParenthesizedList(self): - m = mock_contextmanager_generator() - # This will bind all the arguments to nested() into a single list - # assigned to foo. - # FIXME: what should this do: with nested(m) as (foo,): - with nested(m) as (foo): - self.assertInWithManagerInvariants(m) - self.assertAfterWithManagerInvariantsNoError(m) - - def testSingleArgBoundToMultipleElementTupleError(self): - def shouldThrowValueError(): - with nested(mock_contextmanager_generator()) as (foo, bar): - pass - self.assertRaises(ValueError, shouldThrowValueError) - - def testSingleArgUnbound(self): - mock_contextmanager = mock_contextmanager_generator() - mock_nested = MockNested(mock_contextmanager) - with mock_nested: - self.assertInWithManagerInvariants(mock_contextmanager) - self.assertInWithManagerInvariants(mock_nested) - self.assertAfterWithManagerInvariantsNoError(mock_contextmanager) - self.assertAfterWithManagerInvariantsNoError(mock_nested) - - def testMultipleArgUnbound(self): - m = mock_contextmanager_generator() - n = mock_contextmanager_generator() - o = mock_contextmanager_generator() - mock_nested = MockNested(m, n, o) - with mock_nested: - self.assertInWithManagerInvariants(m) - self.assertInWithManagerInvariants(n) - self.assertInWithManagerInvariants(o) - self.assertInWithManagerInvariants(mock_nested) - self.assertAfterWithManagerInvariantsNoError(m) - self.assertAfterWithManagerInvariantsNoError(n) - self.assertAfterWithManagerInvariantsNoError(o) - self.assertAfterWithManagerInvariantsNoError(mock_nested) - - def testMultipleArgBound(self): - mock_nested = MockNested(mock_contextmanager_generator(), - mock_contextmanager_generator(), mock_contextmanager_generator()) - with mock_nested as (m, n, o): - self.assertInWithGeneratorInvariants(m) - self.assertInWithGeneratorInvariants(n) - self.assertInWithGeneratorInvariants(o) - self.assertInWithManagerInvariants(mock_nested) - self.assertAfterWithGeneratorInvariantsNoError(m) - self.assertAfterWithGeneratorInvariantsNoError(n) - self.assertAfterWithGeneratorInvariantsNoError(o) - self.assertAfterWithManagerInvariantsNoError(mock_nested) - - -class ExceptionalTestCase(unittest.TestCase, ContextmanagerAssertionMixin): - def testSingleResource(self): - cm = mock_contextmanager_generator() - def shouldThrow(): - with cm as self.resource: - self.assertInWithManagerInvariants(cm) - self.assertInWithGeneratorInvariants(self.resource) - self.raiseTestException() - self.assertRaises(RuntimeError, shouldThrow) - self.assertAfterWithManagerInvariantsWithError(cm) - self.assertAfterWithGeneratorInvariantsWithError(self.resource) - - def testNestedSingleStatements(self): - mock_a = mock_contextmanager_generator() - mock_b = mock_contextmanager_generator() - def shouldThrow(): - with mock_a as self.foo: - with mock_b as self.bar: - self.assertInWithManagerInvariants(mock_a) - self.assertInWithManagerInvariants(mock_b) - self.assertInWithGeneratorInvariants(self.foo) - self.assertInWithGeneratorInvariants(self.bar) - self.raiseTestException() - self.assertRaises(RuntimeError, shouldThrow) - self.assertAfterWithManagerInvariantsWithError(mock_a) - self.assertAfterWithManagerInvariantsWithError(mock_b) - self.assertAfterWithGeneratorInvariantsWithError(self.foo) - self.assertAfterWithGeneratorInvariantsWithError(self.bar) - - def testMultipleResourcesInSingleStatement(self): - cm_a = mock_contextmanager_generator() - cm_b = mock_contextmanager_generator() - mock_nested = MockNested(cm_a, cm_b) - def shouldThrow(): - with mock_nested as (self.resource_a, self.resource_b): - self.assertInWithManagerInvariants(cm_a) - self.assertInWithManagerInvariants(cm_b) - self.assertInWithManagerInvariants(mock_nested) - self.assertInWithGeneratorInvariants(self.resource_a) - self.assertInWithGeneratorInvariants(self.resource_b) - self.raiseTestException() - self.assertRaises(RuntimeError, shouldThrow) - self.assertAfterWithManagerInvariantsWithError(cm_a) - self.assertAfterWithManagerInvariantsWithError(cm_b) - self.assertAfterWithManagerInvariantsWithError(mock_nested) - self.assertAfterWithGeneratorInvariantsWithError(self.resource_a) - self.assertAfterWithGeneratorInvariantsWithError(self.resource_b) - - def testNestedExceptionBeforeInnerStatement(self): - mock_a = mock_contextmanager_generator() - mock_b = mock_contextmanager_generator() - self.bar = None - def shouldThrow(): - with mock_a as self.foo: - self.assertInWithManagerInvariants(mock_a) - self.assertInWithGeneratorInvariants(self.foo) - self.raiseTestException() - with mock_b as self.bar: - pass - self.assertRaises(RuntimeError, shouldThrow) - self.assertAfterWithManagerInvariantsWithError(mock_a) - self.assertAfterWithGeneratorInvariantsWithError(self.foo) - - # The inner statement stuff should never have been touched - self.assertEqual(self.bar, None) - self.assertFalse(mock_b.context_called) - self.assertFalse(mock_b.enter_called) - self.assertFalse(mock_b.exit_called) - self.assertEqual(mock_b.exit_args, None) - - def testNestedExceptionAfterInnerStatement(self): - mock_a = mock_contextmanager_generator() - mock_b = mock_contextmanager_generator() - def shouldThrow(): - with mock_a as self.foo: - with mock_b as self.bar: - self.assertInWithManagerInvariants(mock_a) - self.assertInWithManagerInvariants(mock_b) - self.assertInWithGeneratorInvariants(self.foo) - self.assertInWithGeneratorInvariants(self.bar) - self.raiseTestException() - self.assertRaises(RuntimeError, shouldThrow) - self.assertAfterWithManagerInvariantsWithError(mock_a) - self.assertAfterWithManagerInvariantsNoError(mock_b) - self.assertAfterWithGeneratorInvariantsWithError(self.foo) - self.assertAfterWithGeneratorInvariantsNoError(self.bar) - - -class NonLocalFlowControlTestCase(unittest.TestCase): - - def testWithBreak(self): - counter = 0 - while True: - counter += 1 - with mock_contextmanager_generator(): - counter += 10 - break - counter += 100 # Not reached - self.assertEqual(counter, 11) - - def testWithContinue(self): - counter = 0 - while True: - counter += 1 - if counter > 2: - break - with mock_contextmanager_generator(): - counter += 10 - continue - counter += 100 # Not reached - self.assertEqual(counter, 12) - - def testWithReturn(self): - def foo(): - counter = 0 - while True: - counter += 1 - with mock_contextmanager_generator(): - counter += 10 - return counter - counter += 100 # Not reached - self.assertEqual(foo(), 11) - - def testWithYield(self): - def gen(): - with mock_contextmanager_generator(): - yield 12 - yield 13 - x = list(gen()) - self.assertEqual(x, [12, 13]) - - def testWithRaise(self): - counter = 0 - try: - counter += 1 - with mock_contextmanager_generator(): - counter += 10 - raise RuntimeError - counter += 100 # Not reached - except RuntimeError: - self.assertEqual(counter, 11) - else: - self.fail("Didn't raise RuntimeError") - - -class AssignmentTargetTestCase(unittest.TestCase): - - def testSingleComplexTarget(self): - targets = {1: [0, 1, 2]} - with mock_contextmanager_generator() as targets[1][0]: - self.assertEqual(targets.keys(), [1]) - self.assertEqual(targets[1][0].__class__, MockResource) - with mock_contextmanager_generator() as targets.values()[0][1]: - self.assertEqual(targets.keys(), [1]) - self.assertEqual(targets[1][1].__class__, MockResource) - with mock_contextmanager_generator() as targets[2]: - keys = targets.keys() - keys.sort() - self.assertEqual(keys, [1, 2]) - class C: pass - blah = C() - with mock_contextmanager_generator() as blah.foo: - self.assertEqual(hasattr(blah, "foo"), True) - - def testMultipleComplexTargets(self): - class C: - def __context__(self): return self - def __enter__(self): return 1, 2, 3 - def __exit__(self, *a): pass - targets = {1: [0, 1, 2]} - with C() as (targets[1][0], targets[1][1], targets[1][2]): - self.assertEqual(targets, {1: [1, 2, 3]}) - with C() as (targets.values()[0][2], targets.values()[0][1], targets.values()[0][0]): - self.assertEqual(targets, {1: [3, 2, 1]}) - with C() as (targets[1], targets[2], targets[3]): - self.assertEqual(targets, {1: 1, 2: 2, 3: 3}) - class B: pass - blah = B() - with C() as (blah.one, blah.two, blah.three): - self.assertEqual(blah.one, 1) - self.assertEqual(blah.two, 2) - self.assertEqual(blah.three, 3) - - -def test_main(): - run_unittest(FailureTestCase, NonexceptionalTestCase, - NestedNonexceptionalTestCase, ExceptionalTestCase, - NonLocalFlowControlTestCase, - AssignmentTargetTestCase) - - -if __name__ == '__main__': - test_main() +#!/usr/bin/env python
+
+"""Unit tests for the with statement specified in PEP 343."""
+
+__author__ = "Mike Bland"
+__email__ = "mbland at acm dot org"
+
+import unittest
+from test.contextmanager import GeneratorContextManager
+from test.nested import nested
+from test.test_support import run_unittest
+
+
+class MockContextManager(GeneratorContextManager):
+ def __init__(self, gen):
+ GeneratorContextManager.__init__(self, gen)
+ self.context_called = False
+ self.enter_called = False
+ self.exit_called = False
+ self.exit_args = None
+
+ def __context__(self):
+ self.context_called = True
+ return GeneratorContextManager.__context__(self)
+
+ def __enter__(self):
+ self.enter_called = True
+ return GeneratorContextManager.__enter__(self)
+
+ def __exit__(self, type, value, traceback):
+ self.exit_called = True
+ self.exit_args = (type, value, traceback)
+ return GeneratorContextManager.__exit__(self, type, value, traceback)
+
+
+def mock_contextmanager(func):
+ def helper(*args, **kwds):
+ return MockContextManager(func(*args, **kwds))
+ return helper
+
+
+class MockResource(object):
+ def __init__(self):
+ self.yielded = False
+ self.stopped = False
+
+
+@mock_contextmanager
+def mock_contextmanager_generator():
+ mock = MockResource()
+ try:
+ mock.yielded = True
+ yield mock
+ finally:
+ mock.stopped = True
+
+
+class MockNested(nested):
+ def __init__(self, *contexts):
+ nested.__init__(self, *contexts)
+ self.context_called = False
+ self.enter_called = False
+ self.exit_called = False
+ self.exit_args = None
+
+ def __context__(self):
+ self.context_called = True
+ return nested.__context__(self)
+
+ def __enter__(self):
+ self.enter_called = True
+ return nested.__enter__(self)
+
+ def __exit__(self, *exc_info):
+ self.exit_called = True
+ self.exit_args = exc_info
+ return nested.__exit__(self, *exc_info)
+
+
+class FailureTestCase(unittest.TestCase):
+ def testNameError(self):
+ def fooNotDeclared():
+ with foo: pass
+ self.assertRaises(NameError, fooNotDeclared)
+
+ def testContextAttributeError(self):
+ class LacksContext(object):
+ def __enter__(self):
+ pass
+
+ def __exit__(self, type, value, traceback):
+ pass
+
+ def fooLacksContext():
+ foo = LacksContext()
+ with foo: pass
+ self.assertRaises(AttributeError, fooLacksContext)
+
+ def testEnterAttributeError(self):
+ class LacksEnter(object):
+ def __context__(self):
+ pass
+
+ def __exit__(self, type, value, traceback):
+ pass
+
+ def fooLacksEnter():
+ foo = LacksEnter()
+ with foo: pass
+ self.assertRaises(AttributeError, fooLacksEnter)
+
+ def testExitAttributeError(self):
+ class LacksExit(object):
+ def __context__(self):
+ pass
+
+ def __enter__(self):
+ pass
+
+ def fooLacksExit():
+ foo = LacksExit()
+ with foo: pass
+ self.assertRaises(AttributeError, fooLacksExit)
+
+ def assertRaisesSyntaxError(self, codestr):
+ def shouldRaiseSyntaxError(s):
+ compile(s, '', 'single')
+ self.assertRaises(SyntaxError, shouldRaiseSyntaxError, codestr)
+
+ def testAssignmentToNoneError(self):
+ self.assertRaisesSyntaxError('with mock as None:\n pass')
+ self.assertRaisesSyntaxError(
+ 'with mock as (None):\n'
+ ' pass')
+
+ def testAssignmentToEmptyTupleError(self):
+ self.assertRaisesSyntaxError(
+ 'with mock as ():\n'
+ ' pass')
+
+ def testAssignmentToTupleOnlyContainingNoneError(self):
+ self.assertRaisesSyntaxError('with mock as None,:\n pass')
+ self.assertRaisesSyntaxError(
+ 'with mock as (None,):\n'
+ ' pass')
+
+ def testAssignmentToTupleContainingNoneError(self):
+ self.assertRaisesSyntaxError(
+ 'with mock as (foo, None, bar):\n'
+ ' pass')
+
+ def testContextThrows(self):
+ class ContextThrows(object):
+ def __context__(self):
+ raise RuntimeError("Context threw")
+
+ def shouldThrow():
+ ct = ContextThrows()
+ self.foo = None
+ with ct as self.foo:
+ pass
+ self.assertRaises(RuntimeError, shouldThrow)
+ self.assertEqual(self.foo, None)
+
+ def testEnterThrows(self):
+ class EnterThrows(object):
+ def __context__(self):
+ return self
+
+ def __enter__(self):
+ raise RuntimeError("Context threw")
+
+ def __exit__(self, *args):
+ pass
+
+ def shouldThrow():
+ ct = EnterThrows()
+ self.foo = None
+ with ct as self.foo:
+ pass
+ self.assertRaises(RuntimeError, shouldThrow)
+ self.assertEqual(self.foo, None)
+
+ def testExitThrows(self):
+ class ExitThrows(object):
+ def __context__(self):
+ return self
+ def __enter__(self):
+ return
+ def __exit__(self, *args):
+ raise RuntimeError(42)
+ def shouldThrow():
+ with ExitThrows():
+ pass
+ self.assertRaises(RuntimeError, shouldThrow)
+
+class ContextmanagerAssertionMixin(object):
+ TEST_EXCEPTION = RuntimeError("test exception")
+
+ def assertInWithManagerInvariants(self, mock_manager):
+ self.assertTrue(mock_manager.context_called)
+ self.assertTrue(mock_manager.enter_called)
+ self.assertFalse(mock_manager.exit_called)
+ self.assertEqual(mock_manager.exit_args, None)
+
+ def assertAfterWithManagerInvariants(self, mock_manager, exit_args):
+ self.assertTrue(mock_manager.context_called)
+ self.assertTrue(mock_manager.enter_called)
+ self.assertTrue(mock_manager.exit_called)
+ self.assertEqual(mock_manager.exit_args, exit_args)
+
+ def assertAfterWithManagerInvariantsNoError(self, mock_manager):
+ self.assertAfterWithManagerInvariants(mock_manager,
+ (None, None, None))
+
+ def assertInWithGeneratorInvariants(self, mock_generator):
+ self.assertTrue(mock_generator.yielded)
+ self.assertFalse(mock_generator.stopped)
+
+ def assertAfterWithGeneratorInvariantsNoError(self, mock_generator):
+ self.assertTrue(mock_generator.yielded)
+ self.assertTrue(mock_generator.stopped)
+
+ def raiseTestException(self):
+ raise self.TEST_EXCEPTION
+
+ def assertAfterWithManagerInvariantsWithError(self, mock_manager):
+ self.assertTrue(mock_manager.context_called)
+ self.assertTrue(mock_manager.enter_called)
+ self.assertTrue(mock_manager.exit_called)
+ self.assertEqual(mock_manager.exit_args[0], RuntimeError)
+ self.assertEqual(mock_manager.exit_args[1], self.TEST_EXCEPTION)
+
+ def assertAfterWithGeneratorInvariantsWithError(self, mock_generator):
+ self.assertTrue(mock_generator.yielded)
+ self.assertTrue(mock_generator.stopped)
+
+
+class NonexceptionalTestCase(unittest.TestCase, ContextmanagerAssertionMixin):
+ def testInlineGeneratorSyntax(self):
+ with mock_contextmanager_generator():
+ pass
+
+ def testUnboundGenerator(self):
+ mock = mock_contextmanager_generator()
+ with mock:
+ pass
+ self.assertAfterWithManagerInvariantsNoError(mock)
+
+ def testInlineGeneratorBoundSyntax(self):
+ with mock_contextmanager_generator() as foo:
+ self.assertInWithGeneratorInvariants(foo)
+ # FIXME: In the future, we'll try to keep the bound names from leaking
+ self.assertAfterWithGeneratorInvariantsNoError(foo)
+
+ def testInlineGeneratorBoundToExistingVariable(self):
+ foo = None
+ with mock_contextmanager_generator() as foo:
+ self.assertInWithGeneratorInvariants(foo)
+ self.assertAfterWithGeneratorInvariantsNoError(foo)
+
+ def testInlineGeneratorBoundToDottedVariable(self):
+ with mock_contextmanager_generator() as self.foo:
+ self.assertInWithGeneratorInvariants(self.foo)
+ self.assertAfterWithGeneratorInvariantsNoError(self.foo)
+
+ def testBoundGenerator(self):
+ mock = mock_contextmanager_generator()
+ with mock as foo:
+ self.assertInWithGeneratorInvariants(foo)
+ self.assertInWithManagerInvariants(mock)
+ self.assertAfterWithGeneratorInvariantsNoError(foo)
+ self.assertAfterWithManagerInvariantsNoError(mock)
+
+ def testNestedSingleStatements(self):
+ mock_a = mock_contextmanager_generator()
+ with mock_a as foo:
+ mock_b = mock_contextmanager_generator()
+ with mock_b as bar:
+ self.assertInWithManagerInvariants(mock_a)
+ self.assertInWithManagerInvariants(mock_b)
+ self.assertInWithGeneratorInvariants(foo)
+ self.assertInWithGeneratorInvariants(bar)
+ self.assertAfterWithManagerInvariantsNoError(mock_b)
+ self.assertAfterWithGeneratorInvariantsNoError(bar)
+ self.assertInWithManagerInvariants(mock_a)
+ self.assertInWithGeneratorInvariants(foo)
+ self.assertAfterWithManagerInvariantsNoError(mock_a)
+ self.assertAfterWithGeneratorInvariantsNoError(foo)
+
+
+class NestedNonexceptionalTestCase(unittest.TestCase,
+ ContextmanagerAssertionMixin):
+ def testSingleArgInlineGeneratorSyntax(self):
+ with nested(mock_contextmanager_generator()):
+ pass
+
+ def testSingleArgUnbound(self):
+ mock_contextmanager = mock_contextmanager_generator()
+ mock_nested = MockNested(mock_contextmanager)
+ with mock_nested:
+ self.assertInWithManagerInvariants(mock_contextmanager)
+ self.assertInWithManagerInvariants(mock_nested)
+ self.assertAfterWithManagerInvariantsNoError(mock_contextmanager)
+ self.assertAfterWithManagerInvariantsNoError(mock_nested)
+
+ def testSingleArgBoundToNonTuple(self):
+ m = mock_contextmanager_generator()
+ # This will bind all the arguments to nested() into a single list
+ # assigned to foo.
+ with nested(m) as foo:
+ self.assertInWithManagerInvariants(m)
+ self.assertAfterWithManagerInvariantsNoError(m)
+
+ def testSingleArgBoundToSingleElementParenthesizedList(self):
+ m = mock_contextmanager_generator()
+ # This will bind all the arguments to nested() into a single list
+ # assigned to foo.
+ # FIXME: what should this do: with nested(m) as (foo,):
+ with nested(m) as (foo):
+ self.assertInWithManagerInvariants(m)
+ self.assertAfterWithManagerInvariantsNoError(m)
+
+ def testSingleArgBoundToMultipleElementTupleError(self):
+ def shouldThrowValueError():
+ with nested(mock_contextmanager_generator()) as (foo, bar):
+ pass
+ self.assertRaises(ValueError, shouldThrowValueError)
+
+ def testSingleArgUnbound(self):
+ mock_contextmanager = mock_contextmanager_generator()
+ mock_nested = MockNested(mock_contextmanager)
+ with mock_nested:
+ self.assertInWithManagerInvariants(mock_contextmanager)
+ self.assertInWithManagerInvariants(mock_nested)
+ self.assertAfterWithManagerInvariantsNoError(mock_contextmanager)
+ self.assertAfterWithManagerInvariantsNoError(mock_nested)
+
+ def testMultipleArgUnbound(self):
+ m = mock_contextmanager_generator()
+ n = mock_contextmanager_generator()
+ o = mock_contextmanager_generator()
+ mock_nested = MockNested(m, n, o)
+ with mock_nested:
+ self.assertInWithManagerInvariants(m)
+ self.assertInWithManagerInvariants(n)
+ self.assertInWithManagerInvariants(o)
+ self.assertInWithManagerInvariants(mock_nested)
+ self.assertAfterWithManagerInvariantsNoError(m)
+ self.assertAfterWithManagerInvariantsNoError(n)
+ self.assertAfterWithManagerInvariantsNoError(o)
+ self.assertAfterWithManagerInvariantsNoError(mock_nested)
+
+ def testMultipleArgBound(self):
+ mock_nested = MockNested(mock_contextmanager_generator(),
+ mock_contextmanager_generator(), mock_contextmanager_generator())
+ with mock_nested as (m, n, o):
+ self.assertInWithGeneratorInvariants(m)
+ self.assertInWithGeneratorInvariants(n)
+ self.assertInWithGeneratorInvariants(o)
+ self.assertInWithManagerInvariants(mock_nested)
+ self.assertAfterWithGeneratorInvariantsNoError(m)
+ self.assertAfterWithGeneratorInvariantsNoError(n)
+ self.assertAfterWithGeneratorInvariantsNoError(o)
+ self.assertAfterWithManagerInvariantsNoError(mock_nested)
+
+
+class ExceptionalTestCase(unittest.TestCase, ContextmanagerAssertionMixin):
+ def testSingleResource(self):
+ cm = mock_contextmanager_generator()
+ def shouldThrow():
+ with cm as self.resource:
+ self.assertInWithManagerInvariants(cm)
+ self.assertInWithGeneratorInvariants(self.resource)
+ self.raiseTestException()
+ self.assertRaises(RuntimeError, shouldThrow)
+ self.assertAfterWithManagerInvariantsWithError(cm)
+ self.assertAfterWithGeneratorInvariantsWithError(self.resource)
+
+ def testNestedSingleStatements(self):
+ mock_a = mock_contextmanager_generator()
+ mock_b = mock_contextmanager_generator()
+ def shouldThrow():
+ with mock_a as self.foo:
+ with mock_b as self.bar:
+ self.assertInWithManagerInvariants(mock_a)
+ self.assertInWithManagerInvariants(mock_b)
+ self.assertInWithGeneratorInvariants(self.foo)
+ self.assertInWithGeneratorInvariants(self.bar)
+ self.raiseTestException()
+ self.assertRaises(RuntimeError, shouldThrow)
+ self.assertAfterWithManagerInvariantsWithError(mock_a)
+ self.assertAfterWithManagerInvariantsWithError(mock_b)
+ self.assertAfterWithGeneratorInvariantsWithError(self.foo)
+ self.assertAfterWithGeneratorInvariantsWithError(self.bar)
+
+ def testMultipleResourcesInSingleStatement(self):
+ cm_a = mock_contextmanager_generator()
+ cm_b = mock_contextmanager_generator()
+ mock_nested = MockNested(cm_a, cm_b)
+ def shouldThrow():
+ with mock_nested as (self.resource_a, self.resource_b):
+ self.assertInWithManagerInvariants(cm_a)
+ self.assertInWithManagerInvariants(cm_b)
+ self.assertInWithManagerInvariants(mock_nested)
+ self.assertInWithGeneratorInvariants(self.resource_a)
+ self.assertInWithGeneratorInvariants(self.resource_b)
+ self.raiseTestException()
+ self.assertRaises(RuntimeError, shouldThrow)
+ self.assertAfterWithManagerInvariantsWithError(cm_a)
+ self.assertAfterWithManagerInvariantsWithError(cm_b)
+ self.assertAfterWithManagerInvariantsWithError(mock_nested)
+ self.assertAfterWithGeneratorInvariantsWithError(self.resource_a)
+ self.assertAfterWithGeneratorInvariantsWithError(self.resource_b)
+
+ def testNestedExceptionBeforeInnerStatement(self):
+ mock_a = mock_contextmanager_generator()
+ mock_b = mock_contextmanager_generator()
+ self.bar = None
+ def shouldThrow():
+ with mock_a as self.foo:
+ self.assertInWithManagerInvariants(mock_a)
+ self.assertInWithGeneratorInvariants(self.foo)
+ self.raiseTestException()
+ with mock_b as self.bar:
+ pass
+ self.assertRaises(RuntimeError, shouldThrow)
+ self.assertAfterWithManagerInvariantsWithError(mock_a)
+ self.assertAfterWithGeneratorInvariantsWithError(self.foo)
+
+ # The inner statement stuff should never have been touched
+ self.assertEqual(self.bar, None)
+ self.assertFalse(mock_b.context_called)
+ self.assertFalse(mock_b.enter_called)
+ self.assertFalse(mock_b.exit_called)
+ self.assertEqual(mock_b.exit_args, None)
+
+ def testNestedExceptionAfterInnerStatement(self):
+ mock_a = mock_contextmanager_generator()
+ mock_b = mock_contextmanager_generator()
+ def shouldThrow():
+ with mock_a as self.foo:
+ with mock_b as self.bar:
+ self.assertInWithManagerInvariants(mock_a)
+ self.assertInWithManagerInvariants(mock_b)
+ self.assertInWithGeneratorInvariants(self.foo)
+ self.assertInWithGeneratorInvariants(self.bar)
+ self.raiseTestException()
+ self.assertRaises(RuntimeError, shouldThrow)
+ self.assertAfterWithManagerInvariantsWithError(mock_a)
+ self.assertAfterWithManagerInvariantsNoError(mock_b)
+ self.assertAfterWithGeneratorInvariantsWithError(self.foo)
+ self.assertAfterWithGeneratorInvariantsNoError(self.bar)
+
+
+class NonLocalFlowControlTestCase(unittest.TestCase):
+
+ def testWithBreak(self):
+ counter = 0
+ while True:
+ counter += 1
+ with mock_contextmanager_generator():
+ counter += 10
+ break
+ counter += 100 # Not reached
+ self.assertEqual(counter, 11)
+
+ def testWithContinue(self):
+ counter = 0
+ while True:
+ counter += 1
+ if counter > 2:
+ break
+ with mock_contextmanager_generator():
+ counter += 10
+ continue
+ counter += 100 # Not reached
+ self.assertEqual(counter, 12)
+
+ def testWithReturn(self):
+ def foo():
+ counter = 0
+ while True:
+ counter += 1
+ with mock_contextmanager_generator():
+ counter += 10
+ return counter
+ counter += 100 # Not reached
+ self.assertEqual(foo(), 11)
+
+ def testWithYield(self):
+ def gen():
+ with mock_contextmanager_generator():
+ yield 12
+ yield 13
+ x = list(gen())
+ self.assertEqual(x, [12, 13])
+
+ def testWithRaise(self):
+ counter = 0
+ try:
+ counter += 1
+ with mock_contextmanager_generator():
+ counter += 10
+ raise RuntimeError
+ counter += 100 # Not reached
+ except RuntimeError:
+ self.assertEqual(counter, 11)
+ else:
+ self.fail("Didn't raise RuntimeError")
+
+
+class AssignmentTargetTestCase(unittest.TestCase):
+
+ def testSingleComplexTarget(self):
+ targets = {1: [0, 1, 2]}
+ with mock_contextmanager_generator() as targets[1][0]:
+ self.assertEqual(targets.keys(), [1])
+ self.assertEqual(targets[1][0].__class__, MockResource)
+ with mock_contextmanager_generator() as targets.values()[0][1]:
+ self.assertEqual(targets.keys(), [1])
+ self.assertEqual(targets[1][1].__class__, MockResource)
+ with mock_contextmanager_generator() as targets[2]:
+ keys = targets.keys()
+ keys.sort()
+ self.assertEqual(keys, [1, 2])
+ class C: pass
+ blah = C()
+ with mock_contextmanager_generator() as blah.foo:
+ self.assertEqual(hasattr(blah, "foo"), True)
+
+ def testMultipleComplexTargets(self):
+ class C:
+ def __context__(self): return self
+ def __enter__(self): return 1, 2, 3
+ def __exit__(self, *a): pass
+ targets = {1: [0, 1, 2]}
+ with C() as (targets[1][0], targets[1][1], targets[1][2]):
+ self.assertEqual(targets, {1: [1, 2, 3]})
+ with C() as (targets.values()[0][2], targets.values()[0][1], targets.values()[0][0]):
+ self.assertEqual(targets, {1: [3, 2, 1]})
+ with C() as (targets[1], targets[2], targets[3]):
+ self.assertEqual(targets, {1: 1, 2: 2, 3: 3})
+ class B: pass
+ blah = B()
+ with C() as (blah.one, blah.two, blah.three):
+ self.assertEqual(blah.one, 1)
+ self.assertEqual(blah.two, 2)
+ self.assertEqual(blah.three, 3)
+
+
+def test_main():
+ run_unittest(FailureTestCase, NonexceptionalTestCase,
+ NestedNonexceptionalTestCase, ExceptionalTestCase,
+ NonLocalFlowControlTestCase,
+ AssignmentTargetTestCase)
+
+
+if __name__ == '__main__':
+ test_main()
|