Skip to content

Commit a593ef5

Browse files
committed
Add more tests for will; pass raise_exc down to _get_node.
1 parent 0e461d1 commit a593ef5

File tree

2 files changed

+78
-13
lines changed

2 files changed

+78
-13
lines changed

tests/test_varname.py

Lines changed: 73 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,7 @@ def i_will():
386386

387387
func = i_will().abc
388388
assert func.will == 'abc'
389+
assert getattr(func, 'will') == 'abc'
389390

390391
def test_will_deep():
391392

@@ -427,21 +428,31 @@ def do(self):
427428
assert c.will == 'do'
428429
assert result == 'I will do something'
429430

430-
# issue #18
431+
431432
def test_will_method():
432433
class AwesomeClass:
433434
def __init__(self):
434-
self.will = None
435+
self.wills = [None]
436+
437+
def __call__(self, *_):
438+
return self
439+
440+
myself = __call__
441+
__getattr__ = __call__
435442

436443
def permit(self, *_):
437-
self.will = will(raise_exc=False)
438-
if self.will == 'do':
439-
# let self handle do
440-
return self
441-
raise AttributeError('Should do something with AwesomeClass object')
444+
self.wills.append(will(raise_exc=False))
445+
446+
if self.wills[-1] is None:
447+
raise AttributeError(
448+
'Should do something with AwesomeClass object'
449+
)
450+
451+
# let self handle do
452+
return self
442453

443454
def do(self):
444-
if self.will != 'do':
455+
if self.wills[-1] != 'do':
445456
raise AttributeError("You don't have permission to do")
446457
return 'I am doing!'
447458

@@ -456,8 +467,31 @@ def do(self):
456467
awesome.permit()
457468
assert str(exc.value) == 'Should do something with AwesomeClass object'
458469

470+
# clear wills
471+
awesome = AwesomeClass()
459472
ret = awesome.permit().do()
460473
assert ret == 'I am doing!'
474+
assert awesome.wills == [None, 'do']
475+
476+
awesome = AwesomeClass()
477+
ret = awesome.myself().permit().do()
478+
assert ret == 'I am doing!'
479+
assert awesome.wills == [None, 'do']
480+
481+
awesome = AwesomeClass()
482+
ret = awesome().permit().do()
483+
assert ret == 'I am doing!'
484+
assert awesome.wills == [None, 'do']
485+
486+
awesome = AwesomeClass()
487+
ret = awesome.attr.permit().do()
488+
assert ret == 'I am doing!'
489+
assert awesome.wills == [None, 'do']
490+
491+
awesome = AwesomeClass()
492+
ret = awesome.permit().permit().do()
493+
assert ret == 'I am doing!'
494+
assert awesome.wills == [None, 'permit', 'do']
461495

462496
with pytest.raises(AttributeError) as exc:
463497
print(awesome[2])
@@ -466,6 +500,37 @@ def do(self):
466500
ret = awesome[2].do()
467501
assert ret == 'I am doing!'
468502

503+
def test_will_decorated():
504+
505+
def return_self(func):
506+
def wrapper(self, *args, **kwargs):
507+
func(self, *args, **kwargs)
508+
return self
509+
510+
return wrapper
511+
512+
class Foo:
513+
514+
def __init__(self):
515+
self.will = None
516+
517+
def get_will(self):
518+
self.will = will(raise_exc=False)
519+
return self
520+
521+
@return_self
522+
def get_will_decor(self):
523+
self.will = will(2, raise_exc=False)
524+
525+
def __getattr__(self, name):
526+
return self.will
527+
528+
x = Foo().get_will().x
529+
assert x == 'x'
530+
531+
x = Foo().get_will_decor().x
532+
assert x == 'x'
533+
469534

470535
def test_will_fail():
471536

varname.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ def varname(caller: int = 1, raise_exc: bool = True) -> str:
3838
in the assign node. (e.g: `a = b = func()`, in such a case,
3939
`b == 'a'`, may not be the case you want)
4040
"""
41-
node = _get_node(caller)
41+
node = _get_node(caller, raise_exc=raise_exc)
4242
if not node:
4343
if raise_exc:
4444
raise VarnameRetrievingError("Unable to retrieve the ast node.")
@@ -102,7 +102,7 @@ def will(caller: int = 1, raise_exc: bool = True) -> str:
102102
VarnameRetrievingError: When `raise_exc` is `True` and we failed to
103103
detect the attribute name (including not having one)
104104
"""
105-
node = _get_node(caller)
105+
node = _get_node(caller, raise_exc=raise_exc)
106106
if not node:
107107
if raise_exc:
108108
raise VarnameRetrievingError("Unable to retrieve the frame.")
@@ -180,7 +180,7 @@ def nameof(*args, caller: int = 1) -> Union[str, Tuple[str]]:
180180
Returns:
181181
tuple|str: The names of variables passed in
182182
"""
183-
node = _get_node(caller - 1)
183+
node = _get_node(caller - 1, raise_exc=True)
184184
if not node:
185185
if len(args) == 1:
186186
return _bytecode_nameof(caller + 1)
@@ -257,7 +257,7 @@ def _get_frame(caller):
257257
except Exception as exc:
258258
raise VarnameRetrievingError from exc
259259

260-
def _get_node(caller):
260+
def _get_node(caller: int, raise_exc: bool = True):
261261
"""Try to get node from the executing object.
262262
263263
This can fail when a frame is failed to retrieve.
@@ -276,7 +276,7 @@ def _get_node(caller):
276276
if exet.node:
277277
return exet.node
278278

279-
if exet.source.text and exet.source.tree:
279+
if exet.source.text and exet.source.tree and raise_exc:
280280
raise VarnameRetrievingError(
281281
"Couldn't retrieve the call node. "
282282
"This may happen if you're using some other AST magic at the "

0 commit comments

Comments
 (0)