1"""Test suite for the cProfile module."""
2
3import sys
4import unittest
5
6# rip off all interesting stuff from test_profile
7import cProfile
8from test.test_profile import ProfileTest, regenerate_expected_output
9from test.support.script_helper import assert_python_failure
10from test import support
11
12
13class CProfileTest(ProfileTest):
14    profilerclass = cProfile.Profile
15    profilermodule = cProfile
16    expected_max_output = "{built-in method builtins.max}"
17
18    def get_expected_output(self):
19        return _ProfileOutput
20
21    def test_bad_counter_during_dealloc(self):
22        # bpo-3895
23        import _lsprof
24
25        with support.catch_unraisable_exception() as cm:
26            obj = _lsprof.Profiler(lambda: int)
27            obj.enable()
28            obj = _lsprof.Profiler(1)
29            obj.disable()
30            obj.clear()
31
32            self.assertEqual(cm.unraisable.exc_type, TypeError)
33
34    def test_profile_enable_disable(self):
35        prof = self.profilerclass()
36        # Make sure we clean ourselves up if the test fails for some reason.
37        self.addCleanup(prof.disable)
38
39        prof.enable()
40        self.assertIs(sys.getprofile(), prof)
41
42        prof.disable()
43        self.assertIs(sys.getprofile(), None)
44
45    def test_profile_as_context_manager(self):
46        prof = self.profilerclass()
47        # Make sure we clean ourselves up if the test fails for some reason.
48        self.addCleanup(prof.disable)
49
50        with prof as __enter__return_value:
51            # profile.__enter__ should return itself.
52            self.assertIs(prof, __enter__return_value)
53
54            # profile should be set as the global profiler inside the
55            # with-block
56            self.assertIs(sys.getprofile(), prof)
57
58        # profile shouldn't be set once we leave the with-block.
59        self.assertIs(sys.getprofile(), None)
60
61class TestCommandLine(unittest.TestCase):
62    def test_sort(self):
63        rc, out, err = assert_python_failure('-m', 'cProfile', '-s', 'demo')
64        self.assertGreater(rc, 0)
65        self.assertIn(b"option -s: invalid choice: 'demo'", err)
66
67
68def main():
69    if '-r' not in sys.argv:
70        unittest.main()
71    else:
72        regenerate_expected_output(__file__, CProfileTest)
73
74
75# Don't remove this comment. Everything below it is auto-generated.
76#--cut--------------------------------------------------------------------------
77_ProfileOutput = {}
78_ProfileOutput['print_stats'] = """\
79       28    0.028    0.001    0.028    0.001 profilee.py:110(__getattr__)
80        1    0.270    0.270    1.000    1.000 profilee.py:25(testfunc)
81     23/3    0.150    0.007    0.170    0.057 profilee.py:35(factorial)
82       20    0.020    0.001    0.020    0.001 profilee.py:48(mul)
83        2    0.040    0.020    0.600    0.300 profilee.py:55(helper)
84        4    0.116    0.029    0.120    0.030 profilee.py:73(helper1)
85        2    0.000    0.000    0.140    0.070 profilee.py:84(helper2_indirect)
86        8    0.312    0.039    0.400    0.050 profilee.py:88(helper2)
87        8    0.064    0.008    0.080    0.010 profilee.py:98(subhelper)"""
88_ProfileOutput['print_callers'] = """\
89profilee.py:110(__getattr__)                      <-      16    0.016    0.016  profilee.py:98(subhelper)
90profilee.py:25(testfunc)                          <-       1    0.270    1.000  <string>:1(<module>)
91profilee.py:35(factorial)                         <-       1    0.014    0.130  profilee.py:25(testfunc)
92                                                        20/3    0.130    0.147  profilee.py:35(factorial)
93                                                           2    0.006    0.040  profilee.py:84(helper2_indirect)
94profilee.py:48(mul)                               <-      20    0.020    0.020  profilee.py:35(factorial)
95profilee.py:55(helper)                            <-       2    0.040    0.600  profilee.py:25(testfunc)
96profilee.py:73(helper1)                           <-       4    0.116    0.120  profilee.py:55(helper)
97profilee.py:84(helper2_indirect)                  <-       2    0.000    0.140  profilee.py:55(helper)
98profilee.py:88(helper2)                           <-       6    0.234    0.300  profilee.py:55(helper)
99                                                           2    0.078    0.100  profilee.py:84(helper2_indirect)
100profilee.py:98(subhelper)                         <-       8    0.064    0.080  profilee.py:88(helper2)
101{built-in method builtins.hasattr}                <-       4    0.000    0.004  profilee.py:73(helper1)
102                                                           8    0.000    0.008  profilee.py:88(helper2)
103{built-in method sys.exc_info}                    <-       4    0.000    0.000  profilee.py:73(helper1)
104{method 'append' of 'list' objects}               <-       4    0.000    0.000  profilee.py:73(helper1)"""
105_ProfileOutput['print_callees'] = """\
106<string>:1(<module>)                              ->       1    0.270    1.000  profilee.py:25(testfunc)
107profilee.py:110(__getattr__)                      ->
108profilee.py:25(testfunc)                          ->       1    0.014    0.130  profilee.py:35(factorial)
109                                                           2    0.040    0.600  profilee.py:55(helper)
110profilee.py:35(factorial)                         ->    20/3    0.130    0.147  profilee.py:35(factorial)
111                                                          20    0.020    0.020  profilee.py:48(mul)
112profilee.py:48(mul)                               ->
113profilee.py:55(helper)                            ->       4    0.116    0.120  profilee.py:73(helper1)
114                                                           2    0.000    0.140  profilee.py:84(helper2_indirect)
115                                                           6    0.234    0.300  profilee.py:88(helper2)
116profilee.py:73(helper1)                           ->       4    0.000    0.004  {built-in method builtins.hasattr}
117profilee.py:84(helper2_indirect)                  ->       2    0.006    0.040  profilee.py:35(factorial)
118                                                           2    0.078    0.100  profilee.py:88(helper2)
119profilee.py:88(helper2)                           ->       8    0.064    0.080  profilee.py:98(subhelper)
120profilee.py:98(subhelper)                         ->      16    0.016    0.016  profilee.py:110(__getattr__)
121{built-in method builtins.hasattr}                ->      12    0.012    0.012  profilee.py:110(__getattr__)"""
122
123if __name__ == "__main__":
124    main()
125