broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(parent_type, header):
    default = 'message/rfc822' if parent_type == 'multipart/digest' else 'text/plain'
    mtype = default
    charset = None
    if header is not None:
        head, _, rest = header.partition(';')
        cand = head.strip().lower()
        major, slash, minor = cand.partition('/')
        if slash and major and minor and ' ' not in cand:
            mtype = cand
            for piece in rest.split(';'):
                k, eq, v = piece.partition('=')
                if eq and k.strip().lower() == 'charset':
                    charset = v.strip().strip('"').lower()
    if mtype.startswith('text/'):
        charset = charset or 'us-ascii'
    else:
        charset = charset
    return [mtype, charset]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('digest child without header', ('multipart/digest', None), ['message/rfc822', None]), ('mixed child without header', ('multipart/mixed', None), ['text/plain', 'us-ascii']), ('truncated type in digest', ('multipart/digest', 'text/'), ['message/rfc822', None]), ('missing major type', ('multipart/mixed', '/html; charset=utf-8'), ['text/plain', 'us-ascii']), ('quoted upper-case charset', ('multipart/mixed', 'Text/HTML; charset="UTF-8"'), ['text/html', 'utf-8']), ('charset on a binary type', ('multipart/mixed', 'image/png; charset=binary'), ['image/png', None]), ('padded header', ('multipart/alternative', ' text/plain ; charset=ISO-8859-1'), ['text/plain', 'iso-8859-1']), ('nested message parent', ('message/rfc822', None), ['text/plain', 'us-ascii'])], 2: [('digest child without header', ('multipart/digest', None), ['message/rfc822', None]), ('mixed child without header', ('multipart/mixed', None), ['text/plain', 'us-ascii']), ('truncated type in digest', ('multipart/digest', 'text/'), ['message/rfc822', None]), ('missing major type', ('multipart/mixed', '/html; charset=utf-8'), ['text/plain', 'us-ascii']), ('quoted upper-case charset', ('multipart/mixed', 'Text/HTML; charset="Windows-1252"'), ['text/html', 'windows-1252']), ('charset on a binary type', ('multipart/mixed', 'image/png; charset=binary'), ['image/png', None]), ('padded header', ('multipart/alternative', ' text/plain ; charset=ISO-8859-2'), ['text/plain', 'iso-8859-2']), ('nested message parent', ('message/rfc822', None), ['text/plain', 'us-ascii'])], 3: [('digest child without header', ('multipart/digest', None), ['message/rfc822', None]), ('mixed child without header', ('multipart/mixed', None), ['text/plain', 'us-ascii']), ('truncated type in digest', ('multipart/digest', 'text/'), ['message/rfc822', None]), ('missing major type', ('multipart/mixed', '/html; charset=utf-8'), ['text/plain', 'us-ascii']), ('quoted upper-case charset', ('multipart/mixed', 'Text/HTML; charset="KOI8-R"'), ['text/html', 'koi8-r']), ('charset on a binary type', ('multipart/mixed', 'image/png; charset=binary'), ['image/png', None]), ('padded header', ('multipart/alternative', ' text/plain ; charset=ISO-8859-3'), ['text/plain', 'iso-8859-3']), ('nested message parent', ('message/rfc822', None), ['text/plain', 'us-ascii'])], 4: [('digest child without header', ('multipart/digest', None), ['message/rfc822', None]), ('mixed child without header', ('multipart/mixed', None), ['text/plain', 'us-ascii']), ('truncated type in digest', ('multipart/digest', 'text/'), ['message/rfc822', None]), ('missing major type', ('multipart/mixed', '/html; charset=utf-8'), ['text/plain', 'us-ascii']), ('quoted upper-case charset', ('multipart/mixed', 'Text/HTML; charset="Shift_JIS"'), ['text/html', 'shift_jis']), ('charset on a binary type', ('multipart/mixed', 'image/png; charset=binary'), ['image/png', None]), ('padded header', ('multipart/alternative', ' text/plain ; charset=ISO-8859-4'), ['text/plain', 'iso-8859-4']), ('nested message parent', ('message/rfc822', None), ['text/plain', 'us-ascii'])], 5: [('digest child without header', ('multipart/digest', None), ['message/rfc822', None]), ('mixed child without header', ('multipart/mixed', None), ['text/plain', 'us-ascii']), ('truncated type in digest', ('multipart/digest', 'text/'), ['message/rfc822', None]), ('missing major type', ('multipart/mixed', '/html; charset=utf-8'), ['text/plain', 'us-ascii']), ('quoted upper-case charset', ('multipart/mixed', 'Text/HTML; charset="EUC-KR"'), ['text/html', 'euc-kr']), ('charset on a binary type', ('multipart/mixed', 'image/png; charset=binary'), ['image/png', None]), ('padded header', ('multipart/alternative', ' text/plain ; charset=ISO-8859-5'), ['text/plain', 'iso-8859-5']), ('nested message parent', ('message/rfc822', None), ['text/plain', 'us-ascii'])]}
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(parent_type, header):
    default = 'message/rfc822' if parent_type == 'multipart/digest' else 'text/plain'
    mtype = default
    charset = None
    if header is not None:
        head, _, rest = header.partition(';')
        cand = head.strip().lower()
        major, slash, minor = cand.partition('/')
        if slash and major and minor and ' ' not in cand:
            mtype = cand
            for piece in rest.split(';'):
                k, eq, v = piece.partition('=')
                if eq and k.strip().lower() == 'charset':
                    charset = v.strip().strip('"').lower()
    if mtype.startswith('text/'):
        charset = charset or 'us-ascii'
    else:
        charset = None if charset == 'us-ascii' else charset
    return [mtype, charset]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('digest child without header', ('multipart/digest', None), ['message/rfc822', None]), ('mixed child without header', ('multipart/mixed', None), ['text/plain', 'us-ascii']), ('truncated type in digest', ('multipart/digest', 'text/'), ['message/rfc822', None]), ('missing major type', ('multipart/mixed', '/html; charset=utf-8'), ['text/plain', 'us-ascii']), ('quoted upper-case charset', ('multipart/mixed', 'Text/HTML; charset="UTF-8"'), ['text/html', 'utf-8']), ('charset on a binary type', ('multipart/mixed', 'image/png; charset=binary'), ['image/png', None]), ('padded header', ('multipart/alternative', ' text/plain ; charset=ISO-8859-1'), ['text/plain', 'iso-8859-1']), ('nested message parent', ('message/rfc822', None), ['text/plain', 'us-ascii'])], 2: [('digest child without header', ('multipart/digest', None), ['message/rfc822', None]), ('mixed child without header', ('multipart/mixed', None), ['text/plain', 'us-ascii']), ('truncated type in digest', ('multipart/digest', 'text/'), ['message/rfc822', None]), ('missing major type', ('multipart/mixed', '/html; charset=utf-8'), ['text/plain', 'us-ascii']), ('quoted upper-case charset', ('multipart/mixed', 'Text/HTML; charset="Windows-1252"'), ['text/html', 'windows-1252']), ('charset on a binary type', ('multipart/mixed', 'image/png; charset=binary'), ['image/png', None]), ('padded header', ('multipart/alternative', ' text/plain ; charset=ISO-8859-2'), ['text/plain', 'iso-8859-2']), ('nested message parent', ('message/rfc822', None), ['text/plain', 'us-ascii'])], 3: [('digest child without header', ('multipart/digest', None), ['message/rfc822', None]), ('mixed child without header', ('multipart/mixed', None), ['text/plain', 'us-ascii']), ('truncated type in digest', ('multipart/digest', 'text/'), ['message/rfc822', None]), ('missing major type', ('multipart/mixed', '/html; charset=utf-8'), ['text/plain', 'us-ascii']), ('quoted upper-case charset', ('multipart/mixed', 'Text/HTML; charset="KOI8-R"'), ['text/html', 'koi8-r']), ('charset on a binary type', ('multipart/mixed', 'image/png; charset=binary'), ['image/png', None]), ('padded header', ('multipart/alternative', ' text/plain ; charset=ISO-8859-3'), ['text/plain', 'iso-8859-3']), ('nested message parent', ('message/rfc822', None), ['text/plain', 'us-ascii'])], 4: [('digest child without header', ('multipart/digest', None), ['message/rfc822', None]), ('mixed child without header', ('multipart/mixed', None), ['text/plain', 'us-ascii']), ('truncated type in digest', ('multipart/digest', 'text/'), ['message/rfc822', None]), ('missing major type', ('multipart/mixed', '/html; charset=utf-8'), ['text/plain', 'us-ascii']), ('quoted upper-case charset', ('multipart/mixed', 'Text/HTML; charset="Shift_JIS"'), ['text/html', 'shift_jis']), ('charset on a binary type', ('multipart/mixed', 'image/png; charset=binary'), ['image/png', None]), ('padded header', ('multipart/alternative', ' text/plain ; charset=ISO-8859-4'), ['text/plain', 'iso-8859-4']), ('nested message parent', ('message/rfc822', None), ['text/plain', 'us-ascii'])], 5: [('digest child without header', ('multipart/digest', None), ['message/rfc822', None]), ('mixed child without header', ('multipart/mixed', None), ['text/plain', 'us-ascii']), ('truncated type in digest', ('multipart/digest', 'text/'), ['message/rfc822', None]), ('missing major type', ('multipart/mixed', '/html; charset=utf-8'), ['text/plain', 'us-ascii']), ('quoted upper-case charset', ('multipart/mixed', 'Text/HTML; charset="EUC-KR"'), ['text/html', 'euc-kr']), ('charset on a binary type', ('multipart/mixed', 'image/png; charset=binary'), ['image/png', None]), ('padded header', ('multipart/alternative', ' text/plain ; charset=ISO-8859-5'), ['text/plain', 'iso-8859-5']), ('nested message parent', ('message/rfc822', None), ['text/plain', 'us-ascii'])]}
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)

prompt:
Non-text parts report a charset taken from a meaningless parameter.

header is the raw Content-Type value or None. The type is the lower-cased text before ";" with surrounding spaces removed; it is valid only with a non-empty major and minor separated by "/" and no inner space. Missing or invalid types default to message/rfc822 inside multipart/digest and text/plain everywhere else (parameters of an invalid header are ignored). text/* types get the charset parameter (quotes removed, lower-cased) or us-ascii; other types have charset None. Result [type, charset].

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(parent_type, header):
    default = 'message/rfc822' if parent_type == 'multipart/digest' else 'text/plain'
    mtype = default
    charset = None
    if header is not None:
        head, _, rest = header.partition(';')
        cand = head.strip().lower()
        major, slash, minor = cand.partition('/')
        if slash and major and minor and ' ' not in cand:
            mtype = cand
            for piece in rest.split(';'):
                k, eq, v = piece.partition('=')
                if eq and k.strip().lower() == 'charset':
                    charset = v.strip().strip('"')
    if mtype.startswith('text/'):
        charset = charset or 'us-ascii'
    else:
        charset = None
    return [mtype, charset]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('digest child without header', ('multipart/digest', None), ['message/rfc822', None]), ('mixed child without header', ('multipart/mixed', None), ['text/plain', 'us-ascii']), ('truncated type in digest', ('multipart/digest', 'text/'), ['message/rfc822', None]), ('missing major type', ('multipart/mixed', '/html; charset=utf-8'), ['text/plain', 'us-ascii']), ('quoted upper-case charset', ('multipart/mixed', 'Text/HTML; charset="UTF-8"'), ['text/html', 'utf-8']), ('charset on a binary type', ('multipart/mixed', 'image/png; charset=binary'), ['image/png', None]), ('padded header', ('multipart/alternative', ' text/plain ; charset=ISO-8859-1'), ['text/plain', 'iso-8859-1']), ('nested message parent', ('message/rfc822', None), ['text/plain', 'us-ascii'])], 2: [('digest child without header', ('multipart/digest', None), ['message/rfc822', None]), ('mixed child without header', ('multipart/mixed', None), ['text/plain', 'us-ascii']), ('truncated type in digest', ('multipart/digest', 'text/'), ['message/rfc822', None]), ('missing major type', ('multipart/mixed', '/html; charset=utf-8'), ['text/plain', 'us-ascii']), ('quoted upper-case charset', ('multipart/mixed', 'Text/HTML; charset="Windows-1252"'), ['text/html', 'windows-1252']), ('charset on a binary type', ('multipart/mixed', 'image/png; charset=binary'), ['image/png', None]), ('padded header', ('multipart/alternative', ' text/plain ; charset=ISO-8859-2'), ['text/plain', 'iso-8859-2']), ('nested message parent', ('message/rfc822', None), ['text/plain', 'us-ascii'])], 3: [('digest child without header', ('multipart/digest', None), ['message/rfc822', None]), ('mixed child without header', ('multipart/mixed', None), ['text/plain', 'us-ascii']), ('truncated type in digest', ('multipart/digest', 'text/'), ['message/rfc822', None]), ('missing major type', ('multipart/mixed', '/html; charset=utf-8'), ['text/plain', 'us-ascii']), ('quoted upper-case charset', ('multipart/mixed', 'Text/HTML; charset="KOI8-R"'), ['text/html', 'koi8-r']), ('charset on a binary type', ('multipart/mixed', 'image/png; charset=binary'), ['image/png', None]), ('padded header', ('multipart/alternative', ' text/plain ; charset=ISO-8859-3'), ['text/plain', 'iso-8859-3']), ('nested message parent', ('message/rfc822', None), ['text/plain', 'us-ascii'])], 4: [('digest child without header', ('multipart/digest', None), ['message/rfc822', None]), ('mixed child without header', ('multipart/mixed', None), ['text/plain', 'us-ascii']), ('truncated type in digest', ('multipart/digest', 'text/'), ['message/rfc822', None]), ('missing major type', ('multipart/mixed', '/html; charset=utf-8'), ['text/plain', 'us-ascii']), ('quoted upper-case charset', ('multipart/mixed', 'Text/HTML; charset="Shift_JIS"'), ['text/html', 'shift_jis']), ('charset on a binary type', ('multipart/mixed', 'image/png; charset=binary'), ['image/png', None]), ('padded header', ('multipart/alternative', ' text/plain ; charset=ISO-8859-4'), ['text/plain', 'iso-8859-4']), ('nested message parent', ('message/rfc822', None), ['text/plain', 'us-ascii'])], 5: [('digest child without header', ('multipart/digest', None), ['message/rfc822', None]), ('mixed child without header', ('multipart/mixed', None), ['text/plain', 'us-ascii']), ('truncated type in digest', ('multipart/digest', 'text/'), ['message/rfc822', None]), ('missing major type', ('multipart/mixed', '/html; charset=utf-8'), ['text/plain', 'us-ascii']), ('quoted upper-case charset', ('multipart/mixed', 'Text/HTML; charset="EUC-KR"'), ['text/html', 'euc-kr']), ('charset on a binary type', ('multipart/mixed', 'image/png; charset=binary'), ['image/png', None]), ('padded header', ('multipart/alternative', ' text/plain ; charset=ISO-8859-5'), ['text/plain', 'iso-8859-5']), ('nested message parent', ('message/rfc822', None), ['text/plain', 'us-ascii'])]}
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)

meaning: Fixture-count band, not measured model difficulty

deps: stdlib

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(parent_type, header):
    default = 'message/rfc822' if parent_type == 'multipart/digest' else 'text/plain'
    mtype = default
    charset = None
    if header is not None:
        head, _, rest = header.partition(';')
        cand = head.strip().lower()
        major, slash, minor = cand.partition('/')
        if slash and major and minor and ' ' not in cand:
            mtype = cand
            for piece in rest.split(';'):
                k, eq, v = piece.partition('=')
                if eq and k.strip().lower() == 'charset':
                    charset = v.strip().lower()
    if mtype.startswith('text/'):
        charset = charset or 'us-ascii'
    else:
        charset = None
    return [mtype, charset]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('digest child without header', ('multipart/digest', None), ['message/rfc822', None]), ('mixed child without header', ('multipart/mixed', None), ['text/plain', 'us-ascii']), ('truncated type in digest', ('multipart/digest', 'text/'), ['message/rfc822', None]), ('missing major type', ('multipart/mixed', '/html; charset=utf-8'), ['text/plain', 'us-ascii']), ('quoted upper-case charset', ('multipart/mixed', 'Text/HTML; charset="UTF-8"'), ['text/html', 'utf-8']), ('charset on a binary type', ('multipart/mixed', 'image/png; charset=binary'), ['image/png', None]), ('padded header', ('multipart/alternative', ' text/plain ; charset=ISO-8859-1'), ['text/plain', 'iso-8859-1']), ('nested message parent', ('message/rfc822', None), ['text/plain', 'us-ascii'])], 2: [('digest child without header', ('multipart/digest', None), ['message/rfc822', None]), ('mixed child without header', ('multipart/mixed', None), ['text/plain', 'us-ascii']), ('truncated type in digest', ('multipart/digest', 'text/'), ['message/rfc822', None]), ('missing major type', ('multipart/mixed', '/html; charset=utf-8'), ['text/plain', 'us-ascii']), ('quoted upper-case charset', ('multipart/mixed', 'Text/HTML; charset="Windows-1252"'), ['text/html', 'windows-1252']), ('charset on a binary type', ('multipart/mixed', 'image/png; charset=binary'), ['image/png', None]), ('padded header', ('multipart/alternative', ' text/plain ; charset=ISO-8859-2'), ['text/plain', 'iso-8859-2']), ('nested message parent', ('message/rfc822', None), ['text/plain', 'us-ascii'])], 3: [('digest child without header', ('multipart/digest', None), ['message/rfc822', None]), ('mixed child without header', ('multipart/mixed', None), ['text/plain', 'us-ascii']), ('truncated type in digest', ('multipart/digest', 'text/'), ['message/rfc822', None]), ('missing major type', ('multipart/mixed', '/html; charset=utf-8'), ['text/plain', 'us-ascii']), ('quoted upper-case charset', ('multipart/mixed', 'Text/HTML; charset="KOI8-R"'), ['text/html', 'koi8-r']), ('charset on a binary type', ('multipart/mixed', 'image/png; charset=binary'), ['image/png', None]), ('padded header', ('multipart/alternative', ' text/plain ; charset=ISO-8859-3'), ['text/plain', 'iso-8859-3']), ('nested message parent', ('message/rfc822', None), ['text/plain', 'us-ascii'])], 4: [('digest child without header', ('multipart/digest', None), ['message/rfc822', None]), ('mixed child without header', ('multipart/mixed', None), ['text/plain', 'us-ascii']), ('truncated type in digest', ('multipart/digest', 'text/'), ['message/rfc822', None]), ('missing major type', ('multipart/mixed', '/html; charset=utf-8'), ['text/plain', 'us-ascii']), ('quoted upper-case charset', ('multipart/mixed', 'Text/HTML; charset="Shift_JIS"'), ['text/html', 'shift_jis']), ('charset on a binary type', ('multipart/mixed', 'image/png; charset=binary'), ['image/png', None]), ('padded header', ('multipart/alternative', ' text/plain ; charset=ISO-8859-4'), ['text/plain', 'iso-8859-4']), ('nested message parent', ('message/rfc822', None), ['text/plain', 'us-ascii'])], 5: [('digest child without header', ('multipart/digest', None), ['message/rfc822', None]), ('mixed child without header', ('multipart/mixed', None), ['text/plain', 'us-ascii']), ('truncated type in digest', ('multipart/digest', 'text/'), ['message/rfc822', None]), ('missing major type', ('multipart/mixed', '/html; charset=utf-8'), ['text/plain', 'us-ascii']), ('quoted upper-case charset', ('multipart/mixed', 'Text/HTML; charset="EUC-KR"'), ['text/html', 'euc-kr']), ('charset on a binary type', ('multipart/mixed', 'image/png; charset=binary'), ['image/png', None]), ('padded header', ('multipart/alternative', ' text/plain ; charset=ISO-8859-5'), ['text/plain', 'iso-8859-5']), ('nested message parent', ('message/rfc822', None), ['text/plain', 'us-ascii'])]}
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)

prompt:
Charset names keep their original casing, so "UTF-8" and "utf-8" are treated as different charsets.

header is the raw Content-Type value or None. The type is the lower-cased text before ";" with surrounding spaces removed; it is valid only with a non-empty major and minor separated by "/" and no inner space. Missing or invalid types default to message/rfc822 inside multipart/digest and text/plain everywhere else (parameters of an invalid header are ignored). text/* types get the charset parameter (quotes removed, lower-cased) or us-ascii; other types have charset None. Result [type, charset].

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(parent_type, header):
    default = 'message/rfc822' if parent_type == 'multipart/digest' else 'text/plain'
    mtype = default
    charset = None
    if header is not None:
        head, _, rest = header.partition(';')
        cand = head.strip()
        major, slash, minor = cand.partition('/')
        if slash and major and minor and ' ' not in cand:
            mtype = cand
            for piece in rest.split(';'):
                k, eq, v = piece.partition('=')
                if eq and k.strip().lower() == 'charset':
                    charset = v.strip().strip('"').lower()
    if mtype.startswith('text/'):
        charset = charset or 'us-ascii'
    else:
        charset = None
    return [mtype, charset]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('digest child without header', ('multipart/digest', None), ['message/rfc822', None]), ('mixed child without header', ('multipart/mixed', None), ['text/plain', 'us-ascii']), ('truncated type in digest', ('multipart/digest', 'text/'), ['message/rfc822', None]), ('missing major type', ('multipart/mixed', '/html; charset=utf-8'), ['text/plain', 'us-ascii']), ('quoted upper-case charset', ('multipart/mixed', 'Text/HTML; charset="UTF-8"'), ['text/html', 'utf-8']), ('charset on a binary type', ('multipart/mixed', 'image/png; charset=binary'), ['image/png', None]), ('padded header', ('multipart/alternative', ' text/plain ; charset=ISO-8859-1'), ['text/plain', 'iso-8859-1']), ('nested message parent', ('message/rfc822', None), ['text/plain', 'us-ascii'])], 2: [('digest child without header', ('multipart/digest', None), ['message/rfc822', None]), ('mixed child without header', ('multipart/mixed', None), ['text/plain', 'us-ascii']), ('truncated type in digest', ('multipart/digest', 'text/'), ['message/rfc822', None]), ('missing major type', ('multipart/mixed', '/html; charset=utf-8'), ['text/plain', 'us-ascii']), ('quoted upper-case charset', ('multipart/mixed', 'Text/HTML; charset="Windows-1252"'), ['text/html', 'windows-1252']), ('charset on a binary type', ('multipart/mixed', 'image/png; charset=binary'), ['image/png', None]), ('padded header', ('multipart/alternative', ' text/plain ; charset=ISO-8859-2'), ['text/plain', 'iso-8859-2']), ('nested message parent', ('message/rfc822', None), ['text/plain', 'us-ascii'])], 3: [('digest child without header', ('multipart/digest', None), ['message/rfc822', None]), ('mixed child without header', ('multipart/mixed', None), ['text/plain', 'us-ascii']), ('truncated type in digest', ('multipart/digest', 'text/'), ['message/rfc822', None]), ('missing major type', ('multipart/mixed', '/html; charset=utf-8'), ['text/plain', 'us-ascii']), ('quoted upper-case charset', ('multipart/mixed', 'Text/HTML; charset="KOI8-R"'), ['text/html', 'koi8-r']), ('charset on a binary type', ('multipart/mixed', 'image/png; charset=binary'), ['image/png', None]), ('padded header', ('multipart/alternative', ' text/plain ; charset=ISO-8859-3'), ['text/plain', 'iso-8859-3']), ('nested message parent', ('message/rfc822', None), ['text/plain', 'us-ascii'])], 4: [('digest child without header', ('multipart/digest', None), ['message/rfc822', None]), ('mixed child without header', ('multipart/mixed', None), ['text/plain', 'us-ascii']), ('truncated type in digest', ('multipart/digest', 'text/'), ['message/rfc822', None]), ('missing major type', ('multipart/mixed', '/html; charset=utf-8'), ['text/plain', 'us-ascii']), ('quoted upper-case charset', ('multipart/mixed', 'Text/HTML; charset="Shift_JIS"'), ['text/html', 'shift_jis']), ('charset on a binary type', ('multipart/mixed', 'image/png; charset=binary'), ['image/png', None]), ('padded header', ('multipart/alternative', ' text/plain ; charset=ISO-8859-4'), ['text/plain', 'iso-8859-4']), ('nested message parent', ('message/rfc822', None), ['text/plain', 'us-ascii'])], 5: [('digest child without header', ('multipart/digest', None), ['message/rfc822', None]), ('mixed child without header', ('multipart/mixed', None), ['text/plain', 'us-ascii']), ('truncated type in digest', ('multipart/digest', 'text/'), ['message/rfc822', None]), ('missing major type', ('multipart/mixed', '/html; charset=utf-8'), ['text/plain', 'us-ascii']), ('quoted upper-case charset', ('multipart/mixed', 'Text/HTML; charset="EUC-KR"'), ['text/html', 'euc-kr']), ('charset on a binary type', ('multipart/mixed', 'image/png; charset=binary'), ['image/png', None]), ('padded header', ('multipart/alternative', ' text/plain ; charset=ISO-8859-5'), ['text/plain', 'iso-8859-5']), ('nested message parent', ('message/rfc822', None), ['text/plain', 'us-ascii'])]}
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(parent_type, header):
    default = 'message/rfc822' if parent_type == 'multipart/digest' else 'text/plain'
    mtype = default
    charset = None
    if header is not None:
        head, _, rest = header.partition(';')
        cand = head.lower()
        major, slash, minor = cand.partition('/')
        if slash and major and minor and ' ' not in cand:
            mtype = cand
            for piece in rest.split(';'):
                k, eq, v = piece.partition('=')
                if eq and k.strip().lower() == 'charset':
                    charset = v.strip().strip('"').lower()
    if mtype.startswith('text/'):
        charset = charset or 'us-ascii'
    else:
        charset = None
    return [mtype, charset]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('digest child without header', ('multipart/digest', None), ['message/rfc822', None]), ('mixed child without header', ('multipart/mixed', None), ['text/plain', 'us-ascii']), ('truncated type in digest', ('multipart/digest', 'text/'), ['message/rfc822', None]), ('missing major type', ('multipart/mixed', '/html; charset=utf-8'), ['text/plain', 'us-ascii']), ('quoted upper-case charset', ('multipart/mixed', 'Text/HTML; charset="UTF-8"'), ['text/html', 'utf-8']), ('charset on a binary type', ('multipart/mixed', 'image/png; charset=binary'), ['image/png', None]), ('padded header', ('multipart/alternative', ' text/plain ; charset=ISO-8859-1'), ['text/plain', 'iso-8859-1']), ('nested message parent', ('message/rfc822', None), ['text/plain', 'us-ascii'])], 2: [('digest child without header', ('multipart/digest', None), ['message/rfc822', None]), ('mixed child without header', ('multipart/mixed', None), ['text/plain', 'us-ascii']), ('truncated type in digest', ('multipart/digest', 'text/'), ['message/rfc822', None]), ('missing major type', ('multipart/mixed', '/html; charset=utf-8'), ['text/plain', 'us-ascii']), ('quoted upper-case charset', ('multipart/mixed', 'Text/HTML; charset="Windows-1252"'), ['text/html', 'windows-1252']), ('charset on a binary type', ('multipart/mixed', 'image/png; charset=binary'), ['image/png', None]), ('padded header', ('multipart/alternative', ' text/plain ; charset=ISO-8859-2'), ['text/plain', 'iso-8859-2']), ('nested message parent', ('message/rfc822', None), ['text/plain', 'us-ascii'])], 3: [('digest child without header', ('multipart/digest', None), ['message/rfc822', None]), ('mixed child without header', ('multipart/mixed', None), ['text/plain', 'us-ascii']), ('truncated type in digest', ('multipart/digest', 'text/'), ['message/rfc822', None]), ('missing major type', ('multipart/mixed', '/html; charset=utf-8'), ['text/plain', 'us-ascii']), ('quoted upper-case charset', ('multipart/mixed', 'Text/HTML; charset="KOI8-R"'), ['text/html', 'koi8-r']), ('charset on a binary type', ('multipart/mixed', 'image/png; charset=binary'), ['image/png', None]), ('padded header', ('multipart/alternative', ' text/plain ; charset=ISO-8859-3'), ['text/plain', 'iso-8859-3']), ('nested message parent', ('message/rfc822', None), ['text/plain', 'us-ascii'])], 4: [('digest child without header', ('multipart/digest', None), ['message/rfc822', None]), ('mixed child without header', ('multipart/mixed', None), ['text/plain', 'us-ascii']), ('truncated type in digest', ('multipart/digest', 'text/'), ['message/rfc822', None]), ('missing major type', ('multipart/mixed', '/html; charset=utf-8'), ['text/plain', 'us-ascii']), ('quoted upper-case charset', ('multipart/mixed', 'Text/HTML; charset="Shift_JIS"'), ['text/html', 'shift_jis']), ('charset on a binary type', ('multipart/mixed', 'image/png; charset=binary'), ['image/png', None]), ('padded header', ('multipart/alternative', ' text/plain ; charset=ISO-8859-4'), ['text/plain', 'iso-8859-4']), ('nested message parent', ('message/rfc822', None), ['text/plain', 'us-ascii'])], 5: [('digest child without header', ('multipart/digest', None), ['message/rfc822', None]), ('mixed child without header', ('multipart/mixed', None), ['text/plain', 'us-ascii']), ('truncated type in digest', ('multipart/digest', 'text/'), ['message/rfc822', None]), ('missing major type', ('multipart/mixed', '/html; charset=utf-8'), ['text/plain', 'us-ascii']), ('quoted upper-case charset', ('multipart/mixed', 'Text/HTML; charset="EUC-KR"'), ['text/html', 'euc-kr']), ('charset on a binary type', ('multipart/mixed', 'image/png; charset=binary'), ['image/png', None]), ('padded header', ('multipart/alternative', ' text/plain ; charset=ISO-8859-5'), ['text/plain', 'iso-8859-5']), ('nested message parent', ('message/rfc822', None), ['text/plain', 'us-ascii'])]}
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)

prompt:
A mixed-case type such as Text/HTML is not recognised as text.

header is the raw Content-Type value or None. The type is the lower-cased text before ";" with surrounding spaces removed; it is valid only with a non-empty major and minor separated by "/" and no inner space. Missing or invalid types default to message/rfc822 inside multipart/digest and text/plain everywhere else (parameters of an invalid header are ignored). text/* types get the charset parameter (quotes removed, lower-cased) or us-ascii; other types have charset None. Result [type, charset].

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(parts, html_cids):
    out = []
    have_body = False
    for p in parts:
        disp = (p.get('disp') or '').lower()
        if disp == 'attachment' and p.get('cid') not in html_cids:
            kind = 'attachment'
        elif p.get('cid') and p['cid'] in html_cids:
            kind = 'inline'
        elif p['type'].startswith('text/') and not p.get('filename') and not have_body:
            kind = 'body'
            have_body = True
        elif disp == 'inline' and p['type'].startswith('image/'):
            kind = 'inline'
        else:
            kind = 'attachment'
        out.append(kind)
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('referenced image marked attachment', ([{'type': 'text/plain'}, {'type': 'image/png', 'cid': 'logo1@x', 'disp': 'attachment'}], ['logo1@x']), ['body', 'attachment']), ('upper-case disposition', ([{'type': 'text/plain', 'disp': 'ATTACHMENT'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('second text part', ([{'type': 'text/plain'}, {'type': 'text/plain'}], []), ['body', 'attachment']), ('attachment precedes body', ([{'type': 'application/pdf', 'disp': 'attachment'}, {'type': 'text/plain'}, {'type': 'text/plain'}], []), ['attachment', 'body', 'attachment']), ('named text part', ([{'type': 'text/plain', 'filename': 'notes1.txt'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('empty filename', ([{'type': 'text/plain', 'filename': ''}], []), ['body']), ('inline non-images', ([{'type': 'text/html'}, {'type': 'application/pdf', 'disp': 'inline'}, {'type': 'audio/ogg', 'disp': 'inline'}, {'type': 'image/gif', 'disp': 'inline'}], []), ['body', 'attachment', 'attachment', 'inline']), ('cid substring', ([{'type': 'text/html'}, {'type': 'image/png', 'cid': 'a1@x'}, {'type': 'image/png', 'cid': 'ba1@x'}], ['a1@x']), ['body', 'inline', 'attachment'])], 2: [('referenced image marked attachment', ([{'type': 'text/plain'}, {'type': 'image/png', 'cid': 'logo2@x', 'disp': 'attachment'}], ['logo2@x']), ['body', 'attachment']), ('upper-case disposition', ([{'type': 'text/plain', 'disp': 'ATTACHMENT'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('second text part', ([{'type': 'text/plain'}, {'type': 'text/plain'}], []), ['body', 'attachment']), ('attachment precedes body', ([{'type': 'application/pdf', 'disp': 'attachment'}, {'type': 'text/plain'}, {'type': 'text/plain'}], []), ['attachment', 'body', 'attachment']), ('named text part', ([{'type': 'text/plain', 'filename': 'notes2.txt'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('empty filename', ([{'type': 'text/plain', 'filename': ''}], []), ['body']), ('inline non-images', ([{'type': 'text/html'}, {'type': 'application/pdf', 'disp': 'inline'}, {'type': 'audio/ogg', 'disp': 'inline'}, {'type': 'image/gif', 'disp': 'inline'}], []), ['body', 'attachment', 'attachment', 'inline']), ('cid substring', ([{'type': 'text/html'}, {'type': 'image/png', 'cid': 'a2@x'}, {'type': 'image/png', 'cid': 'ba2@x'}], ['a2@x']), ['body', 'inline', 'attachment'])], 3: [('referenced image marked attachment', ([{'type': 'text/plain'}, {'type': 'image/png', 'cid': 'logo3@x', 'disp': 'attachment'}], ['logo3@x']), ['body', 'attachment']), ('upper-case disposition', ([{'type': 'text/plain', 'disp': 'ATTACHMENT'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('second text part', ([{'type': 'text/plain'}, {'type': 'text/plain'}], []), ['body', 'attachment']), ('attachment precedes body', ([{'type': 'application/pdf', 'disp': 'attachment'}, {'type': 'text/plain'}, {'type': 'text/plain'}], []), ['attachment', 'body', 'attachment']), ('named text part', ([{'type': 'text/plain', 'filename': 'notes3.txt'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('empty filename', ([{'type': 'text/plain', 'filename': ''}], []), ['body']), ('inline non-images', ([{'type': 'text/html'}, {'type': 'application/pdf', 'disp': 'inline'}, {'type': 'audio/ogg', 'disp': 'inline'}, {'type': 'image/gif', 'disp': 'inline'}], []), ['body', 'attachment', 'attachment', 'inline']), ('cid substring', ([{'type': 'text/html'}, {'type': 'image/png', 'cid': 'a3@x'}, {'type': 'image/png', 'cid': 'ba3@x'}], ['a3@x']), ['body', 'inline', 'attachment'])], 4: [('referenced image marked attachment', ([{'type': 'text/plain'}, {'type': 'image/png', 'cid': 'logo4@x', 'disp': 'attachment'}], ['logo4@x']), ['body', 'attachment']), ('upper-case disposition', ([{'type': 'text/plain', 'disp': 'ATTACHMENT'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('second text part', ([{'type': 'text/plain'}, {'type': 'text/plain'}], []), ['body', 'attachment']), ('attachment precedes body', ([{'type': 'application/pdf', 'disp': 'attachment'}, {'type': 'text/plain'}, {'type': 'text/plain'}], []), ['attachment', 'body', 'attachment']), ('named text part', ([{'type': 'text/plain', 'filename': 'notes4.txt'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('empty filename', ([{'type': 'text/plain', 'filename': ''}], []), ['body']), ('inline non-images', ([{'type': 'text/html'}, {'type': 'application/pdf', 'disp': 'inline'}, {'type': 'audio/ogg', 'disp': 'inline'}, {'type': 'image/gif', 'disp': 'inline'}], []), ['body', 'attachment', 'attachment', 'inline']), ('cid substring', ([{'type': 'text/html'}, {'type': 'image/png', 'cid': 'a4@x'}, {'type': 'image/png', 'cid': 'ba4@x'}], ['a4@x']), ['body', 'inline', 'attachment'])], 5: [('referenced image marked attachment', ([{'type': 'text/plain'}, {'type': 'image/png', 'cid': 'logo5@x', 'disp': 'attachment'}], ['logo5@x']), ['body', 'attachment']), ('upper-case disposition', ([{'type': 'text/plain', 'disp': 'ATTACHMENT'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('second text part', ([{'type': 'text/plain'}, {'type': 'text/plain'}], []), ['body', 'attachment']), ('attachment precedes body', ([{'type': 'application/pdf', 'disp': 'attachment'}, {'type': 'text/plain'}, {'type': 'text/plain'}], []), ['attachment', 'body', 'attachment']), ('named text part', ([{'type': 'text/plain', 'filename': 'notes5.txt'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('empty filename', ([{'type': 'text/plain', 'filename': ''}], []), ['body']), ('inline non-images', ([{'type': 'text/html'}, {'type': 'application/pdf', 'disp': 'inline'}, {'type': 'audio/ogg', 'disp': 'inline'}, {'type': 'image/gif', 'disp': 'inline'}], []), ['body', 'attachment', 'attachment', 'inline']), ('cid substring', ([{'type': 'text/html'}, {'type': 'image/png', 'cid': 'a5@x'}, {'type': 'image/png', 'cid': 'ba5@x'}], ['a5@x']), ['body', 'inline', 'attachment'])]}
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(parts, html_cids):
    out = []
    have_body = False
    for p in parts:
        disp = (p.get('disp') or '').lower()
        if disp == 'attachment' and not p['type'].startswith('image/'):
            kind = 'attachment'
        elif p.get('cid') and p['cid'] in html_cids:
            kind = 'inline'
        elif p['type'].startswith('text/') and not p.get('filename') and not have_body:
            kind = 'body'
            have_body = True
        elif disp == 'inline' and p['type'].startswith('image/'):
            kind = 'inline'
        else:
            kind = 'attachment'
        out.append(kind)
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('referenced image marked attachment', ([{'type': 'text/plain'}, {'type': 'image/png', 'cid': 'logo1@x', 'disp': 'attachment'}], ['logo1@x']), ['body', 'attachment']), ('upper-case disposition', ([{'type': 'text/plain', 'disp': 'ATTACHMENT'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('second text part', ([{'type': 'text/plain'}, {'type': 'text/plain'}], []), ['body', 'attachment']), ('attachment precedes body', ([{'type': 'application/pdf', 'disp': 'attachment'}, {'type': 'text/plain'}, {'type': 'text/plain'}], []), ['attachment', 'body', 'attachment']), ('named text part', ([{'type': 'text/plain', 'filename': 'notes1.txt'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('empty filename', ([{'type': 'text/plain', 'filename': ''}], []), ['body']), ('inline non-images', ([{'type': 'text/html'}, {'type': 'application/pdf', 'disp': 'inline'}, {'type': 'audio/ogg', 'disp': 'inline'}, {'type': 'image/gif', 'disp': 'inline'}], []), ['body', 'attachment', 'attachment', 'inline']), ('cid substring', ([{'type': 'text/html'}, {'type': 'image/png', 'cid': 'a1@x'}, {'type': 'image/png', 'cid': 'ba1@x'}], ['a1@x']), ['body', 'inline', 'attachment'])], 2: [('referenced image marked attachment', ([{'type': 'text/plain'}, {'type': 'image/png', 'cid': 'logo2@x', 'disp': 'attachment'}], ['logo2@x']), ['body', 'attachment']), ('upper-case disposition', ([{'type': 'text/plain', 'disp': 'ATTACHMENT'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('second text part', ([{'type': 'text/plain'}, {'type': 'text/plain'}], []), ['body', 'attachment']), ('attachment precedes body', ([{'type': 'application/pdf', 'disp': 'attachment'}, {'type': 'text/plain'}, {'type': 'text/plain'}], []), ['attachment', 'body', 'attachment']), ('named text part', ([{'type': 'text/plain', 'filename': 'notes2.txt'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('empty filename', ([{'type': 'text/plain', 'filename': ''}], []), ['body']), ('inline non-images', ([{'type': 'text/html'}, {'type': 'application/pdf', 'disp': 'inline'}, {'type': 'audio/ogg', 'disp': 'inline'}, {'type': 'image/gif', 'disp': 'inline'}], []), ['body', 'attachment', 'attachment', 'inline']), ('cid substring', ([{'type': 'text/html'}, {'type': 'image/png', 'cid': 'a2@x'}, {'type': 'image/png', 'cid': 'ba2@x'}], ['a2@x']), ['body', 'inline', 'attachment'])], 3: [('referenced image marked attachment', ([{'type': 'text/plain'}, {'type': 'image/png', 'cid': 'logo3@x', 'disp': 'attachment'}], ['logo3@x']), ['body', 'attachment']), ('upper-case disposition', ([{'type': 'text/plain', 'disp': 'ATTACHMENT'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('second text part', ([{'type': 'text/plain'}, {'type': 'text/plain'}], []), ['body', 'attachment']), ('attachment precedes body', ([{'type': 'application/pdf', 'disp': 'attachment'}, {'type': 'text/plain'}, {'type': 'text/plain'}], []), ['attachment', 'body', 'attachment']), ('named text part', ([{'type': 'text/plain', 'filename': 'notes3.txt'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('empty filename', ([{'type': 'text/plain', 'filename': ''}], []), ['body']), ('inline non-images', ([{'type': 'text/html'}, {'type': 'application/pdf', 'disp': 'inline'}, {'type': 'audio/ogg', 'disp': 'inline'}, {'type': 'image/gif', 'disp': 'inline'}], []), ['body', 'attachment', 'attachment', 'inline']), ('cid substring', ([{'type': 'text/html'}, {'type': 'image/png', 'cid': 'a3@x'}, {'type': 'image/png', 'cid': 'ba3@x'}], ['a3@x']), ['body', 'inline', 'attachment'])], 4: [('referenced image marked attachment', ([{'type': 'text/plain'}, {'type': 'image/png', 'cid': 'logo4@x', 'disp': 'attachment'}], ['logo4@x']), ['body', 'attachment']), ('upper-case disposition', ([{'type': 'text/plain', 'disp': 'ATTACHMENT'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('second text part', ([{'type': 'text/plain'}, {'type': 'text/plain'}], []), ['body', 'attachment']), ('attachment precedes body', ([{'type': 'application/pdf', 'disp': 'attachment'}, {'type': 'text/plain'}, {'type': 'text/plain'}], []), ['attachment', 'body', 'attachment']), ('named text part', ([{'type': 'text/plain', 'filename': 'notes4.txt'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('empty filename', ([{'type': 'text/plain', 'filename': ''}], []), ['body']), ('inline non-images', ([{'type': 'text/html'}, {'type': 'application/pdf', 'disp': 'inline'}, {'type': 'audio/ogg', 'disp': 'inline'}, {'type': 'image/gif', 'disp': 'inline'}], []), ['body', 'attachment', 'attachment', 'inline']), ('cid substring', ([{'type': 'text/html'}, {'type': 'image/png', 'cid': 'a4@x'}, {'type': 'image/png', 'cid': 'ba4@x'}], ['a4@x']), ['body', 'inline', 'attachment'])], 5: [('referenced image marked attachment', ([{'type': 'text/plain'}, {'type': 'image/png', 'cid': 'logo5@x', 'disp': 'attachment'}], ['logo5@x']), ['body', 'attachment']), ('upper-case disposition', ([{'type': 'text/plain', 'disp': 'ATTACHMENT'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('second text part', ([{'type': 'text/plain'}, {'type': 'text/plain'}], []), ['body', 'attachment']), ('attachment precedes body', ([{'type': 'application/pdf', 'disp': 'attachment'}, {'type': 'text/plain'}, {'type': 'text/plain'}], []), ['attachment', 'body', 'attachment']), ('named text part', ([{'type': 'text/plain', 'filename': 'notes5.txt'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('empty filename', ([{'type': 'text/plain', 'filename': ''}], []), ['body']), ('inline non-images', ([{'type': 'text/html'}, {'type': 'application/pdf', 'disp': 'inline'}, {'type': 'audio/ogg', 'disp': 'inline'}, {'type': 'image/gif', 'disp': 'inline'}], []), ['body', 'attachment', 'attachment', 'inline']), ('cid substring', ([{'type': 'text/html'}, {'type': 'image/png', 'cid': 'a5@x'}, {'type': 'image/png', 'cid': 'ba5@x'}], ['a5@x']), ['body', 'inline', 'attachment'])]}
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)

prompt:
An image the sender explicitly attached disappears into the body because the HTML happens to reference it.

parts are the leaves of a multipart/mixed message in order: {type, disp, cid, filename}. Rules in order: an explicit "attachment" disposition (case-insensitive) is an attachment even when referenced; a part whose cid is exactly one of html_cids is inline; the first text/* part without a (non-empty) filename is the body; an explicit inline image/* is inline; everything else is an attachment.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(parts, html_cids):
    out = []
    have_body = False
    for p in parts:
        disp = p.get('disp') or ''
        if disp == 'attachment':
            kind = 'attachment'
        elif p.get('cid') and p['cid'] in html_cids:
            kind = 'inline'
        elif p['type'].startswith('text/') and not p.get('filename') and not have_body:
            kind = 'body'
            have_body = True
        elif disp == 'inline' and p['type'].startswith('image/'):
            kind = 'inline'
        else:
            kind = 'attachment'
        out.append(kind)
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('referenced image marked attachment', ([{'type': 'text/plain'}, {'type': 'image/png', 'cid': 'logo1@x', 'disp': 'attachment'}], ['logo1@x']), ['body', 'attachment']), ('upper-case disposition', ([{'type': 'text/plain', 'disp': 'ATTACHMENT'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('second text part', ([{'type': 'text/plain'}, {'type': 'text/plain'}], []), ['body', 'attachment']), ('attachment precedes body', ([{'type': 'application/pdf', 'disp': 'attachment'}, {'type': 'text/plain'}, {'type': 'text/plain'}], []), ['attachment', 'body', 'attachment']), ('named text part', ([{'type': 'text/plain', 'filename': 'notes1.txt'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('empty filename', ([{'type': 'text/plain', 'filename': ''}], []), ['body']), ('inline non-images', ([{'type': 'text/html'}, {'type': 'application/pdf', 'disp': 'inline'}, {'type': 'audio/ogg', 'disp': 'inline'}, {'type': 'image/gif', 'disp': 'inline'}], []), ['body', 'attachment', 'attachment', 'inline']), ('cid substring', ([{'type': 'text/html'}, {'type': 'image/png', 'cid': 'a1@x'}, {'type': 'image/png', 'cid': 'ba1@x'}], ['a1@x']), ['body', 'inline', 'attachment'])], 2: [('referenced image marked attachment', ([{'type': 'text/plain'}, {'type': 'image/png', 'cid': 'logo2@x', 'disp': 'attachment'}], ['logo2@x']), ['body', 'attachment']), ('upper-case disposition', ([{'type': 'text/plain', 'disp': 'ATTACHMENT'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('second text part', ([{'type': 'text/plain'}, {'type': 'text/plain'}], []), ['body', 'attachment']), ('attachment precedes body', ([{'type': 'application/pdf', 'disp': 'attachment'}, {'type': 'text/plain'}, {'type': 'text/plain'}], []), ['attachment', 'body', 'attachment']), ('named text part', ([{'type': 'text/plain', 'filename': 'notes2.txt'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('empty filename', ([{'type': 'text/plain', 'filename': ''}], []), ['body']), ('inline non-images', ([{'type': 'text/html'}, {'type': 'application/pdf', 'disp': 'inline'}, {'type': 'audio/ogg', 'disp': 'inline'}, {'type': 'image/gif', 'disp': 'inline'}], []), ['body', 'attachment', 'attachment', 'inline']), ('cid substring', ([{'type': 'text/html'}, {'type': 'image/png', 'cid': 'a2@x'}, {'type': 'image/png', 'cid': 'ba2@x'}], ['a2@x']), ['body', 'inline', 'attachment'])], 3: [('referenced image marked attachment', ([{'type': 'text/plain'}, {'type': 'image/png', 'cid': 'logo3@x', 'disp': 'attachment'}], ['logo3@x']), ['body', 'attachment']), ('upper-case disposition', ([{'type': 'text/plain', 'disp': 'ATTACHMENT'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('second text part', ([{'type': 'text/plain'}, {'type': 'text/plain'}], []), ['body', 'attachment']), ('attachment precedes body', ([{'type': 'application/pdf', 'disp': 'attachment'}, {'type': 'text/plain'}, {'type': 'text/plain'}], []), ['attachment', 'body', 'attachment']), ('named text part', ([{'type': 'text/plain', 'filename': 'notes3.txt'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('empty filename', ([{'type': 'text/plain', 'filename': ''}], []), ['body']), ('inline non-images', ([{'type': 'text/html'}, {'type': 'application/pdf', 'disp': 'inline'}, {'type': 'audio/ogg', 'disp': 'inline'}, {'type': 'image/gif', 'disp': 'inline'}], []), ['body', 'attachment', 'attachment', 'inline']), ('cid substring', ([{'type': 'text/html'}, {'type': 'image/png', 'cid': 'a3@x'}, {'type': 'image/png', 'cid': 'ba3@x'}], ['a3@x']), ['body', 'inline', 'attachment'])], 4: [('referenced image marked attachment', ([{'type': 'text/plain'}, {'type': 'image/png', 'cid': 'logo4@x', 'disp': 'attachment'}], ['logo4@x']), ['body', 'attachment']), ('upper-case disposition', ([{'type': 'text/plain', 'disp': 'ATTACHMENT'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('second text part', ([{'type': 'text/plain'}, {'type': 'text/plain'}], []), ['body', 'attachment']), ('attachment precedes body', ([{'type': 'application/pdf', 'disp': 'attachment'}, {'type': 'text/plain'}, {'type': 'text/plain'}], []), ['attachment', 'body', 'attachment']), ('named text part', ([{'type': 'text/plain', 'filename': 'notes4.txt'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('empty filename', ([{'type': 'text/plain', 'filename': ''}], []), ['body']), ('inline non-images', ([{'type': 'text/html'}, {'type': 'application/pdf', 'disp': 'inline'}, {'type': 'audio/ogg', 'disp': 'inline'}, {'type': 'image/gif', 'disp': 'inline'}], []), ['body', 'attachment', 'attachment', 'inline']), ('cid substring', ([{'type': 'text/html'}, {'type': 'image/png', 'cid': 'a4@x'}, {'type': 'image/png', 'cid': 'ba4@x'}], ['a4@x']), ['body', 'inline', 'attachment'])], 5: [('referenced image marked attachment', ([{'type': 'text/plain'}, {'type': 'image/png', 'cid': 'logo5@x', 'disp': 'attachment'}], ['logo5@x']), ['body', 'attachment']), ('upper-case disposition', ([{'type': 'text/plain', 'disp': 'ATTACHMENT'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('second text part', ([{'type': 'text/plain'}, {'type': 'text/plain'}], []), ['body', 'attachment']), ('attachment precedes body', ([{'type': 'application/pdf', 'disp': 'attachment'}, {'type': 'text/plain'}, {'type': 'text/plain'}], []), ['attachment', 'body', 'attachment']), ('named text part', ([{'type': 'text/plain', 'filename': 'notes5.txt'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('empty filename', ([{'type': 'text/plain', 'filename': ''}], []), ['body']), ('inline non-images', ([{'type': 'text/html'}, {'type': 'application/pdf', 'disp': 'inline'}, {'type': 'audio/ogg', 'disp': 'inline'}, {'type': 'image/gif', 'disp': 'inline'}], []), ['body', 'attachment', 'attachment', 'inline']), ('cid substring', ([{'type': 'text/html'}, {'type': 'image/png', 'cid': 'a5@x'}, {'type': 'image/png', 'cid': 'ba5@x'}], ['a5@x']), ['body', 'inline', 'attachment'])]}
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(parts, html_cids):
    out = []
    have_body = False
    for p in parts:
        disp = (p.get('disp') or '').strip()
        if disp == 'attachment':
            kind = 'attachment'
        elif p.get('cid') and p['cid'] in html_cids:
            kind = 'inline'
        elif p['type'].startswith('text/') and not p.get('filename') and not have_body:
            kind = 'body'
            have_body = True
        elif disp == 'inline' and p['type'].startswith('image/'):
            kind = 'inline'
        else:
            kind = 'attachment'
        out.append(kind)
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('referenced image marked attachment', ([{'type': 'text/plain'}, {'type': 'image/png', 'cid': 'logo1@x', 'disp': 'attachment'}], ['logo1@x']), ['body', 'attachment']), ('upper-case disposition', ([{'type': 'text/plain', 'disp': 'ATTACHMENT'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('second text part', ([{'type': 'text/plain'}, {'type': 'text/plain'}], []), ['body', 'attachment']), ('attachment precedes body', ([{'type': 'application/pdf', 'disp': 'attachment'}, {'type': 'text/plain'}, {'type': 'text/plain'}], []), ['attachment', 'body', 'attachment']), ('named text part', ([{'type': 'text/plain', 'filename': 'notes1.txt'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('empty filename', ([{'type': 'text/plain', 'filename': ''}], []), ['body']), ('inline non-images', ([{'type': 'text/html'}, {'type': 'application/pdf', 'disp': 'inline'}, {'type': 'audio/ogg', 'disp': 'inline'}, {'type': 'image/gif', 'disp': 'inline'}], []), ['body', 'attachment', 'attachment', 'inline']), ('cid substring', ([{'type': 'text/html'}, {'type': 'image/png', 'cid': 'a1@x'}, {'type': 'image/png', 'cid': 'ba1@x'}], ['a1@x']), ['body', 'inline', 'attachment'])], 2: [('referenced image marked attachment', ([{'type': 'text/plain'}, {'type': 'image/png', 'cid': 'logo2@x', 'disp': 'attachment'}], ['logo2@x']), ['body', 'attachment']), ('upper-case disposition', ([{'type': 'text/plain', 'disp': 'ATTACHMENT'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('second text part', ([{'type': 'text/plain'}, {'type': 'text/plain'}], []), ['body', 'attachment']), ('attachment precedes body', ([{'type': 'application/pdf', 'disp': 'attachment'}, {'type': 'text/plain'}, {'type': 'text/plain'}], []), ['attachment', 'body', 'attachment']), ('named text part', ([{'type': 'text/plain', 'filename': 'notes2.txt'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('empty filename', ([{'type': 'text/plain', 'filename': ''}], []), ['body']), ('inline non-images', ([{'type': 'text/html'}, {'type': 'application/pdf', 'disp': 'inline'}, {'type': 'audio/ogg', 'disp': 'inline'}, {'type': 'image/gif', 'disp': 'inline'}], []), ['body', 'attachment', 'attachment', 'inline']), ('cid substring', ([{'type': 'text/html'}, {'type': 'image/png', 'cid': 'a2@x'}, {'type': 'image/png', 'cid': 'ba2@x'}], ['a2@x']), ['body', 'inline', 'attachment'])], 3: [('referenced image marked attachment', ([{'type': 'text/plain'}, {'type': 'image/png', 'cid': 'logo3@x', 'disp': 'attachment'}], ['logo3@x']), ['body', 'attachment']), ('upper-case disposition', ([{'type': 'text/plain', 'disp': 'ATTACHMENT'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('second text part', ([{'type': 'text/plain'}, {'type': 'text/plain'}], []), ['body', 'attachment']), ('attachment precedes body', ([{'type': 'application/pdf', 'disp': 'attachment'}, {'type': 'text/plain'}, {'type': 'text/plain'}], []), ['attachment', 'body', 'attachment']), ('named text part', ([{'type': 'text/plain', 'filename': 'notes3.txt'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('empty filename', ([{'type': 'text/plain', 'filename': ''}], []), ['body']), ('inline non-images', ([{'type': 'text/html'}, {'type': 'application/pdf', 'disp': 'inline'}, {'type': 'audio/ogg', 'disp': 'inline'}, {'type': 'image/gif', 'disp': 'inline'}], []), ['body', 'attachment', 'attachment', 'inline']), ('cid substring', ([{'type': 'text/html'}, {'type': 'image/png', 'cid': 'a3@x'}, {'type': 'image/png', 'cid': 'ba3@x'}], ['a3@x']), ['body', 'inline', 'attachment'])], 4: [('referenced image marked attachment', ([{'type': 'text/plain'}, {'type': 'image/png', 'cid': 'logo4@x', 'disp': 'attachment'}], ['logo4@x']), ['body', 'attachment']), ('upper-case disposition', ([{'type': 'text/plain', 'disp': 'ATTACHMENT'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('second text part', ([{'type': 'text/plain'}, {'type': 'text/plain'}], []), ['body', 'attachment']), ('attachment precedes body', ([{'type': 'application/pdf', 'disp': 'attachment'}, {'type': 'text/plain'}, {'type': 'text/plain'}], []), ['attachment', 'body', 'attachment']), ('named text part', ([{'type': 'text/plain', 'filename': 'notes4.txt'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('empty filename', ([{'type': 'text/plain', 'filename': ''}], []), ['body']), ('inline non-images', ([{'type': 'text/html'}, {'type': 'application/pdf', 'disp': 'inline'}, {'type': 'audio/ogg', 'disp': 'inline'}, {'type': 'image/gif', 'disp': 'inline'}], []), ['body', 'attachment', 'attachment', 'inline']), ('cid substring', ([{'type': 'text/html'}, {'type': 'image/png', 'cid': 'a4@x'}, {'type': 'image/png', 'cid': 'ba4@x'}], ['a4@x']), ['body', 'inline', 'attachment'])], 5: [('referenced image marked attachment', ([{'type': 'text/plain'}, {'type': 'image/png', 'cid': 'logo5@x', 'disp': 'attachment'}], ['logo5@x']), ['body', 'attachment']), ('upper-case disposition', ([{'type': 'text/plain', 'disp': 'ATTACHMENT'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('second text part', ([{'type': 'text/plain'}, {'type': 'text/plain'}], []), ['body', 'attachment']), ('attachment precedes body', ([{'type': 'application/pdf', 'disp': 'attachment'}, {'type': 'text/plain'}, {'type': 'text/plain'}], []), ['attachment', 'body', 'attachment']), ('named text part', ([{'type': 'text/plain', 'filename': 'notes5.txt'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('empty filename', ([{'type': 'text/plain', 'filename': ''}], []), ['body']), ('inline non-images', ([{'type': 'text/html'}, {'type': 'application/pdf', 'disp': 'inline'}, {'type': 'audio/ogg', 'disp': 'inline'}, {'type': 'image/gif', 'disp': 'inline'}], []), ['body', 'attachment', 'attachment', 'inline']), ('cid substring', ([{'type': 'text/html'}, {'type': 'image/png', 'cid': 'a5@x'}, {'type': 'image/png', 'cid': 'ba5@x'}], ['a5@x']), ['body', 'inline', 'attachment'])]}
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)

prompt:
A part marked "ATTACHMENT" is rendered as the message body.

parts are the leaves of a multipart/mixed message in order: {type, disp, cid, filename}. Rules in order: an explicit "attachment" disposition (case-insensitive) is an attachment even when referenced; a part whose cid is exactly one of html_cids is inline; the first text/* part without a (non-empty) filename is the body; an explicit inline image/* is inline; everything else is an attachment.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(parts, html_cids):
    out = []
    have_body = False
    for p in parts:
        disp = (p.get('disp') or '').lower()
        if disp == 'attachment':
            kind = 'attachment'
        elif p.get('cid') and p['cid'] in html_cids:
            kind = 'inline'
        elif p['type'].startswith('text/') and not p.get('filename') :
            kind = 'body'
            have_body = True
        elif disp == 'inline' and p['type'].startswith('image/'):
            kind = 'inline'
        else:
            kind = 'attachment'
        out.append(kind)
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('referenced image marked attachment', ([{'type': 'text/plain'}, {'type': 'image/png', 'cid': 'logo1@x', 'disp': 'attachment'}], ['logo1@x']), ['body', 'attachment']), ('upper-case disposition', ([{'type': 'text/plain', 'disp': 'ATTACHMENT'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('second text part', ([{'type': 'text/plain'}, {'type': 'text/plain'}], []), ['body', 'attachment']), ('attachment precedes body', ([{'type': 'application/pdf', 'disp': 'attachment'}, {'type': 'text/plain'}, {'type': 'text/plain'}], []), ['attachment', 'body', 'attachment']), ('named text part', ([{'type': 'text/plain', 'filename': 'notes1.txt'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('empty filename', ([{'type': 'text/plain', 'filename': ''}], []), ['body']), ('inline non-images', ([{'type': 'text/html'}, {'type': 'application/pdf', 'disp': 'inline'}, {'type': 'audio/ogg', 'disp': 'inline'}, {'type': 'image/gif', 'disp': 'inline'}], []), ['body', 'attachment', 'attachment', 'inline']), ('cid substring', ([{'type': 'text/html'}, {'type': 'image/png', 'cid': 'a1@x'}, {'type': 'image/png', 'cid': 'ba1@x'}], ['a1@x']), ['body', 'inline', 'attachment'])], 2: [('referenced image marked attachment', ([{'type': 'text/plain'}, {'type': 'image/png', 'cid': 'logo2@x', 'disp': 'attachment'}], ['logo2@x']), ['body', 'attachment']), ('upper-case disposition', ([{'type': 'text/plain', 'disp': 'ATTACHMENT'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('second text part', ([{'type': 'text/plain'}, {'type': 'text/plain'}], []), ['body', 'attachment']), ('attachment precedes body', ([{'type': 'application/pdf', 'disp': 'attachment'}, {'type': 'text/plain'}, {'type': 'text/plain'}], []), ['attachment', 'body', 'attachment']), ('named text part', ([{'type': 'text/plain', 'filename': 'notes2.txt'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('empty filename', ([{'type': 'text/plain', 'filename': ''}], []), ['body']), ('inline non-images', ([{'type': 'text/html'}, {'type': 'application/pdf', 'disp': 'inline'}, {'type': 'audio/ogg', 'disp': 'inline'}, {'type': 'image/gif', 'disp': 'inline'}], []), ['body', 'attachment', 'attachment', 'inline']), ('cid substring', ([{'type': 'text/html'}, {'type': 'image/png', 'cid': 'a2@x'}, {'type': 'image/png', 'cid': 'ba2@x'}], ['a2@x']), ['body', 'inline', 'attachment'])], 3: [('referenced image marked attachment', ([{'type': 'text/plain'}, {'type': 'image/png', 'cid': 'logo3@x', 'disp': 'attachment'}], ['logo3@x']), ['body', 'attachment']), ('upper-case disposition', ([{'type': 'text/plain', 'disp': 'ATTACHMENT'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('second text part', ([{'type': 'text/plain'}, {'type': 'text/plain'}], []), ['body', 'attachment']), ('attachment precedes body', ([{'type': 'application/pdf', 'disp': 'attachment'}, {'type': 'text/plain'}, {'type': 'text/plain'}], []), ['attachment', 'body', 'attachment']), ('named text part', ([{'type': 'text/plain', 'filename': 'notes3.txt'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('empty filename', ([{'type': 'text/plain', 'filename': ''}], []), ['body']), ('inline non-images', ([{'type': 'text/html'}, {'type': 'application/pdf', 'disp': 'inline'}, {'type': 'audio/ogg', 'disp': 'inline'}, {'type': 'image/gif', 'disp': 'inline'}], []), ['body', 'attachment', 'attachment', 'inline']), ('cid substring', ([{'type': 'text/html'}, {'type': 'image/png', 'cid': 'a3@x'}, {'type': 'image/png', 'cid': 'ba3@x'}], ['a3@x']), ['body', 'inline', 'attachment'])], 4: [('referenced image marked attachment', ([{'type': 'text/plain'}, {'type': 'image/png', 'cid': 'logo4@x', 'disp': 'attachment'}], ['logo4@x']), ['body', 'attachment']), ('upper-case disposition', ([{'type': 'text/plain', 'disp': 'ATTACHMENT'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('second text part', ([{'type': 'text/plain'}, {'type': 'text/plain'}], []), ['body', 'attachment']), ('attachment precedes body', ([{'type': 'application/pdf', 'disp': 'attachment'}, {'type': 'text/plain'}, {'type': 'text/plain'}], []), ['attachment', 'body', 'attachment']), ('named text part', ([{'type': 'text/plain', 'filename': 'notes4.txt'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('empty filename', ([{'type': 'text/plain', 'filename': ''}], []), ['body']), ('inline non-images', ([{'type': 'text/html'}, {'type': 'application/pdf', 'disp': 'inline'}, {'type': 'audio/ogg', 'disp': 'inline'}, {'type': 'image/gif', 'disp': 'inline'}], []), ['body', 'attachment', 'attachment', 'inline']), ('cid substring', ([{'type': 'text/html'}, {'type': 'image/png', 'cid': 'a4@x'}, {'type': 'image/png', 'cid': 'ba4@x'}], ['a4@x']), ['body', 'inline', 'attachment'])], 5: [('referenced image marked attachment', ([{'type': 'text/plain'}, {'type': 'image/png', 'cid': 'logo5@x', 'disp': 'attachment'}], ['logo5@x']), ['body', 'attachment']), ('upper-case disposition', ([{'type': 'text/plain', 'disp': 'ATTACHMENT'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('second text part', ([{'type': 'text/plain'}, {'type': 'text/plain'}], []), ['body', 'attachment']), ('attachment precedes body', ([{'type': 'application/pdf', 'disp': 'attachment'}, {'type': 'text/plain'}, {'type': 'text/plain'}], []), ['attachment', 'body', 'attachment']), ('named text part', ([{'type': 'text/plain', 'filename': 'notes5.txt'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('empty filename', ([{'type': 'text/plain', 'filename': ''}], []), ['body']), ('inline non-images', ([{'type': 'text/html'}, {'type': 'application/pdf', 'disp': 'inline'}, {'type': 'audio/ogg', 'disp': 'inline'}, {'type': 'image/gif', 'disp': 'inline'}], []), ['body', 'attachment', 'attachment', 'inline']), ('cid substring', ([{'type': 'text/html'}, {'type': 'image/png', 'cid': 'a5@x'}, {'type': 'image/png', 'cid': 'ba5@x'}], ['a5@x']), ['body', 'inline', 'attachment'])]}
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(parts, html_cids):
    out = []
    have_body = False
    for p in parts:
        disp = (p.get('disp') or '').lower()
        if disp == 'attachment':
            kind = 'attachment'
        elif p.get('cid') and p['cid'] in html_cids:
            kind = 'inline'
        elif p['type'].startswith('text/') and not p.get('filename') and not out:
            kind = 'body'
            have_body = True
        elif disp == 'inline' and p['type'].startswith('image/'):
            kind = 'inline'
        else:
            kind = 'attachment'
        out.append(kind)
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('referenced image marked attachment', ([{'type': 'text/plain'}, {'type': 'image/png', 'cid': 'logo1@x', 'disp': 'attachment'}], ['logo1@x']), ['body', 'attachment']), ('upper-case disposition', ([{'type': 'text/plain', 'disp': 'ATTACHMENT'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('second text part', ([{'type': 'text/plain'}, {'type': 'text/plain'}], []), ['body', 'attachment']), ('attachment precedes body', ([{'type': 'application/pdf', 'disp': 'attachment'}, {'type': 'text/plain'}, {'type': 'text/plain'}], []), ['attachment', 'body', 'attachment']), ('named text part', ([{'type': 'text/plain', 'filename': 'notes1.txt'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('empty filename', ([{'type': 'text/plain', 'filename': ''}], []), ['body']), ('inline non-images', ([{'type': 'text/html'}, {'type': 'application/pdf', 'disp': 'inline'}, {'type': 'audio/ogg', 'disp': 'inline'}, {'type': 'image/gif', 'disp': 'inline'}], []), ['body', 'attachment', 'attachment', 'inline']), ('cid substring', ([{'type': 'text/html'}, {'type': 'image/png', 'cid': 'a1@x'}, {'type': 'image/png', 'cid': 'ba1@x'}], ['a1@x']), ['body', 'inline', 'attachment'])], 2: [('referenced image marked attachment', ([{'type': 'text/plain'}, {'type': 'image/png', 'cid': 'logo2@x', 'disp': 'attachment'}], ['logo2@x']), ['body', 'attachment']), ('upper-case disposition', ([{'type': 'text/plain', 'disp': 'ATTACHMENT'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('second text part', ([{'type': 'text/plain'}, {'type': 'text/plain'}], []), ['body', 'attachment']), ('attachment precedes body', ([{'type': 'application/pdf', 'disp': 'attachment'}, {'type': 'text/plain'}, {'type': 'text/plain'}], []), ['attachment', 'body', 'attachment']), ('named text part', ([{'type': 'text/plain', 'filename': 'notes2.txt'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('empty filename', ([{'type': 'text/plain', 'filename': ''}], []), ['body']), ('inline non-images', ([{'type': 'text/html'}, {'type': 'application/pdf', 'disp': 'inline'}, {'type': 'audio/ogg', 'disp': 'inline'}, {'type': 'image/gif', 'disp': 'inline'}], []), ['body', 'attachment', 'attachment', 'inline']), ('cid substring', ([{'type': 'text/html'}, {'type': 'image/png', 'cid': 'a2@x'}, {'type': 'image/png', 'cid': 'ba2@x'}], ['a2@x']), ['body', 'inline', 'attachment'])], 3: [('referenced image marked attachment', ([{'type': 'text/plain'}, {'type': 'image/png', 'cid': 'logo3@x', 'disp': 'attachment'}], ['logo3@x']), ['body', 'attachment']), ('upper-case disposition', ([{'type': 'text/plain', 'disp': 'ATTACHMENT'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('second text part', ([{'type': 'text/plain'}, {'type': 'text/plain'}], []), ['body', 'attachment']), ('attachment precedes body', ([{'type': 'application/pdf', 'disp': 'attachment'}, {'type': 'text/plain'}, {'type': 'text/plain'}], []), ['attachment', 'body', 'attachment']), ('named text part', ([{'type': 'text/plain', 'filename': 'notes3.txt'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('empty filename', ([{'type': 'text/plain', 'filename': ''}], []), ['body']), ('inline non-images', ([{'type': 'text/html'}, {'type': 'application/pdf', 'disp': 'inline'}, {'type': 'audio/ogg', 'disp': 'inline'}, {'type': 'image/gif', 'disp': 'inline'}], []), ['body', 'attachment', 'attachment', 'inline']), ('cid substring', ([{'type': 'text/html'}, {'type': 'image/png', 'cid': 'a3@x'}, {'type': 'image/png', 'cid': 'ba3@x'}], ['a3@x']), ['body', 'inline', 'attachment'])], 4: [('referenced image marked attachment', ([{'type': 'text/plain'}, {'type': 'image/png', 'cid': 'logo4@x', 'disp': 'attachment'}], ['logo4@x']), ['body', 'attachment']), ('upper-case disposition', ([{'type': 'text/plain', 'disp': 'ATTACHMENT'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('second text part', ([{'type': 'text/plain'}, {'type': 'text/plain'}], []), ['body', 'attachment']), ('attachment precedes body', ([{'type': 'application/pdf', 'disp': 'attachment'}, {'type': 'text/plain'}, {'type': 'text/plain'}], []), ['attachment', 'body', 'attachment']), ('named text part', ([{'type': 'text/plain', 'filename': 'notes4.txt'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('empty filename', ([{'type': 'text/plain', 'filename': ''}], []), ['body']), ('inline non-images', ([{'type': 'text/html'}, {'type': 'application/pdf', 'disp': 'inline'}, {'type': 'audio/ogg', 'disp': 'inline'}, {'type': 'image/gif', 'disp': 'inline'}], []), ['body', 'attachment', 'attachment', 'inline']), ('cid substring', ([{'type': 'text/html'}, {'type': 'image/png', 'cid': 'a4@x'}, {'type': 'image/png', 'cid': 'ba4@x'}], ['a4@x']), ['body', 'inline', 'attachment'])], 5: [('referenced image marked attachment', ([{'type': 'text/plain'}, {'type': 'image/png', 'cid': 'logo5@x', 'disp': 'attachment'}], ['logo5@x']), ['body', 'attachment']), ('upper-case disposition', ([{'type': 'text/plain', 'disp': 'ATTACHMENT'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('second text part', ([{'type': 'text/plain'}, {'type': 'text/plain'}], []), ['body', 'attachment']), ('attachment precedes body', ([{'type': 'application/pdf', 'disp': 'attachment'}, {'type': 'text/plain'}, {'type': 'text/plain'}], []), ['attachment', 'body', 'attachment']), ('named text part', ([{'type': 'text/plain', 'filename': 'notes5.txt'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('empty filename', ([{'type': 'text/plain', 'filename': ''}], []), ['body']), ('inline non-images', ([{'type': 'text/html'}, {'type': 'application/pdf', 'disp': 'inline'}, {'type': 'audio/ogg', 'disp': 'inline'}, {'type': 'image/gif', 'disp': 'inline'}], []), ['body', 'attachment', 'attachment', 'inline']), ('cid substring', ([{'type': 'text/html'}, {'type': 'image/png', 'cid': 'a5@x'}, {'type': 'image/png', 'cid': 'ba5@x'}], ['a5@x']), ['body', 'inline', 'attachment'])]}
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)

prompt:
A second text part is rendered as another body instead of being offered as an attachment.

parts are the leaves of a multipart/mixed message in order: {type, disp, cid, filename}. Rules in order: an explicit "attachment" disposition (case-insensitive) is an attachment even when referenced; a part whose cid is exactly one of html_cids is inline; the first text/* part without a (non-empty) filename is the body; an explicit inline image/* is inline; everything else is an attachment.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(parts, html_cids):
    out = []
    have_body = False
    for p in parts:
        disp = (p.get('disp') or '').lower()
        if disp == 'attachment':
            kind = 'attachment'
        elif p.get('cid') and p['cid'] in html_cids:
            kind = 'inline'
        elif p['type'].startswith('text/') and not have_body:
            kind = 'body'
            have_body = True
        elif disp == 'inline' and p['type'].startswith('image/'):
            kind = 'inline'
        else:
            kind = 'attachment'
        out.append(kind)
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('referenced image marked attachment', ([{'type': 'text/plain'}, {'type': 'image/png', 'cid': 'logo1@x', 'disp': 'attachment'}], ['logo1@x']), ['body', 'attachment']), ('upper-case disposition', ([{'type': 'text/plain', 'disp': 'ATTACHMENT'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('second text part', ([{'type': 'text/plain'}, {'type': 'text/plain'}], []), ['body', 'attachment']), ('attachment precedes body', ([{'type': 'application/pdf', 'disp': 'attachment'}, {'type': 'text/plain'}, {'type': 'text/plain'}], []), ['attachment', 'body', 'attachment']), ('named text part', ([{'type': 'text/plain', 'filename': 'notes1.txt'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('empty filename', ([{'type': 'text/plain', 'filename': ''}], []), ['body']), ('inline non-images', ([{'type': 'text/html'}, {'type': 'application/pdf', 'disp': 'inline'}, {'type': 'audio/ogg', 'disp': 'inline'}, {'type': 'image/gif', 'disp': 'inline'}], []), ['body', 'attachment', 'attachment', 'inline']), ('cid substring', ([{'type': 'text/html'}, {'type': 'image/png', 'cid': 'a1@x'}, {'type': 'image/png', 'cid': 'ba1@x'}], ['a1@x']), ['body', 'inline', 'attachment'])], 2: [('referenced image marked attachment', ([{'type': 'text/plain'}, {'type': 'image/png', 'cid': 'logo2@x', 'disp': 'attachment'}], ['logo2@x']), ['body', 'attachment']), ('upper-case disposition', ([{'type': 'text/plain', 'disp': 'ATTACHMENT'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('second text part', ([{'type': 'text/plain'}, {'type': 'text/plain'}], []), ['body', 'attachment']), ('attachment precedes body', ([{'type': 'application/pdf', 'disp': 'attachment'}, {'type': 'text/plain'}, {'type': 'text/plain'}], []), ['attachment', 'body', 'attachment']), ('named text part', ([{'type': 'text/plain', 'filename': 'notes2.txt'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('empty filename', ([{'type': 'text/plain', 'filename': ''}], []), ['body']), ('inline non-images', ([{'type': 'text/html'}, {'type': 'application/pdf', 'disp': 'inline'}, {'type': 'audio/ogg', 'disp': 'inline'}, {'type': 'image/gif', 'disp': 'inline'}], []), ['body', 'attachment', 'attachment', 'inline']), ('cid substring', ([{'type': 'text/html'}, {'type': 'image/png', 'cid': 'a2@x'}, {'type': 'image/png', 'cid': 'ba2@x'}], ['a2@x']), ['body', 'inline', 'attachment'])], 3: [('referenced image marked attachment', ([{'type': 'text/plain'}, {'type': 'image/png', 'cid': 'logo3@x', 'disp': 'attachment'}], ['logo3@x']), ['body', 'attachment']), ('upper-case disposition', ([{'type': 'text/plain', 'disp': 'ATTACHMENT'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('second text part', ([{'type': 'text/plain'}, {'type': 'text/plain'}], []), ['body', 'attachment']), ('attachment precedes body', ([{'type': 'application/pdf', 'disp': 'attachment'}, {'type': 'text/plain'}, {'type': 'text/plain'}], []), ['attachment', 'body', 'attachment']), ('named text part', ([{'type': 'text/plain', 'filename': 'notes3.txt'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('empty filename', ([{'type': 'text/plain', 'filename': ''}], []), ['body']), ('inline non-images', ([{'type': 'text/html'}, {'type': 'application/pdf', 'disp': 'inline'}, {'type': 'audio/ogg', 'disp': 'inline'}, {'type': 'image/gif', 'disp': 'inline'}], []), ['body', 'attachment', 'attachment', 'inline']), ('cid substring', ([{'type': 'text/html'}, {'type': 'image/png', 'cid': 'a3@x'}, {'type': 'image/png', 'cid': 'ba3@x'}], ['a3@x']), ['body', 'inline', 'attachment'])], 4: [('referenced image marked attachment', ([{'type': 'text/plain'}, {'type': 'image/png', 'cid': 'logo4@x', 'disp': 'attachment'}], ['logo4@x']), ['body', 'attachment']), ('upper-case disposition', ([{'type': 'text/plain', 'disp': 'ATTACHMENT'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('second text part', ([{'type': 'text/plain'}, {'type': 'text/plain'}], []), ['body', 'attachment']), ('attachment precedes body', ([{'type': 'application/pdf', 'disp': 'attachment'}, {'type': 'text/plain'}, {'type': 'text/plain'}], []), ['attachment', 'body', 'attachment']), ('named text part', ([{'type': 'text/plain', 'filename': 'notes4.txt'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('empty filename', ([{'type': 'text/plain', 'filename': ''}], []), ['body']), ('inline non-images', ([{'type': 'text/html'}, {'type': 'application/pdf', 'disp': 'inline'}, {'type': 'audio/ogg', 'disp': 'inline'}, {'type': 'image/gif', 'disp': 'inline'}], []), ['body', 'attachment', 'attachment', 'inline']), ('cid substring', ([{'type': 'text/html'}, {'type': 'image/png', 'cid': 'a4@x'}, {'type': 'image/png', 'cid': 'ba4@x'}], ['a4@x']), ['body', 'inline', 'attachment'])], 5: [('referenced image marked attachment', ([{'type': 'text/plain'}, {'type': 'image/png', 'cid': 'logo5@x', 'disp': 'attachment'}], ['logo5@x']), ['body', 'attachment']), ('upper-case disposition', ([{'type': 'text/plain', 'disp': 'ATTACHMENT'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('second text part', ([{'type': 'text/plain'}, {'type': 'text/plain'}], []), ['body', 'attachment']), ('attachment precedes body', ([{'type': 'application/pdf', 'disp': 'attachment'}, {'type': 'text/plain'}, {'type': 'text/plain'}], []), ['attachment', 'body', 'attachment']), ('named text part', ([{'type': 'text/plain', 'filename': 'notes5.txt'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('empty filename', ([{'type': 'text/plain', 'filename': ''}], []), ['body']), ('inline non-images', ([{'type': 'text/html'}, {'type': 'application/pdf', 'disp': 'inline'}, {'type': 'audio/ogg', 'disp': 'inline'}, {'type': 'image/gif', 'disp': 'inline'}], []), ['body', 'attachment', 'attachment', 'inline']), ('cid substring', ([{'type': 'text/html'}, {'type': 'image/png', 'cid': 'a5@x'}, {'type': 'image/png', 'cid': 'ba5@x'}], ['a5@x']), ['body', 'inline', 'attachment'])]}
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(parts, html_cids):
    out = []
    have_body = False
    for p in parts:
        disp = (p.get('disp') or '').lower()
        if disp == 'attachment':
            kind = 'attachment'
        elif p.get('cid') and p['cid'] in html_cids:
            kind = 'inline'
        elif p['type'].startswith('text/') and p.get('filename') is None and not have_body:
            kind = 'body'
            have_body = True
        elif disp == 'inline' and p['type'].startswith('image/'):
            kind = 'inline'
        else:
            kind = 'attachment'
        out.append(kind)
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
_CASES = {1: [('referenced image marked attachment', ([{'type': 'text/plain'}, {'type': 'image/png', 'cid': 'logo1@x', 'disp': 'attachment'}], ['logo1@x']), ['body', 'attachment']), ('upper-case disposition', ([{'type': 'text/plain', 'disp': 'ATTACHMENT'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('second text part', ([{'type': 'text/plain'}, {'type': 'text/plain'}], []), ['body', 'attachment']), ('attachment precedes body', ([{'type': 'application/pdf', 'disp': 'attachment'}, {'type': 'text/plain'}, {'type': 'text/plain'}], []), ['attachment', 'body', 'attachment']), ('named text part', ([{'type': 'text/plain', 'filename': 'notes1.txt'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('empty filename', ([{'type': 'text/plain', 'filename': ''}], []), ['body']), ('inline non-images', ([{'type': 'text/html'}, {'type': 'application/pdf', 'disp': 'inline'}, {'type': 'audio/ogg', 'disp': 'inline'}, {'type': 'image/gif', 'disp': 'inline'}], []), ['body', 'attachment', 'attachment', 'inline']), ('cid substring', ([{'type': 'text/html'}, {'type': 'image/png', 'cid': 'a1@x'}, {'type': 'image/png', 'cid': 'ba1@x'}], ['a1@x']), ['body', 'inline', 'attachment'])], 2: [('referenced image marked attachment', ([{'type': 'text/plain'}, {'type': 'image/png', 'cid': 'logo2@x', 'disp': 'attachment'}], ['logo2@x']), ['body', 'attachment']), ('upper-case disposition', ([{'type': 'text/plain', 'disp': 'ATTACHMENT'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('second text part', ([{'type': 'text/plain'}, {'type': 'text/plain'}], []), ['body', 'attachment']), ('attachment precedes body', ([{'type': 'application/pdf', 'disp': 'attachment'}, {'type': 'text/plain'}, {'type': 'text/plain'}], []), ['attachment', 'body', 'attachment']), ('named text part', ([{'type': 'text/plain', 'filename': 'notes2.txt'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('empty filename', ([{'type': 'text/plain', 'filename': ''}], []), ['body']), ('inline non-images', ([{'type': 'text/html'}, {'type': 'application/pdf', 'disp': 'inline'}, {'type': 'audio/ogg', 'disp': 'inline'}, {'type': 'image/gif', 'disp': 'inline'}], []), ['body', 'attachment', 'attachment', 'inline']), ('cid substring', ([{'type': 'text/html'}, {'type': 'image/png', 'cid': 'a2@x'}, {'type': 'image/png', 'cid': 'ba2@x'}], ['a2@x']), ['body', 'inline', 'attachment'])], 3: [('referenced image marked attachment', ([{'type': 'text/plain'}, {'type': 'image/png', 'cid': 'logo3@x', 'disp': 'attachment'}], ['logo3@x']), ['body', 'attachment']), ('upper-case disposition', ([{'type': 'text/plain', 'disp': 'ATTACHMENT'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('second text part', ([{'type': 'text/plain'}, {'type': 'text/plain'}], []), ['body', 'attachment']), ('attachment precedes body', ([{'type': 'application/pdf', 'disp': 'attachment'}, {'type': 'text/plain'}, {'type': 'text/plain'}], []), ['attachment', 'body', 'attachment']), ('named text part', ([{'type': 'text/plain', 'filename': 'notes3.txt'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('empty filename', ([{'type': 'text/plain', 'filename': ''}], []), ['body']), ('inline non-images', ([{'type': 'text/html'}, {'type': 'application/pdf', 'disp': 'inline'}, {'type': 'audio/ogg', 'disp': 'inline'}, {'type': 'image/gif', 'disp': 'inline'}], []), ['body', 'attachment', 'attachment', 'inline']), ('cid substring', ([{'type': 'text/html'}, {'type': 'image/png', 'cid': 'a3@x'}, {'type': 'image/png', 'cid': 'ba3@x'}], ['a3@x']), ['body', 'inline', 'attachment'])], 4: [('referenced image marked attachment', ([{'type': 'text/plain'}, {'type': 'image/png', 'cid': 'logo4@x', 'disp': 'attachment'}], ['logo4@x']), ['body', 'attachment']), ('upper-case disposition', ([{'type': 'text/plain', 'disp': 'ATTACHMENT'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('second text part', ([{'type': 'text/plain'}, {'type': 'text/plain'}], []), ['body', 'attachment']), ('attachment precedes body', ([{'type': 'application/pdf', 'disp': 'attachment'}, {'type': 'text/plain'}, {'type': 'text/plain'}], []), ['attachment', 'body', 'attachment']), ('named text part', ([{'type': 'text/plain', 'filename': 'notes4.txt'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('empty filename', ([{'type': 'text/plain', 'filename': ''}], []), ['body']), ('inline non-images', ([{'type': 'text/html'}, {'type': 'application/pdf', 'disp': 'inline'}, {'type': 'audio/ogg', 'disp': 'inline'}, {'type': 'image/gif', 'disp': 'inline'}], []), ['body', 'attachment', 'attachment', 'inline']), ('cid substring', ([{'type': 'text/html'}, {'type': 'image/png', 'cid': 'a4@x'}, {'type': 'image/png', 'cid': 'ba4@x'}], ['a4@x']), ['body', 'inline', 'attachment'])], 5: [('referenced image marked attachment', ([{'type': 'text/plain'}, {'type': 'image/png', 'cid': 'logo5@x', 'disp': 'attachment'}], ['logo5@x']), ['body', 'attachment']), ('upper-case disposition', ([{'type': 'text/plain', 'disp': 'ATTACHMENT'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('second text part', ([{'type': 'text/plain'}, {'type': 'text/plain'}], []), ['body', 'attachment']), ('attachment precedes body', ([{'type': 'application/pdf', 'disp': 'attachment'}, {'type': 'text/plain'}, {'type': 'text/plain'}], []), ['attachment', 'body', 'attachment']), ('named text part', ([{'type': 'text/plain', 'filename': 'notes5.txt'}, {'type': 'text/plain'}], []), ['attachment', 'body']), ('empty filename', ([{'type': 'text/plain', 'filename': ''}], []), ['body']), ('inline non-images', ([{'type': 'text/html'}, {'type': 'application/pdf', 'disp': 'inline'}, {'type': 'audio/ogg', 'disp': 'inline'}, {'type': 'image/gif', 'disp': 'inline'}], []), ['body', 'attachment', 'attachment', 'inline']), ('cid substring', ([{'type': 'text/html'}, {'type': 'image/png', 'cid': 'a5@x'}, {'type': 'image/png', 'cid': 'ba5@x'}], ['a5@x']), ['body', 'inline', 'attachment'])]}
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)

prompt:
A named text file such as notes.txt is shown as the message body.

parts are the leaves of a multipart/mixed message in order: {type, disp, cid, filename}. Rules in order: an explicit "attachment" disposition (case-insensitive) is an attachment even when referenced; a part whose cid is exactly one of html_cids is inline; the first text/* part without a (non-empty) filename is the body; an explicit inline image/* is inline; everything else is an attachment.

split: open-access