diff --git a/python_ls/_ls.py b/python_ls/_ls.py index d5fe516..2d17de3 100644 --- a/python_ls/_ls.py +++ b/python_ls/_ls.py @@ -21,16 +21,18 @@ def ls(obj, attr=None, depth=None, dunder=False, under=True): :param under: If True single underscore prefixed attributes are ignored, default is enabled :return: None """ - if depth is None: - depth = 1 - for attr, value in iter_ls(obj, attr=attr, depth=depth, dunder=dunder, under=under): size = '' if has_pandas and isinstance(value, pd.DataFrame): size = '{0}x{1}'.format(*value.shape) elif hasattr(value, '__len__'): - size = len(value) + try: + size = len(value) + except TypeError as exc: + # certain constructor object such as dict, list have a + # __len__ method but it throws a TypeError + pass type_name = type(value).__name__ print('{:<60}{:>20}{:>7}'.format(attr, type_name, size)) diff --git a/tests/test_ls.py b/tests/test_ls.py index 1a71368..b9ee357 100644 --- a/tests/test_ls.py +++ b/tests/test_ls.py @@ -1,4 +1,4 @@ -from python_ls import iter_ls +from python_ls import iter_ls, ls import pytest @@ -14,7 +14,8 @@ def test_obj(): o.foo.bar.something = Object() o.foo.bar.aaa = Object() o.foo.bar.bbb = Object() - o.foo.bar._something_else = dict # a callable (lambda recurses infinitely in Python 2.7 when depth=None) + o.foo.bar._something_else = lambda: None + o.foo.bar.constructor_obj = dict o.foo.baz = {'something_weird': 'going on', 'blah': 'bleh'} o.lala = Object() o.lala.lele = Object() @@ -51,3 +52,29 @@ def test_depth_is_None(test_obj): actual = [x[0] for x in iter_ls(test_obj, 'something', depth=None)] assert actual == expected + +def test_iter_ls_constructor_obj(test_obj): + expected = ['foo.bar.constructor_obj()'] + + actual = [x[0] for x in iter_ls(test_obj, 'constructor', depth=None)] + assert actual == expected + + +def test_basic_ls_usage(test_obj, capsys): + ls(test_obj, 'something') + out, err = capsys.readouterr() + expect = [ + ['foo.bar._something_else()', 'function'], + ['foo.bar.something', 'Object'], + ["foo.baz['something_weird']", 'str', '8'], + ['lala.something', 'Object'] + ] + assert expect == [line.split() for line in out.splitlines()] + + +def test_ls_constructor_obj(test_obj, capsys): + ls(test_obj, 'constructor') + out, err = capsys.readouterr() + expect = [['foo.bar.constructor_obj()', 'type']] + assert expect == [line.split() for line in out.splitlines()] +