Skip to content

Commit b54a68d

Browse files
committed
cython dependency scanner
1 parent da3da25 commit b54a68d

File tree

1 file changed

+39
-5
lines changed

1 file changed

+39
-5
lines changed

site_scons/site_tools/cython.py

+39-5
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,52 @@
1+
import re
12
import SCons
23
from SCons.Action import Action
4+
from SCons.Scanner import Scanner
35

6+
pyx_from_import_re = re.compile(r'^from\s+(\S+)\s+cimport', re.M)
7+
pyx_import_re = re.compile(r'^cimport\s+(\S+)', re.M)
8+
cdef_import_re = re.compile(r'^cdef extern from\s+.(\S+).:', re.M)
9+
10+
11+
def pyx_scan(node, env, path, arg=None):
12+
contents = node.get_text_contents()
13+
14+
# from <module> cimport ...
15+
matches = pyx_from_import_re.findall(contents)
16+
# cimport <module>
17+
matches += pyx_import_re.findall(contents)
18+
19+
# Modules can be either .pxd or .pyx files
20+
files = [m.replace('.', '/') + '.pxd' for m in matches]
21+
files += [m.replace('.', '/') + '.pyx' for m in matches]
22+
23+
# cdef extern from <file>
24+
files += cdef_import_re.findall(contents)
25+
26+
# Handle relative imports
27+
cur_dir = str(node.get_dir())
28+
files = [cur_dir + f if f.startswith('/') else f for f in files]
29+
30+
# Filter out non-existing files (probably system imports)
31+
files = [f for f in files if env.File(f).exists()]
32+
return env.File(files)
33+
34+
35+
pyxscanner = Scanner(function=pyx_scan, skeys=['.pyx', '.pxd'], recursive=True)
436
cythonAction = Action("$CYTHONCOM")
537

38+
639
def create_builder(env):
740
try:
841
cython = env['BUILDERS']['Cython']
942
except KeyError:
1043
cython = SCons.Builder.Builder(
11-
action = cythonAction,
12-
emitter = {},
13-
suffix = cython_suffix_emitter,
14-
single_source = 1
15-
)
44+
action=cythonAction,
45+
emitter={},
46+
suffix=cython_suffix_emitter,
47+
single_source=1
48+
)
49+
env.Append(SCANNERS=pyxscanner)
1650
env['BUILDERS']['Cython'] = cython
1751
return cython
1852

0 commit comments

Comments
 (0)