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
........
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 @@
 
 # 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 @@
     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 @@
         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 @@
         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 @@
         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 @@
             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 @@
     '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 @@
     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 @@
     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 warning_tests
 
-class TestModule(unittest.TestCase):
-    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]
+import warnings as original_warnings
 
-    def test_warn_default_category(self):
-        with test_support.catch_warning() as w:
+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):
+        # 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()
+
+
+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:
+                    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_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(self.module) as w:
+            self.module.filterwarnings("error", "", Warning, "", 0)
+            self.assertRaises(UserWarning, self.module.warn, 'convert to error')
+
+            self.module.resetwarnings()
+            text = 'handle normally'
+            self.module.warn(text)
+            self.assertEqual(str(w.message), text)
+            self.assert_(w.category is UserWarning)
+
+            self.module.filterwarnings("ignore", "", Warning, "", 0)
+            text = 'filtered out'
+            self.module.warn(text)
+            self.assertNotEqual(str(w.message), text)
+
+            self.module.resetwarnings()
+            self.module.filterwarnings("error", "hex*", Warning, "", 0)
+            self.assertRaises(UserWarning, self.module.warn, 'hex/oct')
+            text = 'nonmatching text'
+            self.module.warn(text)
+            self.assertEqual(str(w.message), text)
+            self.assert_(w.category is UserWarning)
+
+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
-                warnings.warn(text)
+                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_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)
-                else:
-                    text = 'unfiltered %s' % category.__name__
-                    warnings.warn(text, category)
-                    self.assertEqual(str(w.message), text)
-                    self.assert_(w.category is category)
-
-    def test_filtering(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')
-
-            warnings.resetwarnings()
-            text = 'handle normally'
-            warnings.warn(text)
-            self.assertEqual(str(w.message), text)
-            self.assert_(w.category is UserWarning)
-
-            warnings.filterwarnings("ignore", "", Warning, "", 0)
-            text = 'filtered out'
-            warnings.warn(text)
-            self.assertNotEqual(str(w.message), text)
-
-            warnings.resetwarnings()
-            warnings.filterwarnings("error", "hex*", Warning, "", 0)
-            self.assertRaises(UserWarning, warnings.warn, 'hex/oct')
-            text = 'nonmatching text'
-            warnings.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')
-
     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("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")
+                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
+
+    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')
+
+    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 @@
         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(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)
+def test_main():
+    test_support.run_unittest(CFilterTests,
+                                PyFilterTests,
+                                CWarnTests,
+                                PyWarnTests,
+                                CWCmdLineTests, PyWCmdLineTests,
+                                _WarningsTests,
+                                CWarningsDisplayTests, PyWarningsDisplayTests,
+                             )
+
 
 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 @@
         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