Skip to content

Conversation

@Guiforge
Copy link

Fix Markdown export under Python optimized mode (-O)

Context

Issue: docling-project/docling-core#460

Markdown export could crash when running Python with optimizations enabled (e.g. python -O or PYTHONOPTIMIZE=1).

Symptom

UnboundLocalError: cannot access local variable 'list_group' where it is not associated with a value

This surfaced during Markdown serialization of list items.

Root cause

In docling_core/transforms/serializer/markdown.py (Markdown list item serialization), list_group was assigned via the walrus operator inside an assert:

  • assert item.parent and isinstance((list_group := item.parent.resolve(doc)), ListGroup)

Under -O, Python strips assert statements entirely, so the assignment never executes. Since Python still treats list_group as a local variable in the function, later references to list_group raise UnboundLocalError.

(Conceptually the same as Ruff rule RUF018: assignment in assert.)

Fix

  • Remove the assignment from the assert.
  • Resolve list_group explicitly (outside of assert) and guard access with an is not None check.
  • If the parent is unexpectedly missing or not a ListGroup, fall back to the safe Markdown marker - rather than crashing.

This preserves existing behavior for valid documents and prevents optimized-mode crashes.

Tests

  • Added test/test_markdown_optimized_mode.py which spawns a subprocess with sys.executable -O and calls DoclingDocument.export_to_markdown() on a minimal document that triggers list marker normalization.

Notes

  • No public APIs changed.
  • Behavior is strictly more robust: malformed list structures no longer crash serialization in optimized mode.

Avoid assignment-in-assert during list marker normalization (issue docling-project#460).
@github-actions
Copy link
Contributor

DCO Check Failed

Hi @Guiforge, your pull request has failed the Developer Certificate of Origin (DCO) check.

This repository supports remediation commits, so you can fix this without rewriting history — but you must follow the required message format.


🛠 Quick Fix: Add a remediation commit

Run this command:

git commit --allow-empty -s -m "DCO Remediation Commit for Guillaume Pouyat <[email protected]>

I, Guillaume Pouyat <[email protected]>, hereby add my Signed-off-by to this commit: a9ce24f7e9bd440812cb60960bad201e2d1caa56"
git push

🔧 Advanced: Sign off each commit directly

For the latest commit:

git commit --amend --signoff
git push --force-with-lease

For multiple commits:

git rebase --signoff origin/main
git push --force-with-lease

More info: DCO check report

@dosubot
Copy link

dosubot bot commented Dec 31, 2025

Related Documentation

Checked 10 published document(s) in 1 knowledge base(s). No updates required.

How did I do? Any feedback?  Join Discord

@mergify
Copy link

mergify bot commented Dec 31, 2025

Merge Protections

Your pull request matches the following merge protections and will not be merged until they are valid.

🔴 Require two reviewer for test updates

This rule is failing.

When test data is updated, we require two reviewers

  • #approved-reviews-by >= 2

🟢 Enforce conventional commit

Wonderful, this rule succeeded.

Make sure that we follow https://www.conventionalcommits.org/en/v1.0.0/

  • title ~= ^(fix|feat|docs|style|refactor|perf|test|build|ci|chore|revert)(?:\(.+\))?(!)?:

@cau-git
Copy link
Member

cau-git commented Jan 13, 2026

@Guiforge thanks for this fix! The change looks good to me, but I would suggest to remove the test unit you provide, it should not require a test at this level.

Also, please follow the steps to remediate the DCO as posted by the github-bot here.

@codecov
Copy link

codecov bot commented Jan 13, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

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