Newer
Older
Wes McKinney
committed
"""
Parts of this file were taken from the pyzmq project
(https://github.com/zeromq/pyzmq) and hence are subject to the terms of the
Lesser GPU General Public License.
"""
Wes McKinney
committed
from glob import glob
import os
import sys
import shutil
import numpy as np
from numpy.distutils.misc_util import Configuration
Wes McKinney
committed
from distutils.core import Command
from distutils.extension import Extension
from distutils.command.build import build
from distutils.command.build_ext import build_ext
from distutils.command.sdist import sdist
from os.path import splitext, basename, join as pjoin
DESCRIPTION = "Cross-section and time series data analysis toolkit"
LONG_DESCRIPTION = """
pandas provides NumPy-based data structures and statistical tools for
common time series and cross-sectional data sets. It is intended to
accomplish the following:
* Simplify working with possibly labeled 1, 2, and 3 dimensional
heterogeneous data sets commonly found in statistics, finance, and
econometrics.
* Provide tools for working with dates, fixed-frequency custom date
ranges, and other necessary time series functionality
* Provide IO utilities for getting data in and out of pandas
* Implement common statistical and time series functionality with a
convenient interface, handling missing data and other common
problems associated with messy statistical data sets
Windows binaries built against NumPy 1.5.1
Wes McKinney
committed
URL = "http://github.com/wesm/pandas"
'Environment :: Console',
'Operating System :: OS Independent',
'Intended Audience :: Science/Research',
'Programming Language :: Python',
'Programming Language :: Cython',
'Topic :: Scientific/Engineering',
]
MAJOR = 0
MINOR = 4
ISRELEASED = False
VERSION = '%d.%d.%d' % (MAJOR, MINOR, MICRO)
FULLVERSION = VERSION
if not ISRELEASED:
Wes McKinney
committed
FULLVERSION += '.dev' + datetime.today().strftime('%Y%m%d')
def write_version_py(filename='pandas/version.py'):
cnt = """\
"""
a = open(filename, 'w')
try:
Wes McKinney
committed
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
class CleanCommand(Command):
"""Custom distutils command to clean the .so and .pyc files."""
user_options = [ ]
def initialize_options(self):
self._clean_me = []
self._clean_trees = []
for root, dirs, files in list(os.walk('pandas')):
for f in files:
if os.path.splitext(f)[-1] in ('.pyc', '.so', '.o', '.pyd'):
self._clean_me.append(pjoin(root, f))
for d in dirs:
if d == '__pycache__':
self._clean_trees.append(pjoin(root, d))
for d in ('build',):
if os.path.exists(d):
self._clean_trees.append(d)
def finalize_options(self):
pass
def run(self):
for clean_me in self._clean_me:
try:
os.unlink(clean_me)
except Exception:
pass
for clean_tree in self._clean_trees:
try:
shutil.rmtree(clean_tree)
except Exception:
pass
class CheckSDist(sdist):
"""Custom sdist that ensures Cython has compiled all pyx files to c."""
_pyxfiles = ['pandas/src/tseries.pyx'
'pandas/src/sparse.pyx']
def initialize_options(self):
sdist.initialize_options(self)
'''
self._pyxfiles = []
for root, dirs, files in os.walk('pandas'):
for f in files:
if f.endswith('.pyx'):
self._pyxfiles.append(pjoin(root, f))
'''
def run(self):
if 'cython' in cmdclass:
self.run_command('cython')
else:
for pyxfile in self._pyxfiles:
cfile = pyxfile[:-3]+'c'
msg = "C-source file '%s' not found."%(cfile)+\
" Run 'setup.py cython' before sdist."
assert os.path.isfile(cfile), msg
sdist.run(self)
class CheckingBuildExt(build_ext):
"""Subclass build_ext to get clearer report if Cython is neccessary."""
def check_cython_extensions(self, extensions):
for ext in extensions:
for src in ext.sources:
if not os.path.exists(src):
fatal("""Cython-generated file '%s' not found.
Cython is required to compile pandas from a development branch.
Please install Cython or download a release package of pandas.
"""%src)
def build_extensions(self):
self.check_cython_extensions(self.extensions)
self.check_extensions_list(self.extensions)
for ext in self.extensions:
self.build_extension(ext)
cmdclass = {'clean': CleanCommand,
'build': build}
try:
from Cython.Distutils import build_ext
cython=True
except ImportError:
cython=False
suffix = '.c'
cmdclass['build_ext'] = CheckingBuildExt
else:
suffix = '.pyx'
class CythonCommand(build_ext):
"""Custom distutils command subclassed from Cython.Distutils.build_ext
to compile pyx->c, and stop there. All this does is override the
C-compile method build_extension() with a no-op."""
def build_extension(self, ext):
pass
cmdclass['cython'] = CythonCommand
cmdclass['build_ext'] = build_ext
cmdclass['sdist'] = CheckSDist
tseries_depends = ['reindex', 'io', 'common', 'groupby'
'skiplist', 'isnull', 'moments', 'operators']
def srcpath(name=None, suffix='.pyx', subdir='src'):
return pjoin('pandas', subdir, name+suffix)
tseries_ext = Extension('pandas._tseries',
sources=[srcpath('tseries', suffix=suffix)],
# depends=[srcpath(f, suffix='.pyx')
# for f in tseries_depends],
include_dirs=[np.get_include()])
sparse_ext = Extension('pandas._sparse',
sources=[srcpath('sparse', suffix=suffix)],
include_dirs=[np.get_include()])
extensions = [tseries_ext,
sparse_ext]
setup(name=DISTNAME,
version=FULLVERSION,
maintainer=MAINTAINER,
packages=['pandas',
'pandas.core',
'pandas.io',
'pandas.stats',
'pandas.util'],
package_data={'pandas' : ['tests/*.py'],
'pandas.io' : ['tests/*.py',
'tests/*.h5'],
'pandas.stats' : ['tests/*.py']},
ext_modules=extensions,
maintainer_email=MAINTAINER_EMAIL,
description=DESCRIPTION,
license=LICENSE,
cmdclass = cmdclass,
url=URL,
download_url=DOWNLOAD_URL,
long_description=LONG_DESCRIPTION,
classifiers=CLASSIFIERS,
platforms='any',
)