test_sys.py revision c5e88d5f471056c14ae9d6677cef5473282936ad
1# -*- coding: iso-8859-1 -*- 2import unittest, test.support 3import sys, io, os 4 5class SysModuleTest(unittest.TestCase): 6 7 def setUp(self): 8 self.orig_stdout = sys.stdout 9 self.orig_stderr = sys.stderr 10 self.orig_displayhook = sys.displayhook 11 12 def tearDown(self): 13 sys.stdout = self.orig_stdout 14 sys.stderr = self.orig_stderr 15 sys.displayhook = self.orig_displayhook 16 17 def test_original_displayhook(self): 18 import builtins 19 out = io.StringIO() 20 sys.stdout = out 21 22 dh = sys.__displayhook__ 23 24 self.assertRaises(TypeError, dh) 25 if hasattr(builtins, "_"): 26 del builtins._ 27 28 dh(None) 29 self.assertEqual(out.getvalue(), "") 30 self.assert_(not hasattr(builtins, "_")) 31 dh(42) 32 self.assertEqual(out.getvalue(), "42\n") 33 self.assertEqual(builtins._, 42) 34 35 del sys.stdout 36 self.assertRaises(RuntimeError, dh, 42) 37 38 def test_lost_displayhook(self): 39 del sys.displayhook 40 code = compile("42", "<string>", "single") 41 self.assertRaises(RuntimeError, eval, code) 42 43 def test_custom_displayhook(self): 44 def baddisplayhook(obj): 45 raise ValueError 46 sys.displayhook = baddisplayhook 47 code = compile("42", "<string>", "single") 48 self.assertRaises(ValueError, eval, code) 49 50 def test_original_excepthook(self): 51 err = io.StringIO() 52 sys.stderr = err 53 54 eh = sys.__excepthook__ 55 56 self.assertRaises(TypeError, eh) 57 try: 58 raise ValueError(42) 59 except ValueError as exc: 60 eh(*sys.exc_info()) 61 62 self.assert_(err.getvalue().endswith("ValueError: 42\n")) 63 64 # FIXME: testing the code for a lost or replaced excepthook in 65 # Python/pythonrun.c::PyErr_PrintEx() is tricky. 66 67 def test_exit(self): 68 self.assertRaises(TypeError, sys.exit, 42, 42) 69 70 # call without argument 71 try: 72 sys.exit(0) 73 except SystemExit as exc: 74 self.assertEquals(exc.code, 0) 75 except: 76 self.fail("wrong exception") 77 else: 78 self.fail("no exception") 79 80 # call with tuple argument with one entry 81 # entry will be unpacked 82 try: 83 sys.exit(42) 84 except SystemExit as exc: 85 self.assertEquals(exc.code, 42) 86 except: 87 self.fail("wrong exception") 88 else: 89 self.fail("no exception") 90 91 # call with integer argument 92 try: 93 sys.exit((42,)) 94 except SystemExit as exc: 95 self.assertEquals(exc.code, 42) 96 except: 97 self.fail("wrong exception") 98 else: 99 self.fail("no exception") 100 101 # call with string argument 102 try: 103 sys.exit("exit") 104 except SystemExit as exc: 105 self.assertEquals(exc.code, "exit") 106 except: 107 self.fail("wrong exception") 108 else: 109 self.fail("no exception") 110 111 # call with tuple argument with two entries 112 try: 113 sys.exit((17, 23)) 114 except SystemExit as exc: 115 self.assertEquals(exc.code, (17, 23)) 116 except: 117 self.fail("wrong exception") 118 else: 119 self.fail("no exception") 120 121 # test that the exit machinery handles SystemExits properly 122 import subprocess 123 rc = subprocess.call([sys.executable, "-c", 124 "raise SystemExit(47)"]) 125 self.assertEqual(rc, 47) 126 127 def test_getdefaultencoding(self): 128 self.assertRaises(TypeError, sys.getdefaultencoding, 42) 129 # can't check more than the type, as the user might have changed it 130 self.assert_(isinstance(sys.getdefaultencoding(), str)) 131 132 # testing sys.settrace() is done in test_trace.py 133 # testing sys.setprofile() is done in test_profile.py 134 135 def test_setcheckinterval(self): 136 self.assertRaises(TypeError, sys.setcheckinterval) 137 orig = sys.getcheckinterval() 138 for n in 0, 100, 120, orig: # orig last to restore starting state 139 sys.setcheckinterval(n) 140 self.assertEquals(sys.getcheckinterval(), n) 141 142 def test_recursionlimit(self): 143 self.assertRaises(TypeError, sys.getrecursionlimit, 42) 144 oldlimit = sys.getrecursionlimit() 145 self.assertRaises(TypeError, sys.setrecursionlimit) 146 self.assertRaises(ValueError, sys.setrecursionlimit, -42) 147 sys.setrecursionlimit(10000) 148 self.assertEqual(sys.getrecursionlimit(), 10000) 149 sys.setrecursionlimit(oldlimit) 150 151 def test_getwindowsversion(self): 152 if hasattr(sys, "getwindowsversion"): 153 v = sys.getwindowsversion() 154 self.assert_(isinstance(v, tuple)) 155 self.assertEqual(len(v), 5) 156 self.assert_(isinstance(v[0], int)) 157 self.assert_(isinstance(v[1], int)) 158 self.assert_(isinstance(v[2], int)) 159 self.assert_(isinstance(v[3], int)) 160 self.assert_(isinstance(v[4], str)) 161 162 def test_dlopenflags(self): 163 if hasattr(sys, "setdlopenflags"): 164 self.assert_(hasattr(sys, "getdlopenflags")) 165 self.assertRaises(TypeError, sys.getdlopenflags, 42) 166 oldflags = sys.getdlopenflags() 167 self.assertRaises(TypeError, sys.setdlopenflags) 168 sys.setdlopenflags(oldflags+1) 169 self.assertEqual(sys.getdlopenflags(), oldflags+1) 170 sys.setdlopenflags(oldflags) 171 172 def test_refcount(self): 173 self.assertRaises(TypeError, sys.getrefcount) 174 c = sys.getrefcount(None) 175 n = None 176 self.assertEqual(sys.getrefcount(None), c+1) 177 del n 178 self.assertEqual(sys.getrefcount(None), c) 179 if hasattr(sys, "gettotalrefcount"): 180 self.assert_(isinstance(sys.gettotalrefcount(), int)) 181 182 def test_getframe(self): 183 self.assertRaises(TypeError, sys._getframe, 42, 42) 184 self.assertRaises(ValueError, sys._getframe, 2000000000) 185 self.assert_( 186 SysModuleTest.test_getframe.__code__ \ 187 is sys._getframe().f_code 188 ) 189 190 # sys._current_frames() is a CPython-only gimmick. 191 def test_current_frames(self): 192 have_threads = True 193 try: 194 import _thread 195 except ImportError: 196 have_threads = False 197 198 if have_threads: 199 self.current_frames_with_threads() 200 else: 201 self.current_frames_without_threads() 202 203 # Test sys._current_frames() in a WITH_THREADS build. 204 def current_frames_with_threads(self): 205 import threading, _thread 206 import traceback 207 208 # Spawn a thread that blocks at a known place. Then the main 209 # thread does sys._current_frames(), and verifies that the frames 210 # returned make sense. 211 entered_g = threading.Event() 212 leave_g = threading.Event() 213 thread_info = [] # the thread's id 214 215 def f123(): 216 g456() 217 218 def g456(): 219 thread_info.append(_thread.get_ident()) 220 entered_g.set() 221 leave_g.wait() 222 223 t = threading.Thread(target=f123) 224 t.start() 225 entered_g.wait() 226 227 # At this point, t has finished its entered_g.set(), although it's 228 # impossible to guess whether it's still on that line or has moved on 229 # to its leave_g.wait(). 230 self.assertEqual(len(thread_info), 1) 231 thread_id = thread_info[0] 232 233 d = sys._current_frames() 234 235 main_id = _thread.get_ident() 236 self.assert_(main_id in d) 237 self.assert_(thread_id in d) 238 239 # Verify that the captured main-thread frame is _this_ frame. 240 frame = d.pop(main_id) 241 self.assert_(frame is sys._getframe()) 242 243 # Verify that the captured thread frame is blocked in g456, called 244 # from f123. This is a litte tricky, since various bits of 245 # threading.py are also in the thread's call stack. 246 frame = d.pop(thread_id) 247 stack = traceback.extract_stack(frame) 248 for i, (filename, lineno, funcname, sourceline) in enumerate(stack): 249 if funcname == "f123": 250 break 251 else: 252 self.fail("didn't find f123() on thread's call stack") 253 254 self.assertEqual(sourceline, "g456()") 255 256 # And the next record must be for g456(). 257 filename, lineno, funcname, sourceline = stack[i+1] 258 self.assertEqual(funcname, "g456") 259 self.assert_(sourceline in ["leave_g.wait()", "entered_g.set()"]) 260 261 # Reap the spawned thread. 262 leave_g.set() 263 t.join() 264 265 # Test sys._current_frames() when thread support doesn't exist. 266 def current_frames_without_threads(self): 267 # Not much happens here: there is only one thread, with artificial 268 # "thread id" 0. 269 d = sys._current_frames() 270 self.assertEqual(len(d), 1) 271 self.assert_(0 in d) 272 self.assert_(d[0] is sys._getframe()) 273 274 def test_attributes(self): 275 self.assert_(isinstance(sys.api_version, int)) 276 self.assert_(isinstance(sys.argv, list)) 277 self.assert_(sys.byteorder in ("little", "big")) 278 self.assert_(isinstance(sys.builtin_module_names, tuple)) 279 self.assert_(isinstance(sys.copyright, str)) 280 self.assert_(isinstance(sys.exec_prefix, str)) 281 self.assert_(isinstance(sys.executable, str)) 282 self.assertEqual(len(sys.float_info), 11) 283 self.assertEqual(sys.float_info.radix, 2) 284 self.assert_(isinstance(sys.hexversion, int)) 285 self.assert_(isinstance(sys.maxsize, int)) 286 self.assert_(isinstance(sys.maxunicode, int)) 287 self.assert_(isinstance(sys.platform, str)) 288 self.assert_(isinstance(sys.prefix, str)) 289 self.assert_(isinstance(sys.version, str)) 290 vi = sys.version_info 291 self.assert_(isinstance(vi, tuple)) 292 self.assertEqual(len(vi), 5) 293 self.assert_(isinstance(vi[0], int)) 294 self.assert_(isinstance(vi[1], int)) 295 self.assert_(isinstance(vi[2], int)) 296 self.assert_(vi[3] in ("alpha", "beta", "candidate", "final")) 297 self.assert_(isinstance(vi[4], int)) 298 299 def test_43581(self): 300 # Can't use sys.stdout, as this is a cStringIO object when 301 # the test runs under regrtest. 302 self.assertEqual(sys.__stdout__.encoding, sys.__stderr__.encoding) 303 304 def test_intern(self): 305 self.assertRaises(TypeError, sys.intern) 306 s = "never interned before" 307 self.assert_(sys.intern(s) is s) 308 s2 = s.swapcase().swapcase() 309 self.assert_(sys.intern(s2) is s) 310 311 # Subclasses of string can't be interned, because they 312 # provide too much opportunity for insane things to happen. 313 # We don't want them in the interned dict and if they aren't 314 # actually interned, we don't want to create the appearance 315 # that they are by allowing intern() to succeeed. 316 class S(str): 317 def __hash__(self): 318 return 123 319 320 self.assertRaises(TypeError, sys.intern, S("abc")) 321 322 323 def test_sys_flags(self): 324 self.failUnless(sys.flags) 325 attrs = ("debug", "division_warning", 326 "inspect", "interactive", "optimize", "dont_write_bytecode", 327 "no_user_site", "no_site", "ignore_environment", "verbose", 328 "bytes_warning") 329 for attr in attrs: 330 self.assert_(hasattr(sys.flags, attr), attr) 331 self.assertEqual(type(getattr(sys.flags, attr)), int, attr) 332 self.assert_(repr(sys.flags)) 333 self.assertEqual(len(sys.flags), len(attrs)) 334 335 def test_clear_type_cache(self): 336 sys._clear_type_cache() 337 338 def test_compact_freelists(self): 339 sys._compact_freelists() 340 r = sys._compact_freelists() 341 ## freed blocks shouldn't change 342 #self.assertEqual(r[0][2], 0) 343 ## fill freelists 344 #ints = list(range(10000)) 345 #floats = [float(i) for i in ints] 346 #del ints 347 #del floats 348 ## should free more than 100 blocks 349 #r = sys._compact_freelists() 350 #self.assert_(r[0][1] > 100, r[0][1]) 351 #self.assert_(r[0][2] > 100, r[0][2]) 352 353 def test_ioencoding(self): 354 import subprocess,os 355 env = dict(os.environ) 356 357 # Test character: cent sign, encoded as 0x4A (ASCII J) in CP424, 358 # not representable in ASCII. 359 360 env["PYTHONIOENCODING"] = "cp424" 361 p = subprocess.Popen([sys.executable, "-c", 'print(chr(0xa2))'], 362 stdout = subprocess.PIPE, env=env) 363 out = p.stdout.read() 364 self.assertEqual(out, "\xa2\n".encode("cp424")) 365 366 env["PYTHONIOENCODING"] = "ascii:replace" 367 p = subprocess.Popen([sys.executable, "-c", 'print(chr(0xa2))'], 368 stdout = subprocess.PIPE, env=env) 369 out = p.stdout.read().strip() 370 self.assertEqual(out, b'?') 371 372 373class SizeofTest(unittest.TestCase): 374 375 def setUp(self): 376 import struct 377 self.i = len(struct.pack('i', 0)) 378 self.l = len(struct.pack('l', 0)) 379 self.p = len(struct.pack('P', 0)) 380 self.headersize = self.l + self.p 381 if hasattr(sys, "gettotalrefcount"): 382 self.headersize += 2 * self.p 383 self.file = open(test.support.TESTFN, 'wb') 384 385 def tearDown(self): 386 self.file.close() 387 test.support.unlink(test.support.TESTFN) 388 389 def check_sizeof(self, o, size): 390 result = sys.getsizeof(o) 391 msg = 'wrong size for %s: got %d, expected %d' \ 392 % (type(o), result, size) 393 self.assertEqual(result, size, msg) 394 395 def align(self, value): 396 mod = value % self.p 397 if mod != 0: 398 return value - mod + self.p 399 else: 400 return value 401 402 def test_align(self): 403 self.assertEqual(self.align(0) % self.p, 0) 404 self.assertEqual(self.align(1) % self.p, 0) 405 self.assertEqual(self.align(3) % self.p, 0) 406 self.assertEqual(self.align(4) % self.p, 0) 407 self.assertEqual(self.align(7) % self.p, 0) 408 self.assertEqual(self.align(8) % self.p, 0) 409 self.assertEqual(self.align(9) % self.p, 0) 410 411 def test_standardtypes(self): 412 i = self.i 413 l = self.l 414 p = self.p 415 h = self.headersize 416 # bool 417 self.check_sizeof(True, h + 2*l) 418 # bytearray 419 self.check_sizeof(bytes(), h + self.align(i) + l + p) 420 # cell 421 def get_cell(): 422 x = 42 423 def inner(): 424 return x 425 return inner 426 self.check_sizeof(get_cell().__closure__[0], h + p) 427 # code XXX wrong size 428 # self.check_sizeof(get_cell().__code__, h + self.align(4*i) + 8*p +\ 429 # self.align(i) + 2*p) 430 # complex 431 self.check_sizeof(complex(0,1), h + 2*8) 432 # enumerate 433 self.check_sizeof(enumerate([]), h + l + 3*p) 434 # reverse 435 self.check_sizeof(reversed(''), h + l + p ) 436 # file XXX wrong size 437 #self.check_sizeof(self.file, h + 4*p + self.align(2*i) + 4*p +\ 438 # self.align(3*i) + 3*p + self.align(i)) 439 # float 440 self.check_sizeof(float(0), h + 8) 441 # function 442 def func(): pass 443 self.check_sizeof(func, h + 11 * p) 444 class c(): 445 @staticmethod 446 def foo(): 447 pass 448 @classmethod 449 def bar(cls): 450 pass 451 # staticmethod 452 self.check_sizeof(foo, h + l) 453 # classmethod 454 self.check_sizeof(bar, h + l) 455 # generator 456 def get_gen(): yield 1 457 self.check_sizeof(get_gen(), h + p + self.align(i) + 2*p) 458 # builtin_function_or_method 459 self.check_sizeof(abs, h + 3*p) 460 # module 461 self.check_sizeof(unittest, h + p) 462 # range 463 self.check_sizeof(range(1), h + 3*p) 464 # slice 465 self.check_sizeof(slice(0), h + 3*p) 466 467 h += l 468 # new-style class 469 class class_newstyle(object): 470 def method(): 471 pass 472 # type (PyTypeObject + PyNumberMethods + PyMappingMethods + 473 # PySequenceMethods + PyBufferProcs) 474 # XXX wrong size 475 # len_typeobject = p + 2*l + 15*p + l + 4*p + l + 9*p + l + 11*p 476 # self.check_sizeof(class_newstyle, 477 # h + len_typeobject + 42*p + 10*p + 3*p + 6*p) 478 479 480 def test_specialtypes(self): 481 i = self.i 482 l = self.l 483 p = self.p 484 h = self.headersize 485 # dict 486 self.check_sizeof({}, h + 3*l + 3*p + 8*(l + 2*p)) 487 longdict = {1:1, 2:2, 3:3, 4:4, 5:5, 6:6, 7:7, 8:8} 488 self.check_sizeof(longdict, h + 3*l + 3*p + 8*(l + 2*p) + 16*(l + 2*p)) 489 # list 490 self.check_sizeof([], h + l + p + l) 491 self.check_sizeof([1, 2, 3], h + l + p + l + 3*l) 492 493 h += l 494 # long 495 self.check_sizeof(0, h + self.align(2)) 496 self.check_sizeof(1, h + self.align(2)) 497 self.check_sizeof(-1, h + self.align(2)) 498 self.check_sizeof(32768, h + self.align(2) + 2) 499 self.check_sizeof(32768*32768-1, h + self.align(2) + 2) 500 self.check_sizeof(32768*32768, h + self.align(2) + 4) 501 # XXX add Unicode support 502 # self.check_sizeof('', h + l + self.align(i + 1)) 503 # self.check_sizeof('abc', h + l + self.align(i + 1) + 3) 504 505 506def test_main(): 507 test.support.run_unittest(SysModuleTest, SizeofTest) 508 509if __name__ == "__main__": 510 test_main() 511