##// END OF EJS Templates
Update package metadata
Matthias Bussonnier -
Show More
@@ -1,125 +1,123 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Release data for the IPython project."""
3 3
4 4 #-----------------------------------------------------------------------------
5 5 # Copyright (c) 2008, IPython Development Team.
6 6 # Copyright (c) 2001, Fernando Perez <fernando.perez@colorado.edu>
7 7 # Copyright (c) 2001, Janko Hauser <jhauser@zscout.de>
8 8 # Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu>
9 9 #
10 10 # Distributed under the terms of the Modified BSD License.
11 11 #
12 12 # The full license is in the file COPYING.txt, distributed with this software.
13 13 #-----------------------------------------------------------------------------
14 14
15 15 # Name of the package for release purposes. This is the name which labels
16 16 # the tarballs and RPMs made by distutils, so it's best to lowercase it.
17 17 name = 'ipython'
18 18
19 19 # IPython version information. An empty _version_extra corresponds to a full
20 20 # release. 'dev' as a _version_extra string means this is a development
21 21 # version
22 22 _version_major = 4
23 23 _version_minor = 1
24 24 _version_patch = 0
25 25 _version_extra = '.dev'
26 26 #_version_extra = 'rc1'
27 27 # _version_extra = '' # Uncomment this for full releases
28 28
29 29 # release.codename is deprecated in 2.0, will be removed in 3.0
30 30 codename = ''
31 31
32 32 # Construct full version string from these.
33 33 _ver = [_version_major, _version_minor, _version_patch]
34 34
35 35 __version__ = '.'.join(map(str, _ver))
36 36 if _version_extra:
37 37 __version__ = __version__ + _version_extra
38 38
39 39 version = __version__ # backwards compatibility name
40 40 version_info = (_version_major, _version_minor, _version_patch, _version_extra)
41 41
42 42 # Change this when incrementing the kernel protocol version
43 43 kernel_protocol_version_info = (5, 0)
44 44 kernel_protocol_version = "%i.%i" % kernel_protocol_version_info
45 45
46 46 description = "IPython: Productive Interactive Computing"
47 47
48 48 long_description = \
49 49 """
50 50 IPython provides a rich toolkit to help you make the most out of using Python
51 51 interactively. Its main components are:
52 52
53 53 * A powerful interactive Python shell
54 54 * A `Jupyter <http://jupyter.org/>`_ kernel to work with Python code in Jupyter
55 55 notebooks and other interactive frontends.
56 56
57 57 The enhanced interactive Python shells have the following main features:
58 58
59 59 * Comprehensive object introspection.
60 60
61 61 * Input history, persistent across sessions.
62 62
63 63 * Caching of output results during a session with automatically generated
64 64 references.
65 65
66 66 * Extensible tab completion, with support by default for completion of python
67 67 variables and keywords, filenames and function keywords.
68 68
69 69 * Extensible system of 'magic' commands for controlling the environment and
70 70 performing many tasks related either to IPython or the operating system.
71 71
72 72 * A rich configuration system with easy switching between different setups
73 73 (simpler than changing $PYTHONSTARTUP environment variables every time).
74 74
75 75 * Session logging and reloading.
76 76
77 77 * Extensible syntax processing for special purpose situations.
78 78
79 79 * Access to the system shell with user-extensible alias system.
80 80
81 81 * Easily embeddable in other Python programs and GUIs.
82 82
83 83 * Integrated access to the pdb debugger and the Python profiler.
84 84
85 85 The latest development version is always available from IPython's `GitHub
86 86 site <http://github.com/ipython>`_.
87 87 """
88 88
89 89 license = 'BSD'
90 90
91 91 authors = {'Fernando' : ('Fernando Perez','fperez.net@gmail.com'),
92 92 'Janko' : ('Janko Hauser','jhauser@zscout.de'),
93 93 'Nathan' : ('Nathaniel Gray','n8gray@caltech.edu'),
94 94 'Ville' : ('Ville Vainio','vivainio@gmail.com'),
95 95 'Brian' : ('Brian E Granger', 'ellisonbg@gmail.com'),
96 96 'Min' : ('Min Ragan-Kelley', 'benjaminrk@gmail.com'),
97 97 'Thomas' : ('Thomas A. Kluyver', 'takowl@gmail.com'),
98 98 'Jorgen' : ('Jorgen Stenarson', 'jorgen.stenarson@bostream.nu'),
99 99 'Matthias' : ('Matthias Bussonnier', 'bussonniermatthias@gmail.com'),
100 100 }
101 101
102 102 author = 'The IPython Development Team'
103 103
104 104 author_email = 'ipython-dev@scipy.org'
105 105
106 106 url = 'http://ipython.org'
107 107
108 download_url = 'https://github.com/ipython/ipython/downloads'
109 108
110 platforms = ['Linux','Mac OSX','Windows XP/Vista/7/8']
109 platforms = ['Linux','Mac OSX','Windows']
111 110
112 keywords = ['Interactive','Interpreter','Shell','Parallel','Distributed',
113 'Web-based computing', 'Qt console', 'Embedding']
111 keywords = ['Interactive','Interpreter','Shell', 'Embedding']
114 112
115 113 classifiers = [
116 114 'Framework :: IPython',
117 115 'Intended Audience :: Developers',
118 116 'Intended Audience :: Science/Research',
119 117 'License :: OSI Approved :: BSD License',
120 118 'Programming Language :: Python',
121 119 'Programming Language :: Python :: 2',
122 120 'Programming Language :: Python :: 2.7',
123 121 'Programming Language :: Python :: 3',
124 122 'Topic :: System :: Shells'
125 123 ]
@@ -1,471 +1,470 b''
1 1 # encoding: utf-8
2 2 """
3 3 This module defines the things that are used in setup.py for building IPython
4 4
5 5 This includes:
6 6
7 7 * The basic arguments to setup
8 8 * Functions for finding things like packages, package data, etc.
9 9 * A function for checking dependencies.
10 10 """
11 11
12 12 # Copyright (c) IPython Development Team.
13 13 # Distributed under the terms of the Modified BSD License.
14 14
15 15 from __future__ import print_function
16 16
17 17 import re
18 18 import os
19 19 import sys
20 20
21 21 from distutils import log
22 22 from distutils.command.build_py import build_py
23 23 from distutils.command.build_scripts import build_scripts
24 24 from distutils.command.install import install
25 25 from distutils.command.install_scripts import install_scripts
26 26 from distutils.cmd import Command
27 27 from glob import glob
28 28
29 29 from setupext import install_data_ext
30 30
31 31 #-------------------------------------------------------------------------------
32 32 # Useful globals and utility functions
33 33 #-------------------------------------------------------------------------------
34 34
35 35 # A few handy globals
36 36 isfile = os.path.isfile
37 37 pjoin = os.path.join
38 38 repo_root = os.path.dirname(os.path.abspath(__file__))
39 39
40 40 def oscmd(s):
41 41 print(">", s)
42 42 os.system(s)
43 43
44 44 # Py3 compatibility hacks, without assuming IPython itself is installed with
45 45 # the full py3compat machinery.
46 46
47 47 try:
48 48 execfile
49 49 except NameError:
50 50 def execfile(fname, globs, locs=None):
51 51 locs = locs or globs
52 52 exec(compile(open(fname).read(), fname, "exec"), globs, locs)
53 53
54 54 # A little utility we'll need below, since glob() does NOT allow you to do
55 55 # exclusion on multiple endings!
56 56 def file_doesnt_endwith(test,endings):
57 57 """Return true if test is a file and its name does NOT end with any
58 58 of the strings listed in endings."""
59 59 if not isfile(test):
60 60 return False
61 61 for e in endings:
62 62 if test.endswith(e):
63 63 return False
64 64 return True
65 65
66 66 #---------------------------------------------------------------------------
67 67 # Basic project information
68 68 #---------------------------------------------------------------------------
69 69
70 70 # release.py contains version, authors, license, url, keywords, etc.
71 71 execfile(pjoin(repo_root, 'IPython','core','release.py'), globals())
72 72
73 73 # Create a dict with the basic information
74 74 # This dict is eventually passed to setup after additional keys are added.
75 75 setup_args = dict(
76 76 name = name,
77 77 version = version,
78 78 description = description,
79 79 long_description = long_description,
80 80 author = author,
81 81 author_email = author_email,
82 82 url = url,
83 download_url = download_url,
84 83 license = license,
85 84 platforms = platforms,
86 85 keywords = keywords,
87 86 classifiers = classifiers,
88 87 cmdclass = {'install_data': install_data_ext},
89 88 )
90 89
91 90
92 91 #---------------------------------------------------------------------------
93 92 # Find packages
94 93 #---------------------------------------------------------------------------
95 94
96 95 def find_packages():
97 96 """
98 97 Find all of IPython's packages.
99 98 """
100 99 excludes = ['deathrow', 'quarantine']
101 100 packages = []
102 101 for dir,subdirs,files in os.walk('IPython'):
103 102 package = dir.replace(os.path.sep, '.')
104 103 if any(package.startswith('IPython.'+exc) for exc in excludes):
105 104 # package is to be excluded (e.g. deathrow)
106 105 continue
107 106 if '__init__.py' not in files:
108 107 # not a package
109 108 continue
110 109 packages.append(package)
111 110 return packages
112 111
113 112 #---------------------------------------------------------------------------
114 113 # Find package data
115 114 #---------------------------------------------------------------------------
116 115
117 116 def find_package_data():
118 117 """
119 118 Find IPython's package_data.
120 119 """
121 120 # This is not enough for these things to appear in an sdist.
122 121 # We need to muck with the MANIFEST to get this to work
123 122
124 123 package_data = {
125 124 'IPython.core' : ['profile/README*'],
126 125 'IPython.core.tests' : ['*.png', '*.jpg', 'daft_extension/*.py'],
127 126 'IPython.lib.tests' : ['*.wav'],
128 127 'IPython.testing.plugin' : ['*.txt'],
129 128 }
130 129
131 130 return package_data
132 131
133 132
134 133 def check_package_data(package_data):
135 134 """verify that package_data globs make sense"""
136 135 print("checking package data")
137 136 for pkg, data in package_data.items():
138 137 pkg_root = pjoin(*pkg.split('.'))
139 138 for d in data:
140 139 path = pjoin(pkg_root, d)
141 140 if '*' in path:
142 141 assert len(glob(path)) > 0, "No files match pattern %s" % path
143 142 else:
144 143 assert os.path.exists(path), "Missing package data: %s" % path
145 144
146 145
147 146 def check_package_data_first(command):
148 147 """decorator for checking package_data before running a given command
149 148
150 149 Probably only needs to wrap build_py
151 150 """
152 151 class DecoratedCommand(command):
153 152 def run(self):
154 153 check_package_data(self.package_data)
155 154 command.run(self)
156 155 return DecoratedCommand
157 156
158 157
159 158 #---------------------------------------------------------------------------
160 159 # Find data files
161 160 #---------------------------------------------------------------------------
162 161
163 162 def make_dir_struct(tag,base,out_base):
164 163 """Make the directory structure of all files below a starting dir.
165 164
166 165 This is just a convenience routine to help build a nested directory
167 166 hierarchy because distutils is too stupid to do this by itself.
168 167
169 168 XXX - this needs a proper docstring!
170 169 """
171 170
172 171 # we'll use these a lot below
173 172 lbase = len(base)
174 173 pathsep = os.path.sep
175 174 lpathsep = len(pathsep)
176 175
177 176 out = []
178 177 for (dirpath,dirnames,filenames) in os.walk(base):
179 178 # we need to strip out the dirpath from the base to map it to the
180 179 # output (installation) path. This requires possibly stripping the
181 180 # path separator, because otherwise pjoin will not work correctly
182 181 # (pjoin('foo/','/bar') returns '/bar').
183 182
184 183 dp_eff = dirpath[lbase:]
185 184 if dp_eff.startswith(pathsep):
186 185 dp_eff = dp_eff[lpathsep:]
187 186 # The output path must be anchored at the out_base marker
188 187 out_path = pjoin(out_base,dp_eff)
189 188 # Now we can generate the final filenames. Since os.walk only produces
190 189 # filenames, we must join back with the dirpath to get full valid file
191 190 # paths:
192 191 pfiles = [pjoin(dirpath,f) for f in filenames]
193 192 # Finally, generate the entry we need, which is a pari of (output
194 193 # path, files) for use as a data_files parameter in install_data.
195 194 out.append((out_path, pfiles))
196 195
197 196 return out
198 197
199 198
200 199 def find_data_files():
201 200 """
202 201 Find IPython's data_files.
203 202
204 203 Just man pages at this point.
205 204 """
206 205
207 206 manpagebase = pjoin('share', 'man', 'man1')
208 207
209 208 # Simple file lists can be made by hand
210 209 manpages = [f for f in glob(pjoin('docs','man','*.1.gz')) if isfile(f)]
211 210 if not manpages:
212 211 # When running from a source tree, the manpages aren't gzipped
213 212 manpages = [f for f in glob(pjoin('docs','man','*.1')) if isfile(f)]
214 213
215 214 # And assemble the entire output list
216 215 data_files = [ (manpagebase, manpages) ]
217 216
218 217 return data_files
219 218
220 219
221 220 def make_man_update_target(manpage):
222 221 """Return a target_update-compliant tuple for the given manpage.
223 222
224 223 Parameters
225 224 ----------
226 225 manpage : string
227 226 Name of the manpage, must include the section number (trailing number).
228 227
229 228 Example
230 229 -------
231 230
232 231 >>> make_man_update_target('ipython.1') #doctest: +NORMALIZE_WHITESPACE
233 232 ('docs/man/ipython.1.gz',
234 233 ['docs/man/ipython.1'],
235 234 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz')
236 235 """
237 236 man_dir = pjoin('docs', 'man')
238 237 manpage_gz = manpage + '.gz'
239 238 manpath = pjoin(man_dir, manpage)
240 239 manpath_gz = pjoin(man_dir, manpage_gz)
241 240 gz_cmd = ( "cd %(man_dir)s && gzip -9c %(manpage)s > %(manpage_gz)s" %
242 241 locals() )
243 242 return (manpath_gz, [manpath], gz_cmd)
244 243
245 244 # The two functions below are copied from IPython.utils.path, so we don't need
246 245 # to import IPython during setup, which fails on Python 3.
247 246
248 247 def target_outdated(target,deps):
249 248 """Determine whether a target is out of date.
250 249
251 250 target_outdated(target,deps) -> 1/0
252 251
253 252 deps: list of filenames which MUST exist.
254 253 target: single filename which may or may not exist.
255 254
256 255 If target doesn't exist or is older than any file listed in deps, return
257 256 true, otherwise return false.
258 257 """
259 258 try:
260 259 target_time = os.path.getmtime(target)
261 260 except os.error:
262 261 return 1
263 262 for dep in deps:
264 263 dep_time = os.path.getmtime(dep)
265 264 if dep_time > target_time:
266 265 #print "For target",target,"Dep failed:",dep # dbg
267 266 #print "times (dep,tar):",dep_time,target_time # dbg
268 267 return 1
269 268 return 0
270 269
271 270
272 271 def target_update(target,deps,cmd):
273 272 """Update a target with a given command given a list of dependencies.
274 273
275 274 target_update(target,deps,cmd) -> runs cmd if target is outdated.
276 275
277 276 This is just a wrapper around target_outdated() which calls the given
278 277 command if target is outdated."""
279 278
280 279 if target_outdated(target,deps):
281 280 os.system(cmd)
282 281
283 282 #---------------------------------------------------------------------------
284 283 # Find scripts
285 284 #---------------------------------------------------------------------------
286 285
287 286 def find_entry_points():
288 287 """Defines the command line entry points for IPython
289 288
290 289 This always uses setuptools-style entry points. When setuptools is not in
291 290 use, our own build_scripts_entrypt class below parses these and builds
292 291 command line scripts.
293 292
294 293 Each of our entry points gets both a plain name, e.g. ipython, and one
295 294 suffixed with the Python major version number, e.g. ipython3.
296 295 """
297 296 ep = [
298 297 'ipython%s = IPython:start_ipython',
299 298 'iptest%s = IPython.testing.iptestcontroller:main',
300 299 ]
301 300 suffix = str(sys.version_info[0])
302 301 return [e % '' for e in ep] + [e % suffix for e in ep]
303 302
304 303 script_src = """#!{executable}
305 304 # This script was automatically generated by setup.py
306 305 if __name__ == '__main__':
307 306 from {mod} import {func}
308 307 {func}()
309 308 """
310 309
311 310 class build_scripts_entrypt(build_scripts):
312 311 """Build the command line scripts
313 312
314 313 Parse setuptools style entry points and write simple scripts to run the
315 314 target functions.
316 315
317 316 On Windows, this also creates .cmd wrappers for the scripts so that you can
318 317 easily launch them from a command line.
319 318 """
320 319 def run(self):
321 320 self.mkpath(self.build_dir)
322 321 outfiles = []
323 322 for script in find_entry_points():
324 323 name, entrypt = script.split('=')
325 324 name = name.strip()
326 325 entrypt = entrypt.strip()
327 326 outfile = os.path.join(self.build_dir, name)
328 327 outfiles.append(outfile)
329 328 print('Writing script to', outfile)
330 329
331 330 mod, func = entrypt.split(':')
332 331 with open(outfile, 'w') as f:
333 332 f.write(script_src.format(executable=sys.executable,
334 333 mod=mod, func=func))
335 334
336 335 if sys.platform == 'win32':
337 336 # Write .cmd wrappers for Windows so 'ipython' etc. work at the
338 337 # command line
339 338 cmd_file = os.path.join(self.build_dir, name + '.cmd')
340 339 cmd = '@"{python}" "%~dp0\{script}" %*\r\n'.format(
341 340 python=sys.executable, script=name)
342 341 log.info("Writing %s wrapper script" % cmd_file)
343 342 with open(cmd_file, 'w') as f:
344 343 f.write(cmd)
345 344
346 345 return outfiles, outfiles
347 346
348 347 class install_lib_symlink(Command):
349 348 user_options = [
350 349 ('install-dir=', 'd', "directory to install to"),
351 350 ]
352 351
353 352 def initialize_options(self):
354 353 self.install_dir = None
355 354
356 355 def finalize_options(self):
357 356 self.set_undefined_options('symlink',
358 357 ('install_lib', 'install_dir'),
359 358 )
360 359
361 360 def run(self):
362 361 if sys.platform == 'win32':
363 362 raise Exception("This doesn't work on Windows.")
364 363 pkg = os.path.join(os.getcwd(), 'IPython')
365 364 dest = os.path.join(self.install_dir, 'IPython')
366 365 if os.path.islink(dest):
367 366 print('removing existing symlink at %s' % dest)
368 367 os.unlink(dest)
369 368 print('symlinking %s -> %s' % (pkg, dest))
370 369 os.symlink(pkg, dest)
371 370
372 371 class unsymlink(install):
373 372 def run(self):
374 373 dest = os.path.join(self.install_lib, 'IPython')
375 374 if os.path.islink(dest):
376 375 print('removing symlink at %s' % dest)
377 376 os.unlink(dest)
378 377 else:
379 378 print('No symlink exists at %s' % dest)
380 379
381 380 class install_symlinked(install):
382 381 def run(self):
383 382 if sys.platform == 'win32':
384 383 raise Exception("This doesn't work on Windows.")
385 384
386 385 # Run all sub-commands (at least those that need to be run)
387 386 for cmd_name in self.get_sub_commands():
388 387 self.run_command(cmd_name)
389 388
390 389 # 'sub_commands': a list of commands this command might have to run to
391 390 # get its work done. See cmd.py for more info.
392 391 sub_commands = [('install_lib_symlink', lambda self:True),
393 392 ('install_scripts_sym', lambda self:True),
394 393 ]
395 394
396 395 class install_scripts_for_symlink(install_scripts):
397 396 """Redefined to get options from 'symlink' instead of 'install'.
398 397
399 398 I love distutils almost as much as I love setuptools.
400 399 """
401 400 def finalize_options(self):
402 401 self.set_undefined_options('build', ('build_scripts', 'build_dir'))
403 402 self.set_undefined_options('symlink',
404 403 ('install_scripts', 'install_dir'),
405 404 ('force', 'force'),
406 405 ('skip_build', 'skip_build'),
407 406 )
408 407
409 408
410 409 #---------------------------------------------------------------------------
411 410 # VCS related
412 411 #---------------------------------------------------------------------------
413 412
414 413
415 414 def git_prebuild(pkg_dir, build_cmd=build_py):
416 415 """Return extended build or sdist command class for recording commit
417 416
418 417 records git commit in IPython.utils._sysinfo.commit
419 418
420 419 for use in IPython.utils.sysinfo.sys_info() calls after installation.
421 420 """
422 421
423 422 class MyBuildPy(build_cmd):
424 423 ''' Subclass to write commit data into installation tree '''
425 424 def run(self):
426 425 # loose as `.dev` is suppose to be invalid
427 426 print("check version number")
428 427 loose_pep440re = re.compile('^(\d+)\.(\d+)\.(\d+((a|b|rc)\d+)?)(\.post\d+)?(\.dev\d*)?$')
429 428 import IPython.core.release as r
430 429 if not loose_pep440re.match(r.version):
431 430 raise ValueError("Version number '%s' is not valid (should match [N!]N(.N)*[{a|b|rc}N][.postN][.devN])" % r.version)
432 431
433 432
434 433 build_cmd.run(self)
435 434 # this one will only fire for build commands
436 435 if hasattr(self, 'build_lib'):
437 436 self._record_commit(self.build_lib)
438 437
439 438 def make_release_tree(self, base_dir, files):
440 439 # this one will fire for sdist
441 440 build_cmd.make_release_tree(self, base_dir, files)
442 441 self._record_commit(base_dir)
443 442
444 443 def _record_commit(self, base_dir):
445 444 import subprocess
446 445 proc = subprocess.Popen('git rev-parse --short HEAD',
447 446 stdout=subprocess.PIPE,
448 447 stderr=subprocess.PIPE,
449 448 shell=True)
450 449 repo_commit, _ = proc.communicate()
451 450 repo_commit = repo_commit.strip().decode("ascii")
452 451
453 452 out_pth = pjoin(base_dir, pkg_dir, 'utils', '_sysinfo.py')
454 453 if os.path.isfile(out_pth) and not repo_commit:
455 454 # nothing to write, don't clobber
456 455 return
457 456
458 457 print("writing git commit '%s' to %s" % (repo_commit, out_pth))
459 458
460 459 # remove to avoid overwriting original via hard link
461 460 try:
462 461 os.remove(out_pth)
463 462 except (IOError, OSError):
464 463 pass
465 464 with open(out_pth, 'w') as out_file:
466 465 out_file.writelines([
467 466 '# GENERATED BY setup.py\n',
468 467 'commit = u"%s"\n' % repo_commit,
469 468 ])
470 469 return MyBuildPy
471 470
General Comments 0
You need to be logged in to leave comments. Login now