Index: Python/errors.c =================================================================== --- Python/errors.c (revision 53303) +++ Python/errors.c (working copy) @@ -629,84 +629,6 @@ Py_XDECREF(tb); } -extern PyObject *PyModule_GetWarningsModule(void); - -/* Function to issue a warning message; may raise an exception. */ -int -PyErr_WarnEx(PyObject *category, const char *message, Py_ssize_t stack_level) -{ - PyObject *dict, *func = NULL; - PyObject *warnings_module = PyModule_GetWarningsModule(); - - if (warnings_module != NULL) { - dict = PyModule_GetDict(warnings_module); - if (dict != NULL) - func = PyDict_GetItemString(dict, "warn"); - } - if (func == NULL) { - PySys_WriteStderr("warning: %s\n", message); - return 0; - } - else { - PyObject *res; - - if (category == NULL) - category = PyExc_RuntimeWarning; - res = PyObject_CallFunction(func, "sOn", - message, category, stack_level); - if (res == NULL) - return -1; - Py_DECREF(res); - return 0; - } -} - -/* PyErr_Warn is only for backwards compatability and will be removed. - Use PyErr_WarnEx instead. */ - -#undef PyErr_Warn - -PyAPI_FUNC(int) -PyErr_Warn(PyObject *category, char *message) -{ - return PyErr_WarnEx(category, message, 1); -} - -/* Warning with explicit origin */ -int -PyErr_WarnExplicit(PyObject *category, const char *message, - const char *filename, int lineno, - const char *module, PyObject *registry) -{ - PyObject *mod, *dict, *func = NULL; - - mod = PyImport_ImportModule("warnings"); - if (mod != NULL) { - dict = PyModule_GetDict(mod); - func = PyDict_GetItemString(dict, "warn_explicit"); - Py_DECREF(mod); - } - if (func == NULL) { - PySys_WriteStderr("warning: %s\n", message); - return 0; - } - else { - PyObject *res; - - if (category == NULL) - category = PyExc_RuntimeWarning; - if (registry == NULL) - registry = Py_None; - res = PyObject_CallFunction(func, "sOsizO", message, category, - filename, lineno, module, registry); - if (res == NULL) - return -1; - Py_DECREF(res); - return 0; - } -} - - /* Set file and line information for the current exception. If the exception is not a SyntaxError, also sets additional attributes to make printing of exceptions believe it is a syntax error. */ Index: Python/traceback.c =================================================================== --- Python/traceback.c (revision 53303) +++ Python/traceback.c (working copy) @@ -123,8 +123,8 @@ return 0; } -static int -tb_displayline(PyObject *f, char *filename, int lineno, char *name) +int +Py_DisplayLine(PyObject *f, const char *filename, int lineno, const char *name) { int err = 0; FILE *xfp; @@ -138,7 +138,7 @@ if (xfp == NULL) { /* Search tail of filename in sys.path before giving up */ PyObject *path; - char *tail = strrchr(filename, SEP); + const char *tail = strrchr(filename, SEP); if (tail == NULL) tail = filename; else @@ -212,10 +212,10 @@ } static int -tb_printinternal(PyTracebackObject *tb, PyObject *f, int limit) +tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit) { int err = 0; - int depth = 0; + long depth = 0; PyTracebackObject *tb1 = tb; while (tb1 != NULL) { depth++; @@ -223,7 +223,7 @@ } while (tb != NULL && err == 0) { if (depth <= limit) { - err = tb_displayline(f, + err = Py_DisplayLine(f, PyString_AsString( tb->tb_frame->f_code->co_filename), tb->tb_lineno, @@ -242,7 +242,7 @@ { int err; PyObject *limitv; - int limit = 1000; + long limit = 1000; if (v == NULL) return 0; if (!PyTraceBack_Check(v)) { Index: Python/pythonrun.c =================================================================== --- Python/pythonrun.c (revision 53303) +++ Python/pythonrun.c (working copy) @@ -79,38 +79,12 @@ true divisions (which they will be in 2.3). */ int _Py_QnewFlag = 0; -/* Reference to 'warnings' module, to avoid importing it - on the fly when the import lock may be held. See 683658/771097 -*/ -static PyObject *warnings_module = NULL; - -/* Returns a borrowed reference to the 'warnings' module, or NULL. - If the module is returned, it is guaranteed to have been obtained - without acquiring the import lock -*/ -PyObject *PyModule_GetWarningsModule(void) +/* PyModule_GetWarningsModule is no longer necessary as of 2.6 +since _warnings is builtin. This API should not be used. */ +PyObject * +PyModule_GetWarningsModule(void) { - PyObject *typ, *val, *tb; - PyObject *all_modules; - /* If we managed to get the module at init time, just use it */ - if (warnings_module) - return warnings_module; - /* If it wasn't available at init time, it may be available - now in sys.modules (common scenario is frozen apps: import - at init time fails, but the frozen init code sets up sys.path - correctly, then does an implicit import of warnings for us - */ - /* Save and restore any exceptions */ - PyErr_Fetch(&typ, &val, &tb); - - all_modules = PySys_GetObject("modules"); - if (all_modules) { - warnings_module = PyDict_GetItemString(all_modules, "warnings"); - /* We keep a ref in the global */ - Py_XINCREF(warnings_module); - } - PyErr_Restore(typ, val, tb); - return warnings_module; + return NULL; } static int initialized = 0; @@ -242,10 +216,6 @@ _PyGILState_Init(interp, tstate); #endif /* WITH_THREAD */ - warnings_module = PyImport_ImportModule("warnings"); - if (!warnings_module) - PyErr_Clear(); - #if defined(Py_USING_UNICODE) && defined(HAVE_LANGINFO_H) && defined(CODESET) /* On Unix, set the file system encoding according to the user's preference, if the CODESET names a well-known @@ -362,10 +332,6 @@ /* Disable signal handling */ PyOS_FiniInterrupts(); - /* drop module references we saved */ - Py_XDECREF(warnings_module); - warnings_module = NULL; - /* Collect garbage. This may call finalizers; it's nice to call these * before all modules are destroyed. * XXX If a __del__ or weakref callback is triggered here, and tries to Index: PCbuild/pythoncore.vcproj =================================================================== --- PCbuild/pythoncore.vcproj (revision 53303) +++ PCbuild/pythoncore.vcproj (working copy) @@ -398,6 +398,9 @@ RelativePath="..\Modules\_typesmodule.c"> + + " - if module[-3:].lower() == ".py": - module = module[:-3] # XXX What about leading pathname? - if registry is None: - registry = {} - if isinstance(message, Warning): - text = str(message) - category = message.__class__ - else: - text = message - message = category(message) - key = (text, category, lineno) - # Quick test for common case - if registry.get(key): - return - # Search the filters - for item in filters: - action, msg, cat, mod, ln = item - if ((msg is None or msg.match(text)) and - issubclass(category, cat) and - (mod is None or mod.match(module)) and - (ln == 0 or lineno == ln)): - break - else: - action = defaultaction - # Early exit actions - if action == "ignore": - registry[key] = 1 - return - - # Prime the linecache for formatting, in case the - # "file" is actually in a zipfile or something. - linecache.getlines(filename, module_globals) - - if action == "error": - raise message - # Other actions - if action == "once": - registry[key] = 1 - oncekey = (text, category) - if onceregistry.get(oncekey): - return - onceregistry[oncekey] = 1 - elif action == "always": - pass - elif action == "module": - registry[key] = 1 - altkey = (text, category, 0) - if registry.get(altkey): - return - registry[altkey] = 1 - elif action == "default": - registry[key] = 1 - else: - # Unrecognized actions are errors - raise RuntimeError( - "Unrecognized action (%r) in warnings.filters:\n %s" % - (action, item)) - # Print message and context - showwarning(message, category, filename, lineno) - def showwarning(message, category, filename, lineno, file=None): """Hook to write a warning to a file; replace if you like.""" if file is None: @@ -139,7 +35,7 @@ s = "%s:%s: %s: %s\n" % (filename, lineno, category.__name__, message) line = linecache.getline(filename, lineno).strip() if line: - s = s + " " + line + "\n" + s += " %s\n" % line return s def filterwarnings(action, message="", category=Warning, module="", lineno=0, @@ -260,5 +156,3 @@ # Module initialization _processoptions(sys.warnoptions) -simplefilter("ignore", category=PendingDeprecationWarning, append=1) -simplefilter("ignore", category=ImportWarning, append=1) Index: Lib/test/test_warnings.py =================================================================== --- Lib/test/test_warnings.py (revision 53303) +++ Lib/test/test_warnings.py (working copy) @@ -1,44 +1,47 @@ import warnings import os +import sys import unittest +import StringIO from test import test_support # The warnings module isn't easily tested, because it relies on module # globals to store configuration information. setUp() and tearDown() # preserve the current settings to avoid bashing them while running tests. -# To capture the warning messages, a replacement for showwarning() is -# used to save warning information in a global variable. - class WarningMessage: "Holds results of latest showwarning() call" pass -def showwarning(message, category, filename, lineno, file=None): - msg.message = str(message) - msg.category = category.__name__ +def showwarning(output): + first_line = output.getvalue().split('\n')[0] + filename, lineno, category, message = first_line.split(':') + output.buf = '' + + msg = UserWarning() + msg.message = message.lstrip() + msg.category = category.lstrip() msg.filename = os.path.basename(filename) msg.lineno = lineno + return msg class TestModule(unittest.TestCase): def setUp(self): - global msg - msg = WarningMessage() + sys.stderr = StringIO.StringIO() self._filters = warnings.filters[:] - self._showwarning = warnings.showwarning - warnings.showwarning = showwarning self.ignored = [w[2].__name__ for w in self._filters if w[0]=='ignore' and w[1] is None and w[3] is None] def tearDown(self): - warnings.filters = self._filters[:] - warnings.showwarning = self._showwarning + warnings.filters[:] = self._filters[:] + sys.stderr = sys.__stderr__ def test_warn_default_category(self): for i in range(4): - text = 'multi %d' %i # Different text on each call + text = 'multi %d' % i # Different text on each call warnings.warn(text) + msg = showwarning(sys.stderr) self.assertEqual(msg.message, text) self.assertEqual(msg.category, 'UserWarning') @@ -50,34 +53,44 @@ if category.__name__ in self.ignored: text = 'filtered out' + category.__name__ warnings.warn(text, category) - self.assertNotEqual(msg.message, text) + self.assertEqual(sys.stderr.getvalue(), '') else: text = 'unfiltered %s' % category.__name__ warnings.warn(text, category) + msg = showwarning(sys.stderr) self.assertEqual(msg.message, text) self.assertEqual(msg.category, category.__name__) + def test_aaa(self): + warnings.filterwarnings("error", "", Warning, "", 0) + self.assertRaises(UserWarning, warnings.warn, 'convert to error') + + def test_bbb(self): + warnings._setoption('error::Warning::0') + self.assertRaises(UserWarning, warnings.warn, 'convert to error') + def test_filtering(self): - warnings.filterwarnings("error", "", Warning, "", 0) self.assertRaises(UserWarning, warnings.warn, 'convert to error') warnings.resetwarnings() text = 'handle normally' warnings.warn(text) + msg = showwarning(sys.stderr) self.assertEqual(msg.message, text) self.assertEqual(msg.category, 'UserWarning') warnings.filterwarnings("ignore", "", Warning, "", 0) text = 'filtered out' warnings.warn(text) - self.assertNotEqual(msg.message, text) + self.assertEqual(sys.stderr.getvalue(), '') warnings.resetwarnings() warnings.filterwarnings("error", "hex*", Warning, "", 0) self.assertRaises(UserWarning, warnings.warn, 'hex/oct') text = 'nonmatching text' warnings.warn(text) + msg = showwarning(sys.stderr) self.assertEqual(msg.message, text) self.assertEqual(msg.category, 'UserWarning') Index: Makefile.pre.in =================================================================== --- Makefile.pre.in (revision 53303) +++ Makefile.pre.in (working copy) @@ -251,6 +251,7 @@ Python/getcompiler.o \ Python/getcopyright.o \ Python/getmtime.o \ + Python/getopt.o \ Python/getplatform.o \ Python/getversion.o \ Python/graminit.o \ @@ -264,13 +265,13 @@ Python/pyarena.o \ Python/pyfpe.o \ Python/pystate.o \ + Python/pystrtod.o \ Python/pythonrun.o \ Python/structmember.o \ Python/symtable.o \ Python/sysmodule.o \ Python/traceback.o \ - Python/getopt.o \ - Python/pystrtod.o \ + Python/_warnings.o \ Python/$(DYNLOADFILE) \ $(MACHDEP_OBJS) \ $(THREADOBJ) Index: PCbuild8/pythoncore.vcproj =================================================================== --- PCbuild8/pythoncore.vcproj (revision 53303) +++ PCbuild8/pythoncore.vcproj (working copy) @@ -1299,6 +1299,9 @@ +