10 September 2026 · Syamjith NK
Three posts on this blog argue that the standard way to make Arabic work in Python corrupts it. That argument has a hole in it: all the evidence was about rendering code. A reversed chart label is embarrassing and fixable. But the same recipe run once, before a file is written, bakes the damage in permanently.
If that ever happened upstream of a training corpus, every model trained on it learned from text no Arabic reader would accept. I could not find anyone who had checked, so I did.
I pulled rows for every Arabic dataset I could find on the Hugging Face Hub through the datasets-server API and scanned them with my own linter. 341 datasets.
The first run said 35.6% of an Islamic heritage OCR corpus was corrupted. Two others came back at 27% and 5%. That is a headline. I nearly had one.
Then I printed the characters it was objecting to:
U+FD3F ﴿ ORNATE RIGHT PARENTHESIS
U+FD3E ﴾ ORNATE LEFT PARENTHESIS
U+FD40 ﵀ ARABIC LIGATURE RAHIMAHU ALLAAH
Those are not damage. `﴾ ﴿` is how you enclose a Quranic quotation, and `﵀` is an honorific. People type them deliberately. My tool was flagging them because Arabic Presentation Forms-A is interleaved: the positional glyph forms and ordinary semantic characters share one block, and I had excluded only the word ligatures at the end of it.
So on Islamic heritage text, which is a large share of all Arabic corpora, the tool was
confidently wrong, in the direction that publicly accuses somebody else's dataset. The fix
was to stop tabulating ranges and derive the class from the Unicode character name: a
shaping artefact is exactly a codepoint named ... ISOLATED/INITIAL/MEDIAL/FINAL
FORM. Everything else in the block is deliberate, and new Unicode additions classify
themselves.
All three datasets then read 0%.
276 datasets readable. 26,318 rows. 119,517 text fields.
Twenty-one had any finding at all, and twenty of those were a single stray
presentation form in otherwise correct text, most often U+FE91 BEH INITIAL
FORM. That is copy-paste out of a PDF, or OCR residue. It is still wrong, because a
tokenizer treats ﺑ and ب as different tokens, so the same word
splits into different vocabulary entries and exact-match lookup fails silently. But it is
not the recipe.
One dataset was the recipe.
Yousefmd/arabic_ocr_dataset — every text field, 400 out of 400 across four sample windows, 23 to 29 presentation forms per label. A sample row:
ﺑﺪﺃﺕ ﻗﺮﺍﺀﺓ ﺍﻟﺼﻔﺤﺎﺕ ﺍﻷﻭﻟﻰ ﻋﻠﻰ ﻧﻐﻤﺎﺕ
The intended text is بدأت قراءة الصفحات الأولى على نغمات. Two things happened to it: every letter was replaced by its contextual glyph form, and then the words were written in visual order. INITIAL, MEDIAL, FINAL and ISOLATED forms all present together. That is the complete signature.
It matters more than its size because of which field is damaged. This is an OCR
dataset, so text is the ground truth. A model trained on it learns to emit
presentation forms in visual order, and then fails string comparison against real Arabic
even when it read the image correctly. That is the path from a rendering bug into model
weights, observed rather than argued for.
Now the honest part: that dataset has 17 downloads. This shows the mechanism reaches training data. It is not evidence that widely-used Arabic corpora are affected, and I am not going to write it as though it were.
65 datasets could not be read, and the viewer fails most often on the largest corpora. So this covers the mid and small end of the distribution well and the head of it poorly. Nothing here reaches web-scale pretraining data. A hundred rows per dataset also cannot find a defect confined to a rare subset.
An earlier version of this audit claimed 121 datasets were unreadable. 61 of those were rate-limit errors caused by my own request rate. A coverage caveat built out of your own impatience is not a caveat, it is a mistake; a slower second pass recovered them.
The audit was one command away from being published with three named datasets and a percentage next to each. What stopped it was reading the flagged characters instead of trusting the count.
If you point a measurement tool at somebody else's work, check its output against text you can actually read before the number leaves your machine. A false positive costs them a public accusation and costs you the only thing that makes the measurement worth anything.