Python print with source map and varnames.
Project description
LK Logger
An alternative to Python built-in print
function with rich features.
Features
- Print with source path, function name and varnames in console.
- Code highlights.
- As simple as using
print
like usual. - Globally replace
print
. - Less code changes, non-intrusive.
Installation
pip install lk-logger
Requires Python 3.8 and above. The latest version is 5.7.0 or higher.
Show Me The Code
Hello world
import lk_logger
lk_logger.setup()
print('hello world')
It shows source path, function name (or module name in top lines) besides main content:
Print with variant names
import lk_logger
lk_logger.setup(show_varnames=True)
a = 1
b = 2
print(a, b, a + b)
lk-logger
detects the variant or expression from the source code. It is similar but much shorter than the traditional way (print(f'a = {}; b = {}; a + b = {}'.format(a, b, a + b))
):
Prints from third party libraries
For libraries from "site-packages" directory, if they have used print(...)
in their source code, lk-logger
will shorten the source path prefixes to be the library names with square brackets.
import lk_logger
lk_logger.setup(quiet=True, show_varnames=True)
import depsland # pip install depsland
# ^ there are some prints in depsland initial time.
# let's see the print results.
print(depsland.__version__)
Highlighting styles
import lk_logger
lk_logger.setup(quiet=True)
print('[red]hello[/] [yellow]world[/]', ':r')
# ^ notice ':r' mark, we'll explain later.
print(':d', 'divider line')
# verbosities
print(':v1', 'debug message')
print(':v2', 'info message')
print(':v3', 'warning message')
print(':v4', 'error message')
print(':v5', 'critical message')
Exceptions
lk-logger
depends on rich
library, it shows pretty exception panel for tracebacks:
import lk_logger
lk_logger.setup(quiet=True)
# try to raise an error
x = 1 / 0
Using in IPython
Indexing and timing
import lk_logger
lk_logger.setup(quiet=True)
print(':d', 'indexing')
print(':i', 'aaa')
print(':i', 'bbb')
print(':i', 'ccc')
print(':i0', 'reset counter')
print(':i', 'ddd')
print(':i', 'eee')
print(':i', 'fff')
print(':d', 'timing')
from time import sleep
sleep(0.1)
print(':t', '... in a short delay')
sleep(1)
print(':t', '... in a little long delay')
sleep(5)
print(':t', '... in a long delay')
Reflect source to parent caller
import lk_logger
lk_logger.setup(quiet=True)
def borrow_a_book(name: str) -> None:
# use ':p' to point to the parent frame
print(f'user borrowed "{name}"', ':p')
record = []
record.append(('shawn', borrow_a_book('python crash course')))
# after some process
...
record.append(('alice', borrow_a_book('deep learning with python')))
The source info is helpful for developer to track different callers to the same function.
Redirect printing to other streamers
import atexit
import lk_logger
from lk_logger import parallel_printing
lk_logger.setup(quiet=True)
class MyLogger:
def __init__(self):
self._buffer = []
atexit.register(self.close)
def write(self, msg: str):
self._buffer.append(msg)
def close(self) -> None:
with open('log.txt', 'w') as f:
f.write('\n'.join(self._buffer))
class MyGui:
def update_ui(self, msg: str) -> None:
""" send message to GUI log panel. """
...
mylogger = MyLogger()
mygui = MyGui()
with parallel_printing(
mylogger.write,
mygui.update_ui,
inherit=True, # default True.
# ^ change to False to prevent default behavior (i.e. printing to console).
):
print('hello world!')
More markups
Here is a list of all available markups. You can also find them from "examples" folder.
import lk_logger
from rich.markdown import Markdown
lk_logger.setup(show_varnames=True)
# -----------------------------------------------------------------------------
print(':dr', '`:e` is [yellow][u]E[/]xception[/]')
try:
raise Exception('this is an exception with locals info')
except Exception as e:
print(':e1', e)
# -----------------------------------------------------------------------------
print(':dr', '`:i` is [yellow][u]I[/]ndexing[/]')
print(':i', 'sunday')
print(':i', 'monday')
print(':i', 'tuesday')
print(':i', 'wednesday')
print(':i', 'thursday')
print(':i', 'friday')
print(':i', 'saturday')
print(':i0')
print(':i', 'sunday in new week')
print(':i', 'monday in new week')
print(':i', 'tuesday in new week')
print(':i', 'wednesday in new week')
print(':i', 'thursday in new week')
print(':i', 'friday in new week')
print(':i', 'saturday in new week')
# -----------------------------------------------------------------------------
print(':dr', '`:l` is [yellow][u]L[/]ong/[u]L[/]oose[/] format')
print(':l', {
'name': 'John',
'age': 30,
'address': {
'country': 'USA',
'city': 'New York',
'street': 'Wall Street'
}
})
# -----------------------------------------------------------------------------
print(':dr', '`:p` is [yellow][u]P[/]arent[/] frame')
def func1():
print('who is calling me?')
print('i am', ':p1')
return 'ok'
response = func1()
print(response)
# -----------------------------------------------------------------------------
print(':dr', '`:r` is [yellow][u]R[/]ich[/] format')
print(':r', '[cyan]hello[/] [yellow]world[/]')
# print a rich renderable object
print(':r1', Markdown('''
# Hello World
This is a markdown document.
- item 1
- item 2
- item 3
Find more usages at [rich](https://github.com/textualize/rich) documentation.
'''))
# automatically convert a dict to a table
print(':r2', {
'Name': ('Alice', 'Bob', 'Charlie'),
'Age': (18, 19, 20),
'City': ('Shanghai', 'Beijing', 'Guangzhou'),
})
# -----------------------------------------------------------------------------
print(':dr', '`:s` [yellow][u]S[/]hort/[u]S[/]imple/[u]S[/]ingle-line[/] format')
a, b = 1, 2
print(':s', a, b, a + b) # without varnames
print(':s1', a, b, a + b) # similar to built-in print (but kept color style)
print(':s2', a, b, a + b) # totally same with built-in print
# -----------------------------------------------------------------------------
print(':dr', '`:t` is [yellow][u]T[/]iming[/]')
print(':t', 'for now')
# -----------------------------------------------------------------------------
print(':dr', '`:v` is [yellow][u]V[/]erbosity[/]')
print(':v0', 'this is a TRACE message')
print(':v1', 'this is a DEBUG message')
print(':v2', 'this is a INFO message')
print(':v3', 'this is a WARN message')
print(':v4', 'this is a ERROR message')
print(':v5', 'this is a FATAL message')
a, b, c = 1, 2, 3
print(':v', a, b, c)
Gallery / Code Screenshots
The projects use lk-logger
to their colorful prints.
More...
Markup References
A markup is a string starts with colon symbol (:
), positioned at the first or the last among positional arguments, and came up with multiple letters and digits.
For example:
print(':i', 'monday')
print(':i', 'tuesday')
print(':i', 'wednesday')
It prints weekdays with a numeric prefix.
Here is a list of all available marks:
Mark | Description |
---|---|
:d |
Divider line |
:e |
Exception |
:f |
Flush |
:i |
Index |
:l |
Long/Loose format (multiple lines) |
:p |
Parent frame |
:r |
Rich style |
:s |
Short/Simple/Single-line format |
:t |
Timestamp |
:v |
Verbosity level |
Markup options:
* d0: divider line
d1: divider block *(not supported)*
* e0: exception trace back
e1: exception trace back with showing locals
e2: enter pdb *(not supported)*
* f0: flush
f1: flush cutoff
f2: flush eddy *(not a good option, maybe removed)*
i0: reset index
* i1: update index
i2: scoped counter
i3: progress *(not supported)*
* l0: long / loose / expanded (multiple lines)
l1: inspect object
p0: self layer
* p1: parent layer
p2: grandparent layer *(be careful using p2+)*
p3: great-grandparent layer
p4: and so on...
* r0: rich style
r1: rich object (rich.table.Table, rich.panel.Panel, etc.)
r2: auto detect rich format (for a limit set of types)
* s0: short / simple / single line
s1: builtin-like print (remains markup features)
s2: builtin print
t0: reset timer
* t1: stop timer and show statistics
t2: temporary timer
* v0: trace / debug / hint (bright black)
v1: info (cyan)
v2: strong info (magenta)
v3: weak success (green dim)
v4: success (green)
v5: weak warning (yellow dim)
v6: warning (yellow)
v7: weak error / failure (red dim)
v8: error / failure (red)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
File details
Details for the file lk_logger-6.0.0-py3-none-any.whl
.
File metadata
- Download URL: lk_logger-6.0.0-py3-none-any.whl
- Upload date:
- Size: 49.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.8.3 CPython/3.13.0 Windows/11
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 6972895ce15c4651cda4373f1f220c925c57edea2a8938c124dda7600f422a0f |
|
MD5 | 38b0c12906389cca37626d7d2468c77a |
|
BLAKE2b-256 | c2b315964c71710580fb57bf6bc655b07a971ed56097ea34ab0f70d893ca5c56 |