Source code for abipy.tools.devtools

# coding: utf-8
import os
import tempfile
import warnings

import logging
logger = logging.getLogger(__file__)


[docs]def profile(statement, global_vars, local_vars): """ Run statement under profiler, supplying your own globals and locals Example:: stats = profile("main()", global_vars=globals(), local_vars=locals()) """ import pstats import cProfile _, filename = tempfile.mkstemp() cProfile.runctx(statement, global_vars, local_vars, filename=filename) s = pstats.Stats(filename) s.strip_dirs().sort_stats("time") s.print_stats() os.remove(filename) return s
[docs]class HtmlDiff(object): """ This object produces diff files in HTML format and displays them in the browser. Usage example: .. code-block:: python HtmlDiff(filepaths).open_browser() """ def __init__(self, filepaths): if len(filepaths) < 2: raise ValueError("You need more than one file to compare!") self.filepaths = filepaths
[docs] def open_browser(self, diffmode="difflib", **kwargs): """ Generate diff with ``diffmode``, open browser, return exit code. """ try: func = getattr(self, diffmode) except AttributeError: raise AttributeError("Unsupported value for diffmode: `%s`" % str(diffmode)) return func(**kwargs)
def _launch_browser(self, tmpname): # pragma: no cover """Open ``tmpname`` file in the default browser.""" # warning: This code is not portable since we should pass a url. if not tmpname.startswith("file://"): tmpname = "file://" + tmpname import webbrowser try: return int(webbrowser.open(tmpname)) except webbrowser.Error as exc: # Warn the user and ignore the exception. warnings.warn(str(exc)) return 1
[docs] def difflib(self, **kwargs): """ Use difflib to generate a HTML file with the diff. Open file in the browser. """ with open(self.filepaths[0], 'rt') as fh: fromlines = fh.readlines() diffs = [] for path in self.filepaths[1:]: with open(path, 'rt') as fh: tolines = fh.readlines() _, tmpname = tempfile.mkstemp(suffix=".html", text=True) import difflib #diff = difflib.HtmlDiff().make_table(fromlines, tolines, diff = difflib.HtmlDiff().make_file(fromlines, tolines, self.filepaths[0], path) #context=options.c, numlines=n) with open(tmpname, "wt") as fh: fh.writelines(diff) return self._launch_browser(tmpname)
[docs] def pygmentize(self): """ Execute ``diff`` and ``pygmentize`` in a subprocess to generate a HTML file with the diff. Open file in the browser. """ for file2 in self.filepaths[1:]: _, tmpname = tempfile.mkstemp(suffix=".html", text=True) # https://stackoverflow.com/questions/641055/diff-to-html-diff2html-program #cmd = "/usr/bin/diff -y %s %s | pygmentize -l diff -f html -O full -o %s" % ( # self.filepaths[0], file2, tmpname) cmd = "diff -U9999999 %s %s | pygmentize -l diff -f html -O full -o %s" % ( self.filepaths[0], file2, tmpname) retcode = os.system(cmd) if retcode != 0: print("Non-zero exit status returned by: `%s", cmd) print("Please install pygmentize with `pip install pygmentize` or `conda install pygmentize`") return retcode return self._launch_browser(tmpname)
[docs]def display_top(snapshot, key_type='lineno', limit=3): """ Profile memory usage in Python. Taken from https://stackoverflow.com/questions/552744/how-do-i-profile-memory-usage-in-python Example:: tracemalloc.start() main() snapshot = tracemalloc.take_snapshot() display_top(snapshot) """ import tracemalloc import linecache snapshot = snapshot.filter_traces(( tracemalloc.Filter(False, "<frozen importlib._bootstrap>"), tracemalloc.Filter(False, "<unknown>"), )) top_stats = snapshot.statistics(key_type) print("Top %s lines" % limit) for index, stat in enumerate(top_stats[:limit], 1): frame = stat.traceback[0] # replace "/path/to/module/file.py" with "module/file.py" filename = os.sep.join(frame.filename.split(os.sep)[-2:]) print("#%s: %s:%s: %.1f KiB" % (index, filename, frame.lineno, stat.size / 1024)) line = linecache.getline(frame.filename, frame.lineno).strip() if line: print(' %s' % line) other = top_stats[limit:] if other: size = sum(stat.size for stat in other) print("%s other: %.1f KiB" % (len(other), size / 1024)) total = sum(stat.size for stat in top_stats) print("Total allocated size: %.1f KiB" % (total / 1024))