summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorChristian Heimes <christian@cheimes.de>2008-04-13 13:53:33 (GMT)
committerChristian Heimes <christian@cheimes.de>2008-04-13 13:53:33 (GMT)
commit33fe8093df5c13e41d7dba764279c71c142a4a7d (patch)
tree9a9faea193e40abff9ef66c16a582d897daf6bdf /Lib
parent659d32df786551044c1265ecb7aac50f7d564c38 (diff)
downloadcpython-33fe8093df5c13e41d7dba764279c71c142a4a7d.zip
cpython-33fe8093df5c13e41d7dba764279c71c142a4a7d.tar.gz
cpython-33fe8093df5c13e41d7dba764279c71c142a4a7d.tar.bz2
Merged revisions 62260-62261,62266,62271,62277-62279,62289-62290,62293-62298,62302-62306,62308,62311,62313-62315,62319-62321 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r62260 | gregory.p.smith | 2008-04-10 01:11:56 +0200 (Thu, 10 Apr 2008) | 2 lines better diagnostics ........ r62261 | gregory.p.smith | 2008-04-10 01:16:37 +0200 (Thu, 10 Apr 2008) | 3 lines Raise SystemError when size < 0 is passed into PyString_FromStringAndSize, PyBytes_FromStringAndSize or PyUnicode_FromStringAndSize. [issue2587] ........ r62266 | neal.norwitz | 2008-04-10 07:46:39 +0200 (Thu, 10 Apr 2008) | 5 lines Remove the test file before writing it in case there is no write permission. This might help fix some of the failures on Windows box(es). It doesn't hurt either way and ensure the tests are a little more self contained (ie have less assumptions). ........ r62271 | gregory.p.smith | 2008-04-10 21:50:36 +0200 (Thu, 10 Apr 2008) | 2 lines get rid of assert (size >= 0) now that an explicit if (size < 0) is in the code. ........ r62277 | andrew.kuchling | 2008-04-10 23:27:10 +0200 (Thu, 10 Apr 2008) | 1 line Remove forward-looking statement ........ r62278 | andrew.kuchling | 2008-04-10 23:28:51 +0200 (Thu, 10 Apr 2008) | 1 line Add punctuation ........ r62279 | andrew.kuchling | 2008-04-10 23:29:01 +0200 (Thu, 10 Apr 2008) | 1 line Use issue directive ........ r62289 | thomas.heller | 2008-04-11 15:05:38 +0200 (Fri, 11 Apr 2008) | 3 lines Move backwards compatibility macro to the correct place; PyIndex_Check() was introduced in Python 2.5. ........ r62290 | thomas.heller | 2008-04-11 16:20:26 +0200 (Fri, 11 Apr 2008) | 2 lines Performance improvements. ........ r62293 | christian.heimes | 2008-04-12 15:03:03 +0200 (Sat, 12 Apr 2008) | 2 lines Applied patch #2617 from Frank Wierzbicki wit some extras from me -J and -X are now reserved for Jython and non-standard arguments (e.g. IronPython). I've added some extra comments to make sure the reservation don't get missed in the future. ........ r62294 | georg.brandl | 2008-04-12 20:11:18 +0200 (Sat, 12 Apr 2008) | 2 lines Use absolute path in sys.path. ........ r62295 | georg.brandl | 2008-04-12 20:36:09 +0200 (Sat, 12 Apr 2008) | 2 lines #2615: small consistency update by Jeroen Ruigrok van der Werven. ........ r62296 | georg.brandl | 2008-04-12 21:00:20 +0200 (Sat, 12 Apr 2008) | 2 lines Add Jeroen. ........ r62297 | georg.brandl | 2008-04-12 21:05:37 +0200 (Sat, 12 Apr 2008) | 2 lines Don't offend snake lovers. ........ r62298 | gregory.p.smith | 2008-04-12 22:37:48 +0200 (Sat, 12 Apr 2008) | 2 lines fix compiler warnings ........ r62302 | gregory.p.smith | 2008-04-13 00:24:04 +0200 (Sun, 13 Apr 2008) | 3 lines socket.error inherits from IOError, it no longer needs listing in the all_errors tuple. ........ r62303 | brett.cannon | 2008-04-13 01:44:07 +0200 (Sun, 13 Apr 2008) | 8 lines Re-implement the 'warnings' module in C. This allows for usage of the 'warnings' code in places where it was previously not possible (e.g., the parser). It could also potentially lead to a speed-up in interpreter start-up if the C version of the code (_warnings) is imported over the use of the Python version in key places. Closes issue #1631171. ........ r62304 | gregory.p.smith | 2008-04-13 02:03:25 +0200 (Sun, 13 Apr 2008) | 3 lines Adds a profile-opt target for easy compilation of a python binary using gcc's profile guided optimization. ........ r62305 | brett.cannon | 2008-04-13 02:18:44 +0200 (Sun, 13 Apr 2008) | 3 lines Fix a bug in PySys_HasWarnOption() where it was not properly checking the length of the list storing the warning options. ........ r62306 | brett.cannon | 2008-04-13 02:25:15 +0200 (Sun, 13 Apr 2008) | 2 lines Fix an accidental bug of an non-existent init function. ........ r62308 | andrew.kuchling | 2008-04-13 03:05:59 +0200 (Sun, 13 Apr 2008) | 1 line Mention -J, -X ........ r62311 | benjamin.peterson | 2008-04-13 04:20:05 +0200 (Sun, 13 Apr 2008) | 2 lines Give the "Interactive Interpreter Changes" section in 2.6 whatsnew a unique link name ........ r62313 | brett.cannon | 2008-04-13 04:42:36 +0200 (Sun, 13 Apr 2008) | 3 lines Fix test_warnings by making the state of things more consistent for each test when it is run. ........ r62314 | skip.montanaro | 2008-04-13 05:17:30 +0200 (Sun, 13 Apr 2008) | 2 lines spelling ........ r62315 | georg.brandl | 2008-04-13 09:07:44 +0200 (Sun, 13 Apr 2008) | 2 lines Fix markup. ........ r62319 | christian.heimes | 2008-04-13 11:30:17 +0200 (Sun, 13 Apr 2008) | 1 line Fix compiler warning Include/warnings.h:19:28: warning: no newline at end of file ........ r62320 | christian.heimes | 2008-04-13 11:33:24 +0200 (Sun, 13 Apr 2008) | 1 line Use PyString_InternFromString instead of PyString_FromString for static vars ........ r62321 | christian.heimes | 2008-04-13 11:37:05 +0200 (Sun, 13 Apr 2008) | 1 line Added new files to the pcbuild files ........
Diffstat (limited to 'Lib')
-rw-r--r--Lib/ftplib.py2
-rwxr-xr-xLib/test/test_array.py1
-rw-r--r--Lib/test/test_deque.py2
-rw-r--r--Lib/test/test_support.py32
-rw-r--r--Lib/test/test_uu.py2
-rw-r--r--Lib/test/test_warnings.py427
-rw-r--r--Lib/warnings.py271
7 files changed, 520 insertions, 217 deletions
diff --git a/Lib/ftplib.py b/Lib/ftplib.py
index 8813d3c..eec20f5 100644
--- a/Lib/ftplib.py
+++ b/Lib/ftplib.py
@@ -65,7 +65,7 @@ class error_proto(Error): pass # response does not begin with [1-5]
# All exceptions (hopefully) that may be raised here and that aren't
# (always) programming errors on our side
-all_errors = (Error, socket.error, IOError, EOFError)
+all_errors = (Error, IOError, EOFError)
# Line terminators (we always output CRLF, but accept any of CRLF, CR, LF)
diff --git a/Lib/test/test_array.py b/Lib/test/test_array.py
index 5e4bde6..70fac66 100755
--- a/Lib/test/test_array.py
+++ b/Lib/test/test_array.py
@@ -162,6 +162,7 @@ class BaseTest(unittest.TestCase):
def test_tofromfile(self):
a = array.array(self.typecode, 2*self.example)
self.assertRaises(TypeError, a.tofile)
+ test_support.unlink(test_support.TESTFN)
f = open(test_support.TESTFN, 'wb')
try:
a.tofile(f)
diff --git a/Lib/test/test_deque.py b/Lib/test/test_deque.py
index c8d0c7e..cb59579 100644
--- a/Lib/test/test_deque.py
+++ b/Lib/test/test_deque.py
@@ -64,6 +64,7 @@ class TestBasic(unittest.TestCase):
self.assertEqual(list(d), [7, 8, 9])
d = deque(range(200), maxlen=10)
d.append(d)
+ test_support.unlink(test_support.TESTFN)
fo = open(test_support.TESTFN, "w")
try:
fo.write(str(d))
@@ -283,6 +284,7 @@ class TestBasic(unittest.TestCase):
d = deque(range(200))
d.append(d)
try:
+ test_support.unlink(test_support.TESTFN)
fo = open(test_support.TESTFN, "w")
print(d, file=fo, end='')
fo.close()
diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py
index b60f98c..f61e70a 100644
--- a/Lib/test/test_support.py
+++ b/Lib/test/test_support.py
@@ -354,14 +354,26 @@ class WarningMessage(object):
self.filename = None
self.lineno = None
- def _showwarning(self, message, category, filename, lineno, file=None):
+ def _showwarning(self, message, category, filename, lineno, file=None,
+ line=None):
self.message = message
self.category = category
self.filename = filename
self.lineno = lineno
+ self.line = line
+
+ def reset(self):
+ self._showwarning(*((None,)*6))
+
+ def __str__(self):
+ return ("{message : %r, category : %r, filename : %r, lineno : %s, "
+ "line : %r}" % (self.message,
+ self.category.__name__ if self.category else None,
+ self.filename, self.lineno, self.line))
+
@contextlib.contextmanager
-def catch_warning():
+def catch_warning(module=warnings):
"""
Guard the warnings filter from being permanently changed and record the
data of the last warning that has been issued.
@@ -372,15 +384,15 @@ def catch_warning():
warnings.warn("foo")
assert str(w.message) == "foo"
"""
- warning = WarningMessage()
- original_filters = warnings.filters[:]
- original_showwarning = warnings.showwarning
- warnings.showwarning = warning._showwarning
+ warning_obj = WarningMessage()
+ original_filters = module.filters[:]
+ original_showwarning = module.showwarning
+ module.showwarning = warning_obj._showwarning
try:
- yield warning
+ yield warning_obj
finally:
- warnings.showwarning = original_showwarning
- warnings.filters = original_filters
+ module.showwarning = original_showwarning
+ module.filters = original_filters
class EnvironmentVarGuard(object):
@@ -542,7 +554,7 @@ def bigmemtest(minsize, memuse, overhead=5*_1M):
'minsize' is the minimum useful size for the test (in arbitrary,
test-interpreted units.) 'memuse' is the number of 'bytes per size' for
the test, or a good estimate of it. 'overhead' specifies fixed overhead,
- independant of the testsize, and defaults to 5Mb.
+ independent of the testsize, and defaults to 5Mb.
The decorator tries to guess a good value for 'size' and passes it to
the decorated test function. If minsize * memuse is more than the
diff --git a/Lib/test/test_uu.py b/Lib/test/test_uu.py
index 4723174..b4bb32b 100644
--- a/Lib/test/test_uu.py
+++ b/Lib/test/test_uu.py
@@ -121,6 +121,7 @@ class UUFileTest(unittest.TestCase):
def test_encode(self):
fin = fout = None
try:
+ test_support.unlink(self.tmpin)
fin = open(self.tmpin, 'wb')
fin.write(plaintext)
fin.close()
@@ -150,6 +151,7 @@ class UUFileTest(unittest.TestCase):
def test_decode(self):
f = None
try:
+ test_support.unlink(self.tmpin)
f = open(self.tmpin, 'wb')
f.write(encodedtextwrapped(0o644, self.tmpout))
f.close()
diff --git a/Lib/test/test_warnings.py b/Lib/test/test_warnings.py
index 8206202..c4fce47 100644
--- a/Lib/test/test_warnings.py
+++ b/Lib/test/test_warnings.py
@@ -1,4 +1,4 @@
-import warnings
+from contextlib import contextmanager
import linecache
import os
from io import StringIO
@@ -8,112 +8,358 @@ from test import test_support
from test import warning_tests
-class TestModule(unittest.TestCase):
+import warnings as original_warnings
+
+sys.modules['_warnings'] = 0
+del sys.modules['warnings']
+
+import warnings as py_warnings
+
+del sys.modules['_warnings']
+del sys.modules['warnings']
+
+import warnings as c_warnings
+
+sys.modules['warnings'] = original_warnings
+
+
+@contextmanager
+def warnings_state(module):
+ """Use a specific warnings implementation in warning_tests."""
+ global __warningregistry__
+ for to_clear in (sys, warning_tests):
+ try:
+ to_clear.__warningregistry__.clear()
+ except AttributeError:
+ pass
+ try:
+ __warningregistry__.clear()
+ except NameError:
+ pass
+ original_warnings = warning_tests.warnings
+ try:
+ warning_tests.warnings = module
+ yield
+ finally:
+ warning_tests.warnings = original_warnings
+
+
+class BaseTest(unittest.TestCase):
+
+ """Basic bookkeeping required for testing."""
+
def setUp(self):
- self.ignored = [w[2].__name__ for w in warnings.filters
- if w[0]=='ignore' and w[1] is None and w[3] is None]
+ # The __warningregistry__ needs to be in a pristine state for tests
+ # to work properly.
+ if '__warningregistry__' in globals():
+ del globals()['__warningregistry__']
+ if hasattr(warning_tests, '__warningregistry__'):
+ del warning_tests.__warningregistry__
+ if hasattr(sys, '__warningregistry__'):
+ del sys.__warningregistry__
+ # The 'warnings' module must be explicitly set so that the proper
+ # interaction between _warnings and 'warnings' can be controlled.
+ sys.modules['warnings'] = self.module
+ super(BaseTest, self).setUp()
+
+ def tearDown(self):
+ sys.modules['warnings'] = original_warnings
+ super(BaseTest, self).tearDown()
- def test_warn_default_category(self):
- with test_support.catch_warning() as w:
- for i in range(4):
- text = 'multi %d' %i # Different text on each call
- warnings.warn(text)
- self.assertEqual(str(w.message), text)
- self.assert_(w.category is UserWarning)
- def test_warn_specific_category(self):
- with test_support.catch_warning() as w:
- text = 'None'
- for category in [DeprecationWarning, FutureWarning,
- PendingDeprecationWarning, RuntimeWarning,
- SyntaxWarning, UserWarning, Warning]:
- if category.__name__ in self.ignored:
- text = 'filtered out' + category.__name__
- warnings.warn(text, category)
- self.assertNotEqual(w.message, text)
+class FilterTests(object):
+
+ """Testing the filtering functionality."""
+
+ def test_error(self):
+ with test_support.catch_warning(self.module) as w:
+ self.module.resetwarnings()
+ self.module.filterwarnings("error", category=UserWarning)
+ self.assertRaises(UserWarning, self.module.warn,
+ "FilterTests.test_error")
+
+ def test_ignore(self):
+ with test_support.catch_warning(self.module) as w:
+ self.module.resetwarnings()
+ self.module.filterwarnings("ignore", category=UserWarning)
+ self.module.warn("FilterTests.test_ignore", UserWarning)
+ self.assert_(not w.message)
+
+ def test_always(self):
+ with test_support.catch_warning(self.module) as w:
+ self.module.resetwarnings()
+ self.module.filterwarnings("always", category=UserWarning)
+ message = "FilterTests.test_always"
+ self.module.warn(message, UserWarning)
+ self.assert_(message, w.message)
+ w.message = None # Reset.
+ self.module.warn(message, UserWarning)
+ self.assert_(w.message, message)
+
+ def test_default(self):
+ with test_support.catch_warning(self.module) as w:
+ self.module.resetwarnings()
+ self.module.filterwarnings("default", category=UserWarning)
+ message = UserWarning("FilterTests.test_default")
+ for x in range(2):
+ self.module.warn(message, UserWarning)
+ if x == 0:
+ self.assertEquals(w.message, message)
+ w.reset()
+ elif x == 1:
+ self.assert_(not w.message, "unexpected warning: " + str(w))
else:
- text = 'unfiltered %s' % category.__name__
- warnings.warn(text, category)
- self.assertEqual(str(w.message), text)
- self.assert_(w.category is category)
+ raise ValueError("loop variant unhandled")
+
+ def test_module(self):
+ with test_support.catch_warning(self.module) as w:
+ self.module.resetwarnings()
+ self.module.filterwarnings("module", category=UserWarning)
+ message = UserWarning("FilterTests.test_module")
+ self.module.warn(message, UserWarning)
+ self.assertEquals(w.message, message)
+ w.reset()
+ self.module.warn(message, UserWarning)
+ self.assert_(not w.message, "unexpected message: " + str(w))
+
+ def test_once(self):
+ with test_support.catch_warning(self.module) as w:
+ self.module.resetwarnings()
+ self.module.filterwarnings("once", category=UserWarning)
+ message = UserWarning("FilterTests.test_once")
+ self.module.warn_explicit(message, UserWarning, "test_warnings.py",
+ 42)
+ self.assertEquals(w.message, message)
+ w.reset()
+ self.module.warn_explicit(message, UserWarning, "test_warnings.py",
+ 13)
+ self.assert_(not w.message)
+ self.module.warn_explicit(message, UserWarning, "test_warnings2.py",
+ 42)
+ self.assert_(not w.message)
- def test_filtering(self):
+ def test_inheritance(self):
+ with test_support.catch_warning(self.module) as w:
+ self.module.resetwarnings()
+ self.module.filterwarnings("error", category=Warning)
+ self.assertRaises(UserWarning, self.module.warn,
+ "FilterTests.test_inheritance", UserWarning)
+
+ def test_ordering(self):
+ with test_support.catch_warning(self.module) as w:
+ self.module.resetwarnings()
+ self.module.filterwarnings("ignore", category=UserWarning)
+ self.module.filterwarnings("error", category=UserWarning,
+ append=True)
+ w.reset()
+ try:
+ self.module.warn("FilterTests.test_ordering", UserWarning)
+ except UserWarning:
+ self.fail("order handling for actions failed")
+ self.assert_(not w.message)
+
+ def test_filterwarnings(self):
# Test filterwarnings().
# Implicitly also tests resetwarnings().
- with test_support.catch_warning() as w:
- warnings.filterwarnings("error", "", Warning, "", 0)
- self.assertRaises(UserWarning, warnings.warn, 'convert to error')
+ with test_support.catch_warning(self.module) as w:
+ self.module.filterwarnings("error", "", Warning, "", 0)
+ self.assertRaises(UserWarning, self.module.warn, 'convert to error')
- warnings.resetwarnings()
+ self.module.resetwarnings()
text = 'handle normally'
- warnings.warn(text)
+ self.module.warn(text)
self.assertEqual(str(w.message), text)
self.assert_(w.category is UserWarning)
- warnings.filterwarnings("ignore", "", Warning, "", 0)
+ self.module.filterwarnings("ignore", "", Warning, "", 0)
text = 'filtered out'
- warnings.warn(text)
+ self.module.warn(text)
self.assertNotEqual(str(w.message), text)
- warnings.resetwarnings()
- warnings.filterwarnings("error", "hex*", Warning, "", 0)
- self.assertRaises(UserWarning, warnings.warn, 'hex/oct')
+ self.module.resetwarnings()
+ self.module.filterwarnings("error", "hex*", Warning, "", 0)
+ self.assertRaises(UserWarning, self.module.warn, 'hex/oct')
text = 'nonmatching text'
- warnings.warn(text)
+ self.module.warn(text)
self.assertEqual(str(w.message), text)
self.assert_(w.category is UserWarning)
- def test_options(self):
- # Uses the private _setoption() function to test the parsing
- # of command-line warning arguments
- with test_support.catch_warning():
- self.assertRaises(warnings._OptionError,
- warnings._setoption, '1:2:3:4:5:6')
- self.assertRaises(warnings._OptionError,
- warnings._setoption, 'bogus::Warning')
- self.assertRaises(warnings._OptionError,
- warnings._setoption, 'ignore:2::4:-5')
- warnings._setoption('error::Warning::0')
- self.assertRaises(UserWarning, warnings.warn, 'convert to error')
+class CFilterTests(BaseTest, FilterTests):
+ module = c_warnings
+
+class PyFilterTests(BaseTest, FilterTests):
+ module = py_warnings
+
+
+class WarnTests(unittest.TestCase):
+
+ """Test warnings.warn() and warnings.warn_explicit()."""
+
+ def test_message(self):
+ with test_support.catch_warning(self.module) as w:
+ for i in range(4):
+ text = 'multi %d' %i # Different text on each call.
+ self.module.warn(text)
+ self.assertEqual(str(w.message), text)
+ self.assert_(w.category is UserWarning)
def test_filename(self):
- with test_support.catch_warning() as w:
- warning_tests.inner("spam1")
- self.assertEqual(os.path.basename(w.filename), "warning_tests.py")
- warning_tests.outer("spam2")
- self.assertEqual(os.path.basename(w.filename), "warning_tests.py")
+ with warnings_state(self.module):
+ with test_support.catch_warning(self.module) as w:
+ warning_tests.inner("spam1")
+ self.assertEqual(os.path.basename(w.filename), "warning_tests.py")
+ warning_tests.outer("spam2")
+ self.assertEqual(os.path.basename(w.filename), "warning_tests.py")
def test_stacklevel(self):
# Test stacklevel argument
# make sure all messages are different, so the warning won't be skipped
- with test_support.catch_warning() as w:
- warning_tests.inner("spam3", stacklevel=1)
- self.assertEqual(os.path.basename(w.filename), "warning_tests.py")
- warning_tests.outer("spam4", stacklevel=1)
- self.assertEqual(os.path.basename(w.filename), "warning_tests.py")
+ with warnings_state(self.module):
+ with test_support.catch_warning(self.module) as w:
+ warning_tests.inner("spam3", stacklevel=1)
+ self.assertEqual(os.path.basename(w.filename), "warning_tests.py")
+ warning_tests.outer("spam4", stacklevel=1)
+ self.assertEqual(os.path.basename(w.filename), "warning_tests.py")
+
+ warning_tests.inner("spam5", stacklevel=2)
+ self.assertEqual(os.path.basename(w.filename), "test_warnings.py")
+ warning_tests.outer("spam6", stacklevel=2)
+ self.assertEqual(os.path.basename(w.filename), "warning_tests.py")
+
+ warning_tests.inner("spam7", stacklevel=9999)
+ self.assertEqual(os.path.basename(w.filename), "sys")
+
+
+class CWarnTests(BaseTest, WarnTests):
+ module = c_warnings
+
+class PyWarnTests(BaseTest, WarnTests):
+ module = py_warnings
+
+
+class WCmdLineTests(unittest.TestCase):
+
+ def test_improper_input(self):
+ # Uses the private _setoption() function to test the parsing
+ # of command-line warning arguments
+ with test_support.catch_warning(self.module):
+ self.assertRaises(self.module._OptionError,
+ self.module._setoption, '1:2:3:4:5:6')
+ self.assertRaises(self.module._OptionError,
+ self.module._setoption, 'bogus::Warning')
+ self.assertRaises(self.module._OptionError,
+ self.module._setoption, 'ignore:2::4:-5')
+ self.module._setoption('error::Warning::0')
+ self.assertRaises(UserWarning, self.module.warn, 'convert to error')
+
+class CWCmdLineTests(BaseTest, WCmdLineTests):
+ module = c_warnings
+
+class PyWCmdLineTests(BaseTest, WCmdLineTests):
+ module = py_warnings
+
+
+class _WarningsTests(BaseTest):
+
+ """Tests specific to the _warnings module."""
+
+ module = c_warnings
- warning_tests.inner("spam5", stacklevel=2)
- self.assertEqual(os.path.basename(w.filename), "test_warnings.py")
- warning_tests.outer("spam6", stacklevel=2)
- self.assertEqual(os.path.basename(w.filename), "warning_tests.py")
+ def test_filter(self):
+ # Everything should function even if 'filters' is not in warnings.
+ with test_support.catch_warning(self.module) as w:
+ self.module.filterwarnings("error", "", Warning, "", 0)
+ self.assertRaises(UserWarning, self.module.warn,
+ 'convert to error')
+ del self.module.filters
+ self.assertRaises(UserWarning, self.module.warn,
+ 'convert to error')
- warning_tests.inner("spam7", stacklevel=9999)
- self.assertEqual(os.path.basename(w.filename), "sys")
+ def test_onceregistry(self):
+ # Replacing or removing the onceregistry should be okay.
+ global __warningregistry__
+ message = UserWarning('onceregistry test')
+ try:
+ original_registry = self.module.onceregistry
+ __warningregistry__ = {}
+ with test_support.catch_warning(self.module) as w:
+ self.module.resetwarnings()
+ self.module.filterwarnings("once", category=UserWarning)
+ self.module.warn_explicit(message, UserWarning, "file", 42)
+ self.failUnlessEqual(w.message, message)
+ w.reset()
+ self.module.warn_explicit(message, UserWarning, "file", 42)
+ self.assert_(not w.message)
+ # Test the resetting of onceregistry.
+ self.module.onceregistry = {}
+ __warningregistry__ = {}
+ self.module.warn('onceregistry test')
+ self.failUnlessEqual(w.message.args, message.args)
+ # Removal of onceregistry is okay.
+ w.reset()
+ del self.module.onceregistry
+ __warningregistry__ = {}
+ self.module.warn_explicit(message, UserWarning, "file", 42)
+ self.failUnless(not w.message)
+ finally:
+ self.module.onceregistry = original_registry
+
+ def test_showwarning_missing(self):
+ # Test that showwarning() missing is okay.
+ text = 'del showwarning test'
+ with test_support.catch_warning(self.module):
+ self.module.filterwarnings("always", category=UserWarning)
+ del self.module.showwarning
+ with test_support.captured_output('stderr') as stream:
+ self.module.warn(text)
+ result = stream.getvalue()
+ self.failUnless(text in result)
+
+ def test_show_warning_output(self):
+ # With showarning() missing, make sure that output is okay.
+ text = 'test show_warning'
+ with test_support.catch_warning(self.module):
+ self.module.filterwarnings("always", category=UserWarning)
+ del self.module.showwarning
+ with test_support.captured_output('stderr') as stream:
+ warning_tests.inner(text)
+ result = stream.getvalue()
+ self.failUnlessEqual(result.count('\n'), 2,
+ "Too many newlines in %r" % result)
+ first_line, second_line = result.split('\n', 1)
+ expected_file = os.path.splitext(warning_tests.__file__)[0] + '.py'
+ path, line, warning_class, message = first_line.split(':')
+ line = int(line)
+ self.failUnlessEqual(expected_file, path)
+ self.failUnlessEqual(warning_class, ' ' + UserWarning.__name__)
+ self.failUnlessEqual(message, ' ' + text)
+ expected_line = ' ' + linecache.getline(path, line).strip() + '\n'
+ assert expected_line
+ self.failUnlessEqual(second_line, expected_line)
class WarningsDisplayTests(unittest.TestCase):
+ """Test the displaying of warnings and the ability to overload functions
+ related to displaying warnings."""
+
def test_formatwarning(self):
message = "msg"
category = Warning
file_name = os.path.splitext(warning_tests.__file__)[0] + '.py'
line_num = 3
file_line = linecache.getline(file_name, line_num).strip()
- expect = "%s:%s: %s: %s\n %s\n" % (file_name, line_num, category.__name__,
- message, file_line)
- self.failUnlessEqual(warnings.formatwarning(message, category,
- file_name, line_num),
- expect)
+ format = "%s:%s: %s: %s\n %s\n"
+ expect = format % (file_name, line_num, category.__name__, message,
+ file_line)
+ self.failUnlessEqual(expect, self.module.formatwarning(message,
+ category, file_name, line_num))
+ # Test the 'line' argument.
+ file_line += " for the win!"
+ expect = format % (file_name, line_num, category.__name__, message,
+ file_line)
+ self.failUnlessEqual(expect, self.module.formatwarning(message,
+ category, file_name, line_num, file_line))
def test_showwarning(self):
file_name = os.path.splitext(warning_tests.__file__)[0] + '.py'
@@ -122,22 +368,37 @@ class WarningsDisplayTests(unittest.TestCase):
message = 'msg'
category = Warning
file_object = StringIO()
- expect = warnings.formatwarning(message, category, file_name, line_num)
- warnings.showwarning(message, category, file_name, line_num,
+ expect = self.module.formatwarning(message, category, file_name,
+ line_num)
+ self.module.showwarning(message, category, file_name, line_num,
file_object)
self.failUnlessEqual(file_object.getvalue(), expect)
+ # Test 'line' argument.
+ expected_file_line += "for the win!"
+ expect = self.module.formatwarning(message, category, file_name,
+ line_num, expected_file_line)
+ file_object = StringIO()
+ self.module.showwarning(message, category, file_name, line_num,
+ file_object, expected_file_line)
+ self.failUnlessEqual(expect, file_object.getvalue())
+
+class CWarningsDisplayTests(BaseTest, WarningsDisplayTests):
+ module = c_warnings
+
+class PyWarningsDisplayTests(BaseTest, WarningsDisplayTests):
+ module = py_warnings
+
+def test_main():
+ test_support.run_unittest(CFilterTests,
+ PyFilterTests,
+ CWarnTests,
+ PyWarnTests,
+ CWCmdLineTests, PyWCmdLineTests,
+ _WarningsTests,
+ CWarningsDisplayTests, PyWarningsDisplayTests,
+ )
-def test_main(verbose=None):
- # Obscure hack so that this test passes after reloads or repeated calls
- # to test_main (regrtest -R).
- if '__warningregistry__' in globals():
- del globals()['__warningregistry__']
- if hasattr(warning_tests, '__warningregistry__'):
- del warning_tests.__warningregistry__
- if hasattr(sys, '__warningregistry__'):
- del sys.__warningregistry__
- test_support.run_unittest(TestModule, WarningsDisplayTests)
if __name__ == "__main__":
- test_main(verbose=True)
+ test_main()
diff --git a/Lib/warnings.py b/Lib/warnings.py
index 40079ba..c95ffc3 100644
--- a/Lib/warnings.py
+++ b/Lib/warnings.py
@@ -3,143 +3,30 @@
# Note: function level imports should *not* be used
# in this module as it may cause import lock deadlock.
# See bug 683658.
-import sys
import linecache
+import sys
+import types
__all__ = ["warn", "showwarning", "formatwarning", "filterwarnings",
"resetwarnings"]
-# filters contains a sequence of filter 5-tuples
-# The components of the 5-tuple are:
-# - an action: error, ignore, always, default, module, or once
-# - a compiled regex that must match the warning message
-# - a class representing the warning category
-# - a compiled regex that must match the module that is being warned
-# - a line number for the line being warning, or 0 to mean any line
-# If either if the compiled regexs are None, match anything.
-filters = []
-defaultaction = "default"
-onceregistry = {}
-
-def warn(message, category=None, stacklevel=1):
- """Issue a warning, or maybe ignore it or raise an exception."""
- # Check if message is already a Warning object
- if isinstance(message, Warning):
- category = message.__class__
- # Check category argument
- if category is None:
- category = UserWarning
- assert issubclass(category, Warning)
- # Get context information
- try:
- caller = sys._getframe(stacklevel)
- except ValueError:
- globals = sys.__dict__
- lineno = 1
- else:
- globals = caller.f_globals
- lineno = caller.f_lineno
- if '__name__' in globals:
- module = globals['__name__']
- else:
- module = "<string>"
- filename = globals.get('__file__')
- if filename:
- fnl = filename.lower()
- if fnl.endswith((".pyc", ".pyo")):
- filename = filename[:-1]
- else:
- if module == "__main__":
- try:
- filename = sys.argv[0]
- except AttributeError:
- # embedded interpreters don't have sys.argv, see bug #839151
- filename = '__main__'
- if not filename:
- filename = module
- registry = globals.setdefault("__warningregistry__", {})
- warn_explicit(message, category, filename, lineno, module, registry,
- globals)
-
-def warn_explicit(message, category, filename, lineno,
- module=None, registry=None, module_globals=None):
- if module is None:
- module = filename or "<unknown>"
- 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):
+def showwarning(message, category, filename, lineno, file=None, line=None):
"""Hook to write a warning to a file; replace if you like."""
if file is None:
file = sys.stderr
try:
- file.write(formatwarning(message, category, filename, lineno))
+ file.write(formatwarning(message, category, filename, lineno, line))
except IOError:
pass # the file (probably stderr) is invalid - this warning gets lost.
-def formatwarning(message, category, filename, lineno):
+def formatwarning(message, category, filename, lineno, line=None):
"""Function to format a warning the standard way."""
s = "%s:%s: %s: %s\n" % (filename, lineno, category.__name__, message)
- line = linecache.getline(filename, lineno).strip()
+ line = linecache.getline(filename, lineno) if line is None else line
if line:
- s = s + " " + line + "\n"
+ line = line.strip()
+ s += " %s\n" % line
return s
def filterwarnings(action, message="", category=Warning, module="", lineno=0,
@@ -257,7 +144,145 @@ def _getcategory(category):
raise _OptionError("invalid warning category: %r" % (category,))
return cat
+
+# Code typically replaced by _warnings
+def warn(message, category=None, stacklevel=1):
+ """Issue a warning, or maybe ignore it or raise an exception."""
+ # Check if message is already a Warning object
+ if isinstance(message, Warning):
+ category = message.__class__
+ # Check category argument
+ if category is None:
+ category = UserWarning
+ assert issubclass(category, Warning)
+ # Get context information
+ try:
+ caller = sys._getframe(stacklevel)
+ except ValueError:
+ globals = sys.__dict__
+ lineno = 1
+ else:
+ globals = caller.f_globals
+ lineno = caller.f_lineno
+ if '__name__' in globals:
+ module = globals['__name__']
+ else:
+ module = "<string>"
+ filename = globals.get('__file__')
+ if filename:
+ fnl = filename.lower()
+ if fnl.endswith((".pyc", ".pyo")):
+ filename = filename[:-1]
+ else:
+ if module == "__main__":
+ try:
+ filename = sys.argv[0]
+ except AttributeError:
+ # embedded interpreters don't have sys.argv, see bug #839151
+ filename = '__main__'
+ if not filename:
+ filename = module
+ registry = globals.setdefault("__warningregistry__", {})
+ warn_explicit(message, category, filename, lineno, module, registry,
+ globals)
+
+def warn_explicit(message, category, filename, lineno,
+ module=None, registry=None, module_globals=None):
+ if module is None:
+ module = filename or "<unknown>"
+ 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)
+
+
+# filters contains a sequence of filter 5-tuples
+# The components of the 5-tuple are:
+# - an action: error, ignore, always, default, module, or once
+# - a compiled regex that must match the warning message
+# - a class representing the warning category
+# - a compiled regex that must match the module that is being warned
+# - a line number for the line being warning, or 0 to mean any line
+# If either if the compiled regexs are None, match anything.
+_warnings_defaults = False
+try:
+ from _warnings import (filters, default_action, once_registry,
+ warn, warn_explicit)
+ defaultaction = default_action
+ onceregistry = once_registry
+ _warnings_defaults = True
+except ImportError:
+ filters = []
+ defaultaction = "default"
+ onceregistry = {}
+
+
# Module initialization
_processoptions(sys.warnoptions)
-simplefilter("ignore", category=PendingDeprecationWarning, append=1)
-simplefilter("ignore", category=ImportWarning, append=1)
+if not _warnings_defaults:
+ simplefilter("ignore", category=PendingDeprecationWarning, append=1)
+ simplefilter("ignore", category=ImportWarning, append=1)
+ bytes_warning = sys.flags.bytes_warning
+ if bytes_warning > 1:
+ bytes_action = "error"
+ elif bytes_warning:
+ bytes_action = "default"
+ else:
+ bytes_action = "ignore"
+ simplefilter(bytes_action, category=BytesWarning, append=1)
+del _warnings_defaults