You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

57 lines
1.7 KiB

  1. import re
  2. import functools
  3. import distutils.core
  4. import distutils.errors
  5. import distutils.extension
  6. from setuptools.extern.six.moves import map
  7. from .monkey import get_unpatched
  8. def _have_cython():
  9. """
  10. Return True if Cython can be imported.
  11. """
  12. cython_impl = 'Cython.Distutils.build_ext'
  13. try:
  14. # from (cython_impl) import build_ext
  15. __import__(cython_impl, fromlist=['build_ext']).build_ext
  16. return True
  17. except Exception:
  18. pass
  19. return False
  20. # for compatibility
  21. have_pyrex = _have_cython
  22. _Extension = get_unpatched(distutils.core.Extension)
  23. class Extension(_Extension):
  24. """Extension that uses '.c' files in place of '.pyx' files"""
  25. def __init__(self, name, sources, *args, **kw):
  26. # The *args is needed for compatibility as calls may use positional
  27. # arguments. py_limited_api may be set only via keyword.
  28. self.py_limited_api = kw.pop("py_limited_api", False)
  29. _Extension.__init__(self, name, sources, *args, **kw)
  30. def _convert_pyx_sources_to_lang(self):
  31. """
  32. Replace sources with .pyx extensions to sources with the target
  33. language extension. This mechanism allows language authors to supply
  34. pre-converted sources but to prefer the .pyx sources.
  35. """
  36. if _have_cython():
  37. # the build has Cython, so allow it to compile the .pyx files
  38. return
  39. lang = self.language or ''
  40. target_ext = '.cpp' if lang.lower() == 'c++' else '.c'
  41. sub = functools.partial(re.sub, '.pyx$', target_ext)
  42. self.sources = list(map(sub, self.sources))
  43. class Library(Extension):
  44. """Just like a regular Extension, but built as a library instead"""