##// END OF EJS Templates
Fix #4777 and #7887...
Fix #4777 and #7887 The function in charge of actually converting cursor offset to CodeMirror line number and character number was actually crashing when the cursor was at the last character (loop until undefined, then access length of variable, which is undefined). This was hiding a bug in which when you would completer to a single completion pressing tab after as-you-type filtering, the completion would be completed twice. The logic that was supposed to detect whether or not all completions had a common prefix was actually faulty as the common prefix used to be a string but was then changed to an object. Hence the logic to check whether or not there was actually a common prefix was always true, even for empty string, leading to the deletion of the line (replace by '') in some cases.

File last commit:

r18420:3a581c30
r20538:ae7f6d6a
Show More
test_pretty.py
256 lines | 6.2 KiB | text/x-python | PythonLexer
"""Tests for IPython.lib.pretty."""
# Copyright (c) IPython Development Team.
# Distributed under the terms of the Modified BSD License.
from __future__ import print_function
# Third-party imports
import nose.tools as nt
# Our own imports
from IPython.lib import pretty
from IPython.testing.decorators import skip_without
from IPython.utils.py3compat import PY3
if PY3:
from io import StringIO
else:
from StringIO import StringIO
class MyList(object):
def __init__(self, content):
self.content = content
def _repr_pretty_(self, p, cycle):
if cycle:
p.text("MyList(...)")
else:
with p.group(3, "MyList(", ")"):
for (i, child) in enumerate(self.content):
if i:
p.text(",")
p.breakable()
else:
p.breakable("")
p.pretty(child)
class MyDict(dict):
def _repr_pretty_(self, p, cycle):
p.text("MyDict(...)")
class MyObj(object):
def somemethod(self):
pass
class Dummy1(object):
def _repr_pretty_(self, p, cycle):
p.text("Dummy1(...)")
class Dummy2(Dummy1):
_repr_pretty_ = None
class NoModule(object):
pass
NoModule.__module__ = None
class Breaking(object):
def _repr_pretty_(self, p, cycle):
with p.group(4,"TG: ",":"):
p.text("Breaking(")
p.break_()
p.text(")")
class BreakingRepr(object):
def __repr__(self):
return "Breaking(\n)"
class BreakingReprParent(object):
def _repr_pretty_(self, p, cycle):
with p.group(4,"TG: ",":"):
p.pretty(BreakingRepr())
class BadRepr(object):
def __repr__(self):
return 1/0
def test_indentation():
"""Test correct indentation in groups"""
count = 40
gotoutput = pretty.pretty(MyList(range(count)))
expectedoutput = "MyList(\n" + ",\n".join(" %d" % i for i in range(count)) + ")"
nt.assert_equal(gotoutput, expectedoutput)
def test_dispatch():
"""
Test correct dispatching: The _repr_pretty_ method for MyDict
must be found before the registered printer for dict.
"""
gotoutput = pretty.pretty(MyDict())
expectedoutput = "MyDict(...)"
nt.assert_equal(gotoutput, expectedoutput)
def test_callability_checking():
"""
Test that the _repr_pretty_ method is tested for callability and skipped if
not.
"""
gotoutput = pretty.pretty(Dummy2())
expectedoutput = "Dummy1(...)"
nt.assert_equal(gotoutput, expectedoutput)
def test_sets():
"""
Test that set and frozenset use Python 3 formatting.
"""
objects = [set(), frozenset(), set([1]), frozenset([1]), set([1, 2]),
frozenset([1, 2]), set([-1, -2, -3])]
expected = ['set()', 'frozenset()', '{1}', 'frozenset({1})', '{1, 2}',
'frozenset({1, 2})', '{-3, -2, -1}']
for obj, expected_output in zip(objects, expected):
got_output = pretty.pretty(obj)
yield nt.assert_equal, got_output, expected_output
@skip_without('xxlimited')
def test_pprint_heap_allocated_type():
"""
Test that pprint works for heap allocated types.
"""
import xxlimited
output = pretty.pretty(xxlimited.Null)
nt.assert_equal(output, 'xxlimited.Null')
def test_pprint_nomod():
"""
Test that pprint works for classes with no __module__.
"""
output = pretty.pretty(NoModule)
nt.assert_equal(output, 'NoModule')
def test_pprint_break():
"""
Test that p.break_ produces expected output
"""
output = pretty.pretty(Breaking())
expected = "TG: Breaking(\n ):"
nt.assert_equal(output, expected)
def test_pprint_break_repr():
"""
Test that p.break_ is used in repr
"""
output = pretty.pretty(BreakingReprParent())
expected = "TG: Breaking(\n ):"
nt.assert_equal(output, expected)
def test_bad_repr():
"""Don't catch bad repr errors"""
with nt.assert_raises(ZeroDivisionError):
output = pretty.pretty(BadRepr())
class BadException(Exception):
def __str__(self):
return -1
class ReallyBadRepr(object):
__module__ = 1
@property
def __class__(self):
raise ValueError("I am horrible")
def __repr__(self):
raise BadException()
def test_really_bad_repr():
with nt.assert_raises(BadException):
output = pretty.pretty(ReallyBadRepr())
class SA(object):
pass
class SB(SA):
pass
def test_super_repr():
output = pretty.pretty(super(SA))
nt.assert_in("SA", output)
sb = SB()
output = pretty.pretty(super(SA, sb))
nt.assert_in("SA", output)
def test_long_list():
lis = list(range(10000))
p = pretty.pretty(lis)
last2 = p.rsplit('\n', 2)[-2:]
nt.assert_equal(last2, [' 999,', ' ...]'])
def test_long_set():
s = set(range(10000))
p = pretty.pretty(s)
last2 = p.rsplit('\n', 2)[-2:]
nt.assert_equal(last2, [' 999,', ' ...}'])
def test_long_tuple():
tup = tuple(range(10000))
p = pretty.pretty(tup)
last2 = p.rsplit('\n', 2)[-2:]
nt.assert_equal(last2, [' 999,', ' ...)'])
def test_long_dict():
d = { n:n for n in range(10000) }
p = pretty.pretty(d)
last2 = p.rsplit('\n', 2)[-2:]
nt.assert_equal(last2, [' 999: 999,', ' ...}'])
def test_unbound_method():
output = pretty.pretty(MyObj.somemethod)
nt.assert_in('MyObj.somemethod', output)
class MetaClass(type):
def __new__(cls, name):
return type.__new__(cls, name, (object,), {'name': name})
def __repr__(self):
return "[CUSTOM REPR FOR CLASS %s]" % self.name
ClassWithMeta = MetaClass('ClassWithMeta')
def test_metaclass_repr():
output = pretty.pretty(ClassWithMeta)
nt.assert_equal(output, "[CUSTOM REPR FOR CLASS ClassWithMeta]")
def test_basic_class():
def type_pprint_wrapper(obj, p, cycle):
if obj is MyObj:
type_pprint_wrapper.called = True
return pretty._type_pprint(obj, p, cycle)
type_pprint_wrapper.called = False
stream = StringIO()
printer = pretty.RepresentationPrinter(stream)
printer.type_pprinters[type] = type_pprint_wrapper
printer.pretty(MyObj)
printer.flush()
output = stream.getvalue()
nt.assert_equal(output, '%s.MyObj' % __name__)
nt.assert_true(type_pprint_wrapper.called)