Skip to content

Commit a6b0149

Browse files
author
Andy Landy
committed
v 2.2.0
1 parent 5e3a561 commit a6b0149

File tree

572 files changed

+1923
-454
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

572 files changed

+1923
-454
lines changed

.github/workflows/dev-test.yml

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,32 @@ on:
88
- '*'
99
jobs:
1010
tests:
11-
runs-on: ${{ matrix.os }}
11+
runs-on: ${{ matrix.arrays.os }}
1212
strategy:
1313
matrix:
14-
os: [ubuntu-latest, windows-latest]
15-
# 3.13 not available yet somehow
16-
# 3.7 has issues with multiline expressions
17-
# 3.6- not found for ubuntu-latest
18-
python-version: [3.8, 3.9, '3.10', 3.11, 3.12]
14+
arrays: [
15+
# {os: ubuntu-22.04, python-version: '3.7.17'}, # multiline code is depicted differently
16+
{os: ubuntu-22.04, python-version: '3.8'},
17+
{os: ubuntu-22.04, python-version: '3.9'},
18+
{os: ubuntu-22.04, python-version: '3.10'},
19+
{os: ubuntu-22.04, python-version: '3.11'},
20+
{os: ubuntu-22.04, python-version: '3.12'},
21+
{os: ubuntu-22.04, python-version: '3.13'},
22+
# {os: ubuntu-22.04, python-version: '3.14.0-alpha.5'}, # too early
23+
# {os: windows-latest, python-version: '3.7.9'}, # multiline code is depicted differently
24+
{os: windows-latest, python-version: '3.8'},
25+
{os: windows-latest, python-version: '3.9'},
26+
{os: windows-latest, python-version: '3.10'},
27+
{os: windows-latest, python-version: '3.11'},
28+
{os: windows-latest, python-version: '3.12'},
29+
{os: windows-latest, python-version: '3.13'}
30+
# {os: windows-latest, python-version: '3.14.0-alpha.5'} # too early
31+
]
1932
steps:
20-
- name: Set up Python ${{ matrix.python-version }}
21-
uses: actions/setup-python@v1
33+
- name: Set up Python ${{ matrix.arrays.python-version }}
34+
uses: actions/setup-python@v4
2235
with:
23-
python-version: ${{ matrix.python-version }}
36+
python-version: ${{ matrix.arrays.python-version }}
2437

2538
- name: Install dependencies
2639
run: |
@@ -35,13 +48,15 @@ jobs:
3548
flake8 traceback_with_variables --count --show-source --statistics --max-line-length=127
3649
3750
- name: Test with pytest
51+
env:
52+
PYTHONHASHSEED: 1
3853
run: |
3954
python -Xfrozen_modules=off -m pytest -vv --cov=traceback_with_variables --cov-report=json
4055
4156
- name: Upload coverage report
4257
uses: actions/upload-artifact@v4
4358
with:
44-
name: coverage-${{ matrix.os }}-${{ matrix.python-version }}
59+
name: coverage-${{ matrix.arrays.os }}-${{ matrix.arrays.python-version }}
4560
path: coverage.json
4661

4762
coverage:

.github/workflows/master-test.yml

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,32 @@ on:
88
- 'master'
99
jobs:
1010
tests:
11-
runs-on: ${{ matrix.os }}
11+
runs-on: ${{ matrix.arrays.os }}
1212
strategy:
1313
matrix:
14-
os: [ubuntu-latest, windows-latest]
15-
# 3.13 not available yet somehow
16-
# 3.7 has issues with multiline expressions
17-
# 3.6- not found for ubuntu-latest
18-
python-version: [3.8, 3.9, '3.10', 3.11, 3.12]
14+
arrays: [
15+
# {os: ubuntu-22.04, python-version: '3.7.17'}, # multiline code is depicted differently
16+
{os: ubuntu-22.04, python-version: '3.8'},
17+
{os: ubuntu-22.04, python-version: '3.9'},
18+
{os: ubuntu-22.04, python-version: '3.10'},
19+
{os: ubuntu-22.04, python-version: '3.11'},
20+
{os: ubuntu-22.04, python-version: '3.12'},
21+
{os: ubuntu-22.04, python-version: '3.13'},
22+
# {os: ubuntu-22.04, python-version: '3.14.0-alpha.5'}, # too early
23+
# {os: windows-latest, python-version: '3.7.9'}, # multiline code is depicted differently
24+
{os: windows-latest, python-version: '3.8'},
25+
{os: windows-latest, python-version: '3.9'},
26+
{os: windows-latest, python-version: '3.10'},
27+
{os: windows-latest, python-version: '3.11'},
28+
{os: windows-latest, python-version: '3.12'},
29+
{os: windows-latest, python-version: '3.13'}
30+
# {os: windows-latest, python-version: '3.14.0-alpha.5'} # too early
31+
]
1932
steps:
20-
- name: Set up Python ${{ matrix.python-version }}
21-
uses: actions/setup-python@v1
33+
- name: Set up Python ${{ matrix.arrays.python-version }}
34+
uses: actions/setup-python@v4
2235
with:
23-
python-version: ${{ matrix.python-version }}
36+
python-version: ${{ matrix.arrays.python-version }}
2437

2538
- name: Install dependencies
2639
run: |
@@ -35,13 +48,15 @@ jobs:
3548
flake8 traceback_with_variables --count --show-source --statistics --max-line-length=127
3649
3750
- name: Test with pytest
51+
env:
52+
PYTHONHASHSEED: 1
3853
run: |
3954
python -Xfrozen_modules=off -m pytest -vv --cov=traceback_with_variables --cov-report=json
4055
4156
- name: Upload coverage report
4257
uses: actions/upload-artifact@v4
4358
with:
44-
name: coverage-${{ matrix.os }}-${{ matrix.python-version }}
59+
name: coverage-${{ matrix.arrays.os }}-${{ matrix.arrays.python-version }}
4560
path: coverage.json
4661

4762
coverage:

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
# Changelog
22

3+
## 2.2.0
4+
- Fully compatible with 2.1.1
5+
- (BIG) Huge collections are printed faster, time depends only on `max_value_str_len`
6+
- Add `hide`, `skip`, `show` as standard prints
7+
- Variables like `password` and `token` are now hidden by default
8+
- Added warning about secrets to readme, an example code to deal with it and a short essay
9+
- Tested in python 3.13 and python 3.7
10+
- More test cases and data types
11+
- All objects without custom `__str__` are printed with all attrs
12+
- Standard backup tracebacks have this library stacks collapsed
13+
314
## 2.1.1
415
- Add "tb" alias creation for lines like `import tb.a`
516

README.md

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
![Example](https://raw.githubusercontent.com/andy-landy/traceback_with_variables/master/header.png)
22

33
<h2 align="center">Python Traceback (Error Message) Printing Variables</h2>
4-
<p align="center">Very simple to use, but versatile when needed. Try for debug and keep for production.</p>
4+
<p align="center">Very simple to use and fast, but versatile when needed. Try for debug and keep for small-scale production.</p>
55

66
<p align="center">
77
<a href="https://github.com/andy-landy/traceback_with_variables/actions"><img alt="Actions Status" src="https://github.com/andy-landy/traceback_with_variables/workflows/tests/badge.svg"></a>
@@ -47,7 +47,7 @@ _Contents:_ **[Installation](#installation)** | **[🚀 Quick Start](#-quick-sta
4747
### Installation
4848

4949
```
50-
pip install traceback-with-variables==2.1.1
50+
pip install traceback-with-variables==2.2.0
5151
```
5252
```
5353
conda install -c conda-forge traceback-with-variables
@@ -109,11 +109,12 @@ Using a logger [<a href="https://github.com/andy-landy/traceback_with_variables/
109109

110110
<a href="https://github.com/andy-landy/traceback_with_variables/tree/master/examples/format_customized.py">Customize</a> any of the previous examples:
111111
```python
112+
from traceback_with_variables import fmt
112113
fmt.max_value_str_len = 10000
113114
fmt.skip_files_except = 'my_project'
115+
fmt.custom_var_printers = [] # show all variables, no skips, no hides
114116
```
115117

116-
117118
### Colors
118119

119120
![Example](https://raw.githubusercontent.com/andy-landy/traceback_with_variables/master/color_schemes.png)
@@ -247,8 +248,8 @@ Using a logger [<a href="https://github.com/andy-landy/traceback_with_variables/
247248

248249
* — Should I use it after debugging is over, i.e. *in production*?
249250

250-
Yes, of course! That way it might save you even more time (watch out for sensitive data
251-
like passwords and tokens in you logs, use skip_files_except to hide code from libs AND custom_var_printers to hide own locals). Note: you can deploy more serious frameworks, e.g. `Sentry`
251+
Yes, of course! That way it might save you even more time (<a href="https://github.com/andy-landy/traceback_with_variables/tree/master/examples/secret_data.py">watch out</a> for sensitive data
252+
like 🔴**passwords** and **tokens** in you logs). Note: you can deploy more serious monitoring frameworks, e.g. `Sentry`
252253

253254
<br/>
254255

@@ -261,7 +262,16 @@ Using a logger [<a href="https://github.com/andy-landy/traceback_with_variables/
261262
step 5: Examine the printouts and possibly add some more info (then go back to step 2). \
262263
step 6: Erase all recently added printouts, logging and exception messages. \
263264
step 7: Go back to step 1 once bugs appear.
264-
265+
266+
267+
* — Is it slow? I have huge lists and dicts and data objects!
268+
269+
Data size doesn't matter! Printing is smart, so only the resulting suffix and prefix are generated, e.g.
270+
271+
`list(range(100000000))` becomes just `"[0, 1, 2, ...9998, 99999999]"` in 0.00012s
272+
273+
Use `fmt`'s `.max_value_str_len`, and `.ellipsis_rel_pos` (0.0 to 1.0) to tweak the output.
274+
265275

266276
### Examples and recipes
267277

@@ -279,6 +289,7 @@ Using a logger [<a href="https://github.com/andy-landy/traceback_with_variables/
279289
* <a href="https://github.com/andy-landy/traceback_with_variables/tree/master/examples/work_with_traceback_lines.py">get traceback lines for custom things</a>
280290
* <a href="https://github.com/andy-landy/traceback_with_variables/tree/master/examples/flask.py">using with `flask`</a>
281291
* <a href="https://github.com/andy-landy/traceback_with_variables/tree/master/examples/format_customized.py">customize the output</a>
292+
* <a href="https://github.com/andy-landy/traceback_with_variables/tree/master/examples/secret_data.py">passwords and tokens in logs</a>
282293

283294
### Reference
284295

@@ -292,7 +303,7 @@ Using a logger [<a href="https://github.com/andy-landy/traceback_with_variables/
292303
* `ellipsis_` string to denote long strings truncation, default=`...`
293304
* `skip_files_except` use to print only certain files; list of regexes, ignored if empty, default=None
294305
* `brief_files_except` use to print variables only in certain files; list of regexes, ignored if empty, default=None
295-
* `custom_var_printers` list of pairs of (filter, printer); filter is a name fragment, a type or a function or a list thereof; printer returns `None` to skip a var
306+
* `custom_var_printers` list of pairs of (filter, printer); filter is a name fragment, a type or a function or a list thereof; printer returns `None` to skip a var, standard ones are `hide`, `skip`, `show`
296307
* `color_scheme` is `None` or one of <a href="https://github.com/andy-landy/traceback_with_variables/tree/master/traceback_with_variables/color.py">`ColorSchemes`</a>: `.none` , `.common`, `.nice`, `.synthwave`. `None` is for auto-detect
297308

298309
---

README.tmpl

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
![Example]({{ content_url }}/header.png)
22

33
<h2 align="center">Python Traceback (Error Message) Printing Variables</h2>
4-
<p align="center">Very simple to use, but versatile when needed. Try for debug and keep for production.</p>
4+
<p align="center">Very simple to use and fast, but versatile when needed. Try for debug and keep for small-scale production.</p>
55

66
<p align="center">
77
<a href="{{ repo_url }}/actions"><img alt="Actions Status" src="{{ repo_url }}/workflows/tests/badge.svg"></a>
@@ -109,11 +109,12 @@ Using a logger [<a href="{{ examples_code_url }}/log_for_function.py">with a dec
109109

110110
<a href="{{ examples_code_url }}/format_customized.py">Customize</a> any of the previous examples:
111111
```python
112+
from traceback_with_variables import fmt
112113
fmt.max_value_str_len = 10000
113114
fmt.skip_files_except = 'my_project'
115+
fmt.custom_var_printers = [] # show all variables, no skips, no hides
114116
```
115117

116-
117118
### Colors
118119

119120
![Example]({{ content_url }}/color_schemes.png)
@@ -247,8 +248,8 @@ Using a logger [<a href="{{ examples_code_url }}/log_for_function.py">with a dec
247248

248249
* — Should I use it after debugging is over, i.e. *in production*?
249250

250-
Yes, of course! That way it might save you even more time (watch out for sensitive data
251-
like passwords and tokens in you logs, use skip_files_except to hide code from libs AND custom_var_printers to hide own locals). Note: you can deploy more serious frameworks, e.g. `Sentry`
251+
Yes, of course! That way it might save you even more time (<a href="{{ examples_code_url }}/secret_data.py">watch out</a> for sensitive data
252+
like 🔴**passwords** and **tokens** in you logs). Note: you can deploy more serious monitoring frameworks, e.g. `Sentry`
252253

253254
<br/>
254255

@@ -261,7 +262,16 @@ Using a logger [<a href="{{ examples_code_url }}/log_for_function.py">with a dec
261262
step 5: Examine the printouts and possibly add some more info (then go back to step 2). \
262263
step 6: Erase all recently added printouts, logging and exception messages. \
263264
step 7: Go back to step 1 once bugs appear.
264-
265+
266+
267+
* — Is it slow? I have huge lists and dicts and data objects!
268+
269+
Data size doesn't matter! Printing is smart, so only the resulting suffix and prefix are generated, e.g.
270+
271+
`list(range(100000000))` becomes just `"[0, 1, 2, ...9998, 99999999]"` in 0.00012s
272+
273+
Use `fmt`'s `.max_value_str_len`, and `.ellipsis_rel_pos` (0.0 to 1.0) to tweak the output.
274+
265275

266276
### Examples and recipes
267277

@@ -279,6 +289,7 @@ Using a logger [<a href="{{ examples_code_url }}/log_for_function.py">with a dec
279289
* <a href="{{ examples_code_url }}/work_with_traceback_lines.py">get traceback lines for custom things</a>
280290
* <a href="{{ examples_code_url }}/flask.py">using with `flask`</a>
281291
* <a href="{{ examples_code_url }}/format_customized.py">customize the output</a>
292+
* <a href="{{ examples_code_url }}/secret_data.py">passwords and tokens in logs</a>
282293

283294
### Reference
284295

@@ -292,7 +303,7 @@ Using a logger [<a href="{{ examples_code_url }}/log_for_function.py">with a dec
292303
* `ellipsis_` string to denote long strings truncation, default=`...`
293304
* `skip_files_except` use to print only certain files; list of regexes, ignored if empty, default=None
294305
* `brief_files_except` use to print variables only in certain files; list of regexes, ignored if empty, default=None
295-
* `custom_var_printers` list of pairs of (filter, printer); filter is a name fragment, a type or a function or a list thereof; printer returns `None` to skip a var
306+
* `custom_var_printers` list of pairs of (filter, printer); filter is a name fragment, a type or a function or a list thereof; printer returns `None` to skip a var, standard ones are `hide`, `skip`, `show`
296307
* `color_scheme` is `None` or one of <a href="{{ lib_code_url }}/color.py">`ColorSchemes`</a>: `.none` , `.common`, `.nice`, `.synthwave`. `None` is for auto-detect
297308

298309
---

examples/format_customized.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
1-
from traceback_with_variables import Format, ColorSchemes, is_ipython_global, fmt
1+
from traceback_with_variables import Format, ColorSchemes, is_ipython_global, fmt, hide, skip
22

33

4-
# approach 1
4+
# approach 1 for simples usage
55

66
fmt.max_value_str_len = 10000
77

8+
# show all vars, no hides, no skips:
89

9-
# approach 2
10+
fmt.custom_var_printers = []
11+
12+
13+
# approach 2 for explicit format passing
1014

1115
fmt2 = Format(
1216
before=3,
@@ -20,17 +24,17 @@
2024
skip_files_except=['my_project', 'site-packages'],
2125
brief_files_except='my_project',
2226
custom_var_printers=[ # first matching is used
23-
('password', lambda v: '...hidden...'), # by name, print const str
27+
('password', hide), # by name, print const str
2428
(list, lambda v: f'list{v}'), # by type, print fancy str
25-
(lambda name, type_, filename, is_global: is_global, lambda v: None), # custom filter, skip printing
29+
(lambda name, type_, filename, is_global: is_global, skip), # custom filter, skip printing
2630
(is_ipython_global, lambda v: None), # same, handy for Jupyter
2731
(['secret', dict, (lambda name, *_: 'asd' in name)], lambda v: '???'), # by different things, print const str
2832
]
2933
)
30-
# print_exc(fmt=fmt2)
34+
print_exc(fmt=fmt2)
3135

3236

33-
# approach 3
37+
# approach 3 for explicit format passing, less code
3438

3539
fmt3 = defaults.replace(max_value_str_len=10000)
36-
# print_exc(fmt=fmt3)
40+
print_exc(fmt=fmt3)

examples/secret_data.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
"""
2+
When you deal with secrets like passwords or tokens any debug report system
3+
puts you at risk of exposing those secrets.
4+
5+
Why? Some secrets are stored securely in databases and are kept decrypted only
6+
for short time in memory while being used in code. So any traceback printout
7+
will save them explicitly for you to read later.
8+
9+
Its not a huge problem if the secret is stored unencrypted, i.e. its your
10+
(not users') secret and the machine is secure. User passwords are a problem.
11+
12+
How to prevent secret vars from being printed? You might
13+
* correctly guess how the secret variables in your code are called
14+
* hide the 3rd party well-established library code totally
15+
16+
It will look like this: some of variables in your code will have
17+
"...hidden..." values, and all library files (where secret variables might go
18+
with unrelated names like "s", "part", "msg" etc.) will be skipped totally.
19+
20+
Default settings include all frequent patterns for your variables:
21+
PATTERN_TO_HIDE = '.*(?i:pass|secret|token|key|api_key|cred|pwd).*'
22+
Which will hide a bit too much, names like "keyword" or "compassion". Address
23+
examples below to fit the hiding.
24+
25+
To hide libraries address examples below, note that you can only allow code,
26+
not deny it, so all 3rd party libraries will be hidden if you use this
27+
setting.
28+
"""
29+
30+
# simple tools usage, for more manual approach address format_customized.py
31+
32+
from traceback_with_variables import fmt, hide
33+
34+
35+
# hide all libraries except couple
36+
37+
fmt.brief_files_except = ['.*my_project.*', '.*some_library_1.*', '.*some_library_2.*']
38+
39+
40+
# show all variables
41+
42+
fmt.custom_var_printers = []
43+
44+
45+
# hide variables differently
46+
47+
fmt.custom_var_printers = [
48+
('.*(precious|ring).*', hide), # by name
49+
(MySecret, hide), # by class
50+
]

0 commit comments

Comments
 (0)