##// END OF EJS Templates
NEP 29 stop support for 3.6
Matthias Bussonnier -
Show More
@@ -1,261 +1,262 b''
1 #!/usr/bin/env python3
1 #!/usr/bin/env python3
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 import os
20 import os
21 import sys
21 import sys
22
22
23 # **Python version check**
23 # **Python version check**
24 #
24 #
25 # This check is also made in IPython/__init__, don't forget to update both when
25 # This check is also made in IPython/__init__, don't forget to update both when
26 # changing Python version requirements.
26 # changing Python version requirements.
27 if sys.version_info < (3, 6):
27 if sys.version_info < (3, 7):
28 pip_message = 'This may be due to an out of date pip. Make sure you have pip >= 9.0.1.'
28 pip_message = 'This may be due to an out of date pip. Make sure you have pip >= 9.0.1.'
29 try:
29 try:
30 import pip
30 import pip
31 pip_version = tuple([int(x) for x in pip.__version__.split('.')[:3]])
31 pip_version = tuple([int(x) for x in pip.__version__.split('.')[:3]])
32 if pip_version < (9, 0, 1) :
32 if pip_version < (9, 0, 1) :
33 pip_message = 'Your pip version is out of date, please install pip >= 9.0.1. '\
33 pip_message = 'Your pip version is out of date, please install pip >= 9.0.1. '\
34 'pip {} detected.'.format(pip.__version__)
34 'pip {} detected.'.format(pip.__version__)
35 else:
35 else:
36 # pip is new enough - it must be something else
36 # pip is new enough - it must be something else
37 pip_message = ''
37 pip_message = ''
38 except Exception:
38 except Exception:
39 pass
39 pass
40
40
41
41
42 error = """
42 error = """
43 IPython 7.10+ supports Python 3.6 and above, following NEP 29.
43 IPython 7.17+ supports Python 3.7 and above, following NEP 29.
44 When using Python 2.7, please install IPython 5.x LTS Long Term Support version.
44 When using Python 2.7, please install IPython 5.x LTS Long Term Support version.
45 Python 3.3 and 3.4 were supported up to IPython 6.x.
45 Python 3.3 and 3.4 were supported up to IPython 6.x.
46 Python 3.5 was supported with IPython 7.0 to 7.9.
46 Python 3.5 was supported with IPython 7.0 to 7.9.
47 Python 3.6 was supported with IPython up to 7.16.
47
48
48 See IPython `README.rst` file for more information:
49 See IPython `README.rst` file for more information:
49
50
50 https://github.com/ipython/ipython/blob/master/README.rst
51 https://github.com/ipython/ipython/blob/master/README.rst
51
52
52 Python {py} detected.
53 Python {py} detected.
53 {pip}
54 {pip}
54 """.format(py=sys.version_info, pip=pip_message )
55 """.format(py=sys.version_info, pip=pip_message )
55
56
56 print(error, file=sys.stderr)
57 print(error, file=sys.stderr)
57 sys.exit(1)
58 sys.exit(1)
58
59
59 # At least we're on the python version we need, move on.
60 # At least we're on the python version we need, move on.
60
61
61 # BEFORE importing distutils, remove MANIFEST. distutils doesn't properly
62 # BEFORE importing distutils, remove MANIFEST. distutils doesn't properly
62 # update it when the contents of directories change.
63 # update it when the contents of directories change.
63 if os.path.exists('MANIFEST'): os.remove('MANIFEST')
64 if os.path.exists('MANIFEST'): os.remove('MANIFEST')
64
65
65 from distutils.core import setup
66 from distutils.core import setup
66
67
67 # Our own imports
68 # Our own imports
68 from setupbase import target_update
69 from setupbase import target_update
69
70
70 from setupbase import (
71 from setupbase import (
71 setup_args,
72 setup_args,
72 find_packages,
73 find_packages,
73 find_package_data,
74 find_package_data,
74 check_package_data_first,
75 check_package_data_first,
75 find_entry_points,
76 find_entry_points,
76 build_scripts_entrypt,
77 build_scripts_entrypt,
77 find_data_files,
78 find_data_files,
78 git_prebuild,
79 git_prebuild,
79 install_symlinked,
80 install_symlinked,
80 install_lib_symlink,
81 install_lib_symlink,
81 install_scripts_for_symlink,
82 install_scripts_for_symlink,
82 unsymlink,
83 unsymlink,
83 )
84 )
84
85
85 isfile = os.path.isfile
86 isfile = os.path.isfile
86 pjoin = os.path.join
87 pjoin = os.path.join
87
88
88 #-------------------------------------------------------------------------------
89 #-------------------------------------------------------------------------------
89 # Handle OS specific things
90 # Handle OS specific things
90 #-------------------------------------------------------------------------------
91 #-------------------------------------------------------------------------------
91
92
92 if os.name in ('nt','dos'):
93 if os.name in ('nt','dos'):
93 os_name = 'windows'
94 os_name = 'windows'
94 else:
95 else:
95 os_name = os.name
96 os_name = os.name
96
97
97 # Under Windows, 'sdist' has not been supported. Now that the docs build with
98 # Under Windows, 'sdist' has not been supported. Now that the docs build with
98 # Sphinx it might work, but let's not turn it on until someone confirms that it
99 # Sphinx it might work, but let's not turn it on until someone confirms that it
99 # actually works.
100 # actually works.
100 if os_name == 'windows' and 'sdist' in sys.argv:
101 if os_name == 'windows' and 'sdist' in sys.argv:
101 print('The sdist command is not available under Windows. Exiting.')
102 print('The sdist command is not available under Windows. Exiting.')
102 sys.exit(1)
103 sys.exit(1)
103
104
104
105
105 #-------------------------------------------------------------------------------
106 #-------------------------------------------------------------------------------
106 # Things related to the IPython documentation
107 # Things related to the IPython documentation
107 #-------------------------------------------------------------------------------
108 #-------------------------------------------------------------------------------
108
109
109 # update the manuals when building a source dist
110 # update the manuals when building a source dist
110 if len(sys.argv) >= 2 and sys.argv[1] in ('sdist','bdist_rpm'):
111 if len(sys.argv) >= 2 and sys.argv[1] in ('sdist','bdist_rpm'):
111
112
112 # List of things to be updated. Each entry is a triplet of args for
113 # List of things to be updated. Each entry is a triplet of args for
113 # target_update()
114 # target_update()
114 to_update = [
115 to_update = [
115 ('docs/man/ipython.1.gz',
116 ('docs/man/ipython.1.gz',
116 ['docs/man/ipython.1'],
117 ['docs/man/ipython.1'],
117 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz'),
118 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz'),
118 ]
119 ]
119
120
120
121
121 [ target_update(*t) for t in to_update ]
122 [ target_update(*t) for t in to_update ]
122
123
123 #---------------------------------------------------------------------------
124 #---------------------------------------------------------------------------
124 # Find all the packages, package data, and data_files
125 # Find all the packages, package data, and data_files
125 #---------------------------------------------------------------------------
126 #---------------------------------------------------------------------------
126
127
127 packages = find_packages()
128 packages = find_packages()
128 package_data = find_package_data()
129 package_data = find_package_data()
129
130
130 data_files = find_data_files()
131 data_files = find_data_files()
131
132
132 setup_args['packages'] = packages
133 setup_args['packages'] = packages
133 setup_args['package_data'] = package_data
134 setup_args['package_data'] = package_data
134 setup_args['data_files'] = data_files
135 setup_args['data_files'] = data_files
135
136
136 #---------------------------------------------------------------------------
137 #---------------------------------------------------------------------------
137 # custom distutils commands
138 # custom distutils commands
138 #---------------------------------------------------------------------------
139 #---------------------------------------------------------------------------
139 # imports here, so they are after setuptools import if there was one
140 # imports here, so they are after setuptools import if there was one
140 from distutils.command.sdist import sdist
141 from distutils.command.sdist import sdist
141
142
142 setup_args['cmdclass'] = {
143 setup_args['cmdclass'] = {
143 'build_py': \
144 'build_py': \
144 check_package_data_first(git_prebuild('IPython')),
145 check_package_data_first(git_prebuild('IPython')),
145 'sdist' : git_prebuild('IPython', sdist),
146 'sdist' : git_prebuild('IPython', sdist),
146 'symlink': install_symlinked,
147 'symlink': install_symlinked,
147 'install_lib_symlink': install_lib_symlink,
148 'install_lib_symlink': install_lib_symlink,
148 'install_scripts_sym': install_scripts_for_symlink,
149 'install_scripts_sym': install_scripts_for_symlink,
149 'unsymlink': unsymlink,
150 'unsymlink': unsymlink,
150 }
151 }
151
152
152
153
153 #---------------------------------------------------------------------------
154 #---------------------------------------------------------------------------
154 # Handle scripts, dependencies, and setuptools specific things
155 # Handle scripts, dependencies, and setuptools specific things
155 #---------------------------------------------------------------------------
156 #---------------------------------------------------------------------------
156
157
157 # For some commands, use setuptools. Note that we do NOT list install here!
158 # For some commands, use setuptools. Note that we do NOT list install here!
158 # If you want a setuptools-enhanced install, just run 'setupegg.py install'
159 # If you want a setuptools-enhanced install, just run 'setupegg.py install'
159 needs_setuptools = {'develop', 'release', 'bdist_egg', 'bdist_rpm',
160 needs_setuptools = {'develop', 'release', 'bdist_egg', 'bdist_rpm',
160 'bdist', 'bdist_dumb', 'bdist_wininst', 'bdist_wheel',
161 'bdist', 'bdist_dumb', 'bdist_wininst', 'bdist_wheel',
161 'egg_info', 'easy_install', 'upload', 'install_egg_info',
162 'egg_info', 'easy_install', 'upload', 'install_egg_info',
162 }
163 }
163
164
164 if len(needs_setuptools.intersection(sys.argv)) > 0:
165 if len(needs_setuptools.intersection(sys.argv)) > 0:
165 import setuptools
166 import setuptools
166
167
167 # This dict is used for passing extra arguments that are setuptools
168 # This dict is used for passing extra arguments that are setuptools
168 # specific to setup
169 # specific to setup
169 setuptools_extra_args = {}
170 setuptools_extra_args = {}
170
171
171 # setuptools requirements
172 # setuptools requirements
172
173
173 extras_require = dict(
174 extras_require = dict(
174 parallel = ['ipyparallel'],
175 parallel = ['ipyparallel'],
175 qtconsole = ['qtconsole'],
176 qtconsole = ['qtconsole'],
176 doc = ['Sphinx>=1.3'],
177 doc = ['Sphinx>=1.3'],
177 test = ['nose>=0.10.1', 'requests', 'testpath', 'pygments', 'nbformat', 'ipykernel', 'numpy>=1.14'],
178 test = ['nose>=0.10.1', 'requests', 'testpath', 'pygments', 'nbformat', 'ipykernel', 'numpy>=1.14'],
178 terminal = [],
179 terminal = [],
179 kernel = ['ipykernel'],
180 kernel = ['ipykernel'],
180 nbformat = ['nbformat'],
181 nbformat = ['nbformat'],
181 notebook = ['notebook', 'ipywidgets'],
182 notebook = ['notebook', 'ipywidgets'],
182 nbconvert = ['nbconvert'],
183 nbconvert = ['nbconvert'],
183 )
184 )
184
185
185 install_requires = [
186 install_requires = [
186 'setuptools>=18.5',
187 'setuptools>=18.5',
187 'jedi>=0.16',
188 'jedi>=0.16',
188 'decorator',
189 'decorator',
189 'pickleshare',
190 'pickleshare',
190 'traitlets>=4.2',
191 'traitlets>=4.2',
191 'prompt_toolkit>=2.0.0,<3.1.0,!=3.0.0,!=3.0.1',
192 'prompt_toolkit>=2.0.0,<3.1.0,!=3.0.0,!=3.0.1',
192 'pygments',
193 'pygments',
193 'backcall',
194 'backcall',
194 'stack_data',
195 'stack_data',
195 ]
196 ]
196
197
197 # Platform-specific dependencies:
198 # Platform-specific dependencies:
198 # This is the correct way to specify these,
199 # This is the correct way to specify these,
199 # but requires pip >= 6. pip < 6 ignores these.
200 # but requires pip >= 6. pip < 6 ignores these.
200
201
201 extras_require.update({
202 extras_require.update({
202 ':sys_platform != "win32"': ['pexpect'],
203 ':sys_platform != "win32"': ['pexpect'],
203 ':sys_platform == "darwin"': ['appnope'],
204 ':sys_platform == "darwin"': ['appnope'],
204 ':sys_platform == "win32"': ['colorama'],
205 ':sys_platform == "win32"': ['colorama'],
205 })
206 })
206 # FIXME: re-specify above platform dependencies for pip < 6
207 # FIXME: re-specify above platform dependencies for pip < 6
207 # These would result in non-portable bdists.
208 # These would result in non-portable bdists.
208 if not any(arg.startswith('bdist') for arg in sys.argv):
209 if not any(arg.startswith('bdist') for arg in sys.argv):
209 if sys.platform == 'darwin':
210 if sys.platform == 'darwin':
210 install_requires.extend(['appnope'])
211 install_requires.extend(['appnope'])
211
212
212 if not sys.platform.startswith('win'):
213 if not sys.platform.startswith('win'):
213 install_requires.append('pexpect')
214 install_requires.append('pexpect')
214
215
215 # workaround pypa/setuptools#147, where setuptools misspells
216 # workaround pypa/setuptools#147, where setuptools misspells
216 # platform_python_implementation as python_implementation
217 # platform_python_implementation as python_implementation
217 if 'setuptools' in sys.modules:
218 if 'setuptools' in sys.modules:
218 for key in list(extras_require):
219 for key in list(extras_require):
219 if 'platform_python_implementation' in key:
220 if 'platform_python_implementation' in key:
220 new_key = key.replace('platform_python_implementation', 'python_implementation')
221 new_key = key.replace('platform_python_implementation', 'python_implementation')
221 extras_require[new_key] = extras_require.pop(key)
222 extras_require[new_key] = extras_require.pop(key)
222
223
223 everything = set()
224 everything = set()
224 for key, deps in extras_require.items():
225 for key, deps in extras_require.items():
225 if ':' not in key:
226 if ':' not in key:
226 everything.update(deps)
227 everything.update(deps)
227 extras_require['all'] = list(sorted(everything))
228 extras_require['all'] = list(sorted(everything))
228
229
229 if 'setuptools' in sys.modules:
230 if 'setuptools' in sys.modules:
230 setuptools_extra_args['python_requires'] = '>=3.6'
231 setuptools_extra_args['python_requires'] = '>=3.7'
231 setuptools_extra_args['zip_safe'] = False
232 setuptools_extra_args['zip_safe'] = False
232 setuptools_extra_args['entry_points'] = {
233 setuptools_extra_args['entry_points'] = {
233 'console_scripts': find_entry_points(),
234 'console_scripts': find_entry_points(),
234 'pygments.lexers': [
235 'pygments.lexers': [
235 'ipythonconsole = IPython.lib.lexers:IPythonConsoleLexer',
236 'ipythonconsole = IPython.lib.lexers:IPythonConsoleLexer',
236 'ipython = IPython.lib.lexers:IPythonLexer',
237 'ipython = IPython.lib.lexers:IPythonLexer',
237 'ipython3 = IPython.lib.lexers:IPython3Lexer',
238 'ipython3 = IPython.lib.lexers:IPython3Lexer',
238 ],
239 ],
239 }
240 }
240 setup_args['extras_require'] = extras_require
241 setup_args['extras_require'] = extras_require
241 setup_args['install_requires'] = install_requires
242 setup_args['install_requires'] = install_requires
242
243
243 else:
244 else:
244 # scripts has to be a non-empty list, or install_scripts isn't called
245 # scripts has to be a non-empty list, or install_scripts isn't called
245 setup_args['scripts'] = [e.split('=')[0].strip() for e in find_entry_points()]
246 setup_args['scripts'] = [e.split('=')[0].strip() for e in find_entry_points()]
246
247
247 setup_args['cmdclass']['build_scripts'] = build_scripts_entrypt
248 setup_args['cmdclass']['build_scripts'] = build_scripts_entrypt
248
249
249 #---------------------------------------------------------------------------
250 #---------------------------------------------------------------------------
250 # Do the actual setup now
251 # Do the actual setup now
251 #---------------------------------------------------------------------------
252 #---------------------------------------------------------------------------
252
253
253 setup_args.update(setuptools_extra_args)
254 setup_args.update(setuptools_extra_args)
254
255
255
256
256
257
257 def main():
258 def main():
258 setup(**setup_args)
259 setup(**setup_args)
259
260
260 if __name__ == '__main__':
261 if __name__ == '__main__':
261 main()
262 main()
General Comments 0
You need to be logged in to leave comments. Login now