email.header: Internationaliserade rubriker

Källkod: Lib/email/header.py


Denna modul är en del av det äldre (Compat32) e-post-API:et. I det nuvarande API:et hanteras kodning och avkodning av rubriker på ett transparent sätt av det ordboksliknande API:et i klassen EmailMessage. Förutom att den här modulen kan användas i äldre kod kan den vara användbar i applikationer som behöver fullständig kontroll över de teckenuppsättningar som används vid kodning av rubriker.

Resterande text i detta avsnitt är modulens originaldokumentation.

RFC 2822 är den basstandard som beskriver formatet för e-postmeddelanden. Den härstammar från den äldre standarden RFC 822 som började användas i stor utsträckning vid en tidpunkt då de flesta e-postmeddelanden endast bestod av ASCII-tecken. RFC 2822 är en specifikation som är skriven under förutsättning att e-postmeddelanden endast innehåller 7-bitars ASCII-tecken.

I takt med att e-post har spridits över hela världen har den naturligtvis internationaliserats, så att språkspecifika teckenuppsättningar nu kan användas i e-postmeddelanden. Basstandarden kräver fortfarande att e-postmeddelanden överförs med endast 7-bitars ASCII-tecken, så en mängd RFC:er har skrivits som beskriver hur man kodar e-postmeddelanden som innehåller icke-ASCII-tecken till ett format som uppfyller kraven i RFC 2822. Dessa RFC:er inkluderar RFC 2045, RFC 2046, RFC 2047 och RFC 2231. Paketet email stöder dessa standarder i modulerna email.header och email.charset.

Om du vill inkludera icke-ASCII-tecken i dina e-postrubriker, t.ex. i fälten Subject eller To, bör du använda klassen Header och tilldela fältet i objektet Message till en instans av Header i stället för att använda en sträng som rubrikvärde. Importera klassen Header från modulen email.header. Till exempel:

>>> from email.message import Message
>>> from email.header import Header
>>> msg = Message()
>>> h = Header('p\xf6stal', 'iso-8859-1')
>>> msg['Subject'] = h
>>> msg.as_string()
'Subject: =?iso-8859-1?q?p=F6stal?=\n\n'

Ser du här hur vi ville att fältet Subject skulle innehålla ett icke-ASCII-tecken? Vi gjorde detta genom att skapa en Header-instans och skicka in den teckenuppsättning som bytesträngen var kodad i. När den efterföljande Message-instansen plattades till, var fältet Subject korrekt RFC 2047-kodat. MIME-medvetna e-postläsare skulle visa detta huvud med hjälp av det inbäddade ISO-8859-1 tecknet.

Här är klassbeskrivningen för Header:

class email.header.Header(s=None, charset=None, maxlinelen=None, header_name=None, continuation_ws=' ', errors='strict')

Skapa ett MIME-kompatibelt huvud som kan innehålla strängar i olika teckenuppsättningar.

Valfritt s är det initiala rubrikvärdet. Om None (standard) anges inte det initiala rubrikvärdet. Du kan senare lägga till i sidhuvudet med append() metodanrop. s kan vara en instans av bytes eller str, men se append()-dokumentationen för semantik.

Det valfria charset har två syften: det har samma betydelse som argumentet charset i metoden append(). Det anger också standardteckensatsen för alla efterföljande append()-anrop som utelämnar charset-argumentet. Om charset inte anges i konstruktören (standard) används teckenuppsättningen us-ascii både som s:s ursprungliga teckenuppsättning och som standard för efterföljande append()-anrop.

Den maximala radlängden kan anges explicit via maxlinelen. Om du vill dela upp den första raden till ett kortare värde (för att ta hänsyn till fältrubriker som inte ingår i s, t.ex. Subject) anger du fältets namn i header_name. Standardvärdet för maxlinelen är 78 och standardvärdet för header_name är None, vilket innebär att det inte tas hänsyn till den första raden i en lång, delad header.

Det valfria tecknet continuation_ws måste vara ett RFC 2822 -kompatibelt folding whitespace, och är vanligtvis antingen ett mellanslag eller en hård tabb. Detta tecken kommer att läggas till på fortsättningsrader. continuation_ws är som standard ett enda mellanslagstecken.

Valfria fel skickas rakt igenom till metoden append().

append(s, charset=None, errors='strict')

Lägg till strängen s i MIME-rubriken.

Det valfria charset, om det anges, bör vara en Charset-instans (se email.charset) eller namnet på en teckenuppsättning, som kommer att konverteras till en Charset-instans. Ett värde på None (standard) innebär att den charset som anges i konstruktören används.

s kan vara en instans av bytes eller str. Om det är en instans av bytes, så är charset kodningen av bytesträngen och ett UnicodeError kommer att uppstå om strängen inte kan avkodas med den teckenuppsättningen.

Om s är en instans av str, är charset en ledtråd som anger teckenuppsättningen för tecknen i strängen.

I båda fallen, när ett RFC 2822-kompatibelt huvud produceras med hjälp av RFC 2047-regler, kommer strängen att kodas med hjälp av utdatakodeken för teckenuppsättningen. Om strängen inte kan kodas med hjälp av utmatningskodeken, kommer ett UnicodeError att uppstå.

Valfri errors skickas som errors-argument till avkodningsanropet om s är en bytesträng.

encode(splitchars=';, \t', maxlinelen=None, linesep='\n')

Koda ett meddelandehuvud till ett RFC-kompatibelt format, eventuellt omsluta långa rader och kapsla in icke-ASCII-delar i base64- eller quoted-printable-kodningar.

Valfritt splitchars är en sträng som innehåller tecken som bör ges extra vikt av delningsalgoritmen under normal rubrikombrytning. Detta är ett mycket grovt stöd för RFC 2822’s ”syntaktiska brytningar på högre nivå”: delningspunkter som föregås av en splitchar föredras vid raddelning, med tecknen föredragna i den ordning de förekommer i strängen. Mellanslag och tabb kan inkluderas i strängen för att ange om det ena ska föredras framför det andra som delningspunkt när andra delningstecken inte förekommer i den rad som delas. Splitchars påverkar inte RFC 2047-kodade rader.

maxlinelen, om den anges, åsidosätter instansens värde för den maximala radlängden.

linesep anger de tecken som används för att separera raderna i den vikta sidhuvudet. Standardvärdet är det mest användbara värdet för Python-programkod (\n), men \r\n kan anges för att producera rubriker med RFC-kompatibla radavgränsare.

Ändrad i version 3.2: Lagt till argumentet linesep.

Klassen Header innehåller också ett antal metoder för att stödja standardoperatorer och inbyggda funktioner.

__str__()

Returnerar en approximation av Header som en sträng, med obegränsad radlängd. Alla delar konverteras till unicode med hjälp av den angivna kodningen och sammanfogas på lämpligt sätt. Alla delar med en teckenuppsättning på 'unknown-8bit' avkodas som ASCII med hjälp av felhanteraren 'replace'.

Ändrad i version 3.2: Lagt till hantering av charsetet 'unknown-8bit'.

__eq__(other)

Med den här metoden kan du jämföra två Header-instanser för att se om de är lika.

__ne__(other)

Med den här metoden kan du jämföra två Header-instanser för ojämlikhet.

Modulen email.header innehåller också följande praktiska funktioner.

email.header.decode_header(header)

Avkodar ett meddelandehuvudvärde utan att konvertera teckenuppsättningen. Huvudvärdet finns i header.

Av historiska skäl kan denna funktion returnera antingen:

  1. En lista med par som innehåller var och en av de avkodade delarna av rubriken, (decoded_bytes, charset), där decoded_bytes alltid är en instans av bytes, och charset är antingen:

    • En sträng med gemener som innehåller namnet på den angivna teckenuppsättningen.

    • None för icke-kodade delar av rubriken.

  2. En lista med längden 1 som innehåller paret (string, None), där string alltid är en instans av str.

En email.errors.HeaderParseError kan uppstå när vissa avkodningsfel inträffar (t.ex. ett base64-avkodningsundantag).

Här är några exempel:

>>> from email.header import decode_header
>>> decode_header('=?iso-8859-1?q?p=F6stal?=')
[(b'p\xf6stal', 'iso-8859-1')]
>>> decode_header('unencoded_string')
[('unencoded_string', None)]
>>> decode_header('bar =?utf-8?B?ZsOzbw==?=')
[(b'bar ', None), (b'f\xc3\xb3o', 'utf-8')]

Anteckning

Denna funktion finns endast för bakåtkompatibilitet. För ny kod rekommenderar vi att du använder email.headerregistry.HeaderRegistry.

email.header.make_header(decoded_seq, maxlinelen=None, header_name=None, continuation_ws=' ')

Skapa en instans av Header från en sekvens av par som returneras av decode_header().

decode_header() tar en rubrikvärdessträng och returnerar en sekvens av par i formatet (decoded_string, charset) där charset är namnet på teckenuppsättningen.

Denna funktion tar en av dessa sekvenser av par och returnerar en Header-instans. De valfria maxlinelen, header_name och continuation_ws är som i konstruktören för Header.

Anteckning

Denna funktion finns endast för bakåtkompatibilitet och rekommenderas inte för användning i ny kod.