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):
88 source_root = os.path.abspath(os.path.dirname(__file__))
89 compiled_modules = ["Cython.Plex.Scanners",
90 "Cython.Compiler.Scanning",
91 "Cython.Compiler.Parsing",
92 "Cython.Compiler.Visitor",
93 "Cython.Runtime.refnanny"]
96 if sys.version_info[0] >= 3:
97 from Cython.Distutils import build_ext as build_ext_orig
98 for module in compiled_modules:
99 source_file = os.path.join(source_root, *module.split('.'))
100 if os.path.exists(source_file + ".py"):
101 pyx_source_file = source_file + ".py"
103 pyx_source_file = source_file + ".pyx"
105 Extension(module, sources = [pyx_source_file])
108 class build_ext(build_ext_orig):
109 # we must keep the original modules alive to make sure
110 # their code keeps working when we remove them from
114 def build_extensions(self):
115 # add path where 2to3 installed the transformed sources
116 # and make sure Python (re-)imports them from there
117 already_imported = [ module for module in sys.modules
118 if module == 'Cython' or module.startswith('Cython.') ]
119 keep_alive = self.dead_modules.append
120 for module in already_imported:
121 keep_alive(sys.modules[module])
122 del sys.modules[module]
123 sys.path.insert(0, os.path.join(source_root, self.build_lib))
126 from Cython.Compiler.Options import directive_defaults
127 directive_defaults['profile'] = True
128 print("Enabled profiling for the Cython binary modules")
129 build_ext_orig.build_extensions(self)
131 setup_args['ext_modules'] = extensions
132 add_command_class("build_ext", build_ext)
135 from distutils.command.build_ext import build_ext as build_ext_orig
137 class build_ext(build_ext_orig):
138 def build_extension(self, ext, *args, **kargs):
140 build_ext_orig.build_extension(self, ext, *args, **kargs)
141 except StandardError:
142 print("Compilation of '%s' failed" % ext.sources[0])
143 from Cython.Compiler.Main import compile
144 from Cython import Utils
146 from Cython.Compiler.Options import directive_defaults
147 directive_defaults['profile'] = True
148 print("Enabled profiling for the Cython binary modules")
149 source_root = os.path.dirname(__file__)
150 for module in compiled_modules:
151 source_file = os.path.join(source_root, *module.split('.'))
152 if os.path.exists(source_file + ".py"):
153 pyx_source_file = source_file + ".py"
155 pyx_source_file = source_file + ".pyx"
156 c_source_file = source_file + ".c"
157 if not os.path.exists(c_source_file) or \
158 Utils.file_newer_than(pyx_source_file,
159 Utils.modification_time(c_source_file)):
160 print("Compiling module %s ..." % module)
161 result = compile(pyx_source_file)
162 c_source_file = result.c_file
164 # Py2 distutils can't handle unicode file paths
165 if isinstance(c_source_file, unicode):
166 filename_encoding = sys.getfilesystemencoding()
167 if filename_encoding is None:
168 filename_encoding = sys.getdefaultencoding()
169 c_source_file = c_source_file.encode(filename_encoding)
171 Extension(module, sources = [c_source_file])
174 print("Compilation failed")
176 setup_args['ext_modules'] = extensions
177 add_command_class("build_ext", build_ext)
182 Extension module compilation failed, looks like Cython cannot run
183 properly on this system. To work around this, pass the option
184 "--no-cython-compile". This will install a pure Python version of
185 Cython without compiling its own sources.
186 ''' % sys.exc_info()[1])
189 cython_profile = '--cython-profile' in sys.argv
191 sys.argv.remove('--cython-profile')
194 sys.argv.remove("--no-cython-compile")
196 compile_cython_modules(cython_profile)
198 setup_args.update(setuptools_extra_args)
200 from Cython import __version__ as version
205 url = 'http://www.cython.org',
206 author = 'Greg Ewing, Robert Bradshaw, Stefan Behnel, Dag Seljebotn, et al.',
207 author_email = 'cython-dev@codespeak.net',
208 description = "The Cython compiler for writing C extensions for the Python language.",
209 long_description = """\
210 The Cython language makes writing C extensions for the Python language as
211 easy as Python itself. Cython is a source code translator based on the
212 well-known Pyrex_, but supports more cutting edge functionality and
215 The Cython language is very close to the Python language (and most Python
216 code is also valid Cython code), but Cython additionally supports calling C
217 functions and declaring C types on variables and class attributes. This
218 allows the compiler to generate very efficient C code from Cython code.
220 This makes Cython the ideal language for writing glue code for external C
221 libraries, and for fast C modules that speed up the execution of Python
224 .. _Pyrex: http://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/
227 "Development Status :: 5 - Production/Stable",
228 "Intended Audience :: Developers",
229 "License :: OSI Approved :: Apache Software License",
230 "Operating System :: OS Independent",
231 "Programming Language :: Python",
232 "Programming Language :: Python :: 2",
233 "Programming Language :: Python :: 3",
234 "Programming Language :: C",
235 "Programming Language :: Cython",
236 "Topic :: Software Development :: Code Generators",
237 "Topic :: Software Development :: Compilers",
238 "Topic :: Software Development :: Libraries :: Python Modules"
250 'Cython.Compiler.Tests',
254 py_modules = ["pyximport/__init__",
255 "pyximport/pyximport",
256 "pyximport/pyxbuild",