88import sys
99
1010
11- # Guard the import of cProfile such that 2.4 people without lsprof can still use
12- # this script.
11+ # Guard the import of cProfile such that 3.x people
12+ # without lsprof can still use this script.
1313try :
1414 from cProfile import Profile
1515except ImportError :
1919 from profile import Profile
2020
2121
22+ # Python 3.x compatibility utils: execfile
23+ # ========================================
24+ try :
25+ execfile
26+ except NameError :
27+ # Python 3.x doesn't have 'execfile' builtin
28+ import builtins
29+ exec_ = getattr (builtins , "exec" )
30+
31+ def execfile (filename , globals = None , locals = None ):
32+ with open (filename ) as f :
33+ exec_ (compile (f .read (), filename , 'exec' ), globals , locals )
34+ # =====================================
35+
36+
37+
2238CO_GENERATOR = 0x0020
2339def is_generator (f ):
2440 """ Return True if a function is a generator.
2541 """
26- isgen = (f .func_code .co_flags & CO_GENERATOR ) != 0
42+ isgen = (f .__code__ .co_flags & CO_GENERATOR ) != 0
2743 return isgen
2844
29- # FIXME: refactor this stuff so that both LineProfiler and ContextualProfile can
30- # use the same implementation.
31- # Code to exec inside of ContextualProfile.__call__ to support PEP-342-style
32- # generators in Python 2.5+.
33- pep342_gen_wrapper = '''
34- def wrap_generator(self, func):
35- """ Wrap a generator to profile it.
36- """
37- def f(*args, **kwds):
38- g = func(*args, **kwds)
39- # The first iterate will not be a .send()
40- self.enable_by_count()
41- try:
42- item = g.next()
43- finally:
44- self.disable_by_count()
45- input = (yield item)
46- # But any following one might be.
47- while True:
48- self.enable_by_count()
49- try:
50- item = g.send(input)
51- finally:
52- self.disable_by_count()
53- input = (yield item)
54- return f
55- '''
5645
5746class ContextualProfile (Profile ):
5847 """ A subclass of Profile that adds a context manager for Python
@@ -95,24 +84,29 @@ def __call__(self, func):
9584 f .__dict__ .update (getattr (func , '__dict__' , {}))
9685 return f
9786
98- if sys .version_info [:2 ] >= (2 ,5 ):
99- # Delay compilation because the syntax is not compatible with older
100- # Python versions.
101- exec pep342_gen_wrapper
102- else :
103- def wrap_generator (self , func ):
104- """ Wrap a generator to profile it.
105- """
106- def f (* args , ** kwds ):
107- g = func (* args , ** kwds )
108- while True :
109- self .enable_by_count ()
110- try :
111- item = g .next ()
112- finally :
113- self .disable_by_count ()
114- yield item
115- return f
87+ # FIXME: refactor this stuff so that both LineProfiler and
88+ # ContextualProfile can use the same implementation.
89+ def wrap_generator (self , func ):
90+ """ Wrap a generator to profile it.
91+ """
92+ def f (* args , ** kwds ):
93+ g = func (* args , ** kwds )
94+ # The first iterate will not be a .send()
95+ self .enable_by_count ()
96+ try :
97+ item = next (g )
98+ finally :
99+ self .disable_by_count ()
100+ input = (yield item )
101+ # But any following one might be.
102+ while True :
103+ self .enable_by_count ()
104+ try :
105+ item = g .send (input )
106+ finally :
107+ self .disable_by_count ()
108+ input = (yield item )
109+ return f
116110
117111 def wrap_function (self , func ):
118112 """ Wrap a function to profile it.
@@ -148,9 +142,10 @@ def find_script(script_name):
148142 if os .path .isfile (fn ):
149143 return fn
150144
151- print >> sys .stderr , 'Could not find script %s' % script_name
145+ sys .stderr . write ( 'Could not find script %s\n ' % script_name )
152146 raise SystemExit (1 )
153147
148+
154149def main (args ):
155150 usage = "%prog [-s setupfile] [-o output_file_path] scriptfile [arg] ..."
156151 parser = optparse .OptionParser (usage = usage , version = "%prog 1.0b2" )
@@ -204,8 +199,11 @@ def main(args):
204199 else :
205200 prof = ContextualProfile ()
206201 if options .builtin :
207- import __builtin__
208- __builtin__ .__dict__ ['profile' ] = prof
202+ try :
203+ import builtins
204+ except ImportError : # Python 2.x
205+ import __builtin__ as builtins
206+ builtins .__dict__ ['profile' ] = prof
209207
210208 script_file = find_script (sys .argv [0 ])
211209 __file__ = script_file
@@ -216,16 +214,17 @@ def main(args):
216214
217215 try :
218216 try :
217+ execfile_ = execfile
219218 ns = locals ()
220219 if options .builtin :
221220 execfile (script_file , ns , ns )
222221 else :
223- prof .runctx ('execfile (%r)' % (script_file ,), ns , ns )
222+ prof .runctx ('execfile_ (%r, globals() )' % (script_file ,), ns , ns )
224223 except (KeyboardInterrupt , SystemExit ):
225224 pass
226225 finally :
227226 prof .dump_stats (options .outfile )
228- print 'Wrote profile results to %s' % options .outfile
227+ print ( 'Wrote profile results to %s' % options .outfile )
229228 if options .view :
230229 prof .print_stats ()
231230
0 commit comments