PageRenderTime 112ms CodeModel.GetById 11ms app.highlight 81ms RepoModel.GetById 1ms app.codeStats 1ms

/Lib/test/test_sys.py

http://unladen-swallow.googlecode.com/
Python | 773 lines | 767 code | 5 blank | 1 comment | 1 complexity | ef6fcaf774386986cb637636bf3f4a7d MD5 | raw file
  1# -*- coding: iso-8859-1 -*-
  2import unittest, test.test_support
  3import sys, cStringIO, os
  4import struct
  5try:
  6    import _llvm
  7except ImportError:
  8    WITH_LLVM = False
  9else:
 10    WITH_LLVM = True
 11    del _llvm
 12
 13class SysModuleTest(unittest.TestCase):
 14
 15    def test_original_displayhook(self):
 16        import __builtin__
 17        savestdout = sys.stdout
 18        out = cStringIO.StringIO()
 19        sys.stdout = out
 20
 21        dh = sys.__displayhook__
 22
 23        self.assertRaises(TypeError, dh)
 24        if hasattr(__builtin__, "_"):
 25            del __builtin__._
 26
 27        dh(None)
 28        self.assertEqual(out.getvalue(), "")
 29        self.assert_(not hasattr(__builtin__, "_"))
 30        dh(42)
 31        self.assertEqual(out.getvalue(), "42\n")
 32        self.assertEqual(__builtin__._, 42)
 33
 34        del sys.stdout
 35        self.assertRaises(RuntimeError, dh, 42)
 36
 37        sys.stdout = savestdout
 38
 39    def test_lost_displayhook(self):
 40        olddisplayhook = sys.displayhook
 41        del sys.displayhook
 42        code = compile("42", "<string>", "single")
 43        self.assertRaises(RuntimeError, eval, code)
 44        sys.displayhook = olddisplayhook
 45
 46    def test_custom_displayhook(self):
 47        olddisplayhook = sys.displayhook
 48        def baddisplayhook(obj):
 49            raise ValueError
 50        sys.displayhook = baddisplayhook
 51        code = compile("42", "<string>", "single")
 52        self.assertRaises(ValueError, eval, code)
 53        sys.displayhook = olddisplayhook
 54
 55    def test_original_excepthook(self):
 56        savestderr = sys.stderr
 57        err = cStringIO.StringIO()
 58        sys.stderr = err
 59
 60        eh = sys.__excepthook__
 61
 62        self.assertRaises(TypeError, eh)
 63        try:
 64            raise ValueError(42)
 65        except ValueError, exc:
 66            eh(*sys.exc_info())
 67
 68        sys.stderr = savestderr
 69        self.assert_(err.getvalue().endswith("ValueError: 42\n"))
 70
 71    # FIXME: testing the code for a lost or replaced excepthook in
 72    # Python/pythonrun.c::PyErr_PrintEx() is tricky.
 73
 74    def test_exc_clear(self):
 75        self.assertRaises(TypeError, sys.exc_clear, 42)
 76
 77        # Verify that exc_info is present and matches exc, then clear it, and
 78        # check that it worked.
 79        def clear_check(exc):
 80            typ, value, traceback = sys.exc_info()
 81            self.assert_(typ is not None)
 82            self.assert_(value is exc)
 83            self.assert_(traceback is not None)
 84
 85            sys.exc_clear()
 86
 87            typ, value, traceback = sys.exc_info()
 88            self.assert_(typ is None)
 89            self.assert_(value is None)
 90            self.assert_(traceback is None)
 91
 92        def clear():
 93            try:
 94                raise ValueError, 42
 95            except ValueError, exc:
 96                clear_check(exc)
 97
 98        # Raise an exception and check that it can be cleared
 99        clear()
100
101        # Verify that a frame currently handling an exception is
102        # unaffected by calling exc_clear in a nested frame.
103        try:
104            raise ValueError, 13
105        except ValueError, exc:
106            typ1, value1, traceback1 = sys.exc_info()
107            clear()
108            typ2, value2, traceback2 = sys.exc_info()
109
110            self.assert_(typ1 is typ2)
111            self.assert_(value1 is exc)
112            self.assert_(value1 is value2)
113            self.assert_(traceback1 is traceback2)
114
115        # Check that an exception can be cleared outside of an except block
116        clear_check(exc)
117
118    def test_exit(self):
119        self.assertRaises(TypeError, sys.exit, 42, 42)
120
121        # call without argument
122        try:
123            sys.exit(0)
124        except SystemExit, exc:
125            self.assertEquals(exc.code, 0)
126        except:
127            self.fail("wrong exception")
128        else:
129            self.fail("no exception")
130
131        # call with tuple argument with one entry
132        # entry will be unpacked
133        try:
134            sys.exit(42)
135        except SystemExit, exc:
136            self.assertEquals(exc.code, 42)
137        except:
138            self.fail("wrong exception")
139        else:
140            self.fail("no exception")
141
142        # call with integer argument
143        try:
144            sys.exit((42,))
145        except SystemExit, exc:
146            self.assertEquals(exc.code, 42)
147        except:
148            self.fail("wrong exception")
149        else:
150            self.fail("no exception")
151
152        # call with string argument
153        try:
154            sys.exit("exit")
155        except SystemExit, exc:
156            self.assertEquals(exc.code, "exit")
157        except:
158            self.fail("wrong exception")
159        else:
160            self.fail("no exception")
161
162        # call with tuple argument with two entries
163        try:
164            sys.exit((17, 23))
165        except SystemExit, exc:
166            self.assertEquals(exc.code, (17, 23))
167        except:
168            self.fail("wrong exception")
169        else:
170            self.fail("no exception")
171
172        # test that the exit machinery handles SystemExits properly
173        import subprocess
174        # both unnormalized...
175        rc = subprocess.call([sys.executable, "-c",
176                              "raise SystemExit, 46"])
177        self.assertEqual(rc, 46)
178        # ... and normalized
179        rc = subprocess.call([sys.executable, "-c",
180                              "raise SystemExit(47)"])
181        self.assertEqual(rc, 47)
182
183
184    def test_getdefaultencoding(self):
185        if test.test_support.have_unicode:
186            self.assertRaises(TypeError, sys.getdefaultencoding, 42)
187            # can't check more than the type, as the user might have changed it
188            self.assert_(isinstance(sys.getdefaultencoding(), str))
189
190    # testing sys.settrace() is done in test_trace.py
191    # testing sys.setprofile() is done in test_profile.py
192
193    def test_setcheckinterval(self):
194        self.assertRaises(TypeError, sys.setcheckinterval)
195        orig = sys.getcheckinterval()
196        for n in 0, 100, 120, orig: # orig last to restore starting state
197            sys.setcheckinterval(n)
198            self.assertEquals(sys.getcheckinterval(), n)
199
200    def test_recursionlimit(self):
201        self.assertRaises(TypeError, sys.getrecursionlimit, 42)
202        oldlimit = sys.getrecursionlimit()
203        self.assertRaises(TypeError, sys.setrecursionlimit)
204        self.assertRaises(ValueError, sys.setrecursionlimit, -42)
205        sys.setrecursionlimit(10000)
206        self.assertEqual(sys.getrecursionlimit(), 10000)
207        sys.setrecursionlimit(oldlimit)
208
209    def test_getwindowsversion(self):
210        if hasattr(sys, "getwindowsversion"):
211            v = sys.getwindowsversion()
212            self.assert_(isinstance(v, tuple))
213            self.assertEqual(len(v), 5)
214            self.assert_(isinstance(v[0], int))
215            self.assert_(isinstance(v[1], int))
216            self.assert_(isinstance(v[2], int))
217            self.assert_(isinstance(v[3], int))
218            self.assert_(isinstance(v[4], str))
219
220    def test_dlopenflags(self):
221        if hasattr(sys, "setdlopenflags"):
222            self.assert_(hasattr(sys, "getdlopenflags"))
223            self.assertRaises(TypeError, sys.getdlopenflags, 42)
224            oldflags = sys.getdlopenflags()
225            self.assertRaises(TypeError, sys.setdlopenflags)
226            sys.setdlopenflags(oldflags+1)
227            self.assertEqual(sys.getdlopenflags(), oldflags+1)
228            sys.setdlopenflags(oldflags)
229
230    def test_refcount(self):
231        # n here must be a global in order for this test to pass while
232        # tracing with a python function.  Tracing calls PyFrame_FastToLocals
233        # which will add a copy of any locals to the frame object, causing
234        # the reference count to increase by 2 instead of 1.
235        global n
236        self.assertRaises(TypeError, sys.getrefcount)
237        c = sys.getrefcount(None)
238        n = None
239        self.assertEqual(sys.getrefcount(None), c+1)
240        del n
241        self.assertEqual(sys.getrefcount(None), c)
242        if hasattr(sys, "gettotalrefcount"):
243            self.assert_(isinstance(sys.gettotalrefcount(), int))
244
245    def test_getframe(self):
246        self.assertRaises(TypeError, sys._getframe, 42, 42)
247        self.assertRaises(ValueError, sys._getframe, 2000000000)
248        self.assert_(
249            SysModuleTest.test_getframe.im_func.func_code \
250            is sys._getframe().f_code
251        )
252
253    # sys._current_frames() is a CPython-only gimmick.
254    def test_current_frames(self):
255        have_threads = True
256        try:
257            import thread
258        except ImportError:
259            have_threads = False
260
261        if have_threads:
262            self.current_frames_with_threads()
263        else:
264            self.current_frames_without_threads()
265
266    # Test sys._current_frames() in a WITH_THREADS build.
267    def current_frames_with_threads(self):
268        import threading, thread
269        import traceback
270
271        # Spawn a thread that blocks at a known place.  Then the main
272        # thread does sys._current_frames(), and verifies that the frames
273        # returned make sense.
274        entered_g = threading.Event()
275        leave_g = threading.Event()
276        thread_info = []  # the thread's id
277
278        def f123():
279            g456()
280
281        def g456():
282            thread_info.append(thread.get_ident())
283            entered_g.set()
284            leave_g.wait()
285
286        t = threading.Thread(target=f123)
287        t.start()
288        entered_g.wait()
289
290        # At this point, t has finished its entered_g.set(), although it's
291        # impossible to guess whether it's still on that line or has moved on
292        # to its leave_g.wait().
293        self.assertEqual(len(thread_info), 1)
294        thread_id = thread_info[0]
295
296        d = sys._current_frames()
297
298        main_id = thread.get_ident()
299        self.assert_(main_id in d)
300        self.assert_(thread_id in d)
301
302        # Verify that the captured main-thread frame is _this_ frame.
303        frame = d.pop(main_id)
304        self.assert_(frame is sys._getframe())
305
306        # Verify that the captured thread frame is blocked in g456, called
307        # from f123.  This is a litte tricky, since various bits of
308        # threading.py are also in the thread's call stack.
309        frame = d.pop(thread_id)
310        stack = traceback.extract_stack(frame)
311        for i, (filename, lineno, funcname, sourceline) in enumerate(stack):
312            if funcname == "f123":
313                break
314        else:
315            self.fail("didn't find f123() on thread's call stack")
316
317        self.assertEqual(sourceline, "g456()")
318
319        # And the next record must be for g456().
320        filename, lineno, funcname, sourceline = stack[i+1]
321        self.assertEqual(funcname, "g456")
322        self.assert_(sourceline in ["leave_g.wait()", "entered_g.set()"])
323
324        # Reap the spawned thread.
325        leave_g.set()
326        t.join()
327
328    # Test sys._current_frames() when thread support doesn't exist.
329    def current_frames_without_threads(self):
330        # Not much happens here:  there is only one thread, with artificial
331        # "thread id" 0.
332        d = sys._current_frames()
333        self.assertEqual(len(d), 1)
334        self.assert_(0 in d)
335        self.assert_(d[0] is sys._getframe())
336
337    def test_attributes(self):
338        self.assert_(isinstance(sys.api_version, int))
339        self.assert_(isinstance(sys.argv, list))
340        self.assert_(sys.byteorder in ("little", "big"))
341        self.assert_(isinstance(sys.builtin_module_names, tuple))
342        self.assert_(isinstance(sys.copyright, basestring))
343        self.assert_(isinstance(sys.exec_prefix, basestring))
344        self.assert_(isinstance(sys.executable, basestring))
345        self.assertEqual(len(sys.float_info), 11)
346        self.assertEqual(sys.float_info.radix, 2)
347        self.assert_(isinstance(sys.hexversion, int))
348        self.assert_(isinstance(sys.maxint, int))
349        if test.test_support.have_unicode:
350            self.assert_(isinstance(sys.maxunicode, int))
351        self.assert_(isinstance(sys.platform, basestring))
352        self.assert_(isinstance(sys.prefix, basestring))
353        self.assert_(isinstance(sys.version, basestring))
354        vi = sys.version_info
355        self.assert_(isinstance(vi, tuple))
356        self.assertEqual(len(vi), 5)
357        self.assert_(isinstance(vi[0], int))
358        self.assert_(isinstance(vi[1], int))
359        self.assert_(isinstance(vi[2], int))
360        self.assert_(vi[3] in ("alpha", "beta", "candidate", "final"))
361        self.assert_(isinstance(vi[4], int))
362
363    def test_43581(self):
364        # Can't use sys.stdout, as this is a cStringIO object when
365        # the test runs under regrtest.
366        self.assert_(sys.__stdout__.encoding == sys.__stderr__.encoding)
367
368    def test_sys_flags(self):
369        self.failUnless(sys.flags)
370        attrs = ("debug", "py3k_warning", "division_warning", "division_new",
371                 "inspect", "interactive", "optimize", "dont_write_bytecode",
372                 "no_site", "ignore_environment", "tabcheck", "verbose",
373                 "unicode", "bytes_warning")
374        for attr in attrs:
375            self.assert_(hasattr(sys.flags, attr), attr)
376            self.assertEqual(type(getattr(sys.flags, attr)), int, attr)
377        self.assert_(hasattr(sys.flags, "jit_control"))
378        self.assert_(repr(sys.flags))
379
380    def test_clear_type_cache(self):
381        sys._clear_type_cache()
382
383    def test_ioencoding(self):
384        import subprocess,os
385        env = dict(os.environ)
386
387        # Test character: cent sign, encoded as 0x4A (ASCII J) in CP424,
388        # not representable in ASCII.
389
390        env["PYTHONIOENCODING"] = "cp424"
391        p = subprocess.Popen([sys.executable, "-c", 'print unichr(0xa2)'],
392                             stdout = subprocess.PIPE, env=env)
393        out = p.stdout.read().strip()
394        self.assertEqual(out, unichr(0xa2).encode("cp424"))
395
396        env["PYTHONIOENCODING"] = "ascii:replace"
397        p = subprocess.Popen([sys.executable, "-c", 'print unichr(0xa2)'],
398                             stdout = subprocess.PIPE, env=env)
399        out = p.stdout.read().strip()
400        self.assertEqual(out, '?')
401
402    if hasattr(sys, "setbailerror"):
403        def test_bailerror(self):
404            # sys.setbailerror() is used to raise an exception when native code
405            # bails to the interpreter. This is useful for testing native code
406            # generation/execution. configuring with --with-llvm is required
407            # to get sys.{set,get}bailerror().
408            tracer = sys.gettrace()
409            bail = sys.getbailerror()
410
411            def foo():
412                sys.settrace(lambda *args: None)
413            def bar():
414                sys.setbailerror(True)
415                foo()
416                return 7
417            bar.__code__.co_optimization = 2
418            bar.__code__.co_use_jit = True
419
420            def run_test():
421                # Once bailerror and tracing have been turned on, they cannot
422                # be turned off by generated machine code, because running
423                # generated machine code under tracing will cause another bail
424                # before we can turn either setting off.  Under -Xjit=always,
425                # any finally or except clauses we write to catch the bail
426                # exception will use the compiled machine code unless we
427                # circumvent the JIT.  The only reliable way at this time to
428                # guarantee execution from the interpreter is to cause a bail
429                # in the function body while bailerror is turned off.  We do
430                # this here by setting tracing and then turning it back off.
431                sys.settrace(lambda *args: None)  # Causes a bail.
432                sys.settrace(tracer)
433                try:
434                    # We need to indirect the settrace through at least one
435                    # function because bailerror doesn't currently respect
436                    # the block stack of the bailing function, so no finally or
437                    # except clauses will be run.
438                    bar()
439                except RuntimeError:
440                    pass
441                else:
442                    self.fail("Failed to raise RuntimeError")
443                finally:
444                    sys.settrace(tracer)
445                    sys.setbailerror(bail)
446            run_test()
447
448
449class SizeofTest(unittest.TestCase):
450
451    TPFLAGS_HAVE_GC = 1<<14
452    TPFLAGS_HEAPTYPE = 1L<<9
453
454    def setUp(self):
455        self.c = len(struct.pack('c', ' '))
456        self.H = len(struct.pack('H', 0))
457        self.i = len(struct.pack('i', 0))
458        self.l = len(struct.pack('l', 0))
459        self.P = len(struct.pack('P', 0))
460        # due to missing size_t information from struct, it is assumed that
461        # sizeof(Py_ssize_t) = sizeof(void*)
462        self.header = 'PP'
463        self.vheader = self.header + 'P'
464        if hasattr(sys, "gettotalrefcount"):
465            self.header += '2P'
466            self.vheader += '2P'
467        import _testcapi
468        self.gc_headsize = _testcapi.SIZEOF_PYGC_HEAD
469        self.file = open(test.test_support.TESTFN, 'wb')
470
471    def tearDown(self):
472        self.file.close()
473        test.test_support.unlink(test.test_support.TESTFN)
474
475    def check_sizeof(self, o, size):
476        result = sys.getsizeof(o)
477        if ((type(o) == type) and (o.__flags__ & self.TPFLAGS_HEAPTYPE) or\
478           ((type(o) != type) and (type(o).__flags__ & self.TPFLAGS_HAVE_GC))):
479            size += self.gc_headsize
480        msg = 'wrong size for %s: got %d, expected %d' \
481                % (type(o), result, size)
482        self.assertEqual(result, size, msg)
483
484    def calcsize(self, fmt):
485        """Wrapper around struct.calcsize which enforces the alignment of the
486        end of a structure to the alignment requirement of pointer.
487
488        Note: This wrapper should only be used if a pointer member is included
489        and no member with a size larger than a pointer exists.
490        """
491        return struct.calcsize(fmt + '0P')
492
493    def test_gc_head_size(self):
494        # Check that the gc header size is added to objects tracked by the gc.
495        h = self.header
496        size = self.calcsize
497        gc_header_size = self.gc_headsize
498        # bool objects are not gc tracked
499        self.assertEqual(sys.getsizeof(True), size(h + 'l'))
500        # but lists are
501        self.assertEqual(sys.getsizeof([]), size(h + 'P PP') + gc_header_size)
502
503    def test_default(self):
504        h = self.header
505        size = self.calcsize
506        self.assertEqual(sys.getsizeof(True, -1), size(h + 'l'))
507
508    def test_objecttypes(self):
509        # check all types defined in Objects/
510        h = self.header
511        vh = self.vheader
512        size = self.calcsize
513        check = self.check_sizeof
514        # bool
515        check(True, size(h + 'l'))
516        # buffer
517        check(buffer(''), size(h + '2P2Pil'))
518        # builtin_function_or_method
519        check(len, size(h + '3P'))
520        # bytearray
521        samples = ['', 'u'*100000]
522        for sample in samples:
523            x = bytearray(sample)
524            check(x, size(vh + 'iPP') + x.__alloc__() * self.c)
525        # bytearray_iterator
526        check(iter(bytearray()), size(h + 'PP'))
527        # cell
528        def get_cell():
529            x = 42
530            def inner():
531                return x
532            return inner
533        check(get_cell().func_closure[0], size(h + 'P'))
534        # classobj (old-style class)
535        class class_oldstyle():
536            def method():
537                pass
538        check(class_oldstyle, size(h + '6P'))
539        # instance (old-style class)
540        check(class_oldstyle(), size(h + '3P'))
541        # instancemethod (old-style class)
542        check(class_oldstyle().method, size(h + '4P'))
543        # complex
544        check(complex(0,1), size(h + '2d'))
545        # code
546        if WITH_LLVM:
547            check(get_cell().func_code, size(h + '4i8Pi6Pc2ilP'))
548        else:
549            check(get_cell().func_code, size(h + '4i8Pi3P'))
550        # BaseException
551        check(BaseException(), size(h + '3P'))
552        # UnicodeEncodeError
553        check(UnicodeEncodeError("", u"", 0, 0, ""), size(h + '5P2PP'))
554        # UnicodeDecodeError
555        check(UnicodeDecodeError("", "", 0, 0, ""), size(h + '5P2PP'))
556        # UnicodeTranslateError
557        check(UnicodeTranslateError(u"", 0, 1, ""), size(h + '5P2PP'))
558        # method_descriptor (descriptor object)
559        check(str.lower, size(h + '2PP'))
560        # classmethod_descriptor (descriptor object)
561        # XXX
562        # member_descriptor (descriptor object)
563        import datetime
564        check(datetime.timedelta.days, size(h + '2PP'))
565        # getset_descriptor (descriptor object)
566        import __builtin__
567        check(__builtin__.file.closed, size(h + '2PP'))
568        # wrapper_descriptor (descriptor object)
569        check(int.__add__, size(h + '2P2P'))
570        # dictproxy
571        class C(object): pass
572        check(C.__dict__, size(h + 'P'))
573        # method-wrapper (descriptor object)
574        check({}.__iter__, size(h + '2P'))
575        # dict
576        dict_llvm_suffix = ''
577        if WITH_LLVM:
578            dict_llvm_suffix = 'P'
579        check({}, size(h + '3P2P' + 8*'P2P' + dict_llvm_suffix))
580        x = {1:1, 2:2, 3:3, 4:4, 5:5, 6:6, 7:7, 8:8}
581        check(x, size(h + '3P2P' + 8*'P2P' + dict_llvm_suffix) + 16*size('P2P'))
582        del dict_llvm_suffix
583        # dictionary-keyiterator
584        check({}.iterkeys(), size(h + 'P2PPP'))
585        # dictionary-valueiterator
586        check({}.itervalues(), size(h + 'P2PPP'))
587        # dictionary-itemiterator
588        check({}.iteritems(), size(h + 'P2PPP'))
589        # ellipses
590        check(Ellipsis, size(h + ''))
591        # EncodingMap
592        import codecs, encodings.iso8859_3
593        x = codecs.charmap_build(encodings.iso8859_3.decoding_table)
594        check(x, size(h + '32B2iB'))
595        # enumerate
596        check(enumerate([]), size(h + 'l3P'))
597        # file
598        check(self.file, size(h + '4P2i4P3i3Pi'))
599        # float
600        check(float(0), size(h + 'd'))
601        # sys.floatinfo
602        check(sys.float_info, size(vh) + self.P * len(sys.float_info))
603        # frame
604        import inspect
605        CO_MAXBLOCKS = 20
606        x = inspect.currentframe()
607        ncells = len(x.f_code.co_cellvars)
608        nfrees = len(x.f_code.co_freevars)
609        extras = x.f_code.co_stacksize + x.f_code.co_nlocals +\
610                 ncells + nfrees - 1
611        if WITH_LLVM:
612            check(x, size(vh + '12P4i' + CO_MAXBLOCKS*'3i' + 'P' + extras*'P'))
613        else:
614            check(x, size(vh + '12P3i' + CO_MAXBLOCKS*'3i' + 'P' + extras*'P'))
615        # function
616        def func(): pass
617        check(func, size(h + '9P'))
618        class c():
619            @staticmethod
620            def foo():
621                pass
622            @classmethod
623            def bar(cls):
624                pass
625            # staticmethod
626            check(foo, size(h + 'P'))
627            # classmethod
628            check(bar, size(h + 'P'))
629        # generator
630        def get_gen(): yield 1
631        check(get_gen(), size(h + 'Pi2P'))
632        # integer
633        check(1, size(h + 'l'))
634        check(100, size(h + 'l'))
635        # iterator
636        check(iter('abc'), size(h + 'lP'))
637        # callable-iterator
638        import re
639        check(re.finditer('',''), size(h + '2P'))
640        # list
641        samples = [[], [1,2,3], ['1', '2', '3']]
642        for sample in samples:
643            check(sample, size(vh + 'PP') + len(sample)*self.P)
644        # sortwrapper (list)
645        # XXX
646        # cmpwrapper (list)
647        # XXX
648        # listiterator (list)
649        check(iter([]), size(h + 'lP'))
650        # listreverseiterator (list)
651        check(reversed([]), size(h + 'lP'))
652        # long
653        check(0L, size(vh + 'H') - self.H)
654        check(1L, size(vh + 'H'))
655        check(-1L, size(vh + 'H'))
656        check(32768L, size(vh + 'H') + self.H)
657        check(32768L*32768L-1, size(vh + 'H') + self.H)
658        check(32768L*32768L, size(vh + 'H') + 2*self.H)
659        # module
660        check(unittest, size(h + 'P'))
661        # None
662        check(None, size(h + ''))
663        # object
664        check(object(), size(h + ''))
665        # property (descriptor object)
666        class C(object):
667            def getx(self): return self.__x
668            def setx(self, value): self.__x = value
669            def delx(self): del self.__x
670            x = property(getx, setx, delx, "")
671            check(x, size(h + '4Pi'))
672        # PyCObject
673        # XXX
674        # rangeiterator
675        check(iter(xrange(1)), size(h + '4l'))
676        # reverse
677        check(reversed(''), size(h + 'PP'))
678        # set
679        # frozenset
680        PySet_MINSIZE = 8
681        samples = [[], range(10), range(50)]
682        s = size(h + '3P2P' + PySet_MINSIZE*'lP' + 'lP')
683        for sample in samples:
684            minused = len(sample)
685            if minused == 0: tmp = 1
686            # the computation of minused is actually a bit more complicated
687            # but this suffices for the sizeof test
688            minused = minused*2
689            newsize = PySet_MINSIZE
690            while newsize <= minused:
691                newsize = newsize << 1
692            if newsize <= 8:
693                check(set(sample), s)
694                check(frozenset(sample), s)
695            else:
696                check(set(sample), s + newsize*struct.calcsize('lP'))
697                check(frozenset(sample), s + newsize*struct.calcsize('lP'))
698        # setiterator
699        check(iter(set()), size(h + 'P3P'))
700        # slice
701        check(slice(1), size(h + '3P'))
702        # str
703        check('', size(vh + 'lic'))
704        check('abc', size(vh + 'lic') + 3*self.c)
705        # super
706        check(super(int), size(h + '3P'))
707        # tuple
708        check((), size(vh))
709        check((1,2,3), size(vh) + 3*self.P)
710        # tupleiterator
711        check(iter(()), size(h + 'lP'))
712        # type
713        # (PyTypeObject + PyNumberMethods +  PyMappingMethods +
714        #  PySequenceMethods + PyBufferProcs)
715        s = size(vh + 'P2P15Pl4PP9PP11PIP') + size('41P 10P 3P 6P')
716        class newstyleclass(object):
717            pass
718        check(newstyleclass, s)
719        # builtin type
720        check(int, s)
721        # NotImplementedType
722        import types
723        check(types.NotImplementedType, s)
724        # unicode
725        usize = len(u'\0'.encode('unicode-internal'))
726        samples = [u'', u'1'*100]
727        # we need to test for both sizes, because we don't know if the string
728        # has been cached
729        for s in samples:
730            check(s, size(h + 'PPlP') + usize * (len(s) + 1))
731        # weakref
732        import weakref
733        check(weakref.ref(int), size(h + '2Pl2P'))
734        # weakproxy
735        # XXX
736        # weakcallableproxy
737        check(weakref.proxy(int), size(h + '2Pl2P'))
738        # xrange
739        check(xrange(1), size(h + '3l'))
740        check(xrange(66000), size(h + '3l'))
741
742    def test_pythontypes(self):
743        # check all types defined in Python/
744        h = self.header
745        vh = self.vheader
746        size = self.calcsize
747        check = self.check_sizeof
748        # _ast.AST
749        import _ast
750        check(_ast.AST(), size(h + ''))
751        # imp.NullImporter
752        import imp
753        check(imp.NullImporter(self.file.name), size(h + ''))
754        try:
755            raise TypeError
756        except TypeError:
757            tb = sys.exc_info()[2]
758            # traceback
759            if tb != None:
760                check(tb, size(h + '2P2i'))
761        # symtable entry
762        # XXX
763        # sys.flags
764        check(sys.flags, size(vh) + self.P * len(sys.flags))
765
766
767def test_main():
768    test_classes = (SysModuleTest, SizeofTest)
769
770    test.test_support.run_unittest(*test_classes)
771
772if __name__ == "__main__":
773    test_main()