field_type = xmlnode.prop("<STR_LIT:type>")<EOL>label = from_utf8(xmlnode.prop("<STR_LIT:label>"))<EOL>name = from_utf8(xmlnode.prop("<STR_LIT>"))<EOL>child = xmlnode.children<EOL>values = []<EOL>options = []<EOL>required = False<EOL>desc = None<EOL>while child:<EOL><INDENT>if child.type != "<STR_LIT>" or child.ns().content != DATAFORM_NS:<EOL><INDENT>pass<EOL><DEDENT>elif child.name == "<STR_LIT>":<EOL><INDENT>required = True<EOL><DEDENT>elif child.name == "<STR_LIT>":<EOL><INDENT>desc = from_utf8(child.getContent())<EOL><DEDENT>elif child.name == "<STR_LIT:value>":<EOL><INDENT>values.append(from_utf8(child.getContent()))<EOL><DEDENT>elif child.name == "<STR_LIT>":<EOL><INDENT>options.append(Option._new_from_xml(child))<EOL><DEDENT>child = child.next<EOL><DEDENT>if field_type and not field_type.endswith("<STR_LIT>") and len(values) > <NUM_LIT:1>:<EOL><INDENT>raise BadRequestProtocolError("<STR_LIT>")<EOL><DEDENT>return cls(name, values, field_type, label, options, required, desc)<EOL>

Create a new `Field` object from an XML element.

        :Parameters:
            - `xmlnode`: the XML element.
        :Types:
            - `xmlnode`: `libxml2.xmlNode`

        :return: the object created.
        :returntype: `Field`


if fields is None:<EOL><INDENT>self.fields = []<EOL><DEDENT>else:<EOL><INDENT>self.fields = list(fields)<EOL><DEDENT>

Initialize an `Item` object.

        :Parameters:
            - `fields`: item fields.
        :Types:
            - `fields`: `list` of `Field`.


def add_field(self, name = None, values = None, field_type = None,<EOL>label = None, options = None, required = False, desc = None, value = None):

field = Field(name, values, field_type, label, options, required, desc, value)<EOL>self.fields.append(field)<EOL>return field<EOL>

Add a field to the item.

        :Parameters:
            - `name`: field name.
            - `values`: raw field values. Not to be used together with `value`.
            - `field_type`: field type.
            - `label`: field label.
            - `options`: optional values for the field.
            - `required`: `True` if the field is required.
            - `desc`: natural-language description of the field.
            - `value`: field value or values in a field_type-specific type. May be used only
              if `values` parameter is not provided.
        :Types:
            - `name`: `unicode`
            - `values`: `list` of `unicode`
            - `field_type`: `str`
            - `label`: `unicode`
            - `options`: `list` of `Option`
            - `required`: `bool`
            - `desc`: `unicode`
            - `value`: `bool` for "boolean" field, `JID` for "jid-single", `list` of `JID`
              for "jid-multi", `list` of `unicode` for "list-multi" and "text-multi"
              and `unicode` for other field types.

        :return: the field added.
        :returntype: `Field`


def complete_xml_element(self, xmlnode, doc):

for field in self.fields:<EOL><INDENT>field.as_xml(xmlnode, doc)<EOL><DEDENT>

Complete the XML node with `self` content.

        :Parameters:
            - `xmlnode`: XML node with the element being built. It has already
              right name and namespace, but no attributes or content.
            - `doc`: document to which the element belongs.
        :Types:
            - `xmlnode`: `libxml2.xmlNode`
            - `doc`: `libxml2.xmlDoc`


child = xmlnode.children<EOL>fields = []<EOL>while child:<EOL><INDENT>if child.type != "<STR_LIT>" or child.ns().content != DATAFORM_NS:<EOL><INDENT>pass<EOL><DEDENT>elif child.name == "<STR_LIT>":<EOL><INDENT>fields.append(Field._new_from_xml(child))<EOL><DEDENT>child = child.next<EOL><DEDENT>return cls(fields)<EOL>

Create a new `Item` object from an XML element.

        :Parameters:
            - `xmlnode`: the XML element.
        :Types:
            - `xmlnode`: `libxml2.xmlNode`

        :return: the object created.
        :returntype: `Item`


def __init__(self, xmlnode_or_type = "<STR_LIT>", title = None, instructions = None,<EOL>fields = None, reported_fields = None, items = None):

if isinstance(xmlnode_or_type, libxml2.xmlNode):<EOL><INDENT>self.__from_xml(xmlnode_or_type)<EOL><DEDENT>elif xmlnode_or_type not in self.allowed_types:<EOL><INDENT>raise ValueError("<STR_LIT>" % (xmlnode_or_type,))<EOL><DEDENT>else:<EOL><INDENT>self.type = xmlnode_or_type<EOL>self.title = title<EOL>self.instructions = instructions<EOL>if fields:<EOL><INDENT>self.fields = list(fields)<EOL><DEDENT>else:<EOL><INDENT>self.fields = []<EOL><DEDENT>if reported_fields:<EOL><INDENT>self.reported_fields = list(reported_fields)<EOL><DEDENT>else:<EOL><INDENT>self.reported_fields = []<EOL><DEDENT>if items:<EOL><INDENT>self.items = list(items)<EOL><DEDENT>else:<EOL><INDENT>self.items = []<EOL><DEDENT><DEDENT>

Initialize a `Form` object.

        :Parameters:
            - `xmlnode_or_type`: XML element to parse or a form title.
            - `title`: form title.
            - `instructions`: instructions for the form.
            - `fields`: form fields.
            - `reported_fields`: fields reported in multi-item data.
            - `items`: items of multi-item data.
        :Types:
            - `xmlnode_or_type`: `libxml2.xmlNode` or `str`
            - `title`: `unicode`
            - `instructions`: `unicode`
            - `fields`: `list` of `Field`
            - `reported_fields`: `list` of `Field`
            - `items`: `list` of `Item`


Add a field to the form.

        :Parameters:
            - `name`: field name.
            - `values`: raw field values. Not to be used together with `value`.
            - `field_type`: field type.
            - `label`: field label.
            - `options`: optional values for the field.
            - `required`: `True` if the field is required.
            - `desc`: natural-language description of the field.
            - `value`: field value or values in a field_type-specific type. May be used only
              if `values` parameter is not provided.
        :Types:
            - `name`: `unicode`
            - `values`: `list` of `unicode`
            - `field_type`: `str`
            - `label`: `unicode`
            - `options`: `list` of `Option`
            - `required`: `bool`
            - `desc`: `unicode`
            - `value`: `bool` for "boolean" field, `JID` for "jid-single", `list` of `JID`
              for "jid-multi", `list` of `unicode` for "list-multi" and "text-multi"
              and `unicode` for other field types.

        :return: the field added.
        :returntype: `Field`


item = Item(fields)<EOL>self.items.append(item)<EOL>return item<EOL>

Add and item to the form.

        :Parameters:
            - `fields`: fields of the item (they may be added later).
        :Types:
            - `fields`: `list` of `Field`

        :return: the item added.
        :returntype: `Item`


def make_submit(self, keep_types = False):

result = Form("<STR_LIT>")<EOL>for field in self.fields:<EOL><INDENT>if field.type == "<STR_LIT>":<EOL><INDENT>continue<EOL><DEDENT>if not field.values:<EOL><INDENT>if field.required:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>continue<EOL><DEDENT>if keep_types:<EOL><INDENT>result.add_field(field.name, field.values, field.type)<EOL><DEDENT>else:<EOL><INDENT>result.add_field(field.name, field.values)<EOL><DEDENT><DEDENT>return result<EOL>

Make a "submit" form using data in `self`.

        Remove uneeded information from the form. The information removed
        includes: title, instructions, field labels, fixed fields etc.

        :raise ValueError: when any required field has no value.

        :Parameters:
            - `keep_types`: when `True` field type information will be included
              in the result form. That is usually not needed.
        :Types:
            - `keep_types`: `bool`

        :return: the form created.
        :returntype: `Form`


return copy.deepcopy(self)<EOL>

Get a deep copy of `self`.

        :return: a deep copy of `self`.
        :returntype: `Form`


if self.type not in self.allowed_types:<EOL><INDENT>raise ValueError("<STR_LIT>" % (self.type,))<EOL><DEDENT>xmlnode.setProp("<STR_LIT:type>", self.type)<EOL>if self.type == "<STR_LIT>":<EOL><INDENT>return<EOL><DEDENT>ns = xmlnode.ns()<EOL>if self.title is not None:<EOL><INDENT>xmlnode.newTextChild(ns, "<STR_LIT:title>", to_utf8(self.title))<EOL><DEDENT>if self.instructions is not None:<EOL><INDENT>xmlnode.newTextChild(ns, "<STR_LIT>", to_utf8(self.instructions))<EOL><DEDENT>for field in self.fields:<EOL><INDENT>field.as_xml(xmlnode, doc)<EOL><DEDENT>if self.type != "<STR_LIT:result>":<EOL><INDENT>return<EOL><DEDENT>if self.reported_fields:<EOL><INDENT>reported = xmlnode.newChild(ns, "<STR_LIT>", None)<EOL>for field in self.reported_fields:<EOL><INDENT>field.as_xml(reported, doc)<EOL><DEDENT><DEDENT>for item in self.items:<EOL><INDENT>item.as_xml(xmlnode, doc)<EOL><DEDENT>


self.fields = []<EOL>self.reported_fields = []<EOL>self.items = []<EOL>self.title = None<EOL>self.instructions = None<EOL>if (xmlnode.type != "<STR_LIT>" or xmlnode.name != "<STR_LIT:x>"<EOL>or xmlnode.ns().content != DATAFORM_NS):<EOL><INDENT>raise ValueError("<STR_LIT>" + xmlnode.serialize())<EOL><DEDENT>self.type = xmlnode.prop("<STR_LIT:type>")<EOL>if not self.type in self.allowed_types:<EOL><INDENT>raise BadRequestProtocolError("<STR_LIT>" % (self.type,))<EOL><DEDENT>child = xmlnode.children<EOL>while child:<EOL><INDENT>if child.type != "<STR_LIT>" or child.ns().content != DATAFORM_NS:<EOL><INDENT>pass<EOL><DEDENT>elif child.name == "<STR_LIT:title>":<EOL><INDENT>self.title = from_utf8(child.getContent())<EOL><DEDENT>elif child.name == "<STR_LIT>":<EOL><INDENT>self.instructions = from_utf8(child.getContent())<EOL><DEDENT>elif child.name == "<STR_LIT>":<EOL><INDENT>self.fields.append(Field._new_from_xml(child))<EOL><DEDENT>elif child.name == "<STR_LIT>":<EOL><INDENT>self.items.append(Item._new_from_xml(child))<EOL><DEDENT>elif child.name == "<STR_LIT>":<EOL><INDENT>self.__get_reported(child)<EOL><DEDENT>child = child.next<EOL><DEDENT>

Initialize a `Form` object from an XML element.

        :Parameters:
            - `xmlnode`: the XML element.
        :Types:
            - `xmlnode`: `libxml2.xmlNode`


child = xmlnode.children<EOL>while child:<EOL><INDENT>if child.type != "<STR_LIT>" or child.ns().content != DATAFORM_NS:<EOL><INDENT>pass<EOL><DEDENT>elif child.name == "<STR_LIT>":<EOL><INDENT>self.reported_fields.append(Field._new_from_xml(child))<EOL><DEDENT>child = child.next<EOL><DEDENT>

Parse the <reported/> element of the form.

        :Parameters:
            - `xmlnode`: the element to parse.
        :Types:
            - `xmlnode`: `libxml2.xmlNode`


def __init__(self, element, from_jid = None, to_jid = None,<EOL>stanza_type = None, stanza_id = None,<EOL>error = None, error_cond = None,<EOL>return_path = None, language = None):

<EOL>self._error = None<EOL>self._from_jid = None<EOL>self._to_jid = None<EOL>self._stanza_type = None<EOL>self._stanza_id = None<EOL>self._language = language<EOL>if isinstance(element, ElementClass):<EOL><INDENT>self._element = element<EOL>self._dirty = False<EOL>self._decode_attributes()<EOL>if not element.tag.startswith("<STR_LIT:{>"):<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>else:<EOL><INDENT>self._namespace, self.element_name = element.tag[<NUM_LIT:1>:].split("<STR_LIT:}>")<EOL>if self._namespace not in STANZA_NAMESPACES:<EOL><INDENT>raise BadRequestProtocolError("<STR_LIT>")<EOL><DEDENT><DEDENT>self._payload = None<EOL><DEDENT>else:<EOL><INDENT>self._element = None<EOL>self._dirty = True<EOL>self.element_name = unicode(element)<EOL>self._namespace = STANZA_CLIENT_NS<EOL>self._payload = []<EOL><DEDENT>self._ns_prefix = "<STR_LIT>".format(self._namespace)<EOL>self._element_qname = self._ns_prefix + self.element_name<EOL>if from_jid is not None:<EOL><INDENT>self.from_jid = from_jid<EOL><DEDENT>if to_jid is not None:<EOL><INDENT>self.to_jid = to_jid<EOL><DEDENT>if stanza_type:<EOL><INDENT>self.stanza_type = stanza_type<EOL><DEDENT>if stanza_id:<EOL><INDENT>self.stanza_id = stanza_id<EOL><DEDENT>if self.stanza_type == "<STR_LIT:error>":<EOL><INDENT>if error:<EOL><INDENT>self._error = StanzaErrorElement(error)<EOL><DEDENT>elif error_cond:<EOL><INDENT>self._error = StanzaErrorElement(error_cond)<EOL><DEDENT>else:<EOL><INDENT>self._decode_error()<EOL><DEDENT><DEDENT>if return_path is not None:<EOL><INDENT>self._return_path = weakref.ref(return_path)<EOL><DEDENT>

Initialize a Stanza object.

        :Parameters:
            - `element`: XML element of this stanza, or element name for a new
              stanza. If element is given it must not be modified later,
              unless `decode_payload()` and `mark_dirty()` methods are called
              first (the element changes won't affec the stanza then).
            - `from_jid`: sender JID.
            - `to_jid`: recipient JID.
            - `stanza_type`: staza type: one of: "get", "set", "result" or
              "error".
            - `stanza_id`: stanza id -- value of stanza's "id" attribute. If
              not given, then unique for the session value is generated.
            - `error`: error object. Ignored if `stanza_type` is not "error".
            - `error_cond`: error condition name. Ignored if `stanza_type` is
              not "error" or `error` is not None.
            - `return_path`: route for sending responses to this stanza. Will
              be weakly referenced.
            - `language`: default language for the stanza content
        :Types:
            - `element`: `unicode` or :etree:`ElementTree.Element`
            - `from_jid`: `JID`
            - `to_jid`: `JID`
            - `stanza_type`: `unicode`
            - `stanza_id`: `unicode`
            - `error`: `pyxmpp.error.StanzaErrorElement`
            - `error_cond`: `unicode`
            - `return_path`: `StanzaRoute`
            - `language`: `unicode`


try:<EOL><INDENT>from_jid = self._element.get('<STR_LIT>')<EOL>if from_jid:<EOL><INDENT>self._from_jid = JID(from_jid)<EOL><DEDENT>to_jid = self._element.get('<STR_LIT:to>')<EOL>if to_jid:<EOL><INDENT>self._to_jid = JID(to_jid)<EOL><DEDENT><DEDENT>except ValueError:<EOL><INDENT>raise JIDMalformedProtocolError<EOL><DEDENT>self._stanza_type = self._element.get('<STR_LIT:type>')<EOL>self._stanza_id = self._element.get('<STR_LIT:id>')<EOL>lang = self._element.get(XML_LANG_QNAME)<EOL>if lang:<EOL><INDENT>self._language = lang<EOL><DEDENT>

Decode attributes of the stanza XML element
        and put them into the stanza properties.


error_qname = self._ns_prefix + "<STR_LIT:error>"<EOL>for child in self._element:<EOL><INDENT>if child.tag == error_qname:<EOL><INDENT>self._error = StanzaErrorElement(child)<EOL>return<EOL><DEDENT><DEDENT>raise BadRequestProtocolError("<STR_LIT>"<EOL>"<STR_LIT>")<EOL>


result = Stanza(self.element_name, self.from_jid, self.to_jid,<EOL>self.stanza_type, self.stanza_id, self.error,<EOL>self._return_path())<EOL>if self._payload is None:<EOL><INDENT>self.decode_payload()<EOL><DEDENT>for payload in self._payload:<EOL><INDENT>result.add_payload(payload.copy())<EOL><DEDENT>return result<EOL>

Create a deep copy of the stanza.

        :returntype: `Stanza`


return serialize(self.get_xml())<EOL>

Serialize the stanza into a Unicode XML string.

        :return: serialized stanza.
        :returntype: `unicode`


attrs = {}<EOL>if self._from_jid:<EOL><INDENT>attrs['<STR_LIT>'] = unicode(self._from_jid)<EOL><DEDENT>if self._to_jid:<EOL><INDENT>attrs['<STR_LIT:to>'] = unicode(self._to_jid)<EOL><DEDENT>if self._stanza_type:<EOL><INDENT>attrs['<STR_LIT:type>'] = self._stanza_type<EOL><DEDENT>if self._stanza_id:<EOL><INDENT>attrs['<STR_LIT:id>'] = self._stanza_id<EOL><DEDENT>if self._language:<EOL><INDENT>attrs[XML_LANG_QNAME] = self._language<EOL><DEDENT>element = ElementTree.Element(self._element_qname, attrs)<EOL>if self._payload is None:<EOL><INDENT>self.decode_payload()<EOL><DEDENT>for payload in self._payload:<EOL><INDENT>element.append(payload.as_xml())<EOL><DEDENT>if self._error:<EOL><INDENT>element.append(self._error.as_xml(<EOL>stanza_namespace = self._namespace))<EOL><DEDENT>return element<EOL>

Return the XML stanza representation.

        Always return an independent copy of the stanza XML representation,
        which can be freely modified without affecting the stanza.

        :returntype: :etree:`ElementTree.Element`


if not self._dirty:<EOL><INDENT>return self._element<EOL><DEDENT>element = self.as_xml()<EOL>self._element = element<EOL>self._dirty = False<EOL>return element<EOL>

Return the XML stanza representation.

        This returns the original or cached XML representation, which
        may be much more efficient than `as_xml`.

        Result of this function should never be modified.

        :returntype: :etree:`ElementTree.Element`


def decode_payload(self, specialize = False):

if self._payload is not None:<EOL><INDENT>return<EOL><DEDENT>if self._element is None:<EOL><INDENT>raise ValueError("<STR_LIT>""<STR_LIT>")<EOL><DEDENT>payload = []<EOL>if specialize:<EOL><INDENT>factory = payload_factory<EOL><DEDENT>else:<EOL><INDENT>factory = XMLPayload<EOL><DEDENT>for child in self._element:<EOL><INDENT>if self.__class__ is not Stanza:<EOL><INDENT>if child.tag.startswith(self._ns_prefix):<EOL><INDENT>continue<EOL><DEDENT><DEDENT>payload.append(factory(child))<EOL><DEDENT>self._payload = payload<EOL>

Decode payload from the element passed to the stanza constructor.

        Iterates over stanza children and creates StanzaPayload objects for
        them. Called automatically by `get_payload()` and other methods that
        access the payload.

        For the `Stanza` class stanza namespace child elements will also be
        included as the payload. For subclasses these are no considered
        payload.


return self._from_jid<EOL>

Source JID of the stanza.

        :returntype: `JID`


return self._to_jid<EOL>

Destination JID of the stanza.

        :returntype: `JID`


return self._stanza_type<EOL>

Stanza type, one of: "get", "set", "result" or "error".

        :returntype: `unicode`


return self._stanza_id<EOL>

Stanza id.

        :returntype: `unicode`


return self._error<EOL>

Stanza error element.

        :returntype: `StanzaErrorElement`


return self._return_path()<EOL>

Stream the stanza was received from.

        :returntype: `StanzaRoute`


self._dirty = True<EOL>

Mark the stanza 'dirty' so the XML representation will be
        re-built the next time it is requested.

        This should be called each time the payload attached to the stanza is
        modifed.


if isinstance(payload, ElementClass):<EOL><INDENT>self._payload = [ XMLPayload(payload) ]<EOL><DEDENT>elif isinstance(payload, StanzaPayload):<EOL><INDENT>self._payload = [ payload ]<EOL><DEDENT>else:<EOL><INDENT>raise TypeError("<STR_LIT>")<EOL><DEDENT>self._dirty = True<EOL>

Set stanza payload to a single item.

        All current stanza content of will be dropped.
        Marks the stanza dirty.

        :Parameters:
            - `payload`: XML element or stanza payload object to use
        :Types:
            - `payload`: :etree:`ElementTree.Element` or `StanzaPayload`


if self._payload is None:<EOL><INDENT>self.decode_payload()<EOL><DEDENT>if isinstance(payload, ElementClass):<EOL><INDENT>self._payload.append(XMLPayload(payload))<EOL><DEDENT>elif isinstance(payload, StanzaPayload):<EOL><INDENT>self._payload.append(payload)<EOL><DEDENT>else:<EOL><INDENT>raise TypeError("<STR_LIT>")<EOL><DEDENT>self._dirty = True<EOL>

Add new the stanza payload.

        Marks the stanza dirty.

        :Parameters:
            - `payload`: XML element or stanza payload object to add
        :Types:
            - `payload`: :etree:`ElementTree.Element` or `StanzaPayload`


def get_all_payload(self, specialize = False):

if self._payload is None:<EOL><INDENT>self.decode_payload(specialize)<EOL><DEDENT>elif specialize:<EOL><INDENT>for i, payload in enumerate(self._payload):<EOL><INDENT>if isinstance(payload, XMLPayload):<EOL><INDENT>klass = payload_class_for_element_name(<EOL>payload.element.tag)<EOL>if klass is not XMLPayload:<EOL><INDENT>payload = klass.from_xml(payload.element)<EOL>self._payload[i] = payload<EOL><DEDENT><DEDENT><DEDENT><DEDENT>return list(self._payload)<EOL>

Return list of stanza payload objects.

        :Parameters:
            - `specialize`: If `True`, then return objects of specialized
              `StanzaPayload` classes whenever possible, otherwise the
              representation already available will be used (often
              `XMLPayload`)

        :Returntype: `list` of `StanzaPayload`


def get_payload(self, payload_class, payload_key = None,<EOL>specialize = False):

if self._payload is None:<EOL><INDENT>self.decode_payload()<EOL><DEDENT>if payload_class is None:<EOL><INDENT>if self._payload:<EOL><INDENT>payload = self._payload[<NUM_LIT:0>]<EOL>if specialize and isinstance(payload, XMLPayload):<EOL><INDENT>klass = payload_class_for_element_name(<EOL>payload.element.tag)<EOL>if klass is not XMLPayload:<EOL><INDENT>payload = klass.from_xml(payload.element)<EOL>self._payload[<NUM_LIT:0>] = payload<EOL><DEDENT><DEDENT>return payload<EOL><DEDENT>else:<EOL><INDENT>return None<EOL><DEDENT><DEDENT>elements = payload_class._pyxmpp_payload_element_name<EOL>for i, payload in enumerate(self._payload):<EOL><INDENT>if isinstance(payload, XMLPayload):<EOL><INDENT>if payload_class is not XMLPayload:<EOL><INDENT>if payload.xml_element_name not in elements:<EOL><INDENT>continue<EOL><DEDENT>payload = payload_class.from_xml(payload.element)<EOL><DEDENT><DEDENT>elif not isinstance(payload, payload_class):<EOL><INDENT>continue<EOL><DEDENT>if payload_key is not None and payload_key != payload.handler_key():<EOL><INDENT>continue<EOL><DEDENT>self._payload[i] = payload<EOL>return payload<EOL><DEDENT>return None<EOL>

Get the first payload item matching the given class
        and optional key.

        Payloads may be addressed using a specific payload class or
        via the generic `XMLPayload` element, though the `XMLPayload`
        representation is available only as long as the element is not
        requested by a more specific type.

        :Parameters:
            - `payload_class`: requested payload class, a subclass of
              `StanzaPayload`. If `None` get the first payload in whatever
              class is available.
            - `payload_key`: optional key for additional match. When used
              with `payload_class` = `XMLPayload` this selects the element to
              match
            - `specialize`: If `True`, and `payload_class` is `None` then
              return object of a specialized `StanzaPayload` subclass whenever
              possible
        :Types:
            - `payload_class`: `StanzaPayload`
            - `specialize`: `bool`

        :Return: payload element found or `None`
        :Returntype: `StanzaPayload`


cls.last_id += <NUM_LIT:1><EOL>return str(cls.last_id)<EOL>

Generate stanza id unique for the session.

        :return: the new id.


if isinstance(data, BMPString):<EOL><INDENT>return bytes(data).decode("<STR_LIT>")<EOL><DEDENT>else:<EOL><INDENT>return bytes(data).decode("<STR_LIT:utf-8>")<EOL><DEDENT>

Convert ASN.1 string to a Unicode string.


return ASN1CertificateData.from_file(filename)<EOL>


if self.subject_name:<EOL><INDENT>return "<STR_LIT:U+002CU+0020>".join( [ "<STR_LIT:U+002CU+0020>".join(<EOL>[ "<STR_LIT>".format(k,v) for k, v in dn_tuple ] )<EOL>for dn_tuple in self.subject_name ])<EOL><DEDENT>for name_type in ("<STR_LIT>", "<STR_LIT>", "<STR_LIT>"):<EOL><INDENT>names = self.alt_names.get(name_type)<EOL>if names:<EOL><INDENT>return names[<NUM_LIT:0>]<EOL><DEDENT><DEDENT>return "<STR_LIT>"<EOL>

Get human-readable subject name derived from the SubjectName
        or SubjectAltName field.


result = []<EOL>if ("<STR_LIT>" in self.alt_names or "<STR_LIT>" in self.alt_names<EOL>or "<STR_LIT>" in self.alt_names):<EOL><INDENT>addrs =  self.alt_names.get("<STR_LIT>", [])<EOL>addrs += [ addr for addr in self.alt_names.get("<STR_LIT>", [])<EOL>if not addr.startswith("<STR_LIT>") ]<EOL>addrs += [ addr.split("<STR_LIT:.>", <NUM_LIT:1>)[<NUM_LIT:1>] for addr<EOL>in self.alt_names.get("<STR_LIT>", [])<EOL>if (addr.startswith("<STR_LIT>")<EOL>or addr.startswith("<STR_LIT>"))]<EOL>warn_bad = True<EOL><DEDENT>elif self.common_names:<EOL><INDENT>addrs = [addr for addr in self.common_names<EOL>if "<STR_LIT:@>" not in addr and "<STR_LIT:/>" not in addr]<EOL>warn_bad = False<EOL><DEDENT>else:<EOL><INDENT>return []<EOL><DEDENT>for addr in addrs:<EOL><INDENT>try:<EOL><INDENT>jid = JID(addr)<EOL>if jid not in result:<EOL><INDENT>result.append(jid)<EOL><DEDENT><DEDENT>except JIDError as err:<EOL><INDENT>if warn_bad:<EOL><INDENT>logger.warning("<STR_LIT>"<EOL>.format(addr, err))<EOL><DEDENT><DEDENT><DEDENT>return result<EOL>

Return JIDs for which this certificate is valid (except the domain
        wildcards).

        :Returtype: `list` of `JID`


def verify_server(self, server_name, srv_type = '<STR_LIT>'):

server_jid = JID(server_name)<EOL>if "<STR_LIT>" not in self.alt_names and "<STR_LIT>" not in self.alt_namesand "<STR_LIT>" not in self.alt_names:<EOL><INDENT>return self.verify_jid_against_common_name(server_jid)<EOL><DEDENT>names = [name for name in self.alt_names.get("<STR_LIT>", [])<EOL>if not name.startswith("<STR_LIT>")]<EOL>names += self.alt_names.get("<STR_LIT>", [])<EOL>for name in names:<EOL><INDENT>logger.debug("<STR_LIT>".format(server_jid,<EOL>name))<EOL>try:<EOL><INDENT>jid = JID(name)<EOL><DEDENT>except ValueError:<EOL><INDENT>logger.debug("<STR_LIT>".format(name))<EOL>continue<EOL><DEDENT>if jid == server_jid:<EOL><INDENT>logger.debug("<STR_LIT>")<EOL>return True<EOL><DEDENT><DEDENT>if srv_type and self.verify_jid_against_srv_name(server_jid, srv_type):<EOL><INDENT>return True<EOL><DEDENT>wildcards = [name[<NUM_LIT:2>:] for name in self.alt_names.get("<STR_LIT>", [])<EOL>if name.startswith("<STR_LIT>")]<EOL>if not wildcards or not "<STR_LIT:.>" in server_jid.domain:<EOL><INDENT>return False<EOL><DEDENT>logger.debug("<STR_LIT>"<EOL>.format(server_jid, wildcards))<EOL>server_domain = JID(domain = server_jid.domain.split("<STR_LIT:.>", <NUM_LIT:1>)[<NUM_LIT:1>])<EOL>for domain in wildcards:<EOL><INDENT>logger.debug("<STR_LIT>".format(server_domain,<EOL>domain))<EOL>try:<EOL><INDENT>jid = JID(domain)<EOL><DEDENT>except ValueError:<EOL><INDENT>logger.debug("<STR_LIT>".format(name))<EOL>continue<EOL><DEDENT>if jid == server_domain:<EOL><INDENT>logger.debug("<STR_LIT>")<EOL>return True<EOL><DEDENT><DEDENT>return False<EOL>

Verify certificate for a server.

        :Parameters:
            - `server_name`: name of the server presenting the cerificate
            - `srv_type`: service type requested, as used in the SRV record
        :Types:
            - `server_name`: `unicode` or `JID`
            - `srv_type`: `unicode`

        :Return: `True` if the certificate is valid for given name, `False`
        otherwise.


if not self.common_names:<EOL><INDENT>return False<EOL><DEDENT>for name in self.common_names:<EOL><INDENT>try:<EOL><INDENT>cn_jid = JID(name)<EOL><DEDENT>except ValueError:<EOL><INDENT>continue<EOL><DEDENT>if jid == cn_jid:<EOL><INDENT>return True<EOL><DEDENT><DEDENT>return False<EOL>

Return `True` if jid is listed in the certificate commonName.

        :Parameters:
            - `jid`: JID requested (domain part only)
        :Types:
            - `jid`: `JID`

        :Returntype: `bool`


def verify_jid_against_srv_name(self, jid, srv_type):

srv_prefix = "<STR_LIT:_>" + srv_type + "<STR_LIT:.>"<EOL>srv_prefix_l = len(srv_prefix)<EOL>for srv in self.alt_names.get("<STR_LIT>", []):<EOL><INDENT>logger.debug("<STR_LIT>".format(jid,<EOL>srv))<EOL>if not srv.startswith(srv_prefix):<EOL><INDENT>logger.debug("<STR_LIT>"<EOL>.format(srv, srv_prefix))<EOL>continue<EOL><DEDENT>try:<EOL><INDENT>srv_jid = JID(srv[srv_prefix_l:])<EOL><DEDENT>except ValueError:<EOL><INDENT>continue<EOL><DEDENT>if srv_jid == jid:<EOL><INDENT>logger.debug("<STR_LIT>")<EOL>return True<EOL><DEDENT><DEDENT>return False<EOL>

Check if the cerificate is valid for given domain-only JID
        and a service type.

        :Parameters:
            - `jid`: JID requested (domain part only)
            - `srv_type`: service type, e.g. 'xmpp-client'
        :Types:
            - `jid`: `JID`
            - `srv_type`: `unicode`
        :Returntype: `bool`


def verify_client(self, client_jid = None, domains = None):

jids = [jid for jid in self.get_jids() if jid.local]<EOL>if not jids:<EOL><INDENT>return None<EOL><DEDENT>if client_jid is not None and client_jid in jids:<EOL><INDENT>return client_jid<EOL><DEDENT>if domains is None:<EOL><INDENT>return jids[<NUM_LIT:0>]<EOL><DEDENT>for jid in jids:<EOL><INDENT>for domain in domains:<EOL><INDENT>if are_domains_equal(jid.domain, domain):<EOL><INDENT>return jid<EOL><DEDENT><DEDENT><DEDENT>return None<EOL>

Verify certificate for a client.

        Please note that `client_jid` is only a hint to choose from the names,
        other JID may be returned if `client_jid` is not included in the
        certificate.

        :Parameters:
            - `client_jid`: client name requested. May be `None` to allow
              any name in one of the `domains`.
            - `domains`: list of domains we can handle.
        :Types:
            - `client_jid`: `JID`
            - `domains`: `list` of `unicode`

        :Return: one of the jids in the certificate or `None` is no authorized
        name is found.


cert = cls()<EOL>try:<EOL><INDENT>data = ssl_socket.getpeercert()<EOL><DEDENT>except AttributeError:<EOL><INDENT>return cert<EOL><DEDENT>logger.debug("<STR_LIT>".format(data))<EOL>if not data:<EOL><INDENT>return cert<EOL><DEDENT>cert.validated = True<EOL>cert.subject_name = data.get('<STR_LIT>')<EOL>cert.alt_names = defaultdict(list)<EOL>if '<STR_LIT>' in data:<EOL><INDENT>for name, value in data['<STR_LIT>']:<EOL><INDENT>cert.alt_names[name].append(value)<EOL><DEDENT><DEDENT>if '<STR_LIT>' in data:<EOL><INDENT>tstamp = ssl.cert_time_to_seconds(data['<STR_LIT>'])<EOL>cert.not_after = datetime.utcfromtimestamp(tstamp)<EOL><DEDENT>if sys.version_info.major < <NUM_LIT:3>:<EOL><INDENT>cert._decode_names() <EOL><DEDENT>cert.common_names = []<EOL>if cert.subject_name:<EOL><INDENT>for part in cert.subject_name:<EOL><INDENT>for name, value in part:<EOL><INDENT>if name == '<STR_LIT>':<EOL><INDENT>cert.common_names.append(value)<EOL><DEDENT><DEDENT><DEDENT><DEDENT>return cert<EOL>

Load certificate data from an SSL socket.


if self.subject_name is not None:<EOL><INDENT>subject_name = []<EOL>for part in self.subject_name:<EOL><INDENT>new_part = []<EOL>for name, value in part:<EOL><INDENT>try:<EOL><INDENT>name = name.decode("<STR_LIT:utf-8>")<EOL>value = value.decode("<STR_LIT:utf-8>")<EOL><DEDENT>except UnicodeError:<EOL><INDENT>continue<EOL><DEDENT>new_part.append((name, value))<EOL><DEDENT>subject_name.append(tuple(new_part))<EOL><DEDENT>self.subject_name = tuple(subject_name)<EOL><DEDENT>for key, old in list(self.alt_names.items()):<EOL><INDENT>new = []<EOL>for name in old:<EOL><INDENT>try:<EOL><INDENT>name = name.decode("<STR_LIT:utf-8>")<EOL><DEDENT>except UnicodeError:<EOL><INDENT>continue<EOL><DEDENT>new.append(name)<EOL><DEDENT>self.alt_names[key] = new<EOL><DEDENT>

Decode names (hopefully ASCII or UTF-8) into Unicode.


try:<EOL><INDENT>data = ssl_socket.getpeercert(True)<EOL><DEDENT>except AttributeError:<EOL><INDENT>data = None<EOL><DEDENT>if not data:<EOL><INDENT>logger.debug("<STR_LIT>")<EOL>return cls()<EOL><DEDENT>result = cls.from_der_data(data)<EOL>result.validated = bool(ssl_socket.getpeercert())<EOL>return result<EOL>

Get certificate data from an SSL socket.


<EOL>logger.debug("<STR_LIT>".format(data))<EOL>if cls._cert_asn1_type is None:<EOL><INDENT>cls._cert_asn1_type = Certificate()<EOL><DEDENT>cert = der_decoder.decode(data, asn1Spec = cls._cert_asn1_type)[<NUM_LIT:0>]<EOL>result = cls()<EOL>tbs_cert = cert.getComponentByName('<STR_LIT>')<EOL>subject = tbs_cert.getComponentByName('<STR_LIT>')<EOL>logger.debug("<STR_LIT>".format(subject))<EOL>result._decode_subject(subject)<EOL>validity = tbs_cert.getComponentByName('<STR_LIT>')<EOL>result._decode_validity(validity)<EOL>extensions = tbs_cert.getComponentByName('<STR_LIT>')<EOL>if extensions:<EOL><INDENT>for extension in extensions:<EOL><INDENT>logger.debug("<STR_LIT>".format(extension))<EOL>oid = extension.getComponentByName('<STR_LIT>')<EOL>logger.debug("<STR_LIT>".format(oid))<EOL>if oid != SUBJECT_ALT_NAME_OID:<EOL><INDENT>continue<EOL><DEDENT>value = extension.getComponentByName('<STR_LIT>')<EOL>logger.debug("<STR_LIT>".format(value))<EOL>if isinstance(value, Any):<EOL><INDENT>value = der_decoder.decode(value,<EOL>asn1Spec = OctetString())[<NUM_LIT:0>]<EOL><DEDENT>alt_names = der_decoder.decode(value,<EOL>asn1Spec = GeneralNames())[<NUM_LIT:0>]<EOL>logger.debug("<STR_LIT>".format(alt_names))<EOL>result._decode_alt_names(alt_names)<EOL><DEDENT><DEDENT>return result<EOL>

Decode DER-encoded certificate.

        :Parameters:
            - `data`: the encoded certificate
        :Types:
            - `data`: `bytes`

        :Return: decoded certificate data
        :Returntype: ASN1CertificateData


self.common_names = []<EOL>subject_name = []<EOL>for rdnss in subject:<EOL><INDENT>for rdns in rdnss:<EOL><INDENT>rdnss_list = []<EOL>for nameval in rdns:<EOL><INDENT>val_type = nameval.getComponentByName('<STR_LIT:type>')<EOL>value = nameval.getComponentByName('<STR_LIT:value>')<EOL>if val_type not in DN_OIDS:<EOL><INDENT>logger.debug("<STR_LIT>".format(val_type))<EOL>continue<EOL><DEDENT>val_type = DN_OIDS[val_type]<EOL>value = der_decoder.decode(value,<EOL>asn1Spec = DirectoryString())[<NUM_LIT:0>]<EOL>value = value.getComponent()<EOL>try:<EOL><INDENT>value = _decode_asn1_string(value)<EOL><DEDENT>except UnicodeError:<EOL><INDENT>logger.debug("<STR_LIT>".format(value))<EOL>continue<EOL><DEDENT>if val_type == "<STR_LIT>":<EOL><INDENT>self.common_names.append(value)<EOL><DEDENT>rdnss_list.append((val_type, value))<EOL><DEDENT>subject_name.append(tuple(rdnss_list))<EOL><DEDENT><DEDENT>self.subject_name = tuple(subject_name)<EOL>


not_after = validity.getComponentByName('<STR_LIT>')<EOL>not_after = str(not_after.getComponent())<EOL>if isinstance(not_after, GeneralizedTime):<EOL><INDENT>self.not_after = datetime.strptime(not_after, "<STR_LIT>")<EOL><DEDENT>else:<EOL><INDENT>self.not_after = datetime.strptime(not_after, "<STR_LIT>")<EOL><DEDENT>self.alt_names = defaultdict(list)<EOL>


for alt_name in alt_names:<EOL><INDENT>tname = alt_name.getName()<EOL>comp = alt_name.getComponent()<EOL>if tname == "<STR_LIT>":<EOL><INDENT>key = "<STR_LIT>"<EOL>value = _decode_asn1_string(comp)<EOL><DEDENT>elif tname == "<STR_LIT>":<EOL><INDENT>key = "<STR_LIT>"<EOL>value = _decode_asn1_string(comp)<EOL><DEDENT>elif tname == "<STR_LIT>":<EOL><INDENT>oid = comp.getComponentByName("<STR_LIT>")<EOL>value = comp.getComponentByName("<STR_LIT:value>")<EOL>if oid == XMPPADDR_OID:<EOL><INDENT>key = "<STR_LIT>"<EOL>value = der_decoder.decode(value,<EOL>asn1Spec = UTF8String())[<NUM_LIT:0>]<EOL>value = _decode_asn1_string(value)<EOL><DEDENT>elif oid == SRVNAME_OID:<EOL><INDENT>key = "<STR_LIT>"<EOL>value = der_decoder.decode(value,<EOL>asn1Spec = IA5String())[<NUM_LIT:0>]<EOL>value = _decode_asn1_string(value)<EOL><DEDENT>else:<EOL><INDENT>logger.debug("<STR_LIT>".format(oid))<EOL>continue<EOL><DEDENT><DEDENT>else:<EOL><INDENT>logger.debug("<STR_LIT>"<EOL>.format(tname))<EOL>continue<EOL><DEDENT>self.alt_names[key].append(value)<EOL><DEDENT>

Load SubjectAltName from a ASN.1 GeneralNames value.

        :Values:
            - `alt_names`: the SubjectAltNama extension value
        :Types:
            - `alt_name`: `GeneralNames`


with open(filename, "<STR_LIT:r>") as pem_file:<EOL><INDENT>data = pem.readPemFromFile(pem_file)<EOL><DEDENT>return cls.from_der_data(data)<EOL>


def __init__(self, element = None, from_jid = None, to_jid = None,<EOL>stanza_type = None, stanza_id = None,<EOL>error = None, error_cond = None, return_path = None,<EOL>language = None,<EOL>show = None, status = None, priority = None):

<EOL>self._show = None<EOL>self._status = None<EOL>self._priority = <NUM_LIT:0><EOL>if element is None:<EOL><INDENT>element = "<STR_LIT>"<EOL><DEDENT>elif not isinstance(element, ElementClass):<EOL><INDENT>raise TypeError("<STR_LIT>" + repr(element))<EOL><DEDENT>if stanza_type is not None and stanza_type not in PRESENCE_TYPES:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>elif stanza_type == '<STR_LIT>':<EOL><INDENT>stanza_type = None<EOL><DEDENT>Stanza.__init__(self, element, from_jid = from_jid, to_jid = to_jid,<EOL>stanza_type = stanza_type, stanza_id = stanza_id,<EOL>error = error, error_cond = error_cond,<EOL>return_path = return_path, language = language)<EOL>if self.element_name != "<STR_LIT>":<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>self._show_tag = self._ns_prefix + "<STR_LIT>"<EOL>self._status_tag = self._ns_prefix + "<STR_LIT:status>"<EOL>self._priority_tag = self._ns_prefix + "<STR_LIT>"<EOL>if self._element is not None:<EOL><INDENT>self._decode_subelements()<EOL><DEDENT>if show is not None:<EOL><INDENT>self.show = show<EOL><DEDENT>if status is not None:<EOL><INDENT>self.status = status<EOL><DEDENT>if priority is not None:<EOL><INDENT>self.priority = priority<EOL><DEDENT>

Initialize a `Presence` object.

        :Parameters:
            - `element`: XML element
            - `from_jid`: sender JID.
            - `to_jid`: recipient JID.
            - `stanza_type`: staza type: one of: None, "available",
              "unavailable", "subscribe", "subscribed", "unsubscribe",
              "unsubscribed" or "error". "available" is automaticaly changed to
              None.
            - `stanza_id`: stanza id -- value of stanza's "id" attribute
            - `language`: default language for the stanza content
            - `show`: "show" field of presence stanza. One of: None, "away",
              "xa", "dnd", "chat".
            - `status`: descriptive text for the presence stanza.
            - `priority`: presence priority.
            - `error_cond`: error condition name. Ignored if `stanza_type` is
              not "error"
        :Types:
            - `element`: :etree:`ElementTree.Element`
            - `from_jid`: `JID`
            - `to_jid`: `JID`
            - `stanza_type`: `unicode`
            - `stanza_id`: `unicode`
            - `language`: `unicode`
            - `show`: `unicode`
            - `status`: `unicode`
            - `priority`: `int`
            - `error_cond`: `unicode`


for child in self._element:<EOL><INDENT>if child.tag == self._show_tag:<EOL><INDENT>self._show = child.text<EOL><DEDENT>elif child.tag == self._status_tag:<EOL><INDENT>self._status = child.text<EOL><DEDENT>elif child.tag == self._priority_tag:<EOL><INDENT>try:<EOL><INDENT>self._priority = int(child.text.strip())<EOL>if self._priority < -<NUM_LIT> or self._priority > <NUM_LIT>:<EOL><INDENT>raise ValueError<EOL><DEDENT><DEDENT>except ValueError:<EOL><INDENT>raise BadRequestProtocolError(<EOL>"<STR_LIT>")<EOL><DEDENT><DEDENT><DEDENT>


result = Stanza.as_xml(self)<EOL>if self._show:<EOL><INDENT>child = ElementTree.SubElement(result, self._show_tag)<EOL>child.text = self._show<EOL><DEDENT>if self._status:<EOL><INDENT>child = ElementTree.SubElement(result, self._status_tag)<EOL>child.text = self._status<EOL><DEDENT>if self._priority:<EOL><INDENT>child = ElementTree.SubElement(result, self._priority_tag)<EOL>child.text = unicode(self._priority)<EOL><DEDENT>return result<EOL>

Return the XML stanza representation.

        Always return an independent copy of the stanza XML representation,
        which can be freely modified without affecting the stanza.

        :returntype: :etree:`ElementTree.Element`


result = Presence(None, self.from_jid, self.to_jid,<EOL>self.stanza_type, self.stanza_id, self.error,<EOL>self._return_path(),<EOL>self._show, self._status, self._priority)<EOL>if self._payload is None:<EOL><INDENT>self.decode_payload()<EOL><DEDENT>for payload in self._payload:<EOL><INDENT>result.add_payload(payload.copy())<EOL><DEDENT>return result<EOL>

Create a deep copy of the stanza.

        :returntype: `Presence`


return self._show<EOL>

Presence status type.

        :returntype: `unicode`


return self._status<EOL>

Presence status message.

        :returntype: `unicode`


return self._priority<EOL>

Presence priority.

        :returntype: `unicode`


if self.stanza_type not in ("<STR_LIT>", "<STR_LIT>",<EOL>"<STR_LIT>", "<STR_LIT>"):<EOL><INDENT>raise ValueError("<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT>stanza = Presence(stanza_type = ACCEPT_RESPONSES[self.stanza_type],<EOL>from_jid = self.to_jid, to_jid = self.from_jid,<EOL>stanza_id = self.stanza_id)<EOL>return stanza<EOL>

Create "accept" response for the "subscribe" / "subscribed" /
        "unsubscribe" / "unsubscribed" presence stanza.

        :return: new stanza.
        :returntype: `Presence`


if self.stanza_type not in ("<STR_LIT>", "<STR_LIT>",<EOL>"<STR_LIT>", "<STR_LIT>"):<EOL><INDENT>raise ValueError("<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT>stanza = Presence(stanza_type = DENY_RESPONSES[self.stanza_type],<EOL>from_jid = self.to_jid, to_jid = self.from_jid,<EOL>stanza_id = self.stanza_id)<EOL>return stanza<EOL>

Create "deny" response for the "subscribe" / "subscribed" /
        "unsubscribe" / "unsubscribed" presence stanza.

        :return: new presence stanza.
        :returntype: `Presence`


if self.stanza_type == "<STR_LIT:error>":<EOL><INDENT>raise ValueError("<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT>stanza = Presence(stanza_type = "<STR_LIT:error>", from_jid = self.from_jid,<EOL>to_jid = self.to_jid, stanza_id = self.stanza_id,<EOL>status = self._status, show = self._show,<EOL>priority = self._priority, error_cond = cond)<EOL>if self._payload is None:<EOL><INDENT>self.decode_payload()<EOL><DEDENT>for payload in self._payload:<EOL><INDENT>stanza.add_payload(payload)<EOL><DEDENT>return stanza<EOL>

Create error response for the any non-error presence stanza.

        :Parameters:
            - `cond`: error condition name, as defined in XMPP specification.
        :Types:
            - `cond`: `unicode`

        :return: new presence stanza.
        :returntype: `Presence`


return EVIL_CHARACTERS_RE.sub("<STR_LIT>", data)<EOL>

Remove control characters (not allowed in XML) from a string.


if getattr(_THREAD, "<STR_LIT>", None) is None:<EOL><INDENT>_THREAD.serializer = XMPPSerializer("<STR_LIT>")<EOL>_THREAD.serializer.emit_head(None, None)<EOL><DEDENT>return _THREAD.serializer.emit_stanza(element)<EOL>

Serialize an XMPP element.

    Utility function for debugging or logging.

        :Parameters:
            - `element`: the element to serialize
        :Types:
            - `element`: :etree:`ElementTree.Element`

        :Return: serialized element
        :Returntype: `unicode`


def __init__(self, stanza_namespace, extra_prefixes = None):

self.stanza_namespace = stanza_namespace<EOL>self._prefixes = {}<EOL>if extra_prefixes:<EOL><INDENT>self._prefixes.update(extra_prefixes)<EOL><DEDENT>self._root_prefixes = None<EOL>self._head_emitted = False<EOL>self._next_id = <NUM_LIT:1><EOL>

:Parameters:
    - `stanza_namespace`: the default namespace used for XMPP stanzas.
      E.g. 'jabber:client' for c2s connections.
    - `extra_prefixes`: mapping of namespaces to prefixes (not the
      other way) to be used on the stream. These prefixes will be
      declared on the root element and used in all descendants. That
      may be used to optimize the stream for size.
:Types:
    - `stanza_namespace`: `unicode`
    - `extra_prefixes`: `unicode` to `unicode` mapping.


def add_prefix(self, namespace, prefix):

if prefix == "<STR_LIT>" and namespace != XML_NS:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>self._prefixes[namespace] = prefix<EOL>

Add a new namespace prefix.

        If the root element has not yet been emitted the prefix will
        be declared there, otherwise the prefix will be declared on the
        top-most element using this namespace in every stanza.

        :Parameters:
            - `namespace`: the namespace URI
            - `prefix`: the prefix string
        :Types:
            - `namespace`: `unicode`
            - `prefix`: `unicode`


def emit_head(self, stream_from, stream_to, stream_id = None,<EOL>version = '<STR_LIT:1.0>', language = None):

<EOL>self._root_prefixes = dict(STANDARD_PREFIXES)<EOL>self._root_prefixes[self.stanza_namespace] = None<EOL>for namespace, prefix in list(self._root_prefixes.items()):<EOL><INDENT>if not prefix or prefix == "<STR_LIT>":<EOL><INDENT>continue<EOL><DEDENT>if namespace in STANDARD_PREFIXES or namespace in STANZA_NAMESPACES:<EOL><INDENT>continue<EOL><DEDENT>self._root_prefixes[namespace] = prefix<EOL><DEDENT>tag = "<STR_LIT>".format(STANDARD_PREFIXES[STREAM_NS],<EOL>quoteattr(version))<EOL>if stream_from:<EOL><INDENT>tag += "<STR_LIT>".format(quoteattr(stream_from))<EOL><DEDENT>if stream_to:<EOL><INDENT>tag += "<STR_LIT>".format(quoteattr(stream_to))<EOL><DEDENT>if stream_id is not None:<EOL><INDENT>tag += "<STR_LIT>".format(quoteattr(stream_id))<EOL><DEDENT>if language is not None:<EOL><INDENT>tag += "<STR_LIT>".format(quoteattr(language))<EOL><DEDENT>for namespace, prefix in list(self._root_prefixes.items()):<EOL><INDENT>if prefix == "<STR_LIT>":<EOL><INDENT>continue<EOL><DEDENT>if prefix:<EOL><INDENT>tag += '<STR_LIT>'.format(prefix, quoteattr(namespace))<EOL><DEDENT>else:<EOL><INDENT>tag += '<STR_LIT>'.format(prefix, quoteattr(namespace))<EOL><DEDENT><DEDENT>tag += "<STR_LIT:>>"<EOL>self._head_emitted = True<EOL>return tag<EOL>

Return the opening tag of the stream root element.

        :Parameters:
            - `stream_from`: the 'from' attribute of the stream. May be `None`.
            - `stream_to`: the 'to' attribute of the stream. May be `None`.
            - `version`: the 'version' of the stream.
            - `language`: the 'xml:lang' of the stream
        :Types:
            - `stream_from`: `unicode`
            - `stream_to`: `unicode`
            - `version`: `unicode`
            - `language`: `unicode`


return "<STR_LIT>".format(self._root_prefixes[STREAM_NS])<EOL>

Return the end tag of the stream root element.


def _split_qname(self, name, is_element):

if name.startswith("<STR_LIT:{>"):<EOL><INDENT>namespace, name = name[<NUM_LIT:1>:].split("<STR_LIT:}>", <NUM_LIT:1>)<EOL>if namespace in STANZA_NAMESPACES:<EOL><INDENT>namespace = self.stanza_namespace<EOL><DEDENT><DEDENT>elif is_element:<EOL><INDENT>raise ValueError("<STR_LIT>".format(name))<EOL><DEDENT>else:<EOL><INDENT>namespace = None<EOL><DEDENT>return namespace, name<EOL>

Split an element of attribute qname into namespace and local
        name.

        :Parameters:
            - `name`: element or attribute QName
            - `is_element`: `True` for an element, `False` for an attribute
        :Types:
            - `name`: `unicode`
            - `is_element`: `bool`

        :Return: namespace URI, local name
        :returntype: `unicode`, `unicode`


used_prefixes = set(self._prefixes.values())<EOL>used_prefixes |= set(declared_prefixes.values())<EOL>while True:<EOL><INDENT>prefix = "<STR_LIT>".format(self._next_id)<EOL>self._next_id += <NUM_LIT:1><EOL>if prefix not in used_prefixes:<EOL><INDENT>break<EOL><DEDENT><DEDENT>return prefix<EOL>

Make up a new namespace prefix, which won't conflict
        with `_prefixes` and prefixes declared in the current scope.

        :Parameters:
            - `declared_prefixes`: namespace to prefix mapping for the current
              scope
        :Types:
            - `declared_prefixes`: `unicode` to `unicode` dictionary

        :Returns: a new prefix
        :Returntype: `unicode`


def _make_prefixed(self, name, is_element, declared_prefixes, declarations):

namespace, name = self._split_qname(name, is_element)<EOL>if namespace is None:<EOL><INDENT>prefix = None<EOL><DEDENT>elif namespace in declared_prefixes:<EOL><INDENT>prefix = declared_prefixes[namespace]<EOL><DEDENT>elif namespace in self._prefixes:<EOL><INDENT>prefix = self._prefixes[namespace]<EOL>declarations[namespace] = prefix<EOL>declared_prefixes[namespace] = prefix<EOL><DEDENT>else:<EOL><INDENT>if is_element:<EOL><INDENT>prefix = None<EOL><DEDENT>else:<EOL><INDENT>prefix = self._make_prefix(declared_prefixes)<EOL><DEDENT>declarations[namespace] = prefix<EOL>declared_prefixes[namespace] = prefix<EOL><DEDENT>if prefix:<EOL><INDENT>return prefix + "<STR_LIT::>" + name<EOL><DEDENT>else:<EOL><INDENT>return name<EOL><DEDENT>

Return namespace-prefixed tag or attribute name.

        Add appropriate declaration to `declarations` when neccessary.

        If no prefix for an element namespace is defined, make the elements
        namespace default (no prefix). For attributes, make up a prefix in such
        case.

        :Parameters:
            - `name`: QName ('{namespace-uri}local-name')
              to convert
            - `is_element`: `True` for element, `False` for an attribute
            - `declared_prefixes`: mapping of prefixes already declared
              at this scope
            - `declarations`: XMLNS declarations on the current element.
        :Types:
            - `name`: `unicode`
            - `is_element`: `bool`
            - `declared_prefixes`: `unicode` to `unicode` dictionary
            - `declarations`: `unicode` to `unicode` dictionary

        :Returntype: `unicode`


result = []<EOL>for namespace, prefix in list(declarations.items()):<EOL><INDENT>if prefix:<EOL><INDENT>result.append('<STR_LIT>'.format(prefix, quoteattr(<EOL>namespace)))<EOL><DEDENT>else:<EOL><INDENT>result.append('<STR_LIT>'.format(prefix, quoteattr(<EOL>namespace)))<EOL><DEDENT>for d_namespace, d_prefix in list(declared_prefixes.items()):<EOL><INDENT>if (not prefix and not d_prefix) or d_prefix == prefix:<EOL><INDENT>if namespace != d_namespace:<EOL><INDENT>del declared_prefixes[d_namespace]<EOL><DEDENT><DEDENT><DEDENT><DEDENT>return "<STR_LIT:U+0020>".join(result)<EOL>

Build namespace declarations and remove obsoleted mappings
        from `declared_prefixes`.

        :Parameters:
            - `declarations`: namespace to prefix mapping of the new
              declarations
            - `declared_prefixes`: namespace to prefix mapping of already
              declared prefixes.
        :Types:
            - `declarations`: `unicode` to `unicode` dictionary
            - `declared_prefixes`: `unicode` to `unicode` dictionary

        :Return: string of namespace declarations to be used in a start tag
        :Returntype: `unicode`


def _emit_element(self, element, level, declared_prefixes):

declarations = {}<EOL>declared_prefixes = dict(declared_prefixes)<EOL>name = element.tag<EOL>prefixed = self._make_prefixed(name, True, declared_prefixes,<EOL>declarations)<EOL>start_tag = "<STR_LIT>".format(prefixed)<EOL>end_tag = "<STR_LIT>".format(prefixed)<EOL>for name, value in list(element.items()):<EOL><INDENT>prefixed = self._make_prefixed(name, False, declared_prefixes,<EOL>declarations)<EOL>start_tag += '<STR_LIT>'.format(prefixed, quoteattr(value))<EOL><DEDENT>declarations = self._make_ns_declarations(declarations,<EOL>declared_prefixes)<EOL>if declarations:<EOL><INDENT>start_tag += "<STR_LIT:U+0020>" + declarations<EOL><DEDENT>children = []<EOL>for child in element:<EOL><INDENT>children.append(self._emit_element(child, level +<NUM_LIT:1>,<EOL>declared_prefixes))<EOL><DEDENT>if not children and not element.text:<EOL><INDENT>start_tag += "<STR_LIT>"<EOL>end_tag = "<STR_LIT>"<EOL>text = "<STR_LIT>"<EOL><DEDENT>else:<EOL><INDENT>start_tag += "<STR_LIT:>>"<EOL>if level > <NUM_LIT:0> and element.text:<EOL><INDENT>text = escape(element.text)<EOL><DEDENT>else:<EOL><INDENT>text = "<STR_LIT>"<EOL><DEDENT><DEDENT>if level > <NUM_LIT:1> and element.tail:<EOL><INDENT>tail = escape(element.tail)<EOL><DEDENT>else:<EOL><INDENT>tail = "<STR_LIT>"<EOL><DEDENT>return start_tag + text + '<STR_LIT>'.join(children) + end_tag + tail<EOL>

Recursive XML element serializer.

        :Parameters:
            - `element`: the element to serialize
            - `level`: nest level (0 - root element, 1 - stanzas, etc.)
            - `declared_prefixes`: namespace to prefix mapping of already
              declared prefixes.
        :Types:
            - `element`: :etree:`ElementTree.Element`
            - `level`: `int`
            - `declared_prefixes`: `unicode` to `unicode` dictionary

        :Return: serialized element
        :Returntype: `unicode`


if not self._head_emitted:<EOL><INDENT>raise RuntimeError("<STR_LIT>")<EOL><DEDENT>string = self._emit_element(element, level = <NUM_LIT:1>,<EOL>declared_prefixes = self._root_prefixes)<EOL>return remove_evil_characters(string)<EOL>

Serialize a stanza.

        Must be called after `emit_head`.

        :Parameters:
            - `element`: the element to serialize
        :Types:
            - `element`: :etree:`ElementTree.Element`

        :Return: serialized element
        :Returntype: `unicode`


self.thread.start()<EOL>


return self.thread.is_alive()<EOL>


self._quit = True<EOL>


return self.thread.join(timeout)<EOL>


logger.debug("<STR_LIT>".format(self.name))<EOL>while True:<EOL><INDENT>try:<EOL><INDENT>self.run()<EOL><DEDENT>except Exception: <EOL><INDENT>self.exc_info = sys.exc_info()<EOL>logger.debug("<STR_LIT>"<EOL>.format(self.name), exc_info = self.exc_info)<EOL>if self.exc_queue:<EOL><INDENT>self.exc_queue.put( (self, self.exc_info) )<EOL>continue<EOL><DEDENT>else:<EOL><INDENT>logger.debug("<STR_LIT>".format(self.name))<EOL>return<EOL><DEDENT><DEDENT>except:<EOL><INDENT>logger.debug("<STR_LIT>".format(self.name))<EOL>return<EOL><DEDENT>break<EOL><DEDENT>logger.debug("<STR_LIT>".format(self.name))<EOL>

The thread function. Calls `self.run()` in loop and if it raises an
        exception, stores it in self.exc_queue. If `exc_queue` is None
        the exception will abort the thread.


raise NotImplementedError<EOL>


<EOL>interval = self.settings["<STR_LIT>"]<EOL>prepared = False<EOL>timeout = <NUM_LIT:0.1><EOL>while not self._quit:<EOL><INDENT>if not prepared:<EOL><INDENT>logger.debug("<STR_LIT>".format(<EOL>self.name, self.io_handler))<EOL>ret = self.io_handler.prepare()<EOL>logger.debug("<STR_LIT>".format(self.name,<EOL>ret))<EOL>if isinstance(ret, HandlerReady):<EOL><INDENT>prepared = True<EOL><DEDENT>elif isinstance(ret, PrepareAgain):<EOL><INDENT>if ret.timeout is not None:<EOL><INDENT>timeout = ret.timeout<EOL><DEDENT><DEDENT>else:<EOL><INDENT>raise TypeError("<STR_LIT>")<EOL><DEDENT><DEDENT>if self.io_handler.is_readable():<EOL><INDENT>logger.debug("<STR_LIT>".format(self.name))<EOL>fileno = self.io_handler.fileno()<EOL>if fileno is not None:<EOL><INDENT>readable = wait_for_read(fileno, interval)<EOL>if readable:<EOL><INDENT>self.io_handler.handle_read()<EOL><DEDENT><DEDENT><DEDENT>elif not prepared:<EOL><INDENT>if timeout:<EOL><INDENT>time.sleep(timeout)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>logger.debug("<STR_LIT>".format(self.name))<EOL>if not self.io_handler.wait_for_readability():<EOL><INDENT>break<EOL><DEDENT><DEDENT><DEDENT>

The thread function.

        First, call the handler's 'prepare' method until it returns
        `HandlerReady` then loop waiting for the socket input and calling
        'handle_read' on the handler.


while not self._quit:<EOL><INDENT>interval = self.settings["<STR_LIT>"]<EOL>if self.io_handler.is_writable():<EOL><INDENT>logger.debug("<STR_LIT>".format(self.name))<EOL>fileno = self.io_handler<EOL>if fileno:<EOL><INDENT>writable = wait_for_write(fileno, interval)<EOL>if writable:<EOL><INDENT>self.io_handler.handle_write()<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>logger.debug("<STR_LIT>".format(self.name))<EOL>if not self.io_handler.wait_for_writability():<EOL><INDENT>break<EOL><DEDENT><DEDENT><DEDENT>

The thread function.

        Loop waiting for the handler and socket being writable and calling
        `interfaces.IOHandler.handle_write`.


logger.debug("<STR_LIT>".format(self.name))<EOL>while True:<EOL><INDENT>try:<EOL><INDENT>self.event_dispatcher.loop()<EOL><DEDENT>except Exception: <EOL><INDENT>self.exc_info = sys.exc_info()<EOL>logger.debug("<STR_LIT>"<EOL>.format(self.name), exc_info = self.exc_info)<EOL>if self.exc_queue:<EOL><INDENT>self.exc_queue.put( (self, self.exc_info) )<EOL>continue<EOL><DEDENT>else:<EOL><INDENT>logger.debug("<STR_LIT>".format(self.name))<EOL>return<EOL><DEDENT><DEDENT>except:<EOL><INDENT>logger.debug("<STR_LIT>".format(self.name))<EOL>return<EOL><DEDENT>break<EOL><DEDENT>logger.debug("<STR_LIT>".format(self.name))<EOL>

The thread function. Calls `self.run()` and if it raises
        an exception, stores it in self.exc_info and exc_queue


The thread function. Calls `self.run()` and if it raises
        an exception, stores it in self.exc_info


<EOL>timeout = self.method._pyxmpp_timeout<EOL>recurring = self.method._pyxmpp_recurring<EOL>while not self._quit and timeout is not None:<EOL><INDENT>if timeout:<EOL><INDENT>time.sleep(timeout)<EOL><DEDENT>if self._quit:<EOL><INDENT>break<EOL><DEDENT>ret = self.method()<EOL>if recurring is None:<EOL><INDENT>timeout = ret<EOL><DEDENT>elif not recurring:<EOL><INDENT>break<EOL><DEDENT><DEDENT>


self.io_handlers.append(handler)<EOL>if self.event_thread is None:<EOL><INDENT>return<EOL><DEDENT>


reader = ReadingThread(self.settings, handler, daemon = self.daemon,<EOL>exc_queue = self.exc_queue)<EOL>writter = WrittingThread(self.settings, handler, daemon = self.daemon,<EOL>exc_queue = self.exc_queue)<EOL>self.io_threads += [reader, writter]<EOL>reader.start()<EOL>writter.start()<EOL>


if handler not in self.io_handlers:<EOL><INDENT>return<EOL><DEDENT>self.io_handlers.remove(handler)<EOL>for thread in self.io_threads:<EOL><INDENT>if thread.io_handler is handler:<EOL><INDENT>thread.stop()<EOL><DEDENT><DEDENT>


self.timeout_handlers.append(handler)<EOL>if self.event_thread is None:<EOL><INDENT>return<EOL><DEDENT>self._run_timeout_threads(handler)<EOL>


<EOL>for dummy, method in inspect.getmembers(handler, callable):<EOL><INDENT>if not hasattr(method, "<STR_LIT>"):<EOL><INDENT>continue<EOL><DEDENT>thread = TimeoutThread(method, daemon = self.daemon,<EOL>exc_queue = self.exc_queue)<EOL>self.timeout_threads.append(thread)<EOL>thread.start()<EOL><DEDENT>


if handler not in self.timeout_handlers:<EOL><INDENT>return<EOL><DEDENT>self.timeout_handlers.remove(handler)<EOL>for thread in self.timeout_threads:<EOL><INDENT>if thread.method.__self__ is handler:<EOL><INDENT>thread.stop()<EOL><DEDENT><DEDENT>


self.daemon = daemon<EOL>self.io_threads = []<EOL>self.event_thread = EventDispatcherThread(self.event_dispatcher,<EOL>daemon = daemon, exc_queue = self.exc_queue)<EOL>self.event_thread.start()<EOL>for handler in self.io_handlers:<EOL><INDENT>self._run_io_threads(handler)<EOL><DEDENT>for handler in self.timeout_handlers:<EOL><INDENT>self._run_timeout_threads(handler)<EOL><DEDENT>


def stop(self, join = False, timeout = None):

logger.debug("<STR_LIT>")<EOL>for handler in self.io_handlers:<EOL><INDENT>handler.close()<EOL><DEDENT>if self.event_thread and self.event_thread.is_alive():<EOL><INDENT>logger.debug("<STR_LIT>")<EOL>self.event_queue.put(QUIT)<EOL><DEDENT>logger.debug("<STR_LIT>")<EOL>threads = self.io_threads + self.timeout_threads<EOL>for thread in threads:<EOL><INDENT>logger.debug("<STR_LIT>".format(thread))<EOL>thread.stop()<EOL><DEDENT>if not join:<EOL><INDENT>return<EOL><DEDENT>if self.event_thread:<EOL><INDENT>threads.append(self.event_thread)<EOL><DEDENT>if timeout is None:<EOL><INDENT>for thread in threads:<EOL><INDENT>thread.join()<EOL><DEDENT><DEDENT>else:<EOL><INDENT>timeout1 = (timeout * <NUM_LIT>) / len(threads)<EOL>threads_left = []<EOL>for thread in threads:<EOL><INDENT>logger.debug("<STR_LIT>".format(thread))<EOL>thread.join(timeout1)<EOL>if thread.is_alive():<EOL><INDENT>logger.debug("<STR_LIT>".format(thread))<EOL>threads_left.append(thread)<EOL><DEDENT><DEDENT>if threads_left:<EOL><INDENT>timeout2 = (timeout * <NUM_LIT>) / len(threads_left)<EOL>for thread in threads_left:<EOL><INDENT>logger.debug("<STR_LIT>".format(thread))<EOL>thread.join(timeout2)<EOL><DEDENT><DEDENT><DEDENT>self.io_threads = []<EOL>self.event_thread = None<EOL>

Stop the threads.

        :Parameters:
            - `join`: join the threads (wait until they exit)
            - `timeout`: maximum time (in seconds) to wait when `join` is
              `True`).  No limit when `timeout` is `None`.


def loop_iteration(self, timeout = <NUM_LIT:0.1>):

try:<EOL><INDENT>exc_info = self.exc_queue.get(True, timeout)[<NUM_LIT:1>]<EOL><DEDENT>except queue.Empty:<EOL><INDENT>return<EOL><DEDENT>exc_type, exc_value, ext_stack = exc_info<EOL>raise exc_type(exc_value).with_traceback(ext_stack)<EOL>

Wait up to `timeout` seconds, raise any exception from the
        threads.


self._unprepared_handlers[handler] = None<EOL>self._configure_io_handler(handler)<EOL>


if self.check_events():<EOL><INDENT>return<EOL><DEDENT>if handler in self._unprepared_handlers:<EOL><INDENT>old_fileno = self._unprepared_handlers[handler]<EOL>prepared = self._prepare_io_handler(handler)<EOL><DEDENT>else:<EOL><INDENT>old_fileno = None<EOL>prepared = True<EOL><DEDENT>fileno = handler.fileno()<EOL>if old_fileno is not None and fileno != old_fileno:<EOL><INDENT>del self._handlers[old_fileno]<EOL>try:<EOL><INDENT>self.poll.unregister(old_fileno)<EOL><DEDENT>except KeyError:<EOL><INDENT>pass<EOL><DEDENT><DEDENT>if not prepared:<EOL><INDENT>self._unprepared_handlers[handler] = fileno<EOL><DEDENT>if not fileno:<EOL><INDENT>return<EOL><DEDENT>self._handlers[fileno] = handler<EOL>events = <NUM_LIT:0><EOL>if handler.is_readable():<EOL><INDENT>logger.debug("<STR_LIT>".format(handler))<EOL>events |= select.POLLIN<EOL><DEDENT>if handler.is_writable():<EOL><INDENT>logger.debug("<STR_LIT>".format(handler))<EOL>events |= select.POLLOUT<EOL><DEDENT>if events:<EOL><INDENT>logger.debug("<STR_LIT>"<EOL>"<STR_LIT>".format(handler, fileno, events))<EOL>self.poll.register(fileno, events)<EOL><DEDENT>

Register an io-handler at the polling object.


logger.debug("<STR_LIT>".format(handler))<EOL>ret = handler.prepare()<EOL>logger.debug("<STR_LIT>".format(ret))<EOL>if isinstance(ret, HandlerReady):<EOL><INDENT>del self._unprepared_handlers[handler]<EOL>prepared = True<EOL><DEDENT>elif isinstance(ret, PrepareAgain):<EOL><INDENT>if ret.timeout is not None:<EOL><INDENT>if self._timeout is not None:<EOL><INDENT>self._timeout = min(self._timeout, ret.timeout)<EOL><DEDENT>else:<EOL><INDENT>self._timeout = ret.timeout<EOL><DEDENT><DEDENT>prepared = False<EOL><DEDENT>else:<EOL><INDENT>raise TypeError("<STR_LIT>")<EOL><DEDENT>return prepared<EOL>

Call the `interfaces.IOHandler.prepare` method and
        remove the handler from unprepared handler list when done.


if handler in self._unprepared_handlers:<EOL><INDENT>old_fileno = self._unprepared_handlers[handler]<EOL>del self._unprepared_handlers[handler]<EOL><DEDENT>else:<EOL><INDENT>old_fileno = handler.fileno()<EOL><DEDENT>if old_fileno is not None:<EOL><INDENT>try:<EOL><INDENT>del self._handlers[old_fileno]<EOL>self.poll.unregister(old_fileno)<EOL><DEDENT>except KeyError:<EOL><INDENT>pass<EOL><DEDENT><DEDENT>


def loop_iteration(self, timeout = <NUM_LIT>):

next_timeout, sources_handled = self._call_timeout_handlers()<EOL>if self._quit:<EOL><INDENT>return sources_handled<EOL><DEDENT>if self._timeout is not None:<EOL><INDENT>timeout = min(timeout, self._timeout)<EOL><DEDENT>if next_timeout is not None:<EOL><INDENT>timeout = min(next_timeout, timeout)<EOL><DEDENT>for handler in list(self._unprepared_handlers):<EOL><INDENT>self._configure_io_handler(handler)<EOL><DEDENT>events = self.poll.poll(timeout * <NUM_LIT:1000>)<EOL>self._timeout = None<EOL>for (fileno, event) in events:<EOL><INDENT>if event & select.POLLHUP:<EOL><INDENT>self._handlers[fileno].handle_hup()<EOL><DEDENT>if event & select.POLLNVAL:<EOL><INDENT>self._handlers[fileno].handle_nval()<EOL><DEDENT>if event & select.POLLIN:<EOL><INDENT>self._handlers[fileno].handle_read()<EOL><DEDENT>elif event & select.POLLERR:<EOL><INDENT>self._handlers[fileno].handle_err()<EOL><DEDENT>if event & select.POLLOUT:<EOL><INDENT>self._handlers[fileno].handle_write()<EOL><DEDENT>sources_handled += <NUM_LIT:1><EOL>self._configure_io_handler(self._handlers[fileno])<EOL><DEDENT>return sources_handled<EOL>

A loop iteration - check any scheduled events
        and I/O available and run the handlers.


def decorator(func):<EOL><INDENT>"""<STR_LIT>"""<EOL>func._pyxmpp_event_handled = event_class<EOL>return func<EOL><DEDENT>return decorator<EOL>

Method decorator generator for decorating event handlers.

    To be used on `EventHandler` subclass methods only.

    Such methods may return:
        - `True`: if they 'completely' handled the event and no more events
          should be called (use with care)
        - `QUIT`: to quit the main loop. Other handlers still will be called
          for current event and nother events in the queue.

    :Parameters:
        - `event_class`: event class expected
    :Types:
        - `event_class`: subclass of `Event`


def timeout_handler(interval, recurring = None):

def decorator(func):<EOL><INDENT>"""<STR_LIT>"""<EOL>func._pyxmpp_timeout = interval<EOL>func._pyxmpp_recurring = recurring<EOL>return func<EOL><DEDENT>return decorator<EOL>

Method decorator generator for decorating event handlers.

    To be used on `TimeoutHandler` subclass methods only.

    :Parameters:
        - `interval`: interval (in seconds) before the method will be called.
        - `recurring`: When `True`, the handler will be called each `interval`
          seconds, when `False` it will be called only once. If `True`,
          then the handler should return the next interval or `None` if it
          should not be called again.
    :Types:
        - `interval`: `float`
        - `recurring`: `bool`


return None<EOL>

Return file descriptor to poll or select.


return False<EOL>

:Return: `True` when the I/O channel can be read


return False<EOL>

Stop current thread until the channel is readable.

:Return: `False` if it won't be readable (e.g. is closed)


return False<EOL>

:Return: `True` when the I/O channel can be written to


return HandlerReady()<EOL>

Prepare the I/O handler for the event loop or an event loop
iteration.

:Return: `HandlerReady()` if there is no need to call `prepare` again
    or `PrepareAgain()` otherwise.
:Returntype: `IOHandlerPrepareResult`


return False<EOL>

Stop current thread until the channel is writable.

:Return: `False` if it won't be readable (e.g. is closed)


pass<EOL>

Handle the 'channel writable' state. E.g. send buffered data via a
socket.


pass<EOL>

Handle the 'channel readable' state. E.g. read from a socket.


pass<EOL>

Handle the 'channel hungup' state. The handler should not be writtable
after this.


pass<EOL>


pass<EOL>

Handle an 'invalid file descriptor' event.


pass<EOL>

Close the channell immediately, so it won't expect more events.


pass<EOL>

Add a new handler to the main loop.

        :Parameters:
            - `handler`: the handler object to add
        :Types:
            - `handler`: `IOHandler` or `EventHandler` or `TimeoutHandler`


pass<EOL>

Add a new handler to the main loop.

        Do nothing if the handler is not registered at the main loop.

        :Parameters:
            - `handler`: the handler object to add
        :Types:
            - `handler`: `IOHandler` or `EventHandler` or `TimeoutHandler`


def delayed_call(self, delay, function):

main_loop = self<EOL>handler = []<EOL>class DelayedCallHandler(TimeoutHandler):<EOL><INDENT>"""<STR_LIT>"""<EOL>@timeout_handler(delay, False)<EOL>def callback(self):<EOL><INDENT>"""<STR_LIT>"""<EOL>try:<EOL><INDENT>function()<EOL><DEDENT>finally:<EOL><INDENT>main_loop.remove_handler(handler[<NUM_LIT:0>])<EOL><DEDENT><DEDENT><DEDENT>handler.append(DelayedCallHandler())<EOL>self.add_handler(handler[<NUM_LIT:0>])<EOL>

Schedule function to be called from the main loop after `delay`
        seconds.

        :Parameters:
            - `delay`: seconds to wait
        :Types:
            - `delay`: `float`


pass<EOL>

Make the loop stop after the current iteration.


return False<EOL>


return False<EOL>

`True` then the loop has been finished or is about to finish (the
        final iteration in progress).


@abstractmethod<EOL><INDENT>def loop(self, timeout = None):<DEDENT>

pass<EOL>

Run the loop.

        :Parameters:
            - `timeout`: time to loop, if not given the method will run
              until `finished`
        :Types:
            - `timeout`: `float`


@abstractmethod<EOL><INDENT>def loop_iteration(self, timeout = <NUM_LIT:1>):<DEDENT>

pass<EOL>

Single loop iteration.

        :Parameters:
            - `timeout`: maximum time (in seconds) to block for
        :Types:
            - `timeout`: `float`


raise NotImplementedError<EOL>


if self.event_dispatcher.flush() is QUIT:<EOL><INDENT>self._quit = True<EOL>return True<EOL><DEDENT>return False<EOL>

Call the event dispatcher.

        Quit the main loop when the `QUIT` event is reached.

        :Return: `True` if `QUIT` was reached.


<EOL>now = time.time()<EOL>for dummy, method in inspect.getmembers(handler, callable):<EOL><INDENT>if not hasattr(method, "<STR_LIT>"):<EOL><INDENT>continue<EOL><DEDENT>self._timeout_handlers.append((now + method._pyxmpp_timeout,<EOL>method))<EOL><DEDENT>self._timeout_handlers.sort(key = lambda x: x[<NUM_LIT:0>])<EOL>

Add a `TimeoutHandler` to the main loop.


self._timeout_handlers = [(t, h) for (t, h)<EOL>in self._timeout_handlers<EOL>if h.im_self != handler]<EOL>

Remove `TimeoutHandler` from the main loop.


sources_handled = <NUM_LIT:0><EOL>now = time.time()<EOL>schedule = None<EOL>while self._timeout_handlers:<EOL><INDENT>schedule, handler = self._timeout_handlers[<NUM_LIT:0>]<EOL>if schedule <= now:<EOL><INDENT>logger.debug("<STR_LIT>"<EOL>.format(handler))<EOL>self._timeout_handlers = self._timeout_handlers[<NUM_LIT:1>:]<EOL>result = handler()<EOL>logger.debug("<STR_LIT>".format(result))<EOL>rec = handler._pyxmpp_recurring<EOL>if rec:<EOL><INDENT>logger.debug("<STR_LIT>"<EOL>.format(handler._pyxmpp_timeout))<EOL>self._timeout_handlers.append(<EOL>(now + handler._pyxmpp_timeout, handler))<EOL>self._timeout_handlers.sort(key = lambda x: x[<NUM_LIT:0>])<EOL><DEDENT>elif rec is None and result is not None:<EOL><INDENT>logger.debug("<STR_LIT>"<EOL>.format(result))<EOL>self._timeout_handlers.append((now + result, handler))<EOL>self._timeout_handlers.sort(key = lambda x: x[<NUM_LIT:0>])<EOL><DEDENT>sources_handled += <NUM_LIT:1><EOL><DEDENT>else:<EOL><INDENT>break<EOL><DEDENT>if self.check_events():<EOL><INDENT>return <NUM_LIT:0>, sources_handled<EOL><DEDENT><DEDENT>if self._timeout_handlers and schedule:<EOL><INDENT>timeout = schedule - now<EOL><DEDENT>else:<EOL><INDENT>timeout = None<EOL><DEDENT>return timeout, sources_handled<EOL>

Call the timeout handlers due.

        :Return: (next_event_timeout, sources_handled) tuple.
            next_event_timeout is number of seconds until the next timeout
            event, sources_handled is number of handlers called.


if self.check_events():<EOL><INDENT>return <NUM_LIT:0><EOL><DEDENT>next_timeout, sources_handled = self._call_timeout_handlers()<EOL>if self._quit:<EOL><INDENT>return sources_handled<EOL><DEDENT>if next_timeout is not None:<EOL><INDENT>timeout = min(next_timeout, timeout)<EOL><DEDENT>readable, writable, next_timeout = self._prepare_handlers()<EOL>if next_timeout is not None:<EOL><INDENT>timeout = min(next_timeout, timeout)<EOL><DEDENT>if not readable and not writable:<EOL><INDENT>readable, writable, _unused = [], [], None<EOL>time.sleep(timeout)<EOL><DEDENT>else:<EOL><INDENT>logger.debug("<STR_LIT>"<EOL>.format( readable, writable,timeout))<EOL>readable, writable, _unused = select.select(<EOL>readable, writable, [], timeout)<EOL><DEDENT>for handler in readable:<EOL><INDENT>handler.handle_read()<EOL>sources_handled += <NUM_LIT:1><EOL><DEDENT>for handler in writable:<EOL><INDENT>handler.handle_write()<EOL>sources_handled += <NUM_LIT:1><EOL><DEDENT>return sources_handled<EOL>

A loop iteration - check any scheduled events
        and I/O available and run the handlers.


timeout = None<EOL>readable = []<EOL>writable = []<EOL>for handler in self._handlers:<EOL><INDENT>if handler not in self._prepared:<EOL><INDENT>logger.debug("<STR_LIT>".format(handler))<EOL>ret = handler.prepare()<EOL>logger.debug("<STR_LIT>".format(ret))<EOL>if isinstance(ret, HandlerReady):<EOL><INDENT>self._prepared.add(handler)<EOL><DEDENT>elif isinstance(ret, PrepareAgain):<EOL><INDENT>if ret.timeout is not None:<EOL><INDENT>if timeout is None:<EOL><INDENT>timeout = ret.timeout<EOL><DEDENT>else:<EOL><INDENT>timeout = min(timeout, ret.timeout)<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>raise TypeError("<STR_LIT>")<EOL><DEDENT><DEDENT>if not handler.fileno():<EOL><INDENT>logger.debug("<STR_LIT>".format(handler))<EOL>continue<EOL><DEDENT>if handler.is_readable():<EOL><INDENT>logger.debug("<STR_LIT>".format(handler))<EOL>readable.append(handler)<EOL><DEDENT>if handler.is_writable():<EOL><INDENT>logger.debug("<STR_LIT>".format(handler))<EOL>writable.append(handler)<EOL><DEDENT><DEDENT>return readable, writable, timeout<EOL>

Prepare the I/O handlers.

        :Return: (readable, writable, timeout) tuple. 'readable' is the list
            of readable handlers, 'writable' - the list of writable handlers,
            'timeout' the suggested maximum timeout for this loop iteration or
            `None`


@functools.wraps(method)<EOL>def wrapper(self, *args, **kwargs):<EOL><INDENT>"""<STR_LIT>"""<EOL>try:<EOL><INDENT>return method(self, *args, **kwargs)<EOL><DEDENT>except Exception:<EOL><INDENT>if self.exc_info:<EOL><INDENT>raise<EOL><DEDENT>if not self._stack:<EOL><INDENT>logger.debug('<STR_LIT>'<EOL>'<STR_LIT>'.format(method))<EOL>raise<EOL><DEDENT>self.exc_info = sys.exc_info()<EOL>logger.debug("<STR_LIT>",<EOL>exc_info = self.exc_info)<EOL>main_loop = self._stack[-<NUM_LIT:1>]<EOL>if main_loop is not None:<EOL><INDENT>main_loop.quit()<EOL><DEDENT>return False<EOL><DEDENT><DEDENT>return wrapper<EOL>

Decorator for glib callback methods of GLibMainLoop used to store the
    exception raised.


if self.check_events():<EOL><INDENT>return<EOL><DEDENT>if handler in self._unprepared_handlers:<EOL><INDENT>old_fileno = self._unprepared_handlers[handler]<EOL>prepared = self._prepare_io_handler(handler)<EOL><DEDENT>else:<EOL><INDENT>old_fileno = None<EOL>prepared = True<EOL><DEDENT>fileno = handler.fileno()<EOL>if old_fileno is not None and fileno != old_fileno:<EOL><INDENT>tag = self._io_sources.pop(handler, None)<EOL>if tag is not None:<EOL><INDENT>glib.source_remove(tag)<EOL><DEDENT><DEDENT>if not prepared:<EOL><INDENT>self._unprepared_handlers[handler] = fileno<EOL><DEDENT>if fileno is None:<EOL><INDENT>logger.debug("<STR_LIT>"<EOL>.format(handler))<EOL>return<EOL><DEDENT>events = <NUM_LIT:0><EOL>if handler.is_readable():<EOL><INDENT>logger.debug("<STR_LIT>".format(handler))<EOL>events |= glib.IO_IN | glib.IO_ERR<EOL><DEDENT>if handler.is_writable():<EOL><INDENT>logger.debug("<STR_LIT>".format(handler))<EOL>events |= glib.IO_OUT | glib.IO_HUP | glib.IO_ERR<EOL><DEDENT>if events:<EOL><INDENT>logger.debug("<STR_LIT>"<EOL>"<STR_LIT>".format(handler, fileno, events))<EOL>glib.io_add_watch(fileno, events, self._io_callback, handler)<EOL><DEDENT>

Register an io-handler with the glib main loop.


@hold_exception<EOL><INDENT>def _io_callback(self, fileno, condition, handler):<DEDENT>

<EOL>self._anything_done = True<EOL>logger.debug("<STR_LIT>".format(handler,<EOL>condition))<EOL>try:<EOL><INDENT>if condition & glib.IO_HUP:<EOL><INDENT>handler.handle_hup()<EOL><DEDENT>if condition & glib.IO_IN:<EOL><INDENT>handler.handle_read()<EOL><DEDENT>elif condition & glib.IO_ERR:<EOL><INDENT>handler.handle_err()<EOL><DEDENT>if condition & glib.IO_OUT:<EOL><INDENT>handler.handle_write()<EOL><DEDENT>if self.check_events():<EOL><INDENT>return False<EOL><DEDENT><DEDENT>finally:<EOL><INDENT>self._io_sources.pop(handler, None)<EOL>self._configure_io_handler(handler)<EOL>self._prepare_pending()<EOL><DEDENT>return False<EOL>


logger.debug("<STR_LIT>".format(handler))<EOL>self._unprepared_pending.discard(handler)<EOL>ret = handler.prepare()<EOL>logger.debug("<STR_LIT>".format(ret))<EOL>if isinstance(ret, HandlerReady):<EOL><INDENT>del self._unprepared_handlers[handler]<EOL>prepared = True<EOL><DEDENT>elif isinstance(ret, PrepareAgain):<EOL><INDENT>if ret.timeout == <NUM_LIT:0>:<EOL><INDENT>tag = glib.idle_add(self._prepare_io_handler_cb, handler)<EOL>self._prepare_sources[handler] = tag<EOL><DEDENT>elif ret.timeout is not None:<EOL><INDENT>timeout = ret.timeout<EOL>timeout = int(timeout * <NUM_LIT:1000>)<EOL>if not timeout:<EOL><INDENT>timeout = <NUM_LIT:1><EOL><DEDENT>tag = glib.timeout_add(timeout, self._prepare_io_handler_cb,<EOL>handler)<EOL>self._prepare_sources[handler] = tag<EOL><DEDENT>else:<EOL><INDENT>self._unprepared_pending.add(handler)<EOL><DEDENT>prepared = False<EOL><DEDENT>else:<EOL><INDENT>raise TypeError("<STR_LIT>")<EOL><DEDENT>return prepared<EOL>

Call the `interfaces.IOHandler.prepare` method and
        remove the handler from unprepared handler list when done.


if not self._unprepared_pending:<EOL><INDENT>return<EOL><DEDENT>for handler in list(self._unprepared_pending):<EOL><INDENT>self._configure_io_handler(handler)<EOL><DEDENT>self.check_events()<EOL>


self._anything_done = True<EOL>logger.debug("<STR_LIT>".format(handler))<EOL>self._configure_io_handler(handler)<EOL>self._prepare_sources.pop(handler, None)<EOL>return False<EOL>

Timeout callback called to try prepare an IOHandler again.


if handler in self._unprepared_handlers:<EOL><INDENT>del self._unprepared_handlers[handler]<EOL><DEDENT>tag = self._prepare_sources.pop(handler, None)<EOL>if tag is not None:<EOL><INDENT>glib.source_remove(tag)<EOL><DEDENT>tag = self._io_sources.pop(handler, None)<EOL>if tag is not None:<EOL><INDENT>glib.source_remove(tag)<EOL><DEDENT>


<EOL>for dummy, method in inspect.getmembers(handler, callable):<EOL><INDENT>if not hasattr(method, "<STR_LIT>"):<EOL><INDENT>continue<EOL><DEDENT>tag = glib.timeout_add(int(method._pyxmpp_timeout * <NUM_LIT:1000>),<EOL>self._timeout_cb, method)<EOL>self._timer_sources[method] = tag<EOL><DEDENT>


for dummy, method in inspect.getmembers(handler, callable):<EOL><INDENT>if not hasattr(method, "<STR_LIT>"):<EOL><INDENT>continue<EOL><DEDENT>tag = self._timer_sources.pop(method, None)<EOL>if tag is not None:<EOL><INDENT>glib.source_remove(tag)<EOL><DEDENT><DEDENT>


self._anything_done = True<EOL>logger.debug("<STR_LIT>".format(method))<EOL>result = method()<EOL>rec = method._pyxmpp_recurring<EOL>if rec:<EOL><INDENT>self._prepare_pending()<EOL>return True<EOL><DEDENT>if rec is None and result is not None:<EOL><INDENT>logger.debug("<STR_LIT>"<EOL>.format(result))<EOL>tag = glib.timeout_add(int(result * <NUM_LIT:1000>), self._timeout_cb, method)<EOL>self._timer_sources[method] = tag<EOL><DEDENT>else:<EOL><INDENT>self._timer_sources.pop(method, None)<EOL><DEDENT>self._prepare_pending()<EOL>return False<EOL>


self._anything_done = True<EOL>logger.debug("<STR_LIT>")<EOL>main_loop.quit()<EOL>

Stops the loop after the time specified in the `loop` call.


return queue.Queue(settings["<STR_LIT>"])<EOL>

Create the default event queue object.

    Use the :r:`event_queue_max_size setting` for the maximum queue size.


def __init__(self, settings = None, handlers = None):

if settings is None:<EOL><INDENT>settings = XMPPSettings()<EOL><DEDENT>self.queue = settings["<STR_LIT>"]<EOL>self._handler_map = defaultdict(list)<EOL>if handlers:<EOL><INDENT>self.handlers = list(handlers)<EOL><DEDENT>else:<EOL><INDENT>self.handlers = []<EOL><DEDENT>self._update_handlers()<EOL>self.lock = threading.RLock()<EOL>

Initialize the event dispatcher.

        :Parameters:
            - `settings`: the settings. "event_queue" settings provides the
              event queue object.
            - `handlers`: the initial list of event handler objects.
        :Types:
            - `settings`: `XMPPSettings`
            - `handlers`: iterable of objects


if not isinstance(handler, EventHandler):<EOL><INDENT>raise TypeError("<STR_LIT>")<EOL><DEDENT>with self.lock:<EOL><INDENT>if handler in self.handlers:<EOL><INDENT>return<EOL><DEDENT>self.handlers.append(handler)<EOL>self._update_handlers()<EOL><DEDENT>

Add a handler object.

        :Parameters:
            - `handler`: the object providing event handler methods
        :Types:
            - `handler`: `EventHandler`


with self.lock:<EOL><INDENT>if handler in self.handlers:<EOL><INDENT>self.handlers.remove(handler)<EOL>self._update_handlers()<EOL><DEDENT><DEDENT>

Remove a handler object.

        :Parameters:
            - `handler`: the object to remove


handler_map = defaultdict(list)<EOL>for i, obj in enumerate(self.handlers):<EOL><INDENT>for dummy, handler in inspect.getmembers(obj, callable):<EOL><INDENT>if not hasattr(handler, "<STR_LIT>"):<EOL><INDENT>continue<EOL><DEDENT>event_class = handler._pyxmpp_event_handled<EOL>handler_map[event_class].append( (i, handler) )<EOL><DEDENT><DEDENT>self._handler_map = handler_map<EOL>

Update `_handler_map` after `handlers` have been
        modified.


def dispatch(self, block = False, timeout = None):

logger.debug("<STR_LIT>")<EOL>try:<EOL><INDENT>event = self.queue.get(block, timeout)<EOL><DEDENT>except queue.Empty:<EOL><INDENT>logger.debug("<STR_LIT>")<EOL>return None<EOL><DEDENT>try:<EOL><INDENT>logger.debug("<STR_LIT>".format(event))<EOL>if event is QUIT:<EOL><INDENT>return QUIT<EOL><DEDENT>handlers = list(self._handler_map[None])<EOL>klass = event.__class__<EOL>if klass in self._handler_map:<EOL><INDENT>handlers += self._handler_map[klass]<EOL><DEDENT>logger.debug("<STR_LIT>".format(handlers))<EOL>handlers.sort(key = lambda x: x[<NUM_LIT:0>])<EOL>for dummy, handler in handlers:<EOL><INDENT>logger.debug("<STR_LIT>".format(handler))<EOL>result = handler(event)<EOL>if isinstance(result, Event):<EOL><INDENT>self.queue.put(result)<EOL><DEDENT>elif result and event is not QUIT:<EOL><INDENT>return event<EOL><DEDENT><DEDENT>return event<EOL><DEDENT>finally:<EOL><INDENT>self.queue.task_done()<EOL><DEDENT>

Get the next event from the queue and pass it to
        the appropriate handlers.

        :Parameters:
            - `block`: wait for event if the queue is empty
            - `timeout`: maximum time, in seconds, to wait if `block` is `True`
        :Types:
            - `block`: `bool`
            - `timeout`: `float`

        :Return: the event handled (may be `QUIT`) or `None`


if dispatch:<EOL><INDENT>while True:<EOL><INDENT>event = self.dispatch(False)<EOL>if event in (None, QUIT):<EOL><INDENT>return event<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>while True:<EOL><INDENT>try:<EOL><INDENT>self.queue.get(False)<EOL><DEDENT>except queue.Empty:<EOL><INDENT>return None<EOL><DEDENT><DEDENT><DEDENT>

Read all events currently in the queue and dispatch them to the
        handlers unless `dispatch` is `False`.

        Note: If the queue contains `QUIT` the events after it won't be
        removed.

        :Parameters:
            - `dispatch`: if the events should be handled (`True`) or ignored
              (`False`)

        :Return: `QUIT` if the `QUIT` event was reached.


while self.dispatch(True) is not QUIT:<EOL><INDENT>pass<EOL><DEDENT>

Wait for and dispatch events until `QUIT` is reached.


logger.debug('<STR_LIT>', handler)<EOL>self._unprepared_handlers[handler] = None<EOL>self._configure_io_handler(handler)<EOL>


if self.check_events():<EOL><INDENT>return<EOL><DEDENT>if handler in self._unprepared_handlers:<EOL><INDENT>old_fileno = self._unprepared_handlers[handler]<EOL>prepared = self._prepare_io_handler(handler)<EOL><DEDENT>else:<EOL><INDENT>old_fileno = None<EOL>prepared = True<EOL><DEDENT>fileno = handler.fileno()<EOL>if old_fileno is not None and fileno != old_fileno:<EOL><INDENT>del self._handlers[old_fileno]<EOL>self.io_loop.remove_handler(old_fileno)<EOL><DEDENT>if not prepared:<EOL><INDENT>self._unprepared_handlers[handler] = fileno<EOL><DEDENT>if not fileno:<EOL><INDENT>return<EOL><DEDENT>update = fileno in self._handlers<EOL>events = ioloop.IOLoop.NONE<EOL>if handler.is_readable():<EOL><INDENT>logger.debug("<STR_LIT>".format(handler))<EOL>events |= ioloop.IOLoop.READ<EOL><DEDENT>if handler.is_writable():<EOL><INDENT>logger.debug("<STR_LIT>".format(handler))<EOL>events |= ioloop.IOLoop.WRITE<EOL><DEDENT>if self._handlers.get(fileno, None) == events:<EOL><INDENT>return<EOL><DEDENT>self._handlers[fileno] = events<EOL>if events:<EOL><INDENT>logger.debug("<STR_LIT>"<EOL>"<STR_LIT>".format(handler, fileno, events))<EOL>if update:<EOL><INDENT>self.io_loop.update_handler(fileno, events)<EOL><DEDENT>else:<EOL><INDENT>self.io_loop.add_handler(<EOL>fileno, partial(self._handle_event, handler), events<EOL>)<EOL><DEDENT><DEDENT>

Register an io-handler at the polling object.


logger.debug("<STR_LIT>".format(handler))<EOL>ret = handler.prepare()<EOL>logger.debug("<STR_LIT>".format(ret))<EOL>if isinstance(ret, HandlerReady):<EOL><INDENT>del self._unprepared_handlers[handler]<EOL>prepared = True<EOL><DEDENT>elif isinstance(ret, PrepareAgain):<EOL><INDENT>if ret.timeout is not None:<EOL><INDENT>now = time.time()<EOL>self.io_loop.add_timeout(<EOL>now + ret.timeout,<EOL>partial(self._configure_io_handler, handler)<EOL>)<EOL><DEDENT>else:<EOL><INDENT>self.io_loop.add_callback(<EOL>partial(self._configure_io_handler, handler)<EOL>)<EOL><DEDENT>prepared = False<EOL><DEDENT>else:<EOL><INDENT>raise TypeError("<STR_LIT>")<EOL><DEDENT>return prepared<EOL>


if handler in self._unprepared_handlers:<EOL><INDENT>old_fileno = self._unprepared_handlers[handler]<EOL>del self._unprepared_handlers[handler]<EOL><DEDENT>else:<EOL><INDENT>old_fileno = handler.fileno()<EOL><DEDENT>if old_fileno is not None:<EOL><INDENT>del self._handlers[old_fileno]<EOL>self.io_loop.remove_handler(handler.fileno())<EOL><DEDENT>


def _handle_event(self, handler, fd, event):

<EOL>logger.debug('<STR_LIT>', handler, fd, event)<EOL>if event & ioloop.IOLoop.ERROR:<EOL><INDENT>handler.handle_hup()<EOL><DEDENT>if event & ioloop.IOLoop.READ:<EOL><INDENT>handler.handle_read()<EOL><DEDENT>if event & ioloop.IOLoop.WRITE:<EOL><INDENT>handler.handle_write()<EOL><DEDENT>self._configure_io_handler(handler)<EOL>


def decorator(class_):<EOL><INDENT>"""<STR_LIT>"""<EOL>if "<STR_LIT>" not in class_.__dict__:<EOL><INDENT>class_._pyxmpp_feature_uris = set()<EOL><DEDENT>class_._pyxmpp_feature_uris.add(uri)<EOL>return class_<EOL><DEDENT>return decorator<EOL>

Decorating attaching a feature URI (for Service Discovery or Capability
    to a XMPPFeatureHandler class.


def _iq_handler(iq_type, payload_class, payload_key, usage_restriction):

def decorator(func):<EOL><INDENT>"""<STR_LIT>"""<EOL>func._pyxmpp_stanza_handled = ("<STR_LIT>", iq_type)<EOL>func._pyxmpp_payload_class_handled = payload_class<EOL>func._pyxmpp_payload_key = payload_key<EOL>func._pyxmpp_usage_restriction = usage_restriction<EOL>return func<EOL><DEDENT>return decorator<EOL>

Method decorator generator for decorating <iq type='get'/> stanza
    handler methods in `XMPPFeatureHandler` subclasses.

    :Parameters:
        - `payload_class`: payload class expected
        - `payload_key`: payload class specific filtering key
        - `usage_restriction`: optional usage restriction: "pre-auth" or
          "post-auth"
    :Types:
        - `payload_class`: subclass of `StanzaPayload`
        - `usage_restriction`: `unicode`


def iq_get_stanza_handler(payload_class, payload_key = None,<EOL>usage_restriction = "<STR_LIT>"):

return _iq_handler("<STR_LIT>", payload_class, payload_key, usage_restriction)<EOL>


def iq_set_stanza_handler(payload_class, payload_key = None,<EOL>usage_restriction = "<STR_LIT>"):

Method decorator generator for decorating <iq type='set'/> stanza
    handler methods in `XMPPFeatureHandler` subclasses.

    :Parameters:
        - `payload_class`: payload class expected
        - `payload_key`: payload class specific filtering key
        - `usage_restriction`: optional usage restriction: "pre-auth" or
          "post-auth"
    :Types:
        - `payload_class`: subclass of `StanzaPayload`
        - `usage_restriction`: `unicode`


def _stanza_handler(element_name, stanza_type, payload_class, payload_key,<EOL>usage_restriction):

def decorator(func):<EOL><INDENT>"""<STR_LIT>"""<EOL>func._pyxmpp_stanza_handled = (element_name, stanza_type)<EOL>func._pyxmpp_payload_class_handled = payload_class<EOL>func._pyxmpp_payload_key = payload_key<EOL>func._pyxmpp_usage_restriction = usage_restriction<EOL>return func<EOL><DEDENT>return decorator<EOL>

Method decorator generator for decorating <message/> or <presence/>
    stanza handler methods in `XMPPFeatureHandler` subclasses.

    :Parameters:
        - `element_name`: "message" or "presence"
        - `stanza_type`: expected value of the 'type' attribute of the stanza
        - `payload_class`: payload class expected
        - `payload_key`: payload class specific filtering key
        - `usage_restriction`: optional usage restriction: "pre-auth" or
          "post-auth"
    :Types:
        - `element_name`: `unicode`
        - `stanza_type`: `unicode`
        - `payload_class`: subclass of `StanzaPayload`
        - `usage_restriction`: `unicode`


def message_stanza_handler(stanza_type = None, payload_class = None,<EOL>payload_key = None, usage_restriction = "<STR_LIT>"):

if stanza_type is None:<EOL><INDENT>stanza_type = "<STR_LIT>"<EOL><DEDENT>return _stanza_handler("<STR_LIT:message>", stanza_type, payload_class, payload_key,<EOL>usage_restriction)<EOL>

Method decorator generator for decorating <message/>
    stanza handler methods in `XMPPFeatureHandler` subclasses.

    :Parameters:
        - `payload_class`: payload class expected
        - `stanza_type`: expected value of the 'type' attribute of the stanza.
          `None` means all types except 'error'
        - `payload_key`: payload class specific filtering key
        - `usage_restriction`: optional usage restriction: "pre-auth" or
          "post-auth"
    :Types:
        - `payload_class`: subclass of `StanzaPayload`
        - `stanza_type`: `unicode`
        - `usage_restriction`: `unicode`


def presence_stanza_handler(stanza_type = None, payload_class = None,<EOL>payload_key = None, usage_restriction = "<STR_LIT>"):

return _stanza_handler("<STR_LIT>", stanza_type, payload_class, payload_key,<EOL>usage_restriction)<EOL>

Method decorator generator for decorating <presence/>
    stanza handler methods in `XMPPFeatureHandler` subclasses.

    :Parameters:
        - `payload_class`: payload class expected
        - `stanza_type`: expected value of the 'type' attribute of the stanza.
        - `payload_key`: payload class specific filtering key
        - `usage_restriction`: optional usage restriction: "pre-auth" or
          "post-auth"
    :Types:
        - `payload_class`: subclass of `StanzaPayload`
        - `stanza_type`: `unicode`
        - `usage_restriction`: `unicode`


def decorator(klass):<EOL><INDENT>"""<STR_LIT>"""<EOL>from .stanzapayload import STANZA_PAYLOAD_CLASSES<EOL>from .stanzapayload import STANZA_PAYLOAD_ELEMENTS<EOL>if hasattr(klass, "<STR_LIT>"):<EOL><INDENT>klass._pyxmpp_payload_element_name.append(element_name)<EOL><DEDENT>else:<EOL><INDENT>klass._pyxmpp_payload_element_name = [element_name]<EOL><DEDENT>if element_name in STANZA_PAYLOAD_CLASSES:<EOL><INDENT>logger = logging.getLogger('<STR_LIT>')<EOL>logger.warning("<STR_LIT>".format(<EOL>element_name))<EOL><DEDENT>STANZA_PAYLOAD_CLASSES[element_name] = klass<EOL>STANZA_PAYLOAD_ELEMENTS[klass].append(element_name)<EOL>return klass<EOL><DEDENT>return decorator<EOL>

Class decorator generator for decorationg
    `StanzaPayload` subclasses.

    :Parameters:
        - `element_name`: XML element qname handled by the class
    :Types:
        - `element_name`: `unicode`


def stream_element_handler(element_name, usage_restriction = None):

def decorator(func):<EOL><INDENT>"""<STR_LIT>"""<EOL>func._pyxmpp_stream_element_handled = element_name<EOL>func._pyxmpp_usage_restriction = usage_restriction<EOL>return func<EOL><DEDENT>return decorator<EOL>

Method decorator generator for decorating stream element
    handler methods in `StreamFeatureHandler` subclasses.

    :Parameters:
        - `element_name`: stream element QName
        - `usage_restriction`: optional usage restriction: "initiator" or
          "receiver"
    :Types:
        - `element_name`: `unicode`
        - `usage_restriction`: `unicode`


@abstractmethod<EOL><INDENT>def resolve_srv(self, domain, service, protocol, callback):<DEDENT>

raise NotImplementedError<EOL>

Start looking up an SRV record for `service` at `domain`.

        `callback` will be called with a properly sorted list of (hostname,
        port) pairs on success. The list will be empty on error and it will
        contain only (".", 0) when the service is explicitely disabled.

        :Parameters:
            - `domain`: domain name to look up
            - `service`: service name e.g. 'xmpp-client'
            - `protocol`: protocol name, e.g. 'tcp'
            - `callback`: a function to be called with a list of received
              addresses
        :Types:
            - `domain`: `unicode`
            - `service`: `unicode`
            - `protocol`: `unicode`
            - `callback`: function accepting a single argument


@abstractmethod<EOL><INDENT>def resolve_address(self, hostname, callback, allow_cname = True):<DEDENT>

raise NotImplementedError<EOL>

Start looking up an A or AAAA record.

        `callback` will be called with a list of IPv4 or IPv6 address literals
        on success. The list will be empty on error.

        :Parameters:
            - `hostname`: the host name to look up
            - `callback`: a function to be called with a list of received
              addresses
            - `allow_cname`: `True` if CNAMEs should be followed
        :Types:
            - `hostname`: `unicode`
            - `callback`: function accepting a single argument
            - `allow_cname`: `bool`


pass<EOL>

Make the `stream` the target for this transport instance.

        The 'stream_start', 'stream_end' and 'stream_element' methods
        of the target will be called when appropriate content is received.

        :Parameters:
            - `stream`: the stream handler to receive stream content
              from the transport
        :Types:
            - `stream`: `StreamBase`


@abstractmethod<EOL><INDENT>def send_stream_head(self, stanza_namespace, stream_from, stream_to,<EOL>stream_id = None, version = u'<STR_LIT:1.0>', language = None):<DEDENT>

<EOL>pass<EOL>

Send stream head via the transport.

:Parameters:
    - `stanza_namespace`: namespace of stream stanzas (e.g.
      'jabber:client')
    - `stream_from`: the 'from' attribute of the stream. May be `None`.
    - `stream_to`: the 'to' attribute of the stream. May be `None`.
    - `version`: the 'version' of the stream.
    - `language`: the 'xml:lang' of the stream
:Types:
    - `stanza_namespace`: `unicode`
    - `stream_from`: `unicode`
    - `stream_to`: `unicode`
    - `version`: `unicode`
    - `language`: `unicode`


pass<EOL>

Restart the stream after SASL or StartTLS handshake.

        For the initiator a new call to `send_stream_head` is required too.


pass<EOL>


return False<EOL>

Check if the transport is connected.

:Return: `True` if is connected.


return {}<EOL>

Channel properties for authentication and authorization.


<EOL>raise NotImplementedError<EOL>

Create a `cls` instance from an XML element.

        :Parameters:
            - `element`: the XML element
        :Types:
            - `element`: :etree:`ElementTree.Element`


raise NotImplementedError<EOL>

Return the XML representation of the payload.

        :returntype: :etree:`ElementTree.Element`


return deepcopy(self)<EOL>


<EOL>return None<EOL>

Defines a key which may be used when registering handlers
        for stanzas with this payload.


def handle_stream_features(self, stream, features):

<EOL>return False<EOL>

Handle features announced by the stream peer.

        [initiator only]

        :Parameters:
            - `stream`: the stream
            - `features`: the features element just received
        :Types:
            - `stream`: `StreamBase`
            - `features`: :etree:`ElementTree.Element`

        :Return:
            - `StreamFeatureHandled` instance if a feature was recognized and
              handled
            - `StreamFeatureNotHandled` instance if a feature was recognized
              but not handled
            - `None` if no feature was recognized


def make_stream_features(self, stream, features):

<EOL>return False<EOL>

Update the features element announced by the stream.

        [receiver only]

        :Parameters:
            - `stream`: the stream
            - `features`: the features element about to be sent
        :Types:
            - `stream`: `StreamBase`
            - `features`: :etree:`ElementTree.Element`


index = <NUM_LIT:0><EOL>for i, handler in enumerate(handlers):<EOL><INDENT>if isinstance(handler, SessionHandler):<EOL><INDENT>index = i<EOL>break<EOL><DEDENT><DEDENT>if index:<EOL><INDENT>handlers[:index + <NUM_LIT:1>] = [handlers[index]] + handlers[:index]<EOL><DEDENT>

Find a SessionHandler instance in the list and move it to the beginning.


<EOL>return Presence()<EOL>

Factory for the :r:`initial_presence setting` default.


def __init__(self, jid, handlers, settings = None, main_loop = None):

self._ml_handlers = []<EOL>self.jid = jid<EOL>self.settings = settings if settings else XMPPSettings()<EOL>StanzaProcessor.__init__(self, self.settings[u"<STR_LIT>"])<EOL>self.handlers = handlers<EOL>self._base_handlers = self.base_handlers_factory()<EOL>self.roster_client = self.roster_client_factory()<EOL>self._base_handlers += [self.roster_client]<EOL>self._ml_handlers += list(handlers) + self._base_handlers + [self]<EOL>_move_session_handler(self._ml_handlers)<EOL>if main_loop is not None:<EOL><INDENT>self.main_loop = main_loop<EOL>for handler in self._ml_handlers:<EOL><INDENT>self.main_loop.add_handler(handler)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>self.main_loop = main_loop_factory(settings, self._ml_handlers)<EOL><DEDENT>self.stream = None<EOL>

Initialize a Client object.

        :Parameters:
            - `jid`: user JID for the connection.
            - `settings`: client settings.
            - `main_loop`: Main event loop to attach to. If None, a loop
              will be created.
        :Types:
            - `jid`: `jid.JID`
            - `settings`: `settings.XMPPSettings`
            - `main_loop`: `main_loop.interfaces.MainLoop`


with self.lock:<EOL><INDENT>if self.roster_client is not None:<EOL><INDENT>return self.roster_client.roster<EOL><DEDENT>else:<EOL><INDENT>return None<EOL><DEDENT><DEDENT>

Current roster.

        Shortcut for ``self.roster_client.roster``.