Skip to content

Commit c5f79b8

Browse files
authored
Merge branch 'master' into stream-unicode-bugfix
2 parents 7b92098 + 8194a59 commit c5f79b8

13 files changed

Lines changed: 209 additions & 89 deletions

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,6 @@ MANIFEST
88

99
# Ignore mprof generated files
1010
mprofile_*.dat
11+
12+
# virtual environment
13+
venv/

.travis.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
language: python
22
python:
33
- "2.7"
4-
- "3.3"
54
- "3.4"
65
- "3.5"
76
- "3.6"

Makefile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ PYTHON ?= python
55
test:
66
$(PYTHON) -m memory_profiler test/test_func.py
77
$(PYTHON) -m memory_profiler test/test_loop.py
8+
$(PYTHON) -m memory_profiler test/test_mprofile.py
89
$(PYTHON) -m memory_profiler test/test_as.py
910
$(PYTHON) -m memory_profiler test/test_global.py
1011
$(PYTHON) -m memory_profiler test/test_precision_command_line.py
@@ -15,3 +16,8 @@ test:
1516
$(PYTHON) test/test_memory_usage.py
1617
$(PYTHON) test/test_precision_import.py
1718
$(PYTHON) test/test_exception.py
19+
$(PYTHON) test/test_exit_code.py
20+
$(PYTHON) test/test_mprof.py
21+
22+
develop:
23+
pip install -e .

README.rst

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,12 @@ programs. It is a pure python module which depends on the `psutil
1414
==============
1515
Installation
1616
==============
17-
To install through easy_install or pip::
17+
Install via pip::
1818

19-
$ easy_install -U memory_profiler # pip install -U memory_profiler
19+
$ pip install -U memory_profiler
20+
21+
The package is also available on `conda-forge
22+
<https://github.com/conda-forge/memory_profiler-feedstock>`_.
2023

2124
To install from source, download the package, extract and type::
2225

delta_memory_test.py

Lines changed: 0 additions & 27 deletions
This file was deleted.

memory_profiler.py

Lines changed: 54 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,22 @@
33
# .. we'll use this to pass it to the child script ..
44
_CLEAN_GLOBALS = globals().copy()
55

6-
__version__ = '0.50.0'
6+
__version__ = '0.55.0'
77

88
_CMD_USAGE = "python -m memory_profiler script_file.py"
99

10-
import time
11-
import sys
10+
from functools import wraps
11+
import inspect
12+
import linecache
13+
import logging
1214
import os
1315
import pdb
14-
import warnings
15-
import linecache
16-
import inspect
1716
import subprocess
18-
import logging
17+
import sys
18+
import time
1919
import traceback
20+
import warnings
21+
2022
if sys.platform == "win32":
2123
# any value except signal.CTRL_C_EVENT and signal.CTRL_BREAK_EVENT
2224
# can be used to kill a process unconditionally in Windows
@@ -47,6 +49,7 @@
4749
if PY2:
4850
import __builtin__ as builtins
4951
to_str = lambda x: x
52+
from future_builtins import filter
5053
else:
5154
import builtins
5255
to_str = lambda x: str(x)
@@ -403,13 +406,13 @@ def memory_usage(proc=-1, interval=.1, timeout=None, timestamps=False,
403406

404407
# Write children to the stream file
405408
if multiprocess:
406-
for idx, chldmem in enumerate(_get_child_memory(proc.pid)):
409+
for idx, chldmem in enumerate(_get_child_memory(proc)):
407410
stream.write("CHLD {0} {1:.6f} {2:.4f}\n".format(idx, chldmem, time.time()))
408411
else:
409412
# Create a nested list with the child memory
410413
if multiprocess:
411414
mem_usage = [mem_usage]
412-
for chldmem in _get_child_memory(proc.pid):
415+
for chldmem in _get_child_memory(proc):
413416
mem_usage.append(chldmem)
414417

415418
# Append the memory usage to the return value
@@ -592,9 +595,7 @@ def trace(self, code, lineno, prev_lineno):
592595

593596
prev_line_value = self[code].get(prev_lineno, None) if prev_lineno else None
594597
prev_line_memory = prev_line_value[1] if prev_line_value else 0
595-
#inc = (memory-prev_line_memory)
596-
#print('trace lineno=%(lineno)s prev_lineno=%(prev_lineno)s mem=%(memory)s prev_inc=%(previous_inc)s inc=%(inc)s' % locals())
597-
self[code][lineno] = (previous_inc + (memory-prev_line_memory), max(memory, previous_memory))
598+
self[code][lineno] = (max(previous_inc, memory-prev_line_memory), max(memory, previous_memory))
598599

599600
def items(self):
600601
"""Iterate on the toplevel code blocks."""
@@ -1065,6 +1066,7 @@ def profile(func=None, stream=None, precision=1, backend='psutil'):
10651066
if not tracemalloc.is_tracing():
10661067
tracemalloc.start()
10671068
if func is not None:
1069+
@wraps(func)
10681070
def wrapper(*args, **kwargs):
10691071
prof = LineProfiler(backend=backend)
10701072
val = prof(func)(*args, **kwargs)
@@ -1111,23 +1113,35 @@ def choose_backend(new_backend=None):
11111113
# globally defined (global variables is not enough
11121114
# for all cases, e.g. a script that imports another
11131115
# script where @profile is used)
1114-
if PY2:
1115-
def exec_with_profiler(filename, profiler, backend):
1116-
builtins.__dict__['profile'] = profiler
1117-
ns = dict(_CLEAN_GLOBALS, profile=profiler)
1118-
choose_backend(backend)
1119-
execfile(filename, ns, ns)
1120-
else:
1121-
def exec_with_profiler(filename, profiler, backend):
1122-
_backend = choose_backend(backend)
1116+
def exec_with_profiler(filename, profiler, backend, passed_args=[]):
1117+
from runpy import run_module
1118+
builtins.__dict__['profile'] = profiler
1119+
ns = dict(_CLEAN_GLOBALS, profile=profiler)
1120+
_backend = choose_backend(backend)
1121+
sys.argv = [filename] + passed_args
1122+
try:
1123+
if _backend == 'tracemalloc' and has_tracemalloc:
1124+
tracemalloc.start()
1125+
with open(filename) as f:
1126+
exec(compile(f.read(), filename, 'exec'), ns, ns)
1127+
finally:
1128+
if has_tracemalloc and tracemalloc.is_tracing():
1129+
tracemalloc.stop()
1130+
1131+
1132+
def run_module_with_profiler(module, profiler, backend, passed_args=[]):
1133+
from runpy import run_module
1134+
builtins.__dict__['profile'] = profiler
1135+
ns = dict(_CLEAN_GLOBALS, profile=profiler)
1136+
_backend = choose_backend(backend)
1137+
sys.argv = [module] + passed_args
1138+
if PY2:
1139+
run_module(module, run_name="__main__", init_globals=ns)
1140+
else:
11231141
if _backend == 'tracemalloc' and has_tracemalloc:
11241142
tracemalloc.start()
1125-
builtins.__dict__['profile'] = profiler
1126-
# shadow the profile decorator defined above
1127-
ns = dict(_CLEAN_GLOBALS, profile=profiler)
11281143
try:
1129-
with open(filename) as f:
1130-
exec(compile(f.read(), filename, 'exec'), ns, ns)
1144+
run_module(module, run_name="__main__", init_globals=ns)
11311145
finally:
11321146
if has_tracemalloc and tracemalloc.is_tracing():
11331147
tracemalloc.stop()
@@ -1166,7 +1180,7 @@ def flush(self):
11661180

11671181

11681182
if __name__ == '__main__':
1169-
from argparse import ArgumentParser
1183+
from argparse import ArgumentParser, REMAINDER
11701184

11711185
parser = ArgumentParser(usage=_CMD_USAGE)
11721186
parser.add_argument('--version', action='version', version=__version__)
@@ -1189,18 +1203,28 @@ def flush(self):
11891203
choices=['tracemalloc', 'psutil', 'posix'], default='psutil',
11901204
help='backend using for getting memory info '
11911205
'(one of the {tracemalloc, psutil, posix})')
1192-
parser.add_argument('script', help='script file run on memory_profiler')
1206+
parser.add_argument("program", nargs=REMAINDER,
1207+
help='python script or module followed by command line arguements to run')
11931208
args = parser.parse_args()
11941209

1195-
script_filename = _find_script(args.script)
1210+
if len(args.program) == 0:
1211+
print("A program to run must be provided. Use -h for help")
1212+
sys.exit(1)
1213+
1214+
target = args.program[0]
1215+
script_args = args.program[1:]
11961216
_backend = choose_backend(args.backend)
11971217
if args.timestamp:
11981218
prof = TimeStamper(_backend)
11991219
else:
12001220
prof = LineProfiler(max_mem=args.max_mem, backend=_backend)
12011221

12021222
try:
1203-
exec_with_profiler(script_filename, prof, args.backend)
1223+
if args.program[0].endswith('.py'):
1224+
script_filename = _find_script(args.program[0])
1225+
exec_with_profiler(script_filename, prof, args.backend, script_args)
1226+
else:
1227+
run_module_with_profiler(target, prof, args.backend, script_args)
12041228
finally:
12051229
if args.out_filename is not None:
12061230
out_file = open(args.out_filename, "a")

mprof.bat

Lines changed: 0 additions & 2 deletions
This file was deleted.

0 commit comments

Comments
 (0)