summaryrefslogtreecommitdiff
path: root/tests/build
diff options
context:
space:
mode:
authorStefan Behnel <stefan_ml@behnel.de>2022-02-02 03:23:34 +0100
committerStefan Behnel <stefan_ml@behnel.de>2022-02-02 03:23:34 +0100
commit79637b23da77732e753b1e1ab5669b3e29978be3 (patch)
treebad1f61f8e6035d70d2c8c4dd3bef233e6a2b8ae /tests/build
parent5a76c404c803601b6941525cb8ec8096ddb10356 (diff)
downloadcython-79637b23da77732e753b1e1ab5669b3e29978be3.tar.gz
Always regenerate .c/cpp output files when changing the Cython version. This is probably what users expect since silently keeping outdated files is error prone.
Diffstat (limited to 'tests/build')
-rw-r--r--tests/build/cythonize_newer_files.srctree87
1 files changed, 87 insertions, 0 deletions
diff --git a/tests/build/cythonize_newer_files.srctree b/tests/build/cythonize_newer_files.srctree
new file mode 100644
index 000000000..3c330d869
--- /dev/null
+++ b/tests/build/cythonize_newer_files.srctree
@@ -0,0 +1,87 @@
+"""
+PYTHON test.py
+"""
+
+######## a.pyx ########
+
+######## test.py ########
+
+import os.path
+
+from Cython.Utils import GENERATED_BY_MARKER_BYTES, clear_function_caches, clear_method_caches
+from Cython.Build.Dependencies import cythonize, DependencyTree
+import Cython.Build.Dependencies
+
+getmtime = os.path.getmtime
+
+def wait_for_newer_mtime(filename, old_mtime):
+ mtime = old_mtime
+ while mtime <= old_mtime:
+ os.utime(filename, None)
+ mtime = getmtime(filename)
+ return mtime
+
+
+# test the mtime waiting itself
+with open("test_file.txt", 'wb') as f:
+ pass
+orig_mtime = getmtime("test_file.txt")
+wait_for_newer_mtime("test_file.txt", orig_mtime)
+assert orig_mtime < getmtime("test_file.txt")
+
+
+def fresh_cythonize(*args):
+ clear_function_caches()
+ clear_method_caches(DependencyTree.timestamp)
+ Cython.Build.Dependencies._dep_tree = None
+ cythonize(*args)
+
+
+assert not os.path.exists("a.c")
+
+# new
+fresh_cythonize("*.pyx")
+assert os.path.isfile("a.c")
+mtime = getmtime("a.c")
+
+# already exists
+fresh_cythonize("*.pyx")
+assert mtime == getmtime("a.c")
+
+# outdated
+wait_for_newer_mtime("a.pyx", mtime)
+assert mtime < getmtime("a.pyx")
+fresh_cythonize("*.pyx")
+new_mtime = getmtime("a.c")
+assert mtime < new_mtime
+
+# now up to date
+fresh_cythonize("*.pyx")
+assert new_mtime == getmtime("a.c")
+
+# different Cython version (even though newer)
+marker = b"/* Generated by Cython "
+assert GENERATED_BY_MARKER_BYTES.startswith(marker) # safety belt
+with open("a.c", "rb") as f:
+ content = f.read()
+
+assert content.startswith(GENERATED_BY_MARKER_BYTES)
+content = marker + b"123" + content[len(marker):]
+
+with open("a.c", "wb") as f:
+ f.write(content)
+wait_for_newer_mtime("a.c", new_mtime)
+
+other_cython_mtime = getmtime("a.c")
+assert mtime < new_mtime < other_cython_mtime
+
+fresh_cythonize("*.pyx")
+latest_mtime = getmtime("a.c")
+assert mtime < new_mtime < other_cython_mtime <= latest_mtime
+
+with open("a.c", "rb") as f:
+ assert f.read(len(GENERATED_BY_MARKER_BYTES)) == GENERATED_BY_MARKER_BYTES # file was rewritten
+
+# now up to date
+fresh_cythonize("*.pyx")
+assert mtime < new_mtime < other_cython_mtime <= latest_mtime == getmtime("a.c")