Show More
@@ -15,7 +15,7 b' jobs:' | |||||
15 | runs-on: ubuntu-latest |
|
15 | runs-on: ubuntu-latest | |
16 | strategy: |
|
16 | strategy: | |
17 | matrix: |
|
17 | matrix: | |
18 |
python-version: [ |
|
18 | python-version: ["3.x"] | |
19 |
|
19 | |||
20 | steps: |
|
20 | steps: | |
21 | - uses: actions/checkout@v3 |
|
21 | - uses: actions/checkout@v3 |
@@ -19,7 +19,7 b' jobs:' | |||||
19 | fail-fast: false |
|
19 | fail-fast: false | |
20 | matrix: |
|
20 | matrix: | |
21 | os: [ubuntu-latest, windows-latest] |
|
21 | os: [ubuntu-latest, windows-latest] | |
22 | python-version: ["3.8", "3.9", "3.10"] |
|
22 | python-version: ["3.8", "3.9", "3.10", "3.11"] | |
23 | deps: [test_extra] |
|
23 | deps: [test_extra] | |
24 | # Test all on ubuntu, test ends on macos |
|
24 | # Test all on ubuntu, test ends on macos | |
25 | include: |
|
25 | include: | |
@@ -27,15 +27,15 b' jobs:' | |||||
27 | python-version: "3.8" |
|
27 | python-version: "3.8" | |
28 | deps: test_extra |
|
28 | deps: test_extra | |
29 | - os: macos-latest |
|
29 | - os: macos-latest | |
30 |
python-version: "3.1 |
|
30 | python-version: "3.11" | |
31 | deps: test_extra |
|
31 | deps: test_extra | |
32 | # Tests minimal dependencies set |
|
32 | # Tests minimal dependencies set | |
33 | - os: ubuntu-latest |
|
33 | - os: ubuntu-latest | |
34 |
python-version: "3.1 |
|
34 | python-version: "3.11" | |
35 | deps: test |
|
35 | deps: test | |
36 | # Tests latest development Python version |
|
36 | # Tests latest development Python version | |
37 | - os: ubuntu-latest |
|
37 | - os: ubuntu-latest | |
38 |
python-version: "3.1 |
|
38 | python-version: "3.12-dev" | |
39 | deps: test |
|
39 | deps: test | |
40 | # Installing optional dependencies stuff takes ages on PyPy |
|
40 | # Installing optional dependencies stuff takes ages on PyPy | |
41 | - os: ubuntu-latest |
|
41 | - os: ubuntu-latest |
@@ -59,7 +59,8 b' and press :kbd:`Tab` to expand it to its latex form.' | |||||
59 |
|
59 | |||
60 |
|
60 | |||
61 | Both forward and backward completions can be deactivated by setting the |
|
61 | Both forward and backward completions can be deactivated by setting the | |
62 |
: |
|
62 | :std:configtrait:`Completer.backslash_combining_completions` option to | |
|
63 | ``False``. | |||
63 |
|
64 | |||
64 |
|
65 | |||
65 | Experimental |
|
66 | Experimental | |
@@ -166,7 +167,7 b' this can be achieved by adding a list of identifiers of matchers which' | |||||
166 | should not be suppressed to ``MatcherResult`` under ``do_not_suppress`` key. |
|
167 | should not be suppressed to ``MatcherResult`` under ``do_not_suppress`` key. | |
167 |
|
168 | |||
168 | The suppression behaviour can is user-configurable via |
|
169 | The suppression behaviour can is user-configurable via | |
169 |
: |
|
170 | :std:configtrait:`IPCompleter.suppress_competing_matchers`. | |
170 | """ |
|
171 | """ | |
171 |
|
172 | |||
172 |
|
173 | |||
@@ -255,7 +256,7 b' except ImportError:' | |||||
255 | JEDI_INSTALLED = False |
|
256 | JEDI_INSTALLED = False | |
256 |
|
257 | |||
257 |
|
258 | |||
258 | if TYPE_CHECKING or GENERATING_DOCUMENTATION: |
|
259 | if TYPE_CHECKING or GENERATING_DOCUMENTATION and sys.version_info >= (3, 11): | |
259 | from typing import cast |
|
260 | from typing import cast | |
260 | from typing_extensions import TypedDict, NotRequired, Protocol, TypeAlias, TypeGuard |
|
261 | from typing_extensions import TypedDict, NotRequired, Protocol, TypeAlias, TypeGuard | |
261 | else: |
|
262 | else: | |
@@ -284,7 +285,7 b' if GENERATING_DOCUMENTATION:' | |||||
284 | # write this). With below range we cover them all, with a density of ~67% |
|
285 | # write this). With below range we cover them all, with a density of ~67% | |
285 | # biggest next gap we consider only adds up about 1% density and there are 600 |
|
286 | # biggest next gap we consider only adds up about 1% density and there are 600 | |
286 | # gaps that would need hard coding. |
|
287 | # gaps that would need hard coding. | |
287 |
_UNICODE_RANGES = [(32, 0x3 |
|
288 | _UNICODE_RANGES = [(32, 0x323B0), (0xE0001, 0xE01F0)] | |
288 |
|
289 | |||
289 | # Public API |
|
290 | # Public API | |
290 | __all__ = ["Completer", "IPCompleter"] |
|
291 | __all__ = ["Completer", "IPCompleter"] | |
@@ -972,7 +973,7 b' class Completer(Configurable):' | |||||
972 | help="""Activate greedy completion. |
|
973 | help="""Activate greedy completion. | |
973 |
|
974 | |||
974 | .. deprecated:: 8.8 |
|
975 | .. deprecated:: 8.8 | |
975 |
Use : |
|
976 | Use :std:configtrait:`Completer.evaluation` and :std:configtrait:`Completer.auto_close_dict_keys` instead. | |
976 |
|
977 | |||
977 | When enabled in IPython 8.8 or newer, changes configuration as follows: |
|
978 | When enabled in IPython 8.8 or newer, changes configuration as follows: | |
978 |
|
979 |
@@ -16,7 +16,7 b'' | |||||
16 | # release. 'dev' as a _version_extra string means this is a development |
|
16 | # release. 'dev' as a _version_extra string means this is a development | |
17 | # version |
|
17 | # version | |
18 | _version_major = 8 |
|
18 | _version_major = 8 | |
19 |
_version_minor = |
|
19 | _version_minor = 9 | |
20 | _version_patch = 0 |
|
20 | _version_patch = 0 | |
21 | _version_extra = ".dev" |
|
21 | _version_extra = ".dev" | |
22 | # _version_extra = "rc1" |
|
22 | # _version_extra = "rc1" |
@@ -99,7 +99,7 b' def test_unicode_range():' | |||||
99 | assert len_exp == len_test, message |
|
99 | assert len_exp == len_test, message | |
100 |
|
100 | |||
101 | # fail if new unicode symbols have been added. |
|
101 | # fail if new unicode symbols have been added. | |
102 |
assert len_exp <= 1 |
|
102 | assert len_exp <= 143041, message | |
103 |
|
103 | |||
104 |
|
104 | |||
105 | @contextmanager |
|
105 | @contextmanager |
@@ -369,7 +369,8 b' class TestAutoreload(Fixture):' | |||||
369 | self.shell.run_code("assert func2() == 'changed'") |
|
369 | self.shell.run_code("assert func2() == 'changed'") | |
370 | self.shell.run_code("t = Test(); assert t.new_func() == 'changed'") |
|
370 | self.shell.run_code("t = Test(); assert t.new_func() == 'changed'") | |
371 | self.shell.run_code("assert number == 1") |
|
371 | self.shell.run_code("assert number == 1") | |
372 | self.shell.run_code("assert TestEnum.B.value == 'added'") |
|
372 | if sys.version_info < (3, 12): | |
|
373 | self.shell.run_code("assert TestEnum.B.value == 'added'") | |||
373 |
|
374 | |||
374 | # ----------- TEST IMPORT FROM MODULE -------------------------- |
|
375 | # ----------- TEST IMPORT FROM MODULE -------------------------- | |
375 |
|
376 |
@@ -4,11 +4,14 b'' | |||||
4 | # Distributed under the terms of the Modified BSD License. |
|
4 | # Distributed under the terms of the Modified BSD License. | |
5 |
|
5 | |||
6 | from unittest import TestCase |
|
6 | from unittest import TestCase | |
|
7 | from pygments import __version__ as pygments_version | |||
7 | from pygments.token import Token |
|
8 | from pygments.token import Token | |
8 | from pygments.lexers import BashLexer |
|
9 | from pygments.lexers import BashLexer | |
9 |
|
10 | |||
10 | from .. import lexers |
|
11 | from .. import lexers | |
11 |
|
12 | |||
|
13 | pyg214 = tuple(int(x) for x in pygments_version.split(".")[:2]) >= (2, 14) | |||
|
14 | ||||
12 |
|
15 | |||
13 | class TestLexers(TestCase): |
|
16 | class TestLexers(TestCase): | |
14 | """Collection of lexers tests""" |
|
17 | """Collection of lexers tests""" | |
@@ -18,25 +21,26 b' class TestLexers(TestCase):' | |||||
18 |
|
21 | |||
19 | def testIPythonLexer(self): |
|
22 | def testIPythonLexer(self): | |
20 | fragment = '!echo $HOME\n' |
|
23 | fragment = '!echo $HOME\n' | |
21 | tokens = [ |
|
24 | bash_tokens = [ | |
22 | (Token.Operator, '!'), |
|
25 | (Token.Operator, '!'), | |
23 | ] |
|
26 | ] | |
24 | tokens.extend(self.bash_lexer.get_tokens(fragment[1:])) |
|
27 | bash_tokens.extend(self.bash_lexer.get_tokens(fragment[1:])) | |
25 |
|
|
28 | ipylex_token = list(self.lexer.get_tokens(fragment)) | |
|
29 | assert bash_tokens[:-1] == ipylex_token[:-1] | |||
26 |
|
30 | |||
27 |
fragment_2 = |
|
31 | fragment_2 = "!" + fragment | |
28 | tokens_2 = [ |
|
32 | tokens_2 = [ | |
29 | (Token.Operator, '!!'), |
|
33 | (Token.Operator, '!!'), | |
30 | ] + tokens[1:] |
|
34 | ] + bash_tokens[1:] | |
31 |
|
|
35 | assert tokens_2[:-1] == list(self.lexer.get_tokens(fragment_2))[:-1] | |
32 |
|
36 | |||
33 | fragment_2 = '\t %%!\n' + fragment[1:] |
|
37 | fragment_2 = '\t %%!\n' + fragment[1:] | |
34 | tokens_2 = [ |
|
38 | tokens_2 = [ | |
35 | (Token.Text, '\t '), |
|
39 | (Token.Text, '\t '), | |
36 | (Token.Operator, '%%!'), |
|
40 | (Token.Operator, '%%!'), | |
37 | (Token.Text, '\n'), |
|
41 | (Token.Text, '\n'), | |
38 | ] + tokens[1:] |
|
42 | ] + bash_tokens[1:] | |
39 |
|
|
43 | assert tokens_2 == list(self.lexer.get_tokens(fragment_2)) | |
40 |
|
44 | |||
41 | fragment_2 = 'x = ' + fragment |
|
45 | fragment_2 = 'x = ' + fragment | |
42 | tokens_2 = [ |
|
46 | tokens_2 = [ | |
@@ -44,8 +48,8 b' class TestLexers(TestCase):' | |||||
44 | (Token.Text, ' '), |
|
48 | (Token.Text, ' '), | |
45 | (Token.Operator, '='), |
|
49 | (Token.Operator, '='), | |
46 | (Token.Text, ' '), |
|
50 | (Token.Text, ' '), | |
47 | ] + tokens |
|
51 | ] + bash_tokens | |
48 |
|
|
52 | assert tokens_2[:-1] == list(self.lexer.get_tokens(fragment_2))[:-1] | |
49 |
|
53 | |||
50 | fragment_2 = 'x, = ' + fragment |
|
54 | fragment_2 = 'x, = ' + fragment | |
51 | tokens_2 = [ |
|
55 | tokens_2 = [ | |
@@ -54,8 +58,8 b' class TestLexers(TestCase):' | |||||
54 | (Token.Text, ' '), |
|
58 | (Token.Text, ' '), | |
55 | (Token.Operator, '='), |
|
59 | (Token.Operator, '='), | |
56 | (Token.Text, ' '), |
|
60 | (Token.Text, ' '), | |
57 | ] + tokens |
|
61 | ] + bash_tokens | |
58 |
|
|
62 | assert tokens_2[:-1] == list(self.lexer.get_tokens(fragment_2))[:-1] | |
59 |
|
63 | |||
60 | fragment_2 = 'x, = %sx ' + fragment[1:] |
|
64 | fragment_2 = 'x, = %sx ' + fragment[1:] | |
61 | tokens_2 = [ |
|
65 | tokens_2 = [ | |
@@ -67,8 +71,10 b' class TestLexers(TestCase):' | |||||
67 | (Token.Operator, '%'), |
|
71 | (Token.Operator, '%'), | |
68 | (Token.Keyword, 'sx'), |
|
72 | (Token.Keyword, 'sx'), | |
69 | (Token.Text, ' '), |
|
73 | (Token.Text, ' '), | |
70 | ] + tokens[1:] |
|
74 | ] + bash_tokens[1:] | |
71 | self.assertEqual(tokens_2, list(self.lexer.get_tokens(fragment_2))) |
|
75 | if tokens_2[7] == (Token.Text, " ") and pyg214: # pygments 2.14+ | |
|
76 | tokens_2[7] = (Token.Text.Whitespace, " ") | |||
|
77 | assert tokens_2[:-1] == list(self.lexer.get_tokens(fragment_2))[:-1] | |||
72 |
|
78 | |||
73 | fragment_2 = 'f = %R function () {}\n' |
|
79 | fragment_2 = 'f = %R function () {}\n' | |
74 | tokens_2 = [ |
|
80 | tokens_2 = [ | |
@@ -80,7 +86,7 b' class TestLexers(TestCase):' | |||||
80 | (Token.Keyword, 'R'), |
|
86 | (Token.Keyword, 'R'), | |
81 | (Token.Text, ' function () {}\n'), |
|
87 | (Token.Text, ' function () {}\n'), | |
82 | ] |
|
88 | ] | |
83 |
|
|
89 | assert tokens_2 == list(self.lexer.get_tokens(fragment_2)) | |
84 |
|
90 | |||
85 | fragment_2 = '\t%%xyz\n$foo\n' |
|
91 | fragment_2 = '\t%%xyz\n$foo\n' | |
86 | tokens_2 = [ |
|
92 | tokens_2 = [ | |
@@ -89,7 +95,7 b' class TestLexers(TestCase):' | |||||
89 | (Token.Keyword, 'xyz'), |
|
95 | (Token.Keyword, 'xyz'), | |
90 | (Token.Text, '\n$foo\n'), |
|
96 | (Token.Text, '\n$foo\n'), | |
91 | ] |
|
97 | ] | |
92 |
|
|
98 | assert tokens_2 == list(self.lexer.get_tokens(fragment_2)) | |
93 |
|
99 | |||
94 | fragment_2 = '%system?\n' |
|
100 | fragment_2 = '%system?\n' | |
95 | tokens_2 = [ |
|
101 | tokens_2 = [ | |
@@ -98,7 +104,7 b' class TestLexers(TestCase):' | |||||
98 | (Token.Operator, '?'), |
|
104 | (Token.Operator, '?'), | |
99 | (Token.Text, '\n'), |
|
105 | (Token.Text, '\n'), | |
100 | ] |
|
106 | ] | |
101 |
|
|
107 | assert tokens_2[:-1] == list(self.lexer.get_tokens(fragment_2))[:-1] | |
102 |
|
108 | |||
103 | fragment_2 = 'x != y\n' |
|
109 | fragment_2 = 'x != y\n' | |
104 | tokens_2 = [ |
|
110 | tokens_2 = [ | |
@@ -109,7 +115,7 b' class TestLexers(TestCase):' | |||||
109 | (Token.Name, 'y'), |
|
115 | (Token.Name, 'y'), | |
110 | (Token.Text, '\n'), |
|
116 | (Token.Text, '\n'), | |
111 | ] |
|
117 | ] | |
112 |
|
|
118 | assert tokens_2[:-1] == list(self.lexer.get_tokens(fragment_2))[:-1] | |
113 |
|
119 | |||
114 | fragment_2 = ' ?math.sin\n' |
|
120 | fragment_2 = ' ?math.sin\n' | |
115 | tokens_2 = [ |
|
121 | tokens_2 = [ | |
@@ -118,7 +124,7 b' class TestLexers(TestCase):' | |||||
118 | (Token.Text, 'math.sin'), |
|
124 | (Token.Text, 'math.sin'), | |
119 | (Token.Text, '\n'), |
|
125 | (Token.Text, '\n'), | |
120 | ] |
|
126 | ] | |
121 |
|
|
127 | assert tokens_2[:-1] == list(self.lexer.get_tokens(fragment_2))[:-1] | |
122 |
|
128 | |||
123 | fragment = ' *int*?\n' |
|
129 | fragment = ' *int*?\n' | |
124 | tokens = [ |
|
130 | tokens = [ | |
@@ -126,7 +132,7 b' class TestLexers(TestCase):' | |||||
126 | (Token.Operator, '?'), |
|
132 | (Token.Operator, '?'), | |
127 | (Token.Text, '\n'), |
|
133 | (Token.Text, '\n'), | |
128 | ] |
|
134 | ] | |
129 |
|
|
135 | assert tokens == list(self.lexer.get_tokens(fragment)) | |
130 |
|
136 | |||
131 | fragment = '%%writefile -a foo.py\nif a == b:\n pass' |
|
137 | fragment = '%%writefile -a foo.py\nif a == b:\n pass' | |
132 | tokens = [ |
|
138 | tokens = [ | |
@@ -145,7 +151,9 b' class TestLexers(TestCase):' | |||||
145 | (Token.Keyword, 'pass'), |
|
151 | (Token.Keyword, 'pass'), | |
146 | (Token.Text, '\n'), |
|
152 | (Token.Text, '\n'), | |
147 | ] |
|
153 | ] | |
148 | self.assertEqual(tokens, list(self.lexer.get_tokens(fragment))) |
|
154 | if tokens[10] == (Token.Text, "\n") and pyg214: # pygments 2.14+ | |
|
155 | tokens[10] = (Token.Text.Whitespace, "\n") | |||
|
156 | assert tokens[:-1] == list(self.lexer.get_tokens(fragment))[:-1] | |||
149 |
|
157 | |||
150 | fragment = '%%timeit\nmath.sin(0)' |
|
158 | fragment = '%%timeit\nmath.sin(0)' | |
151 | tokens = [ |
|
159 | tokens = [ | |
@@ -173,4 +181,4 b' class TestLexers(TestCase):' | |||||
173 | (Token.Punctuation, '>'), |
|
181 | (Token.Punctuation, '>'), | |
174 | (Token.Text, '\n'), |
|
182 | (Token.Text, '\n'), | |
175 | ] |
|
183 | ] | |
176 |
|
|
184 | assert tokens == list(self.lexer.get_tokens(fragment)) |
@@ -68,10 +68,15 b' def create_ipython_shortcuts(shell):' | |||||
68 | reformat_text_before_cursor(event.current_buffer, event.current_buffer.document, shell) |
|
68 | reformat_text_before_cursor(event.current_buffer, event.current_buffer.document, shell) | |
69 | event.current_buffer.validate_and_handle() |
|
69 | event.current_buffer.validate_and_handle() | |
70 |
|
70 | |||
71 | kb.add('escape', 'enter', filter=(has_focus(DEFAULT_BUFFER) |
|
71 | @Condition | |
72 | & ~has_selection |
|
72 | def ebivim(): | |
73 | & insert_mode |
|
73 | return shell.emacs_bindings_in_vi_insert_mode | |
74 | ))(reformat_and_execute) |
|
74 | ||
|
75 | kb.add( | |||
|
76 | "escape", | |||
|
77 | "enter", | |||
|
78 | filter=(has_focus(DEFAULT_BUFFER) & ~has_selection & insert_mode & ebivim), | |||
|
79 | )(reformat_and_execute) | |||
75 |
|
80 | |||
76 | kb.add("c-\\")(quit) |
|
81 | kb.add("c-\\")(quit) | |
77 |
|
82 | |||
@@ -333,10 +338,6 b' def create_ipython_shortcuts(shell):' | |||||
333 | if sys.platform == "win32": |
|
338 | if sys.platform == "win32": | |
334 | kb.add("c-v", filter=(has_focus(DEFAULT_BUFFER) & ~vi_mode))(win_paste) |
|
339 | kb.add("c-v", filter=(has_focus(DEFAULT_BUFFER) & ~vi_mode))(win_paste) | |
335 |
|
340 | |||
336 | @Condition |
|
|||
337 | def ebivim(): |
|
|||
338 | return shell.emacs_bindings_in_vi_insert_mode |
|
|||
339 |
|
||||
340 | focused_insert_vi = has_focus(DEFAULT_BUFFER) & vi_insert_mode |
|
341 | focused_insert_vi = has_focus(DEFAULT_BUFFER) & vi_insert_mode | |
341 |
|
342 | |||
342 | @kb.add("end", filter=has_focus(DEFAULT_BUFFER) & (ebivim | ~vi_insert_mode)) |
|
343 | @kb.add("end", filter=has_focus(DEFAULT_BUFFER) & (ebivim | ~vi_insert_mode)) |
@@ -2,6 +2,44 b'' | |||||
2 | 8.x Series |
|
2 | 8.x Series | |
3 | ============ |
|
3 | ============ | |
4 |
|
4 | |||
|
5 | .. _version 8.8.0: | |||
|
6 | ||||
|
7 | IPython 8.8.0 | |||
|
8 | ------------- | |||
|
9 | ||||
|
10 | First release of IPython in 2023 as there was no release at the end of | |||
|
11 | December. | |||
|
12 | ||||
|
13 | This is an unusually big release (relatively speaking) with more than 15 Pull | |||
|
14 | Requests merge. | |||
|
15 | ||||
|
16 | Of particular interest are: | |||
|
17 | ||||
|
18 | - :ghpull:`13852` that replace the greedy completer and improve | |||
|
19 | completion, in particular for dictionary keys. | |||
|
20 | - :ghpull:`13858` that adds ``py.typed`` to ``setup.cfg`` to make sure it is | |||
|
21 | bundled in wheels. | |||
|
22 | - :ghpull:`13869` that implements tab completions for IPython options in the | |||
|
23 | shell when using `argcomplete <https://github.com/kislyuk/argcomplete>`. I | |||
|
24 | believe this also needs a recent version of Traitlets. | |||
|
25 | - :ghpull:`13865` makes the ``inspector`` class of `InteractiveShell` | |||
|
26 | configurable. | |||
|
27 | - :ghpull:`13880` that remove minor-version entrypoints as the minor version | |||
|
28 | entry points that would be included in the wheel would be the one of the | |||
|
29 | Python version that was used to build the ``whl`` file. | |||
|
30 | ||||
|
31 | In no particular order, the rest of the changes update the test suite to be | |||
|
32 | compatible with Pygments 2.14, various docfixes, testing on more recent python | |||
|
33 | versions and various updates. | |||
|
34 | ||||
|
35 | As usual you can find the full list of PRs on GitHub under `the 8.8 milestone | |||
|
36 | <https://github.com/ipython/ipython/milestone/110>`__. | |||
|
37 | ||||
|
38 | Many thanks to @krassowski for the many PRs and @jasongrout for reviewing and | |||
|
39 | merging contributions. | |||
|
40 | ||||
|
41 | Thanks to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring | |||
|
42 | work on IPython and related libraries. | |||
5 |
|
43 | |||
6 | .. _version 8.7.0: |
|
44 | .. _version 8.7.0: | |
7 |
|
45 | |||
@@ -138,7 +176,7 b' Here is a non exhaustive list of changes that have been implemented for IPython' | |||||
138 | - Fix paste magic on wayland. :ghpull:`13671` |
|
176 | - Fix paste magic on wayland. :ghpull:`13671` | |
139 | - show maxlen in deque's repr. :ghpull:`13648` |
|
177 | - show maxlen in deque's repr. :ghpull:`13648` | |
140 |
|
178 | |||
141 |
Restore line numbers for Input |
|
179 | Restore line numbers for Input | |
142 | ------------------------------ |
|
180 | ------------------------------ | |
143 |
|
181 | |||
144 | Line number information in tracebacks from input are restored. |
|
182 | Line number information in tracebacks from input are restored. | |
@@ -269,7 +307,7 b' Thanks to the `D. E. Shaw group <https://deshaw.com/>`__ for sponsoring' | |||||
269 | work on IPython and related libraries. |
|
307 | work on IPython and related libraries. | |
270 |
|
308 | |||
271 | .. _version 8.1.1: |
|
309 | .. _version 8.1.1: | |
272 |
|
310 | |||
273 | IPython 8.1.1 |
|
311 | IPython 8.1.1 | |
274 | ------------- |
|
312 | ------------- | |
275 |
|
313 | |||
@@ -403,10 +441,10 b' The 8.x branch started diverging from its predecessor around IPython 7.12' | |||||
403 | (January 2020). |
|
441 | (January 2020). | |
404 |
|
442 | |||
405 | This release contains 250+ pull requests, in addition to many of the features |
|
443 | This release contains 250+ pull requests, in addition to many of the features | |
406 |
and backports that have made it to the 7.x branch. Please see the |
|
444 | and backports that have made it to the 7.x branch. Please see the | |
407 | `8.0 milestone <https://github.com/ipython/ipython/milestone/73?closed=1>`__ for the full list of pull requests. |
|
445 | `8.0 milestone <https://github.com/ipython/ipython/milestone/73?closed=1>`__ for the full list of pull requests. | |
408 |
|
446 | |||
409 |
Please feel free to send pull requests to updates those notes after release, |
|
447 | Please feel free to send pull requests to updates those notes after release, | |
410 | I have likely forgotten a few things reviewing 250+ PRs. |
|
448 | I have likely forgotten a few things reviewing 250+ PRs. | |
411 |
|
449 | |||
412 | Dependencies changes/downstream packaging |
|
450 | Dependencies changes/downstream packaging | |
@@ -421,7 +459,7 b' looking for help to do so.' | |||||
421 | - minimal Python is now 3.8 |
|
459 | - minimal Python is now 3.8 | |
422 | - ``nose`` is not a testing requirement anymore |
|
460 | - ``nose`` is not a testing requirement anymore | |
423 | - ``pytest`` replaces nose. |
|
461 | - ``pytest`` replaces nose. | |
424 |
- ``iptest``/``iptest3`` cli entrypoints do not exists anymore. |
|
462 | - ``iptest``/``iptest3`` cli entrypoints do not exists anymore. | |
425 | - minimum officially support ``numpy`` version has been bumped, but this should |
|
463 | - minimum officially support ``numpy`` version has been bumped, but this should | |
426 | not have much effect on packaging. |
|
464 | not have much effect on packaging. | |
427 |
|
465 | |||
@@ -443,7 +481,7 b' deprecation warning:' | |||||
443 | - Please add **since which version** something is deprecated. |
|
481 | - Please add **since which version** something is deprecated. | |
444 |
|
482 | |||
445 | As a side note, it is much easier to conditionally compare version |
|
483 | As a side note, it is much easier to conditionally compare version | |
446 |
numbers rather than using ``try/except`` when functionality changes with a version. |
|
484 | numbers rather than using ``try/except`` when functionality changes with a version. | |
447 |
|
485 | |||
448 | I won't list all the removed features here, but modules like ``IPython.kernel``, |
|
486 | I won't list all the removed features here, but modules like ``IPython.kernel``, | |
449 | which was just a shim module around ``ipykernel`` for the past 8 years, have been |
|
487 | which was just a shim module around ``ipykernel`` for the past 8 years, have been | |
@@ -475,7 +513,7 b' by mypy.' | |||||
475 | Featured changes |
|
513 | Featured changes | |
476 | ---------------- |
|
514 | ---------------- | |
477 |
|
515 | |||
478 |
Here is a features list of changes in IPython 8.0. This is of course non-exhaustive. |
|
516 | Here is a features list of changes in IPython 8.0. This is of course non-exhaustive. | |
479 | Please note as well that many features have been added in the 7.x branch as well |
|
517 | Please note as well that many features have been added in the 7.x branch as well | |
480 | (and hence why you want to read the 7.x what's new notes), in particular |
|
518 | (and hence why you want to read the 7.x what's new notes), in particular | |
481 | features contributed by QuantStack (with respect to debugger protocol and Xeus |
|
519 | features contributed by QuantStack (with respect to debugger protocol and Xeus | |
@@ -523,7 +561,7 b' The error traceback is now correctly formatted, showing the cell number in which' | |||||
523 |
|
561 | |||
524 | ZeroDivisionError: division by zero |
|
562 | ZeroDivisionError: division by zero | |
525 |
|
563 | |||
526 |
The ``stack_data`` package has been integrated, which provides smarter information in the traceback; |
|
564 | The ``stack_data`` package has been integrated, which provides smarter information in the traceback; | |
527 | in particular it will highlight the AST node where an error occurs which can help to quickly narrow down errors. |
|
565 | in particular it will highlight the AST node where an error occurs which can help to quickly narrow down errors. | |
528 |
|
566 | |||
529 | For example in the following snippet:: |
|
567 | For example in the following snippet:: | |
@@ -563,7 +601,7 b' and IPython 8.0 is capable of telling you where the index error occurs::' | |||||
563 | ----> 3 return x[0][i][0] |
|
601 | ----> 3 return x[0][i][0] | |
564 | ^^^^^^^ |
|
602 | ^^^^^^^ | |
565 |
|
603 | |||
566 |
The corresponding locations marked here with ``^`` will show up highlighted in |
|
604 | The corresponding locations marked here with ``^`` will show up highlighted in | |
567 | the terminal and notebooks. |
|
605 | the terminal and notebooks. | |
568 |
|
606 | |||
569 | Finally, a colon ``::`` and line number is appended after a filename in |
|
607 | Finally, a colon ``::`` and line number is appended after a filename in | |
@@ -760,7 +798,7 b' Previously, this was not the case for the Vi-mode prompts::' | |||||
760 | This is now fixed, and Vi prompt prefixes - ``[ins]`` and ``[nav]`` - are |
|
798 | This is now fixed, and Vi prompt prefixes - ``[ins]`` and ``[nav]`` - are | |
761 | skipped just as the normal ``In`` would be. |
|
799 | skipped just as the normal ``In`` would be. | |
762 |
|
800 | |||
763 |
IPython shell can be started in the Vi mode using ``ipython --TerminalInteractiveShell.editing_mode=vi``, |
|
801 | IPython shell can be started in the Vi mode using ``ipython --TerminalInteractiveShell.editing_mode=vi``, | |
764 | You should be able to change mode dynamically with ``%config TerminalInteractiveShell.editing_mode='vi'`` |
|
802 | You should be able to change mode dynamically with ``%config TerminalInteractiveShell.editing_mode='vi'`` | |
765 |
|
803 | |||
766 | Empty History Ranges |
|
804 | Empty History Ranges | |
@@ -787,8 +825,8 b' when followed with :kbd:`F2`), send it to `dpaste.org <http://dpast.org>`_ using' | |||||
787 |
|
825 | |||
788 | Windows timing implementation: Switch to process_time |
|
826 | Windows timing implementation: Switch to process_time | |
789 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
827 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
790 |
Timing on Windows, for example with ``%%time``, was changed from being based on ``time.perf_counter`` |
|
828 | Timing on Windows, for example with ``%%time``, was changed from being based on ``time.perf_counter`` | |
791 |
(which counted time even when the process was sleeping) to being based on ``time.process_time`` instead |
|
829 | (which counted time even when the process was sleeping) to being based on ``time.process_time`` instead | |
792 | (which only counts CPU time). This brings it closer to the behavior on Linux. See :ghpull:`12984`. |
|
830 | (which only counts CPU time). This brings it closer to the behavior on Linux. See :ghpull:`12984`. | |
793 |
|
831 | |||
794 | Miscellaneous |
|
832 | Miscellaneous | |
@@ -813,7 +851,7 b' Re-added support for XDG config directories' | |||||
813 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|
851 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
814 |
|
852 | |||
815 | XDG support through the years comes and goes. There is a tension between having |
|
853 | XDG support through the years comes and goes. There is a tension between having | |
816 |
an identical location for configuration in all platforms versus having simple instructions. |
|
854 | an identical location for configuration in all platforms versus having simple instructions. | |
817 | After initial failures a couple of years ago, IPython was modified to automatically migrate XDG |
|
855 | After initial failures a couple of years ago, IPython was modified to automatically migrate XDG | |
818 | config files back into ``~/.ipython``. That migration code has now been removed. |
|
856 | config files back into ``~/.ipython``. That migration code has now been removed. | |
819 | IPython now checks the XDG locations, so if you _manually_ move your config |
|
857 | IPython now checks the XDG locations, so if you _manually_ move your config | |
@@ -841,7 +879,7 b' Removing support for older Python versions' | |||||
841 |
|
879 | |||
842 |
|
880 | |||
843 | We are removing support for Python up through 3.7, allowing internal code to use the more |
|
881 | We are removing support for Python up through 3.7, allowing internal code to use the more | |
844 |
efficient ``pathlib`` and to make better use of type annotations. |
|
882 | efficient ``pathlib`` and to make better use of type annotations. | |
845 |
|
883 | |||
846 | .. image:: ../_images/8.0/pathlib_pathlib_everywhere.jpg |
|
884 | .. image:: ../_images/8.0/pathlib_pathlib_everywhere.jpg | |
847 | :alt: "Meme image of Toy Story with Woody and Buzz, with the text 'pathlib, pathlib everywhere'" |
|
885 | :alt: "Meme image of Toy Story with Woody and Buzz, with the text 'pathlib, pathlib everywhere'" |
@@ -211,20 +211,15 b' def find_entry_points():' | |||||
211 | use, our own build_scripts_entrypt class below parses these and builds |
|
211 | use, our own build_scripts_entrypt class below parses these and builds | |
212 | command line scripts. |
|
212 | command line scripts. | |
213 |
|
213 | |||
214 | Each of our entry points gets a plain name, e.g. ipython, a name |
|
214 | Each of our entry points gets a plain name, e.g. ipython, and a name | |
215 |
suffixed with the Python major version number, e.g. ipython3 |
|
215 | suffixed with the Python major version number, e.g. ipython3. | |
216 | a name suffixed with the Python major.minor version number, eg. ipython3.8. |
|
|||
217 | """ |
|
216 | """ | |
218 | ep = [ |
|
217 | ep = [ | |
219 | 'ipython%s = IPython:start_ipython', |
|
218 | 'ipython%s = IPython:start_ipython', | |
220 | ] |
|
219 | ] | |
221 | major_suffix = str(sys.version_info[0]) |
|
220 | major_suffix = str(sys.version_info[0]) | |
222 | minor_suffix = ".".join([str(sys.version_info[0]), str(sys.version_info[1])]) |
|
221 | return [e % "" for e in ep] + [e % major_suffix for e in ep] | |
223 | return ( |
|
222 | ||
224 | [e % "" for e in ep] |
|
|||
225 | + [e % major_suffix for e in ep] |
|
|||
226 | + [e % minor_suffix for e in ep] |
|
|||
227 | ) |
|
|||
228 |
|
223 | |||
229 | class install_lib_symlink(Command): |
|
224 | class install_lib_symlink(Command): | |
230 | user_options = [ |
|
225 | user_options = [ |
@@ -2,15 +2,6 b'' | |||||
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 |
|
||||
6 | python -c 'import keyring' |
|
|||
7 | python -c 'import twine' |
|
|||
8 | python -c 'import sphinx' |
|
|||
9 | python -c 'import sphinx_rtd_theme' |
|
|||
10 | python -c 'import pytest' |
|
|||
11 | python -c 'import build' |
|
|||
12 |
|
||||
13 |
|
||||
14 | BLACK=$(tput setaf 1) |
|
5 | BLACK=$(tput setaf 1) | |
15 | RED=$(tput setaf 1) |
|
6 | RED=$(tput setaf 1) | |
16 | GREEN=$(tput setaf 2) |
|
7 | GREEN=$(tput setaf 2) | |
@@ -22,6 +13,22 b' WHITE=$(tput setaf 7)' | |||||
22 | NOR=$(tput sgr0) |
|
13 | NOR=$(tput sgr0) | |
23 |
|
14 | |||
24 |
|
15 | |||
|
16 | echo "Checking all tools are installed..." | |||
|
17 | ||||
|
18 | python -c 'import keyring' | |||
|
19 | python -c 'import twine' | |||
|
20 | python -c 'import sphinx' | |||
|
21 | python -c 'import sphinx_rtd_theme' | |||
|
22 | python -c 'import pytest' | |||
|
23 | python -c 'import build' | |||
|
24 | # those are necessary fo building the docs | |||
|
25 | echo "Checking imports for docs" | |||
|
26 | python -c 'import numpy' | |||
|
27 | python -c 'import matplotlib' | |||
|
28 | ||||
|
29 | ||||
|
30 | ||||
|
31 | ||||
25 | echo "Will use $BLUE'$EDITOR'$NOR to edit files when necessary" |
|
32 | echo "Will use $BLUE'$EDITOR'$NOR to edit files when necessary" | |
26 | echo -n "PREV_RELEASE (X.y.z) [$PREV_RELEASE]: " |
|
33 | echo -n "PREV_RELEASE (X.y.z) [$PREV_RELEASE]: " | |
27 | read input |
|
34 | read input |
General Comments 0
You need to be logged in to leave comments.
Login now