2
#----------------------------------------------------------------------
3
# Setup script for the tables package
8
from os.path import exists, expanduser
13
# Using ``setuptools`` enables lots of goodies, such as building eggs.
14
if 'FORCE_SETUPTOOLS' in os.environ:
15
from setuptools import setup, find_packages
18
from distutils.core import setup
19
has_setuptools = False
21
from distutils.core import Extension
22
from distutils.dep_util import newer
23
from distutils.util import convert_path
25
# The minimum required versions
26
# (keep these in sync with tables.req_versions and user's guide and README)
27
min_numpy_version = '1.4.1'
28
min_numexpr_version = '1.4.1'
29
min_cython_version = '0.13'
31
# Some functions for showing errors and warnings.
32
def _print_admonition(kind, head, body):
33
tw = textwrap.TextWrapper(
34
initial_indent=' ', subsequent_indent=' ')
36
print ".. %s:: %s" % (kind.upper(), head)
37
for line in tw.wrap(body):
40
def exit_with_error(head, body=''):
41
_print_admonition('error', head, body)
44
def print_warning(head, body=''):
45
_print_admonition('warning', head, body)
48
if not (sys.version_info[0] >= 2 and sys.version_info[1] >= 4):
49
exit_with_error("You need Python 2.4 or greater to install PyTables!")
51
# Check for required Python packages
52
def check_import(pkgname, pkgver):
54
mod = __import__(pkgname)
57
"You need %(pkgname)s %(pkgver)s or greater to run PyTables!"
58
% {'pkgname': pkgname, 'pkgver': pkgver} )
60
if mod.__version__ < pkgver:
62
"You need %(pkgname)s %(pkgver)s or greater to run PyTables!"
63
% {'pkgname': pkgname, 'pkgver': pkgver} )
65
print ( "* Found %(pkgname)s %(pkgver)s package installed."
66
% {'pkgname': pkgname, 'pkgver': mod.__version__} )
67
globals()[pkgname] = mod
69
check_import('numpy', min_numpy_version)
70
# Check for numexpr only if not using setuptools (see #298)
71
if not has_setuptools:
72
check_import('numexpr', min_numexpr_version)
74
# Check if Cython is installed or not (requisite)
76
from Cython.Distutils import build_ext
77
from Cython.Compiler.Main import Version
78
cmdclass = {'build_ext': build_ext}
81
"You need %(pkgname)s %(pkgver)s or greater to compile PyTables!"
82
% {'pkgname': 'Cython', 'pkgver': min_cython_version} )
84
if Version.version < min_cython_version:
86
"At least Cython %s is needed so as to generate extensions!"
87
% (min_cython_version) )
89
print ( "* Found %(pkgname)s %(pkgver)s package installed."
90
% {'pkgname': 'Cython', 'pkgver': Version.version} )
92
VERSION = open('VERSION').read().strip()
94
#----------------------------------------------------------------------
96
debug = '--debug' in sys.argv
102
data_files = [] # list of data files to add to packages (mainly for DLL's)
104
default_header_dirs = None
105
default_library_dirs = None
106
default_runtime_dirs = None
108
def add_from_path(envname, dirs):
110
dirs.extend(os.environ[envname].split(os.pathsep))
114
def add_from_flags(envname, flag_key, dirs):
115
for flag in os.environ.get(envname, "").split():
116
if flag.startswith(flag_key):
117
dirs.append(flag[len(flag_key):])
119
if os.name == 'posix':
120
default_header_dirs = []
121
add_from_path("CPATH", default_header_dirs)
122
add_from_path("C_INCLUDE_PATH", default_header_dirs)
123
add_from_flags("CPPFLAGS", "-I", default_header_dirs)
124
default_header_dirs.extend(['/usr/include', '/usr/local/include'])
126
default_library_dirs = []
127
add_from_flags("LDFLAGS", "-L", default_library_dirs)
128
default_library_dirs.extend(
129
os.path.join(_tree, _arch)
130
for _tree in ('/', '/usr', '/usr/local')
131
for _arch in ('lib64', 'lib') )
132
default_runtime_dirs = default_library_dirs
134
elif os.name == 'nt':
135
default_header_dirs = [] # no default, must be given explicitly
136
default_library_dirs = [] # no default, must be given explicitly
137
default_runtime_dirs = [ # look for DLL files in ``%PATH%``
138
_path for _path in os.environ['PATH'].split(';') ]
139
# Add the \Windows\system to the runtime list (necessary for Vista)
140
default_runtime_dirs.append('\\windows\\system')
141
# Add the \path_to_python\DLLs and tables package to the list
142
default_runtime_dirs.extend(
143
[ os.path.join(sys.prefix, 'Lib\\site-packages\\tables') ] )
145
from numpy.distutils.misc_util import get_numpy_include_dirs
146
inc_dirs.extend(get_numpy_include_dirs())
148
# Gcc 4.0.1 on Mac OS X 10.4 does not seem to include the default
149
# header and library paths. See ticket #18.
150
if sys.platform.lower().startswith('darwin'):
151
inc_dirs.extend(default_header_dirs)
152
lib_dirs.extend(default_library_dirs)
154
def _find_file_path(name, locations, prefixes=[''], suffixes=['']):
155
for prefix in prefixes:
156
for suffix in suffixes:
157
for location in locations:
158
path = os.path.join(location, prefix + name + suffix)
159
if os.path.isfile(path):
164
class Package(object):
165
def find_header_path(self, locations=default_header_dirs):
166
return _find_file_path(
167
self.header_name, locations, suffixes=['.h'] )
169
def find_library_path(self, locations=default_library_dirs):
170
return _find_file_path(
171
self.library_name, locations,
172
self._library_prefixes, self._library_suffixes )
174
def find_runtime_path(self, locations=default_runtime_dirs):
176
returns True if the runtime can be found
177
returns None otherwise
179
# An explicit path can not be provided for runtime libraries.
180
# (The argument is accepted for compatibility with previous methods.)
182
# dlopen() won't tell us where the file is, just whether
183
# success occurred, so this returns True instead of a filename
184
for prefix in self._runtime_prefixes:
185
for suffix in self._runtime_suffixes:
187
ctypes.CDLL(prefix + self.runtime_name + suffix)
192
def find_directories(self, location):
194
(self.header_name, self.find_header_path, default_header_dirs),
195
(self.library_name, self.find_library_path, default_library_dirs),
196
(self.runtime_name, self.find_runtime_path, default_runtime_dirs), ]
200
# The path of a custom install of the package has been
201
# provided, so the directories where the components
202
# (headers, libraries, runtime) are going to be searched
203
# are constructed by appending platform-dependent
204
# component directories to the given path.
205
# Remove leading and trailing '"' chars that can mislead
206
# the finding routines on Windows machines
207
locations = [ os.path.join(location.strip('"'), compdir)
208
for compdir in self._component_dirs ]
210
directories = [None, None, None] # headers, libraries, runtime
211
for idx, (name, find_path, default_dirs) in enumerate(dirdata):
212
path = find_path(locations or default_dirs)
215
directories[idx] = True
218
# Take care of not returning a directory component
219
# included in the name. For instance, if name is
220
# 'foo/bar' and path is '/path/foo/bar.h', do *not*
221
# take '/path/foo', but just '/path'. This also works
222
# for name 'libfoo.so' and path '/path/libfoo.so'.
223
# This has been modified to just work over include files.
224
# For libraries, its names can be something like 'bzip2'
225
# and if they are located in places like:
226
# \stuff\bzip2-1.0.3\lib\bzip2.lib
227
# then, the directory will be returned as '\stuff' (!!)
228
# F. Alted 2006-02-16
230
directories[idx] = os.path.dirname(path[:path.rfind(name)])
232
directories[idx] = os.path.dirname(path)
234
return tuple(directories)
236
class PosixPackage(Package):
237
_library_prefixes = ['lib']
238
_library_suffixes = ['.so', '.dylib', '.a']
239
_runtime_prefixes = _library_prefixes
240
_runtime_suffixes = ['.so', '.dylib']
242
_component_dirs = ['include', 'lib']
244
def __init__(self, name, tag, header_name, library_name):
247
self.header_name = header_name
248
self.library_name = library_name
249
self.runtime_name = library_name
251
class WindowsPackage(Package):
252
_library_prefixes = ['']
253
_library_suffixes = ['.lib']
254
_runtime_prefixes = ['']
255
_runtime_suffixes = ['.dll']
257
# lookup in '.' seems necessary for LZO2
258
_component_dirs = ['include', 'lib', 'dll', '.']
260
def __init__(self, name, tag, header_name, library_name, runtime_name):
263
self.header_name = header_name
264
self.library_name = library_name
265
self.runtime_name = runtime_name
267
def find_runtime_path(self, locations=default_runtime_dirs):
268
# An explicit path can not be provided for runtime libraries.
269
# (The argument is accepted for compatibility with previous methods.)
270
return _find_file_path(
271
self.runtime_name, default_runtime_dirs,
272
self._runtime_prefixes, self._runtime_suffixes )
274
# Get the HDF5 version provided the 'H5public.h' header
275
def get_hdf5_version(headername):
279
for line in open(headername):
280
if 'H5_VERS_MAJOR' in line:
281
major_version = int(re.split("\s*", line)[2])
282
if 'H5_VERS_MINOR' in line:
283
minor_version = int(re.split("\s*", line)[2])
284
if 'H5_VERS_RELEASE' in line:
285
release_version = int(re.split("\s*", line)[2])
286
if (major_version != -1 and
287
minor_version != -1 and
288
release_version != -1):
290
if (major_version == -1 or
291
minor_version == -1 or
292
release_version == -1):
293
exit_with_error("Unable to detect HDF5 library version!")
294
return (major_version, minor_version, release_version)
298
if os.name == 'posix':
299
_Package = PosixPackage
300
_platdep = { # package tag -> platform-dependent components
306
elif os.name == 'nt':
307
_Package = WindowsPackage
308
_platdep = { # package tag -> platform-dependent components
309
'HDF5': ['hdf5dll', 'hdf5dll'],
310
'LZO2': ['lzo2', 'lzo2'],
311
'LZO': ['liblzo', 'lzo1'],
312
'BZ2': ['bzip2', 'bzip2'],
314
# Copy the next DLL's to binaries by default.
315
# Update these paths for your own system!
316
dll_files = ['\\windows\\system\\zlib1.dll',
317
'\\windows\\system\\szip.dll',
319
if '--debug' in sys.argv:
320
_platdep['HDF5'] = ['hdf5ddll', 'hdf5ddll']
322
hdf5_package = _Package("HDF5", 'HDF5', 'H5public', *_platdep['HDF5'])
323
lzo2_package = _Package("LZO 2", 'LZO2', _cp('lzo/lzo1x'), *_platdep['LZO2'])
324
lzo1_package = _Package("LZO 1", 'LZO', 'lzo1x', *_platdep['LZO'])
325
bzip2_package = _Package("bzip2", 'BZ2', 'bzlib', *_platdep['BZ2'])
328
#-----------------------------------------------------------------
330
def_macros = [('NDEBUG', 1)]
331
# Define macros for Windows platform
333
def_macros.append(('WIN32', 1))
334
def_macros.append(('_HDF5USEDLL_', 1))
336
# Allow setting the HDF5 dir and additional link flags either in
337
# the environment or on the command line.
338
# First check the environment...
339
HDF5_DIR = os.environ.get('HDF5_DIR', '')
340
LZO_DIR = os.environ.get('LZO_DIR', '')
341
BZIP2_DIR = os.environ.get('BZIP2_DIR', '')
342
LFLAGS = os.environ.get('LFLAGS', '').split()
343
# in GCC-style compilers, -w in extra flags will get rid of copious
344
# 'uninitialized variable' Cython warnings. However, this shouldn't be
345
# the default as it will suppress *all* the warnings, which definitely
346
# is not a good idea.
347
CFLAGS = os.environ.get('CFLAGS', '').split()
348
LIBS = os.environ.get('LIBS', '').split()
350
# ...then the command line.
351
# Handle --hdf5=[PATH] --lzo=[PATH] --bzip2=[PATH]
352
# --lflags=[FLAGS] --cflags=[FLAGS] and --debug
355
if arg.find('--hdf5=') == 0:
356
HDF5_DIR = expanduser(arg.split('=')[1])
358
elif arg.find('--lzo=') == 0:
359
LZO_DIR = expanduser(arg.split('=')[1])
361
elif arg.find('--bzip2=') == 0:
362
BZIP2_DIR = expanduser(arg.split('=')[1])
364
elif arg.find('--lflags=') == 0:
365
LFLAGS = arg.split('=')[1].split()
367
elif arg.find('--cflags=') == 0:
368
CFLAGS = arg.split('=')[1].split()
370
elif arg.find('--debug') == 0:
371
# For debugging (mainly compression filters)
372
if os.name != 'nt': # to prevent including dlfcn.h by utils.c!!!
373
def_macros = [('DEBUG', 1)]
374
# Don't delete this argument. It maybe useful for distutils
375
# when adding more flags later on
376
#sys.argv.remove(arg)
378
# The next flag for the C compiler is needed for finding the C headers for
379
# the Cython extensions
380
CFLAGS.append("-Isrc")
381
# The next flag for the C compiler is needed when using the HDF5 1.8.x series
382
CFLAGS.append("-DH5_USE_16_API")
384
# Try to locate the compulsory and optional libraries.
386
for (package, location) in [
387
(hdf5_package, HDF5_DIR),
388
(lzo2_package, LZO_DIR),
389
(lzo1_package, LZO_DIR),
390
(bzip2_package, BZIP2_DIR),
393
if package.tag == 'LZO' and lzo2_enabled:
394
print ( "* Skipping detection of %s since %s has already been found."
395
% (lzo1_package.name, lzo2_package.name) )
396
continue # do not use LZO 1 if LZO 2 is available
398
(hdrdir, libdir, rundir) = package.find_directories(location)
400
if not (hdrdir and libdir):
401
if package.tag in ['HDF5']: # these are compulsory!
402
pname, ptag = package.name, package.tag
404
"Could not find a local %s installation." % pname,
405
"You may need to explicitly state "
406
"where your local %(name)s headers and library can be found "
407
"by setting the ``%(tag)s_DIR`` environment variable "
408
"or by using the ``--%(ltag)s`` command-line option."
409
% dict(name=pname, tag=ptag, ltag=ptag.lower()) )
410
print ( "* Could not find %s headers and library; "
411
"disabling support for it." % package.name)
412
continue # look for the next library
414
print ( "* Found %s headers at ``%s``, library at ``%s``."
415
% (package.name, hdrdir, libdir) )
417
if package.tag in ['HDF5']:
418
hdf5_header = os.path.join(hdrdir, "H5public.h")
419
hdf5_version = get_hdf5_version(hdf5_header)
420
if hdf5_version < (1, 8, 0):
421
warnings.warn("Support for HDF5 v1.6.x will be removed in future "
424
if hdrdir not in default_header_dirs:
425
inc_dirs.append(hdrdir) # save header directory if needed
426
if libdir not in default_library_dirs:
427
# save library directory if needed
429
# Important to quote the libdir for Windows (Vista) systems
430
lib_dirs.append('"'+libdir+'"')
432
lib_dirs.append(libdir)
434
if package.tag not in ['HDF5']:
435
# Keep record of the optional libraries found.
436
optional_libs.append(package.tag)
437
def_macros.append(('HAVE_%s_LIB' % package.tag, 1))
441
"Could not find the %s runtime." % package.name,
442
( "The %(name)s shared library was *not* found "
443
+ { 'posix': "in the default library paths.",
444
'nt': "in any of the directories in %%PATH%%.", }[os.name]
445
+ " In case of runtime problems, please remember to install it." )
446
% dict(name=package.name) )
449
# LZO DLLs cannot be copied to the binary package for license reasons
450
if package.tag not in ['LZO', 'LZO2']:
451
dll_file = _platdep[package.tag][1] + '.dll'
452
# If DLL is not in rundir, do nothing. This can be useful
453
# for BZIP2, that can be linked either statically (.LIB)
454
# or dinamically (.DLL)
455
if rundir is not None:
456
dll_files.append(os.path.join(rundir, dll_file))
458
if package.tag == 'LZO2':
462
lzo_package = lzo2_package
464
lzo_package = lzo1_package
466
#------------------------------------------------------------------------------
479
def get_cython_extfiles(extnames):
483
for extname in extnames:
484
extfile = os.path.join(extdir, extname)
485
extpfile = '%s.pyx' % extfile
486
extcfile = '%s.c' % extfile
488
# Copy extensions that depends on the HDF5 version
489
hdf5_maj_version, hdf5_min_version = hdf5_version[:2]
490
hdf5_majmin = "%d%d" % (hdf5_maj_version, hdf5_min_version)
491
if not hdf5_majmin in ("16", "18"):
492
exit_with_error("Unsupported HDF5 version!")
493
specific_ext = os.path.join(extdir, extname + hdf5_majmin + ".pyx")
494
if exists(specific_ext):
495
shutil.copy(specific_ext, extpfile)
497
if not exists(extcfile) or newer(extpfile, extcfile):
498
# For some reason, setup in setuptools does not compile
499
# Cython files (!) Do that manually...
500
print "cythoning %s to %s" % (extpfile, extcfile)
501
retcode = subprocess.call([sys.executable, "-m", "cython", extpfile])
503
print "cython aborted compilation with retcode:", retcode
505
extfiles[extname] = extcfile
510
cython_extfiles = get_cython_extfiles(cython_extnames)
512
# Update the version.h file if this file is newer
513
if newer('VERSION', 'src/version.h'):
514
open('src/version.h', 'w').write(
515
'#define PYTABLES_VERSION "%s"\n' % VERSION)
517
#--------------------------------------------------------------------
519
# Package information for ``setuptools``.
520
setuptools_kwargs = {}
522
# PyTables contains data files for tests.
523
setuptools_kwargs['zip_safe'] = False
525
# ``NumPy`` headers are needed for building the extensions, as
527
setuptools_kwargs['setup_requires'] = [
528
'numpy>=%s' % min_numpy_version,
529
'cython>=%s' % min_cython_version,
531
# ``NumPy`` and ``Numexpr`` are absolutely required for running PyTables.
532
setuptools_kwargs['install_requires'] = [
533
'numpy>=%s' % min_numpy_version,
534
'numexpr>=%s' % min_numexpr_version,
536
setuptools_kwargs['extras_require'] = {
537
'Numeric': ['Numeric>=24.2'], # for ``Numeric`` support
538
'netCDF': ['ScientificPython'], # for netCDF interchange
539
'numarray': ['numarray>=1.5.2'], # for ``numarray`` support
542
# Detect packages automatically.
543
setuptools_kwargs['packages'] = find_packages(exclude=['*.bench'])
544
# Entry points for automatic creation of scripts.
545
setuptools_kwargs['entry_points'] = {
547
'ptdump = tables.scripts.ptdump:main',
548
'ptrepack = tables.scripts.ptrepack:main',
549
'nctoh5 = tables.netcdf3.scripts.nctoh5:main [netCDF]',
553
setuptools_kwargs['test_suite'] = 'tables.tests.test_all.suite'
554
setuptools_kwargs['scripts'] = []
556
# The next should work with stock distutils, but it does not!
557
# It is better to rely on check_import
558
# setuptools_kwargs['requires'] = ['numpy (>= %s)' % min_numpy_version,
559
# 'numexpr (>= %s)' % min_numexpr_version]
560
# There is no other chance, these values must be hardwired.
561
setuptools_kwargs['packages'] = [
562
'tables', 'tables.nodes', 'tables.scripts',
563
'tables.nra', 'tables.netcdf3', 'tables.netcdf3.scripts',
566
'tables.tests', 'tables.nodes.tests',
567
'tables.netcdf3.tests', 'tables.nra.tests']
568
setuptools_kwargs['scripts'] = [
569
'utils/ptdump', 'utils/ptrepack', 'utils/nctoh5']
570
# Copy additional data for packages that need it.
571
setuptools_kwargs['package_data'] = {
572
'tables.tests': ['*.h5'],
573
'tables.nodes.tests': ['*.dat', '*.xbm', '*.h5']}
576
#Having the Python version included in the package name makes managing a
577
#system with multiple versions of Python much easier.
579
def find_name(base='tables'):
580
'''If "--name-with-python-version" is on the command line then
581
append "-pyX.Y" to the base name'''
583
if '--name-with-python-version' in sys.argv:
584
name += '-py%i.%i'%(sys.version_info[0],sys.version_info[1])
585
sys.argv.remove('--name-with-python-version')
592
# Add DLL's to the final package for windows
593
data_files.extend([('Lib/site-packages/%s'%name, dll_files),
596
ADDLIBS = [hdf5_package.library_name, ]
597
utilsExtension_libs = LIBS + ADDLIBS
598
hdf5Extension_libs = LIBS + ADDLIBS
599
tableExtension_libs = LIBS + ADDLIBS
600
linkExtension_libs = LIBS + ADDLIBS
601
indexesExtension_libs = LIBS + ADDLIBS
602
lrucacheExtension_libs = [] # Doesn't need external libraries
604
# Compressor modules only need other libraries if they are enabled.
605
_comp_lzo_libs = LIBS[:]
606
_comp_bzip2_libs = LIBS[:]
607
for (package, complibs) in [
608
(lzo_package, _comp_lzo_libs),
609
(bzip2_package, _comp_bzip2_libs), ]:
611
if package.tag in optional_libs:
612
complibs.extend([hdf5_package.library_name, package.library_name])
614
# List of Blosc file dependencies
615
blosc_files = ["blosc/blosc.c", "blosc/blosclz.c", "blosc/shuffle.c",
616
"blosc/blosc_filter.c"]
619
Extension( "tables.utilsExtension",
620
include_dirs=inc_dirs,
621
define_macros=def_macros,
622
sources=[ cython_extfiles['utilsExtension'],
627
library_dirs=lib_dirs,
628
libraries=utilsExtension_libs,
629
extra_link_args=LFLAGS,
630
extra_compile_args=CFLAGS ),
632
Extension( "tables.hdf5Extension",
633
include_dirs=inc_dirs,
634
define_macros=def_macros,
635
sources=[ cython_extfiles['hdf5Extension'],
643
library_dirs=lib_dirs,
644
libraries=hdf5Extension_libs,
645
extra_link_args=LFLAGS,
646
extra_compile_args=CFLAGS ),
648
Extension( "tables.tableExtension",
649
include_dirs=inc_dirs,
650
define_macros=def_macros,
651
sources=[ cython_extfiles['tableExtension'],
657
library_dirs=lib_dirs,
658
libraries=tableExtension_libs,
659
extra_link_args=LFLAGS,
660
extra_compile_args=CFLAGS ),
662
Extension( "tables._comp_lzo",
663
include_dirs=inc_dirs,
664
define_macros=def_macros,
665
sources=[ cython_extfiles['_comp_lzo'],
667
library_dirs=lib_dirs,
668
libraries=_comp_lzo_libs,
669
extra_link_args=LFLAGS,
670
extra_compile_args=CFLAGS ),
672
Extension( "tables._comp_bzip2",
673
include_dirs=inc_dirs,
674
define_macros=def_macros,
675
sources=[ cython_extfiles['_comp_bzip2'],
677
library_dirs=lib_dirs,
678
libraries=_comp_bzip2_libs,
679
extra_link_args=LFLAGS,
680
extra_compile_args=CFLAGS ),
682
Extension( "tables.linkExtension",
683
include_dirs=inc_dirs,
684
define_macros=def_macros,
685
sources=[ cython_extfiles['linkExtension'] ],
686
library_dirs=lib_dirs,
687
libraries=tableExtension_libs,
688
extra_link_args=LFLAGS,
689
extra_compile_args=CFLAGS ),
694
if 'lrucacheExtension' in cython_extnames:
696
Extension( "tables.lrucacheExtension",
697
include_dirs=inc_dirs,
698
define_macros=def_macros,
699
sources=[cython_extfiles['lrucacheExtension']],
700
library_dirs=lib_dirs,
701
libraries=lrucacheExtension_libs,
702
extra_link_args=LFLAGS,
703
extra_compile_args=CFLAGS ) )
705
if 'indexesExtension' in cython_extnames:
707
Extension( "tables.indexesExtension",
708
include_dirs=inc_dirs,
709
define_macros=def_macros,
710
sources = [ cython_extfiles['indexesExtension'],
713
library_dirs=lib_dirs,
714
libraries=indexesExtension_libs,
715
extra_link_args=LFLAGS,
716
extra_compile_args=CFLAGS ) )
720
Development Status :: 5 - Production/Stable
721
Intended Audience :: Developers
722
Intended Audience :: Information Technology
723
Intended Audience :: Science/Research
724
License :: OSI Approved :: BSD License
725
Programming Language :: Python
727
Topic :: Software Development :: Libraries :: Python Modules
728
Operating System :: Microsoft :: Windows
729
Operating System :: Unix
733
description = 'Hierarchical datasets for Python',
734
long_description = """\
736
PyTables is a package for managing hierarchical datasets and
737
designed to efficently cope with extremely large amounts of
738
data. PyTables is built on top of the HDF5 library and the
739
NumPy package and features an object-oriented interface
740
that, combined with C-code generated from Cython sources,
741
makes of it a fast, yet extremely easy to use tool for
742
interactively save and retrieve large amounts of data.
745
classifiers = filter(None, classifiers.split("\n")),
746
author = 'Francesc Alted, Ivan Vilata, et al.',
747
author_email = 'pytables@pytables.org',
748
maintainer = 'Francesc Alted',
749
maintainer_email = 'pytables@pytables.org',
750
url = 'http://www.pytables.org/',
751
license = 'http://www.opensource.org/licenses/bsd-license.php',
752
download_url = "http://sourceforge.net/projects/pytables/files/pytables/%s/tables-%s.tar.gz" % (VERSION, VERSION),
754
ext_modules = extensions,
756
data_files = data_files,