summaryrefslogtreecommitdiffstats
path: root/contrib/tools/cython/Cython/Build/Tests/TestIpythonMagic.py
diff options
context:
space:
mode:
authornik-bes <[email protected]>2025-05-19 07:20:13 +0300
committernik-bes <[email protected]>2025-05-19 07:36:02 +0300
commit317b7368e24941ff76499f500579fd9b10f6656e (patch)
treeabbcbaea595e7d2e9f23cf59a408b3082fe4340d /contrib/tools/cython/Cython/Build/Tests/TestIpythonMagic.py
parent6b666a52d40308ab9b3532cd8d3008b9f37cfffb (diff)
Update Cython to 3.0.10.
commit_hash:b43c96b868cd36d636192fd2c6024d9f0d2fb6f8
Diffstat (limited to 'contrib/tools/cython/Cython/Build/Tests/TestIpythonMagic.py')
-rw-r--r--contrib/tools/cython/Cython/Build/Tests/TestIpythonMagic.py132
1 files changed, 111 insertions, 21 deletions
diff --git a/contrib/tools/cython/Cython/Build/Tests/TestIpythonMagic.py b/contrib/tools/cython/Cython/Build/Tests/TestIpythonMagic.py
index 24213091b26..65d801c6b72 100644
--- a/contrib/tools/cython/Cython/Build/Tests/TestIpythonMagic.py
+++ b/contrib/tools/cython/Cython/Build/Tests/TestIpythonMagic.py
@@ -6,10 +6,14 @@
from __future__ import absolute_import
import os
+import io
import sys
from contextlib import contextmanager
+from unittest import skipIf
+
from Cython.Build import IpythonMagic
from Cython.TestUtils import CythonTest
+from Cython.Compiler.Annotate import AnnotationCCodeWriter
try:
import IPython.testing.globalipapp
@@ -21,6 +25,10 @@ else:
def skip_if_not_installed(c):
return c
+# not using IPython's decorators here because they depend on "nose"
+skip_win32 = skipIf(sys.platform == 'win32', "Skip on Windows")
+skip_py27 = skipIf(sys.version_info[:2] == (2,7), "Disabled in Py2.7")
+
try:
# disable IPython history thread before it gets started to avoid having to clean it up
from IPython.core.history import HistoryManager
@@ -28,6 +36,26 @@ try:
except ImportError:
pass
+
+@contextmanager
+def capture_output():
+ backup = sys.stdout, sys.stderr
+ try:
+ replacement = [
+ io.TextIOWrapper(io.BytesIO(), encoding=sys.stdout.encoding),
+ io.TextIOWrapper(io.BytesIO(), encoding=sys.stderr.encoding),
+ ]
+ sys.stdout, sys.stderr = replacement
+ output = []
+ yield output
+ finally:
+ sys.stdout, sys.stderr = backup
+ for wrapper in replacement:
+ wrapper.seek(0) # rewind
+ output.append(wrapper.read())
+ wrapper.close()
+
+
code = u"""\
def f(x):
return 2*x
@@ -47,24 +75,26 @@ def main():
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
+compile_error_code = u'''\
+cdef extern from *:
+ """
+ xxx a=1;
+ """
+ int a;
+def doit():
+ return a
+'''
+
+compile_warning_code = u'''\
+cdef extern from *:
+ """
+ #pragma message ( "CWarning" )
+ int a = 42;
+ """
+ int a;
+def doit():
+ return a
+'''
@skip_if_not_installed
@@ -85,7 +115,7 @@ class TestIPythonMagic(CythonTest):
result = ip.run_cell_magic('cython_inline', '', 'return a+b')
self.assertEqual(result, 30)
- @skip_win32('Skip on Windows')
+ @skip_win32
def test_cython_pyximport(self):
ip = self._ip
module_name = '_test_cython_pyximport'
@@ -142,7 +172,41 @@ class TestIPythonMagic(CythonTest):
self.assertEqual(ip.user_ns['g'], 2 // 10)
self.assertEqual(ip.user_ns['h'], 2 // 10)
- @skip_win32('Skip on Windows')
+ def test_cython_compile_error_shown(self):
+ ip = self._ip
+ with capture_output() as out:
+ ip.run_cell_magic('cython', '-3', compile_error_code)
+ captured_out, captured_err = out
+
+ # it could be that c-level output is captured by distutil-extension
+ # (and not by us) and is printed to stdout:
+ captured_all = captured_out + "\n" + captured_err
+ self.assertTrue("error" in captured_all, msg="error in " + captured_all)
+
+ def test_cython_link_error_shown(self):
+ ip = self._ip
+ with capture_output() as out:
+ ip.run_cell_magic('cython', '-3 -l=xxxxxxxx', code)
+ captured_out, captured_err = out
+
+ # it could be that c-level output is captured by distutil-extension
+ # (and not by us) and is printed to stdout:
+ captured_all = captured_out + "\n!" + captured_err
+ self.assertTrue("error" in captured_all, msg="error in " + captured_all)
+
+ def test_cython_warning_shown(self):
+ ip = self._ip
+ with capture_output() as out:
+ # force rebuild, otherwise no warning as after the first success
+ # no build step is performed
+ ip.run_cell_magic('cython', '-3 -f', compile_warning_code)
+ captured_out, captured_err = out
+
+ # check that warning was printed to stdout even if build hasn't failed
+ self.assertTrue("CWarning" in captured_out)
+
+ @skip_py27 # Not strictly broken in Py2.7 but currently fails in CI due to C compiler issues.
+ @skip_win32
def test_cython3_pgo(self):
# The Cython cell defines the functions f() and call().
ip = self._ip
@@ -151,7 +215,7 @@ class TestIPythonMagic(CythonTest):
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')
+ @skip_win32
def test_extlibs(self):
ip = self._ip
code = u"""
@@ -203,3 +267,29 @@ x = sin(0.0)
ip.ex('g = f(10)')
self.assertEqual(ip.user_ns['g'], 20.0)
self.assertEqual([normal_log.INFO], normal_log.thresholds)
+
+ def test_cython_no_annotate(self):
+ ip = self._ip
+ html = ip.run_cell_magic('cython', '', code)
+ self.assertTrue(html is None)
+
+ def test_cython_annotate(self):
+ ip = self._ip
+ html = ip.run_cell_magic('cython', '--annotate', code)
+ # somewhat brittle way to differentiate between annotated htmls
+ # with/without complete source code:
+ self.assertTrue(AnnotationCCodeWriter.COMPLETE_CODE_TITLE not in html.data)
+
+ def test_cython_annotate_default(self):
+ ip = self._ip
+ html = ip.run_cell_magic('cython', '-a', code)
+ # somewhat brittle way to differentiate between annotated htmls
+ # with/without complete source code:
+ self.assertTrue(AnnotationCCodeWriter.COMPLETE_CODE_TITLE not in html.data)
+
+ def test_cython_annotate_complete_c_code(self):
+ ip = self._ip
+ html = ip.run_cell_magic('cython', '--annotate-fullc', code)
+ # somewhat brittle way to differentiate between annotated htmls
+ # with/without complete source code:
+ self.assertTrue(AnnotationCCodeWriter.COMPLETE_CODE_TITLE in html.data)