A set of message identifiers usable by both IMAP4Client and IMAP4Server via IMailboxIMAP.store and IMailboxIMAP.fetch.

These identifiers can be either message sequence numbers or unique identifiers. See Section 2.3.1, "Message Numbers", RFC 3501.

This represents the sequence-set described in Section 9, "Formal Syntax" of RFC 3501:

  • A MessageSet can describe a single identifier, e.g. MessageSet(1)
  • A MessageSet can describe * via None, e.g. MessageSet(None)
  • A MessageSet can describe a range of identifiers, e.g. MessageSet(1, 2). The range is inclusive and unordered (see seq-range in RFC 3501, Section 9), so that Message(2, 1) is equivalent to MessageSet(1, 2), and both describe messages 1 and 2. Ranges can include * by specifying None, e.g. MessageSet(None, 1). In all cases ranges are normalized so that the smallest identifier comes first, and None always comes last; Message(2, 1) becomes MessageSet(1, 2) and MessageSet(None, 1) becomes MessageSet(1, None)
  • A MessageSet can describe a sequence of single identifiers and ranges, constructed by addition. MessageSet(1) + MessageSet(5, 10) refers the message identified by 1 and the messages identified by 5 through 10.

NB: The meaning of * varies, but it always represents the largest number in use.

For servers: Your IMailboxIMAP provider must set MessageSet.last to the highest-valued identifier (unique or message sequence) before iterating over it.

For clients: * consumes ranges smaller than it, e.g. MessageSet(1, 100) + MessageSet(50, None) is equivalent to 1:*.

Instance Variable getnext A function that returns the next message number, used when iterating through the MessageSet. By default, a function returning the next integer is supplied, but as this can be rather inefficient for sparse UID iterations, it is recommended to supply one when messages are requested by UID. The argument is provided as a hint to the implementation and may be ignored if it makes sense to do so (eg, if an iterator is being used that maintains its own state, it is guaranteed that it will not be called out-of-order). (type: Function taking int returning int)
Method __init__ Create a new MessageSet()
Method last Undocumented
Method add Add another range
Method __add__ Undocumented
Method extend Extend our messages with another message or set of messages.
Method clean Clean ranges list, combining adjacent ranges
Method __contains__ May raise TypeError if we encounter an open-ended range
Method __iter__ Undocumented
Method __len__ Undocumented
Method __str__ Undocumented
Method __repr__ Undocumented
Method __eq__ Undocumented
Method __ne__ Undocumented
Method _noneInRanges Is there a None in our ranges?
Method _iterator Undocumented
getnext =
A function that returns the next message number, used when iterating through the MessageSet. By default, a function returning the next integer is supplied, but as this can be rather inefficient for sparse UID iterations, it is recommended to supply one when messages are requested by UID. The argument is provided as a hint to the implementation and may be ignored if it makes sense to do so (eg, if an iterator is being used that maintains its own state, it is guaranteed that it will not be called out-of-order). (type: Function taking int returning int)
def __init__(self, start=_empty, end=_empty): (source)

Create a new MessageSet()

ParametersstartStart of range, or only message number (type: Optional int)
endEnd of range. (type: Optional int)
def last(): (source)
Undocumented
def add(self, start, end=_empty): (source)

Add another range

ParametersstartStart of range, or only message number (type: int)
endEnd of range. (type: Optional int)
def __add__(self, other): (source)
Undocumented
def extend(self, other): (source)

Extend our messages with another message or set of messages.

ParametersotherThe messages to include. (type: MessageSet, tuple of two ints, or a single int)
def clean(self): (source)

Clean ranges list, combining adjacent ranges

def _noneInRanges(self): (source)

Is there a None in our ranges?

MessageSet.clean merges overlapping or consecutive ranges. None is represents a value larger than any number. There are thus two cases:

  1. (x, *) + (y, z) such that x is smaller than y
  2. (z, *) + (x, y) such that z is larger than y

(Other cases, such as y < x < z, can be split into these two cases; for example (y - 1, y) + (x, x) + (z, z + 1))

In case 1, * > y and * > z, so (x, *) + (y, z) = (x, *)

In case 2, z > x and z > y, so the intervals do not merge, and the ranges are sorted as [(x, y), (z, *)]. * is represented as (*, *), so this is the same as 2. but with a z that is greater than everything.

The result is that there is a maximum of two Nones, and one of them has to be the high element in the last tuple in self.ranges. That means checking if self.ranges[-1][-1] is None suffices to check if any element is None.

ReturnsTrue if None is in some range in ranges and False if otherwise.
def __contains__(self, value): (source)

May raise TypeError if we encounter an open-ended range

ParametersvalueIs this in our ranges? (type: int)
def _iterator(self): (source)
Undocumented
def __iter__(self): (source)
Undocumented
def __len__(self): (source)
Undocumented
def __str__(self): (source)
Undocumented
def __repr__(self): (source)
Undocumented
def __eq__(self, other): (source)
Undocumented
def __ne__(self, other): (source)
Undocumented
API Documentation for Twisted, generated by pydoctor at 2019-04-10 22:20:19.