185
185
from distutils.extension import Extension
189
from Cython.Distutils import build_ext
190
from Cython.Compiler.Version import version as pyrex_version
192
print("No Cython, trying Pyrex...")
193
from Pyrex.Distutils import build_ext
194
from Pyrex.Compiler.Version import version as pyrex_version
188
from Cython.Distutils import build_ext
189
from Cython.Compiler.Version import version as cython_version
195
190
except ImportError:
197
192
# try to build the extension from the prior generated source.
199
print("The python package 'Pyrex' is not available."
194
print("The python package 'Cython' is not available."
200
195
" If the .c files are available,")
201
196
print("they will be built,"
202
197
" but modifying the .pyx files will not rebuild them.")
204
199
from distutils.command.build_ext import build_ext
207
pyrex_version_info = LooseVersion(pyrex_version)
202
cython_version_info = LooseVersion(cython_version)
210
205
class build_ext_if_possible(build_ext):
251
# Override the build_ext if we have Pyrex available
246
# Override the build_ext if we have Cython available
252
247
command_classes['build_ext'] = build_ext_if_possible
253
248
unavailable_files = []
256
def add_pyrex_extension(module_name, libraries=None, extra_source=[]):
257
"""Add a pyrex module to build.
251
def add_cython_extension(module_name, libraries=None, extra_source=[]):
252
"""Add a cython module to build.
259
This will use Pyrex to auto-generate the .c file if it is available.
254
This will use Cython to auto-generate the .c file if it is available.
260
255
Otherwise it will fall back on the .c file. If the .c file is not
261
256
available, it will warn, and not add anything.
267
262
determine the .pyx and .c files to use.
269
264
path = module_name.replace('.', '/')
270
pyrex_name = path + '.pyx'
265
cython_name = path + '.pyx'
271
266
c_name = path + '.c'
272
267
define_macros = []
273
268
if sys.platform == 'win32':
274
# pyrex uses the macro WIN32 to detect the platform, even though it
269
# cython uses the macro WIN32 to detect the platform, even though it
275
270
# should be using something like _WIN32 or MS_WINDOWS, oh well, we can
276
271
# give it the right value.
277
272
define_macros.append(('WIN32', None))
279
source = [pyrex_name]
274
source = [cython_name]
281
276
if not os.path.isfile(c_name):
282
277
unavailable_files.append(c_name)
288
283
define_macros=define_macros, libraries=libraries))
291
add_pyrex_extension('breezy._annotator_pyx')
292
add_pyrex_extension('breezy._bencode_pyx')
293
add_pyrex_extension('breezy._chunks_to_lines_pyx')
294
add_pyrex_extension('breezy._groupcompress_pyx',
286
add_cython_extension('breezy._annotator_pyx')
287
add_cython_extension('breezy._bencode_pyx')
288
add_cython_extension('breezy._chunks_to_lines_pyx')
289
add_cython_extension('breezy._groupcompress_pyx',
295
290
extra_source=['breezy/diff-delta.c'])
296
add_pyrex_extension('breezy._knit_load_data_pyx')
297
add_pyrex_extension('breezy._known_graph_pyx')
298
add_pyrex_extension('breezy._rio_pyx')
291
add_cython_extension('breezy._knit_load_data_pyx')
292
add_cython_extension('breezy._known_graph_pyx')
293
add_cython_extension('breezy._rio_pyx')
299
294
if sys.platform == 'win32':
300
add_pyrex_extension('breezy._dirstate_helpers_pyx',
295
add_cython_extension('breezy._dirstate_helpers_pyx',
301
296
libraries=['Ws2_32'])
302
add_pyrex_extension('breezy._walkdirs_win32')
297
add_cython_extension('breezy._walkdirs_win32')
304
if have_pyrex and pyrex_version_info == LooseVersion("0.9.4.1"):
305
# Pyrex 0.9.4.1 fails to compile this extension correctly
306
# The code it generates re-uses a "local" pointer and
307
# calls "PY_DECREF" after having set it to NULL. (It mixes PY_XDECREF
308
# which is NULL safe with PY_DECREF which is not.)
309
# <https://bugs.launchpad.net/bzr/+bug/449372>
310
# <https://bugs.launchpad.net/bzr/+bug/276868>
311
print('Cannot build extension "breezy._dirstate_helpers_pyx" using')
312
print(('your version of pyrex "%s". Please upgrade your pyrex'
314
print('install. For now, the non-compiled (python) version will')
315
print('be used instead.')
317
add_pyrex_extension('breezy._dirstate_helpers_pyx')
318
add_pyrex_extension('breezy._readdir_pyx')
319
add_pyrex_extension('breezy._chk_map_pyx')
299
add_cython_extension('breezy._dirstate_helpers_pyx')
300
add_cython_extension('breezy._readdir_pyx')
301
add_cython_extension('breezy._chk_map_pyx')
320
302
ext_modules.append(Extension('breezy._patiencediff_c',
321
303
['breezy/_patiencediff_c.c']))
322
if have_pyrex and pyrex_version_info < LooseVersion("0.9.6.3"):
304
if have_cython and cython_version_info < LooseVersion("0.9.6.3"):
324
print(('Your Pyrex/Cython version %s is too old to build the simple_set' % (
306
print(('Your Cython version %s is too old to build the simple_set' % (
326
308
print('and static_tuple extensions.')
327
print('Please upgrade to at least Pyrex 0.9.6.3')
309
print('Please upgrade to at least Cython 0.9.6.3')
329
311
# TODO: Should this be a fatal error?
331
313
# We only need 0.9.6.3 to build _simple_set_pyx, but static_tuple depends
333
add_pyrex_extension('breezy._simple_set_pyx')
315
add_cython_extension('breezy._simple_set_pyx')
334
316
ext_modules.append(Extension('breezy._static_tuple_c',
335
317
['breezy/_static_tuple_c.c']))
336
add_pyrex_extension('breezy._btree_serializer_pyx')
318
add_cython_extension('breezy._btree_serializer_pyx')
339
321
if unavailable_files: