Skip to content

Commit 4243c26

Browse files
authored
Mitigate UnicodeDecodeError due to wrong ASCII charset guess for long files (#2360)
* Add json-bug test * Harden ipyn_ converter accepts * Extend the window used to guess the charset * Add help message in case of UnicodeDecodeError * Fix style * Remove leftover print
1 parent 9dc0d65 commit 4243c26

4 files changed

Lines changed: 29 additions & 2 deletions

File tree

‎packages/markitdown/src/markitdown/_exceptions.py‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,10 @@ def __init__(
7373
else:
7474
message += f" - {type(attempt.converter).__name__} threw {attempt.exc_info[0].__name__} with message: {attempt.exc_info[1]}\n"
7575

76+
if isinstance(attempt.exc_info[1], UnicodeDecodeError):
77+
message += (
78+
"The charset may have been automatically guessed incorrectly. "
79+
"If you didn't specify the charset, please retry with an explicitly defined one.\n"
80+
)
81+
7682
super().__init__(message)

‎packages/markitdown/src/markitdown/_markitdown.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -726,9 +726,9 @@ def _get_stream_info_guesses(
726726
# If it's text, also guess the charset
727727
charset = None
728728
if result.prediction.output.is_text:
729-
# Read the first 4k to guess the charset
729+
# Read the first 64k to guess the charset
730730
file_stream.seek(cur_pos)
731-
stream_page = file_stream.read(4096)
731+
stream_page = file_stream.read(65536)
732732
charset_result = charset_normalizer.from_bytes(stream_page).best()
733733

734734
if charset_result is not None:

‎packages/markitdown/src/markitdown/converters/_ipynb_converter.py‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ def accepts(
3838
"nbformat" in notebook_content
3939
and "nbformat_minor" in notebook_content
4040
)
41+
except Exception as e:
42+
pass
4143
finally:
4244
file_stream.seek(cur_pos)
4345

‎packages/markitdown/tests/test_module_misc.py‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#!/usr/bin/env python3 -m pytest
22
import io
3+
import json
34
import os
45
import re
56
import shutil
@@ -587,6 +588,24 @@ def test_markitdown_llm() -> None:
587588
validate_strings(result, PPTX_TEST_STRINGS)
588589

589590

591+
def test_json_with_late_non_ascii_character(tmp_path) -> None:
592+
payload = {
593+
"record": {
594+
"title": "Example record",
595+
"abstract": "This is sample test. " * 500,
596+
},
597+
"notes": "non-ASCII character: è",
598+
}
599+
json_path = tmp_path / "input.json"
600+
json_path.write_text(
601+
json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8"
602+
)
603+
604+
result = MarkItDown().convert(str(json_path))
605+
606+
assert "non-ASCII character: è" in result.text_content
607+
608+
590609
if __name__ == "__main__":
591610
"""Runs this file's tests from the command line."""
592611
for test in [

0 commit comments

Comments
 (0)