test_formatters.py
432 lines
| 11.9 KiB
| text/x-python
|
PythonLexer
MinRK
|
r13977 | """Tests for the Formatters.""" | |
Robert Kern
|
r3209 | ||
Min RK
|
r19557 | import warnings | |
MinRK
|
r3350 | from math import pi | |
try: | |||
import numpy | |||
except: | |||
numpy = None | |||
Robert Kern
|
r3209 | import nose.tools as nt | |
Min RK
|
r19557 | from IPython import get_ipython | |
MinRK
|
r15216 | from IPython.config import Config | |
Brian E. Granger
|
r15121 | from IPython.core.formatters import ( | |
Min RK
|
r19384 | PlainTextFormatter, HTMLFormatter, PDFFormatter, _mod_name_key, | |
Min RK
|
r19557 | DisplayFormatter, JSONFormatter, | |
Brian E. Granger
|
r15121 | ) | |
MinRK
|
r13977 | from IPython.utils.io import capture_output | |
Robert Kern
|
r3209 | ||
class A(object): | |||
def __repr__(self): | |||
return 'A()' | |||
class B(A): | |||
def __repr__(self): | |||
return 'B()' | |||
MinRK
|
r13781 | class C: | |
pass | |||
MinRK
|
r18025 | class BadRepr(object): | |
def __repr__(self): | |||
raise ValueError("bad repr") | |||
Robert Kern
|
r6268 | class BadPretty(object): | |
_repr_pretty_ = None | |||
class GoodPretty(object): | |||
def _repr_pretty_(self, pp, cycle): | |||
pp.text('foo') | |||
def __repr__(self): | |||
return 'GoodPretty()' | |||
Robert Kern
|
r3209 | def foo_printer(obj, pp, cycle): | |
pp.text('foo') | |||
def test_pretty(): | |||
MinRK
|
r3350 | f = PlainTextFormatter() | |
Robert Kern
|
r3209 | f.for_type(A, foo_printer) | |
Bradley M. Froehle
|
r7875 | nt.assert_equal(f(A()), 'foo') | |
nt.assert_equal(f(B()), 'foo') | |||
nt.assert_equal(f(GoodPretty()), 'foo') | |||
Robert Kern
|
r6268 | # Just don't raise an exception for the following: | |
f(BadPretty()) | |||
Robert Kern
|
r3209 | f.pprint = False | |
Bradley M. Froehle
|
r7875 | nt.assert_equal(f(A()), 'A()') | |
nt.assert_equal(f(B()), 'B()') | |||
nt.assert_equal(f(GoodPretty()), 'GoodPretty()') | |||
Robert Kern
|
r6268 | ||
Robert Kern
|
r3209 | ||
def test_deferred(): | |||
MinRK
|
r3350 | f = PlainTextFormatter() | |
def test_precision(): | |||
"""test various values for float_precision.""" | |||
f = PlainTextFormatter() | |||
Bradley M. Froehle
|
r7875 | nt.assert_equal(f(pi), repr(pi)) | |
MinRK
|
r3350 | f.float_precision = 0 | |
if numpy: | |||
po = numpy.get_printoptions() | |||
Bradley M. Froehle
|
r7875 | nt.assert_equal(po['precision'], 0) | |
nt.assert_equal(f(pi), '3') | |||
MinRK
|
r3350 | f.float_precision = 2 | |
if numpy: | |||
po = numpy.get_printoptions() | |||
Bradley M. Froehle
|
r7875 | nt.assert_equal(po['precision'], 2) | |
nt.assert_equal(f(pi), '3.14') | |||
MinRK
|
r3350 | f.float_precision = '%g' | |
if numpy: | |||
po = numpy.get_printoptions() | |||
Bradley M. Froehle
|
r7875 | nt.assert_equal(po['precision'], 2) | |
nt.assert_equal(f(pi), '3.14159') | |||
MinRK
|
r3350 | f.float_precision = '%e' | |
Bradley M. Froehle
|
r7875 | nt.assert_equal(f(pi), '3.141593e+00') | |
MinRK
|
r3350 | f.float_precision = '' | |
if numpy: | |||
po = numpy.get_printoptions() | |||
Bradley M. Froehle
|
r7875 | nt.assert_equal(po['precision'], 8) | |
nt.assert_equal(f(pi), repr(pi)) | |||
MinRK
|
r3350 | ||
def test_bad_precision(): | |||
"""test various invalid values for float_precision.""" | |||
f = PlainTextFormatter() | |||
def set_fp(p): | |||
f.float_precision=p | |||
nt.assert_raises(ValueError, set_fp, '%') | |||
nt.assert_raises(ValueError, set_fp, '%.3f%i') | |||
nt.assert_raises(ValueError, set_fp, 'foo') | |||
nt.assert_raises(ValueError, set_fp, -1) | |||
MinRK
|
r13655 | def test_for_type(): | |
f = PlainTextFormatter() | |||
MinRK
|
r13783 | # initial return, None | |
nt.assert_is(f.for_type(C, foo_printer), None) | |||
MinRK
|
r13655 | # no func queries | |
MinRK
|
r13783 | nt.assert_is(f.for_type(C), foo_printer) | |
MinRK
|
r13655 | # shouldn't change anything | |
MinRK
|
r13783 | nt.assert_is(f.for_type(C), foo_printer) | |
MinRK
|
r13781 | # None should do the same | |
MinRK
|
r13783 | nt.assert_is(f.for_type(C, None), foo_printer) | |
nt.assert_is(f.for_type(C, None), foo_printer) | |||
MinRK
|
r13655 | ||
MinRK
|
r13781 | def test_for_type_string(): | |
MinRK
|
r13655 | f = PlainTextFormatter() | |
mod = C.__module__ | |||
MinRK
|
r13781 | type_str = '%s.%s' % (C.__module__, 'C') | |
MinRK
|
r13783 | # initial return, None | |
nt.assert_is(f.for_type(type_str, foo_printer), None) | |||
MinRK
|
r13781 | # no func queries | |
MinRK
|
r13783 | nt.assert_is(f.for_type(type_str), foo_printer) | |
nt.assert_in(_mod_name_key(C), f.deferred_printers) | |||
nt.assert_is(f.for_type(C), foo_printer) | |||
nt.assert_not_in(_mod_name_key(C), f.deferred_printers) | |||
nt.assert_in(C, f.type_printers) | |||
MinRK
|
r13781 | ||
def test_for_type_by_name(): | |||
f = PlainTextFormatter() | |||
mod = C.__module__ | |||
MinRK
|
r13655 | ||
MinRK
|
r13783 | # initial return, None | |
nt.assert_is(f.for_type_by_name(mod, 'C', foo_printer), None) | |||
MinRK
|
r13655 | # no func queries | |
MinRK
|
r13783 | nt.assert_is(f.for_type_by_name(mod, 'C'), foo_printer) | |
MinRK
|
r13655 | # shouldn't change anything | |
MinRK
|
r13783 | nt.assert_is(f.for_type_by_name(mod, 'C'), foo_printer) | |
MinRK
|
r13781 | # None should do the same | |
MinRK
|
r13783 | nt.assert_is(f.for_type_by_name(mod, 'C', None), foo_printer) | |
nt.assert_is(f.for_type_by_name(mod, 'C', None), foo_printer) | |||
MinRK
|
r13655 | ||
MinRK
|
r13781 | def test_lookup(): | |
f = PlainTextFormatter() | |||
MinRK
|
r13783 | f.for_type(C, foo_printer) | |
nt.assert_is(f.lookup(C()), foo_printer) | |||
with nt.assert_raises(KeyError): | |||
f.lookup(A()) | |||
def test_lookup_string(): | |||
f = PlainTextFormatter() | |||
type_str = '%s.%s' % (C.__module__, 'C') | |||
f.for_type(type_str, foo_printer) | |||
nt.assert_is(f.lookup(C()), foo_printer) | |||
# should move from deferred to imported dict | |||
nt.assert_not_in(_mod_name_key(C), f.deferred_printers) | |||
nt.assert_in(C, f.type_printers) | |||
def test_lookup_by_type(): | |||
f = PlainTextFormatter() | |||
f.for_type(C, foo_printer) | |||
nt.assert_is(f.lookup_by_type(C), foo_printer) | |||
type_str = '%s.%s' % (C.__module__, 'C') | |||
with nt.assert_raises(KeyError): | |||
f.lookup_by_type(A) | |||
def test_lookup_by_type_string(): | |||
f = PlainTextFormatter() | |||
type_str = '%s.%s' % (C.__module__, 'C') | |||
f.for_type(type_str, foo_printer) | |||
# verify insertion | |||
nt.assert_in(_mod_name_key(C), f.deferred_printers) | |||
nt.assert_not_in(C, f.type_printers) | |||
MinRK
|
r13781 | ||
MinRK
|
r13788 | nt.assert_is(f.lookup_by_type(type_str), foo_printer) | |
# lookup by string doesn't cause import | |||
nt.assert_in(_mod_name_key(C), f.deferred_printers) | |||
nt.assert_not_in(C, f.type_printers) | |||
MinRK
|
r13783 | nt.assert_is(f.lookup_by_type(C), foo_printer) | |
# should move from deferred to imported dict | |||
nt.assert_not_in(_mod_name_key(C), f.deferred_printers) | |||
nt.assert_in(C, f.type_printers) | |||
MinRK
|
r13788 | def test_in_formatter(): | |
f = PlainTextFormatter() | |||
f.for_type(C, foo_printer) | |||
type_str = '%s.%s' % (C.__module__, 'C') | |||
nt.assert_in(C, f) | |||
nt.assert_in(type_str, f) | |||
def test_string_in_formatter(): | |||
f = PlainTextFormatter() | |||
type_str = '%s.%s' % (C.__module__, 'C') | |||
f.for_type(type_str, foo_printer) | |||
nt.assert_in(type_str, f) | |||
nt.assert_in(C, f) | |||
MinRK
|
r13783 | def test_pop(): | |
f = PlainTextFormatter() | |||
f.for_type(C, foo_printer) | |||
nt.assert_is(f.lookup_by_type(C), foo_printer) | |||
MinRK
|
r13788 | nt.assert_is(f.pop(C, None), foo_printer) | |
f.for_type(C, foo_printer) | |||
nt.assert_is(f.pop(C), foo_printer) | |||
MinRK
|
r13783 | with nt.assert_raises(KeyError): | |
f.lookup_by_type(C) | |||
with nt.assert_raises(KeyError): | |||
f.pop(C) | |||
with nt.assert_raises(KeyError): | |||
f.pop(A) | |||
MinRK
|
r13788 | nt.assert_is(f.pop(A, None), None) | |
MinRK
|
r13783 | ||
def test_pop_string(): | |||
f = PlainTextFormatter() | |||
MinRK
|
r13781 | type_str = '%s.%s' % (C.__module__, 'C') | |
MinRK
|
r13783 | with nt.assert_raises(KeyError): | |
f.pop(type_str) | |||
f.for_type(type_str, foo_printer) | |||
f.pop(type_str) | |||
with nt.assert_raises(KeyError): | |||
f.lookup_by_type(C) | |||
with nt.assert_raises(KeyError): | |||
f.pop(type_str) | |||
f.for_type(C, foo_printer) | |||
MinRK
|
r13788 | nt.assert_is(f.pop(type_str, None), foo_printer) | |
MinRK
|
r13783 | with nt.assert_raises(KeyError): | |
f.lookup_by_type(C) | |||
with nt.assert_raises(KeyError): | |||
f.pop(type_str) | |||
MinRK
|
r13788 | nt.assert_is(f.pop(type_str, None), None) | |
MinRK
|
r13783 | ||
MinRK
|
r18025 | def test_error_method(): | |
MinRK
|
r13977 | f = HTMLFormatter() | |
class BadHTML(object): | |||
def _repr_html_(self): | |||
MinRK
|
r18025 | raise ValueError("Bad HTML") | |
MinRK
|
r13977 | bad = BadHTML() | |
with capture_output() as captured: | |||
result = f(bad) | |||
nt.assert_is(result, None) | |||
MinRK
|
r18025 | nt.assert_in("Traceback", captured.stdout) | |
nt.assert_in("Bad HTML", captured.stdout) | |||
nt.assert_in("_repr_html_", captured.stdout) | |||
MinRK
|
r13977 | ||
MinRK
|
r14636 | def test_nowarn_notimplemented(): | |
f = HTMLFormatter() | |||
class HTMLNotImplemented(object): | |||
def _repr_html_(self): | |||
raise NotImplementedError | |||
h = HTMLNotImplemented() | |||
with capture_output() as captured: | |||
result = f(h) | |||
nt.assert_is(result, None) | |||
MinRK
|
r18025 | nt.assert_equal("", captured.stderr) | |
nt.assert_equal("", captured.stdout) | |||
MinRK
|
r14636 | ||
MinRK
|
r13977 | def test_warn_error_for_type(): | |
f = HTMLFormatter() | |||
f.for_type(int, lambda i: name_error) | |||
with capture_output() as captured: | |||
result = f(5) | |||
nt.assert_is(result, None) | |||
MinRK
|
r18025 | nt.assert_in("Traceback", captured.stdout) | |
nt.assert_in("NameError", captured.stdout) | |||
nt.assert_in("name_error", captured.stdout) | |||
MinRK
|
r13977 | ||
MinRK
|
r18025 | def test_error_pretty_method(): | |
MinRK
|
r13977 | f = PlainTextFormatter() | |
class BadPretty(object): | |||
def _repr_pretty_(self): | |||
return "hello" | |||
bad = BadPretty() | |||
with capture_output() as captured: | |||
result = f(bad) | |||
nt.assert_is(result, None) | |||
MinRK
|
r18025 | nt.assert_in("Traceback", captured.stdout) | |
nt.assert_in("_repr_pretty_", captured.stdout) | |||
nt.assert_in("given", captured.stdout) | |||
nt.assert_in("argument", captured.stdout) | |||
def test_bad_repr_traceback(): | |||
f = PlainTextFormatter() | |||
bad = BadRepr() | |||
with capture_output() as captured: | |||
result = f(bad) | |||
# catches error, returns None | |||
nt.assert_is(result, None) | |||
nt.assert_in("Traceback", captured.stdout) | |||
nt.assert_in("__repr__", captured.stdout) | |||
nt.assert_in("ValueError", captured.stdout) | |||
MinRK
|
r13977 | ||
Brian E. Granger
|
r15121 | class MakePDF(object): | |
def _repr_pdf_(self): | |||
return 'PDF' | |||
MinRK
|
r13655 | ||
Brian E. Granger
|
r15121 | def test_pdf_formatter(): | |
pdf = MakePDF() | |||
f = PDFFormatter() | |||
nt.assert_equal(f(pdf), 'PDF') | |||
MinRK
|
r15216 | ||
def test_print_method_bound(): | |||
f = HTMLFormatter() | |||
class MyHTML(object): | |||
def _repr_html_(self): | |||
return "hello" | |||
with capture_output() as captured: | |||
result = f(MyHTML) | |||
nt.assert_is(result, None) | |||
nt.assert_not_in("FormatterWarning", captured.stderr) | |||
with capture_output() as captured: | |||
result = f(MyHTML()) | |||
nt.assert_equal(result, "hello") | |||
nt.assert_equal(captured.stderr, "") | |||
Min RK
|
r19026 | def test_print_method_weird(): | |
class TextMagicHat(object): | |||
def __getattr__(self, key): | |||
return key | |||
f = HTMLFormatter() | |||
text_hat = TextMagicHat() | |||
nt.assert_equal(text_hat._repr_html_, '_repr_html_') | |||
with capture_output() as captured: | |||
result = f(text_hat) | |||
nt.assert_is(result, None) | |||
nt.assert_not_in("FormatterWarning", captured.stderr) | |||
class CallableMagicHat(object): | |||
def __getattr__(self, key): | |||
return lambda : key | |||
call_hat = CallableMagicHat() | |||
with capture_output() as captured: | |||
result = f(call_hat) | |||
Min RK
|
r19128 | nt.assert_equal(result, None) | |
Min RK
|
r19026 | ||
class BadReprArgs(object): | |||
def _repr_html_(self, extra, args): | |||
return "html" | |||
bad = BadReprArgs() | |||
with capture_output() as captured: | |||
result = f(bad) | |||
nt.assert_is(result, None) | |||
nt.assert_not_in("FormatterWarning", captured.stderr) | |||
MinRK
|
r15216 | def test_format_config(): | |
"""config objects don't pretend to support fancy reprs with lazy attrs""" | |||
f = HTMLFormatter() | |||
cfg = Config() | |||
with capture_output() as captured: | |||
result = f(cfg) | |||
nt.assert_is(result, None) | |||
nt.assert_equal(captured.stderr, "") | |||
with capture_output() as captured: | |||
result = f(Config) | |||
nt.assert_is(result, None) | |||
nt.assert_equal(captured.stderr, "") | |||
Min RK
|
r18518 | ||
def test_pretty_max_seq_length(): | |||
f = PlainTextFormatter(max_seq_length=1) | |||
lis = list(range(3)) | |||
text = f(lis) | |||
nt.assert_equal(text, '[0, ...]') | |||
f.max_seq_length = 0 | |||
text = f(lis) | |||
nt.assert_equal(text, '[0, 1, 2]') | |||
text = f(list(range(1024))) | |||
lines = text.splitlines() | |||
nt.assert_equal(len(lines), 1024) | |||
Min RK
|
r19384 | ||
def test_ipython_display_formatter(): | |||
"""Objects with _ipython_display_ defined bypass other formatters""" | |||
f = get_ipython().display_formatter | |||
catcher = [] | |||
class SelfDisplaying(object): | |||
def _ipython_display_(self): | |||
catcher.append(self) | |||
class NotSelfDisplaying(object): | |||
def __repr__(self): | |||
return "NotSelfDisplaying" | |||
def _ipython_display_(self): | |||
raise NotImplementedError | |||
yes = SelfDisplaying() | |||
no = NotSelfDisplaying() | |||
d, md = f.format(no) | |||
nt.assert_equal(d, {'text/plain': repr(no)}) | |||
nt.assert_equal(md, {}) | |||
nt.assert_equal(catcher, []) | |||
d, md = f.format(yes) | |||
nt.assert_equal(d, {}) | |||
nt.assert_equal(md, {}) | |||
nt.assert_equal(catcher, [yes]) | |||
Min RK
|
r19557 | def test_json_as_string_deprecated(): | |
class JSONString(object): | |||
def _repr_json_(self): | |||
return '{}' | |||
f = JSONFormatter() | |||
with warnings.catch_warnings(record=True) as w: | |||
d = f(JSONString()) | |||
nt.assert_equal(d, {}) | |||
nt.assert_equal(len(w), 1) | |||