From 900be4f6b8c62beeadc8abd38a22b0b3034836ea Mon Sep 17 00:00:00 2001 From: Jay Shah Date: Mon, 16 Nov 2020 13:01:40 +0000 Subject: [PATCH 1/2] change default ls to infinite depth --- python_ls/_ls.py | 10 ++++++---- tests/test_ls.py | 17 +++++++++++++++-- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/python_ls/_ls.py b/python_ls/_ls.py index d5fe516..522e545 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 objects such as the dict type have __len__ + # method which raises 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..6007b4a 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) + # a callable (lambda recurses infinitely in Python 2.7 when depth=None) + o.foo.bar._something_else = dict o.foo.baz = {'something_weird': 'going on', 'blah': 'bleh'} o.lala = Object() o.lala.lele = Object() @@ -51,3 +52,15 @@ 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_basic_ls_usage(test_obj, capsys): + ls(test_obj, 'something') + out, err = capsys.readouterr() + expect = [ + ['foo.bar._something_else()', 'type'], + ['foo.bar.something', 'Object'], + ["foo.baz['something_weird']", 'str', '8'], + ['lala.something', 'Object'] + ] + assert expect == [line.split() for line in out.splitlines()] + From f4ffcacfeb1a7003f6eead36b2c491f832a69930 Mon Sep 17 00:00:00 2001 From: Jay Shah Date: Mon, 16 Nov 2020 13:18:23 +0000 Subject: [PATCH 2/2] constructor object as attributes --- python_ls/_ls.py | 4 ++-- tests/test_ls.py | 20 +++++++++++++++++--- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/python_ls/_ls.py b/python_ls/_ls.py index 522e545..2d17de3 100644 --- a/python_ls/_ls.py +++ b/python_ls/_ls.py @@ -30,8 +30,8 @@ def ls(obj, attr=None, depth=None, dunder=False, under=True): try: size = len(value) except TypeError as exc: - # certain objects such as the dict type have __len__ - # method which raises TypeError + # 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 6007b4a..b9ee357 100644 --- a/tests/test_ls.py +++ b/tests/test_ls.py @@ -14,8 +14,8 @@ def test_obj(): o.foo.bar.something = Object() o.foo.bar.aaa = Object() o.foo.bar.bbb = Object() - # a callable (lambda recurses infinitely in Python 2.7 when depth=None) - o.foo.bar._something_else = dict + 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() @@ -53,14 +53,28 @@ def test_depth_is_None(test_obj): 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()', 'type'], + ['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()] +