123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- # -*- coding: utf-8 -*-
- # tag: ipython
- """Tests for the Cython magics extension."""
- from __future__ import absolute_import
- import os
- import sys
- from contextlib import contextmanager
- from Cython.Build import IpythonMagic
- from Cython.TestUtils import CythonTest
- try:
- import IPython.testing.globalipapp
- except ImportError:
- # Disable tests and fake helpers for initialisation below.
- def skip_if_not_installed(_):
- return None
- else:
- def skip_if_not_installed(c):
- return c
- try:
- # disable IPython history thread before it gets started to avoid having to clean it up
- from IPython.core.history import HistoryManager
- HistoryManager.enabled = False
- except ImportError:
- pass
- code = u"""\
- def f(x):
- return 2*x
- """
- cython3_code = u"""\
- def f(int x):
- return 2 / x
- def call(x):
- return f(*(x,))
- """
- pgo_cython3_code = cython3_code + u"""\
- def main():
- for _ in range(100): call(5)
- main()
- """
- if sys.platform == 'win32':
- # not using IPython's decorators here because they depend on "nose"
- try:
- from unittest import skip as skip_win32
- except ImportError:
- # poor dev's silent @unittest.skip()
- def skip_win32(dummy):
- def _skip_win32(func):
- return None
- return _skip_win32
- else:
- def skip_win32(dummy):
- def _skip_win32(func):
- def wrapper(*args, **kwargs):
- func(*args, **kwargs)
- return wrapper
- return _skip_win32
- @skip_if_not_installed
- class TestIPythonMagic(CythonTest):
- @classmethod
- def setUpClass(cls):
- CythonTest.setUpClass()
- cls._ip = IPython.testing.globalipapp.get_ipython()
- def setUp(self):
- CythonTest.setUp(self)
- self._ip.extension_manager.load_extension('cython')
- def test_cython_inline(self):
- ip = self._ip
- ip.ex('a=10; b=20')
- result = ip.run_cell_magic('cython_inline', '', 'return a+b')
- self.assertEqual(result, 30)
- @skip_win32('Skip on Windows')
- def test_cython_pyximport(self):
- ip = self._ip
- module_name = '_test_cython_pyximport'
- ip.run_cell_magic('cython_pyximport', module_name, code)
- ip.ex('g = f(10)')
- self.assertEqual(ip.user_ns['g'], 20.0)
- ip.run_cell_magic('cython_pyximport', module_name, code)
- ip.ex('h = f(-10)')
- self.assertEqual(ip.user_ns['h'], -20.0)
- try:
- os.remove(module_name + '.pyx')
- except OSError:
- pass
- def test_cython(self):
- ip = self._ip
- ip.run_cell_magic('cython', '', code)
- ip.ex('g = f(10)')
- self.assertEqual(ip.user_ns['g'], 20.0)
- def test_cython_name(self):
- # The Cython module named 'mymodule' defines the function f.
- ip = self._ip
- ip.run_cell_magic('cython', '--name=mymodule', code)
- # This module can now be imported in the interactive namespace.
- ip.ex('import mymodule; g = mymodule.f(10)')
- self.assertEqual(ip.user_ns['g'], 20.0)
- def test_cython_language_level(self):
- # The Cython cell defines the functions f() and call().
- ip = self._ip
- ip.run_cell_magic('cython', '', cython3_code)
- ip.ex('g = f(10); h = call(10)')
- if sys.version_info[0] < 3:
- self.assertEqual(ip.user_ns['g'], 2 // 10)
- self.assertEqual(ip.user_ns['h'], 2 // 10)
- else:
- self.assertEqual(ip.user_ns['g'], 2.0 / 10.0)
- self.assertEqual(ip.user_ns['h'], 2.0 / 10.0)
- def test_cython3(self):
- # The Cython cell defines the functions f() and call().
- ip = self._ip
- ip.run_cell_magic('cython', '-3', cython3_code)
- ip.ex('g = f(10); h = call(10)')
- self.assertEqual(ip.user_ns['g'], 2.0 / 10.0)
- self.assertEqual(ip.user_ns['h'], 2.0 / 10.0)
- def test_cython2(self):
- # The Cython cell defines the functions f() and call().
- ip = self._ip
- ip.run_cell_magic('cython', '-2', cython3_code)
- ip.ex('g = f(10); h = call(10)')
- self.assertEqual(ip.user_ns['g'], 2 // 10)
- self.assertEqual(ip.user_ns['h'], 2 // 10)
- @skip_win32('Skip on Windows')
- def test_cython3_pgo(self):
- # The Cython cell defines the functions f() and call().
- ip = self._ip
- ip.run_cell_magic('cython', '-3 --pgo', pgo_cython3_code)
- ip.ex('g = f(10); h = call(10); main()')
- self.assertEqual(ip.user_ns['g'], 2.0 / 10.0)
- self.assertEqual(ip.user_ns['h'], 2.0 / 10.0)
- @skip_win32('Skip on Windows')
- def test_extlibs(self):
- ip = self._ip
- code = u"""
- from libc.math cimport sin
- x = sin(0.0)
- """
- ip.user_ns['x'] = 1
- ip.run_cell_magic('cython', '-l m', code)
- self.assertEqual(ip.user_ns['x'], 0)
- def test_cython_verbose(self):
- ip = self._ip
- 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
- ip = self._ip
- 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)
|