mirror of
https://github.com/python/cpython.git
synced 2025-07-19 09:15:34 +00:00

svn+ssh://pythondev@svn.python.org/python/trunk ........ r70712 | benjamin.peterson | 2009-03-30 10:15:38 -0500 (Mon, 30 Mar 2009) | 1 line don't rely on the order dict repr #5605 ........ r70714 | brett.cannon | 2009-03-30 10:20:53 -0500 (Mon, 30 Mar 2009) | 1 line Add an entry to developers.txt. ........ r70764 | martin.v.loewis | 2009-03-30 17:06:33 -0500 (Mon, 30 Mar 2009) | 2 lines Add several VM developers. ........ r70765 | georg.brandl | 2009-03-30 17:09:34 -0500 (Mon, 30 Mar 2009) | 1 line #5199: make warning about vars() assignment more visible. ........ r70769 | andrew.kuchling | 2009-03-30 17:29:53 -0500 (Mon, 30 Mar 2009) | 1 line Remove comment ........ r70770 | andrew.kuchling | 2009-03-30 17:30:20 -0500 (Mon, 30 Mar 2009) | 1 line Add several items and placeholders ........ r70771 | andrew.kuchling | 2009-03-30 17:31:11 -0500 (Mon, 30 Mar 2009) | 1 line Many edits ........ r70773 | georg.brandl | 2009-03-30 17:43:00 -0500 (Mon, 30 Mar 2009) | 1 line #5039: make it clear that the impl. note refers to CPython. ........ r70776 | andrew.kuchling | 2009-03-30 18:08:24 -0500 (Mon, 30 Mar 2009) | 1 line typo fix ........ r70777 | andrew.kuchling | 2009-03-30 18:09:46 -0500 (Mon, 30 Mar 2009) | 1 line Add more items ........ r70788 | andrew.kuchling | 2009-03-30 20:21:01 -0500 (Mon, 30 Mar 2009) | 1 line Add various items ........ r70789 | georg.brandl | 2009-03-30 20:25:15 -0500 (Mon, 30 Mar 2009) | 1 line Fix a wrong struct field assignment (docstring as closure). ........ r70824 | georg.brandl | 2009-03-31 10:43:20 -0500 (Tue, 31 Mar 2009) | 1 line #5519: remove reference to Kodos, which seems dead. ........ r70828 | georg.brandl | 2009-03-31 10:50:16 -0500 (Tue, 31 Mar 2009) | 1 line #5581: fget argument of abstractproperty is optional as well. ........ r70832 | georg.brandl | 2009-03-31 11:31:11 -0500 (Tue, 31 Mar 2009) | 1 line #1386675: specify WindowsError as the exception, because it has a winerror attribute that EnvironmentError doesnt have. ........ r70836 | georg.brandl | 2009-03-31 11:50:25 -0500 (Tue, 31 Mar 2009) | 1 line #5417: replace references to undocumented functions by ones to documented functions. ........ r70842 | georg.brandl | 2009-03-31 12:13:06 -0500 (Tue, 31 Mar 2009) | 1 line #970783: document PyObject_Generic[GS]etAttr. ........ r70851 | georg.brandl | 2009-03-31 13:26:55 -0500 (Tue, 31 Mar 2009) | 1 line #837577: note cryptic return value of spawn*e on invalid env dicts. ........ r70855 | georg.brandl | 2009-03-31 13:30:37 -0500 (Tue, 31 Mar 2009) | 1 line #5245: note that PyRun_SimpleString doesnt return on SystemExit. ........ r70857 | georg.brandl | 2009-03-31 13:33:10 -0500 (Tue, 31 Mar 2009) | 1 line #5227: note that Py_Main doesnt return on SystemExit. ........ r70866 | georg.brandl | 2009-03-31 14:06:57 -0500 (Tue, 31 Mar 2009) | 1 line #4882: document named group behavior a bit better. ........ r70867 | georg.brandl | 2009-03-31 14:10:35 -0500 (Tue, 31 Mar 2009) | 1 line #1096310: document usage of sys.__std*__ a bit better. ........ r70868 | georg.brandl | 2009-03-31 14:12:17 -0500 (Tue, 31 Mar 2009) | 1 line #5190: export make_option in __all__. ........ r70869 | georg.brandl | 2009-03-31 14:14:42 -0500 (Tue, 31 Mar 2009) | 1 line Fix-up unwanted change. ........ r70870 | georg.brandl | 2009-03-31 14:26:24 -0500 (Tue, 31 Mar 2009) | 1 line #4411: document mro() and __mro__. (I hope I got it right.) ........ r70871 | georg.brandl | 2009-03-31 14:30:56 -0500 (Tue, 31 Mar 2009) | 1 line #5618: fix typo. ........ r70872 | r.david.murray | 2009-03-31 14:31:17 -0500 (Tue, 31 Mar 2009) | 3 lines Delete out-of-date and little-known README from the test directory by consensus of devs at pycon sprint. ........ r70883 | georg.brandl | 2009-03-31 15:41:08 -0500 (Tue, 31 Mar 2009) | 1 line #1674032: return value of flag from Event.wait(). OKed by Guido. ........ r70885 | tarek.ziade | 2009-03-31 15:48:31 -0500 (Tue, 31 Mar 2009) | 1 line using log.warn for sys.stderr ........ r70893 | georg.brandl | 2009-03-31 15:56:32 -0500 (Tue, 31 Mar 2009) | 1 line #1530012: move TQS section before raw strings. ........ r70894 | benjamin.peterson | 2009-03-31 16:06:30 -0500 (Tue, 31 Mar 2009) | 1 line take the usual lock precautions around _active_limbo_lock ........ r70896 | georg.brandl | 2009-03-31 16:15:33 -0500 (Tue, 31 Mar 2009) | 1 line #5598: document DocFileSuite *args argument. ........ r70897 | benjamin.peterson | 2009-03-31 16:34:42 -0500 (Tue, 31 Mar 2009) | 1 line fix Thread.ident when it is the main thread or a dummy thread #5632 ........ r70903 | georg.brandl | 2009-03-31 16:45:18 -0500 (Tue, 31 Mar 2009) | 1 line #1676135: remove trailing slashes from --prefix argument. ........ r70905 | georg.brandl | 2009-03-31 17:03:40 -0500 (Tue, 31 Mar 2009) | 1 line #5563: more documentation for bdist_msi. ........ r70906 | georg.brandl | 2009-03-31 17:11:53 -0500 (Tue, 31 Mar 2009) | 1 line #1651995: fix _convert_ref for non-ASCII characters. ........ r70907 | georg.brandl | 2009-03-31 17:18:19 -0500 (Tue, 31 Mar 2009) | 1 line #3427: document correct return type for urlopen().info(). ........ r70915 | georg.brandl | 2009-03-31 17:40:16 -0500 (Tue, 31 Mar 2009) | 1 line #5018: remove confusing paragraph. ........ r70927 | georg.brandl | 2009-03-31 18:01:27 -0500 (Tue, 31 Mar 2009) | 1 line Dont shout to users. ........ r70933 | georg.brandl | 2009-03-31 19:04:33 -0500 (Tue, 31 Mar 2009) | 2 lines Issue #5635: Fix running test_sys with tracing enabled. ........ r70951 | georg.brandl | 2009-04-01 09:02:27 -0500 (Wed, 01 Apr 2009) | 1 line Add Maksim, who worked on several issues at the sprint. ........ r70960 | jesse.noller | 2009-04-01 11:42:19 -0500 (Wed, 01 Apr 2009) | 1 line Issue 3270: document Listener address restrictions on windows ........ r70962 | brett.cannon | 2009-04-01 12:07:16 -0500 (Wed, 01 Apr 2009) | 2 lines Ron DuPlain was given commit privileges at PyCon 2009 to work on 3to2. ........ r70963 | georg.brandl | 2009-04-01 12:46:01 -0500 (Wed, 01 Apr 2009) | 1 line #5655: fix docstring oversight. ........ r70964 | brett.cannon | 2009-04-01 12:52:13 -0500 (Wed, 01 Apr 2009) | 2 lines Paul Kippes was given commit privileges to work on 3to2. ........ r70998 | georg.brandl | 2009-04-01 16:54:21 -0500 (Wed, 01 Apr 2009) | 1 line In Pdb, stop assigning values to __builtin__._ which interferes with the one commonly installed by gettext. ........ r71001 | brett.cannon | 2009-04-01 18:01:12 -0500 (Wed, 01 Apr 2009) | 3 lines Add my initials to Misc/developers.txt. Names are now sorted by number of characters in the person's name. ........ r71006 | georg.brandl | 2009-04-01 18:32:17 -0500 (Wed, 01 Apr 2009) | 1 line Cache the f_locals dict of the current frame, since every access to frame.f_locals overrides its contents with the real locals which undoes modifications made by the debugging user. ........ r71008 | andrew.kuchling | 2009-04-01 19:02:14 -0500 (Wed, 01 Apr 2009) | 1 line Typo fix ........ r71010 | benjamin.peterson | 2009-04-01 19:11:52 -0500 (Wed, 01 Apr 2009) | 1 line fix markup ........ r71011 | benjamin.peterson | 2009-04-01 19:12:47 -0500 (Wed, 01 Apr 2009) | 1 line this should be :noindex: ........ r71019 | georg.brandl | 2009-04-01 21:00:01 -0500 (Wed, 01 Apr 2009) | 1 line Fix test_doctest, missed two assignments to curframe. ........ r71037 | r.david.murray | 2009-04-01 23:34:04 -0500 (Wed, 01 Apr 2009) | 6 lines Clarify that datetime strftime does not produce leap seconds and datetime strptime does not accept it in the strftime behavior section of the datetime docs. Closes issue 2568. ........ r71056 | georg.brandl | 2009-04-02 12:43:07 -0500 (Thu, 02 Apr 2009) | 2 lines Actually the displayhook should print the repr. ........ r71094 | vinay.sajip | 2009-04-03 05:23:18 -0500 (Fri, 03 Apr 2009) | 1 line Added warning about logging use from asynchronous signal handlers. ........ r71101 | andrew.kuchling | 2009-04-03 16:43:00 -0500 (Fri, 03 Apr 2009) | 1 line Add some items ........ r71102 | andrew.kuchling | 2009-04-03 16:44:49 -0500 (Fri, 03 Apr 2009) | 1 line Fix 'the the'; grammar fix ........ r71103 | andrew.kuchling | 2009-04-03 16:45:29 -0500 (Fri, 03 Apr 2009) | 1 line Fix 'the the' duplication ........ r71106 | vinay.sajip | 2009-04-03 16:58:16 -0500 (Fri, 03 Apr 2009) | 1 line Clarified warning about logging use from asynchronous signal handlers. ........ r71119 | raymond.hettinger | 2009-04-04 00:37:47 -0500 (Sat, 04 Apr 2009) | 1 line Add helpful link. ........ r71123 | r.david.murray | 2009-04-04 01:39:56 -0500 (Sat, 04 Apr 2009) | 2 lines Fix error in description of 'oct' (issue 5678). ........ r71149 | georg.brandl | 2009-04-04 08:42:39 -0500 (Sat, 04 Apr 2009) | 1 line #5642: clarify map() compatibility to the builtin. ........ r71150 | georg.brandl | 2009-04-04 08:45:49 -0500 (Sat, 04 Apr 2009) | 1 line #5601: clarify that webbrowser is not meant for file names. ........ r71203 | benjamin.peterson | 2009-04-04 18:46:34 -0500 (Sat, 04 Apr 2009) | 1 line note how using iter* are unsafe while mutating and document iter(dict) ........ r71212 | georg.brandl | 2009-04-05 05:24:20 -0500 (Sun, 05 Apr 2009) | 1 line #1742837: expand HTTP server docs, and fix SocketServer ones to document methods as methods, not functions. ........ r71214 | georg.brandl | 2009-04-05 05:29:57 -0500 (Sun, 05 Apr 2009) | 1 line Normalize spelling of Mac OS X. ........ r71215 | georg.brandl | 2009-04-05 05:32:26 -0500 (Sun, 05 Apr 2009) | 1 line Avoid sure signs of a diseased mind. ........ r71216 | georg.brandl | 2009-04-05 05:41:02 -0500 (Sun, 05 Apr 2009) | 1 line #1718017: document the relation of os.path and the posixpath, ntpath etc. modules better. ........ r71217 | georg.brandl | 2009-04-05 05:48:47 -0500 (Sun, 05 Apr 2009) | 1 line #1726172: dont raise an unexpected IndexError if a voidresp() call has an empty response. ........ r71221 | vinay.sajip | 2009-04-05 06:06:24 -0500 (Sun, 05 Apr 2009) | 1 line Issue #5695: Moved logging.captureWarnings() call inside with statement in WarningsTest.test_warnings. ........ r71240 | georg.brandl | 2009-04-05 09:40:06 -0500 (Sun, 05 Apr 2009) | 1 line #5370: doc update about unpickling objects with custom __getattr__ etc. methods. ........
741 lines
26 KiB
Python
741 lines
26 KiB
Python
# -*- coding: iso-8859-1 -*-
|
|
import unittest, test.support
|
|
import sys, io, os
|
|
import struct
|
|
import subprocess
|
|
import textwrap
|
|
|
|
class SysModuleTest(unittest.TestCase):
|
|
|
|
def setUp(self):
|
|
self.orig_stdout = sys.stdout
|
|
self.orig_stderr = sys.stderr
|
|
self.orig_displayhook = sys.displayhook
|
|
|
|
def tearDown(self):
|
|
sys.stdout = self.orig_stdout
|
|
sys.stderr = self.orig_stderr
|
|
sys.displayhook = self.orig_displayhook
|
|
|
|
def test_original_displayhook(self):
|
|
import builtins
|
|
out = io.StringIO()
|
|
sys.stdout = out
|
|
|
|
dh = sys.__displayhook__
|
|
|
|
self.assertRaises(TypeError, dh)
|
|
if hasattr(builtins, "_"):
|
|
del builtins._
|
|
|
|
dh(None)
|
|
self.assertEqual(out.getvalue(), "")
|
|
self.assert_(not hasattr(builtins, "_"))
|
|
dh(42)
|
|
self.assertEqual(out.getvalue(), "42\n")
|
|
self.assertEqual(builtins._, 42)
|
|
|
|
del sys.stdout
|
|
self.assertRaises(RuntimeError, dh, 42)
|
|
|
|
def test_lost_displayhook(self):
|
|
del sys.displayhook
|
|
code = compile("42", "<string>", "single")
|
|
self.assertRaises(RuntimeError, eval, code)
|
|
|
|
def test_custom_displayhook(self):
|
|
def baddisplayhook(obj):
|
|
raise ValueError
|
|
sys.displayhook = baddisplayhook
|
|
code = compile("42", "<string>", "single")
|
|
self.assertRaises(ValueError, eval, code)
|
|
|
|
def test_original_excepthook(self):
|
|
err = io.StringIO()
|
|
sys.stderr = err
|
|
|
|
eh = sys.__excepthook__
|
|
|
|
self.assertRaises(TypeError, eh)
|
|
try:
|
|
raise ValueError(42)
|
|
except ValueError as exc:
|
|
eh(*sys.exc_info())
|
|
|
|
self.assert_(err.getvalue().endswith("ValueError: 42\n"))
|
|
|
|
def test_excepthook(self):
|
|
with test.support.captured_output("stderr") as stderr:
|
|
sys.excepthook(1, '1', 1)
|
|
self.assert_("TypeError: print_exception(): Exception expected for " \
|
|
"value, str found" in stderr.getvalue())
|
|
|
|
# FIXME: testing the code for a lost or replaced 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 as 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 as 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 as 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 as 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 as exc:
|
|
self.assertEquals(exc.code, (17, 23))
|
|
except:
|
|
self.fail("wrong exception")
|
|
else:
|
|
self.fail("no exception")
|
|
|
|
# test that the exit machinery handles SystemExits properly
|
|
import subprocess
|
|
rc = subprocess.call([sys.executable, "-c",
|
|
"raise SystemExit(47)"])
|
|
self.assertEqual(rc, 47)
|
|
|
|
def test_getdefaultencoding(self):
|
|
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)
|
|
orig = sys.getcheckinterval()
|
|
for n in 0, 100, 120, orig: # orig last to restore starting state
|
|
sys.setcheckinterval(n)
|
|
self.assertEquals(sys.getcheckinterval(), n)
|
|
|
|
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_recursionlimit_recovery(self):
|
|
# NOTE: this test is slightly fragile in that it depends on the current
|
|
# recursion count when executing the test being low enough so as to
|
|
# trigger the recursion recovery detection in the _Py_MakeEndRecCheck
|
|
# macro (see ceval.h).
|
|
oldlimit = sys.getrecursionlimit()
|
|
def f():
|
|
f()
|
|
try:
|
|
for i in (50, 1000):
|
|
# Issue #5392: stack overflow after hitting recursion limit twice
|
|
sys.setrecursionlimit(i)
|
|
self.assertRaises(RuntimeError, f)
|
|
self.assertRaises(RuntimeError, f)
|
|
finally:
|
|
sys.setrecursionlimit(oldlimit)
|
|
|
|
def test_recursionlimit_fatalerror(self):
|
|
# A fatal error occurs if a second recursion limit is hit when recovering
|
|
# from a first one.
|
|
if os.name == "nt":
|
|
raise unittest.SkipTest(
|
|
"under Windows, test would generate a spurious crash dialog")
|
|
code = textwrap.dedent("""
|
|
import sys
|
|
|
|
def f():
|
|
try:
|
|
f()
|
|
except RuntimeError:
|
|
f()
|
|
|
|
sys.setrecursionlimit(%d)
|
|
f()""")
|
|
for i in (50, 1000):
|
|
sub = subprocess.Popen([sys.executable, '-c', code % i],
|
|
stderr=subprocess.PIPE)
|
|
err = sub.communicate()[1]
|
|
self.assertTrue(sub.returncode, sub.returncode)
|
|
self.assertTrue(
|
|
b"Fatal Python error: Cannot recover from stack overflow" in err,
|
|
err)
|
|
|
|
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_call_tracing(self):
|
|
self.assertRaises(TypeError, sys.call_tracing, type, 2)
|
|
|
|
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):
|
|
# n here must be a global in order for this test to pass while
|
|
# tracing with a python function. Tracing calls PyFrame_FastToLocals
|
|
# which will add a copy of any locals to the frame object, causing
|
|
# the reference count to increase by 2 instead of 1.
|
|
global n
|
|
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, 2000000000)
|
|
self.assert_(
|
|
SysModuleTest.test_getframe.__code__ \
|
|
is sys._getframe().f_code
|
|
)
|
|
|
|
# sys._current_frames() is a CPython-only gimmick.
|
|
def test_current_frames(self):
|
|
have_threads = True
|
|
try:
|
|
import _thread
|
|
except ImportError:
|
|
have_threads = False
|
|
|
|
if have_threads:
|
|
self.current_frames_with_threads()
|
|
else:
|
|
self.current_frames_without_threads()
|
|
|
|
# Test sys._current_frames() in a WITH_THREADS build.
|
|
def current_frames_with_threads(self):
|
|
import threading, _thread
|
|
import traceback
|
|
|
|
# Spawn a thread that blocks at a known place. Then the main
|
|
# thread does sys._current_frames(), and verifies that the frames
|
|
# returned make sense.
|
|
entered_g = threading.Event()
|
|
leave_g = threading.Event()
|
|
thread_info = [] # the thread's id
|
|
|
|
def f123():
|
|
g456()
|
|
|
|
def g456():
|
|
thread_info.append(_thread.get_ident())
|
|
entered_g.set()
|
|
leave_g.wait()
|
|
|
|
t = threading.Thread(target=f123)
|
|
t.start()
|
|
entered_g.wait()
|
|
|
|
# At this point, t has finished its entered_g.set(), although it's
|
|
# impossible to guess whether it's still on that line or has moved on
|
|
# to its leave_g.wait().
|
|
self.assertEqual(len(thread_info), 1)
|
|
thread_id = thread_info[0]
|
|
|
|
d = sys._current_frames()
|
|
|
|
main_id = _thread.get_ident()
|
|
self.assert_(main_id in d)
|
|
self.assert_(thread_id in d)
|
|
|
|
# Verify that the captured main-thread frame is _this_ frame.
|
|
frame = d.pop(main_id)
|
|
self.assert_(frame is sys._getframe())
|
|
|
|
# Verify that the captured thread frame is blocked in g456, called
|
|
# from f123. This is a litte tricky, since various bits of
|
|
# threading.py are also in the thread's call stack.
|
|
frame = d.pop(thread_id)
|
|
stack = traceback.extract_stack(frame)
|
|
for i, (filename, lineno, funcname, sourceline) in enumerate(stack):
|
|
if funcname == "f123":
|
|
break
|
|
else:
|
|
self.fail("didn't find f123() on thread's call stack")
|
|
|
|
self.assertEqual(sourceline, "g456()")
|
|
|
|
# And the next record must be for g456().
|
|
filename, lineno, funcname, sourceline = stack[i+1]
|
|
self.assertEqual(funcname, "g456")
|
|
self.assert_(sourceline in ["leave_g.wait()", "entered_g.set()"])
|
|
|
|
# Reap the spawned thread.
|
|
leave_g.set()
|
|
t.join()
|
|
|
|
# Test sys._current_frames() when thread support doesn't exist.
|
|
def current_frames_without_threads(self):
|
|
# Not much happens here: there is only one thread, with artificial
|
|
# "thread id" 0.
|
|
d = sys._current_frames()
|
|
self.assertEqual(len(d), 1)
|
|
self.assert_(0 in d)
|
|
self.assert_(d[0] is sys._getframe())
|
|
|
|
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, str))
|
|
self.assert_(isinstance(sys.exec_prefix, str))
|
|
self.assert_(isinstance(sys.executable, str))
|
|
self.assertEqual(len(sys.float_info), 11)
|
|
self.assertEqual(sys.float_info.radix, 2)
|
|
self.assertEqual(len(sys.int_info), 2)
|
|
self.assert_(sys.int_info.bits_per_digit % 5 == 0)
|
|
self.assert_(sys.int_info.sizeof_digit >= 1)
|
|
self.assert_(isinstance(sys.hexversion, int))
|
|
self.assert_(isinstance(sys.maxsize, int))
|
|
self.assert_(isinstance(sys.maxunicode, int))
|
|
self.assert_(isinstance(sys.platform, str))
|
|
self.assert_(isinstance(sys.prefix, str))
|
|
self.assert_(isinstance(sys.version, str))
|
|
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))
|
|
self.assert_(isinstance(vi.major, int))
|
|
self.assert_(isinstance(vi.minor, int))
|
|
self.assert_(isinstance(vi.micro, int))
|
|
self.assert_(vi.releaselevel in
|
|
("alpha", "beta", "candidate", "final"))
|
|
self.assert_(isinstance(vi.serial, int))
|
|
self.assertEqual(vi[0], vi.major)
|
|
self.assertEqual(vi[1], vi.minor)
|
|
self.assertEqual(vi[2], vi.micro)
|
|
self.assertEqual(vi[3], vi.releaselevel)
|
|
self.assertEqual(vi[4], vi.serial)
|
|
self.assert_(vi > (1,0,0))
|
|
|
|
def test_43581(self):
|
|
# Can't use sys.stdout, as this is a StringIO object when
|
|
# the test runs under regrtest.
|
|
self.assertEqual(sys.__stdout__.encoding, sys.__stderr__.encoding)
|
|
|
|
def test_intern(self):
|
|
self.assertRaises(TypeError, sys.intern)
|
|
s = "never interned before"
|
|
self.assert_(sys.intern(s) is s)
|
|
s2 = s.swapcase().swapcase()
|
|
self.assert_(sys.intern(s2) is s)
|
|
|
|
# Subclasses of string can't be interned, because they
|
|
# provide too much opportunity for insane things to happen.
|
|
# We don't want them in the interned dict and if they aren't
|
|
# actually interned, we don't want to create the appearance
|
|
# that they are by allowing intern() to succeeed.
|
|
class S(str):
|
|
def __hash__(self):
|
|
return 123
|
|
|
|
self.assertRaises(TypeError, sys.intern, S("abc"))
|
|
|
|
|
|
def test_sys_flags(self):
|
|
self.failUnless(sys.flags)
|
|
attrs = ("debug", "division_warning",
|
|
"inspect", "interactive", "optimize", "dont_write_bytecode",
|
|
"no_user_site", "no_site", "ignore_environment", "verbose",
|
|
"bytes_warning")
|
|
for attr in attrs:
|
|
self.assert_(hasattr(sys.flags, attr), attr)
|
|
self.assertEqual(type(getattr(sys.flags, attr)), int, attr)
|
|
self.assert_(repr(sys.flags))
|
|
self.assertEqual(len(sys.flags), len(attrs))
|
|
|
|
def test_clear_type_cache(self):
|
|
sys._clear_type_cache()
|
|
|
|
def test_ioencoding(self):
|
|
import subprocess,os
|
|
env = dict(os.environ)
|
|
|
|
# Test character: cent sign, encoded as 0x4A (ASCII J) in CP424,
|
|
# not representable in ASCII.
|
|
|
|
env["PYTHONIOENCODING"] = "cp424"
|
|
p = subprocess.Popen([sys.executable, "-c", 'print(chr(0xa2))'],
|
|
stdout = subprocess.PIPE, env=env)
|
|
out = p.stdout.read()
|
|
self.assertEqual(out, "\xa2\n".encode("cp424"))
|
|
|
|
env["PYTHONIOENCODING"] = "ascii:replace"
|
|
p = subprocess.Popen([sys.executable, "-c", 'print(chr(0xa2))'],
|
|
stdout = subprocess.PIPE, env=env)
|
|
out = p.stdout.read().strip()
|
|
self.assertEqual(out, b'?')
|
|
|
|
|
|
class SizeofTest(unittest.TestCase):
|
|
|
|
TPFLAGS_HAVE_GC = 1<<14
|
|
TPFLAGS_HEAPTYPE = 1<<9
|
|
|
|
def setUp(self):
|
|
self.c = len(struct.pack('c', ' '))
|
|
self.H = len(struct.pack('H', 0))
|
|
self.i = len(struct.pack('i', 0))
|
|
self.l = len(struct.pack('l', 0))
|
|
self.P = len(struct.pack('P', 0))
|
|
# due to missing size_t information from struct, it is assumed that
|
|
# sizeof(Py_ssize_t) = sizeof(void*)
|
|
self.header = 'PP'
|
|
self.vheader = self.header + 'P'
|
|
if hasattr(sys, "gettotalrefcount"):
|
|
self.header += '2P'
|
|
self.vheader += '2P'
|
|
self.longdigit = sys.int_info.sizeof_digit
|
|
import _testcapi
|
|
self.gc_headsize = _testcapi.SIZEOF_PYGC_HEAD
|
|
self.file = open(test.support.TESTFN, 'wb')
|
|
|
|
def tearDown(self):
|
|
self.file.close()
|
|
test.support.unlink(test.support.TESTFN)
|
|
|
|
def check_sizeof(self, o, size):
|
|
result = sys.getsizeof(o)
|
|
# add GC header size
|
|
if ((type(o) == type) and (o.__flags__ & self.TPFLAGS_HEAPTYPE) or\
|
|
((type(o) != type) and (type(o).__flags__ & self.TPFLAGS_HAVE_GC))):
|
|
size += self.gc_headsize
|
|
msg = 'wrong size for %s: got %d, expected %d' \
|
|
% (type(o), result, size)
|
|
self.assertEqual(result, size, msg)
|
|
|
|
def calcsize(self, fmt):
|
|
"""Wrapper around struct.calcsize which enforces the alignment of the
|
|
end of a structure to the alignment requirement of pointer.
|
|
|
|
Note: This wrapper should only be used if a pointer member is included
|
|
and no member with a size larger than a pointer exists.
|
|
"""
|
|
return struct.calcsize(fmt + '0P')
|
|
|
|
def test_gc_head_size(self):
|
|
# Check that the gc header size is added to objects tracked by the gc.
|
|
h = self.header
|
|
vh = self.vheader
|
|
size = self.calcsize
|
|
gc_header_size = self.gc_headsize
|
|
# bool objects are not gc tracked
|
|
self.assertEqual(sys.getsizeof(True), size(vh) + self.longdigit)
|
|
# but lists are
|
|
self.assertEqual(sys.getsizeof([]), size(vh + 'PP') + gc_header_size)
|
|
|
|
def test_default(self):
|
|
h = self.header
|
|
vh = self.vheader
|
|
size = self.calcsize
|
|
self.assertEqual(sys.getsizeof(True), size(vh) + self.longdigit)
|
|
self.assertEqual(sys.getsizeof(True, -1), size(vh) + self.longdigit)
|
|
|
|
def test_objecttypes(self):
|
|
# check all types defined in Objects/
|
|
h = self.header
|
|
vh = self.vheader
|
|
size = self.calcsize
|
|
check = self.check_sizeof
|
|
# bool
|
|
check(True, size(vh) + self.longdigit)
|
|
# buffer
|
|
# XXX
|
|
# builtin_function_or_method
|
|
check(len, size(h + '3P'))
|
|
# bytearray
|
|
samples = [b'', b'u'*100000]
|
|
for sample in samples:
|
|
x = bytearray(sample)
|
|
check(x, size(vh + 'iPP') + x.__alloc__() * self.c)
|
|
# bytearray_iterator
|
|
check(iter(bytearray()), size(h + 'PP'))
|
|
# cell
|
|
def get_cell():
|
|
x = 42
|
|
def inner():
|
|
return x
|
|
return inner
|
|
check(get_cell().__closure__[0], size(h + 'P'))
|
|
# code
|
|
check(get_cell().__code__, size(h + '5i8Pi2P'))
|
|
# complex
|
|
check(complex(0,1), size(h + '2d'))
|
|
# method_descriptor (descriptor object)
|
|
check(str.lower, size(h + '2PP'))
|
|
# classmethod_descriptor (descriptor object)
|
|
# XXX
|
|
# member_descriptor (descriptor object)
|
|
import datetime
|
|
check(datetime.timedelta.days, size(h + '2PP'))
|
|
# getset_descriptor (descriptor object)
|
|
import collections
|
|
check(collections.defaultdict.default_factory, size(h + '2PP'))
|
|
# wrapper_descriptor (descriptor object)
|
|
check(int.__add__, size(h + '2P2P'))
|
|
# method-wrapper (descriptor object)
|
|
check({}.__iter__, size(h + '2P'))
|
|
# dict
|
|
check({}, size(h + '3P2P' + 8*'P2P'))
|
|
longdict = {1:1, 2:2, 3:3, 4:4, 5:5, 6:6, 7:7, 8:8}
|
|
check(longdict, size(h + '3P2P' + 8*'P2P') + 16*size('P2P'))
|
|
# dictionary-keyiterator
|
|
check({}.keys(), size(h + 'P'))
|
|
# dictionary-valueiterator
|
|
check({}.values(), size(h + 'P'))
|
|
# dictionary-itemiterator
|
|
check({}.items(), size(h + 'P'))
|
|
# dictproxy
|
|
class C(object): pass
|
|
check(C.__dict__, size(h + 'P'))
|
|
# BaseException
|
|
check(BaseException(), size(h + '5P'))
|
|
# UnicodeEncodeError
|
|
check(UnicodeEncodeError("", "", 0, 0, ""), size(h + '5P 2P2PP'))
|
|
# UnicodeDecodeError
|
|
# XXX
|
|
# check(UnicodeDecodeError("", "", 0, 0, ""), size(h + '5P2PP'))
|
|
# UnicodeTranslateError
|
|
check(UnicodeTranslateError("", 0, 1, ""), size(h + '5P 2P2PP'))
|
|
# ellipses
|
|
check(Ellipsis, size(h + ''))
|
|
# EncodingMap
|
|
import codecs, encodings.iso8859_3
|
|
x = codecs.charmap_build(encodings.iso8859_3.decoding_table)
|
|
check(x, size(h + '32B2iB'))
|
|
# enumerate
|
|
check(enumerate([]), size(h + 'l3P'))
|
|
# reverse
|
|
check(reversed(''), size(h + 'PP'))
|
|
# float
|
|
check(float(0), size(h + 'd'))
|
|
# sys.floatinfo
|
|
check(sys.float_info, size(vh) + self.P * len(sys.float_info))
|
|
# frame
|
|
import inspect
|
|
CO_MAXBLOCKS = 20
|
|
x = inspect.currentframe()
|
|
ncells = len(x.f_code.co_cellvars)
|
|
nfrees = len(x.f_code.co_freevars)
|
|
extras = x.f_code.co_stacksize + x.f_code.co_nlocals +\
|
|
ncells + nfrees - 1
|
|
check(x, size(vh + '12P3i' + CO_MAXBLOCKS*'3i' + 'P' + extras*'P'))
|
|
# function
|
|
def func(): pass
|
|
check(func, size(h + '11P'))
|
|
class c():
|
|
@staticmethod
|
|
def foo():
|
|
pass
|
|
@classmethod
|
|
def bar(cls):
|
|
pass
|
|
# staticmethod
|
|
check(foo, size(h + 'P'))
|
|
# classmethod
|
|
check(bar, size(h + 'P'))
|
|
# generator
|
|
def get_gen(): yield 1
|
|
check(get_gen(), size(h + 'Pi2P'))
|
|
# iterator
|
|
check(iter('abc'), size(h + 'lP'))
|
|
# callable-iterator
|
|
import re
|
|
check(re.finditer('',''), size(h + '2P'))
|
|
# list
|
|
samples = [[], [1,2,3], ['1', '2', '3']]
|
|
for sample in samples:
|
|
check(sample, size(vh + 'PP') + len(sample)*self.P)
|
|
# sortwrapper (list)
|
|
# XXX
|
|
# cmpwrapper (list)
|
|
# XXX
|
|
# listiterator (list)
|
|
check(iter([]), size(h + 'lP'))
|
|
# listreverseiterator (list)
|
|
check(reversed([]), size(h + 'lP'))
|
|
# long
|
|
check(0, size(vh))
|
|
check(1, size(vh) + self.longdigit)
|
|
check(-1, size(vh) + self.longdigit)
|
|
PyLong_BASE = 2**sys.int_info.bits_per_digit
|
|
check(PyLong_BASE, size(vh) + 2*self.longdigit)
|
|
check(PyLong_BASE**2-1, size(vh) + 2*self.longdigit)
|
|
check(PyLong_BASE**2, size(vh) + 3*self.longdigit)
|
|
# memory
|
|
check(memoryview(b''), size(h + 'P PP2P2i7P'))
|
|
# module
|
|
check(unittest, size(h + '3P'))
|
|
# None
|
|
check(None, size(h + ''))
|
|
# NotImplementedType
|
|
check(NotImplemented, size(h))
|
|
# object
|
|
check(object(), size(h + ''))
|
|
# property (descriptor object)
|
|
class C(object):
|
|
def getx(self): return self.__x
|
|
def setx(self, value): self.__x = value
|
|
def delx(self): del self.__x
|
|
x = property(getx, setx, delx, "")
|
|
check(x, size(h + '4Pi'))
|
|
# PyCObject
|
|
# XXX
|
|
# rangeiterator
|
|
check(iter(range(1)), size(h + '4l'))
|
|
# reverse
|
|
check(reversed(''), size(h + 'PP'))
|
|
# range
|
|
check(range(1), size(h + '3P'))
|
|
check(range(66000), size(h + '3P'))
|
|
# set
|
|
# frozenset
|
|
PySet_MINSIZE = 8
|
|
samples = [[], range(10), range(50)]
|
|
s = size(h + '3P2P' + PySet_MINSIZE*'lP' + 'lP')
|
|
for sample in samples:
|
|
minused = len(sample)
|
|
if minused == 0: tmp = 1
|
|
# the computation of minused is actually a bit more complicated
|
|
# but this suffices for the sizeof test
|
|
minused = minused*2
|
|
newsize = PySet_MINSIZE
|
|
while newsize <= minused:
|
|
newsize = newsize << 1
|
|
if newsize <= 8:
|
|
check(set(sample), s)
|
|
check(frozenset(sample), s)
|
|
else:
|
|
check(set(sample), s + newsize*struct.calcsize('lP'))
|
|
check(frozenset(sample), s + newsize*struct.calcsize('lP'))
|
|
# setiterator
|
|
check(iter(set()), size(h + 'P3P'))
|
|
# slice
|
|
check(slice(0), size(h + '3P'))
|
|
# super
|
|
check(super(int), size(h + '3P'))
|
|
# tuple
|
|
check((), size(vh))
|
|
check((1,2,3), size(vh) + 3*self.P)
|
|
# type
|
|
# (PyTypeObject + PyNumberMethods + PyMappingMethods +
|
|
# PySequenceMethods + PyBufferProcs)
|
|
s = size(vh + 'P2P15Pl4PP9PP11PI') + size('16Pi17P 3P 10P 2P 2P')
|
|
check(int, s)
|
|
# class
|
|
class newstyleclass(object): pass
|
|
check(newstyleclass, s)
|
|
# unicode
|
|
usize = len('\0'.encode('unicode-internal'))
|
|
samples = ['', '1'*100]
|
|
# we need to test for both sizes, because we don't know if the string
|
|
# has been cached
|
|
for s in samples:
|
|
basicsize = size(h + 'PPliP') + usize * (len(s) + 1)
|
|
check(s, basicsize)
|
|
# weakref
|
|
import weakref
|
|
check(weakref.ref(int), size(h + '2Pl2P'))
|
|
# weakproxy
|
|
# XXX
|
|
# weakcallableproxy
|
|
check(weakref.proxy(int), size(h + '2Pl2P'))
|
|
|
|
def test_pythontypes(self):
|
|
# check all types defined in Python/
|
|
h = self.header
|
|
vh = self.vheader
|
|
size = self.calcsize
|
|
check = self.check_sizeof
|
|
# _ast.AST
|
|
import _ast
|
|
check(_ast.AST(), size(h + ''))
|
|
# imp.NullImporter
|
|
import imp
|
|
check(imp.NullImporter(self.file.name), size(h + ''))
|
|
try:
|
|
raise TypeError
|
|
except TypeError:
|
|
tb = sys.exc_info()[2]
|
|
# traceback
|
|
if tb != None:
|
|
check(tb, size(h + '2P2i'))
|
|
# symtable entry
|
|
# XXX
|
|
# sys.flags
|
|
check(sys.flags, size(vh) + self.P * len(sys.flags))
|
|
|
|
def test_setfilesystemencoding(self):
|
|
old = sys.getfilesystemencoding()
|
|
sys.setfilesystemencoding("iso-8859-1")
|
|
self.assertEqual(sys.getfilesystemencoding(), "iso-8859-1")
|
|
sys.setfilesystemencoding(old)
|
|
|
|
def test_main():
|
|
test.support.run_unittest(SysModuleTest, SizeofTest)
|
|
|
|
if __name__ == "__main__":
|
|
test_main()
|