diff --git a/Doc/library/exceptions.rst b/Doc/library/exceptions.rst index 9fa5022d901..7b1f1b9a72d 100644 --- a/Doc/library/exceptions.rst +++ b/Doc/library/exceptions.rst @@ -153,11 +153,13 @@ The following exceptions are the exceptions that are actually raised. .. exception:: GeneratorExit Raise when a :term:`generator`\'s :meth:`close` method is called. It - directly inherits from :exc:`Exception` instead of :exc:`StandardError` since + directly inherits from :exc:`BaseException` instead of :exc:`StandardError` since it is technically not an error. .. versionadded:: 2.5 + .. versionchanged:: 2.6 + Changed to inherit from :exc:`BaseException`. .. exception:: IOError diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index 706d0f19516..0f45f94ce34 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -430,9 +430,6 @@ generator functions:: ... while True: ... try: ... value = (yield value) - ... except GeneratorExit: - ... # never catch GeneratorExit - ... raise ... except Exception, e: ... value = e ... finally: diff --git a/Lib/test/exception_hierarchy.txt b/Lib/test/exception_hierarchy.txt index a03f7bbd718..1be5ce09be8 100644 --- a/Lib/test/exception_hierarchy.txt +++ b/Lib/test/exception_hierarchy.txt @@ -1,8 +1,8 @@ BaseException +-- SystemExit +-- KeyboardInterrupt + +-- GeneratorExit +-- Exception - +-- GeneratorExit +-- StopIteration +-- StandardError | +-- ArithmeticError @@ -33,10 +33,10 @@ BaseException | +-- SystemError | +-- TypeError | +-- ValueError - | | +-- UnicodeError - | | +-- UnicodeDecodeError - | | +-- UnicodeEncodeError - | | +-- UnicodeTranslateError + | +-- UnicodeError + | +-- UnicodeDecodeError + | +-- UnicodeEncodeError + | +-- UnicodeTranslateError +-- Warning +-- DeprecationWarning +-- PendingDeprecationWarning diff --git a/Lib/test/test_generators.py b/Lib/test/test_generators.py index 5d50187b2c6..ce3db72e66c 100644 --- a/Lib/test/test_generators.py +++ b/Lib/test/test_generators.py @@ -1658,6 +1658,19 @@ And finalization: exiting +GeneratorExit is not caught by except Exception: + +>>> def f(): +... try: yield +... except Exception: print 'except' +... finally: print 'finally' + +>>> g = f() +>>> g.next() +>>> del g +finally + + Now let's try some ill-behaved generators: >>> def f(): diff --git a/Misc/NEWS b/Misc/NEWS index a1d1160fe55..4c3369c7e63 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -305,6 +305,8 @@ Core and builtins - Bug #1664966: Fix crash in exec if Unicode filename can't be decoded. +- Issue #1537: Changed GeneratorExit's base class from Exception to BaseException. + Library ------- diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 64f655ceb07..f7c44e7e5c9 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -437,9 +437,9 @@ SimpleExtendsException(PyExc_Exception, StopIteration, /* - * GeneratorExit extends Exception + * GeneratorExit extends BaseException */ -SimpleExtendsException(PyExc_Exception, GeneratorExit, +SimpleExtendsException(PyExc_BaseException, GeneratorExit, "Request that a generator exit.");