Add a new test script that tests various features of the sys
module. This increases code coverage of Python/sysmodule.c
from 68% to 77% (on Linux).

The script doesn't exercise the error branch that handles an evil
or lost sys.excepthook in Python/pythonrun.c::PyErr_PrintEx().

Also this script might not work on Jython in its current form.

From SF patch #662807.
diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py
new file mode 100644
index 0000000..ae2f207
--- /dev/null
+++ b/Lib/test/test_sys.py
@@ -0,0 +1,211 @@
+# -*- coding: iso-8859-1 -*-
+import unittest, test.test_support
+import sys, cStringIO
+
+class SysModuleTest(unittest.TestCase):
+
+    def test_original_displayhook(self):
+        import __builtin__
+        savestdout = sys.stdout
+        out = cStringIO.StringIO()
+        sys.stdout = out
+
+        dh = sys.__displayhook__
+
+        self.assertRaises(TypeError, dh)
+        if hasattr(__builtin__, "_"):
+            del __builtin__._
+
+        dh(None)
+        self.assertEqual(out.getvalue(), "")
+        self.assert_(not hasattr(__builtin__, "_"))
+        dh(42)
+        self.assertEqual(out.getvalue(), "42\n")
+        self.assertEqual(__builtin__._, 42)
+
+        del sys.stdout
+        self.assertRaises(RuntimeError, dh, 42)
+
+        sys.stdout = savestdout
+
+    def test_lost_displayhook(self):
+        olddisplayhook = sys.displayhook
+        del sys.displayhook
+        code = compile("42", "<string>", "single")
+        self.assertRaises(RuntimeError, eval, code)
+        sys.displayhook = olddisplayhook
+
+    def test_custom_displayhook(self):
+        olddisplayhook = sys.displayhook
+        def baddisplayhook(obj):
+            raise ValueError
+        sys.displayhook = baddisplayhook
+        code = compile("42", "<string>", "single")
+        self.assertRaises(ValueError, eval, code)
+        sys.displayhook = olddisplayhook
+
+    def test_original_excepthook(self):
+        savestderr = sys.stderr
+        err = cStringIO.StringIO()
+        sys.stderr = err
+
+        eh = sys.__excepthook__
+
+        self.assertRaises(TypeError, eh)
+        try:
+            raise ValueError(42)
+        except ValueError, exc:
+            eh(*sys.exc_info())
+
+        sys.stderr = savestderr
+        self.assert_(err.getvalue().endswith("ValueError: 42\n"))
+
+    # FIXME: testing the code for a lost or replace excepthook in
+    # Python/pythonrun.c::PyErr_PrintEx() is tricky.
+
+    def test_exit(self):
+        self.assertRaises(TypeError, sys.exit, 42, 42)
+
+        # call without argument
+        try:
+            sys.exit(0)
+        except SystemExit, exc:
+            self.assertEquals(exc.code, 0)
+        except:
+            self.fail("wrong exception")
+        else:
+            self.fail("no exception")
+
+        # call with tuple argument with one entry
+        # entry will be unpacked
+        try:
+            sys.exit(42)
+        except SystemExit, exc:
+            self.assertEquals(exc.code, 42)
+        except:
+            self.fail("wrong exception")
+        else:
+            self.fail("no exception")
+
+        # call with integer argument
+        try:
+            sys.exit((42,))
+        except SystemExit, exc:
+            self.assertEquals(exc.code, 42)
+        except:
+            self.fail("wrong exception")
+        else:
+            self.fail("no exception")
+
+        # call with string argument
+        try:
+            sys.exit("exit")
+        except SystemExit, exc:
+            self.assertEquals(exc.code, "exit")
+        except:
+            self.fail("wrong exception")
+        else:
+            self.fail("no exception")
+
+        # call with tuple argument with two entries
+        try:
+            sys.exit((17, 23))
+        except SystemExit, exc:
+            self.assertEquals(exc.code, (17, 23))
+        except:
+            self.fail("wrong exception")
+        else:
+            self.fail("no exception")
+
+    def test_getdefaultencoding(self):
+        if test.test_support.have_unicode:
+            self.assertRaises(TypeError, sys.getdefaultencoding, 42)
+            # can't check more than the type, as the user might have changed it
+            self.assert_(isinstance(sys.getdefaultencoding(), str))
+
+    # testing sys.settrace() is done in test_trace.py
+    # testing sys.setprofile() is done in test_profile.py
+
+    def test_setcheckinterval(self):
+         self.assertRaises(TypeError, sys.setcheckinterval)
+         sys.setcheckinterval(120)
+         sys.setcheckinterval(100)
+
+    def test_recursionlimit(self):
+         self.assertRaises(TypeError, sys.getrecursionlimit, 42)
+         oldlimit = sys.getrecursionlimit()
+         self.assertRaises(TypeError, sys.setrecursionlimit)
+         self.assertRaises(ValueError, sys.setrecursionlimit, -42)
+         sys.setrecursionlimit(10000)
+         self.assertEqual(sys.getrecursionlimit(), 10000)
+         sys.setrecursionlimit(oldlimit)
+
+    def test_getwindowsversion(self):
+        if hasattr(sys, "getwindowsversion"):
+            v = sys.getwindowsversion()
+            self.assert_(isinstance(v, tuple))
+            self.assertEqual(len(v), 5)
+            self.assert_(isinstance(v[0], int))
+            self.assert_(isinstance(v[1], int))
+            self.assert_(isinstance(v[2], int))
+            self.assert_(isinstance(v[3], int))
+            self.assert_(isinstance(v[4], str))
+
+    def test_dlopenflags(self):
+        if hasattr(sys, "setdlopenflags"):
+            self.assert_(hasattr(sys, "getdlopenflags"))
+            self.assertRaises(TypeError, sys.getdlopenflags, 42)
+            oldflags = sys.getdlopenflags()
+            self.assertRaises(TypeError, sys.setdlopenflags)
+            sys.setdlopenflags(oldflags+1)
+            self.assertEqual(sys.getdlopenflags(), oldflags+1)
+            sys.setdlopenflags(oldflags)
+
+    def test_refcount(self):
+        self.assertRaises(TypeError, sys.getrefcount)
+        c = sys.getrefcount(None)
+        n = None
+        self.assertEqual(sys.getrefcount(None), c+1)
+        del n
+        self.assertEqual(sys.getrefcount(None), c)
+        if hasattr(sys, "gettotalrefcount"):
+            self.assert_(isinstance(sys.gettotalrefcount(), int))
+
+    def test_getframe(self):
+        self.assertRaises(TypeError, sys._getframe, 42, 42)
+        self.assertRaises(ValueError, sys._getframe, sys.maxint)
+        self.assert_(
+            SysModuleTest.test_getframe.im_func.func_code \
+            is sys._getframe().f_code
+        )
+
+    def test_attributes(self):
+        self.assert_(isinstance(sys.api_version, int))
+        self.assert_(isinstance(sys.argv, list))
+        self.assert_(sys.byteorder in ("little", "big"))
+        self.assert_(isinstance(sys.builtin_module_names, tuple))
+        self.assert_(isinstance(sys.copyright, basestring))
+        self.assert_(isinstance(sys.exec_prefix, basestring))
+        self.assert_(isinstance(sys.executable, basestring))
+        self.assert_(isinstance(sys.hexversion, int))
+        self.assert_(isinstance(sys.maxint, int))
+        self.assert_(isinstance(sys.maxunicode, int))
+        self.assert_(isinstance(sys.platform, basestring))
+        self.assert_(isinstance(sys.prefix, basestring))
+        self.assert_(isinstance(sys.version, basestring))
+        vi = sys.version_info
+        self.assert_(isinstance(vi, tuple))
+        self.assertEqual(len(vi), 5)
+        self.assert_(isinstance(vi[0], int))
+        self.assert_(isinstance(vi[1], int))
+        self.assert_(isinstance(vi[2], int))
+        self.assert_(vi[3] in ("alpha", "beta", "candidate", "final"))
+        self.assert_(isinstance(vi[4], int))
+
+def test_main():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(SysModuleTest))
+    test.test_support.run_suite(suite)
+
+if __name__ == "__main__":
+    test_main()