1 from distutils.core import setup, Extension
2 from distutils.sysconfig import get_python_lib
6 if 'sdist' in sys.argv and sys.platform != "win32" and sys.version_info >= (2,4):
7 # Record the current revision in .hgrev
8 import subprocess # os.popen is cleaner but deprecated
9 changeset = subprocess.Popen("hg identify --id --rev tip".split(),
10 stdout=subprocess.PIPE).stdout.read()
11 rev = changeset.decode('ISO-8859-1').strip()
12 hgrev = open('.hgrev', 'w')
16 if sys.platform == "darwin":
17 # Don't create resource files on OS X tar.
18 os.environ['COPY_EXTENDED_ATTRIBUTES_DISABLE'] = 'true'
19 os.environ['COPYFILE_DISABLE'] = 'true'
23 def add_command_class(name, cls):
24 cmdclasses = setup_args.get('cmdclass', {})
25 cmdclasses[name] = cls
26 setup_args['cmdclass'] = cmdclasses
28 if sys.version_info[0] >= 3:
29 import lib2to3.refactor
30 from distutils.command.build_py \
31 import build_py_2to3 as build_py
32 # need to convert sources to Py3 on installation
33 fixers = [ fix for fix in lib2to3.refactor.get_fixers_from_package("lib2to3.fixes")
34 if fix.split('fix_')[-1] not in ('next',)
36 build_py.fixer_names = fixers
37 add_command_class("build_py", build_py)
40 directory for directory, dirs, files in os.walk('Cython/Includes')
41 if '__init__.pyx' in files or '__init__.pxd' in files
42 or directory == 'Cython/Includes' or directory == 'Cython/Includes/Deprecated']
44 pxd_include_patterns = [
45 p+'/*.pxd' for p in pxd_include_dirs ] + [
46 p+'/*.pyx' for p in pxd_include_dirs ]
48 if sys.version_info < (2,4):
49 install_base_dir = get_python_lib(prefix='')
51 patterns = pxd_include_patterns + [
53 'Cython/Compiler/*.pxd',
54 'Cython/Runtime/*.pyx'
56 setup_args['data_files'] = [
57 (os.path.dirname(os.path.join(install_base_dir, pattern)),
58 [ f for f in glob.glob(pattern) ])
59 for pattern in patterns
62 setup_args['package_data'] = {
63 'Cython.Plex' : ['*.pxd'],
64 'Cython.Compiler' : ['*.pxd'],
65 'Cython.Runtime' : ['*.pyx', '*.pxd'],
66 'Cython' : [ p[7:] for p in pxd_include_patterns ],
69 # This dict is used for passing extra arguments that are setuptools
71 setuptools_extra_args = {}
73 if 'setuptools' in sys.modules:
74 setuptools_extra_args['zip_safe'] = False
75 setuptools_extra_args['entry_points'] = {
77 'cython = Cython.Compiler.Main:setuptools_main',
82 if os.name == "posix":
83 scripts = ["bin/cython"]
85 scripts = ["cython.py"]
87 def compile_cython_modules(profile=False, compile_more=False, cython_with_refnanny=False):
88 source_root = os.path.abspath(os.path.dirname(__file__))
89 compiled_modules = ["Cython.Plex.Scanners",
90 "Cython.Plex.Actions",
91 "Cython.Compiler.Lexicon",
92 "Cython.Compiler.Scanning",
93 "Cython.Compiler.Parsing",
94 "Cython.Compiler.Visitor",
95 "Cython.Runtime.refnanny"]
97 compiled_modules.extend([
98 "Cython.Compiler.ParseTreeTransforms",
99 "Cython.Compiler.Nodes",
100 "Cython.Compiler.ExprNodes",
101 "Cython.Compiler.ModuleNode",
102 "Cython.Compiler.Optimize",
106 if cython_with_refnanny:
107 defines.append(('CYTHON_REFNANNY', '1'))
110 if sys.version_info[0] >= 3:
111 from Cython.Distutils import build_ext as build_ext_orig
112 for module in compiled_modules:
113 source_file = os.path.join(source_root, *module.split('.'))
114 if os.path.exists(source_file + ".py"):
115 pyx_source_file = source_file + ".py"
117 pyx_source_file = source_file + ".pyx"
119 if os.path.exists(source_file + '.pxd'):
120 dep_files.append(source_file + '.pxd')
121 if '.refnanny' in module:
122 defines_for_module = []
124 defines_for_module = defines
126 Extension(module, sources = [pyx_source_file],
127 define_macros = defines_for_module,
131 class build_ext(build_ext_orig):
132 # we must keep the original modules alive to make sure
133 # their code keeps working when we remove them from
137 def build_extensions(self):
138 # add path where 2to3 installed the transformed sources
139 # and make sure Python (re-)imports them from there
140 already_imported = [ module for module in sys.modules
141 if module == 'Cython' or module.startswith('Cython.') ]
142 keep_alive = self.dead_modules.append
143 for module in already_imported:
144 keep_alive(sys.modules[module])
145 del sys.modules[module]
146 sys.path.insert(0, os.path.join(source_root, self.build_lib))
149 from Cython.Compiler.Options import directive_defaults
150 directive_defaults['profile'] = True
151 print("Enabled profiling for the Cython binary modules")
152 build_ext_orig.build_extensions(self)
154 setup_args['ext_modules'] = extensions
155 add_command_class("build_ext", build_ext)
158 from distutils.command.build_ext import build_ext as build_ext_orig
160 class build_ext(build_ext_orig):
161 def build_extension(self, ext, *args, **kargs):
163 build_ext_orig.build_extension(self, ext, *args, **kargs)
164 except StandardError:
165 print("Compilation of '%s' failed" % ext.sources[0])
166 from Cython.Compiler.Main import compile
167 from Cython import Utils
169 from Cython.Compiler.Options import directive_defaults
170 directive_defaults['profile'] = True
171 print("Enabled profiling for the Cython binary modules")
172 source_root = os.path.dirname(__file__)
173 for module in compiled_modules:
174 source_file = os.path.join(source_root, *module.split('.'))
175 if os.path.exists(source_file + ".py"):
176 pyx_source_file = source_file + ".py"
178 pyx_source_file = source_file + ".pyx"
179 c_source_file = source_file + ".c"
180 source_is_newer = False
181 if not os.path.exists(c_source_file):
182 source_is_newer = True
184 c_last_modified = Utils.modification_time(c_source_file)
185 if Utils.file_newer_than(pyx_source_file, c_last_modified):
186 source_is_newer = True
188 pxd_source_file = source_file + ".pxd"
189 if os.path.exists(pxd_source_file) and Utils.file_newer_than(pxd_source_file, c_last_modified):
190 source_is_newer = True
192 print("Compiling module %s ..." % module)
193 result = compile(pyx_source_file)
194 c_source_file = result.c_file
196 # Py2 distutils can't handle unicode file paths
197 if isinstance(c_source_file, unicode):
198 filename_encoding = sys.getfilesystemencoding()
199 if filename_encoding is None:
200 filename_encoding = sys.getdefaultencoding()
201 c_source_file = c_source_file.encode(filename_encoding)
202 if '.refnanny' in module:
203 defines_for_module = []
205 defines_for_module = defines
207 Extension(module, sources = [c_source_file],
208 define_macros = defines_for_module)
211 print("Compilation failed")
213 setup_args['ext_modules'] = extensions
214 add_command_class("build_ext", build_ext)
219 Extension module compilation failed, looks like Cython cannot run
220 properly on this system. To work around this, pass the option
221 "--no-cython-compile". This will install a pure Python version of
222 Cython without compiling its own sources.
223 ''' % sys.exc_info()[1])
226 cython_profile = '--cython-profile' in sys.argv
228 sys.argv.remove('--cython-profile')
231 sys.argv.remove("--cython-compile-all")
232 cython_compile_more = True
234 cython_compile_more = False
237 sys.argv.remove("--cython-with-refnanny")
238 cython_with_refnanny = True
240 cython_with_refnanny = False
243 sys.argv.remove("--no-cython-compile")
245 compile_cython_modules(cython_profile, cython_compile_more, cython_with_refnanny)
247 setup_args.update(setuptools_extra_args)
249 from Cython import __version__ as version
254 url = 'http://www.cython.org',
255 author = 'Greg Ewing, Robert Bradshaw, Stefan Behnel, Dag Seljebotn, et al.',
256 author_email = 'cython-dev@codespeak.net',
257 description = "The Cython compiler for writing C extensions for the Python language.",
258 long_description = """\
259 The Cython language makes writing C extensions for the Python language as
260 easy as Python itself. Cython is a source code translator based on the
261 well-known Pyrex_, but supports more cutting edge functionality and
264 The Cython language is very close to the Python language (and most Python
265 code is also valid Cython code), but Cython additionally supports calling C
266 functions and declaring C types on variables and class attributes. This
267 allows the compiler to generate very efficient C code from Cython code.
269 This makes Cython the ideal language for writing glue code for external C
270 libraries, and for fast C modules that speed up the execution of Python
273 .. _Pyrex: http://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/
276 "Development Status :: 5 - Production/Stable",
277 "Intended Audience :: Developers",
278 "License :: OSI Approved :: Apache Software License",
279 "Operating System :: OS Independent",
280 "Programming Language :: Python",
281 "Programming Language :: Python :: 2",
282 "Programming Language :: Python :: 3",
283 "Programming Language :: C",
284 "Programming Language :: Cython",
285 "Topic :: Software Development :: Code Generators",
286 "Topic :: Software Development :: Compilers",
287 "Topic :: Software Development :: Libraries :: Python Modules"
300 'Cython.Compiler.Tests',
304 py_modules = ["pyximport/__init__",
305 "pyximport/pyximport",
306 "pyximport/pyxbuild",