%global _empty_manifest_terminate_build 0
Name: python-varname
Version: 0.11.0
Release: 1
Summary: Dark magics about variable names in python.
License: MIT
URL: https://github.com/pwwang/python-varname
Source0: https://mirrors.nju.edu.cn/pypi/web/packages/a1/d8/c07c3f2302b4b039439701d0781cd0265ad3127e141da9dbc3f6dc8323d5/varname-0.11.0.tar.gz
BuildArch: noarch
Requires: python3-executing
Requires: python3-asttokens
Requires: python3-pure_eval
%description
![varname][7]
[![Pypi][3]][4] [![Github][5]][6] [![PythonVers][8]][4] ![Building][10]
[![Docs and API][9]][15] [![Codacy][12]][13] [![Codacy coverage][14]][13]
![Downloads][17]
Dark magics about variable names in python
[CHANGELOG][16] | [API][15] | [Playground][11] | :fire: [StackOverflow answer][20]
## Installation
```shell
pip install -U varname
```
Note if you use `python < 3.8`, install `varname < 0.11`
## Features
- Core features:
- Retrieving names of variables a function/class call is assigned to from inside it, using `varname`.
- Retrieving variable names directly, using `nameof`
- Detecting next immediate attribute name, using `will`
- Fetching argument names/sources passed to a function using `argname`
- Other helper APIs (built based on core features):
- A value wrapper to store the variable name that a value is assigned to, using `Wrapper`
- A decorator to register `__varname__` to functions/classes, using `register`
- A `debug` function to print variables with their names and values
## Credits
Thanks goes to these awesome people/projects:
Special thanks to [@HanyuuLu][2] to give up the name `varname` in pypi for this project.
## Usage
### Retrieving the variable names using `varname(...)`
- From inside a function
```python
from varname import varname
def function():
return varname()
func = function() # func == 'func'
```
When there are intermediate frames:
```python
def wrapped():
return function()
def function():
# retrieve the variable name at the 2nd frame from this one
return varname(frame=2)
func = wrapped() # func == 'func'
```
Or use `ignore` to ignore the wrapped frame:
```python
def wrapped():
return function()
def function():
return varname(ignore=wrapped)
func = wrapped() # func == 'func'
```
Calls from standard libraries are ignored by default:
```python
import asyncio
async def function():
return varname()
func = asyncio.run(function()) # func == 'func'
```
Use `strict` to control whether the call should be assigned to
the variable directly:
```python
def function(strict):
return varname(strict=strict)
func = function(True) # OK, direct assignment, func == 'func'
func = [function(True)] # Not a direct assignment, raises ImproperUseError
func = [function(False)] # OK, func == ['func']
func = function(False), function(False) # OK, func = ('func', 'func')
```
- Retrieving name of a class instance
```python
class Foo:
def __init__(self):
self.id = varname()
def copy(self):
# also able to fetch inside a method call
copied = Foo() # copied.id == 'copied'
copied.id = varname() # assign id to whatever variable name
return copied
foo = Foo() # foo.id == 'foo'
foo2 = foo.copy() # foo2.id == 'foo2'
```
- Multiple variables on Left-hand side
```python
# since v0.5.4
def func():
return varname(multi_vars=True)
a = func() # a == ('a',)
a, b = func() # (a, b) == ('a', 'b')
[a, b] = func() # (a, b) == ('a', 'b')
# hierarchy is also possible
a, (b, c) = func() # (a, b, c) == ('a', 'b', 'c')
```
- Some unusual use
```python
def function(**kwargs):
return varname(strict=False)
func = func1 = function() # func == func1 == 'func1'
# if varname < 0.8: func == func1 == 'func'
# a warning will be shown
# since you may not want func to be 'func1'
x = function(y = function()) # x == 'x'
# get part of the name
func_abc = function()[-3:] # func_abc == 'abc'
# function alias supported now
function2 = function
func = function2() # func == 'func'
a = lambda: 0
a.b = function() # a.b == 'b'
```
### The decorator way to register `__varname__` to functions/classes
- Registering `__varname__` to functions
```python
from varname.helpers import register
@register
def function():
return __varname__
func = function() # func == 'func'
```
```python
# arguments also allowed (frame, ignore and raise_exc)
@register(frame=2)
def function():
return __varname__
def wrapped():
return function()
func = wrapped() # func == 'func'
```
- Registering `__varname__` as a class property
```python
@register
class Foo:
...
foo = Foo()
# foo.__varname__ == 'foo'
```
### Getting variable names directly using `nameof`
```python
from varname import varname, nameof
a = 1
nameof(a) # 'a'
b = 2
nameof(a, b) # ('a', 'b')
def func():
return varname() + '_suffix'
f = func() # f == 'f_suffix'
nameof(f) # 'f'
# get full names of (chained) attribute calls
func.a = func
nameof(func.a, vars_only=False) # 'func.a'
func.a.b = 1
nameof(func.a.b, vars_only=False) # 'func.a.b'
```
### Detecting next immediate attribute name
```python
from varname import will
class AwesomeClass:
def __init__(self):
self.will = None
def permit(self):
self.will = will(raise_exc=False)
if self.will == 'do':
# let self handle do
return self
raise AttributeError('Should do something with AwesomeClass object')
def do(self):
if self.will != 'do':
raise AttributeError("You don't have permission to do")
return 'I am doing!'
awesome = AwesomeClass()
awesome.do() # AttributeError: You don't have permission to do
awesome.permit() # AttributeError: Should do something with AwesomeClass object
awesome.permit().do() == 'I am doing!'
```
### Fetching argument names/sources using `argname`
```python
from varname import argname
def func(a, b=1):
print(argname('a'))
x = y = z = 2
func(x) # prints: x
def func2(a, b=1):
print(argname('a', 'b'))
func2(y, b=x) # prints: ('y', 'x')
# allow expressions
def func3(a, b=1):
print(argname('a', 'b', vars_only=False))
func3(x+y, y+x) # prints: ('x+y', 'y+x')
# positional and keyword arguments
def func4(*args, **kwargs):
print(argname('args[1]', 'kwargs[c]'))
func4(y, x, c=z) # prints: ('x', 'z')
# As of 0.9.0 (see: https://pwwang.github.io/python-varname/CHANGELOG/#v090)
# Can also fetch the source of the argument for
# __getattr__/__getitem__/__setattr/__setitem__/__add__/__lt__, etc.
class Foo:
def __setattr__(self, name, value):
print(argname("name", "value"))
Foo().a = 1 # prints: ("'a'", '1')
```
### Value wrapper
```python
from varname.helpers import Wrapper
foo = Wrapper(True)
# foo.name == 'foo'
# foo.value == True
bar = Wrapper(False)
# bar.name == 'bar'
# bar.value == False
def values_to_dict(*args):
return {val.name: val.value for val in args}
mydict = values_to_dict(foo, bar)
# {'foo': True, 'bar': False}
```
### Debugging with `debug`
```python
from varname.helpers import debug
a = 'value'
b = ['val']
debug(a)
# "DEBUG: a='value'\n"
debug(b)
# "DEBUG: b=['val']\n"
debug(a, b)
# "DEBUG: a='value'\nDEBUG: b=['val']\n"
debug(a, b, merge=True)
# "DEBUG: a='value', b=['val']\n"
debug(a, repr=False, prefix='')
# 'a=value\n'
# also debug an expression
debug(a+a)
# "DEBUG: a+a='valuevalue'\n"
# If you want to disable it:
debug(a+a, vars_only=True) # ImproperUseError
```
## Reliability and limitations
`varname` is all depending on `executing` package to look for the node.
The node `executing` detects is ensured to be the correct one (see [this][19]).
It partially works with environments where other AST magics apply, including
`pytest`, `ipython`, `macropy`, `birdseye`, `reticulate` with `R`, etc. Neither
`executing` nor `varname` is 100% working with those environments. Use
it at your own risk.
For example:
- This will not work with `pytest`:
```python
a = 1
assert nameof(a) == 'a' # pytest manipulated the ast here
# do this instead
name_a = nameof(a)
assert name_a == 'a'
```
[1]: https://github.com/pwwang/python-varname
[2]: https://github.com/HanyuuLu
[3]: https://img.shields.io/pypi/v/varname?style=flat-square
[4]: https://pypi.org/project/varname/
[5]: https://img.shields.io/github/tag/pwwang/python-varname?style=flat-square
[6]: https://github.com/pwwang/python-varname
[7]: logo.png
[8]: https://img.shields.io/pypi/pyversions/varname?style=flat-square
[9]: https://img.shields.io/github/actions/workflow/status/pwwang/python-varname/docs.yml?branch=master
[10]: https://img.shields.io/github/actions/workflow/status/pwwang/python-varname/build.yml?branch=master
[11]: https://mybinder.org/v2/gh/pwwang/python-varname/dev?filepath=playground%2Fplayground.ipynb
[12]: https://img.shields.io/codacy/grade/6fdb19c845f74c5c92056e88d44154f7?style=flat-square
[13]: https://app.codacy.com/gh/pwwang/python-varname/dashboard
[14]: https://img.shields.io/codacy/coverage/6fdb19c845f74c5c92056e88d44154f7?style=flat-square
[15]: https://pwwang.github.io/python-varname/api/varname
[16]: https://pwwang.github.io/python-varname/CHANGELOG/
[17]: https://img.shields.io/pypi/dm/varname?style=flat-square
[19]: https://github.com/alexmojaki/executing#is-it-reliable
[20]: https://stackoverflow.com/a/59364138/5088165
%package -n python3-varname
Summary: Dark magics about variable names in python.
Provides: python-varname
BuildRequires: python3-devel
BuildRequires: python3-setuptools
BuildRequires: python3-pip
%description -n python3-varname
![varname][7]
[![Pypi][3]][4] [![Github][5]][6] [![PythonVers][8]][4] ![Building][10]
[![Docs and API][9]][15] [![Codacy][12]][13] [![Codacy coverage][14]][13]
![Downloads][17]
Dark magics about variable names in python
[CHANGELOG][16] | [API][15] | [Playground][11] | :fire: [StackOverflow answer][20]
## Installation
```shell
pip install -U varname
```
Note if you use `python < 3.8`, install `varname < 0.11`
## Features
- Core features:
- Retrieving names of variables a function/class call is assigned to from inside it, using `varname`.
- Retrieving variable names directly, using `nameof`
- Detecting next immediate attribute name, using `will`
- Fetching argument names/sources passed to a function using `argname`
- Other helper APIs (built based on core features):
- A value wrapper to store the variable name that a value is assigned to, using `Wrapper`
- A decorator to register `__varname__` to functions/classes, using `register`
- A `debug` function to print variables with their names and values
## Credits
Thanks goes to these awesome people/projects:
Special thanks to [@HanyuuLu][2] to give up the name `varname` in pypi for this project.
## Usage
### Retrieving the variable names using `varname(...)`
- From inside a function
```python
from varname import varname
def function():
return varname()
func = function() # func == 'func'
```
When there are intermediate frames:
```python
def wrapped():
return function()
def function():
# retrieve the variable name at the 2nd frame from this one
return varname(frame=2)
func = wrapped() # func == 'func'
```
Or use `ignore` to ignore the wrapped frame:
```python
def wrapped():
return function()
def function():
return varname(ignore=wrapped)
func = wrapped() # func == 'func'
```
Calls from standard libraries are ignored by default:
```python
import asyncio
async def function():
return varname()
func = asyncio.run(function()) # func == 'func'
```
Use `strict` to control whether the call should be assigned to
the variable directly:
```python
def function(strict):
return varname(strict=strict)
func = function(True) # OK, direct assignment, func == 'func'
func = [function(True)] # Not a direct assignment, raises ImproperUseError
func = [function(False)] # OK, func == ['func']
func = function(False), function(False) # OK, func = ('func', 'func')
```
- Retrieving name of a class instance
```python
class Foo:
def __init__(self):
self.id = varname()
def copy(self):
# also able to fetch inside a method call
copied = Foo() # copied.id == 'copied'
copied.id = varname() # assign id to whatever variable name
return copied
foo = Foo() # foo.id == 'foo'
foo2 = foo.copy() # foo2.id == 'foo2'
```
- Multiple variables on Left-hand side
```python
# since v0.5.4
def func():
return varname(multi_vars=True)
a = func() # a == ('a',)
a, b = func() # (a, b) == ('a', 'b')
[a, b] = func() # (a, b) == ('a', 'b')
# hierarchy is also possible
a, (b, c) = func() # (a, b, c) == ('a', 'b', 'c')
```
- Some unusual use
```python
def function(**kwargs):
return varname(strict=False)
func = func1 = function() # func == func1 == 'func1'
# if varname < 0.8: func == func1 == 'func'
# a warning will be shown
# since you may not want func to be 'func1'
x = function(y = function()) # x == 'x'
# get part of the name
func_abc = function()[-3:] # func_abc == 'abc'
# function alias supported now
function2 = function
func = function2() # func == 'func'
a = lambda: 0
a.b = function() # a.b == 'b'
```
### The decorator way to register `__varname__` to functions/classes
- Registering `__varname__` to functions
```python
from varname.helpers import register
@register
def function():
return __varname__
func = function() # func == 'func'
```
```python
# arguments also allowed (frame, ignore and raise_exc)
@register(frame=2)
def function():
return __varname__
def wrapped():
return function()
func = wrapped() # func == 'func'
```
- Registering `__varname__` as a class property
```python
@register
class Foo:
...
foo = Foo()
# foo.__varname__ == 'foo'
```
### Getting variable names directly using `nameof`
```python
from varname import varname, nameof
a = 1
nameof(a) # 'a'
b = 2
nameof(a, b) # ('a', 'b')
def func():
return varname() + '_suffix'
f = func() # f == 'f_suffix'
nameof(f) # 'f'
# get full names of (chained) attribute calls
func.a = func
nameof(func.a, vars_only=False) # 'func.a'
func.a.b = 1
nameof(func.a.b, vars_only=False) # 'func.a.b'
```
### Detecting next immediate attribute name
```python
from varname import will
class AwesomeClass:
def __init__(self):
self.will = None
def permit(self):
self.will = will(raise_exc=False)
if self.will == 'do':
# let self handle do
return self
raise AttributeError('Should do something with AwesomeClass object')
def do(self):
if self.will != 'do':
raise AttributeError("You don't have permission to do")
return 'I am doing!'
awesome = AwesomeClass()
awesome.do() # AttributeError: You don't have permission to do
awesome.permit() # AttributeError: Should do something with AwesomeClass object
awesome.permit().do() == 'I am doing!'
```
### Fetching argument names/sources using `argname`
```python
from varname import argname
def func(a, b=1):
print(argname('a'))
x = y = z = 2
func(x) # prints: x
def func2(a, b=1):
print(argname('a', 'b'))
func2(y, b=x) # prints: ('y', 'x')
# allow expressions
def func3(a, b=1):
print(argname('a', 'b', vars_only=False))
func3(x+y, y+x) # prints: ('x+y', 'y+x')
# positional and keyword arguments
def func4(*args, **kwargs):
print(argname('args[1]', 'kwargs[c]'))
func4(y, x, c=z) # prints: ('x', 'z')
# As of 0.9.0 (see: https://pwwang.github.io/python-varname/CHANGELOG/#v090)
# Can also fetch the source of the argument for
# __getattr__/__getitem__/__setattr/__setitem__/__add__/__lt__, etc.
class Foo:
def __setattr__(self, name, value):
print(argname("name", "value"))
Foo().a = 1 # prints: ("'a'", '1')
```
### Value wrapper
```python
from varname.helpers import Wrapper
foo = Wrapper(True)
# foo.name == 'foo'
# foo.value == True
bar = Wrapper(False)
# bar.name == 'bar'
# bar.value == False
def values_to_dict(*args):
return {val.name: val.value for val in args}
mydict = values_to_dict(foo, bar)
# {'foo': True, 'bar': False}
```
### Debugging with `debug`
```python
from varname.helpers import debug
a = 'value'
b = ['val']
debug(a)
# "DEBUG: a='value'\n"
debug(b)
# "DEBUG: b=['val']\n"
debug(a, b)
# "DEBUG: a='value'\nDEBUG: b=['val']\n"
debug(a, b, merge=True)
# "DEBUG: a='value', b=['val']\n"
debug(a, repr=False, prefix='')
# 'a=value\n'
# also debug an expression
debug(a+a)
# "DEBUG: a+a='valuevalue'\n"
# If you want to disable it:
debug(a+a, vars_only=True) # ImproperUseError
```
## Reliability and limitations
`varname` is all depending on `executing` package to look for the node.
The node `executing` detects is ensured to be the correct one (see [this][19]).
It partially works with environments where other AST magics apply, including
`pytest`, `ipython`, `macropy`, `birdseye`, `reticulate` with `R`, etc. Neither
`executing` nor `varname` is 100% working with those environments. Use
it at your own risk.
For example:
- This will not work with `pytest`:
```python
a = 1
assert nameof(a) == 'a' # pytest manipulated the ast here
# do this instead
name_a = nameof(a)
assert name_a == 'a'
```
[1]: https://github.com/pwwang/python-varname
[2]: https://github.com/HanyuuLu
[3]: https://img.shields.io/pypi/v/varname?style=flat-square
[4]: https://pypi.org/project/varname/
[5]: https://img.shields.io/github/tag/pwwang/python-varname?style=flat-square
[6]: https://github.com/pwwang/python-varname
[7]: logo.png
[8]: https://img.shields.io/pypi/pyversions/varname?style=flat-square
[9]: https://img.shields.io/github/actions/workflow/status/pwwang/python-varname/docs.yml?branch=master
[10]: https://img.shields.io/github/actions/workflow/status/pwwang/python-varname/build.yml?branch=master
[11]: https://mybinder.org/v2/gh/pwwang/python-varname/dev?filepath=playground%2Fplayground.ipynb
[12]: https://img.shields.io/codacy/grade/6fdb19c845f74c5c92056e88d44154f7?style=flat-square
[13]: https://app.codacy.com/gh/pwwang/python-varname/dashboard
[14]: https://img.shields.io/codacy/coverage/6fdb19c845f74c5c92056e88d44154f7?style=flat-square
[15]: https://pwwang.github.io/python-varname/api/varname
[16]: https://pwwang.github.io/python-varname/CHANGELOG/
[17]: https://img.shields.io/pypi/dm/varname?style=flat-square
[19]: https://github.com/alexmojaki/executing#is-it-reliable
[20]: https://stackoverflow.com/a/59364138/5088165
%package help
Summary: Development documents and examples for varname
Provides: python3-varname-doc
%description help
![varname][7]
[![Pypi][3]][4] [![Github][5]][6] [![PythonVers][8]][4] ![Building][10]
[![Docs and API][9]][15] [![Codacy][12]][13] [![Codacy coverage][14]][13]
![Downloads][17]
Dark magics about variable names in python
[CHANGELOG][16] | [API][15] | [Playground][11] | :fire: [StackOverflow answer][20]
## Installation
```shell
pip install -U varname
```
Note if you use `python < 3.8`, install `varname < 0.11`
## Features
- Core features:
- Retrieving names of variables a function/class call is assigned to from inside it, using `varname`.
- Retrieving variable names directly, using `nameof`
- Detecting next immediate attribute name, using `will`
- Fetching argument names/sources passed to a function using `argname`
- Other helper APIs (built based on core features):
- A value wrapper to store the variable name that a value is assigned to, using `Wrapper`
- A decorator to register `__varname__` to functions/classes, using `register`
- A `debug` function to print variables with their names and values
## Credits
Thanks goes to these awesome people/projects:
Special thanks to [@HanyuuLu][2] to give up the name `varname` in pypi for this project.
## Usage
### Retrieving the variable names using `varname(...)`
- From inside a function
```python
from varname import varname
def function():
return varname()
func = function() # func == 'func'
```
When there are intermediate frames:
```python
def wrapped():
return function()
def function():
# retrieve the variable name at the 2nd frame from this one
return varname(frame=2)
func = wrapped() # func == 'func'
```
Or use `ignore` to ignore the wrapped frame:
```python
def wrapped():
return function()
def function():
return varname(ignore=wrapped)
func = wrapped() # func == 'func'
```
Calls from standard libraries are ignored by default:
```python
import asyncio
async def function():
return varname()
func = asyncio.run(function()) # func == 'func'
```
Use `strict` to control whether the call should be assigned to
the variable directly:
```python
def function(strict):
return varname(strict=strict)
func = function(True) # OK, direct assignment, func == 'func'
func = [function(True)] # Not a direct assignment, raises ImproperUseError
func = [function(False)] # OK, func == ['func']
func = function(False), function(False) # OK, func = ('func', 'func')
```
- Retrieving name of a class instance
```python
class Foo:
def __init__(self):
self.id = varname()
def copy(self):
# also able to fetch inside a method call
copied = Foo() # copied.id == 'copied'
copied.id = varname() # assign id to whatever variable name
return copied
foo = Foo() # foo.id == 'foo'
foo2 = foo.copy() # foo2.id == 'foo2'
```
- Multiple variables on Left-hand side
```python
# since v0.5.4
def func():
return varname(multi_vars=True)
a = func() # a == ('a',)
a, b = func() # (a, b) == ('a', 'b')
[a, b] = func() # (a, b) == ('a', 'b')
# hierarchy is also possible
a, (b, c) = func() # (a, b, c) == ('a', 'b', 'c')
```
- Some unusual use
```python
def function(**kwargs):
return varname(strict=False)
func = func1 = function() # func == func1 == 'func1'
# if varname < 0.8: func == func1 == 'func'
# a warning will be shown
# since you may not want func to be 'func1'
x = function(y = function()) # x == 'x'
# get part of the name
func_abc = function()[-3:] # func_abc == 'abc'
# function alias supported now
function2 = function
func = function2() # func == 'func'
a = lambda: 0
a.b = function() # a.b == 'b'
```
### The decorator way to register `__varname__` to functions/classes
- Registering `__varname__` to functions
```python
from varname.helpers import register
@register
def function():
return __varname__
func = function() # func == 'func'
```
```python
# arguments also allowed (frame, ignore and raise_exc)
@register(frame=2)
def function():
return __varname__
def wrapped():
return function()
func = wrapped() # func == 'func'
```
- Registering `__varname__` as a class property
```python
@register
class Foo:
...
foo = Foo()
# foo.__varname__ == 'foo'
```
### Getting variable names directly using `nameof`
```python
from varname import varname, nameof
a = 1
nameof(a) # 'a'
b = 2
nameof(a, b) # ('a', 'b')
def func():
return varname() + '_suffix'
f = func() # f == 'f_suffix'
nameof(f) # 'f'
# get full names of (chained) attribute calls
func.a = func
nameof(func.a, vars_only=False) # 'func.a'
func.a.b = 1
nameof(func.a.b, vars_only=False) # 'func.a.b'
```
### Detecting next immediate attribute name
```python
from varname import will
class AwesomeClass:
def __init__(self):
self.will = None
def permit(self):
self.will = will(raise_exc=False)
if self.will == 'do':
# let self handle do
return self
raise AttributeError('Should do something with AwesomeClass object')
def do(self):
if self.will != 'do':
raise AttributeError("You don't have permission to do")
return 'I am doing!'
awesome = AwesomeClass()
awesome.do() # AttributeError: You don't have permission to do
awesome.permit() # AttributeError: Should do something with AwesomeClass object
awesome.permit().do() == 'I am doing!'
```
### Fetching argument names/sources using `argname`
```python
from varname import argname
def func(a, b=1):
print(argname('a'))
x = y = z = 2
func(x) # prints: x
def func2(a, b=1):
print(argname('a', 'b'))
func2(y, b=x) # prints: ('y', 'x')
# allow expressions
def func3(a, b=1):
print(argname('a', 'b', vars_only=False))
func3(x+y, y+x) # prints: ('x+y', 'y+x')
# positional and keyword arguments
def func4(*args, **kwargs):
print(argname('args[1]', 'kwargs[c]'))
func4(y, x, c=z) # prints: ('x', 'z')
# As of 0.9.0 (see: https://pwwang.github.io/python-varname/CHANGELOG/#v090)
# Can also fetch the source of the argument for
# __getattr__/__getitem__/__setattr/__setitem__/__add__/__lt__, etc.
class Foo:
def __setattr__(self, name, value):
print(argname("name", "value"))
Foo().a = 1 # prints: ("'a'", '1')
```
### Value wrapper
```python
from varname.helpers import Wrapper
foo = Wrapper(True)
# foo.name == 'foo'
# foo.value == True
bar = Wrapper(False)
# bar.name == 'bar'
# bar.value == False
def values_to_dict(*args):
return {val.name: val.value for val in args}
mydict = values_to_dict(foo, bar)
# {'foo': True, 'bar': False}
```
### Debugging with `debug`
```python
from varname.helpers import debug
a = 'value'
b = ['val']
debug(a)
# "DEBUG: a='value'\n"
debug(b)
# "DEBUG: b=['val']\n"
debug(a, b)
# "DEBUG: a='value'\nDEBUG: b=['val']\n"
debug(a, b, merge=True)
# "DEBUG: a='value', b=['val']\n"
debug(a, repr=False, prefix='')
# 'a=value\n'
# also debug an expression
debug(a+a)
# "DEBUG: a+a='valuevalue'\n"
# If you want to disable it:
debug(a+a, vars_only=True) # ImproperUseError
```
## Reliability and limitations
`varname` is all depending on `executing` package to look for the node.
The node `executing` detects is ensured to be the correct one (see [this][19]).
It partially works with environments where other AST magics apply, including
`pytest`, `ipython`, `macropy`, `birdseye`, `reticulate` with `R`, etc. Neither
`executing` nor `varname` is 100% working with those environments. Use
it at your own risk.
For example:
- This will not work with `pytest`:
```python
a = 1
assert nameof(a) == 'a' # pytest manipulated the ast here
# do this instead
name_a = nameof(a)
assert name_a == 'a'
```
[1]: https://github.com/pwwang/python-varname
[2]: https://github.com/HanyuuLu
[3]: https://img.shields.io/pypi/v/varname?style=flat-square
[4]: https://pypi.org/project/varname/
[5]: https://img.shields.io/github/tag/pwwang/python-varname?style=flat-square
[6]: https://github.com/pwwang/python-varname
[7]: logo.png
[8]: https://img.shields.io/pypi/pyversions/varname?style=flat-square
[9]: https://img.shields.io/github/actions/workflow/status/pwwang/python-varname/docs.yml?branch=master
[10]: https://img.shields.io/github/actions/workflow/status/pwwang/python-varname/build.yml?branch=master
[11]: https://mybinder.org/v2/gh/pwwang/python-varname/dev?filepath=playground%2Fplayground.ipynb
[12]: https://img.shields.io/codacy/grade/6fdb19c845f74c5c92056e88d44154f7?style=flat-square
[13]: https://app.codacy.com/gh/pwwang/python-varname/dashboard
[14]: https://img.shields.io/codacy/coverage/6fdb19c845f74c5c92056e88d44154f7?style=flat-square
[15]: https://pwwang.github.io/python-varname/api/varname
[16]: https://pwwang.github.io/python-varname/CHANGELOG/
[17]: https://img.shields.io/pypi/dm/varname?style=flat-square
[19]: https://github.com/alexmojaki/executing#is-it-reliable
[20]: https://stackoverflow.com/a/59364138/5088165
%prep
%autosetup -n varname-0.11.0
%build
%py3_build
%install
%py3_install
install -d -m755 %{buildroot}/%{_pkgdocdir}
if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi
if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi
if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi
if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi
pushd %{buildroot}
if [ -d usr/lib ]; then
find usr/lib -type f -printf "/%h/%f\n" >> filelist.lst
fi
if [ -d usr/lib64 ]; then
find usr/lib64 -type f -printf "/%h/%f\n" >> filelist.lst
fi
if [ -d usr/bin ]; then
find usr/bin -type f -printf "/%h/%f\n" >> filelist.lst
fi
if [ -d usr/sbin ]; then
find usr/sbin -type f -printf "/%h/%f\n" >> filelist.lst
fi
touch doclist.lst
if [ -d usr/share/man ]; then
find usr/share/man -type f -printf "/%h/%f.gz\n" >> doclist.lst
fi
popd
mv %{buildroot}/filelist.lst .
mv %{buildroot}/doclist.lst .
%files -n python3-varname -f filelist.lst
%dir %{python3_sitelib}/*
%files help -f doclist.lst
%{_docdir}/*
%changelog
* Sun Apr 23 2023 Python_Bot - 0.11.0-1
- Package Spec generated