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
BaseHeader
frå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 modulenerrors
fö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 avNone
betyder obegränsat. Värdet förBaseHeader
för detta attribut ärNone
; det förväntas att specialiserade header-klasser åsidosätter detta värde efter behov.
BaseHeader
tillhandahå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
linesep
tecken som krävs för att vika headern korrekt enligt policy. Encte_type
på8bit
kommer 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.
BaseHeader
kan 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äverBaseHeader
att 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 ordlistankwds
innehålla värden för åtminstone nycklarnadecoded
ochdefects
.decoded
bö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 dessinit
metod. Den specialiserade klassen behöver bara tillhandahålla eninit
-metod om den vill ställa in ytterligare attribut utöver de som tillhandahålls avBaseHeader
sjä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
kwds
-ordlistan ska tas bort och hanteras, och det återstående innehållet ikw
(ochargs
) skickas tillBaseHeader
init
-metoden.
- 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
UnstructuredHeader
parser 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
DateHeader
kä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), kommerdatetime
att vara en naivdatetime
. Om en specifik tidszonförskjutning hittas (inklusive+0000
), kommerdatetime
att innehålla en medvetendatetime
som använderdatetime.timezone
för att registrera tidszonförskjutningen.
Det
avkodade
värdet på rubriken bestäms genom att formateradatatiden
enligt reglerna i RFC 5322, dvs. det sätts till:email.utils.format_datetime(self.datetime)
När du skapar en
DateHeader
, kan värde varadatetime
instans. 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
datetime
kommer 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
AddressHeader
tillhandahå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 adresserGroups
varsdisplay_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 attributetgroups
med', '
.En lista med objekten
Address
ochGroup
i valfri kombination kan användas för att ange värdet på ett adresshuvud.Group
-objekt varsdisplay_name
ärNone
tolkas 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
AddressHeader
som 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 ärNone
fö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¶
inline
ochattachment
ä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
EmailPolicy
som standard.HeaderRegistry
bygger 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
HeaderRegistry
har 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
Address
att 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än
i 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
Address
ett specialfall: omusername
ochdomain
bå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
Group
också användas för att representera enskilda adresser som inte ingår i en grupp genom att sätta display_name tillNone
och tillhandahålla en lista över de enskilda adresserna som addresses.- display_name¶
Gruppens
display_name
. Om det ärNone
och det finns exakt enAddress
iaddresses
, representerarGroup
en enskild adress som inte ingår i någon grupp.
Fotnoter