Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setup for Python 2/3 #4473

Merged
merged 3 commits into from Nov 5, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 0 additions & 16 deletions IPython/parallel/scripts/__init__.py

This file was deleted.

16 changes: 0 additions & 16 deletions IPython/parallel/scripts/ipcluster

This file was deleted.

16 changes: 0 additions & 16 deletions IPython/parallel/scripts/ipcontroller

This file was deleted.

16 changes: 0 additions & 16 deletions IPython/parallel/scripts/ipengine

This file was deleted.

16 changes: 0 additions & 16 deletions IPython/parallel/scripts/iplogger

This file was deleted.

Empty file removed IPython/scripts/__init__.py
Empty file.
24 changes: 0 additions & 24 deletions IPython/scripts/iptest

This file was deleted.

6 changes: 0 additions & 6 deletions IPython/scripts/ipython

This file was deleted.

9 changes: 0 additions & 9 deletions IPython/scripts/irunner

This file was deleted.

21 changes: 13 additions & 8 deletions setup.py
Expand Up @@ -58,8 +58,8 @@
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,
Expand All @@ -68,6 +68,9 @@
require_submodules,
UpdateSubmodules,
CompileCSS,
install_symlinked,
install_lib_symlink,
install_scripts_for_symlink,
)
from setupext import setupext

Expand Down Expand Up @@ -148,7 +151,6 @@ def 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()
Expand Down Expand Up @@ -231,6 +233,9 @@ def run(self):
'upload_wininst' : UploadWindowsInstallers,
'submodule' : UpdateSubmodules,
'css' : CompileCSS,
'symlink': install_symlinked,
'install_lib_symlink': install_lib_symlink,
'install_scripts_sym': install_scripts_for_symlink,
}

#---------------------------------------------------------------------------
Expand Down Expand Up @@ -263,7 +268,7 @@ def run(self):
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'],
Expand Down Expand Up @@ -316,10 +321,10 @@ def run(self):
# 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
Expand Down
117 changes: 82 additions & 35 deletions setupbase.py
Expand Up @@ -20,15 +20,14 @@
#-------------------------------------------------------------------------------
# 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
Expand Down Expand Up @@ -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:
Expand All @@ -322,46 +321,94 @@ 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',
'iplogger%s = IPython.parallel.apps.iploggerapp:launch_new_instance',
'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]

script_src = """#!{executable}
# This script was automatically generated by setup.py
from {mod} import {func}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Want to add a comment that thoses script are autogenerated by setup.py ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems sensible. Done.

{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

class build_scripts_rename(build_scripts):
"""Use this on Python 3 to rename scripts to ipython3 etc."""
_suffix = '3'
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
Expand Down