##// END OF EJS Templates
Merge pull request from GHSA-pq7m-3gw7-gq5x...
Matthias Bussonnier -
Show More
@@ -0,0 +1,56 b''
1 """
2 Test that CVEs stay fixed.
3 """
4
5 from IPython.utils.tempdir import TemporaryDirectory, TemporaryWorkingDirectory
6 from pathlib import Path
7 import random
8 import sys
9 import os
10 import string
11 import subprocess
12 import time
13
14 def test_cve_2022_21699():
15 """
16 Here we test CVE-2022-21699.
17
18 We create a temporary directory, cd into it.
19 Make a profile file that should not be executed and start IPython in a subprocess,
20 checking for the value.
21
22
23
24 """
25
26 dangerous_profile_dir = Path('profile_default')
27
28 dangerous_startup_dir = dangerous_profile_dir / 'startup'
29 dangerous_expected = 'CVE-2022-21699-'+''.join([random.choice(string.ascii_letters) for i in range(10)])
30
31 with TemporaryWorkingDirectory() as t:
32 dangerous_startup_dir.mkdir(parents=True)
33 (dangerous_startup_dir/ 'foo.py').write_text(f'print("{dangerous_expected}")')
34 # 1 sec to make sure FS is flushed.
35 #time.sleep(1)
36 cmd = [sys.executable,'-m', 'IPython']
37 env = os.environ.copy()
38 env['IPY_TEST_SIMPLE_PROMPT'] = '1'
39
40
41 # First we fake old behavior, making sure the profile is/was actually dangerous
42 p_dangerous = subprocess.Popen(cmd + [f'--profile-dir={dangerous_profile_dir}'], env=env, stdin=subprocess.PIPE,
43 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
44 out_dangerous, err_dangerouns = p_dangerous.communicate(b"exit\r")
45 assert dangerous_expected in out_dangerous.decode()
46
47 # Now that we know it _would_ have been dangerous, we test it's not loaded
48 p = subprocess.Popen(cmd, env=env, stdin=subprocess.PIPE,
49 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
50 out, err = p.communicate(b"exit\r")
51 assert b'IPython' in out
52 assert dangerous_expected not in out.decode()
53 assert err == b''
54
55
56
@@ -1,152 +1,156 b''
1 1 # encoding: utf-8
2 2 """
3 3 IPython: tools for interactive and parallel computing in Python.
4 4
5 5 https://ipython.org
6 6 """
7 7 #-----------------------------------------------------------------------------
8 8 # Copyright (c) 2008-2011, IPython Development Team.
9 9 # Copyright (c) 2001-2007, Fernando Perez <fernando.perez@colorado.edu>
10 10 # Copyright (c) 2001, Janko Hauser <jhauser@zscout.de>
11 11 # Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu>
12 12 #
13 13 # Distributed under the terms of the Modified BSD License.
14 14 #
15 15 # The full license is in the file COPYING.txt, distributed with this software.
16 16 #-----------------------------------------------------------------------------
17 17
18 18 #-----------------------------------------------------------------------------
19 19 # Imports
20 20 #-----------------------------------------------------------------------------
21 21
22 22 import os
23 23 import sys
24 24
25 25 #-----------------------------------------------------------------------------
26 26 # Setup everything
27 27 #-----------------------------------------------------------------------------
28 28
29 29 # Don't forget to also update setup.py when this changes!
30 30 if sys.version_info < (3, 6):
31 31 raise ImportError(
32 32 """
33 33 IPython 7.10+ supports Python 3.6 and above.
34 34 When using Python 2.7, please install IPython 5.x LTS Long Term Support version.
35 35 Python 3.3 and 3.4 were supported up to IPython 6.x.
36 36 Python 3.5 was supported with IPython 7.0 to 7.9.
37 37
38 38 See IPython `README.rst` file for more information:
39 39
40 40 https://github.com/ipython/ipython/blob/master/README.rst
41 41
42 42 """)
43 43
44 44 # Make it easy to import extensions - they are always directly on pythonpath.
45 45 # Therefore, non-IPython modules can be added to extensions directory.
46 46 # This should probably be in ipapp.py.
47 47 sys.path.append(os.path.join(os.path.dirname(__file__), "extensions"))
48 48
49 49 #-----------------------------------------------------------------------------
50 50 # Setup the top level names
51 51 #-----------------------------------------------------------------------------
52 52
53 53 from .core.getipython import get_ipython
54 54 from .core import release
55 55 from .core.application import Application
56 56 from .terminal.embed import embed
57 57
58 58 from .core.interactiveshell import InteractiveShell
59 59 from .testing import test
60 60 from .utils.sysinfo import sys_info
61 61 from .utils.frame import extract_module_locals
62 62
63 63 # Release data
64 64 __author__ = '%s <%s>' % (release.author, release.author_email)
65 65 __license__ = release.license
66 66 __version__ = release.version
67 67 version_info = release.version_info
68 # list of CVEs that should have been patched in this release.
69 # this is informational and should not be relied upon.
70 __patched_cves__ = {"CVE-2022-21699"}
71
68 72
69 73 def embed_kernel(module=None, local_ns=None, **kwargs):
70 74 """Embed and start an IPython kernel in a given scope.
71 75
72 76 If you don't want the kernel to initialize the namespace
73 77 from the scope of the surrounding function,
74 78 and/or you want to load full IPython configuration,
75 79 you probably want `IPython.start_kernel()` instead.
76 80
77 81 Parameters
78 82 ----------
79 83 module : types.ModuleType, optional
80 84 The module to load into IPython globals (default: caller)
81 85 local_ns : dict, optional
82 86 The namespace to load into IPython user namespace (default: caller)
83 87
84 88 kwargs : various, optional
85 89 Further keyword args are relayed to the IPKernelApp constructor,
86 90 allowing configuration of the Kernel. Will only have an effect
87 91 on the first embed_kernel call for a given process.
88 92 """
89 93
90 94 (caller_module, caller_locals) = extract_module_locals(1)
91 95 if module is None:
92 96 module = caller_module
93 97 if local_ns is None:
94 98 local_ns = caller_locals
95 99
96 100 # Only import .zmq when we really need it
97 101 from ipykernel.embed import embed_kernel as real_embed_kernel
98 102 real_embed_kernel(module=module, local_ns=local_ns, **kwargs)
99 103
100 104 def start_ipython(argv=None, **kwargs):
101 105 """Launch a normal IPython instance (as opposed to embedded)
102 106
103 107 `IPython.embed()` puts a shell in a particular calling scope,
104 108 such as a function or method for debugging purposes,
105 109 which is often not desirable.
106 110
107 111 `start_ipython()` does full, regular IPython initialization,
108 112 including loading startup files, configuration, etc.
109 113 much of which is skipped by `embed()`.
110 114
111 115 This is a public API method, and will survive implementation changes.
112 116
113 117 Parameters
114 118 ----------
115 119
116 120 argv : list or None, optional
117 121 If unspecified or None, IPython will parse command-line options from sys.argv.
118 122 To prevent any command-line parsing, pass an empty list: `argv=[]`.
119 123 user_ns : dict, optional
120 124 specify this dictionary to initialize the IPython user namespace with particular values.
121 125 kwargs : various, optional
122 126 Any other kwargs will be passed to the Application constructor,
123 127 such as `config`.
124 128 """
125 129 from IPython.terminal.ipapp import launch_new_instance
126 130 return launch_new_instance(argv=argv, **kwargs)
127 131
128 132 def start_kernel(argv=None, **kwargs):
129 133 """Launch a normal IPython kernel instance (as opposed to embedded)
130 134
131 135 `IPython.embed_kernel()` puts a shell in a particular calling scope,
132 136 such as a function or method for debugging purposes,
133 137 which is often not desirable.
134 138
135 139 `start_kernel()` does full, regular IPython initialization,
136 140 including loading startup files, configuration, etc.
137 141 much of which is skipped by `embed()`.
138 142
139 143 Parameters
140 144 ----------
141 145
142 146 argv : list or None, optional
143 147 If unspecified or None, IPython will parse command-line options from sys.argv.
144 148 To prevent any command-line parsing, pass an empty list: `argv=[]`.
145 149 user_ns : dict, optional
146 150 specify this dictionary to initialize the IPython user namespace with particular values.
147 151 kwargs : various, optional
148 152 Any other kwargs will be passed to the Application constructor,
149 153 such as `config`.
150 154 """
151 155 from IPython.kernel.zmq.kernelapp import launch_new_instance
152 156 return launch_new_instance(argv=argv, **kwargs)
@@ -1,462 +1,462 b''
1 1 # encoding: utf-8
2 2 """
3 3 An application for IPython.
4 4
5 5 All top-level applications should use the classes in this module for
6 6 handling configuration and creating configurables.
7 7
8 8 The job of an :class:`Application` is to create the master configuration
9 9 object and then create the configurable objects, passing the config to them.
10 10 """
11 11
12 12 # Copyright (c) IPython Development Team.
13 13 # Distributed under the terms of the Modified BSD License.
14 14
15 15 import atexit
16 16 from copy import deepcopy
17 17 import glob
18 18 import logging
19 19 import os
20 20 import shutil
21 21 import sys
22 22
23 23 from traitlets.config.application import Application, catch_config_error
24 24 from traitlets.config.loader import ConfigFileNotFound, PyFileConfigLoader
25 25 from IPython.core import release, crashhandler
26 26 from IPython.core.profiledir import ProfileDir, ProfileDirError
27 27 from IPython.paths import get_ipython_dir, get_ipython_package_dir
28 28 from IPython.utils.path import ensure_dir_exists
29 29 from traitlets import (
30 30 List, Unicode, Type, Bool, Set, Instance, Undefined,
31 31 default, observe,
32 32 )
33 33
34 34 if os.name == 'nt':
35 35 programdata = os.environ.get('PROGRAMDATA', None)
36 36 if programdata:
37 37 SYSTEM_CONFIG_DIRS = [os.path.join(programdata, 'ipython')]
38 38 else: # PROGRAMDATA is not defined by default on XP.
39 39 SYSTEM_CONFIG_DIRS = []
40 40 else:
41 41 SYSTEM_CONFIG_DIRS = [
42 42 "/usr/local/etc/ipython",
43 43 "/etc/ipython",
44 44 ]
45 45
46 46
47 47 ENV_CONFIG_DIRS = []
48 48 _env_config_dir = os.path.join(sys.prefix, 'etc', 'ipython')
49 49 if _env_config_dir not in SYSTEM_CONFIG_DIRS:
50 50 # only add ENV_CONFIG if sys.prefix is not already included
51 51 ENV_CONFIG_DIRS.append(_env_config_dir)
52 52
53 53
54 54 _envvar = os.environ.get('IPYTHON_SUPPRESS_CONFIG_ERRORS')
55 55 if _envvar in {None, ''}:
56 56 IPYTHON_SUPPRESS_CONFIG_ERRORS = None
57 57 else:
58 58 if _envvar.lower() in {'1','true'}:
59 59 IPYTHON_SUPPRESS_CONFIG_ERRORS = True
60 60 elif _envvar.lower() in {'0','false'} :
61 61 IPYTHON_SUPPRESS_CONFIG_ERRORS = False
62 62 else:
63 63 sys.exit("Unsupported value for environment variable: 'IPYTHON_SUPPRESS_CONFIG_ERRORS' is set to '%s' which is none of {'0', '1', 'false', 'true', ''}."% _envvar )
64 64
65 65 # aliases and flags
66 66
67 67 base_aliases = {
68 68 'profile-dir' : 'ProfileDir.location',
69 69 'profile' : 'BaseIPythonApplication.profile',
70 70 'ipython-dir' : 'BaseIPythonApplication.ipython_dir',
71 71 'log-level' : 'Application.log_level',
72 72 'config' : 'BaseIPythonApplication.extra_config_file',
73 73 }
74 74
75 75 base_flags = dict(
76 76 debug = ({'Application' : {'log_level' : logging.DEBUG}},
77 77 "set log level to logging.DEBUG (maximize logging output)"),
78 78 quiet = ({'Application' : {'log_level' : logging.CRITICAL}},
79 79 "set log level to logging.CRITICAL (minimize logging output)"),
80 80 init = ({'BaseIPythonApplication' : {
81 81 'copy_config_files' : True,
82 82 'auto_create' : True}
83 83 }, """Initialize profile with default config files. This is equivalent
84 84 to running `ipython profile create <profile>` prior to startup.
85 85 """)
86 86 )
87 87
88 88 class ProfileAwareConfigLoader(PyFileConfigLoader):
89 89 """A Python file config loader that is aware of IPython profiles."""
90 90 def load_subconfig(self, fname, path=None, profile=None):
91 91 if profile is not None:
92 92 try:
93 93 profile_dir = ProfileDir.find_profile_dir_by_name(
94 94 get_ipython_dir(),
95 95 profile,
96 96 )
97 97 except ProfileDirError:
98 98 return
99 99 path = profile_dir.location
100 100 return super(ProfileAwareConfigLoader, self).load_subconfig(fname, path=path)
101 101
102 102 class BaseIPythonApplication(Application):
103 103
104 104 name = u'ipython'
105 105 description = Unicode(u'IPython: an enhanced interactive Python shell.')
106 106 version = Unicode(release.version)
107 107
108 108 aliases = base_aliases
109 109 flags = base_flags
110 110 classes = List([ProfileDir])
111 111
112 112 # enable `load_subconfig('cfg.py', profile='name')`
113 113 python_config_loader_class = ProfileAwareConfigLoader
114 114
115 115 # Track whether the config_file has changed,
116 116 # because some logic happens only if we aren't using the default.
117 117 config_file_specified = Set()
118 118
119 119 config_file_name = Unicode()
120 120 @default('config_file_name')
121 121 def _config_file_name_default(self):
122 122 return self.name.replace('-','_') + u'_config.py'
123 123 @observe('config_file_name')
124 124 def _config_file_name_changed(self, change):
125 125 if change['new'] != change['old']:
126 126 self.config_file_specified.add(change['new'])
127 127
128 128 # The directory that contains IPython's builtin profiles.
129 129 builtin_profile_dir = Unicode(
130 130 os.path.join(get_ipython_package_dir(), u'config', u'profile', u'default')
131 131 )
132 132
133 133 config_file_paths = List(Unicode())
134 134 @default('config_file_paths')
135 135 def _config_file_paths_default(self):
136 return [os.getcwd()]
136 return []
137 137
138 138 extra_config_file = Unicode(
139 139 help="""Path to an extra config file to load.
140 140
141 141 If specified, load this config file in addition to any other IPython config.
142 142 """).tag(config=True)
143 143 @observe('extra_config_file')
144 144 def _extra_config_file_changed(self, change):
145 145 old = change['old']
146 146 new = change['new']
147 147 try:
148 148 self.config_files.remove(old)
149 149 except ValueError:
150 150 pass
151 151 self.config_file_specified.add(new)
152 152 self.config_files.append(new)
153 153
154 154 profile = Unicode(u'default',
155 155 help="""The IPython profile to use."""
156 156 ).tag(config=True)
157 157
158 158 @observe('profile')
159 159 def _profile_changed(self, change):
160 160 self.builtin_profile_dir = os.path.join(
161 161 get_ipython_package_dir(), u'config', u'profile', change['new']
162 162 )
163 163
164 164 ipython_dir = Unicode(
165 165 help="""
166 166 The name of the IPython directory. This directory is used for logging
167 167 configuration (through profiles), history storage, etc. The default
168 168 is usually $HOME/.ipython. This option can also be specified through
169 169 the environment variable IPYTHONDIR.
170 170 """
171 171 ).tag(config=True)
172 172 @default('ipython_dir')
173 173 def _ipython_dir_default(self):
174 174 d = get_ipython_dir()
175 175 self._ipython_dir_changed({
176 176 'name': 'ipython_dir',
177 177 'old': d,
178 178 'new': d,
179 179 })
180 180 return d
181 181
182 182 _in_init_profile_dir = False
183 183 profile_dir = Instance(ProfileDir, allow_none=True)
184 184 @default('profile_dir')
185 185 def _profile_dir_default(self):
186 186 # avoid recursion
187 187 if self._in_init_profile_dir:
188 188 return
189 189 # profile_dir requested early, force initialization
190 190 self.init_profile_dir()
191 191 return self.profile_dir
192 192
193 193 overwrite = Bool(False,
194 194 help="""Whether to overwrite existing config files when copying"""
195 195 ).tag(config=True)
196 196 auto_create = Bool(False,
197 197 help="""Whether to create profile dir if it doesn't exist"""
198 198 ).tag(config=True)
199 199
200 200 config_files = List(Unicode())
201 201 @default('config_files')
202 202 def _config_files_default(self):
203 203 return [self.config_file_name]
204 204
205 205 copy_config_files = Bool(False,
206 206 help="""Whether to install the default config files into the profile dir.
207 207 If a new profile is being created, and IPython contains config files for that
208 208 profile, then they will be staged into the new directory. Otherwise,
209 209 default config files will be automatically generated.
210 210 """).tag(config=True)
211 211
212 212 verbose_crash = Bool(False,
213 213 help="""Create a massive crash report when IPython encounters what may be an
214 214 internal error. The default is to append a short message to the
215 215 usual traceback""").tag(config=True)
216 216
217 217 # The class to use as the crash handler.
218 218 crash_handler_class = Type(crashhandler.CrashHandler)
219 219
220 220 @catch_config_error
221 221 def __init__(self, **kwargs):
222 222 super(BaseIPythonApplication, self).__init__(**kwargs)
223 223 # ensure current working directory exists
224 224 try:
225 225 os.getcwd()
226 226 except:
227 227 # exit if cwd doesn't exist
228 228 self.log.error("Current working directory doesn't exist.")
229 229 self.exit(1)
230 230
231 231 #-------------------------------------------------------------------------
232 232 # Various stages of Application creation
233 233 #-------------------------------------------------------------------------
234 234
235 235 deprecated_subcommands = {}
236 236
237 237 def initialize_subcommand(self, subc, argv=None):
238 238 if subc in self.deprecated_subcommands:
239 239 self.log.warning("Subcommand `ipython {sub}` is deprecated and will be removed "
240 240 "in future versions.".format(sub=subc))
241 241 self.log.warning("You likely want to use `jupyter {sub}` in the "
242 242 "future".format(sub=subc))
243 243 return super(BaseIPythonApplication, self).initialize_subcommand(subc, argv)
244 244
245 245 def init_crash_handler(self):
246 246 """Create a crash handler, typically setting sys.excepthook to it."""
247 247 self.crash_handler = self.crash_handler_class(self)
248 248 sys.excepthook = self.excepthook
249 249 def unset_crashhandler():
250 250 sys.excepthook = sys.__excepthook__
251 251 atexit.register(unset_crashhandler)
252 252
253 253 def excepthook(self, etype, evalue, tb):
254 254 """this is sys.excepthook after init_crashhandler
255 255
256 256 set self.verbose_crash=True to use our full crashhandler, instead of
257 257 a regular traceback with a short message (crash_handler_lite)
258 258 """
259 259
260 260 if self.verbose_crash:
261 261 return self.crash_handler(etype, evalue, tb)
262 262 else:
263 263 return crashhandler.crash_handler_lite(etype, evalue, tb)
264 264
265 265 @observe('ipython_dir')
266 266 def _ipython_dir_changed(self, change):
267 267 old = change['old']
268 268 new = change['new']
269 269 if old is not Undefined:
270 270 str_old = os.path.abspath(old)
271 271 if str_old in sys.path:
272 272 sys.path.remove(str_old)
273 273 str_path = os.path.abspath(new)
274 274 sys.path.append(str_path)
275 275 ensure_dir_exists(new)
276 276 readme = os.path.join(new, 'README')
277 277 readme_src = os.path.join(get_ipython_package_dir(), u'config', u'profile', 'README')
278 278 if not os.path.exists(readme) and os.path.exists(readme_src):
279 279 shutil.copy(readme_src, readme)
280 280 for d in ('extensions', 'nbextensions'):
281 281 path = os.path.join(new, d)
282 282 try:
283 283 ensure_dir_exists(path)
284 284 except OSError as e:
285 285 # this will not be EEXIST
286 286 self.log.error("couldn't create path %s: %s", path, e)
287 287 self.log.debug("IPYTHONDIR set to: %s" % new)
288 288
289 289 def load_config_file(self, suppress_errors=IPYTHON_SUPPRESS_CONFIG_ERRORS):
290 290 """Load the config file.
291 291
292 292 By default, errors in loading config are handled, and a warning
293 293 printed on screen. For testing, the suppress_errors option is set
294 294 to False, so errors will make tests fail.
295 295
296 296 `suppress_errors` default value is to be `None` in which case the
297 297 behavior default to the one of `traitlets.Application`.
298 298
299 299 The default value can be set :
300 300 - to `False` by setting 'IPYTHON_SUPPRESS_CONFIG_ERRORS' environment variable to '0', or 'false' (case insensitive).
301 301 - to `True` by setting 'IPYTHON_SUPPRESS_CONFIG_ERRORS' environment variable to '1' or 'true' (case insensitive).
302 302 - to `None` by setting 'IPYTHON_SUPPRESS_CONFIG_ERRORS' environment variable to '' (empty string) or leaving it unset.
303 303
304 304 Any other value are invalid, and will make IPython exit with a non-zero return code.
305 305 """
306 306
307 307
308 308 self.log.debug("Searching path %s for config files", self.config_file_paths)
309 309 base_config = 'ipython_config.py'
310 310 self.log.debug("Attempting to load config file: %s" %
311 311 base_config)
312 312 try:
313 313 if suppress_errors is not None:
314 314 old_value = Application.raise_config_file_errors
315 315 Application.raise_config_file_errors = not suppress_errors;
316 316 Application.load_config_file(
317 317 self,
318 318 base_config,
319 319 path=self.config_file_paths
320 320 )
321 321 except ConfigFileNotFound:
322 322 # ignore errors loading parent
323 323 self.log.debug("Config file %s not found", base_config)
324 324 pass
325 325 if suppress_errors is not None:
326 326 Application.raise_config_file_errors = old_value
327 327
328 328 for config_file_name in self.config_files:
329 329 if not config_file_name or config_file_name == base_config:
330 330 continue
331 331 self.log.debug("Attempting to load config file: %s" %
332 332 self.config_file_name)
333 333 try:
334 334 Application.load_config_file(
335 335 self,
336 336 config_file_name,
337 337 path=self.config_file_paths
338 338 )
339 339 except ConfigFileNotFound:
340 340 # Only warn if the default config file was NOT being used.
341 341 if config_file_name in self.config_file_specified:
342 342 msg = self.log.warning
343 343 else:
344 344 msg = self.log.debug
345 345 msg("Config file not found, skipping: %s", config_file_name)
346 346 except Exception:
347 347 # For testing purposes.
348 348 if not suppress_errors:
349 349 raise
350 350 self.log.warning("Error loading config file: %s" %
351 351 self.config_file_name, exc_info=True)
352 352
353 353 def init_profile_dir(self):
354 354 """initialize the profile dir"""
355 355 self._in_init_profile_dir = True
356 356 if self.profile_dir is not None:
357 357 # already ran
358 358 return
359 359 if 'ProfileDir.location' not in self.config:
360 360 # location not specified, find by profile name
361 361 try:
362 362 p = ProfileDir.find_profile_dir_by_name(self.ipython_dir, self.profile, self.config)
363 363 except ProfileDirError:
364 364 # not found, maybe create it (always create default profile)
365 365 if self.auto_create or self.profile == 'default':
366 366 try:
367 367 p = ProfileDir.create_profile_dir_by_name(self.ipython_dir, self.profile, self.config)
368 368 except ProfileDirError:
369 369 self.log.fatal("Could not create profile: %r"%self.profile)
370 370 self.exit(1)
371 371 else:
372 372 self.log.info("Created profile dir: %r"%p.location)
373 373 else:
374 374 self.log.fatal("Profile %r not found."%self.profile)
375 375 self.exit(1)
376 376 else:
377 377 self.log.debug("Using existing profile dir: %r"%p.location)
378 378 else:
379 379 location = self.config.ProfileDir.location
380 380 # location is fully specified
381 381 try:
382 382 p = ProfileDir.find_profile_dir(location, self.config)
383 383 except ProfileDirError:
384 384 # not found, maybe create it
385 385 if self.auto_create:
386 386 try:
387 387 p = ProfileDir.create_profile_dir(location, self.config)
388 388 except ProfileDirError:
389 389 self.log.fatal("Could not create profile directory: %r"%location)
390 390 self.exit(1)
391 391 else:
392 392 self.log.debug("Creating new profile dir: %r"%location)
393 393 else:
394 394 self.log.fatal("Profile directory %r not found."%location)
395 395 self.exit(1)
396 396 else:
397 397 self.log.info("Using existing profile dir: %r"%location)
398 398 # if profile_dir is specified explicitly, set profile name
399 399 dir_name = os.path.basename(p.location)
400 400 if dir_name.startswith('profile_'):
401 401 self.profile = dir_name[8:]
402 402
403 403 self.profile_dir = p
404 404 self.config_file_paths.append(p.location)
405 405 self._in_init_profile_dir = False
406 406
407 407 def init_config_files(self):
408 408 """[optionally] copy default config files into profile dir."""
409 409 self.config_file_paths.extend(ENV_CONFIG_DIRS)
410 410 self.config_file_paths.extend(SYSTEM_CONFIG_DIRS)
411 411 # copy config files
412 412 path = self.builtin_profile_dir
413 413 if self.copy_config_files:
414 414 src = self.profile
415 415
416 416 cfg = self.config_file_name
417 417 if path and os.path.exists(os.path.join(path, cfg)):
418 418 self.log.warning("Staging %r from %s into %r [overwrite=%s]"%(
419 419 cfg, src, self.profile_dir.location, self.overwrite)
420 420 )
421 421 self.profile_dir.copy_config_file(cfg, path=path, overwrite=self.overwrite)
422 422 else:
423 423 self.stage_default_config_file()
424 424 else:
425 425 # Still stage *bundled* config files, but not generated ones
426 426 # This is necessary for `ipython profile=sympy` to load the profile
427 427 # on the first go
428 428 files = glob.glob(os.path.join(path, '*.py'))
429 429 for fullpath in files:
430 430 cfg = os.path.basename(fullpath)
431 431 if self.profile_dir.copy_config_file(cfg, path=path, overwrite=False):
432 432 # file was copied
433 433 self.log.warning("Staging bundled %s from %s into %r"%(
434 434 cfg, self.profile, self.profile_dir.location)
435 435 )
436 436
437 437
438 438 def stage_default_config_file(self):
439 439 """auto generate default config file, and stage it into the profile."""
440 440 s = self.generate_config_file()
441 441 fname = os.path.join(self.profile_dir.location, self.config_file_name)
442 442 if self.overwrite or not os.path.exists(fname):
443 443 self.log.warning("Generating default config file: %r"%(fname))
444 444 with open(fname, 'w') as f:
445 445 f.write(s)
446 446
447 447 @catch_config_error
448 448 def initialize(self, argv=None):
449 449 # don't hook up crash handler before parsing command-line
450 450 self.parse_command_line(argv)
451 451 self.init_crash_handler()
452 452 if self.subapp is not None:
453 453 # stop here if subapp is taking over
454 454 return
455 455 # save a copy of CLI config to re-load after config files
456 456 # so that it has highest priority
457 457 cl_config = deepcopy(self.config)
458 458 self.init_profile_dir()
459 459 self.init_config_files()
460 460 self.load_config_file()
461 461 # enforce cl-opts override configfile opts:
462 462 self.update_config(cl_config)
@@ -1,311 +1,312 b''
1 1 # encoding: utf-8
2 2 """
3 3 An application for managing IPython profiles.
4 4
5 5 To be invoked as the `ipython profile` subcommand.
6 6
7 7 Authors:
8 8
9 9 * Min RK
10 10
11 11 """
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Copyright (C) 2008 The IPython Development Team
15 15 #
16 16 # Distributed under the terms of the BSD License. The full license is in
17 17 # the file COPYING, distributed as part of this software.
18 18 #-----------------------------------------------------------------------------
19 19
20 20 #-----------------------------------------------------------------------------
21 21 # Imports
22 22 #-----------------------------------------------------------------------------
23 23
24 24 import os
25 25
26 26 from traitlets.config.application import Application
27 27 from IPython.core.application import (
28 28 BaseIPythonApplication, base_flags
29 29 )
30 30 from IPython.core.profiledir import ProfileDir
31 31 from IPython.utils.importstring import import_item
32 32 from IPython.paths import get_ipython_dir, get_ipython_package_dir
33 33 from traitlets import Unicode, Bool, Dict, observe
34 34
35 35 #-----------------------------------------------------------------------------
36 36 # Constants
37 37 #-----------------------------------------------------------------------------
38 38
39 39 create_help = """Create an IPython profile by name
40 40
41 41 Create an ipython profile directory by its name or
42 42 profile directory path. Profile directories contain
43 43 configuration, log and security related files and are named
44 44 using the convention 'profile_<name>'. By default they are
45 45 located in your ipython directory. Once created, you will
46 46 can edit the configuration files in the profile
47 47 directory to configure IPython. Most users will create a
48 48 profile directory by name,
49 49 `ipython profile create myprofile`, which will put the directory
50 50 in `<ipython_dir>/profile_myprofile`.
51 51 """
52 52 list_help = """List available IPython profiles
53 53
54 54 List all available profiles, by profile location, that can
55 55 be found in the current working directly or in the ipython
56 56 directory. Profile directories are named using the convention
57 57 'profile_<profile>'.
58 58 """
59 59 profile_help = """Manage IPython profiles
60 60
61 61 Profile directories contain
62 62 configuration, log and security related files and are named
63 63 using the convention 'profile_<name>'. By default they are
64 64 located in your ipython directory. You can create profiles
65 65 with `ipython profile create <name>`, or see the profiles you
66 66 already have with `ipython profile list`
67 67
68 68 To get started configuring IPython, simply do:
69 69
70 70 $> ipython profile create
71 71
72 72 and IPython will create the default profile in <ipython_dir>/profile_default,
73 73 where you can edit ipython_config.py to start configuring IPython.
74 74
75 75 """
76 76
77 77 _list_examples = "ipython profile list # list all profiles"
78 78
79 79 _create_examples = """
80 80 ipython profile create foo # create profile foo w/ default config files
81 81 ipython profile create foo --reset # restage default config files over current
82 82 ipython profile create foo --parallel # also stage parallel config files
83 83 """
84 84
85 85 _main_examples = """
86 86 ipython profile create -h # show the help string for the create subcommand
87 87 ipython profile list -h # show the help string for the list subcommand
88 88
89 89 ipython locate profile foo # print the path to the directory for profile 'foo'
90 90 """
91 91
92 92 #-----------------------------------------------------------------------------
93 93 # Profile Application Class (for `ipython profile` subcommand)
94 94 #-----------------------------------------------------------------------------
95 95
96 96
97 97 def list_profiles_in(path):
98 98 """list profiles in a given root directory"""
99 99 profiles = []
100 100
101 101 # for python 3.6+ rewrite to: with os.scandir(path) as dirlist:
102 102 files = os.scandir(path)
103 103 for f in files:
104 104 if f.is_dir() and f.name.startswith('profile_'):
105 105 profiles.append(f.name.split('_', 1)[-1])
106 106 return profiles
107 107
108 108
109 109 def list_bundled_profiles():
110 110 """list profiles that are bundled with IPython."""
111 111 path = os.path.join(get_ipython_package_dir(), u'core', u'profile')
112 112 profiles = []
113 113
114 114 # for python 3.6+ rewrite to: with os.scandir(path) as dirlist:
115 115 files = os.scandir(path)
116 116 for profile in files:
117 117 if profile.is_dir() and profile.name != "__pycache__":
118 118 profiles.append(profile.name)
119 119 return profiles
120 120
121 121
122 122 class ProfileLocate(BaseIPythonApplication):
123 123 description = """print the path to an IPython profile dir"""
124 124
125 125 def parse_command_line(self, argv=None):
126 126 super(ProfileLocate, self).parse_command_line(argv)
127 127 if self.extra_args:
128 128 self.profile = self.extra_args[0]
129 129
130 130 def start(self):
131 131 print(self.profile_dir.location)
132 132
133 133
134 134 class ProfileList(Application):
135 135 name = u'ipython-profile'
136 136 description = list_help
137 137 examples = _list_examples
138 138
139 139 aliases = Dict({
140 140 'ipython-dir' : 'ProfileList.ipython_dir',
141 141 'log-level' : 'Application.log_level',
142 142 })
143 143 flags = Dict(dict(
144 144 debug = ({'Application' : {'log_level' : 0}},
145 145 "Set Application.log_level to 0, maximizing log output."
146 146 )
147 147 ))
148 148
149 149 ipython_dir = Unicode(get_ipython_dir(),
150 150 help="""
151 151 The name of the IPython directory. This directory is used for logging
152 152 configuration (through profiles), history storage, etc. The default
153 153 is usually $HOME/.ipython. This options can also be specified through
154 154 the environment variable IPYTHONDIR.
155 155 """
156 156 ).tag(config=True)
157 157
158 158
159 159 def _print_profiles(self, profiles):
160 160 """print list of profiles, indented."""
161 161 for profile in profiles:
162 162 print(' %s' % profile)
163 163
164 164 def list_profile_dirs(self):
165 165 profiles = list_bundled_profiles()
166 166 if profiles:
167 167 print()
168 168 print("Available profiles in IPython:")
169 169 self._print_profiles(profiles)
170 170 print()
171 171 print(" The first request for a bundled profile will copy it")
172 172 print(" into your IPython directory (%s)," % self.ipython_dir)
173 173 print(" where you can customize it.")
174 174
175 175 profiles = list_profiles_in(self.ipython_dir)
176 176 if profiles:
177 177 print()
178 178 print("Available profiles in %s:" % self.ipython_dir)
179 179 self._print_profiles(profiles)
180 180
181 181 profiles = list_profiles_in(os.getcwd())
182 182 if profiles:
183 183 print()
184 print("Available profiles in current directory (%s):" % os.getcwd())
185 self._print_profiles(profiles)
186
184 print(
185 "Profiles from CWD have been removed for security reason, see CVE-2022-21699:"
186 )
187
187 188 print()
188 189 print("To use any of the above profiles, start IPython with:")
189 190 print(" ipython --profile=<name>")
190 191 print()
191 192
192 193 def start(self):
193 194 self.list_profile_dirs()
194 195
195 196
196 197 create_flags = {}
197 198 create_flags.update(base_flags)
198 199 # don't include '--init' flag, which implies running profile create in other apps
199 200 create_flags.pop('init')
200 201 create_flags['reset'] = ({'ProfileCreate': {'overwrite' : True}},
201 202 "reset config files in this profile to the defaults.")
202 203 create_flags['parallel'] = ({'ProfileCreate': {'parallel' : True}},
203 204 "Include the config files for parallel "
204 205 "computing apps (ipengine, ipcontroller, etc.)")
205 206
206 207
207 208 class ProfileCreate(BaseIPythonApplication):
208 209 name = u'ipython-profile'
209 210 description = create_help
210 211 examples = _create_examples
211 212 auto_create = Bool(True)
212 213 def _log_format_default(self):
213 214 return "[%(name)s] %(message)s"
214 215
215 216 def _copy_config_files_default(self):
216 217 return True
217 218
218 219 parallel = Bool(False,
219 220 help="whether to include parallel computing config files"
220 221 ).tag(config=True)
221 222
222 223 @observe('parallel')
223 224 def _parallel_changed(self, change):
224 225 parallel_files = [ 'ipcontroller_config.py',
225 226 'ipengine_config.py',
226 227 'ipcluster_config.py'
227 228 ]
228 229 if change['new']:
229 230 for cf in parallel_files:
230 231 self.config_files.append(cf)
231 232 else:
232 233 for cf in parallel_files:
233 234 if cf in self.config_files:
234 235 self.config_files.remove(cf)
235 236
236 237 def parse_command_line(self, argv):
237 238 super(ProfileCreate, self).parse_command_line(argv)
238 239 # accept positional arg as profile name
239 240 if self.extra_args:
240 241 self.profile = self.extra_args[0]
241 242
242 243 flags = Dict(create_flags)
243 244
244 245 classes = [ProfileDir]
245 246
246 247 def _import_app(self, app_path):
247 248 """import an app class"""
248 249 app = None
249 250 name = app_path.rsplit('.', 1)[-1]
250 251 try:
251 252 app = import_item(app_path)
252 253 except ImportError:
253 254 self.log.info("Couldn't import %s, config file will be excluded", name)
254 255 except Exception:
255 256 self.log.warning('Unexpected error importing %s', name, exc_info=True)
256 257 return app
257 258
258 259 def init_config_files(self):
259 260 super(ProfileCreate, self).init_config_files()
260 261 # use local imports, since these classes may import from here
261 262 from IPython.terminal.ipapp import TerminalIPythonApp
262 263 apps = [TerminalIPythonApp]
263 264 for app_path in (
264 265 'ipykernel.kernelapp.IPKernelApp',
265 266 ):
266 267 app = self._import_app(app_path)
267 268 if app is not None:
268 269 apps.append(app)
269 270 if self.parallel:
270 271 from ipyparallel.apps.ipcontrollerapp import IPControllerApp
271 272 from ipyparallel.apps.ipengineapp import IPEngineApp
272 273 from ipyparallel.apps.ipclusterapp import IPClusterStart
273 274 apps.extend([
274 275 IPControllerApp,
275 276 IPEngineApp,
276 277 IPClusterStart,
277 278 ])
278 279 for App in apps:
279 280 app = App()
280 281 app.config.update(self.config)
281 282 app.log = self.log
282 283 app.overwrite = self.overwrite
283 284 app.copy_config_files=True
284 285 app.ipython_dir=self.ipython_dir
285 286 app.profile_dir=self.profile_dir
286 287 app.init_config_files()
287 288
288 289 def stage_default_config_file(self):
289 290 pass
290 291
291 292
292 293 class ProfileApp(Application):
293 294 name = u'ipython profile'
294 295 description = profile_help
295 296 examples = _main_examples
296 297
297 298 subcommands = Dict(dict(
298 299 create = (ProfileCreate, ProfileCreate.description.splitlines()[0]),
299 300 list = (ProfileList, ProfileList.description.splitlines()[0]),
300 301 locate = (ProfileLocate, ProfileLocate.description.splitlines()[0]),
301 302 ))
302 303
303 304 def start(self):
304 305 if self.subapp is None:
305 306 print("No subcommand specified. Must specify one of: %s"%(self.subcommands.keys()))
306 307 print()
307 308 self.print_description()
308 309 self.print_subcommands()
309 310 self.exit(1)
310 311 else:
311 312 return self.subapp.start()
@@ -1,223 +1,223 b''
1 1 # encoding: utf-8
2 2 """An object for managing IPython profile directories."""
3 3
4 4 # Copyright (c) IPython Development Team.
5 5 # Distributed under the terms of the Modified BSD License.
6 6
7 7 import os
8 8 import shutil
9 9 import errno
10 10
11 11 from traitlets.config.configurable import LoggingConfigurable
12 12 from ..paths import get_ipython_package_dir
13 13 from ..utils.path import expand_path, ensure_dir_exists
14 14 from traitlets import Unicode, Bool, observe
15 15
16 16 #-----------------------------------------------------------------------------
17 17 # Module errors
18 18 #-----------------------------------------------------------------------------
19 19
20 20 class ProfileDirError(Exception):
21 21 pass
22 22
23 23
24 24 #-----------------------------------------------------------------------------
25 25 # Class for managing profile directories
26 26 #-----------------------------------------------------------------------------
27 27
28 28 class ProfileDir(LoggingConfigurable):
29 29 """An object to manage the profile directory and its resources.
30 30
31 31 The profile directory is used by all IPython applications, to manage
32 32 configuration, logging and security.
33 33
34 34 This object knows how to find, create and manage these directories. This
35 35 should be used by any code that wants to handle profiles.
36 36 """
37 37
38 38 security_dir_name = Unicode('security')
39 39 log_dir_name = Unicode('log')
40 40 startup_dir_name = Unicode('startup')
41 41 pid_dir_name = Unicode('pid')
42 42 static_dir_name = Unicode('static')
43 43 security_dir = Unicode(u'')
44 44 log_dir = Unicode(u'')
45 45 startup_dir = Unicode(u'')
46 46 pid_dir = Unicode(u'')
47 47 static_dir = Unicode(u'')
48 48
49 49 location = Unicode(u'',
50 50 help="""Set the profile location directly. This overrides the logic used by the
51 51 `profile` option.""",
52 52 ).tag(config=True)
53 53
54 54 _location_isset = Bool(False) # flag for detecting multiply set location
55 55 @observe('location')
56 56 def _location_changed(self, change):
57 57 if self._location_isset:
58 58 raise RuntimeError("Cannot set profile location more than once.")
59 59 self._location_isset = True
60 60 new = change['new']
61 61 ensure_dir_exists(new)
62 62
63 63 # ensure config files exist:
64 64 self.security_dir = os.path.join(new, self.security_dir_name)
65 65 self.log_dir = os.path.join(new, self.log_dir_name)
66 66 self.startup_dir = os.path.join(new, self.startup_dir_name)
67 67 self.pid_dir = os.path.join(new, self.pid_dir_name)
68 68 self.static_dir = os.path.join(new, self.static_dir_name)
69 69 self.check_dirs()
70 70
71 71 def _mkdir(self, path, mode=None):
72 72 """ensure a directory exists at a given path
73 73
74 74 This is a version of os.mkdir, with the following differences:
75 75
76 76 - returns True if it created the directory, False otherwise
77 77 - ignores EEXIST, protecting against race conditions where
78 78 the dir may have been created in between the check and
79 79 the creation
80 80 - sets permissions if requested and the dir already exists
81 81 """
82 82 if os.path.exists(path):
83 83 if mode and os.stat(path).st_mode != mode:
84 84 try:
85 85 os.chmod(path, mode)
86 86 except OSError:
87 87 self.log.warning(
88 88 "Could not set permissions on %s",
89 89 path
90 90 )
91 91 return False
92 92 try:
93 93 if mode:
94 94 os.mkdir(path, mode)
95 95 else:
96 96 os.mkdir(path)
97 97 except OSError as e:
98 98 if e.errno == errno.EEXIST:
99 99 return False
100 100 else:
101 101 raise
102 102
103 103 return True
104 104
105 105 @observe('log_dir')
106 106 def check_log_dir(self, change=None):
107 107 self._mkdir(self.log_dir)
108 108
109 109 @observe('startup_dir')
110 110 def check_startup_dir(self, change=None):
111 111 self._mkdir(self.startup_dir)
112 112
113 113 readme = os.path.join(self.startup_dir, 'README')
114 114 src = os.path.join(get_ipython_package_dir(), u'core', u'profile', u'README_STARTUP')
115 115
116 116 if not os.path.exists(src):
117 117 self.log.warning("Could not copy README_STARTUP to startup dir. Source file %s does not exist.", src)
118 118
119 119 if os.path.exists(src) and not os.path.exists(readme):
120 120 shutil.copy(src, readme)
121 121
122 122 @observe('security_dir')
123 123 def check_security_dir(self, change=None):
124 124 self._mkdir(self.security_dir, 0o40700)
125 125
126 126 @observe('pid_dir')
127 127 def check_pid_dir(self, change=None):
128 128 self._mkdir(self.pid_dir, 0o40700)
129 129
130 130 def check_dirs(self):
131 131 self.check_security_dir()
132 132 self.check_log_dir()
133 133 self.check_pid_dir()
134 134 self.check_startup_dir()
135 135
136 136 def copy_config_file(self, config_file, path=None, overwrite=False):
137 137 """Copy a default config file into the active profile directory.
138 138
139 139 Default configuration files are kept in :mod:`IPython.core.profile`.
140 140 This function moves these from that location to the working profile
141 141 directory.
142 142 """
143 143 dst = os.path.join(self.location, config_file)
144 144 if os.path.isfile(dst) and not overwrite:
145 145 return False
146 146 if path is None:
147 147 path = os.path.join(get_ipython_package_dir(), u'core', u'profile', u'default')
148 148 src = os.path.join(path, config_file)
149 149 shutil.copy(src, dst)
150 150 return True
151 151
152 152 @classmethod
153 153 def create_profile_dir(cls, profile_dir, config=None):
154 154 """Create a new profile directory given a full path.
155 155
156 156 Parameters
157 157 ----------
158 158 profile_dir : str
159 159 The full path to the profile directory. If it does exist, it will
160 160 be used. If not, it will be created.
161 161 """
162 162 return cls(location=profile_dir, config=config)
163 163
164 164 @classmethod
165 165 def create_profile_dir_by_name(cls, path, name=u'default', config=None):
166 166 """Create a profile dir by profile name and path.
167 167
168 168 Parameters
169 169 ----------
170 170 path : unicode
171 171 The path (directory) to put the profile directory in.
172 172 name : unicode
173 173 The name of the profile. The name of the profile directory will
174 174 be "profile_<profile>".
175 175 """
176 176 if not os.path.isdir(path):
177 177 raise ProfileDirError('Directory not found: %s' % path)
178 178 profile_dir = os.path.join(path, u'profile_' + name)
179 179 return cls(location=profile_dir, config=config)
180 180
181 181 @classmethod
182 182 def find_profile_dir_by_name(cls, ipython_dir, name=u'default', config=None):
183 183 """Find an existing profile dir by profile name, return its ProfileDir.
184 184
185 185 This searches through a sequence of paths for a profile dir. If it
186 186 is not found, a :class:`ProfileDirError` exception will be raised.
187 187
188 188 The search path algorithm is:
189 1. ``os.getcwd()``
189 1. ``os.getcwd()`` # removed for security reason.
190 190 2. ``ipython_dir``
191 191
192 192 Parameters
193 193 ----------
194 194 ipython_dir : unicode or str
195 195 The IPython directory to use.
196 196 name : unicode or str
197 197 The name of the profile. The name of the profile directory
198 198 will be "profile_<profile>".
199 199 """
200 200 dirname = u'profile_' + name
201 paths = [os.getcwd(), ipython_dir]
201 paths = [ipython_dir]
202 202 for p in paths:
203 203 profile_dir = os.path.join(p, dirname)
204 204 if os.path.isdir(profile_dir):
205 205 return cls(location=profile_dir, config=config)
206 206 else:
207 207 raise ProfileDirError('Profile directory not found in paths: %s' % dirname)
208 208
209 209 @classmethod
210 210 def find_profile_dir(cls, profile_dir, config=None):
211 211 """Find/create a profile dir and return its ProfileDir.
212 212
213 213 This will create the profile directory if it doesn't exist.
214 214
215 215 Parameters
216 216 ----------
217 217 profile_dir : unicode or str
218 218 The path of the profile directory.
219 219 """
220 220 profile_dir = expand_path(profile_dir)
221 221 if not os.path.isdir(profile_dir):
222 222 raise ProfileDirError('Profile directory not found: %s' % profile_dir)
223 223 return cls(location=profile_dir, config=config)
@@ -1,1079 +1,1087 b''
1 1 ============
2 2 7.x Series
3 3 ============
4 4
5 =======
6 .. _version 7.16.3:
7
8 IPython 7.16.3 (CVE-2022-21699)
9 ===============================
10
11 Fixed CVE-2022-21699, see IPython 8.0.1 release notes for informations.
12
5 13 .. _version 716:
6 14
7 15 IPython 7.16.1, 7.16.2
8 16 ======================
9 17
10 18 IPython 7.16.1 was release immediately after 7.16.0 to fix a conda packaging issue.
11 19 The source is identical to 7.16.0 but the file permissions in the tar are different.
12 20
13 21 IPython 7.16.2 pins jedi dependency to "<=0.17.2" which should prevent some
14 22 issues for users still on python 3.6. This may not be sufficient as pip may
15 23 still allow to downgrade IPython.
16 24
17 25 Compatibility with Jedi > 0.17.2 was not added as this would have meant bumping
18 26 the minimal version to >0.16.
19 27
20 28 IPython 7.16
21 29 ============
22 30
23 31
24 32 The default traceback mode will now skip frames that are marked with
25 33 ``__tracebackhide__ = True`` and show how many traceback frames have been
26 34 skipped. This can be toggled by using :magic:`xmode` with the ``--show`` or
27 35 ``--hide`` attribute. It will have no effect on non verbose traceback modes.
28 36
29 37 The ipython debugger also now understands ``__tracebackhide__`` as well and will
30 38 skip hidden frames when displaying. Movement up and down the stack will skip the
31 39 hidden frames and will show how many frames were hidden. Internal IPython frames
32 40 are also now hidden by default. The behavior can be changed with the
33 41 ``skip_hidden`` while in the debugger, command and accepts "yes", "no", "true"
34 42 and "false" case insensitive parameters.
35 43
36 44
37 45 Misc Noticeable changes:
38 46 ------------------------
39 47
40 48 - Exceptions are now (re)raised when running notebooks via the :magic:`%run`, helping to catch issues in workflows and
41 49 pipelines. :ghpull:`12301`
42 50 - Fix inputhook for qt 5.15.0 :ghpull:`12355`
43 51 - Fix wx inputhook :ghpull:`12375`
44 52 - Add handling for malformed pathext env var (Windows) :ghpull:`12367`
45 53 - use $SHELL in system_piped :ghpull:`12360` for uniform behavior with
46 54 ipykernel.
47 55
48 56 Reproducible Build
49 57 ------------------
50 58
51 59 IPython 7.15 reproducible build did not work, so we try again this month
52 60 :ghpull:`12358`.
53 61
54 62
55 63 API Changes
56 64 -----------
57 65
58 66 Change of API and exposed objects automatically detected using `frappuccino
59 67 <https://pypi.org/project/frappuccino/>`_ (still in beta):
60 68
61 69
62 70 The following items are new and mostly related to understanding ``__tracebackbhide__``::
63 71
64 72 + IPython.core.debugger.Pdb.do_down(self, arg)
65 73 + IPython.core.debugger.Pdb.do_skip_hidden(self, arg)
66 74 + IPython.core.debugger.Pdb.do_up(self, arg)
67 75 + IPython.core.debugger.Pdb.hidden_frames(self, stack)
68 76 + IPython.core.debugger.Pdb.stop_here(self, frame)
69 77
70 78
71 79 The following items have been removed::
72 80
73 81 - IPython.core.debugger.Pdb.new_do_down
74 82 - IPython.core.debugger.Pdb.new_do_up
75 83
76 84 Those were implementation details.
77 85
78 86
79 87 .. _version 715:
80 88
81 89 IPython 7.15
82 90 ============
83 91
84 92 IPython 7.15 brings a number of bug fixes and user facing improvements.
85 93
86 94 Misc Noticeable changes:
87 95 ------------------------
88 96
89 97 - Long completion name have better elision in terminal :ghpull:`12284`
90 98 - I've started to test on Python 3.9 :ghpull:`12307` and fix some errors.
91 99 - Hi DPI scaling of figures when using qt eventloop :ghpull:`12314`
92 100 - Document the ability to have systemwide configuration for IPython.
93 101 :ghpull:`12328`
94 102 - Fix issues with input autoformatting :ghpull:`12336`
95 103 - ``IPython.core.debugger.Pdb`` is now interruptible (:ghpull:`12168`, in 7.14
96 104 but forgotten in release notes)
97 105 - Video HTML attributes (:ghpull:`12212`, in 7.14 but forgotten in release
98 106 notes)
99 107
100 108 Reproducible Build
101 109 ------------------
102 110
103 111 Starting with IPython 7.15, I am attempting to provide reproducible builds,
104 112 that is to say you should be able from the source tree to generate an sdist
105 113 and wheel that are identical byte for byte with the publish version on PyPI.
106 114
107 115 I've only tested on a couple of machines so far and the process is relatively
108 116 straightforward, so this mean that IPython not only have a deterministic build
109 117 process, but also I have either removed, or put under control all effects of
110 118 the build environments on the final artifact. I encourage you to attempt the
111 119 build process on your machine as documented in :ref:`core_developer_guide`
112 120 and let me know if you do not obtain an identical artifact.
113 121
114 122 While reproducible builds is critical to check that the supply chain of (open
115 123 source) software has not been compromised, it can also help to speedup many
116 124 of the build processes in large environment (conda, apt...) by allowing
117 125 better caching of intermediate build steps.
118 126
119 127 Learn more on `<https://reproducible-builds.org/>`_. `Reflections on trusting
120 128 trust <https://dl.acm.org/doi/10.1145/358198.358210>`_ is also one of the
121 129 cornerstone and recommended reads on this subject.
122 130
123 131 .. note::
124 132
125 133 The build commit from which the sdist is generated is also `signed
126 134 <https://en.wikipedia.org/wiki/Digital_signature>`_, so you should be able to
127 135 check it has not been compromised, and the git repository is a `merkle-tree
128 136 <https://en.wikipedia.org/wiki/Merkle_tree>`_, you can check the consistency
129 137 with `git-fsck <https://git-scm.com/docs/git-fsck>`_ which you likely `want
130 138 to enable by default
131 139 <https://gist.github.com/mbbx6spp/14b86437e794bffb4120>`_.
132 140
133 141 NEP29: Last version to support Python 3.6
134 142 -----------------------------------------
135 143
136 144 IPython 7.15 will be the Last IPython version to officially support Python
137 145 3.6, as stated by `NumPy Enhancement Proposal 29
138 146 <https://numpy.org/neps/nep-0029-deprecation_policy.html>`_. Starting with
139 147 next minor version of IPython I may stop testing on Python 3.6 and may stop
140 148 publishing release artifacts that install on Python 3.6
141 149
142 150 Highlighted features
143 151 --------------------
144 152
145 153 Highlighted features are not new, but seem to not be widely known, this
146 154 section will help you discover in more narrative form what you can do with
147 155 IPython.
148 156
149 157 Increase Tab Completion Menu Height
150 158 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
151 159
152 160 In terminal IPython it is possible to increase the hight of the tab-completion
153 161 menu. To do so set the value of
154 162 :configtrait:`TerminalInteractiveShell.space_for_menu`, this will reserve more
155 163 space at the bottom of the screen for various kind of menus in IPython including
156 164 tab completion and searching in history.
157 165
158 166 Autoformat Code in the terminal
159 167 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
160 168
161 169 If you have a preferred code formatter, you can configure IPython to
162 170 reformat your code. Set the value of
163 171 :configtrait:`TerminalInteractiveShell.autoformatter` to for example ``'black'``
164 172 and IPython will auto format your code when possible.
165 173
166 174
167 175 .. _version 714:
168 176
169 177 IPython 7.14
170 178 ============
171 179
172 180 IPython 7.14 is a minor release that fix a couple of bugs and prepare
173 181 compatibility with new or future versions of some libraries.
174 182
175 183 Important changes:
176 184 ------------------
177 185
178 186 - Fix compatibility with Sphinx 3+ :ghpull:`12235`
179 187 - Remove deprecated matplotlib parameter usage, compatibility with matplotlib
180 188 3.3+ :`122250`
181 189
182 190 Misc Changes
183 191 ------------
184 192
185 193 - set ``.py`` extension when editing current buffer in vi/emacs. :ghpull:`12167`
186 194 - support for unicode identifiers in ``?``/``??`` :ghpull:`12208`
187 195 - add extra options to the ``Video`` Rich objects :ghpull:`12212`
188 196 - add pretty-printing to ``SimpleNamespace`` :ghpull:`12230`
189 197
190 198 IPython.core.debugger.Pdb is now interruptible
191 199 ----------------------------------------------
192 200
193 201 A ``KeyboardInterrupt`` will now interrupt IPython's extended debugger, in order to make Jupyter able to interrupt it. (:ghpull:`12168`)
194 202
195 203 Video HTML attributes
196 204 ---------------------
197 205
198 206 Add an option to `IPython.display.Video` to change the attributes of the HTML display of the video (:ghpull:`12212`)
199 207
200 208
201 209 Pending deprecated imports
202 210 --------------------------
203 211
204 212 Many object present in ``IPython.core.display`` are there for internal use only,
205 213 and should already been imported from ``IPython.display`` by users and external
206 214 libraries. Trying to import those from ``IPython.core.display`` is still possible
207 215 but will trigger a
208 216 deprecation warning in later versions of IPython and will become errors in the
209 217 future.
210 218
211 219 This will simplify compatibility with other Python kernels (like Xeus-Python),
212 220 and simplify code base.
213 221
214 222
215 223
216 224
217 225 .. _version 713:
218 226
219 227 IPython 7.13
220 228 ============
221 229
222 230 IPython 7.13 is the final release of the 7.x branch since master is diverging
223 231 toward an 8.0. Exiting new features have already been merged in 8.0 and will
224 232 not be available on the 7.x branch. All the changes below have been backported
225 233 from the master branch.
226 234
227 235
228 236 - Fix inability to run PDB when inside an event loop :ghpull:`12141`
229 237 - Fix ability to interrupt some processes on windows :ghpull:`12137`
230 238 - Fix debugger shortcuts :ghpull:`12132`
231 239 - improve tab completion when inside a string by removing irrelevant elements :ghpull:`12128`
232 240 - Fix display of filename tab completion when the path is long :ghpull:`12122`
233 241 - Many removal of Python 2 specific code path :ghpull:`12110`
234 242 - displaying wav files do not require NumPy anymore, and is 5x to 30x faster :ghpull:`12113`
235 243
236 244 See the list of all closed issues and pull request on `github
237 245 <https://github.com/ipython/ipython/pulls?q=is%3Aclosed+milestone%3A7.13>`_.
238 246
239 247 .. _version 712:
240 248
241 249 IPython 7.12
242 250 ============
243 251
244 252 IPython 7.12 is a minor update that mostly brings code cleanup, removal of
245 253 longtime deprecated function and a couple update to documentation cleanup as well.
246 254
247 255 Notable changes are the following:
248 256
249 257 - Exit non-zero when ipython is given a file path to run that doesn't exist :ghpull:`12074`
250 258 - Test PR on ARM64 with Travis-CI :ghpull:`12073`
251 259 - Update CI to work with latest Pytest :ghpull:`12086`
252 260 - Add infrastructure to run ipykernel eventloop via trio :ghpull:`12097`
253 261 - Support git blame ignore revs :ghpull:`12091`
254 262 - Start multi-line ``__repr__`` s on their own line :ghpull:`12099`
255 263
256 264 .. _version 7111:
257 265
258 266 IPython 7.11.1
259 267 ==============
260 268
261 269 A couple of deprecated functions (no-op) have been reintroduces in py3compat as
262 270 Cython was still relying on them, and will be removed in a couple of versions.
263 271
264 272 .. _version 711:
265 273
266 274 IPython 7.11
267 275 ============
268 276
269 277 IPython 7.11 received a couple of compatibility fixes and code cleanup.
270 278
271 279 A number of function in the ``py3compat`` have been removed; a number of types
272 280 in the IPython code base are now non-ambiguous and now always ``unicode``
273 281 instead of ``Union[Unicode,bytes]``; many of the relevant code path have thus
274 282 been simplified/cleaned and types annotation added.
275 283
276 284 IPython support several verbosity level from exceptions. ``xmode plain`` now
277 285 support chained exceptions. :ghpull:`11999`
278 286
279 287 We are starting to remove ``shell=True`` in some usages of subprocess. While not directly
280 288 a security issue (as IPython is made to run arbitrary code anyway) it is not good
281 289 practice and we'd like to show the example. :ghissue:`12023`. This discussion
282 290 was started by ``@mschwager`` thanks to a new auditing tool they are working on
283 291 with duo-labs (`dlint <https://github.com/duo-labs/dlint>`_).
284 292
285 293 Work around some bugs in Python 3.9 tokenizer :ghpull:`12057`
286 294
287 295 IPython will now print its version after a crash. :ghpull:`11986`
288 296
289 297 This is likely the last release from the 7.x series that will see new feature.
290 298 The master branch will soon accept large code changes and thrilling new
291 299 features; the 7.x branch will only start to accept critical bug fixes, and
292 300 update dependencies.
293 301
294 302 .. _version 7102:
295 303
296 304 IPython 7.10.2
297 305 ==============
298 306
299 307 IPython 7.10.2 fix a couple of extra incompatibility between IPython, ipdb,
300 308 asyncio and Prompt Toolkit 3.
301 309
302 310 .. _version 7101:
303 311
304 312 IPython 7.10.1
305 313 ==============
306 314
307 315 IPython 7.10.1 fix a couple of incompatibilities with Prompt toolkit 3 (please
308 316 update Prompt toolkit to 3.0.2 at least), and fixes some interaction with
309 317 headless IPython.
310 318
311 319 .. _version 7100:
312 320
313 321 IPython 7.10.0
314 322 ==============
315 323
316 324 IPython 7.10 is the first double digit minor release in the last decade, and
317 325 first since the release of IPython 1.0, previous double digit minor release was
318 326 in August 2009.
319 327
320 328 We've been trying to give you regular release on the last Friday of every month
321 329 for a guaranty of rapid access to bug fixes and new features.
322 330
323 331 Unlike the previous first few releases that have seen only a couple of code
324 332 changes, 7.10 bring a number of changes, new features and bugfixes.
325 333
326 334 Stop Support for Python 3.5 – Adopt NEP 29
327 335 ------------------------------------------
328 336
329 337 IPython has decided to follow the informational `NEP 29
330 338 <https://numpy.org/neps/nep-0029-deprecation_policy.html>`_ which layout a clear
331 339 policy as to which version of (C)Python and NumPy are supported.
332 340
333 341 We thus dropped support for Python 3.5, and cleaned up a number of code path
334 342 that were Python-version dependant. If you are on 3.5 or earlier pip should
335 343 automatically give you the latest compatible version of IPython so you do not
336 344 need to pin to a given version.
337 345
338 346 Support for Prompt Toolkit 3.0
339 347 ------------------------------
340 348
341 349 Prompt Toolkit 3.0 was release a week before IPython 7.10 and introduces a few
342 350 breaking changes. We believe IPython 7.10 should be compatible with both Prompt
343 351 Toolkit 2.x and 3.x, though it has not been extensively tested with 3.x so
344 352 please report any issues.
345 353
346 354
347 355 Prompt Rendering Performance improvements
348 356 -----------------------------------------
349 357
350 358 Pull Request :ghpull:`11933` introduced an optimisation in the prompt rendering
351 359 logic that should decrease the resource usage of IPython when using the
352 360 _default_ configuration but could potentially introduce a regression of
353 361 functionalities if you are using a custom prompt.
354 362
355 363 We know assume if you haven't changed the default keybindings that the prompt
356 364 **will not change** during the duration of your input – which is for example
357 365 not true when using vi insert mode that switches between `[ins]` and `[nor]`
358 366 for the current mode.
359 367
360 368 If you are experiencing any issue let us know.
361 369
362 370 Code autoformatting
363 371 -------------------
364 372
365 373 The IPython terminal can now auto format your code just before entering a new
366 374 line or executing a command. To do so use the
367 375 ``--TerminalInteractiveShell.autoformatter`` option and set it to ``'black'``;
368 376 if black is installed IPython will use black to format your code when possible.
369 377
370 378 IPython cannot always properly format your code; in particular it will
371 379 auto formatting with *black* will only work if:
372 380
373 381 - Your code does not contains magics or special python syntax.
374 382
375 383 - There is no code after your cursor.
376 384
377 385 The Black API is also still in motion; so this may not work with all versions of
378 386 black.
379 387
380 388 It should be possible to register custom formatter, though the API is till in
381 389 flux.
382 390
383 391 Arbitrary Mimetypes Handing in Terminal (Aka inline images in terminal)
384 392 -----------------------------------------------------------------------
385 393
386 394 When using IPython terminal it is now possible to register function to handle
387 395 arbitrary mimetypes. While rendering non-text based representation was possible in
388 396 many jupyter frontend; it was not possible in terminal IPython, as usually
389 397 terminal are limited to displaying text. As many terminal these days provide
390 398 escape sequences to display non-text; bringing this loved feature to IPython CLI
391 399 made a lot of sens. This functionality will not only allow inline images; but
392 400 allow opening of external program; for example ``mplayer`` to "display" sound
393 401 files.
394 402
395 403 So far only the hooks necessary for this are in place, but no default mime
396 404 renderers added; so inline images will only be available via extensions. We will
397 405 progressively enable these features by default in the next few releases, and
398 406 contribution is welcomed.
399 407
400 408 We welcome any feedback on the API. See :ref:`shell_mimerenderer` for more
401 409 informations.
402 410
403 411 This is originally based on work form in :ghpull:`10610` from @stephanh42
404 412 started over two years ago, and still a lot need to be done.
405 413
406 414 MISC
407 415 ----
408 416
409 417 - Completions can define their own ordering :ghpull:`11855`
410 418 - Enable Plotting in the same cell than the one that import matplotlib
411 419 :ghpull:`11916`
412 420 - Allow to store and restore multiple variables at once :ghpull:`11930`
413 421
414 422 You can see `all pull-requests <https://github.com/ipython/ipython/pulls?q=is%3Apr+milestone%3A7.10+is%3Aclosed>`_ for this release.
415 423
416 424 API Changes
417 425 -----------
418 426
419 427 Change of API and exposed objects automatically detected using `frappuccino <https://pypi.org/project/frappuccino/>`_ (still in beta):
420 428
421 429 The following items are new in IPython 7.10::
422 430
423 431 + IPython.terminal.shortcuts.reformat_text_before_cursor(buffer, document, shell)
424 432 + IPython.terminal.interactiveshell.PTK3
425 433 + IPython.terminal.interactiveshell.black_reformat_handler(text_before_cursor)
426 434 + IPython.terminal.prompts.RichPromptDisplayHook.write_format_data(self, format_dict, md_dict='None')
427 435
428 436 The following items have been removed in 7.10::
429 437
430 438 - IPython.lib.pretty.DICT_IS_ORDERED
431 439
432 440 The following signatures differ between versions::
433 441
434 442 - IPython.extensions.storemagic.restore_aliases(ip)
435 443 + IPython.extensions.storemagic.restore_aliases(ip, alias='None')
436 444
437 445 Special Thanks
438 446 --------------
439 447
440 448 - @stephanh42 who started the work on inline images in terminal 2 years ago
441 449 - @augustogoulart who spent a lot of time triaging issues and responding to
442 450 users.
443 451 - @con-f-use who is my (@Carreau) first sponsor on GitHub, as a reminder if you
444 452 like IPython, Jupyter and many other library of the SciPy stack you can
445 453 donate to numfocus.org non profit
446 454
447 455 .. _version 790:
448 456
449 457 IPython 7.9.0
450 458 =============
451 459
452 460 IPython 7.9 is a small release with a couple of improvement and bug fixes.
453 461
454 462 - Xterm terminal title should be restored on exit :ghpull:`11910`
455 463 - special variables ``_``,``__``, ``___`` are not set anymore when cache size
456 464 is 0 or less. :ghpull:`11877`
457 465 - Autoreload should have regained some speed by using a new heuristic logic to
458 466 find all objects needing reload. This should avoid large objects traversal
459 467 like pandas dataframes. :ghpull:`11876`
460 468 - Get ready for Python 4. :ghpull:`11874`
461 469 - `%env` Magic now has heuristic to hide potentially sensitive values :ghpull:`11896`
462 470
463 471 This is a small release despite a number of Pull Request Pending that need to
464 472 be reviewed/worked on. Many of the core developers have been busy outside of
465 473 IPython/Jupyter and we thanks all contributor for their patience; we'll work on
466 474 these as soon as we have time.
467 475
468 476
469 477 .. _version780:
470 478
471 479 IPython 7.8.0
472 480 =============
473 481
474 482 IPython 7.8.0 contain a few bugfix and 2 new APIs:
475 483
476 484 - Enable changing the font color for LaTeX rendering :ghpull:`11840`
477 485 - and Re-Expose some PDB API (see below)
478 486
479 487 Expose Pdb API
480 488 --------------
481 489
482 490 Expose the built-in ``pdb.Pdb`` API. ``Pdb`` constructor arguments are generically
483 491 exposed, regardless of python version.
484 492 Newly exposed arguments:
485 493
486 494 - ``skip`` - Python 3.1+
487 495 - ``nosiginnt`` - Python 3.2+
488 496 - ``readrc`` - Python 3.6+
489 497
490 498 Try it out::
491 499
492 500 from IPython.terminal.debugger import TerminalPdb
493 501 pdb = TerminalPdb(skip=["skipthismodule"])
494 502
495 503
496 504 See :ghpull:`11840`
497 505
498 506 .. _version770:
499 507
500 508 IPython 7.7.0
501 509 =============
502 510
503 511 IPython 7.7.0 contain multiple bug fixes and documentation updates; Here are a
504 512 few of the outstanding issue fixed:
505 513
506 514 - Fix a bug introduced in 7.6 where the ``%matplotlib`` magic would fail on
507 515 previously acceptable arguments :ghpull:`11814`.
508 516 - Fix the manage location on freebsd :ghpull:`11808`.
509 517 - Fix error message about aliases after ``%reset`` call in ipykernel
510 518 :ghpull:`11806`
511 519 - Fix Duplication completions in emacs :ghpull:`11803`
512 520
513 521 We are planning to adopt `NEP29 <https://github.com/numpy/numpy/pull/14086>`_
514 522 (still currently in draft) which may make this minor version of IPython the
515 523 last one to support Python 3.5 and will make the code base more aggressive
516 524 toward removing compatibility with older versions of Python.
517 525
518 526 GitHub now support to give only "Triage" permissions to users; if you'd like to
519 527 help close stale issues and labels issues please reach to us with your GitHub
520 528 Username and we'll add you to the triage team. It is a great way to start
521 529 contributing and a path toward getting commit rights.
522 530
523 531 .. _version761:
524 532
525 533 IPython 7.6.1
526 534 =============
527 535
528 536 IPython 7.6.1 contain a critical bugfix in the ``%timeit`` magic, which would
529 537 crash on some inputs as a side effect of :ghpull:`11716`. See :ghpull:`11812`
530 538
531 539
532 540 .. _whatsnew760:
533 541
534 542 IPython 7.6.0
535 543 =============
536 544
537 545 IPython 7.6.0 contains a couple of bug fixes and number of small features
538 546 additions as well as some compatibility with the current development version of
539 547 Python 3.8.
540 548
541 549 - Add a ``-l`` option to :magic:`psearch` to list the available search
542 550 types. :ghpull:`11672`
543 551 - Support ``PathLike`` for ``DisplayObject`` and ``Image``. :ghpull:`11764`
544 552 - Configurability of timeout in the test suite for slow platforms.
545 553 :ghpull:`11756`
546 554 - Accept any casing for matplotlib backend. :ghpull:`121748`
547 555 - Properly skip test that requires numpy to be installed :ghpull:`11723`
548 556 - More support for Python 3.8 and positional only arguments (pep570)
549 557 :ghpull:`11720`
550 558 - Unicode names for the completion are loaded lazily on first use which
551 559 should decrease startup time. :ghpull:`11693`
552 560 - Autoreload now update the types of reloaded objects; this for example allow
553 561 pickling of reloaded objects. :ghpull:`11644`
554 562 - Fix a bug where ``%%time`` magic would suppress cell output. :ghpull:`11716`
555 563
556 564
557 565 Prepare migration to pytest (instead of nose) for testing
558 566 ---------------------------------------------------------
559 567
560 568 Most of the work between 7.5 and 7.6 was to prepare the migration from our
561 569 testing framework to pytest. Most of the test suite should now work by simply
562 570 issuing ``pytest`` from the root of the repository.
563 571
564 572 The migration to pytest is just at its beginning. Many of our test still rely
565 573 on IPython-specific plugins for nose using pytest (doctest using IPython syntax
566 574 is one example of this where test appear as "passing", while no code has been
567 575 ran). Many test also need to be updated like ``yield-test`` to be properly
568 576 parametrized tests.
569 577
570 578 Migration to pytest allowed me to discover a number of issues in our test
571 579 suite; which was hiding a number of subtle issues – or not actually running
572 580 some of the tests in our test suite – I have thus corrected many of those; like
573 581 improperly closed resources; or used of deprecated features. I also made use of
574 582 the ``pytest --durations=...`` to find some of our slowest test and speed them
575 583 up (our test suite can now be up to 10% faster). Pytest as also a variety of
576 584 plugins and flags which will make the code quality of IPython and the testing
577 585 experience better.
578 586
579 587 Misc
580 588 ----
581 589
582 590 We skipped the release of 7.6 at the end of May, but will attempt to get back
583 591 on schedule. We are starting to think about making introducing backward
584 592 incompatible change and start the 8.0 series.
585 593
586 594 Special Thanks to Gabriel (@gpotter2 on GitHub), who among other took care many
587 595 of the remaining task for 7.4 and 7.5, like updating the website.
588 596
589 597 .. _whatsnew750:
590 598
591 599 IPython 7.5.0
592 600 =============
593 601
594 602 IPython 7.5.0 consist mostly of bug-fixes, and documentation updates, with one
595 603 minor new feature. The `Audio` display element can now be assigned an element
596 604 id when displayed in browser. See :ghpull:`11670`
597 605
598 606 The major outstanding bug fix correct a change of behavior that was introduce
599 607 in 7.4.0 where some cell magics would not be able to access or modify global
600 608 scope when using the ``@needs_local_scope`` decorator. This was typically
601 609 encountered with the ``%%time`` and ``%%timeit`` magics. See :ghissue:`11659`
602 610 and :ghpull:`11698`.
603 611
604 612 .. _whatsnew740:
605 613
606 614 IPython 7.4.0
607 615 =============
608 616
609 617 Unicode name completions
610 618 ------------------------
611 619
612 620 Previously, we provided completion for a unicode name with its relative symbol.
613 621 With this, now IPython provides complete suggestions to unicode name symbols.
614 622
615 623 As on the PR, if user types ``\LAT<tab>``, IPython provides a list of
616 624 possible completions. In this case, it would be something like::
617 625
618 626 'LATIN CAPITAL LETTER A',
619 627 'LATIN CAPITAL LETTER B',
620 628 'LATIN CAPITAL LETTER C',
621 629 'LATIN CAPITAL LETTER D',
622 630 ....
623 631
624 632 This help to type unicode character that do not have short latex aliases, and
625 633 have long unicode names. for example ``Ν°``, ``\GREEK CAPITAL LETTER HETA``.
626 634
627 635 This feature was contributed by Luciana Marques :ghpull:`11583`.
628 636
629 637 Make audio normalization optional
630 638 ---------------------------------
631 639
632 640 Added 'normalize' argument to `IPython.display.Audio`. This argument applies
633 641 when audio data is given as an array of samples. The default of `normalize=True`
634 642 preserves prior behavior of normalizing the audio to the maximum possible range.
635 643 Setting to `False` disables normalization.
636 644
637 645
638 646 Miscellaneous
639 647 -------------
640 648
641 649 - Fix improper acceptation of ``return`` outside of functions. :ghpull:`11641`.
642 650 - Fixed PyQt 5.11 backwards incompatibility causing sip import failure.
643 651 :ghpull:`11613`.
644 652 - Fix Bug where ``type?`` would crash IPython. :ghpull:`1608`.
645 653 - Allow to apply ``@needs_local_scope`` to cell magics for convenience.
646 654 :ghpull:`11542`.
647 655
648 656 .. _whatsnew730:
649 657
650 658 IPython 7.3.0
651 659 =============
652 660
653 661 .. _whatsnew720:
654 662
655 663 IPython 7.3.0 bring several bug fixes and small improvements that you will
656 664 described bellow.
657 665
658 666 The biggest change to this release is the implementation of the ``%conda`` and
659 667 ``%pip`` magics, that will attempt to install packages in the **current
660 668 environment**. You may still need to restart your interpreter or kernel for the
661 669 change to be taken into account, but it should simplify installation of packages
662 670 into remote environment. Installing using pip/conda from the command line is
663 671 still the prefer method.
664 672
665 673 The ``%pip`` magic was already present, but was only printing a warning; now it
666 674 will actually forward commands to pip.
667 675
668 676 Misc bug fixes and improvements:
669 677
670 678 - Compatibility with Python 3.8.
671 679 - Do not expand shell variable in execution magics, and added the
672 680 ``no_var_expand`` decorator for magic requiring a similar functionality
673 681 :ghpull:`11516`
674 682 - Add ``%pip`` and ``%conda`` magic :ghpull:`11524`
675 683 - Re-initialize posix aliases after a ``%reset`` :ghpull:`11528`
676 684 - Allow the IPython command line to run ``*.ipynb`` files :ghpull:`11529`
677 685
678 686 IPython 7.2.0
679 687 =============
680 688
681 689 IPython 7.2.0 brings minor bugfixes, improvements, and new configuration options:
682 690
683 691 - Fix a bug preventing PySide2 GUI integration from working :ghpull:`11464`
684 692 - Run CI on Mac OS ! :ghpull:`11471`
685 693 - Fix IPython "Demo" mode. :ghpull:`11498`
686 694 - Fix ``%run`` magic with path in name :ghpull:`11499`
687 695 - Fix: add CWD to sys.path *after* stdlib :ghpull:`11502`
688 696 - Better rendering of signatures, especially long ones. :ghpull:`11505`
689 697 - Re-enable jedi by default if it's installed :ghpull:`11506`
690 698 - Add New ``minimal`` exception reporting mode (useful for educational purpose). See :ghpull:`11509`
691 699
692 700
693 701 Added ability to show subclasses when using pinfo and other utilities
694 702 ---------------------------------------------------------------------
695 703
696 704 When using ``?``/``??`` on a class, IPython will now list the first 10 subclasses.
697 705
698 706 Special Thanks to Chris Mentzel of the Moore Foundation for this feature. Chris
699 707 is one of the people who played a critical role in IPython/Jupyter getting
700 708 funding.
701 709
702 710 We are grateful for all the help Chris has given us over the years,
703 711 and we're now proud to have code contributed by Chris in IPython.
704 712
705 713 OSMagics.cd_force_quiet configuration option
706 714 --------------------------------------------
707 715
708 716 You can set this option to force the %cd magic to behave as if ``-q`` was passed:
709 717 ::
710 718
711 719 In [1]: cd /
712 720 /
713 721
714 722 In [2]: %config OSMagics.cd_force_quiet = True
715 723
716 724 In [3]: cd /tmp
717 725
718 726 In [4]:
719 727
720 728 See :ghpull:`11491`
721 729
722 730 In vi editing mode, whether the prompt includes the current vi mode can now be configured
723 731 -----------------------------------------------------------------------------------------
724 732
725 733 Set the ``TerminalInteractiveShell.prompt_includes_vi_mode`` to a boolean value
726 734 (default: True) to control this feature. See :ghpull:`11492`
727 735
728 736 .. _whatsnew710:
729 737
730 738 IPython 7.1.0
731 739 =============
732 740
733 741 IPython 7.1.0 is the first minor release after 7.0.0 and mostly brings fixes to
734 742 new features, internal refactoring, and fixes for regressions that happened during the 6.x->7.x
735 743 transition. It also brings **Compatibility with Python 3.7.1**, as we're
736 744 unwillingly relying on a bug in CPython.
737 745
738 746 New Core Dev:
739 747
740 748 - We welcome Jonathan Slenders to the commiters. Jonathan has done a fantastic
741 749 work on prompt_toolkit, and we'd like to recognise his impact by giving him
742 750 commit rights. :ghissue:`11397`
743 751
744 752 Notable Changes
745 753
746 754 - Major update of "latex to unicode" tab completion map (see below)
747 755
748 756 Notable New Features:
749 757
750 758 - Restore functionality and documentation of the **sphinx directive**, which
751 759 is now stricter (fail on error by daefault), has new configuration options,
752 760 has a brand new documentation page :ref:`ipython_directive` (which needs
753 761 some cleanup). It is also now *tested* so we hope to have less regressions.
754 762 :ghpull:`11402`
755 763
756 764 - ``IPython.display.Video`` now supports ``width`` and ``height`` arguments,
757 765 allowing a custom width and height to be set instead of using the video's
758 766 width and height. :ghpull:`11353`
759 767
760 768 - Warn when using ``HTML('<iframe>')`` instead of ``IFrame`` :ghpull:`11350`
761 769
762 770 - Allow Dynamic switching of editing mode between vi/emacs and show
763 771 normal/input mode in prompt when using vi. :ghpull:`11390`. Use ``%config
764 772 TerminalInteractiveShell.editing_mode = 'vi'`` or ``%config
765 773 TerminalInteractiveShell.editing_mode = 'emacs'`` to dynamically switch
766 774 between modes.
767 775
768 776
769 777 Notable Fixes:
770 778
771 779 - Fix entering of **multi-line blocks in terminal** IPython, and various
772 780 crashes in the new input transformation machinery :ghpull:`11354`,
773 781 :ghpull:`11356`, :ghpull:`11358`. These also fix a **Compatibility bug
774 782 with Python 3.7.1**.
775 783
776 784 - Fix moving through generator stack in ipdb :ghpull:`11266`
777 785
778 786 - %Magic command arguments now support quoting. :ghpull:`11330`
779 787
780 788 - Re-add ``rprint`` and ``rprinte`` aliases. :ghpull:`11331`
781 789
782 790 - Remove implicit dependency on ``ipython_genutils`` :ghpull:`11317`
783 791
784 792 - Make ``nonlocal`` raise ``SyntaxError`` instead of silently failing in async
785 793 mode. :ghpull:`11382`
786 794
787 795 - Fix mishandling of magics and ``= !`` assignment just after a dedent in
788 796 nested code blocks :ghpull:`11418`
789 797
790 798 - Fix instructions for custom shortcuts :ghpull:`11426`
791 799
792 800
793 801 Notable Internals improvements:
794 802
795 803 - Use of ``os.scandir`` (Python 3 only) to speed up some file system operations.
796 804 :ghpull:`11365`
797 805
798 806 - use ``perf_counter`` instead of ``clock`` for more precise
799 807 timing results with ``%time`` :ghpull:`11376`
800 808
801 809 Many thanks to all the contributors and in particular to ``bartskowron`` and
802 810 ``tonyfast`` who handled some pretty complicated bugs in the input machinery. We
803 811 had a number of first time contributors and maybe hacktoberfest participants that
804 812 made significant contributions and helped us free some time to focus on more
805 813 complicated bugs.
806 814
807 815 You
808 816 can see all the closed issues and Merged PR, new features and fixes `here
809 817 <https://github.com/ipython/ipython/issues?utf8=%E2%9C%93&q=+is%3Aclosed+milestone%3A7.1+>`_.
810 818
811 819 Unicode Completion update
812 820 -------------------------
813 821
814 822 In IPython 7.1 the Unicode completion map has been updated and synchronized with
815 823 the Julia language.
816 824
817 825 Added and removed character characters:
818 826
819 827 ``\jmath`` (``Θ·``), ``\\underleftrightarrow`` (U+034D, combining) have been
820 828 added, while ``\\textasciicaron`` have been removed
821 829
822 830 Some sequences have seen their prefix removed:
823 831
824 832 - 6 characters ``\text...<tab>`` should now be inputed with ``\...<tab>`` directly,
825 833 - 45 characters ``\Elz...<tab>`` should now be inputed with ``\...<tab>`` directly,
826 834 - 65 characters ``\B...<tab>`` should now be inputed with ``\...<tab>`` directly,
827 835 - 450 characters ``\m...<tab>`` should now be inputed with ``\...<tab>`` directly,
828 836
829 837 Some sequences have seen their prefix shortened:
830 838
831 839 - 5 characters ``\mitBbb...<tab>`` should now be inputed with ``\bbi...<tab>`` directly,
832 840 - 52 characters ``\mit...<tab>`` should now be inputed with ``\i...<tab>`` directly,
833 841 - 216 characters ``\mbfit...<tab>`` should now be inputed with ``\bi...<tab>`` directly,
834 842 - 222 characters ``\mbf...<tab>`` should now be inputed with ``\b...<tab>`` directly,
835 843
836 844 A couple of characters had their sequence simplified:
837 845
838 846 - ``Γ°``, type ``\dh<tab>``, instead of ``\eth<tab>``
839 847 - ``Δ§``, type ``\hbar<tab>``, instead of ``\Elzxh<tab>``
840 848 - ``ΙΈ``, type ``\ltphi<tab>``, instead of ``\textphi<tab>``
841 849 - ``Ο΄``, type ``\varTheta<tab>``, instead of ``\textTheta<tab>``
842 850 - ``ℇ``, type ``\eulermascheroni<tab>``, instead of ``\Eulerconst<tab>``
843 851 - ``β„Ž``, type ``\planck<tab>``, instead of ``\Planckconst<tab>``
844 852
845 853 - U+0336 (COMBINING LONG STROKE OVERLAY), type ``\strike<tab>``, instead of ``\Elzbar<tab>``.
846 854
847 855 A couple of sequences have been updated:
848 856
849 857 - ``\varepsilon`` now gives ``Ι›`` (GREEK SMALL LETTER EPSILON) instead of ``Ξ΅`` (GREEK LUNATE EPSILON SYMBOL),
850 858 - ``\underbar`` now gives U+0331 (COMBINING MACRON BELOW) instead of U+0332 (COMBINING LOW LINE).
851 859
852 860
853 861 .. _whatsnew700:
854 862
855 863 IPython 7.0.0
856 864 =============
857 865
858 866 Released Thursday September 27th, 2018
859 867
860 868 IPython 7 includes major feature improvements.
861 869 This is also the second major version of IPython to support only
862 870 Python 3 – starting at Python 3.4. Python 2 is still community-supported
863 871 on the bugfix only 5.x branch, but we remind you that Python 2 "end of life"
864 872 is on Jan 1st 2020.
865 873
866 874 We were able to backport bug fixes to the 5.x branch thanks to our backport bot which
867 875 backported more than `70 Pull-Requests
868 876 <https://github.com/ipython/ipython/pulls?page=3&q=is%3Apr+sort%3Aupdated-desc+author%3Aapp%2Fmeeseeksdev++5.x&utf8=%E2%9C%93>`_, but there are still many PRs that required manual work. This is an area of the project where you can easily contribute by looking for `PRs that still need manual backport <https://github.com/ipython/ipython/issues?q=label%3A%22Still+Needs+Manual+Backport%22+is%3Aclosed+sort%3Aupdated-desc>`_
869 877
870 878 The IPython 6.x branch will likely not see any further release unless critical
871 879 bugs are found.
872 880
873 881 Make sure you have pip > 9.0 before upgrading. You should be able to update by running:
874 882
875 883 .. code::
876 884
877 885 pip install ipython --upgrade
878 886
879 887 .. only:: ipydev
880 888
881 889 If you are trying to install or update an ``alpha``, ``beta``, or ``rc``
882 890 version, use pip ``--pre`` flag.
883 891
884 892 .. code::
885 893
886 894 pip install ipython --upgrade --pre
887 895
888 896
889 897 Or, if you have conda installed:
890 898
891 899 .. code::
892 900
893 901 conda install ipython
894 902
895 903
896 904
897 905 Prompt Toolkit 2.0
898 906 ------------------
899 907
900 908 IPython 7.0+ now uses ``prompt_toolkit 2.0``. If you still need to use an earlier
901 909 ``prompt_toolkit`` version, you may need to pin IPython to ``<7.0``.
902 910
903 911 Autowait: Asynchronous REPL
904 912 ---------------------------
905 913
906 914 Staring with IPython 7.0 on Python 3.6+, IPython can automatically ``await``
907 915 top level code. You should not need to access an event loop or runner
908 916 yourself. To learn more, read the :ref:`autoawait` section of our docs, see
909 917 :ghpull:`11265`, or try the following code::
910 918
911 919 Python 3.6.0
912 920 Type 'copyright', 'credits' or 'license' for more information
913 921 IPython 7.0.0 -- An enhanced Interactive Python. Type '?' for help.
914 922
915 923 In [1]: import aiohttp
916 924 ...: result = aiohttp.get('https://api.github.com')
917 925
918 926 In [2]: response = await result
919 927 <pause for a few 100s ms>
920 928
921 929 In [3]: await response.json()
922 930 Out[3]:
923 931 {'authorizations_url': 'https://api.github.com/authorizations',
924 932 'code_search_url': 'https://api.github.com/search/code?q={query}{&page,per_page,sort,order}',
925 933 ...
926 934 }
927 935
928 936 .. note::
929 937
930 938 Async integration is experimental code, behavior may change or be removed
931 939 between Python and IPython versions without warnings.
932 940
933 941 Integration is by default with `asyncio`, but other libraries can be configured --
934 942 like ``curio`` or ``trio`` -- to improve concurrency in the REPL::
935 943
936 944 In [1]: %autoawait trio
937 945
938 946 In [2]: import trio
939 947
940 948 In [3]: async def child(i):
941 949 ...: print(" child %s goes to sleep"%i)
942 950 ...: await trio.sleep(2)
943 951 ...: print(" child %s wakes up"%i)
944 952
945 953 In [4]: print('parent start')
946 954 ...: async with trio.open_nursery() as n:
947 955 ...: for i in range(3):
948 956 ...: n.spawn(child, i)
949 957 ...: print('parent end')
950 958 parent start
951 959 child 2 goes to sleep
952 960 child 0 goes to sleep
953 961 child 1 goes to sleep
954 962 <about 2 seconds pause>
955 963 child 2 wakes up
956 964 child 1 wakes up
957 965 child 0 wakes up
958 966 parent end
959 967
960 968 See :ref:`autoawait` for more information.
961 969
962 970
963 971 Asynchronous code in a Notebook interface or any other frontend using the
964 972 Jupyter Protocol will require further updates to the IPykernel package.
965 973
966 974 Non-Asynchronous code
967 975 ~~~~~~~~~~~~~~~~~~~~~
968 976
969 977 As the internal API of IPython is now asynchronous, IPython needs to run under
970 978 an event loop. In order to allow many workflows, (like using the :magic:`%run`
971 979 magic, or copy-pasting code that explicitly starts/stop event loop), when
972 980 top-level code is detected as not being asynchronous, IPython code is advanced
973 981 via a pseudo-synchronous runner, and may not advance pending tasks.
974 982
975 983 Change to Nested Embed
976 984 ~~~~~~~~~~~~~~~~~~~~~~
977 985
978 986 The introduction of the ability to run async code had some effect on the
979 987 ``IPython.embed()`` API. By default, embed will not allow you to run asynchronous
980 988 code unless an event loop is specified.
981 989
982 990 Effects on Magics
983 991 ~~~~~~~~~~~~~~~~~
984 992
985 993 Some magics will not work with async until they're updated.
986 994 Contributions welcome.
987 995
988 996 Expected Future changes
989 997 ~~~~~~~~~~~~~~~~~~~~~~~
990 998
991 999 We expect more internal but public IPython functions to become ``async``, and
992 1000 will likely end up having a persistent event loop while IPython is running.
993 1001
994 1002 Thanks
995 1003 ~~~~~~
996 1004
997 1005 This release took more than a year in the making.
998 1006 The code was rebased a number of
999 1007 times; leading to commit authorship that may have been lost in the final
1000 1008 Pull-Request. Huge thanks to many people for contribution, discussion, code,
1001 1009 documentation, use-cases: dalejung, danielballan, ellisonbg, fperez, gnestor,
1002 1010 minrk, njsmith, pganssle, tacaswell, takluyver , vidartf ... And many others.
1003 1011
1004 1012
1005 1013 Autoreload Improvement
1006 1014 ----------------------
1007 1015
1008 1016 The magic :magic:`%autoreload 2 <autoreload>` now captures new methods added to
1009 1017 classes. Earlier, only methods existing as of the initial import were being
1010 1018 tracked and updated.
1011 1019
1012 1020 This new feature helps dual environment development - Jupyter+IDE - where the
1013 1021 code gradually moves from notebook cells to package files as it gets
1014 1022 structured.
1015 1023
1016 1024 **Example**: An instance of the class ``MyClass`` will be able to access the
1017 1025 method ``cube()`` after it is uncommented and the file ``file1.py`` is saved on
1018 1026 disk.
1019 1027
1020 1028
1021 1029 .. code::
1022 1030
1023 1031 # notebook
1024 1032
1025 1033 from mymodule import MyClass
1026 1034 first = MyClass(5)
1027 1035
1028 1036 .. code::
1029 1037
1030 1038 # mymodule/file1.py
1031 1039
1032 1040 class MyClass:
1033 1041
1034 1042 def __init__(self, a=10):
1035 1043 self.a = a
1036 1044
1037 1045 def square(self):
1038 1046 print('compute square')
1039 1047 return self.a*self.a
1040 1048
1041 1049 # def cube(self):
1042 1050 # print('compute cube')
1043 1051 # return self.a*self.a*self.a
1044 1052
1045 1053
1046 1054
1047 1055
1048 1056 Misc
1049 1057 ----
1050 1058
1051 1059 The autoindent feature that was deprecated in 5.x was re-enabled and
1052 1060 un-deprecated in :ghpull:`11257`
1053 1061
1054 1062 Make :magic:`%run -n -i ... <run>` work correctly. Earlier, if :magic:`%run` was
1055 1063 passed both arguments, ``-n`` would be silently ignored. See :ghpull:`10308`
1056 1064
1057 1065
1058 1066 The :cellmagic:`%%script` (as well as :cellmagic:`%%bash`,
1059 1067 :cellmagic:`%%ruby`... ) cell magics now raise by default if the return code of
1060 1068 the given code is non-zero (thus halting execution of further cells in a
1061 1069 notebook). The behavior can be disable by passing the ``--no-raise-error`` flag.
1062 1070
1063 1071
1064 1072 Deprecations
1065 1073 ------------
1066 1074
1067 1075 A couple of unused functions and methods have been deprecated and will be removed
1068 1076 in future versions:
1069 1077
1070 1078 - ``IPython.utils.io.raw_print_err``
1071 1079 - ``IPython.utils.io.raw_print``
1072 1080
1073 1081
1074 1082 Backwards incompatible changes
1075 1083 ------------------------------
1076 1084
1077 1085 * The API for transforming input before it is parsed as Python code has been
1078 1086 completely redesigned: any custom input transformations will need to be
1079 1087 rewritten. See :doc:`/config/inputtransforms` for details of the new API.
General Comments 0
You need to be logged in to leave comments. Login now