##// END OF EJS Templates
Simplify color definition. (#14291)...
M Bussonnier -
r28588:b14df380 merge
parent child Browse files
Show More
@@ -1,258 +1,264 b''
1 1 # encoding: utf-8
2 2 """
3 3 System command aliases.
4 4
5 5 Authors:
6 6
7 7 * Fernando Perez
8 8 * Brian Granger
9 9 """
10 10
11 11 #-----------------------------------------------------------------------------
12 12 # Copyright (C) 2008-2011 The IPython Development Team
13 13 #
14 14 # Distributed under the terms of the BSD License.
15 15 #
16 16 # The full license is in the file COPYING.txt, distributed with this software.
17 17 #-----------------------------------------------------------------------------
18 18
19 19 #-----------------------------------------------------------------------------
20 20 # Imports
21 21 #-----------------------------------------------------------------------------
22 22
23 23 import os
24 24 import re
25 25 import sys
26 26
27 27 from traitlets.config.configurable import Configurable
28 28 from .error import UsageError
29 29
30 30 from traitlets import List, Instance
31 31 from logging import error
32 32
33 33 #-----------------------------------------------------------------------------
34 34 # Utilities
35 35 #-----------------------------------------------------------------------------
36 36
37 37 # This is used as the pattern for calls to split_user_input.
38 38 shell_line_split = re.compile(r'^(\s*)()(\S+)(.*$)')
39 39
40 40 def default_aliases():
41 41 """Return list of shell aliases to auto-define.
42 42 """
43 43 # Note: the aliases defined here should be safe to use on a kernel
44 44 # regardless of what frontend it is attached to. Frontends that use a
45 45 # kernel in-process can define additional aliases that will only work in
46 46 # their case. For example, things like 'less' or 'clear' that manipulate
47 47 # the terminal should NOT be declared here, as they will only work if the
48 48 # kernel is running inside a true terminal, and not over the network.
49 49
50 50 if os.name == 'posix':
51 51 default_aliases = [('mkdir', 'mkdir'), ('rmdir', 'rmdir'),
52 52 ('mv', 'mv'), ('rm', 'rm'), ('cp', 'cp'),
53 53 ('cat', 'cat'),
54 54 ]
55 55 # Useful set of ls aliases. The GNU and BSD options are a little
56 56 # different, so we make aliases that provide as similar as possible
57 57 # behavior in ipython, by passing the right flags for each platform
58 58 if sys.platform.startswith('linux'):
59 59 ls_aliases = [('ls', 'ls -F --color'),
60 60 # long ls
61 61 ('ll', 'ls -F -o --color'),
62 62 # ls normal files only
63 63 ('lf', 'ls -F -o --color %l | grep ^-'),
64 64 # ls symbolic links
65 65 ('lk', 'ls -F -o --color %l | grep ^l'),
66 66 # directories or links to directories,
67 67 ('ldir', 'ls -F -o --color %l | grep /$'),
68 68 # things which are executable
69 69 ('lx', 'ls -F -o --color %l | grep ^-..x'),
70 70 ]
71 71 elif sys.platform.startswith('openbsd') or sys.platform.startswith('netbsd'):
72 72 # OpenBSD, NetBSD. The ls implementation on these platforms do not support
73 73 # the -G switch and lack the ability to use colorized output.
74 74 ls_aliases = [('ls', 'ls -F'),
75 75 # long ls
76 76 ('ll', 'ls -F -l'),
77 77 # ls normal files only
78 78 ('lf', 'ls -F -l %l | grep ^-'),
79 79 # ls symbolic links
80 80 ('lk', 'ls -F -l %l | grep ^l'),
81 81 # directories or links to directories,
82 82 ('ldir', 'ls -F -l %l | grep /$'),
83 83 # things which are executable
84 84 ('lx', 'ls -F -l %l | grep ^-..x'),
85 85 ]
86 86 else:
87 87 # BSD, OSX, etc.
88 88 ls_aliases = [('ls', 'ls -F -G'),
89 89 # long ls
90 90 ('ll', 'ls -F -l -G'),
91 91 # ls normal files only
92 92 ('lf', 'ls -F -l -G %l | grep ^-'),
93 93 # ls symbolic links
94 94 ('lk', 'ls -F -l -G %l | grep ^l'),
95 95 # directories or links to directories,
96 96 ('ldir', 'ls -F -G -l %l | grep /$'),
97 97 # things which are executable
98 98 ('lx', 'ls -F -l -G %l | grep ^-..x'),
99 99 ]
100 100 default_aliases = default_aliases + ls_aliases
101 101 elif os.name in ['nt', 'dos']:
102 102 default_aliases = [('ls', 'dir /on'),
103 103 ('ddir', 'dir /ad /on'), ('ldir', 'dir /ad /on'),
104 104 ('mkdir', 'mkdir'), ('rmdir', 'rmdir'),
105 105 ('echo', 'echo'), ('ren', 'ren'), ('copy', 'copy'),
106 106 ]
107 107 else:
108 108 default_aliases = []
109 109
110 110 return default_aliases
111 111
112 112
113 113 class AliasError(Exception):
114 114 pass
115 115
116 116
117 117 class InvalidAliasError(AliasError):
118 118 pass
119 119
120 120 class Alias(object):
121 121 """Callable object storing the details of one alias.
122 122
123 123 Instances are registered as magic functions to allow use of aliases.
124 124 """
125 125
126 126 # Prepare blacklist
127 127 blacklist = {'cd','popd','pushd','dhist','alias','unalias'}
128 128
129 129 def __init__(self, shell, name, cmd):
130 130 self.shell = shell
131 131 self.name = name
132 132 self.cmd = cmd
133 133 self.__doc__ = "Alias for `!{}`".format(cmd)
134 134 self.nargs = self.validate()
135 135
136 136 def validate(self):
137 137 """Validate the alias, and return the number of arguments."""
138 138 if self.name in self.blacklist:
139 139 raise InvalidAliasError("The name %s can't be aliased "
140 140 "because it is a keyword or builtin." % self.name)
141 141 try:
142 142 caller = self.shell.magics_manager.magics['line'][self.name]
143 143 except KeyError:
144 144 pass
145 145 else:
146 146 if not isinstance(caller, Alias):
147 147 raise InvalidAliasError("The name %s can't be aliased "
148 148 "because it is another magic command." % self.name)
149 149
150 150 if not (isinstance(self.cmd, str)):
151 151 raise InvalidAliasError("An alias command must be a string, "
152 152 "got: %r" % self.cmd)
153 153
154 154 nargs = self.cmd.count('%s') - self.cmd.count('%%s')
155 155
156 156 if (nargs > 0) and (self.cmd.find('%l') >= 0):
157 157 raise InvalidAliasError('The %s and %l specifiers are mutually '
158 158 'exclusive in alias definitions.')
159 159
160 160 return nargs
161 161
162 162 def __repr__(self):
163 163 return "<alias {} for {!r}>".format(self.name, self.cmd)
164 164
165 165 def __call__(self, rest=''):
166 166 cmd = self.cmd
167 167 nargs = self.nargs
168 168 # Expand the %l special to be the user's input line
169 169 if cmd.find('%l') >= 0:
170 170 cmd = cmd.replace('%l', rest)
171 171 rest = ''
172 172
173 173 if nargs==0:
174 174 if cmd.find('%%s') >= 1:
175 175 cmd = cmd.replace('%%s', '%s')
176 176 # Simple, argument-less aliases
177 177 cmd = '%s %s' % (cmd, rest)
178 178 else:
179 179 # Handle aliases with positional arguments
180 180 args = rest.split(None, nargs)
181 181 if len(args) < nargs:
182 182 raise UsageError('Alias <%s> requires %s arguments, %s given.' %
183 183 (self.name, nargs, len(args)))
184 184 cmd = '%s %s' % (cmd % tuple(args[:nargs]),' '.join(args[nargs:]))
185 185
186 186 self.shell.system(cmd)
187 187
188 188 #-----------------------------------------------------------------------------
189 189 # Main AliasManager class
190 190 #-----------------------------------------------------------------------------
191 191
192 192 class AliasManager(Configurable):
193
194 default_aliases = List(default_aliases()).tag(config=True)
195 user_aliases = List(default_value=[]).tag(config=True)
196 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
193 default_aliases: List = List(default_aliases()).tag(config=True)
194 user_aliases: List = List(default_value=[]).tag(config=True)
195 shell = Instance(
196 "IPython.core.interactiveshell.InteractiveShellABC", allow_none=True
197 )
197 198
198 199 def __init__(self, shell=None, **kwargs):
199 200 super(AliasManager, self).__init__(shell=shell, **kwargs)
200 201 # For convenient access
201 self.linemagics = self.shell.magics_manager.magics['line']
202 self.init_aliases()
202 if self.shell is not None:
203 self.linemagics = self.shell.magics_manager.magics["line"]
204 self.init_aliases()
203 205
204 206 def init_aliases(self):
205 207 # Load default & user aliases
206 208 for name, cmd in self.default_aliases + self.user_aliases:
207 if cmd.startswith('ls ') and self.shell.colors == 'NoColor':
208 cmd = cmd.replace(' --color', '')
209 if (
210 cmd.startswith("ls ")
211 and self.shell is not None
212 and self.shell.colors == "NoColor"
213 ):
214 cmd = cmd.replace(" --color", "")
209 215 self.soft_define_alias(name, cmd)
210 216
211 217 @property
212 218 def aliases(self):
213 219 return [(n, func.cmd) for (n, func) in self.linemagics.items()
214 220 if isinstance(func, Alias)]
215 221
216 222 def soft_define_alias(self, name, cmd):
217 223 """Define an alias, but don't raise on an AliasError."""
218 224 try:
219 225 self.define_alias(name, cmd)
220 226 except AliasError as e:
221 227 error("Invalid alias: %s" % e)
222 228
223 229 def define_alias(self, name, cmd):
224 230 """Define a new alias after validating it.
225 231
226 232 This will raise an :exc:`AliasError` if there are validation
227 233 problems.
228 234 """
229 235 caller = Alias(shell=self.shell, name=name, cmd=cmd)
230 236 self.shell.magics_manager.register_function(caller, magic_kind='line',
231 237 magic_name=name)
232 238
233 239 def get_alias(self, name):
234 240 """Return an alias, or None if no alias by that name exists."""
235 241 aname = self.linemagics.get(name, None)
236 242 return aname if isinstance(aname, Alias) else None
237 243
238 244 def is_alias(self, name):
239 245 """Return whether or not a given name has been defined as an alias"""
240 246 return self.get_alias(name) is not None
241 247
242 248 def undefine_alias(self, name):
243 249 if self.is_alias(name):
244 250 del self.linemagics[name]
245 251 else:
246 252 raise ValueError('%s is not an alias' % name)
247 253
248 254 def clear_aliases(self):
249 for name, cmd in self.aliases:
255 for name, _ in self.aliases:
250 256 self.undefine_alias(name)
251 257
252 258 def retrieve_alias(self, name):
253 259 """Retrieve the command to which an alias expands."""
254 260 caller = self.get_alias(name)
255 261 if caller:
256 262 return caller.cmd
257 263 else:
258 264 raise ValueError('%s is not an alias' % name)
@@ -1,165 +1,175 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 Color schemes for exception handling code in IPython.
4 4 """
5 5
6 6 import os
7 7
8 8 #*****************************************************************************
9 9 # Copyright (C) 2005-2006 Fernando Perez <fperez@colorado.edu>
10 10 #
11 11 # Distributed under the terms of the BSD License. The full license is in
12 12 # the file COPYING, distributed as part of this software.
13 13 #*****************************************************************************
14 14
15 15 from IPython.utils.coloransi import ColorSchemeTable, TermColors, ColorScheme
16 16
17 17 def exception_colors():
18 18 """Return a color table with fields for exception reporting.
19 19
20 20 The table is an instance of ColorSchemeTable with schemes added for
21 21 'Neutral', 'Linux', 'LightBG' and 'NoColor' and fields for exception handling filled
22 22 in.
23 23
24 24 Examples:
25 25
26 26 >>> ec = exception_colors()
27 27 >>> ec.active_scheme_name
28 28 ''
29 29 >>> print(ec.active_colors)
30 30 None
31 31
32 32 Now we activate a color scheme:
33 33 >>> ec.set_active_scheme('NoColor')
34 34 >>> ec.active_scheme_name
35 35 'NoColor'
36 36 >>> sorted(ec.active_colors.keys())
37 37 ['Normal', 'caret', 'em', 'excName', 'filename', 'filenameEm', 'line',
38 38 'lineno', 'linenoEm', 'name', 'nameEm', 'normalEm', 'topline', 'vName',
39 39 'val', 'valEm']
40 40 """
41 41
42 42 ex_colors = ColorSchemeTable()
43 43
44 44 # Populate it with color schemes
45 C = TermColors # shorthand and local lookup
46 ex_colors.add_scheme(ColorScheme(
47 'NoColor',
48 # The color to be used for the top line
49 topline = C.NoColor,
50
51 # The colors to be used in the traceback
52 filename = C.NoColor,
53 lineno = C.NoColor,
54 name = C.NoColor,
55 vName = C.NoColor,
56 val = C.NoColor,
57 em = C.NoColor,
58
59 # Emphasized colors for the last frame of the traceback
60 normalEm = C.NoColor,
61 filenameEm = C.NoColor,
62 linenoEm = C.NoColor,
63 nameEm = C.NoColor,
64 valEm = C.NoColor,
65
66 # Colors for printing the exception
67 excName = C.NoColor,
68 line = C.NoColor,
69 caret = C.NoColor,
70 Normal = C.NoColor
71 ))
45 C = TermColors # shorthand and local lookup
46 ex_colors.add_scheme(
47 ColorScheme(
48 "NoColor",
49 {
50 # The color to be used for the top line
51 "topline": C.NoColor,
52
53 # The colors to be used in the traceback
54 "filename": C.NoColor,
55 "lineno": C.NoColor,
56 "name": C.NoColor,
57 "vName": C.NoColor,
58 "val": C.NoColor,
59 "em": C.NoColor,
60
61 # Emphasized colors for the last frame of the traceback
62 "normalEm": C.NoColor,
63 "filenameEm": C.NoColor,
64 "linenoEm": C.NoColor,
65 "nameEm": C.NoColor,
66 "valEm": C.NoColor,
67
68 # Colors for printing the exception
69 "excName": C.NoColor,
70 "line": C.NoColor,
71 "caret": C.NoColor,
72 "Normal": C.NoColor,
73 },
74 )
75 )
72 76
73 77 # make some schemes as instances so we can copy them for modification easily
74 ex_colors.add_scheme(ColorScheme(
75 'Linux',
76 # The color to be used for the top line
77 topline = C.LightRed,
78
79 # The colors to be used in the traceback
80 filename = C.Green,
81 lineno = C.Green,
82 name = C.Purple,
83 vName = C.Cyan,
84 val = C.Green,
85 em = C.LightCyan,
86
87 # Emphasized colors for the last frame of the traceback
88 normalEm = C.LightCyan,
89 filenameEm = C.LightGreen,
90 linenoEm = C.LightGreen,
91 nameEm = C.LightPurple,
92 valEm = C.LightBlue,
93
94 # Colors for printing the exception
95 excName = C.LightRed,
96 line = C.Yellow,
97 caret = C.White,
98 Normal = C.Normal
99 ))
78 ex_colors.add_scheme(
79 ColorScheme(
80 "Linux",
81 {
82 # The color to be used for the top line
83 "topline": C.LightRed,
84 # The colors to be used in the traceback
85 "filename": C.Green,
86 "lineno": C.Green,
87 "name": C.Purple,
88 "vName": C.Cyan,
89 "val": C.Green,
90 "em": C.LightCyan,
91 # Emphasized colors for the last frame of the traceback
92 "normalEm": C.LightCyan,
93 "filenameEm": C.LightGreen,
94 "linenoEm": C.LightGreen,
95 "nameEm": C.LightPurple,
96 "valEm": C.LightBlue,
97 # Colors for printing the exception
98 "excName": C.LightRed,
99 "line": C.Yellow,
100 "caret": C.White,
101 "Normal": C.Normal,
102 },
103 )
104 )
100 105
101 106 # For light backgrounds, swap dark/light colors
102 ex_colors.add_scheme(ColorScheme(
103 'LightBG',
104 # The color to be used for the top line
105 topline = C.Red,
106
107 # The colors to be used in the traceback
108 filename = C.LightGreen,
109 lineno = C.LightGreen,
110 name = C.LightPurple,
111 vName = C.Cyan,
112 val = C.LightGreen,
113 em = C.Cyan,
114
115 # Emphasized colors for the last frame of the traceback
116 normalEm = C.Cyan,
117 filenameEm = C.Green,
118 linenoEm = C.Green,
119 nameEm = C.Purple,
120 valEm = C.Blue,
121
122 # Colors for printing the exception
123 excName = C.Red,
124 #line = C.Brown, # brown often is displayed as yellow
125 line = C.Red,
126 caret = C.Normal,
127 Normal = C.Normal,
128 ))
129
130 ex_colors.add_scheme(ColorScheme(
131 'Neutral',
132 # The color to be used for the top line
133 topline = C.Red,
134
135 # The colors to be used in the traceback
136 filename = C.LightGreen,
137 lineno = C.LightGreen,
138 name = C.LightPurple,
139 vName = C.Cyan,
140 val = C.LightGreen,
141 em = C.Cyan,
142
143 # Emphasized colors for the last frame of the traceback
144 normalEm = C.Cyan,
145 filenameEm = C.Green,
146 linenoEm = C.Green,
147 nameEm = C.Purple,
148 valEm = C.Blue,
149
150 # Colors for printing the exception
151 excName = C.Red,
152 #line = C.Brown, # brown often is displayed as yellow
153 line = C.Red,
154 caret = C.Normal,
155 Normal = C.Normal,
156 ))
107 ex_colors.add_scheme(
108 ColorScheme(
109 "LightBG",
110 {
111 # The color to be used for the top line
112 "topline": C.Red,
113
114 # The colors to be used in the traceback
115 "filename": C.LightGreen,
116 "lineno": C.LightGreen,
117 "name": C.LightPurple,
118 "vName": C.Cyan,
119 "val": C.LightGreen,
120 "em": C.Cyan,
121
122 # Emphasized colors for the last frame of the traceback
123 "normalEm": C.Cyan,
124 "filenameEm": C.Green,
125 "linenoEm": C.Green,
126 "nameEm": C.Purple,
127 "valEm": C.Blue,
128
129 # Colors for printing the exception
130 "excName": C.Red,
131 # "line": C.Brown, # brown often is displayed as yellow
132 "line": C.Red,
133 "caret": C.Normal,
134 "Normal": C.Normal,
135 },
136 )
137 )
138
139 ex_colors.add_scheme(
140 ColorScheme(
141 "Neutral",
142 {
143 # The color to be used for the top line
144 "topline": C.Red,
145 # The colors to be used in the traceback
146 "filename": C.LightGreen,
147 "lineno": C.LightGreen,
148 "name": C.LightPurple,
149 "vName": C.Cyan,
150 "val": C.LightGreen,
151 "em": C.Cyan,
152 # Emphasized colors for the last frame of the traceback
153 "normalEm": C.Cyan,
154 "filenameEm": C.Green,
155 "linenoEm": C.Green,
156 "nameEm": C.Purple,
157 "valEm": C.Blue,
158 # Colors for printing the exception
159 "excName": C.Red,
160 # line = C.Brown, # brown often is displayed as yellow
161 "line": C.Red,
162 "caret": C.Normal,
163 "Normal": C.Normal,
164 },
165 )
166 )
157 167
158 168 # Hack: the 'neutral' colours are not very visible on a dark background on
159 169 # Windows. Since Windows command prompts have a dark background by default, and
160 170 # relatively few users are likely to alter that, we will use the 'Linux' colours,
161 171 # designed for a dark background, as the default on Windows.
162 172 if os.name == "nt":
163 173 ex_colors.add_scheme(ex_colors['Linux'].copy('Neutral'))
164 174
165 175 return ex_colors
@@ -1,151 +1,150 b''
1 1 # encoding: utf-8
2 2 """A class for managing IPython extensions."""
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 os.path
9 9 import sys
10 10 from importlib import import_module, reload
11 11
12 12 from traitlets.config.configurable import Configurable
13 from IPython.utils.path import ensure_dir_exists, compress_user
14 from IPython.utils.decorators import undoc
13 from IPython.utils.path import ensure_dir_exists
15 14 from traitlets import Instance
16 15
17 16
18 17 #-----------------------------------------------------------------------------
19 18 # Main class
20 19 #-----------------------------------------------------------------------------
21 20
22 21 BUILTINS_EXTS = {"storemagic": False, "autoreload": False}
23 22
24 23
25 24 class ExtensionManager(Configurable):
26 25 """A class to manage IPython extensions.
27 26
28 27 An IPython extension is an importable Python module that has
29 28 a function with the signature::
30 29
31 30 def load_ipython_extension(ipython):
32 31 # Do things with ipython
33 32
34 33 This function is called after your extension is imported and the
35 34 currently active :class:`InteractiveShell` instance is passed as
36 35 the only argument. You can do anything you want with IPython at
37 36 that point, including defining new magic and aliases, adding new
38 37 components, etc.
39 38
40 39 You can also optionally define an :func:`unload_ipython_extension(ipython)`
41 40 function, which will be called if the user unloads or reloads the extension.
42 41 The extension manager will only call :func:`load_ipython_extension` again
43 42 if the extension is reloaded.
44 43
45 44 You can put your extension modules anywhere you want, as long as
46 45 they can be imported by Python's standard import mechanism. However,
47 46 to make it easy to write extensions, you can also put your extensions
48 47 in ``os.path.join(self.ipython_dir, 'extensions')``. This directory
49 48 is added to ``sys.path`` automatically.
50 49 """
51 50
52 51 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
53 52
54 53 def __init__(self, shell=None, **kwargs):
55 54 super(ExtensionManager, self).__init__(shell=shell, **kwargs)
56 55 self.shell.observe(
57 56 self._on_ipython_dir_changed, names=('ipython_dir',)
58 57 )
59 58 self.loaded = set()
60 59
61 60 @property
62 61 def ipython_extension_dir(self):
63 62 return os.path.join(self.shell.ipython_dir, u'extensions')
64 63
65 64 def _on_ipython_dir_changed(self, change):
66 65 ensure_dir_exists(self.ipython_extension_dir)
67 66
68 67 def load_extension(self, module_str: str):
69 68 """Load an IPython extension by its module name.
70 69
71 70 Returns the string "already loaded" if the extension is already loaded,
72 71 "no load function" if the module doesn't have a load_ipython_extension
73 72 function, or None if it succeeded.
74 73 """
75 74 try:
76 75 return self._load_extension(module_str)
77 76 except ModuleNotFoundError:
78 77 if module_str in BUILTINS_EXTS:
79 78 BUILTINS_EXTS[module_str] = True
80 79 return self._load_extension("IPython.extensions." + module_str)
81 80 raise
82 81
83 82 def _load_extension(self, module_str: str):
84 83 if module_str in self.loaded:
85 84 return "already loaded"
86 85
87 from IPython.utils.syspathcontext import prepended_to_syspath
86 assert self.shell is not None
88 87
89 88 with self.shell.builtin_trap:
90 89 if module_str not in sys.modules:
91 90 mod = import_module(module_str)
92 91 mod = sys.modules[module_str]
93 92 if self._call_load_ipython_extension(mod):
94 93 self.loaded.add(module_str)
95 94 else:
96 95 return "no load function"
97 96
98 97 def unload_extension(self, module_str: str):
99 98 """Unload an IPython extension by its module name.
100 99
101 100 This function looks up the extension's name in ``sys.modules`` and
102 101 simply calls ``mod.unload_ipython_extension(self)``.
103 102
104 103 Returns the string "no unload function" if the extension doesn't define
105 104 a function to unload itself, "not loaded" if the extension isn't loaded,
106 105 otherwise None.
107 106 """
108 107 if BUILTINS_EXTS.get(module_str, False) is True:
109 108 module_str = "IPython.extensions." + module_str
110 109 if module_str not in self.loaded:
111 110 return "not loaded"
112 111
113 112 if module_str in sys.modules:
114 113 mod = sys.modules[module_str]
115 114 if self._call_unload_ipython_extension(mod):
116 115 self.loaded.discard(module_str)
117 116 else:
118 117 return "no unload function"
119 118
120 119 def reload_extension(self, module_str: str):
121 120 """Reload an IPython extension by calling reload.
122 121
123 122 If the module has not been loaded before,
124 123 :meth:`InteractiveShell.load_extension` is called. Otherwise
125 124 :func:`reload` is called and then the :func:`load_ipython_extension`
126 125 function of the module, if it exists is called.
127 126 """
128 127 from IPython.utils.syspathcontext import prepended_to_syspath
129 128
130 129 if BUILTINS_EXTS.get(module_str, False) is True:
131 130 module_str = "IPython.extensions." + module_str
132 131
133 132 if (module_str in self.loaded) and (module_str in sys.modules):
134 133 self.unload_extension(module_str)
135 134 mod = sys.modules[module_str]
136 135 with prepended_to_syspath(self.ipython_extension_dir):
137 136 reload(mod)
138 137 if self._call_load_ipython_extension(mod):
139 138 self.loaded.add(module_str)
140 139 else:
141 140 self.load_extension(module_str)
142 141
143 142 def _call_load_ipython_extension(self, mod):
144 143 if hasattr(mod, 'load_ipython_extension'):
145 144 mod.load_ipython_extension(self.shell)
146 145 return True
147 146
148 147 def _call_unload_ipython_extension(self, mod):
149 148 if hasattr(mod, 'unload_ipython_extension'):
150 149 mod.unload_ipython_extension(self.shell)
151 150 return True
@@ -1,55 +1,54 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Payload system for IPython.
3 3
4 4 Authors:
5 5
6 6 * Fernando Perez
7 7 * Brian Granger
8 8 """
9 9
10 10 #-----------------------------------------------------------------------------
11 11 # Copyright (C) 2008-2011 The IPython Development Team
12 12 #
13 13 # Distributed under the terms of the BSD License. The full license is in
14 14 # the file COPYING, distributed as part of this software.
15 15 #-----------------------------------------------------------------------------
16 16
17 17 #-----------------------------------------------------------------------------
18 18 # Imports
19 19 #-----------------------------------------------------------------------------
20 20
21 21 from traitlets.config.configurable import Configurable
22 22 from traitlets import List
23 23
24 24 #-----------------------------------------------------------------------------
25 25 # Main payload class
26 26 #-----------------------------------------------------------------------------
27 27
28 28 class PayloadManager(Configurable):
29
30 _payload = List([])
29 _payload: List = List([])
31 30
32 31 def write_payload(self, data, single=True):
33 32 """Include or update the specified `data` payload in the PayloadManager.
34 33
35 34 If a previous payload with the same source exists and `single` is True,
36 35 it will be overwritten with the new one.
37 36 """
38 37
39 38 if not isinstance(data, dict):
40 39 raise TypeError('Each payload write must be a dict, got: %r' % data)
41 40
42 41 if single and 'source' in data:
43 42 source = data['source']
44 43 for i, pl in enumerate(self._payload):
45 44 if 'source' in pl and pl['source'] == source:
46 45 self._payload[i] = data
47 46 return
48 47
49 48 self._payload.append(data)
50 49
51 50 def read_payload(self):
52 51 return self._payload
53 52
54 53 def clear_payload(self):
55 54 self._payload = []
@@ -1,127 +1,128 b''
1 1 """Terminal input and output prompts."""
2 2
3 3 from pygments.token import Token
4 4 import sys
5 5
6 6 from IPython.core.displayhook import DisplayHook
7 7
8 8 from prompt_toolkit.formatted_text import fragment_list_width, PygmentsTokens
9 9 from prompt_toolkit.shortcuts import print_formatted_text
10 10 from prompt_toolkit.enums import EditingMode
11 11
12 12
13 13 class Prompts(object):
14 14 def __init__(self, shell):
15 15 self.shell = shell
16 16
17 17 def vi_mode(self):
18 18 if (getattr(self.shell.pt_app, 'editing_mode', None) == EditingMode.VI
19 19 and self.shell.prompt_includes_vi_mode):
20 20 mode = str(self.shell.pt_app.app.vi_state.input_mode)
21 21 if mode.startswith('InputMode.'):
22 22 mode = mode[10:13].lower()
23 23 elif mode.startswith('vi-'):
24 24 mode = mode[3:6]
25 25 return '['+mode+'] '
26 26 return ''
27 27
28 28 def current_line(self) -> int:
29 29 if self.shell.pt_app is not None:
30 30 return self.shell.pt_app.default_buffer.document.cursor_position_row or 0
31 31 return 0
32 32
33 33 def in_prompt_tokens(self):
34 34 return [
35 35 (Token.Prompt, self.vi_mode()),
36 36 (
37 37 Token.Prompt,
38 38 self.shell.prompt_line_number_format.format(
39 39 line=1, rel_line=-self.current_line()
40 40 ),
41 41 ),
42 42 (Token.Prompt, "In ["),
43 43 (Token.PromptNum, str(self.shell.execution_count)),
44 44 (Token.Prompt, ']: '),
45 45 ]
46 46
47 47 def _width(self):
48 48 return fragment_list_width(self.in_prompt_tokens())
49 49
50 50 def continuation_prompt_tokens(self, width=None, *, lineno=None):
51 51 if width is None:
52 52 width = self._width()
53 53 line = lineno + 1 if lineno is not None else 0
54 54 prefix = " " * len(
55 55 self.vi_mode()
56 56 ) + self.shell.prompt_line_number_format.format(
57 57 line=line, rel_line=line - self.current_line() - 1
58 58 )
59 59 return [
60 60 (
61 61 Token.Prompt,
62 62 prefix + (" " * (width - len(prefix) - 5)) + "...: ",
63 63 ),
64 64 ]
65 65
66 66 def rewrite_prompt_tokens(self):
67 67 width = self._width()
68 68 return [
69 69 (Token.Prompt, ('-' * (width - 2)) + '> '),
70 70 ]
71 71
72 72 def out_prompt_tokens(self):
73 73 return [
74 74 (Token.OutPrompt, 'Out['),
75 75 (Token.OutPromptNum, str(self.shell.execution_count)),
76 76 (Token.OutPrompt, ']: '),
77 77 ]
78 78
79 79 class ClassicPrompts(Prompts):
80 80 def in_prompt_tokens(self):
81 81 return [
82 82 (Token.Prompt, '>>> '),
83 83 ]
84 84
85 85 def continuation_prompt_tokens(self, width=None):
86 86 return [
87 87 (Token.Prompt, '... ')
88 88 ]
89 89
90 90 def rewrite_prompt_tokens(self):
91 91 return []
92 92
93 93 def out_prompt_tokens(self):
94 94 return []
95 95
96 96 class RichPromptDisplayHook(DisplayHook):
97 97 """Subclass of base display hook using coloured prompt"""
98 98 def write_output_prompt(self):
99 99 sys.stdout.write(self.shell.separate_out)
100 100 # If we're not displaying a prompt, it effectively ends with a newline,
101 101 # because the output will be left-aligned.
102 102 self.prompt_end_newline = True
103 103
104 104 if self.do_full_cache:
105 105 tokens = self.shell.prompts.out_prompt_tokens()
106 prompt_txt = ''.join(s for t, s in tokens)
107 if prompt_txt and not prompt_txt.endswith('\n'):
106 prompt_txt = "".join(s for _, s in tokens)
107 if prompt_txt and not prompt_txt.endswith("\n"):
108 108 # Ask for a newline before multiline output
109 109 self.prompt_end_newline = False
110 110
111 111 if self.shell.pt_app:
112 112 print_formatted_text(PygmentsTokens(tokens),
113 113 style=self.shell.pt_app.app.style, end='',
114 114 )
115 115 else:
116 116 sys.stdout.write(prompt_txt)
117 117
118 118 def write_format_data(self, format_dict, md_dict=None) -> None:
119 assert self.shell is not None
119 120 if self.shell.mime_renderers:
120 121
121 122 for mime, handler in self.shell.mime_renderers.items():
122 123 if mime in format_dict:
123 124 handler(format_dict[mime], None)
124 125 return
125 126
126 127 super().write_format_data(format_dict, md_dict)
127 128
@@ -1,187 +1,191 b''
1 # -*- coding: utf-8 -*-
2 1 """Tools for coloring text in ANSI terminals.
3 2 """
4 3
5 4 #*****************************************************************************
6 5 # Copyright (C) 2002-2006 Fernando Perez. <fperez@colorado.edu>
7 6 #
8 7 # Distributed under the terms of the BSD License. The full license is in
9 8 # the file COPYING, distributed as part of this software.
10 9 #*****************************************************************************
11 10
12 __all__ = ['TermColors','InputTermColors','ColorScheme','ColorSchemeTable']
13 11
14 12 import os
15 13
16 14 from IPython.utils.ipstruct import Struct
17 15
16 __all__ = ["TermColors", "InputTermColors", "ColorScheme", "ColorSchemeTable"]
17
18 18 color_templates = (
19 19 # Dark colors
20 20 ("Black" , "0;30"),
21 21 ("Red" , "0;31"),
22 22 ("Green" , "0;32"),
23 23 ("Brown" , "0;33"),
24 24 ("Blue" , "0;34"),
25 25 ("Purple" , "0;35"),
26 26 ("Cyan" , "0;36"),
27 27 ("LightGray" , "0;37"),
28 28 # Light colors
29 29 ("DarkGray" , "1;30"),
30 30 ("LightRed" , "1;31"),
31 31 ("LightGreen" , "1;32"),
32 32 ("Yellow" , "1;33"),
33 33 ("LightBlue" , "1;34"),
34 34 ("LightPurple" , "1;35"),
35 35 ("LightCyan" , "1;36"),
36 36 ("White" , "1;37"),
37 37 # Blinking colors. Probably should not be used in anything serious.
38 38 ("BlinkBlack" , "5;30"),
39 39 ("BlinkRed" , "5;31"),
40 40 ("BlinkGreen" , "5;32"),
41 41 ("BlinkYellow" , "5;33"),
42 42 ("BlinkBlue" , "5;34"),
43 43 ("BlinkPurple" , "5;35"),
44 44 ("BlinkCyan" , "5;36"),
45 45 ("BlinkLightGray", "5;37"),
46 46 )
47 47
48 48 def make_color_table(in_class):
49 49 """Build a set of color attributes in a class.
50 50
51 51 Helper function for building the :class:`TermColors` and
52 52 :class`InputTermColors`.
53 53 """
54 54 for name,value in color_templates:
55 55 setattr(in_class,name,in_class._base % value)
56 56
57 57 class TermColors:
58 58 """Color escape sequences.
59 59
60 60 This class defines the escape sequences for all the standard (ANSI?)
61 61 colors in terminals. Also defines a NoColor escape which is just the null
62 62 string, suitable for defining 'dummy' color schemes in terminals which get
63 63 confused by color escapes.
64 64
65 65 This class should be used as a mixin for building color schemes."""
66 66
67 67 NoColor = '' # for color schemes in color-less terminals.
68 68 Normal = '\033[0m' # Reset normal coloring
69 69 _base = '\033[%sm' # Template for all other colors
70 70
71 71 # Build the actual color table as a set of class attributes:
72 72 make_color_table(TermColors)
73 73
74 74 class InputTermColors:
75 75 """Color escape sequences for input prompts.
76 76
77 77 This class is similar to TermColors, but the escapes are wrapped in \\001
78 78 and \\002 so that readline can properly know the length of each line and
79 79 can wrap lines accordingly. Use this class for any colored text which
80 80 needs to be used in input prompts, such as in calls to raw_input().
81 81
82 82 This class defines the escape sequences for all the standard (ANSI?)
83 83 colors in terminals. Also defines a NoColor escape which is just the null
84 84 string, suitable for defining 'dummy' color schemes in terminals which get
85 85 confused by color escapes.
86 86
87 87 This class should be used as a mixin for building color schemes."""
88 88
89 89 NoColor = '' # for color schemes in color-less terminals.
90 90
91 91 if os.name == 'nt' and os.environ.get('TERM','dumb') == 'emacs':
92 92 # (X)emacs on W32 gets confused with \001 and \002 so we remove them
93 93 Normal = '\033[0m' # Reset normal coloring
94 94 _base = '\033[%sm' # Template for all other colors
95 95 else:
96 96 Normal = '\001\033[0m\002' # Reset normal coloring
97 97 _base = '\001\033[%sm\002' # Template for all other colors
98 98
99 99 # Build the actual color table as a set of class attributes:
100 100 make_color_table(InputTermColors)
101 101
102 102 class NoColors:
103 103 """This defines all the same names as the colour classes, but maps them to
104 104 empty strings, so it can easily be substituted to turn off colours."""
105 105 NoColor = ''
106 106 Normal = ''
107 107
108 108 for name, value in color_templates:
109 109 setattr(NoColors, name, '')
110 110
111 111 class ColorScheme:
112 112 """Generic color scheme class. Just a name and a Struct."""
113
114 name: str
115 colors: Struct
116
113 117 def __init__(self,__scheme_name_,colordict=None,**colormap):
114 118 self.name = __scheme_name_
115 119 if colordict is None:
116 120 self.colors = Struct(**colormap)
117 121 else:
118 122 self.colors = Struct(colordict)
119 123
120 124 def copy(self,name=None):
121 125 """Return a full copy of the object, optionally renaming it."""
122 126 if name is None:
123 127 name = self.name
124 128 return ColorScheme(name, self.colors.dict())
125 129
126 130 class ColorSchemeTable(dict):
127 131 """General class to handle tables of color schemes.
128 132
129 133 It's basically a dict of color schemes with a couple of shorthand
130 134 attributes and some convenient methods.
131 135
132 136 active_scheme_name -> obvious
133 137 active_colors -> actual color table of the active scheme"""
134 138
135 139 def __init__(self, scheme_list=None, default_scheme=''):
136 140 """Create a table of color schemes.
137 141
138 142 The table can be created empty and manually filled or it can be
139 143 created with a list of valid color schemes AND the specification for
140 144 the default active scheme.
141 145 """
142 146
143 147 # create object attributes to be set later
144 148 self.active_scheme_name = ''
145 149 self.active_colors = None
146 150
147 151 if scheme_list:
148 152 if default_scheme == '':
149 153 raise ValueError('you must specify the default color scheme')
150 154 for scheme in scheme_list:
151 155 self.add_scheme(scheme)
152 156 self.set_active_scheme(default_scheme)
153 157
154 158 def copy(self):
155 159 """Return full copy of object"""
156 160 return ColorSchemeTable(self.values(),self.active_scheme_name)
157 161
158 162 def add_scheme(self,new_scheme):
159 163 """Add a new color scheme to the table."""
160 164 if not isinstance(new_scheme,ColorScheme):
161 165 raise ValueError('ColorSchemeTable only accepts ColorScheme instances')
162 166 self[new_scheme.name] = new_scheme
163 167
164 168 def set_active_scheme(self,scheme,case_sensitive=0):
165 169 """Set the currently active scheme.
166 170
167 171 Names are by default compared in a case-insensitive way, but this can
168 172 be changed by setting the parameter case_sensitive to true."""
169 173
170 174 scheme_names = list(self.keys())
171 175 if case_sensitive:
172 176 valid_schemes = scheme_names
173 177 scheme_test = scheme
174 178 else:
175 179 valid_schemes = [s.lower() for s in scheme_names]
176 180 scheme_test = scheme.lower()
177 181 try:
178 182 scheme_idx = valid_schemes.index(scheme_test)
179 183 except ValueError as e:
180 184 raise ValueError('Unrecognized color scheme: ' + scheme + \
181 185 '\nValid schemes: '+str(scheme_names).replace("'', ",'')) from e
182 186 else:
183 187 active = scheme_names[scheme_idx]
184 188 self.active_scheme_name = active
185 189 self.active_colors = self[active].colors
186 190 # Now allow using '' as an index for the current active scheme
187 191 self[''] = self[active]
@@ -1,81 +1,84 b''
1 1 [build-system]
2 2 requires = ["setuptools >= 51.0.0"]
3 3 build-backend = "setuptools.build_meta"
4 4
5 5 [tool.mypy]
6 python_version = 3.10
6 python_version = "3.10"
7 7 ignore_missing_imports = true
8 8 follow_imports = 'silent'
9 9 exclude = [
10 10 'test_\.+\.py',
11 11 'IPython.utils.tests.test_wildcard',
12 12 'testing',
13 13 'tests',
14 14 'PyColorize.py',
15 15 '_process_win32_controller.py',
16 16 'IPython/core/application.py',
17 17 'IPython/core/completerlib.py',
18 18 'IPython/core/displaypub.py',
19 19 'IPython/core/historyapp.py',
20 20 #'IPython/core/interactiveshell.py',
21 21 'IPython/core/magic.py',
22 22 'IPython/core/profileapp.py',
23 23 # 'IPython/core/ultratb.py',
24 24 'IPython/lib/deepreload.py',
25 25 'IPython/lib/pretty.py',
26 26 'IPython/sphinxext/ipython_directive.py',
27 27 'IPython/terminal/ipapp.py',
28 28 'IPython/utils/_process_win32.py',
29 29 'IPython/utils/path.py',
30 30 'IPython/utils/timing.py',
31 31 'IPython/utils/text.py'
32 32 ]
33 33
34 34 [tool.pytest.ini_options]
35 35 addopts = [
36 36 "--durations=10",
37 37 "-pIPython.testing.plugin.pytest_ipdoctest",
38 38 "--ipdoctest-modules",
39 39 "--ignore=docs",
40 40 "--ignore=examples",
41 41 "--ignore=htmlcov",
42 42 "--ignore=ipython_kernel",
43 43 "--ignore=ipython_parallel",
44 44 "--ignore=results",
45 45 "--ignore=tmp",
46 46 "--ignore=tools",
47 47 "--ignore=traitlets",
48 48 "--ignore=IPython/core/tests/daft_extension",
49 49 "--ignore=IPython/sphinxext",
50 50 "--ignore=IPython/terminal/pt_inputhooks",
51 51 "--ignore=IPython/__main__.py",
52 52 "--ignore=IPython/external/qt_for_kernel.py",
53 53 "--ignore=IPython/html/widgets/widget_link.py",
54 54 "--ignore=IPython/html/widgets/widget_output.py",
55 55 "--ignore=IPython/terminal/console.py",
56 56 "--ignore=IPython/utils/_process_cli.py",
57 57 "--ignore=IPython/utils/_process_posix.py",
58 58 "--ignore=IPython/utils/_process_win32.py",
59 59 "--ignore=IPython/utils/_process_win32_controller.py",
60 60 "--ignore=IPython/utils/daemonize.py",
61 61 "--ignore=IPython/utils/eventful.py",
62 62 "--ignore=IPython/kernel",
63 63 "--ignore=IPython/consoleapp.py",
64 64 "--ignore=IPython/core/inputsplitter.py",
65 65 "--ignore=IPython/lib/kernel.py",
66 66 "--ignore=IPython/utils/jsonutil.py",
67 67 "--ignore=IPython/utils/localinterfaces.py",
68 68 "--ignore=IPython/utils/log.py",
69 69 "--ignore=IPython/utils/signatures.py",
70 70 "--ignore=IPython/utils/traitlets.py",
71 71 "--ignore=IPython/utils/version.py"
72 72 ]
73 73 doctest_optionflags = [
74 74 "NORMALIZE_WHITESPACE",
75 75 "ELLIPSIS"
76 76 ]
77 77 ipdoctest_optionflags = [
78 78 "NORMALIZE_WHITESPACE",
79 79 "ELLIPSIS"
80 80 ]
81 81 asyncio_mode = "strict"
82
83 [tool.pyright]
84 pythonPlatform="All"
General Comments 0
You need to be logged in to leave comments. Login now