Skip to content

Commit 867e4ae

Browse files
authored
Add ignore argument to argname2() (#55)
* Add `ignore` argument to `argname2()` * 0.7.1 * Fix utils.get_argument_sources() when kwargs is given as **kwargs.
1 parent a39f4c9 commit 867e4ae

File tree

9 files changed

+51
-27
lines changed

9 files changed

+51
-27
lines changed

docs/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## v0.7.1
2+
- Add `ignore` argument to `argname2()`
3+
- Fix Fix utils.get_argument_sources() when kwargs is given as `**kwargs`.
4+
15
## v0.7.0
26
- `ImproperUseError` is now independent of `VarnameRetrievingError`
37
- Deprecate `argname`, superseded by `argname2`

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "poetry.masonry.api"
44

55
[tool.poetry]
66
name = "varname"
7-
version = "0.7.0"
7+
version = "0.7.1"
88
description = "Dark magics about variable names in python."
99
authors = [ "pwwang <[email protected]>",]
1010
license = "MIT"

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
setup(
2525
long_description=readme,
2626
name='varname',
27-
version='0.7.0',
27+
version='0.7.1',
2828
description='Dark magics about variable names in python.',
2929
python_requires='==3.*,>=3.6.0',
3030
project_urls={"homepage": "https://github.com/pwwang/python-varname",

tests/test_argname.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -373,10 +373,19 @@ def func(x):
373373
func(1)
374374

375375
def test_argname2_frame_error():
376-
377376
def func(x):
378377
return argname2('x', frame=2)
379378

380-
with pytest.raises(VarnameRetrievingError):
379+
with pytest.raises(ValueError):
381380
func(1)
382381

382+
def test_argname2_ignore():
383+
def target(*args):
384+
return argname2('*args', ignore=wrapper)
385+
386+
def wrapper(*args):
387+
return target(*args)
388+
389+
x = y = 1
390+
out = wrapper(x, y)
391+
assert out == ('x', 'y')

tests/test_varname.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -511,11 +511,12 @@ def foo3():
511511
x = foo1()
512512
assert x == 'x'
513513
msgs = capsys.readouterr().err.splitlines()
514-
assert "Ignored by IgnoreModule('varname')" in msgs[0]
515-
assert "Skipping (2 more to skip) [In 'foo3'" in msgs[1]
516-
assert "Ignored by IgnoreModuleQualname('tests.test_varname', '*.wrapper')" in msgs[2]
517-
assert "Skipping (1 more to skip) [In 'foo2'" in msgs[3]
518-
assert "Ignored by IgnoreModuleQualname('tests.test_varname', '*.wrapper')" in msgs[4]
519-
assert "Skipping (0 more to skip) [In 'foo1'" in msgs[5]
520-
assert "Ignored by IgnoreModuleQualname('tests.test_varname', '*.wrapper')" in msgs[6]
521-
assert "Gotcha! [In 'test_internal_debug'" in msgs[7]
514+
assert ">>> IgnoreList initiated <<<" in msgs[0]
515+
assert "Ignored by IgnoreModule('varname')" in msgs[1]
516+
assert "Skipping (2 more to skip) [In 'foo3'" in msgs[2]
517+
assert "Ignored by IgnoreModuleQualname('tests.test_varname', '*.wrapper')" in msgs[3]
518+
assert "Skipping (1 more to skip) [In 'foo2'" in msgs[4]
519+
assert "Ignored by IgnoreModuleQualname('tests.test_varname', '*.wrapper')" in msgs[5]
520+
assert "Skipping (0 more to skip) [In 'foo1'" in msgs[6]
521+
assert "Ignored by IgnoreModuleQualname('tests.test_varname', '*.wrapper')" in msgs[7]
522+
assert "Gotcha! [In 'test_internal_debug'" in msgs[8]

varname/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@
1111
)
1212
from .core import varname, nameof, will, argname, argname2
1313

14-
__version__ = "0.7.0"
14+
__version__ = "0.7.1"

varname/core.py

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ def will(frame: int = 1, raise_exc: bool = True) -> str:
202202

203203

204204
def nameof(
205-
var, # pylint: disable=unused-argument
205+
var, # pylint: disable=unused-argument
206206
*more_vars,
207207
# *, keyword only argument, supported with python3.8+
208208
frame: int = 1,
@@ -294,10 +294,10 @@ def nameof(
294294
out = argname2(
295295
"var", "*more_vars", func=nameof, frame=frame, vars_only=vars_only
296296
)
297-
return out if more_vars else out[0] # type: ignore
297+
return out if more_vars else out[0] # type: ignore
298298

299299

300-
def argname( # pylint: disable=unused-argument,too-many-branches
300+
def argname( # pylint: disable=unused-argument,too-many-branches
301301
arg: Any,
302302
*more_args: Any,
303303
# *, keyword-only argument, only available with python3.8+
@@ -393,7 +393,7 @@ def argname( # pylint: disable=unused-argument,too-many-branches
393393
pos_only=pos_only,
394394
)
395395

396-
ret = [] # type: List[ArgSourceType]
396+
ret = [] # type: List[ArgSourceType]
397397
for argnode in argname_node.args:
398398
if not isinstance(argnode, (ast.Name, ast.Subscript, ast.Starred)):
399399
raise ValueError(
@@ -412,7 +412,7 @@ def argname( # pylint: disable=unused-argument,too-many-branches
412412
raise ValueError(
413413
f"No such variable positional argument {posvar!r}"
414414
)
415-
ret.extend(argument_sources[argnode.value.id]) # type: ignore
415+
ret.extend(argument_sources[argnode.value.id]) # type: ignore
416416

417417
elif isinstance(argnode, ast.Name):
418418
if argnode.id not in argument_sources:
@@ -441,7 +441,7 @@ def argname( # pylint: disable=unused-argument,too-many-branches
441441
f"{name!r} is not a keyword argument "
442442
"(**kwargs, for example)."
443443
)
444-
ret.append(argument_sources[name][subscript]) # type: ignore
444+
ret.append(argument_sources[name][subscript]) # type: ignore
445445

446446
if vars_only:
447447
for source in ret:
@@ -451,7 +451,7 @@ def argname( # pylint: disable=unused-argument,too-many-branches
451451
"or an attribute."
452452
)
453453

454-
return ret[0] if not more_args else tuple(ret) # type: ignore
454+
return ret[0] if not more_args else tuple(ret) # type: ignore
455455

456456

457457
def argname2(
@@ -461,6 +461,7 @@ def argname2(
461461
func: Callable = None,
462462
dispatch: Type = None,
463463
frame: int = 1,
464+
ignore: IgnoreType = None,
464465
vars_only: bool = True,
465466
) -> ArgSourceType:
466467
"""Get the names/sources of arguments passed to a function.
@@ -505,14 +506,19 @@ def argname2(
505506
specified, expect `func` to be the generic function if provided.
506507
frame: The frame where target function is called from this call.
507508
Calls from python standard libraries are ignored.
509+
ignore: The intermediate calls to be ignored. See `varname.ignore`
508510
vars_only: Require the arguments to be variables only.
509511
If False, `asttokens` is required to retrieve the source.
510512
511513
Returns:
512514
Scalar string if
513515
514516
"""
515-
ignore_list = IgnoreList.create(ignore_lambda=False, ignore_varname=False)
517+
ignore_list = IgnoreList.create(
518+
ignore,
519+
ignore_lambda=False,
520+
ignore_varname=False,
521+
)
516522
# where func(...) is called, skip the argname2() call
517523
func_frame = ignore_list.get_frame(frame + 1)
518524
func_node = get_node_by_frame(func_frame)
@@ -545,17 +551,17 @@ def argname2(
545551
vars_only=vars_only,
546552
pos_only=False,
547553
)
548-
except TypeError as terr:
554+
except Exception as err:
549555
raise VarnameRetrievingError(
550556
"Have you specified the right `frame`?"
551-
) from terr
557+
) from err
552558

553-
out = [] # type: List[ArgSourceType]
559+
out = [] # type: List[ArgSourceType]
554560
farg_star = False
555561
for farg in (arg, *more_args):
556562

557563
farg_name = farg
558-
farg_subscript = None # type: str | int
564+
farg_subscript = None # type: str | int
559565
match = re.match(r"^([\w_]+)\[(.+)\]$", farg)
560566
if match:
561567
farg_name = match.group(1)
@@ -582,7 +588,7 @@ def argname2(
582588
)
583589

584590
if farg_subscript is not None:
585-
out.append(source[farg_subscript]) # type: ignore
591+
out.append(source[farg_subscript]) # type: ignore
586592
elif farg_star:
587593
out.extend(source)
588594
else:
@@ -591,5 +597,5 @@ def argname2(
591597
return (
592598
out[0]
593599
if not more_args and not farg_star
594-
else tuple(out) # type: ignore
600+
else tuple(out) # type: ignore
595601
)

varname/ignore.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,9 @@ def create(
331331

332332
def __init__(self, ignore_list: List[IgnoreElemType]) -> None:
333333
self.ignore_list = ignore_list
334+
debug_ignore_frame(
335+
'>>> IgnoreList initiated <<<'
336+
)
334337

335338
def nextframe_to_check(
336339
self, frame_no: int, frameinfos: List[inspect.FrameInfo]

varname/utils.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,7 @@ def get_argument_sources(
324324
{
325325
argnode.arg: argnode_source(source, argnode.value, vars_only)
326326
for argnode in node.keywords
327+
if argnode.arg is not None
327328
}
328329
if not pos_only
329330
else {}

0 commit comments

Comments
 (0)