diff options
author | Stefan Behnel <stefan_ml@behnel.de> | 2018-08-25 18:22:42 +0200 |
---|---|---|
committer | Stefan Behnel <stefan_ml@behnel.de> | 2018-08-25 18:22:42 +0200 |
commit | 4caf76b45ec588d5c6424824cc1e4bf6bc796b19 (patch) | |
tree | 1f214f0d25c2bcdfdbfc4d688200981c486e9795 | |
parent | 4ce754271ff4cfbd8df2b278e812154fb1b02319 (diff) | |
download | cython-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.srctree | 79 |
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__) |