##// END OF EJS Templates
reformat previous commit
reformat previous commit

File last commit:

r26943:69dbfc1c
r26943:69dbfc1c
Show More
setupbase.py
408 lines | 13.8 KiB | text/x-python | PythonLexer
Brian E Granger
Initial work towards refactoring the setup.py scripts to accept the new ipython1 packages...
r1237 # encoding: utf-8
Brian E Granger
Adding documentation to setup* files.
r1239 """
This module defines the things that are used in setup.py for building IPython
This includes:
* The basic arguments to setup
* Functions for finding things like packages, package data, etc.
* A function for checking dependencies.
"""
Brian E Granger
Initial work towards refactoring the setup.py scripts to accept the new ipython1 packages...
r1237
MinRK
add ipython[terminal] dependency group...
r16386 # Copyright (c) IPython Development Team.
# Distributed under the terms of the Modified BSD License.
Fernando Perez
Add utility to record commit information in archives/tarballs....
r3198 import os
farisachugthai
Cleanup: Remove distutils...
r26089 import re
Fernando Perez
Add utility to record commit information in archives/tarballs....
r3198 import sys
farisachugthai
Cleanup: Remove distutils...
r26089 from glob import glob
from logging import log
Brian E Granger
Initial work towards refactoring the setup.py scripts to accept the new ipython1 packages...
r1237
farisachugthai
Cleanup: Remove distutils...
r26089 from setuptools import Command
from setuptools.command.build_py import build_py
Matthias Bussonnier
autoreformat with darker
r26112
farisachugthai
Cleanup: Remove distutils...
r26089 # TODO: Replacement for this?
Thomas Kluyver
Fix renaming scripts with 3 suffix on Python 3
r13368 from distutils.command.build_scripts import build_scripts
farisachugthai
Cleanup: Remove distutils...
r26089 from setuptools.command.install import install
from setuptools.command.install_scripts import install_scripts
Brian E Granger
Initial work towards refactoring the setup.py scripts to accept the new ipython1 packages...
r1237
from setupext import install_data_ext
#-------------------------------------------------------------------------------
# Useful globals and utility functions
#-------------------------------------------------------------------------------
# A few handy globals
isfile = os.path.isfile
pjoin = os.path.join
Takafumi Arakaki
Fix: "python ABS/PATH/TO/ipython.py" fails...
r10610 repo_root = os.path.dirname(os.path.abspath(__file__))
Brian E Granger
Initial work towards refactoring the setup.py scripts to accept the new ipython1 packages...
r1237
Hugo
Remove redundant Python 2 code
r24010 def execfile(fname, globs, locs=None):
locs = locs or globs
Matthias Bussonnier
Properly close file in setupbase
r25078 with open(fname) as f:
exec(compile(f.read(), fname, "exec"), globs, locs)
Brian E Granger
Initial work towards refactoring the setup.py scripts to accept the new ipython1 packages...
r1237
# A little utility we'll need below, since glob() does NOT allow you to do
# exclusion on multiple endings!
def file_doesnt_endwith(test,endings):
"""Return true if test is a file and its name does NOT end with any
of the strings listed in endings."""
if not isfile(test):
return False
for e in endings:
if test.endswith(e):
return False
return True
#---------------------------------------------------------------------------
# Basic project information
#---------------------------------------------------------------------------
Brian Granger
Merging -r 1192 from lp:ipython.
r2146 # release.py contains version, authors, license, url, keywords, etc.
Takafumi Arakaki
Fix: "python ABS/PATH/TO/ipython.py" fails...
r10610 execfile(pjoin(repo_root, 'IPython','core','release.py'), globals())
Brian E Granger
Initial work towards refactoring the setup.py scripts to accept the new ipython1 packages...
r1237
# Create a dict with the basic information
# This dict is eventually passed to setup after additional keys are added.
setup_args = dict(
name = name,
version = version,
description = description,
long_description = long_description,
author = author,
author_email = author_email,
url = url,
license = license,
platforms = platforms,
keywords = keywords,
Thomas Kluyver
Add Trove classifiers for PyPI.
r4771 classifiers = classifiers,
Brian E Granger
Initial work towards refactoring the setup.py scripts to accept the new ipython1 packages...
r1237 cmdclass = {'install_data': install_data_ext},
Matthias Bussonnier
Add some extra metadata for PyPI (in the sidebar)...
r24517 project_urls={
'Documentation': 'https://ipython.readthedocs.io/',
'Funding' : 'https://numfocus.org/',
'Source' : 'https://github.com/ipython/ipython',
'Tracker' : 'https://github.com/ipython/ipython/issues',
}
Brian E Granger
Initial work towards refactoring the setup.py scripts to accept the new ipython1 packages...
r1237 )
#---------------------------------------------------------------------------
# Find packages
#---------------------------------------------------------------------------
def find_packages():
Brian E Granger
Adding documentation to setup* files.
r1239 """
Find all of IPython's packages.
"""
Thomas Kluyver
Exclude IPython.quarantine from installation.
r6492 excludes = ['deathrow', 'quarantine']
MinRK
Generate package list automatically in find_packages...
r4466 packages = []
Matthias Bussonnier
reformat previous commit
r26943 for directory, subdirs, files in os.walk("IPython"):
package = directory.replace(os.path.sep, ".")
if any(package.startswith("IPython." + exc) for exc in excludes):
MinRK
Generate package list automatically in find_packages...
r4466 # package is to be excluded (e.g. deathrow)
continue
if '__init__.py' not in files:
# not a package
continue
packages.append(package)
Brian E Granger
Initial work towards refactoring the setup.py scripts to accept the new ipython1 packages...
r1237 return packages
#---------------------------------------------------------------------------
# Find package data
#---------------------------------------------------------------------------
def find_package_data():
Brian E Granger
Adding documentation to setup* files.
r1239 """
Find IPython's package_data.
"""
Brian E Granger
Initial work towards refactoring the setup.py scripts to accept the new ipython1 packages...
r1237 # This is not enough for these things to appear in an sdist.
# We need to muck with the MANIFEST to get this to work
farisachugthai
Cleanup: Remove distutils...
r26089
Brian E Granger
package_data was missing the .txt files in the testing directories. This was causing ...
r1317 package_data = {
Min RK
remove bundled profiles...
r20870 'IPython.core' : ['profile/README*'],
Min RK
don't install test extension...
r21840 'IPython.core.tests' : ['*.png', '*.jpg', 'daft_extension/*.py'],
Thomas Kluyver
Add sample wav file to package_data
r13550 'IPython.lib.tests' : ['*.wav'],
MinRK
add missing plugin .txt to package_data
r7774 'IPython.testing.plugin' : ['*.txt'],
Brian E Granger
package_data was missing the .txt files in the testing directories. This was causing ...
r1317 }
farisachugthai
Cleanup: Remove distutils...
r26089
MinRK
only validate package_data when it might be used...
r15114 return package_data
MinRK
run check_package_data as part of build_py...
r15165
MinRK
only validate package_data when it might be used...
r15114 def check_package_data(package_data):
"""verify that package_data globs make sense"""
print("checking package data")
MinRK
validate package_data...
r15035 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
Brian E Granger
Initial work towards refactoring the setup.py scripts to accept the new ipython1 packages...
r1237
MinRK
run check_package_data as part of build_py...
r15165 def check_package_data_first(command):
"""decorator for checking package_data before running a given command
Matthias Bussonnier
Reformat some of the IPython docstrings.
r25884
MinRK
run check_package_data as part of build_py...
r15165 Probably only needs to wrap build_py
"""
class DecoratedCommand(command):
def run(self):
check_package_data(self.package_data)
command.run(self)
return DecoratedCommand
Brian E Granger
Initial work towards refactoring the setup.py scripts to accept the new ipython1 packages...
r1237
#---------------------------------------------------------------------------
# Find data files
#---------------------------------------------------------------------------
def find_data_files():
Brian E Granger
Adding documentation to setup* files.
r1239 """
Find IPython's data_files.
Fernando Perez
Fixes to build/setup machinery....
r1525
MinRK
we only install man pages to usr/share...
r15032 Just man pages at this point.
Brian E Granger
Adding documentation to setup* files.
r1239 """
Bernardo B. Marques
remove all trailling spaces
r4872
Po-Chuan Hsieh
Fix manpage path in FreeBSD...
r25130 if "freebsd" in sys.platform:
manpagebase = pjoin('man', 'man1')
else:
manpagebase = pjoin('share', 'man', 'man1')
Bernardo B. Marques
remove all trailling spaces
r4872
Fernando Perez
Fixes to build/setup machinery....
r1525 # Simple file lists can be made by hand
Thomas Robitaille
Fix a bug that caused man pages to not be installed in Python 3 when running from the source tree.
r8454 manpages = [f for f in glob(pjoin('docs','man','*.1.gz')) if isfile(f)]
Fernando Perez
Fix installation of manpages.
r4420 if not manpages:
# When running from a source tree, the manpages aren't gzipped
Thomas Robitaille
Fix a bug that caused man pages to not be installed in Python 3 when running from the source tree.
r8454 manpages = [f for f in glob(pjoin('docs','man','*.1')) if isfile(f)]
Fernando Perez
Fixes to build/setup machinery....
r1525 # And assemble the entire output list
MinRK
we only install man pages to usr/share...
r15032 data_files = [ (manpagebase, manpages) ]
Brian Granger
Lots of work on the display system, focused on pylab stuff....
r3280
Fernando Perez
Fixes to build system.
r1522 return data_files
Brian E Granger
Initial work towards refactoring the setup.py scripts to accept the new ipython1 packages...
r1237
Fernando Perez
Update setup and support tools to include new man pages.
r2100
Thomas Kluyver
Make single setup script work on Python 2 and Python 3.
r5828 # The two functions below are copied from IPython.utils.path, so we don't need
# to import IPython during setup, which fails on Python 3.
def target_outdated(target,deps):
"""Determine whether a target is out of date.
target_outdated(target,deps) -> 1/0
deps: list of filenames which MUST exist.
target: single filename which may or may not exist.
If target doesn't exist or is older than any file listed in deps, return
true, otherwise return false.
"""
try:
target_time = os.path.getmtime(target)
except os.error:
return 1
for dep in deps:
dep_time = os.path.getmtime(dep)
if dep_time > target_time:
#print "For target",target,"Dep failed:",dep # dbg
#print "times (dep,tar):",dep_time,target_time # dbg
return 1
return 0
def target_update(target,deps,cmd):
"""Update a target with a given command given a list of dependencies.
target_update(target,deps,cmd) -> runs cmd if target is outdated.
This is just a wrapper around target_outdated() which calls the given
command if target is outdated."""
if target_outdated(target,deps):
MinRK
fix system->os.system typo...
r6144 os.system(cmd)
Thomas Kluyver
Make single setup script work on Python 2 and Python 3.
r5828
Brian E Granger
Initial work towards refactoring the setup.py scripts to accept the new ipython1 packages...
r1237 #---------------------------------------------------------------------------
# Find scripts
#---------------------------------------------------------------------------
Thomas Kluyver
Rework setup to allow installing on Python 2 and 3....
r13452 def find_entry_points():
Thomas Kluyver
Update some docstrings
r18769 """Defines the command line entry points for IPython
Bernardo B. Marques
remove all trailling spaces
r4872
Thomas Kluyver
Update some docstrings
r18769 This always uses setuptools-style entry points. When setuptools is not in
use, our own build_scripts_entrypt class below parses these and builds
command line scripts.
Bernardo B. Marques
remove all trailling spaces
r4872
Thomas Kluyver
Update some docstrings
r18769 Each of our entry points gets both a plain name, e.g. ipython, and one
farisachugthai
Cleanup: Remove distutils...
r26089 suffixed with the Python major version number, e.g. ipython3.
Brian E Granger
Adding documentation to setup* files.
r1239 """
Thomas Kluyver
Rework setup to allow installing on Python 2 and 3....
r13452 ep = [
MinRK
use start_ipython in entry points...
r11177 'ipython%s = IPython:start_ipython',
Thomas Kluyver
Fix iptest setuptools entry point
r12618 'iptest%s = IPython.testing.iptestcontroller:main',
Evan Patterson
Make ipython-qtconsole a GUI script in setuptools.
r3838 ]
Thomas Kluyver
Rework setup to allow installing on Python 2 and 3....
r13452 suffix = str(sys.version_info[0])
return [e % '' for e in ep] + [e % suffix for e in ep]
script_src = """#!{executable}
Thomas Kluyver
Add comment to automatically generated scripts.
r13497 # This script was automatically generated by setup.py
MinRK
use if main block in entry points...
r13845 if __name__ == '__main__':
MinRK
move import into ifmain block
r13861 from {mod} import {func}
MinRK
use if main block in entry points...
r13845 {func}()
Thomas Kluyver
Rework setup to allow installing on Python 2 and 3....
r13452 """
class build_scripts_entrypt(build_scripts):
Thomas Kluyver
Update some docstrings
r18769 """Build the command line scripts
farisachugthai
Cleanup: Remove distutils...
r26089
Thomas Kluyver
Update some docstrings
r18769 Parse setuptools style entry points and write simple scripts to run the
target functions.
farisachugthai
Cleanup: Remove distutils...
r26089
Thomas Kluyver
Update some docstrings
r18769 On Windows, this also creates .cmd wrappers for the scripts so that you can
easily launch them from a command line.
"""
Thomas Kluyver
Rework setup to allow installing on Python 2 and 3....
r13452 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))
farisachugthai
Cleanup: Remove distutils...
r26089
Thomas Kluyver
Install on Windows without using setuptools...
r18768 if sys.platform == 'win32':
# Write .cmd wrappers for Windows so 'ipython' etc. work at the
# command line
cmd_file = os.path.join(self.build_dir, name + '.cmd')
Mickaël Schoentgen
Fix several DeprecationWarning: invalid escape sequence...
r24896 cmd = r'@"{python}" "%~dp0\{script}" %*\r\n'.format(
Thomas Kluyver
Install on Windows without using setuptools...
r18768 python=sys.executable, script=name)
log.info("Writing %s wrapper script" % cmd_file)
with open(cmd_file, 'w') as f:
f.write(cmd)
Thomas Kluyver
Rework setup to allow installing on Python 2 and 3....
r13452
return outfiles, outfiles
class install_lib_symlink(Command):
user_options = [
('install-dir=', 'd', "directory to install to"),
]
Evan Patterson
Make ipython-qtconsole a GUI script in setuptools.
r3838
Thomas Kluyver
Rework setup to allow installing on Python 2 and 3....
r13452 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')
Thomas Kluyver
If symlink already exists, clobber it with current one
r13857 if os.path.islink(dest):
print('removing existing symlink at %s' % dest)
os.unlink(dest)
Thomas Kluyver
Rework setup to allow installing on Python 2 and 3....
r13452 print('symlinking %s -> %s' % (pkg, dest))
Thomas Kluyver
If symlink already exists, clobber it with current one
r13857 os.symlink(pkg, dest)
Thomas Kluyver
Rework setup to allow installing on Python 2 and 3....
r13452
Thomas Kluyver
Add 'unsymlink command to remove the symlink
r13862 class unsymlink(install):
def run(self):
dest = os.path.join(self.install_lib, 'IPython')
if os.path.islink(dest):
print('removing symlink at %s' % dest)
os.unlink(dest)
else:
print('No symlink exists at %s' % dest)
Thomas Kluyver
Rework setup to allow installing on Python 2 and 3....
r13452
class install_symlinked(install):
def run(self):
if sys.platform == 'win32':
raise Exception("This doesn't work on Windows.")
Thomas Kluyver
Don't build Python modules unnecessarily before symlinking to site-packages
r13840
# Run all sub-commands (at least those that need to be run)
for cmd_name in self.get_sub_commands():
self.run_command(cmd_name)
farisachugthai
Cleanup: Remove distutils...
r26089
Thomas Kluyver
Rework setup to allow installing on Python 2 and 3....
r13452 # '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'.
farisachugthai
Cleanup: Remove distutils...
r26089
Thomas Kluyver
Rework setup to allow installing on Python 2 and 3....
r13452 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'),
)
Thomas Kluyver
Fix renaming scripts with 3 suffix on Python 3
r13368
Fernando Perez
Add utility to record commit information in archives/tarballs....
r3198
MinRK
ensure submodules exist prior to doing anything...
r10484 #---------------------------------------------------------------------------
# VCS related
#---------------------------------------------------------------------------
def git_prebuild(pkg_dir, build_cmd=build_py):
"""Return extended build or sdist command class for recording commit
Matthias Bussonnier
Reformat some of the IPython docstrings.
r25884
MinRK
store git commit hash in utils._sysinfo instead of hidden git_commit_info.ini data file.
r6315 records git commit in IPython.utils._sysinfo.commit
Matthias Bussonnier
Reformat some of the IPython docstrings.
r25884
MinRK
store git commit hash in utils._sysinfo instead of hidden git_commit_info.ini data file.
r6315 for use in IPython.utils.sysinfo.sys_info() calls after installation.
Fernando Perez
Add utility to record commit information in archives/tarballs....
r3198 """
farisachugthai
Cleanup: Remove distutils...
r26089
Fernando Perez
Add utility to record commit information in archives/tarballs....
r3198 class MyBuildPy(build_cmd):
''' Subclass to write commit data into installation tree '''
def run(self):
Matthias Bussonnier
Check verison number only at build time or pip install -e fails
r21989 # loose as `.dev` is suppose to be invalid
print("check version number")
Mickaël Schoentgen
Fix several DeprecationWarning: invalid escape sequence...
r24896 loose_pep440re = re.compile(r'^(\d+)\.(\d+)\.(\d+((a|b|rc)\d+)?)(\.post\d+)?(\.dev\d*)?$')
Thomas Kluyver
Don't import IPython to check version number in setup...
r22056 if not loose_pep440re.match(version):
raise ValueError("Version number '%s' is not valid (should match [N!]N(.N)*[{a|b|rc}N][.postN][.devN])" % version)
Matthias Bussonnier
Check verison number only at build time or pip install -e fails
r21989
Thomas Kluyver
Fix IPython.utils.sysinfo for Python 3.
r4900 build_cmd.run(self)
MinRK
record sysinfo in sdist...
r7794 # this one will only fire for build commands
if hasattr(self, 'build_lib'):
self._record_commit(self.build_lib)
farisachugthai
Cleanup: Remove distutils...
r26089
MinRK
record sysinfo in sdist...
r7794 def make_release_tree(self, base_dir, files):
# this one will fire for sdist
build_cmd.make_release_tree(self, base_dir, files)
self._record_commit(base_dir)
farisachugthai
Cleanup: Remove distutils...
r26089
MinRK
record sysinfo in sdist...
r7794 def _record_commit(self, base_dir):
Fernando Perez
Add utility to record commit information in archives/tarballs....
r3198 import subprocess
proc = subprocess.Popen('git rev-parse --short HEAD',
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
shell=True)
repo_commit, _ = proc.communicate()
MinRK
record sysinfo in sdist...
r7794 repo_commit = repo_commit.strip().decode("ascii")
farisachugthai
Cleanup: Remove distutils...
r26089
MinRK
record sysinfo in sdist...
r7794 out_pth = pjoin(base_dir, pkg_dir, 'utils', '_sysinfo.py')
if os.path.isfile(out_pth) and not repo_commit:
# nothing to write, don't clobber
return
farisachugthai
Cleanup: Remove distutils...
r26089
MinRK
record sysinfo in sdist...
r7794 print("writing git commit '%s' to %s" % (repo_commit, out_pth))
farisachugthai
Cleanup: Remove distutils...
r26089
MinRK
record sysinfo in sdist...
r7794 # remove to avoid overwriting original via hard link
try:
os.remove(out_pth)
except (IOError, OSError):
pass
Thomas Kluyver
Fix writing git commit ID to a file on build with Python 3.
r6449 with open(out_pth, 'w') as out_file:
out_file.writelines([
Fernando Perez
Emergency fix for py3 breakage introduced in 576f6f (merge of #1538)...
r6446 '# GENERATED BY setup.py\n',
Matthias Bussonnier
cast unicode to allow json dump
r18039 'commit = u"%s"\n' % repo_commit,
Thomas Kluyver
Fix writing git commit ID to a file on build with Python 3.
r6449 ])
Min RK
remove notebook-specific parts of setup, git-hooks
r21249 return MyBuildPy
MinRK
ensure submodules exist prior to doing anything...
r10484