Skip to content

Commit 1e8f051

Browse files
authored
Add a debug function to print variable name and value together. (#27)
* Add a debug function to print variable name and value together. * 0.5.3 * Deprecate namedtuple * Remove namedtuple from readme
1 parent 6928033 commit 1e8f051

File tree

7 files changed

+90
-19
lines changed

7 files changed

+90
-19
lines changed

.pylintrc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,10 @@ disable=print-statement,
152152
too-few-public-methods,
153153
protected-access,
154154
too-many-instance-attributes,
155-
too-many-arguments
155+
too-many-arguments,
156+
too-many-return-statements,
157+
too-many-locals,
158+
not-callable
156159

157160
# Enable the message, report, category or checker with the given id(s). You can
158161
# either give multiple identifier separated by comma (,) or put this option
@@ -308,6 +311,7 @@ good-names=i,
308311
y,
309312
z,
310313
np,
314+
gc,
311315
nn,
312316
ns,
313317
t,

README.md

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ pip install varname
1919
- Fetching variable names directly using `nameof`
2020
- A value wrapper to store the variable name that a value is assigned to using `Wrapper`
2121
- Detecting next immediate attribute name using `will`
22-
- Shortcut for `collections.namedtuple`
2322
- Injecting `__varname__` to objects
23+
- A `debug` function to print variables with their names and values.
2424

2525
## Credits
2626

@@ -197,17 +197,6 @@ awesome.permit() # AttributeError: Should do something with AwesomeClass object
197197
awesome.permit().do() == 'I am doing!'
198198
```
199199

200-
### Shortcut for `collections.namedtuple`
201-
```python
202-
# instead of
203-
from collections import namedtuple
204-
Name = namedtuple('Name', ['first', 'last'])
205-
206-
# we can do:
207-
from varname import namedtuple
208-
Name = namedtuple(['first', 'last'])
209-
```
210-
211200
### Injecting `__varname__`
212201

213202
```python
@@ -230,6 +219,20 @@ b.append(1)
230219
a == b
231220
```
232221

222+
### Debugging with `debug`
223+
```python
224+
a = 'value'
225+
b = object()
226+
debug(a) # DEBUG: a='value'
227+
debug(b) # DEBUG: b=<object object at 0x2b70580e5f20>
228+
debug(a, b)
229+
# DEBUG: a='value'
230+
# DEBUG: b=<object object at 0x2b70580e5f20>
231+
debug(a, b, merge=True)
232+
# DEBUG: a='value', b=<object object at 0x2b70580e5f20>
233+
debug(a, repr=False, prefix='') # a=value
234+
```
235+
233236
## Reliability and limitations
234237
`varname` is all depending on `executing` package to look for the node.
235238
The node `executing` detects is ensured to be the correct one (see [this][19]).

README.rst

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
:target: https://img.shields.io/github/tag/pwwang/python-varname?style=flat-square
1515
:alt: Github
1616
<https://github.com/pwwang/python-varname>`_ `
17-
.. image:: https://img.shields.io/pypi/pyversions/python-varname?style=flat-square
18-
:target: https://img.shields.io/pypi/pyversions/python-varname?style=flat-square
17+
.. image:: https://img.shields.io/pypi/pyversions/varname?style=flat-square
18+
:target: https://img.shields.io/pypi/pyversions/varname?style=flat-square
1919
:alt: PythonVers
2020
<https://pypi.org/project/varname/>`_
2121
.. image:: https://img.shields.io/github/workflow/status/pwwang/python-varname/Build%20and%20Deploy?style=flat-square
@@ -62,6 +62,7 @@ Features
6262
* Detecting next immediate attribute name using ``will``
6363
* Shortcut for ``collections.namedtuple``
6464
* Injecting ``__varname__`` to objects
65+
* A ``debug`` function to print variables with their names and values.
6566

6667
Credits
6768
-------
@@ -291,6 +292,22 @@ Injecting ``__varname__``
291292
b.append(1)
292293
a == b
293294
295+
Debugging with ``debug``
296+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
297+
298+
.. code-block:: python
299+
300+
a = 'value'
301+
b = object()
302+
debug(a) # DEBUG: a='value'
303+
debug(b) # DEBUG: b=<object object at 0x2b70580e5f20>
304+
debug(a, b)
305+
# DEBUG: a='value'
306+
# DEBUG: b=<object object at 0x2b70580e5f20>
307+
debug(a, b, merge=True)
308+
# DEBUG: a='value', b=<object object at 0x2b70580e5f20>
309+
debug(a, repr=False, prefix='') # a=value
310+
294311
Reliability and limitations
295312
---------------------------
296313

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.5.2"
7+
version = "0.5.3"
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
@@ -21,7 +21,7 @@
2121
setup(
2222
long_description=readme,
2323
name='varname',
24-
version='0.5.2',
24+
version='0.5.3',
2525
description='Dark magics about variable names in python.',
2626
python_requires='==3.*,>=3.6.0',
2727
project_urls={

tests/test_varname.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,3 +534,11 @@ def test_nameof_node_not_retrieved():
534534
code = compile(source, filename="<string2>", mode="exec")
535535
with pytest.raises(VarnameRetrievingError, match='Source code unavailable'):
536536
exec(code)
537+
538+
def test_debug(capsys):
539+
a = 1
540+
b = object()
541+
debug(a)
542+
assert 'DEBUG: a=1\n' == capsys.readouterr().out
543+
debug(a, b, merge=True)
544+
assert 'DEBUG: a=1, b=<object' in capsys.readouterr().out

varname.py

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010

1111
import executing
1212

13-
__version__ = "0.5.2"
13+
__version__ = "0.5.3"
1414
__all__ = [
1515
"VarnameRetrievingError", "varname", "will",
16-
"inject", "nameof", "namedtuple", "Wrapper"
16+
"inject", "nameof", "namedtuple", "Wrapper", "debug"
1717
]
1818

1919
class VarnameRetrievingError(Exception):
@@ -267,6 +267,42 @@ def nameof(var, *more_vars, # pylint: disable=unused-argument
267267

268268
return ret[0] if not more_vars else tuple(ret)
269269

270+
def debug(var, *more_vars,
271+
prefix: str = 'DEBUG: ',
272+
merge: bool = False,
273+
repr: bool = True) -> None: # pylint: disable=redefined-builtin
274+
"""Print variable names and values.
275+
276+
Examples:
277+
>>> a = 1
278+
>>> b = object
279+
>>> print(f'a={a}') # previously, we have to do
280+
>>> print(f'{a=}') # or with python3.8
281+
>>> # instead we can do:
282+
>>> debug(a) # DEBUG: a=1
283+
>>> debug(a, prefix='') # a=1
284+
>>> debug(a, b, merge=True) # a=1, b=<object object at 0x2b9a4c89cf00>
285+
286+
Args:
287+
var: The variable to print
288+
*more_vars: Other variables to print
289+
prefix: A prefix to print for each line
290+
merge: Whether merge all variables in one line or not
291+
repr: Print the value as `repr(var)`? otherwise `str(var)`
292+
"""
293+
var_names = nameof(var, *more_vars, caller=2, full=True)
294+
if not isinstance(var_names, tuple):
295+
var_names = (var_names, )
296+
variables = (var, *more_vars)
297+
name_and_values = [f"{var_name}={variables[i]!r}" if repr
298+
else f"{var_name}={variables[i]}"
299+
for i, var_name in enumerate(var_names)]
300+
if merge:
301+
print(f"{prefix}{', '.join(name_and_values)}")
302+
else:
303+
for name_and_value in name_and_values:
304+
print(f"{prefix}{name_and_value}")
305+
270306
def namedtuple(*args, **kwargs) -> type:
271307
"""A shortcut for namedtuple
272308
@@ -289,6 +325,9 @@ def namedtuple(*args, **kwargs) -> type:
289325
Returns:
290326
The namedtuple you desired.
291327
"""
328+
warnings.warn("Shortcut for namedtuple is deprecated and "
329+
"will be removed in 0.6.0. Use the standard way instead.",
330+
DeprecationWarning)
292331
typename = varname(raise_exc=True)
293332
return standard_namedtuple(typename, *args, **kwargs)
294333

0 commit comments

Comments
 (0)