summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Behnel <stefan_ml@behnel.de>2018-08-25 18:22:42 +0200
committerStefan Behnel <stefan_ml@behnel.de>2018-08-25 18:22:42 +0200
commit4caf76b45ec588d5c6424824cc1e4bf6bc796b19 (patch)
tree1f214f0d25c2bcdfdbfc4d688200981c486e9795
parent4ce754271ff4cfbd8df2b278e812154fb1b02319 (diff)
downloadcython-4caf76b45ec588d5c6424824cc1e4bf6bc796b19.tar.gz
Add test for Cython module usage in subinterpreters. In Py3.5, we should now raise an exception when trying to re-import a module into a different subinterpreter.
-rw-r--r--tests/run/reimport_from_subinterpreter.srctree79
1 files changed, 79 insertions, 0 deletions
diff --git a/tests/run/reimport_from_subinterpreter.srctree b/tests/run/reimport_from_subinterpreter.srctree
new file mode 100644
index 000000000..fd3d15941
--- /dev/null
+++ b/tests/run/reimport_from_subinterpreter.srctree
@@ -0,0 +1,79 @@
+# mode: run
+# tag: pep489, subinterpreter
+
+PYTHON setup.py build_ext --inplace
+PYTHON -c 'import subtest; subtest.run_main()'
+PYTHON -c 'import subtest; subtest.run_sub()'
+PYTHON -c 'import subtest; subtest.run_main(); subtest.run_sub()'
+
+######## setup.py ########
+
+from Cython.Build.Dependencies import cythonize
+from distutils.core import setup
+
+setup(
+ ext_modules = cythonize("**/*.pyx"),
+ )
+
+######## subtest.pyx ########
+
+cdef extern from *:
+ """
+ /* Copied from CPython's _testcapi.c module */
+ static PyObject *run_in_subinterpreter(const char *code) {
+ int r;
+ PyThreadState *substate, *mainstate;
+
+ mainstate = PyThreadState_Get();
+
+ PyThreadState_Swap(NULL);
+
+ substate = Py_NewInterpreter();
+ if (substate == NULL) {
+ /* Since no new thread state was created, there is no exception to
+ propagate; raise a fresh one after swapping in the old thread
+ state. */
+ PyThreadState_Swap(mainstate);
+ PyErr_SetString(PyExc_RuntimeError, "sub-interpreter creation failed");
+ return NULL;
+ }
+ r = PyRun_SimpleString(code);
+ Py_EndInterpreter(substate);
+
+ PyThreadState_Swap(mainstate);
+ return PyLong_FromLong(r);
+ }
+ """
+ object run_in_subinterpreter(const char *code)
+
+
+MAIN_HAS_IMPORTED = False
+
+def run_main():
+ global MAIN_HAS_IMPORTED
+ MAIN_HAS_IMPORTED = True
+ import package.subtest
+ from package import subtest
+
+def run_sub():
+ assert 0 == run_in_subinterpreter(b'1+1')
+ assert 0 == run_in_subinterpreter(b'2+2')
+
+ assert 0 == run_in_subinterpreter(b'import package')
+ assert 0 == run_in_subinterpreter(b'import package')
+
+ import sys
+ result = run_in_subinterpreter(b'import package.subtest')
+ if not MAIN_HAS_IMPORTED:
+ assert result == 0, result # imports only in subinterpreters are ok
+ elif sys.version_info >= (3, 5):
+ assert result == -1, result # re-import in a different subinterpreter fails in Py3.5+ (with PEP-489)
+ else:
+ assert result == 0, result # re-import in a different subinterpreter reuses the module in Py<3.5
+
+
+######## package/__init__.py ########
+
+######## package/subtest.pyx ########
+
+print("Module loaded: %s" % __name__)