1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
|
import os
import sys
import numpy
from Cython.Build import cythonize
from setuptools import Command, Extension, setup
BASEDIR = os.path.abspath(os.path.dirname(__file__))
SRCDIR = os.path.join(BASEDIR,'src')
CMDS_NOCYTHONIZE = ['clean','clean_cython','sdist']
COMPILER_DIRECTIVES = {
# Cython 3.0.0 changes the default of the c_api_binop_methods directive to
# False, resulting in errors in datetime and timedelta arithmetic:
# https://github.com/Unidata/cftime/issues/271. We explicitly set it to
# True to retain Cython 0.x behavior for future Cython versions. This
# directive was added in Cython version 0.29.20.
"c_api_binop_methods": True
}
COVERAGE_COMPILER_DIRECTIVES = {
"linetrace": True,
"warn.maybe_uninitialized": False,
"warn.unreachable": False,
"warn.unused": False,
}
DEFINE_MACROS = [("NPY_NO_DEPRECATED_API", "NPY_1_7_API_VERSION")]
FLAG_COVERAGE = '--cython-coverage' # custom flag enabling Cython line tracing
NAME = 'cftime'
CFTIME_DIR = os.path.join(SRCDIR, NAME)
CYTHON_FNAME = os.path.join(CFTIME_DIR, '_{}.pyx'.format(NAME))
class CleanCython(Command):
description = 'Purge artifacts built by Cython'
user_options = []
def initialize_options(self):
pass
def finalize_options(self):
pass
def run(self):
for rpath, _, fnames in os.walk(CFTIME_DIR):
for fname in fnames:
_, ext = os.path.splitext(fname)
if ext in ('.pyc', '.pyo', '.c', '.so'):
artifact = os.path.join(rpath, fname)
if os.path.exists(artifact):
print('clean: removing file {!r}'.format(artifact))
os.remove(artifact)
else:
print('clean: skipping file {!r}'.format(artifact))
if ((FLAG_COVERAGE in sys.argv or os.environ.get('CYTHON_COVERAGE', None))
and cythonize):
COMPILER_DIRECTIVES = {
**COMPILER_DIRECTIVES, **COVERAGE_COMPILER_DIRECTIVES
}
DEFINE_MACROS += [('CYTHON_TRACE', '1'),
('CYTHON_TRACE_NOGIL', '1')]
if FLAG_COVERAGE in sys.argv:
sys.argv.remove(FLAG_COVERAGE)
print('enable: "linetrace" Cython compiler directive')
# See https://github.com/Unidata/cftime/issues/91
if any([arg in CMDS_NOCYTHONIZE for arg in sys.argv]):
ext_modules = []
else:
extension = Extension('{}._{}'.format(NAME, NAME),
sources=[os.path.relpath(CYTHON_FNAME, BASEDIR)],
define_macros=DEFINE_MACROS,
include_dirs=[numpy.get_include(),])
ext_modules = cythonize(
extension,
compiler_directives=COMPILER_DIRECTIVES,
language_level=3,
)
setup(
cmdclass={'clean_cython': CleanCython},
ext_modules=ext_modules,
)
|