Commit 0e171504 authored by Boris Filippov's avatar Boris Filippov Committed by Boris Filippov

Add --verbose option for cython magic

This fixes issue #1569
parent 7cac3e06
...@@ -53,8 +53,10 @@ import re ...@@ -53,8 +53,10 @@ import re
import sys import sys
import time import time
import copy import copy
import distutils.log
import textwrap import textwrap
try: try:
reload reload
except NameError: # Python 3 except NameError: # Python 3
...@@ -236,6 +238,11 @@ class CythonMagics(Magics): ...@@ -236,6 +238,11 @@ class CythonMagics(Magics):
help=("Enable profile guided optimisation in the C compiler. " help=("Enable profile guided optimisation in the C compiler. "
"Compiles the cell twice and executes it in between to generate a runtime profile.") "Compiles the cell twice and executes it in between to generate a runtime profile.")
) )
@magic_arguments.argument(
'--verbose', dest='quiet', action='store_false', default=True,
help=("Print debug information like generated .c/.cpp file location "
"and exact gcc/g++ command invoked.")
)
@cell_magic @cell_magic
def cython(self, line, cell): def cython(self, line, cell):
"""Compile and import everything from a Cython code cell. """Compile and import everything from a Cython code cell.
...@@ -282,7 +289,6 @@ class CythonMagics(Magics): ...@@ -282,7 +289,6 @@ class CythonMagics(Magics):
args = magic_arguments.parse_argstring(self.cython, line) args = magic_arguments.parse_argstring(self.cython, line)
code = cell if cell.endswith('\n') else cell + '\n' code = cell if cell.endswith('\n') else cell + '\n'
lib_dir = os.path.join(get_ipython_cache_dir(), 'cython') lib_dir = os.path.join(get_ipython_cache_dir(), 'cython')
quiet = True
key = (code, line, sys.version_info, sys.executable, cython_version) key = (code, line, sys.version_info, sys.executable, cython_version)
if not os.path.exists(lib_dir): if not os.path.exists(lib_dir):
...@@ -311,7 +317,7 @@ class CythonMagics(Magics): ...@@ -311,7 +317,7 @@ class CythonMagics(Magics):
extension = None extension = None
if need_cythonize: if need_cythonize:
extensions = self._cythonize(module_name, code, lib_dir, args, quiet=quiet) extensions = self._cythonize(module_name, code, lib_dir, args, quiet=args.quiet)
assert len(extensions) == 1 assert len(extensions) == 1
extension = extensions[0] extension = extensions[0]
self._code_cache[key] = module_name self._code_cache[key] = module_name
...@@ -319,7 +325,8 @@ class CythonMagics(Magics): ...@@ -319,7 +325,8 @@ class CythonMagics(Magics):
if args.pgo: if args.pgo:
self._profile_pgo_wrapper(extension, lib_dir) self._profile_pgo_wrapper(extension, lib_dir)
self._build_extension(extension, lib_dir, pgo_step_name='use' if args.pgo else None) self._build_extension(extension, lib_dir, pgo_step_name='use' if args.pgo else None,
quiet=args.quiet)
module = imp.load_dynamic(module_name, module_path) module = imp.load_dynamic(module_name, module_path)
self._import_all(module) self._import_all(module)
...@@ -386,7 +393,7 @@ class CythonMagics(Magics): ...@@ -386,7 +393,7 @@ class CythonMagics(Magics):
so_module_path = os.path.join(lib_dir, pgo_module_name + self.so_ext) so_module_path = os.path.join(lib_dir, pgo_module_name + self.so_ext)
imp.load_dynamic(pgo_module_name, so_module_path) imp.load_dynamic(pgo_module_name, so_module_path)
def _cythonize(self, module_name, code, lib_dir, args, quiet=False): def _cythonize(self, module_name, code, lib_dir, args, quiet=True):
pyx_file = os.path.join(lib_dir, module_name + '.pyx') pyx_file = os.path.join(lib_dir, module_name + '.pyx')
pyx_file = py3compat.cast_bytes_py2(pyx_file, encoding=sys.getfilesystemencoding()) pyx_file = py3compat.cast_bytes_py2(pyx_file, encoding=sys.getfilesystemencoding())
...@@ -422,10 +429,17 @@ class CythonMagics(Magics): ...@@ -422,10 +429,17 @@ class CythonMagics(Magics):
except CompileError: except CompileError:
return None return None
def _build_extension(self, extension, lib_dir, temp_dir=None, pgo_step_name=None): def _build_extension(self, extension, lib_dir, temp_dir=None, pgo_step_name=None, quiet=True):
build_extension = self._get_build_extension( build_extension = self._get_build_extension(
extension, lib_dir=lib_dir, temp_dir=temp_dir, pgo_step_name=pgo_step_name) extension, lib_dir=lib_dir, temp_dir=temp_dir, pgo_step_name=pgo_step_name)
build_extension.run() old_threshold = None
try:
if not quiet:
old_threshold = distutils.log.set_threshold(distutils.log.DEBUG)
build_extension.run()
finally:
if not quiet and old_threshold is not None:
distutils.log.set_threshold(old_threshold)
def _add_pgo_flags(self, build_extension, step_name, temp_dir): def _add_pgo_flags(self, build_extension, step_name, temp_dir):
compiler_type = build_extension.compiler.compiler_type compiler_type = build_extension.compiler.compiler_type
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
import os import os
import sys import sys
from contextlib import contextmanager
from Cython.Build import IpythonMagic
try: try:
from IPython.testing.globalipapp import get_ipython from IPython.testing.globalipapp import get_ipython
...@@ -139,3 +141,43 @@ x = sin(0.0) ...@@ -139,3 +141,43 @@ x = sin(0.0)
ip.user_ns['x'] = 1 ip.user_ns['x'] = 1
ip.run_cell_magic('cython', '-l m', code) ip.run_cell_magic('cython', '-l m', code)
self.assertEqual(ip.user_ns['x'], 0) self.assertEqual(ip.user_ns['x'], 0)
def test_cython_verbose(self):
ip.run_cell_magic('cython', '--verbose', code)
ip.ex('g = f(10)')
self.assertEqual(ip.user_ns['g'], 20.0)
def test_cython_verbose_thresholds(self):
@contextmanager
def mock_distutils():
class MockLog:
DEBUG = 1
INFO = 2
thresholds = [INFO]
def set_threshold(self, val):
self.thresholds.append(val)
return self.thresholds[-2]
new_log = MockLog()
old_log = IpythonMagic.distutils.log
try:
IpythonMagic.distutils.log = new_log
yield new_log
finally:
IpythonMagic.distutils.log = old_log
with mock_distutils() as verbose_log:
ip.run_cell_magic('cython', '--verbose', code)
ip.ex('g = f(10)')
self.assertEqual(ip.user_ns['g'], 20.0)
self.assertEquals([verbose_log.INFO, verbose_log.DEBUG, verbose_log.INFO],
verbose_log.thresholds)
with mock_distutils() as normal_log:
ip.run_cell_magic('cython', '', code)
ip.ex('g = f(10)')
self.assertEqual(ip.user_ns['g'], 20.0)
self.assertEquals([normal_log.INFO], normal_log.thresholds)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment