You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by jd...@apache.org on 2021/08/14 07:57:19 UTC

[qpid-proton] branch main updated: PROTON-2407 [python] still more annotations; properties; fix type for message tag (#331)

This is an automated email from the ASF dual-hosted git repository.

jdanek pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/qpid-proton.git


The following commit(s) were added to refs/heads/main by this push:
     new 6f8a29d  PROTON-2407 [python] still more annotations; properties; fix type for message tag (#331)
6f8a29d is described below

commit 6f8a29dfb7a55f64ad8f47dcd4c349b2c3068520
Author: Jiri Daněk <jd...@redhat.com>
AuthorDate: Sat Aug 14 09:57:12 2021 +0200

    PROTON-2407 [python] still more annotations; properties; fix type for message tag (#331)
---
 python/proton/_endpoints.py  | 416 +++++++++++++++++++------------------------
 python/proton/_events.py     |   2 +-
 python/proton/_message.py    | 362 ++++++++++++++++++-------------------
 python/proton/_reactor.py    |   2 +-
 python/proton/_selectable.py |  14 +-
 python/proton/_transport.py  | 152 +++++++---------
 6 files changed, 428 insertions(+), 520 deletions(-)

diff --git a/python/proton/_endpoints.py b/python/proton/_endpoints.py
index b27be28..3c8d8ed 100644
--- a/python/proton/_endpoints.py
+++ b/python/proton/_endpoints.py
@@ -67,7 +67,7 @@ from typing import Callable, Dict, List, Optional, Union, TYPE_CHECKING, Any
 
 if TYPE_CHECKING:
     from ._condition import Condition
-    from ._data import Array, symbol
+    from ._data import Array, PythonAMQPData, symbol
     from ._events import Collector, Handler
     from ._message import Message
 
@@ -216,42 +216,32 @@ class Connection(Wrapper, Endpoint):
             pn_connection_collect(self._impl, collector._impl)
         self._collector = weakref.ref(collector)
 
-    def _get_container(self):
+    @property
+    def container(self) -> str:
+        """The container name for this connection object."""
         return utf82unicode(pn_connection_get_container(self._impl))
 
-    def _set_container(self, name):
+    @container.setter
+    def container(self, name: str) -> None:
         pn_connection_set_container(self._impl, unicode2utf8(name))
 
-    container = property(_get_container, _set_container, doc="""
-        The container name for this connection object.
-
-        :type: ``str``
-        """)
-
-    def _get_hostname(self):
-        return utf82unicode(pn_connection_get_hostname(self._impl))
-
-    def _set_hostname(self, name):
-        pn_connection_set_hostname(self._impl, unicode2utf8(name))
-
-    hostname = property(_get_hostname, _set_hostname, doc="""
-        Set the name of the host (either fully qualified or relative) to which this
+    @property
+    def hostname(self) -> Optional[str]:
+        """Set the name of the host (either fully qualified or relative) to which this
         connection is connecting to.  This information may be used by the remote
         peer to determine the correct back-end service to connect the client to.
         This value will be sent in the Open performative, and will be used by SSL
         and SASL layers to identify the peer.
+        """
+        return utf82unicode(pn_connection_get_hostname(self._impl))
 
-        :type: ``str``
-        """)
-
-    def _get_user(self):
-        return utf82unicode(pn_connection_get_user(self._impl))
-
-    def _set_user(self, name):
-        pn_connection_set_user(self._impl, unicode2utf8(name))
+    @hostname.setter
+    def hostname(self, name: str) -> None:
+        pn_connection_set_hostname(self._impl, unicode2utf8(name))
 
-    user = property(_get_user, _set_user, doc="""
-        The authentication username for a client connection.
+    @property
+    def user(self) -> Optional[str]:
+        """The authentication username for a client connection.
 
         It is necessary to set the username and password before binding
         the connection to a transport and it isn't allowed to change
@@ -261,18 +251,16 @@ class Connection(Wrapper, Endpoint):
         client sasl layer is explicitly created (this would be for something
         like Kerberos where the credentials are implicit in the environment,
         or to explicitly use the ``ANONYMOUS`` SASL mechanism)
+        """
+        return utf82unicode(pn_connection_get_user(self._impl))
 
-        :type: ``str``
-        """)
-
-    def _get_authorization(self):
-        return utf82unicode(pn_connection_get_authorization(self._impl))
-
-    def _set_authorization(self, name):
-        pn_connection_set_authorization(self._impl, unicode2utf8(name))
+    @user.setter
+    def user(self, name: str) -> None:
+        pn_connection_set_user(self._impl, unicode2utf8(name))
 
-    authorization = property(_get_authorization, _set_authorization, doc="""
-        The authorization username for a client connection.
+    @property
+    def authorization(self) -> str:
+        """The authorization username for a client connection.
 
         It is necessary to set the authorization before binding
         the connection to a transport and it isn't allowed to change
@@ -280,29 +268,30 @@ class Connection(Wrapper, Endpoint):
 
         If not set then implicitly the requested authorization is the same as the
         authentication user.
+        """
+        return utf82unicode(pn_connection_get_authorization(self._impl))
 
-        :type: ``str``
-        """)
-
-    def _get_password(self):
-        return None
-
-    def _set_password(self, name):
-        pn_connection_set_password(self._impl, unicode2utf8(name))
+    @authorization.setter
+    def authorization(self, name: str) -> None:
+        pn_connection_set_authorization(self._impl, unicode2utf8(name))
 
-    password = property(_get_password, _set_password, doc="""
-        Set the authentication password for a client connection.
+    @property
+    def password(self) -> None:
+        """Set the authentication password for a client connection.
 
         It is necessary to set the username and password before binding the connection
         to a transport and it isn't allowed to change after the binding.
 
         .. note:: Getting the password always returns ``None``.
+        """
+        return None
 
-        :type: ``str``
-        """)
+    @password.setter
+    def password(self, name: str) -> None:
+        pn_connection_set_password(self._impl, unicode2utf8(name))
 
     @property
-    def remote_container(self):
+    def remote_container(self) -> Optional[str]:
         """
         The container identifier specified by the remote peer for this connection.
 
@@ -318,7 +307,7 @@ class Connection(Wrapper, Endpoint):
         return pn_connection_remote_container(self._impl)
 
     @property
-    def remote_hostname(self):
+    def remote_hostname(self) -> Optional[str]:
         """
         The hostname specified by the remote peer for this connection.
 
@@ -328,8 +317,6 @@ class Connection(Wrapper, Endpoint):
         Any (non ``None``) name returned by this operation will be valid until
         the connection object is unbound from a transport or freed,
         whichever happens sooner.
-
-        :type: ``str``
         """
         return pn_connection_remote_hostname(self._impl)
 
@@ -525,65 +512,65 @@ class Connection(Wrapper, Endpoint):
         """
         pn_connection_release(self._impl)
 
-    def _get_offered_capabilities(self):
+    @property
+    def offered_capabilities(self) -> Optional[Union['Array', SymbolList]]:
+        """Offered capabilities as a list of symbols. The AMQP 1.0 specification
+        restricts this list to symbol elements only. It is possible to use
+        the special ``list`` subclass :class:`SymbolList` as it will by
+        default enforce this restriction on construction. In addition, if a
+        string type is used, it will be silently converted into the required
+        symbol.
+        """
         return self.offered_capabilities_list
 
-    def _set_offered_capabilities(self, offered_capability_list):
+    @offered_capabilities.setter
+    def offered_capabilities(
+            self,
+            offered_capability_list: Optional[Union['Array', List['symbol'], SymbolList, List[str]]]
+    ) -> None:
         if isinstance(offered_capability_list, list):
             self.offered_capabilities_list = SymbolList(offered_capability_list, raise_on_error=False)
         else:
             self.offered_capabilities_list = offered_capability_list
 
-    offered_capabilities = property(_get_offered_capabilities, _set_offered_capabilities, doc="""
-    Offered capabilities as a list of symbols. The AMQP 1.0 specification
-    restricts this list to symbol elements only. It is possible to use
-    the special ``list`` subclass :class:`SymbolList` as it will by
-    default enforce this restriction on construction. In addition, if a
-    string type is used, it will be silently converted into the required
-    symbol.
-
-    :type: ``list`` containing :class:`symbol`.
-    """)
-
-    def _get_desired_capabilities(self):
+    @property
+    def desired_capabilities(self) -> Optional[Union['Array', SymbolList]]:
+        """Desired capabilities as a list of symbols. The AMQP 1.0 specification
+        restricts this list to symbol elements only. It is possible to use
+        the special ``list`` subclass :class:`SymbolList` which will by
+        default enforce this restriction on construction. In addition, if string
+        types are used, this class will be silently convert them into symbols.
+        """
         return self.desired_capabilities_list
 
-    def _set_desired_capabilities(self, desired_capability_list):
+    @desired_capabilities.setter
+    def desired_capabilities(
+            self,
+            desired_capability_list: Optional[Union['Array', List['symbol'], SymbolList, List[str]]]
+    ) -> None:
         if isinstance(desired_capability_list, list):
             self.desired_capabilities_list = SymbolList(desired_capability_list, raise_on_error=False)
         else:
             self.desired_capabilities_list = desired_capability_list
 
-    desired_capabilities = property(_get_desired_capabilities, _set_desired_capabilities, doc="""
-    Desired capabilities as a list of symbols. The AMQP 1.0 specification
-    restricts this list to symbol elements only. It is possible to use
-    the special ``list`` subclass :class:`SymbolList` which will by
-    default enforce this restriction on construction. In addition, if string
-    types are used, this class will be silently convert them into symbols.
-
-    :type: ``list`` containing :class:`symbol`.
-    """)
-
-    def _get_properties(self):
+    @property
+    def properties(self) -> Optional[PropertyDict]:
+        """Connection properties as a dictionary of key/values. The AMQP 1.0
+        specification restricts this dictionary to have keys that are only
+        :class:`symbol` types. It is possible to use the special ``dict``
+        subclass :class:`PropertyDict` which will by default enforce this
+        restrictions on construction. In addition, if strings type are used,
+        this will silently convert them into symbols.
+        """
         return self.properties_dict
 
-    def _set_properties(self, properties_dict):
+    @properties.setter
+    def properties(self, properties_dict: Optional[Union[PropertyDict, Dict[str, 'PythonAMQPData']]]) -> None:
         if isinstance(properties_dict, dict):
             self.properties_dict = PropertyDict(properties_dict, raise_on_error=False)
         else:
             self.properties_dict = properties_dict
 
-    properties = property(_get_properties, _set_properties, doc="""
-    Connection properties as a dictionary of key/values. The AMQP 1.0
-    specification restricts this dictionary to have keys that are only
-    :class:`symbol` types. It is possible to use the special ``dict``
-    subclass :class:`PropertyDict` which will by default enforce this
-    restrictions on construction. In addition, if strings type are used,
-    this will silently convert them into symbols.
-
-    :type: ``dict`` containing :class:`symbol`` keys.
-    """)
-
 
 class Session(Wrapper, Endpoint):
     """A container of links"""
@@ -606,14 +593,9 @@ class Session(Wrapper, Endpoint):
     def _get_remote_cond_impl(self):
         return pn_session_remote_condition(self._impl)
 
-    def _get_incoming_capacity(self):
-        return pn_session_get_incoming_capacity(self._impl)
-
-    def _set_incoming_capacity(self, capacity):
-        pn_session_set_incoming_capacity(self._impl, capacity)
-
-    incoming_capacity = property(_get_incoming_capacity, _set_incoming_capacity, doc="""
-        The incoming capacity of this session in bytes. The incoming capacity
+    @property
+    def incoming_capacity(self) -> int:
+        """The incoming capacity of this session in bytes. The incoming capacity
         of a session determines how much incoming message data the session
         can buffer.
 
@@ -622,29 +604,26 @@ class Session(Wrapper, Endpoint):
             frames when dividing remaining capacity at a given time by the connection
             max frame size. As such, capacity and max frame size should be chosen so
             as to ensure the frame window isn't unduly small and limiting performance.
+        """
+        return pn_session_get_incoming_capacity(self._impl)
 
-        :type: ``int`` (bytes)
-        """)
+    @incoming_capacity.setter
+    def incoming_capacity(self, capacity: int) -> None:
+        pn_session_set_incoming_capacity(self._impl, capacity)
 
-    def _get_outgoing_window(self):
+    @property
+    def outgoing_window(self) -> int:
+        """The outgoing window for this session."""
         return pn_session_get_outgoing_window(self._impl)
 
-    def _set_outgoing_window(self, window):
+    @outgoing_window.setter
+    def outgoing_window(self, window: int) -> None:
         pn_session_set_outgoing_window(self._impl, window)
 
-    outgoing_window = property(_get_outgoing_window, _set_outgoing_window, doc="""
-        The outgoing window for this session.
-
-        :type: ``int``
-        """)
-
     @property
-    def outgoing_bytes(self):
-        """
-        The number of outgoing bytes currently buffered.
-
-        :type: ``int`` (bytes)
+    def outgoing_bytes(self) -> int:
         """
+        The number of outgoing bytes currently buffered."""
         return pn_session_outgoing_bytes(self._impl)
 
     @property
@@ -1051,41 +1030,31 @@ class Link(Wrapper, Endpoint):
         """
         return pn_link_remote_rcv_settle_mode(self._impl)
 
-    def _get_snd_settle_mode(self):
-        return pn_link_snd_settle_mode(self._impl)
-
-    def _set_snd_settle_mode(self, mode):
-        pn_link_set_snd_settle_mode(self._impl, mode)
-
-    snd_settle_mode = property(_get_snd_settle_mode, _set_snd_settle_mode, doc="""
-        The local sender settle mode for this link. One of
+    @property
+    def snd_settle_mode(self) -> int:
+        """The local sender settle mode for this link. One of
         :const:`SND_UNSETTLED`, :const:`SND_SETTLED` or
         :const:`SND_MIXED`.
+        """
+        return pn_link_snd_settle_mode(self._impl)
 
-        :type: ``int``
-        """)
+    @snd_settle_mode.setter
+    def snd_settle_mode(self, mode: int) -> None:
+        pn_link_set_snd_settle_mode(self._impl, mode)
 
-    def _get_rcv_settle_mode(self):
+    @property
+    def rcv_settle_mode(self) -> int:
+        """The local receiver settle mode for this link. One of
+        :const:`RCV_FIRST` or :const:`RCV_SECOND`."""
         return pn_link_rcv_settle_mode(self._impl)
 
-    def _set_rcv_settle_mode(self, mode):
+    @rcv_settle_mode.setter
+    def rcv_settle_mode(self, mode: int) -> None:
         pn_link_set_rcv_settle_mode(self._impl, mode)
 
-    rcv_settle_mode = property(_get_rcv_settle_mode, _set_rcv_settle_mode, doc="""
-        The local receiver settle mode for this link. One of
-        :const:`RCV_FIRST` or :const:`RCV_SECOND`.
-
-        :type: ``int``
-        """)
-
-    def _get_drain(self):
-        return pn_link_get_drain(self._impl)
-
-    def _set_drain(self, b):
-        pn_link_set_drain(self._impl, bool(b))
-
-    drain_mode = property(_get_drain, _set_drain, doc="""
-        The drain mode on this link.
+    @property
+    def drain_mode(self) -> bool:
+        """The drain mode on this link.
 
         If a link is in drain mode (``True``), then the sending
         endpoint of a link must immediately use up all available
@@ -1094,9 +1063,12 @@ class Link(Wrapper, Endpoint):
         the receiving endpoint can set the drain mode.
 
         When ``False``, this link is not in drain mode.
+        """
+        return pn_link_get_drain(self._impl)
 
-        :type: ``bool``
-        """)
+    @drain_mode.setter
+    def drain_mode(self, b: bool):
+        pn_link_set_drain(self._impl, bool(b))
 
     def drained(self) -> int:
         """
@@ -1131,22 +1103,20 @@ class Link(Wrapper, Endpoint):
         """
         return pn_link_remote_max_message_size(self._impl)
 
-    def _get_max_message_size(self):
-        return pn_link_max_message_size(self._impl)
-
-    def _set_max_message_size(self, mode):
-        pn_link_set_max_message_size(self._impl, mode)
-
-    max_message_size = property(_get_max_message_size, _set_max_message_size, doc="""
-        The maximum message size for this link. A zero value means the
+    @property
+    def max_message_size(self) -> int:
+        """The maximum message size for this link. A zero value means the
         size is unlimited.
 
         .. warning:: **Unsettled API**
+        """
+        return pn_link_max_message_size(self._impl)
 
-        :type: ``long``
-        """)
+    @max_message_size.setter
+    def max_message_size(self, mode: int) -> None:
+        pn_link_set_max_message_size(self._impl, mode)
 
-    def detach(self):
+    def detach(self) -> None:
         """
         Detach this link.
         """
@@ -1175,26 +1145,24 @@ class Link(Wrapper, Endpoint):
         """
         return dat2obj(pn_link_remote_properties(self._impl))
 
-    def _get_properties(self):
+    @property
+    def properties(self) -> Optional[PropertyDict]:
+        """Link properties as a dictionary of key/values. The AMQP 1.0
+        specification restricts this dictionary to have keys that are only
+        :class:`symbol` types. It is possible to use the special ``dict``
+        subclass :class:`PropertyDict` which will by default enforce this
+        restrictions on construction. In addition, if strings type are used,
+        this will silently convert them into symbols.
+        """
         return self._properties_dict
 
-    def _set_properties(self, properties_dict):
+    @properties.setter
+    def properties(self, properties_dict: Optional[Dict['symbol', 'PythonAMQPData']]) -> None:
         if isinstance(properties_dict, dict):
             self._properties_dict = PropertyDict(properties_dict, raise_on_error=False)
         else:
             self._properties_dict = properties_dict
 
-    properties = property(_get_properties, _set_properties, doc="""
-    Link properties as a dictionary of key/values. The AMQP 1.0
-    specification restricts this dictionary to have keys that are only
-    :class:`symbol` types. It is possible to use the special ``dict``
-    subclass :class:`PropertyDict` which will by default enforce this
-    restrictions on construction. In addition, if strings type are used,
-    this will silently convert them into symbols.
-
-    :type: ``dict`` containing :class:`symbol`` keys.
-    """)
-
 
 class Sender(Link):
     """
@@ -1218,7 +1186,7 @@ class Sender(Link):
         """
         return self._check(pn_link_send(self._impl, data))
 
-    def send(self, obj, tag=None):
+    def send(self, obj: Union[bytes, 'Message'], tag: Optional[str] = None) -> Union[int, Delivery]:
         """
         A convenience method to send objects as message content.
 
@@ -1356,101 +1324,79 @@ class Terminus(object):
         else:
             return err
 
-    def _get_type(self):
+    @property
+    def type(self) -> int:
+        """The terminus type, must be one of :const:`UNSPECIFIED`,
+        :const:`SOURCE`, :const:`TARGET` or :const:`COORDINATOR`.
+        """
         return pn_terminus_get_type(self._impl)
 
-    def _set_type(self, type):
+    @type.setter
+    def type(self, type: int) -> None:
         self._check(pn_terminus_set_type(self._impl, type))
 
-    type = property(_get_type, _set_type, doc="""
-        The terminus type, must be one of :const:`UNSPECIFIED`,
-        :const:`SOURCE`, :const:`TARGET` or :const:`COORDINATOR`
-
-        :type: ``int``
-        """)
-
-    def _get_address(self):
-        """
-        The address that identifies the source or target node
-        """
+    @property
+    def address(self) -> Optional[str]:
+        """The address that identifies the source or target node"""
         return utf82unicode(pn_terminus_get_address(self._impl))
 
-    def _set_address(self, address):
+    @address.setter
+    def address(self, address: str) -> None:
         self._check(pn_terminus_set_address(self._impl, unicode2utf8(address)))
 
-    address = property(_get_address, _set_address, doc="""
-        The terminus address.
-
-        :type: ``str``
-        """)
-
-    def _get_durability(self):
-        return pn_terminus_get_durability(self._impl)
-
-    def _set_durability(self, seconds):
-        self._check(pn_terminus_set_durability(self._impl, seconds))
-
-    durability = property(_get_durability, _set_durability, doc="""
-        The terminus durability mode, must be one of :const:`NONDURABLE`,
+    @property
+    def durability(self) -> int:
+        """The terminus durability mode, must be one of :const:`NONDURABLE`,
         :const:`CONFIGURATION` or :const:`DELIVERIES`.
+        """
+        return pn_terminus_get_durability(self._impl)
 
-        :type: ``int``
-        """)
-
-    def _get_expiry_policy(self):
-        return pn_terminus_get_expiry_policy(self._impl)
-
-    def _set_expiry_policy(self, seconds):
-        self._check(pn_terminus_set_expiry_policy(self._impl, seconds))
+    @durability.setter
+    def durability(self, mode: int):
+        self._check(pn_terminus_set_durability(self._impl, mode))
 
-    expiry_policy = property(_get_expiry_policy, _set_expiry_policy, doc="""
-        The terminus expiry policy, must be one of :const:`EXPIRE_WITH_LINK`,
+    @property
+    def expiry_policy(self) -> int:
+        """The terminus expiry policy, must be one of :const:`EXPIRE_WITH_LINK`,
         :const:`EXPIRE_WITH_SESSION`, :const:`EXPIRE_WITH_CONNECTION` or
         :const:`EXPIRE_NEVER`.
+        """
+        return pn_terminus_get_expiry_policy(self._impl)
 
-        :type: ``int``
-        """)
+    @expiry_policy.setter
+    def expiry_policy(self, policy: int):
+        self._check(pn_terminus_set_expiry_policy(self._impl, policy))
 
-    def _get_timeout(self):
+    @property
+    def timeout(self) -> int:
+        """The terminus timeout in seconds."""
         return pn_terminus_get_timeout(self._impl)
 
-    def _set_timeout(self, seconds):
+    @timeout.setter
+    def timeout(self, seconds: int) -> None:
         self._check(pn_terminus_set_timeout(self._impl, seconds))
 
-    timeout = property(_get_timeout, _set_timeout, doc="""
-        The terminus timeout in seconds.
-
-        :type: ``int``
-        """)
-
-    def _is_dynamic(self):
+    @property
+    def dynamic(self) -> bool:
         """Indicates whether the source or target node was dynamically
         created"""
         return pn_terminus_is_dynamic(self._impl)
 
-    def _set_dynamic(self, dynamic):
+    @dynamic.setter
+    def dynamic(self, dynamic: bool) -> None:
         self._check(pn_terminus_set_dynamic(self._impl, dynamic))
 
-    dynamic = property(_is_dynamic, _set_dynamic, doc="""
-        The dynamic flag for this terminus object. This indicates if this
-        terminus was dynamically created.
-
-        :type: ``bool``
-        """)
-
-    def _get_distribution_mode(self):
+    @property
+    def distribution_mode(self) -> int:
+        """The terminus distribution mode, must be one of :const:`DIST_MODE_UNSPECIFIED`,
+        :const:`DIST_MODE_COPY` or :const:`DIST_MODE_MOVE`.
+        """
         return pn_terminus_get_distribution_mode(self._impl)
 
-    def _set_distribution_mode(self, mode):
+    @distribution_mode.setter
+    def distribution_mode(self, mode: int) -> None:
         self._check(pn_terminus_set_distribution_mode(self._impl, mode))
 
-    distribution_mode = property(_get_distribution_mode, _set_distribution_mode, doc="""
-        The terminus distribution mode, must be one of :const:`DIST_MODE_UNSPECIFIED`,
-        :const:`DIST_MODE_COPY` or :const:`DIST_MODE_MOVE`.
-
-        :type: ``int``
-        """)
-
     @property
     def properties(self):
         """
@@ -1481,7 +1427,7 @@ class Terminus(object):
     @property
     def filter(self):
         """
-        A filter on a source allows the set of messages transfered over
+        A filter on a source allows the set of messages transferred over
         the link to be restricted. The symbol-keyed map represents a'
         filter set.
 
diff --git a/python/proton/_events.py b/python/proton/_events.py
index bee0bf7..edc34e3 100644
--- a/python/proton/_events.py
+++ b/python/proton/_events.py
@@ -47,7 +47,7 @@ class Collector:
     def __init__(self) -> None:
         self._impl = pn_collector()
 
-    def put(self, obj, etype):
+    def put(self, obj: 'Selectable', etype: 'EventType') -> None:
         pn_collector_put(self._impl, PN_PYREF, pn_py2void(obj), etype.number)
 
     def peek(self) -> Optional['Event']:
diff --git a/python/proton/_message.py b/python/proton/_message.py
index 54e9fe9..6952c8a 100644
--- a/python/proton/_message.py
+++ b/python/proton/_message.py
@@ -43,7 +43,7 @@ if TYPE_CHECKING:
     from proton._delivery import Delivery
     from proton._endpoints import Sender, Receiver
     from uuid import UUID
-    from proton._data import Described
+    from proton._data import Described, PythonAMQPData
 
 
 class Message(object):
@@ -56,7 +56,6 @@ class Message(object):
     :ivar ~.properties: application defined message properties
     :vartype ~.properties: ``dict``
     :ivar body: message body
-    :vartype body: bytes | unicode | dict | list | int | long | float | UUID
 
     :param kwargs: Message property name/value pairs to initialize the Message
     """
@@ -64,7 +63,11 @@ class Message(object):
     DEFAULT_PRIORITY = PN_DEFAULT_PRIORITY
     """ Default AMQP message priority"""
 
-    def __init__(self, body=None, **kwargs):
+    def __init__(
+            self,
+            body: Union[bytes, str, dict, list, int, float, 'UUID', 'Described', None] = None,
+            **kwargs
+    ) -> None:
         self._msg = pn_message()
         self._id = Data(pn_message_id(self._msg))
         self._correlation_id = Data(pn_message_correlation_id(self._msg))
@@ -171,46 +174,39 @@ class Message(object):
         self.properties = None
         self.body = None
 
-    def _is_inferred(self):
-        return pn_message_is_inferred(self._msg)
-
-    def _set_inferred(self, value):
-        self._check(pn_message_set_inferred(self._msg, bool(value)))
-
-    inferred = property(_is_inferred, _set_inferred, doc="""
-        The inferred flag for a message indicates how the message content
+    @property
+    def inferred(self) -> bool:
+        """The inferred flag for a message indicates how the message content
         is encoded into AMQP sections. If inferred is true then binary and
         list values in the body of the message will be encoded as AMQP DATA
         and AMQP SEQUENCE sections, respectively. If inferred is false,
         then all values in the body of the message will be encoded as AMQP
         VALUE sections regardless of their type.
 
-        :type: ``bool``
         :raise: :exc:`MessageException` if there is any Proton error when using the setter.
-        """)
-
-    def _is_durable(self):
-        return pn_message_is_durable(self._msg)
+        """
+        return pn_message_is_inferred(self._msg)
 
-    def _set_durable(self, value):
-        self._check(pn_message_set_durable(self._msg, bool(value)))
+    @inferred.setter
+    def inferred(self, value: bool) -> None:
+        self._check(pn_message_set_inferred(self._msg, bool(value)))
 
-    durable = property(_is_durable, _set_durable, doc="""
-        The durable property indicates that the message should be held durably
+    @property
+    def durable(self) -> bool:
+        """The durable property indicates that the message should be held durably
         by any intermediaries taking responsibility for the message.
 
-        :type: ``bool``
         :raise: :exc:`MessageException` if there is any Proton error when using the setter.
-        """)
-
-    def _get_priority(self):
-        return pn_message_get_priority(self._msg)
+        """
+        return pn_message_is_durable(self._msg)
 
-    def _set_priority(self, value):
-        self._check(pn_message_set_priority(self._msg, value))
+    @durable.setter
+    def durable(self, value: bool) -> None:
+        self._check(pn_message_set_durable(self._msg, bool(value)))
 
-    priority = property(_get_priority, _set_priority, doc="""
-        The relative priority of the message, with higher numbers indicating
+    @property
+    def priority(self) -> int:
+        """The relative priority of the message, with higher numbers indicating
         higher priority. The number of available priorities depends
         on the implementation, but AMQP defines the default priority as
         the value ``4``. See the
@@ -218,62 +214,55 @@ class Message(object):
         <http://docs.oasis-open.org/amqp/core/v1.0/os/amqp-core-messaging-v1.0-os.html#type-header>`_
         for more details on message priority.
 
-        :type: ``int``
         :raise: :exc:`MessageException` if there is any Proton error when using the setter.
-        """)
+        """
+        return pn_message_get_priority(self._msg)
 
-    def _get_ttl(self):
+    @priority.setter
+    def priority(self, value: int) -> None:
+        self._check(pn_message_set_priority(self._msg, value))
+
+    @property
+    def ttl(self) -> float:
+        """The time to live of the message measured in seconds. Expired messages
+        may be dropped.
+
+        :raise: :exc:`MessageException` if there is any Proton error when using the setter.
+        """
         return millis2secs(pn_message_get_ttl(self._msg))
 
-    def _set_ttl(self, value):
+    @ttl.setter
+    def ttl(self, value: Union[float, int]) -> None:
         self._check(pn_message_set_ttl(self._msg, secs2millis(value)))
 
-    ttl = property(_get_ttl, _set_ttl, doc="""
-        The time to live of the message measured in seconds. Expired messages
-        may be dropped.
+    @property
+    def first_acquirer(self) -> bool:
+        """``True`` iff the recipient is the first to acquire the message,
+        ``False`` otherwise.
 
-        :type: ``int``
         :raise: :exc:`MessageException` if there is any Proton error when using the setter.
-        """)
-
-    def _is_first_acquirer(self):
+        """
         return pn_message_is_first_acquirer(self._msg)
 
-    def _set_first_acquirer(self, value):
+    @first_acquirer.setter
+    def first_acquirer(self, value: bool) -> None:
         self._check(pn_message_set_first_acquirer(self._msg, bool(value)))
 
-    first_acquirer = property(_is_first_acquirer, _set_first_acquirer, doc="""
-        ``True`` iff the recipient is the first to acquire the message,
-        ``False`` otherwise.
+    @property
+    def delivery_count(self) -> int:
+        """The number of delivery attempts made for this message.
 
-        :type: ``bool``
         :raise: :exc:`MessageException` if there is any Proton error when using the setter.
-        """)
-
-    def _get_delivery_count(self):
+        """
         return pn_message_get_delivery_count(self._msg)
 
-    def _set_delivery_count(self, value):
+    @delivery_count.setter
+    def delivery_count(self, value: int) -> None:
         self._check(pn_message_set_delivery_count(self._msg, value))
 
-    delivery_count = property(_get_delivery_count, _set_delivery_count, doc="""
-        The number of delivery attempts made for this message.
-
-        :type: ``int``
-        :raise: :exc:`MessageException` if there is any Proton error when using the setter.
-        """)
-
-    def _get_id(self):
-        return self._id.get_object()
-
-    def _set_id(self, value):
-        if isinteger(value):
-            value = ulong(value)
-        self._id.rewind()
-        self._id.put_object(value)
-
-    id = property(_get_id, _set_id, doc="""
-        The globally unique id of the message, and can be used
+    @property
+    def id(self) -> Optional[Union[str, bytes, 'UUID', ulong]]:
+        """The globally unique id of the message, and can be used
         to determine if a received message is a duplicate. The allowed
         types to set the id are:
 
@@ -283,214 +272,211 @@ class Message(object):
                * ``uuid.UUID``
                * ``bytes``
                * ``str``
-        """)
+        """
+        return self._id.get_object()
+
+    @id.setter
+    def id(self, value: Optional[Union[str, bytes, 'UUID', int]]) -> None:
+        if isinteger(value):
+            value = ulong(value)
+        self._id.rewind()
+        self._id.put_object(value)
+
+    @property
+    def user_id(self) -> bytes:
+        """The user id of the message creator.
 
-    def _get_user_id(self):
+        :raise: :exc:`MessageException` if there is any Proton error when using the setter.
+        """
         return pn_message_get_user_id(self._msg)
 
-    def _set_user_id(self, value):
+    @user_id.setter
+    def user_id(self, value: bytes) -> None:
         self._check(pn_message_set_user_id(self._msg, value))
 
-    user_id = property(_get_user_id, _set_user_id, doc="""
-        The user id of the message creator.
+    @property
+    def address(self) -> Optional[str]:
+        """The address of the message.
 
-        :type: ``bytes``
         :raise: :exc:`MessageException` if there is any Proton error when using the setter.
-        """)
-
-    def _get_address(self):
+        """
         return utf82unicode(pn_message_get_address(self._msg))
 
-    def _set_address(self, value):
+    @address.setter
+    def address(self, value: str) -> None:
         self._check(pn_message_set_address(self._msg, unicode2utf8(value)))
 
-    address = property(_get_address, _set_address, doc="""
-        The address of the message.
+    @property
+    def subject(self) -> Optional[str]:
+        """The subject of the message.
 
-        :type: ``str``
         :raise: :exc:`MessageException` if there is any Proton error when using the setter.
-        """)
-
-    def _get_subject(self):
+        """
         return utf82unicode(pn_message_get_subject(self._msg))
 
-    def _set_subject(self, value):
+    @subject.setter
+    def subject(self, value: str) -> None:
         self._check(pn_message_set_subject(self._msg, unicode2utf8(value)))
 
-    subject = property(_get_subject, _set_subject, doc="""
-        The subject of the message.
+    @property
+    def reply_to(self) -> Optional[str]:
+        """The reply-to address for the message.
 
-        :type: ``str``
         :raise: :exc:`MessageException` if there is any Proton error when using the setter.
-        """)
-
-    def _get_reply_to(self):
+        """
         return utf82unicode(pn_message_get_reply_to(self._msg))
 
-    def _set_reply_to(self, value):
+    @reply_to.setter
+    def reply_to(self, value: str) -> None:
         self._check(pn_message_set_reply_to(self._msg, unicode2utf8(value)))
 
-    reply_to = property(_get_reply_to, _set_reply_to, doc="""
-        The reply-to address for the message.
+    @property
+    def correlation_id(self) -> Optional[Union['UUID', ulong, str, bytes]]:
+        """The correlation-id for the message.
 
-        :type: ``str``
-        :raise: :exc:`MessageException` if there is any Proton error when using the setter.
-        """)
+        :type: The valid AMQP types for a correlation-id are one of:
 
-    def _get_correlation_id(self):
+               * ``int`` (unsigned)
+               * ``uuid.UUID``
+               * ``bytes``
+               * ``str``
+        """
         return self._correlation_id.get_object()
 
-    def _set_correlation_id(self, value):
+    @correlation_id.setter
+    def correlation_id(self, value: Optional[Union[str, bytes, 'UUID', int]]) -> None:
         if isinteger(value):
             value = ulong(value)
         self._correlation_id.rewind()
         self._correlation_id.put_object(value)
 
-    correlation_id = property(_get_correlation_id, _set_correlation_id, doc="""
-        The correlation-id for the message.
-
-        :type: The valid AMQP types for a correlation-id are one of:
-
-               * ``int`` (unsigned)
-               * ``uuid.UUID``
-               * ``bytes``
-               * ``str``
-        """)
+    @property
+    def content_type(self) -> symbol:
+        """The RFC-2046 [RFC2046] MIME type for the message body.
 
-    def _get_content_type(self):
+        :raise: :exc:`MessageException` if there is any Proton error when using the setter.
+        """
         return symbol(utf82unicode(pn_message_get_content_type(self._msg)))
 
-    def _set_content_type(self, value):
+    @content_type.setter
+    def content_type(self, value: str) -> None:
         self._check(pn_message_set_content_type(self._msg, unicode2utf8(value)))
 
-    content_type = property(_get_content_type, _set_content_type, doc="""
-        The RFC-2046 [RFC2046] MIME type for the message body.
+    @property
+    def content_encoding(self) -> symbol:
+        """The content-encoding of the message.
 
-        :type: :class:`symbol`
         :raise: :exc:`MessageException` if there is any Proton error when using the setter.
-        """)
-
-    def _get_content_encoding(self):
+        """
         return symbol(utf82unicode(pn_message_get_content_encoding(self._msg)))
 
-    def _set_content_encoding(self, value):
+    @content_encoding.setter
+    def content_encoding(self, value: str) -> None:
         self._check(pn_message_set_content_encoding(self._msg, unicode2utf8(value)))
 
-    content_encoding = property(_get_content_encoding, _set_content_encoding, doc="""
-        The content-encoding of the message.
+    @property
+    def expiry_time(self) -> float:  # TODO doc said int
+        """The absolute expiry time of the message in seconds using the Unix time_t [IEEE1003] encoding.
 
-        :type: :class:`symbol`
         :raise: :exc:`MessageException` if there is any Proton error when using the setter.
-        """)
-
-    def _get_expiry_time(self):
+        """
         return millis2secs(pn_message_get_expiry_time(self._msg))
 
-    def _set_expiry_time(self, value):
+    @expiry_time.setter
+    def expiry_time(self, value: Union[float, int]) -> None:
         self._check(pn_message_set_expiry_time(self._msg, secs2millis(value)))
 
-    expiry_time = property(_get_expiry_time, _set_expiry_time, doc="""
-        The absolute expiry time of the message in seconds using the Unix time_t [IEEE1003] encoding.
+    @property
+    def creation_time(self) -> float:
+        """The creation time of the message in seconds using the Unix time_t [IEEE1003] encoding.
 
-        :type: ``int``
         :raise: :exc:`MessageException` if there is any Proton error when using the setter.
-        """)
-
-    def _get_creation_time(self):
+        """
         return millis2secs(pn_message_get_creation_time(self._msg))
 
-    def _set_creation_time(self, value):
+    @creation_time.setter
+    def creation_time(self, value: Union[float, int]) -> None:
         self._check(pn_message_set_creation_time(self._msg, secs2millis(value)))
 
-    creation_time = property(_get_creation_time, _set_creation_time, doc="""
-        The creation time of the message in seconds using the Unix time_t [IEEE1003] encoding.
+    @property
+    def group_id(self) -> Optional[str]:
+        """The group id of the message.
 
-        :type: ``int``
         :raise: :exc:`MessageException` if there is any Proton error when using the setter.
-        """)
-
-    def _get_group_id(self):
+        """
         return utf82unicode(pn_message_get_group_id(self._msg))
 
-    def _set_group_id(self, value):
+    @group_id.setter
+    def group_id(self, value: str) -> None:
         self._check(pn_message_set_group_id(self._msg, unicode2utf8(value)))
 
-    group_id = property(_get_group_id, _set_group_id, doc="""
-        The group id of the message.
+    @property
+    def group_sequence(self) -> int:
+        """The sequence of the message within its group.
 
-        :type: ``str``
         :raise: :exc:`MessageException` if there is any Proton error when using the setter.
-        """)
-
-    def _get_group_sequence(self):
+        """
         return pn_message_get_group_sequence(self._msg)
 
-    def _set_group_sequence(self, value):
+    @group_sequence.setter
+    def group_sequence(self, value: int) -> None:
         self._check(pn_message_set_group_sequence(self._msg, value))
 
-    group_sequence = property(_get_group_sequence, _set_group_sequence, doc="""
-        The sequence of the message within its group.
+    @property
+    def reply_to_group_id(self) -> Optional[str]:
+        """The group-id for any replies.
 
-        :type: ``int``
         :raise: :exc:`MessageException` if there is any Proton error when using the setter.
-        """)
-
-    def _get_reply_to_group_id(self):
+        """
         return utf82unicode(pn_message_get_reply_to_group_id(self._msg))
 
-    def _set_reply_to_group_id(self, value):
+    @reply_to_group_id.setter
+    def reply_to_group_id(self, value: str) -> None:
         self._check(pn_message_set_reply_to_group_id(self._msg, unicode2utf8(value)))
 
-    reply_to_group_id = property(_get_reply_to_group_id, _set_reply_to_group_id, doc="""
-        The group-id for any replies.
-
-        :type: ``str``
-        :raise: :exc:`MessageException` if there is any Proton error when using the setter.
-        """)
-
-    def _get_instructions(self):
+    @property
+    def instructions(self) -> Optional[AnnotationDict]:
+        """Delivery annotations as a dictionary of key/values. The AMQP 1.0
+        specification restricts this dictionary to have keys that are either
+        :class:`symbol` or :class:`ulong` types. It is possible to use
+        the special ``dict`` subclass :class:`AnnotationDict` which
+        will by default enforce these restrictions on construction. In addition,
+        if string types are used, this class will be silently convert them into
+        symbols.
+
+        :type: :class:`AnnotationDict`. Any ``dict`` with :class:`ulong` or :class:`symbol` keys.
+        """
         return self.instruction_dict
 
-    def _set_instructions(self, instructions):
+    @instructions.setter
+    def instructions(self, instructions: Optional[Dict[Union[str, int], 'PythonAMQPData']]) -> None:
         if isinstance(instructions, dict):
             self.instruction_dict = AnnotationDict(instructions, raise_on_error=False)
         else:
             self.instruction_dict = instructions
 
-    instructions = property(_get_instructions, _set_instructions, doc="""
-    Delivery annotations as a dictionary of key/values. The AMQP 1.0
-    specification restricts this dictionary to have keys that are either
-    :class:`symbol` or :class:`ulong` types. It is possible to use
-    the special ``dict`` subclass :class:`AnnotationDict` which
-    will by default enforce these restrictions on construction. In addition,
-    if string types are used, this class will be silently convert them into
-    symbols.
-
-    :type: :class:`AnnotationDict`. Any ``dict`` with :class:`ulong` or :class:`symbol` keys.
-    """)
-
-    def _get_annotations(self):
+    @property
+    def annotations(self) -> Optional[AnnotationDict]:
+        """Message annotations as a dictionary of key/values. The AMQP 1.0
+        specification restricts this dictionary to have keys that are either
+        :class:`symbol` or :class:`ulong` types. It is possible to use
+        the special ``dict`` subclass :class:`AnnotationDict` which
+        will by default enforce these restrictions on construction. In addition,
+        if a string types are used, this class will silently convert them into
+        symbols.
+
+        :type: :class:`AnnotationDict`. Any ``dict`` with :class:`ulong` or :class:`symbol` keys.
+        """
         return self.annotation_dict
 
-    def _set_annotations(self, annotations):
+    @annotations.setter
+    def annotations(self, annotations: Optional[Dict[Union[str, int], 'PythonAMQPData']]) -> None:
         if isinstance(annotations, dict):
             self.annotation_dict = AnnotationDict(annotations, raise_on_error=False)
         else:
             self.annotation_dict = annotations
 
-    annotations = property(_get_annotations, _set_annotations, doc="""
-    Message annotations as a dictionary of key/values. The AMQP 1.0
-    specification restricts this dictionary to have keys that are either
-    :class:`symbol` or :class:`ulong` types. It is possible to use
-    the special ``dict`` subclass :class:`AnnotationDict` which
-    will by default enforce these restrictions on construction. In addition,
-    if a string types are used, this class will silently convert them into
-    symbols.
-
-    :type: :class:`AnnotationDict`. Any ``dict`` with :class:`ulong` or :class:`symbol` keys.
-    """)
-
-    def encode(self):
+    def encode(self) -> bytes:
         self._pre_encode()
         sz = 16
         while True:
diff --git a/python/proton/_reactor.py b/python/proton/_reactor.py
index aeabc53..a71328f 100644
--- a/python/proton/_reactor.py
+++ b/python/proton/_reactor.py
@@ -582,7 +582,7 @@ class Transaction(object):
             self,
             sender: 'Sender',
             msg: Message,
-            tag: Optional[bytes] = None,
+            tag: Optional[str] = None,
     ) -> Delivery:
         """
         Send a message under this transaction.
diff --git a/python/proton/_selectable.py b/python/proton/_selectable.py
index 4eb370d..12645fd 100644
--- a/python/proton/_selectable.py
+++ b/python/proton/_selectable.py
@@ -58,22 +58,26 @@ class Selectable(object):
     def __getattr__(self, name: str) -> Any:
         return getattr(self._delegate, name)
 
-    def _get_deadline(self):
+    @property
+    def deadline(self) -> Optional[float]:
         tstamp = self._deadline
         if tstamp:
             return tstamp
         else:
             return None
 
-    def _set_deadline(self, deadline):
+    @deadline.setter
+    def deadline(self, deadline: Optional[float]) -> None:
         if not deadline:
             self._deadline = 0
         else:
             self._deadline = deadline
 
-    deadline = property(_get_deadline, _set_deadline)
-
-    def push_event(self, context, etype):
+    def push_event(
+            self,
+            context: 'Selectable',
+            etype: 'EventType',
+    ) -> None:
         self._reactor.push_event(context, etype)
 
     def update(self) -> None:
diff --git a/python/proton/_transport.py b/python/proton/_transport.py
index bf5e5ab..be90b23 100644
--- a/python/proton/_transport.py
+++ b/python/proton/_transport.py
@@ -117,24 +117,22 @@ class Transport(Wrapper):
         else:
             return err
 
-    def _set_tracer(self, tracer):
-        pn_transport_set_pytracer(self._impl, TraceAdapter(tracer))
-
-    def _get_tracer(self):
+    @property
+    def tracer(self) -> Optional[Callable[['Transport', str], None]]:
+        """A callback for trace logging. The callback is passed the transport
+        and log message. For no tracer callback, value is ``None``.
+        """
         adapter = pn_transport_get_pytracer(self._impl)
         if adapter:
             return adapter.tracer
         else:
             return None
 
-    tracer = property(_get_tracer, _set_tracer, doc="""
-        A callback for trace logging. The callback is passed the transport
-        and log message. For no tracer callback, value is ``None``.
-
-        :type: Tracer callback function
-        """)
+    @tracer.setter
+    def tracer(self, tracer: Callable[['Transport', str], None]) -> None:
+        pn_transport_set_pytracer(self._impl, TraceAdapter(tracer))
 
-    def log(self, message):
+    def log(self, message: str) -> None:
         """
         Log a message using a transport's logging mechanism.
 
@@ -344,7 +342,7 @@ class Transport(Wrapper):
             self._check(cd)
             return out
 
-    def pop(self, size):
+    def pop(self, size: int) -> None:
         """
         Removes ``size`` bytes of output from the pending output queue
         following the transport's head pointer.
@@ -353,8 +351,7 @@ class Transport(Wrapper):
         well as the number of pending bytes reported by
         :meth:`pending`.
 
-        :param size: Number of bytes to return.
-        :type size: ``int``
+        :param size: Number of bytes to remove.
         """
         pn_transport_pop(self._impl, size)
 
@@ -377,36 +374,25 @@ class Transport(Wrapper):
         return pn_transport_closed(self._impl)
 
     # AMQP 1.0 max-frame-size
-    def _get_max_frame_size(self):
+    @property
+    def max_frame_size(self) -> int:
+        """The maximum size for transport frames (in bytes)."""
         return pn_transport_get_max_frame(self._impl)
 
-    def _set_max_frame_size(self, value):
+    @max_frame_size.setter
+    def max_frame_size(self, value: int) -> None:
         pn_transport_set_max_frame(self._impl, value)
 
-    max_frame_size = property(_get_max_frame_size, _set_max_frame_size, doc="""
-        The maximum size for transport frames (in bytes).
-
-        :type: ``int``
-        """)
-
     @property
-    def remote_max_frame_size(self):
+    def remote_max_frame_size(self) -> int:
         """
         The maximum frame size of a transport's remote peer (in bytes).
-
-        :type: ``int``
         """
         return pn_transport_get_remote_max_frame(self._impl)
 
-    def _get_channel_max(self):
-        return pn_transport_get_channel_max(self._impl)
-
-    def _set_channel_max(self, value):
-        if pn_transport_set_channel_max(self._impl, value):
-            raise SessionException("Too late to change channel max.")
-
-    channel_max = property(_get_channel_max, _set_channel_max, doc="""
-        The maximum channel number that may be used on this transport.
+    @property
+    def channel_max(self) -> int:
+        """The maximum channel number that may be used on this transport.
 
         .. note:: This is the maximum channel number allowed, giving a
             valid channel number range of ``[0 .. channel_max]``. Therefore the
@@ -421,34 +407,35 @@ class Transport(Wrapper):
         After the ``OPEN`` frame has been sent to the remote peer,
         further calls to this function will have no effect.
 
-        :type: ``int``
         :raise: :exc:`SessionException` if the ``OPEN`` frame has already
                 been sent.
-        """)
+        """
+        return pn_transport_get_channel_max(self._impl)
+
+    @channel_max.setter
+    def channel_max(self, value: int) -> None:
+        if pn_transport_set_channel_max(self._impl, value):
+            raise SessionException("Too late to change channel max.")
 
     @property
-    def remote_channel_max(self):
+    def remote_channel_max(self) -> int:
         """
         The maximum allowed channel number of a transport's remote peer.
-
-        :type: ``int``
         """
         return pn_transport_remote_channel_max(self._impl)
 
     # AMQP 1.0 idle-time-out
-    def _get_idle_timeout(self):
+    @property
+    def idle_timeout(self) -> float:
+        """The idle timeout of the connection in seconds. A zero idle
+        timeout means heartbeats are disabled.
+        """
         return millis2secs(pn_transport_get_idle_timeout(self._impl))
 
-    def _set_idle_timeout(self, sec):
+    @idle_timeout.setter
+    def idle_timeout(self, sec: Union[float, int]) -> None:
         pn_transport_set_idle_timeout(self._impl, secs2millis(sec))
 
-    idle_timeout = property(_get_idle_timeout, _set_idle_timeout, doc="""
-        The idle timeout of the connection in seconds. A zero idle
-        timeout means heartbeats are disabled.
-
-        :type: ``float``
-        """)
-
     @property
     def remote_idle_timeout(self) -> float:
         """
@@ -494,31 +481,25 @@ class Transport(Wrapper):
             self._ssl = SSL(self, domain, session_details)
         return self._ssl
 
-    def _get_condition(self):
-        return cond2obj(pn_transport_condition(self._impl))
-
-    def _set_condition(self, cond):
-        pn_cond = pn_transport_condition(self._impl)
-        obj2cond(cond, pn_cond)
-
-    condition = property(_get_condition, _set_condition, doc="""
-        Get additional information about the condition of the transport.
+    @property
+    def condition(self) -> Optional['Condition']:
+        """Get additional information about the condition of the transport.
 
         When a :const:`Event.TRANSPORT_ERROR` event occurs, this operation
         can be used to access the details of the error condition.
 
         See :class:`Condition` for more information.
+        """
+        return cond2obj(pn_transport_condition(self._impl))
 
-        :type: :class:`Condition`
-        """)
+    @condition.setter
+    def condition(self, cond: 'Condition') -> None:
+        pn_cond = pn_transport_condition(self._impl)
+        obj2cond(cond, pn_cond)
 
     @property
-    def connection(self):
-        """
-        The connection bound to this transport.
-
-        :type: :class:`Connection`
-        """
+    def connection(self) -> 'Connection':
+        """The connection bound to this transport."""
         from . import _endpoints
         return _endpoints.Connection.wrap(pn_transport_connection(self._impl))
 
@@ -664,17 +645,15 @@ class SASL(Wrapper):
             mechs = " ".join(mechs)
         pn_sasl_allowed_mechs(self._sasl, unicode2utf8(mechs))
 
-    def _get_allow_insecure_mechs(self):
+    @property
+    def allow_insecure_mechs(self) -> bool:
+        """Allow unencrypted cleartext passwords (PLAIN mech)"""
         return pn_sasl_get_allow_insecure_mechs(self._sasl)
 
-    def _set_allow_insecure_mechs(self, insecure):
+    @allow_insecure_mechs.setter
+    def allow_insecure_mechs(self, insecure: bool) -> None:
         pn_sasl_set_allow_insecure_mechs(self._sasl, insecure)
 
-    allow_insecure_mechs = property(_get_allow_insecure_mechs, _set_allow_insecure_mechs,
-                                    doc="""
-Allow unencrypted cleartext passwords (PLAIN mech)
-""")
-
     def done(self, outcome):
         """
         Set the outcome of SASL negotiation. Used by the server to set the
@@ -1049,7 +1028,7 @@ class SSL(object):
         """
         return self.get_cert_subject_subfield(SSL.CERT_STATE_OR_PROVINCE)
 
-    def get_cert_fingerprint(self, fingerprint_length, digest_name):
+    def get_cert_fingerprint(self, fingerprint_length: int, digest_name: int) -> Optional[str]:
         """
         Get the fingerprint of the certificate. The certificate fingerprint
         (as displayed in the Fingerprints section when looking at a certificate
@@ -1061,12 +1040,9 @@ class SSL(object):
         :param fingerprint_length: Must be :math:`>= 33` for md5, :math:`>= 41`
                                    for sha1, :math:`>= 65` for sha256 and :math:`>= 129`
                                    for sha512.
-        :type fingerprint_length: ``int``
         :param digest_name: The hash algorithm to use. Must be one of :const:`SHA1`,
                             :const:`SHA256`, :const:`SHA512`,  :const:`MD5`.
-        :type digest_name: ``str``
         :return: Hex fingerprint in a string, or ``None`` if an error occurred.
-        :rtype: ``str`` or ``None``
         """
         rc, fingerprint_str = pn_ssl_get_cert_fingerprint(self._ssl, fingerprint_length, digest_name)
         if rc == PN_OK:
@@ -1148,20 +1124,12 @@ class SSL(object):
                  * :const:`RESUME_UNKNOWN`
                  * :const:`RESUME_NEW`
                  * :const:`RESUME_REUSED`
-        :rtype: ``int``
         """
         return pn_ssl_resume_status(self._ssl)
 
-    def _set_peer_hostname(self, hostname):
-        self._check(pn_ssl_set_peer_hostname(self._ssl, unicode2utf8(hostname)))
-
-    def _get_peer_hostname(self):
-        err, name = pn_ssl_get_peer_hostname(self._ssl, 1024)
-        self._check(err)
-        return utf82unicode(name)
-
-    peer_hostname = property(_get_peer_hostname, _set_peer_hostname, doc="""
-        Manage the expected name of the remote peer.
+    @property
+    def peer_hostname(self) -> str:
+        """Manage the expected name of the remote peer.
 
         The hostname is used for two purposes:
 
@@ -1175,10 +1143,14 @@ class SSL(object):
 
         .. note:: Verification of the hostname is only done if
             :const:`SSLDomain.VERIFY_PEER_NAME` is set using
-            :meth:`SSLDomain.set_peer_authentication`.
+            :meth:`SSLDomain.set_peer_authentication`."""
+        err, name = pn_ssl_get_peer_hostname(self._ssl, 1024)
+        self._check(err)
+        return utf82unicode(name)
 
-        :type: ``str``
-        """)
+    @peer_hostname.setter
+    def peer_hostname(self, hostname: Optional[str]) -> None:
+        self._check(pn_ssl_set_peer_hostname(self._ssl, unicode2utf8(hostname)))
 
 
 class SSLSessionDetails(object):

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org