email.headerregistry: Anpassade rubrikobjekt¶
Källkod: Lib/email/headerregistry.py
Tillagd i version 3.6: [1]
Headers representeras av anpassade subklasser av str. Den särskilda klass som används för att representera ett visst huvud bestäms av header_factory i policy som gäller när huvudena skapas. Det här avsnittet dokumenterar den särskilda header_factory som implementerats av e-postpaketet för hantering av e-postmeddelanden som uppfyller kraven i RFC 5322, som inte bara tillhandahåller anpassade rubrikobjekt för olika rubriktyper, utan också tillhandahåller en tilläggsmekanism för program att lägga till sina egna anpassade rubriktyper.
När du använder något av de policyobjekt som härrör från EmailPolicy, produceras alla rubriker av HeaderRegistry och har BaseHeader som sista basklass. Varje header-klass har ytterligare en basklass som bestäms av typen av header. Många headers har t.ex. klassen UnstructuredHeader som sin andra basklass. Den specialiserade andra klassen för en header bestäms av namnet på headern med hjälp av en uppslagstabell som lagras i HeaderRegistry. Allt detta hanteras transparent för det typiska applikationsprogrammet, men gränssnitt tillhandahålls för att ändra standardbeteendet för användning av mer komplexa applikationer.
I avsnitten nedan dokumenteras först headerbasklasserna och deras attribut, därefter API:et för att ändra beteendet hos HeaderRegistry och slutligen de stödklasser som används för att representera data som analyseras från strukturerade headers.
- class email.headerregistry.BaseHeader(name, value)¶
name och value skickas till
BaseHeaderfrån anropetheader_factory. Strängvärdet för ett header-objekt är värdet fullt avkodat till unicode.Denna basklass definierar följande skrivskyddade egenskaper:
- name¶
Namnet på rubriken (den del av fältet som ligger före ’:’). Detta är exakt det värde som skickades i
header_factory-anropet för name; dvs. skiftlägesskillnaden bevaras.
- defects¶
En tupel av
HeaderDefect-instanser som rapporterar eventuella RFC-överensstämmelseproblem som upptäckts under parsningen. E-postpaketet försöker vara komplett när det gäller att upptäcka problem med efterlevnad. Se modulenerrorsför en diskussion om vilka typer av defekter som kan rapporteras.
- max_count¶
Det maximala antalet rubriker av denna typ som kan ha samma
namn. Ett värde avNonebetyder obegränsat. Värdet förBaseHeaderför detta attribut ärNone; det förväntas att specialiserade header-klasser åsidosätter detta värde efter behov.
BaseHeadertillhandahåller också följande metod, som anropas av e-postbibliotekskoden och i allmänhet inte bör anropas av applikationsprogram:- fold(*, policy)¶
Returnerar en sträng som innehåller
lineseptecken som krävs för att vika headern korrekt enligt policy. Encte_typepå8bitkommer att behandlas som om den vore7bit, eftersom rubriker inte får innehålla godtyckliga binära data. Omutf8ärFalse, kommer icke-ASCII-data att kodas enligt RFC 2047.
BaseHeaderkan i sig inte användas för att skapa ett rubrikobjekt. Den definierar ett protokoll som varje specialiserad header samarbetar med för att producera header-objektet. Specifikt kräverBaseHeaderatt den specialiserade klassen tillhandahåller enclassmethod`()med namnetparse. Denna metod anropas på följande sätt:parse(string, kwds)
kwdsär en ordbok som innehåller en förinitialiserad nyckel,defects.defectsär en tom lista. Parse-metoden bör lägga till alla upptäckta defekter till denna lista. Vid återlämnandet måste ordlistankwdsinnehålla värden för åtminstone nycklarnadecodedochdefects.decodedbör vara strängvärdet för rubriken (det vill säga rubrikvärdet helt avkodat till unicode). Parse-metoden bör anta att sträng kan innehålla innehållsöverföringskodade delar, men bör korrekt hantera alla giltiga Unicode-tecken också så att den kan parsa okodade rubrikvärden.BaseHeader’s__new__skapar sedan header-instansen och anropar dessinitmetod. Den specialiserade klassen behöver bara tillhandahålla eninit-metod om den vill ställa in ytterligare attribut utöver de som tillhandahålls avBaseHeadersjälv. En sådaninit-metod bör se ut så här:def init(self, /, *args, **kw): self._myattr = kw.pop('myattr') super().init(*args, **kw)
Det vill säga, allt extra som den specialiserade klassen lägger till i ordlistan
kwdsska tas bort och hanteras, och det återstående innehållet ikw(ochargs) ska skickas till metodenBaseHeaderinit.
- class email.headerregistry.UnstructuredHeader¶
En ”ostrukturerad” header är standardtypen av header i RFC 5322. Alla rubriker som inte har en specificerad syntax behandlas som ostrukturerade. Det klassiska exemplet på ett ostrukturerat huvud är Subject-huvudet.
I RFC 5322, är en ostrukturerad header en körning av godtycklig text i ASCII teckenuppsättning. RFC 2047, har dock en RFC 5322 kompatibel mekanism för kodning av icke-ASCII text som ASCII tecken inom en header värde. När ett värde som innehåller kodade ord skickas till konstruktören, konverterar
UnstructuredHeaderparser sådana kodade ord till unicode, enligt RFC 2047 regler för ostrukturerad text. Parsern använder heuristik för att försöka avkoda vissa icke-kompatibla kodade ord. Defekter registreras i sådana fall, liksom defekter för problem som ogiltiga tecken inom de kodade orden eller den icke-kodade texten.Denna rubriktyp innehåller inga ytterligare attribut.
- class email.headerregistry.DateHeader¶
RFC 5322 specificerar ett mycket specifikt format för datum i e-postrubriker. Parsern
DateHeaderkänner igen det datumformatet, samt känner igen ett antal varianter som ibland finns ”i naturen”.Denna rubriktyp innehåller följande ytterligare attribut:
- datetime¶
Om rubrikvärdet kan identifieras som ett giltigt datum i en eller annan form, kommer detta attribut att innehålla en
datetime-instans som representerar detta datum. Om tidszonen för indatadatumet anges som\-0000(vilket indikerar att det är i UTC men inte innehåller någon information om källans tidszon), kommerdatetimeatt vara en naivdatetime. Om en specifik tidszonförskjutning hittas (inklusive+0000), kommerdatetimeatt innehålla en medvetendatetimesom använderdatetime.timezoneför att registrera tidszonförskjutningen.
Det
avkodadevärdet på rubriken bestäms genom att formateradatatidenenligt reglerna i RFC 5322, dvs. det sätts till:email.utils.format_datetime(self.datetime)
När du skapar en
DateHeader, kan värde varadatetimeinstans. Detta innebär t.ex. att följande kod är giltig och gör vad man förväntar sig:msg['Date'] = datetime(2011,7,15,21)
Eftersom detta är en naiv
datetimekommer den att tolkas som en UTC-tidsstämpel, och det resulterande värdet kommer att ha tidszonen\-0000. Mycket mer användbart är att använda funktionenlocaltime()från modulenutils:msg['Date'] = utils.localtime()
I det här exemplet ställs datumrubriken in på aktuell tid och aktuellt datum med aktuell tidszonsförskjutning.
- class email.headerregistry.AddressHeader¶
Adressrubriker är en av de mest komplexa strukturerade rubriktyperna. Klassen
AddressHeadertillhandahåller ett generiskt gränssnitt för alla adressrubriker.Denna rubriktyp innehåller följande ytterligare attribut:
- groups¶
En tupel av
Group-objekt som kodar de adresser och grupper som finns i rubrikvärdet. Adresser som inte är en del av en grupp representeras i denna lista som enstaka adresserGroupsvarsdisplay_nameärNone.
- addresses¶
En tupel av
Address-objekt som kodar alla individuella adresser från rubrikvärdet. Om rubrikvärdet innehåller några grupper, inkluderas de enskilda adresserna från gruppen i listan vid den punkt där gruppen förekommer i värdet (dvs. adresslistan ”plattas till” till en endimensionell lista).
Det
decoded-värdet i rubriken kommer att ha alla kodade ord avkodade till unicode.idna-kodade domännamn avkodas också till unicode. Detdecoded-värdet ställs in genom att joiningstr-värdet för elementen i attributetgroupsmed', '.En lista med objekten
AddressochGroupi valfri kombination kan användas för att ange värdet på ett adresshuvud.Group-objekt varsdisplay_nameärNonetolkas som enskilda adresser, vilket gör att en adresslista kan kopieras med grupperna intakta genom att använda den lista som erhålls frångroups-attributet i källhuvudet.
- class email.headerregistry.SingleAddressHeader¶
En subklass av
AddressHeadersom lägger till ytterligare ett attribut:- address¶
Den enskilda adress som kodas av rubrikvärdet. Om rubrikvärdet faktiskt innehåller mer än en adress (vilket skulle vara ett brott mot RFC enligt standard
policy), kommer åtkomst till detta attribut att resultera i ettValueError.
Många av ovanstående klasser har också en Unique variant (t.ex. UniqueUnstructuredHeader). Den enda skillnaden är att i Unique-varianten är max_count satt till 1.
- class email.headerregistry.MIMEVersionHeader¶
Det finns egentligen bara ett giltigt värde för rubriken MIME-Version, och det är
1.0. För att vara framtidssäker stöder denna rubrikklass andra giltiga versionsnummer. Om ett versionsnummer har ett giltigt värde enligt RFC 2045, så kommer rubrikobjektet att ha värden som inte ärNoneför följande attribut:- version¶
Versionsnumret som en sträng, med eventuella blanksteg och/eller kommentarer borttagna.
- major¶
Huvudversionsnumret som ett heltal
- minor¶
Det mindre versionsnumret som ett heltal
- class email.headerregistry.ParameterizedMIMEHeader¶
MIME-rubriker börjar alla med prefixet ”Content-”. Varje specifik header har ett visst värde, som beskrivs under klassen för den headern. Vissa kan också ta en lista med kompletterande parametrar, som har ett gemensamt format. Denna klass fungerar som en bas för alla MIME-rubriker som tar parametrar.
- params¶
En ordlista som mappar parameternamn till parametervärden.
- class email.headerregistry.ContentTypeHeader¶
En
ParameterizedMIMEHeader-klass som hanterar Content-Type-huvudet.- content_type¶
Strängen för innehållstypen, i formatet
maintype/subtype.
- maintype¶
- subtype¶
- class email.headerregistry.ContentDispositionHeader¶
En
ParameterizedMIMEHeader-klass som hanterar Content-Disposition-huvudet.- content_disposition¶
inlineochattachmentär de enda giltiga värdena som används i allmänhet.
- class email.headerregistry.ContentTransferEncoding¶
Hanterar rubriken Content-Transfer-Encoding.
- class email.headerregistry.HeaderRegistry(base_class=BaseHeader, default_class=UnstructuredHeader, use_default_map=True)¶
Detta är den fabrik som används av
EmailPolicysom standard.HeaderRegistrybygger den klass som används för att skapa en header-instans dynamiskt, med hjälp av base_class och en specialiserad klass som hämtas från ett register som den innehar. När ett visst headernamn inte finns i registret används den klass som anges av default_class som specialiserad klass. När use_default_map ärTrue(standard) kopieras standardmappningen av headernamn till klasser in i registret under initialiseringen. base_class är alltid den sista klassen i den genererade klassens__bases__-lista.Standardmappningarna är:
- subject:
UniqueUnstructuredHeader
- date:
UniqueDateHeader
- resent-date:
DateHeader
- orig-date:
UniqueDateHeader
- sender:
UniqueSingleAddressHeader
- resent-sender:
SingleAddressHeader
- to:
UniqueAddressHeader
- resent-to:
AddressHeader
- cc:
UniqueAddressHeader
- resent-cc:
AddressHeader
- bcc:
UniqueAddressHeader
- resent-bcc:
AddressHeader
- from:
UniqueAddressHeader
- resent-from:
AddressHeader
- reply-to:
UniqueAddressHeader
- mime-version:
MIMEVersionHeader
- content-type:
ContentTypeHeader
- content-disposition:
ContentDispositionHeader
- content-transfer-encoding:
ContentTransferEncodingHeader
- message-id:
MessageIDHeader
HeaderRegistryhar följande metoder:- map_to_type(self, name, cls)¶
name är namnet på den header som ska mappas. Det kommer att konverteras till gemener i registret. cls är den specialiserade klass som ska användas tillsammans med base_class för att skapa den klass som används för att instansiera rubriker som matchar name.
- __getitem__(name)¶
Konstruera och returnera en klass som hanterar skapandet av en header med namn.
- __call__(name, value)¶
Hämtar den specialiserade header som associeras med namn från registret (med hjälp av default_class om namn inte finns i registret) och sätter ihop den med base_class för att skapa en klass, anropar den konstruerade klassens konstruktor med samma argumentlista och returnerar slutligen den klassinstans som skapats på detta sätt.
Följande klasser är de klasser som används för att representera data som analyseras från strukturerade rubriker och kan i allmänhet användas av ett applikationsprogram för att konstruera strukturerade värden som ska tilldelas specifika rubriker.
- class email.headerregistry.Address(display_name='', username='', domain='', addr_spec=None)¶
Den klass som används för att representera en e-postadress. Den allmänna formen av en adress är:
[display_name] <användarnamn@domän>
eller:
användarnamn@domän
där varje del måste överensstämma med specifika syntaxregler som anges i RFC 5322.
Som en bekvämlighet kan addr_spec anges i stället för användarnamn och domän, i vilket fall användarnamn och domän kommer att tolkas från addr_spec. En addr_spec måste vara en korrekt RFC-citerad sträng; om den inte är det kommer
Addressatt ge upphov till ett fel. Unicode-tecken är tillåtna och kommer att vara egenskapskodade när de serialiseras. Enligt RFC är dock unicode inte tillåtet i användarnamnsdelen av adressen.- display_name¶
Eventuellt visningsnamn för adressen, med alla citattecken borttagna. Om adressen inte har något visningsnamn kommer detta attribut att vara en tom sträng.
- username¶
”Användarnamn”-delen av adressen, med alla citattecken borttagna.
- domain¶
Den del av adressen som kallas ”domän”.
- addr_spec¶
Delen
användarnamn@domäni adressen, korrekt citerad för användning som en ren adress (den andra formen visas ovan). Detta attribut är inte muterbart.
- __str__()¶
Objektets
str-värde är adressen citerad enligt RFC 5322-reglerna, men utan Content Transfer Encoding av några icke-ASCII-tecken.
För att stödja SMTP (RFC 5321) hanterar
Addressett specialfall: omusernameochdomainbåda är den tomma strängen (ellerNone), så är strängvärdet förAddress<>.
- class email.headerregistry.Group(display_name=None, addresses=None)¶
Den klass som används för att representera en adressgrupp. Den allmänna formen för en adressgrupp är:
display_name: [address-list];
För att underlätta bearbetningen av adresslistor som består av en blandning av grupper och enskilda adresser kan en
Groupockså användas för att representera enskilda adresser som inte ingår i en grupp genom att sätta display_name tillNoneoch tillhandahålla en lista över de enskilda adresserna som addresses.- display_name¶
Gruppens
display_name. Om det ärNoneoch det finns exakt enAddressiaddresses, representerarGroupen enskild adress som inte ingår i någon grupp.
Fotnoter