r53605 - in python/trunk: Doc/lib/libexcs.tex Doc/ref/ref4.tex Lib/test/test_pep352.py Misc/NEWS Python/ceval.c
Author: brett.cannon Date: Tue Jan 30 22:34:36 2007 New Revision: 53605 Modified: python/trunk/Doc/lib/libexcs.tex python/trunk/Doc/ref/ref4.tex python/trunk/Lib/test/test_pep352.py python/trunk/Misc/NEWS python/trunk/Python/ceval.c Log: No more raising of string exceptions! The next step of PEP 352 (for 2.6) causes raising a string exception to trigger a TypeError. Trying to catch a string exception raises a DeprecationWarning. References to string exceptions has been removed from the docs since they are now just an error. Modified: python/trunk/Doc/lib/libexcs.tex ============================================================================== --- python/trunk/Doc/lib/libexcs.tex (original) +++ python/trunk/Doc/lib/libexcs.tex Tue Jan 30 22:34:36 2007 @@ -10,22 +10,6 @@ provided in the built-in namespace as well as the \module{exceptions} module. -\begin{notice} -In past versions of Python string exceptions were supported. In -Python 1.5 and newer versions, all standard exceptions have been -converted to class objects and users are encouraged to do the same. -String exceptions will raise a \code{DeprecationWarning} in Python 2.5 and -newer. -In future versions, support for string exceptions will be removed. - -Two distinct string objects with the same value are considered different -exceptions. This is done to force programmers to use exception names -rather than their string value when specifying exception handlers. -The string value of all built-in exceptions is their name, but this is -not a requirement for user-defined exceptions or exceptions defined by -library modules. -\end{notice} - For class exceptions, in a \keyword{try}\stindex{try} statement with an \keyword{except}\stindex{except} clause that mentions a particular class, that clause also handles any exception classes derived from Modified: python/trunk/Doc/ref/ref4.tex ============================================================================== --- python/trunk/Doc/ref/ref4.tex (original) +++ python/trunk/Doc/ref/ref4.tex Tue Jan 30 22:34:36 2007 @@ -203,10 +203,6 @@ value can be raised along with the identifying string which can be passed to the handler. -\deprecated{2.5}{String exceptions should not be used in new code. -They will not be supported in a future version of Python. Old code -should be rewritten to use class exceptions instead.} - \begin{notice}[warning] Messages to exceptions are not part of the Python API. Their contents may change from one version of Python to the next without warning and should not Modified: python/trunk/Lib/test/test_pep352.py ============================================================================== --- python/trunk/Lib/test/test_pep352.py (original) +++ python/trunk/Lib/test/test_pep352.py Tue Jan 30 22:34:36 2007 @@ -2,7 +2,7 @@ import __builtin__ import exceptions import warnings -from test.test_support import run_unittest +from test.test_support import run_unittest, guard_warnings_filter import os from platform import system as platform_system @@ -113,13 +113,8 @@ """Test usage of exceptions""" - def setUp(self): - self._filters = warnings.filters[:] - - def tearDown(self): - warnings.filters = self._filters[:] - def test_raise_classic(self): + # Raising a classic class is okay (for now). class ClassicClass: pass try: @@ -136,6 +131,10 @@ self.fail("unable to raise class class instance") def test_raise_new_style_non_exception(self): + # You cannot raise a new-style class that does not inherit from + # BaseException; the ability was not possible until BaseException's + # introduction so no need to support new-style objects that do not + # inherit from it. class NewStyleClass(object): pass try: @@ -143,35 +142,52 @@ except TypeError: pass except: - self.fail("unable to raise new-style class") + self.fail("able to raise new-style class") try: raise NewStyleClass() except TypeError: pass except: - self.fail("unable to raise new-style class instance") + self.fail("able to raise new-style class instance") def test_raise_string(self): - warnings.resetwarnings() - warnings.filterwarnings("error") + # Raising a string raises TypeError. try: raise "spam" - except DeprecationWarning: + except TypeError: pass except: - self.fail("raising a string did not cause a DeprecationWarning") + self.fail("was able to raise a string exception") def test_catch_string(self): - # Test will be pertinent when catching exceptions raises a - # DeprecationWarning - warnings.filterwarnings("ignore", "raising") - str_exc = "spam" - try: - raise str_exc - except str_exc: - pass - except: - self.fail("catching a string exception failed") + # Catching a string should trigger a DeprecationWarning. + with guard_warnings_filter(): + warnings.resetwarnings() + warnings.filterwarnings("error") + str_exc = "spam" + try: + try: + raise StandardError + except str_exc: + pass + except DeprecationWarning: + pass + except StandardError: + self.fail("catching a string exception did not raise " + "DeprecationWarning") + # Make sure that even if the string exception is listed in a tuple + # that a warning is raised. + try: + try: + raise StandardError + except (AssertionError, str_exc): + pass + except DeprecationWarning: + pass + except StandardError: + self.fail("catching a string exception specified in a tuple did " + "not raise DeprecationWarning") + def test_main(): run_unittest(ExceptionClassTests, UsageTests) Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Tue Jan 30 22:34:36 2007 @@ -12,6 +12,9 @@ Core and builtins ----------------- +- PEP 352: Raising a string exception now triggers a TypeError. Attempting to + catch a string exception raises DeprecationWarning. + - Bug #1377858: Fix the segfaulting of the interpreter when an object created a weakref on itself during a __del__ call for new-style classes (classic classes still have the bug). Modified: python/trunk/Python/ceval.c ============================================================================== --- python/trunk/Python/ceval.c (original) +++ python/trunk/Python/ceval.c Tue Jan 30 22:34:36 2007 @@ -2206,8 +2206,9 @@ case SETUP_LOOP: case SETUP_EXCEPT: case SETUP_FINALLY: - /* NOTE: If you add any new block-setup opcodes that are not try/except/finally - handlers, you may need to update the PyGen_NeedsFinalizing() function. */ + /* NOTE: If you add any new block-setup opcodes that are + not try/except/finally handlers, you may need to + update the PyGen_NeedsFinalizing() function. */ PyFrame_BlockSetup(f, opcode, INSTR_OFFSET() + oparg, STACK_LEVEL()); @@ -3069,15 +3070,7 @@ Py_DECREF(tmp); } - if (PyString_CheckExact(type)) { - /* Raising builtin string is deprecated but still allowed -- - * do nothing. Raising an instance of a new-style str - * subclass is right out. */ - if (PyErr_Warn(PyExc_DeprecationWarning, - "raising a string exception is deprecated")) - goto raise_error; - } - else if (PyExceptionClass_Check(type)) + if (PyExceptionClass_Check(type)) PyErr_NormalizeException(&type, &value, &tb); else if (PyExceptionInstance_Check(type)) { @@ -3099,8 +3092,7 @@ /* Not something you can raise. You get an exception anyway, just not what you specified :-) */ PyErr_Format(PyExc_TypeError, - "exceptions must be classes, instances, or " - "strings (deprecated), not %s", + "exceptions must be classes or instances, not %s", type->ob_type->tp_name); goto raise_error; } @@ -3985,6 +3977,35 @@ res = !res; break; case PyCmp_EXC_MATCH: + if (PyTuple_Check(w)) { + Py_ssize_t i, length; + length = PyTuple_Size(w); + for (i = 0; i < length; i += 1) { + PyObject *exc = PyTuple_GET_ITEM(w, i); + if (PyString_Check(exc)) { + int ret_val; + ret_val = PyErr_WarnEx( + PyExc_DeprecationWarning, + "catching of string " + "exceptions is " + "deprecated", 1); + if (ret_val == -1) + return NULL; + } + } + } + else { + if (PyString_Check(w)) { + int ret_val; + ret_val = PyErr_WarnEx( + PyExc_DeprecationWarning, + "catching of string " + "exceptions is deprecated", + 1); + if (ret_val == -1) + return NULL; + } + } res = PyErr_GivenExceptionMatches(v, w); break; default:
participants (1)
-
brett.cannon