Skip to content

Commit f30ff08

Browse files
committed
Review code
1 parent 1715632 commit f30ff08

1 file changed

Lines changed: 53 additions & 65 deletions

File tree

memory_profiler.py

Lines changed: 53 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,9 @@
1515
import linecache
1616
import inspect
1717
import subprocess
18-
from copy import copy
1918
import logging
2019

21-
# TODO: provide alternative when multprocessing is not available
20+
# TODO: provide alternative when multiprocessing is not available
2221
try:
2322
from multiprocessing import Process, Pipe
2423
except ImportError:
@@ -36,14 +35,17 @@
3635

3736
_TWO_20 = float(2 ** 20)
3837

39-
has_psutil = False
38+
if PY3:
39+
import builtins
40+
else:
41+
import __builtin__ as builtins
4042

4143
# .. get available packages ..
4244
try:
4345
import psutil
4446
has_psutil = True
4547
except ImportError:
46-
pass
48+
has_psutil = False
4749

4850

4951
def _get_memory(pid, timestamps=False, include_children=False):
@@ -102,7 +104,7 @@ def _get_memory(pid, timestamps=False, include_children=False):
102104
if timestamps:
103105
return (-1, time.time())
104106
else:
105-
return -1
107+
return -1
106108
else:
107109
raise NotImplementedError('The psutil module is required for non-unix '
108110
'platforms')
@@ -121,29 +123,21 @@ def __init__(self, monitor_pid, interval, pipe, max_usage=False,
121123
self.max_usage = max_usage
122124
self.n_measurements = 1
123125

124-
if "timestamps" in kw:
125-
self.timestamps = kw["timestamps"]
126-
del kw["timestamps"]
127-
else:
128-
self.timestamps = False
129-
if "include_children" in kw:
130-
self.include_children = kw["include_children"]
131-
del kw["include_children"]
132-
else:
133-
self.include_children = False
126+
self.timestamps = kw.pop("timestamps", False)
127+
self.include_children = kw.pop("include_children", False)
128+
134129
# get baseline memory usage
135130
self.mem_usage = [
136131
_get_memory(self.monitor_pid, timestamps=self.timestamps,
137132
include_children=self.include_children)]
138133
super(MemTimer, self).__init__(*args, **kw)
139134

140-
141135
def run(self):
142136
self.pipe.send(0) # we're ready
143137
stop = False
144138
while True:
145139
cur_mem = _get_memory(self.monitor_pid, timestamps=self.timestamps,
146-
include_children=self.include_children)
140+
include_children=self.include_children)
147141
if not self.max_usage:
148142
self.mem_usage.append(cur_mem)
149143
else:
@@ -223,7 +217,7 @@ def memory_usage(proc=-1, interval=.1, timeout=None, timestamps=False,
223217
# for a Python function wait until it finishes
224218
max_iter = float('inf')
225219

226-
if hasattr(proc, '__call__'):
220+
if callable(proc):
227221
proc = (proc, (), {})
228222
if isinstance(proc, (list, tuple)):
229223
if len(proc) == 1:
@@ -238,7 +232,7 @@ def memory_usage(proc=-1, interval=.1, timeout=None, timestamps=False,
238232
while True:
239233
child_conn, parent_conn = Pipe() # this will store MemTimer's results
240234
p = MemTimer(os.getpid(), interval, child_conn, timestamps=timestamps,
241-
max_usage=max_usage, include_children=include_children)
235+
max_usage=max_usage, include_children=include_children)
242236
p.start()
243237
parent_conn.recv() # wait until we start getting memory
244238
returned = f(*args, **kw)
@@ -263,9 +257,9 @@ def memory_usage(proc=-1, interval=.1, timeout=None, timestamps=False,
263257
else:
264258
ret.append(mem_usage)
265259
else:
266-
ret = max([ret,
267-
_get_memory(proc.pid,
268-
include_children=include_children)])
260+
ret = max(ret,
261+
_get_memory(proc.pid,
262+
include_children=include_children))
269263
time.sleep(interval)
270264
line_count += 1
271265
# flush every 50 lines. Make 'tail -f' usable on profile file
@@ -351,7 +345,7 @@ def __init__(self):
351345

352346
def __call__(self, func=None, precision=None):
353347
if func is not None:
354-
if not hasattr(func, "__call__"):
348+
if not callable(func):
355349
raise ValueError("Value must be callable")
356350

357351
self.add_function(func)
@@ -380,7 +374,7 @@ def timestamp(self, name="<block>"):
380374
return _TimeStamperCM(timestamps)
381375

382376
def add_function(self, func):
383-
if not func in self.functions:
377+
if func not in self.functions:
384378
self.functions[func] = []
385379

386380
def wrap_function(self, func):
@@ -391,11 +385,10 @@ def f(*args, **kwds):
391385
timestamps = [_get_memory(os.getpid(), timestamps=True)]
392386
self.functions[func].append(timestamps)
393387
try:
394-
result = func(*args, **kwds)
388+
return func(*args, **kwds)
395389
finally:
396390
# end time
397391
timestamps.append(_get_memory(os.getpid(), timestamps=True))
398-
return result
399392
return f
400393

401394
def show_results(self, stream=None):
@@ -459,10 +452,9 @@ def wrap_function(self, func):
459452
def f(*args, **kwds):
460453
self.enable_by_count()
461454
try:
462-
result = func(*args, **kwds)
455+
return func(*args, **kwds)
463456
finally:
464457
self.disable_by_count()
465-
return result
466458
return f
467459

468460
def run(self, cmd):
@@ -521,8 +513,8 @@ def trace_max_mem(self, frame, event, arg):
521513
if event in ('line', 'return') and frame.f_code in self.code_map:
522514
c = _get_memory(-1)
523515
if c >= self.max_mem:
524-
t = ('Current memory {0:.2f} MiB exceeded the maximum'
525-
''.format(c) + 'of {0:.2f} MiB\n'.format(self.max_mem))
516+
t = ('Current memory {0:.2f} MiB exceeded the '
517+
'maximum of {1:.2f} MiB\n'.format(c, self.max_mem))
526518
sys.stdout.write(t)
527519
sys.stdout.write('Stepping into the debugger \n')
528520
frame.f_lineno -= 2
@@ -655,11 +647,8 @@ def mprun(self, parameter_s='', cell=None):
655647
656648
-c: If present, add the memory usage of any children process to the report.
657649
"""
650+
from io import StringIO
658651
from memory_profiler import show_results, LineProfiler
659-
try:
660-
from StringIO import StringIO
661-
except ImportError: # Python 3.x
662-
from io import StringIO
663652

664653
# Local imports to avoid hard dependency.
665654
from distutils.version import LooseVersion
@@ -700,11 +689,6 @@ def mprun(self, parameter_s='', cell=None):
700689
profile(func)
701690

702691
# Add the profiler to the builtins for @profile.
703-
if PY3:
704-
import builtins
705-
else:
706-
import __builtin__ as builtins
707-
708692
if 'profile' in builtins.__dict__:
709693
had_profile = True
710694
old_profile = builtins.__dict__['profile']
@@ -714,14 +698,13 @@ def mprun(self, parameter_s='', cell=None):
714698
builtins.__dict__['profile'] = profile
715699

716700
try:
717-
try:
718-
profile.runctx(arg_str, global_ns, local_ns)
719-
message = ''
720-
except SystemExit:
721-
message = "*** SystemExit exception caught in code being profiled."
722-
except KeyboardInterrupt:
723-
message = ("*** KeyboardInterrupt exception caught in code being "
724-
"profiled.")
701+
profile.runctx(arg_str, global_ns, local_ns)
702+
message = ''
703+
except SystemExit:
704+
message = "*** SystemExit exception caught in code being profiled."
705+
except KeyboardInterrupt:
706+
message = ("*** KeyboardInterrupt exception caught in code being "
707+
"profiled.")
725708
finally:
726709
if had_profile:
727710
builtins.__dict__['profile'] = old_profile
@@ -888,6 +871,25 @@ def inner_wrapper(f):
888871
return profile(f, stream=stream, precision=precision)
889872
return inner_wrapper
890873

874+
875+
# Insert in the built-ins to have profile
876+
# globally defined (global variables is not enough
877+
# for all cases, e.g. a script that imports another
878+
# script where @profile is used)
879+
if PY3:
880+
def exec_with_profiler(filename, profiler):
881+
builtins.__dict__['profile'] = profiler
882+
# shadow the profile decorator defined above
883+
ns = dict(_CLEAN_GLOBALS, profile=profiler)
884+
with open(filename) as f:
885+
exec(compile(f.read(), filename, 'exec'), ns, ns)
886+
else:
887+
def exec_with_profiler(filename, profiler):
888+
builtins.__dict__['profile'] = profiler
889+
ns = dict(_CLEAN_GLOBALS, profile=profiler)
890+
execfile(filename, ns, ns)
891+
892+
891893
class LogFile(object):
892894
"""File-like object to log text using the `logging` module and the log report can be customised."""
893895

@@ -905,7 +907,7 @@ def __init__(self, name=None, reportIncrementFlag=False):
905907

906908
def write(self, msg, level=logging.INFO):
907909
if self.reportIncrementFlag:
908-
if "MiB" in msg and float(msg.split("MiB")[1].strip())>0:
910+
if "MiB" in msg and float(msg.split("MiB")[1].strip()) > 0:
909911
self.logger.log(level, msg)
910912
elif msg.__contains__("Filename:") or msg.__contains__("Line Contents"):
911913
self.logger.log(level, msg)
@@ -916,6 +918,7 @@ def flush(self):
916918
for handler in self.logger.handlers:
917919
handler.flush()
918920

921+
919922
if __name__ == '__main__':
920923
from optparse import OptionParser
921924
parser = OptionParser(usage=_CMD_USAGE, version=__version__)
@@ -947,24 +950,9 @@ def flush(self):
947950
prof = TimeStamper()
948951
else:
949952
prof = LineProfiler(max_mem=options.max_mem)
950-
__file__ = _find_script(args[0])
953+
script_filename = _find_script(args[0])
951954
try:
952-
if not PY3:
953-
# we need to ovewrite the builtins to have profile
954-
# globally defined (global variables is not enough
955-
# for all cases, e.g. a script that imports another
956-
# script where @profile is used)
957-
import __builtin__
958-
__builtin__.__dict__['profile'] = prof
959-
ns = copy(_CLEAN_GLOBALS)
960-
ns['profile'] = prof # shadow the profile decorator defined above
961-
execfile(__file__, ns, ns)
962-
else:
963-
import builtins
964-
builtins.__dict__['profile'] = prof
965-
ns = copy(_CLEAN_GLOBALS)
966-
ns['profile'] = prof # shadow the profile decorator defined above
967-
exec(compile(open(__file__).read(), __file__, 'exec'), ns, ns)
955+
exec_with_profiler(script_filename, prof)
968956
finally:
969957
if options.out_filename is not None:
970958
out_file = open(options.out_filename, "a")

0 commit comments

Comments
 (0)