Skip to content

Commit 0bd5d93

Browse files
defer numpy&cython
1 parent 633c4d3 commit 0bd5d93

File tree

2 files changed

+121
-33
lines changed

2 files changed

+121
-33
lines changed

Dockerfile

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Dockerfile for TA-Lib. To build:
2+
#
3+
# docker build --rm -t talib -f Dockerfile .
4+
#
5+
# To run:
6+
#
7+
# docker run --rm -it talib bash
8+
#
9+
FROM python:3.6
10+
11+
RUN apt-get update && apt-get install -y \
12+
gfortran \
13+
libfreetype6-dev \
14+
libhdf5-dev \
15+
liblapack-dev \
16+
libopenblas-dev \
17+
libpng-dev \
18+
&& rm -rf /var/lib/apt/lists/* \
19+
&& curl -L http://prdownloads.sourceforge.net/ta-lib/ta-lib-0.4.0-src.tar.gz \
20+
| tar xvz \
21+
&& cd /ta-lib \
22+
&& ./configure --prefix=/usr \
23+
&& make \
24+
&& make install \
25+
&& pip install --upgrade pip
26+
27+
WORKDIR /TA-Lib
28+
COPY . .
29+
30+
RUN python setup.py egg_info \
31+
&& python setup.py --help \
32+
&& pip install -e . \
33+
&& pip -V \
34+
&& pip freeze \
35+
&& pip show numpy cython TA_Lib \
36+
&& python -c 'import numpy; import talib; close = numpy.random.random(100); output = talib.SMA(close); print(output)' \
37+
&& pip install -r requirements_dev.txt \
38+
&& pip install -r requirements_test.txt \
39+
&& nosetests -w .

setup.py

Lines changed: 82 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,15 @@
66

77
from distutils.dist import Distribution
88

9-
display_option_names = Distribution.display_option_names + ['help', 'help-commands']
10-
query_only = any('--' + opt in sys.argv for opt in display_option_names) or len(sys.argv) < 2 or sys.argv[1] == 'egg_info'
9+
# display_option_names = Distribution.display_option_names + ['help', 'help-commands']
10+
# query_only = any('--' + opt in sys.argv for opt in display_option_names) or len(sys.argv) < 2 or sys.argv[1] == 'egg_info'
1111

1212
try:
1313
from setuptools import setup, Extension
14-
requires = {"install_requires": ["numpy"]}
14+
requires = {
15+
"install_requires": ["numpy", 'cython'],
16+
"setup_requires": ['numpy', 'cython']
17+
}
1518
except:
1619
from distutils.core import setup
1720
from distutils.extension import Extension
@@ -57,16 +60,16 @@
5760
if not platform_supported:
5861
raise NotImplementedError(sys.platform)
5962

60-
# Do not require numpy or cython for just querying the package
61-
if not query_only:
62-
import numpy
63-
include_dirs.insert(0, numpy.get_include())
64-
65-
try:
66-
from Cython.Distutils import build_ext
67-
has_cython = True
68-
except ImportError:
69-
has_cython = False
63+
# # Do not require numpy or cython for just querying the package
64+
# if not query_only:
65+
# import numpy
66+
# include_dirs.insert(0, numpy.get_include())
67+
#
68+
# try:
69+
# from Cython.Distutils import build_ext
70+
# has_cython = True
71+
# except ImportError:
72+
# has_cython = False
7073

7174
for lib_talib_dir in lib_talib_dirs:
7275
try:
@@ -78,30 +81,77 @@
7881
else:
7982
warnings.warn('Cannot find ta-lib library, installation may fail.')
8083

81-
cmdclass = {}
82-
if has_cython:
83-
cmdclass['build_ext'] = build_ext
84+
# cmdclass = {}
85+
# if has_cython:
86+
# cmdclass['build_ext'] = build_ext
87+
88+
89+
class LazyBuildExtCommandClass(dict):
90+
"""
91+
Lazy command class that defers operations requiring Cython and numpy until
92+
they've actually been downloaded and installed by setup_requires.
93+
"""
94+
95+
def __contains__(self, key):
96+
return (key == 'build_ext' or
97+
super(LazyBuildExtCommandClass, self).__contains__(key))
98+
99+
def __setitem__(self, key, value):
100+
if key == 'build_ext':
101+
raise AssertionError("build_ext overridden!")
102+
super(LazyBuildExtCommandClass, self).__setitem__(key, value)
103+
104+
def __getitem__(self, key):
105+
global include_dirs
106+
if key != 'build_ext':
107+
return super(LazyBuildExtCommandClass, self).__getitem__(key)
108+
109+
from Cython.Distutils import build_ext as cython_build_ext
110+
import numpy
111+
112+
# Cython_build_ext isn't a new-style class in Py2.
113+
class build_ext(cython_build_ext, object):
114+
"""
115+
Custom build_ext command that lazily adds numpy's include_dir to
116+
extensions.
117+
"""
118+
119+
def build_extensions(self):
120+
"""
121+
Lazily append numpy's include directory to Extension includes.
122+
This is done here rather than at module scope because setup.py
123+
may be run before numpy has been installed, in which case
124+
importing numpy and calling `numpy.get_include()` will fail.
125+
"""
126+
numpy_incl = numpy.get_include()
127+
for ext in self.extensions:
128+
ext.include_dirs.append(numpy_incl)
129+
130+
super(build_ext, self).build_extensions()
131+
132+
return build_ext
133+
134+
135+
cmdclass = LazyBuildExtCommandClass()
84136

85137
ext_modules = [
86138
Extension(
87139
'talib._ta_lib',
88-
['talib/_ta_lib.pyx' if has_cython else 'talib/_ta_lib.c'],
140+
['talib/_ta_lib.pyx'], # if has_cython else 'talib/_ta_lib.c'],
89141
include_dirs=include_dirs,
90142
library_dirs=lib_talib_dirs,
91143
libraries=[lib_talib_name],
92-
runtime_library_dirs=runtime_lib_dirs
93-
)
144+
runtime_library_dirs=runtime_lib_dirs)
94145
]
95-
96146
setup(
97-
name = 'TA-Lib',
98-
version = '0.4.18',
99-
description = 'Python wrapper for TA-Lib',
100-
author = 'John Benediktsson',
101-
author_email = 'mrjbq7@gmail.com',
102-
url = 'https://github.com/mrjbq7/ta-lib',
103-
download_url = 'https://github.com/mrjbq7/ta-lib/releases',
104-
classifiers = [
147+
name='TA-Lib',
148+
version='0.4.18',
149+
description='Python wrapper for TA-Lib',
150+
author='John Benediktsson',
151+
author_email='mrjbq7@gmail.com',
152+
url='https://github.com/mrjbq7/ta-lib',
153+
download_url='https://github.com/mrjbq7/ta-lib/releases',
154+
classifiers=[
105155
"License :: OSI Approved :: BSD License",
106156
"Development Status :: 4 - Beta",
107157
"Operating System :: Unix",
@@ -122,8 +172,7 @@
122172
"Intended Audience :: Science/Research",
123173
"Intended Audience :: Financial and Insurance Industry",
124174
],
125-
packages = ['talib'],
126-
ext_modules = ext_modules,
127-
cmdclass = cmdclass,
128-
**requires
129-
)
175+
packages=['talib'],
176+
ext_modules=ext_modules,
177+
cmdclass=cmdclass,
178+
**requires)

0 commit comments

Comments
 (0)