mirror of
https://github.com/jupyter/notebook.git
synced 2025-01-24 12:05:22 +08:00
Rework setup to allow installing on Python 2 and 3.
Scripts named ipython and ipython[23], etc. Neither distutils nor setuptools made this easy.
This commit is contained in:
parent
c4b9e69793
commit
883c46b5b5
21
setup.py
21
setup.py
@ -58,8 +58,8 @@ from setupbase import (
|
||||
setup_args,
|
||||
find_packages,
|
||||
find_package_data,
|
||||
find_scripts,
|
||||
build_scripts_rename,
|
||||
find_entry_points,
|
||||
build_scripts_entrypt,
|
||||
find_data_files,
|
||||
check_for_dependencies,
|
||||
git_prebuild,
|
||||
@ -68,6 +68,9 @@ from setupbase import (
|
||||
require_submodules,
|
||||
UpdateSubmodules,
|
||||
CompileCSS,
|
||||
install_symlinked,
|
||||
install_lib_symlink,
|
||||
install_scripts_for_symlink,
|
||||
)
|
||||
from setupext import setupext
|
||||
|
||||
@ -148,7 +151,6 @@ require_clean_submodules()
|
||||
|
||||
# update the manuals when building a source dist
|
||||
if len(sys.argv) >= 2 and sys.argv[1] in ('sdist','bdist_rpm'):
|
||||
import textwrap
|
||||
|
||||
# List of things to be updated. Each entry is a triplet of args for
|
||||
# target_update()
|
||||
@ -231,6 +233,9 @@ setup_args['cmdclass'] = {
|
||||
'upload_wininst' : UploadWindowsInstallers,
|
||||
'submodule' : UpdateSubmodules,
|
||||
'css' : CompileCSS,
|
||||
'symlink': install_symlinked,
|
||||
'install_lib_symlink': install_lib_symlink,
|
||||
'install_scripts_sym': install_scripts_for_symlink,
|
||||
}
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
@ -263,7 +268,7 @@ if 'setuptools' in sys.modules:
|
||||
setup_args['cmdclass']['develop'] = require_submodules(develop)
|
||||
|
||||
setuptools_extra_args['zip_safe'] = False
|
||||
setuptools_extra_args['entry_points'] = find_scripts(True, suffix = '3' if PY3 else '')
|
||||
setuptools_extra_args['entry_points'] = {'console_scripts':find_entry_points()}
|
||||
setup_args['extras_require'] = dict(
|
||||
parallel = 'pyzmq>=2.1.11',
|
||||
qtconsole = ['pyzmq>=2.1.11', 'pygments'],
|
||||
@ -316,10 +321,10 @@ else:
|
||||
# check for dependencies an inform the user what is needed. This is
|
||||
# just to make life easy for users.
|
||||
check_for_dependencies()
|
||||
setup_args['scripts'] = find_scripts(False)
|
||||
if PY3:
|
||||
# Rename scripts with '3' suffix
|
||||
setup_args['cmdclass']['build_scripts'] = build_scripts_rename
|
||||
# scripts has to be a non-empty list, or install_scripts isn't called
|
||||
setup_args['scripts'] = [e.split('=')[0].strip() for e in find_entry_points()]
|
||||
|
||||
setup_args['cmdclass']['build_scripts'] = build_scripts_entrypt
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Do the actual setup now
|
||||
|
116
setupbase.py
116
setupbase.py
@ -20,15 +20,14 @@ from __future__ import print_function
|
||||
#-------------------------------------------------------------------------------
|
||||
# Imports
|
||||
#-------------------------------------------------------------------------------
|
||||
import errno
|
||||
import os
|
||||
import sys
|
||||
|
||||
try:
|
||||
from configparser import ConfigParser
|
||||
except:
|
||||
from ConfigParser import ConfigParser
|
||||
from distutils.command.build_py import build_py
|
||||
from distutils.command.build_scripts import build_scripts
|
||||
from distutils.command.install import install
|
||||
from distutils.command.install_scripts import install_scripts
|
||||
from distutils.cmd import Command
|
||||
from glob import glob
|
||||
from subprocess import call
|
||||
@ -311,7 +310,7 @@ def target_update(target,deps,cmd):
|
||||
# Find scripts
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
def find_scripts(entry_points=False, suffix=''):
|
||||
def find_entry_points():
|
||||
"""Find IPython's scripts.
|
||||
|
||||
if entry_points is True:
|
||||
@ -322,8 +321,7 @@ def find_scripts(entry_points=False, suffix=''):
|
||||
suffix is appended to script names if entry_points is True, so that the
|
||||
Python 3 scripts get named "ipython3" etc.
|
||||
"""
|
||||
if entry_points:
|
||||
console_scripts = [s % suffix for s in [
|
||||
ep = [
|
||||
'ipython%s = IPython:start_ipython',
|
||||
'ipcontroller%s = IPython.parallel.apps.ipcontrollerapp:launch_new_instance',
|
||||
'ipengine%s = IPython.parallel.apps.ipengineapp:launch_new_instance',
|
||||
@ -331,37 +329,85 @@ def find_scripts(entry_points=False, suffix=''):
|
||||
'ipcluster%s = IPython.parallel.apps.ipclusterapp:launch_new_instance',
|
||||
'iptest%s = IPython.testing.iptestcontroller:main',
|
||||
'irunner%s = IPython.lib.irunner:main',
|
||||
]]
|
||||
gui_scripts = []
|
||||
scripts = dict(console_scripts=console_scripts, gui_scripts=gui_scripts)
|
||||
else:
|
||||
parallel_scripts = pjoin('IPython','parallel','scripts')
|
||||
main_scripts = pjoin('IPython','scripts')
|
||||
scripts = [
|
||||
pjoin(parallel_scripts, 'ipengine'),
|
||||
pjoin(parallel_scripts, 'ipcontroller'),
|
||||
pjoin(parallel_scripts, 'ipcluster'),
|
||||
pjoin(parallel_scripts, 'iplogger'),
|
||||
pjoin(main_scripts, 'ipython'),
|
||||
pjoin(main_scripts, 'irunner'),
|
||||
pjoin(main_scripts, 'iptest')
|
||||
]
|
||||
return scripts
|
||||
suffix = str(sys.version_info[0])
|
||||
return [e % '' for e in ep] + [e % suffix for e in ep]
|
||||
|
||||
class build_scripts_rename(build_scripts):
|
||||
"""Use this on Python 3 to rename scripts to ipython3 etc."""
|
||||
_suffix = '3'
|
||||
script_src = """#!{executable}
|
||||
from {mod} import {func}
|
||||
{func}()
|
||||
"""
|
||||
|
||||
class build_scripts_entrypt(build_scripts):
|
||||
def run(self):
|
||||
self.mkpath(self.build_dir)
|
||||
outfiles = []
|
||||
for script in find_entry_points():
|
||||
name, entrypt = script.split('=')
|
||||
name = name.strip()
|
||||
entrypt = entrypt.strip()
|
||||
outfile = os.path.join(self.build_dir, name)
|
||||
outfiles.append(outfile)
|
||||
print('Writing script to', outfile)
|
||||
|
||||
mod, func = entrypt.split(':')
|
||||
with open(outfile, 'w') as f:
|
||||
f.write(script_src.format(executable=sys.executable,
|
||||
mod=mod, func=func))
|
||||
|
||||
return outfiles, outfiles
|
||||
|
||||
class install_lib_symlink(Command):
|
||||
user_options = [
|
||||
('install-dir=', 'd', "directory to install to"),
|
||||
]
|
||||
|
||||
def initialize_options(self):
|
||||
self.install_dir = None
|
||||
|
||||
def finalize_options(self):
|
||||
self.set_undefined_options('symlink',
|
||||
('install_lib', 'install_dir'),
|
||||
)
|
||||
|
||||
def run(self):
|
||||
if sys.platform == 'win32':
|
||||
raise Exception("This doesn't work on Windows.")
|
||||
pkg = os.path.join(os.getcwd(), 'IPython')
|
||||
dest = os.path.join(self.install_dir, 'IPython')
|
||||
print('symlinking %s -> %s' % (pkg, dest))
|
||||
try:
|
||||
os.symlink(pkg, dest)
|
||||
except OSError as e:
|
||||
if e.errno == errno.EEXIST:
|
||||
print('ALREADY EXISTS')
|
||||
else:
|
||||
raise
|
||||
|
||||
class install_symlinked(install):
|
||||
def run(self):
|
||||
if sys.platform == 'win32':
|
||||
raise Exception("This doesn't work on Windows.")
|
||||
install.run(self)
|
||||
|
||||
def copy_scripts(self):
|
||||
outfiles, updated_files = super(build_scripts_rename, self).copy_scripts()
|
||||
new_outfiles = [p + self._suffix for p in outfiles]
|
||||
updated_files = [p + self._suffix for p in updated_files]
|
||||
for old, new in zip(outfiles, new_outfiles):
|
||||
if os.path.exists(new):
|
||||
os.unlink(new)
|
||||
self.move_file(old, new)
|
||||
return new_outfiles, updated_files
|
||||
|
||||
# 'sub_commands': a list of commands this command might have to run to
|
||||
# get its work done. See cmd.py for more info.
|
||||
sub_commands = [('install_lib_symlink', lambda self:True),
|
||||
('install_scripts_sym', lambda self:True),
|
||||
]
|
||||
|
||||
class install_scripts_for_symlink(install_scripts):
|
||||
"""Redefined to get options from 'symlink' instead of 'install'.
|
||||
|
||||
I love distutils almost as much as I love setuptools.
|
||||
"""
|
||||
def finalize_options(self):
|
||||
self.set_undefined_options('build', ('build_scripts', 'build_dir'))
|
||||
self.set_undefined_options('symlink',
|
||||
('install_scripts', 'install_dir'),
|
||||
('force', 'force'),
|
||||
('skip_build', 'skip_build'),
|
||||
)
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Verify all dependencies
|
||||
|
Loading…
Reference in New Issue
Block a user