Merge pull request #4975 from minrk/t2pp

setup.py changes for 2.0
This commit is contained in:
Thomas Kluyver 2014-02-04 17:39:12 -08:00
commit b8101613eb
2 changed files with 140 additions and 62 deletions

View File

@ -67,6 +67,7 @@ from setupbase import (
update_submodules, update_submodules,
require_submodules, require_submodules,
UpdateSubmodules, UpdateSubmodules,
get_bdist_wheel,
CompileCSS, CompileCSS,
JavascriptVersion, JavascriptVersion,
install_symlinked, install_symlinked,
@ -242,8 +243,8 @@ setup_args['cmdclass'] = {
# For some commands, use setuptools. Note that we do NOT list install here! # For some commands, use setuptools. Note that we do NOT list install here!
# If you want a setuptools-enhanced install, just run 'setupegg.py install' # If you want a setuptools-enhanced install, just run 'setupegg.py install'
needs_setuptools = set(('develop', 'release', 'bdist_egg', 'bdist_rpm', needs_setuptools = set(('develop', 'release', 'bdist_egg', 'bdist_rpm',
'bdist', 'bdist_dumb', 'bdist_wininst', 'install_egg_info', 'bdist', 'bdist_dumb', 'bdist_wininst', 'bdist_wheel',
'egg_info', 'easy_install', 'upload', 'egg_info', 'easy_install', 'upload', 'install_egg_info',
)) ))
if sys.platform == 'win32': if sys.platform == 'win32':
# Depend on setuptools for install on *Windows only* # Depend on setuptools for install on *Windows only*
@ -259,43 +260,38 @@ if len(needs_setuptools.intersection(sys.argv)) > 0:
# specific to setup # specific to setup
setuptools_extra_args = {} setuptools_extra_args = {}
# setuptools requirements
extras_require = dict(
parallel = ['pyzmq>=2.1.11'],
qtconsole = ['pyzmq>=2.1.11', 'pygments'],
zmq = ['pyzmq>=2.1.11'],
doc = ['Sphinx>=1.1', 'numpydoc'],
test = ['nose>=0.10.1'],
notebook = ['tornado>=3.1', 'pyzmq>=2.1.11', 'jinja2'],
nbconvert = ['pygments', 'jinja2', 'Sphinx>=0.3']
)
everything = set()
for deps in extras_require.values():
everything.update(deps)
extras_require['all'] = everything
install_requires = []
if sys.platform == 'darwin':
install_requires.append('readline')
elif sys.platform.startswith('win'):
# Pyreadline has unicode and Python 3 fixes in 2.0
install_requires.append('pyreadline>=2.0')
if 'setuptools' in sys.modules: if 'setuptools' in sys.modules:
# setup.py develop should check for submodules # setup.py develop should check for submodules
from setuptools.command.develop import develop from setuptools.command.develop import develop
setup_args['cmdclass']['develop'] = require_submodules(develop) setup_args['cmdclass']['develop'] = require_submodules(develop)
setup_args['cmdclass']['bdist_wheel'] = get_bdist_wheel()
setuptools_extra_args['zip_safe'] = False setuptools_extra_args['zip_safe'] = False
setuptools_extra_args['entry_points'] = {'console_scripts':find_entry_points()} setuptools_extra_args['entry_points'] = {'console_scripts':find_entry_points()}
setup_args['extras_require'] = dict( setup_args['extras_require'] = extras_require
parallel = 'pyzmq>=2.1.11', requires = setup_args['install_requires'] = install_requires
qtconsole = ['pyzmq>=2.1.11', 'pygments'],
zmq = 'pyzmq>=2.1.11',
doc = ['Sphinx>=1.1', 'numpydoc'],
test = 'nose>=0.10.1',
notebook = ['tornado>=3.1', 'pyzmq>=2.1.11', 'jinja2'],
nbconvert = ['pygments', 'jinja2', 'Sphinx>=0.3']
)
everything = set()
for deps in setup_args['extras_require'].values():
if not isinstance(deps, list):
deps = [deps]
for dep in deps:
everything.add(dep)
setup_args['extras_require']['all'] = everything
requires = setup_args.setdefault('install_requires', [])
setupext.display_status = False
if not setupext.check_for_readline():
if sys.platform == 'darwin':
requires.append('readline')
elif sys.platform.startswith('win'):
# Pyreadline 64 bit windows issue solved in versions >=1.7.1
# Also solves issues with some older versions of pyreadline that
# satisfy the unconstrained depdendency.
requires.append('pyreadline>=1.7.1')
else:
pass
# do we want to install readline here?
# Script to be run by the windows binary installer after the default setup # Script to be run by the windows binary installer after the default setup
# routine, to add shortcuts and similar windows-only things. Windows # routine, to add shortcuts and similar windows-only things. Windows
@ -314,10 +310,13 @@ if 'setuptools' in sys.modules:
"ipython_win_post_install.py"}} "ipython_win_post_install.py"}}
else: else:
# If we are running without setuptools, call this function which will # If we are installing without setuptools, call this function which will
# check for dependencies an inform the user what is needed. This is # check for dependencies an inform the user what is needed. This is
# just to make life easy for users. # just to make life easy for users.
check_for_dependencies() for install_cmd in ('install', 'symlink'):
if install_cmd in sys.argv:
check_for_dependencies()
break
# scripts has to be a non-empty list, or install_scripts isn't called # 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['scripts'] = [e.split('=')[0].strip() for e in find_entry_points()]

View File

@ -127,23 +127,44 @@ def find_package_data():
# This is not enough for these things to appear in an sdist. # This is not enough for these things to appear in an sdist.
# We need to muck with the MANIFEST to get this to work # We need to muck with the MANIFEST to get this to work
# exclude static things that we don't ship (e.g. mathjax) # exclude components from the walk,
excludes = ['mathjax'] # we will build the components separately
excludes = ['components']
# add 'static/' prefix to exclusions, and tuplify for use in startswith # add 'static/' prefix to exclusions, and tuplify for use in startswith
excludes = tuple([os.path.join('static', ex) for ex in excludes]) excludes = tuple([pjoin('static', ex) for ex in excludes])
# walk notebook resources: # walk notebook resources:
cwd = os.getcwd() cwd = os.getcwd()
os.chdir(os.path.join('IPython', 'html')) os.chdir(os.path.join('IPython', 'html'))
static_walk = list(os.walk('static'))
static_data = [] static_data = []
for parent, dirs, files in static_walk: for parent, dirs, files in os.walk('static'):
if parent.startswith(excludes): if parent.startswith(excludes):
continue continue
for f in files: for f in files:
static_data.append(os.path.join(parent, f)) static_data.append(pjoin(parent, f))
components = pjoin("static", "components")
# select the components we actually need to install
# (there are lots of resources we bundle for sdist-reasons that we don't actually use)
static_data.extend([
pjoin(components, "backbone", "backbone-min.js"),
pjoin(components, "bootstrap", "bootstrap", "js", "bootstrap.min.js"),
pjoin(components, "font-awesome", "font", "*.*"),
pjoin(components, "highlight.js", "build", "highlight.pack.js"),
pjoin(components, "jquery", "jquery.min.js"),
pjoin(components, "jquery-ui", "ui", "minified", "jquery-ui.min.js"),
pjoin(components, "jquery-ui", "themes", "smoothness", "jquery-ui.min.css"),
pjoin(components, "marked", "lib", "marked.js"),
pjoin(components, "requirejs", "require.js"),
pjoin(components, "underscore", "underscore-min.js"),
])
# Ship all of Codemirror's CSS and JS
for parent, dirs, files in os.walk(pjoin(components, 'codemirror')):
for f in files:
if f.endswith(('.js', '.css')):
static_data.append(pjoin(parent, f))
os.chdir(os.path.join('tests',)) os.chdir(os.path.join('tests',))
js_tests = glob('casperjs/*.*') + glob('casperjs/*/*') js_tests = glob('casperjs/*.*') + glob('casperjs/*/*')
@ -157,7 +178,6 @@ def find_package_data():
'IPython.config.profile' : ['README*', '*/*.py'], 'IPython.config.profile' : ['README*', '*/*.py'],
'IPython.core.tests' : ['*.png', '*.jpg'], 'IPython.core.tests' : ['*.png', '*.jpg'],
'IPython.lib.tests' : ['*.wav'], 'IPython.lib.tests' : ['*.wav'],
'IPython.testing' : ['*.txt'],
'IPython.testing.plugin' : ['*.txt'], 'IPython.testing.plugin' : ['*.txt'],
'IPython.html' : ['templates/*'] + static_data, 'IPython.html' : ['templates/*'] + static_data,
'IPython.html.tests' : js_tests, 'IPython.html.tests' : js_tests,
@ -167,6 +187,17 @@ def find_package_data():
'IPython.nbconvert.filters' : ['marked.js'], 'IPython.nbconvert.filters' : ['marked.js'],
'IPython.nbformat' : ['tests/*.ipynb'] 'IPython.nbformat' : ['tests/*.ipynb']
} }
# verify that package_data makes sense
for pkg, data in package_data.items():
pkg_root = pjoin(*pkg.split('.'))
for d in data:
path = pjoin(pkg_root, d)
if '*' in path:
assert len(glob(path)) > 0, "No files match pattern %s" % path
else:
assert os.path.exists(path), "Missing package data: %s" % path
return package_data return package_data
@ -215,10 +246,9 @@ def find_data_files():
""" """
Find IPython's data_files. Find IPython's data_files.
Most of these are docs. Just man pages at this point.
""" """
docdirbase = pjoin('share', 'doc', 'ipython')
manpagebase = pjoin('share', 'man', 'man1') manpagebase = pjoin('share', 'man', 'man1')
# Simple file lists can be made by hand # Simple file lists can be made by hand
@ -227,24 +257,8 @@ def find_data_files():
# When running from a source tree, the manpages aren't gzipped # When running from a source tree, the manpages aren't gzipped
manpages = [f for f in glob(pjoin('docs','man','*.1')) if isfile(f)] manpages = [f for f in glob(pjoin('docs','man','*.1')) if isfile(f)]
igridhelpfiles = [f for f in glob(pjoin('IPython','extensions','igrid_help.*')) if isfile(f)]
# For nested structures, use the utility above
example_files = make_dir_struct(
'data',
pjoin('docs','examples'),
pjoin(docdirbase,'examples')
)
manual_files = make_dir_struct(
'data',
pjoin('docs','html'),
pjoin(docdirbase,'manual')
)
# And assemble the entire output list # And assemble the entire output list
data_files = [ (manpagebase, manpages), data_files = [ (manpagebase, manpages) ]
(pjoin(docdirbase, 'extensions'), igridhelpfiles),
] + manual_files + example_files
return data_files return data_files
@ -452,7 +466,8 @@ def check_for_dependencies():
check_for_sphinx() check_for_sphinx()
check_for_pygments() check_for_pygments()
check_for_nose() check_for_nose()
check_for_pexpect() if os.name == 'posix':
check_for_pexpect()
check_for_pyzmq() check_for_pyzmq()
check_for_tornado() check_for_tornado()
check_for_readline() check_for_readline()
@ -555,6 +570,70 @@ def require_submodules(command):
command.run(self) command.run(self)
return DecoratedCommand return DecoratedCommand
#---------------------------------------------------------------------------
# bdist related
#---------------------------------------------------------------------------
def get_bdist_wheel():
"""Construct bdist_wheel command for building wheels
Constructs py2-none-any tag, instead of py2.7-none-any
"""
class RequiresWheel(Command):
description = "Dummy command for missing bdist_wheel"
user_options = []
def initialize_options(self):
pass
def finalize_options(self):
pass
def run(self):
print("bdist_wheel requires the wheel package")
sys.exit(1)
if 'setuptools' not in sys.modules:
return RequiresWheel
else:
try:
from wheel.bdist_wheel import bdist_wheel, read_pkg_info, write_pkg_info
except ImportError:
return RequiresWheel
class bdist_wheel_tag(bdist_wheel):
def get_tag(self):
return ('py%i' % sys.version_info[0], 'none', 'any')
def add_requirements(self, metadata_path):
"""transform platform-dependent requirements"""
pkg_info = read_pkg_info(metadata_path)
# pkg_info is an email.Message object (?!)
# we have to remove the unconditional 'readline' and/or 'pyreadline' entries
# and transform them to conditionals
requires = pkg_info.get_all('Requires-Dist')
del pkg_info['Requires-Dist']
def _remove_startswith(lis, prefix):
"""like list.remove, but with startswith instead of =="""
found = False
for idx, item in enumerate(lis):
if item.startswith(prefix):
found = True
break
if found:
lis.pop(idx)
for pkg in ("readline", "pyreadline"):
_remove_startswith(requires, pkg)
requires.append("readline; sys.platform == 'darwin'")
requires.append("pyreadline (>=2.0); sys.platform == 'win32'")
for r in requires:
pkg_info['Requires-Dist'] = r
write_pkg_info(metadata_path, pkg_info)
return bdist_wheel_tag
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# Notebook related # Notebook related
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------