Skip to content

Commit 12d61bb

Browse files
RF: update cythexts / setup_helpers from regreg
1 parent f380bd2 commit 12d61bb

File tree

1 file changed

+39
-21
lines changed

1 file changed

+39
-21
lines changed

Diff for: cythexts.py

+39-21
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import os
22
from os.path import splitext, sep as filesep, join as pjoin, relpath
33
from hashlib import sha1
4-
from subprocess import check_call
54

65
from distutils.command.build_ext import build_ext
76
from distutils.command.sdist import sdist
@@ -95,6 +94,8 @@ def cyproc_exts(exts, cython_min_version,
9594
Can be ``build_ext`` input (if we have good c files) or cython
9695
``build_ext`` if we have a good cython, or a class raising an informative
9796
error on ``run()``
97+
need_cython : bool
98+
True if we need Cython to build extensions, False otherwise.
9899
"""
99100
if stamped_pyx_ok(exts, hash_stamps_fname):
100101
# Replace pyx with c files, use standard builder
@@ -107,29 +108,33 @@ def cyproc_exts(exts, cython_min_version,
107108
else:
108109
sources.append(source)
109110
mod.sources = sources
110-
return build_ext
111+
return build_ext, False
111112
# We need cython
112113
try:
113114
from Cython.Compiler.Version import version as cyversion
114115
except ImportError:
115-
cython_ok = False
116-
else:
117-
cython_ok = LooseVersion(cyversion) >= cython_min_version
118-
if cython_ok:
116+
return derror_maker(build_ext,
117+
'Need cython>={0} to build extensions '
118+
'but cannot import "Cython"'.format(
119+
cython_min_version)), True
120+
if LooseVersion(cyversion) >= cython_min_version:
119121
from Cython.Distutils import build_ext as extbuilder
120-
return extbuilder
122+
return extbuilder, True
121123
return derror_maker(build_ext,
122-
'Need cython>=%s to build extensions'
123-
% cython_min_version)
124+
'Need cython>={0} to build extensions'
125+
'but found cython version {1}'.format(
126+
cython_min_version, cyversion)), True
124127

125128

126-
def build_stamp(pyxes):
129+
def build_stamp(pyxes, include_dirs=()):
127130
""" Cythonize files in `pyxes`, return pyx, C filenames, hashes
128131
129132
Parameters
130133
----------
131134
pyxes : sequence
132135
sequence of filenames of files on which to run Cython
136+
include_dirs : sequence
137+
Any extra include directories in which to find Cython files.
133138
134139
Returns
135140
-------
@@ -139,11 +144,17 @@ def build_stamp(pyxes):
139144
hash>; "c_filename", <c filemane>; "c_hash", <c file SHA1 hash>.
140145
"""
141146
pyx_defs = {}
147+
from Cython.Compiler.Main import compile
148+
from Cython.Compiler.CmdLine import parse_command_line
149+
includes = sum([['--include-dir', d] for d in include_dirs], [])
142150
for source in pyxes:
143151
base, ext = splitext(source)
144152
pyx_hash = sha1(open(source, 'rt').read()).hexdigest()
145153
c_filename = base + '.c'
146-
check_call('cython ' + source, shell=True)
154+
options, sources = parse_command_line(includes + [source])
155+
result = compile(sources, options)
156+
if result.num_errors > 0:
157+
raise RuntimeError('Cython failed to compile ' + source)
147158
c_hash = sha1(open(c_filename, 'rt').read()).hexdigest()
148159
pyx_defs[source] = dict(pyx_hash=pyx_hash,
149160
c_filename=c_filename,
@@ -173,22 +184,19 @@ def write_stamps(pyx_defs, stamp_fname='pyx-stamps'):
173184
pyx_info['c_hash']))
174185

175186

176-
def find_pyx(root_dir=None):
187+
def find_pyx(root_dir):
177188
""" Recursively find files with extension '.pyx' starting at `root_dir`
178189
179190
Parameters
180191
----------
181-
root_dir : None or str, optional
182-
Directory from which to search for pyx files. If None, use current
183-
working directory.
192+
root_dir : str
193+
Directory from which to search for pyx files.
184194
185195
Returns
186196
-------
187197
pyxes : list
188198
list of filenames relative to `root_dir`
189199
"""
190-
if root_dir is None:
191-
root_dir = os.getcwd()
192200
pyxes = []
193201
for dirpath, dirnames, filenames in os.walk(root_dir):
194202
for filename in filenames:
@@ -199,7 +207,8 @@ def find_pyx(root_dir=None):
199207
return pyxes
200208

201209

202-
def get_pyx_sdist(sdist_like=sdist, hash_stamps_fname='pyx-stamps'):
210+
def get_pyx_sdist(sdist_like=sdist, hash_stamps_fname='pyx-stamps',
211+
include_dirs=()):
203212
""" Add pyx->c conversion, hash recording to sdist command `sdist_like`
204213
205214
Parameters
@@ -210,6 +219,8 @@ def get_pyx_sdist(sdist_like=sdist, hash_stamps_fname='pyx-stamps'):
210219
hash_stamps_fname : str, optional
211220
filename to which to write hashes of pyx / py and c files. Default is
212221
``pyx-stamps``
222+
include_dirs : sequence
223+
Any extra include directories in which to find Cython files.
213224
214225
Returns
215226
-------
@@ -240,7 +251,7 @@ def make_distribution(self):
240251
base, ext = splitext(source)
241252
if ext in ('.pyx', '.py'):
242253
pyxes.append(source)
243-
self.pyx_defs = build_stamp(pyxes)
254+
self.pyx_defs = build_stamp(pyxes, include_dirs)
244255
for pyx_fname, pyx_info in self.pyx_defs.items():
245256
self.filelist.append(pyx_info['c_filename'])
246257
sdist_like.make_distribution(self)
@@ -254,7 +265,8 @@ def make_release_tree(self, base_dir, files):
254265
return PyxSDist
255266

256267

257-
def build_stamp_source(root_dir=None, stamp_fname='pyx-stamps'):
268+
def build_stamp_source(root_dir=None, stamp_fname='pyx-stamps',
269+
include_dirs=None):
258270
""" Build cython c files, make stamp file in source tree `root_dir`
259271
260272
Parameters
@@ -264,7 +276,13 @@ def build_stamp_source(root_dir=None, stamp_fname='pyx-stamps'):
264276
working directory.
265277
stamp_fname : str, optional
266278
Filename for stamp file we will write
279+
include_dirs : None or sequence
280+
Any extra Cython include directories
267281
"""
282+
if root_dir is None:
283+
root_dir = os.getcwd()
284+
if include_dirs is None:
285+
include_dirs = [pjoin(root_dir, 'src')]
268286
pyxes = find_pyx(root_dir)
269-
pyx_defs = build_stamp(pyxes)
287+
pyx_defs = build_stamp(pyxes, include_dirs=include_dirs)
270288
write_stamps(pyx_defs, stamp_fname)

0 commit comments

Comments
 (0)