Locations where AMQP symbol is required by AMQP 1.0 spec: Types: ===== 1. Descriptor name 2. Descriptor value (or ulong) _data.py:257: No checks on either descriptor name or value. NB: Value can be either symbol or ulong. NB: Docs state that any AMQP type is valid for descriptor, but not tying up with AMQP spec Transport: ========= 2.7.1: Open * outgoing-locales - ietf-language-tag - see 2.8.12 * incoming-locales - ietf-language-tag - see 2.8.12 * offered-capabilities * desired-capabilities * properties - fields type - map with symbol keys - see 2.8.13 (Connection) These values are set as follows: _reactor.py:1249: No checks in kwargs for 'offered_capabilities' type in _connect(). _reactor.py:1250: No checks in kwargs for 'desired_capabilities' type in _connect(). _reactor.py:1251: No checks in kwargs for 'properties' type in _connect(). They are then processed by Connection.open(): _endpoints.py:376: No checks when Connection.offered_capabilities is encoded into pn_connection_offered_capabilities. _endpoints.py:378: No checks when Connection.desired_capabilities is encoded into pn_connection_desired_capabilities. _endpoints.py:380: No checks when Connection.properties is encoded into pn_connection_properties. I cannot find any implementation of * incoming-locales * outgoing-locales in either the Python API or the Proton C API. 2.7.2: Begin * offered-capabilities * desired-capabilities * properties - fields type - map with symbol keys - see 2.8.13 (Session) I cannot find any implementation of: * offered_capabilities * desired_capabilities * properties in either the Python API or the Proton C API. 2.7.3: Attach * offered-capabilities * desired-capabilities * properties - fields type - map with symbol keys - see 2.8.13 (Link) I cannot find any implementation of: * offered_capabilities * desired_capabilities * properties in either the Python API or the Proton C API. 2.7.4: Flow * properties - fields type - map with symbol keys - see 2.8.13 I cannot find where this is implemented. 2.7.7: Detach * error: error type - see 2.8.14 (Link) This will be exposed in two places: * When closing a link from a client with an error. I cannot find where this is implemented. * When receiving notification that the peer has closed the link with an error. I assume this will happen through either the on_link_close or on_link_error callbacks, and that the error will be accessible through the event object associated with the callback. Will the error object be a string or a symbol? Proton c: pn_link_error(): link->endpoint.error. Never exposed in Python API. Used by Link._check(). 2.7.8: End * error: error type - see 2.8.14 (Session) Ditto for on_session_closed and/or on_session_error. Proton c: pn_session_error(): session->endpoint.error. Never exposed or used in Python API. 2.7.9: Close * error: error type - see 2.8.14 (Connection) Ditto for on_connection_closed and/or on_connection_error. Proton c: pn_connection_error(): connection->endpoint.error. Never exposed in Python API. Used by Link._check(). There is also a Connection.error property which returns pn_error_code(pn_connection_error(self._impl)) and returns an int. NOTE: The error handling in Connections vs Sessions vs Links are implemented a little inconsistently. The underlying Proton C implementation is consistent, but the Python implementation is different for each of these. Maybe this is a deliberate design decision if the errors are all handled internally and are low-level and have no relevance at the API level. 2.8.12: IETF Language Tag - type="ietf-language-tag" A type used in: * 2.7.1 Open performative 2.8.13: Fields: map type with symbol keys - type="fields" A type used in: * 2.7.1: Open performative properties field * 2.7.2: Begin performative properties field (but not implemented) * 2.7.3: Attach performative properties field (but not implemented) * 2.7.4: Flow performative properties field (but not implemented) * 2.8.14: Error info field * 3.4.5: Modified message-annotations field 2.8.14: Error - type="error" * condition: requires="error-condition" may contain any selection from any of the following (all symbols): * AMQP Error - see 2.8.15 * Connection Error - see 2.8.16 * Session Error - see 2.8.17 * Link Error - see 2.8.18 * info: fields type - map with symbol keys - see 2.8.13 2.8.15: AMQP Error: type="amqp-error" provides="error-condition" List of defined error conditions, each a symbol. [internal-error, not-found, unauthorized-access, decode-error, resource-limit-exceeded, not-allowed, invalid-field, not-implemented, resource-locked, precondition-failed, resource-deleted, illegal-state, frame-size-too-small] 2.8.16: Connection Error: type="connection-error" provides="error-condition" List of defined error conditions, each a symbol. [forced, framing-error, redirect] 2.8.17: Session Error: type="session-error" provides="error-condition" List of defined error conditions, each a symbol. [window-violation, errant-link, handle-in-use, unattached-handle] 2.8.18: Link Error: type="link-error" provides="error-condition" List of defined error conditions, each a symbol. [detach-forced, transfer-limit-exceeded, message-size-exceeded, redirect] Messaging: ========= 3.2.2: Delivery Annotations - non-standard properties at the head of the message - Message.instructions? * MAY have a symbol key: ** Reserved annotation: symbolic key "rejected" with value of type Error - see 2.8.14 Check for key string 'rejected', convert to symbol if needed in Message._pre_encode() (_message.py:110) 3.2.4: Properties - immutable properties of the message * content-type - symbol * content-encoding - symbol _message.py:342: Message._get_content_type() returns a Symbol - no action needed. _message.py:342: Message._set_content_type() performs unicode2utf8() on the value. This will probably fail with a TypeError if a Symbol type is used here, see _common.py:63. Ditto for Message._get_content_encoding() and Message._set_content_encoding() at _message.py:355. 3.2.10: Annotations - properties of the message which are aimed at the infrastructure * a map with keys which are symbols or ulong There is no method for adding properties, this map, which is a Message property, is set directly by the user. Perhaps the method Message._pre_encode() (_message.py:113) should type check each property as it is being added. 3.4.3: Rejected - delivery outcome * error: error type - see 2.8.14 Two cases: * Client rejects message I can't find where this is implemented in the API. * Client's peer rejects message. The cleint receives notification via on_rejected() Not sure where to look in the Event object to see the error. 3.4.5: Modified - delivery outcome * message-annotations: fields type - map with symbol keys - see 2.8.13 Two cases: * Client marks message modified - transfer was not and will not be acted upon. * Cleint who sent message is notified - message is no longer acquired by the receiver. I can't find where in the API any of these are implemented. 3.5.3: Source * expiry-policy - symbol from list in 3.5.6 * dynamic-node-properties - node-properties type - map with symbol keys - see 3.5.9 * distribution-mode - symbol from list in 3.5.7 * filter - filter set - map with symbol keys - see 3.5.8 * outcomes - symbol - may be multiple outcomes * capabilities - symbol - may be multiple capabilities Derived from Terminus. _endpoints.py:1347: Terminus.expiry_policy property. Appears to use the Proton int constants for each of the possible policies. In addition, the _set_expiry_policy uses a 'seconds' parameter, which is misleading. Perhaps change this to 'policy' (which matches the C API)? This is not a string type, no action needed here. I assume it will come out on the wire as the correct symbol type and value. _endpoints.py:1396: Terminus.properties property. Uses pn_terminus_properties(). Only getter, no setter. pn_terminus_properties() returns a pointer to the map, so I assume it can be modified also under Python... There are no checks for key type. _endpoints.py:1388: Terminus.distribution_mode property. Appears to use the Proton int constants for each of the possible policies. _endpoints.py:1423: Terminus.filter property. Uses pn_terminus_filter(). Only getter, no setter. pn_terminus_filter() returns a pointer to the map, so I assume it can be modified also under Python. There are no checks for key type. _endpoints.py:1414: Terminus.outcomes property. Uses pn_terminus_outcomes(). Only getter, no setter. pn_terminus_outcomes() returns a pointer to the map, so I assume it can be modified also under Python. There are no checks for key type. _endpoints.py:1405: Terminus.capabilities property. Uses pn_terminus_capabilities(). Only getter, no setter. pn_terminus_capabilities() returns a pointer to the map, so I assume it can be modified also under Python. There are no checks for key type. 3.5.4: Target * expiry-policy - symbol from list in 3.5.6 * dynamic-node-properties - node-properties type - map with symbol keys - see 3.5.9 * capabilities - symbol - may be multiple capabilities As for Source above, derived from Terminus. 3.5.6: Terminus Expiry Policy List of policies, must be symbols [link-detatch, session-end, connection-close, never] 3.5.7: Standard Distribution Mode List of modes, must be symbols [move, copy] 3.5.8: Filter Set Map with keys which are symbols 3.5.9: Node Properties Map with symbol keys [lifetime-policy, supported-dist-modes] Transactions: ============ 4.5.1: Coordinator * capabilities: symbol from list in 4.5.7 I cannot find any implementation of this, either in Proton or Python. 4.5.7: Transaction Capability List of capabilities - symbol type [local-transactions, distributed-transactions, promotable-transactions, mulit-txns-per-ssn, multi-ssns-per txn] 4.5.8: Transaction Error List of errors [unknown-id, rollback, timeout] Security: ======== 5.3.3.1: SASL Mechanisms * sasl-server-mechanisms - symbol type _transport.py:635 allowed_mechs() sets mechs with a single value or list. Crrently no check for type, assumes strings. Docs give type as string or list of strings. pn_sasl_allowed_mechs(self._sasl, unicode2utf8(mechs)) - proton is accepting utf8 string. 5.3.3.2: SASL Init * mechanism - symbol type Within Proton, this is a char*. I can't find how this is set from Python, I don't understand how it is used.