From 1e21b9bde57da26b89aac57c98c3f10c3ec3c5a4 Mon Sep 17 00:00:00 2001 From: AreWeDreaming Date: Wed, 4 Mar 2026 23:11:55 -0800 Subject: [PATCH] This PR properly compiles cython to remove pyximport --- .gitignore | 3 ++- omas/omas_utils.py | 19 ++++++------------- omas/tests/test_omas_utils.py | 11 +++++++++++ pyproject.toml | 3 +++ setup.py | 13 ++++++++++++- 5 files changed, 34 insertions(+), 15 deletions(-) create mode 100644 pyproject.toml diff --git a/.gitignore b/.gitignore index 36163ced4..679d656e8 100644 --- a/.gitignore +++ b/.gitignore @@ -10,7 +10,8 @@ build/ .DS_Store /site-packages/ /tmp - +*.cpython* +omas_cython.c omas/data-dictionary omas/Saxon* omas/imas_structures/*/*.xml diff --git a/omas/omas_utils.py b/omas/omas_utils.py index f2c971d1c..75c793e48 100644 --- a/omas/omas_utils.py +++ b/omas/omas_utils.py @@ -868,21 +868,14 @@ def omas_global_quantities(imas_version=omas_rcparams['default_imas_version']): return _global_quantities[imas_version] -# only attempt cython if effective user owns this copy of omas -# disabled for Windows: need to add check for file ownership under Windows -if os.name == 'nt' or os.geteuid() != os.stat(__file__).st_uid: +# Import compiled Cython extension +# Fall back to pure Python implementation if the compiled extension is not available +try: + from .omas_cython import * +except ImportError as _excp: + warnings.warn('Compiled Cython extension not available, falling back to pure Python: ' + str(_excp)) with open(os.path.split(__file__)[0] + os.sep + 'omas_cython.pyx', 'r') as f: exec(f.read(), globals()) -else: - try: - import pyximport - - pyximport.install(language_level=3) - from .omas_cython import * - except Exception as _excp: - warnings.warn('omas cython failed: ' + str(_excp)) - with open(os.path.split(__file__)[0] + os.sep + 'omas_cython.pyx', 'r') as f: - exec(f.read(), globals()) def l2ut(path): diff --git a/omas/tests/test_omas_utils.py b/omas/tests/test_omas_utils.py index e72a839d4..28010311a 100755 --- a/omas/tests/test_omas_utils.py +++ b/omas/tests/test_omas_utils.py @@ -117,6 +117,17 @@ def test_omas_info(self): ods_info_list = omas_info(get_list) assert all(item in ods_info_list for item in get_list) + def test_cython_extension_compiled(self): + """Test that the Cython extension was properly compiled and is being used""" + import omas.omas_cython as cython_module + # Check that we're using the compiled extension (.so file) not the .pyx source + assert hasattr(cython_module, '__file__'), "Cython module should have a __file__ attribute" + module_file = cython_module.__file__ + # Compiled extension should end with .so (Linux/Mac) or .pyd (Windows) + assert module_file.endswith('.so') or module_file.endswith('.pyd'), \ + f"Expected compiled extension (.so/.pyd), but got: {module_file}" + print(f"✓ Using compiled Cython extension: {module_file}") + def test_p2l(self): assert p2l('0') == [0] assert p2l('equilibrium') == ['equilibrium'] diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 000000000..1e9f4822c --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["setuptools>=41.2", "Cython>=0.29", "numpy>=1.16.1"] +build-backend = "setuptools.build_meta" diff --git a/setup.py b/setup.py index 343ef9bac..80e267cd9 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,8 @@ import os import glob import subprocess +from setuptools import Extension +from Cython.Build import cythonize install_requires = [ 'numpy>=1.16.1', @@ -51,7 +53,7 @@ packages = ['omas', 'omas.examples', 'omas.samples', 'omas.tests', 'omas.utilities'] package_data = { - 'omas': ['*.py', '*.pyx', 'version'], + 'omas': ['*.py', 'version'], 'omas.examples': ['*.py'], 'omas.samples': ['*'], 'omas.tests': ['*.py'], @@ -109,6 +111,13 @@ from setuptools import setup +# Build Cython extension +ext_modules = cythonize( + [Extension("omas.omas_cython", ["omas/omas_cython.pyx"])], + language_level=3, + compiler_directives={'embedsignature': True} +) + setup( name='omas', version=open(here + 'omas/version', 'r').read().strip(), @@ -124,4 +133,6 @@ package_data=package_data, install_requires=install_requires, extras_require=extras_require, + ext_modules=ext_modules, + setup_requires=['Cython>=0.29', 'numpy>=1.16.1'], )