FA-76641 / Email MIME structure / Open access
Collect the plain-text body to display: alternative empty skip · case 01
An HTML-only last alternative produces an empty display although a text alternative exists.
ROOT CAUSE
The alternative empty skip decision evaluates `if True:` where the contract requires `if got:`.
VERIFIED REPAIR
Use `if got:` for the alternative empty skip decision and keep every other rule of the model unchanged.
Unsuccessful approach: An empty list is not None, so the empty HTML result is still accepted. The attempted `if got is not None:` still disagrees with a fixture.
Case contract
Returns the text/plain strings to display in order. Types compare case-insensitively. multipart/alternative yields the result of its last child that yields any text; other multiparts concatenate their children. Entities with an attachment disposition yield nothing. A message/rfc822 without attachment disposition yields its body; text/plain yields its text; everything else yields nothing.
Why this case matters
Text extraction powers previews, replies and search; wrong choices quote attachments or skip the real body.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(tree):
def walk(n):
t = n['type'].lower()
disp = (n.get('disp') or 'inline').lower()
if t == 'multipart/alternative':
for child in reversed(n['parts']):
got = walk(child)
if True:
return got
return []
if t.startswith('multipart/'):
out = []
for child in n['parts']:
out.extend(walk(child))
return out
if disp == 'attachment':
return []
if t == 'message/rfc822':
return walk(n['body'])
if t == 'text/plain':
return [n['text']]
return []
return walk(tree)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('richer alternative holds text', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'A1'}, {'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'B1'}, {'type': 'image/png'}]}]},), ['B1']), ('html last alternative', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'plain 1'}, {'type': 'text/html'}]},), ['plain 1']), ('attached message and log', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'hi'}, {'type': 'message/rfc822', 'disp': 'attachment', 'body': {'type': 'text/plain', 'text': 'inner'}}, {'type': 'text/plain', 'disp': 'attachment', 'text': 'log 1'}]},), ['hi']), ('inline forwarded alternative', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'x'}, {'type': 'message/rfc822', 'body': {'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'fw1'}, {'type': 'text/html'}]}}]},), ['x', 'fw1']), ('mixed-case types', ({'type': 'MULTIPART/Mixed', 'parts': [{'type': 'Text/Plain', 'text': 't1'}, {'type': 'TEXT/PLAIN', 'text': 'u'}]},), ['t1', 'u']), ('no text at all', ({'type': 'multipart/mixed', 'parts': [{'type': 'image/png'}, {'type': 'application/pdf'}]},), [])], 2: [('richer alternative holds text', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'A2'}, {'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'B2'}, {'type': 'image/png'}]}]},), ['B2']), ('html last alternative', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'plain 2'}, {'type': 'text/html'}]},), ['plain 2']), ('attached message and log', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'hi'}, {'type': 'message/rfc822', 'disp': 'attachment', 'body': {'type': 'text/plain', 'text': 'inner'}}, {'type': 'text/plain', 'disp': 'attachment', 'text': 'log 2'}]},), ['hi']), ('inline forwarded alternative', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'x'}, {'type': 'message/rfc822', 'body': {'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'fw2'}, {'type': 'text/html'}]}}]},), ['x', 'fw2']), ('mixed-case types', ({'type': 'MULTIPART/Mixed', 'parts': [{'type': 'Text/Plain', 'text': 't2'}, {'type': 'TEXT/PLAIN', 'text': 'u'}]},), ['t2', 'u']), ('no text at all', ({'type': 'multipart/mixed', 'parts': [{'type': 'image/png'}, {'type': 'application/pdf'}]},), [])], 3: [('richer alternative holds text', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'A3'}, {'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'B3'}, {'type': 'image/png'}]}]},), ['B3']), ('html last alternative', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'plain 3'}, {'type': 'text/html'}]},), ['plain 3']), ('attached message and log', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'hi'}, {'type': 'message/rfc822', 'disp': 'attachment', 'body': {'type': 'text/plain', 'text': 'inner'}}, {'type': 'text/plain', 'disp': 'attachment', 'text': 'log 3'}]},), ['hi']), ('inline forwarded alternative', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'x'}, {'type': 'message/rfc822', 'body': {'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'fw3'}, {'type': 'text/html'}]}}]},), ['x', 'fw3']), ('mixed-case types', ({'type': 'MULTIPART/Mixed', 'parts': [{'type': 'Text/Plain', 'text': 't3'}, {'type': 'TEXT/PLAIN', 'text': 'u'}]},), ['t3', 'u']), ('no text at all', ({'type': 'multipart/mixed', 'parts': [{'type': 'image/png'}, {'type': 'application/pdf'}]},), [])], 4: [('richer alternative holds text', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'A4'}, {'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'B4'}, {'type': 'image/png'}]}]},), ['B4']), ('html last alternative', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'plain 4'}, {'type': 'text/html'}]},), ['plain 4']), ('attached message and log', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'hi'}, {'type': 'message/rfc822', 'disp': 'attachment', 'body': {'type': 'text/plain', 'text': 'inner'}}, {'type': 'text/plain', 'disp': 'attachment', 'text': 'log 4'}]},), ['hi']), ('inline forwarded alternative', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'x'}, {'type': 'message/rfc822', 'body': {'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'fw4'}, {'type': 'text/html'}]}}]},), ['x', 'fw4']), ('mixed-case types', ({'type': 'MULTIPART/Mixed', 'parts': [{'type': 'Text/Plain', 'text': 't4'}, {'type': 'TEXT/PLAIN', 'text': 'u'}]},), ['t4', 'u']), ('no text at all', ({'type': 'multipart/mixed', 'parts': [{'type': 'image/png'}, {'type': 'application/pdf'}]},), [])], 5: [('richer alternative holds text', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'A5'}, {'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'B5'}, {'type': 'image/png'}]}]},), ['B5']), ('html last alternative', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'plain 5'}, {'type': 'text/html'}]},), ['plain 5']), ('attached message and log', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'hi'}, {'type': 'message/rfc822', 'disp': 'attachment', 'body': {'type': 'text/plain', 'text': 'inner'}}, {'type': 'text/plain', 'disp': 'attachment', 'text': 'log 5'}]},), ['hi']), ('inline forwarded alternative', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'x'}, {'type': 'message/rfc822', 'body': {'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'fw5'}, {'type': 'text/html'}]}}]},), ['x', 'fw5']), ('mixed-case types', ({'type': 'MULTIPART/Mixed', 'parts': [{'type': 'Text/Plain', 'text': 't5'}, {'type': 'TEXT/PLAIN', 'text': 'u'}]},), ['t5', 'u']), ('no text at all', ({'type': 'multipart/mixed', 'parts': [{'type': 'image/png'}, {'type': 'application/pdf'}]},), [])]}
for _label, _args, _expected in _CASES[N]:
check(_label, solve(*_args), _expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| richer alternative holds text | ['B1'] | ['B1'] | Passed |
| html last alternative | [] | ['plain 1'] | Failed |
| attached message and log | ['hi'] | ['hi'] | Passed |
| inline forwarded alternative | ['x'] | ['x', 'fw1'] | Failed |
| mixed-case types | ['t1', 'u'] | ['t1', 'u'] | Passed |
| no text at all | [] | [] | Passed |
SHA-256 / 5bb0c4fac26004cb6133b39d7e437021d5cb4e60bb8f1c0e0b0d97ee970d255d
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(tree):
def walk(n):
t = n['type'].lower()
disp = (n.get('disp') or 'inline').lower()
if t == 'multipart/alternative':
for child in reversed(n['parts']):
got = walk(child)
if got is not None:
return got
return []
if t.startswith('multipart/'):
out = []
for child in n['parts']:
out.extend(walk(child))
return out
if disp == 'attachment':
return []
if t == 'message/rfc822':
return walk(n['body'])
if t == 'text/plain':
return [n['text']]
return []
return walk(tree)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('richer alternative holds text', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'A1'}, {'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'B1'}, {'type': 'image/png'}]}]},), ['B1']), ('html last alternative', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'plain 1'}, {'type': 'text/html'}]},), ['plain 1']), ('attached message and log', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'hi'}, {'type': 'message/rfc822', 'disp': 'attachment', 'body': {'type': 'text/plain', 'text': 'inner'}}, {'type': 'text/plain', 'disp': 'attachment', 'text': 'log 1'}]},), ['hi']), ('inline forwarded alternative', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'x'}, {'type': 'message/rfc822', 'body': {'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'fw1'}, {'type': 'text/html'}]}}]},), ['x', 'fw1']), ('mixed-case types', ({'type': 'MULTIPART/Mixed', 'parts': [{'type': 'Text/Plain', 'text': 't1'}, {'type': 'TEXT/PLAIN', 'text': 'u'}]},), ['t1', 'u']), ('no text at all', ({'type': 'multipart/mixed', 'parts': [{'type': 'image/png'}, {'type': 'application/pdf'}]},), [])], 2: [('richer alternative holds text', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'A2'}, {'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'B2'}, {'type': 'image/png'}]}]},), ['B2']), ('html last alternative', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'plain 2'}, {'type': 'text/html'}]},), ['plain 2']), ('attached message and log', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'hi'}, {'type': 'message/rfc822', 'disp': 'attachment', 'body': {'type': 'text/plain', 'text': 'inner'}}, {'type': 'text/plain', 'disp': 'attachment', 'text': 'log 2'}]},), ['hi']), ('inline forwarded alternative', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'x'}, {'type': 'message/rfc822', 'body': {'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'fw2'}, {'type': 'text/html'}]}}]},), ['x', 'fw2']), ('mixed-case types', ({'type': 'MULTIPART/Mixed', 'parts': [{'type': 'Text/Plain', 'text': 't2'}, {'type': 'TEXT/PLAIN', 'text': 'u'}]},), ['t2', 'u']), ('no text at all', ({'type': 'multipart/mixed', 'parts': [{'type': 'image/png'}, {'type': 'application/pdf'}]},), [])], 3: [('richer alternative holds text', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'A3'}, {'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'B3'}, {'type': 'image/png'}]}]},), ['B3']), ('html last alternative', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'plain 3'}, {'type': 'text/html'}]},), ['plain 3']), ('attached message and log', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'hi'}, {'type': 'message/rfc822', 'disp': 'attachment', 'body': {'type': 'text/plain', 'text': 'inner'}}, {'type': 'text/plain', 'disp': 'attachment', 'text': 'log 3'}]},), ['hi']), ('inline forwarded alternative', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'x'}, {'type': 'message/rfc822', 'body': {'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'fw3'}, {'type': 'text/html'}]}}]},), ['x', 'fw3']), ('mixed-case types', ({'type': 'MULTIPART/Mixed', 'parts': [{'type': 'Text/Plain', 'text': 't3'}, {'type': 'TEXT/PLAIN', 'text': 'u'}]},), ['t3', 'u']), ('no text at all', ({'type': 'multipart/mixed', 'parts': [{'type': 'image/png'}, {'type': 'application/pdf'}]},), [])], 4: [('richer alternative holds text', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'A4'}, {'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'B4'}, {'type': 'image/png'}]}]},), ['B4']), ('html last alternative', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'plain 4'}, {'type': 'text/html'}]},), ['plain 4']), ('attached message and log', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'hi'}, {'type': 'message/rfc822', 'disp': 'attachment', 'body': {'type': 'text/plain', 'text': 'inner'}}, {'type': 'text/plain', 'disp': 'attachment', 'text': 'log 4'}]},), ['hi']), ('inline forwarded alternative', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'x'}, {'type': 'message/rfc822', 'body': {'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'fw4'}, {'type': 'text/html'}]}}]},), ['x', 'fw4']), ('mixed-case types', ({'type': 'MULTIPART/Mixed', 'parts': [{'type': 'Text/Plain', 'text': 't4'}, {'type': 'TEXT/PLAIN', 'text': 'u'}]},), ['t4', 'u']), ('no text at all', ({'type': 'multipart/mixed', 'parts': [{'type': 'image/png'}, {'type': 'application/pdf'}]},), [])], 5: [('richer alternative holds text', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'A5'}, {'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'B5'}, {'type': 'image/png'}]}]},), ['B5']), ('html last alternative', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'plain 5'}, {'type': 'text/html'}]},), ['plain 5']), ('attached message and log', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'hi'}, {'type': 'message/rfc822', 'disp': 'attachment', 'body': {'type': 'text/plain', 'text': 'inner'}}, {'type': 'text/plain', 'disp': 'attachment', 'text': 'log 5'}]},), ['hi']), ('inline forwarded alternative', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'x'}, {'type': 'message/rfc822', 'body': {'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'fw5'}, {'type': 'text/html'}]}}]},), ['x', 'fw5']), ('mixed-case types', ({'type': 'MULTIPART/Mixed', 'parts': [{'type': 'Text/Plain', 'text': 't5'}, {'type': 'TEXT/PLAIN', 'text': 'u'}]},), ['t5', 'u']), ('no text at all', ({'type': 'multipart/mixed', 'parts': [{'type': 'image/png'}, {'type': 'application/pdf'}]},), [])]}
for _label, _args, _expected in _CASES[N]:
check(_label, solve(*_args), _expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| richer alternative holds text | ['B1'] | ['B1'] | Passed |
| html last alternative | [] | ['plain 1'] | Failed |
| attached message and log | ['hi'] | ['hi'] | Passed |
| inline forwarded alternative | ['x'] | ['x', 'fw1'] | Failed |
| mixed-case types | ['t1', 'u'] | ['t1', 'u'] | Passed |
| no text at all | [] | [] | Passed |
SHA-256 / c92a2d045aafe5ccaf76ea8daec4bf965cafc80e9d6d083ec99750b9d7c00dff
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(tree):
def walk(n):
t = n['type'].lower()
disp = (n.get('disp') or 'inline').lower()
if t == 'multipart/alternative':
for child in reversed(n['parts']):
got = walk(child)
if got:
return got
return []
if t.startswith('multipart/'):
out = []
for child in n['parts']:
out.extend(walk(child))
return out
if disp == 'attachment':
return []
if t == 'message/rfc822':
return walk(n['body'])
if t == 'text/plain':
return [n['text']]
return []
return walk(tree)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('richer alternative holds text', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'A1'}, {'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'B1'}, {'type': 'image/png'}]}]},), ['B1']), ('html last alternative', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'plain 1'}, {'type': 'text/html'}]},), ['plain 1']), ('attached message and log', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'hi'}, {'type': 'message/rfc822', 'disp': 'attachment', 'body': {'type': 'text/plain', 'text': 'inner'}}, {'type': 'text/plain', 'disp': 'attachment', 'text': 'log 1'}]},), ['hi']), ('inline forwarded alternative', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'x'}, {'type': 'message/rfc822', 'body': {'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'fw1'}, {'type': 'text/html'}]}}]},), ['x', 'fw1']), ('mixed-case types', ({'type': 'MULTIPART/Mixed', 'parts': [{'type': 'Text/Plain', 'text': 't1'}, {'type': 'TEXT/PLAIN', 'text': 'u'}]},), ['t1', 'u']), ('no text at all', ({'type': 'multipart/mixed', 'parts': [{'type': 'image/png'}, {'type': 'application/pdf'}]},), [])], 2: [('richer alternative holds text', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'A2'}, {'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'B2'}, {'type': 'image/png'}]}]},), ['B2']), ('html last alternative', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'plain 2'}, {'type': 'text/html'}]},), ['plain 2']), ('attached message and log', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'hi'}, {'type': 'message/rfc822', 'disp': 'attachment', 'body': {'type': 'text/plain', 'text': 'inner'}}, {'type': 'text/plain', 'disp': 'attachment', 'text': 'log 2'}]},), ['hi']), ('inline forwarded alternative', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'x'}, {'type': 'message/rfc822', 'body': {'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'fw2'}, {'type': 'text/html'}]}}]},), ['x', 'fw2']), ('mixed-case types', ({'type': 'MULTIPART/Mixed', 'parts': [{'type': 'Text/Plain', 'text': 't2'}, {'type': 'TEXT/PLAIN', 'text': 'u'}]},), ['t2', 'u']), ('no text at all', ({'type': 'multipart/mixed', 'parts': [{'type': 'image/png'}, {'type': 'application/pdf'}]},), [])], 3: [('richer alternative holds text', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'A3'}, {'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'B3'}, {'type': 'image/png'}]}]},), ['B3']), ('html last alternative', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'plain 3'}, {'type': 'text/html'}]},), ['plain 3']), ('attached message and log', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'hi'}, {'type': 'message/rfc822', 'disp': 'attachment', 'body': {'type': 'text/plain', 'text': 'inner'}}, {'type': 'text/plain', 'disp': 'attachment', 'text': 'log 3'}]},), ['hi']), ('inline forwarded alternative', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'x'}, {'type': 'message/rfc822', 'body': {'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'fw3'}, {'type': 'text/html'}]}}]},), ['x', 'fw3']), ('mixed-case types', ({'type': 'MULTIPART/Mixed', 'parts': [{'type': 'Text/Plain', 'text': 't3'}, {'type': 'TEXT/PLAIN', 'text': 'u'}]},), ['t3', 'u']), ('no text at all', ({'type': 'multipart/mixed', 'parts': [{'type': 'image/png'}, {'type': 'application/pdf'}]},), [])], 4: [('richer alternative holds text', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'A4'}, {'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'B4'}, {'type': 'image/png'}]}]},), ['B4']), ('html last alternative', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'plain 4'}, {'type': 'text/html'}]},), ['plain 4']), ('attached message and log', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'hi'}, {'type': 'message/rfc822', 'disp': 'attachment', 'body': {'type': 'text/plain', 'text': 'inner'}}, {'type': 'text/plain', 'disp': 'attachment', 'text': 'log 4'}]},), ['hi']), ('inline forwarded alternative', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'x'}, {'type': 'message/rfc822', 'body': {'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'fw4'}, {'type': 'text/html'}]}}]},), ['x', 'fw4']), ('mixed-case types', ({'type': 'MULTIPART/Mixed', 'parts': [{'type': 'Text/Plain', 'text': 't4'}, {'type': 'TEXT/PLAIN', 'text': 'u'}]},), ['t4', 'u']), ('no text at all', ({'type': 'multipart/mixed', 'parts': [{'type': 'image/png'}, {'type': 'application/pdf'}]},), [])], 5: [('richer alternative holds text', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'A5'}, {'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'B5'}, {'type': 'image/png'}]}]},), ['B5']), ('html last alternative', ({'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'plain 5'}, {'type': 'text/html'}]},), ['plain 5']), ('attached message and log', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'hi'}, {'type': 'message/rfc822', 'disp': 'attachment', 'body': {'type': 'text/plain', 'text': 'inner'}}, {'type': 'text/plain', 'disp': 'attachment', 'text': 'log 5'}]},), ['hi']), ('inline forwarded alternative', ({'type': 'multipart/mixed', 'parts': [{'type': 'text/plain', 'text': 'x'}, {'type': 'message/rfc822', 'body': {'type': 'multipart/alternative', 'parts': [{'type': 'text/plain', 'text': 'fw5'}, {'type': 'text/html'}]}}]},), ['x', 'fw5']), ('mixed-case types', ({'type': 'MULTIPART/Mixed', 'parts': [{'type': 'Text/Plain', 'text': 't5'}, {'type': 'TEXT/PLAIN', 'text': 'u'}]},), ['t5', 'u']), ('no text at all', ({'type': 'multipart/mixed', 'parts': [{'type': 'image/png'}, {'type': 'application/pdf'}]},), [])]}
for _label, _args, _expected in _CASES[N]:
check(_label, solve(*_args), _expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| richer alternative holds text | ['B1'] | ['B1'] | Passed |
| html last alternative | ['plain 1'] | ['plain 1'] | Passed |
| attached message and log | ['hi'] | ['hi'] | Passed |
| inline forwarded alternative | ['x', 'fw1'] | ['x', 'fw1'] | Passed |
| mixed-case types | ['t1', 'u'] | ['t1', 'u'] | Passed |
| no text at all | [] | [] | Passed |
SHA-256 / f1be4396ec22927d1b8a710afb41affde67f9ec6d7239ad0d04e2efbb6c09514
Verification & scope
Stipulated offline model over pre-parsed MIME dictionaries; not a conforming MIME parser, generator or mail client. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.
Observations recorded using Python 3.12.14 at 2026-09-29T14:49:18.055892+00:00.
Case digest / 80860f72560134d4e31e7b63e0b472bb8a9ac34ee8bd100790c1b56dbd53dd24