mail.imap.parser
import mail.imap.parser
The IMAP grammar: turning what a server says into something a program can read.
IMAP does not speak in lines alone. A response may carry a literal, which is a byte count followed by exactly that many bytes of anything at all, including line breaks, so reading one response can mean reading several lines and a block of raw data. That is why this reads from the connection rather than from a string.
import mail.imap.parser
var tokens = parser.tokenize('(\\Seen \\Answered) "/" "INBOX"')
echo tokens[0]
echo tokens[2]
[\Seen, \Answered]
INBOX
Constants
STATUSES
mail.parser.STATUSES = [...]
SYSTEM_FLAGS
mail.parser.SYSTEM_FLAGS = [...]
Functions
tokenize()
mail.parser.tokenize(text: string, source) -> list
Reads a run of IMAP values out of text.
source is only needed when the text can contain a literal, which is to
say whenever it came from a server rather than from a test.
Parameters
text(string)source(?LineStream) — Where to read a literal’s bytes from.
Returns list
Raises ProtocolError if the text is not well formed.
quote()
mail.parser.quote(value: string) -> string|Literal
Writes a value the way a command has to carry it.
A name that is plain enough goes as it is, one that is not is quoted, and one that cannot be quoted at all, because it holds a line break or characters outside ASCII, is sent as a literal.
Parameters
value(string)
Returns string|Literal
Classes
Literal
class mail.parser.Literal
A run of bytes a server sent as a literal.
Kept apart from an ordinary string because a literal is where a message body arrives, and a body is bytes: decoding it as text would corrupt anything that is not text.
- printable — has a
@to_string(), soechoandprint()show something useful
Constructor
mail.parser.Literal(data)
Parameters
data(bytes)
Literal.to_text()
mail.parser.Literal.to_text() -> string
The literal read as UTF-8 text.
Returns string
Literal.length()
mail.parser.Literal.length() -> number
How many bytes it holds.
Returns number
Literal.to_string()
mail.parser.Literal.to_string()
Response
class mail.parser.Response
One response from the server.
kind is tagged for the answer to a command, untagged for
everything a server says on its own, and continuation for the
invitation to send the rest of a command.
- printable — has a
@to_string(), soechoandprint()show something useful
Constructor
mail.parser.Response(kind: string, tag: ?string, tokens: list, line: string)
Parameters
kind(string)tag(?string)tokens(list) — The values in the response, in order.line(string) — The first line it was read from.
Response.is_ok()
mail.parser.Response.is_ok() -> bool
Whether this is a command’s answer and the answer was yes.
Returns bool
Response.name()
mail.parser.Response.name() -> string|nil
The name of an untagged data response, such as EXISTS, FETCH or
LIST, or nil when it is not one.
A numbered response puts the number first, so the name is the second value in those and the first in the rest.
Returns string|nil
Response.number()
mail.parser.Response.number() -> number|nil
The number a numbered response carries, such as the message number in * 12 FETCH,
or nil when it carries none.
Returns number|nil
Response.arguments()
mail.parser.Response.arguments() -> list
The values after the response’s name.
Returns list
Response.to_string()
mail.parser.Response.to_string()
Reader
class mail.parser.Reader
Reads responses off a connection, one at a time.
- printable — has a
@to_string(), soechoandprint()show something useful
Constructor
mail.parser.Reader(source)
Parameters
source(LineStream)
Reader.next()
mail.parser.Reader.next() -> Response
Reads the next response, however many lines and literals it takes.
Returns Response
Raises ProtocolError if what arrives is not a response.
Raises ConnectionClosed if the connection ends first.
Reader.to_string()
mail.parser.Reader.to_string()
2026, Richard Ore and Zuri contributors