Skip to content

Invalid caret position when reconstructing traceback #76

Open
@achille-roussel

Description

@achille-roussel

Hello!

Thanks for maintaining this library, it's been very useful.

I'm opening this issue to discuss an improvement that could create a better experience for developers when they are shown a stack trace for an exception that was reconstructed with tblib.Traceback.form_string(s).as_traceback().

In most cases, Python is able to show a caret below the expression that triggered the exception (e.g., as a sequence of ^).

The Python traceback package creates a FrameSummary containing colno and end_colno to track the position of the caret.

However, the dynamic traceback reconstruction that is done by tblib via compilation of code snippets results in a caret that is always ``:

  • The length corresponds to the length of the __traceback_maker type.
  • The column offset is somehow always interpreted as zero. That I haven't figured out why yet, I would expect it to be 6 since the full line triggering the exception is raise __traceback_maker.

There may be a relationship to #75 as well, since it is my understanding that the column offsets are derived from the instruction position in Python 3.11+.

def _walk_tb_with_full_positions(tb):
    # Internal version of walk_tb that yields full code positions including
    # end line and column information.
    while tb is not None:
        positions = _get_code_position(tb.tb_frame.f_code, tb.tb_lasti)
        # Yield tb_lineno when co_positions does not have a line number to
        # maintain behavior with walk_tb.
        if positions[0] is None:
            yield tb.tb_frame, (tb.tb_lineno, ) + positions[1:]
        else:
            yield tb.tb_frame, positions
        tb = tb.tb_next


def _get_code_position(code, instruction_index):
    if instruction_index < 0:
        return (None, None, None, None)
    positions_gen = code.co_positions()
    return next(itertools.islice(positions_gen, instruction_index // 2, None))

I attempted a fix in master...achille-roussel:python-tblib:fix-traceback-caret-position, but without much success, the column offsets get lost after reconstructing the traceback.

This seems like it would be worthy of more discussion before investing further, let me know what you think about the issue!

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