zipline/setup.py
llllllllll bd0da175ad BLD: Adds versioneer
versioneer let's us track the version using git tags. This prevents
issues like the 0.8.2->0.8.3 push. This also puts the number of commits
from the release and the commit you are on in the version.
2015-11-11 18:47:51 -05:00

251 lines
7 KiB
Python

#!/usr/bin/env python
#
# Copyright 2014 Quantopian, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import print_function
import re
import sys
from operator import lt, gt, eq, le, ge
from os.path import (
abspath,
dirname,
join,
)
from distutils.version import StrictVersion
from setuptools import (
Extension,
find_packages,
setup,
)
import versioneer
class LazyCythonizingList(list):
cythonized = False
def lazy_cythonize(self):
if self.cythonized:
return
self.cythonized = True
from Cython.Build import cythonize
from numpy import get_include
self[:] = cythonize(
[
Extension(*ext_args, include_dirs=[get_include()])
for ext_args in self
]
)
def __iter__(self):
self.lazy_cythonize()
return super(LazyCythonizingList, self).__iter__()
def __getitem__(self, num):
self.lazy_cythonize()
return super(LazyCythonizingList, self).__getitem__(num)
ext_modules = LazyCythonizingList([
('zipline.assets._assets', ['zipline/assets/_assets.pyx']),
('zipline.lib.adjusted_array', ['zipline/lib/adjusted_array.pyx']),
('zipline.lib.adjustment', ['zipline/lib/adjustment.pyx']),
('zipline.lib.rank', ['zipline/lib/rank.pyx']),
(
'zipline.data._equities',
['zipline/data/_equities.pyx'],
),
(
'zipline.data._adjustments',
['zipline/data/_adjustments.pyx'],
),
])
STR_TO_CMP = {
'<': lt,
'<=': le,
'=': eq,
'==': eq,
'>': gt,
'>=': ge,
}
def _filter_requirements(lines_iter):
for line in lines_iter:
line = line.strip()
if not line or line.startswith('#'):
continue
# pip install -r understands line with ;python_version<'3.0', but
# whatever happens inside extras_requires doesn't. Parse the line
# manually and conditionally add it if needed.
if ';' not in line:
yield line
continue
requirement, version_spec = line.split(';')
try:
groups = re.match(
"(python_version)([<>=]{1,2})(')([0-9\.]+)(')(.*)",
version_spec,
).groups()
comp = STR_TO_CMP[groups[1]]
version_spec = StrictVersion(groups[3])
except Exception as e:
# My kingdom for a 'raise from'!
raise AssertionError(
"Couldn't parse requirement line; '%s'\n"
"Error was:\n"
"%r" % (line, e)
)
sys_version = '.'.join(list(map(str, sys.version_info[:3])))
if comp(sys_version, version_spec):
yield requirement
REQ_UPPER_BOUNDS = {
}
def _with_bounds(req):
try:
req, lower = req.split('==')
except ValueError:
return req
else:
with_bounds = [req, '>=', lower]
upper = REQ_UPPER_BOUNDS.get(req)
if upper:
with_bounds.extend([',', upper])
return ''.join(with_bounds)
def read_requirements(path, strict_bounds):
"""
Read a requirements.txt file, expressed as a path relative to Zipline root.
Returns requirements with the pinned versions as lower bounds
if `strict_bounds` is falsey.
"""
real_path = join(dirname(abspath(__file__)), path)
with open(real_path) as f:
reqs = _filter_requirements(f.readlines())
if strict_bounds:
return list(reqs)
else:
return list(map(_with_bounds, reqs))
def install_requires(strict_bounds=False):
return read_requirements('etc/requirements.txt',
strict_bounds=strict_bounds)
def extras_requires():
dev_reqs = read_requirements('etc/requirements_dev.txt',
strict_bounds=True)
talib_reqs = ['TA-Lib==0.4.9']
return {
'dev': dev_reqs,
'talib': talib_reqs,
'all': dev_reqs + talib_reqs,
}
def module_requirements(requirements_path, module_names):
module_names = set(module_names)
found = set()
module_lines = []
parser = re.compile("([^=<>]+)([<=>]{1,2})(.*)")
for line in read_requirements(requirements_path, strict_bounds=False):
match = parser.match(line)
if match is None:
raise AssertionError("Could not parse requirement: '%s'" % line)
groups = match.groups()
name = groups[0]
if name in module_names:
found.add(name)
module_lines.append(line)
if found != module_names:
raise AssertionError(
"No requirements found for %s." % module_names - found
)
return module_lines
def pre_setup():
if not set(sys.argv) & {'install', 'develop', 'egg_info', 'bdist_wheel'}:
return
try:
import pip
if StrictVersion(pip.__version__) < StrictVersion('7.1.0'):
raise AssertionError(
"Zipline installation requires pip>=7.1.0, but your pip "
"version is {version}. \n"
"You can upgrade your pip with "
"'pip install --upgrade pip'.".format(
version=pip.__version__,
)
)
except ImportError:
raise AssertionError("Zipline installation requires pip")
required = ('Cython', 'numpy')
for line in module_requirements('etc/requirements.txt', required):
pip.main(['install', line])
pre_setup()
setup(
name='zipline',
version=versioneer.get_version(),
cmdclass=versioneer.get_cmdclass(),
description='A backtester for financial algorithms.',
author='Quantopian Inc.',
author_email='opensource@quantopian.com',
packages=find_packages('.', include=['zipline', 'zipline.*']),
ext_modules=ext_modules,
scripts=['scripts/run_algo.py'],
include_package_data=True,
license='Apache 2.0',
classifiers=[
'Development Status :: 4 - Beta',
'License :: OSI Approved :: Apache Software License',
'Natural Language :: English',
'Programming Language :: Python',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Operating System :: OS Independent',
'Intended Audience :: Science/Research',
'Topic :: Office/Business :: Financial',
'Topic :: Scientific/Engineering :: Information Analysis',
'Topic :: System :: Distributed Computing',
],
install_requires=install_requires(),
extras_require=extras_requires(),
url="http://zipline.io",
)