99from distutils .version import StrictVersion
1010
1111import pkg_resources
12- from setuptools import setup , Extension , find_packages , Command
12+ import versioneer
13+ from Cython .Build import cythonize
14+ from setuptools import Command , Extension , find_packages , setup
1315from setuptools .dist import Distribution
1416
15- import versioneer
17+ CYTHON_COVERAGE = os .environ .get ('ARCH_CYTHON_COVERAGE' , '0' ) in ('true' , '1' , 'True' )
18+ if CYTHON_COVERAGE :
19+ print ('Building with coverage for cython modules, ARCH_CYTHON_COVERAGE=' +
20+ os .environ ['ARCH_CYTHON_COVERAGE' ])
1621
1722try :
1823 from Cython .Distutils .build_ext import build_ext as _build_ext
19-
24+
2025 CYTHON_INSTALLED = True
2126except ImportError :
2227 CYTHON_INSTALLED = False
23-
24-
28+ if CYTHON_COVERAGE :
29+ raise ImportError ('cython is required for cython coverage. Unset '
30+ 'ARCH_CYTHON_COVERAGE' )
31+
32+
2533 class _build_ext (object ):
2634 pass
2735
@@ -47,7 +55,7 @@ class _build_ext(object):
4755class build_ext (_build_ext ):
4856 def build_extensions (self ):
4957 numpy_incl = pkg_resources .resource_filename ('numpy' , 'core/include' )
50-
58+
5159 for ext in self .extensions :
5260 if (hasattr (ext , 'include_dirs' ) and
5361 numpy_incl not in ext .include_dirs ):
@@ -59,17 +67,12 @@ def build_extensions(self):
5967REQUIREMENTS = {'Cython' : '0.24' ,
6068 'matplotlib' : '1.5' ,
6169 'scipy' : '0.16' ,
62- 'pandas' : '0.16 ' ,
63- 'statsmodels' : '0.6 ' }
70+ 'pandas' : '0.18 ' ,
71+ 'statsmodels' : '0.8 ' }
6472
6573ALL_REQUIREMENTS = SETUP_REQUIREMENTS .copy ()
6674ALL_REQUIREMENTS .update (REQUIREMENTS )
6775
68- ext_modules = []
69- ext_modules .append (Extension ("arch.univariate.recursions" ,
70- ["./arch/univariate/recursions.pyx" ]))
71- ext_modules .append (Extension ("arch.bootstrap._samplers" ,
72- ["./arch/bootstrap/_samplers.pyx" ]))
7376cmdclass ['build_ext' ] = build_ext
7477
7578
@@ -79,44 +82,17 @@ def is_pure(self):
7982
8083
8184class CleanCommand (Command ):
82- """Custom distutils command to clean the .so and .pyc files."""
83-
84- user_options = [("all" , "a" , "" )]
85-
85+ user_options = []
86+
87+ def run (self ):
88+ raise NotImplementedError ('Use git clean -xfd instead' )
89+
8690 def initialize_options (self ):
87- self .all = True
88- self ._clean_files = []
89- self ._clean_trees = []
90- for root , dirs , files in list (os .walk ('arch' )):
91- for f in files :
92- if os .path .splitext (f )[- 1 ] == '.pyx' :
93- search = os .path .join (root , os .path .splitext (f )[0 ] + '.*' )
94- candidates = glob .glob (search )
95- for c in candidates :
96- if os .path .splitext (c )[- 1 ] in ('.pyc' , '.c' , '.so' ,
97- '.pyd' , '.dll' ):
98- self ._clean_files .append (c )
99-
100- for d in ('build' ,):
101- if os .path .exists (d ):
102- self ._clean_trees .append (d )
103-
91+ pass
92+
10493 def finalize_options (self ):
10594 pass
10695
107- def run (self ):
108- for f in self ._clean_files :
109- try :
110- os .unlink (f )
111- except Exception :
112- pass
113- for clean_tree in self ._clean_trees :
114- try :
115- import shutil
116- shutil .rmtree (clean_tree )
117- except Exception :
118- pass
119-
12096
12197cmdclass ['clean' ] = CleanCommand
12298
@@ -141,25 +117,25 @@ def strip_rc(version):
141117 if key == 'numpy' :
142118 try :
143119 import numpy
144-
120+
145121 try :
146122 from numpy .version import short_version as version
147123 except ImportError :
148124 satisfies_req = False
149125 except ImportError :
150126 pass
151-
127+
152128 elif key == 'scipy' :
153129 try :
154130 import scipy
155-
131+
156132 try :
157133 from scipy .version import short_version as version
158134 except ImportError :
159135 satisfies_req = False
160136 except ImportError :
161137 pass
162-
138+
163139 elif key == 'pandas' :
164140 try :
165141 from pandas .version import short_version as version
@@ -169,7 +145,7 @@ def strip_rc(version):
169145 satisfies_req = False
170146 else :
171147 raise NotImplementedError ('Unknown package' )
172-
148+
173149 if version :
174150 existing_version = StrictVersion (strip_rc (version ))
175151 satisfies_req = existing_version >= ALL_REQUIREMENTS [key ]
@@ -191,7 +167,7 @@ def strip_rc(version):
191167 long_description = open (os .path .join (cwd , "README.rst" )).read ()
192168except IOError as e :
193169 import warnings
194-
170+
195171 warnings .warn ('Unable to convert README.md. Most likely because pandoc '
196172 'is not installed' )
197173
@@ -205,66 +181,82 @@ def strip_rc(version):
205181try :
206182 import nbformat as nbformat
207183 from nbconvert import RSTExporter
208-
184+
209185 notebooks = glob .glob (os .path .join (cwd , 'examples' , '*.ipynb' ))
210186 for notebook in notebooks :
211187 try :
212188 with open (notebook , 'rt' ) as f :
213189 example_nb = f .read ()
214-
190+
215191 rst_path = os .path .join (cwd , 'doc' , 'source' )
216192 path_parts = os .path .split (notebook )
217193 nb_filename = path_parts [- 1 ]
218194 nb_filename = nb_filename .split ('.' )[0 ]
219195 source_dir = nb_filename .split ('_' )[0 ]
220196 rst_filename = os .path .join (cwd , 'doc' , 'source' ,
221197 source_dir , nb_filename + '.rst' )
222-
198+
223199 example_nb = nbformat .reader .reads (example_nb )
224200 rst_export = RSTExporter ()
225201 (body , resources ) = rst_export .from_notebook_node (example_nb )
226202 with open (rst_filename , 'wt' ) as rst :
227203 rst .write (body )
228-
204+
229205 for key in resources ['outputs' ].keys ():
230206 if key .endswith ('.png' ):
231207 resource_filename = os .path .join (cwd , 'doc' , 'source' ,
232208 source_dir , key )
233209 with open (resource_filename , 'wb' ) as resource :
234210 resource .write (resources ['outputs' ][key ])
235-
211+
236212 except :
237213 import warnings
238-
214+
239215 warnings .warn ('Unable to convert {original} to {target}. This '
240216 'only affects documentation generation and not the '
241217 'operation of the '
242218 'module.' .format (original = notebook ,
243219 target = rst_filename ))
244220 print ('The last error was:' )
245221 import sys
246-
222+
247223 print (sys .exc_info ()[0 ])
248224 print (sys .exc_info ()[1 ])
249225
250226except :
251227 import warnings
252-
228+
253229 warnings .warn ('Unable to import required modules from the jupyter project.'
254230 ' This only affects documentation generation and not the '
255231 'operation of the module.' )
256232 print ('The last error was:' )
257233 import sys
258-
234+
259235 print (sys .exc_info ()[0 ])
260236 print (sys .exc_info ()[1 ])
261237
262238
263239def run_setup (binary = True ):
264- extensions = ext_modules if binary else []
265240 if not binary :
266241 del REQUIREMENTS ['Cython' ]
267-
242+ extensions = []
243+ else :
244+ directives = {'linetrace' : CYTHON_COVERAGE }
245+ macros = []
246+ if CYTHON_COVERAGE :
247+ macros .append (('CYTHON_TRACE' , '1' ))
248+
249+ ext_modules = []
250+ ext_modules .append (Extension ("arch.univariate.recursions" ,
251+ ["./arch/univariate/recursions.pyx" ],
252+ define_macros = macros ))
253+ ext_modules .append (Extension ("arch.bootstrap._samplers" ,
254+ ["./arch/bootstrap/_samplers.pyx" ],
255+ define_macros = macros ))
256+ extensions = cythonize (ext_modules ,
257+ force = CYTHON_COVERAGE ,
258+ compiler_directives = directives )
259+
268260 setup (name = 'arch' ,
269261 license = 'NCSA' ,
270262 version = versioneer .get_version (),
@@ -310,10 +302,10 @@ def run_setup(binary=True):
310302 build_binary = '--no-binary' not in sys .argv and CYTHON_INSTALLED
311303 if '--no-binary' in sys .argv :
312304 sys .argv .remove ('--no-binary' )
313-
305+
314306 run_setup (binary = build_binary )
315307except (CCompilerError , DistutilsExecError , DistutilsPlatformError , IOError , ValueError ):
316308 run_setup (binary = False )
317309 import warnings
318-
310+
319311 warnings .warn (FAILED_COMPILER_ERROR , UserWarning )
0 commit comments