##// END OF EJS Templates
Improve API documentation around configuration of embedded IPython (#13989)...
Matthias Bussonnier -
r28197:ad452c1d merge
parent child Browse files
Show More
@@ -1,39 +1,40 b''
1 MANIFEST
1 MANIFEST
2 build
2 build
3 dist
3 dist
4 _build
4 _build
5 docs/man/*.gz
5 docs/man/*.gz
6 docs/source/api/generated
6 docs/source/api/generated
7 docs/source/config/options
7 docs/source/config/options
8 docs/source/config/shortcuts/*.csv
8 docs/source/config/shortcuts/*.csv
9 docs/source/config/shortcuts/table.tsv
9 docs/source/savefig
10 docs/source/savefig
10 docs/source/interactive/magics-generated.txt
11 docs/source/interactive/magics-generated.txt
11 docs/gh-pages
12 docs/gh-pages
12 jupyter_notebook/notebook/static/mathjax
13 jupyter_notebook/notebook/static/mathjax
13 jupyter_notebook/static/style/*.map
14 jupyter_notebook/static/style/*.map
14 *.py[co]
15 *.py[co]
15 __pycache__
16 __pycache__
16 *.egg-info
17 *.egg-info
17 *~
18 *~
18 *.bak
19 *.bak
19 .ipynb_checkpoints
20 .ipynb_checkpoints
20 .tox
21 .tox
21 .DS_Store
22 .DS_Store
22 \#*#
23 \#*#
23 .#*
24 .#*
24 .cache
25 .cache
25 .coverage
26 .coverage
26 *.swp
27 *.swp
27 .pytest_cache
28 .pytest_cache
28 .python-version
29 .python-version
29 venv*/
30 venv*/
30 .mypy_cache/
31 .mypy_cache/
31
32
32 # jetbrains ide stuff
33 # jetbrains ide stuff
33 *.iml
34 *.iml
34 .idea/
35 .idea/
35
36
36 # vscode ide stuff
37 # vscode ide stuff
37 *.code-workspace
38 *.code-workspace
38 .history
39 .history
39 .vscode
40 .vscode
@@ -1,156 +1,161 b''
1 # PYTHON_ARGCOMPLETE_OK
1 # PYTHON_ARGCOMPLETE_OK
2 """
2 """
3 IPython: tools for interactive and parallel computing in Python.
3 IPython: tools for interactive and parallel computing in Python.
4
4
5 https://ipython.org
5 https://ipython.org
6 """
6 """
7 #-----------------------------------------------------------------------------
7 #-----------------------------------------------------------------------------
8 # Copyright (c) 2008-2011, IPython Development Team.
8 # Copyright (c) 2008-2011, IPython Development Team.
9 # Copyright (c) 2001-2007, Fernando Perez <fernando.perez@colorado.edu>
9 # Copyright (c) 2001-2007, Fernando Perez <fernando.perez@colorado.edu>
10 # Copyright (c) 2001, Janko Hauser <jhauser@zscout.de>
10 # Copyright (c) 2001, Janko Hauser <jhauser@zscout.de>
11 # Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu>
11 # Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu>
12 #
12 #
13 # Distributed under the terms of the Modified BSD License.
13 # Distributed under the terms of the Modified BSD License.
14 #
14 #
15 # The full license is in the file COPYING.txt, distributed with this software.
15 # The full license is in the file COPYING.txt, distributed with this software.
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17
17
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19 # Imports
19 # Imports
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21
21
22 import sys
22 import sys
23
23
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25 # Setup everything
25 # Setup everything
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27
27
28 # Don't forget to also update setup.py when this changes!
28 # Don't forget to also update setup.py when this changes!
29 if sys.version_info < (3, 8):
29 if sys.version_info < (3, 8):
30 raise ImportError(
30 raise ImportError(
31 """
31 """
32 IPython 8+ supports Python 3.8 and above, following NEP 29.
32 IPython 8+ supports Python 3.8 and above, following NEP 29.
33 When using Python 2.7, please install IPython 5.x LTS Long Term Support version.
33 When using Python 2.7, please install IPython 5.x LTS Long Term Support version.
34 Python 3.3 and 3.4 were supported up to IPython 6.x.
34 Python 3.3 and 3.4 were supported up to IPython 6.x.
35 Python 3.5 was supported with IPython 7.0 to 7.9.
35 Python 3.5 was supported with IPython 7.0 to 7.9.
36 Python 3.6 was supported with IPython up to 7.16.
36 Python 3.6 was supported with IPython up to 7.16.
37 Python 3.7 was still supported with the 7.x branch.
37 Python 3.7 was still supported with the 7.x branch.
38
38
39 See IPython `README.rst` file for more information:
39 See IPython `README.rst` file for more information:
40
40
41 https://github.com/ipython/ipython/blob/main/README.rst
41 https://github.com/ipython/ipython/blob/main/README.rst
42
42
43 """
43 """
44 )
44 )
45
45
46 #-----------------------------------------------------------------------------
46 #-----------------------------------------------------------------------------
47 # Setup the top level names
47 # Setup the top level names
48 #-----------------------------------------------------------------------------
48 #-----------------------------------------------------------------------------
49
49
50 from .core.getipython import get_ipython
50 from .core.getipython import get_ipython
51 from .core import release
51 from .core import release
52 from .core.application import Application
52 from .core.application import Application
53 from .terminal.embed import embed
53 from .terminal.embed import embed
54
54
55 from .core.interactiveshell import InteractiveShell
55 from .core.interactiveshell import InteractiveShell
56 from .utils.sysinfo import sys_info
56 from .utils.sysinfo import sys_info
57 from .utils.frame import extract_module_locals
57 from .utils.frame import extract_module_locals
58
58
59 __all__ = ["start_ipython", "embed", "start_kernel", "embed_kernel"]
60
59 # Release data
61 # Release data
60 __author__ = '%s <%s>' % (release.author, release.author_email)
62 __author__ = '%s <%s>' % (release.author, release.author_email)
61 __license__ = release.license
63 __license__ = release.license
62 __version__ = release.version
64 __version__ = release.version
63 version_info = release.version_info
65 version_info = release.version_info
64 # list of CVEs that should have been patched in this release.
66 # list of CVEs that should have been patched in this release.
65 # this is informational and should not be relied upon.
67 # this is informational and should not be relied upon.
66 __patched_cves__ = {"CVE-2022-21699", "CVE-2023-24816"}
68 __patched_cves__ = {"CVE-2022-21699", "CVE-2023-24816"}
67
69
68
70
69 def embed_kernel(module=None, local_ns=None, **kwargs):
71 def embed_kernel(module=None, local_ns=None, **kwargs):
70 """Embed and start an IPython kernel in a given scope.
72 """Embed and start an IPython kernel in a given scope.
71
73
72 If you don't want the kernel to initialize the namespace
74 If you don't want the kernel to initialize the namespace
73 from the scope of the surrounding function,
75 from the scope of the surrounding function,
74 and/or you want to load full IPython configuration,
76 and/or you want to load full IPython configuration,
75 you probably want `IPython.start_kernel()` instead.
77 you probably want `IPython.start_kernel()` instead.
76
78
77 Parameters
79 Parameters
78 ----------
80 ----------
79 module : types.ModuleType, optional
81 module : types.ModuleType, optional
80 The module to load into IPython globals (default: caller)
82 The module to load into IPython globals (default: caller)
81 local_ns : dict, optional
83 local_ns : dict, optional
82 The namespace to load into IPython user namespace (default: caller)
84 The namespace to load into IPython user namespace (default: caller)
83 **kwargs : various, optional
85 **kwargs : various, optional
84 Further keyword args are relayed to the IPKernelApp constructor,
86 Further keyword args are relayed to the IPKernelApp constructor,
85 allowing configuration of the Kernel. Will only have an effect
87 such as `config`, a traitlets :class:`Config` object (see :ref:`configure_start_ipython`),
88 allowing configuration of the kernel (see :ref:`kernel_options`). Will only have an effect
86 on the first embed_kernel call for a given process.
89 on the first embed_kernel call for a given process.
87 """
90 """
88
91
89 (caller_module, caller_locals) = extract_module_locals(1)
92 (caller_module, caller_locals) = extract_module_locals(1)
90 if module is None:
93 if module is None:
91 module = caller_module
94 module = caller_module
92 if local_ns is None:
95 if local_ns is None:
93 local_ns = caller_locals
96 local_ns = caller_locals
94
97
95 # Only import .zmq when we really need it
98 # Only import .zmq when we really need it
96 from ipykernel.embed import embed_kernel as real_embed_kernel
99 from ipykernel.embed import embed_kernel as real_embed_kernel
97 real_embed_kernel(module=module, local_ns=local_ns, **kwargs)
100 real_embed_kernel(module=module, local_ns=local_ns, **kwargs)
98
101
99 def start_ipython(argv=None, **kwargs):
102 def start_ipython(argv=None, **kwargs):
100 """Launch a normal IPython instance (as opposed to embedded)
103 """Launch a normal IPython instance (as opposed to embedded)
101
104
102 `IPython.embed()` puts a shell in a particular calling scope,
105 `IPython.embed()` puts a shell in a particular calling scope,
103 such as a function or method for debugging purposes,
106 such as a function or method for debugging purposes,
104 which is often not desirable.
107 which is often not desirable.
105
108
106 `start_ipython()` does full, regular IPython initialization,
109 `start_ipython()` does full, regular IPython initialization,
107 including loading startup files, configuration, etc.
110 including loading startup files, configuration, etc.
108 much of which is skipped by `embed()`.
111 much of which is skipped by `embed()`.
109
112
110 This is a public API method, and will survive implementation changes.
113 This is a public API method, and will survive implementation changes.
111
114
112 Parameters
115 Parameters
113 ----------
116 ----------
114 argv : list or None, optional
117 argv : list or None, optional
115 If unspecified or None, IPython will parse command-line options from sys.argv.
118 If unspecified or None, IPython will parse command-line options from sys.argv.
116 To prevent any command-line parsing, pass an empty list: `argv=[]`.
119 To prevent any command-line parsing, pass an empty list: `argv=[]`.
117 user_ns : dict, optional
120 user_ns : dict, optional
118 specify this dictionary to initialize the IPython user namespace with particular values.
121 specify this dictionary to initialize the IPython user namespace with particular values.
119 **kwargs : various, optional
122 **kwargs : various, optional
120 Any other kwargs will be passed to the Application constructor,
123 Any other kwargs will be passed to the Application constructor,
121 such as `config`.
124 such as `config`, a traitlets :class:`Config` object (see :ref:`configure_start_ipython`),
125 allowing configuration of the instance (see :ref:`terminal_options`).
122 """
126 """
123 from IPython.terminal.ipapp import launch_new_instance
127 from IPython.terminal.ipapp import launch_new_instance
124 return launch_new_instance(argv=argv, **kwargs)
128 return launch_new_instance(argv=argv, **kwargs)
125
129
126 def start_kernel(argv=None, **kwargs):
130 def start_kernel(argv=None, **kwargs):
127 """Launch a normal IPython kernel instance (as opposed to embedded)
131 """Launch a normal IPython kernel instance (as opposed to embedded)
128
132
129 `IPython.embed_kernel()` puts a shell in a particular calling scope,
133 `IPython.embed_kernel()` puts a shell in a particular calling scope,
130 such as a function or method for debugging purposes,
134 such as a function or method for debugging purposes,
131 which is often not desirable.
135 which is often not desirable.
132
136
133 `start_kernel()` does full, regular IPython initialization,
137 `start_kernel()` does full, regular IPython initialization,
134 including loading startup files, configuration, etc.
138 including loading startup files, configuration, etc.
135 much of which is skipped by `embed()`.
139 much of which is skipped by `embed_kernel()`.
136
140
137 Parameters
141 Parameters
138 ----------
142 ----------
139 argv : list or None, optional
143 argv : list or None, optional
140 If unspecified or None, IPython will parse command-line options from sys.argv.
144 If unspecified or None, IPython will parse command-line options from sys.argv.
141 To prevent any command-line parsing, pass an empty list: `argv=[]`.
145 To prevent any command-line parsing, pass an empty list: `argv=[]`.
142 user_ns : dict, optional
146 user_ns : dict, optional
143 specify this dictionary to initialize the IPython user namespace with particular values.
147 specify this dictionary to initialize the IPython user namespace with particular values.
144 **kwargs : various, optional
148 **kwargs : various, optional
145 Any other kwargs will be passed to the Application constructor,
149 Any other kwargs will be passed to the Application constructor,
146 such as `config`.
150 such as `config`, a traitlets :class:`Config` object (see :ref:`configure_start_ipython`),
151 allowing configuration of the kernel (see :ref:`kernel_options`).
147 """
152 """
148 import warnings
153 import warnings
149
154
150 warnings.warn(
155 warnings.warn(
151 "start_kernel is deprecated since IPython 8.0, use from `ipykernel.kernelapp.launch_new_instance`",
156 "start_kernel is deprecated since IPython 8.0, use from `ipykernel.kernelapp.launch_new_instance`",
152 DeprecationWarning,
157 DeprecationWarning,
153 stacklevel=2,
158 stacklevel=2,
154 )
159 )
155 from ipykernel.kernelapp import launch_new_instance
160 from ipykernel.kernelapp import launch_new_instance
156 return launch_new_instance(argv=argv, **kwargs)
161 return launch_new_instance(argv=argv, **kwargs)
@@ -1,410 +1,420 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 An embedded IPython shell.
3 An embedded IPython shell.
4 """
4 """
5 # Copyright (c) IPython Development Team.
5 # Copyright (c) IPython Development Team.
6 # Distributed under the terms of the Modified BSD License.
6 # Distributed under the terms of the Modified BSD License.
7
7
8
8
9 import sys
9 import sys
10 import warnings
10 import warnings
11
11
12 from IPython.core import ultratb, compilerop
12 from IPython.core import ultratb, compilerop
13 from IPython.core import magic_arguments
13 from IPython.core import magic_arguments
14 from IPython.core.magic import Magics, magics_class, line_magic
14 from IPython.core.magic import Magics, magics_class, line_magic
15 from IPython.core.interactiveshell import DummyMod, InteractiveShell
15 from IPython.core.interactiveshell import DummyMod, InteractiveShell
16 from IPython.terminal.interactiveshell import TerminalInteractiveShell
16 from IPython.terminal.interactiveshell import TerminalInteractiveShell
17 from IPython.terminal.ipapp import load_default_config
17 from IPython.terminal.ipapp import load_default_config
18
18
19 from traitlets import Bool, CBool, Unicode
19 from traitlets import Bool, CBool, Unicode
20 from IPython.utils.io import ask_yes_no
20 from IPython.utils.io import ask_yes_no
21
21
22 from typing import Set
22 from typing import Set
23
23
24 class KillEmbedded(Exception):pass
24 class KillEmbedded(Exception):pass
25
25
26 # kept for backward compatibility as IPython 6 was released with
26 # kept for backward compatibility as IPython 6 was released with
27 # the typo. See https://github.com/ipython/ipython/pull/10706
27 # the typo. See https://github.com/ipython/ipython/pull/10706
28 KillEmbeded = KillEmbedded
28 KillEmbeded = KillEmbedded
29
29
30 # This is an additional magic that is exposed in embedded shells.
30 # This is an additional magic that is exposed in embedded shells.
31 @magics_class
31 @magics_class
32 class EmbeddedMagics(Magics):
32 class EmbeddedMagics(Magics):
33
33
34 @line_magic
34 @line_magic
35 @magic_arguments.magic_arguments()
35 @magic_arguments.magic_arguments()
36 @magic_arguments.argument('-i', '--instance', action='store_true',
36 @magic_arguments.argument('-i', '--instance', action='store_true',
37 help='Kill instance instead of call location')
37 help='Kill instance instead of call location')
38 @magic_arguments.argument('-x', '--exit', action='store_true',
38 @magic_arguments.argument('-x', '--exit', action='store_true',
39 help='Also exit the current session')
39 help='Also exit the current session')
40 @magic_arguments.argument('-y', '--yes', action='store_true',
40 @magic_arguments.argument('-y', '--yes', action='store_true',
41 help='Do not ask confirmation')
41 help='Do not ask confirmation')
42 def kill_embedded(self, parameter_s=''):
42 def kill_embedded(self, parameter_s=''):
43 """%kill_embedded : deactivate for good the current embedded IPython
43 """%kill_embedded : deactivate for good the current embedded IPython
44
44
45 This function (after asking for confirmation) sets an internal flag so
45 This function (after asking for confirmation) sets an internal flag so
46 that an embedded IPython will never activate again for the given call
46 that an embedded IPython will never activate again for the given call
47 location. This is useful to permanently disable a shell that is being
47 location. This is useful to permanently disable a shell that is being
48 called inside a loop: once you've figured out what you needed from it,
48 called inside a loop: once you've figured out what you needed from it,
49 you may then kill it and the program will then continue to run without
49 you may then kill it and the program will then continue to run without
50 the interactive shell interfering again.
50 the interactive shell interfering again.
51
51
52 Kill Instance Option:
52 Kill Instance Option:
53
53
54 If for some reasons you need to kill the location where the instance
54 If for some reasons you need to kill the location where the instance
55 is created and not called, for example if you create a single
55 is created and not called, for example if you create a single
56 instance in one place and debug in many locations, you can use the
56 instance in one place and debug in many locations, you can use the
57 ``--instance`` option to kill this specific instance. Like for the
57 ``--instance`` option to kill this specific instance. Like for the
58 ``call location`` killing an "instance" should work even if it is
58 ``call location`` killing an "instance" should work even if it is
59 recreated within a loop.
59 recreated within a loop.
60
60
61 .. note::
61 .. note::
62
62
63 This was the default behavior before IPython 5.2
63 This was the default behavior before IPython 5.2
64
64
65 """
65 """
66
66
67 args = magic_arguments.parse_argstring(self.kill_embedded, parameter_s)
67 args = magic_arguments.parse_argstring(self.kill_embedded, parameter_s)
68 print(args)
68 print(args)
69 if args.instance:
69 if args.instance:
70 # let no ask
70 # let no ask
71 if not args.yes:
71 if not args.yes:
72 kill = ask_yes_no(
72 kill = ask_yes_no(
73 "Are you sure you want to kill this embedded instance? [y/N] ", 'n')
73 "Are you sure you want to kill this embedded instance? [y/N] ", 'n')
74 else:
74 else:
75 kill = True
75 kill = True
76 if kill:
76 if kill:
77 self.shell._disable_init_location()
77 self.shell._disable_init_location()
78 print("This embedded IPython instance will not reactivate anymore "
78 print("This embedded IPython instance will not reactivate anymore "
79 "once you exit.")
79 "once you exit.")
80 else:
80 else:
81 if not args.yes:
81 if not args.yes:
82 kill = ask_yes_no(
82 kill = ask_yes_no(
83 "Are you sure you want to kill this embedded call_location? [y/N] ", 'n')
83 "Are you sure you want to kill this embedded call_location? [y/N] ", 'n')
84 else:
84 else:
85 kill = True
85 kill = True
86 if kill:
86 if kill:
87 self.shell.embedded_active = False
87 self.shell.embedded_active = False
88 print("This embedded IPython call location will not reactivate anymore "
88 print("This embedded IPython call location will not reactivate anymore "
89 "once you exit.")
89 "once you exit.")
90
90
91 if args.exit:
91 if args.exit:
92 # Ask-exit does not really ask, it just set internals flags to exit
92 # Ask-exit does not really ask, it just set internals flags to exit
93 # on next loop.
93 # on next loop.
94 self.shell.ask_exit()
94 self.shell.ask_exit()
95
95
96
96
97 @line_magic
97 @line_magic
98 def exit_raise(self, parameter_s=''):
98 def exit_raise(self, parameter_s=''):
99 """%exit_raise Make the current embedded kernel exit and raise and exception.
99 """%exit_raise Make the current embedded kernel exit and raise and exception.
100
100
101 This function sets an internal flag so that an embedded IPython will
101 This function sets an internal flag so that an embedded IPython will
102 raise a `IPython.terminal.embed.KillEmbedded` Exception on exit, and then exit the current I. This is
102 raise a `IPython.terminal.embed.KillEmbedded` Exception on exit, and then exit the current I. This is
103 useful to permanently exit a loop that create IPython embed instance.
103 useful to permanently exit a loop that create IPython embed instance.
104 """
104 """
105
105
106 self.shell.should_raise = True
106 self.shell.should_raise = True
107 self.shell.ask_exit()
107 self.shell.ask_exit()
108
108
109
109
110 class _Sentinel:
110 class _Sentinel:
111 def __init__(self, repr):
111 def __init__(self, repr):
112 assert isinstance(repr, str)
112 assert isinstance(repr, str)
113 self.repr = repr
113 self.repr = repr
114
114
115 def __repr__(self):
115 def __repr__(self):
116 return repr
116 return repr
117
117
118
118
119 class InteractiveShellEmbed(TerminalInteractiveShell):
119 class InteractiveShellEmbed(TerminalInteractiveShell):
120
120
121 dummy_mode = Bool(False)
121 dummy_mode = Bool(False)
122 exit_msg = Unicode('')
122 exit_msg = Unicode('')
123 embedded = CBool(True)
123 embedded = CBool(True)
124 should_raise = CBool(False)
124 should_raise = CBool(False)
125 # Like the base class display_banner is not configurable, but here it
125 # Like the base class display_banner is not configurable, but here it
126 # is True by default.
126 # is True by default.
127 display_banner = CBool(True)
127 display_banner = CBool(True)
128 exit_msg = Unicode()
128 exit_msg = Unicode()
129
129
130 # When embedding, by default we don't change the terminal title
130 # When embedding, by default we don't change the terminal title
131 term_title = Bool(False,
131 term_title = Bool(False,
132 help="Automatically set the terminal title"
132 help="Automatically set the terminal title"
133 ).tag(config=True)
133 ).tag(config=True)
134
134
135 _inactive_locations: Set[str] = set()
135 _inactive_locations: Set[str] = set()
136
136
137 def _disable_init_location(self):
137 def _disable_init_location(self):
138 """Disable the current Instance creation location"""
138 """Disable the current Instance creation location"""
139 InteractiveShellEmbed._inactive_locations.add(self._init_location_id)
139 InteractiveShellEmbed._inactive_locations.add(self._init_location_id)
140
140
141 @property
141 @property
142 def embedded_active(self):
142 def embedded_active(self):
143 return (self._call_location_id not in InteractiveShellEmbed._inactive_locations)\
143 return (self._call_location_id not in InteractiveShellEmbed._inactive_locations)\
144 and (self._init_location_id not in InteractiveShellEmbed._inactive_locations)
144 and (self._init_location_id not in InteractiveShellEmbed._inactive_locations)
145
145
146 @embedded_active.setter
146 @embedded_active.setter
147 def embedded_active(self, value):
147 def embedded_active(self, value):
148 if value:
148 if value:
149 InteractiveShellEmbed._inactive_locations.discard(
149 InteractiveShellEmbed._inactive_locations.discard(
150 self._call_location_id)
150 self._call_location_id)
151 InteractiveShellEmbed._inactive_locations.discard(
151 InteractiveShellEmbed._inactive_locations.discard(
152 self._init_location_id)
152 self._init_location_id)
153 else:
153 else:
154 InteractiveShellEmbed._inactive_locations.add(
154 InteractiveShellEmbed._inactive_locations.add(
155 self._call_location_id)
155 self._call_location_id)
156
156
157 def __init__(self, **kw):
157 def __init__(self, **kw):
158 assert (
158 assert (
159 "user_global_ns" not in kw
159 "user_global_ns" not in kw
160 ), "Key word argument `user_global_ns` has been replaced by `user_module` since IPython 4.0."
160 ), "Key word argument `user_global_ns` has been replaced by `user_module` since IPython 4.0."
161
161
162 clid = kw.pop('_init_location_id', None)
162 clid = kw.pop('_init_location_id', None)
163 if not clid:
163 if not clid:
164 frame = sys._getframe(1)
164 frame = sys._getframe(1)
165 clid = '%s:%s' % (frame.f_code.co_filename, frame.f_lineno)
165 clid = '%s:%s' % (frame.f_code.co_filename, frame.f_lineno)
166 self._init_location_id = clid
166 self._init_location_id = clid
167
167
168 super(InteractiveShellEmbed,self).__init__(**kw)
168 super(InteractiveShellEmbed,self).__init__(**kw)
169
169
170 # don't use the ipython crash handler so that user exceptions aren't
170 # don't use the ipython crash handler so that user exceptions aren't
171 # trapped
171 # trapped
172 sys.excepthook = ultratb.FormattedTB(color_scheme=self.colors,
172 sys.excepthook = ultratb.FormattedTB(color_scheme=self.colors,
173 mode=self.xmode,
173 mode=self.xmode,
174 call_pdb=self.pdb)
174 call_pdb=self.pdb)
175
175
176 def init_sys_modules(self):
176 def init_sys_modules(self):
177 """
177 """
178 Explicitly overwrite :mod:`IPython.core.interactiveshell` to do nothing.
178 Explicitly overwrite :mod:`IPython.core.interactiveshell` to do nothing.
179 """
179 """
180 pass
180 pass
181
181
182 def init_magics(self):
182 def init_magics(self):
183 super(InteractiveShellEmbed, self).init_magics()
183 super(InteractiveShellEmbed, self).init_magics()
184 self.register_magics(EmbeddedMagics)
184 self.register_magics(EmbeddedMagics)
185
185
186 def __call__(
186 def __call__(
187 self,
187 self,
188 header="",
188 header="",
189 local_ns=None,
189 local_ns=None,
190 module=None,
190 module=None,
191 dummy=None,
191 dummy=None,
192 stack_depth=1,
192 stack_depth=1,
193 compile_flags=None,
193 compile_flags=None,
194 **kw
194 **kw
195 ):
195 ):
196 """Activate the interactive interpreter.
196 """Activate the interactive interpreter.
197
197
198 __call__(self,header='',local_ns=None,module=None,dummy=None) -> Start
198 __call__(self,header='',local_ns=None,module=None,dummy=None) -> Start
199 the interpreter shell with the given local and global namespaces, and
199 the interpreter shell with the given local and global namespaces, and
200 optionally print a header string at startup.
200 optionally print a header string at startup.
201
201
202 The shell can be globally activated/deactivated using the
202 The shell can be globally activated/deactivated using the
203 dummy_mode attribute. This allows you to turn off a shell used
203 dummy_mode attribute. This allows you to turn off a shell used
204 for debugging globally.
204 for debugging globally.
205
205
206 However, *each* time you call the shell you can override the current
206 However, *each* time you call the shell you can override the current
207 state of dummy_mode with the optional keyword parameter 'dummy'. For
207 state of dummy_mode with the optional keyword parameter 'dummy'. For
208 example, if you set dummy mode on with IPShell.dummy_mode = True, you
208 example, if you set dummy mode on with IPShell.dummy_mode = True, you
209 can still have a specific call work by making it as IPShell(dummy=False).
209 can still have a specific call work by making it as IPShell(dummy=False).
210 """
210 """
211
211
212 # we are called, set the underlying interactiveshell not to exit.
212 # we are called, set the underlying interactiveshell not to exit.
213 self.keep_running = True
213 self.keep_running = True
214
214
215 # If the user has turned it off, go away
215 # If the user has turned it off, go away
216 clid = kw.pop('_call_location_id', None)
216 clid = kw.pop('_call_location_id', None)
217 if not clid:
217 if not clid:
218 frame = sys._getframe(1)
218 frame = sys._getframe(1)
219 clid = '%s:%s' % (frame.f_code.co_filename, frame.f_lineno)
219 clid = '%s:%s' % (frame.f_code.co_filename, frame.f_lineno)
220 self._call_location_id = clid
220 self._call_location_id = clid
221
221
222 if not self.embedded_active:
222 if not self.embedded_active:
223 return
223 return
224
224
225 # Normal exits from interactive mode set this flag, so the shell can't
225 # Normal exits from interactive mode set this flag, so the shell can't
226 # re-enter (it checks this variable at the start of interactive mode).
226 # re-enter (it checks this variable at the start of interactive mode).
227 self.exit_now = False
227 self.exit_now = False
228
228
229 # Allow the dummy parameter to override the global __dummy_mode
229 # Allow the dummy parameter to override the global __dummy_mode
230 if dummy or (dummy != 0 and self.dummy_mode):
230 if dummy or (dummy != 0 and self.dummy_mode):
231 return
231 return
232
232
233 # self.banner is auto computed
233 # self.banner is auto computed
234 if header:
234 if header:
235 self.old_banner2 = self.banner2
235 self.old_banner2 = self.banner2
236 self.banner2 = self.banner2 + '\n' + header + '\n'
236 self.banner2 = self.banner2 + '\n' + header + '\n'
237 else:
237 else:
238 self.old_banner2 = ''
238 self.old_banner2 = ''
239
239
240 if self.display_banner:
240 if self.display_banner:
241 self.show_banner()
241 self.show_banner()
242
242
243 # Call the embedding code with a stack depth of 1 so it can skip over
243 # Call the embedding code with a stack depth of 1 so it can skip over
244 # our call and get the original caller's namespaces.
244 # our call and get the original caller's namespaces.
245 self.mainloop(
245 self.mainloop(
246 local_ns, module, stack_depth=stack_depth, compile_flags=compile_flags
246 local_ns, module, stack_depth=stack_depth, compile_flags=compile_flags
247 )
247 )
248
248
249 self.banner2 = self.old_banner2
249 self.banner2 = self.old_banner2
250
250
251 if self.exit_msg is not None:
251 if self.exit_msg is not None:
252 print(self.exit_msg)
252 print(self.exit_msg)
253
253
254 if self.should_raise:
254 if self.should_raise:
255 raise KillEmbedded('Embedded IPython raising error, as user requested.')
255 raise KillEmbedded('Embedded IPython raising error, as user requested.')
256
256
257 def mainloop(
257 def mainloop(
258 self,
258 self,
259 local_ns=None,
259 local_ns=None,
260 module=None,
260 module=None,
261 stack_depth=0,
261 stack_depth=0,
262 compile_flags=None,
262 compile_flags=None,
263 ):
263 ):
264 """Embeds IPython into a running python program.
264 """Embeds IPython into a running python program.
265
265
266 Parameters
266 Parameters
267 ----------
267 ----------
268 local_ns, module
268 local_ns, module
269 Working local namespace (a dict) and module (a module or similar
269 Working local namespace (a dict) and module (a module or similar
270 object). If given as None, they are automatically taken from the scope
270 object). If given as None, they are automatically taken from the scope
271 where the shell was called, so that program variables become visible.
271 where the shell was called, so that program variables become visible.
272 stack_depth : int
272 stack_depth : int
273 How many levels in the stack to go to looking for namespaces (when
273 How many levels in the stack to go to looking for namespaces (when
274 local_ns or module is None). This allows an intermediate caller to
274 local_ns or module is None). This allows an intermediate caller to
275 make sure that this function gets the namespace from the intended
275 make sure that this function gets the namespace from the intended
276 level in the stack. By default (0) it will get its locals and globals
276 level in the stack. By default (0) it will get its locals and globals
277 from the immediate caller.
277 from the immediate caller.
278 compile_flags
278 compile_flags
279 A bit field identifying the __future__ features
279 A bit field identifying the __future__ features
280 that are enabled, as passed to the builtin :func:`compile` function.
280 that are enabled, as passed to the builtin :func:`compile` function.
281 If given as None, they are automatically taken from the scope where
281 If given as None, they are automatically taken from the scope where
282 the shell was called.
282 the shell was called.
283
283
284 """
284 """
285
285
286 # Get locals and globals from caller
286 # Get locals and globals from caller
287 if ((local_ns is None or module is None or compile_flags is None)
287 if ((local_ns is None or module is None or compile_flags is None)
288 and self.default_user_namespaces):
288 and self.default_user_namespaces):
289 call_frame = sys._getframe(stack_depth).f_back
289 call_frame = sys._getframe(stack_depth).f_back
290
290
291 if local_ns is None:
291 if local_ns is None:
292 local_ns = call_frame.f_locals
292 local_ns = call_frame.f_locals
293 if module is None:
293 if module is None:
294 global_ns = call_frame.f_globals
294 global_ns = call_frame.f_globals
295 try:
295 try:
296 module = sys.modules[global_ns['__name__']]
296 module = sys.modules[global_ns['__name__']]
297 except KeyError:
297 except KeyError:
298 warnings.warn("Failed to get module %s" % \
298 warnings.warn("Failed to get module %s" % \
299 global_ns.get('__name__', 'unknown module')
299 global_ns.get('__name__', 'unknown module')
300 )
300 )
301 module = DummyMod()
301 module = DummyMod()
302 module.__dict__ = global_ns
302 module.__dict__ = global_ns
303 if compile_flags is None:
303 if compile_flags is None:
304 compile_flags = (call_frame.f_code.co_flags &
304 compile_flags = (call_frame.f_code.co_flags &
305 compilerop.PyCF_MASK)
305 compilerop.PyCF_MASK)
306
306
307 # Save original namespace and module so we can restore them after
307 # Save original namespace and module so we can restore them after
308 # embedding; otherwise the shell doesn't shut down correctly.
308 # embedding; otherwise the shell doesn't shut down correctly.
309 orig_user_module = self.user_module
309 orig_user_module = self.user_module
310 orig_user_ns = self.user_ns
310 orig_user_ns = self.user_ns
311 orig_compile_flags = self.compile.flags
311 orig_compile_flags = self.compile.flags
312
312
313 # Update namespaces and fire up interpreter
313 # Update namespaces and fire up interpreter
314
314
315 # The global one is easy, we can just throw it in
315 # The global one is easy, we can just throw it in
316 if module is not None:
316 if module is not None:
317 self.user_module = module
317 self.user_module = module
318
318
319 # But the user/local one is tricky: ipython needs it to store internal
319 # But the user/local one is tricky: ipython needs it to store internal
320 # data, but we also need the locals. We'll throw our hidden variables
320 # data, but we also need the locals. We'll throw our hidden variables
321 # like _ih and get_ipython() into the local namespace, but delete them
321 # like _ih and get_ipython() into the local namespace, but delete them
322 # later.
322 # later.
323 if local_ns is not None:
323 if local_ns is not None:
324 reentrant_local_ns = {k: v for (k, v) in local_ns.items() if k not in self.user_ns_hidden.keys()}
324 reentrant_local_ns = {k: v for (k, v) in local_ns.items() if k not in self.user_ns_hidden.keys()}
325 self.user_ns = reentrant_local_ns
325 self.user_ns = reentrant_local_ns
326 self.init_user_ns()
326 self.init_user_ns()
327
327
328 # Compiler flags
328 # Compiler flags
329 if compile_flags is not None:
329 if compile_flags is not None:
330 self.compile.flags = compile_flags
330 self.compile.flags = compile_flags
331
331
332 # make sure the tab-completer has the correct frame information, so it
332 # make sure the tab-completer has the correct frame information, so it
333 # actually completes using the frame's locals/globals
333 # actually completes using the frame's locals/globals
334 self.set_completer_frame()
334 self.set_completer_frame()
335
335
336 with self.builtin_trap, self.display_trap:
336 with self.builtin_trap, self.display_trap:
337 self.interact()
337 self.interact()
338
338
339 # now, purge out the local namespace of IPython's hidden variables.
339 # now, purge out the local namespace of IPython's hidden variables.
340 if local_ns is not None:
340 if local_ns is not None:
341 local_ns.update({k: v for (k, v) in self.user_ns.items() if k not in self.user_ns_hidden.keys()})
341 local_ns.update({k: v for (k, v) in self.user_ns.items() if k not in self.user_ns_hidden.keys()})
342
342
343
343
344 # Restore original namespace so shell can shut down when we exit.
344 # Restore original namespace so shell can shut down when we exit.
345 self.user_module = orig_user_module
345 self.user_module = orig_user_module
346 self.user_ns = orig_user_ns
346 self.user_ns = orig_user_ns
347 self.compile.flags = orig_compile_flags
347 self.compile.flags = orig_compile_flags
348
348
349
349
350 def embed(*, header="", compile_flags=None, **kwargs):
350 def embed(*, header="", compile_flags=None, **kwargs):
351 """Call this to embed IPython at the current point in your program.
351 """Call this to embed IPython at the current point in your program.
352
352
353 The first invocation of this will create an :class:`InteractiveShellEmbed`
353 The first invocation of this will create a :class:`terminal.embed.InteractiveShellEmbed`
354 instance and then call it. Consecutive calls just call the already
354 instance and then call it. Consecutive calls just call the already
355 created instance.
355 created instance.
356
356
357 If you don't want the kernel to initialize the namespace
357 If you don't want the kernel to initialize the namespace
358 from the scope of the surrounding function,
358 from the scope of the surrounding function,
359 and/or you want to load full IPython configuration,
359 and/or you want to load full IPython configuration,
360 you probably want `IPython.start_ipython()` instead.
360 you probably want `IPython.start_ipython()` instead.
361
361
362 Here is a simple example::
362 Here is a simple example::
363
363
364 from IPython import embed
364 from IPython import embed
365 a = 10
365 a = 10
366 b = 20
366 b = 20
367 embed(header='First time')
367 embed(header='First time')
368 c = 30
368 c = 30
369 d = 40
369 d = 40
370 embed()
370 embed()
371
371
372 Full customization can be done by passing a :class:`Config` in as the
372 Parameters
373 config argument.
373 ----------
374
375 header : str
376 Optional header string to print at startup.
377 compile_flags
378 Passed to the `compile_flags` parameter of :py:meth:`terminal.embed.InteractiveShellEmbed.mainloop()`,
379 which is called when the :class:`terminal.embed.InteractiveShellEmbed` instance is called.
380 **kwargs : various, optional
381 Any other kwargs will be passed to the :class:`terminal.embed.InteractiveShellEmbed` constructor.
382 Full customization can be done by passing a traitlets :class:`Config` in as the
383 `config` argument (see :ref:`configure_start_ipython` and :ref:`terminal_options`).
374 """
384 """
375 config = kwargs.get('config')
385 config = kwargs.get('config')
376 if config is None:
386 if config is None:
377 config = load_default_config()
387 config = load_default_config()
378 config.InteractiveShellEmbed = config.TerminalInteractiveShell
388 config.InteractiveShellEmbed = config.TerminalInteractiveShell
379 kwargs['config'] = config
389 kwargs['config'] = config
380 using = kwargs.get('using', 'sync')
390 using = kwargs.get('using', 'sync')
381 if using :
391 if using :
382 kwargs['config'].update({'TerminalInteractiveShell':{'loop_runner':using, 'colors':'NoColor', 'autoawait': using!='sync'}})
392 kwargs['config'].update({'TerminalInteractiveShell':{'loop_runner':using, 'colors':'NoColor', 'autoawait': using!='sync'}})
383 #save ps1/ps2 if defined
393 #save ps1/ps2 if defined
384 ps1 = None
394 ps1 = None
385 ps2 = None
395 ps2 = None
386 try:
396 try:
387 ps1 = sys.ps1
397 ps1 = sys.ps1
388 ps2 = sys.ps2
398 ps2 = sys.ps2
389 except AttributeError:
399 except AttributeError:
390 pass
400 pass
391 #save previous instance
401 #save previous instance
392 saved_shell_instance = InteractiveShell._instance
402 saved_shell_instance = InteractiveShell._instance
393 if saved_shell_instance is not None:
403 if saved_shell_instance is not None:
394 cls = type(saved_shell_instance)
404 cls = type(saved_shell_instance)
395 cls.clear_instance()
405 cls.clear_instance()
396 frame = sys._getframe(1)
406 frame = sys._getframe(1)
397 shell = InteractiveShellEmbed.instance(_init_location_id='%s:%s' % (
407 shell = InteractiveShellEmbed.instance(_init_location_id='%s:%s' % (
398 frame.f_code.co_filename, frame.f_lineno), **kwargs)
408 frame.f_code.co_filename, frame.f_lineno), **kwargs)
399 shell(header=header, stack_depth=2, compile_flags=compile_flags,
409 shell(header=header, stack_depth=2, compile_flags=compile_flags,
400 _call_location_id='%s:%s' % (frame.f_code.co_filename, frame.f_lineno))
410 _call_location_id='%s:%s' % (frame.f_code.co_filename, frame.f_lineno))
401 InteractiveShellEmbed.clear_instance()
411 InteractiveShellEmbed.clear_instance()
402 #restore previous instance
412 #restore previous instance
403 if saved_shell_instance is not None:
413 if saved_shell_instance is not None:
404 cls = type(saved_shell_instance)
414 cls = type(saved_shell_instance)
405 cls.clear_instance()
415 cls.clear_instance()
406 for subclass in cls._walk_mro():
416 for subclass in cls._walk_mro():
407 subclass._instance = saved_shell_instance
417 subclass._instance = saved_shell_instance
408 if ps1 is not None:
418 if ps1 is not None:
409 sys.ps1 = ps1
419 sys.ps1 = ps1
410 sys.ps2 = ps2
420 sys.ps2 = ps2
@@ -1,64 +1,64 b''
1 IPython Documentation
1 IPython Documentation
2 ---------------------
2 ---------------------
3
3
4 This directory contains the majority of the documentation for IPython.
4 This directory contains the majority of the documentation for IPython.
5
5
6
6
7 Deploy docs
7 Deploy docs
8 -----------
8 -----------
9
9
10 Documentation is automatically deployed on ReadTheDocs on every push or merged
10 Documentation is automatically deployed on ReadTheDocs on every push or merged
11 Pull requests.
11 Pull requests.
12
12
13
13
14 Requirements
14 Requirements
15 ------------
15 ------------
16
16
17 The documentation must be built using Python 3.
17 The documentation must be built using Python 3.
18
18
19 In addition to :ref:`devinstall`,
19 In addition to :ref:`devinstall`,
20 the following tools are needed to build the documentation:
20 the following tools are needed to build the documentation:
21
21
22 - sphinx
22 - sphinx
23 - sphinx_rtd_theme
23 - sphinx_rtd_theme
24 - docrepr
24 - docrepr
25
25
26 In a conda environment, or a Python 3 ``venv``, you should be able to run::
26 In a conda environment, or a Python 3 ``venv``, you should be able to run::
27
27
28 cd ipython
28 cd ipython
29 pip install .[doc] -U
29 pip install -U -r docs/requirements.txt
30
30
31
31
32 Build Commands
32 Build Commands
33 --------------
33 --------------
34
34
35 The documentation gets built using ``make``, and comes in several flavors.
35 The documentation gets built using ``make``, and comes in several flavors.
36
36
37 ``make html`` - build the API and narrative documentation web pages, this is
37 ``make html`` - build the API and narrative documentation web pages, this is
38 the default ``make`` target, so running just ``make`` is equivalent to ``make
38 the default ``make`` target, so running just ``make`` is equivalent to ``make
39 html``.
39 html``.
40
40
41 ``make html_noapi`` - same as above, but without running the auto-generated API
41 ``make html_noapi`` - same as above, but without running the auto-generated API
42 docs. When you are working on the narrative documentation, the most time
42 docs. When you are working on the narrative documentation, the most time
43 consuming portion of the build process is the processing and rendering of the
43 consuming portion of the build process is the processing and rendering of the
44 API documentation. This build target skips that.
44 API documentation. This build target skips that.
45
45
46 ``make pdf`` will compile a pdf from the documentation.
46 ``make pdf`` will compile a pdf from the documentation.
47
47
48 You can run ``make help`` to see information on all possible make targets.
48 You can run ``make help`` to see information on all possible make targets.
49
49
50 To save time,
50 To save time,
51 the make targets above only process the files that have been changed since the
51 the make targets above only process the files that have been changed since the
52 previous docs build.
52 previous docs build.
53 To remove the previous docs build you can use ``make clean``.
53 To remove the previous docs build you can use ``make clean``.
54 You can also combine ``clean`` with other `make` commands;
54 You can also combine ``clean`` with other `make` commands;
55 for example,
55 for example,
56 ``make clean html`` will do a complete rebuild of the docs or ``make clean pdf`` will do a complete build of the pdf.
56 ``make clean html`` will do a complete rebuild of the docs or ``make clean pdf`` will do a complete build of the pdf.
57
57
58
58
59 Continuous Integration
59 Continuous Integration
60 ----------------------
60 ----------------------
61
61
62 Documentation builds are included in the Travis-CI continuous integration process,
62 Documentation builds are included in the Travis-CI continuous integration process,
63 so you can see the results of the docs build for any pull request at
63 so you can see the results of the docs build for any pull request at
64 https://travis-ci.org/ipython/ipython/pull_requests.
64 https://travis-ci.org/ipython/ipython/pull_requests.
@@ -1,80 +1,83 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 """Script to auto-generate our API docs.
2 """Script to auto-generate our API docs.
3 """
3 """
4
4
5 import os
5 import os
6 import sys
6 import sys
7
7
8 pjoin = os.path.join
8 pjoin = os.path.join
9
9
10 here = os.path.abspath(os.path.dirname(__file__))
10 here = os.path.abspath(os.path.dirname(__file__))
11 sys.path.append(pjoin(os.path.abspath(here), 'sphinxext'))
11 sys.path.append(pjoin(os.path.abspath(here), 'sphinxext'))
12
12
13 from apigen import ApiDocWriter
13 from apigen import ApiDocWriter
14
14
15 source = pjoin(here, 'source')
15 source = pjoin(here, 'source')
16
16
17 #*****************************************************************************
17 #*****************************************************************************
18 if __name__ == '__main__':
18 if __name__ == '__main__':
19 package = 'IPython'
19 package = 'IPython'
20 outdir = pjoin(source, 'api', 'generated')
20 outdir = pjoin(source, 'api', 'generated')
21 docwriter = ApiDocWriter(package,rst_extension='.rst')
21 docwriter = ApiDocWriter(package,rst_extension='.rst')
22 # You have to escape the . here because . is a special char for regexps.
22 # You have to escape the . here because . is a special char for regexps.
23 # You must do make clean if you change this!
23 # You must do make clean if you change this!
24 docwriter.package_skip_patterns += [r'\.external$',
24 docwriter.package_skip_patterns += [r'\.external$',
25 # Extensions are documented elsewhere.
25 # Extensions are documented elsewhere.
26 r'\.extensions',
26 r'\.extensions',
27 # Magics are documented separately
27 # Magics are documented separately
28 r'\.core\.magics',
28 r'\.core\.magics',
29 # This isn't API
29 # This isn't API
30 r'\.sphinxext',
30 r'\.sphinxext',
31 # Shims
31 # Shims
32 r'\.kernel',
32 r'\.kernel',
33 r'\.terminal\.pt_inputhooks',
33 r'\.terminal\.pt_inputhooks',
34 ]
34 ]
35
35
36 # The inputhook* modules often cause problems on import, such as trying to
36 # The inputhook* modules often cause problems on import, such as trying to
37 # load incompatible Qt bindings. It's easiest to leave them all out. The
37 # load incompatible Qt bindings. It's easiest to leave them all out. The
38 docwriter.module_skip_patterns += [
38 docwriter.module_skip_patterns += [
39 r"\.lib\.inputhook.+",
39 r"\.lib\.inputhook.+",
40 r"\.ipdoctest",
40 r"\.ipdoctest",
41 r"\.testing\.plugin",
41 r"\.testing\.plugin",
42 # Backwards compat import for lib.lexers
42 # Backwards compat import for lib.lexers
43 r"\.nbconvert\.utils\.lexers",
43 r"\.nbconvert\.utils\.lexers",
44 # We document this manually.
44 # We document this manually.
45 r"\.utils\.py3compat",
45 r"\.utils\.py3compat",
46 # These are exposed in display
46 # These are exposed in display
47 r"\.core\.display",
47 r"\.core\.display",
48 r"\.lib\.display",
48 r"\.lib\.display",
49 # Shims
49 # Shims
50 r"\.config",
50 r"\.config",
51 r"\.consoleapp",
51 r"\.consoleapp",
52 r"\.frontend$",
52 r"\.frontend$",
53 r"\.html",
53 r"\.html",
54 r"\.nbconvert",
54 r"\.nbconvert",
55 r"\.nbformat",
55 r"\.nbformat",
56 r"\.parallel",
56 r"\.parallel",
57 r"\.qt",
57 r"\.qt",
58 # this is deprecated.
58 # this is deprecated.
59 r"\.utils\.version",
59 r"\.utils\.version",
60 # Private APIs (there should be a lot more here)
60 # Private APIs (there should be a lot more here)
61 r"\.terminal\.ptutils",
61 r"\.terminal\.ptutils",
62 ]
62 ]
63 # main API is in the inputhook module, which is documented.
63 # main API is in the inputhook module, which is documented.
64
64
65 # These modules import functions and classes from other places to expose
65 # These modules import functions and classes from other places to expose
66 # them as part of the public API. They must have __all__ defined. The
66 # them as part of the public API. They must have __all__ defined. The
67 # non-API modules they import from should be excluded by the skip patterns
67 # non-API modules they import from should be excluded by the skip patterns
68 # above.
68 # above.
69 docwriter.names_from__all__.update({
69 docwriter.names_from__all__.update(
70 'IPython.display',
70 {
71 })
71 "IPython",
72
72 "IPython.display",
73 }
74 )
75
73 # Now, generate the outputs
76 # Now, generate the outputs
74 docwriter.write_api_docs(outdir)
77 docwriter.write_api_docs(outdir)
75 # Write index with .txt extension - we can include it, but Sphinx won't try
78 # Write index with .txt extension - we can include it, but Sphinx won't try
76 # to compile it
79 # to compile it
77 docwriter.write_index(outdir, 'gen.txt',
80 docwriter.write_index(outdir, 'gen.txt',
78 relative_to = pjoin(source, 'api')
81 relative_to = pjoin(source, 'api')
79 )
82 )
80 print ('%d files written' % len(docwriter.written_modules))
83 print ('%d files written' % len(docwriter.written_modules))
@@ -1,126 +1,127 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2
2
3 import inspect
3 import inspect
4 from pathlib import Path
4 from pathlib import Path
5 from IPython.terminal.ipapp import TerminalIPythonApp
5 from IPython.terminal.ipapp import TerminalIPythonApp
6 from ipykernel.kernelapp import IPKernelApp
6 from ipykernel.kernelapp import IPKernelApp
7 from traitlets import Undefined
7 from traitlets import Undefined
8 from collections import defaultdict
8 from collections import defaultdict
9
9
10 here = (Path(__file__)).parent
10 here = (Path(__file__)).parent
11 options = here / "source" / "config" / "options"
11 options = here / "source" / "config" / "options"
12 generated = options / "config-generated.txt"
12 generated = options / "config-generated.txt"
13
13
14 import textwrap
14 import textwrap
15 indent = lambda text,n: textwrap.indent(text,n*' ')
15 indent = lambda text,n: textwrap.indent(text,n*' ')
16
16
17
17
18 def interesting_default_value(dv):
18 def interesting_default_value(dv):
19 if (dv is None) or (dv is Undefined):
19 if (dv is None) or (dv is Undefined):
20 return False
20 return False
21 if isinstance(dv, (str, list, tuple, dict, set)):
21 if isinstance(dv, (str, list, tuple, dict, set)):
22 return bool(dv)
22 return bool(dv)
23 return True
23 return True
24
24
25 def format_aliases(aliases):
25 def format_aliases(aliases):
26 fmted = []
26 fmted = []
27 for a in aliases:
27 for a in aliases:
28 dashes = '-' if len(a) == 1 else '--'
28 dashes = '-' if len(a) == 1 else '--'
29 fmted.append('``%s%s``' % (dashes, a))
29 fmted.append('``%s%s``' % (dashes, a))
30 return ', '.join(fmted)
30 return ', '.join(fmted)
31
31
32 def class_config_rst_doc(cls, trait_aliases):
32 def class_config_rst_doc(cls, trait_aliases):
33 """Generate rST documentation for this class' config options.
33 """Generate rST documentation for this class' config options.
34
34
35 Excludes traits defined on parent classes.
35 Excludes traits defined on parent classes.
36 """
36 """
37 lines = []
37 lines = []
38 classname = cls.__name__
38 classname = cls.__name__
39 for k, trait in sorted(cls.class_traits(config=True).items()):
39 for k, trait in sorted(cls.class_traits(config=True).items()):
40 ttype = trait.__class__.__name__
40 ttype = trait.__class__.__name__
41
41
42 fullname = classname + '.' + trait.name
42 fullname = classname + '.' + trait.name
43 lines += ['.. configtrait:: ' + fullname,
43 lines += ['.. configtrait:: ' + fullname,
44 ''
44 ''
45 ]
45 ]
46
46
47 help = trait.help.rstrip() or 'No description'
47 help = trait.help.rstrip() or 'No description'
48 lines.append(indent(inspect.cleandoc(help), 4) + '\n')
48 lines.append(indent(inspect.cleandoc(help), 4) + '\n')
49
49
50 # Choices or type
50 # Choices or type
51 if 'Enum' in ttype:
51 if 'Enum' in ttype:
52 # include Enum choices
52 # include Enum choices
53 lines.append(indent(
53 lines.append(indent(
54 ':options: ' + ', '.join('``%r``' % x for x in trait.values), 4))
54 ':options: ' + ', '.join('``%r``' % x for x in trait.values), 4))
55 else:
55 else:
56 lines.append(indent(':trait type: ' + ttype, 4))
56 lines.append(indent(':trait type: ' + ttype, 4))
57
57
58 # Default value
58 # Default value
59 # Ignore boring default values like None, [] or ''
59 # Ignore boring default values like None, [] or ''
60 if interesting_default_value(trait.default_value):
60 if interesting_default_value(trait.default_value):
61 try:
61 try:
62 dvr = trait.default_value_repr()
62 dvr = trait.default_value_repr()
63 except Exception:
63 except Exception:
64 dvr = None # ignore defaults we can't construct
64 dvr = None # ignore defaults we can't construct
65 if dvr is not None:
65 if dvr is not None:
66 if len(dvr) > 64:
66 if len(dvr) > 64:
67 dvr = dvr[:61] + '...'
67 dvr = dvr[:61] + '...'
68 # Double up backslashes, so they get to the rendered docs
68 # Double up backslashes, so they get to the rendered docs
69 dvr = dvr.replace('\\n', '\\\\n')
69 dvr = dvr.replace('\\n', '\\\\n')
70 lines.append(indent(':default: ``%s``' % dvr, 4))
70 lines.append(indent(':default: ``%s``' % dvr, 4))
71
71
72 # Command line aliases
72 # Command line aliases
73 if trait_aliases[fullname]:
73 if trait_aliases[fullname]:
74 fmt_aliases = format_aliases(trait_aliases[fullname])
74 fmt_aliases = format_aliases(trait_aliases[fullname])
75 lines.append(indent(':CLI option: ' + fmt_aliases, 4))
75 lines.append(indent(':CLI option: ' + fmt_aliases, 4))
76
76
77 # Blank line
77 # Blank line
78 lines.append('')
78 lines.append('')
79
79
80 return '\n'.join(lines)
80 return '\n'.join(lines)
81
81
82 def reverse_aliases(app):
82 def reverse_aliases(app):
83 """Produce a mapping of trait names to lists of command line aliases.
83 """Produce a mapping of trait names to lists of command line aliases.
84 """
84 """
85 res = defaultdict(list)
85 res = defaultdict(list)
86 for alias, trait in app.aliases.items():
86 for alias, trait in app.aliases.items():
87 res[trait].append(alias)
87 res[trait].append(alias)
88
88
89 # Flags also often act as aliases for a boolean trait.
89 # Flags also often act as aliases for a boolean trait.
90 # Treat flags which set one trait to True as aliases.
90 # Treat flags which set one trait to True as aliases.
91 for flag, (cfg, _) in app.flags.items():
91 for flag, (cfg, _) in app.flags.items():
92 if len(cfg) == 1:
92 if len(cfg) == 1:
93 classname = list(cfg)[0]
93 classname = list(cfg)[0]
94 cls_cfg = cfg[classname]
94 cls_cfg = cfg[classname]
95 if len(cls_cfg) == 1:
95 if len(cls_cfg) == 1:
96 traitname = list(cls_cfg)[0]
96 traitname = list(cls_cfg)[0]
97 if cls_cfg[traitname] is True:
97 if cls_cfg[traitname] is True:
98 res[classname+'.'+traitname].append(flag)
98 res[classname+'.'+traitname].append(flag)
99
99
100 return res
100 return res
101
101
102 def write_doc(name, title, app, preamble=None):
102 def write_doc(name, title, app, preamble=None):
103 trait_aliases = reverse_aliases(app)
103 trait_aliases = reverse_aliases(app)
104 filename = options / (name + ".rst")
104 filename = options / (name + ".rst")
105 with open(filename, "w", encoding="utf-8") as f:
105 with open(filename, "w", encoding="utf-8") as f:
106 f.write(".. _" + name + "_options:" + "\n\n")
106 f.write(title + "\n")
107 f.write(title + "\n")
107 f.write(("=" * len(title)) + "\n")
108 f.write(("=" * len(title)) + "\n")
108 f.write("\n")
109 f.write("\n")
109 if preamble is not None:
110 if preamble is not None:
110 f.write(preamble + '\n\n')
111 f.write(preamble + '\n\n')
111 #f.write(app.document_config_options())
112 #f.write(app.document_config_options())
112
113
113 for c in app._classes_inc_parents():
114 for c in app._classes_inc_parents():
114 f.write(class_config_rst_doc(c, trait_aliases))
115 f.write(class_config_rst_doc(c, trait_aliases))
115 f.write('\n')
116 f.write('\n')
116
117
117
118
118 if __name__ == '__main__':
119 if __name__ == '__main__':
119 # Touch this file for the make target
120 # Touch this file for the make target
120 Path(generated).write_text("", encoding="utf-8")
121 Path(generated).write_text("", encoding="utf-8")
121
122
122 write_doc('terminal', 'Terminal IPython options', TerminalIPythonApp())
123 write_doc('terminal', 'Terminal IPython options', TerminalIPythonApp())
123 write_doc('kernel', 'IPython kernel options', IPKernelApp(),
124 write_doc('kernel', 'IPython kernel options', IPKernelApp(),
124 preamble=("These options can be used in :file:`ipython_kernel_config.py`. "
125 preamble=("These options can be used in :file:`ipython_kernel_config.py`. "
125 "The kernel also respects any options in `ipython_config.py`"),
126 "The kernel also respects any options in `ipython_config.py`"),
126 )
127 )
@@ -1,221 +1,221 b''
1 from dataclasses import dataclass
1 from dataclasses import dataclass
2 from inspect import getsource
2 from inspect import getsource
3 from pathlib import Path
3 from pathlib import Path
4 from typing import cast, List, Union
4 from typing import cast, List, Union
5 from html import escape as html_escape
5 from html import escape as html_escape
6 import re
6 import re
7
7
8 from prompt_toolkit.keys import KEY_ALIASES
8 from prompt_toolkit.keys import KEY_ALIASES
9 from prompt_toolkit.key_binding import KeyBindingsBase
9 from prompt_toolkit.key_binding import KeyBindingsBase
10 from prompt_toolkit.filters import Filter, Condition
10 from prompt_toolkit.filters import Filter, Condition
11 from prompt_toolkit.shortcuts import PromptSession
11 from prompt_toolkit.shortcuts import PromptSession
12
12
13 from IPython.terminal.shortcuts import create_ipython_shortcuts, create_identifier
13 from IPython.terminal.shortcuts import create_ipython_shortcuts, create_identifier
14 from IPython.terminal.shortcuts.filters import KEYBINDING_FILTERS
14 from IPython.terminal.shortcuts.filters import KEYBINDING_FILTERS
15
15
16
16
17 @dataclass
17 @dataclass
18 class Shortcut:
18 class Shortcut:
19 #: a sequence of keys (each element on the list corresponds to pressing one or more keys)
19 #: a sequence of keys (each element on the list corresponds to pressing one or more keys)
20 keys_sequence: list[str]
20 keys_sequence: List[str]
21 filter: str
21 filter: str
22
22
23
23
24 @dataclass
24 @dataclass
25 class Handler:
25 class Handler:
26 description: str
26 description: str
27 identifier: str
27 identifier: str
28
28
29
29
30 @dataclass
30 @dataclass
31 class Binding:
31 class Binding:
32 handler: Handler
32 handler: Handler
33 shortcut: Shortcut
33 shortcut: Shortcut
34
34
35
35
36 class _NestedFilter(Filter):
36 class _NestedFilter(Filter):
37 """Protocol reflecting non-public prompt_toolkit's `_AndList` and `_OrList`."""
37 """Protocol reflecting non-public prompt_toolkit's `_AndList` and `_OrList`."""
38
38
39 filters: List[Filter]
39 filters: List[Filter]
40
40
41
41
42 class _Invert(Filter):
42 class _Invert(Filter):
43 """Protocol reflecting non-public prompt_toolkit's `_Invert`."""
43 """Protocol reflecting non-public prompt_toolkit's `_Invert`."""
44
44
45 filter: Filter
45 filter: Filter
46
46
47
47
48 conjunctions_labels = {"_AndList": "&", "_OrList": "|"}
48 conjunctions_labels = {"_AndList": "&", "_OrList": "|"}
49
49
50 ATOMIC_CLASSES = {"Never", "Always", "Condition"}
50 ATOMIC_CLASSES = {"Never", "Always", "Condition"}
51
51
52
52
53 HUMAN_NAMES_FOR_FILTERS = {
53 HUMAN_NAMES_FOR_FILTERS = {
54 filter_: name for name, filter_ in KEYBINDING_FILTERS.items()
54 filter_: name for name, filter_ in KEYBINDING_FILTERS.items()
55 }
55 }
56
56
57
57
58 def format_filter(
58 def format_filter(
59 filter_: Union[Filter, _NestedFilter, Condition, _Invert],
59 filter_: Union[Filter, _NestedFilter, Condition, _Invert],
60 is_top_level=True,
60 is_top_level=True,
61 skip=None,
61 skip=None,
62 ) -> str:
62 ) -> str:
63 """Create easily readable description of the filter."""
63 """Create easily readable description of the filter."""
64 s = filter_.__class__.__name__
64 s = filter_.__class__.__name__
65 if s == "Condition":
65 if s == "Condition":
66 func = cast(Condition, filter_).func
66 func = cast(Condition, filter_).func
67 if filter_ in HUMAN_NAMES_FOR_FILTERS:
67 if filter_ in HUMAN_NAMES_FOR_FILTERS:
68 return HUMAN_NAMES_FOR_FILTERS[filter_]
68 return HUMAN_NAMES_FOR_FILTERS[filter_]
69 name = func.__name__
69 name = func.__name__
70 if name == "<lambda>":
70 if name == "<lambda>":
71 source = getsource(func)
71 source = getsource(func)
72 return source.split("=")[0].strip()
72 return source.split("=")[0].strip()
73 return func.__name__
73 return func.__name__
74 elif s == "_Invert":
74 elif s == "_Invert":
75 operand = cast(_Invert, filter_).filter
75 operand = cast(_Invert, filter_).filter
76 if operand.__class__.__name__ in ATOMIC_CLASSES:
76 if operand.__class__.__name__ in ATOMIC_CLASSES:
77 return f"~{format_filter(operand, is_top_level=False)}"
77 return f"~{format_filter(operand, is_top_level=False)}"
78 return f"~({format_filter(operand, is_top_level=False)})"
78 return f"~({format_filter(operand, is_top_level=False)})"
79 elif s in conjunctions_labels:
79 elif s in conjunctions_labels:
80 filters = cast(_NestedFilter, filter_).filters
80 filters = cast(_NestedFilter, filter_).filters
81 if filter_ in HUMAN_NAMES_FOR_FILTERS:
81 if filter_ in HUMAN_NAMES_FOR_FILTERS:
82 return HUMAN_NAMES_FOR_FILTERS[filter_]
82 return HUMAN_NAMES_FOR_FILTERS[filter_]
83 conjunction = conjunctions_labels[s]
83 conjunction = conjunctions_labels[s]
84 glue = f" {conjunction} "
84 glue = f" {conjunction} "
85 result = glue.join(format_filter(x, is_top_level=False) for x in filters)
85 result = glue.join(format_filter(x, is_top_level=False) for x in filters)
86 if len(filters) > 1 and not is_top_level:
86 if len(filters) > 1 and not is_top_level:
87 result = f"({result})"
87 result = f"({result})"
88 return result
88 return result
89 elif s in ["Never", "Always"]:
89 elif s in ["Never", "Always"]:
90 return s.lower()
90 return s.lower()
91 else:
91 else:
92 raise ValueError(f"Unknown filter type: {filter_}")
92 raise ValueError(f"Unknown filter type: {filter_}")
93
93
94
94
95 def sentencize(s) -> str:
95 def sentencize(s) -> str:
96 """Extract first sentence"""
96 """Extract first sentence"""
97 s = re.split(r"\.\W", s.replace("\n", " ").strip())
97 s = re.split(r"\.\W", s.replace("\n", " ").strip())
98 s = s[0] if len(s) else ""
98 s = s[0] if len(s) else ""
99 if not s.endswith("."):
99 if not s.endswith("."):
100 s += "."
100 s += "."
101 try:
101 try:
102 return " ".join(s.split())
102 return " ".join(s.split())
103 except AttributeError:
103 except AttributeError:
104 return s
104 return s
105
105
106
106
107 class _DummyTerminal:
107 class _DummyTerminal:
108 """Used as a buffer to get prompt_toolkit bindings
108 """Used as a buffer to get prompt_toolkit bindings
109 """
109 """
110 handle_return = None
110 handle_return = None
111 input_transformer_manager = None
111 input_transformer_manager = None
112 display_completions = None
112 display_completions = None
113 editing_mode = "emacs"
113 editing_mode = "emacs"
114 auto_suggest = None
114 auto_suggest = None
115
115
116
116
117 def bindings_from_prompt_toolkit(prompt_bindings: KeyBindingsBase) -> List[Binding]:
117 def bindings_from_prompt_toolkit(prompt_bindings: KeyBindingsBase) -> List[Binding]:
118 """Collect bindings to a simple format that does not depend on prompt-toolkit internals"""
118 """Collect bindings to a simple format that does not depend on prompt-toolkit internals"""
119 bindings: List[Binding] = []
119 bindings: List[Binding] = []
120
120
121 for kb in prompt_bindings.bindings:
121 for kb in prompt_bindings.bindings:
122 bindings.append(
122 bindings.append(
123 Binding(
123 Binding(
124 handler=Handler(
124 handler=Handler(
125 description=kb.handler.__doc__ or "",
125 description=kb.handler.__doc__ or "",
126 identifier=create_identifier(kb.handler),
126 identifier=create_identifier(kb.handler),
127 ),
127 ),
128 shortcut=Shortcut(
128 shortcut=Shortcut(
129 keys_sequence=[
129 keys_sequence=[
130 str(k.value) if hasattr(k, "value") else k for k in kb.keys
130 str(k.value) if hasattr(k, "value") else k for k in kb.keys
131 ],
131 ],
132 filter=format_filter(kb.filter, skip={"has_focus_filter"}),
132 filter=format_filter(kb.filter, skip={"has_focus_filter"}),
133 ),
133 ),
134 )
134 )
135 )
135 )
136 return bindings
136 return bindings
137
137
138
138
139 INDISTINGUISHABLE_KEYS = {**KEY_ALIASES, **{v: k for k, v in KEY_ALIASES.items()}}
139 INDISTINGUISHABLE_KEYS = {**KEY_ALIASES, **{v: k for k, v in KEY_ALIASES.items()}}
140
140
141
141
142 def format_prompt_keys(keys: str, add_alternatives=True) -> str:
142 def format_prompt_keys(keys: str, add_alternatives=True) -> str:
143 """Format prompt toolkit key with modifier into an RST representation."""
143 """Format prompt toolkit key with modifier into an RST representation."""
144
144
145 def to_rst(key):
145 def to_rst(key):
146 escaped = key.replace("\\", "\\\\")
146 escaped = key.replace("\\", "\\\\")
147 return f":kbd:`{escaped}`"
147 return f":kbd:`{escaped}`"
148
148
149 keys_to_press: list[str]
149 keys_to_press: List[str]
150
150
151 prefixes = {
151 prefixes = {
152 "c-s-": [to_rst("ctrl"), to_rst("shift")],
152 "c-s-": [to_rst("ctrl"), to_rst("shift")],
153 "s-c-": [to_rst("ctrl"), to_rst("shift")],
153 "s-c-": [to_rst("ctrl"), to_rst("shift")],
154 "c-": [to_rst("ctrl")],
154 "c-": [to_rst("ctrl")],
155 "s-": [to_rst("shift")],
155 "s-": [to_rst("shift")],
156 }
156 }
157
157
158 for prefix, modifiers in prefixes.items():
158 for prefix, modifiers in prefixes.items():
159 if keys.startswith(prefix):
159 if keys.startswith(prefix):
160 remainder = keys[len(prefix) :]
160 remainder = keys[len(prefix) :]
161 keys_to_press = [*modifiers, to_rst(remainder)]
161 keys_to_press = [*modifiers, to_rst(remainder)]
162 break
162 break
163 else:
163 else:
164 keys_to_press = [to_rst(keys)]
164 keys_to_press = [to_rst(keys)]
165
165
166 result = " + ".join(keys_to_press)
166 result = " + ".join(keys_to_press)
167
167
168 if keys in INDISTINGUISHABLE_KEYS and add_alternatives:
168 if keys in INDISTINGUISHABLE_KEYS and add_alternatives:
169 alternative = INDISTINGUISHABLE_KEYS[keys]
169 alternative = INDISTINGUISHABLE_KEYS[keys]
170
170
171 result = (
171 result = (
172 result
172 result
173 + " (or "
173 + " (or "
174 + format_prompt_keys(alternative, add_alternatives=False)
174 + format_prompt_keys(alternative, add_alternatives=False)
175 + ")"
175 + ")"
176 )
176 )
177
177
178 return result
178 return result
179
179
180
180
181 if __name__ == '__main__':
181 if __name__ == '__main__':
182 here = Path(__file__).parent
182 here = Path(__file__).parent
183 dest = here / "source" / "config" / "shortcuts"
183 dest = here / "source" / "config" / "shortcuts"
184
184
185 ipy_bindings = create_ipython_shortcuts(_DummyTerminal())
185 ipy_bindings = create_ipython_shortcuts(_DummyTerminal())
186
186
187 session = PromptSession(key_bindings=ipy_bindings)
187 session = PromptSession(key_bindings=ipy_bindings)
188 prompt_bindings = session.app.key_bindings
188 prompt_bindings = session.app.key_bindings
189
189
190 assert prompt_bindings
190 assert prompt_bindings
191 # Ensure that we collected the default shortcuts
191 # Ensure that we collected the default shortcuts
192 assert len(prompt_bindings.bindings) > len(ipy_bindings.bindings)
192 assert len(prompt_bindings.bindings) > len(ipy_bindings.bindings)
193
193
194 bindings = bindings_from_prompt_toolkit(prompt_bindings)
194 bindings = bindings_from_prompt_toolkit(prompt_bindings)
195
195
196 def sort_key(binding: Binding):
196 def sort_key(binding: Binding):
197 return binding.handler.identifier, binding.shortcut.filter
197 return binding.handler.identifier, binding.shortcut.filter
198
198
199 filters = []
199 filters = []
200 with (dest / "table.tsv").open("w", encoding="utf-8") as csv:
200 with (dest / "table.tsv").open("w", encoding="utf-8") as csv:
201 for binding in sorted(bindings, key=sort_key):
201 for binding in sorted(bindings, key=sort_key):
202 sequence = ", ".join(
202 sequence = ", ".join(
203 [format_prompt_keys(keys) for keys in binding.shortcut.keys_sequence]
203 [format_prompt_keys(keys) for keys in binding.shortcut.keys_sequence]
204 )
204 )
205 if binding.shortcut.filter == "always":
205 if binding.shortcut.filter == "always":
206 condition_label = "-"
206 condition_label = "-"
207 else:
207 else:
208 # we cannot fit all the columns as the filters got too complex over time
208 # we cannot fit all the columns as the filters got too complex over time
209 condition_label = "ⓘ"
209 condition_label = "ⓘ"
210
210
211 csv.write(
211 csv.write(
212 "\t".join(
212 "\t".join(
213 [
213 [
214 sequence,
214 sequence,
215 sentencize(binding.handler.description)
215 sentencize(binding.handler.description)
216 + f" :raw-html:`<br>` `{binding.handler.identifier}`",
216 + f" :raw-html:`<br>` `{binding.handler.identifier}`",
217 f':raw-html:`<span title="{html_escape(binding.shortcut.filter)}" style="cursor: help">{condition_label}</span>`',
217 f':raw-html:`<span title="{html_escape(binding.shortcut.filter)}" style="cursor: help">{condition_label}</span>`',
218 ]
218 ]
219 )
219 )
220 + "\n"
220 + "\n"
221 )
221 )
@@ -1,235 +1,235 b''
1 =====================================
1 =====================================
2 Introduction to IPython configuration
2 Introduction to IPython configuration
3 =====================================
3 =====================================
4
4
5 .. _setting_config:
5 .. _setting_config:
6
6
7 Setting configurable options
7 Setting configurable options
8 ============================
8 ============================
9
9
10 Many of IPython's classes have configurable attributes (see
10 Many of IPython's classes have configurable attributes (see
11 :doc:`options/index` for the list). These can be
11 :doc:`options/index` for the list). These can be
12 configured in several ways.
12 configured in several ways.
13
13
14 Python configuration files
14 Python configuration files
15 --------------------------
15 --------------------------
16
16
17 To create the blank configuration files, run::
17 To create the blank configuration files, run::
18
18
19 ipython profile create [profilename]
19 ipython profile create [profilename]
20
20
21 If you leave out the profile name, the files will be created for the
21 If you leave out the profile name, the files will be created for the
22 ``default`` profile (see :ref:`profiles`). These will typically be located in
22 ``default`` profile (see :ref:`profiles`). These will typically be located in
23 :file:`~/.ipython/profile_default/`, and will be named
23 :file:`~/.ipython/profile_default/`, and will be named
24 :file:`ipython_config.py`, for historical reasons you may also find files
24 :file:`ipython_config.py`, for historical reasons you may also find files
25 named with IPython prefix instead of Jupyter:
25 named with IPython prefix instead of Jupyter:
26 :file:`ipython_notebook_config.py`, etc. The settings in
26 :file:`ipython_notebook_config.py`, etc. The settings in
27 :file:`ipython_config.py` apply to all IPython commands.
27 :file:`ipython_config.py` apply to all IPython commands.
28
28
29 By default, configuration files are fully featured Python scripts that can
29 By default, configuration files are fully featured Python scripts that can
30 execute arbitrary code, the main usage is to set value on the configuration
30 execute arbitrary code, the main usage is to set value on the configuration
31 object ``c`` which exist in your configuration file.
31 object ``c`` which exist in your configuration file.
32
32
33 You can then configure class attributes like this::
33 You can then configure class attributes like this::
34
34
35 c.InteractiveShell.automagic = False
35 c.InteractiveShell.automagic = False
36
36
37 Be careful with spelling--incorrect names will simply be ignored, with
37 Be careful with spelling--incorrect names will simply be ignored, with
38 no error.
38 no error.
39
39
40 To add to a collection which may have already been defined elsewhere or have
40 To add to a collection which may have already been defined elsewhere or have
41 default values, you can use methods like those found on lists, dicts and
41 default values, you can use methods like those found on lists, dicts and
42 sets: append, extend, :meth:`~traitlets.config.LazyConfigValue.prepend` (like
42 sets: append, extend, :meth:`~traitlets.config.LazyConfigValue.prepend` (like
43 extend, but at the front), add and update (which works both for dicts and
43 extend, but at the front), add and update (which works both for dicts and
44 sets)::
44 sets)::
45
45
46 c.InteractiveShellApp.extensions.append('Cython')
46 c.InteractiveShellApp.extensions.append('Cython')
47
47
48 .. versionadded:: 2.0
48 .. versionadded:: 2.0
49 list, dict and set methods for config values
49 list, dict and set methods for config values
50
50
51 Example configuration file
51 Example configuration file
52 ``````````````````````````
52 ``````````````````````````
53
53
54 ::
54 ::
55
55
56 # sample ipython_config.py
56 # sample ipython_config.py
57
57
58 c.TerminalIPythonApp.display_banner = True
58 c.TerminalIPythonApp.display_banner = True
59 c.InteractiveShellApp.log_level = 20
59 c.InteractiveShellApp.log_level = 20
60 c.InteractiveShellApp.extensions = [
60 c.InteractiveShellApp.extensions = [
61 'myextension'
61 'myextension'
62 ]
62 ]
63 c.InteractiveShellApp.exec_lines = [
63 c.InteractiveShellApp.exec_lines = [
64 'import numpy',
64 'import numpy',
65 'import scipy'
65 'import scipy'
66 ]
66 ]
67 c.InteractiveShellApp.exec_files = [
67 c.InteractiveShellApp.exec_files = [
68 'mycode.py',
68 'mycode.py',
69 'fancy.ipy'
69 'fancy.ipy'
70 ]
70 ]
71 c.InteractiveShell.colors = 'LightBG'
71 c.InteractiveShell.colors = 'LightBG'
72 c.InteractiveShell.xmode = 'Context'
72 c.InteractiveShell.xmode = 'Context'
73 c.TerminalInteractiveShell.confirm_exit = False
73 c.TerminalInteractiveShell.confirm_exit = False
74 c.TerminalInteractiveShell.editor = 'nano'
74 c.TerminalInteractiveShell.editor = 'nano'
75
75
76 c.PrefilterManager.multi_line_specials = True
76 c.PrefilterManager.multi_line_specials = True
77
77
78 c.AliasManager.user_aliases = [
78 c.AliasManager.user_aliases = [
79 ('la', 'ls -al')
79 ('la', 'ls -al')
80 ]
80 ]
81
81
82 JSON Configuration files
82 JSON Configuration files
83 ------------------------
83 ------------------------
84
84
85 In case where executability of configuration can be problematic, or
85 In case where executability of configuration can be problematic, or
86 configurations need to be modified programmatically, IPython also support a
86 configurations need to be modified programmatically, IPython also support a
87 limited set of functionalities via ``.json`` configuration files.
87 limited set of functionalities via ``.json`` configuration files.
88
88
89 You can defined most of the configuration options via a json object which
89 You can defined most of the configuration options via a json object which
90 hierarchy represent the value you would normally set on the ``c`` object of
90 hierarchy represent the value you would normally set on the ``c`` object of
91 ``.py`` configuration files. The following ``ipython_config.json`` file::
91 ``.py`` configuration files. The following ``ipython_config.json`` file::
92
92
93 {
93 {
94 "InteractiveShell": {
94 "InteractiveShell": {
95 "colors": "LightBG",
95 "colors": "LightBG",
96 },
96 },
97 "InteractiveShellApp": {
97 "InteractiveShellApp": {
98 "extensions": [
98 "extensions": [
99 "myextension"
99 "myextension"
100 ]
100 ]
101 },
101 },
102 "TerminalInteractiveShell": {
102 "TerminalInteractiveShell": {
103 "editor": "nano"
103 "editor": "nano"
104 }
104 }
105 }
105 }
106
106
107 Is equivalent to the following ``ipython_config.py``::
107 Is equivalent to the following ``ipython_config.py``::
108
108
109 c.InteractiveShellApp.extensions = [
109 c.InteractiveShellApp.extensions = [
110 'myextension'
110 'myextension'
111 ]
111 ]
112
112
113 c.InteractiveShell.colors = 'LightBG'
113 c.InteractiveShell.colors = 'LightBG'
114 c.TerminalInteractiveShell.editor = 'nano'
114 c.TerminalInteractiveShell.editor = 'nano'
115
115
116
116
117 Command line arguments
117 Command line arguments
118 ----------------------
118 ----------------------
119
119
120 Every configurable value can be set from the command line, using this
120 Every configurable value can be set from the command line, using this
121 syntax::
121 syntax::
122
122
123 ipython --ClassName.attribute=value
123 ipython --ClassName.attribute=value
124
124
125 Many frequently used options have short aliases and flags, such as
125 Many frequently used options have short aliases and flags, such as
126 ``--matplotlib`` (to integrate with a matplotlib GUI event loop) or
126 ``--matplotlib`` (to integrate with a matplotlib GUI event loop) or
127 ``--pdb`` (automatic post-mortem debugging of exceptions).
127 ``--pdb`` (automatic post-mortem debugging of exceptions).
128
128
129 To see all of these abbreviated options, run::
129 To see all of these abbreviated options, run::
130
130
131 ipython --help
131 ipython --help
132 jupyter notebook --help
132 jupyter notebook --help
133 # etc.
133 # etc.
134
134
135 Options specified at the command line, in either format, override
135 Options specified at the command line, in either format, override
136 options set in a configuration file.
136 options set in a configuration file.
137
137
138 The config magic
138 The config magic
139 ----------------
139 ----------------
140
140
141 You can also modify config from inside IPython, using a magic command::
141 You can also modify config from inside IPython, using a magic command::
142
142
143 %config IPCompleter.greedy = True
143 %config IPCompleter.greedy = True
144
144
145 At present, this only affects the current session - changes you make to
145 At present, this only affects the current session - changes you make to
146 config are not saved anywhere. Also, some options are only read when
146 config are not saved anywhere. Also, some options are only read when
147 IPython starts, so they can't be changed like this.
147 IPython starts, so they can't be changed like this.
148
148
149 .. _configure_start_ipython:
149 .. _configure_start_ipython:
150
150
151 Running IPython from Python
151 Running IPython from Python
152 ----------------------------
152 ----------------------------
153
153
154 If you are using :ref:`embedding` to start IPython from a normal
154 If you are using :ref:`embedding` to start IPython from a normal
155 python file, you can set configuration options the same way as in a
155 python file, you can set configuration options the same way as in a
156 config file by creating a traitlets config object and passing it to
156 config file by creating a traitlets :class:`Config` object and passing it to
157 start_ipython like in the example below.
157 start_ipython like in the example below.
158
158
159 .. literalinclude:: ../../../examples/Embedding/start_ipython_config.py
159 .. literalinclude:: ../../../examples/Embedding/start_ipython_config.py
160 :language: python
160 :language: python
161
161
162 .. _profiles:
162 .. _profiles:
163
163
164 Profiles
164 Profiles
165 ========
165 ========
166
166
167 IPython can use multiple profiles, with separate configuration and
167 IPython can use multiple profiles, with separate configuration and
168 history. By default, if you don't specify a profile, IPython always runs
168 history. By default, if you don't specify a profile, IPython always runs
169 in the ``default`` profile. To use a new profile::
169 in the ``default`` profile. To use a new profile::
170
170
171 ipython profile create foo # create the profile foo
171 ipython profile create foo # create the profile foo
172 ipython --profile=foo # start IPython using the new profile
172 ipython --profile=foo # start IPython using the new profile
173
173
174 Profiles are typically stored in :ref:`ipythondir`, but you can also keep
174 Profiles are typically stored in :ref:`ipythondir`, but you can also keep
175 a profile in the current working directory, for example to distribute it
175 a profile in the current working directory, for example to distribute it
176 with a project. To find a profile directory on the filesystem::
176 with a project. To find a profile directory on the filesystem::
177
177
178 ipython locate profile foo
178 ipython locate profile foo
179
179
180 .. _ipythondir:
180 .. _ipythondir:
181
181
182 The IPython directory
182 The IPython directory
183 =====================
183 =====================
184
184
185 IPython stores its files---config, command history and extensions---in
185 IPython stores its files---config, command history and extensions---in
186 the directory :file:`~/.ipython/` by default.
186 the directory :file:`~/.ipython/` by default.
187
187
188 .. envvar:: IPYTHONDIR
188 .. envvar:: IPYTHONDIR
189
189
190 If set, this environment variable should be the path to a directory,
190 If set, this environment variable should be the path to a directory,
191 which IPython will use for user data. IPython will create it if it
191 which IPython will use for user data. IPython will create it if it
192 does not exist.
192 does not exist.
193
193
194 .. option:: --ipython-dir=<path>
194 .. option:: --ipython-dir=<path>
195
195
196 This command line option can also be used to override the default
196 This command line option can also be used to override the default
197 IPython directory.
197 IPython directory.
198
198
199 To see where IPython is looking for the IPython directory, use the command
199 To see where IPython is looking for the IPython directory, use the command
200 ``ipython locate``, or the Python function :func:`IPython.paths.get_ipython_dir`.
200 ``ipython locate``, or the Python function :func:`IPython.paths.get_ipython_dir`.
201
201
202
202
203 Systemwide configuration
203 Systemwide configuration
204 ========================
204 ========================
205
205
206 It can be useful to deploy systemwide ipython or ipykernel configuration
206 It can be useful to deploy systemwide ipython or ipykernel configuration
207 when managing environment for many users. At startup time IPython and
207 when managing environment for many users. At startup time IPython and
208 IPykernel will search for configuration file in multiple systemwide
208 IPykernel will search for configuration file in multiple systemwide
209 locations, mainly:
209 locations, mainly:
210
210
211 - ``/etc/ipython/``
211 - ``/etc/ipython/``
212 - ``/usr/local/etc/ipython/``
212 - ``/usr/local/etc/ipython/``
213
213
214 When the global install is a standalone python distribution it may also
214 When the global install is a standalone python distribution it may also
215 search in distribution specific location, for example:
215 search in distribution specific location, for example:
216
216
217 - ``$ANACONDA_LOCATION/etc/ipython/``
217 - ``$ANACONDA_LOCATION/etc/ipython/``
218
218
219 In those locations, Terminal IPython will look for a file called
219 In those locations, Terminal IPython will look for a file called
220 ``ipython_config.py`` and ``ipython_config.json``, ipykernel will look for
220 ``ipython_config.py`` and ``ipython_config.json``, ipykernel will look for
221 ``ipython_kernel_config.py`` and ``ipython_kernel.json``.
221 ``ipython_kernel_config.py`` and ``ipython_kernel.json``.
222
222
223 Configuration files are loaded in order and merged with configuration on
223 Configuration files are loaded in order and merged with configuration on
224 later location taking precedence on earlier locations (that is to say a user
224 later location taking precedence on earlier locations (that is to say a user
225 can overwrite a systemwide configuration option).
225 can overwrite a systemwide configuration option).
226
226
227 You can see all locations in which IPython is looking for configuration files
227 You can see all locations in which IPython is looking for configuration files
228 by starting ipython in debug mode::
228 by starting ipython in debug mode::
229
229
230 $ ipython --debug -c 'exit()'
230 $ ipython --debug -c 'exit()'
231
231
232 Identically with ipykernel though the command is currently blocking until
232 Identically with ipykernel though the command is currently blocking until
233 this process is killed with ``Ctrl-\``::
233 this process is killed with ``Ctrl-\``::
234
234
235 $ python -m ipykernel --debug
235 $ python -m ipykernel --debug
@@ -1,12 +1,12 b''
1 ===============
1 ===============
2 IPython options
2 IPython options
3 ===============
3 ===============
4
4
5 Any of the options listed here can be set in config files, at the
5 Any of the options listed here can be set in config files, at the
6 command line, or from inside IPython. See :ref:`setting_config` for
6 command line, from inside IPython, or using a traitlets :class:`Config` object.
7 details.
7 See :ref:`setting_config` for details.
8
8
9 .. toctree::
9 .. toctree::
10
10
11 terminal
11 terminal
12 kernel
12 kernel
General Comments 0
You need to be logged in to leave comments. Login now