diff options
author | Raymond Hettinger <python@rcn.com> | 2016-11-22 01:24:58 (GMT) |
---|---|---|
committer | Raymond Hettinger <python@rcn.com> | 2016-11-22 01:24:58 (GMT) |
commit | 9af740b99a19a85ad5f38379b6175cf4ead685ba (patch) | |
tree | de76487e51219a7715b441643be24bd8827c4397 | |
parent | 21fb9f17619f8b360d2444b098f0fba511969df4 (diff) | |
parent | a3fec1543dc252934e79a4a50b1cbbf4708b4e7e (diff) | |
download | cpython-9af740b99a19a85ad5f38379b6175cf4ead685ba.zip cpython-9af740b99a19a85ad5f38379b6175cf4ead685ba.tar.gz cpython-9af740b99a19a85ad5f38379b6175cf4ead685ba.tar.bz2 |
merge
-rw-r--r-- | Lib/test/test_with.py | 15 | ||||
-rw-r--r-- | Misc/NEWS | 4 | ||||
-rw-r--r-- | Python/ceval.c | 8 |
3 files changed, 20 insertions, 7 deletions
diff --git a/Lib/test/test_with.py b/Lib/test/test_with.py index e247ff6..cbb85da 100644 --- a/Lib/test/test_with.py +++ b/Lib/test/test_with.py @@ -109,7 +109,7 @@ class FailureTestCase(unittest.TestCase): with foo: pass self.assertRaises(NameError, fooNotDeclared) - def testEnterAttributeError(self): + def testEnterAttributeError1(self): class LacksEnter(object): def __exit__(self, type, value, traceback): pass @@ -117,7 +117,16 @@ class FailureTestCase(unittest.TestCase): def fooLacksEnter(): foo = LacksEnter() with foo: pass - self.assertRaises(AttributeError, fooLacksEnter) + self.assertRaisesRegexp(AttributeError, '__enter__', fooLacksEnter) + + def testEnterAttributeError2(self): + class LacksEnterAndExit(object): + pass + + def fooLacksEnterAndExit(): + foo = LacksEnterAndExit() + with foo: pass + self.assertRaisesRegexp(AttributeError, '__enter__', fooLacksEnterAndExit) def testExitAttributeError(self): class LacksExit(object): @@ -127,7 +136,7 @@ class FailureTestCase(unittest.TestCase): def fooLacksExit(): foo = LacksExit() with foo: pass - self.assertRaises(AttributeError, fooLacksExit) + self.assertRaisesRegexp(AttributeError, '__exit__', fooLacksExit) def assertRaisesSyntaxError(self, codestr): def shouldRaiseSyntaxError(s): @@ -15,6 +15,10 @@ Core and Builtins - Issue #28532: Show sys.version when -V option is supplied twice. +- Issue #27100: The with-statement now checks for __enter__ before it + checks for __exit__. This gives less confusing error messages when + both methods are missing. Patch by Jonathan Ellington. + - Issue #28746: Fix the set_inheritable() file descriptor method on platforms that do not have the ioctl FIOCLEX and FIONCLEX commands. diff --git a/Python/ceval.c b/Python/ceval.c index b08427d..b18fd91 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -3141,15 +3141,15 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag) _Py_IDENTIFIER(__exit__); _Py_IDENTIFIER(__enter__); PyObject *mgr = TOP(); - PyObject *exit = special_lookup(mgr, &PyId___exit__), *enter; + PyObject *enter = special_lookup(mgr, &PyId___enter__), *exit; PyObject *res; + if (enter == NULL) + goto error; + exit = special_lookup(mgr, &PyId___exit__); if (exit == NULL) goto error; SET_TOP(exit); - enter = special_lookup(mgr, &PyId___enter__); Py_DECREF(mgr); - if (enter == NULL) - goto error; res = PyObject_CallFunctionObjArgs(enter, NULL); Py_DECREF(enter); if (res == NULL) |