From d23dc694867408094a2164b8a48bb2fe5881c92f Mon Sep 17 00:00:00 2001 From: Alex Hall Date: Tue, 4 Aug 2020 18:54:37 +0200 Subject: [PATCH 1/3] Support attributes in varname and nameof --- tests/test_varname.py | 5 +---- varname.py | 23 +++++++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/tests/test_varname.py b/tests/test_varname.py index 6d0e538..bac2f1f 100644 --- a/tests/test_varname.py +++ b/tests/test_varname.py @@ -322,10 +322,7 @@ def test_nameof_expr(): lam = lambda: 0 lam.a = 1 - with pytest.raises(VarnameRetrievingError) as vrerr: - varname_module.nameof(test, lam.a) - assert str(vrerr.value) == ("Only variables should " - "be passed to nameof.") + assert varname_module.nameof(test, lam.a) == ("test", "a") def test_class_property(): class C: diff --git a/varname.py b/varname.py index 2fda4ec..57aef6b 100644 --- a/varname.py +++ b/varname.py @@ -160,14 +160,20 @@ def varname(caller=1, raise_exc=False): "on the very left will be used.", MultipleTargetAssignmentWarning) target = node.targets[0] + return _node_name(target) - # must be a variable - if isinstance(target, ast.Name): - return target.id - raise VarnameRetrievingError( - f"Invaid variable assigned: {ast.dump(target)!r}" - ) +def _node_name(node): + if isinstance(node, ast.Name): + return node.id + elif isinstance(node, ast.Attribute): + return node.attr + else: + raise VarnameRetrievingError( + f"Can only get name of a variable or attribute, " + f"not {ast.dump(node)}" + ) + def will(caller=1, raise_exc=False): """Detect the attribute name right immediately after a function call. @@ -263,10 +269,7 @@ def nameof(*args, caller=1): ret = [] for arg in node.args: - if not isinstance(arg, ast.Name): - raise VarnameRetrievingError("Only variables should " - "be passed to nameof.") - ret.append(arg.id) + ret.append(_node_name(arg)) if not ret: raise VarnameRetrievingError("At least one variable should be " From a317f030623d1f539693992646d44eaf0db263a0 Mon Sep 17 00:00:00 2001 From: Alex Hall Date: Sun, 9 Aug 2020 18:00:37 +0200 Subject: [PATCH 2/3] Remove elses for pylint --- varname.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/varname.py b/varname.py index 57aef6b..11c534d 100644 --- a/varname.py +++ b/varname.py @@ -166,13 +166,13 @@ def varname(caller=1, raise_exc=False): def _node_name(node): if isinstance(node, ast.Name): return node.id - elif isinstance(node, ast.Attribute): + if isinstance(node, ast.Attribute): return node.attr - else: - raise VarnameRetrievingError( - f"Can only get name of a variable or attribute, " - f"not {ast.dump(node)}" - ) + + raise VarnameRetrievingError( + f"Can only get name of a variable or attribute, " + f"not {ast.dump(node)}" + ) def will(caller=1, raise_exc=False): From 303eb1f2bc9803c8ae4e48976a0ee1900e3cfbb6 Mon Sep 17 00:00:00 2001 From: Alex Hall Date: Tue, 11 Aug 2020 22:09:46 +0200 Subject: [PATCH 3/3] Add more tests for nameof attributes --- tests/test_varname.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/test_varname.py b/tests/test_varname.py index cc19d30..b33929f 100644 --- a/tests/test_varname.py +++ b/tests/test_varname.py @@ -327,11 +327,20 @@ def test_nameof_expr(self): lam = lambda: 0 lam.a = 1 + lam.lam = lam + lams = [lam] self.assertEqual( varname_module.nameof(test, lam.a), ("test", "a"), ) + self.assertEqual(nameof(lam.a), "a") + self.assertEqual(nameof(lam.lam.lam.lam.a), "a") + self.assertEqual(nameof(lam.lam.lam.lam), "lam") + self.assertEqual(nameof(lams[0].lam), "lam") + self.assertEqual(nameof(lams[0].lam.a), "a") + self.assertEqual(nameof((lam() or lams[0]).lam.a), "a") + def test_nameof_pytest_fail(): with pytest.raises(