diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 6dca8cb9..3777df89 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -302,9 +302,9 @@ jobs: CIBW_TEST_COMMAND: PYTHONUNBUFFERED=1 python -m pytest ${{ matrix.test_args || '{project}' }} # default to test all run: | set -eux - + mkdir cffi - + tar zxf ${{ steps.fetch_sdist.outputs.download-path }}/cffi*.tar.gz --strip-components=1 -C cffi python -m pip install --upgrade "${{ matrix.cibw_version || 'cibuildwheel' }}" @@ -509,9 +509,7 @@ jobs: CIBW_BUILD: ${{ matrix.spec }} CIBW_PRERELEASE_PYTHONS: 'True' CIBW_TEST_REQUIRES: pytest setuptools - CIBW_TEST_COMMAND: 'python -m pytest {package}/src/c' - # FIXME: /testing takes ~45min on Windows and has some failures... - # CIBW_TEST_COMMAND='python -m pytest {package}/src/c {project}/testing' + CIBW_TEST_COMMAND: 'python -m pytest {package}' run: | set -eux diff --git a/src/cffi/verifier.py b/src/cffi/verifier.py index e392a2b7..f7594c2c 100644 --- a/src/cffi/verifier.py +++ b/src/cffi/verifier.py @@ -197,8 +197,20 @@ def _write_source(self, file=None): def _compile_module(self): # compile this C source + # Note: compilation will create artifacts in tmpdir + sourcefilename + # This can exceed the windows MAXPATH quite easily. To make it shorter, + # cd into tmpdir and make the sourcefilename relative to tmdir tmpdir = os.path.dirname(self.sourcefilename) - outputfilename = ffiplatform.compile(tmpdir, self.get_extension()) + olddir = os.getcwd() + os.chdir(tmpdir) + self.sourcefilename_orig = self.sourcefilename + try: + self.sourcefilename = os.path.relpath(self.sourcefilename) + output_rel_filename = ffiplatform.compile(tmpdir, self.get_extension()) + outputfilename = os.path.join(tmpdir, output_rel_filename) + finally: + os.chdir(olddir) + self.sourcefilename = self.sourcefilename_orig try: same = ffiplatform.samefile(outputfilename, self.modulefilename) except OSError: @@ -272,7 +284,9 @@ def cleanup_tmpdir(tmpdir=None, keep_so=False): suffix = _get_so_suffixes()[0].lower() for fn in filelist: if fn.lower().startswith('_cffi_') and ( - fn.lower().endswith(suffix) or fn.lower().endswith('.c')): + fn.lower().endswith(suffix) or + fn.lower().endswith('.c') or + fn.lower().endswith('.o')): try: os.unlink(os.path.join(tmpdir, fn)) except OSError: diff --git a/testing/cffi0/test_ownlib.py b/testing/cffi0/test_ownlib.py index e1a61d67..b414510e 100644 --- a/testing/cffi0/test_ownlib.py +++ b/testing/cffi0/test_ownlib.py @@ -141,10 +141,15 @@ def setup_class(cls): return # try (not too hard) to find the version used to compile this python # no mingw - from distutils.msvc9compiler import get_build_version - version = get_build_version() - toolskey = "VS%0.f0COMNTOOLS" % version - toolsdir = os.environ.get(toolskey, None) + toolsdir = None + try: + # This will always fail on setuptools>73 which removes msvc9compiler + from distutils.msvc9compiler import get_build_version + version = get_build_version() + toolskey = "VS%0.f0COMNTOOLS" % version + toolsdir = os.environ.get(toolskey, None) + except Exception: + pass if toolsdir is None: return productdir = os.path.join(toolsdir, os.pardir, os.pardir, "VC") diff --git a/testing/cffi0/test_verify.py b/testing/cffi0/test_verify.py index 4942bba6..0e85fcaa 100644 --- a/testing/cffi0/test_verify.py +++ b/testing/cffi0/test_verify.py @@ -52,9 +52,11 @@ def test_module_type(): ffi = FFI() lib = ffi.verify() if hasattr(lib, '_cffi_python_module'): - print('verify got a PYTHON module') + pass + # print('verify got a PYTHON module') if hasattr(lib, '_cffi_generic_module'): - print('verify got a GENERIC module') + pass + # print('verify got a GENERIC module') expected_generic = (cffi.verifier._FORCE_GENERIC_ENGINE or '__pypy__' in sys.builtin_module_names) assert hasattr(lib, '_cffi_python_module') == (not expected_generic) @@ -2246,10 +2248,10 @@ def test_implicit_unicode_on_windows(): def test_use_local_dir(): ffi = FFI() - lib = ffi.verify("", modulename="test_use_local_dir") + lib = ffi.verify("", modulename="_cffi_test_use_local_dir") this_dir = os.path.dirname(__file__) pycache_files = os.listdir(os.path.join(this_dir, '__pycache__')) - assert any('test_use_local_dir' in s for s in pycache_files) + assert any('_cffi_test_use_local_dir' in s for s in pycache_files) def test_define_known_value(): ffi = FFI() @@ -2585,3 +2587,21 @@ def test_passing_large_list(): arg = list(range(20000000)) lib.passing_large_list(arg) # assert did not segfault + +def test_no_regen(): + from cffi.verifier import Verifier, _caller_dir_pycache, _FORCE_GENERIC_ENGINE + import os + ffi = FFI() + # make sure the module name is unique + modulename = "_cffi_test_no_regen" + str(_FORCE_GENERIC_ENGINE) + ffi.cdef("double cos(double x);") + lib = ffi.verify('#include ', libraries=lib_m, modulename=modulename) + assert lib.cos(1.23) == math.cos(1.23) + # Make sure that recompiling the same code does not rebuild the C file + cfile = os.path.join(ffi.verifier.tmpdir, f"{modulename}.c") + assert os.path.exists(cfile) + os.unlink(cfile) + assert not os.path.exists(cfile) + lib = ffi.verify('#include ', libraries=lib_m, modulename=modulename) + assert lib.cos(1.23) == math.cos(1.23) + assert not os.path.exists(cfile) diff --git a/testing/cffi0/test_verify2.py b/testing/cffi0/test_verify2.py deleted file mode 100644 index 25f1e3f5..00000000 --- a/testing/cffi0/test_verify2.py +++ /dev/null @@ -1,13 +0,0 @@ -import pytest -from .test_verify import * - -# eliminate warning noise from common test modules that are repeatedly re-imported -pytestmark = pytest.mark.filterwarnings("ignore:reimporting:UserWarning") - -# This test file runs normally after test_verify. We only clean up the .c -# sources, to check that it also works when we have only the .so. The -# tests should run much faster than test_verify. - -def setup_module(): - import cffi.verifier - cffi.verifier.cleanup_tmpdir(keep_so=True) diff --git a/testing/cffi0/test_vgen2.py b/testing/cffi0/test_vgen2.py deleted file mode 100644 index 34147c87..00000000 --- a/testing/cffi0/test_vgen2.py +++ /dev/null @@ -1,13 +0,0 @@ -import cffi.verifier -from .test_vgen import * - -# This test file runs normally after test_vgen. We only clean up the .c -# sources, to check that it also works when we have only the .so. The -# tests should run much faster than test_vgen. - -def setup_module(): - cffi.verifier.cleanup_tmpdir(keep_so=True) - cffi.verifier._FORCE_GENERIC_ENGINE = True - -def teardown_module(): - cffi.verifier._FORCE_GENERIC_ENGINE = False diff --git a/testing/cffi0/test_zdistutils.py b/testing/cffi0/test_zdistutils.py index 08c432c7..75edcda8 100644 --- a/testing/cffi0/test_zdistutils.py +++ b/testing/cffi0/test_zdistutils.py @@ -90,7 +90,7 @@ def test_compile_module_explicit_filename(self): csrc = '/*hi there %s!2*/\n#include \n' % self v = Verifier(ffi, csrc, force_generic_engine=self.generic, libraries=[self.lib_m]) - basename = self.__class__.__name__[:10] + '_test_compile_module' + basename = self.__class__.__name__[:20] + '_test_compile_module' v.modulefilename = filename = str(udir.join(basename + '.so')) v.compile_module() assert filename == v.modulefilename diff --git a/testing/embedding/__init__.py b/testing/embedding/__init__.py index e69de29b..13bb2072 100644 --- a/testing/embedding/__init__.py +++ b/testing/embedding/__init__.py @@ -0,0 +1,5 @@ +import sys +import pytest + +if sys.platform == "win32": + pytest.skip("XXX fixme", allow_module_level=True)