Show More
@@ -0,0 +1,37 b'' | |||
|
1 | IPython provides a rich toolkit to help you make the most out of using Python | |
|
2 | interactively. Its main components are: | |
|
3 | ||
|
4 | * A powerful interactive Python shell | |
|
5 | * A `Jupyter <https://jupyter.org/>`_ kernel to work with Python code in Jupyter | |
|
6 | notebooks and other interactive frontends. | |
|
7 | ||
|
8 | The enhanced interactive Python shells have the following main features: | |
|
9 | ||
|
10 | * Comprehensive object introspection. | |
|
11 | ||
|
12 | * Input history, persistent across sessions. | |
|
13 | ||
|
14 | * Caching of output results during a session with automatically generated | |
|
15 | references. | |
|
16 | ||
|
17 | * Extensible tab completion, with support by default for completion of python | |
|
18 | variables and keywords, filenames and function keywords. | |
|
19 | ||
|
20 | * Extensible system of 'magic' commands for controlling the environment and | |
|
21 | performing many tasks related either to IPython or the operating system. | |
|
22 | ||
|
23 | * A rich configuration system with easy switching between different setups | |
|
24 | (simpler than changing $PYTHONSTARTUP environment variables every time). | |
|
25 | ||
|
26 | * Session logging and reloading. | |
|
27 | ||
|
28 | * Extensible syntax processing for special purpose situations. | |
|
29 | ||
|
30 | * Access to the system shell with user-extensible alias system. | |
|
31 | ||
|
32 | * Easily embeddable in other Python programs and GUIs. | |
|
33 | ||
|
34 | * Integrated access to the pdb debugger and the Python profiler. | |
|
35 | ||
|
36 | The latest development version is always available from IPython's `GitHub | |
|
37 | site <http://github.com/ipython>`_. |
@@ -1,47 +1,48 b'' | |||
|
1 | 1 | include README.rst |
|
2 | 2 | include COPYING.rst |
|
3 | 3 | include LICENSE |
|
4 | 4 | include setupbase.py |
|
5 | 5 | include MANIFEST.in |
|
6 | 6 | include pytest.ini |
|
7 | 7 | include mypy.ini |
|
8 | 8 | include .mailmap |
|
9 | 9 | include .flake8 |
|
10 | 10 | include .pre-commit-config.yaml |
|
11 | include long_description.rst | |
|
11 | 12 | |
|
12 | 13 | recursive-exclude tools * |
|
13 | 14 | exclude tools |
|
14 | 15 | exclude CONTRIBUTING.md |
|
15 | 16 | exclude .editorconfig |
|
16 | 17 | |
|
17 | 18 | graft setupext |
|
18 | 19 | |
|
19 | 20 | graft scripts |
|
20 | 21 | |
|
21 | 22 | # Load main dir but exclude things we don't want in the distro |
|
22 | 23 | graft IPython |
|
23 | 24 | |
|
24 | 25 | # Documentation |
|
25 | 26 | graft docs |
|
26 | 27 | exclude docs/\#* |
|
27 | 28 | exclude docs/man/*.1.gz |
|
28 | 29 | |
|
29 | 30 | exclude .git-blame-ignore-revs |
|
30 | 31 | |
|
31 | 32 | # Examples |
|
32 | 33 | graft examples |
|
33 | 34 | |
|
34 | 35 | # docs subdirs we want to skip |
|
35 | 36 | prune docs/build |
|
36 | 37 | prune docs/gh-pages |
|
37 | 38 | prune docs/dist |
|
38 | 39 | |
|
39 | 40 | # Patterns to exclude from any directory |
|
40 | 41 | global-exclude *~ |
|
41 | 42 | global-exclude *.flc |
|
42 | 43 | global-exclude *.yml |
|
43 | 44 | global-exclude *.pyc |
|
44 | 45 | global-exclude *.pyo |
|
45 | 46 | global-exclude .dircopy.log |
|
46 | 47 | global-exclude .git |
|
47 | 48 | global-exclude .ipynb_checkpoints |
@@ -1,108 +1,71 b'' | |||
|
1 | 1 | [metadata] |
|
2 | 2 | name = ipython |
|
3 | 3 | version = attr: IPython.core.release.__version__ |
|
4 | 4 | url = https://ipython.org |
|
5 | 5 | description = IPython: Productive Interactive Computing |
|
6 | 6 | long_description_content_type = text/x-rst |
|
7 | long_description = IPython provides a rich toolkit to help you make the most out of using Python | |
|
8 | interactively. Its main components are: | |
|
9 | ||
|
10 | * A powerful interactive Python shell | |
|
11 | * A `Jupyter <https://jupyter.org/>`_ kernel to work with Python code in Jupyter | |
|
12 | notebooks and other interactive frontends. | |
|
13 | ||
|
14 | The enhanced interactive Python shells have the following main features: | |
|
15 | ||
|
16 | * Comprehensive object introspection. | |
|
17 | ||
|
18 | * Input history, persistent across sessions. | |
|
19 | ||
|
20 | * Caching of output results during a session with automatically generated | |
|
21 | references. | |
|
22 | ||
|
23 | * Extensible tab completion, with support by default for completion of python | |
|
24 | variables and keywords, filenames and function keywords. | |
|
25 | ||
|
26 | * Extensible system of 'magic' commands for controlling the environment and | |
|
27 | performing many tasks related either to IPython or the operating system. | |
|
28 | ||
|
29 | * A rich configuration system with easy switching between different setups | |
|
30 | (simpler than changing $PYTHONSTARTUP environment variables every time). | |
|
31 | ||
|
32 | * Session logging and reloading. | |
|
33 | ||
|
34 | * Extensible syntax processing for special purpose situations. | |
|
35 | ||
|
36 | * Access to the system shell with user-extensible alias system. | |
|
37 | ||
|
38 | * Easily embeddable in other Python programs and GUIs. | |
|
39 | ||
|
40 | * Integrated access to the pdb debugger and the Python profiler. | |
|
41 | ||
|
42 | The latest development version is always available from IPython's `GitHub | |
|
43 | site <http://github.com/ipython>`_. | |
|
44 | ||
|
7 | long_description = file: long_description.rst | |
|
45 | 8 | license_file = LICENSE |
|
46 | 9 | project_urls = |
|
47 | 10 | Documentation = https://ipython.readthedocs.io/ |
|
48 | 11 | Funding = https://numfocus.org/ |
|
49 | 12 | Source = https://github.com/ipython/ipython |
|
50 | 13 | Tracker = https://github.com/ipython/ipython/issues |
|
51 | 14 | keywords = Interactive, Interpreter, Shell, Embedding |
|
52 | 15 | platforms = Linux, Mac OSX, Windows |
|
53 | 16 | classifiers = |
|
54 | 17 | Framework :: IPython |
|
55 | 18 | Intended Audience :: Developers |
|
56 | 19 | Intended Audience :: Science/Research |
|
57 | 20 | License :: OSI Approved :: BSD License |
|
58 | 21 | Programming Language :: Python |
|
59 | 22 | Programming Language :: Python :: 3 |
|
60 | 23 | Programming Language :: Python :: 3 :: Only |
|
61 | 24 | Topic :: System :: Shells |
|
62 | 25 | |
|
63 | 26 | |
|
64 | 27 | [options] |
|
65 | 28 | packages = find: |
|
66 | 29 | python_requires = >=3.8 |
|
67 | 30 | zip_safe = False |
|
68 | 31 | install_requires = |
|
69 | 32 | setuptools>=18.5 |
|
70 | 33 | jedi>=0.16 |
|
71 | 34 | decorator |
|
72 | 35 | pickleshare |
|
73 | 36 | traitlets>=5 |
|
74 | 37 | prompt_toolkit>=2.0.0,<3.1.0,!=3.0.0,!=3.0.1 |
|
75 | 38 | pygments |
|
76 | 39 | backcall |
|
77 | 40 | stack_data |
|
78 | 41 | matplotlib-inline |
|
79 | 42 | pexpect>4.3; sys_platform != "win32" |
|
80 | 43 | appnope; sys_platform == "darwin" |
|
81 | 44 | colorama; sys_platform == "win32" |
|
82 | 45 | |
|
83 | 46 | [options.packages.find] |
|
84 | 47 | exclude = |
|
85 | 48 | setupext |
|
86 | 49 | |
|
87 | 50 | [options.package_data] |
|
88 | 51 | IPython.core = profile/README* |
|
89 | 52 | IPython.core.tests = *.png, *.jpg, daft_extension/*.py |
|
90 | 53 | IPython.lib.tests = *.wav |
|
91 | 54 | IPython.testing.plugin = *.txt |
|
92 | 55 | |
|
93 | 56 | [options.entry_points] |
|
94 | 57 | console_scripts = |
|
95 | 58 | ipython = IPython:start_ipython |
|
96 | 59 | ipython3 = IPython:start_ipython |
|
97 | 60 | pygments.lexers = |
|
98 | 61 | ipythonconsole = IPython.lib.lexers:IPythonConsoleLexer |
|
99 | 62 | ipython = IPython.lib.lexers:IPythonLexer |
|
100 | 63 | ipython3 = IPython.lib.lexers:IPython3Lexer |
|
101 | 64 | |
|
102 | 65 | [velin] |
|
103 | 66 | ignore_patterns = |
|
104 | 67 | IPython/core/tests |
|
105 | 68 | IPython/testing |
|
106 | 69 | |
|
107 | 70 | [tool.black] |
|
108 | 71 | exclude = 'timing\.py' |
@@ -1,23 +1,23 b'' | |||
|
1 | 1 | #!/usr/bin/env python3 |
|
2 | 2 | """IPython release build script. |
|
3 | 3 | """ |
|
4 | 4 | import os |
|
5 | 5 | import sys |
|
6 | 6 | from shutil import rmtree |
|
7 | 7 | |
|
8 | 8 | from toollib import sh, pjoin, get_ipdir, cd, sdists, buildwheels |
|
9 | 9 | |
|
10 | 10 | def build_release(): |
|
11 | 11 | |
|
12 | 12 | # Get main ipython dir, this will raise if it doesn't pass some checks |
|
13 | 13 | ipdir = get_ipdir() |
|
14 | 14 | cd(ipdir) |
|
15 | 15 | |
|
16 | 16 | # Build source and binary distros |
|
17 | 17 | sh(sdists) |
|
18 | 18 | buildwheels() |
|
19 | # don't try to change, xz, bz2 deprecated. | |
|
19 | 20 | sh(' '.join([sys.executable, 'tools/retar.py', 'dist/*.gz'])) |
|
20 | sh(' '.join([sys.executable, 'tools/retar.py', 'dist/*.xz'])) | |
|
21 | 21 | |
|
22 | 22 | if __name__ == '__main__': |
|
23 | 23 | build_release() |
@@ -1,93 +1,93 b'' | |||
|
1 | 1 | #!/usr/bin/env python3 |
|
2 | 2 | """IPython release script. |
|
3 | 3 | |
|
4 | 4 | This should ONLY be run at real release time. |
|
5 | 5 | """ |
|
6 | 6 | from __future__ import print_function |
|
7 | 7 | |
|
8 | 8 | import os |
|
9 | 9 | from glob import glob |
|
10 | 10 | from subprocess import call |
|
11 | 11 | import sys |
|
12 | 12 | |
|
13 | 13 | from toollib import (get_ipdir, pjoin, cd, execfile, sh, archive, |
|
14 | 14 | sdists, archive_user, archive_dir, buildwheels) |
|
15 | 15 | from gh_api import post_download |
|
16 | 16 | |
|
17 | 17 | # Get main ipython dir, this will raise if it doesn't pass some checks |
|
18 | 18 | ipdir = get_ipdir() |
|
19 | 19 | tooldir = pjoin(ipdir, 'tools') |
|
20 | 20 | distdir = pjoin(ipdir, 'dist') |
|
21 | 21 | |
|
22 | 22 | # Where I keep static backups of each release |
|
23 | 23 | ipbackupdir = os.path.expanduser('~/ipython/backup') |
|
24 | 24 | if not os.path.exists(ipbackupdir): |
|
25 | 25 | os.makedirs(ipbackupdir) |
|
26 | 26 | |
|
27 | 27 | # Start in main IPython dir |
|
28 | 28 | cd(ipdir) |
|
29 | 29 | |
|
30 | 30 | # Load release info |
|
31 | 31 | version = None |
|
32 | 32 | execfile(pjoin('IPython','core','release.py'), globals()) |
|
33 | 33 | |
|
34 | 34 | # Build site addresses for file uploads |
|
35 | 35 | release_site = '%s/release/%s' % (archive, version) |
|
36 | 36 | backup_site = '%s/backup/' % archive |
|
37 | 37 | |
|
38 | 38 | # Start actual release process |
|
39 | 39 | print() |
|
40 | 40 | print('Releasing IPython') |
|
41 | 41 | print('=================') |
|
42 | 42 | print() |
|
43 | 43 | print('Version:', version) |
|
44 | 44 | print() |
|
45 | 45 | print('Source IPython directory:', ipdir) |
|
46 | 46 | print() |
|
47 | 47 | |
|
48 | 48 | # Perform local backup, go to tools dir to run it. |
|
49 | 49 | cd(tooldir) |
|
50 | 50 | |
|
51 | 51 | if 'upload' in sys.argv: |
|
52 | 52 | cd(distdir) |
|
53 | 53 | |
|
54 | 54 | # do not upload OS specific files like .DS_Store |
|
55 | 55 | to_upload = glob('*.whl')+glob('*.tar.gz') |
|
56 | 56 | for fname in to_upload: |
|
57 | 57 | # TODO: update to GitHub releases API |
|
58 | 58 | continue |
|
59 | 59 | print('uploading %s to GitHub' % fname) |
|
60 | 60 | desc = "IPython %s source distribution" % version |
|
61 | 61 | post_download("ipython/ipython", fname, description=desc) |
|
62 | 62 | |
|
63 | 63 | # Make target dir if it doesn't exist |
|
64 | 64 | print('1. Uploading IPython to archive.ipython.org') |
|
65 | 65 | sh('ssh %s "mkdir -p %s/release/%s" ' % (archive_user, archive_dir, version)) |
|
66 | 66 | sh('scp *.tar.gz *.tar.xz *.whl %s' % release_site) |
|
67 | 67 | |
|
68 | 68 | print('2. Uploading backup files...') |
|
69 | 69 | cd(ipbackupdir) |
|
70 | 70 | sh('scp `ls -1tr *tgz | tail -1` %s' % backup_site) |
|
71 | 71 | |
|
72 | 72 | print('3. Uploading to PyPI using twine') |
|
73 | 73 | cd(distdir) |
|
74 | call(['twine', 'upload'] + to_upload) | |
|
74 | call(['twine', 'upload', '--verbose'] + to_upload) | |
|
75 | 75 | |
|
76 | 76 | else: |
|
77 | 77 | # Build, but don't upload |
|
78 | 78 | |
|
79 | 79 | # Make backup tarball |
|
80 | 80 | sh('./make_tarball.py') |
|
81 | 81 | sh('mv ipython-*.tgz %s' % ipbackupdir) |
|
82 | 82 | |
|
83 | 83 | # Build release files |
|
84 | 84 | sh('./build_release') |
|
85 | 85 | |
|
86 | 86 | cd(ipdir) |
|
87 | 87 | |
|
88 | 88 | buildwheels() |
|
89 | 89 | print("`./release upload` to upload source distribution on PyPI and ipython archive") |
|
90 | 90 | sys.exit(0) |
|
91 | 91 | |
|
92 | 92 | |
|
93 | 93 |
@@ -1,83 +1,85 b'' | |||
|
1 | 1 | """ |
|
2 | 2 | Un-targz and retargz a targz file to ensure reproducible build. |
|
3 | 3 | |
|
4 | 4 | usage: |
|
5 | 5 | |
|
6 | 6 | $ export SOURCE_DATE_EPOCH=$(date +%s) |
|
7 | 7 | ... |
|
8 | 8 | $ python retar.py <tarfile.gz> |
|
9 | 9 | |
|
10 | 10 | The process of creating an sdist can be non-reproducible: |
|
11 | 11 | - directory created during the process get a mtime of the creation date; |
|
12 | 12 | - gziping files embed the timestamp of zip creation. |
|
13 | 13 | |
|
14 | 14 | This will untar-retar; ensuring that all mtime > SOURCE_DATE_EPOCH will be set |
|
15 | 15 | equal to SOURCE_DATE_EPOCH. |
|
16 | 16 | |
|
17 | 17 | """ |
|
18 | 18 | |
|
19 | 19 | import tarfile |
|
20 | 20 | import sys |
|
21 | 21 | import os |
|
22 | 22 | import gzip |
|
23 | 23 | import io |
|
24 | 24 | |
|
25 | 25 | from pathlib import Path |
|
26 | 26 | |
|
27 | 27 | if len(sys.argv) > 2: |
|
28 | 28 | raise ValueError("Too many arguments") |
|
29 | 29 | |
|
30 | 30 | |
|
31 | 31 | timestamp = int(os.environ["SOURCE_DATE_EPOCH"]) |
|
32 | 32 | |
|
33 | 33 | path = Path(sys.argv[1]) |
|
34 | 34 | old_buf = io.BytesIO() |
|
35 | 35 | with open(path, "rb") as f: |
|
36 | 36 | old_buf.write(f.read()) |
|
37 | 37 | old_buf.seek(0) |
|
38 | 38 | if path.name.endswith("gz"): |
|
39 | 39 | r_mode = "r:gz" |
|
40 |
if path.name.endswith( |
|
|
41 |
r_mode = "r: |
|
|
40 | if path.name.endswith("bz2"): | |
|
41 | r_mode = "r:bz2" | |
|
42 | if path.name.endswith("xz"): | |
|
43 | raise ValueError("XZ is deprecated but it's written nowhere") | |
|
42 | 44 | old = tarfile.open(fileobj=old_buf, mode=r_mode) |
|
43 | 45 | |
|
44 | 46 | buf = io.BytesIO() |
|
45 | 47 | new = tarfile.open(fileobj=buf, mode="w", format=tarfile.GNU_FORMAT) |
|
46 | 48 | for i, m in enumerate(old): |
|
47 | 49 | data = None |
|
48 | 50 | # mutation does not work, copy |
|
49 | 51 | if m.name.endswith('.DS_Store'): |
|
50 | 52 | continue |
|
51 | 53 | m2 = tarfile.TarInfo(m.name) |
|
52 | 54 | m2.mtime = min(timestamp, m.mtime) |
|
53 | 55 | m2.pax_headers["mtime"] = m2.mtime |
|
54 | 56 | m2.size = m.size |
|
55 | 57 | m2.type = m.type |
|
56 | 58 | m2.linkname = m.linkname |
|
57 | 59 | m2.mode = m.mode |
|
58 | 60 | if m.isdir(): |
|
59 | 61 | new.addfile(m2) |
|
60 | 62 | else: |
|
61 | 63 | data = old.extractfile(m) |
|
62 | 64 | new.addfile(m2, data) |
|
63 | 65 | new.close() |
|
64 | 66 | old.close() |
|
65 | 67 | |
|
66 | 68 | buf.seek(0) |
|
67 | 69 | |
|
68 | 70 | if r_mode == "r:gz": |
|
69 | 71 | with open(path, "wb") as f: |
|
70 | 72 | with gzip.GzipFile("", "wb", fileobj=f, mtime=timestamp) as gzf: |
|
71 | 73 | gzf.write(buf.read()) |
|
72 |
elif r_mode == "r: |
|
|
73 |
import |
|
|
74 | elif r_mode == "r:bz2": | |
|
75 | import bz2 | |
|
74 | 76 | |
|
75 |
with |
|
|
77 | with bz2.open(path, "wb") as f: | |
|
76 | 78 | f.write(buf.read()) |
|
77 | 79 | |
|
78 | 80 | else: |
|
79 | 81 | assert False |
|
80 | 82 | |
|
81 | 83 | # checks the archive is valid. |
|
82 | 84 | archive = tarfile.open(path) |
|
83 | 85 | names = archive.getnames() |
@@ -1,51 +1,51 b'' | |||
|
1 | 1 | """Various utilities common to IPython release and maintenance tools. |
|
2 | 2 | """ |
|
3 | 3 | |
|
4 | 4 | # Library imports |
|
5 | 5 | import os |
|
6 | 6 | import sys |
|
7 | 7 | |
|
8 | 8 | # Useful shorthands |
|
9 | 9 | pjoin = os.path.join |
|
10 | 10 | cd = os.chdir |
|
11 | 11 | |
|
12 | 12 | # Constants |
|
13 | 13 | |
|
14 | 14 | # SSH root address of the archive site |
|
15 | 15 | archive_user = 'ipython@archive.ipython.org' |
|
16 | 16 | archive_dir = 'archive.ipython.org' |
|
17 | 17 | archive = '%s:%s' % (archive_user, archive_dir) |
|
18 | 18 | |
|
19 | 19 | # Build commands |
|
20 | 20 | # Source dists |
|
21 |
sdists = "{python} setup.py sdist --formats= |
|
|
21 | sdists = "{python} setup.py sdist --formats=gztar".format(python=sys.executable) | |
|
22 | 22 | # Binary dists |
|
23 | 23 | def buildwheels(): |
|
24 | 24 | sh("{python} setup.py bdist_wheel".format(python=sys.executable)) |
|
25 | 25 | |
|
26 | 26 | |
|
27 | 27 | # Utility functions |
|
28 | 28 | def sh(cmd): |
|
29 | 29 | """Run system command in shell, raise SystemExit if it returns an error.""" |
|
30 | 30 | print("$", cmd) |
|
31 | 31 | stat = os.system(cmd) |
|
32 | 32 | #stat = 0 # Uncomment this and comment previous to run in debug mode |
|
33 | 33 | if stat: |
|
34 | 34 | raise SystemExit("Command %s failed with code: %s" % (cmd, stat)) |
|
35 | 35 | |
|
36 | 36 | def get_ipdir(): |
|
37 | 37 | """Get IPython directory from command line, or assume it's the one above.""" |
|
38 | 38 | |
|
39 | 39 | # Initialize arguments and check location |
|
40 | 40 | ipdir = pjoin(os.path.dirname(__file__), os.pardir) |
|
41 | 41 | |
|
42 | 42 | ipdir = os.path.abspath(ipdir) |
|
43 | 43 | |
|
44 | 44 | cd(ipdir) |
|
45 | 45 | if not os.path.isdir('IPython') and os.path.isfile('setup.py'): |
|
46 | 46 | raise SystemExit('Invalid ipython directory: %s' % ipdir) |
|
47 | 47 | return ipdir |
|
48 | 48 | |
|
49 | 49 | def execfile(fname, globs, locs=None): |
|
50 | 50 | locs = locs or globs |
|
51 | 51 | exec(compile(open(fname).read(), fname, "exec"), globs, locs) |
General Comments 0
You need to be logged in to leave comments.
Login now