Skip to content

Commit 9b62327

Browse files
committedSep 7, 2011
Allow 'python setup.py install' to work correctly for either Python 2 or 3.
1 parent 2467d2e commit 9b62327

File tree

4 files changed

+300
-281
lines changed

4 files changed

+300
-281
lines changed
 

‎setup.py

100755100644
+5-265
Original file line numberDiff line numberDiff line change
@@ -1,270 +1,10 @@
1-
#!/usr/bin/env python
2-
# -*- coding: utf-8 -*-
3-
"""Setup script for IPython.
4-
5-
Under Posix environments it works like a typical setup.py script.
6-
Under Windows, the command sdist is not supported, since IPython
7-
requires 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.txt, distributed with this software.
18-
#-----------------------------------------------------------------------------
19-
20-
#-----------------------------------------------------------------------------
21-
# Minimal Python version sanity check
22-
#-----------------------------------------------------------------------------
1+
"""This calls the setup routine for Python 2 or 3 as required."""
232

243
import sys
254

26-
# This check is also made in IPython/__init__, don't forget to update both when
27-
# changing Python version requirements.
28-
if sys.version[0:3] < '2.6':
29-
error = """\
30-
ERROR: 'IPython requires Python Version 2.6 or above.'
31-
Exiting."""
32-
print >> sys.stderr, error
33-
sys.exit(1)
34-
35-
# At least we're on the python version we need, move on.
36-
37-
#-------------------------------------------------------------------------------
38-
# Imports
39-
#-------------------------------------------------------------------------------
40-
41-
# Stdlib imports
42-
import os
43-
import shutil
44-
45-
from glob import glob
46-
47-
# BEFORE importing distutils, remove MANIFEST. distutils doesn't properly
48-
# update it when the contents of directories change.
49-
if os.path.exists('MANIFEST'): os.remove('MANIFEST')
50-
51-
from distutils.core import setup
52-
53-
# Our own imports
54-
from IPython.utils.path import target_update
55-
56-
from setupbase import (
57-
setup_args,
58-
find_packages,
59-
find_package_data,
60-
find_scripts,
61-
find_data_files,
62-
check_for_dependencies,
63-
record_commit_info,
64-
)
65-
from setupext import setupext
66-
67-
isfile = os.path.isfile
68-
pjoin = os.path.join
69-
70-
#-----------------------------------------------------------------------------
71-
# Function definitions
72-
#-----------------------------------------------------------------------------
73-
74-
def cleanup():
75-
"""Clean up the junk left around by the build process"""
76-
if "develop" not in sys.argv:
77-
try:
78-
shutil.rmtree('ipython.egg-info')
79-
except:
80-
try:
81-
os.unlink('ipython.egg-info')
82-
except:
83-
pass
84-
85-
#-------------------------------------------------------------------------------
86-
# Handle OS specific things
87-
#-------------------------------------------------------------------------------
88-
89-
if os.name == 'posix':
90-
os_name = 'posix'
91-
elif os.name in ['nt','dos']:
92-
os_name = 'windows'
5+
if sys.version_info[0] >= 3:
6+
from setup3 import main
937
else:
94-
print 'Unsupported operating system:',os.name
95-
sys.exit(1)
96-
97-
# 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-
# actually works.
100-
if os_name == 'windows' and 'sdist' in sys.argv:
101-
print 'The sdist command is not available under Windows. Exiting.'
102-
sys.exit(1)
103-
104-
#-------------------------------------------------------------------------------
105-
# Things related to the IPython documentation
106-
#-------------------------------------------------------------------------------
107-
108-
# update the manuals when building a source dist
109-
if len(sys.argv) >= 2 and sys.argv[1] in ('sdist','bdist_rpm'):
110-
import textwrap
111-
112-
# List of things to be updated. Each entry is a triplet of args for
113-
# target_update()
114-
to_update = [
115-
# FIXME - Disabled for now: we need to redo an automatic way
116-
# of generating the magic info inside the rst.
117-
#('docs/magic.tex',
118-
#['IPython/Magic.py'],
119-
#"cd doc && ./update_magic.sh" ),
120-
121-
('docs/man/ipcluster.1.gz',
122-
['docs/man/ipcluster.1'],
123-
'cd docs/man && gzip -9c ipcluster.1 > ipcluster.1.gz'),
124-
125-
('docs/man/ipcontroller.1.gz',
126-
['docs/man/ipcontroller.1'],
127-
'cd docs/man && gzip -9c ipcontroller.1 > ipcontroller.1.gz'),
128-
129-
('docs/man/ipengine.1.gz',
130-
['docs/man/ipengine.1'],
131-
'cd docs/man && gzip -9c ipengine.1 > ipengine.1.gz'),
132-
133-
('docs/man/iplogger.1.gz',
134-
['docs/man/iplogger.1'],
135-
'cd docs/man && gzip -9c iplogger.1 > iplogger.1.gz'),
136-
137-
('docs/man/ipython.1.gz',
138-
['docs/man/ipython.1'],
139-
'cd docs/man && gzip -9c ipython.1 > ipython.1.gz'),
140-
141-
('docs/man/irunner.1.gz',
142-
['docs/man/irunner.1'],
143-
'cd docs/man && gzip -9c irunner.1 > irunner.1.gz'),
144-
145-
('docs/man/pycolor.1.gz',
146-
['docs/man/pycolor.1'],
147-
'cd docs/man && gzip -9c pycolor.1 > pycolor.1.gz'),
148-
]
149-
150-
# Only build the docs if sphinx is present
151-
try:
152-
import sphinx
153-
except ImportError:
154-
pass
155-
else:
156-
# The Makefile calls the do_sphinx scripts to build html and pdf, so
157-
# just one target is enough to cover all manual generation
158-
159-
# First, compute all the dependencies that can force us to rebuild the
160-
# docs. Start with the main release file that contains metadata
161-
docdeps = ['IPython/core/release.py']
162-
# Inculde all the reST sources
163-
pjoin = os.path.join
164-
for dirpath,dirnames,filenames in os.walk('docs/source'):
165-
if dirpath in ['_static','_templates']:
166-
continue
167-
docdeps += [ pjoin(dirpath,f) for f in filenames
168-
if f.endswith('.txt') ]
169-
# and the examples
170-
for dirpath,dirnames,filenames in os.walk('docs/example'):
171-
docdeps += [ pjoin(dirpath,f) for f in filenames
172-
if not f.endswith('~') ]
173-
# then, make them all dependencies for the main html docs
174-
to_update.append(
175-
('docs/dist/index.html',
176-
docdeps,
177-
"cd docs && make dist")
178-
)
179-
180-
[ target_update(*t) for t in to_update ]
181-
182-
#---------------------------------------------------------------------------
183-
# Find all the packages, package data, and data_files
184-
#---------------------------------------------------------------------------
185-
186-
packages = find_packages()
187-
package_data = find_package_data()
188-
data_files = find_data_files()
189-
190-
#---------------------------------------------------------------------------
191-
# Handle scripts, dependencies, and setuptools specific things
192-
#---------------------------------------------------------------------------
193-
194-
# For some commands, use setuptools. Note that we do NOT list install here!
195-
# If you want a setuptools-enhanced install, just run 'setupegg.py install'
196-
needs_setuptools = set(('develop', 'sdist', 'release', 'bdist_egg', 'bdist_rpm',
197-
'bdist', 'bdist_dumb', 'bdist_wininst', 'install_egg_info',
198-
'build_sphinx', 'egg_info', 'easy_install', 'upload',
199-
))
200-
if sys.platform == 'win32':
201-
# Depend on setuptools for install on *Windows only*
202-
# If we get script-installation working without setuptools,
203-
# then we can back off, but until then use it.
204-
# See Issue #369 on GitHub for more
205-
needs_setuptools.add('install')
206-
207-
if len(needs_setuptools.intersection(sys.argv)) > 0:
208-
import setuptools
209-
210-
# This dict is used for passing extra arguments that are setuptools
211-
# specific to setup
212-
setuptools_extra_args = {}
213-
214-
if 'setuptools' in sys.modules:
215-
setuptools_extra_args['zip_safe'] = False
216-
setuptools_extra_args['entry_points'] = find_scripts(True)
217-
setup_args['extras_require'] = dict(
218-
parallel = 'pyzmq>=2.1.4',
219-
zmq = 'pyzmq>=2.1.4',
220-
doc = 'Sphinx>=0.3',
221-
test = 'nose>=0.10.1',
222-
notebook = 'tornado>=2.0'
223-
)
224-
requires = setup_args.setdefault('install_requires', [])
225-
setupext.display_status = False
226-
if not setupext.check_for_readline():
227-
if sys.platform == 'darwin':
228-
requires.append('readline')
229-
elif sys.platform.startswith('win') and sys.maxsize < 2**32:
230-
# only require pyreadline on 32b Windows, due to 64b bug in pyreadline:
231-
# https://bugs.launchpad.net/pyreadline/+bug/787574
232-
requires.append('pyreadline')
233-
else:
234-
pass
235-
# do we want to install readline here?
236-
237-
# Script to be run by the windows binary installer after the default setup
238-
# routine, to add shortcuts and similar windows-only things. Windows
239-
# post-install scripts MUST reside in the scripts/ dir, otherwise distutils
240-
# doesn't find them.
241-
if 'bdist_wininst' in sys.argv:
242-
if len(sys.argv) > 2 and \
243-
('sdist' in sys.argv or 'bdist_rpm' in sys.argv):
244-
print >> sys.stderr, "ERROR: bdist_wininst must be run alone. Exiting."
245-
sys.exit(1)
246-
setup_args['scripts'] = [pjoin('scripts','ipython_win_post_install.py')]
247-
setup_args['options'] = {"bdist_wininst":
248-
{"install_script":
249-
"ipython_win_post_install.py"}}
250-
else:
251-
# If we are running without setuptools, call this function which will
252-
# check for dependencies an inform the user what is needed. This is
253-
# just to make life easy for users.
254-
check_for_dependencies()
255-
setup_args['scripts'] = find_scripts(False)
256-
257-
#---------------------------------------------------------------------------
258-
# Do the actual setup now
259-
#---------------------------------------------------------------------------
260-
261-
setup_args['cmdclass'] = {'build_py': record_commit_info('IPython')}
262-
setup_args['packages'] = packages
263-
setup_args['package_data'] = package_data
264-
setup_args['data_files'] = data_files
265-
setup_args.update(setuptools_extra_args)
266-
8+
from setup2 import main
2679

268-
if __name__ == '__main__':
269-
setup(**setup_args)
270-
cleanup()
10+
main()

‎setup2.py

+272
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,272 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
"""Setup script for IPython.
4+
5+
Under Posix environments it works like a typical setup.py script.
6+
Under Windows, the command sdist is not supported, since IPython
7+
requires 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.txt, distributed with this software.
18+
#-----------------------------------------------------------------------------
19+
20+
#-----------------------------------------------------------------------------
21+
# Minimal Python version sanity check
22+
#-----------------------------------------------------------------------------
23+
24+
import sys
25+
26+
# This check is also made in IPython/__init__, don't forget to update both when
27+
# changing Python version requirements.
28+
if sys.version[0:3] < '2.6':
29+
error = """\
30+
ERROR: 'IPython requires Python Version 2.6 or above.'
31+
Exiting."""
32+
print >> sys.stderr, error
33+
sys.exit(1)
34+
35+
# At least we're on the python version we need, move on.
36+
37+
#-------------------------------------------------------------------------------
38+
# Imports
39+
#-------------------------------------------------------------------------------
40+
41+
# Stdlib imports
42+
import os
43+
import shutil
44+
45+
from glob import glob
46+
47+
# BEFORE importing distutils, remove MANIFEST. distutils doesn't properly
48+
# update it when the contents of directories change.
49+
if os.path.exists('MANIFEST'): os.remove('MANIFEST')
50+
51+
from distutils.core import setup
52+
53+
# Our own imports
54+
from IPython.utils.path import target_update
55+
56+
from setupbase import (
57+
setup_args,
58+
find_packages,
59+
find_package_data,
60+
find_scripts,
61+
find_data_files,
62+
check_for_dependencies,
63+
record_commit_info,
64+
)
65+
from setupext import setupext
66+
67+
isfile = os.path.isfile
68+
pjoin = os.path.join
69+
70+
#-----------------------------------------------------------------------------
71+
# Function definitions
72+
#-----------------------------------------------------------------------------
73+
74+
def cleanup():
75+
"""Clean up the junk left around by the build process"""
76+
if "develop" not in sys.argv:
77+
try:
78+
shutil.rmtree('ipython.egg-info')
79+
except:
80+
try:
81+
os.unlink('ipython.egg-info')
82+
except:
83+
pass
84+
85+
#-------------------------------------------------------------------------------
86+
# Handle OS specific things
87+
#-------------------------------------------------------------------------------
88+
89+
if os.name == 'posix':
90+
os_name = 'posix'
91+
elif os.name in ['nt','dos']:
92+
os_name = 'windows'
93+
else:
94+
print 'Unsupported operating system:',os.name
95+
sys.exit(1)
96+
97+
# 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+
# actually works.
100+
if os_name == 'windows' and 'sdist' in sys.argv:
101+
print 'The sdist command is not available under Windows. Exiting.'
102+
sys.exit(1)
103+
104+
#-------------------------------------------------------------------------------
105+
# Things related to the IPython documentation
106+
#-------------------------------------------------------------------------------
107+
108+
# update the manuals when building a source dist
109+
if len(sys.argv) >= 2 and sys.argv[1] in ('sdist','bdist_rpm'):
110+
import textwrap
111+
112+
# List of things to be updated. Each entry is a triplet of args for
113+
# target_update()
114+
to_update = [
115+
# FIXME - Disabled for now: we need to redo an automatic way
116+
# of generating the magic info inside the rst.
117+
#('docs/magic.tex',
118+
#['IPython/Magic.py'],
119+
#"cd doc && ./update_magic.sh" ),
120+
121+
('docs/man/ipcluster.1.gz',
122+
['docs/man/ipcluster.1'],
123+
'cd docs/man && gzip -9c ipcluster.1 > ipcluster.1.gz'),
124+
125+
('docs/man/ipcontroller.1.gz',
126+
['docs/man/ipcontroller.1'],
127+
'cd docs/man && gzip -9c ipcontroller.1 > ipcontroller.1.gz'),
128+
129+
('docs/man/ipengine.1.gz',
130+
['docs/man/ipengine.1'],
131+
'cd docs/man && gzip -9c ipengine.1 > ipengine.1.gz'),
132+
133+
('docs/man/iplogger.1.gz',
134+
['docs/man/iplogger.1'],
135+
'cd docs/man && gzip -9c iplogger.1 > iplogger.1.gz'),
136+
137+
('docs/man/ipython.1.gz',
138+
['docs/man/ipython.1'],
139+
'cd docs/man && gzip -9c ipython.1 > ipython.1.gz'),
140+
141+
('docs/man/irunner.1.gz',
142+
['docs/man/irunner.1'],
143+
'cd docs/man && gzip -9c irunner.1 > irunner.1.gz'),
144+
145+
('docs/man/pycolor.1.gz',
146+
['docs/man/pycolor.1'],
147+
'cd docs/man && gzip -9c pycolor.1 > pycolor.1.gz'),
148+
]
149+
150+
# Only build the docs if sphinx is present
151+
try:
152+
import sphinx
153+
except ImportError:
154+
pass
155+
else:
156+
# The Makefile calls the do_sphinx scripts to build html and pdf, so
157+
# just one target is enough to cover all manual generation
158+
159+
# First, compute all the dependencies that can force us to rebuild the
160+
# docs. Start with the main release file that contains metadata
161+
docdeps = ['IPython/core/release.py']
162+
# Inculde all the reST sources
163+
pjoin = os.path.join
164+
for dirpath,dirnames,filenames in os.walk('docs/source'):
165+
if dirpath in ['_static','_templates']:
166+
continue
167+
docdeps += [ pjoin(dirpath,f) for f in filenames
168+
if f.endswith('.txt') ]
169+
# and the examples
170+
for dirpath,dirnames,filenames in os.walk('docs/example'):
171+
docdeps += [ pjoin(dirpath,f) for f in filenames
172+
if not f.endswith('~') ]
173+
# then, make them all dependencies for the main html docs
174+
to_update.append(
175+
('docs/dist/index.html',
176+
docdeps,
177+
"cd docs && make dist")
178+
)
179+
180+
[ target_update(*t) for t in to_update ]
181+
182+
#---------------------------------------------------------------------------
183+
# Find all the packages, package data, and data_files
184+
#---------------------------------------------------------------------------
185+
186+
packages = find_packages()
187+
package_data = find_package_data()
188+
data_files = find_data_files()
189+
190+
#---------------------------------------------------------------------------
191+
# Handle scripts, dependencies, and setuptools specific things
192+
#---------------------------------------------------------------------------
193+
194+
# For some commands, use setuptools. Note that we do NOT list install here!
195+
# If you want a setuptools-enhanced install, just run 'setupegg.py install'
196+
needs_setuptools = set(('develop', 'sdist', 'release', 'bdist_egg', 'bdist_rpm',
197+
'bdist', 'bdist_dumb', 'bdist_wininst', 'install_egg_info',
198+
'build_sphinx', 'egg_info', 'easy_install', 'upload',
199+
))
200+
if sys.platform == 'win32':
201+
# Depend on setuptools for install on *Windows only*
202+
# If we get script-installation working without setuptools,
203+
# then we can back off, but until then use it.
204+
# See Issue #369 on GitHub for more
205+
needs_setuptools.add('install')
206+
207+
if len(needs_setuptools.intersection(sys.argv)) > 0:
208+
import setuptools
209+
210+
# This dict is used for passing extra arguments that are setuptools
211+
# specific to setup
212+
setuptools_extra_args = {}
213+
214+
if 'setuptools' in sys.modules:
215+
setuptools_extra_args['zip_safe'] = False
216+
setuptools_extra_args['entry_points'] = find_scripts(True)
217+
setup_args['extras_require'] = dict(
218+
parallel = 'pyzmq>=2.1.4',
219+
zmq = 'pyzmq>=2.1.4',
220+
doc = 'Sphinx>=0.3',
221+
test = 'nose>=0.10.1',
222+
notebook = 'tornado>=2.0'
223+
)
224+
requires = setup_args.setdefault('install_requires', [])
225+
setupext.display_status = False
226+
if not setupext.check_for_readline():
227+
if sys.platform == 'darwin':
228+
requires.append('readline')
229+
elif sys.platform.startswith('win') and sys.maxsize < 2**32:
230+
# only require pyreadline on 32b Windows, due to 64b bug in pyreadline:
231+
# https://bugs.launchpad.net/pyreadline/+bug/787574
232+
requires.append('pyreadline')
233+
else:
234+
pass
235+
# do we want to install readline here?
236+
237+
# Script to be run by the windows binary installer after the default setup
238+
# routine, to add shortcuts and similar windows-only things. Windows
239+
# post-install scripts MUST reside in the scripts/ dir, otherwise distutils
240+
# doesn't find them.
241+
if 'bdist_wininst' in sys.argv:
242+
if len(sys.argv) > 2 and \
243+
('sdist' in sys.argv or 'bdist_rpm' in sys.argv):
244+
print >> sys.stderr, "ERROR: bdist_wininst must be run alone. Exiting."
245+
sys.exit(1)
246+
setup_args['scripts'] = [pjoin('scripts','ipython_win_post_install.py')]
247+
setup_args['options'] = {"bdist_wininst":
248+
{"install_script":
249+
"ipython_win_post_install.py"}}
250+
else:
251+
# If we are running without setuptools, call this function which will
252+
# check for dependencies an inform the user what is needed. This is
253+
# just to make life easy for users.
254+
check_for_dependencies()
255+
setup_args['scripts'] = find_scripts(False)
256+
257+
#---------------------------------------------------------------------------
258+
# Do the actual setup now
259+
#---------------------------------------------------------------------------
260+
261+
setup_args['cmdclass'] = {'build_py': record_commit_info('IPython')}
262+
setup_args['packages'] = packages
263+
setup_args['package_data'] = package_data
264+
setup_args['data_files'] = data_files
265+
setup_args.update(setuptools_extra_args)
266+
267+
def main():
268+
setup(**setup_args)
269+
cleanup()
270+
271+
if __name__ == '__main__':
272+
main()

‎setup3.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@
33

44
from setupbase import (setup_args, find_scripts, find_packages)
55

6-
setup_args['entry_points'] = find_scripts(True)
6+
setup_args['entry_points'] = find_scripts(True, suffix='3')
77
setup_args['packages'] = find_packages()
88

9-
setup(use_2to3 = True, **setup_args)
9+
def main():
10+
setup(use_2to3 = True, **setup_args)
11+
12+
if __name__ == "__main__":
13+
main()

‎setupbase.py

+17-14
Original file line numberDiff line numberDiff line change
@@ -245,28 +245,31 @@ def make_man_update_target(manpage):
245245
# Find scripts
246246
#---------------------------------------------------------------------------
247247

248-
def find_scripts(entry_points=False):
248+
def find_scripts(entry_points=False, suffix=''):
249249
"""Find IPython's scripts.
250250
251251
if entry_points is True:
252252
return setuptools entry_point-style definitions
253253
else:
254254
return file paths of plain scripts [default]
255+
256+
suffix is appended to script names if entry_points is True, so that the
257+
Python 3 scripts get named "ipython3" etc.
255258
"""
256259
if entry_points:
257-
console_scripts = [
258-
'ipython = IPython.frontend.terminal.ipapp:launch_new_instance',
259-
'pycolor = IPython.utils.PyColorize:main',
260-
'ipcontroller = IPython.parallel.apps.ipcontrollerapp:launch_new_instance',
261-
'ipengine = IPython.parallel.apps.ipengineapp:launch_new_instance',
262-
'iplogger = IPython.parallel.apps.iploggerapp:launch_new_instance',
263-
'ipcluster = IPython.parallel.apps.ipclusterapp:launch_new_instance',
264-
'iptest = IPython.testing.iptest:main',
265-
'irunner = IPython.lib.irunner:main'
266-
]
267-
gui_scripts = [
268-
'ipython-qtconsole = IPython.frontend.qt.console.qtconsoleapp:main',
269-
]
260+
console_scripts = [s % suffix for s in [
261+
'ipython%s = IPython.frontend.terminal.ipapp:launch_new_instance',
262+
'pycolor%s = IPython.utils.PyColorize:main',
263+
'ipcontroller%s = IPython.parallel.apps.ipcontrollerapp:launch_new_instance',
264+
'ipengine%s = IPython.parallel.apps.ipengineapp:launch_new_instance',
265+
'iplogger%s = IPython.parallel.apps.iploggerapp:launch_new_instance',
266+
'ipcluster%s = IPython.parallel.apps.ipclusterapp:launch_new_instance',
267+
'iptest%s = IPython.testing.iptest:main',
268+
'irunner%s = IPython.lib.irunner:main'
269+
]]
270+
gui_scripts = [s % suffix for s in [
271+
'ipython%s-qtconsole = IPython.frontend.qt.console.qtconsoleapp:main',
272+
]]
270273
scripts = dict(console_scripts=console_scripts, gui_scripts=gui_scripts)
271274
else:
272275
parallel_scripts = pjoin('IPython','parallel','scripts')

0 commit comments

Comments
 (0)
Please sign in to comment.