varview
A tiny, zero-dependency debug-printing helper for people who check their work, for clean automation.
from varview import debug
count = 42
total = 137
status = "active"
debug(count, total, status)
count = 42
total = 137
status = active
Why this exists
Most debugging habits start the same way: print(f"count: {count}"),
scattered through a script, forgotten about, and left in, or worse,
silently shaping a result nobody meant to ship.
varview grew out of a data analyst's day-to-day discipline: if
you can't see your intermediate values clearly, you can't trust your
final ones. The habit it's built for is simple: being able to see
every variable in your code, at the point it's actually computed, is
what lets you notice when something is wrong, a value that shifted
type, a filter that let too much or too little through, a join that
didn't do what you expected. Data leakage and other silent
corruption is usually invisible not because it's hard to catch, but
because nobody was looking at the value when it happened. Making
that look cheap and habitual, instead of a special debugging step
you only reach for once something already seems broken, is the whole
point.
That's the whole philosophy behind this package:
- See it before you trust it. Print the name and the value, side by side, with no risk of the label drifting out of sync with what it's labeling.
- Validate loudly, not quietly. Every parameter is checked up front. Bad input fails fast with a clear error instead of producing a confusing result three functions later.
- Make leakage a choice, not an accident. One global switch silences every debug call in a file at once, so nothing you used to sanity-check an intermediate value can slip into a shared notebook or a production run by accident.
varview doesn't detect leakage, drift, or corruption on its own,
it has no idea what your data means. What it does is make the habit
that catches those problems, actually looking at your intermediate
values, cheap enough to do every time instead of only after
something already looks wrong.
Install
pip install varview
Usage
Basic
from varview import debug
count = 42
debug(count) # unquoted variable
debug("count") # a quoted string also works — looked up by name
Multiple variables, comma-separated
Pass as many variables as you want, separated by commas — no need to wrap them in a list:
count = 42
total = 137
status = "active"
debug(count, total, status)
count = 42
total = 137
status = active
Unquoted variables
You don't have to quote the name at all. varview reads the call's
own source code to recover the label, so the variable itself can be
passed directly:
debug(count) # prints "count = 42", no quotes needed
debug(count, total) # prints both, labels taken straight from source
This is resolved from the source text of the call, not from the
runtime type of the value, so it stays correct even if a variable
happens to hold a string. region = "north" passed unquoted as
debug(region) still prints region = north, it is never mistaken
for a name lookup the way a quoted "region" would be (which would
instead look for a variable literally named north).
If the source can't be recovered (for example, calls made from a REPL
or from exec()'d code), varview falls back to a best-effort
heuristic instead of failing.
A variable holding a list or tuple is printed as one value
Each comma-separated argument is always treated as exactly one entry, no matter what its runtime value turns out to be, including when that value is itself a list or tuple:
quarterly_revenue = [120000, 135000, 128000, 151000]
debug(quarterly_revenue)
quarterly_revenue = [120000, 135000, 128000, 151000]
This prints as a single line, the variable is never unpacked into one entry per element. To see multiple entries, pass multiple comma-separated arguments instead:
monthly_churn_rate = 0.034
active_subscribers = 8421
quarterly_revenue = [120000, 135000, 128000, 151000]
debug(monthly_churn_rate, active_subscribers, quarterly_revenue)
monthly_churn_rate = 0.034
active_subscribers = 8421
quarterly_revenue = [120000, 135000, 128000, 151000]
Seeing a value instead of assuming it
The pattern that motivated this package: a quick, visible check right where a value is computed, left in place instead of deleted, and silenced in one line before anything ships.
raw_rows = len(df)
df = df.dropna(subset=["customer_id"])
clean_rows = len(df)
dropped = raw_rows - clean_rows
debug(raw_rows, clean_rows, dropped, color="red")
raw_rows = 10482
clean_rows = 10471
dropped = 11
Seeing dropped here is the difference between knowing exactly what
a cleaning step did and just assuming it did what you meant.
Note: older versions of
varviewused a list-bracket calling convention,debug(["count", "total"]). That form is no longer treated specially,debug([a, b])is now one argument whose value is a 2-element list, printed as a single line, not unpacked into two. Use plain comma-separated arguments instead:debug(a, b).
Color-code by what the value means to you
debug(count, color="green") # default, all good
debug(count, color="yellow") # worth a second look
debug(count, color="red") # flag it
Lay it out the way you're scanning
debug(count, total, status) # vertical (default)
debug(count, total, status, orientation="horizontal") # count = 42, total = 137, status = active
In vertical layout, you can pad labels so every = lines up in a
neat column with align:
debug(count, total, status) # default: align=None, no padding, labels print as-is
debug(count, total, status, align="right") # labels right-aligned
debug(count, total, status, align="left") # labels left-aligned
debug(count, total, status, align="center") # labels centered
align only affects orientation="vertical". It has no effect on
horizontal output, since there's only one line to begin with.
Trim the surrounding whitespace
debug(count, total, margin=False)
By default, debug() prints a blank line before and after its
output so it stands out in a busy terminal or log. Set margin=False
for tightly packed output with nothing extra around it.
Turn one call off without deleting it
debug(count, display=False)
Turn every call off at once, before you share or ship
from varview import debug_off, debug_on
debug_off() # every debug() call in the process goes silent, even display=True ones
# ... run the rest of your pipeline, notebook export, whatever needs to be clean ...
debug_on() # back to normal for your next debugging session
debug_off() is the one-line answer to "did I leave a debug print
in this notebook before I sent it to someone." Flip it at the top of
a cell, or right before a scheduled job runs, and every debug()
call downstream goes quiet, no hunting through the file for calls
you forgot about.
Typos don't kill the whole block
debug("count", "totall", "status")
# count = 42
# totall = <not found>
# status = active
One bad quoted name prints <not found> in place instead of raising
and losing every other value you wanted to see. This applies to
quoted names only. Unquoted variables are resolved directly from the
argument itself, so there is no lookup that can fail.
API
debug(*names, color="green", display=True, orientation="vertical", align=None, margin=True)
| Param | Type | Default | Notes |
|---|---|---|---|
*names |
one or more str, or unquoted variables, comma-separated |
(required, at least one) | Quoted strings are looked up by name in the caller's local scope; unquoted variables have their label recovered from source and their value used directly, even if that value is a list or tuple |
color |
"green", "red", "yellow" |
"green" |
Label color only, values always print in black |
display |
bool |
True |
Silences this one call when False |
orientation |
"vertical", "horizontal" |
"vertical" |
Layout of the printed pairs |
align |
None, "left", "center", "right" |
None |
Label padding within the column, vertical layout only. None means no padding, labels print at their natural length |
margin |
bool |
True |
Blank line before and after the printed output |
All parameters are validated on every call: an invalid color,
orientation, or align raises ValueError, an invalid display or
margin type raises TypeError. Nothing gets a chance to fail
silently or print something misleading.
debug_off() / debug_on()
Module-level switch. debug_off() silences every debug() call in
the running process, regardless of that call's own display value.
debug_on() restores normal behavior.
License
MIT
Metadata
Release files for varview 0.6.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| varview-0.6.1.tar.gz | 12.9 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| varview-0.6.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 27.8 kB
Release files / varview-0.6.1.tar.gz
| Download URL | varview-0.6.1.tar.gz |
|---|---|
| Size | 12.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2eab017c80dd7fb1a9e5b9c0819d40f42232cdce3c4215af61152f3ad603eaff
|
|
BLAKE2b-256 checksum How to use checksums |
9b36c380af2ce380ab2cd75ff1281d18f6c166638064b8b823b06ec7f848fd3b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.1
|
Release files / varview-0.6.1-py3-none-any.whl
| Download URL | varview-0.6.1-py3-none-any.whl |
|---|---|
| Size | 14.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
334842039fd79b283d7a47ba2aec39b4d2780a99130fe97f21408e0e0301a7cf
|
|
BLAKE2b-256 checksum How to use checksums |
9e54e1e7271157a0dad621e325e510c98df659975c51fb7bc3b29312d2e83802
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.1
|
Security for varview 0.6.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.