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