Skip to content
Browse files

Add DollarFormatter and tests.

  • Loading branch information...
1 parent 355e7dd commit 7f99d3346138bdd68097395d5c1ada7b3b004445 @takluyver takluyver committed
Showing with 57 additions and 9 deletions.
  1. +25 −9 IPython/utils/tests/test_text.py
  2. +32 −0 IPython/utils/text.py
View
34 IPython/utils/tests/test_text.py
@@ -44,8 +44,7 @@ def test_columnize_long():
out = text.columnize(items, displaywidth=size-1)
nt.assert_equals(out, '\n'.join(items+['']))
-def test_eval_formatter():
- f = text.EvalFormatter()
+def eval_formatter_check(f):
ns = dict(n=12, pi=math.pi, stuff='hello there', os=os)
s = f.format("{n} {n//4} {stuff.split()[0]}", **ns)
nt.assert_equals(s, "12 3 hello")
@@ -60,10 +59,7 @@ def test_eval_formatter():
nt.assert_raises(NameError, f.format, '{dne}', **ns)
-
-def test_eval_formatter_slicing():
- f = text.EvalFormatter()
- f.allow_slicing = True
+def eval_formatter_slicing_check(f):
ns = dict(n=12, pi=math.pi, stuff='hello there', os=os)
s = f.format(" {stuff.split()[:]} ", **ns)
nt.assert_equals(s, " ['hello', 'there'] ")
@@ -75,9 +71,7 @@ def test_eval_formatter_slicing():
nt.assert_raises(SyntaxError, f.format, "{n:x}", **ns)
-def test_eval_formatter_no_slicing():
- f = text.EvalFormatter()
- f.allow_slicing = False
+def eval_formatter_no_slicing_check(f):
ns = dict(n=12, pi=math.pi, stuff='hello there', os=os)
s = f.format('{n:x} {pi**2:+f}', **ns)
@@ -85,3 +79,25 @@ def test_eval_formatter_no_slicing():
nt.assert_raises(SyntaxError, f.format, "{a[:]}")
+def test_eval_formatter():
+ f = text.EvalFormatter()
+ eval_formatter_check(f)
+ eval_formatter_no_slicing_check(f)
+
+def test_full_eval_formatter():
+ f = text.FullEvalFormatter()
+ eval_formatter_check(f)
+ eval_formatter_slicing_check(f)
+
+def test_dollar_formatter():
+ f = text.DollarFormatter()
+ eval_formatter_check(f)
+ eval_formatter_slicing_check(f)
+
+ ns = dict(n=12, pi=math.pi, stuff='hello there', os=os)
+ s = f.format("$n", **ns)
+ nt.assert_equals(s, "12")
+ s = f.format("$n.real", **ns)
+ nt.assert_equals(s, "12")
+ s = f.format("$n/{stuff[:5]}", **ns)
+ nt.assert_equals(s, "12/hello")
View
32 IPython/utils/text.py
@@ -677,6 +677,38 @@ def _vformat(self, format_string, args, kwargs, used_args, recursion_depth):
return ''.join(result)
+class DollarFormatter(FullEvalFormatter):
+ """Formatter allowing Itpl style $foo replacement, for names and attribute
+ access only. Standard {foo} replacement also works, and allows full
+ evaluation of its arguments.
+
+ Examples
+ --------
+ In [1]: f = DollarFormatter()
+ In [2]: f.format('{n//4}', n=8)
+ Out[2]: '2'
+
+ In [3]: f.format('23 * 76 is $result', result=23*76)
+ Out[3]: '23 * 76 is 1748'
+
+ In [4]: f.format('$a or {b}', a=1, b=2)
+ Out[4]: '1 or 2'
+ """
+ _dollar_pattern = re.compile("(.*)\$([\w\.]+)")
+ def parse(self, fmt_string):
+ for literal_txt, field_name, format_spec, conversion \
+ in Formatter.parse(self, fmt_string):
+
+ # Find $foo patterns in the literal text.
+ continue_from = 0
+ for m in self._dollar_pattern.finditer(literal_txt):
+ new_txt, new_field = m.group(1,2)
+ yield (new_txt, new_field, "", "s")
+ continue_from = m.end()
+
+ # Re-yield the {foo} style pattern
+ yield (literal_txt[continue_from:], field_name, format_spec, conversion)
+
def columnize(items, separator=' ', displaywidth=80):
""" Transform a list of strings into a single string with columns.

0 comments on commit 7f99d33

Please sign in to comment.
Something went wrong with that request. Please try again.