##// END OF EJS Templates
Merge pull request #13729 from jarrodmillman/master2main...
Matthias Bussonnier -
r27714:57eaa12c merge
parent child Browse files
Show More
@@ -1,34 +1,34 b''
1 name: Run MyPy
1 name: Run MyPy
2
2
3 on:
3 on:
4 push:
4 push:
5 branches: [ master, 7.x]
5 branches: [ main, 7.x]
6 pull_request:
6 pull_request:
7 branches: [ master, 7.x]
7 branches: [ main, 7.x]
8
8
9 jobs:
9 jobs:
10 build:
10 build:
11
11
12 runs-on: ubuntu-latest
12 runs-on: ubuntu-latest
13 strategy:
13 strategy:
14 matrix:
14 matrix:
15 python-version: [3.8]
15 python-version: [3.8]
16
16
17 steps:
17 steps:
18 - uses: actions/checkout@v2
18 - uses: actions/checkout@v2
19 - name: Set up Python ${{ matrix.python-version }}
19 - name: Set up Python ${{ matrix.python-version }}
20 uses: actions/setup-python@v2
20 uses: actions/setup-python@v2
21 with:
21 with:
22 python-version: ${{ matrix.python-version }}
22 python-version: ${{ matrix.python-version }}
23 - name: Install dependencies
23 - name: Install dependencies
24 run: |
24 run: |
25 python -m pip install --upgrade pip
25 python -m pip install --upgrade pip
26 pip install mypy pyflakes flake8
26 pip install mypy pyflakes flake8
27 - name: Lint with mypy
27 - name: Lint with mypy
28 run: |
28 run: |
29 mypy -p IPython.terminal
29 mypy -p IPython.terminal
30 mypy -p IPython.core.magics
30 mypy -p IPython.core.magics
31 - name: Lint with pyflakes
31 - name: Lint with pyflakes
32 run: |
32 run: |
33 flake8 IPython/core/magics/script.py
33 flake8 IPython/core/magics/script.py
34 flake8 IPython/core/magics/packaging.py
34 flake8 IPython/core/magics/packaging.py
@@ -1,40 +1,40 b''
1 # This workflow will install Python dependencies, run tests and lint with a variety of Python versions
1 # This workflow will install Python dependencies, run tests and lint with a variety of Python versions
2 # For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
2 # For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
3
3
4 name: Python package
4 name: Python package
5
5
6 on:
6 on:
7 push:
7 push:
8 branches: [ master, 7.x ]
8 branches: [ main, 7.x ]
9 pull_request:
9 pull_request:
10 branches: [ master, 7.x ]
10 branches: [ main, 7.x ]
11
11
12 jobs:
12 jobs:
13 formatting:
13 formatting:
14
14
15 runs-on: ubuntu-latest
15 runs-on: ubuntu-latest
16 timeout-minutes: 5
16 timeout-minutes: 5
17 strategy:
17 strategy:
18 matrix:
18 matrix:
19 python-version: [3.8]
19 python-version: [3.8]
20
20
21 steps:
21 steps:
22 - uses: actions/checkout@v2
22 - uses: actions/checkout@v2
23 with:
23 with:
24 fetch-depth: 0
24 fetch-depth: 0
25 - name: Set up Python ${{ matrix.python-version }}
25 - name: Set up Python ${{ matrix.python-version }}
26 uses: actions/setup-python@v2
26 uses: actions/setup-python@v2
27 with:
27 with:
28 python-version: ${{ matrix.python-version }}
28 python-version: ${{ matrix.python-version }}
29 - name: Install dependencies
29 - name: Install dependencies
30 run: |
30 run: |
31 python -m pip install --upgrade pip
31 python -m pip install --upgrade pip
32 pip install darker black==21.12b0
32 pip install darker black==21.12b0
33 - name: Lint with darker
33 - name: Lint with darker
34 run: |
34 run: |
35 darker -r 60625f241f298b5039cb2debc365db38aa7bb522 --check --diff . || (
35 darker -r 60625f241f298b5039cb2debc365db38aa7bb522 --check --diff . || (
36 echo "Changes need auto-formatting. Run:"
36 echo "Changes need auto-formatting. Run:"
37 echo " darker -r 60625f241f298b5039cb2debc365db38aa7bb522"
37 echo " darker -r 60625f241f298b5039cb2debc365db38aa7bb522"
38 echo "then commit and push changes to fix."
38 echo "then commit and push changes to fix."
39 exit 1
39 exit 1
40 )
40 )
@@ -1,81 +1,80 b''
1 name: Run tests
1 name: Run tests
2
2
3 on:
3 on:
4 push:
4 push:
5 branches:
5 branches:
6 - main
6 - main
7 - master
8 - '*.x'
7 - '*.x'
9 pull_request:
8 pull_request:
10 # Run weekly on Monday at 1:23 UTC
9 # Run weekly on Monday at 1:23 UTC
11 schedule:
10 schedule:
12 - cron: '23 1 * * 1'
11 - cron: '23 1 * * 1'
13 workflow_dispatch:
12 workflow_dispatch:
14
13
15
14
16 jobs:
15 jobs:
17 test:
16 test:
18 runs-on: ${{ matrix.os }}
17 runs-on: ${{ matrix.os }}
19 strategy:
18 strategy:
20 fail-fast: false
19 fail-fast: false
21 matrix:
20 matrix:
22 os: [ubuntu-latest, windows-latest]
21 os: [ubuntu-latest, windows-latest]
23 python-version: ["3.8", "3.9", "3.10"]
22 python-version: ["3.8", "3.9", "3.10"]
24 deps: [test_extra]
23 deps: [test_extra]
25 # Test all on ubuntu, test ends on macos
24 # Test all on ubuntu, test ends on macos
26 include:
25 include:
27 - os: macos-latest
26 - os: macos-latest
28 python-version: "3.8"
27 python-version: "3.8"
29 deps: test_extra
28 deps: test_extra
30 - os: macos-latest
29 - os: macos-latest
31 python-version: "3.10"
30 python-version: "3.10"
32 deps: test_extra
31 deps: test_extra
33 # Tests minimal dependencies set
32 # Tests minimal dependencies set
34 - os: ubuntu-latest
33 - os: ubuntu-latest
35 python-version: "3.10"
34 python-version: "3.10"
36 deps: test
35 deps: test
37 # Tests latest development Python version
36 # Tests latest development Python version
38 - os: ubuntu-latest
37 - os: ubuntu-latest
39 python-version: "3.11-dev"
38 python-version: "3.11-dev"
40 deps: test
39 deps: test
41 # Installing optional dependencies stuff takes ages on PyPy
40 # Installing optional dependencies stuff takes ages on PyPy
42 - os: ubuntu-latest
41 - os: ubuntu-latest
43 python-version: "pypy-3.8"
42 python-version: "pypy-3.8"
44 deps: test
43 deps: test
45 - os: windows-latest
44 - os: windows-latest
46 python-version: "pypy-3.8"
45 python-version: "pypy-3.8"
47 deps: test
46 deps: test
48 - os: macos-latest
47 - os: macos-latest
49 python-version: "pypy-3.8"
48 python-version: "pypy-3.8"
50 deps: test
49 deps: test
51
50
52 steps:
51 steps:
53 - uses: actions/checkout@v2
52 - uses: actions/checkout@v2
54 - name: Set up Python ${{ matrix.python-version }}
53 - name: Set up Python ${{ matrix.python-version }}
55 uses: actions/setup-python@v2
54 uses: actions/setup-python@v2
56 with:
55 with:
57 python-version: ${{ matrix.python-version }}
56 python-version: ${{ matrix.python-version }}
58 cache: pip
57 cache: pip
59 - name: Install latex
58 - name: Install latex
60 if: runner.os == 'Linux' && matrix.deps == 'test_extra'
59 if: runner.os == 'Linux' && matrix.deps == 'test_extra'
61 run: echo "disable latex for now, issues in mirros" #sudo apt-get -yq -o Acquire::Retries=3 --no-install-suggests --no-install-recommends install texlive dvipng
60 run: echo "disable latex for now, issues in mirros" #sudo apt-get -yq -o Acquire::Retries=3 --no-install-suggests --no-install-recommends install texlive dvipng
62 - name: Install and update Python dependencies
61 - name: Install and update Python dependencies
63 run: |
62 run: |
64 python -m pip install --upgrade pip setuptools wheel build
63 python -m pip install --upgrade pip setuptools wheel build
65 python -m pip install --upgrade -e .[${{ matrix.deps }}]
64 python -m pip install --upgrade -e .[${{ matrix.deps }}]
66 python -m pip install --upgrade check-manifest pytest-cov
65 python -m pip install --upgrade check-manifest pytest-cov
67 - name: Try building with Python build
66 - name: Try building with Python build
68 if: runner.os != 'Windows' # setup.py does not support sdist on Windows
67 if: runner.os != 'Windows' # setup.py does not support sdist on Windows
69 run: |
68 run: |
70 python -m build
69 python -m build
71 shasum -a 256 dist/*
70 shasum -a 256 dist/*
72 - name: Check manifest
71 - name: Check manifest
73 if: runner.os != 'Windows' # setup.py does not support sdist on Windows
72 if: runner.os != 'Windows' # setup.py does not support sdist on Windows
74 run: check-manifest
73 run: check-manifest
75 - name: pytest
74 - name: pytest
76 env:
75 env:
77 COLUMNS: 120
76 COLUMNS: 120
78 run: |
77 run: |
79 pytest --color=yes -raXxs ${{ startsWith(matrix.python-version, 'pypy') && ' ' || '--cov --cov-report=xml' }}
78 pytest --color=yes -raXxs ${{ startsWith(matrix.python-version, 'pypy') && ' ' || '--cov --cov-report=xml' }}
80 - name: Upload coverage to Codecov
79 - name: Upload coverage to Codecov
81 uses: codecov/codecov-action@v2
80 uses: codecov/codecov-action@v2
@@ -1,90 +1,90 b''
1 ## Triaging Issues
1 ## Triaging Issues
2
2
3 On the IPython repository, we strive to trust users and give them responsibility.
3 On the IPython repository, we strive to trust users and give them responsibility.
4 By using one of our bots, any user can close issues or add/remove
4 By using one of our bots, any user can close issues or add/remove
5 labels by mentioning the bot and asking it to do things on your behalf.
5 labels by mentioning the bot and asking it to do things on your behalf.
6
6
7 To close an issue (or PR), even if you did not create it, use the following:
7 To close an issue (or PR), even if you did not create it, use the following:
8
8
9 > @meeseeksdev close
9 > @meeseeksdev close
10
10
11 This command can be in the middle of another comment, but must start on its
11 This command can be in the middle of another comment, but must start on its
12 own line.
12 own line.
13
13
14 To add labels to an issue, ask the bot to `tag` with a comma-separated list of
14 To add labels to an issue, ask the bot to `tag` with a comma-separated list of
15 tags to add:
15 tags to add:
16
16
17 > @meeseeksdev tag windows, documentation
17 > @meeseeksdev tag windows, documentation
18
18
19 Only already pre-created tags can be added. So far, the list is limited to:
19 Only already pre-created tags can be added. So far, the list is limited to:
20 `async/await`, `backported`, `help wanted`, `documentation`, `notebook`,
20 `async/await`, `backported`, `help wanted`, `documentation`, `notebook`,
21 `tab-completion`, `windows`
21 `tab-completion`, `windows`
22
22
23 To remove a label, use the `untag` command:
23 To remove a label, use the `untag` command:
24
24
25 > @meeseeksdev untag windows, documentation
25 > @meeseeksdev untag windows, documentation
26
26
27 We'll be adding additional capabilities for the bot and will share them here
27 We'll be adding additional capabilities for the bot and will share them here
28 when they are ready to be used.
28 when they are ready to be used.
29
29
30 ## Opening an Issue
30 ## Opening an Issue
31
31
32 When opening a new Issue, please take the following steps:
32 When opening a new Issue, please take the following steps:
33
33
34 1. Search GitHub and/or Google for your issue to avoid duplicate reports.
34 1. Search GitHub and/or Google for your issue to avoid duplicate reports.
35 Keyword searches for your error messages are most helpful.
35 Keyword searches for your error messages are most helpful.
36 2. If possible, try updating to master and reproducing your issue,
36 2. If possible, try updating to main and reproducing your issue,
37 because we may have already fixed it.
37 because we may have already fixed it.
38 3. Try to include a minimal reproducible test case.
38 3. Try to include a minimal reproducible test case.
39 4. Include relevant system information. Start with the output of:
39 4. Include relevant system information. Start with the output of:
40
40
41 python -c "import IPython; print(IPython.sys_info())"
41 python -c "import IPython; print(IPython.sys_info())"
42
42
43 And include any relevant package versions, depending on the issue, such as
43 And include any relevant package versions, depending on the issue, such as
44 matplotlib, numpy, Qt, Qt bindings (PyQt/PySide), tornado, web browser, etc.
44 matplotlib, numpy, Qt, Qt bindings (PyQt/PySide), tornado, web browser, etc.
45
45
46 ## Pull Requests
46 ## Pull Requests
47
47
48 Some guidelines on contributing to IPython:
48 Some guidelines on contributing to IPython:
49
49
50 * All work is submitted via Pull Requests.
50 * All work is submitted via Pull Requests.
51 * Pull Requests can be submitted as soon as there is code worth discussing.
51 * Pull Requests can be submitted as soon as there is code worth discussing.
52 Pull Requests track the branch, so you can continue to work after the PR is submitted.
52 Pull Requests track the branch, so you can continue to work after the PR is submitted.
53 Review and discussion can begin well before the work is complete,
53 Review and discussion can begin well before the work is complete,
54 and the more discussion the better.
54 and the more discussion the better.
55 The worst case is that the PR is closed.
55 The worst case is that the PR is closed.
56 * Pull Requests should generally be made against master
56 * Pull Requests should generally be made against main
57 * Pull Requests should be tested, if feasible:
57 * Pull Requests should be tested, if feasible:
58 - bugfixes should include regression tests.
58 - bugfixes should include regression tests.
59 - new behavior should at least get minimal exercise.
59 - new behavior should at least get minimal exercise.
60 * New features and backwards-incompatible changes should be documented by adding
60 * New features and backwards-incompatible changes should be documented by adding
61 a new file to the [pr](docs/source/whatsnew/pr) directory, see [the README.md
61 a new file to the [pr](docs/source/whatsnew/pr) directory, see [the README.md
62 there](docs/source/whatsnew/pr/README.md) for details.
62 there](docs/source/whatsnew/pr/README.md) for details.
63 * Don't make 'cleanup' pull requests just to change code style.
63 * Don't make 'cleanup' pull requests just to change code style.
64 We don't follow any style guide strictly, and we consider formatting changes
64 We don't follow any style guide strictly, and we consider formatting changes
65 unnecessary noise.
65 unnecessary noise.
66 If you're making functional changes, you can clean up the specific pieces of
66 If you're making functional changes, you can clean up the specific pieces of
67 code you're working on.
67 code you're working on.
68
68
69 [Travis](http://travis-ci.org/#!/ipython/ipython) does a pretty good job testing
69 [Travis](http://travis-ci.org/#!/ipython/ipython) does a pretty good job testing
70 IPython and Pull Requests, but it may make sense to manually perform tests,
70 IPython and Pull Requests, but it may make sense to manually perform tests,
71 particularly for PRs that affect `IPython.parallel` or Windows.
71 particularly for PRs that affect `IPython.parallel` or Windows.
72
72
73 For more detailed information, see our [GitHub Workflow](https://github.com/ipython/ipython/wiki/Dev:-GitHub-workflow).
73 For more detailed information, see our [GitHub Workflow](https://github.com/ipython/ipython/wiki/Dev:-GitHub-workflow).
74
74
75 ## Running Tests
75 ## Running Tests
76
76
77 All the tests can be run by using
77 All the tests can be run by using
78 ```shell
78 ```shell
79 pytest
79 pytest
80 ```
80 ```
81
81
82 All the tests for a single module (for example **test_alias**) can be run by using the fully qualified path to the module.
82 All the tests for a single module (for example **test_alias**) can be run by using the fully qualified path to the module.
83 ```shell
83 ```shell
84 pytest IPython/core/tests/test_alias.py
84 pytest IPython/core/tests/test_alias.py
85 ```
85 ```
86
86
87 Only a single test (for example **test_alias_lifecycle**) within a single file can be run by adding the specific test after a `::` at the end:
87 Only a single test (for example **test_alias_lifecycle**) within a single file can be run by adding the specific test after a `::` at the end:
88 ```shell
88 ```shell
89 pytest IPython/core/tests/test_alias.py::test_alias_lifecycle
89 pytest IPython/core/tests/test_alias.py::test_alias_lifecycle
90 ```
90 ```
@@ -1,156 +1,156 b''
1 """
1 """
2 IPython: tools for interactive and parallel computing in Python.
2 IPython: tools for interactive and parallel computing in Python.
3
3
4 https://ipython.org
4 https://ipython.org
5 """
5 """
6 #-----------------------------------------------------------------------------
6 #-----------------------------------------------------------------------------
7 # Copyright (c) 2008-2011, IPython Development Team.
7 # Copyright (c) 2008-2011, IPython Development Team.
8 # Copyright (c) 2001-2007, Fernando Perez <fernando.perez@colorado.edu>
8 # Copyright (c) 2001-2007, Fernando Perez <fernando.perez@colorado.edu>
9 # Copyright (c) 2001, Janko Hauser <jhauser@zscout.de>
9 # Copyright (c) 2001, Janko Hauser <jhauser@zscout.de>
10 # Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu>
10 # Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu>
11 #
11 #
12 # Distributed under the terms of the Modified BSD License.
12 # Distributed under the terms of the Modified BSD License.
13 #
13 #
14 # The full license is in the file COPYING.txt, distributed with this software.
14 # The full license is in the file COPYING.txt, distributed with this software.
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18 # Imports
18 # Imports
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20
20
21 import os
21 import os
22 import sys
22 import sys
23
23
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25 # Setup everything
25 # Setup everything
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27
27
28 # Don't forget to also update setup.py when this changes!
28 # Don't forget to also update setup.py when this changes!
29 if sys.version_info < (3, 8):
29 if sys.version_info < (3, 8):
30 raise ImportError(
30 raise ImportError(
31 """
31 """
32 IPython 8+ supports Python 3.8 and above, following NEP 29.
32 IPython 8+ supports Python 3.8 and above, following NEP 29.
33 When using Python 2.7, please install IPython 5.x LTS Long Term Support version.
33 When using Python 2.7, please install IPython 5.x LTS Long Term Support version.
34 Python 3.3 and 3.4 were supported up to IPython 6.x.
34 Python 3.3 and 3.4 were supported up to IPython 6.x.
35 Python 3.5 was supported with IPython 7.0 to 7.9.
35 Python 3.5 was supported with IPython 7.0 to 7.9.
36 Python 3.6 was supported with IPython up to 7.16.
36 Python 3.6 was supported with IPython up to 7.16.
37 Python 3.7 was still supported with the 7.x branch.
37 Python 3.7 was still supported with the 7.x branch.
38
38
39 See IPython `README.rst` file for more information:
39 See IPython `README.rst` file for more information:
40
40
41 https://github.com/ipython/ipython/blob/master/README.rst
41 https://github.com/ipython/ipython/blob/main/README.rst
42
42
43 """
43 """
44 )
44 )
45
45
46 #-----------------------------------------------------------------------------
46 #-----------------------------------------------------------------------------
47 # Setup the top level names
47 # Setup the top level names
48 #-----------------------------------------------------------------------------
48 #-----------------------------------------------------------------------------
49
49
50 from .core.getipython import get_ipython
50 from .core.getipython import get_ipython
51 from .core import release
51 from .core import release
52 from .core.application import Application
52 from .core.application import Application
53 from .terminal.embed import embed
53 from .terminal.embed import embed
54
54
55 from .core.interactiveshell import InteractiveShell
55 from .core.interactiveshell import InteractiveShell
56 from .utils.sysinfo import sys_info
56 from .utils.sysinfo import sys_info
57 from .utils.frame import extract_module_locals
57 from .utils.frame import extract_module_locals
58
58
59 # Release data
59 # Release data
60 __author__ = '%s <%s>' % (release.author, release.author_email)
60 __author__ = '%s <%s>' % (release.author, release.author_email)
61 __license__ = release.license
61 __license__ = release.license
62 __version__ = release.version
62 __version__ = release.version
63 version_info = release.version_info
63 version_info = release.version_info
64 # list of CVEs that should have been patched in this release.
64 # list of CVEs that should have been patched in this release.
65 # this is informational and should not be relied upon.
65 # this is informational and should not be relied upon.
66 __patched_cves__ = {"CVE-2022-21699"}
66 __patched_cves__ = {"CVE-2022-21699"}
67
67
68
68
69 def embed_kernel(module=None, local_ns=None, **kwargs):
69 def embed_kernel(module=None, local_ns=None, **kwargs):
70 """Embed and start an IPython kernel in a given scope.
70 """Embed and start an IPython kernel in a given scope.
71
71
72 If you don't want the kernel to initialize the namespace
72 If you don't want the kernel to initialize the namespace
73 from the scope of the surrounding function,
73 from the scope of the surrounding function,
74 and/or you want to load full IPython configuration,
74 and/or you want to load full IPython configuration,
75 you probably want `IPython.start_kernel()` instead.
75 you probably want `IPython.start_kernel()` instead.
76
76
77 Parameters
77 Parameters
78 ----------
78 ----------
79 module : types.ModuleType, optional
79 module : types.ModuleType, optional
80 The module to load into IPython globals (default: caller)
80 The module to load into IPython globals (default: caller)
81 local_ns : dict, optional
81 local_ns : dict, optional
82 The namespace to load into IPython user namespace (default: caller)
82 The namespace to load into IPython user namespace (default: caller)
83 **kwargs : various, optional
83 **kwargs : various, optional
84 Further keyword args are relayed to the IPKernelApp constructor,
84 Further keyword args are relayed to the IPKernelApp constructor,
85 allowing configuration of the Kernel. Will only have an effect
85 allowing configuration of the Kernel. Will only have an effect
86 on the first embed_kernel call for a given process.
86 on the first embed_kernel call for a given process.
87 """
87 """
88
88
89 (caller_module, caller_locals) = extract_module_locals(1)
89 (caller_module, caller_locals) = extract_module_locals(1)
90 if module is None:
90 if module is None:
91 module = caller_module
91 module = caller_module
92 if local_ns is None:
92 if local_ns is None:
93 local_ns = caller_locals
93 local_ns = caller_locals
94
94
95 # Only import .zmq when we really need it
95 # Only import .zmq when we really need it
96 from ipykernel.embed import embed_kernel as real_embed_kernel
96 from ipykernel.embed import embed_kernel as real_embed_kernel
97 real_embed_kernel(module=module, local_ns=local_ns, **kwargs)
97 real_embed_kernel(module=module, local_ns=local_ns, **kwargs)
98
98
99 def start_ipython(argv=None, **kwargs):
99 def start_ipython(argv=None, **kwargs):
100 """Launch a normal IPython instance (as opposed to embedded)
100 """Launch a normal IPython instance (as opposed to embedded)
101
101
102 `IPython.embed()` puts a shell in a particular calling scope,
102 `IPython.embed()` puts a shell in a particular calling scope,
103 such as a function or method for debugging purposes,
103 such as a function or method for debugging purposes,
104 which is often not desirable.
104 which is often not desirable.
105
105
106 `start_ipython()` does full, regular IPython initialization,
106 `start_ipython()` does full, regular IPython initialization,
107 including loading startup files, configuration, etc.
107 including loading startup files, configuration, etc.
108 much of which is skipped by `embed()`.
108 much of which is skipped by `embed()`.
109
109
110 This is a public API method, and will survive implementation changes.
110 This is a public API method, and will survive implementation changes.
111
111
112 Parameters
112 Parameters
113 ----------
113 ----------
114 argv : list or None, optional
114 argv : list or None, optional
115 If unspecified or None, IPython will parse command-line options from sys.argv.
115 If unspecified or None, IPython will parse command-line options from sys.argv.
116 To prevent any command-line parsing, pass an empty list: `argv=[]`.
116 To prevent any command-line parsing, pass an empty list: `argv=[]`.
117 user_ns : dict, optional
117 user_ns : dict, optional
118 specify this dictionary to initialize the IPython user namespace with particular values.
118 specify this dictionary to initialize the IPython user namespace with particular values.
119 **kwargs : various, optional
119 **kwargs : various, optional
120 Any other kwargs will be passed to the Application constructor,
120 Any other kwargs will be passed to the Application constructor,
121 such as `config`.
121 such as `config`.
122 """
122 """
123 from IPython.terminal.ipapp import launch_new_instance
123 from IPython.terminal.ipapp import launch_new_instance
124 return launch_new_instance(argv=argv, **kwargs)
124 return launch_new_instance(argv=argv, **kwargs)
125
125
126 def start_kernel(argv=None, **kwargs):
126 def start_kernel(argv=None, **kwargs):
127 """Launch a normal IPython kernel instance (as opposed to embedded)
127 """Launch a normal IPython kernel instance (as opposed to embedded)
128
128
129 `IPython.embed_kernel()` puts a shell in a particular calling scope,
129 `IPython.embed_kernel()` puts a shell in a particular calling scope,
130 such as a function or method for debugging purposes,
130 such as a function or method for debugging purposes,
131 which is often not desirable.
131 which is often not desirable.
132
132
133 `start_kernel()` does full, regular IPython initialization,
133 `start_kernel()` does full, regular IPython initialization,
134 including loading startup files, configuration, etc.
134 including loading startup files, configuration, etc.
135 much of which is skipped by `embed()`.
135 much of which is skipped by `embed()`.
136
136
137 Parameters
137 Parameters
138 ----------
138 ----------
139 argv : list or None, optional
139 argv : list or None, optional
140 If unspecified or None, IPython will parse command-line options from sys.argv.
140 If unspecified or None, IPython will parse command-line options from sys.argv.
141 To prevent any command-line parsing, pass an empty list: `argv=[]`.
141 To prevent any command-line parsing, pass an empty list: `argv=[]`.
142 user_ns : dict, optional
142 user_ns : dict, optional
143 specify this dictionary to initialize the IPython user namespace with particular values.
143 specify this dictionary to initialize the IPython user namespace with particular values.
144 **kwargs : various, optional
144 **kwargs : various, optional
145 Any other kwargs will be passed to the Application constructor,
145 Any other kwargs will be passed to the Application constructor,
146 such as `config`.
146 such as `config`.
147 """
147 """
148 import warnings
148 import warnings
149
149
150 warnings.warn(
150 warnings.warn(
151 "start_kernel is deprecated since IPython 8.0, use from `ipykernel.kernelapp.launch_new_instance`",
151 "start_kernel is deprecated since IPython 8.0, use from `ipykernel.kernelapp.launch_new_instance`",
152 DeprecationWarning,
152 DeprecationWarning,
153 stacklevel=2,
153 stacklevel=2,
154 )
154 )
155 from ipykernel.kernelapp import launch_new_instance
155 from ipykernel.kernelapp import launch_new_instance
156 return launch_new_instance(argv=argv, **kwargs)
156 return launch_new_instance(argv=argv, **kwargs)
@@ -1,171 +1,171 b''
1 .. image:: https://codecov.io/github/ipython/ipython/coverage.svg?branch=master
1 .. image:: https://codecov.io/github/ipython/ipython/coverage.svg?branch=main
2 :target: https://codecov.io/github/ipython/ipython?branch=master
2 :target: https://codecov.io/github/ipython/ipython?branch=main
3
3
4 .. image:: https://img.shields.io/pypi/v/IPython.svg
4 .. image:: https://img.shields.io/pypi/v/IPython.svg
5 :target: https://pypi.python.org/pypi/ipython
5 :target: https://pypi.python.org/pypi/ipython
6
6
7 .. image:: https://github.com/ipython/ipython/actions/workflows/test.yml/badge.svg
7 .. image:: https://github.com/ipython/ipython/actions/workflows/test.yml/badge.svg
8 :target: https://github.com/ipython/ipython/actions/workflows/test.yml)
8 :target: https://github.com/ipython/ipython/actions/workflows/test.yml)
9
9
10 .. image:: https://www.codetriage.com/ipython/ipython/badges/users.svg
10 .. image:: https://www.codetriage.com/ipython/ipython/badges/users.svg
11 :target: https://www.codetriage.com/ipython/ipython/
11 :target: https://www.codetriage.com/ipython/ipython/
12
12
13 .. image:: https://raster.shields.io/badge/Follows-NEP29-brightgreen.png
13 .. image:: https://raster.shields.io/badge/Follows-NEP29-brightgreen.png
14 :target: https://numpy.org/neps/nep-0029-deprecation_policy.html
14 :target: https://numpy.org/neps/nep-0029-deprecation_policy.html
15
15
16
16
17 ===========================================
17 ===========================================
18 IPython: Productive Interactive Computing
18 IPython: Productive Interactive Computing
19 ===========================================
19 ===========================================
20
20
21 Overview
21 Overview
22 ========
22 ========
23
23
24 Welcome to IPython. Our full documentation is available on `ipython.readthedocs.io
24 Welcome to IPython. Our full documentation is available on `ipython.readthedocs.io
25 <https://ipython.readthedocs.io/en/stable/>`_ and contains information on how to install, use, and
25 <https://ipython.readthedocs.io/en/stable/>`_ and contains information on how to install, use, and
26 contribute to the project.
26 contribute to the project.
27 IPython (Interactive Python) is a command shell for interactive computing in multiple programming languages, originally developed for the Python programming language, that offers introspection, rich media, shell syntax, tab completion, and history.
27 IPython (Interactive Python) is a command shell for interactive computing in multiple programming languages, originally developed for the Python programming language, that offers introspection, rich media, shell syntax, tab completion, and history.
28
28
29 **IPython versions and Python Support**
29 **IPython versions and Python Support**
30
30
31 Starting with IPython 7.10, IPython follows `NEP 29 <https://numpy.org/neps/nep-0029-deprecation_policy.html>`_
31 Starting with IPython 7.10, IPython follows `NEP 29 <https://numpy.org/neps/nep-0029-deprecation_policy.html>`_
32
32
33 **IPython 7.17+** requires Python version 3.7 and above.
33 **IPython 7.17+** requires Python version 3.7 and above.
34
34
35 **IPython 7.10+** requires Python version 3.6 and above.
35 **IPython 7.10+** requires Python version 3.6 and above.
36
36
37 **IPython 7.0** requires Python version 3.5 and above.
37 **IPython 7.0** requires Python version 3.5 and above.
38
38
39 **IPython 6.x** requires Python version 3.3 and above.
39 **IPython 6.x** requires Python version 3.3 and above.
40
40
41 **IPython 5.x LTS** is the compatible release for Python 2.7.
41 **IPython 5.x LTS** is the compatible release for Python 2.7.
42 If you require Python 2 support, you **must** use IPython 5.x LTS. Please
42 If you require Python 2 support, you **must** use IPython 5.x LTS. Please
43 update your project configurations and requirements as necessary.
43 update your project configurations and requirements as necessary.
44
44
45
45
46 The Notebook, Qt console and a number of other pieces are now parts of *Jupyter*.
46 The Notebook, Qt console and a number of other pieces are now parts of *Jupyter*.
47 See the `Jupyter installation docs <https://jupyter.readthedocs.io/en/latest/install.html>`__
47 See the `Jupyter installation docs <https://jupyter.readthedocs.io/en/latest/install.html>`__
48 if you want to use these.
48 if you want to use these.
49
49
50 Main features of IPython
50 Main features of IPython
51 ========================
51 ========================
52 Comprehensive object introspection.
52 Comprehensive object introspection.
53
53
54 Input history, persistent across sessions.
54 Input history, persistent across sessions.
55
55
56 Caching of output results during a session with automatically generated references.
56 Caching of output results during a session with automatically generated references.
57
57
58 Extensible tab completion, with support by default for completion of python variables and keywords, filenames and function keywords.
58 Extensible tab completion, with support by default for completion of python variables and keywords, filenames and function keywords.
59
59
60 Extensible system of β€˜magic’ commands for controlling the environment and performing many tasks related to IPython or the operating system.
60 Extensible system of β€˜magic’ commands for controlling the environment and performing many tasks related to IPython or the operating system.
61
61
62 A rich configuration system with easy switching between different setups (simpler than changing $PYTHONSTARTUP environment variables every time).
62 A rich configuration system with easy switching between different setups (simpler than changing $PYTHONSTARTUP environment variables every time).
63
63
64 Session logging and reloading.
64 Session logging and reloading.
65
65
66 Extensible syntax processing for special purpose situations.
66 Extensible syntax processing for special purpose situations.
67
67
68 Access to the system shell with user-extensible alias system.
68 Access to the system shell with user-extensible alias system.
69
69
70 Easily embeddable in other Python programs and GUIs.
70 Easily embeddable in other Python programs and GUIs.
71
71
72 Integrated access to the pdb debugger and the Python profiler.
72 Integrated access to the pdb debugger and the Python profiler.
73
73
74
74
75 Development and Instant running
75 Development and Instant running
76 ===============================
76 ===============================
77
77
78 You can find the latest version of the development documentation on `readthedocs
78 You can find the latest version of the development documentation on `readthedocs
79 <https://ipython.readthedocs.io/en/latest/>`_.
79 <https://ipython.readthedocs.io/en/latest/>`_.
80
80
81 You can run IPython from this directory without even installing it system-wide
81 You can run IPython from this directory without even installing it system-wide
82 by typing at the terminal::
82 by typing at the terminal::
83
83
84 $ python -m IPython
84 $ python -m IPython
85
85
86 Or see the `development installation docs
86 Or see the `development installation docs
87 <https://ipython.readthedocs.io/en/latest/install/install.html#installing-the-development-version>`_
87 <https://ipython.readthedocs.io/en/latest/install/install.html#installing-the-development-version>`_
88 for the latest revision on read the docs.
88 for the latest revision on read the docs.
89
89
90 Documentation and installation instructions for older version of IPython can be
90 Documentation and installation instructions for older version of IPython can be
91 found on the `IPython website <https://ipython.org/documentation.html>`_
91 found on the `IPython website <https://ipython.org/documentation.html>`_
92
92
93
93
94
94
95 IPython requires Python version 3 or above
95 IPython requires Python version 3 or above
96 ==========================================
96 ==========================================
97
97
98 Starting with version 6.0, IPython does not support Python 2.7, 3.0, 3.1, or
98 Starting with version 6.0, IPython does not support Python 2.7, 3.0, 3.1, or
99 3.2.
99 3.2.
100
100
101 For a version compatible with Python 2.7, please install the 5.x LTS Long Term
101 For a version compatible with Python 2.7, please install the 5.x LTS Long Term
102 Support version.
102 Support version.
103
103
104 If you are encountering this error message you are likely trying to install or
104 If you are encountering this error message you are likely trying to install or
105 use IPython from source. You need to checkout the remote 5.x branch. If you are
105 use IPython from source. You need to checkout the remote 5.x branch. If you are
106 using git the following should work::
106 using git the following should work::
107
107
108 $ git fetch origin
108 $ git fetch origin
109 $ git checkout 5.x
109 $ git checkout 5.x
110
110
111 If you encounter this error message with a regular install of IPython, then you
111 If you encounter this error message with a regular install of IPython, then you
112 likely need to update your package manager, for example if you are using `pip`
112 likely need to update your package manager, for example if you are using `pip`
113 check the version of pip with::
113 check the version of pip with::
114
114
115 $ pip --version
115 $ pip --version
116
116
117 You will need to update pip to the version 9.0.1 or greater. If you are not using
117 You will need to update pip to the version 9.0.1 or greater. If you are not using
118 pip, please inquiry with the maintainers of the package for your package
118 pip, please inquiry with the maintainers of the package for your package
119 manager.
119 manager.
120
120
121 For more information see one of our blog posts:
121 For more information see one of our blog posts:
122
122
123 https://blog.jupyter.org/release-of-ipython-5-0-8ce60b8d2e8e
123 https://blog.jupyter.org/release-of-ipython-5-0-8ce60b8d2e8e
124
124
125 As well as the following Pull-Request for discussion:
125 As well as the following Pull-Request for discussion:
126
126
127 https://github.com/ipython/ipython/pull/9900
127 https://github.com/ipython/ipython/pull/9900
128
128
129 This error does also occur if you are invoking ``setup.py`` directly – which you
129 This error does also occur if you are invoking ``setup.py`` directly – which you
130 should not – or are using ``easy_install`` If this is the case, use ``pip
130 should not – or are using ``easy_install`` If this is the case, use ``pip
131 install .`` instead of ``setup.py install`` , and ``pip install -e .`` instead
131 install .`` instead of ``setup.py install`` , and ``pip install -e .`` instead
132 of ``setup.py develop`` If you are depending on IPython as a dependency you may
132 of ``setup.py develop`` If you are depending on IPython as a dependency you may
133 also want to have a conditional dependency on IPython depending on the Python
133 also want to have a conditional dependency on IPython depending on the Python
134 version::
134 version::
135
135
136 install_req = ['ipython']
136 install_req = ['ipython']
137 if sys.version_info[0] < 3 and 'bdist_wheel' not in sys.argv:
137 if sys.version_info[0] < 3 and 'bdist_wheel' not in sys.argv:
138 install_req.remove('ipython')
138 install_req.remove('ipython')
139 install_req.append('ipython<6')
139 install_req.append('ipython<6')
140
140
141 setup(
141 setup(
142 ...
142 ...
143 install_requires=install_req
143 install_requires=install_req
144 )
144 )
145
145
146 Alternatives to IPython
146 Alternatives to IPython
147 =======================
147 =======================
148
148
149 IPython may not be to your taste; if that's the case there might be similar
149 IPython may not be to your taste; if that's the case there might be similar
150 project that you might want to use:
150 project that you might want to use:
151
151
152 - The classic Python REPL.
152 - The classic Python REPL.
153 - `bpython <https://bpython-interpreter.org/>`_
153 - `bpython <https://bpython-interpreter.org/>`_
154 - `mypython <https://www.asmeurer.com/mypython/>`_
154 - `mypython <https://www.asmeurer.com/mypython/>`_
155 - `ptpython and ptipython <https://pypi.org/project/ptpython/>`_
155 - `ptpython and ptipython <https://pypi.org/project/ptpython/>`_
156 - `Xonsh <https://xon.sh/>`_
156 - `Xonsh <https://xon.sh/>`_
157
157
158 Ignoring commits with git blame.ignoreRevsFile
158 Ignoring commits with git blame.ignoreRevsFile
159 ==============================================
159 ==============================================
160
160
161 As of git 2.23, it is possible to make formatting changes without breaking
161 As of git 2.23, it is possible to make formatting changes without breaking
162 ``git blame``. See the `git documentation
162 ``git blame``. See the `git documentation
163 <https://git-scm.com/docs/git-config#Documentation/git-config.txt-blameignoreRevsFile>`_
163 <https://git-scm.com/docs/git-config#Documentation/git-config.txt-blameignoreRevsFile>`_
164 for more details.
164 for more details.
165
165
166 To use this feature you must:
166 To use this feature you must:
167
167
168 - Install git >= 2.23
168 - Install git >= 2.23
169 - Configure your local git repo by running:
169 - Configure your local git repo by running:
170 - POSIX: ``tools\configure-git-blame-ignore-revs.sh``
170 - POSIX: ``tools\configure-git-blame-ignore-revs.sh``
171 - Windows: ``tools\configure-git-blame-ignore-revs.bat``
171 - Windows: ``tools\configure-git-blame-ignore-revs.bat``
@@ -1,320 +1,320 b''
1 .. _core_developer_guide:
1 .. _core_developer_guide:
2
2
3 =================================
3 =================================
4 Guide for IPython core Developers
4 Guide for IPython core Developers
5 =================================
5 =================================
6
6
7 This guide documents the development of IPython itself. Alternatively,
7 This guide documents the development of IPython itself. Alternatively,
8 developers of third party tools and libraries that use IPython should see the
8 developers of third party tools and libraries that use IPython should see the
9 :doc:`../development/index`.
9 :doc:`../development/index`.
10
10
11
11
12 For instructions on how to make a developer install see :ref:`devinstall`.
12 For instructions on how to make a developer install see :ref:`devinstall`.
13
13
14 Backporting Pull requests
14 Backporting Pull requests
15 =========================
15 =========================
16
16
17 All pull requests should usually be made against ``master``, if a Pull Request
17 All pull requests should usually be made against ``main``, if a Pull Request
18 need to be backported to an earlier release; then it should be tagged with the
18 need to be backported to an earlier release; then it should be tagged with the
19 correct ``milestone``.
19 correct ``milestone``.
20
20
21 If you tag a pull request with a milestone **before** merging the pull request,
21 If you tag a pull request with a milestone **before** merging the pull request,
22 and the base ref is ``master``, then our backport bot should automatically create
22 and the base ref is ``main``, then our backport bot should automatically create
23 a corresponding pull-request that backport on the correct branch.
23 a corresponding pull-request that backport on the correct branch.
24
24
25 If you have write access to the IPython repository you can also just mention the
25 If you have write access to the IPython repository you can also just mention the
26 **backport bot** to do the work for you. The bot is evolving so instructions may
26 **backport bot** to do the work for you. The bot is evolving so instructions may
27 be different. At the time of this writing you can use::
27 be different. At the time of this writing you can use::
28
28
29 @meeseeksdev[bot] backport [to] <branchname>
29 @meeseeksdev[bot] backport [to] <branchname>
30
30
31 The bot will attempt to backport the current pull-request and issue a PR if
31 The bot will attempt to backport the current pull-request and issue a PR if
32 possible.
32 possible.
33
33
34 .. note::
34 .. note::
35
35
36 The ``@`` and ``[bot]`` when mentioning the bot should be optional and can
36 The ``@`` and ``[bot]`` when mentioning the bot should be optional and can
37 be omitted.
37 be omitted.
38
38
39 If the pull request cannot be automatically backported, the bot should tell you
39 If the pull request cannot be automatically backported, the bot should tell you
40 so on the PR and apply a "Need manual backport" tag to the origin PR.
40 so on the PR and apply a "Need manual backport" tag to the origin PR.
41
41
42 .. _release_process:
42 .. _release_process:
43
43
44 IPython release process
44 IPython release process
45 =======================
45 =======================
46
46
47 This document contains the process that is used to create an IPython release.
47 This document contains the process that is used to create an IPython release.
48
48
49 Conveniently, the ``release`` script in the ``tools`` directory of the ``IPython``
49 Conveniently, the ``release`` script in the ``tools`` directory of the ``IPython``
50 repository automates most of the release process. This document serves as a
50 repository automates most of the release process. This document serves as a
51 handy reminder and checklist for the release manager.
51 handy reminder and checklist for the release manager.
52
52
53 During the release process, you might need the extra following dependencies:
53 During the release process, you might need the extra following dependencies:
54
54
55 - ``keyring`` to access your GitHub authentication tokens
55 - ``keyring`` to access your GitHub authentication tokens
56 - ``graphviz`` to generate some graphs in the documentation
56 - ``graphviz`` to generate some graphs in the documentation
57 - ``ghpro`` to generate the stats
57 - ``ghpro`` to generate the stats
58
58
59 Make sure you have all the required dependencies to run the tests as well.
59 Make sure you have all the required dependencies to run the tests as well.
60
60
61 You can try to ``source tools/release_helper.sh`` when releasing via bash, it
61 You can try to ``source tools/release_helper.sh`` when releasing via bash, it
62 should guide you through most of the process.
62 should guide you through most of the process.
63
63
64
64
65 1. Set Environment variables
65 1. Set Environment variables
66 ----------------------------
66 ----------------------------
67
67
68 Set environment variables to document previous release tag, current
68 Set environment variables to document previous release tag, current
69 release milestone, current release version, and git tag.
69 release milestone, current release version, and git tag.
70
70
71 These variables may be used later to copy/paste as answers to the script
71 These variables may be used later to copy/paste as answers to the script
72 questions instead of typing the appropriate command when the time comes. These
72 questions instead of typing the appropriate command when the time comes. These
73 variables are not used by the scripts directly; therefore, there is no need to
73 variables are not used by the scripts directly; therefore, there is no need to
74 ``export`` them. The format for bash is as follows, but note that these values
74 ``export`` them. The format for bash is as follows, but note that these values
75 are just an example valid only for the 5.0 release; you'll need to update them
75 are just an example valid only for the 5.0 release; you'll need to update them
76 for the release you are actually making::
76 for the release you are actually making::
77
77
78 PREV_RELEASE=4.2.1
78 PREV_RELEASE=4.2.1
79 MILESTONE=5.0
79 MILESTONE=5.0
80 VERSION=5.0.0
80 VERSION=5.0.0
81 BRANCH=master
81 BRANCH=main
82
82
83 For `reproducibility of builds <https://reproducible-builds.org/specs/source-date-epoch/>`_,
83 For `reproducibility of builds <https://reproducible-builds.org/specs/source-date-epoch/>`_,
84 we recommend setting ``SOURCE_DATE_EPOCH`` prior to running the build; record the used value
84 we recommend setting ``SOURCE_DATE_EPOCH`` prior to running the build; record the used value
85 of ``SOURCE_DATE_EPOCH`` as it may not be available from build artifact. You
85 of ``SOURCE_DATE_EPOCH`` as it may not be available from build artifact. You
86 should be able to use ``date +%s`` to get a formatted timestamp::
86 should be able to use ``date +%s`` to get a formatted timestamp::
87
87
88 SOURCE_DATE_EPOCH=$(date +%s)
88 SOURCE_DATE_EPOCH=$(date +%s)
89
89
90
90
91 2. Create GitHub stats and finish release note
91 2. Create GitHub stats and finish release note
92 ----------------------------------------------
92 ----------------------------------------------
93
93
94 .. note::
94 .. note::
95
95
96 This step is optional if making a Beta or RC release.
96 This step is optional if making a Beta or RC release.
97
97
98 .. note::
98 .. note::
99
99
100 Before generating the GitHub stats, verify that all closed issues and pull
100 Before generating the GitHub stats, verify that all closed issues and pull
101 requests have `appropriate milestones
101 requests have `appropriate milestones
102 <https://github.com/ipython/ipython/wiki/Dev:-GitHub-workflow#milestones>`_.
102 <https://github.com/ipython/ipython/wiki/Dev:-GitHub-workflow#milestones>`_.
103 `This search
103 `This search
104 <https://github.com/ipython/ipython/issues?q=is%3Aclosed+no%3Amilestone+is%3Aissue>`_
104 <https://github.com/ipython/ipython/issues?q=is%3Aclosed+no%3Amilestone+is%3Aissue>`_
105 should return no results before creating the GitHub stats.
105 should return no results before creating the GitHub stats.
106
106
107 If a major release:
107 If a major release:
108
108
109 - merge any pull request notes into what's new::
109 - merge any pull request notes into what's new::
110
110
111 python tools/update_whatsnew.py
111 python tools/update_whatsnew.py
112
112
113 - update ``docs/source/whatsnew/development.rst``, to ensure it covers
113 - update ``docs/source/whatsnew/development.rst``, to ensure it covers
114 the major release features
114 the major release features
115
115
116 - move the contents of ``development.rst`` to ``versionX.rst`` where ``X`` is
116 - move the contents of ``development.rst`` to ``versionX.rst`` where ``X`` is
117 the numerical release version
117 the numerical release version
118
118
119 - generate summary of GitHub contributions, which can be done with::
119 - generate summary of GitHub contributions, which can be done with::
120
120
121 python tools/github_stats.py --milestone $MILESTONE > stats.rst
121 python tools/github_stats.py --milestone $MILESTONE > stats.rst
122
122
123 which may need some manual cleanup of ``stats.rst``. Add the cleaned
123 which may need some manual cleanup of ``stats.rst``. Add the cleaned
124 ``stats.rst`` results to ``docs/source/whatsnew/github-stats-X.rst``
124 ``stats.rst`` results to ``docs/source/whatsnew/github-stats-X.rst``
125 where ``X`` is the numerical release version (don't forget to add it to
125 where ``X`` is the numerical release version (don't forget to add it to
126 the git repository as well). If creating a major release, make a new
126 the git repository as well). If creating a major release, make a new
127 ``github-stats-X.rst`` file; if creating a minor release, the content
127 ``github-stats-X.rst`` file; if creating a minor release, the content
128 from ``stats.rst`` may simply be added to the top of an existing
128 from ``stats.rst`` may simply be added to the top of an existing
129 ``github-stats-X.rst`` file.
129 ``github-stats-X.rst`` file.
130
130
131 - Edit ``docs/source/whatsnew/index.rst`` to list the new ``github-stats-X``
131 - Edit ``docs/source/whatsnew/index.rst`` to list the new ``github-stats-X``
132 file you just created.
132 file you just created.
133
133
134 - You do not need to temporarily remove the first entry called
134 - You do not need to temporarily remove the first entry called
135 ``development``, nor re-add it after the release, it will automatically be
135 ``development``, nor re-add it after the release, it will automatically be
136 hidden when releasing a stable version of IPython (if ``_version_extra``
136 hidden when releasing a stable version of IPython (if ``_version_extra``
137 in ``release.py`` is an empty string.
137 in ``release.py`` is an empty string.
138
138
139 Make sure that the stats file has a header or it won't be rendered in
139 Make sure that the stats file has a header or it won't be rendered in
140 the final documentation.
140 the final documentation.
141
141
142 To find duplicates and update `.mailmap`, use::
142 To find duplicates and update `.mailmap`, use::
143
143
144 git log --format="%aN <%aE>" $PREV_RELEASE... | sort -u -f
144 git log --format="%aN <%aE>" $PREV_RELEASE... | sort -u -f
145
145
146 If a minor release you might need to do some of the above points manually, and
146 If a minor release you might need to do some of the above points manually, and
147 forward port the changes.
147 forward port the changes.
148
148
149 3. Make sure the repository is clean
149 3. Make sure the repository is clean
150 ------------------------------------
150 ------------------------------------
151
151
152 of any file that could be problematic.
152 of any file that could be problematic.
153 Remove all non-tracked files with:
153 Remove all non-tracked files with:
154
154
155 .. code::
155 .. code::
156
156
157 git clean -xfdi
157 git clean -xfdi
158
158
159 This will ask for confirmation before removing all untracked files. Make
159 This will ask for confirmation before removing all untracked files. Make
160 sure the ``dist/`` folder is clean to avoid any stale builds from
160 sure the ``dist/`` folder is clean to avoid any stale builds from
161 previous build attempts.
161 previous build attempts.
162
162
163
163
164 4. Update the release version number
164 4. Update the release version number
165 ------------------------------------
165 ------------------------------------
166
166
167 Edit ``IPython/core/release.py`` to have the current version.
167 Edit ``IPython/core/release.py`` to have the current version.
168
168
169 in particular, update version number and ``_version_extra`` content in
169 in particular, update version number and ``_version_extra`` content in
170 ``IPython/core/release.py``.
170 ``IPython/core/release.py``.
171
171
172 Step 5 will validate your changes automatically, but you might still want to
172 Step 5 will validate your changes automatically, but you might still want to
173 make sure the version number matches pep440.
173 make sure the version number matches pep440.
174
174
175 In particular, ``rc`` and ``beta`` are not separated by ``.`` or the ``sdist``
175 In particular, ``rc`` and ``beta`` are not separated by ``.`` or the ``sdist``
176 and ``bdist`` will appear as different releases. For example, a valid version
176 and ``bdist`` will appear as different releases. For example, a valid version
177 number for a release candidate (rc) release is: ``1.3rc1``. Notice that there
177 number for a release candidate (rc) release is: ``1.3rc1``. Notice that there
178 is no separator between the '3' and the 'r'. Check the environment variable
178 is no separator between the '3' and the 'r'. Check the environment variable
179 ``$VERSION`` as well.
179 ``$VERSION`` as well.
180
180
181 You will likely just have to modify/comment/uncomment one of the lines setting
181 You will likely just have to modify/comment/uncomment one of the lines setting
182 ``_version_extra``
182 ``_version_extra``
183
183
184
184
185 5. Run the `tools/build_release` script
185 5. Run the `tools/build_release` script
186 ---------------------------------------
186 ---------------------------------------
187
187
188 Running ``tools/build_release`` does all the file checking and building that
188 Running ``tools/build_release`` does all the file checking and building that
189 the real release script will do. This makes test installations, checks that
189 the real release script will do. This makes test installations, checks that
190 the build procedure runs OK, and tests other steps in the release process.
190 the build procedure runs OK, and tests other steps in the release process.
191
191
192 The ``build_release`` script will in particular verify that the version number
192 The ``build_release`` script will in particular verify that the version number
193 match PEP 440, in order to avoid surprise at the time of build upload.
193 match PEP 440, in order to avoid surprise at the time of build upload.
194
194
195 We encourage creating a test build of the docs as well.
195 We encourage creating a test build of the docs as well.
196
196
197 6. Create and push the new tag
197 6. Create and push the new tag
198 ------------------------------
198 ------------------------------
199
199
200 Commit the changes to release.py::
200 Commit the changes to release.py::
201
201
202 git commit -am "release $VERSION" -S
202 git commit -am "release $VERSION" -S
203 git push origin $BRANCH
203 git push origin $BRANCH
204
204
205 (omit the ``-S`` if you are no signing the package)
205 (omit the ``-S`` if you are no signing the package)
206
206
207 Create and push the tag::
207 Create and push the tag::
208
208
209 git tag -am "release $VERSION" "$VERSION" -s
209 git tag -am "release $VERSION" "$VERSION" -s
210 git push origin $VERSION
210 git push origin $VERSION
211
211
212 (omit the ``-s`` if you are no signing the package)
212 (omit the ``-s`` if you are no signing the package)
213
213
214 Update release.py back to ``x.y-dev`` or ``x.y-maint`` commit and push::
214 Update release.py back to ``x.y-dev`` or ``x.y-maint`` commit and push::
215
215
216 git commit -am "back to development" -S
216 git commit -am "back to development" -S
217 git push origin $BRANCH
217 git push origin $BRANCH
218
218
219 (omit the ``-S`` if you are no signing the package)
219 (omit the ``-S`` if you are no signing the package)
220
220
221 Now checkout the tag we just made::
221 Now checkout the tag we just made::
222
222
223 git checkout $VERSION
223 git checkout $VERSION
224
224
225 7. Run the release script
225 7. Run the release script
226 -------------------------
226 -------------------------
227
227
228 Run the ``release`` script, this step requires having a current wheel, Python
228 Run the ``release`` script, this step requires having a current wheel, Python
229 >=3.4 and Python 2.7.::
229 >=3.4 and Python 2.7.::
230
230
231 ./tools/release
231 ./tools/release
232
232
233 This makes the tarballs and wheels, and puts them under the ``dist/``
233 This makes the tarballs and wheels, and puts them under the ``dist/``
234 folder. Be sure to test the ``wheels`` and the ``sdist`` locally before
234 folder. Be sure to test the ``wheels`` and the ``sdist`` locally before
235 uploading them to PyPI. We do not use an universal wheel as each wheel
235 uploading them to PyPI. We do not use an universal wheel as each wheel
236 installs an ``ipython2`` or ``ipython3`` script, depending on the version of
236 installs an ``ipython2`` or ``ipython3`` script, depending on the version of
237 Python it is built for. Using an universal wheel would prevent this.
237 Python it is built for. Using an universal wheel would prevent this.
238
238
239 Check the shasum of files with::
239 Check the shasum of files with::
240
240
241 shasum -a 256 dist/*
241 shasum -a 256 dist/*
242
242
243 and takes notes of them you might need them to update the conda-forge recipes.
243 and takes notes of them you might need them to update the conda-forge recipes.
244 Rerun the command and check the hash have not changed::
244 Rerun the command and check the hash have not changed::
245
245
246 ./tools/release
246 ./tools/release
247 shasum -a 256 dist/*
247 shasum -a 256 dist/*
248
248
249 Use the following to actually upload the result of the build::
249 Use the following to actually upload the result of the build::
250
250
251 ./tools/release upload
251 ./tools/release upload
252
252
253 It should posts them to ``archive.ipython.org`` and to PyPI.
253 It should posts them to ``archive.ipython.org`` and to PyPI.
254
254
255 PyPI/Warehouse will automatically hide previous releases. If you are uploading
255 PyPI/Warehouse will automatically hide previous releases. If you are uploading
256 a non-stable version, make sure to log-in to PyPI and un-hide previous version.
256 a non-stable version, make sure to log-in to PyPI and un-hide previous version.
257
257
258
258
259 8. Draft a short release announcement
259 8. Draft a short release announcement
260 -------------------------------------
260 -------------------------------------
261
261
262 The announcement should include:
262 The announcement should include:
263
263
264 - release highlights
264 - release highlights
265 - a link to the html version of the *What's new* section of the documentation
265 - a link to the html version of the *What's new* section of the documentation
266 - a link to upgrade or installation tips (if necessary)
266 - a link to upgrade or installation tips (if necessary)
267
267
268 Post the announcement to the mailing list and or blog, and link from Twitter.
268 Post the announcement to the mailing list and or blog, and link from Twitter.
269
269
270 .. note::
270 .. note::
271
271
272 If you are doing a RC or Beta, you can likely skip the next steps.
272 If you are doing a RC or Beta, you can likely skip the next steps.
273
273
274 9. Update milestones on GitHub
274 9. Update milestones on GitHub
275 -------------------------------
275 -------------------------------
276
276
277 These steps will bring milestones up to date:
277 These steps will bring milestones up to date:
278
278
279 - close the just released milestone
279 - close the just released milestone
280 - open a new milestone for the next release (x, y+1), if the milestone doesn't
280 - open a new milestone for the next release (x, y+1), if the milestone doesn't
281 exist already
281 exist already
282
282
283 10. Update the IPython website
283 10. Update the IPython website
284 ------------------------------
284 ------------------------------
285
285
286 The IPython website should document the new release:
286 The IPython website should document the new release:
287
287
288 - add release announcement (news, announcements)
288 - add release announcement (news, announcements)
289 - update current version and download links
289 - update current version and download links
290 - update links on the documentation page (especially if a major release)
290 - update links on the documentation page (especially if a major release)
291
291
292 11. Update readthedocs
292 11. Update readthedocs
293 ----------------------
293 ----------------------
294
294
295 Make sure to update readthedocs and set the latest tag as stable, as well as
295 Make sure to update readthedocs and set the latest tag as stable, as well as
296 checking that previous release is still building under its own tag.
296 checking that previous release is still building under its own tag.
297
297
298 12. Update the Conda-Forge feedstock
298 12. Update the Conda-Forge feedstock
299 ------------------------------------
299 ------------------------------------
300
300
301 Follow the instructions on `the repository <https://github.com/conda-forge/ipython-feedstock>`_
301 Follow the instructions on `the repository <https://github.com/conda-forge/ipython-feedstock>`_
302
302
303 13. Celebrate!
303 13. Celebrate!
304 --------------
304 --------------
305
305
306 Celebrate the release and please thank the contributors for their work. Great
306 Celebrate the release and please thank the contributors for their work. Great
307 job!
307 job!
308
308
309
309
310
310
311 Old Documentation
311 Old Documentation
312 =================
312 =================
313
313
314 Out of date documentation is still available and have been kept for archival purposes.
314 Out of date documentation is still available and have been kept for archival purposes.
315
315
316 .. note::
316 .. note::
317
317
318 Developers documentation used to be on the IPython wiki, but are now out of
318 Developers documentation used to be on the IPython wiki, but are now out of
319 date. The wiki is though still available for historical reasons: `Old IPython
319 date. The wiki is though still available for historical reasons: `Old IPython
320 GitHub Wiki. <https://github.com/ipython/ipython/wiki/Dev:-Index>`_
320 GitHub Wiki. <https://github.com/ipython/ipython/wiki/Dev:-Index>`_
@@ -1,285 +1,285 b''
1 {
1 {
2 "cells": [
2 "cells": [
3 {
3 {
4 "cell_type": "markdown",
4 "cell_type": "markdown",
5 "metadata": {},
5 "metadata": {},
6 "source": [
6 "source": [
7 "# A few things that work best/only at the IPython terminal or Qt console clients"
7 "# A few things that work best/only at the IPython terminal or Qt console clients"
8 ]
8 ]
9 },
9 },
10 {
10 {
11 "cell_type": "markdown",
11 "cell_type": "markdown",
12 "metadata": {},
12 "metadata": {},
13 "source": [
13 "source": [
14 "## Running code with `%run`"
14 "## Running code with `%run`"
15 ]
15 ]
16 },
16 },
17 {
17 {
18 "cell_type": "code",
18 "cell_type": "code",
19 "execution_count": 1,
19 "execution_count": 1,
20 "metadata": {
20 "metadata": {
21 "collapsed": false
21 "collapsed": false
22 },
22 },
23 "outputs": [
23 "outputs": [
24 {
24 {
25 "name": "stdout",
25 "name": "stdout",
26 "output_type": "stream",
26 "output_type": "stream",
27 "text": [
27 "text": [
28 "Writing script.py\n"
28 "Writing script.py\n"
29 ]
29 ]
30 }
30 }
31 ],
31 ],
32 "source": [
32 "source": [
33 "%%writefile script.py\n",
33 "%%writefile script.py\n",
34 "x = 10\n",
34 "x = 10\n",
35 "y = 20\n",
35 "y = 20\n",
36 "z = x+y\n",
36 "z = x+y\n",
37 "print('z is: %s' % z)"
37 "print('z is: %s' % z)"
38 ]
38 ]
39 },
39 },
40 {
40 {
41 "cell_type": "code",
41 "cell_type": "code",
42 "execution_count": 2,
42 "execution_count": 2,
43 "metadata": {
43 "metadata": {
44 "collapsed": false
44 "collapsed": false
45 },
45 },
46 "outputs": [
46 "outputs": [
47 {
47 {
48 "name": "stdout",
48 "name": "stdout",
49 "output_type": "stream",
49 "output_type": "stream",
50 "text": [
50 "text": [
51 "z is: 30\n"
51 "z is: 30\n"
52 ]
52 ]
53 }
53 }
54 ],
54 ],
55 "source": [
55 "source": [
56 "%run script"
56 "%run script"
57 ]
57 ]
58 },
58 },
59 {
59 {
60 "cell_type": "code",
60 "cell_type": "code",
61 "execution_count": 3,
61 "execution_count": 3,
62 "metadata": {
62 "metadata": {
63 "collapsed": false
63 "collapsed": false
64 },
64 },
65 "outputs": [
65 "outputs": [
66 {
66 {
67 "data": {
67 "data": {
68 "text/plain": [
68 "text/plain": [
69 "10"
69 "10"
70 ]
70 ]
71 },
71 },
72 "execution_count": 3,
72 "execution_count": 3,
73 "metadata": {},
73 "metadata": {},
74 "output_type": "execute_result"
74 "output_type": "execute_result"
75 }
75 }
76 ],
76 ],
77 "source": [
77 "source": [
78 "x"
78 "x"
79 ]
79 ]
80 },
80 },
81 {
81 {
82 "cell_type": "markdown",
82 "cell_type": "markdown",
83 "metadata": {},
83 "metadata": {},
84 "source": [
84 "source": [
85 "## Event loop and GUI integration"
85 "## Event loop and GUI integration"
86 ]
86 ]
87 },
87 },
88 {
88 {
89 "cell_type": "markdown",
89 "cell_type": "markdown",
90 "metadata": {},
90 "metadata": {},
91 "source": [
91 "source": [
92 "The `%gui` magic enables the integration of GUI event loops with the interactive execution loop, allowing you to run GUI code without blocking IPython.\n",
92 "The `%gui` magic enables the integration of GUI event loops with the interactive execution loop, allowing you to run GUI code without blocking IPython.\n",
93 "\n",
93 "\n",
94 "Consider for example the execution of Qt-based code. Once we enable the Qt gui support:"
94 "Consider for example the execution of Qt-based code. Once we enable the Qt gui support:"
95 ]
95 ]
96 },
96 },
97 {
97 {
98 "cell_type": "code",
98 "cell_type": "code",
99 "execution_count": 4,
99 "execution_count": 4,
100 "metadata": {
100 "metadata": {
101 "collapsed": false
101 "collapsed": false
102 },
102 },
103 "outputs": [],
103 "outputs": [],
104 "source": [
104 "source": [
105 "%gui qt"
105 "%gui qt"
106 ]
106 ]
107 },
107 },
108 {
108 {
109 "cell_type": "markdown",
109 "cell_type": "markdown",
110 "metadata": {},
110 "metadata": {},
111 "source": [
111 "source": [
112 "We can define a simple Qt application class (simplified version from [this Qt tutorial](http://zetcode.com/tutorials/pyqt4/firstprograms)):"
112 "We can define a simple Qt application class (simplified version from [this Qt tutorial](http://zetcode.com/tutorials/pyqt4/firstprograms)):"
113 ]
113 ]
114 },
114 },
115 {
115 {
116 "cell_type": "code",
116 "cell_type": "code",
117 "execution_count": 5,
117 "execution_count": 5,
118 "metadata": {
118 "metadata": {
119 "collapsed": false
119 "collapsed": false
120 },
120 },
121 "outputs": [],
121 "outputs": [],
122 "source": [
122 "source": [
123 "import sys\n",
123 "import sys\n",
124 "from PyQt4 import QtGui, QtCore\n",
124 "from PyQt4 import QtGui, QtCore\n",
125 "\n",
125 "\n",
126 "class SimpleWindow(QtGui.QWidget):\n",
126 "class SimpleWindow(QtGui.QWidget):\n",
127 " def __init__(self, parent=None):\n",
127 " def __init__(self, parent=None):\n",
128 " QtGui.QWidget.__init__(self, parent)\n",
128 " QtGui.QWidget.__init__(self, parent)\n",
129 "\n",
129 "\n",
130 " self.setGeometry(300, 300, 200, 80)\n",
130 " self.setGeometry(300, 300, 200, 80)\n",
131 " self.setWindowTitle('Hello World')\n",
131 " self.setWindowTitle('Hello World')\n",
132 "\n",
132 "\n",
133 " quit = QtGui.QPushButton('Close', self)\n",
133 " quit = QtGui.QPushButton('Close', self)\n",
134 " quit.setGeometry(10, 10, 60, 35)\n",
134 " quit.setGeometry(10, 10, 60, 35)\n",
135 "\n",
135 "\n",
136 " self.connect(quit, QtCore.SIGNAL('clicked()'),\n",
136 " self.connect(quit, QtCore.SIGNAL('clicked()'),\n",
137 " self, QtCore.SLOT('close()'))"
137 " self, QtCore.SLOT('close()'))"
138 ]
138 ]
139 },
139 },
140 {
140 {
141 "cell_type": "markdown",
141 "cell_type": "markdown",
142 "metadata": {},
142 "metadata": {},
143 "source": [
143 "source": [
144 "And now we can instantiate it:"
144 "And now we can instantiate it:"
145 ]
145 ]
146 },
146 },
147 {
147 {
148 "cell_type": "code",
148 "cell_type": "code",
149 "execution_count": 6,
149 "execution_count": 6,
150 "metadata": {
150 "metadata": {
151 "collapsed": false
151 "collapsed": false
152 },
152 },
153 "outputs": [],
153 "outputs": [],
154 "source": [
154 "source": [
155 "app = QtCore.QCoreApplication.instance()\n",
155 "app = QtCore.QCoreApplication.instance()\n",
156 "if app is None:\n",
156 "if app is None:\n",
157 " app = QtGui.QApplication([])\n",
157 " app = QtGui.QApplication([])\n",
158 "\n",
158 "\n",
159 "sw = SimpleWindow()\n",
159 "sw = SimpleWindow()\n",
160 "sw.show()\n",
160 "sw.show()\n",
161 "\n",
161 "\n",
162 "from IPython.lib.guisupport import start_event_loop_qt4\n",
162 "from IPython.lib.guisupport import start_event_loop_qt4\n",
163 "start_event_loop_qt4(app)"
163 "start_event_loop_qt4(app)"
164 ]
164 ]
165 },
165 },
166 {
166 {
167 "cell_type": "markdown",
167 "cell_type": "markdown",
168 "metadata": {},
168 "metadata": {},
169 "source": [
169 "source": [
170 "But IPython still remains responsive:"
170 "But IPython still remains responsive:"
171 ]
171 ]
172 },
172 },
173 {
173 {
174 "cell_type": "code",
174 "cell_type": "code",
175 "execution_count": 7,
175 "execution_count": 7,
176 "metadata": {
176 "metadata": {
177 "collapsed": false
177 "collapsed": false
178 },
178 },
179 "outputs": [
179 "outputs": [
180 {
180 {
181 "data": {
181 "data": {
182 "text/plain": [
182 "text/plain": [
183 "12"
183 "12"
184 ]
184 ]
185 },
185 },
186 "execution_count": 7,
186 "execution_count": 7,
187 "metadata": {},
187 "metadata": {},
188 "output_type": "execute_result"
188 "output_type": "execute_result"
189 }
189 }
190 ],
190 ],
191 "source": [
191 "source": [
192 "10+2"
192 "10+2"
193 ]
193 ]
194 },
194 },
195 {
195 {
196 "cell_type": "markdown",
196 "cell_type": "markdown",
197 "metadata": {},
197 "metadata": {},
198 "source": [
198 "source": [
199 "The `%gui` magic can be similarly used to control Wx, Tk, glut and pyglet applications, [as can be seen in our examples](https://github.com/ipython/ipython/tree/master/examples/lib)."
199 "The `%gui` magic can be similarly used to control Wx, Tk, glut and pyglet applications, [as can be seen in our examples](https://github.com/ipython/ipython/tree/main/examples/lib)."
200 ]
200 ]
201 },
201 },
202 {
202 {
203 "cell_type": "markdown",
203 "cell_type": "markdown",
204 "metadata": {},
204 "metadata": {},
205 "source": [
205 "source": [
206 "## Embedding IPython in a terminal application"
206 "## Embedding IPython in a terminal application"
207 ]
207 ]
208 },
208 },
209 {
209 {
210 "cell_type": "code",
210 "cell_type": "code",
211 "execution_count": 8,
211 "execution_count": 8,
212 "metadata": {
212 "metadata": {
213 "collapsed": false
213 "collapsed": false
214 },
214 },
215 "outputs": [
215 "outputs": [
216 {
216 {
217 "name": "stdout",
217 "name": "stdout",
218 "output_type": "stream",
218 "output_type": "stream",
219 "text": [
219 "text": [
220 "Writing simple-embed.py\n"
220 "Writing simple-embed.py\n"
221 ]
221 ]
222 }
222 }
223 ],
223 ],
224 "source": [
224 "source": [
225 "%%writefile simple-embed.py\n",
225 "%%writefile simple-embed.py\n",
226 "# This shows how to use the new top-level embed function. It is a simpler\n",
226 "# This shows how to use the new top-level embed function. It is a simpler\n",
227 "# API that manages the creation of the embedded shell.\n",
227 "# API that manages the creation of the embedded shell.\n",
228 "\n",
228 "\n",
229 "from IPython import embed\n",
229 "from IPython import embed\n",
230 "\n",
230 "\n",
231 "a = 10\n",
231 "a = 10\n",
232 "b = 20\n",
232 "b = 20\n",
233 "\n",
233 "\n",
234 "embed(header='First time', banner1='')\n",
234 "embed(header='First time', banner1='')\n",
235 "\n",
235 "\n",
236 "c = 30\n",
236 "c = 30\n",
237 "d = 40\n",
237 "d = 40\n",
238 "\n",
238 "\n",
239 "embed(header='The second time')"
239 "embed(header='The second time')"
240 ]
240 ]
241 },
241 },
242 {
242 {
243 "cell_type": "markdown",
243 "cell_type": "markdown",
244 "metadata": {},
244 "metadata": {},
245 "source": [
245 "source": [
246 "The example in kernel-embedding shows how to embed a full kernel into an application and how to connect to this kernel from an external process."
246 "The example in kernel-embedding shows how to embed a full kernel into an application and how to connect to this kernel from an external process."
247 ]
247 ]
248 },
248 },
249 {
249 {
250 "cell_type": "markdown",
250 "cell_type": "markdown",
251 "metadata": {},
251 "metadata": {},
252 "source": [
252 "source": [
253 "## Logging terminal sessions and transitioning to a notebook"
253 "## Logging terminal sessions and transitioning to a notebook"
254 ]
254 ]
255 },
255 },
256 {
256 {
257 "cell_type": "markdown",
257 "cell_type": "markdown",
258 "metadata": {},
258 "metadata": {},
259 "source": [
259 "source": [
260 "The `%logstart` magic lets you log a terminal session with various degrees of control, and the `%notebook` one will convert an interactive console session into a notebook with all input cells already created for you (but no output)."
260 "The `%logstart` magic lets you log a terminal session with various degrees of control, and the `%notebook` one will convert an interactive console session into a notebook with all input cells already created for you (but no output)."
261 ]
261 ]
262 }
262 }
263 ],
263 ],
264 "metadata": {
264 "metadata": {
265 "kernelspec": {
265 "kernelspec": {
266 "display_name": "Python 3",
266 "display_name": "Python 3",
267 "language": "python",
267 "language": "python",
268 "name": "python3"
268 "name": "python3"
269 },
269 },
270 "language_info": {
270 "language_info": {
271 "codemirror_mode": {
271 "codemirror_mode": {
272 "name": "ipython",
272 "name": "ipython",
273 "version": 3
273 "version": 3
274 },
274 },
275 "file_extension": ".py",
275 "file_extension": ".py",
276 "mimetype": "text/x-python",
276 "mimetype": "text/x-python",
277 "name": "python",
277 "name": "python",
278 "nbconvert_exporter": "python",
278 "nbconvert_exporter": "python",
279 "pygments_lexer": "ipython3",
279 "pygments_lexer": "ipython3",
280 "version": "3.4.2"
280 "version": "3.4.2"
281 }
281 }
282 },
282 },
283 "nbformat": 4,
283 "nbformat": 4,
284 "nbformat_minor": 0
284 "nbformat_minor": 0
285 }
285 }
@@ -1,148 +1,148 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Setup script for IPython.
2 """Setup script for IPython.
3
3
4 Under Posix environments it works like a typical setup.py script.
4 Under Posix environments it works like a typical setup.py script.
5 Under Windows, the command sdist is not supported, since IPython
5 Under Windows, the command sdist is not supported, since IPython
6 requires utilities which are not available under Windows."""
6 requires utilities which are not available under Windows."""
7
7
8 #-----------------------------------------------------------------------------
8 #-----------------------------------------------------------------------------
9 # Copyright (c) 2008-2011, IPython Development Team.
9 # Copyright (c) 2008-2011, IPython Development Team.
10 # Copyright (c) 2001-2007, Fernando Perez <fernando.perez@colorado.edu>
10 # Copyright (c) 2001-2007, Fernando Perez <fernando.perez@colorado.edu>
11 # Copyright (c) 2001, Janko Hauser <jhauser@zscout.de>
11 # Copyright (c) 2001, Janko Hauser <jhauser@zscout.de>
12 # Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu>
12 # Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu>
13 #
13 #
14 # Distributed under the terms of the Modified BSD License.
14 # Distributed under the terms of the Modified BSD License.
15 #
15 #
16 # The full license is in the file COPYING.rst, distributed with this software.
16 # The full license is in the file COPYING.rst, distributed with this software.
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 import os
19 import os
20 import sys
20 import sys
21
21
22 # **Python version check**
22 # **Python version check**
23 #
23 #
24 # This check is also made in IPython/__init__, don't forget to update both when
24 # This check is also made in IPython/__init__, don't forget to update both when
25 # changing Python version requirements.
25 # changing Python version requirements.
26 if sys.version_info < (3, 8):
26 if sys.version_info < (3, 8):
27 pip_message = 'This may be due to an out of date pip. Make sure you have pip >= 9.0.1.'
27 pip_message = 'This may be due to an out of date pip. Make sure you have pip >= 9.0.1.'
28 try:
28 try:
29 import pip
29 import pip
30 pip_version = tuple([int(x) for x in pip.__version__.split('.')[:3]])
30 pip_version = tuple([int(x) for x in pip.__version__.split('.')[:3]])
31 if pip_version < (9, 0, 1) :
31 if pip_version < (9, 0, 1) :
32 pip_message = 'Your pip version is out of date, please install pip >= 9.0.1. '\
32 pip_message = 'Your pip version is out of date, please install pip >= 9.0.1. '\
33 'pip {} detected.'.format(pip.__version__)
33 'pip {} detected.'.format(pip.__version__)
34 else:
34 else:
35 # pip is new enough - it must be something else
35 # pip is new enough - it must be something else
36 pip_message = ''
36 pip_message = ''
37 except Exception:
37 except Exception:
38 pass
38 pass
39
39
40
40
41 error = """
41 error = """
42 IPython 8+ supports Python 3.8 and above, following NEP 29.
42 IPython 8+ supports Python 3.8 and above, following NEP 29.
43 When using Python 2.7, please install IPython 5.x LTS Long Term Support version.
43 When using Python 2.7, please install IPython 5.x LTS Long Term Support version.
44 Python 3.3 and 3.4 were supported up to IPython 6.x.
44 Python 3.3 and 3.4 were supported up to IPython 6.x.
45 Python 3.5 was supported with IPython 7.0 to 7.9.
45 Python 3.5 was supported with IPython 7.0 to 7.9.
46 Python 3.6 was supported with IPython up to 7.16.
46 Python 3.6 was supported with IPython up to 7.16.
47 Python 3.7 was still supported with the 7.x branch.
47 Python 3.7 was still supported with the 7.x branch.
48
48
49 See IPython `README.rst` file for more information:
49 See IPython `README.rst` file for more information:
50
50
51 https://github.com/ipython/ipython/blob/master/README.rst
51 https://github.com/ipython/ipython/blob/main/README.rst
52
52
53 Python {py} detected.
53 Python {py} detected.
54 {pip}
54 {pip}
55 """.format(
55 """.format(
56 py=sys.version_info, pip=pip_message
56 py=sys.version_info, pip=pip_message
57 )
57 )
58
58
59 print(error, file=sys.stderr)
59 print(error, file=sys.stderr)
60 sys.exit(1)
60 sys.exit(1)
61
61
62 # At least we're on the python version we need, move on.
62 # At least we're on the python version we need, move on.
63
63
64 from setuptools import setup
64 from setuptools import setup
65
65
66 # Our own imports
66 # Our own imports
67 sys.path.insert(0, ".")
67 sys.path.insert(0, ".")
68
68
69 from setupbase import target_update
69 from setupbase import target_update
70
70
71 from setupbase import (
71 from setupbase import (
72 setup_args,
72 setup_args,
73 check_package_data_first,
73 check_package_data_first,
74 find_data_files,
74 find_data_files,
75 git_prebuild,
75 git_prebuild,
76 install_symlinked,
76 install_symlinked,
77 install_lib_symlink,
77 install_lib_symlink,
78 install_scripts_for_symlink,
78 install_scripts_for_symlink,
79 unsymlink,
79 unsymlink,
80 )
80 )
81
81
82 #-------------------------------------------------------------------------------
82 #-------------------------------------------------------------------------------
83 # Handle OS specific things
83 # Handle OS specific things
84 #-------------------------------------------------------------------------------
84 #-------------------------------------------------------------------------------
85
85
86 if os.name in ('nt','dos'):
86 if os.name in ('nt','dos'):
87 os_name = 'windows'
87 os_name = 'windows'
88 else:
88 else:
89 os_name = os.name
89 os_name = os.name
90
90
91 # Under Windows, 'sdist' has not been supported. Now that the docs build with
91 # Under Windows, 'sdist' has not been supported. Now that the docs build with
92 # Sphinx it might work, but let's not turn it on until someone confirms that it
92 # Sphinx it might work, but let's not turn it on until someone confirms that it
93 # actually works.
93 # actually works.
94 if os_name == 'windows' and 'sdist' in sys.argv:
94 if os_name == 'windows' and 'sdist' in sys.argv:
95 print('The sdist command is not available under Windows. Exiting.')
95 print('The sdist command is not available under Windows. Exiting.')
96 sys.exit(1)
96 sys.exit(1)
97
97
98
98
99 #-------------------------------------------------------------------------------
99 #-------------------------------------------------------------------------------
100 # Things related to the IPython documentation
100 # Things related to the IPython documentation
101 #-------------------------------------------------------------------------------
101 #-------------------------------------------------------------------------------
102
102
103 # update the manuals when building a source dist
103 # update the manuals when building a source dist
104 if len(sys.argv) >= 2 and sys.argv[1] in ('sdist','bdist_rpm'):
104 if len(sys.argv) >= 2 and sys.argv[1] in ('sdist','bdist_rpm'):
105
105
106 # List of things to be updated. Each entry is a triplet of args for
106 # List of things to be updated. Each entry is a triplet of args for
107 # target_update()
107 # target_update()
108 to_update = [
108 to_update = [
109 (
109 (
110 "docs/man/ipython.1.gz",
110 "docs/man/ipython.1.gz",
111 ["docs/man/ipython.1"],
111 ["docs/man/ipython.1"],
112 "cd docs/man && python -m gzip --best ipython.1",
112 "cd docs/man && python -m gzip --best ipython.1",
113 ),
113 ),
114 ]
114 ]
115
115
116
116
117 [ target_update(*t) for t in to_update ]
117 [ target_update(*t) for t in to_update ]
118
118
119 #---------------------------------------------------------------------------
119 #---------------------------------------------------------------------------
120 # Find all the packages, package data, and data_files
120 # Find all the packages, package data, and data_files
121 #---------------------------------------------------------------------------
121 #---------------------------------------------------------------------------
122
122
123 data_files = find_data_files()
123 data_files = find_data_files()
124
124
125 setup_args['data_files'] = data_files
125 setup_args['data_files'] = data_files
126
126
127 #---------------------------------------------------------------------------
127 #---------------------------------------------------------------------------
128 # custom distutils commands
128 # custom distutils commands
129 #---------------------------------------------------------------------------
129 #---------------------------------------------------------------------------
130 # imports here, so they are after setuptools import if there was one
130 # imports here, so they are after setuptools import if there was one
131 from setuptools.command.sdist import sdist
131 from setuptools.command.sdist import sdist
132
132
133 setup_args['cmdclass'] = {
133 setup_args['cmdclass'] = {
134 'build_py': \
134 'build_py': \
135 check_package_data_first(git_prebuild('IPython')),
135 check_package_data_first(git_prebuild('IPython')),
136 'sdist' : git_prebuild('IPython', sdist),
136 'sdist' : git_prebuild('IPython', sdist),
137 'symlink': install_symlinked,
137 'symlink': install_symlinked,
138 'install_lib_symlink': install_lib_symlink,
138 'install_lib_symlink': install_lib_symlink,
139 'install_scripts_sym': install_scripts_for_symlink,
139 'install_scripts_sym': install_scripts_for_symlink,
140 'unsymlink': unsymlink,
140 'unsymlink': unsymlink,
141 }
141 }
142
142
143 #---------------------------------------------------------------------------
143 #---------------------------------------------------------------------------
144 # Do the actual setup now
144 # Do the actual setup now
145 #---------------------------------------------------------------------------
145 #---------------------------------------------------------------------------
146
146
147 if __name__ == "__main__":
147 if __name__ == "__main__":
148 setup(**setup_args)
148 setup(**setup_args)
@@ -1,230 +1,230 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 """Simple tools to query github.com and gather stats about issues.
2 """Simple tools to query github.com and gather stats about issues.
3
3
4 To generate a report for IPython 2.0, run:
4 To generate a report for IPython 2.0, run:
5
5
6 python github_stats.py --milestone 2.0 --since-tag rel-1.0.0
6 python github_stats.py --milestone 2.0 --since-tag rel-1.0.0
7 """
7 """
8 #-----------------------------------------------------------------------------
8 #-----------------------------------------------------------------------------
9 # Imports
9 # Imports
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11
11
12
12
13 import sys
13 import sys
14
14
15 from argparse import ArgumentParser
15 from argparse import ArgumentParser
16 from datetime import datetime, timedelta
16 from datetime import datetime, timedelta
17 from subprocess import check_output
17 from subprocess import check_output
18
18
19 from gh_api import (
19 from gh_api import (
20 get_paged_request, make_auth_header, get_pull_request, is_pull_request,
20 get_paged_request, make_auth_header, get_pull_request, is_pull_request,
21 get_milestone_id, get_issues_list, get_authors,
21 get_milestone_id, get_issues_list, get_authors,
22 )
22 )
23 #-----------------------------------------------------------------------------
23 #-----------------------------------------------------------------------------
24 # Globals
24 # Globals
25 #-----------------------------------------------------------------------------
25 #-----------------------------------------------------------------------------
26
26
27 ISO8601 = "%Y-%m-%dT%H:%M:%SZ"
27 ISO8601 = "%Y-%m-%dT%H:%M:%SZ"
28 PER_PAGE = 100
28 PER_PAGE = 100
29
29
30 #-----------------------------------------------------------------------------
30 #-----------------------------------------------------------------------------
31 # Functions
31 # Functions
32 #-----------------------------------------------------------------------------
32 #-----------------------------------------------------------------------------
33
33
34 def round_hour(dt):
34 def round_hour(dt):
35 return dt.replace(minute=0,second=0,microsecond=0)
35 return dt.replace(minute=0,second=0,microsecond=0)
36
36
37 def _parse_datetime(s):
37 def _parse_datetime(s):
38 """Parse dates in the format returned by the Github API."""
38 """Parse dates in the format returned by the Github API."""
39 if s:
39 if s:
40 return datetime.strptime(s, ISO8601)
40 return datetime.strptime(s, ISO8601)
41 else:
41 else:
42 return datetime.fromtimestamp(0)
42 return datetime.fromtimestamp(0)
43
43
44 def issues2dict(issues):
44 def issues2dict(issues):
45 """Convert a list of issues to a dict, keyed by issue number."""
45 """Convert a list of issues to a dict, keyed by issue number."""
46 idict = {}
46 idict = {}
47 for i in issues:
47 for i in issues:
48 idict[i['number']] = i
48 idict[i['number']] = i
49 return idict
49 return idict
50
50
51 def split_pulls(all_issues, project="ipython/ipython"):
51 def split_pulls(all_issues, project="ipython/ipython"):
52 """split a list of closed issues into non-PR Issues and Pull Requests"""
52 """split a list of closed issues into non-PR Issues and Pull Requests"""
53 pulls = []
53 pulls = []
54 issues = []
54 issues = []
55 for i in all_issues:
55 for i in all_issues:
56 if is_pull_request(i):
56 if is_pull_request(i):
57 pull = get_pull_request(project, i['number'], auth=True)
57 pull = get_pull_request(project, i['number'], auth=True)
58 pulls.append(pull)
58 pulls.append(pull)
59 else:
59 else:
60 issues.append(i)
60 issues.append(i)
61 return issues, pulls
61 return issues, pulls
62
62
63
63
64 def issues_closed_since(period=timedelta(days=365), project="ipython/ipython", pulls=False):
64 def issues_closed_since(period=timedelta(days=365), project="ipython/ipython", pulls=False):
65 """Get all issues closed since a particular point in time. period
65 """Get all issues closed since a particular point in time. period
66 can either be a datetime object, or a timedelta object. In the
66 can either be a datetime object, or a timedelta object. In the
67 latter case, it is used as a time before the present.
67 latter case, it is used as a time before the present.
68 """
68 """
69
69
70 which = 'pulls' if pulls else 'issues'
70 which = 'pulls' if pulls else 'issues'
71
71
72 if isinstance(period, timedelta):
72 if isinstance(period, timedelta):
73 since = round_hour(datetime.utcnow() - period)
73 since = round_hour(datetime.utcnow() - period)
74 else:
74 else:
75 since = period
75 since = period
76 url = "https://api.github.com/repos/%s/%s?state=closed&sort=updated&since=%s&per_page=%i" % (project, which, since.strftime(ISO8601), PER_PAGE)
76 url = "https://api.github.com/repos/%s/%s?state=closed&sort=updated&since=%s&per_page=%i" % (project, which, since.strftime(ISO8601), PER_PAGE)
77 allclosed = get_paged_request(url, headers=make_auth_header())
77 allclosed = get_paged_request(url, headers=make_auth_header())
78
78
79 filtered = [ i for i in allclosed if _parse_datetime(i['closed_at']) > since ]
79 filtered = [ i for i in allclosed if _parse_datetime(i['closed_at']) > since ]
80 if pulls:
80 if pulls:
81 filtered = [ i for i in filtered if _parse_datetime(i['merged_at']) > since ]
81 filtered = [ i for i in filtered if _parse_datetime(i['merged_at']) > since ]
82 # filter out PRs not against master (backports)
82 # filter out PRs not against main (backports)
83 filtered = [ i for i in filtered if i['base']['ref'] == 'master' ]
83 filtered = [ i for i in filtered if i['base']['ref'] == 'main' ]
84 else:
84 else:
85 filtered = [ i for i in filtered if not is_pull_request(i) ]
85 filtered = [ i for i in filtered if not is_pull_request(i) ]
86
86
87 return filtered
87 return filtered
88
88
89
89
90 def sorted_by_field(issues, field='closed_at', reverse=False):
90 def sorted_by_field(issues, field='closed_at', reverse=False):
91 """Return a list of issues sorted by closing date date."""
91 """Return a list of issues sorted by closing date date."""
92 return sorted(issues, key = lambda i:i[field], reverse=reverse)
92 return sorted(issues, key = lambda i:i[field], reverse=reverse)
93
93
94
94
95 def report(issues, show_urls=False):
95 def report(issues, show_urls=False):
96 """Summary report about a list of issues, printing number and title."""
96 """Summary report about a list of issues, printing number and title."""
97 if show_urls:
97 if show_urls:
98 for i in issues:
98 for i in issues:
99 role = 'ghpull' if 'merged_at' in i else 'ghissue'
99 role = 'ghpull' if 'merged_at' in i else 'ghissue'
100 print(u'* :%s:`%d`: %s' % (role, i['number'],
100 print(u'* :%s:`%d`: %s' % (role, i['number'],
101 i['title'].replace(u'`', u'``')))
101 i['title'].replace(u'`', u'``')))
102 else:
102 else:
103 for i in issues:
103 for i in issues:
104 print(u'* %d: %s' % (i['number'], i['title'].replace(u'`', u'``')))
104 print(u'* %d: %s' % (i['number'], i['title'].replace(u'`', u'``')))
105
105
106 #-----------------------------------------------------------------------------
106 #-----------------------------------------------------------------------------
107 # Main script
107 # Main script
108 #-----------------------------------------------------------------------------
108 #-----------------------------------------------------------------------------
109
109
110 if __name__ == "__main__":
110 if __name__ == "__main__":
111
111
112 print("DEPRECATE: backport_pr.py is deprecated and it is now recommended"
112 print("DEPRECATE: backport_pr.py is deprecated and it is now recommended"
113 "to install `ghpro` from PyPI.", file=sys.stderr)
113 "to install `ghpro` from PyPI.", file=sys.stderr)
114
114
115
115
116 # Whether to add reST urls for all issues in printout.
116 # Whether to add reST urls for all issues in printout.
117 show_urls = True
117 show_urls = True
118
118
119 parser = ArgumentParser()
119 parser = ArgumentParser()
120 parser.add_argument('--since-tag', type=str,
120 parser.add_argument('--since-tag', type=str,
121 help="The git tag to use for the starting point (typically the last major release)."
121 help="The git tag to use for the starting point (typically the last major release)."
122 )
122 )
123 parser.add_argument('--milestone', type=str,
123 parser.add_argument('--milestone', type=str,
124 help="The GitHub milestone to use for filtering issues [optional]."
124 help="The GitHub milestone to use for filtering issues [optional]."
125 )
125 )
126 parser.add_argument('--days', type=int,
126 parser.add_argument('--days', type=int,
127 help="The number of days of data to summarize (use this or --since-tag)."
127 help="The number of days of data to summarize (use this or --since-tag)."
128 )
128 )
129 parser.add_argument('--project', type=str, default="ipython/ipython",
129 parser.add_argument('--project', type=str, default="ipython/ipython",
130 help="The project to summarize."
130 help="The project to summarize."
131 )
131 )
132 parser.add_argument('--links', action='store_true', default=False,
132 parser.add_argument('--links', action='store_true', default=False,
133 help="Include links to all closed Issues and PRs in the output."
133 help="Include links to all closed Issues and PRs in the output."
134 )
134 )
135
135
136 opts = parser.parse_args()
136 opts = parser.parse_args()
137 tag = opts.since_tag
137 tag = opts.since_tag
138
138
139 # set `since` from days or git tag
139 # set `since` from days or git tag
140 if opts.days:
140 if opts.days:
141 since = datetime.utcnow() - timedelta(days=opts.days)
141 since = datetime.utcnow() - timedelta(days=opts.days)
142 else:
142 else:
143 if not tag:
143 if not tag:
144 tag = check_output(['git', 'describe', '--abbrev=0']).strip().decode('utf8')
144 tag = check_output(['git', 'describe', '--abbrev=0']).strip().decode('utf8')
145 cmd = ['git', 'log', '-1', '--format=%ai', tag]
145 cmd = ['git', 'log', '-1', '--format=%ai', tag]
146 tagday, tz = check_output(cmd).strip().decode('utf8').rsplit(' ', 1)
146 tagday, tz = check_output(cmd).strip().decode('utf8').rsplit(' ', 1)
147 since = datetime.strptime(tagday, "%Y-%m-%d %H:%M:%S")
147 since = datetime.strptime(tagday, "%Y-%m-%d %H:%M:%S")
148 h = int(tz[1:3])
148 h = int(tz[1:3])
149 m = int(tz[3:])
149 m = int(tz[3:])
150 td = timedelta(hours=h, minutes=m)
150 td = timedelta(hours=h, minutes=m)
151 if tz[0] == '-':
151 if tz[0] == '-':
152 since += td
152 since += td
153 else:
153 else:
154 since -= td
154 since -= td
155
155
156 since = round_hour(since)
156 since = round_hour(since)
157
157
158 milestone = opts.milestone
158 milestone = opts.milestone
159 project = opts.project
159 project = opts.project
160
160
161 print("fetching GitHub stats since %s (tag: %s, milestone: %s)" % (since, tag, milestone), file=sys.stderr)
161 print("fetching GitHub stats since %s (tag: %s, milestone: %s)" % (since, tag, milestone), file=sys.stderr)
162 if milestone:
162 if milestone:
163 milestone_id = get_milestone_id(project=project, milestone=milestone,
163 milestone_id = get_milestone_id(project=project, milestone=milestone,
164 auth=True)
164 auth=True)
165 issues_and_pulls = get_issues_list(project=project,
165 issues_and_pulls = get_issues_list(project=project,
166 milestone=milestone_id,
166 milestone=milestone_id,
167 state='closed',
167 state='closed',
168 auth=True,
168 auth=True,
169 )
169 )
170 issues, pulls = split_pulls(issues_and_pulls, project=project)
170 issues, pulls = split_pulls(issues_and_pulls, project=project)
171 else:
171 else:
172 issues = issues_closed_since(since, project=project, pulls=False)
172 issues = issues_closed_since(since, project=project, pulls=False)
173 pulls = issues_closed_since(since, project=project, pulls=True)
173 pulls = issues_closed_since(since, project=project, pulls=True)
174
174
175 # For regular reports, it's nice to show them in reverse chronological order
175 # For regular reports, it's nice to show them in reverse chronological order
176 issues = sorted_by_field(issues, reverse=True)
176 issues = sorted_by_field(issues, reverse=True)
177 pulls = sorted_by_field(pulls, reverse=True)
177 pulls = sorted_by_field(pulls, reverse=True)
178
178
179 n_issues, n_pulls = map(len, (issues, pulls))
179 n_issues, n_pulls = map(len, (issues, pulls))
180 n_total = n_issues + n_pulls
180 n_total = n_issues + n_pulls
181
181
182 # Print summary report we can directly include into release notes.
182 # Print summary report we can directly include into release notes.
183
183
184 print()
184 print()
185 since_day = since.strftime("%Y/%m/%d")
185 since_day = since.strftime("%Y/%m/%d")
186 today = datetime.today().strftime("%Y/%m/%d")
186 today = datetime.today().strftime("%Y/%m/%d")
187 print("GitHub stats for %s - %s (tag: %s)" % (since_day, today, tag))
187 print("GitHub stats for %s - %s (tag: %s)" % (since_day, today, tag))
188 print()
188 print()
189 print("These lists are automatically generated, and may be incomplete or contain duplicates.")
189 print("These lists are automatically generated, and may be incomplete or contain duplicates.")
190 print()
190 print()
191
191
192 ncommits = 0
192 ncommits = 0
193 all_authors = []
193 all_authors = []
194 if tag:
194 if tag:
195 # print git info, in addition to GitHub info:
195 # print git info, in addition to GitHub info:
196 since_tag = tag+'..'
196 since_tag = tag+'..'
197 cmd = ['git', 'log', '--oneline', since_tag]
197 cmd = ['git', 'log', '--oneline', since_tag]
198 ncommits += len(check_output(cmd).splitlines())
198 ncommits += len(check_output(cmd).splitlines())
199
199
200 author_cmd = ['git', 'log', '--use-mailmap', "--format=* %aN", since_tag]
200 author_cmd = ['git', 'log', '--use-mailmap', "--format=* %aN", since_tag]
201 all_authors.extend(check_output(author_cmd).decode('utf-8', 'replace').splitlines())
201 all_authors.extend(check_output(author_cmd).decode('utf-8', 'replace').splitlines())
202
202
203 pr_authors = []
203 pr_authors = []
204 for pr in pulls:
204 for pr in pulls:
205 pr_authors.extend(get_authors(pr))
205 pr_authors.extend(get_authors(pr))
206 ncommits = len(pr_authors) + ncommits - len(pulls)
206 ncommits = len(pr_authors) + ncommits - len(pulls)
207 author_cmd = ['git', 'check-mailmap'] + pr_authors
207 author_cmd = ['git', 'check-mailmap'] + pr_authors
208 with_email = check_output(author_cmd).decode('utf-8', 'replace').splitlines()
208 with_email = check_output(author_cmd).decode('utf-8', 'replace').splitlines()
209 all_authors.extend([ u'* ' + a.split(' <')[0] for a in with_email ])
209 all_authors.extend([ u'* ' + a.split(' <')[0] for a in with_email ])
210 unique_authors = sorted(set(all_authors), key=lambda s: s.lower())
210 unique_authors = sorted(set(all_authors), key=lambda s: s.lower())
211
211
212 print("We closed %d issues and merged %d pull requests." % (n_issues, n_pulls))
212 print("We closed %d issues and merged %d pull requests." % (n_issues, n_pulls))
213 if milestone:
213 if milestone:
214 print("The full list can be seen `on GitHub <https://github.com/{project}/issues?q=milestone%3A{milestone}>`__".format(project=project,milestone=milestone)
214 print("The full list can be seen `on GitHub <https://github.com/{project}/issues?q=milestone%3A{milestone}>`__".format(project=project,milestone=milestone)
215 )
215 )
216
216
217 print()
217 print()
218 print("The following %i authors contributed %i commits." % (len(unique_authors), ncommits))
218 print("The following %i authors contributed %i commits." % (len(unique_authors), ncommits))
219 print()
219 print()
220 print('\n'.join(unique_authors))
220 print('\n'.join(unique_authors))
221
221
222 if opts.links:
222 if opts.links:
223 print()
223 print()
224 print("GitHub issues and pull requests:")
224 print("GitHub issues and pull requests:")
225 print()
225 print()
226 print('Pull Requests (%d):\n' % n_pulls)
226 print('Pull Requests (%d):\n' % n_pulls)
227 report(pulls, show_urls)
227 report(pulls, show_urls)
228 print()
228 print()
229 print('Issues (%d):\n' % n_issues)
229 print('Issues (%d):\n' % n_issues)
230 report(issues, show_urls)
230 report(issues, show_urls)
@@ -1,251 +1,251 b''
1 # Simple tool to help for release
1 # Simple tool to help for release
2 # when releasing with bash, simple source it to get asked questions.
2 # when releasing with bash, simple source it to get asked questions.
3
3
4 # misc check before starting
4 # misc check before starting
5
5
6 python -c 'import keyring'
6 python -c 'import keyring'
7 python -c 'import twine'
7 python -c 'import twine'
8 python -c 'import sphinx'
8 python -c 'import sphinx'
9 python -c 'import sphinx_rtd_theme'
9 python -c 'import sphinx_rtd_theme'
10 python -c 'import pytest'
10 python -c 'import pytest'
11
11
12
12
13 BLACK=$(tput setaf 1)
13 BLACK=$(tput setaf 1)
14 RED=$(tput setaf 1)
14 RED=$(tput setaf 1)
15 GREEN=$(tput setaf 2)
15 GREEN=$(tput setaf 2)
16 YELLOW=$(tput setaf 3)
16 YELLOW=$(tput setaf 3)
17 BLUE=$(tput setaf 4)
17 BLUE=$(tput setaf 4)
18 MAGENTA=$(tput setaf 5)
18 MAGENTA=$(tput setaf 5)
19 CYAN=$(tput setaf 6)
19 CYAN=$(tput setaf 6)
20 WHITE=$(tput setaf 7)
20 WHITE=$(tput setaf 7)
21 NOR=$(tput sgr0)
21 NOR=$(tput sgr0)
22
22
23
23
24 echo "Will use $BLUE'$EDITOR'$NOR to edit files when necessary"
24 echo "Will use $BLUE'$EDITOR'$NOR to edit files when necessary"
25 echo -n "PREV_RELEASE (X.y.z) [$PREV_RELEASE]: "
25 echo -n "PREV_RELEASE (X.y.z) [$PREV_RELEASE]: "
26 read input
26 read input
27 PREV_RELEASE=${input:-$PREV_RELEASE}
27 PREV_RELEASE=${input:-$PREV_RELEASE}
28 echo -n "MILESTONE (X.y) [$MILESTONE]: "
28 echo -n "MILESTONE (X.y) [$MILESTONE]: "
29 read input
29 read input
30 MILESTONE=${input:-$MILESTONE}
30 MILESTONE=${input:-$MILESTONE}
31 echo -n "VERSION (X.y.z) [$VERSION]:"
31 echo -n "VERSION (X.y.z) [$VERSION]:"
32 read input
32 read input
33 VERSION=${input:-$VERSION}
33 VERSION=${input:-$VERSION}
34 echo -n "BRANCH (master|X.y) [$BRANCH]:"
34 echo -n "BRANCH (main|X.y) [$BRANCH]:"
35 read input
35 read input
36 BRANCH=${input:-$BRANCH}
36 BRANCH=${input:-$BRANCH}
37
37
38 ask_section(){
38 ask_section(){
39 echo
39 echo
40 echo $BLUE"$1"$NOR
40 echo $BLUE"$1"$NOR
41 echo -n $GREEN"Press Enter to continue, S to skip: "$NOR
41 echo -n $GREEN"Press Enter to continue, S to skip: "$NOR
42 if [ "$ZSH_NAME" = "zsh" ] ; then
42 if [ "$ZSH_NAME" = "zsh" ] ; then
43 read -k1 value
43 read -k1 value
44 value=${value%$'\n'}
44 value=${value%$'\n'}
45 else
45 else
46 read -n1 value
46 read -n1 value
47 fi
47 fi
48 if [ -z "$value" ] || [ $value = 'y' ]; then
48 if [ -z "$value" ] || [ $value = 'y' ]; then
49 return 0
49 return 0
50 fi
50 fi
51 return 1
51 return 1
52 }
52 }
53
53
54
54
55 maybe_edit(){
55 maybe_edit(){
56 echo
56 echo
57 echo $BLUE"$1"$NOR
57 echo $BLUE"$1"$NOR
58 echo -n $GREEN"Press ${BLUE}e$GREEN to Edit ${BLUE}$1$GREEN, any other keys to skip: "$NOR
58 echo -n $GREEN"Press ${BLUE}e$GREEN to Edit ${BLUE}$1$GREEN, any other keys to skip: "$NOR
59 if [ "$ZSH_NAME" = "zsh" ] ; then
59 if [ "$ZSH_NAME" = "zsh" ] ; then
60 read -k1 value
60 read -k1 value
61 value=${value%$'\n'}
61 value=${value%$'\n'}
62 else
62 else
63 read -n1 value
63 read -n1 value
64 fi
64 fi
65
65
66 echo
66 echo
67 if [ $value = 'e' ] ; then
67 if [ $value = 'e' ] ; then
68 $=EDITOR $1
68 $=EDITOR $1
69 fi
69 fi
70 }
70 }
71
71
72
72
73
73
74 echo
74 echo
75 if ask_section "Updating what's new with information from docs/source/whatsnew/pr"
75 if ask_section "Updating what's new with information from docs/source/whatsnew/pr"
76 then
76 then
77 python tools/update_whatsnew.py
77 python tools/update_whatsnew.py
78
78
79 echo
79 echo
80 echo $BLUE"please move the contents of "docs/source/whatsnew/development.rst" to version-X.rst"$NOR
80 echo $BLUE"please move the contents of "docs/source/whatsnew/development.rst" to version-X.rst"$NOR
81 echo $GREEN"Press enter to continue"$NOR
81 echo $GREEN"Press enter to continue"$NOR
82 read
82 read
83 fi
83 fi
84
84
85 if ask_section "Gen Stats, and authors"
85 if ask_section "Gen Stats, and authors"
86 then
86 then
87
87
88 echo
88 echo
89 echo $BLUE"here are all the authors that contributed to this release:"$NOR
89 echo $BLUE"here are all the authors that contributed to this release:"$NOR
90 git log --format="%aN <%aE>" $PREV_RELEASE... | sort -u -f
90 git log --format="%aN <%aE>" $PREV_RELEASE... | sort -u -f
91
91
92 echo
92 echo
93 echo $BLUE"If you see any duplicates cancel (Ctrl-C), then edit .mailmap."
93 echo $BLUE"If you see any duplicates cancel (Ctrl-C), then edit .mailmap."
94 echo $GREEN"Press enter to continue:"$NOR
94 echo $GREEN"Press enter to continue:"$NOR
95 read
95 read
96
96
97 echo $BLUE"generating stats"$NOR
97 echo $BLUE"generating stats"$NOR
98 python tools/github_stats.py --milestone $MILESTONE > stats.rst
98 python tools/github_stats.py --milestone $MILESTONE > stats.rst
99
99
100 echo $BLUE"stats.rst files generated."$NOR
100 echo $BLUE"stats.rst files generated."$NOR
101 echo $GREEN"Please merge it with the right file (github-stats-X.rst) and commit."$NOR
101 echo $GREEN"Please merge it with the right file (github-stats-X.rst) and commit."$NOR
102 echo $GREEN"press enter to continue."$NOR
102 echo $GREEN"press enter to continue."$NOR
103 read
103 read
104
104
105 fi
105 fi
106
106
107 if ask_section "Generate API difference (using frapuccino)"
107 if ask_section "Generate API difference (using frapuccino)"
108 then
108 then
109 echo $BLUE"Checking out $PREV_RELEASE"$NOR
109 echo $BLUE"Checking out $PREV_RELEASE"$NOR
110 git checkout $PREV_RELEASE
110 git checkout $PREV_RELEASE
111 sleep 1
111 sleep 1
112 echo $BLUE"Saving API to file $PREV_RELEASE"$NOR
112 echo $BLUE"Saving API to file $PREV_RELEASE"$NOR
113 frappuccino IPython IPython.kernel IPython.lib IPython.qt IPython.lib.kernel IPython.html IPython.frontend IPython.external --save IPython-$PREV_RELEASE.json
113 frappuccino IPython IPython.kernel IPython.lib IPython.qt IPython.lib.kernel IPython.html IPython.frontend IPython.external --save IPython-$PREV_RELEASE.json
114 echo $BLUE"coming back to $BRANCH"$NOR
114 echo $BLUE"coming back to $BRANCH"$NOR
115 git checkout $BRANCH
115 git checkout $BRANCH
116 sleep 1
116 sleep 1
117 echo $BLUE"comparing ..."$NOR
117 echo $BLUE"comparing ..."$NOR
118 frappuccino IPython IPython.kernel IPython.lib --compare IPython-$PREV_RELEASE.json
118 frappuccino IPython IPython.kernel IPython.lib --compare IPython-$PREV_RELEASE.json
119 echo $GREEN"Use the above guideline to write an API changelog ..."$NOR
119 echo $GREEN"Use the above guideline to write an API changelog ..."$NOR
120 echo $GREEN"Press any keys to continue"$NOR
120 echo $GREEN"Press any keys to continue"$NOR
121 read
121 read
122 fi
122 fi
123
123
124 echo "Cleaning repository"
124 echo "Cleaning repository"
125 git clean -xfdi
125 git clean -xfdi
126
126
127 echo $GREEN"please update version number in ${RED}IPython/core/release.py${NOR} , Do not commit yet – we'll do it later."$NOR
127 echo $GREEN"please update version number in ${RED}IPython/core/release.py${NOR} , Do not commit yet – we'll do it later."$NOR
128 echo $GREEN"I tried ${RED}sed -i bkp -e '/Uncomment/s/^# //g' IPython/core/release.py${NOR}"
128 echo $GREEN"I tried ${RED}sed -i bkp -e '/Uncomment/s/^# //g' IPython/core/release.py${NOR}"
129 sed -i bkp -e '/Uncomment/s/^# //g' IPython/core/release.py
129 sed -i bkp -e '/Uncomment/s/^# //g' IPython/core/release.py
130 rm IPython/core/release.pybkp
130 rm IPython/core/release.pybkp
131 git diff | cat
131 git diff | cat
132 maybe_edit IPython/core/release.py
132 maybe_edit IPython/core/release.py
133
133
134 echo $GREEN"Press enter to continue"$NOR
134 echo $GREEN"Press enter to continue"$NOR
135 read
135 read
136
136
137 if ask_section "Build the documentation ?"
137 if ask_section "Build the documentation ?"
138 then
138 then
139 make html -C docs
139 make html -C docs
140 echo
140 echo
141 echo $GREEN"Check the docs, press enter to continue"$NOR
141 echo $GREEN"Check the docs, press enter to continue"$NOR
142 read
142 read
143
143
144 fi
144 fi
145
145
146 if ask_section "Should we commit, tag, push... etc ? "
146 if ask_section "Should we commit, tag, push... etc ? "
147 then
147 then
148 echo
148 echo
149 echo $BLUE"Let's commit : git commit -am \"release $VERSION\" -S"
149 echo $BLUE"Let's commit : git commit -am \"release $VERSION\" -S"
150 echo $GREEN"Press enter to commit"$NOR
150 echo $GREEN"Press enter to commit"$NOR
151 read
151 read
152 git commit -am "release $VERSION" -S
152 git commit -am "release $VERSION" -S
153
153
154 echo
154 echo
155 echo $BLUE"git push origin \$BRANCH ($BRANCH)?"$NOR
155 echo $BLUE"git push origin \$BRANCH ($BRANCH)?"$NOR
156 echo $GREEN"Make sure you can push"$NOR
156 echo $GREEN"Make sure you can push"$NOR
157 echo $GREEN"Press enter to continue"$NOR
157 echo $GREEN"Press enter to continue"$NOR
158 read
158 read
159 git push origin $BRANCH
159 git push origin $BRANCH
160
160
161 echo
161 echo
162 echo "Let's tag : git tag -am \"release $VERSION\" \"$VERSION\" -s"
162 echo "Let's tag : git tag -am \"release $VERSION\" \"$VERSION\" -s"
163 echo $GREEN"Press enter to tag commit"$NOR
163 echo $GREEN"Press enter to tag commit"$NOR
164 read
164 read
165 git tag -am "release $VERSION" "$VERSION" -s
165 git tag -am "release $VERSION" "$VERSION" -s
166
166
167 echo
167 echo
168 echo $BLUE"And push the tag: git push origin \$VERSION ?"$NOR
168 echo $BLUE"And push the tag: git push origin \$VERSION ?"$NOR
169 echo $GREEN"Press enter to continue"$NOR
169 echo $GREEN"Press enter to continue"$NOR
170 read
170 read
171 git push origin $VERSION
171 git push origin $VERSION
172
172
173
173
174 echo $GREEN"please update version number and back to .dev in ${RED}IPython/core/release.py"
174 echo $GREEN"please update version number and back to .dev in ${RED}IPython/core/release.py"
175 echo $GREEN"I tried ${RED}sed -i bkp -e '/Uncomment/s/^/# /g' IPython/core/release.py${NOR}"
175 echo $GREEN"I tried ${RED}sed -i bkp -e '/Uncomment/s/^/# /g' IPython/core/release.py${NOR}"
176 sed -i bkp -e '/Uncomment/s/^/# /g' IPython/core/release.py
176 sed -i bkp -e '/Uncomment/s/^/# /g' IPython/core/release.py
177 rm IPython/core/release.pybkp
177 rm IPython/core/release.pybkp
178 git diff | cat
178 git diff | cat
179 echo $GREEN"Please bump ${RED}the minor version number${NOR}"
179 echo $GREEN"Please bump ${RED}the minor version number${NOR}"
180 maybe_edit IPython/core/release.py
180 maybe_edit IPython/core/release.py
181 echo ${BLUE}"Do not commit yet – we'll do it later."$NOR
181 echo ${BLUE}"Do not commit yet – we'll do it later."$NOR
182
182
183
183
184 echo $GREEN"Press enter to continue"$NOR
184 echo $GREEN"Press enter to continue"$NOR
185 read
185 read
186
186
187 echo
187 echo
188 echo "Let's commit : "$BLUE"git commit -am \"back to dev\""$NOR
188 echo "Let's commit : "$BLUE"git commit -am \"back to dev\""$NOR
189 echo $GREEN"Press enter to commit"$NOR
189 echo $GREEN"Press enter to commit"$NOR
190 read
190 read
191 git commit -am "back to dev"
191 git commit -am "back to dev"
192
192
193 echo
193 echo
194 echo $BLUE"git push origin \$BRANCH ($BRANCH)?"$NOR
194 echo $BLUE"git push origin \$BRANCH ($BRANCH)?"$NOR
195 echo $GREEN"Press enter to continue"$NOR
195 echo $GREEN"Press enter to continue"$NOR
196 read
196 read
197 git push origin $BRANCH
197 git push origin $BRANCH
198
198
199
199
200 echo
200 echo
201 echo $BLUE"let's : git checkout $VERSION"$NOR
201 echo $BLUE"let's : git checkout $VERSION"$NOR
202 echo $GREEN"Press enter to continue"$NOR
202 echo $GREEN"Press enter to continue"$NOR
203 read
203 read
204 git checkout $VERSION
204 git checkout $VERSION
205 fi
205 fi
206
206
207 if ask_section "Should we build and release ?"
207 if ask_section "Should we build and release ?"
208 then
208 then
209
209
210 echo $BLUE"going to set SOURCE_DATE_EPOCH"$NOR
210 echo $BLUE"going to set SOURCE_DATE_EPOCH"$NOR
211 echo $BLUE'export SOURCE_DATE_EPOCH=$(git show -s --format=%ct HEAD)'$NOR
211 echo $BLUE'export SOURCE_DATE_EPOCH=$(git show -s --format=%ct HEAD)'$NOR
212 echo $GREEN"Press enter to continue"$NOR
212 echo $GREEN"Press enter to continue"$NOR
213 read
213 read
214
214
215 export SOURCE_DATE_EPOCH=$(git show -s --format=%ct HEAD)
215 export SOURCE_DATE_EPOCH=$(git show -s --format=%ct HEAD)
216
216
217 echo $BLUE"SOURCE_DATE_EPOCH set to $SOURCE_DATE_EPOCH"$NOR
217 echo $BLUE"SOURCE_DATE_EPOCH set to $SOURCE_DATE_EPOCH"$NOR
218 echo $GREEN"Press enter to continue"$NOR
218 echo $GREEN"Press enter to continue"$NOR
219 read
219 read
220
220
221
221
222
222
223 echo
223 echo
224 echo $BLUE"Attempting to build package..."$NOR
224 echo $BLUE"Attempting to build package..."$NOR
225
225
226 tools/release
226 tools/release
227
227
228
228
229 echo $RED'$ shasum -a 256 dist/*'
229 echo $RED'$ shasum -a 256 dist/*'
230 shasum -a 256 dist/*
230 shasum -a 256 dist/*
231 echo $NOR
231 echo $NOR
232
232
233 echo $BLUE"We are going to rebuild, node the hash above, and compare them to the rebuild"$NOR
233 echo $BLUE"We are going to rebuild, node the hash above, and compare them to the rebuild"$NOR
234 echo $GREEN"Press enter to continue"$NOR
234 echo $GREEN"Press enter to continue"$NOR
235 read
235 read
236
236
237 echo
237 echo
238 echo $BLUE"Attempting to build package..."$NOR
238 echo $BLUE"Attempting to build package..."$NOR
239
239
240 tools/release
240 tools/release
241
241
242 echo $RED"Check the shasum for SOURCE_DATE_EPOCH=$SOURCE_DATE_EPOCH"
242 echo $RED"Check the shasum for SOURCE_DATE_EPOCH=$SOURCE_DATE_EPOCH"
243 echo $RED'$ shasum -a 256 dist/*'
243 echo $RED'$ shasum -a 256 dist/*'
244 shasum -a 256 dist/*
244 shasum -a 256 dist/*
245 echo $NOR
245 echo $NOR
246
246
247 if ask_section "upload packages ?"
247 if ask_section "upload packages ?"
248 then
248 then
249 tools/release upload
249 tools/release upload
250 fi
250 fi
251 fi
251 fi
General Comments 0
You need to be logged in to leave comments. Login now