Skip to content

Conversation

@Tronic
Copy link
Member

@Tronic Tronic commented Jun 26, 2025

This updates the project to use the new traceback facilities added since Python 3.10 and following versions, e.g. to show the exact position on line where the error occurs. This includes such major changes that no internal compatibility with the long-lived 1.x branch is preserved, although the main APIs (e.g. HTML output) remain the same.

Furthermore, the Python tooling is updated to modern tools such as uv and ruff, with tests (finally) added, and setup.py replaced by pyproject.toml.

This PR tracks the progress of the major changes, and is intended to be published as version 2.0.0 after sufficient development and testing has been conducted in the environments where tracerite is being used (mainly Jupyter and Sanic).

Tronic added 14 commits June 26, 2025 15:41
… exact columns of the error and a caret position if available.
…nly mark the actual error (yellow background), with em (red font) for caret.
- Based on CPython formatting code.

Plenty of bugfixes but issues remain too. Tests are passing.
- Added fallback mechanism for multiline operator detection when caret anchor extraction fails
- Implemented _fallback_multiline_operator_detection() to find standalone operators in multiline segments
- Fixed em_columns population for complex multiline cases with comments
- Enhanced fragment splitting to correctly handle whitespace between code and comments
- Added comprehensive tests for all error cases in test_trace.py and test_html.py
- All tests now pass across Python 3.8-3.13

Fixes multiline operator highlighting in cases like:
_ = (1
    +   # Comment
    "a")
@Tronic
Copy link
Member Author

Tronic commented Jul 1, 2025

After a few failed approaches, now it finally is getting significantly better than the old version. The coolest bit is that we can do Python 3.10+ style error formatting even on Python 3.8. This PR adds unit tests and modern project toolchain, usability improvements and a lot more code (that I would prefer to reduce).

To users of HTML formatting, there is one breaking change, that is now only the relevant code is <mark>ed, not including indent or other extras. For the entire line (sans trailing whitespace), span instead wraps it, while mark is reserved for the problematic code only, and further using em within that for "caret" highlights. These require a few lines of CSS changes for those who run a custom stylesheet (such as the Sanic server).

@Tronic
Copy link
Member Author

Tronic commented Jul 1, 2025

I'll need to concentrate on other things in the coming days, but the main TODO:

  • SyntaxErrors (need special handling, missing from 1.x too)
  • Correction hints/suggestions, produced by CPython but not currently used in Tracerite
  • Variable Inspector needs a closer look, has a placeholder implementation at the moment
  • A few bugs here and there, with mispositioned or missing mark and carot (em)
  • CSS updates to make it look better if run in VS code dark mode or other things other than white-bg Jupyter
  • Various minor visual issues, like the tooltips, some scrollbars appearing etc. need to be taken care of

Tronic added 14 commits June 30, 2025 23:41
…ing logic

- Extract helper functions for frame metadata processing:
  - _get_qualified_function_name
  - _get_frame_relevance
  - _build_position_map
  - _find_bug_frame
- Extract complex emphasis column extraction logic into separate functions:
  - _extract_emphasis_columns
  - _extract_single_line_anchors
  - _extract_full_segment_anchors
- Consolidate position/range conversion logic:
  - Unified _positions_to_consecutive_ranges function
  - _get_highlight_boundaries for boundary calculation
- Simplify extract_frames function by removing inline logic and duplicated code
- Reduce code complexity while maintaining functionality
- Extract helper functions for common line parsing patterns:
  - _split_line_content: unified line ending handling
  - _process_indentation: dedent and indent processing
  - _create_content_fragments: unified fragment creation with type handling
- Simplify _parse_line_to_fragments by removing nested conditionals
- Reduce code duplication in fragment creation for different content types
- Maintain same functionality while improving code readability
- Extract _calculate_mark_range function to handle mark range logic for different line types
- Extract _calculate_common_indent function for cleaner indentation calculation
- Simplify _parse_lines_to_fragments by removing nested conditional logic
- Reduce code duplication in mark range calculations for multi-line vs single-line errors
- Maintain same functionality while improving code organization
- Extract OPERATOR_PATTERN as module-level constant to avoid repeated compilation
- Remove duplicate import re statement in _fallback_multiline_operator_detection
- Extract _create_summary function to simplify exception message truncation logic
- Reduce code repetition and improve maintainability with cleaner organization
- Modified _extract_emphasis_columns to return either None or 4-tuple (left_end_lineno, right_start_lineno, left_end_offset, right_start_offset)
- Created unified highlighting system using _convert_4tuple_to_positions to convert both mark and em coordinates to absolute character positions
- Replaced separate mark_range and em_columns processing with unified _create_unified_fragments approach
- Removed duplicate code including _calculate_mark_range, old _parse_line_to_fragments, _create_content_fragments, and _create_highlighted_fragments
- Added _create_highlighted_fragments_unified and _parse_line_to_fragments_unified for cleaner unified processing
- Simplified logic by taking advantage of em only occurring within mark regions
- All tests now pass with the new unified approach
- Introduce Range namedtuple (lfirst, lfinal, cbeg, cend) for all position data
- Standardize to 1-based inclusive line numbers, 0-based exclusive columns
- Remove all legacy mark/em column handling and old field names
- Update tracerite/trace.py: unified Range-based traceback and fragment logic
- Update tracerite/html.py: use Range for display and tooltip logic
- Update tests/test_trace.py: use Range structure for all assertions
- All tests pass across Python 3.8-3.13
@Tronic
Copy link
Member Author

Tronic commented Jul 2, 2025

Apparently all issues listed in the previous message are now handled. I have a local branch for SyntaxError but hooking it up to Jupyter/IPython is somewhat ugly so I omitted it from here for now. Also it does not display input cell name correctly, nor does it display any code, so the built-in handling (UltraTB) is better still. Major style update also. The tooltip popups never functioned correctly, so they are now displayed all the time next to emoji symbols in code.

@Tronic Tronic marked this pull request as ready for review July 2, 2025 03:16
@Tronic
Copy link
Member Author

Tronic commented Jul 2, 2025

Please review, test on your box etc. But do NOT merge yet.

@Tronic
Copy link
Member Author

Tronic commented Jul 2, 2025

Screenshots available at https://drop.zi.fi/#/tracerite/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants