Show More
@@ -26,6 +26,8 b' import socket' | |||
|
26 | 26 | import sys |
|
27 | 27 | import time |
|
28 | 28 | |
|
29 | from string import Formatter | |
|
30 | ||
|
29 | 31 | from IPython.config.configurable import Configurable |
|
30 | 32 | from IPython.core import release |
|
31 | 33 | from IPython.utils import coloransi |
@@ -241,6 +243,26 b' def _lenlastline(s):' | |||
|
241 | 243 | return 0 |
|
242 | 244 | return len(s.splitlines()[-1]) |
|
243 | 245 | |
|
246 | ||
|
247 | class UserNSFormatter(Formatter): | |
|
248 | """A Formatter that falls back on a shell's user_ns and __builtins__ for name resolution""" | |
|
249 | def __init__(self, shell): | |
|
250 | self.shell = shell | |
|
251 | ||
|
252 | def get_value(self, key, args, kwargs): | |
|
253 | # try regular formatting first: | |
|
254 | try: | |
|
255 | return Formatter.get_value(self, key, args, kwargs) | |
|
256 | except Exception: | |
|
257 | pass | |
|
258 | # next, look in user_ns and builtins: | |
|
259 | for container in (self.shell.user_ns, __builtins__): | |
|
260 | if key in container: | |
|
261 | return container[key] | |
|
262 | # nothing found, put error message in its place | |
|
263 | return "<ERROR: '%s' not found>" % key | |
|
264 | ||
|
265 | ||
|
244 | 266 | class PromptManager(Configurable): |
|
245 | 267 | """This is the primary interface for producing IPython's prompts.""" |
|
246 | 268 | shell = Instance('IPython.core.interactiveshell.InteractiveShellABC') |
@@ -293,6 +315,7 b' class PromptManager(Configurable):' | |||
|
293 | 315 | self.color_scheme_table = coloransi.ColorSchemeTable([PColNoColors, |
|
294 | 316 | PColLinux, PColLightBG], self.color_scheme) |
|
295 | 317 | |
|
318 | self._formatter = UserNSFormatter(shell) | |
|
296 | 319 | # Prepare templates & numbers of invisible characters |
|
297 | 320 | self.update_prompt('in', self.in_template) |
|
298 | 321 | self.update_prompt('in2', self.in2_template) |
@@ -357,7 +380,7 b' class PromptManager(Configurable):' | |||
|
357 | 380 | prompt = colors.prompt + self.templates[name] + colors.normal |
|
358 | 381 | |
|
359 | 382 | # Fill in required fields |
|
360 |
return |
|
|
383 | return self._formatter.format(prompt, **fmtargs) | |
|
361 | 384 | |
|
362 | 385 | def _render_rewrite(self, color=True): |
|
363 | 386 | """Render the ---> rewrite prompt.""" |
@@ -38,6 +38,25 b' class PromptTests(unittest.TestCase):' | |||
|
38 | 38 | |
|
39 | 39 | tt.check_pairs(do_translate, pairs) |
|
40 | 40 | |
|
41 | def test_user_ns(self): | |
|
42 | self.pm.color_scheme = 'NoColor' | |
|
43 | ip.ex("foo='bar'") | |
|
44 | self.pm.in_template = "In [{foo}]" | |
|
45 | prompt = self.pm.render('in') | |
|
46 | self.assertEquals(prompt, u'In [bar]') | |
|
47 | ||
|
48 | def test_builtins(self): | |
|
49 | self.pm.color_scheme = 'NoColor' | |
|
50 | self.pm.in_template = "In [{int}]" | |
|
51 | prompt = self.pm.render('in') | |
|
52 | self.assertEquals(prompt, u"In [<type 'int'>]") | |
|
53 | ||
|
54 | def test_undefined(self): | |
|
55 | self.pm.color_scheme = 'NoColor' | |
|
56 | self.pm.in_template = "In [{foo_dne}]" | |
|
57 | prompt = self.pm.render('in') | |
|
58 | self.assertEquals(prompt, u"In [<ERROR: 'foo_dne' not found>]") | |
|
59 | ||
|
41 | 60 | def test_render(self): |
|
42 | 61 | self.pm.in_template = r'\#>' |
|
43 | 62 | self.assertEqual(self.pm.render('in',color=False), '%d>' % ip.execution_count) |
General Comments 0
You need to be logged in to leave comments.
Login now