##// END OF EJS Templates
Backport PR #10165: Don't install numpy to test on Python 3.3
Thomas Kluyver -
Show More
@@ -1,44 +1,44 b''
1 # http://travis-ci.org/#!/ipython/ipython
1 # http://travis-ci.org/#!/ipython/ipython
2 language: python
2 language: python
3 python:
3 python:
4 - "nightly"
4 - "nightly"
5 - 3.5
5 - 3.5
6 - 3.4
6 - 3.4
7 - 3.3
7 - 3.3
8 - 2.7
8 - 2.7
9 - pypy
9 - pypy
10 sudo: false
10 sudo: false
11 before_install:
11 before_install:
12 - git clone --quiet --depth 1 https://github.com/minrk/travis-wheels travis-wheels
12 - git clone --quiet --depth 1 https://github.com/minrk/travis-wheels travis-wheels
13 - 'if [[ $GROUP != js* ]]; then COVERAGE=""; fi'
13 - 'if [[ $GROUP != js* ]]; then COVERAGE=""; fi'
14 install:
14 install:
15 - pip install "setuptools>=18.5"
15 - pip install "setuptools>=18.5" pip --upgrade
16 # Installs PyPy (+ its Numpy). Based on @frol comment at:
16 # Installs PyPy (+ its Numpy). Based on @frol comment at:
17 # https://github.com/travis-ci/travis-ci/issues/5027
17 # https://github.com/travis-ci/travis-ci/issues/5027
18 - |
18 - |
19 if [ "$TRAVIS_PYTHON_VERSION" = "pypy" ]; then
19 if [ "$TRAVIS_PYTHON_VERSION" = "pypy" ]; then
20 export PYENV_ROOT="$HOME/.pyenv"
20 export PYENV_ROOT="$HOME/.pyenv"
21 if [ -f "$PYENV_ROOT/bin/pyenv" ]; then
21 if [ -f "$PYENV_ROOT/bin/pyenv" ]; then
22 cd "$PYENV_ROOT" && git pull
22 cd "$PYENV_ROOT" && git pull
23 else
23 else
24 rm -rf "$PYENV_ROOT" && git clone --depth 1 https://github.com/yyuu/pyenv.git "$PYENV_ROOT"
24 rm -rf "$PYENV_ROOT" && git clone --depth 1 https://github.com/yyuu/pyenv.git "$PYENV_ROOT"
25 fi
25 fi
26 export PYPY_VERSION="5.3.1"
26 export PYPY_VERSION="5.3.1"
27 "$PYENV_ROOT/bin/pyenv" install "pypy-$PYPY_VERSION"
27 "$PYENV_ROOT/bin/pyenv" install "pypy-$PYPY_VERSION"
28 virtualenv --python="$PYENV_ROOT/versions/pypy-$PYPY_VERSION/bin/python" "$HOME/virtualenvs/pypy-$PYPY_VERSION"
28 virtualenv --python="$PYENV_ROOT/versions/pypy-$PYPY_VERSION/bin/python" "$HOME/virtualenvs/pypy-$PYPY_VERSION"
29 source "$HOME/virtualenvs/pypy-$PYPY_VERSION/bin/activate"
29 source "$HOME/virtualenvs/pypy-$PYPY_VERSION/bin/activate"
30 pip install https://bitbucket.org/pypy/numpy/get/master.zip
30 pip install https://bitbucket.org/pypy/numpy/get/master.zip
31 fi
31 fi
32 - pip install -f travis-wheels/wheelhouse -e file://$PWD#egg=ipython[test]
32 - pip install -f travis-wheels/wheelhouse -e file://$PWD#egg=ipython[test]
33 - pip install codecov
33 - pip install codecov
34 script:
34 script:
35 - cd /tmp && iptest --coverage xml && cd -
35 - cd /tmp && iptest --coverage xml && cd -
36 after_success:
36 after_success:
37 - cp /tmp/ipy_coverage.xml ./
37 - cp /tmp/ipy_coverage.xml ./
38 - cp /tmp/.coverage ./
38 - cp /tmp/.coverage ./
39 - codecov
39 - codecov
40
40
41 matrix:
41 matrix:
42 allow_failures:
42 allow_failures:
43 - python: nightly
43 - python: nightly
44 - python: pypy
44 - python: pypy
@@ -1,289 +1,290 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
2 # -*- coding: utf-8 -*-
3 """Setup script for IPython.
3 """Setup script for IPython.
4
4
5 Under Posix environments it works like a typical setup.py script.
5 Under Posix environments it works like a typical setup.py script.
6 Under Windows, the command sdist is not supported, since IPython
6 Under Windows, the command sdist is not supported, since IPython
7 requires utilities which are not available under Windows."""
7 requires utilities which are not available under Windows."""
8
8
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10 # Copyright (c) 2008-2011, IPython Development Team.
10 # Copyright (c) 2008-2011, IPython Development Team.
11 # Copyright (c) 2001-2007, Fernando Perez <fernando.perez@colorado.edu>
11 # Copyright (c) 2001-2007, Fernando Perez <fernando.perez@colorado.edu>
12 # Copyright (c) 2001, Janko Hauser <jhauser@zscout.de>
12 # Copyright (c) 2001, Janko Hauser <jhauser@zscout.de>
13 # Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu>
13 # Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu>
14 #
14 #
15 # Distributed under the terms of the Modified BSD License.
15 # Distributed under the terms of the Modified BSD License.
16 #
16 #
17 # The full license is in the file COPYING.rst, distributed with this software.
17 # The full license is in the file COPYING.rst, distributed with this software.
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19
19
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21 # Minimal Python version sanity check
21 # Minimal Python version sanity check
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23 from __future__ import print_function
23 from __future__ import print_function
24
24
25 import sys
25 import sys
26
26
27 # This check is also made in IPython/__init__, don't forget to update both when
27 # This check is also made in IPython/__init__, don't forget to update both when
28 # changing Python version requirements.
28 # changing Python version requirements.
29 v = sys.version_info
29 v = sys.version_info
30 if v[:2] < (2,7) or (v[0] >= 3 and v[:2] < (3,3)):
30 if v[:2] < (2,7) or (v[0] >= 3 and v[:2] < (3,3)):
31 error = "ERROR: IPython requires Python version 2.7 or 3.3 or above."
31 error = "ERROR: IPython requires Python version 2.7 or 3.3 or above."
32 print(error, file=sys.stderr)
32 print(error, file=sys.stderr)
33 sys.exit(1)
33 sys.exit(1)
34
34
35 PY3 = (sys.version_info[0] >= 3)
35 PY3 = (sys.version_info[0] >= 3)
36
36
37 # At least we're on the python version we need, move on.
37 # At least we're on the python version we need, move on.
38
38
39 #-------------------------------------------------------------------------------
39 #-------------------------------------------------------------------------------
40 # Imports
40 # Imports
41 #-------------------------------------------------------------------------------
41 #-------------------------------------------------------------------------------
42
42
43 # Stdlib imports
43 # Stdlib imports
44 import os
44 import os
45
45
46 from glob import glob
46 from glob import glob
47
47
48 # BEFORE importing distutils, remove MANIFEST. distutils doesn't properly
48 # BEFORE importing distutils, remove MANIFEST. distutils doesn't properly
49 # update it when the contents of directories change.
49 # update it when the contents of directories change.
50 if os.path.exists('MANIFEST'): os.remove('MANIFEST')
50 if os.path.exists('MANIFEST'): os.remove('MANIFEST')
51
51
52 from distutils.core import setup
52 from distutils.core import setup
53
53
54 # Our own imports
54 # Our own imports
55 from setupbase import target_update
55 from setupbase import target_update
56
56
57 from setupbase import (
57 from setupbase import (
58 setup_args,
58 setup_args,
59 find_packages,
59 find_packages,
60 find_package_data,
60 find_package_data,
61 check_package_data_first,
61 check_package_data_first,
62 find_entry_points,
62 find_entry_points,
63 build_scripts_entrypt,
63 build_scripts_entrypt,
64 find_data_files,
64 find_data_files,
65 git_prebuild,
65 git_prebuild,
66 install_symlinked,
66 install_symlinked,
67 install_lib_symlink,
67 install_lib_symlink,
68 install_scripts_for_symlink,
68 install_scripts_for_symlink,
69 unsymlink,
69 unsymlink,
70 )
70 )
71
71
72 isfile = os.path.isfile
72 isfile = os.path.isfile
73 pjoin = os.path.join
73 pjoin = os.path.join
74
74
75 #-------------------------------------------------------------------------------
75 #-------------------------------------------------------------------------------
76 # Handle OS specific things
76 # Handle OS specific things
77 #-------------------------------------------------------------------------------
77 #-------------------------------------------------------------------------------
78
78
79 if os.name in ('nt','dos'):
79 if os.name in ('nt','dos'):
80 os_name = 'windows'
80 os_name = 'windows'
81 else:
81 else:
82 os_name = os.name
82 os_name = os.name
83
83
84 # Under Windows, 'sdist' has not been supported. Now that the docs build with
84 # Under Windows, 'sdist' has not been supported. Now that the docs build with
85 # Sphinx it might work, but let's not turn it on until someone confirms that it
85 # Sphinx it might work, but let's not turn it on until someone confirms that it
86 # actually works.
86 # actually works.
87 if os_name == 'windows' and 'sdist' in sys.argv:
87 if os_name == 'windows' and 'sdist' in sys.argv:
88 print('The sdist command is not available under Windows. Exiting.')
88 print('The sdist command is not available under Windows. Exiting.')
89 sys.exit(1)
89 sys.exit(1)
90
90
91
91
92 #-------------------------------------------------------------------------------
92 #-------------------------------------------------------------------------------
93 # Things related to the IPython documentation
93 # Things related to the IPython documentation
94 #-------------------------------------------------------------------------------
94 #-------------------------------------------------------------------------------
95
95
96 # update the manuals when building a source dist
96 # update the manuals when building a source dist
97 if len(sys.argv) >= 2 and sys.argv[1] in ('sdist','bdist_rpm'):
97 if len(sys.argv) >= 2 and sys.argv[1] in ('sdist','bdist_rpm'):
98
98
99 # List of things to be updated. Each entry is a triplet of args for
99 # List of things to be updated. Each entry is a triplet of args for
100 # target_update()
100 # target_update()
101 to_update = [
101 to_update = [
102 ('docs/man/ipython.1.gz',
102 ('docs/man/ipython.1.gz',
103 ['docs/man/ipython.1'],
103 ['docs/man/ipython.1'],
104 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz'),
104 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz'),
105 ]
105 ]
106
106
107
107
108 [ target_update(*t) for t in to_update ]
108 [ target_update(*t) for t in to_update ]
109
109
110 #---------------------------------------------------------------------------
110 #---------------------------------------------------------------------------
111 # Find all the packages, package data, and data_files
111 # Find all the packages, package data, and data_files
112 #---------------------------------------------------------------------------
112 #---------------------------------------------------------------------------
113
113
114 packages = find_packages()
114 packages = find_packages()
115 package_data = find_package_data()
115 package_data = find_package_data()
116
116
117 data_files = find_data_files()
117 data_files = find_data_files()
118
118
119 setup_args['packages'] = packages
119 setup_args['packages'] = packages
120 setup_args['package_data'] = package_data
120 setup_args['package_data'] = package_data
121 setup_args['data_files'] = data_files
121 setup_args['data_files'] = data_files
122
122
123 #---------------------------------------------------------------------------
123 #---------------------------------------------------------------------------
124 # custom distutils commands
124 # custom distutils commands
125 #---------------------------------------------------------------------------
125 #---------------------------------------------------------------------------
126 # imports here, so they are after setuptools import if there was one
126 # imports here, so they are after setuptools import if there was one
127 from distutils.command.sdist import sdist
127 from distutils.command.sdist import sdist
128 from distutils.command.upload import upload
128 from distutils.command.upload import upload
129
129
130 class UploadWindowsInstallers(upload):
130 class UploadWindowsInstallers(upload):
131
131
132 description = "Upload Windows installers to PyPI (only used from tools/release_windows.py)"
132 description = "Upload Windows installers to PyPI (only used from tools/release_windows.py)"
133 user_options = upload.user_options + [
133 user_options = upload.user_options + [
134 ('files=', 'f', 'exe file (or glob) to upload')
134 ('files=', 'f', 'exe file (or glob) to upload')
135 ]
135 ]
136 def initialize_options(self):
136 def initialize_options(self):
137 upload.initialize_options(self)
137 upload.initialize_options(self)
138 meta = self.distribution.metadata
138 meta = self.distribution.metadata
139 base = '{name}-{version}'.format(
139 base = '{name}-{version}'.format(
140 name=meta.get_name(),
140 name=meta.get_name(),
141 version=meta.get_version()
141 version=meta.get_version()
142 )
142 )
143 self.files = os.path.join('dist', '%s.*.exe' % base)
143 self.files = os.path.join('dist', '%s.*.exe' % base)
144
144
145 def run(self):
145 def run(self):
146 for dist_file in glob(self.files):
146 for dist_file in glob(self.files):
147 self.upload_file('bdist_wininst', 'any', dist_file)
147 self.upload_file('bdist_wininst', 'any', dist_file)
148
148
149 setup_args['cmdclass'] = {
149 setup_args['cmdclass'] = {
150 'build_py': \
150 'build_py': \
151 check_package_data_first(git_prebuild('IPython')),
151 check_package_data_first(git_prebuild('IPython')),
152 'sdist' : git_prebuild('IPython', sdist),
152 'sdist' : git_prebuild('IPython', sdist),
153 'upload_wininst' : UploadWindowsInstallers,
153 'upload_wininst' : UploadWindowsInstallers,
154 'symlink': install_symlinked,
154 'symlink': install_symlinked,
155 'install_lib_symlink': install_lib_symlink,
155 'install_lib_symlink': install_lib_symlink,
156 'install_scripts_sym': install_scripts_for_symlink,
156 'install_scripts_sym': install_scripts_for_symlink,
157 'unsymlink': unsymlink,
157 'unsymlink': unsymlink,
158 }
158 }
159
159
160
160
161 #---------------------------------------------------------------------------
161 #---------------------------------------------------------------------------
162 # Handle scripts, dependencies, and setuptools specific things
162 # Handle scripts, dependencies, and setuptools specific things
163 #---------------------------------------------------------------------------
163 #---------------------------------------------------------------------------
164
164
165 # For some commands, use setuptools. Note that we do NOT list install here!
165 # For some commands, use setuptools. Note that we do NOT list install here!
166 # If you want a setuptools-enhanced install, just run 'setupegg.py install'
166 # If you want a setuptools-enhanced install, just run 'setupegg.py install'
167 needs_setuptools = set(('develop', 'release', 'bdist_egg', 'bdist_rpm',
167 needs_setuptools = set(('develop', 'release', 'bdist_egg', 'bdist_rpm',
168 'bdist', 'bdist_dumb', 'bdist_wininst', 'bdist_wheel',
168 'bdist', 'bdist_dumb', 'bdist_wininst', 'bdist_wheel',
169 'egg_info', 'easy_install', 'upload', 'install_egg_info',
169 'egg_info', 'easy_install', 'upload', 'install_egg_info',
170 ))
170 ))
171
171
172 if len(needs_setuptools.intersection(sys.argv)) > 0:
172 if len(needs_setuptools.intersection(sys.argv)) > 0:
173 import setuptools
173 import setuptools
174
174
175 # This dict is used for passing extra arguments that are setuptools
175 # This dict is used for passing extra arguments that are setuptools
176 # specific to setup
176 # specific to setup
177 setuptools_extra_args = {}
177 setuptools_extra_args = {}
178
178
179 # setuptools requirements
179 # setuptools requirements
180
180
181 extras_require = dict(
181 extras_require = dict(
182 parallel = ['ipyparallel'],
182 parallel = ['ipyparallel'],
183 qtconsole = ['qtconsole'],
183 qtconsole = ['qtconsole'],
184 doc = ['Sphinx>=1.3'],
184 doc = ['Sphinx>=1.3'],
185 test = ['nose>=0.10.1', 'requests', 'testpath', 'pygments', 'nbformat', 'ipykernel', 'numpy'],
185 test = ['nose>=0.10.1', 'requests', 'testpath', 'pygments', 'nbformat', 'ipykernel'],
186 terminal = [],
186 terminal = [],
187 kernel = ['ipykernel'],
187 kernel = ['ipykernel'],
188 nbformat = ['nbformat'],
188 nbformat = ['nbformat'],
189 notebook = ['notebook', 'ipywidgets'],
189 notebook = ['notebook', 'ipywidgets'],
190 nbconvert = ['nbconvert'],
190 nbconvert = ['nbconvert'],
191 )
191 )
192
192
193 install_requires = [
193 install_requires = [
194 'setuptools>=18.5',
194 'setuptools>=18.5',
195 'decorator',
195 'decorator',
196 'pickleshare',
196 'pickleshare',
197 'simplegeneric>0.8',
197 'simplegeneric>0.8',
198 'traitlets>=4.2',
198 'traitlets>=4.2',
199 'prompt_toolkit>=1.0.4,<2.0.0',
199 'prompt_toolkit>=1.0.4,<2.0.0',
200 'pygments',
200 'pygments',
201 ]
201 ]
202
202
203 # Platform-specific dependencies:
203 # Platform-specific dependencies:
204 # This is the correct way to specify these,
204 # This is the correct way to specify these,
205 # but requires pip >= 6. pip < 6 ignores these.
205 # but requires pip >= 6. pip < 6 ignores these.
206
206
207 extras_require.update({
207 extras_require.update({
208 ':python_version == "2.7"': ['backports.shutil_get_terminal_size'],
208 ':python_version == "2.7"': ['backports.shutil_get_terminal_size'],
209 ':python_version == "2.7" or python_version == "3.3"': ['pathlib2'],
209 ':python_version == "2.7" or python_version == "3.3"': ['pathlib2'],
210 'test:python_version >= "3.4"': ['numpy'],
210 ':sys_platform != "win32"': ['pexpect'],
211 ':sys_platform != "win32"': ['pexpect'],
211 ':sys_platform == "darwin"': ['appnope'],
212 ':sys_platform == "darwin"': ['appnope'],
212 ':sys_platform == "win32"': ['colorama'],
213 ':sys_platform == "win32"': ['colorama'],
213 ':sys_platform == "win32" and python_version < "3.6"': ['win_unicode_console>=0.5'],
214 ':sys_platform == "win32" and python_version < "3.6"': ['win_unicode_console>=0.5'],
214 'test:python_version == "2.7"': ['mock'],
215 'test:python_version == "2.7"': ['mock'],
215 })
216 })
216 # FIXME: re-specify above platform dependencies for pip < 6
217 # FIXME: re-specify above platform dependencies for pip < 6
217 # These would result in non-portable bdists.
218 # These would result in non-portable bdists.
218 if not any(arg.startswith('bdist') for arg in sys.argv):
219 if not any(arg.startswith('bdist') for arg in sys.argv):
219 if sys.version_info < (3, 3):
220 if sys.version_info < (3, 3):
220 extras_require['test'].append('mock')
221 extras_require['test'].append('mock')
221
222
222 if sys.platform == 'darwin':
223 if sys.platform == 'darwin':
223 install_requires.extend(['appnope'])
224 install_requires.extend(['appnope'])
224
225
225 if not sys.platform.startswith('win'):
226 if not sys.platform.startswith('win'):
226 install_requires.append('pexpect')
227 install_requires.append('pexpect')
227
228
228 # workaround pypa/setuptools#147, where setuptools misspells
229 # workaround pypa/setuptools#147, where setuptools misspells
229 # platform_python_implementation as python_implementation
230 # platform_python_implementation as python_implementation
230 if 'setuptools' in sys.modules:
231 if 'setuptools' in sys.modules:
231 for key in list(extras_require):
232 for key in list(extras_require):
232 if 'platform_python_implementation' in key:
233 if 'platform_python_implementation' in key:
233 new_key = key.replace('platform_python_implementation', 'python_implementation')
234 new_key = key.replace('platform_python_implementation', 'python_implementation')
234 extras_require[new_key] = extras_require.pop(key)
235 extras_require[new_key] = extras_require.pop(key)
235
236
236 everything = set()
237 everything = set()
237 for key, deps in extras_require.items():
238 for key, deps in extras_require.items():
238 if ':' not in key:
239 if ':' not in key:
239 everything.update(deps)
240 everything.update(deps)
240 extras_require['all'] = everything
241 extras_require['all'] = everything
241
242
242 if 'setuptools' in sys.modules:
243 if 'setuptools' in sys.modules:
243 setuptools_extra_args['zip_safe'] = False
244 setuptools_extra_args['zip_safe'] = False
244 setuptools_extra_args['entry_points'] = {
245 setuptools_extra_args['entry_points'] = {
245 'console_scripts': find_entry_points(),
246 'console_scripts': find_entry_points(),
246 'pygments.lexers': [
247 'pygments.lexers': [
247 'ipythonconsole = IPython.lib.lexers:IPythonConsoleLexer',
248 'ipythonconsole = IPython.lib.lexers:IPythonConsoleLexer',
248 'ipython = IPython.lib.lexers:IPythonLexer',
249 'ipython = IPython.lib.lexers:IPythonLexer',
249 'ipython3 = IPython.lib.lexers:IPython3Lexer',
250 'ipython3 = IPython.lib.lexers:IPython3Lexer',
250 ],
251 ],
251 }
252 }
252 setup_args['extras_require'] = extras_require
253 setup_args['extras_require'] = extras_require
253 requires = setup_args['install_requires'] = install_requires
254 requires = setup_args['install_requires'] = install_requires
254
255
255 # Script to be run by the windows binary installer after the default setup
256 # Script to be run by the windows binary installer after the default setup
256 # routine, to add shortcuts and similar windows-only things. Windows
257 # routine, to add shortcuts and similar windows-only things. Windows
257 # post-install scripts MUST reside in the scripts/ dir, otherwise distutils
258 # post-install scripts MUST reside in the scripts/ dir, otherwise distutils
258 # doesn't find them.
259 # doesn't find them.
259 if 'bdist_wininst' in sys.argv:
260 if 'bdist_wininst' in sys.argv:
260 if len(sys.argv) > 2 and \
261 if len(sys.argv) > 2 and \
261 ('sdist' in sys.argv or 'bdist_rpm' in sys.argv):
262 ('sdist' in sys.argv or 'bdist_rpm' in sys.argv):
262 print("ERROR: bdist_wininst must be run alone. Exiting.", file=sys.stderr)
263 print("ERROR: bdist_wininst must be run alone. Exiting.", file=sys.stderr)
263 sys.exit(1)
264 sys.exit(1)
264 setup_args['data_files'].append(
265 setup_args['data_files'].append(
265 ['Scripts', ('scripts/ipython.ico', 'scripts/ipython_nb.ico')])
266 ['Scripts', ('scripts/ipython.ico', 'scripts/ipython_nb.ico')])
266 setup_args['scripts'] = [pjoin('scripts','ipython_win_post_install.py')]
267 setup_args['scripts'] = [pjoin('scripts','ipython_win_post_install.py')]
267 setup_args['options'] = {"bdist_wininst":
268 setup_args['options'] = {"bdist_wininst":
268 {"install_script":
269 {"install_script":
269 "ipython_win_post_install.py"}}
270 "ipython_win_post_install.py"}}
270
271
271 else:
272 else:
272 # scripts has to be a non-empty list, or install_scripts isn't called
273 # scripts has to be a non-empty list, or install_scripts isn't called
273 setup_args['scripts'] = [e.split('=')[0].strip() for e in find_entry_points()]
274 setup_args['scripts'] = [e.split('=')[0].strip() for e in find_entry_points()]
274
275
275 setup_args['cmdclass']['build_scripts'] = build_scripts_entrypt
276 setup_args['cmdclass']['build_scripts'] = build_scripts_entrypt
276
277
277 #---------------------------------------------------------------------------
278 #---------------------------------------------------------------------------
278 # Do the actual setup now
279 # Do the actual setup now
279 #---------------------------------------------------------------------------
280 #---------------------------------------------------------------------------
280
281
281 setup_args.update(setuptools_extra_args)
282 setup_args.update(setuptools_extra_args)
282
283
283
284
284
285
285 def main():
286 def main():
286 setup(**setup_args)
287 setup(**setup_args)
287
288
288 if __name__ == '__main__':
289 if __name__ == '__main__':
289 main()
290 main()
General Comments 0
You need to be logged in to leave comments. Login now