##// END OF EJS Templates
add `float_precision` trait to PlainTextFormatter...
MinRK -
Show More
@@ -20,6 +20,7 b' Authors:'
20 20 #-----------------------------------------------------------------------------
21 21
22 22 # Stdlib imports
23 import sys
23 24 import abc
24 25 # We must use StringIO, as cStringIO doesn't handle unicode properly.
25 26 from StringIO import StringIO
@@ -27,7 +28,7 b' from StringIO import StringIO'
27 28 # Our own imports
28 29 from IPython.config.configurable import Configurable
29 30 from IPython.external import pretty
30 from IPython.utils.traitlets import Bool, Dict, Int, Str
31 from IPython.utils.traitlets import Bool, Dict, Int, Str, CStr
31 32
32 33
33 34 #-----------------------------------------------------------------------------
@@ -352,13 +353,65 b' class PlainTextFormatter(BaseFormatter):'
352 353
353 354 # The newline character.
354 355 newline = Str('\n', config=True)
356
357 # format-string for pprinting floats
358 float_format = Str('%r')
359 # setter for float precision, either int or direct format-string
360 float_precision = CStr('', config=True)
361
362 def _float_precision_changed(self, name, old, new):
363 """float_precision changed, set float_format accordingly.
364
365 float_precision can be set by int or str.
366 This will set float_format, after interpreting input.
367 If numpy has been imported, numpy print precision will also be set.
368
369 integer `n` sets format to '%.nf', otherwise, format set directly.
370
371 An empty string returns to defaults (repr for float, 8 for numpy).
372
373 This parameter can be set via the '%precision' magic.
374 """
375
376 if '%' in new:
377 # got explicit format string
378 fmt = new
379 try:
380 fmt%3.14159
381 except Exception:
382 raise ValueError("Precision must be int or format string, not %r"%new)
383 elif new:
384 # otherwise, should be an int
385 try:
386 i = int(new)
387 assert i >= 0
388 except ValueError:
389 raise ValueError("Precision must be int or format string, not %r"%new)
390 except AssertionError:
391 raise ValueError("int precision must be non-negative, not %r"%i)
392
393 fmt = '%%.%if'%i
394 if 'numpy' in sys.modules:
395 # set numpy precision if it has been imported
396 import numpy
397 numpy.set_printoptions(precision=i)
398 else:
399 # default back to repr
400 fmt = '%r'
401 if 'numpy' in sys.modules:
402 import numpy
403 # numpy default is 8
404 numpy.set_printoptions(precision=8)
405 self.float_format = fmt
355 406
356 407 # Use the default pretty printers from IPython.external.pretty.
357 408 def _singleton_printers_default(self):
358 409 return pretty._singleton_pprinters.copy()
359 410
360 411 def _type_printers_default(self):
361 return pretty._type_pprinters.copy()
412 d = pretty._type_pprinters.copy()
413 d[float] = lambda obj,p,cycle: p.text(self.float_format%obj)
414 return d
362 415
363 416 def _deferred_printers_default(self):
364 417 return pretty._deferred_type_pprinters.copy()
@@ -3478,58 +3478,33 b' Defaulting color scheme to \'NoColor\'"""'
3478 3478 In [1]: from math import pi
3479 3479
3480 3480 In [2]: %precision 3
3481 Out[2]: '%.3f'
3481 3482
3482 3483 In [3]: pi
3483 3484 Out[3]: 3.142
3484 3485
3485 3486 In [4]: %precision %i
3487 Out[4]: '%i'
3486 3488
3487 3489 In [5]: pi
3488 3490 Out[5]: 3
3489 3491
3490 3492 In [6]: %precision %e
3493 Out[6]: '%e'
3491 3494
3492 3495 In [7]: pi**10
3493 3496 Out[7]: 9.364805e+04
3494 3497
3495 3498 In [8]: %precision
3499 Out[8]: '%r'
3496 3500
3497 3501 In [9]: pi**10
3498 3502 Out[9]: 93648.047476082982
3499 3503
3500 3504 """
3501 3505
3502 if '%' in s:
3503 # got explicit format string
3504 fmt = s
3505 try:
3506 fmt%3.14159
3507 except Exception:
3508 raise ValueError("Precision must be int or format string, not %r"%s)
3509 elif s:
3510 # otherwise, should be an int
3511 try:
3512 i = int(s)
3513 assert i >= 0
3514 except (ValueError, AssertionError):
3515 raise ValueError("Precision must be non-negative int or format string, not %r"%s)
3516
3517 fmt = '%%.%if'%i
3518 if 'numpy' in sys.modules:
3519 import numpy
3520 numpy.set_printoptions(precision=i)
3521 else:
3522 # default back to repr
3523 fmt = '%r'
3524 if 'numpy' in sys.modules:
3525 import numpy
3526 # numpy default is 8
3527 numpy.set_printoptions(precision=8)
3528
3529 def _pretty_float(obj,p,cycle):
3530 p.text(fmt%obj)
3531
3532 3506 ptformatter = self.shell.display_formatter.formatters['text/plain']
3533 ptformatter.for_type(float, _pretty_float)
3507 ptformatter.float_precision = s
3508 return ptformatter.float_format
3534 3509
3535 3510 # end Magic
@@ -1,9 +1,15 b''
1 1 """Tests for the Formatters.
2 2 """
3 3
4 from math import pi
5
6 try:
7 import numpy
8 except:
9 numpy = None
4 10 import nose.tools as nt
5 11
6 from IPython.core.formatters import FormatterABC, DefaultFormatter
12 from IPython.core.formatters import FormatterABC, PlainTextFormatter
7 13
8 14 class A(object):
9 15 def __repr__(self):
@@ -17,7 +23,7 b' def foo_printer(obj, pp, cycle):'
17 23 pp.text('foo')
18 24
19 25 def test_pretty():
20 f = DefaultFormatter()
26 f = PlainTextFormatter()
21 27 f.for_type(A, foo_printer)
22 28 nt.assert_equals(f(A()), 'foo')
23 29 nt.assert_equals(f(B()), 'foo')
@@ -26,5 +32,43 b' def test_pretty():'
26 32 nt.assert_equals(f(B()), 'B()')
27 33
28 34 def test_deferred():
29 f = DefaultFormatter()
35 f = PlainTextFormatter()
36
37 def test_precision():
38 """test various values for float_precision."""
39 f = PlainTextFormatter()
40 nt.assert_equals(f(pi), repr(pi))
41 f.float_precision = 0
42 if numpy:
43 po = numpy.get_printoptions()
44 nt.assert_equals(po['precision'], 0)
45 nt.assert_equals(f(pi), '3')
46 f.float_precision = 2
47 if numpy:
48 po = numpy.get_printoptions()
49 nt.assert_equals(po['precision'], 2)
50 nt.assert_equals(f(pi), '3.14')
51 f.float_precision = '%g'
52 if numpy:
53 po = numpy.get_printoptions()
54 nt.assert_equals(po['precision'], 2)
55 nt.assert_equals(f(pi), '3.14159')
56 f.float_precision = '%e'
57 nt.assert_equals(f(pi), '3.141593e+00')
58 f.float_precision = ''
59 if numpy:
60 po = numpy.get_printoptions()
61 nt.assert_equals(po['precision'], 8)
62 nt.assert_equals(f(pi), repr(pi))
63
64 def test_bad_precision():
65 """test various invalid values for float_precision."""
66 f = PlainTextFormatter()
67 def set_fp(p):
68 f.float_precision=p
69 nt.assert_raises(ValueError, set_fp, '%')
70 nt.assert_raises(ValueError, set_fp, '%.3f%i')
71 nt.assert_raises(ValueError, set_fp, 'foo')
72 nt.assert_raises(ValueError, set_fp, -1)
73
30 74
@@ -386,4 +386,23 b' def doctest_who():'
386 386
387 387 In [7]: %who_ls
388 388 Out[7]: ['alpha', 'beta']
389 """ No newline at end of file
389 """
390
391 def doctest_precision():
392 """doctest for %precision
393
394 In [1]: f = get_ipython().shell.display_formatter.formatters['text/plain']
395
396 In [2]: %precision 5
397 Out[2]: '%.5f'
398
399 In [3]: f.float_format
400 Out[3]: '%.5f'
401
402 In [4]: %precision %e
403 Out[4]: '%e'
404
405 In [5]: f(3.1415927)
406 Out[5]: '3.141593e+00'
407 """
408
General Comments 0
You need to be logged in to leave comments. Login now