Skip to content

Stackprinter shows full log for suppressed_paths #40

Closed
@spacemanspiff2007

Description

@spacemanspiff2007

In my application stackprinter ignores the passed in supressed_paths and I am not sure why (this has already worked and I am not sure what changed).
I can't seem to create a short snippet which reproduces the error but in my application it fails every time.

This is the function where I get the traceback.
If I set a break point with the debugger I see that suppressed_paths is indeed properly populated. However if I inspect the returned lines I see the traceback with the included library files.

grafik

I have created a testcase for pytest which fails every time.

Excerpt from github actions (just open the tox part in line 12)

  ERROR    WrapperTest:wrapper.py:179 File "/opt/hostedtoolcache/Python/3.9.0/x64/lib/python3.9/asyncio/base_events.py", line 1056, in create_connection
  ERROR    WrapperTest:wrapper.py:179     967  async def create_connection(
  ERROR    WrapperTest:wrapper.py:179     968          self, protocol_factory, host=None, port=None,
  ERROR    WrapperTest:wrapper.py:179     969          *, ssl=None, family=0,
  ERROR    WrapperTest:wrapper.py:179     970          proto=0, flags=0, sock=None,
I tried to recreate the issue with a snipped but the library files are correctly ignored here, so I am confident that my regexes are correct and that I pass in the parameters correctly.
from pathlib import Path

import aiohttp, typing
import asyncio
import re
import stackprinter

SUPPRESSED_PATHS = (
    re.compile(f'[/\\\\]{Path(__file__).name}$'),   # this file

    # rule file loader
    re.compile(r'[/\\]rule_file.py$'),
    re.compile(r'[/\\]runpy.py$'),

    # Worker functions
    re.compile(r'[/\\]wrappedfunction.py$'),

    # Don't print stack for used libraries
    re.compile(r'[/\\](site-packages|lib)[/\\]asyncio[/\\]'),
    re.compile(r'[/\\]site-packages[/\\]aiohttp[/\\]'),
    re.compile(r'[/\\]site-packages[/\\]voluptuous[/\\]'),
    re.compile(r'[/\\]site-packages[/\\]pydantic[/\\]'),
)
SKIP_TB = tuple(re.compile(k.pattern.replace('$', ', ')) for k in SUPPRESSED_PATHS)


def format_exception(e: typing.Union[Exception, typing.Tuple[typing.Any, typing.Any, typing.Any]]) -> typing.List[str]:
    tb = []
    skip = 0

    lines = stackprinter.format(e, line_wrap=0, truncate_vals=2000, suppressed_paths=SUPPRESSED_PATHS).splitlines()
    for i, line in enumerate(lines):
        if not skip:
            for s in SKIP_TB:
                if s.search(line):
                    # if it's just a two line traceback we skip it
                    if lines[i + 1].startswith('    ') and lines[i + 2].startswith('File'):
                        skip = 2
                        continue
        if skip:
            skip -= 1
            continue

        tb.append(line)

    return tb


class PrintException:
    def __enter__(self):
        pass

    def __exit__(self, exc_type, exc_val, exc_tb):
        # no exception -> we exit gracefully
        if exc_type is None and exc_val is None:
            return True
        for l in format_exception((exc_type, exc_val, exc_tb)):
            print(l)
        return True


def test_run():
    async def test():
        async with aiohttp.ClientSession(timeout=aiohttp.ClientTimeout(0.01)) as session:
            async with session.get('http://localhost:12345') as resp:
                pass

    with PrintException():
        asyncio.get_event_loop().run_until_complete(test())

Do you have any idea what the issue might be?
It would be really nice if you could check out the dev branch and run pytest on the test_wrapper.py file.

The tests need the following libraries additionally to the ones in requirements.txt:
pytest pytest-asyncio asynctest

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions