def get_backend(name: str) -> Backend:
"""Get the specified asynchronous backend.
- *name*, a ``str``, the name of the backend. Currently the "trio"
- and "asyncio" backends are available.
-
- Raises NotImplementedError if an unknown backend name is specified.
+ :param name: The name of the backend. Currently ``"trio"`` and
+ ``"asyncio"`` are available.
+ :type name: str
+ :raises NotImplementedError: If an unknown backend name is specified.
"""
# pylint: disable=import-outside-toplevel,redefined-outer-name
backend = _backends.get(name)
) -> tuple[int, float]:
"""Send a DNS message to the specified UDP socket.
- *sock*, a ``dns.asyncbackend.DatagramSocket``.
-
- *what*, a ``bytes`` or ``dns.message.Message``, the message to send.
-
- *destination*, a destination tuple appropriate for the address family
- of the socket, specifying where to send the query.
-
- *expiration*, a ``float`` or ``None``, the absolute time at which
- a timeout exception should be raised. If ``None``, no timeout will
- occur. The expiration value is meaningless for the asyncio backend, as
- asyncio's transport sendto() never blocks.
-
- Returns an ``(int, float)`` tuple of bytes sent and the sent time.
+ :param sock: The socket to use.
+ :type sock: :py:class:`dns.asyncbackend.DatagramSocket`
+ :param what: The message to send.
+ :type what: bytes or :py:class:`dns.message.Message`
+ :param destination: A destination tuple appropriate for the address
+ family of the socket.
+ :param expiration: The absolute time at which to raise a timeout
+ exception. ``None`` means no timeout (and is meaningless for the
+ asyncio backend, as ``sendto()`` never blocks there).
+ :type expiration: float or ``None``
+ :returns: A ``(bytes_sent, sent_time)`` tuple.
+ :rtype: tuple[int, float]
"""
if isinstance(what, dns.message.Message):
) -> Any:
"""Read a DNS message from a UDP socket.
- *sock*, a ``dns.asyncbackend.DatagramSocket``.
+ :param sock: The socket to read from.
+ :type sock: :py:class:`dns.asyncbackend.DatagramSocket`
- See :py:func:`dns.query.receive_udp()` for the documentation of the other
- parameters, and exceptions.
+ See :py:func:`dns.query.receive_udp` for the documentation of the other
+ parameters and exceptions.
- Returns a ``(dns.message.Message, float, tuple)`` tuple of the received message, the
- received time, and the address where the message arrived from.
+ :returns: A ``(message, received_time, from_address)`` tuple.
+ :rtype: tuple
"""
wire = b""
) -> dns.message.Message:
"""Return the response obtained after sending a query via UDP.
- *sock*, a ``dns.asyncbackend.DatagramSocket``, or ``None``,
- the socket to use for the query. If ``None``, the default, a
- socket is created. Note that if a socket is provided, the
- *source*, *source_port*, and *backend* are ignored.
-
- *backend*, a ``dns.asyncbackend.Backend``, or ``None``. If ``None``,
- the default, then dnspython will use the default backend.
+ :param sock: The socket to use. If ``None`` (the default), a socket is
+ created. Note that if a socket is provided, *source*, *source_port*,
+ and *backend* are ignored.
+ :type sock: :py:class:`dns.asyncbackend.DatagramSocket` or ``None``
+ :param backend: The async backend. If ``None`` (the default), dnspython
+ will use the default backend.
+ :type backend: :py:class:`dns.asyncbackend.Backend` or ``None``
See :py:func:`dns.query.udp()` for the documentation of the other
parameters, exceptions, and return type of this method.
"""Return the response to the query, trying UDP first and falling back
to TCP if UDP results in a truncated response.
- *udp_sock*, a ``dns.asyncbackend.DatagramSocket``, or ``None``,
- the socket to use for the UDP query. If ``None``, the default, a
- socket is created. Note that if a socket is provided the *source*,
- *source_port*, and *backend* are ignored for the UDP query.
-
- *tcp_sock*, a ``dns.asyncbackend.StreamSocket``, or ``None``, the
- socket to use for the TCP query. If ``None``, the default, a
- socket is created. Note that if a socket is provided *where*,
- *source*, *source_port*, and *backend* are ignored for the TCP query.
-
- *backend*, a ``dns.asyncbackend.Backend``, or ``None``. If ``None``,
- the default, then dnspython will use the default backend.
+ :param udp_sock: The socket to use for the UDP query. If ``None``
+ (the default), a socket is created. Note that if a socket is provided,
+ *source*, *source_port*, and *backend* are ignored for the UDP query.
+ :type udp_sock: :py:class:`dns.asyncbackend.DatagramSocket` or ``None``
+ :param tcp_sock: The socket to use for the TCP query. If ``None``
+ (the default), a socket is created. Note that if a socket is provided,
+ *where*, *source*, *source_port*, and *backend* are ignored for the
+ TCP query.
+ :type tcp_sock: :py:class:`dns.asyncbackend.StreamSocket` or ``None``
+ :param backend: The async backend. If ``None`` (the default), dnspython
+ will use the default backend.
+ :type backend: :py:class:`dns.asyncbackend.Backend` or ``None``
See :py:func:`dns.query.udp_with_fallback()` for the documentation
of the other parameters, exceptions, and return type of this
) -> tuple[int, float]:
"""Send a DNS message to the specified TCP socket.
- *sock*, a ``dns.asyncbackend.StreamSocket``.
+ :param sock: The socket to use.
+ :type sock: :py:class:`dns.asyncbackend.StreamSocket`
See :py:func:`dns.query.send_tcp()` for the documentation of the other
parameters, exceptions, and return type of this method.
) -> tuple[dns.message.Message, float]:
"""Read a DNS message from a TCP socket.
- *sock*, a ``dns.asyncbackend.StreamSocket``.
+ :param sock: The socket to use.
+ :type sock: :py:class:`dns.asyncbackend.StreamSocket`
See :py:func:`dns.query.receive_tcp()` for the documentation of the other
parameters, exceptions, and return type of this method.
) -> dns.message.Message:
"""Return the response obtained after sending a query via TCP.
- *sock*, a ``dns.asyncbacket.StreamSocket``, or ``None``, the
- socket to use for the query. If ``None``, the default, a socket
- is created. Note that if a socket is provided
- *where*, *port*, *source*, *source_port*, and *backend* are ignored.
-
- *backend*, a ``dns.asyncbackend.Backend``, or ``None``. If ``None``,
- the default, then dnspython will use the default backend.
+ :param sock: The socket to use. If ``None`` (the default), a socket is
+ created. Note that if a socket is provided, *where*, *port*,
+ *source*, *source_port*, and *backend* are ignored.
+ :type sock: :py:class:`dns.asyncbackend.StreamSocket` or ``None``
+ :param backend: The async backend. If ``None`` (the default), dnspython
+ will use the default backend.
+ :type backend: :py:class:`dns.asyncbackend.Backend` or ``None``
See :py:func:`dns.query.tcp()` for the documentation of the other
parameters, exceptions, and return type of this method.
) -> dns.message.Message:
"""Return the response obtained after sending a query via TLS.
- *sock*, an ``asyncbackend.StreamSocket``, or ``None``, the socket
- to use for the query. If ``None``, the default, a socket is
- created. Note that if a socket is provided, it must be a
- connected SSL stream socket, and *where*, *port*,
- *source*, *source_port*, *backend*, *ssl_context*, and *server_hostname*
- are ignored.
-
- *backend*, a ``dns.asyncbackend.Backend``, or ``None``. If ``None``,
- the default, then dnspython will use the default backend.
+ :param sock: The socket to use. If ``None`` (the default), a socket is
+ created. Note that if a socket is provided, it must be a connected
+ SSL stream socket, and *where*, *port*, *source*, *source_port*,
+ *backend*, *ssl_context*, and *server_hostname* are ignored.
+ :type sock: :py:class:`dns.asyncbackend.StreamSocket` or ``None``
+ :param backend: The async backend. If ``None`` (the default), dnspython
+ will use the default backend.
+ :type backend: :py:class:`dns.asyncbackend.Backend` or ``None``
See :py:func:`dns.query.tls()` for the documentation of the other
parameters, exceptions, and return type of this method.
) -> dns.message.Message:
"""Return the response obtained after sending a query via DNS-over-HTTPS.
- *client*, a ``httpx.AsyncClient``. If provided, the client to use for
- the query.
-
- Unlike the other dnspython async functions, a backend cannot be provided
- in this function because httpx always auto-detects the async backend.
+ :param client: If provided, the client to use for the query. Unlike the
+ other dnspython async functions, a backend cannot be provided here
+ because httpx always auto-detects the async backend.
+ :type client: ``httpx.AsyncClient`` or ``None``
See :py:func:`dns.query.https()` for the documentation of the other
parameters, exceptions, and return type of this method.
"""Return the response obtained after sending an asynchronous query via
DNS-over-QUIC.
- *backend*, a ``dns.asyncbackend.Backend``, or ``None``. If ``None``,
- the default, then dnspython will use the default backend.
+ :param backend: The async backend. If ``None`` (the default), dnspython
+ will use the default backend.
+ :type backend: :py:class:`dns.asyncbackend.Backend` or ``None``
See :py:func:`dns.query.quic()` for the documentation of the other
parameters, exceptions, and return type of this method.
"""Conduct an inbound transfer and apply it via a transaction from the
txn_manager.
- *backend*, a ``dns.asyncbackend.Backend``, or ``None``. If ``None``,
- the default, then dnspython will use the default backend.
+ :param backend: The async backend. If ``None`` (the default), dnspython
+ will use the default backend.
+ :type backend: :py:class:`dns.asyncbackend.Backend` or ``None``
See :py:func:`dns.query.inbound_xfr()` for the documentation of
the other parameters, exceptions, and return type of this method.
) -> dns.resolver.Answer:
"""Query nameservers asynchronously to find the answer to the question.
- *backend*, a ``dns.asyncbackend.Backend``, or ``None``. If ``None``,
- the default, then dnspython will use the default backend.
+ :param backend: The async backend. If ``None`` (the default), dnspython
+ will use the default backend.
+ :type backend: :py:class:`dns.asyncbackend.Backend` or ``None``
See :py:func:`dns.resolver.Resolver.resolve()` for the
documentation of the other parameters, exceptions, and return
This utilizes the resolve() method to perform a PTR lookup on the
specified IP address.
- *ipaddr*, a ``str``, the IPv4 or IPv6 address you want to get
- the PTR record for.
+ :param ipaddr: The IPv4 or IPv6 address to look up.
+ :type ipaddr: str
All other arguments that can be passed to the resolve() function
except for rdtype and rdclass are also supported by this
This utilizes the resolve() method to perform A and/or AAAA lookups on
the specified name.
- *qname*, a ``dns.name.Name`` or ``str``, the name to resolve.
-
- *family*, an ``int``, the address family. If socket.AF_UNSPEC
- (the default), both A and AAAA records will be retrieved.
+ :param name: The name to resolve.
+ :type name: :py:class:`dns.name.Name` or str
+ :param family: The address family. If ``socket.AF_UNSPEC`` (the
+ default), both A and AAAA records will be retrieved.
+ :type family: int
All other arguments that can be passed to the resolve() function
except for rdtype and rdclass are also supported by this
The canonical name is the name the resolver uses for queries
after all CNAME and DNAME renamings have been applied.
- *name*, a ``dns.name.Name`` or ``str``, the query name.
-
- This method can raise any exception that ``resolve()`` can
- raise, other than ``dns.resolver.NoAnswer`` and
- ``dns.resolver.NXDOMAIN``.
+ :param name: The query name.
+ :type name: :py:class:`dns.name.Name` or str
+ :rtype: :py:class:`dns.name.Name`
- Returns a ``dns.name.Name``.
+ This method can raise any exception that
+ :py:meth:`~dns.asyncresolver.Resolver.resolve` can raise, other than
+ :py:exc:`dns.resolver.NoAnswer` and :py:exc:`dns.resolver.NXDOMAIN`.
"""
try:
answer = await self.resolve(name, raise_on_no_answer=False)
) -> dns.name.Name:
"""Find the name of the zone which contains the specified name.
- See :py:func:`dns.resolver.Resolver.zone_for_name` for more
+ See :py:func:`dns.resolver.zone_for_name` for more
information on the parameters and possible exceptions.
"""
) -> Resolver:
"""Make a stub resolver using the specified destination as the full resolver.
- *where*, a ``dns.name.Name`` or ``str`` the domain name or IP address of the
- full resolver.
-
- *port*, an ``int``, the port to use. If not specified, the default is 53.
-
- *family*, an ``int``, the address family to use. This parameter is used if
- *where* is not an address. The default is ``socket.AF_UNSPEC`` in which case
- the first address returned by ``resolve_name()`` will be used, otherwise the
- first address of the specified family will be used.
-
- *resolver*, a ``dns.asyncresolver.Resolver`` or ``None``, the resolver to use for
- resolution of hostnames. If not specified, the default resolver will be used.
-
- Returns a ``dns.resolver.Resolver`` or raises an exception.
+ :param where: The domain name or IP address of the full resolver.
+ :type where: :py:class:`dns.name.Name` or str
+ :param port: The port to use. Default is 53.
+ :type port: int
+ :param family: The address family. Used only when *where* is not an
+ address literal. ``socket.AF_UNSPEC`` (default) uses the first
+ address returned; otherwise the first address of the given family.
+ :type family: int
+ :param resolver: The resolver to use for hostname resolution. If
+ ``None``, the default resolver is used.
+ :type resolver: :py:class:`dns.asyncresolver.Resolver` or ``None``
+ :rtype: :py:class:`dns.resolver.Resolver`
"""
if resolver is None:
resolver = get_default_resolver()
"""Get the index of the ``Element`` matching ``key`` or the index of its
least successor.
- Returns a tuple of the index and an ``equal`` boolean that is ``True`` iff.
- the key was found.
+ :returns: A tuple of the index and an ``equal`` boolean that is ``True``
+ iff the key was found.
+ :rtype: tuple[int, bool]
"""
l = len(self.elts)
if l > 0 and key > self.elts[l - 1].key():
"""Get the node associated with key and its index, doing
copy-on-write if we have to descend.
- Returns a tuple of the node and the index, or the tuple ``(None, 0)``
- if the key was not found.
+ :returns: A tuple of the node and the index, or ``(None, 0)``
+ if the key was not found.
"""
i, equal = self.search_in_node(key)
if equal:
def try_left_steal(self, parent: "_Node[KT, ET]", index: int) -> bool:
"""Try to steal from this Node's left sibling for balancing purposes.
- Returns ``True`` if the theft was successful, or ``False`` if not.
+ :returns: ``True`` if the theft was successful, ``False`` if not.
+ :rtype: bool
"""
if index != 0:
left = parent.children[index - 1]
def try_right_steal(self, parent: "_Node[KT, ET]", index: int) -> bool:
"""Try to steal from this Node's right sibling for balancing purposes.
- Returns ``True`` if the theft was successful, or ``False`` if not.
+ :returns: ``True`` if the theft was successful, ``False`` if not.
+ :rtype: bool
"""
if index + 1 < len(parent.children):
right = parent.children[index + 1]
def insert_element(self, elt: ET, in_order: bool = False) -> ET | None:
"""Insert the element into the BTree.
- If *in_order* is ``True``, then extra work will be done to make left siblings
- full, which optimizes storage space when the the elements are inserted in-order
- or close to it.
-
- Returns the previously existing element at the element's key or ``None``.
+ :param bool in_order: If ``True``, extra work will be done to make left
+ siblings full, which optimizes storage space when elements are inserted
+ in-order or close to it.
+ :returns: The previously existing element at the element's key, or ``None``.
"""
self._check_mutable_and_park()
cloned = self.root.maybe_cow(self.creator)
def delete_key(self, key: KT) -> ET | None:
"""Delete the element matching *key* from the BTree.
- Returns the matching element or ``None`` if it does not exist.
+ :returns: The matching element, or ``None`` if it does not exist.
"""
return self._delete(key, None)
def delete_exact(self, element: ET) -> ET | None:
"""Delete *element* from the BTree.
- Returns the matching element or ``None`` if it was not in the BTree.
+ :returns: The matching element, or ``None`` if it was not in the BTree.
"""
delt = self._delete(element.key(), element)
assert delt is element
class NodeFlags(enum.IntFlag):
+ """Flags that classify a node's role in the zone.
+
+ ``ORIGIN`` is set on the zone origin node.
+
+ ``DELEGATION`` is set at NS delegation points (not at the origin, and not
+ on nodes beneath a delegation).
+
+ ``GLUE`` is set on nodes that are proper subdomains of a delegation point.
+ """
+
ORIGIN = 0x01
DELEGATION = 0x02
GLUE = 0x04
class Node(dns.node.Node):
+ """A BTree zone node, extending :py:class:`dns.node.Node` with ``flags`` and
+ ``id`` fields.
+
+ .. attribute:: flags
+
+ The node's role flags.
+
+ :type: :py:class:`dns.btreezone.NodeFlags`
+
+ .. attribute:: id
+
+ The version id of the last write that touched this node.
+
+ :type: int
+ """
+
__slots__ = ["flags", "id"]
def __init__(self, flags: NodeFlags | None = None):
self.id = 0
def is_delegation(self):
+ """Return ``True`` if this node is an NS delegation point.
+
+ :rtype: bool
+ """
return (self.flags & NodeFlags.DELEGATION) != 0
def is_glue(self):
+ """Return ``True`` if this node is beneath a delegation point.
+
+ :rtype: bool
+ """
return (self.flags & NodeFlags.GLUE) != 0
def is_origin(self):
+ """Return ``True`` if this node is the zone origin.
+
+ :rtype: bool
+ """
return (self.flags & NodeFlags.ORIGIN) != 0
def is_origin_or_glue(self):
+ """Return ``True`` if this node is at the origin or beneath a delegation.
+
+ :rtype: bool
+ """
return (self.flags & (NodeFlags.ORIGIN | NodeFlags.GLUE)) != 0
@dns.immutable.immutable
class ImmutableNode(Node):
+ """An immutable :py:class:`dns.btreezone.Node`.
+
+ Mutation methods raise :py:exc:`TypeError`.
+ """
+
def __init__(self, node: Node):
super().__init__()
self.id = node.id
class Delegations(dns.btree.BTreeSet[dns.name.Name]):
+ """A sorted set of delegation-point names.
+
+ Used by :py:class:`dns.btreezone.WritableVersion` and
+ :py:class:`dns.btreezone.ImmutableVersion` to efficiently determine
+ whether a given name is at or beneath a delegation point.
+ """
+
def get_delegation(self, name: dns.name.Name) -> tuple[dns.name.Name | None, bool]:
"""Get the delegation applicable to *name*, if it exists.
- If there delegation, then return a tuple consisting of the name of
- the delegation point, and a boolean which is `True` if the name is a proper
- subdomain of the delegation point, and `False` if it is equal to the delegation
- point.
+ :returns: A tuple of the delegation point name and a boolean which is
+ ``True`` if *name* is a proper subdomain of the delegation point,
+ or ``False`` if it is equal to the delegation point. If there is
+ no applicable delegation, returns ``(None, False)``.
+ :rtype: tuple[:py:class:`dns.name.Name` or ``None``, bool]
"""
cursor = self.cursor()
cursor.seek(name, before=False)
class WritableVersion(dns.zone.WritableVersion):
+ """A mutable version of a :py:class:`dns.btreezone.Zone`.
+
+ Extends :py:class:`dns.zone.WritableVersion` with a
+ :py:class:`dns.btreezone.Delegations` index and automatic management of
+ ``NodeFlags.ORIGIN``, ``NodeFlags.DELEGATION``, and ``NodeFlags.GLUE``
+ flags on every node.
+
+ Instances are created internally by the zone; callers should not
+ construct them directly.
+ """
+
def __init__(self, zone: dns.zone.Zone, replacement: bool = False):
super().__init__(zone, True)
if not replacement:
return (node, name)
def update_glue_flag(self, name: dns.name.Name, is_glue: bool) -> None:
+ """Set or clear the ``NodeFlags.GLUE`` flag on all nodes that are
+ subdomains of *name*.
+
+ :param name: The delegation-point name whose subtree should be updated.
+ :type name: :py:class:`dns.name.Name`
+ :param is_glue: ``True`` to set the GLUE flag; ``False`` to clear it.
+ :type is_glue: bool
+ """
cursor = self.nodes.cursor() # pyright: ignore
cursor.seek(name, False)
updates = []
self.nodes[ename] = node
def delete_node(self, name: dns.name.Name) -> None:
+ """Delete the node at *name*, updating delegation tracking as needed.
+
+ If *name* is a delegation point, it is removed from the delegations
+ index and the GLUE flag is cleared from its subtree. If *name* does
+ not exist in the zone, this method is a no-op.
+
+ :param name: The name of the node to delete.
+ :type name: :py:class:`dns.name.Name`
+ """
name = self._validate_name(name)
node = self.nodes.get(name)
if node is not None:
def put_rdataset(
self, name: dns.name.Name, rdataset: dns.rdataset.Rdataset
) -> None:
+ """Store *rdataset* at *name*, updating delegation flags as needed.
+
+ If *rdataset* is an NS rdataset and *name* is not the origin or beneath
+ an existing delegation, the ``DELEGATION`` flag is set on the node and
+ the ``GLUE`` flag is set on all nodes in *name*'s subtree.
+
+ :param name: The owner name.
+ :type name: :py:class:`dns.name.Name`
+ :param rdataset: The rdataset to store.
+ :type rdataset: :py:class:`dns.rdataset.Rdataset`
+ """
node, name = self._maybe_cow_with_name(name)
if (
rdataset.rdtype == dns.rdatatype.NS
rdtype: dns.rdatatype.RdataType,
covers: dns.rdatatype.RdataType,
) -> None:
+ """Delete the rdataset with *rdtype* and *covers* at *name*.
+
+ If the deleted rdataset was the NS rdataset at a delegation point,
+ the ``DELEGATION`` flag is cleared from that node and the ``GLUE``
+ flag is cleared from all nodes in its subtree.
+
+ :param name: The owner name.
+ :type name: :py:class:`dns.name.Name`
+ :param rdtype: The rdata type to remove.
+ :type rdtype: :py:class:`dns.rdatatype.RdataType`
+ :param covers: The covered type (usually ``dns.rdatatype.NONE``).
+ :type covers: :py:class:`dns.rdatatype.RdataType`
+ """
node, name = self._maybe_cow_with_name(name)
if rdtype == dns.rdatatype.NS and name in self.delegations: # pyright: ignore
node.flags &= ~NodeFlags.DELEGATION # type: ignore
@dataclass(frozen=True)
class Bounds:
+ """The result of a :py:meth:`~dns.btreezone.ImmutableVersion.bounds` query.
+
+ Useful for constructing authoritative responses and for on-the-fly DNSSEC
+ signatures.
+
+ .. attribute:: name
+
+ The queried name.
+
+ :type: :py:class:`dns.name.Name`
+
+ .. attribute:: left
+
+ The greatest name in the zone that is less than or equal to ``name``.
+
+ :type: :py:class:`dns.name.Name`
+
+ .. attribute:: right
+
+ The least name in the zone that is greater than ``name``, or ``None``
+ if ``name`` is greater than every name in the zone.
+
+ :type: :py:class:`dns.name.Name` or ``None``
+
+ .. attribute:: closest_encloser
+
+ The name with the greatest number of labels that is a common ancestor
+ of ``name`` and is present in the zone (explicitly or as an implied
+ empty non-terminal).
+
+ :type: :py:class:`dns.name.Name`
+
+ .. attribute:: is_equal
+
+ ``True`` if ``name`` is present in the zone (i.e. ``name == left``).
+
+ :type: bool
+
+ .. attribute:: is_delegation
+
+ ``True`` if the left bound is a delegation point.
+
+ :type: bool
+ """
+
name: dns.name.Name
left: dns.name.Name
right: dns.name.Name | None
@dns.immutable.immutable
class ImmutableVersion(dns.zone.Version):
+ """An immutable, committed version of a :py:class:`dns.btreezone.Zone`.
+
+ In addition to the standard read-only zone API, provides the
+ :py:meth:`bounds` method for DNSSEC and authoritative-response support.
+
+ Instances are created internally when a
+ :py:class:`dns.btreezone.WritableVersion` is committed; callers should
+ not construct them directly.
+ """
+
def __init__(self, version: dns.zone.Version):
if not isinstance(version, WritableVersion):
raise ValueError(
self.delegations.make_immutable()
def bounds(self, name: dns.name.Name | str) -> Bounds:
- """Return the 'bounds' of *name* in its zone.
+ """Return the bounds of *name* in its zone.
The bounds information is useful when making an authoritative response, as
it can be used to determine whether the query name is at or beneath a delegation
- point. The other data in the ``Bounds`` object is useful for making on-the-fly
- DNSSEC signatures.
+ point. The other data in the :py:class:`dns.btreezone.Bounds` object is useful
+ for making on-the-fly DNSSEC signatures.
The left bound of *name* is *name* itself if it is in the zone, or the greatest
predecessor which is in the zone.
*name* that is in the zone, either explicitly or by the implied existence
of empty non-terminals.
- The bounds *is_equal* field is ``True`` if and only if *name* is equal to
- its left bound.
+ The *is_equal* field of the result is ``True`` if and only if *name* is equal
+ to its left bound.
+
+ The *is_delegation* field of the result is ``True`` if and only if the left
+ bound is a delegation point.
- The bounds *is_delegation* field is ``True`` if and only if the left bound is a
- delegation point.
+ :param name: The name to look up.
+ :type name: :py:class:`dns.name.Name` or str
+ :rtype: :py:class:`dns.btreezone.Bounds`
"""
assert self.origin is not None
# validate the origin because we may need to relativize
class Zone(dns.versioned.Zone):
+ """A versioned DNS zone backed by a BTree.
+
+ Extends :py:class:`dns.versioned.Zone` with:
+
+ - **Sorted iteration order**: names are always visited in DNS canonical order.
+ - **Automatic flag tracking**: every node is tagged with
+ :py:class:`dns.btreezone.NodeFlags` (``ORIGIN``, ``DELEGATION``,
+ ``GLUE``) as rdatasets are added and removed.
+ - **Efficient copy-on-write versioning**: the underlying
+ :py:class:`dns.btree.BTreeDict` shares structure between versions so
+ that creating a new version is cheap.
+ - **DNSSEC / authoritative-response support**: committed versions expose
+ :py:meth:`~dns.btreezone.ImmutableVersion.bounds`, which returns the
+ nearest names and closest encloser for any query name.
+ """
+
node_factory: Callable[[], dns.node.Node] = Node
map_factory: Callable[[], MutableMapping[dns.name.Name, dns.node.Node]] = cast(
Callable[[], MutableMapping[dns.name.Name, dns.node.Node]],
def algorithm_from_text(text: str) -> Algorithm:
"""Convert text into a DNSSEC algorithm value.
- *text*, a ``str``, the text to convert to into an algorithm value.
-
- Returns an ``int``.
+ :param text: The text to convert into an algorithm value.
+ :type text: str
+ :rtype: int
"""
return Algorithm.from_text(text)
def algorithm_to_text(value: Algorithm | int) -> str:
"""Convert a DNSSEC algorithm value to text
- *value*, a ``dns.dnssec.Algorithm``.
-
- Returns a ``str``, the name of a DNSSEC algorithm.
+ :param value: The algorithm value.
+ :type value: :py:class:`dns.dnssectypes.Algorithm`
+ :rtype: str
"""
return Algorithm.to_text(value)
def key_id(key: DNSKEY | CDNSKEY) -> int:
"""Return the key id (a 16-bit number) for the specified key.
- *key*, a ``dns.rdtypes.ANY.DNSKEY.DNSKEY``
-
- Returns an ``int`` between 0 and 65535
+ :param key: The DNSKEY or CDNSKEY rdata.
+ :type key: :py:class:`dns.rdtypes.ANY.DNSKEY.DNSKEY`
+ :rtype: int
"""
return key.key_id()
) -> DS:
"""Create a DS record for a DNSSEC key.
- *name*, a ``dns.name.Name`` or ``str``, the owner name of the DS record.
-
- *key*, a ``dns.rdtypes.ANY.DNSKEY.DNSKEY`` or ``dns.rdtypes.ANY.DNSKEY.CDNSKEY``,
- the key the DS is about.
-
- *algorithm*, a ``str`` or ``int`` specifying the hash algorithm.
- The currently supported hashes are "SHA1", "SHA256", and "SHA384". Case
- does not matter for these strings.
-
- *origin*, a ``dns.name.Name`` or ``None``. If *key* is a relative name,
- then it will be made absolute using the specified origin.
-
- *policy*, a ``dns.dnssec.Policy`` or ``None``. If ``None``, the default policy,
- ``dns.dnssec.default_policy`` is used; this policy defaults to that of RFC 8624.
-
- *validating*, a ``bool``. If ``True``, then policy is checked in
- validating mode, i.e. "Is it ok to validate using this digest algorithm?".
- Otherwise the policy is checked in creating mode, i.e. "Is it ok to create a DS with
- this digest algorithm?".
-
- Raises ``UnsupportedAlgorithm`` if the algorithm is unknown.
-
- Raises ``DeniedByPolicy`` if the algorithm is denied by policy.
-
- Returns a ``dns.rdtypes.ANY.DS.DS``
+ :param name: The owner name of the DS record.
+ :type name: :py:class:`dns.name.Name` or str
+ :param key: The key the DS is about.
+ :type key: :py:class:`dns.rdtypes.ANY.DNSKEY.DNSKEY` or
+ :py:class:`dns.rdtypes.ANY.CDNSKEY.CDNSKEY`
+ :param algorithm: The hash algorithm. Currently supported: ``"SHA1"``,
+ ``"SHA256"``, ``"SHA384"`` (case-insensitive).
+ :type algorithm: str or int
+ :param origin: If *key* is a relative name, it will be made absolute
+ using this origin.
+ :type origin: :py:class:`dns.name.Name` or ``None``
+ :param policy: The policy to use. If ``None``, ``dns.dnssec.default_policy``
+ is used (defaults to RFC 8624 policy).
+ :type policy: :py:class:`dns.dnssec.Policy` or ``None``
+ :param validating: If ``True``, policy is checked in validating mode ("Is it
+ ok to validate using this digest algorithm?"). Otherwise checked in
+ creating mode.
+ :type validating: bool
+ :raises UnsupportedAlgorithm: If the algorithm is unknown.
+ :raises DeniedByPolicy: If the algorithm is denied by policy.
+ :rtype: :py:class:`dns.rdtypes.ANY.DS.DS`
"""
if policy is None:
) -> CDS:
"""Create a CDS record for a DNSSEC key.
- *name*, a ``dns.name.Name`` or ``str``, the owner name of the DS record.
-
- *key*, a ``dns.rdtypes.ANY.DNSKEY.DNSKEY`` or ``dns.rdtypes.ANY.DNSKEY.CDNSKEY``,
- the key the DS is about.
-
- *algorithm*, a ``str`` or ``int`` specifying the hash algorithm.
- The currently supported hashes are "SHA1", "SHA256", and "SHA384". Case
- does not matter for these strings.
-
- *origin*, a ``dns.name.Name`` or ``None``. If *key* is a relative name,
- then it will be made absolute using the specified origin.
-
- Raises ``UnsupportedAlgorithm`` if the algorithm is unknown.
-
- Returns a ``dns.rdtypes.ANY.DS.CDS``
+ :param name: The owner name of the DS record.
+ :type name: :py:class:`dns.name.Name` or str
+ :param key: The key the DS is about.
+ :type key: :py:class:`dns.rdtypes.ANY.DNSKEY.DNSKEY` or
+ :py:class:`dns.rdtypes.ANY.CDNSKEY.CDNSKEY`
+ :param algorithm: The hash algorithm. Currently supported: ``"SHA1"``,
+ ``"SHA256"``, ``"SHA384"`` (case-insensitive).
+ :type algorithm: str or int
+ :param origin: If *key* is a relative name, it will be made absolute
+ using this origin.
+ :type origin: :py:class:`dns.name.Name` or ``None``
+ :raises UnsupportedAlgorithm: If the algorithm is unknown.
+ :rtype: :py:class:`dns.rdtypes.ANY.CDS.CDS`
"""
ds = make_ds(name, key, algorithm, origin)
``dns.rrset.RRset`` or a (``dns.name.Name``, ``dns.rdataset.Rdataset``)
tuple.
- *rrsig*, a ``dns.rdata.Rdata``, the signature to validate.
-
- *keys*, the key dictionary, used to find the DNSKEY associated
- with a given name. The dictionary is keyed by a
- ``dns.name.Name``, and has ``dns.node.Node`` or
- ``dns.rdataset.Rdataset`` values.
-
- *origin*, a ``dns.name.Name`` or ``None``, the origin to use for relative
- names.
-
- *now*, a ``float`` or ``None``, the time, in seconds since the epoch, to
- use as the current time when validating. If ``None``, the actual current
- time is used.
-
- *policy*, a ``dns.dnssec.Policy`` or ``None``. If ``None``, the default policy,
- ``dns.dnssec.default_policy`` is used; this policy defaults to that of RFC 8624.
-
- Raises ``ValidationFailure`` if the signature is expired, not yet valid,
- the public key is invalid, the algorithm is unknown, the verification
- fails, etc.
-
- Raises ``UnsupportedAlgorithm`` if the algorithm is recognized by
- dnspython but not implemented.
+ :param rrsig: The signature to validate.
+ :type rrsig: :py:class:`dns.rdata.Rdata`
+ :param keys: The key dictionary, keyed by :py:class:`dns.name.Name`, with
+ :py:class:`dns.node.Node` or :py:class:`dns.rdataset.Rdataset` values.
+ :param origin: The origin to use for relative names.
+ :type origin: :py:class:`dns.name.Name` or ``None``
+ :param now: The current time in seconds since the epoch. If ``None``,
+ the actual current time is used.
+ :type now: float or ``None``
+ :param policy: The policy to use. If ``None``, ``dns.dnssec.default_policy``
+ is used (defaults to RFC 8624 policy).
+ :type policy: :py:class:`dns.dnssec.Policy` or ``None``
+ :raises ValidationFailure: If the signature is expired, not yet valid, the
+ public key is invalid, the algorithm is unknown, verification fails, etc.
+ :raises UnsupportedAlgorithm: If the algorithm is recognized but not
+ implemented.
"""
if policy is None:
"""Validate an RRset against a signature RRset, throwing an exception
if none of the signatures validate.
- *rrset*, the RRset to validate. This can be a
- ``dns.rrset.RRset`` or a (``dns.name.Name``, ``dns.rdataset.Rdataset``)
- tuple.
-
- *rrsigset*, the signature RRset. This can be a
- ``dns.rrset.RRset`` or a (``dns.name.Name``, ``dns.rdataset.Rdataset``)
- tuple.
-
- *keys*, the key dictionary, used to find the DNSKEY associated
- with a given name. The dictionary is keyed by a
- ``dns.name.Name``, and has ``dns.node.Node`` or
- ``dns.rdataset.Rdataset`` values.
-
- *origin*, a ``dns.name.Name``, the origin to use for relative names;
- defaults to None.
-
- *now*, an ``int`` or ``None``, the time, in seconds since the epoch, to
- use as the current time when validating. If ``None``, the actual current
- time is used.
-
- *policy*, a ``dns.dnssec.Policy`` or ``None``. If ``None``, the default policy,
- ``dns.dnssec.default_policy`` is used; this policy defaults to that of RFC 8624.
-
- Raises ``ValidationFailure`` if the signature is expired, not yet valid,
- the public key is invalid, the algorithm is unknown, the verification
- fails, etc.
+ :param rrset: The RRset to validate — a :py:class:`dns.rrset.RRset` or a
+ (:py:class:`dns.name.Name`, :py:class:`dns.rdataset.Rdataset`) tuple.
+ :param rrsigset: The signature RRset — a :py:class:`dns.rrset.RRset` or a
+ (:py:class:`dns.name.Name`, :py:class:`dns.rdataset.Rdataset`) tuple.
+ :param keys: The key dictionary, keyed by :py:class:`dns.name.Name`, with
+ :py:class:`dns.node.Node` or :py:class:`dns.rdataset.Rdataset` values.
+ :param origin: The origin to use for relative names. Defaults to ``None``.
+ :type origin: :py:class:`dns.name.Name` or ``None``
+ :param now: The current time in seconds since the epoch. If ``None``,
+ the actual current time is used.
+ :type now: int or ``None``
+ :param policy: The policy to use. If ``None``, ``dns.dnssec.default_policy``
+ is used (defaults to RFC 8624 policy).
+ :type policy: :py:class:`dns.dnssec.Policy` or ``None``
+ :raises ValidationFailure: If the signature is expired, not yet valid, the
+ public key is invalid, the algorithm is unknown, verification fails, etc.
"""
if policy is None:
) -> RRSIG:
"""Sign RRset using private key.
- *rrset*, the RRset to validate. This can be a
- ``dns.rrset.RRset`` or a (``dns.name.Name``, ``dns.rdataset.Rdataset``)
- tuple.
-
- *private_key*, the private key to use for signing, a
- ``cryptography.hazmat.primitives.asymmetric`` private key class applicable
- for DNSSEC.
-
- *signer*, a ``dns.name.Name``, the Signer's name.
-
- *dnskey*, a ``DNSKEY`` matching ``private_key``.
-
- *inception*, a ``datetime``, ``str``, ``int``, ``float`` or ``None``, the
- signature inception time. If ``None``, the current time is used. If a ``str``, the
- format is "YYYYMMDDHHMMSS" or alternatively the number of seconds since the UNIX
- epoch in text form; this is the same the RRSIG rdata's text form.
- Values of type `int` or `float` are interpreted as seconds since the UNIX epoch.
-
- *expiration*, a ``datetime``, ``str``, ``int``, ``float`` or ``None``, the signature
- expiration time. If ``None``, the expiration time will be the inception time plus
- the value of the *lifetime* parameter. See the description of *inception* above
- for how the various parameter types are interpreted.
-
- *lifetime*, an ``int`` or ``None``, the signature lifetime in seconds. This
- parameter is only meaningful if *expiration* is ``None``.
-
- *verify*, a ``bool``. If set to ``True``, the signer will verify signatures
- after they are created; the default is ``False``.
-
- *policy*, a ``dns.dnssec.Policy`` or ``None``. If ``None``, the default policy,
- ``dns.dnssec.default_policy`` is used; this policy defaults to that of RFC 8624.
-
- *origin*, a ``dns.name.Name`` or ``None``. If ``None``, the default, then all
- names in the rrset (including its owner name) must be absolute; otherwise the
- specified origin will be used to make names absolute when signing.
-
- *deterministic*, a ``bool``. If ``True``, the default, use deterministic
- (reproducible) signatures when supported by the algorithm used for signing.
- Currently, this only affects ECDSA.
-
- Raises ``DeniedByPolicy`` if the signature is denied by policy.
+ :param rrset: The RRset to sign — a :py:class:`dns.rrset.RRset` or a
+ (:py:class:`dns.name.Name`, :py:class:`dns.rdataset.Rdataset`) tuple.
+ :param private_key: The private key to use for signing.
+ :param signer: The signer's name.
+ :type signer: :py:class:`dns.name.Name`
+ :param dnskey: A DNSKEY matching *private_key*.
+ :param inception: The signature inception time. If ``None``, the current
+ time is used. If a ``str``, the format is ``"YYYYMMDDHHMMSS"`` or the
+ number of seconds since the UNIX epoch. ``int`` and ``float`` values
+ are interpreted as seconds since the UNIX epoch.
+ :type inception: datetime, str, int, float, or ``None``
+ :param expiration: The signature expiration time. If ``None``, the
+ expiration is *inception* plus *lifetime*. Interpreted the same as
+ *inception*.
+ :type expiration: datetime, str, int, float, or ``None``
+ :param lifetime: The signature lifetime in seconds. Only meaningful if
+ *expiration* is ``None``.
+ :type lifetime: int or ``None``
+ :param verify: If ``True``, signatures will be verified after creation.
+ Default is ``False``.
+ :type verify: bool
+ :param policy: The policy to use. If ``None``, ``dns.dnssec.default_policy``
+ is used (defaults to RFC 8624 policy).
+ :type policy: :py:class:`dns.dnssec.Policy` or ``None``
+ :param origin: If ``None`` (the default), all names must be absolute.
+ Otherwise, this origin is used to make names absolute when signing.
+ :type origin: :py:class:`dns.name.Name` or ``None``
+ :param deterministic: If ``True`` (the default), use deterministic
+ (reproducible) signatures when supported. Currently affects ECDSA.
+ :type deterministic: bool
+ :raises DeniedByPolicy: If the signature is denied by policy.
"""
if policy is None:
) -> bytes:
"""Create signature rdata.
- *rrset*, the RRset to sign/validate. This can be a
- ``dns.rrset.RRset`` or a (``dns.name.Name``, ``dns.rdataset.Rdataset``)
- tuple.
-
- *rrsig*, a ``dns.rdata.Rdata``, the signature to validate, or the
- signature template used when signing.
-
- *origin*, a ``dns.name.Name`` or ``None``, the origin to use for relative
- names.
-
- Raises ``UnsupportedAlgorithm`` if the algorithm is recognized by
- dnspython but not implemented.
+ :param rrset: The RRset to sign/validate — a :py:class:`dns.rrset.RRset`
+ or a (:py:class:`dns.name.Name`, :py:class:`dns.rdataset.Rdataset`)
+ tuple.
+ :param rrsig: The signature to validate, or the signature template used
+ when signing.
+ :type rrsig: :py:class:`dns.rdata.Rdata`
+ :param origin: The origin to use for relative names.
+ :type origin: :py:class:`dns.name.Name` or ``None``
+ :raises UnsupportedAlgorithm: If the algorithm is recognized but not
+ implemented.
"""
if isinstance(origin, str):
) -> DNSKEY:
"""Convert a public key to DNSKEY Rdata
- *public_key*, a ``PublicKey`` (``GenericPublicKey`` or
- ``cryptography.hazmat.primitives.asymmetric``) to convert.
-
- *algorithm*, a ``str`` or ``int`` specifying the DNSKEY algorithm.
-
- *flags*: DNSKEY flags field as an integer.
-
- *protocol*: DNSKEY protocol field as an integer.
-
- Raises ``ValueError`` if the specified key algorithm parameters are not
- unsupported, ``TypeError`` if the key type is unsupported,
- `UnsupportedAlgorithm` if the algorithm is unknown and
- `AlgorithmKeyMismatch` if the algorithm does not match the key type.
-
- Return DNSKEY ``Rdata``.
+ :param public_key: The public key to convert (a ``GenericPublicKey`` or
+ ``cryptography.hazmat.primitives.asymmetric`` key).
+ :param algorithm: The DNSKEY algorithm.
+ :type algorithm: str or int
+ :param flags: DNSKEY flags field.
+ :type flags: int
+ :param protocol: DNSKEY protocol field.
+ :type protocol: int
+ :raises ValueError: If the key algorithm parameters are unsupported.
+ :raises TypeError: If the key type is unsupported.
+ :raises UnsupportedAlgorithm: If the algorithm is unknown.
+ :raises AlgorithmKeyMismatch: If the algorithm does not match the key type.
+ :rtype: :py:class:`dns.rdtypes.ANY.DNSKEY.DNSKEY`
"""
algorithm = Algorithm.make(algorithm)
) -> CDNSKEY:
"""Convert a public key to CDNSKEY Rdata
- *public_key*, the public key to convert, a
- ``cryptography.hazmat.primitives.asymmetric`` public key class applicable
- for DNSSEC.
-
- *algorithm*, a ``str`` or ``int`` specifying the DNSKEY algorithm.
-
- *flags*: DNSKEY flags field as an integer.
-
- *protocol*: DNSKEY protocol field as an integer.
-
- Raises ``ValueError`` if the specified key algorithm parameters are not
- unsupported, ``TypeError`` if the key type is unsupported,
- `UnsupportedAlgorithm` if the algorithm is unknown and
- `AlgorithmKeyMismatch` if the algorithm does not match the key type.
-
- Return CDNSKEY ``Rdata``.
+ :param public_key: The public key to convert
+ (``cryptography.hazmat.primitives.asymmetric`` key for DNSSEC).
+ :param algorithm: The DNSKEY algorithm.
+ :type algorithm: str or int
+ :param flags: DNSKEY flags field.
+ :type flags: int
+ :param protocol: DNSKEY protocol field.
+ :type protocol: int
+ :raises ValueError: If the key algorithm parameters are unsupported.
+ :raises TypeError: If the key type is unsupported.
+ :raises UnsupportedAlgorithm: If the algorithm is unknown.
+ :raises AlgorithmKeyMismatch: If the algorithm does not match the key type.
+ :rtype: :py:class:`dns.rdtypes.ANY.CDNSKEY.CDNSKEY`
"""
dnskey = _make_dnskey(public_key, algorithm, flags, protocol)
Calculate the NSEC3 hash, according to
https://tools.ietf.org/html/rfc5155#section-5
- *domain*, a ``dns.name.Name`` or ``str``, the name to hash.
-
- *salt*, a ``str``, ``bytes``, or ``None``, the hash salt. If a
- string, it is decoded as a hex string.
-
- *iterations*, an ``int``, the number of iterations.
-
- *algorithm*, a ``str`` or ``int``, the hash algorithm.
- The only defined algorithm is SHA1.
-
- Returns a ``str``, the encoded NSEC3 hash.
+ :param domain: The name to hash.
+ :type domain: :py:class:`dns.name.Name` or str
+ :param salt: The hash salt. If a string, it is decoded as a hex string.
+ :type salt: str, bytes, or ``None``
+ :param iterations: The number of iterations.
+ :type iterations: int
+ :param algorithm: The hash algorithm. The only defined algorithm is SHA1.
+ :type algorithm: str or int
+ :rtype: str
"""
b32_conversion = str.maketrans(
) -> dns.rdataset.Rdataset:
"""Create a DS record from DNSKEY/CDNSKEY/CDS.
- *rrset*, the RRset to create DS Rdataset for. This can be a
- ``dns.rrset.RRset`` or a (``dns.name.Name``, ``dns.rdataset.Rdataset``)
- tuple.
-
- *algorithms*, a set of ``str`` or ``int`` specifying the hash algorithms.
- The currently supported hashes are "SHA1", "SHA256", and "SHA384". Case
- does not matter for these strings. If the RRset is a CDS, only digest
- algorithms matching algorithms are accepted.
-
- *origin*, a ``dns.name.Name`` or ``None``. If `key` is a relative name,
- then it will be made absolute using the specified origin.
-
- Raises ``UnsupportedAlgorithm`` if any of the algorithms are unknown and
- ``ValueError`` if the given RRset is not usable.
-
- Returns a ``dns.rdataset.Rdataset``
+ :param rrset: The RRset — a :py:class:`dns.rrset.RRset` or a
+ (:py:class:`dns.name.Name`, :py:class:`dns.rdataset.Rdataset`) tuple.
+ :param algorithms: A set of hash algorithms. Currently supported:
+ ``"SHA1"``, ``"SHA256"``, ``"SHA384"`` (case-insensitive). If the
+ RRset is a CDS, only digest algorithms matching *algorithms* are
+ accepted.
+ :type algorithms: set of str or int
+ :param origin: If the key name is relative, it will be made absolute
+ using this origin.
+ :type origin: :py:class:`dns.name.Name` or ``None``
+ :raises UnsupportedAlgorithm: If any algorithm is unknown.
+ :raises ValueError: If the given RRset is not usable.
+ :rtype: :py:class:`dns.rdataset.Rdataset`
"""
rrname, rdataset = _get_rrname_rdataset(rrset)
) -> dns.rdataset.Rdataset:
"""Create a CDS record from DS.
- *rdataset*, a ``dns.rdataset.Rdataset``, to create DS Rdataset for.
-
- Raises ``ValueError`` if the rdataset is not CDS.
-
- Returns a ``dns.rdataset.Rdataset``
+ :param rdataset: The CDS rdataset to convert to DS.
+ :type rdataset: :py:class:`dns.rdataset.Rdataset`
+ :raises ValueError: If the rdataset is not CDS.
+ :rtype: :py:class:`dns.rdataset.Rdataset`
"""
if rdataset.rdtype != dns.rdatatype.CDS:
) -> dns.rdataset.Rdataset:
"""Create a CDS record from DNSKEY/CDNSKEY.
- *name*, a ``dns.name.Name`` or ``str``, the owner name of the CDS record.
-
- *rdataset*, a ``dns.rdataset.Rdataset``, to create DS Rdataset for.
-
- *algorithm*, a ``str`` or ``int`` specifying the hash algorithm.
- The currently supported hashes are "SHA1", "SHA256", and "SHA384". Case
- does not matter for these strings.
-
- *origin*, a ``dns.name.Name`` or ``None``. If `key` is a relative name,
- then it will be made absolute using the specified origin.
-
- Raises ``UnsupportedAlgorithm`` if the algorithm is unknown or
- ``ValueError`` if the rdataset is not DNSKEY/CDNSKEY.
-
- Returns a ``dns.rdataset.Rdataset``
+ :param name: The owner name of the CDS record.
+ :type name: :py:class:`dns.name.Name` or str
+ :param rdataset: The DNSKEY/CDNSKEY rdataset to create CDS for.
+ :type rdataset: :py:class:`dns.rdataset.Rdataset`
+ :param algorithm: The hash algorithm. Currently supported: ``"SHA1"``,
+ ``"SHA256"``, ``"SHA384"`` (case-insensitive).
+ :type algorithm: str or int
+ :param origin: If the key name is relative, it will be made absolute
+ using this origin.
+ :type origin: :py:class:`dns.name.Name` or ``None``
+ :raises UnsupportedAlgorithm: If the algorithm is unknown.
+ :raises ValueError: If the rdataset is not DNSKEY/CDNSKEY.
+ :rtype: :py:class:`dns.rdataset.Rdataset`
"""
if rdataset.rdtype not in (dns.rdatatype.DNSKEY, dns.rdatatype.CDNSKEY):
) -> dns.rdataset.Rdataset:
"""Create a CDNSKEY record from DNSKEY.
- *rdataset*, a ``dns.rdataset.Rdataset``, to create CDNSKEY Rdataset for.
-
- Returns a ``dns.rdataset.Rdataset``
+ :param rdataset: The DNSKEY rdataset to convert to CDNSKEY.
+ :type rdataset: :py:class:`dns.rdataset.Rdataset`
+ :rtype: :py:class:`dns.rdataset.Rdataset`
"""
if rdataset.rdtype != dns.rdatatype.DNSKEY:
) -> None:
"""Sign zone.
- *zone*, a ``dns.zone.Zone``, the zone to sign.
-
- *txn*, a ``dns.transaction.Transaction``, an optional transaction to use for
- signing.
-
- *keys*, a list of (``PrivateKey``, ``DNSKEY``) tuples, to use for signing. KSK/ZSK
- roles are assigned automatically if the SEP flag is used, otherwise all RRsets are
- signed by all keys.
-
- *add_dnskey*, a ``bool``. If ``True``, the default, all specified DNSKEYs are
- automatically added to the zone on signing.
-
- *dnskey_ttl*, a``int``, specifies the TTL for DNSKEY RRs. If not specified the TTL
- of the existing DNSKEY RRset used or the TTL of the SOA RRset.
-
- *inception*, a ``datetime``, ``str``, ``int``, ``float`` or ``None``, the signature
- inception time. If ``None``, the current time is used. If a ``str``, the format is
- "YYYYMMDDHHMMSS" or alternatively the number of seconds since the UNIX epoch in text
- form; this is the same the RRSIG rdata's text form. Values of type `int` or `float`
- are interpreted as seconds since the UNIX epoch.
-
- *expiration*, a ``datetime``, ``str``, ``int``, ``float`` or ``None``, the signature
- expiration time. If ``None``, the expiration time will be the inception time plus
- the value of the *lifetime* parameter. See the description of *inception* above for
- how the various parameter types are interpreted.
-
- *lifetime*, an ``int`` or ``None``, the signature lifetime in seconds. This
- parameter is only meaningful if *expiration* is ``None``.
-
- *nsec3*, a ``NSEC3PARAM`` Rdata, configures signing using NSEC3. Not yet
- implemented.
-
- *rrset_signer*, a ``Callable``, an optional function for signing RRsets. The
- function requires two arguments: transaction and RRset. If the not specified,
- ``dns.dnssec.default_rrset_signer`` will be used.
-
- *deterministic*, a ``bool``. If ``True``, the default, use deterministic
- (reproducible) signatures when supported by the algorithm used for signing.
- Currently, this only affects ECDSA.
-
- Returns ``None``.
+ :param zone: The zone to sign.
+ :type zone: :py:class:`dns.zone.Zone`
+ :param txn: An optional transaction to use for signing.
+ :type txn: :py:class:`dns.transaction.Transaction` or ``None``
+ :param keys: A list of (``PrivateKey``, ``DNSKEY``) tuples to use for
+ signing. KSK/ZSK roles are assigned automatically if the SEP flag is
+ used; otherwise all RRsets are signed by all keys.
+ :param add_dnskey: If ``True`` (the default), all specified DNSKEYs are
+ automatically added to the zone on signing.
+ :type add_dnskey: bool
+ :param dnskey_ttl: The TTL for DNSKEY RRs. If not specified, uses the TTL
+ of the existing DNSKEY RRset or the SOA RRset.
+ :type dnskey_ttl: int or ``None``
+ :param inception: The signature inception time. If ``None``, the current
+ time is used. If a ``str``, the format is ``"YYYYMMDDHHMMSS"`` or
+ seconds since UNIX epoch. ``int`` and ``float`` are seconds since epoch.
+ :type inception: datetime, str, int, float, or ``None``
+ :param expiration: The signature expiration time. If ``None``, the
+ expiration is *inception* plus *lifetime*. Interpreted the same as
+ *inception*.
+ :type expiration: datetime, str, int, float, or ``None``
+ :param lifetime: The signature lifetime in seconds. Only meaningful if
+ *expiration* is ``None``.
+ :type lifetime: int or ``None``
+ :param nsec3: If specified, configures signing using NSEC3. Not yet
+ implemented.
+ :param rrset_signer: An optional function for signing RRsets, accepting
+ two arguments: transaction and RRset. If not specified,
+ ``dns.dnssec.default_rrset_signer`` is used.
+ :param deterministic: If ``True`` (the default), use deterministic
+ (reproducible) signatures when supported. Currently affects ECDSA.
+ :type deterministic: bool
"""
ksks = []
) -> type[GenericPrivateKey]:
"""Get Private Key class from Algorithm.
- *algorithm*, a ``str`` or ``int`` specifying the DNSKEY algorithm.
-
- Raises ``UnsupportedAlgorithm`` if the algorithm is unknown.
-
- Returns a ``dns.dnssecalgs.GenericPrivateKey``
+ :param algorithm: The DNSKEY algorithm.
+ :type algorithm: str or int
+ :raises UnsupportedAlgorithm: If the algorithm is unknown.
+ :rtype: type[:py:class:`dns.dnssecalgs.base.GenericPrivateKey`]
"""
algorithm = Algorithm.make(algorithm)
cls = algorithms.get((algorithm, prefix))
def get_algorithm_cls_from_dnskey(dnskey: DNSKEY) -> type[GenericPrivateKey]:
"""Get Private Key class from DNSKEY.
- *dnskey*, a ``DNSKEY`` to get Algorithm class for.
-
- Raises ``UnsupportedAlgorithm`` if the algorithm is unknown.
-
- Returns a ``dns.dnssecalgs.GenericPrivateKey``
+ :param dnskey: The DNSKEY rdata to get the algorithm class for.
+ :type dnskey: :py:class:`dns.rdtypes.ANY.DNSKEY.DNSKEY`
+ :raises UnsupportedAlgorithm: If the algorithm is unknown.
+ :rtype: type[:py:class:`dns.dnssecalgs.base.GenericPrivateKey`]
"""
prefix: AlgorithmPrefix = None
if dnskey.algorithm == Algorithm.PRIVATEDNS:
) -> None:
"""Register Algorithm Private Key class.
- *algorithm*, a ``str`` or ``int`` specifying the DNSKEY algorithm.
-
- *algorithm_cls*: A `GenericPrivateKey` class.
-
- *name*, an optional ``dns.name.Name`` or ``str``, for for PRIVATEDNS algorithms.
-
- *oid*: an optional BER-encoded `bytes` for PRIVATEOID algorithms.
-
- Raises ``ValueError`` if a name or oid is specified incorrectly.
+ :param algorithm: The DNSKEY algorithm.
+ :type algorithm: str or int
+ :param algorithm_cls: A :py:class:`dns.dnssecalgs.base.GenericPrivateKey`
+ subclass.
+ :param name: For PRIVATEDNS algorithms, the algorithm name.
+ :type name: :py:class:`dns.name.Name`, str, or ``None``
+ :param oid: For PRIVATEOID algorithms, a BER-encoded OID.
+ :type oid: bytes or ``None``
+ :raises ValueError: If a name or oid is specified incorrectly.
"""
if not issubclass(algorithm_cls, GenericPrivateKey):
raise TypeError("Invalid algorithm class")
Non-digits in the text are ignored, i.e. "16505551212",
"+1.650.555.1212" and "1 (650) 555-1212" are all the same.
- *text*, a ``str``, is an E.164 number in textual form.
-
- *origin*, a ``dns.name.Name``, the domain in which the number
- should be constructed. The default is ``e164.arpa.``.
-
- Returns a ``dns.name.Name``.
+ :param text: An E.164 number in textual form.
+ :type text: str
+ :param origin: The domain in which the number should be constructed.
+ Default is ``e164.arpa.``
+ :type origin: :py:class:`dns.name.Name`
+ :rtype: :py:class:`dns.name.Name`
"""
parts = [d for d in text if d.isdigit()]
emitted as a simple string of digits, prefixed by a '+' (unless
*want_plus_prefix* is ``False``).
- *name* is a ``dns.name.Name``, the ENUM domain name.
-
- *origin* is a ``dns.name.Name``, a domain containing the ENUM
- domain name. The name is relativized to this domain before being
- converted to text. If ``None``, no relativization is done.
-
- *want_plus_prefix* is a ``bool``. If True, add a '+' to the beginning of
- the returned number.
-
- Returns a ``str``.
-
+ :param name: The ENUM domain name.
+ :type name: :py:class:`dns.name.Name`
+ :param origin: A domain containing the ENUM domain name. The name is
+ relativized to this domain before conversion. If ``None``, no
+ relativization is done.
+ :type origin: :py:class:`dns.name.Name` or ``None``
+ :param want_plus_prefix: If ``True``, add a ``'+'`` prefix to the
+ returned number.
+ :type want_plus_prefix: bool
+ :rtype: str
"""
if origin is not None:
name = name.relativize(origin)
e.g. lookup('16505551212', ['e164.dnspython.org.', 'e164.arpa.'])
- *number*, a ``str`` is the number to look for.
-
- *domains* is an iterable containing ``dns.name.Name`` values.
-
- *resolver*, a ``dns.resolver.Resolver``, is the resolver to use. If
- ``None``, the default resolver is used.
+ :param number: The E.164 number to look up.
+ :type number: str
+ :param domains: An iterable of domain names to search.
+ :param resolver: The resolver to use. If ``None``, the default resolver
+ is used.
+ :type resolver: :py:class:`dns.resolver.Resolver` or ``None``
"""
if resolver is None:
def __init__(self, otype: OptionType | str):
"""Initialize an option.
- *otype*, a ``dns.edns.OptionType``, is the option type.
+ :param otype: The option type.
+ :type otype: :py:class:`dns.edns.OptionType`
"""
self.otype = OptionType.make(otype)
def to_wire(self, file: Any | None = None) -> bytes | None:
"""Convert an option to wire format.
- Returns a ``bytes`` or ``None``.
-
+ :rtype: bytes or ``None``
"""
raise NotImplementedError # pragma: no cover
raise NotImplementedError # pragma: no cover
def to_generic(self) -> "GenericOption":
- """Creates a dns.edns.GenericOption equivalent of this rdata.
+ """Create a :py:class:`dns.edns.GenericOption` equivalent of this option.
- Returns a ``dns.edns.GenericOption``.
+ :rtype: :py:class:`dns.edns.GenericOption`
"""
wire = self.to_wire()
assert wire is not None # for mypy
def from_wire_parser(cls, otype: OptionType, parser: "dns.wire.Parser") -> "Option":
"""Build an EDNS option object from wire format.
- *otype*, a ``dns.edns.OptionType``, is the option type.
-
- *parser*, a ``dns.wire.Parser``, the parser, which should be
- restructed to the option length.
-
- Returns a ``dns.edns.Option``.
+ :param otype: The option type.
+ :type otype: :py:class:`dns.edns.OptionType`
+ :param parser: The parser, restricted to the option length.
+ :type parser: :py:class:`dns.wire.Parser`
+ :rtype: :py:class:`dns.edns.Option`
"""
raise NotImplementedError # pragma: no cover
"""EDNS Client Subnet (ECS, RFC7871)"""
def __init__(self, address: str, srclen: int | None = None, scopelen: int = 0):
- """*address*, a ``str``, is the client address information.
-
- *srclen*, an ``int``, the source prefix length, which is the
- leftmost number of bits of the address to be used for the
- lookup. The default is 24 for IPv4 and 56 for IPv6.
-
- *scopelen*, an ``int``, the scope prefix length. This value
- must be 0 in queries, and should be set in responses.
+ """Initialize an ECSOption.
+
+ :param address: The client address information.
+ :type address: str
+ :param srclen: The source prefix length (leftmost number of bits of the
+ address to be used for the lookup). Defaults to 24 for IPv4 and 56
+ for IPv6.
+ :type srclen: int or ``None``
+ :param scopelen: The scope prefix length. Must be 0 in queries; should
+ be set in responses.
+ :type scopelen: int
"""
super().__init__(OptionType.ECS)
_preserve_case = {"DNSKEY", "DS", "DNSSEC", "RRSIGs", "NSEC", "NXDOMAIN"}
def __init__(self, code: EDECode | str, text: str | None = None):
- """*code*, a ``dns.edns.EDECode`` or ``str``, the info code of the
- extended error.
+ """Initialize an EDEOption.
- *text*, a ``str`` or ``None``, specifying additional information about
- the error.
+ :param code: The info code of the extended error.
+ :type code: :py:class:`dns.edns.EDECode` or str
+ :param text: Additional information about the error.
+ :type text: str or ``None``
"""
super().__init__(OptionType.EDE)
) -> Option:
"""Build an EDNS option object from wire format.
- *otype*, an ``int``, is the option type.
-
- *parser*, a ``dns.wire.Parser``, the parser, which should be
- restricted to the option length.
-
- Returns an instance of a subclass of ``dns.edns.Option``.
+ :param otype: The option type.
+ :type otype: int or :py:class:`dns.edns.OptionType`
+ :param parser: The parser, restricted to the option length.
+ :type parser: :py:class:`dns.wire.Parser`
+ :rtype: :py:class:`dns.edns.Option`
"""
otype = OptionType.make(otype)
cls = get_option_class(otype)
) -> Option:
"""Build an EDNS option object from wire format.
- *otype*, an ``int``, is the option type.
-
- *wire*, a ``bytes``, is the wire-format message.
-
- *current*, an ``int``, is the offset in *wire* of the beginning
- of the rdata.
-
- *olen*, an ``int``, is the length of the wire-format option data
-
- Returns an instance of a subclass of ``dns.edns.Option``.
+ :param otype: The option type.
+ :type otype: int or :py:class:`dns.edns.OptionType`
+ :param wire: The wire-format message.
+ :type wire: bytes
+ :param current: The offset in *wire* of the beginning of the rdata.
+ :type current: int
+ :param olen: The length of the wire-format option data.
+ :type olen: int
+ :rtype: :py:class:`dns.edns.Option`
"""
parser = dns.wire.Parser(wire, current)
with parser.restrict_to(olen):
def register_type(implementation: Any, otype: OptionType) -> None:
"""Register the implementation of an option type.
- *implementation*, a ``class``, is a subclass of ``dns.edns.Option``.
-
- *otype*, an ``int``, is the option type.
+ :param implementation: A subclass of :py:class:`dns.edns.Option`.
+ :param otype: The option type.
+ :type otype: :py:class:`dns.edns.OptionType`
"""
_type_to_class[otype] = implementation
def make(cls: type[TIntEnum], value: int | str) -> TIntEnum:
"""Convert text or a value into an enumerated type, if possible.
- *value*, the ``int`` or ``str`` to convert.
-
- Raises a class-specific exception if a ``str`` is provided that
- cannot be converted.
-
- Raises ``ValueError`` if the value is out of range.
-
- Returns an enumeration from the calling class corresponding to the
- value, if one is defined, or an ``int`` otherwise.
+ :param value: The value to convert.
+ :type value: int or str
+ :raises ValueError: If the value is out of range.
+ :returns: An enumeration from the calling class corresponding to the
+ value, if one is defined, or an ``int`` otherwise.
"""
if isinstance(value, str):
"""Convert a space-separated list of flag text values into a flags
value.
- Returns an ``int``
+ :rtype: int
"""
return _from_text(text, Flag)
"""Convert a flags value into a space-separated list of flag text
values.
- Returns a ``str``.
+ :rtype: str
"""
return _to_text(flags, Flag)
"""Convert a space-separated list of EDNS flag text values into a EDNS
flags value.
- Returns an ``int``
+ :rtype: int
"""
return _from_text(text, EDNSFlag)
"""Convert an EDNS flags value into a space-separated list of EDNS flag
text values.
- Returns a ``str``.
+ :rtype: str
"""
return _to_text(flags, EDNSFlag)
"""Convert the text form of a range in a ``$GENERATE`` statement to an
integer.
- *text*, a ``str``, the textual range in ``$GENERATE`` form.
-
- Returns a tuple of three ``int`` values ``(start, stop, step)``.
+ :param text: The textual range in ``$GENERATE`` form.
+ :type text: str
+ :rtype: tuple[int, int, int]
"""
start = -1
def inet_pton(family: int, text: str) -> bytes:
"""Convert the textual form of a network address into its binary form.
- *family* is an ``int``, the address family.
-
- *text* is a ``str``, the textual address.
-
- Raises ``NotImplementedError`` if the address family specified is not
- implemented.
-
- Returns a ``bytes``.
+ :param family: The address family.
+ :type family: int
+ :param text: The textual address.
+ :type text: str
+ :raises NotImplementedError: If the address family is not implemented.
+ :rtype: bytes
"""
if family == AF_INET:
def inet_ntop(family: int, address: bytes) -> str:
"""Convert the binary form of a network address into its textual form.
- *family* is an ``int``, the address family.
-
- *address* is a ``bytes``, the network address in binary form.
-
- Raises ``NotImplementedError`` if the address family specified is not
- implemented.
-
- Returns a ``str``.
+ :param family: The address family.
+ :type family: int
+ :param address: The network address in binary form.
+ :type address: bytes
+ :raises NotImplementedError: If the address family is not implemented.
+ :rtype: str
"""
if family == AF_INET:
def af_for_address(text: str) -> int:
"""Determine the address family of a textual-form network address.
- *text*, a ``str``, the textual address.
-
- Raises ``ValueError`` if the address family cannot be determined
- from the input.
-
- Returns an ``int``.
+ :param text: The textual address.
+ :type text: str
+ :raises ValueError: If the address family cannot be determined.
+ :rtype: int
"""
try:
def is_multicast(text: str) -> bool:
"""Is the textual-form network address a multicast address?
- *text*, a ``str``, the textual address.
-
- Raises ``ValueError`` if the address family cannot be determined
- from the input.
-
- Returns a ``bool``.
+ :param text: The textual address.
+ :type text: str
+ :raises ValueError: If the address family cannot be determined.
+ :rtype: bool
"""
try:
def is_address(text: str) -> bool:
"""Is the specified string an IPv4 or IPv6 address?
- *text*, a ``str``, the textual address.
-
- Returns a ``bool``.
+ :param text: The textual address.
+ :type text: str
+ :rtype: bool
"""
try:
"""Verify that *address* is a valid text form IPv4 or IPv6 address and return its
canonical text form. IPv6 addresses with scopes are rejected.
- *text*, a ``str``, the address in textual form.
-
- Raises ``ValueError`` if the text is not valid.
+ :param text: The address in textual form.
+ :type text: str
+ :raises ValueError: If the text is not a valid address.
"""
try:
return dns.ipv6.canonicalize(text)
def inet_ntoa(address: bytes) -> str:
"""Convert an IPv4 address in binary form to text form.
- *address*, a ``bytes``, the IPv4 address in binary form.
-
- Returns a ``str``.
+ :param address: The IPv4 address in binary form.
+ :type address: bytes
+ :rtype: str
"""
if len(address) != 4:
def inet_aton(text: str | bytes) -> bytes:
"""Convert an IPv4 address in text form to binary form.
- *text*, a ``str`` or ``bytes``, the IPv4 address in textual form.
-
- Returns a ``bytes``.
+ :param text: The IPv4 address in textual form.
+ :type text: str or bytes
+ :rtype: bytes
"""
if not isinstance(text, bytes):
"""Verify that *address* is a valid text form IPv4 address and return its
canonical text form.
- *text*, a ``str`` or ``bytes``, the IPv4 address in textual form.
-
- Raises ``dns.exception.SyntaxError`` if the text is not valid.
+ :param text: The IPv4 address in textual form.
+ :type text: str or bytes
+ :raises dns.exception.SyntaxError: If the text is not valid.
"""
# Note that inet_aton() only accepts canonial form, but we still run through
# inet_ntoa() to ensure the output is a str.
def inet_ntoa(address: bytes) -> str:
"""Convert an IPv6 address in binary form to text form.
- *address*, a ``bytes``, the IPv6 address in binary form.
-
- Raises ``ValueError`` if the address isn't 16 bytes long.
- Returns a ``str``.
+ :param address: The IPv6 address in binary form.
+ :type address: bytes
+ :raises ValueError: If the address is not 16 bytes long.
+ :rtype: str
"""
if len(address) != 16:
def inet_aton(text: str | bytes, ignore_scope: bool = False) -> bytes:
"""Convert an IPv6 address in text form to binary form.
- *text*, a ``str`` or ``bytes``, the IPv6 address in textual form.
-
- *ignore_scope*, a ``bool``. If ``True``, a scope will be ignored.
- If ``False``, the default, it is an error for a scope to be present.
-
- Returns a ``bytes``.
+ :param text: The IPv6 address in textual form.
+ :type text: str or bytes
+ :param ignore_scope: If ``True``, a scope is ignored; if ``False``
+ (the default), a scope is an error.
+ :type ignore_scope: bool
+ :rtype: bytes
"""
#
def is_mapped(address: bytes) -> bool:
"""Is the specified address a mapped IPv4 address?
- *address*, a ``bytes`` is an IPv6 address in binary form.
-
- Returns a ``bool``.
+ :param address: An IPv6 address in binary form.
+ :type address: bytes
+ :rtype: bool
"""
return address.startswith(_mapped_prefix)
"""Verify that *address* is a valid text form IPv6 address and return its
canonical text form. Addresses with scopes are rejected.
- *text*, a ``str`` or ``bytes``, the IPv6 address in textual form.
-
- Raises ``dns.exception.SyntaxError`` if the text is not valid.
+ :param text: The IPv6 address in textual form.
+ :type text: str or bytes
+ :raises dns.exception.SyntaxError: If the text is not valid.
"""
return inet_ntoa(inet_aton(text))
def message(self):
"""As much of the message as could be processed.
- Returns a ``dns.message.Message``.
+ :rtype: :py:class:`dns.message.Message`
"""
return self.kwargs["message"]
The *origin*, *relativize*, and any other keyword
arguments are passed to the RRset ``to_text()`` method.
- *style*, a :py:class:`dns.rdataset.RdatasetStyle` or ``None`` (the default). If
- specified, the style overrides the other parameters.
-
- Returns a ``str``.
+ :param style: If specified, overrides *origin* and *relativize*.
+ :type style: :py:class:`dns.rdataset.RdatasetStyle` or ``None``
+ :rtype: str
"""
if style is None:
kw = kw.copy()
def to_styled_text(self, style: MessageStyle) -> str:
"""Convert the message to styled text.
- *style*, a :py:class:`dns.rdataset.RdatasetStyle` or ``None`` (the default). If
- specified, the style overrides the other parameters.
-
- Returns a ``str``.
+ :param style: The style to use for formatting.
+ :type style: :py:class:`dns.message.MessageStyle`
+ :rtype: str
"""
s = io.StringIO()
"""Two messages are equal if they have the same content in the
header, question, answer, and authority sections.
- Returns a ``bool``.
+ :rtype: bool
"""
if not isinstance(other, Message):
return not self.__eq__(other)
def is_response(self, other: "Message") -> bool:
- """Is *other*, also a ``dns.message.Message``, a response to this
- message?
+ """Is *other* a response to this message?
- Returns a ``bool``.
+ :param other: The message to check.
+ :type other: :py:class:`dns.message.Message`
+ :rtype: bool
"""
if (
"""Return the "section number" of the specified section for use
in indexing.
- *section* is one of the section attributes of this message.
-
- Raises ``ValueError`` if the section isn't known.
-
- Returns an ``int``.
+ :param section: One of the section attributes of this message.
+ :raises ValueError: If the section is not known.
+ :rtype: int
"""
for i, our_section in enumerate(self.sections):
"""Return the section list associated with the specified section
number.
- *number* is a section number `int` or the text form of a section
- name.
-
- Raises ``ValueError`` if the section isn't known.
-
- Returns a ``list``.
+ :param number: A section number (``int``) or text name of a section.
+ :raises ValueError: If the section is not known.
+ :rtype: list
"""
section = self._section_enum.make(number)
) -> dns.rrset.RRset:
"""Find the RRset with the given attributes in the specified section.
- *section*, an ``int`` section number, a ``str`` section name, or one of
- the section attributes of this message. This specifies the
- the section of the message to search. For example::
+ *section* may be an ``int`` section number, a ``str`` section name, or
+ one of the section list attributes of this message. For example::
my_message.find_rrset(my_message.answer, name, rdclass, rdtype)
my_message.find_rrset(dns.message.ANSWER, name, rdclass, rdtype)
my_message.find_rrset("ANSWER", name, rdclass, rdtype)
- *name*, a ``dns.name.Name`` or ``str``, the name of the RRset.
-
- *rdclass*, an ``int`` or ``str``, the class of the RRset.
-
- *rdtype*, an ``int`` or ``str``, the type of the RRset.
-
- *covers*, an ``int`` or ``str``, the covers value of the RRset.
- The default is ``dns.rdatatype.NONE``.
-
- *deleting*, an ``int``, ``str``, or ``None``, the deleting value of the
- RRset. The default is ``None``.
-
- *create*, a ``bool``. If ``True``, create the RRset if it is not found.
- The created RRset is appended to *section*.
-
- *force_unique*, a ``bool``. If ``True`` and *create* is also ``True``,
- create a new RRset regardless of whether a matching RRset exists
- already. The default is ``False``. This is useful when creating
- DDNS Update messages, as order matters for them.
-
- *idna_codec*, a ``dns.name.IDNACodec``, specifies the IDNA
- encoder/decoder. If ``None``, the default IDNA 2003 encoder/decoder
- is used.
-
- Raises ``KeyError`` if the RRset was not found and create was
- ``False``.
-
- Returns a ``dns.rrset.RRset object``.
+ :param name: The owner name.
+ :type name: :py:class:`dns.name.Name` or ``str``
+ :param rdclass: The rdata class.
+ :type rdclass: :py:class:`dns.rdataclass.RdataClass` or ``str``
+ :param rdtype: The rdata type.
+ :type rdtype: :py:class:`dns.rdatatype.RdataType` or ``str``
+ :param covers: The covered type; default is ``dns.rdatatype.NONE``.
+ :type covers: :py:class:`dns.rdatatype.RdataType` or ``str``
+ :param deleting: The deleting value; default is ``None``.
+ :type deleting: :py:class:`dns.rdataclass.RdataClass`, ``str``, or ``None``
+ :param create: If ``True``, create and append the RRset if not found.
+ :type create: bool
+ :param force_unique: If ``True`` and *create* is ``True``, always create
+ a new RRset even if a matching one exists. Useful for DDNS updates.
+ :type force_unique: bool
+ :param idna_codec: The IDNA encoder/decoder. Defaults to IDNA 2003.
+ :type idna_codec: :py:class:`dns.name.IDNACodec` or ``None``
+ :raises KeyError: If the RRset was not found and *create* is ``False``.
+ :rtype: :py:class:`dns.rrset.RRset`
"""
if isinstance(section, int):
) -> dns.rrset.RRset | None:
"""Get the RRset with the given attributes in the specified section.
- If the RRset is not found, None is returned.
-
- *section*, an ``int`` section number, a ``str`` section name, or one of
- the section attributes of this message. This specifies the
- the section of the message to search. For example::
-
- my_message.get_rrset(my_message.answer, name, rdclass, rdtype)
- my_message.get_rrset(dns.message.ANSWER, name, rdclass, rdtype)
- my_message.get_rrset("ANSWER", name, rdclass, rdtype)
-
- *name*, a ``dns.name.Name`` or ``str``, the name of the RRset.
-
- *rdclass*, an ``int`` or ``str``, the class of the RRset.
-
- *rdtype*, an ``int`` or ``str``, the type of the RRset.
-
- *covers*, an ``int`` or ``str``, the covers value of the RRset.
- The default is ``dns.rdatatype.NONE``.
-
- *deleting*, an ``int``, ``str``, or ``None``, the deleting value of the
- RRset. The default is ``None``.
-
- *create*, a ``bool``. If ``True``, create the RRset if it is not found.
- The created RRset is appended to *section*.
-
- *force_unique*, a ``bool``. If ``True`` and *create* is also ``True``,
- create a new RRset regardless of whether a matching RRset exists
- already. The default is ``False``. This is useful when creating
- DDNS Update messages, as order matters for them.
-
- *idna_codec*, a ``dns.name.IDNACodec``, specifies the IDNA
- encoder/decoder. If ``None``, the default IDNA 2003 encoder/decoder
- is used.
-
- Returns a ``dns.rrset.RRset object`` or ``None``.
+ Like :py:meth:`find_rrset` but returns ``None`` instead of raising
+ :py:exc:`KeyError` when the RRset is not found.
+
+ *section* may be an ``int`` section number, a ``str`` section name, or
+ one of the section list attributes of this message.
+
+ :param name: The owner name.
+ :type name: :py:class:`dns.name.Name` or ``str``
+ :param rdclass: The rdata class.
+ :type rdclass: :py:class:`dns.rdataclass.RdataClass` or ``str``
+ :param rdtype: The rdata type.
+ :type rdtype: :py:class:`dns.rdatatype.RdataType` or ``str``
+ :param covers: The covered type; default is ``dns.rdatatype.NONE``.
+ :type covers: :py:class:`dns.rdatatype.RdataType` or ``str``
+ :param deleting: The deleting value; default is ``None``.
+ :type deleting: :py:class:`dns.rdataclass.RdataClass`, ``str``, or ``None``
+ :param create: If ``True``, create and append the RRset if not found.
+ :type create: bool
+ :param force_unique: If ``True`` and *create* is ``True``, always create
+ a new RRset even if a matching one exists.
+ :type force_unique: bool
+ :param idna_codec: The IDNA encoder/decoder. Defaults to IDNA 2003.
+ :type idna_codec: :py:class:`dns.name.IDNACodec` or ``None``
+ :returns: The matching RRset, or ``None`` if not found.
+ :rtype: :py:class:`dns.rrset.RRset` or ``None``
"""
try:
def section_count(self, section: SectionType) -> int:
"""Returns the number of records in the specified section.
- *section*, an ``int`` section number, a ``str`` section name, or one of
- the section attributes of this message. This specifies the
- the section of the message to count. For example::
+ :param section: An ``int`` section number, a ``str`` section name, or
+ one of the section attributes of this message. For example::
- my_message.section_count(my_message.answer)
- my_message.section_count(dns.message.ANSWER)
- my_message.section_count("ANSWER")
+ my_message.section_count(my_message.answer)
+ my_message.section_count(dns.message.ANSWER)
+ my_message.section_count("ANSWER")
"""
if isinstance(section, int):
prefer_truncation: bool = False,
**kw: Any,
) -> bytes:
- """Return a string containing the message in DNS compressed wire
- format.
+ """Return the message in DNS compressed wire format.
Additional keyword arguments are passed to the RRset ``to_wire()``
method.
- *origin*, a ``dns.name.Name`` or ``None``, the origin to be appended
- to any relative names. If ``None``, and the message has an origin
- attribute that is not ``None``, then it will be used.
-
- *max_size*, an ``int``, the maximum size of the wire format
- output; default is 0, which means "the message's request
- payload, if nonzero, or 65535".
-
- *multi*, a ``bool``, should be set to ``True`` if this message is
- part of a multiple message sequence.
-
- *tsig_ctx*, a ``dns.tsig.HMACTSig`` or ``dns.tsig.GSSTSig`` object, the
- ongoing TSIG context, used when signing zone transfers.
-
- *prepend_length*, a ``bool``, should be set to ``True`` if the caller
- wants the message length prepended to the message itself. This is
- useful for messages sent over TCP, TLS (DoT), or QUIC (DoQ).
-
- *prefer_truncation*, a ``bool``, should be set to ``True`` if the caller
- wants the message to be truncated if it would otherwise exceed the
- maximum length. If the truncation occurs before the additional section,
- the TC bit will be set.
-
- Raises ``dns.exception.TooBig`` if *max_size* was exceeded.
-
- Returns a ``bytes``.
+ :param origin: Origin to append to relative names. If ``None``, the
+ message's own origin (if any) is used.
+ :type origin: :py:class:`dns.name.Name` or ``None``
+ :param max_size: Maximum wire format size; 0 means use the request
+ payload or 65535.
+ :type max_size: int
+ :param multi: ``True`` if this message is part of a multi-message sequence.
+ :type multi: bool
+ :param tsig_ctx: Ongoing TSIG context for zone transfer signing.
+ :param prepend_length: If ``True``, prepend the 2-byte message length
+ (useful for TCP/TLS/QUIC).
+ :type prepend_length: bool
+ :param prefer_truncation: If ``True``, truncate instead of raising when
+ the message exceeds *max_size*. Sets TC if truncation is before the
+ additional section.
+ :type prefer_truncation: bool
+ :raises dns.exception.TooBig: If *max_size* is exceeded and
+ *prefer_truncation* is ``False``.
+ :rtype: bytes
"""
if origin is None and self.origin is not None:
other_data: bytes = b"",
algorithm: dns.name.Name | str = dns.tsig.default_algorithm,
) -> None:
- """When sending, a TSIG signature using the specified key
- should be added.
-
- *keyring*, a ``dict``, ``callable`` or ``dns.tsig.Key``, is either
- the TSIG keyring or key to use.
-
- The format of a keyring dict is a mapping from TSIG key name, as
- ``dns.name.Name`` to ``dns.tsig.Key`` or a TSIG secret, a ``bytes``.
- If a ``dict`` *keyring* is specified but a *keyname* is not, the key
- used will be the first key in the *keyring*. Note that the order of
- keys in a dictionary is not defined, so applications should supply a
- keyname when a ``dict`` keyring is used, unless they know the keyring
- contains only one key. If a ``callable`` keyring is specified, the
- callable will be called with the message and the keyname, and is
- expected to return a key.
-
- *keyname*, a ``dns.name.Name``, ``str`` or ``None``, the name of
- this TSIG key to use; defaults to ``None``. If *keyring* is a
- ``dict``, the key must be defined in it. If *keyring* is a
- ``dns.tsig.Key``, this is ignored.
-
- *fudge*, an ``int``, the TSIG time fudge.
-
- *original_id*, an ``int``, the TSIG original id. If ``None``,
- the message's id is used.
-
- *tsig_error*, an ``int``, the TSIG error code.
-
- *other_data*, a ``bytes``, the TSIG other data.
-
- *algorithm*, a ``dns.name.Name`` or ``str``, the TSIG algorithm to use. This is
- only used if *keyring* is a ``dict``, and the key entry is a ``bytes``.
+ """Arrange for a TSIG signature to be added when sending.
+
+ :param keyring: The TSIG keyring or key. A ``dict`` maps
+ :py:class:`dns.name.Name` keys to :py:class:`dns.tsig.Key` objects
+ or ``bytes`` secrets. If a ``dict`` is given without *keyname*, the
+ first key in the dict is used. A callable is invoked with the message
+ and *keyname* and must return a key.
+ :type keyring: dict, callable, or :py:class:`dns.tsig.Key`
+ :param keyname: The TSIG key name. Ignored if *keyring* is a
+ :py:class:`dns.tsig.Key`. Defaults to ``None``.
+ :type keyname: :py:class:`dns.name.Name`, ``str``, or ``None``
+ :param fudge: The TSIG time fudge.
+ :type fudge: int
+ :param original_id: The TSIG original id. Defaults to the message id.
+ :type original_id: int or ``None``
+ :param tsig_error: The TSIG error code.
+ :type tsig_error: int
+ :param other_data: The TSIG other data.
+ :type other_data: bytes
+ :param algorithm: The TSIG algorithm. Only used when *keyring* is a
+ ``dict`` and the key entry is ``bytes``.
+ :type algorithm: :py:class:`dns.name.Name` or ``str``
"""
if isinstance(keyring, dns.tsig.Key):
) -> None:
"""Configure EDNS behavior.
- *edns*, an ``int``, is the EDNS level to use. Specifying ``None``, ``False``,
- or ``-1`` means "do not use EDNS", and in this case the other parameters are
- ignored. Specifying ``True`` is equivalent to specifying 0, i.e. "use EDNS0".
-
- *ednsflags*, an ``int``, the EDNS flag values.
-
- *payload*, an ``int``, is the EDNS sender's payload field, which is the maximum
- size of UDP datagram the sender can handle. I.e. how big a response to this
- message can be.
-
- *request_payload*, an ``int``, is the EDNS payload size to use when sending this
- message. If not specified, defaults to the value of *payload*.
-
- *options*, a list of ``dns.edns.Option`` objects or ``None``, the EDNS options.
-
- *pad*, a non-negative ``int``. If 0, the default, do not pad; otherwise add
- padding bytes to make the message size a multiple of *pad*. Note that if
- padding is non-zero, an EDNS PADDING option will always be added to the
- message.
+ :param edns: The EDNS level to use. Specifying ``None``, ``False``, or
+ ``-1`` means "do not use EDNS" (other parameters are ignored).
+ Specifying ``True`` is equivalent to specifying 0 (use EDNS0).
+ :type edns: int or ``None``
+ :param ednsflags: The EDNS flag values.
+ :type ednsflags: int
+ :param payload: The EDNS sender's payload field — the maximum UDP
+ datagram size the sender can handle (i.e. how big a response can be).
+ :type payload: int
+ :param request_payload: The EDNS payload size to use when sending.
+ Defaults to the value of *payload*.
+ :type request_payload: int or ``None``
+ :param options: The EDNS options.
+ :type options: list of :py:class:`dns.edns.Option` or ``None``
+ :param pad: If 0 (the default), do not pad; otherwise add padding bytes
+ to make the message size a multiple of *pad*. When nonzero, an EDNS
+ PADDING option is always added.
+ :type pad: int
"""
if edns is None or edns is False:
def want_dnssec(self, wanted: bool = True) -> None:
"""Enable or disable 'DNSSEC desired' flag in requests.
- *wanted*, a ``bool``. If ``True``, then DNSSEC data is
- desired in the response, EDNS is enabled if required, and then
- the DO bit is set. If ``False``, the DO bit is cleared if
- EDNS is enabled.
+ :param wanted: If ``True``, DNSSEC data is desired in the response,
+ EDNS is enabled if required, and the DO bit is set. If ``False``,
+ the DO bit is cleared if EDNS is enabled.
+ :type wanted: bool
"""
if wanted:
def rcode(self) -> dns.rcode.Rcode:
"""Return the rcode.
- Returns a ``dns.rcode.Rcode``.
+ :rtype: :py:class:`dns.rcode.Rcode`
"""
return dns.rcode.from_flags(int(self.flags), int(self.ednsflags))
def opcode(self) -> dns.opcode.Opcode:
"""Return the opcode.
- Returns a ``dns.opcode.Opcode``.
+ :rtype: :py:class:`dns.opcode.Opcode`
"""
return dns.opcode.from_flags(int(self.flags))
def set_opcode(self, opcode: dns.opcode.Opcode) -> None:
"""Set the opcode.
- *opcode*, a ``dns.opcode.Opcode``, is the opcode to set.
+ :param opcode: The opcode to set.
+ :type opcode: :py:class:`dns.opcode.Opcode`
"""
self.flags &= 0x87FF
self.flags |= dns.opcode.to_flags(opcode)
"""Follow the CNAME chain in the response to determine the answer
RRset.
- Raises ``dns.message.NotQueryResponse`` if the message is not
- a response.
-
- Raises ``dns.message.ChainTooLong`` if the CNAME chain is too long.
-
- Raises ``dns.message.AnswerForNXDOMAIN`` if the rcode is NXDOMAIN
- but an answer was found.
-
- Raises ``dns.exception.FormError`` if the question count is not 1.
-
- Returns a ChainingResult object.
+ :raises dns.message.NotQueryResponse: If the message is not a response.
+ :raises dns.message.ChainTooLong: If the CNAME chain is too long.
+ :raises dns.message.AnswerForNXDOMAIN: If the rcode is NXDOMAIN but
+ an answer was found.
+ :raises dns.exception.FormError: If the question count is not 1.
+ :rtype: :py:class:`dns.message.ChainingResult`
"""
if self.flags & dns.flags.QR == 0:
raise NotQueryResponse
"""Return the canonical name of the first name in the question
section.
- Raises ``dns.message.NotQueryResponse`` if the message is not
- a response.
-
- Raises ``dns.message.ChainTooLong`` if the CNAME chain is too long.
-
- Raises ``dns.message.AnswerForNXDOMAIN`` if the rcode is NXDOMAIN
- but an answer was found.
-
- Raises ``dns.exception.FormError`` if the question count is not 1.
+ :raises dns.message.NotQueryResponse: If the message is not a response.
+ :raises dns.message.ChainTooLong: If the CNAME chain is too long.
+ :raises dns.message.AnswerForNXDOMAIN: If the rcode is NXDOMAIN but
+ an answer was found.
+ :raises dns.exception.FormError: If the question count is not 1.
"""
return self.resolve_chaining().canonical_name
) -> Message:
"""Convert a DNS wire format message into a message object.
- *keyring*, a ``dns.tsig.Key``, ``dict``, ``bool``, or ``None``, the key or keyring
- to use if the message is signed. If ``None`` or ``True``, then trying to decode
- a message with a TSIG will fail as it cannot be validated. If ``False``, then
- TSIG validation is disabled.
-
- *request_mac*, a ``bytes`` or ``None``. If the message is a response to a
- TSIG-signed request, *request_mac* should be set to the MAC of that request.
-
- *xfr*, a ``bool``, should be set to ``True`` if this message is part of a zone
- transfer.
-
- *origin*, a ``dns.name.Name`` or ``None``. If the message is part of a zone
- transfer, *origin* should be the origin name of the zone. If not ``None``, names
- will be relativized to the origin.
-
- *tsig_ctx*, a ``dns.tsig.HMACTSig`` or ``dns.tsig.GSSTSig`` object, the ongoing TSIG
- context, used when validating zone transfers.
-
- *multi*, a ``bool``, should be set to ``True`` if this message is part of a multiple
- message sequence.
-
- *question_only*, a ``bool``. If ``True``, read only up to the end of the question
- section.
-
- *one_rr_per_rrset*, a ``bool``. If ``True``, put each RR into its own RRset.
-
- *ignore_trailing*, a ``bool``. If ``True``, ignore trailing junk at end of the
- message.
-
- *raise_on_truncation*, a ``bool``. If ``True``, raise an exception if the TC bit is
- set.
-
- *continue_on_error*, a ``bool``. If ``True``, try to continue parsing even if
- errors occur. Erroneous rdata will be ignored. Errors will be accumulated as a
- list of MessageError objects in the message's ``errors`` attribute. This option is
- recommended only for DNS analysis tools, or for use in a server as part of an error
- handling path. The default is ``False``.
-
- Raises ``dns.message.ShortHeader`` if the message is less than 12 octets long.
-
- Raises ``dns.message.TrailingJunk`` if there were octets in the message past the end
- of the proper DNS message, and *ignore_trailing* is ``False``.
-
- Raises ``dns.message.BadEDNS`` if an OPT record was in the wrong section, or
- occurred more than once.
-
- Raises ``dns.message.BadTSIG`` if a TSIG record was not the last record of the
- additional data section.
-
- Raises ``dns.message.Truncated`` if the TC flag is set and *raise_on_truncation* is
- ``True``.
-
- Returns a ``dns.message.Message``.
+ :param keyring: The key or keyring for TSIG validation. ``None`` or
+ ``True`` causes TSIG-signed messages to fail; ``False`` disables
+ validation.
+ :type keyring: :py:class:`dns.tsig.Key`, dict, bool, or ``None``
+ :param request_mac: MAC of the TSIG-signed request this message responds
+ to, if any.
+ :type request_mac: bytes or ``None``
+ :param xfr: ``True`` if this message is part of a zone transfer.
+ :type xfr: bool
+ :param origin: Zone origin for zone transfers; names are relativized to
+ this if not ``None``.
+ :type origin: :py:class:`dns.name.Name` or ``None``
+ :param tsig_ctx: Ongoing TSIG context for zone transfer validation.
+ :param multi: ``True`` if this message is part of a multi-message sequence.
+ :type multi: bool
+ :param question_only: If ``True``, read only the question section.
+ :type question_only: bool
+ :param one_rr_per_rrset: If ``True``, put each RR into its own RRset.
+ :type one_rr_per_rrset: bool
+ :param ignore_trailing: If ``True``, ignore trailing octets after the
+ message.
+ :type ignore_trailing: bool
+ :param raise_on_truncation: If ``True``, raise
+ :py:exc:`dns.message.Truncated` when the TC bit is set.
+ :type raise_on_truncation: bool
+ :param continue_on_error: If ``True``, try to continue parsing on errors
+ and accumulate them in the message's ``errors`` attribute.
+ :type continue_on_error: bool
+ :raises dns.message.ShortHeader: If the message is less than 12 octets.
+ :raises dns.message.TrailingJunk: If trailing octets are present and
+ *ignore_trailing* is ``False``.
+ :raises dns.message.BadEDNS: If an OPT record is in the wrong section.
+ :raises dns.message.BadTSIG: If a TSIG record is not the last additional
+ record.
+ :raises dns.message.Truncated: If the TC flag is set and
+ *raise_on_truncation* is ``True``.
+ :rtype: :py:class:`dns.message.Message`
"""
# We permit None for request_mac solely for backwards compatibility
facilitate reading multiple messages from a single file with
``dns.message.from_file()``.
- *text*, a ``str``, the text format message.
-
- *idna_codec*, a ``dns.name.IDNACodec``, specifies the IDNA
- encoder/decoder. If ``None``, the default IDNA 2003 encoder/decoder
- is used.
-
- *one_rr_per_rrset*, a ``bool``. If ``True``, then each RR is put
- into its own rrset. The default is ``False``.
-
- *origin*, a ``dns.name.Name`` (or ``None``), the
- origin to use for relative names.
-
- *relativize*, a ``bool``. If true, name will be relativized.
-
- *relativize_to*, a ``dns.name.Name`` (or ``None``), the origin to use
- when relativizing names. If not set, the *origin* value will be used.
-
- Raises ``dns.message.UnknownHeaderField`` if a header is unknown.
-
- Raises ``dns.exception.SyntaxError`` if the text is badly formed.
-
- Returns a ``dns.message.Message object``
+ :param text: The text format message.
+ :type text: str
+ :param idna_codec: The IDNA encoder/decoder. Defaults to IDNA 2003.
+ :type idna_codec: :py:class:`dns.name.IDNACodec` or ``None``
+ :param one_rr_per_rrset: If ``True``, put each RR into its own RRset.
+ :type one_rr_per_rrset: bool
+ :param origin: The origin to use for relative names.
+ :type origin: :py:class:`dns.name.Name` or ``None``
+ :param relativize: If ``True``, names will be relativized.
+ :type relativize: bool
+ :param relativize_to: The origin to relativize to. Defaults to *origin*.
+ :type relativize_to: :py:class:`dns.name.Name` or ``None``
+ :raises dns.message.UnknownHeaderField: If a header field is unknown.
+ :raises dns.exception.SyntaxError: If the text is badly formed.
+ :rtype: :py:class:`dns.message.Message`
"""
# 'text' can also be a file, but we don't publish that fact
Message blocks are separated by a single blank line.
- *f*, a ``file`` or ``str``. If *f* is text, it is treated as the
- pathname of a file to open.
-
- *idna_codec*, a ``dns.name.IDNACodec``, specifies the IDNA
- encoder/decoder. If ``None``, the default IDNA 2003 encoder/decoder
- is used.
-
- *one_rr_per_rrset*, a ``bool``. If ``True``, then each RR is put
- into its own rrset. The default is ``False``.
-
- Raises ``dns.message.UnknownHeaderField`` if a header is unknown.
-
- Raises ``dns.exception.SyntaxError`` if the text is badly formed.
-
- Returns a ``dns.message.Message object``
+ :param f: A file object or a pathname string.
+ :param idna_codec: The IDNA encoder/decoder. Defaults to IDNA 2003.
+ :type idna_codec: :py:class:`dns.name.IDNACodec` or ``None``
+ :param one_rr_per_rrset: If ``True``, put each RR into its own RRset.
+ :type one_rr_per_rrset: bool
+ :raises dns.message.UnknownHeaderField: If a header field is unknown.
+ :raises dns.exception.SyntaxError: If the text is badly formed.
+ :rtype: :py:class:`dns.message.Message`
"""
if isinstance(f, str):
) -> QueryMessage:
"""Make a query message.
- The query name, type, and class may all be specified either
- as objects of the appropriate type, or as strings.
-
- The query will have a randomly chosen query id, and its DNS flags
- will be set to dns.flags.RD.
-
- qname, a ``dns.name.Name`` or ``str``, the query name.
-
- *rdtype*, an ``int`` or ``str``, the desired rdata type.
-
- *rdclass*, an ``int`` or ``str``, the desired rdata class; the default
- is class IN.
-
- *use_edns*, an ``int``, ``bool`` or ``None``. The EDNS level to use; the
- default is ``None``. If ``None``, EDNS will be enabled only if other
- parameters (*ednsflags*, *payload*, *request_payload*, or *options*) are
- set.
- See the description of :py:func:`dns.message.Message.use_edns()` for the
- possible values for use_edns and their meanings.
-
- *want_dnssec*, a ``bool``. If ``True``, DNSSEC data is desired.
-
- *ednsflags*, an ``int``, the EDNS flag values.
-
- *payload*, an ``int``, is the EDNS sender's payload field, which is the
- maximum size of UDP datagram the sender can handle. I.e. how big
- a response to this message can be.
-
- *request_payload*, an ``int``, is the EDNS payload size to use when
- sending this message. If not specified, defaults to the value of
- *payload*.
-
- *options*, a list of ``dns.edns.Option`` objects or ``None``, the EDNS
- options.
-
- *idna_codec*, a ``dns.name.IDNACodec``, specifies the IDNA
- encoder/decoder. If ``None``, the default IDNA 2003 encoder/decoder
- is used.
-
- *id*, an ``int`` or ``None``, the desired query id. The default is
- ``None``, which generates a random query id.
-
- *flags*, an ``int``, the desired query flags. The default is
- ``dns.flags.RD``.
-
- *pad*, a non-negative ``int``. If 0, the default, do not pad; otherwise add
- padding bytes to make the message size a multiple of *pad*. Note that if
- padding is non-zero, an EDNS PADDING option will always be added to the
- message.
-
- Returns a ``dns.message.QueryMessage``
+ The query name, type, and class may be specified as objects of the
+ appropriate type or as strings. The query id is chosen at random, and
+ the DNS flags are set to ``dns.flags.RD``.
+
+ :param qname: The query name.
+ :type qname: :py:class:`dns.name.Name` or ``str``
+ :param rdtype: The desired rdata type.
+ :type rdtype: :py:class:`dns.rdatatype.RdataType` or ``str``
+ :param rdclass: The desired rdata class; default is IN.
+ :type rdclass: :py:class:`dns.rdataclass.RdataClass` or ``str``
+ :param use_edns: The EDNS level; ``None`` enables EDNS only if other EDNS
+ parameters are set. See :py:meth:`dns.message.Message.use_edns`.
+ :type use_edns: int, bool, or ``None``
+ :param want_dnssec: If ``True``, DNSSEC data is desired.
+ :type want_dnssec: bool
+ :param ednsflags: The EDNS flag values.
+ :type ednsflags: int
+ :param payload: The EDNS sender payload field (max UDP response size).
+ :type payload: int
+ :param request_payload: The EDNS payload size to advertise when sending.
+ Defaults to *payload*.
+ :type request_payload: int
+ :param options: The EDNS options.
+ :type options: list of :py:class:`dns.edns.Option` or ``None``
+ :param idna_codec: The IDNA encoder/decoder. Defaults to IDNA 2003.
+ :type idna_codec: :py:class:`dns.name.IDNACodec` or ``None``
+ :param id: The query id. Defaults to a random id.
+ :type id: int or ``None``
+ :param flags: The query flags. Default is ``dns.flags.RD``.
+ :type flags: int
+ :param pad: If non-zero, add EDNS PADDING to make size a multiple of this.
+ :type pad: int
+ :rtype: :py:class:`dns.message.QueryMessage`
"""
if isinstance(qname, str):
How should sections be copied when making an update response?
"""
+ #: Copy no sections; only suitable for testing
NOTHING = 0
+ #: Copy only the question section, if present.
QUESTION = 1
+ #: Copy all sections, other than OPT and TSIG RRs.
EVERYTHING = 2
pad: int | None = None,
copy_mode: CopyMode | None = None,
) -> Message:
- """Make a message which is a response for the specified query.
- The message returned is really a response skeleton; it has all of the infrastructure
- required of a response, but none of the content.
-
- Response section(s) which are copied are shallow copies of the matching section(s)
- in the query, so the query's RRsets should not be changed.
-
- *query*, a ``dns.message.Message``, the query to respond to.
-
- *recursion_available*, a ``bool``, should RA be set in the response?
-
- *our_payload*, an ``int``, the payload size to advertise in EDNS responses.
-
- *fudge*, an ``int``, the TSIG time fudge.
-
- *tsig_error*, an ``int``, the TSIG error.
-
- *pad*, a non-negative ``int`` or ``None``. If 0, the default, do not pad; otherwise
- if not ``None`` add padding bytes to make the message size a multiple of *pad*. Note
- that if padding is non-zero, an EDNS PADDING option will always be added to the
- message. If ``None``, add padding following RFC 8467, namely if the request is
- padded, pad the response to 468 otherwise do not pad.
-
- *copy_mode*, a ``dns.message.CopyMode`` or ``None``, determines how sections are
- copied. The default, ``None`` copies sections according to the default for the
- message's opcode, which is currently ``dns.message.CopyMode.QUESTION`` for all
- opcodes. ``dns.message.CopyMode.QUESTION`` copies only the question section.
- ``dns.message.CopyMode.EVERYTHING`` copies all sections other than OPT or TSIG
- records, which are created appropriately if needed. ``dns.message.CopyMode.NOTHING``
- copies no sections; note that this mode is for server testing purposes and is
- otherwise not recommended for use. In particular, ``dns.message.is_response()``
- will be ``False`` if you create a response this way and the rcode is not
- ``FORMERR``, ``SERVFAIL``, ``NOTIMP``, or ``REFUSED``.
-
- Returns a ``dns.message.Message`` object whose specific class is appropriate for the
- query. For example, if query is a ``dns.update.UpdateMessage``, the response will
- be one too.
+ """Make a response skeleton for the specified query.
+
+ The returned message has all required response infrastructure but no
+ content. Copied sections are shallow copies, so the query's RRsets
+ should not be changed.
+
+ :param query: The query to respond to.
+ :type query: :py:class:`dns.message.Message`
+ :param recursion_available: If ``True``, set the RA bit.
+ :type recursion_available: bool
+ :param our_payload: The EDNS payload size to advertise.
+ :type our_payload: int
+ :param fudge: The TSIG time fudge.
+ :type fudge: int
+ :param tsig_error: The TSIG error code.
+ :type tsig_error: int
+ :param pad: If 0, no padding; if not ``None`` pad to a multiple of this
+ value; if ``None``, follow RFC 8467 (pad to 468 if request was padded).
+ :type pad: int or ``None``
+ :param copy_mode: Controls which sections are copied. ``None`` uses the
+ default for the opcode (currently
+ :py:attr:`dns.message.CopyMode.QUESTION`).
+ :type copy_mode: :py:class:`dns.message.CopyMode` or ``None``
+ :returns: A response message of the same class as *query*.
+ :rtype: :py:class:`dns.message.Message`
"""
if query.flags & dns.flags.QR:
def _escapify(label: bytes | str) -> str:
"""Escape the characters in label which need it.
- @returns: the escaped string
- @rtype: string"""
+
+ :returns: the escaped string
+ :rtype: str
+ """
if isinstance(label, bytes):
# Ordinary DNS label mode. Escape special characters and values
# < 0x20 or > 0x7f.
def __init__(self, strict_decode: bool = False):
"""Initialize the IDNA 2003 encoder/decoder.
- *strict_decode* is a ``bool``. If `True`, then IDNA2003 checking
- is done when decoding. This can cause failures if the name
- was encoded with IDNA2008. The default is `False`.
+ :param bool strict_decode: If ``True``, then IDNA2003 checking
+ is done when decoding. This can cause failures if the name
+ was encoded with IDNA2008. The default is ``False``.
"""
super().__init__()
):
"""Initialize the IDNA 2008 encoder/decoder.
- *uts_46* is a ``bool``. If True, apply Unicode IDNA
- compatibility processing as described in Unicode Technical
- Standard #46 (https://unicode.org/reports/tr46/).
- If False, do not apply the mapping. The default is False.
-
- *transitional* is a ``bool``: If True, use the
- "transitional" mode described in Unicode Technical Standard
- #46. The default is False. This setting has no effect
- in idna 3.11 and later as transitional support has been removed.
-
- *allow_pure_ascii* is a ``bool``. If True, then a label which
- consists of only ASCII characters is allowed. This is less
- strict than regular IDNA 2008, but is also necessary for mixed
- names, e.g. a name with starting with "_sip._tcp." and ending
- in an IDN suffix which would otherwise be disallowed. The
- default is False.
-
- *strict_decode* is a ``bool``: If True, then IDNA2008 checking
- is done when decoding. This can cause failures if the name
- was encoded with IDNA2003. The default is False.
+ :param bool uts_46: If ``True``, apply Unicode IDNA compatibility
+ processing as described in Unicode Technical Standard #46
+ (https://unicode.org/reports/tr46/). If ``False``, do not
+ apply the mapping. The default is ``False``.
+ :param bool transitional: If ``True``, use the "transitional" mode
+ described in Unicode Technical Standard #46. The default is
+ ``False``. This setting has no effect in idna 3.11 and later
+ as transitional support has been removed.
+ :param bool allow_pure_ascii: If ``True``, then a label which
+ consists of only ASCII characters is allowed. This is less
+ strict than regular IDNA 2008, but is also necessary for mixed
+ names, e.g. a name starting with ``_sip._tcp.`` and ending
+ in an IDN suffix which would otherwise be disallowed. The
+ default is ``False``.
+ :param bool strict_decode: If ``True``, then IDNA2008 checking
+ is done when decoding. This can cause failures if the name
+ was encoded with IDNA2003. The default is ``False``.
"""
super().__init__()
self.uts_46 = uts_46
"""Check for empty labels in the middle of a label sequence,
labels that are too long, and for too many labels.
- Raises ``dns.name.NameTooLong`` if the name as a whole is too long.
-
- Raises ``dns.name.EmptyLabel`` if a label is empty (i.e. the root
- label) and appears in a position other than the end of the label
- sequence
-
+ :raises dns.name.NameTooLong: if the name as a whole is too long.
+ :raises dns.name.EmptyLabel: if a label is empty (i.e. the root
+ label) and appears in a position other than the end of the label
+ sequence.
"""
l = len(labels)
@dataclasses.dataclass(frozen=True)
class NameStyle(BaseStyle):
- """Name text styles
-
- *omit_final_dot* is a ``bool``. If True, don't emit the final
- dot (denoting the root label) for absolute names. The default
- is False.
-
- *idna_codec* specifies the IDNA decoder to use. The default is ``None``
- which means all text is in the standard DNS zonefile format, i.e.
- punycode will not be decoded.
-
- If *origin* is ``None``, the default, then the name's relativity is not
- altered before conversion to text. Otherwise, if *relativize* is ``True``
- the name is relativized, and if *relativize* is ``False`` the name is
- derelativized.
+ """Name text styles.
+
+ :param bool omit_final_dot: If ``True``, don't emit the final dot
+ (denoting the root label) for absolute names. The default is
+ ``False``.
+ :param idna_codec: The IDNA decoder to use. The default is ``None``,
+ which means all text is in the standard DNS zonefile format, i.e.
+ punycode will not be decoded.
+ :type idna_codec: :py:class:`dns.name.IDNACodec` or ``None``
+ :param origin: If ``None`` (the default), the name's relativity is not
+ altered before conversion to text. Otherwise, if *relativize* is
+ ``True`` the name is relativized, and if *relativize* is ``False``
+ the name is derelativized.
+ :type origin: :py:class:`dns.name.Name` or ``None``
+ :param bool relativize: Controls the direction of relativization when
+ *origin* is set.
"""
omit_final_dot: bool = False
__slots__ = ["labels"]
def __init__(self, labels: Iterable[bytes | str]):
- """*labels* is any iterable whose values are ``str`` or ``bytes``."""
+ """Initialize a DNS name.
+
+ :param labels: An iterable whose values are ``str`` or ``bytes``.
+ """
blabels = [_maybe_convert_to_binary(x) for x in labels]
self.labels = tuple(blabels)
def is_absolute(self) -> bool:
"""Is the most significant label of this name the root label?
- Returns a ``bool``.
+ :rtype: bool
"""
return len(self.labels) > 0 and self.labels[-1] == b""
def is_wild(self) -> bool:
- """Is this name wild? (I.e. Is the least significant label '*'?)
+ """Is this name wild? (I.e. Is the least significant label ``'*'``?)
- Returns a ``bool``.
+ :rtype: bool
"""
return len(self.labels) > 0 and self.labels[0] == b"*"
def __hash__(self) -> int:
"""Return a case-insensitive hash of the name.
- Returns an ``int``.
+ :rtype: int
"""
h = 0
"""Compare two names, returning a 3-tuple
``(relation, order, nlabels)``.
- *relation* describes the relation ship between the names,
- and is one of: ``dns.name.NameRelation.NONE``,
- ``dns.name.NameRelation.SUPERDOMAIN``, ``dns.name.NameRelation.SUBDOMAIN``,
- ``dns.name.NameRelation.EQUAL``, or ``dns.name.NameRelation.COMMONANCESTOR``.
+ *relation* describes the relationship between the names, and is one
+ of: :py:attr:`dns.name.NameRelation.NONE`,
+ :py:attr:`dns.name.NameRelation.SUPERDOMAIN`,
+ :py:attr:`dns.name.NameRelation.SUBDOMAIN`,
+ :py:attr:`dns.name.NameRelation.EQUAL`, or
+ :py:attr:`dns.name.NameRelation.COMMONANCESTOR`.
*order* is < 0 if *self* < *other*, > 0 if *self* > *other*, and ==
0 if *self* == *other*. A relative name is always less than an
example1 example2. none < 0 0
example1. example2 none > 0 0
============= ============= =========== ===== =======
+
+ :param other: The name to compare with.
+ :type other: :py:class:`dns.name.Name`
+ :returns: A 3-tuple ``(relation, order, nlabels)``.
+ :rtype: tuple[:py:class:`dns.name.NameRelation`, int, int]
"""
sabs = self.is_absolute()
"""Is self a subdomain of other?
Note that the notion of subdomain includes equality, e.g.
- "dnspython.org" is a subdomain of itself.
+ ``dnspython.org`` is a subdomain of itself.
- Returns a ``bool``.
+ :rtype: bool
"""
nr, _, _ = self.fullcompare(other)
"""Is self a superdomain of other?
Note that the notion of superdomain includes equality, e.g.
- "dnspython.org" is a superdomain of itself.
+ ``dnspython.org`` is a superdomain of itself.
- Returns a ``bool``.
+ :rtype: bool
"""
nr, _, _ = self.fullcompare(other)
def canonicalize(self) -> "Name":
"""Return a name which is equal to the current name, but is in
DNSSEC canonical form.
+
+ :rtype: :py:class:`dns.name.Name`
"""
return Name([x.lower() for x in self.labels])
) -> str:
"""Convert name to DNS text format.
- *omit_final_dot* is a ``bool``. If True, don't emit the final
- dot (denoting the root label) for absolute names. The default
- is False.
-
- *style*, a :py:class:`dns.name.NameStyle` or ``None`` (the default). If
- specified, the style overrides the other parameters.
-
- Returns a ``str``.
+ :param bool omit_final_dot: If ``True``, don't emit the final dot
+ (denoting the root label) for absolute names. The default is
+ ``False``.
+ :param style: If specified, the style overrides the other parameters.
+ :type style: :py:class:`dns.name.NameStyle` or ``None``
+ :rtype: str
"""
if style is None:
style = NameStyle(omit_final_dot=omit_final_dot)
IDN ACE labels are converted to Unicode using the specified codec.
- *omit_final_dot* is a ``bool``. If True, don't emit the final
- dot (denoting the root label) for absolute names. The default
- is False.
-
- Returns a ``str``.
+ :param bool omit_final_dot: If ``True``, don't emit the final dot
+ (denoting the root label) for absolute names. The default is
+ ``False``.
+ :param idna_codec: The IDNA codec to use for decoding ACE labels.
+ If ``None``, the default IDNA codec is used.
+ :type idna_codec: :py:class:`dns.name.IDNACodec` or ``None``
+ :param style: If specified, the style overrides the other parameters.
+ :type style: :py:class:`dns.name.NameStyle` or ``None``
+ :rtype: str
"""
if idna_codec is None:
idna_codec = IDNA_DEFAULT
See the documentation for :py:class:`dns.name.NameStyle` for a description
of the style parameters.
- Returns a ``str``.
+ :param style: The style to apply.
+ :type style: :py:class:`dns.name.NameStyle`
+ :rtype: str
"""
name = self.choose_relativity(style.origin, style.relativize)
format. All names in wire format are absolute. If the name
is a relative name, then an origin must be supplied.
- *origin* is a ``dns.name.Name`` or ``None``. If the name is
- relative and origin is not ``None``, then origin will be appended
- to the name.
-
- Raises ``dns.name.NeedAbsoluteNameOrOrigin`` if the name is
- relative and no origin was provided.
-
- Returns a ``bytes``.
+ :param origin: If the name is relative and *origin* is not ``None``,
+ then *origin* will be appended to the name.
+ :type origin: :py:class:`dns.name.Name` or ``None``
+ :raises dns.name.NeedAbsoluteNameOrOrigin: if the name is relative
+ and no origin was provided.
+ :rtype: bytes
"""
digest = self.to_wire(origin=origin, canonicalize=True)
) -> bytes | None:
"""Convert name to wire format, possibly compressing it.
- *file* is the file where the name is emitted (typically an
- io.BytesIO file). If ``None`` (the default), a ``bytes``
- containing the wire name will be returned.
-
- *compress*, a ``dict``, is the compression table to use. If
- ``None`` (the default), names will not be compressed. Note that
- the compression code assumes that compression offset 0 is the
- start of *file*, and thus compression will not be correct
- if this is not the case.
-
- *origin* is a ``dns.name.Name`` or ``None``. If the name is
- relative and origin is not ``None``, then *origin* will be appended
- to it.
-
- *canonicalize*, a ``bool``, indicates whether the name should
- be canonicalized; that is, converted to a format suitable for
- digesting in hashes.
-
- Raises ``dns.name.NeedAbsoluteNameOrOrigin`` if the name is
- relative and no origin was provided.
-
- Returns a ``bytes`` or ``None``.
+ :param file: The file where the name is emitted (typically an
+ ``io.BytesIO`` file). If ``None`` (the default), a ``bytes``
+ containing the wire name will be returned.
+ :param compress: The compression table to use. If ``None`` (the
+ default), names will not be compressed. Note that the compression
+ code assumes that compression offset 0 is the start of *file*,
+ and thus compression will not be correct if this is not the case.
+ :type compress: dict or ``None``
+ :param origin: If the name is relative and *origin* is not ``None``,
+ then *origin* will be appended to it.
+ :type origin: :py:class:`dns.name.Name` or ``None``
+ :param bool canonicalize: Whether the name should be canonicalized;
+ that is, converted to a format suitable for digesting in hashes.
+ :raises dns.name.NeedAbsoluteNameOrOrigin: if the name is relative
+ and no origin was provided.
+ :returns: ``None`` if *file* is provided, otherwise the wire format
+ as ``bytes``.
+ :rtype: bytes or ``None``
"""
if file is None:
def __len__(self) -> int:
"""The length of the name (in labels).
- Returns an ``int``.
+ :rtype: int
"""
return len(self.labels)
def split(self, depth: int) -> tuple["Name", "Name"]:
"""Split a name into a prefix and suffix names at the specified depth.
- *depth* is an ``int`` specifying the number of labels in the suffix
-
- Raises ``ValueError`` if *depth* was not >= 0 and <= the length of the
- name.
-
- Returns the tuple ``(prefix, suffix)``.
+ :param int depth: The number of labels in the suffix.
+ :raises ValueError: if *depth* is not >= 0 and <= the length of the
+ name.
+ :returns: A ``(prefix, suffix)`` tuple.
+ :rtype: tuple[:py:class:`dns.name.Name`, :py:class:`dns.name.Name`]
"""
l = len(self.labels)
def concatenate(self, other: "Name") -> "Name":
"""Return a new name which is the concatenation of self and other.
- Raises ``dns.name.AbsoluteConcatenation`` if the name is
- absolute and *other* is not the empty name.
-
- Returns a ``dns.name.Name``.
+ :param other: The name to concatenate.
+ :type other: :py:class:`dns.name.Name`
+ :raises dns.name.AbsoluteConcatenation: if the name is absolute and
+ *other* is not the empty name.
+ :rtype: :py:class:`dns.name.Name`
"""
if self.is_absolute() and len(other) > 0:
``dnspython.org.`` returns the name ``www``. Relativizing ``example.``
to origin ``dnspython.org.`` returns ``example.``.
- Returns a ``dns.name.Name``.
+ :param origin: The origin to relativize against.
+ :type origin: :py:class:`dns.name.Name`
+ :rtype: :py:class:`dns.name.Name`
"""
if self.is_subdomain(origin):
returns the name ``www.dnspython.org.``. Derelativizing ``example.``
to origin ``dnspython.org.`` returns ``example.``.
- Returns a ``dns.name.Name``.
+ :param origin: The origin to append.
+ :type origin: :py:class:`dns.name.Name`
+ :rtype: :py:class:`dns.name.Name`
"""
if not self.is_absolute():
relativized, and if *relativize* is ``False`` the name is
derelativized.
- Returns a ``dns.name.Name``.
+ :param origin: If not ``None``, controls relativization.
+ :type origin: :py:class:`dns.name.Name` or ``None``
+ :param bool relativize: If ``True``, relativize; if ``False``,
+ derelativize.
+ :rtype: :py:class:`dns.name.Name`
"""
if origin:
def parent(self) -> "Name":
"""Return the parent of the name.
- For example, the parent of ``www.dnspython.org.`` is ``dnspython.org``.
-
- Raises ``dns.name.NoParent`` if the name is either the root name or the
- empty name, and thus has no parent.
+ For example, the parent of ``www.dnspython.org.`` is ``dnspython.org.``.
- Returns a ``dns.name.Name``.
+ :raises dns.name.NoParent: if the name is either the root name or the
+ empty name, and thus has no parent.
+ :rtype: :py:class:`dns.name.Name`
"""
if self == root or self == empty:
return Name(self.labels[1:])
def predecessor(self, origin: "Name", prefix_ok: bool = True) -> "Name":
- """Return the maximal predecessor of *name* in the DNSSEC ordering in the zone
- whose origin is *origin*, or return the longest name under *origin* if the
- name is origin (i.e. wrap around to the longest name, which may still be
- *origin* due to length considerations.
+ """Return the maximal predecessor of the name in the DNSSEC ordering.
+
+ Returns the maximal predecessor in the zone whose origin is *origin*,
+ or returns the longest name under *origin* if the name is *origin*
+ (i.e. wraps around to the longest name, which may still be *origin*
+ due to length considerations).
The relativity of the name is preserved, so if this name is relative
then the method will return a relative name, and likewise if this name
is absolute then the predecessor will be absolute.
- *prefix_ok* indicates if prefixing labels is allowed, and
- defaults to ``True``. Normally it is good to allow this, but if computing
- a maximal predecessor at a zone cut point then ``False`` must be specified.
+ :param origin: The zone origin.
+ :type origin: :py:class:`dns.name.Name`
+ :param bool prefix_ok: If ``True`` (the default), prefixing labels is
+ allowed. Specify ``False`` when computing a maximal predecessor
+ at a zone cut point.
+ :rtype: :py:class:`dns.name.Name`
"""
return _handle_relativity_and_call(
_absolute_predecessor, self, origin, prefix_ok
)
def successor(self, origin: "Name", prefix_ok: bool = True) -> "Name":
- """Return the minimal successor of *name* in the DNSSEC ordering in the zone
- whose origin is *origin*, or return *origin* if the successor cannot be
- computed due to name length limitations.
+ """Return the minimal successor of the name in the DNSSEC ordering.
+
+ Returns the minimal successor in the zone whose origin is *origin*,
+ or returns *origin* if the successor cannot be computed due to name
+ length limitations.
Note that *origin* is returned in the "too long" cases because wrapping
around to the origin is how NSEC records express "end of the zone".
then the method will return a relative name, and likewise if this name
is absolute then the successor will be absolute.
- *prefix_ok* indicates if prefixing a new minimal label is allowed, and
- defaults to ``True``. Normally it is good to allow this, but if computing
- a minimal successor at a zone cut point then ``False`` must be specified.
+ :param origin: The zone origin.
+ :type origin: :py:class:`dns.name.Name`
+ :param bool prefix_ok: If ``True`` (the default), prefixing a new
+ minimal label is allowed. Specify ``False`` when computing a
+ minimal successor at a zone cut point.
+ :rtype: :py:class:`dns.name.Name`
"""
return _handle_relativity_and_call(_absolute_successor, self, origin, prefix_ok)
def from_unicode(
text: str, origin: Name | None = root, idna_codec: IDNACodec | None = None
) -> Name:
- """Convert unicode text into a Name object.
+ """Convert unicode text into a :py:class:`dns.name.Name` object.
Labels are encoded in IDN ACE form according to rules specified by
the IDNA codec.
- *text*, a ``str``, is the text to convert into a name.
-
- *origin*, a ``dns.name.Name``, specifies the origin to
- append to non-absolute names. The default is the root name.
-
- *idna_codec*, a ``dns.name.IDNACodec``, specifies the IDNA
- encoder/decoder. If ``None``, the default IDNA encoder/decoder
- is used.
-
- Returns a ``dns.name.Name``.
+ :param str text: The text to convert into a name.
+ :param origin: The origin to append to non-absolute names. The
+ default is the root name.
+ :type origin: :py:class:`dns.name.Name` or ``None``
+ :param idna_codec: The IDNA encoder/decoder. If ``None``, the default
+ IDNA encoder/decoder is used.
+ :type idna_codec: :py:class:`dns.name.IDNACodec` or ``None``
+ :rtype: :py:class:`dns.name.Name`
"""
labels = []
origin: Name | None = root,
idna_codec: IDNACodec | None = None,
) -> Name:
- """Convert text into a Name object.
-
- *text*, a ``bytes`` or ``str``, is the text to convert into a name.
-
- *origin*, a ``dns.name.Name``, specifies the origin to
- append to non-absolute names. The default is the root name.
-
- *idna_codec*, a ``dns.name.IDNACodec``, specifies the IDNA
- encoder/decoder. If ``None``, the default IDNA encoder/decoder
- is used.
-
- Returns a ``dns.name.Name``.
+ """Convert text into a :py:class:`dns.name.Name` object.
+
+ :param text: The text to convert into a name.
+ :type text: bytes or str
+ :param origin: The origin to append to non-absolute names. The
+ default is the root name.
+ :type origin: :py:class:`dns.name.Name` or ``None``
+ :param idna_codec: The IDNA encoder/decoder. If ``None``, the default
+ IDNA encoder/decoder is used.
+ :type idna_codec: :py:class:`dns.name.IDNACodec` or ``None``
+ :rtype: :py:class:`dns.name.Name`
"""
if isinstance(text, str):
def from_wire_parser(parser: dns.wirebase.Parser) -> Name:
- """Convert possibly compressed wire format into a Name.
-
- *parser* is a dns.wirebase.Parser.
-
- Raises ``dns.name.BadPointer`` if a compression pointer did not
- point backwards in the message.
-
- Raises ``dns.name.BadLabelType`` if an invalid label type was encountered.
-
- Returns a ``dns.name.Name``
+ """Convert possibly compressed wire format into a :py:class:`dns.name.Name`.
+
+ :param parser: The wire format parser.
+ :type parser: :py:class:`dns.wirebase.Parser`
+ :raises dns.name.BadPointer: if a compression pointer did not
+ point backwards in the message.
+ :raises dns.name.BadLabelType: if an invalid label type was encountered.
+ :rtype: :py:class:`dns.name.Name`
"""
labels = []
def from_wire(message: bytes, current: int) -> tuple[Name, int]:
- """Convert possibly compressed wire format into a Name.
-
- *message* is a ``bytes`` containing an entire DNS message in DNS
- wire form.
-
- *current*, an ``int``, is the offset of the beginning of the name
- from the start of the message
-
- Raises ``dns.name.BadPointer`` if a compression pointer did not
- point backwards in the message.
-
- Raises ``dns.name.BadLabelType`` if an invalid label type was encountered.
-
- Returns a ``(dns.name.Name, int)`` tuple consisting of the name
- that was read and the number of bytes of the wire format message
- which were consumed reading it.
+ """Convert possibly compressed wire format into a :py:class:`dns.name.Name`.
+
+ :param bytes message: A ``bytes`` containing an entire DNS message in DNS
+ wire form.
+ :param int current: The offset of the beginning of the name from the
+ start of the message.
+ :raises dns.name.BadPointer: if a compression pointer did not
+ point backwards in the message.
+ :raises dns.name.BadLabelType: if an invalid label type was encountered.
+ :returns: A tuple of the name that was read and the number of bytes of
+ the wire format message which were consumed reading it.
+ :rtype: tuple[:py:class:`dns.name.Name`, int]
"""
parser = dns.wirebase.Parser(message, current)
a superdomain of *name*. Note that *superdomain* includes matching
*name* itself.
- *name*, a ``dns.name.Name``, the name to find.
-
- Returns a ``(key, value)`` where *key* is the deepest
- ``dns.name.Name``, and *value* is the value associated with *key*.
+ :param name: The name to find.
+ :type name: :py:class:`dns.name.Name`
+ :returns: A ``(key, value)`` tuple where *key* is the deepest
+ matching :py:class:`dns.name.Name`.
"""
depth = len(name)
class NodeKind(enum.Enum):
"""Rdatasets in nodes"""
+ #: Has rdatasets not compatible with CNAME
REGULAR = 0 # a.k.a "other data"
+ #: Has rdatasets compatible with CNAME, but no CNAME
NEUTRAL = 1
+ #: Has a CNAME or RRSIG(CNAME)
CNAME = 2
@classmethod
Each rdataset at the node is printed. Any keyword arguments
to this method are passed on to the rdataset's to_text() method.
- *name*, a ``dns.name.Name``, the owner name of the
- rdatasets.
-
- *style*, a :py:class:`dns.node.NodeStyle` or ``None`` (the default). If
- specified, the style overrides the other parameters except *name*.
-
- Returns a ``str``.
+ :param name: The owner name of the rdatasets.
+ :type name: :py:class:`dns.name.Name`
+ :param style: If specified, overrides the other parameters except
+ *name*.
+ :type style: :py:class:`dns.node.NodeStyle` or ``None``
+ :rtype: str
"""
if style is None:
style = NodeStyle.from_keywords(kw)
Each rdataset at the node is printed.
- *name*, a ``dns.name.Name``, the owner name of the
- rdatasets.
+ :param name: The owner name of the rdatasets.
+ :type name: :py:class:`dns.name.Name`
See the documentation for :py:class:`dns.node.NodeStyle` for a description
of the style parameters.
- Returns a ``str``.
+ :rtype: str
"""
s = io.StringIO()
"""Find an rdataset matching the specified properties in the
current node.
- *rdclass*, a ``dns.rdataclass.RdataClass``, the class of the rdataset.
-
- *rdtype*, a ``dns.rdatatype.RdataType``, the type of the rdataset.
-
- *covers*, a ``dns.rdatatype.RdataType``, the covered type.
- Usually this value is ``dns.rdatatype.NONE``, but if the
- rdtype is ``dns.rdatatype.SIG`` or ``dns.rdatatype.RRSIG``,
- then the covers value will be the rdata type the SIG/RRSIG
- covers. The library treats the SIG and RRSIG types as if they
- were a family of types, e.g. RRSIG(A), RRSIG(NS), RRSIG(SOA).
- This makes RRSIGs much easier to work with than if RRSIGs
- covering different rdata types were aggregated into a single
- RRSIG rdataset.
-
- *create*, a ``bool``. If True, create the rdataset if it is not found.
-
- Raises ``KeyError`` if an rdataset of the desired type and class does
- not exist and *create* is not ``True``.
-
- Returns a ``dns.rdataset.Rdataset``.
+ :param rdclass: The class of the rdataset.
+ :type rdclass: :py:class:`dns.rdataclass.RdataClass`
+ :param rdtype: The type of the rdataset.
+ :type rdtype: :py:class:`dns.rdatatype.RdataType`
+ :param covers: The covered type. Usually ``dns.rdatatype.NONE``, but
+ for SIG/RRSIG the type being covered (e.g. A, NS, SOA).
+ :type covers: :py:class:`dns.rdatatype.RdataType`
+ :param create: If ``True``, create the rdataset if not found.
+ :type create: bool
+ :raises KeyError: If no matching rdataset exists and *create* is not
+ ``True``.
+ :rtype: :py:class:`dns.rdataset.Rdataset`
"""
for rds in self.rdatasets:
None is returned if an rdataset of the specified type and
class does not exist and *create* is not ``True``.
- *rdclass*, an ``int``, the class of the rdataset.
-
- *rdtype*, an ``int``, the type of the rdataset.
-
- *covers*, an ``int``, the covered type. Usually this value is
- dns.rdatatype.NONE, but if the rdtype is dns.rdatatype.SIG or
- dns.rdatatype.RRSIG, then the covers value will be the rdata
- type the SIG/RRSIG covers. The library treats the SIG and RRSIG
- types as if they were a family of
- types, e.g. RRSIG(A), RRSIG(NS), RRSIG(SOA). This makes RRSIGs much
- easier to work with than if RRSIGs covering different rdata
- types were aggregated into a single RRSIG rdataset.
-
- *create*, a ``bool``. If True, create the rdataset if it is not found.
-
- Returns a ``dns.rdataset.Rdataset`` or ``None``.
+ :param rdclass: The class of the rdataset.
+ :type rdclass: :py:class:`dns.rdataclass.RdataClass`
+ :param rdtype: The type of the rdataset.
+ :type rdtype: :py:class:`dns.rdatatype.RdataType`
+ :param covers: The covered type (usually ``dns.rdatatype.NONE``).
+ :type covers: :py:class:`dns.rdatatype.RdataType`
+ :param create: If ``True``, create the rdataset if not found.
+ :type create: bool
+ :rtype: :py:class:`dns.rdataset.Rdataset` or ``None``
"""
try:
If a matching rdataset does not exist, it is not an error.
- *rdclass*, an ``int``, the class of the rdataset.
-
- *rdtype*, an ``int``, the type of the rdataset.
-
- *covers*, an ``int``, the covered type.
+ :param rdclass: The class of the rdataset.
+ :type rdclass: :py:class:`dns.rdataclass.RdataClass`
+ :param rdtype: The type of the rdataset.
+ :type rdtype: :py:class:`dns.rdatatype.RdataType`
+ :param covers: The covered type.
+ :type covers: :py:class:`dns.rdatatype.RdataType`
"""
rds = self.get_rdataset(rdclass, rdtype, covers)
in other words, this method does not store a copy of *replacement*
at the node, it stores *replacement* itself.
- *replacement*, a ``dns.rdataset.Rdataset``.
-
- Raises ``ValueError`` if *replacement* is not a
- ``dns.rdataset.Rdataset``.
+ :param replacement: The replacement rdataset.
+ :type replacement: :py:class:`dns.rdataset.Rdataset`
+ :raises ValueError: If *replacement* is not a
+ :py:class:`dns.rdataset.Rdataset`.
"""
if not isinstance(replacement, dns.rdataset.Rdataset):
def from_text(text: str) -> Opcode:
"""Convert text into an opcode.
- *text*, a ``str``, the textual opcode
-
- Raises ``dns.opcode.UnknownOpcode`` if the opcode is unknown.
-
- Returns an ``int``.
+ :param text: The textual opcode.
+ :type text: str
+ :raises dns.opcode.UnknownOpcode: If the opcode is unknown.
+ :rtype: :py:class:`dns.opcode.Opcode`
"""
return Opcode.from_text(text)
def from_flags(flags: int) -> Opcode:
"""Extract an opcode from DNS message flags.
- *flags*, an ``int``, the DNS flags.
-
- Returns an ``int``.
+ :param flags: The DNS message flags.
+ :type flags: int
+ :rtype: :py:class:`dns.opcode.Opcode`
"""
return Opcode((flags & 0x7800) >> 11)
"""Convert an opcode to a value suitable for ORing into DNS message
flags.
- *value*, an ``int``, the DNS opcode value.
-
- Returns an ``int``.
+ :param value: The DNS opcode value.
+ :type value: :py:class:`dns.opcode.Opcode`
+ :rtype: int
"""
return (value << 11) & 0x7800
def to_text(value: Opcode) -> str:
"""Convert an opcode to text.
- *value*, an ``int`` the opcode value,
-
- Raises ``dns.opcode.UnknownOpcode`` if the opcode is unknown.
-
- Returns a ``str``.
+ :param value: The opcode value.
+ :type value: :py:class:`dns.opcode.Opcode`
+ :raises dns.opcode.UnknownOpcode: If the opcode is unknown.
+ :rtype: str
"""
return Opcode.to_text(value)
def is_update(flags: int) -> bool:
"""Is the opcode in flags UPDATE?
- *flags*, an ``int``, the DNS message flags.
-
- Returns a ``bool``.
+ :param flags: The DNS message flags.
+ :type flags: int
+ :rtype: bool
"""
return from_flags(flags) == Opcode.UPDATE
type: socket.SocketKind,
source: Any | None = None,
) -> socket.socket:
- """Make a socket.
-
- This function uses the module's ``socket_factory`` to make a socket of the
- specified address family and type.
-
- *af*, a ``socket.AddressFamily`` or ``int`` is the address family, either
- ``socket.AF_INET`` or ``socket.AF_INET6``.
-
- *type*, a ``socket.SocketKind`` is the type of socket, e.g. ``socket.SOCK_DGRAM``,
- a datagram socket, or ``socket.SOCK_STREAM``, a stream socket. Note that the
- ``proto`` attribute of a socket is always zero with this API, so a datagram socket
- will always be a UDP socket, and a stream socket will always be a TCP socket.
-
- *source* is the source address and port to bind to, if any. The default is
- ``None`` which will bind to the wildcard address and a randomly chosen port.
- If not ``None``, it should be a (low-level) address tuple appropriate for *af*.
+ """Make a socket using the module's ``socket_factory``.
+
+ :param af: Address family: ``socket.AF_INET`` or ``socket.AF_INET6``.
+ :type af: ``socket.AddressFamily`` or int
+ :param type: Socket type, e.g. ``socket.SOCK_DGRAM`` or
+ ``socket.SOCK_STREAM``. The ``proto`` is always 0, so datagram
+ sockets are UDP and stream sockets are TCP.
+ :type type: ``socket.SocketKind``
+ :param source: Source address/port tuple to bind to, or ``None`` (bind
+ to wildcard address and random port).
"""
s = socket_factory(af, type, 0)
try:
server_hostname: dns.name.Name | str | None = None,
source: Any | None = None,
) -> ssl.SSLSocket:
- """Make a socket.
-
- This function uses the module's ``socket_factory`` to make a socket of the
- specified address family and type.
-
- *af*, a ``socket.AddressFamily`` or ``int`` is the address family, either
- ``socket.AF_INET`` or ``socket.AF_INET6``.
-
- *type*, a ``socket.SocketKind`` is the type of socket, e.g. ``socket.SOCK_DGRAM``,
- a datagram socket, or ``socket.SOCK_STREAM``, a stream socket. Note that the
- ``proto`` attribute of a socket is always zero with this API, so a datagram socket
- will always be a UDP socket, and a stream socket will always be a TCP socket.
-
- If *ssl_context* is not ``None``, then it specifies the SSL context to use,
- typically created with ``make_ssl_context()``.
-
- If *server_hostname* is not ``None``, then it is the hostname to use for server
- certificate validation. A valid hostname must be supplied if *ssl_context*
- requires hostname checking.
-
- *source* is the source address and port to bind to, if any. The default is
- ``None`` which will bind to the wildcard address and a randomly chosen port.
- If not ``None``, it should be a (low-level) address tuple appropriate for *af*.
+ """Make an SSL socket using the module's ``socket_factory``.
+
+ :param af: Address family: ``socket.AF_INET`` or ``socket.AF_INET6``.
+ :type af: ``socket.AddressFamily`` or int
+ :param type: Socket type, e.g. ``socket.SOCK_DGRAM`` or
+ ``socket.SOCK_STREAM``.
+ :type type: ``socket.SocketKind``
+ :param ssl_context: The SSL context to use, typically created with
+ :py:func:`make_ssl_context`.
+ :type ssl_context: ``ssl.SSLContext``
+ :param server_hostname: The hostname for server certificate validation,
+ or ``None``. Required when *ssl_context* uses hostname checking.
+ :type server_hostname: :py:class:`dns.name.Name` or str or ``None``
+ :param source: Source address/port tuple to bind to, or ``None`` (bind
+ to wildcard address and random port).
"""
sock = make_socket(af, type, source)
if isinstance(server_hostname, dns.name.Name):
) -> dns.message.Message:
"""Return the response obtained after sending a query via DNS-over-HTTPS.
- *q*, a ``dns.message.Message``, the query to send.
-
- *where*, a ``str``, the nameserver IP address or the full URL. If an IP address is
- given, the URL will be constructed using the following schema:
- https://<IP-address>:<port>/<path>.
-
- *timeout*, a ``float`` or ``None``, the number of seconds to wait before the query
- times out. If ``None``, the default, wait forever.
-
- *port*, a ``int``, the port to send the query to. The default is 443.
-
- *source*, a ``str`` containing an IPv4 or IPv6 address, specifying the source
- address. The default is the wildcard address.
-
- *source_port*, an ``int``, the port from which to send the message. The default is
- 0.
-
- *one_rr_per_rrset*, a ``bool``. If ``True``, put each RR into its own RRset.
-
- *ignore_trailing*, a ``bool``. If ``True``, ignore trailing junk at end of the
- received message.
-
- *session*, an ``httpx.Client``. If provided, the client session to use to send the
- queries.
-
- *path*, a ``str``. If *where* is an IP address, then *path* will be used to
- construct the URL to send the DNS query to.
-
- *post*, a ``bool``. If ``True``, the default, POST method will be used.
-
- *bootstrap_address*, a ``str``, the IP address to use to bypass resolution.
-
- *verify*, a ``bool`` or ``str``. If a ``True``, then TLS certificate verification
- of the server is done using the default CA bundle; if ``False``, then no
- verification is done; if a `str` then it specifies the path to a certificate file or
- directory which will be used for verification.
-
- *resolver*, a ``dns.resolver.Resolver`` or ``None``, the resolver to use for
- resolution of hostnames in URLs. If not specified, a new resolver with a default
- configuration will be used; note this is *not* the default resolver as that resolver
- might have been configured to use DoH causing a chicken-and-egg problem. This
- parameter only has an effect if the HTTP library is httpx.
-
- *family*, an ``int``, the address family. If socket.AF_UNSPEC (the default), both A
- and AAAA records will be retrieved.
-
- *http_version*, a ``dns.query.HTTPVersion``, indicating which HTTP version to use.
-
- Returns a ``dns.message.Message``.
+ :param q: The query to send.
+ :type q: :py:class:`dns.message.Message`
+ :param where: The nameserver IP address or full URL. If an IP address is
+ given, the URL is constructed as
+ ``https://<IP-address>:<port>/<path>``.
+ :type where: str
+ :param timeout: Seconds to wait before timing out. ``None`` means wait
+ forever.
+ :type timeout: float or ``None``
+ :param port: The port to send the query to. Default is 443.
+ :type port: int
+ :param source: Source IPv4 or IPv6 address. Default is the wildcard
+ address.
+ :type source: str or ``None``
+ :param source_port: The port from which to send the message. Default is
+ 0.
+ :type source_port: int
+ :param one_rr_per_rrset: If ``True``, put each RR into its own RRset.
+ :type one_rr_per_rrset: bool
+ :param ignore_trailing: If ``True``, ignore trailing junk at end of the
+ received message.
+ :type ignore_trailing: bool
+ :param session: If provided, the client session to use to send the
+ queries.
+ :type session: ``httpx.Client`` or ``None``
+ :param path: If *where* is an IP address, *path* is used to construct the
+ query URL.
+ :type path: str
+ :param post: If ``True`` (the default), use the POST method.
+ :type post: bool
+ :param bootstrap_address: The IP address to use to bypass resolution.
+ :type bootstrap_address: str or ``None``
+ :param verify: If ``True``, verify the TLS certificate using default CA
+ roots; if ``False``, disable verification; if a ``str``, path to a
+ certificate file or directory.
+ :type verify: bool or str
+ :param resolver: Resolver to use for hostname resolution in URLs. If
+ ``None``, a new resolver with default configuration is used (not the
+ default resolver, to avoid a DoH chicken-and-egg problem). Only
+ effective when using httpx.
+ :type resolver: :py:class:`dns.resolver.Resolver` or ``None``
+ :param family: Address family. ``socket.AF_UNSPEC`` (the default)
+ retrieves both A and AAAA records.
+ :type family: int
+ :param http_version: Which HTTP version to use.
+ :type http_version: :py:class:`dns.query.HTTPVersion`
+ :rtype: :py:class:`dns.message.Message`
"""
af, _, the_source = _destination_and_source(where, port, source, source_port, False)
) -> tuple[int, float]:
"""Send a DNS message to the specified UDP socket.
- *sock*, a ``socket``.
-
- *what*, a ``bytes`` or ``dns.message.Message``, the message to send.
-
- *destination*, a destination tuple appropriate for the address family
- of the socket, specifying where to send the query.
-
- *expiration*, a ``float`` or ``None``, the absolute time at which
- a timeout exception should be raised. If ``None``, no timeout will
- occur.
-
- Returns an ``(int, float)`` tuple of bytes sent and the sent time.
+ :param sock: The socket to use.
+ :type sock: socket
+ :param what: The message to send.
+ :type what: bytes or :py:class:`dns.message.Message`
+ :param destination: A destination tuple appropriate for the address family
+ of the socket.
+ :param expiration: The absolute time at which to raise a timeout
+ exception. ``None`` means no timeout.
+ :type expiration: float or ``None``
+ :returns: A ``(bytes_sent, sent_time)`` tuple.
+ :rtype: tuple[int, float]
"""
if isinstance(what, dns.message.Message):
) -> Any:
"""Read a DNS message from a UDP socket.
- *sock*, a ``socket``.
-
- *destination*, a destination tuple appropriate for the address family
- of the socket, specifying where the message is expected to arrive from.
- When receiving a response, this would be where the associated query was
- sent.
-
- *expiration*, a ``float`` or ``None``, the absolute time at which
- a timeout exception should be raised. If ``None``, no timeout will
- occur.
-
- *ignore_unexpected*, a ``bool``. If ``True``, ignore responses from
- unexpected sources.
-
- *one_rr_per_rrset*, a ``bool``. If ``True``, put each RR into its own
- RRset.
-
- *keyring*, a ``dict``, the keyring to use for TSIG.
-
- *request_mac*, a ``bytes`` or ``None``, the MAC of the request (for TSIG).
-
- *ignore_trailing*, a ``bool``. If ``True``, ignore trailing
- junk at end of the received message.
-
- *raise_on_truncation*, a ``bool``. If ``True``, raise an exception if
- the TC bit is set.
-
Raises if the message is malformed, if network errors occur, of if
there is a timeout.
- If *destination* is not ``None``, returns a ``(dns.message.Message, float)``
- tuple of the received message and the received time.
-
- If *destination* is ``None``, returns a
- ``(dns.message.Message, float, tuple)``
- tuple of the received message, the received time, and the address where
- the message arrived from.
-
- *ignore_errors*, a ``bool``. If various format errors or response
- mismatches occur, ignore them and keep listening for a valid response.
- The default is ``False``.
-
- *query*, a ``dns.message.Message`` or ``None``. If not ``None`` and
- *ignore_errors* is ``True``, check that the received message is a response
- to this query, and if not keep listening for a valid response.
+ :param sock: The socket to read from.
+ :type sock: socket
+ :param destination: Destination tuple indicating where the message is
+ expected to arrive from (where the associated query was sent).
+ ``None`` means accept from any source.
+ :param expiration: The absolute time at which to raise a timeout
+ exception. ``None`` means no timeout.
+ :type expiration: float or ``None``
+ :param ignore_unexpected: If ``True``, ignore responses from unexpected
+ sources.
+ :type ignore_unexpected: bool
+ :param one_rr_per_rrset: If ``True``, put each RR into its own RRset.
+ :type one_rr_per_rrset: bool
+ :param keyring: The keyring to use for TSIG.
+ :type keyring: dict or ``None``
+ :param request_mac: The MAC of the request (for TSIG).
+ :type request_mac: bytes or ``None``
+ :param ignore_trailing: If ``True``, ignore trailing junk at end of the
+ received message.
+ :type ignore_trailing: bool
+ :param raise_on_truncation: If ``True``, raise an exception if the TC
+ bit is set.
+ :type raise_on_truncation: bool
+ :param ignore_errors: If ``True``, ignore format errors or response
+ mismatches and keep listening for a valid response.
+ :type ignore_errors: bool
+ :param query: If not ``None`` and *ignore_errors* is ``True``, verify
+ the received message is a response to this query.
+ :type query: :py:class:`dns.message.Message` or ``None``
+ :returns: If *destination* is not ``None``, a
+ ``(message, received_time)`` tuple; otherwise a
+ ``(message, received_time, from_address)`` tuple.
+ :rtype: tuple
"""
wire = b""
) -> dns.message.Message:
"""Return the response obtained after sending a query via UDP.
- *q*, a ``dns.message.Message``, the query to send
-
- *where*, a ``str`` containing an IPv4 or IPv6 address, where
- to send the message.
-
- *timeout*, a ``float`` or ``None``, the number of seconds to wait before the
- query times out. If ``None``, the default, wait forever.
-
- *port*, an ``int``, the port send the message to. The default is 53.
-
- *source*, a ``str`` containing an IPv4 or IPv6 address, specifying
- the source address. The default is the wildcard address.
-
- *source_port*, an ``int``, the port from which to send the message.
- The default is 0.
-
- *ignore_unexpected*, a ``bool``. If ``True``, ignore responses from
- unexpected sources.
-
- *one_rr_per_rrset*, a ``bool``. If ``True``, put each RR into its own
- RRset.
-
- *ignore_trailing*, a ``bool``. If ``True``, ignore trailing
- junk at end of the received message.
-
- *raise_on_truncation*, a ``bool``. If ``True``, raise an exception if
- the TC bit is set.
-
- *sock*, a ``socket.socket``, or ``None``, the socket to use for the
- query. If ``None``, the default, a socket is created. Note that
- if a socket is provided, it must be a nonblocking datagram socket,
- and the *source* and *source_port* are ignored.
-
- *ignore_errors*, a ``bool``. If various format errors or response
- mismatches occur, ignore them and keep listening for a valid response.
- The default is ``False``.
-
- Returns a ``dns.message.Message``.
+ :param q: The query to send.
+ :type q: :py:class:`dns.message.Message`
+ :param where: IPv4 or IPv6 address of the nameserver.
+ :type where: str
+ :param timeout: Seconds to wait before timing out. ``None`` means wait
+ forever.
+ :type timeout: float or ``None``
+ :param port: The port to send the message to. Default is 53.
+ :type port: int
+ :param source: Source IPv4 or IPv6 address. Default is the wildcard
+ address.
+ :type source: str or ``None``
+ :param source_port: The port from which to send the message. Default
+ is 0.
+ :type source_port: int
+ :param ignore_unexpected: If ``True``, ignore responses from unexpected
+ sources.
+ :type ignore_unexpected: bool
+ :param one_rr_per_rrset: If ``True``, put each RR into its own RRset.
+ :type one_rr_per_rrset: bool
+ :param ignore_trailing: If ``True``, ignore trailing junk at end of the
+ received message.
+ :type ignore_trailing: bool
+ :param raise_on_truncation: If ``True``, raise an exception if the TC
+ bit is set.
+ :type raise_on_truncation: bool
+ :param sock: The socket to use. If ``None`` (the default), a socket is
+ created. If provided, must be a nonblocking datagram socket; *source*
+ and *source_port* are ignored.
+ :type sock: ``socket.socket`` or ``None``
+ :param ignore_errors: If ``True``, ignore format errors or response
+ mismatches and keep listening for a valid response.
+ :type ignore_errors: bool
+ :rtype: :py:class:`dns.message.Message`
"""
wire = q.to_wire()
"""Return the response to the query, trying UDP first and falling back
to TCP if UDP results in a truncated response.
- *q*, a ``dns.message.Message``, the query to send
-
- *where*, a ``str`` containing an IPv4 or IPv6 address, where to send the message.
-
- *timeout*, a ``float`` or ``None``, the number of seconds to wait before the query
- times out. If ``None``, the default, wait forever.
-
- *port*, an ``int``, the port send the message to. The default is 53.
-
- *source*, a ``str`` containing an IPv4 or IPv6 address, specifying the source
- address. The default is the wildcard address.
-
- *source_port*, an ``int``, the port from which to send the message. The default is
- 0.
-
- *ignore_unexpected*, a ``bool``. If ``True``, ignore responses from unexpected
- sources.
-
- *one_rr_per_rrset*, a ``bool``. If ``True``, put each RR into its own RRset.
-
- *ignore_trailing*, a ``bool``. If ``True``, ignore trailing junk at end of the
- received message.
-
- *udp_sock*, a ``socket.socket``, or ``None``, the socket to use for the UDP query.
- If ``None``, the default, a socket is created. Note that if a socket is provided,
- it must be a nonblocking datagram socket, and the *source* and *source_port* are
- ignored for the UDP query.
-
- *tcp_sock*, a ``socket.socket``, or ``None``, the connected socket to use for the
- TCP query. If ``None``, the default, a socket is created. Note that if a socket is
- provided, it must be a nonblocking connected stream socket, and *where*, *source*
- and *source_port* are ignored for the TCP query.
-
- *ignore_errors*, a ``bool``. If various format errors or response mismatches occur
- while listening for UDP, ignore them and keep listening for a valid response. The
- default is ``False``.
-
- Returns a (``dns.message.Message``, tcp) tuple where tcp is ``True`` if and only if
- TCP was used.
+ :param q: The query to send.
+ :type q: :py:class:`dns.message.Message`
+ :param where: IPv4 or IPv6 address of the nameserver.
+ :type where: str
+ :param timeout: Seconds to wait before timing out. ``None`` means wait
+ forever.
+ :type timeout: float or ``None``
+ :param port: The port to send the message to. Default is 53.
+ :type port: int
+ :param source: Source IPv4 or IPv6 address. Default is the wildcard
+ address.
+ :type source: str or ``None``
+ :param source_port: The port from which to send the message. Default
+ is 0.
+ :type source_port: int
+ :param ignore_unexpected: If ``True``, ignore responses from unexpected
+ sources.
+ :type ignore_unexpected: bool
+ :param one_rr_per_rrset: If ``True``, put each RR into its own RRset.
+ :type one_rr_per_rrset: bool
+ :param ignore_trailing: If ``True``, ignore trailing junk at end of the
+ received message.
+ :type ignore_trailing: bool
+ :param udp_sock: The socket to use for the UDP query. If ``None``
+ (the default), a socket is created. If provided, must be a
+ nonblocking datagram socket; *source* and *source_port* are ignored.
+ :type udp_sock: ``socket.socket`` or ``None``
+ :param tcp_sock: The connected socket to use for the TCP query. If
+ ``None`` (the default), a socket is created. If provided, must be a
+ nonblocking connected stream socket; *where*, *source* and
+ *source_port* are ignored.
+ :type tcp_sock: ``socket.socket`` or ``None``
+ :param ignore_errors: If ``True``, ignore UDP format errors or response
+ mismatches and keep listening for a valid response.
+ :type ignore_errors: bool
+ :returns: A ``(message, used_tcp)`` tuple; *used_tcp* is ``True`` if and
+ only if TCP was used.
+ :rtype: tuple[:py:class:`dns.message.Message`, bool]
"""
try:
response = udp(
) -> tuple[int, float]:
"""Send a DNS message to the specified TCP socket.
- *sock*, a ``socket``.
-
- *what*, a ``bytes`` or ``dns.message.Message``, the message to send.
-
- *expiration*, a ``float`` or ``None``, the absolute time at which
- a timeout exception should be raised. If ``None``, no timeout will
- occur.
-
- Returns an ``(int, float)`` tuple of bytes sent and the sent time.
+ :param sock: The socket to use.
+ :type sock: socket
+ :param what: The message to send.
+ :type what: bytes or :py:class:`dns.message.Message`
+ :param expiration: The absolute time at which to raise a timeout
+ exception. ``None`` means no timeout.
+ :type expiration: float or ``None``
+ :returns: A ``(bytes_sent, sent_time)`` tuple.
+ :rtype: tuple[int, float]
"""
if isinstance(what, dns.message.Message):
) -> tuple[dns.message.Message, float]:
"""Read a DNS message from a TCP socket.
- *sock*, a ``socket``.
-
- *expiration*, a ``float`` or ``None``, the absolute time at which
- a timeout exception should be raised. If ``None``, no timeout will
- occur.
-
- *one_rr_per_rrset*, a ``bool``. If ``True``, put each RR into its own
- RRset.
-
- *keyring*, a ``dict``, the keyring to use for TSIG.
-
- *request_mac*, a ``bytes`` or ``None``, the MAC of the request (for TSIG).
-
- *ignore_trailing*, a ``bool``. If ``True``, ignore trailing
- junk at end of the received message.
-
- Raises if the message is malformed, if network errors occur, of if
- there is a timeout.
-
- Returns a ``(dns.message.Message, float)`` tuple of the received message
- and the received time.
+ :param sock: The socket to read from.
+ :type sock: socket
+ :param expiration: The absolute time at which to raise a timeout
+ exception. ``None`` means no timeout.
+ :type expiration: float or ``None``
+ :param one_rr_per_rrset: If ``True``, put each RR into its own RRset.
+ :type one_rr_per_rrset: bool
+ :param keyring: The keyring to use for TSIG.
+ :type keyring: dict or ``None``
+ :param request_mac: The MAC of the request (for TSIG).
+ :type request_mac: bytes or ``None``
+ :param ignore_trailing: If ``True``, ignore trailing junk at end of the
+ received message.
+ :type ignore_trailing: bool
+ :returns: A ``(message, received_time)`` tuple.
+ :rtype: tuple[:py:class:`dns.message.Message`, float]
"""
ldata = _net_read(sock, 2, expiration)
) -> dns.message.Message:
"""Return the response obtained after sending a query via TCP.
- *q*, a ``dns.message.Message``, the query to send
-
- *where*, a ``str`` containing an IPv4 or IPv6 address, where
- to send the message.
-
- *timeout*, a ``float`` or ``None``, the number of seconds to wait before the
- query times out. If ``None``, the default, wait forever.
-
- *port*, an ``int``, the port send the message to. The default is 53.
-
- *source*, a ``str`` containing an IPv4 or IPv6 address, specifying
- the source address. The default is the wildcard address.
-
- *source_port*, an ``int``, the port from which to send the message.
- The default is 0.
-
- *one_rr_per_rrset*, a ``bool``. If ``True``, put each RR into its own
- RRset.
-
- *ignore_trailing*, a ``bool``. If ``True``, ignore trailing
- junk at end of the received message.
-
- *sock*, a ``socket.socket``, or ``None``, the connected socket to use for the
- query. If ``None``, the default, a socket is created. Note that
- if a socket is provided, it must be a nonblocking connected stream
- socket, and *where*, *port*, *source* and *source_port* are ignored.
-
- Returns a ``dns.message.Message``.
+ :param q: The query to send.
+ :type q: :py:class:`dns.message.Message`
+ :param where: IPv4 or IPv6 address of the nameserver.
+ :type where: str
+ :param timeout: Seconds to wait before timing out. ``None`` means wait
+ forever.
+ :type timeout: float or ``None``
+ :param port: The port to send the message to. Default is 53.
+ :type port: int
+ :param source: Source IPv4 or IPv6 address. Default is the wildcard
+ address.
+ :type source: str or ``None``
+ :param source_port: The port from which to send the message. Default
+ is 0.
+ :type source_port: int
+ :param one_rr_per_rrset: If ``True``, put each RR into its own RRset.
+ :type one_rr_per_rrset: bool
+ :param ignore_trailing: If ``True``, ignore trailing junk at end of the
+ received message.
+ :type ignore_trailing: bool
+ :param sock: The connected socket to use. If ``None`` (the default), a
+ socket is created. If provided, must be a nonblocking connected
+ stream socket; *where*, *port*, *source* and *source_port* are
+ ignored.
+ :type sock: ``socket.socket`` or ``None``
+ :rtype: :py:class:`dns.message.Message`
"""
wire = q.to_wire()
) -> dns.message.Message:
"""Return the response obtained after sending a query via TLS.
- *q*, a ``dns.message.Message``, the query to send
-
- *where*, a ``str`` containing an IPv4 or IPv6 address, where
- to send the message.
-
- *timeout*, a ``float`` or ``None``, the number of seconds to wait before the
- query times out. If ``None``, the default, wait forever.
-
- *port*, an ``int``, the port send the message to. The default is 853.
-
- *source*, a ``str`` containing an IPv4 or IPv6 address, specifying
- the source address. The default is the wildcard address.
-
- *source_port*, an ``int``, the port from which to send the message.
- The default is 0.
-
- *one_rr_per_rrset*, a ``bool``. If ``True``, put each RR into its own
- RRset.
-
- *ignore_trailing*, a ``bool``. If ``True``, ignore trailing
- junk at end of the received message.
-
- *sock*, an ``ssl.SSLSocket``, or ``None``, the socket to use for
- the query. If ``None``, the default, a socket is created. Note
- that if a socket is provided, it must be a nonblocking connected
- SSL stream socket, and *where*, *port*, *source*, *source_port*,
- and *ssl_context* are ignored.
-
- *ssl_context*, an ``ssl.SSLContext``, the context to use when establishing
- a TLS connection. If ``None``, the default, creates one with the default
- configuration.
-
- *server_hostname*, a ``str`` containing the server's hostname. The
- default is ``None``, which means that no hostname is known, and if an
- SSL context is created, hostname checking will be disabled.
-
- *verify*, a ``bool`` or ``str``. If a ``True``, then TLS certificate verification
- of the server is done using the default CA bundle; if ``False``, then no
- verification is done; if a `str` then it specifies the path to a certificate file or
- directory which will be used for verification.
-
- Returns a ``dns.message.Message``.
-
+ :param q: The query to send.
+ :type q: :py:class:`dns.message.Message`
+ :param where: IPv4 or IPv6 address of the nameserver.
+ :type where: str
+ :param timeout: Seconds to wait before timing out. ``None`` means wait
+ forever.
+ :type timeout: float or ``None``
+ :param port: The port to send the message to. Default is 853.
+ :type port: int
+ :param source: Source IPv4 or IPv6 address. Default is the wildcard
+ address.
+ :type source: str or ``None``
+ :param source_port: The port from which to send the message. Default
+ is 0.
+ :type source_port: int
+ :param one_rr_per_rrset: If ``True``, put each RR into its own RRset.
+ :type one_rr_per_rrset: bool
+ :param ignore_trailing: If ``True``, ignore trailing junk at end of the
+ received message.
+ :type ignore_trailing: bool
+ :param sock: The SSL socket to use. If ``None`` (the default), a socket
+ is created. If provided, must be a nonblocking connected SSL stream
+ socket; *where*, *port*, *source*, *source_port*, and *ssl_context*
+ are ignored.
+ :type sock: ``ssl.SSLSocket`` or ``None``
+ :param ssl_context: The SSL context to use when establishing the TLS
+ connection. If ``None`` (the default), one is created with the
+ default configuration.
+ :type ssl_context: ``ssl.SSLContext`` or ``None``
+ :param server_hostname: The server's hostname, or ``None``. If ``None``
+ and an SSL context is created, hostname checking is disabled.
+ :type server_hostname: str or ``None``
+ :param verify: If ``True``, verify the TLS certificate using default CA
+ roots; if ``False``, disable verification; if a ``str``, path to a
+ certificate file or directory.
+ :type verify: bool or str
+ :rtype: :py:class:`dns.message.Message`
"""
if sock:
) -> dns.message.Message:
"""Return the response obtained after sending a query via DNS-over-QUIC.
- *q*, a ``dns.message.Message``, the query to send.
-
- *where*, a ``str``, the nameserver IP address.
-
- *timeout*, a ``float`` or ``None``, the number of seconds to wait before the query
- times out. If ``None``, the default, wait forever.
-
- *port*, a ``int``, the port to send the query to. The default is 853.
-
- *source*, a ``str`` containing an IPv4 or IPv6 address, specifying the source
- address. The default is the wildcard address.
-
- *source_port*, an ``int``, the port from which to send the message. The default is
- 0.
-
- *one_rr_per_rrset*, a ``bool``. If ``True``, put each RR into its own RRset.
-
- *ignore_trailing*, a ``bool``. If ``True``, ignore trailing junk at end of the
- received message.
-
- *connection*, a ``dns.quic.SyncQuicConnection``. If provided, the connection to use
- to send the query.
-
- *verify*, a ``bool`` or ``str``. If a ``True``, then TLS certificate verification
- of the server is done using the default CA bundle; if ``False``, then no
- verification is done; if a `str` then it specifies the path to a certificate file or
- directory which will be used for verification.
-
- *hostname*, a ``str`` containing the server's hostname or ``None``. The default is
- ``None``, which means that no hostname is known, and if an SSL context is created,
- hostname checking will be disabled. This value is ignored if *url* is not
- ``None``.
-
- *server_hostname*, a ``str`` or ``None``. This item is for backwards compatibility
- only, and has the same meaning as *hostname*.
-
- Returns a ``dns.message.Message``.
+ :param q: The query to send.
+ :type q: :py:class:`dns.message.Message`
+ :param where: The nameserver IP address.
+ :type where: str
+ :param timeout: Seconds to wait before timing out. ``None`` means wait
+ forever.
+ :type timeout: float or ``None``
+ :param port: The port to send the query to. Default is 853.
+ :type port: int
+ :param source: Source IPv4 or IPv6 address. Default is the wildcard
+ address.
+ :type source: str or ``None``
+ :param source_port: The port from which to send the message. Default
+ is 0.
+ :type source_port: int
+ :param one_rr_per_rrset: If ``True``, put each RR into its own RRset.
+ :type one_rr_per_rrset: bool
+ :param ignore_trailing: If ``True``, ignore trailing junk at end of the
+ received message.
+ :type ignore_trailing: bool
+ :param connection: If provided, the QUIC connection to use.
+ :type connection: :py:class:`dns.quic.SyncQuicConnection` or ``None``
+ :param verify: If ``True``, verify the TLS certificate using default CA
+ roots; if ``False``, disable verification; if a ``str``, path to a
+ certificate file or directory.
+ :type verify: bool or str
+ :param hostname: The server's hostname, or ``None``. If ``None`` and an
+ SSL context is created, hostname checking is disabled.
+ :type hostname: str or ``None``
+ :param server_hostname: Deprecated alias for *hostname*.
+ :type server_hostname: str or ``None``
+ :rtype: :py:class:`dns.message.Message`
"""
if not dns.quic.have_quic:
) -> Any:
"""Return a generator for the responses to a zone transfer.
- *where*, a ``str`` containing an IPv4 or IPv6 address, where
- to send the message.
-
- *zone*, a ``dns.name.Name`` or ``str``, the name of the zone to transfer.
-
- *rdtype*, an ``int`` or ``str``, the type of zone transfer. The
- default is ``dns.rdatatype.AXFR``. ``dns.rdatatype.IXFR`` can be
- used to do an incremental transfer instead.
-
- *rdclass*, an ``int`` or ``str``, the class of the zone transfer.
- The default is ``dns.rdataclass.IN``.
-
- *timeout*, a ``float``, the number of seconds to wait for each
- response message. If None, the default, wait forever.
-
- *port*, an ``int``, the port send the message to. The default is 53.
-
- *keyring*, a ``dict``, the keyring to use for TSIG.
-
- *keyname*, a ``dns.name.Name`` or ``str``, the name of the TSIG
- key to use.
-
- *relativize*, a ``bool``. If ``True``, all names in the zone will be
- relativized to the zone origin. It is essential that the
- relativize setting matches the one specified to
- ``dns.zone.from_xfr()`` if using this generator to make a zone.
-
- *lifetime*, a ``float``, the total number of seconds to spend
- doing the transfer. If ``None``, the default, then there is no
- limit on the time the transfer may take.
-
- *source*, a ``str`` containing an IPv4 or IPv6 address, specifying
- the source address. The default is the wildcard address.
-
- *source_port*, an ``int``, the port from which to send the message.
- The default is 0.
-
- *serial*, an ``int``, the SOA serial number to use as the base for
- an IXFR diff sequence (only meaningful if *rdtype* is
- ``dns.rdatatype.IXFR``).
-
- *use_udp*, a ``bool``. If ``True``, use UDP (only meaningful for IXFR).
-
- *keyalgorithm*, a ``dns.name.Name`` or ``str``, the TSIG algorithm to use.
-
- Raises on errors, and so does the generator.
-
- Returns a generator of ``dns.message.Message`` objects.
+ :param where: IPv4 or IPv6 address of the nameserver.
+ :type where: str
+ :param zone: The name of the zone to transfer.
+ :type zone: :py:class:`dns.name.Name` or str
+ :param rdtype: The type of zone transfer. Default is
+ ``dns.rdatatype.AXFR``; use ``dns.rdatatype.IXFR`` for incremental.
+ :type rdtype: :py:class:`dns.rdatatype.RdataType` or str or int
+ :param rdclass: The class of the zone transfer. Default is
+ ``dns.rdataclass.IN``.
+ :type rdclass: :py:class:`dns.rdataclass.RdataClass` or str or int
+ :param timeout: Seconds to wait for each response message. ``None``
+ means wait forever.
+ :type timeout: float or ``None``
+ :param port: The port to send the message to. Default is 53.
+ :type port: int
+ :param keyring: The keyring to use for TSIG.
+ :type keyring: dict or ``None``
+ :param keyname: The name of the TSIG key to use.
+ :type keyname: :py:class:`dns.name.Name` or str or ``None``
+ :param relativize: If ``True``, relativize all names to the zone origin.
+ Must match the setting passed to ``dns.zone.from_xfr()``.
+ :type relativize: bool
+ :param lifetime: Total seconds to spend on the transfer. ``None`` means
+ no limit.
+ :type lifetime: float or ``None``
+ :param source: Source IPv4 or IPv6 address. Default is the wildcard
+ address.
+ :type source: str or ``None``
+ :param source_port: The port from which to send the message. Default
+ is 0.
+ :type source_port: int
+ :param serial: SOA serial number to use as the IXFR base (only
+ meaningful when *rdtype* is ``dns.rdatatype.IXFR``).
+ :type serial: int
+ :param use_udp: If ``True``, use UDP (only meaningful for IXFR).
+ :type use_udp: bool
+ :param keyalgorithm: The TSIG algorithm to use.
+ :type keyalgorithm: :py:class:`dns.name.Name` or str
+ :returns: A generator of :py:class:`dns.message.Message` objects.
"""
class DummyTransactionManager(dns.transaction.TransactionManager):
"""Conduct an inbound transfer and apply it via a transaction from the
txn_manager.
- *where*, a ``str`` containing an IPv4 or IPv6 address, where
- to send the message.
-
- *txn_manager*, a ``dns.transaction.TransactionManager``, the txn_manager
- for this transfer (typically a ``dns.zone.Zone``).
-
- *query*, the query to send. If not supplied, a default query is
- constructed using information from the *txn_manager*.
-
- *port*, an ``int``, the port send the message to. The default is 53.
-
- *timeout*, a ``float``, the number of seconds to wait for each
- response message. If None, the default, wait forever.
-
- *lifetime*, a ``float``, the total number of seconds to spend
- doing the transfer. If ``None``, the default, then there is no
- limit on the time the transfer may take.
-
- *source*, a ``str`` containing an IPv4 or IPv6 address, specifying
- the source address. The default is the wildcard address.
-
- *source_port*, an ``int``, the port from which to send the message.
- The default is 0.
-
- *udp_mode*, a ``dns.query.UDPMode``, determines how UDP is used
- for IXFRs. The default is ``dns.query.UDPMode.NEVER``, i.e. only use
- TCP. Other possibilities are ``dns.query.UDPMode.TRY_FIRST``, which
- means "try UDP but fallback to TCP if needed", and
- ``dns.query.UDPMode.ONLY``, which means "try UDP and raise
- ``dns.xfr.UseTCP`` if it does not succeed.
-
- Raises on errors.
+ :param where: IPv4 or IPv6 address of the nameserver.
+ :type where: str
+ :param txn_manager: The transaction manager for this transfer (typically
+ a :py:class:`dns.zone.Zone`).
+ :type txn_manager: :py:class:`dns.transaction.TransactionManager`
+ :param query: The query to send. If not supplied, a default query is
+ constructed from *txn_manager*.
+ :param port: The port to send the message to. Default is 53.
+ :type port: int
+ :param timeout: Seconds to wait for each response message. ``None``
+ means wait forever.
+ :type timeout: float or ``None``
+ :param lifetime: Total seconds to spend on the transfer. ``None`` means
+ no limit.
+ :type lifetime: float or ``None``
+ :param source: Source IPv4 or IPv6 address. Default is the wildcard
+ address.
+ :type source: str or ``None``
+ :param source_port: The port from which to send the message. Default
+ is 0.
+ :type source_port: int
+ :param udp_mode: How to use UDP for IXFRs. Default is
+ ``dns.query.UDPMode.NEVER`` (TCP only). ``TRY_FIRST`` tries UDP
+ with TCP fallback; ``ONLY`` raises :py:exc:`dns.xfr.UseTCP` if UDP
+ does not succeed.
+ :type udp_mode: :py:class:`dns.query.UDPMode`
"""
if query is None:
query, serial = dns.xfr.make_query(txn_manager)
def from_text(text: str) -> Rcode:
"""Convert text into an rcode.
- *text*, a ``str``, the textual rcode or an integer in textual form.
-
- Raises ``dns.rcode.UnknownRcode`` if the rcode mnemonic is unknown.
-
- Returns a ``dns.rcode.Rcode``.
+ :param text: The textual rcode or an integer in textual form.
+ :type text: str
+ :raises dns.rcode.UnknownRcode: If the rcode mnemonic is unknown.
+ :rtype: :py:class:`dns.rcode.Rcode`
"""
return Rcode.from_text(text)
def from_flags(flags: int, ednsflags: int) -> Rcode:
"""Return the rcode value encoded by flags and ednsflags.
- *flags*, an ``int``, the DNS flags field.
-
- *ednsflags*, an ``int``, the EDNS flags field.
-
- Raises ``ValueError`` if rcode is < 0 or > 4095
-
- Returns a ``dns.rcode.Rcode``.
+ :param flags: The DNS flags field.
+ :type flags: int
+ :param ednsflags: The EDNS flags field.
+ :type ednsflags: int
+ :raises ValueError: If the rcode is < 0 or > 4095.
+ :rtype: :py:class:`dns.rcode.Rcode`
"""
value = (flags & 0x000F) | ((ednsflags >> 20) & 0xFF0)
def to_flags(value: Rcode) -> tuple[int, int]:
- """Return a (flags, ednsflags) tuple which encodes the rcode.
+ """Return a ``(flags, ednsflags)`` tuple which encodes the rcode.
- *value*, a ``dns.rcode.Rcode``, the rcode.
-
- Raises ``ValueError`` if rcode is < 0 or > 4095.
-
- Returns an ``(int, int)`` tuple.
+ :param value: The rcode.
+ :type value: :py:class:`dns.rcode.Rcode`
+ :raises ValueError: If the rcode is < 0 or > 4095.
+ :rtype: tuple[int, int]
"""
if value < 0 or value > 4095:
def to_text(value: Rcode, tsig: bool = False) -> str:
"""Convert rcode into text.
- *value*, a ``dns.rcode.Rcode``, the rcode.
-
- Raises ``ValueError`` if rcode is < 0 or > 4095.
-
- Returns a ``str``.
+ :param value: The rcode.
+ :type value: :py:class:`dns.rcode.Rcode`
+ :raises ValueError: If the rcode is < 0 or > 4095.
+ :rtype: str
"""
if tsig and value == Rcode.BADVERS:
An ``RdataStyle`` is also a :py:class:`dns.name.NameStyle`; see that class
for a description of its options.
- If *txt_is_utf8* is ``True``, then TXT-like records will be treated
- as UTF-8 if they decode successfully, and the output string may contain any
- Unicode codepoint. If ``False``, the default, then TXT-like records are
- treated according to RFC 1035 rules.
+ .. attribute:: txt_is_utf8
- *base64_chunk_size*, an ``int`` with default 32, specifies the chunk size for
- text representations that break base64 strings into chunks.
+ A ``bool``. If ``True``, TXT-like records will be treated as UTF-8 if
+ they decode successfully, and the output string may contain any Unicode
+ codepoint. If ``False`` (the default), TXT-like records are treated
+ according to RFC 1035 rules.
- *base64_chunk_separator*, a ``str`` with default ``" "``, specifies the
- chunk separator for text representations that break base64 strings into chunks.
+ .. attribute:: base64_chunk_size
- *hex_chunk_size*, an ``int`` with default 128, specifies the chunk size for
- text representations that break hex strings into chunks.
+ An ``int`` (default 32). The chunk size for text representations that
+ break base64 strings into chunks.
- *hex_chunk_separator*, a ``str`` with default ``" "``, specifies the
- chunk separator for text representations that break hex strings into chunks.
+ .. attribute:: base64_chunk_separator
- *truncate_crypto*, a ``bool``. The default is ``False``. If ``True``, then
- output of crypto types (e.g. DNSKEY) is altered to be readable
- by humans in a debugging context, but the crypto content will be removed.
- A sample use would be a "dig" application where you wanted to see how many
- DNSKEYs there were, and what key ids they had, without seeing the actual
- public key data. Use of this option will lose information.
+ A ``str`` (default ``" "``). The separator for text representations
+ that break base64 strings into chunks.
+
+ .. attribute:: hex_chunk_size
+
+ An ``int`` (default 128). The chunk size for text representations that
+ break hex strings into chunks.
+
+ .. attribute:: hex_chunk_separator
+
+ A ``str`` (default ``" "``). The separator for text representations
+ that break hex strings into chunks.
+
+ .. attribute:: truncate_crypto
+
+ A ``bool`` (default ``False``). If ``True``, output of crypto types
+ (e.g. DNSKEY) is altered to be human-readable in a debugging context,
+ but the crypto content is removed. Use of this option will lose
+ information.
"""
txt_is_utf8: bool = False
) -> None:
"""Initialize an rdata.
- *rdclass*, an ``int`` is the rdataclass of the Rdata.
-
- *rdtype*, an ``int`` is the rdatatype of the Rdata.
+ :param rdclass: The rdata class.
+ :type rdclass: :py:class:`dns.rdataclass.RdataClass`
+ :param rdtype: The rdata type.
+ :type rdtype: :py:class:`dns.rdatatype.RdataType`
"""
self.rdclass = self._as_rdataclass(rdclass)
creating rdatasets, allowing the rdataset to contain only RRSIGs
of a particular type, e.g. RRSIG(NS).
- Returns a ``dns.rdatatype.RdataType``.
+ :rtype: :py:class:`dns.rdatatype.RdataType`
"""
return dns.rdatatype.NONE
which are the ordinary DNS type, and the upper 16 bits of which are
the "covered" type, if any.
- Returns an ``int``.
+ :rtype: int
"""
return self.covers() << 16 | self.rdtype
) -> str:
"""Convert an rdata to text format.
- *style*, a :py:class:`dns.rdata.RdataStyle` or ``None`` (the default). If
- specified, the style overrides the other parameters.
-
- Returns a ``str``.
+ :param style: If specified, overrides *origin* and *relativize*.
+ :type style: :py:class:`dns.rdata.RdataStyle` or ``None``
+ :rtype: str
"""
if style is None:
kw = kw.copy()
See the documentation for :py:class:`dns.rdata.RdataStyle` for a description
of the style parameters.
- Returns a ``str``.
+ :rtype: str
"""
raise NotImplementedError # pragma: no cover
) -> bytes | None:
"""Convert an rdata to wire format.
- Returns a ``bytes`` if no output file was specified, or ``None`` otherwise.
+ :returns: Wire-format bytes if no output file was specified, or ``None``
+ if a file was provided.
+ :rtype: bytes or ``None``
"""
if file:
return f.getvalue()
def to_generic(self, origin: dns.name.Name | None = None) -> "GenericRdata":
- """Creates a dns.rdata.GenericRdata equivalent of this rdata.
+ """Create a :py:class:`dns.rdata.GenericRdata` equivalent of this rdata.
- Returns a ``dns.rdata.GenericRdata``.
+ :rtype: :py:class:`dns.rdata.GenericRdata`
"""
wire = self.to_wire(origin=origin)
assert wire is not None # for type checkers
"""Convert rdata to a format suitable for digesting in hashes. This
is also the DNSSEC canonical form.
- Returns a ``bytes``.
+ :rtype: bytes
"""
wire = self.to_wire(origin=origin, canonicalize=True)
assert wire is not None # for mypy
raise NotImplementedError # pragma: no cover
def replace(self, **kwargs: Any) -> "Rdata":
- """
- Create a new Rdata instance based on the instance replace was
+ """Create a new Rdata instance based on the instance replace was
invoked on. It is possible to pass different parameters to
override the corresponding properties of the base Rdata.
Any field specific to the Rdata type can be replaced, but the
*rdtype* and *rdclass* fields cannot.
- Returns an instance of the same Rdata subclass as *self*.
+ :returns: A new instance of the same :py:class:`Rdata` subclass as *self*.
+ :rtype: :py:class:`Rdata`
"""
# Get the constructor parameters.
Normally dnspython loads DNS rdatatype implementations on demand, but in some
specialized cases loading all types at an application-controlled time is preferred.
- If *disable_dynamic_load*, a ``bool``, is ``True`` then dnspython will not attempt
- to use its dynamic loading mechanism if an unknown type is subsequently encountered,
- and will simply use the ``GenericRdata`` class.
+ :param disable_dynamic_load: If ``True`` (the default), dnspython will not
+ attempt to use its dynamic loading mechanism if an unknown type is
+ subsequently encountered, and will simply use the ``GenericRdata``
+ class.
+ :type disable_dynamic_load: bool
"""
# Load class IN and ANY types.
for rdtype in dns.rdatatype.RdataType:
If *tok* is a ``str``, then a tokenizer is created and the string
is used as its input.
- *rdclass*, a ``dns.rdataclass.RdataClass`` or ``str``, the rdataclass.
-
- *rdtype*, a ``dns.rdatatype.RdataType`` or ``str``, the rdatatype.
-
- *tok*, a ``dns.tokenizer.Tokenizer`` or a ``str``.
-
- *origin*, a ``dns.name.Name`` (or ``None``), the
- origin to use for relative names.
-
- *relativize*, a ``bool``. If true, name will be relativized.
-
- *relativize_to*, a ``dns.name.Name`` (or ``None``), the origin to use
- when relativizing names. If not set, the *origin* value will be used.
-
- *idna_codec*, a ``dns.name.IDNACodec``, specifies the IDNA
- encoder/decoder to use if a tokenizer needs to be created. If
- ``None``, the default IDNA 2003 encoder/decoder is used. If a
- tokenizer is not created, then the codec associated with the tokenizer
- is the one that is used.
-
- Returns an instance of the chosen Rdata subclass.
+ :param rdclass: The rdata class.
+ :type rdclass: :py:class:`dns.rdataclass.RdataClass` or ``str``
+ :param rdtype: The rdata type.
+ :type rdtype: :py:class:`dns.rdatatype.RdataType` or ``str``
+ :param tok: The tokenizer or input string.
+ :type tok: :py:class:`dns.tokenizer.Tokenizer` or ``str``
+ :param origin: The origin to use for relative names.
+ :type origin: :py:class:`dns.name.Name` or ``None``
+ :param relativize: If ``True``, names will be relativized. Default is ``True``.
+ :type relativize: bool
+ :param relativize_to: The origin to use when relativizing. Defaults to *origin*.
+ :type relativize_to: :py:class:`dns.name.Name` or ``None``
+ :param idna_codec: The IDNA encoder/decoder to use when creating a tokenizer.
+ If ``None``, the default IDNA 2003 codec is used.
+ :type idna_codec: :py:class:`dns.name.IDNACodec` or ``None``
+ :returns: An instance of the chosen :py:class:`Rdata` subclass.
+ :rtype: :py:class:`Rdata`
"""
if isinstance(tok, str):
Once a class is chosen, its from_wire() class method is called
with the parameters to this function.
- *rdclass*, a ``dns.rdataclass.RdataClass`` or ``str``, the rdataclass.
-
- *rdtype*, a ``dns.rdatatype.RdataType`` or ``str``, the rdatatype.
-
- *parser*, a ``dns.wire.Parser``, the parser, which should be
- restricted to the rdata length.
-
- *origin*, a ``dns.name.Name`` (or ``None``). If not ``None``,
- then names will be relativized to this origin.
-
- Returns an instance of the chosen Rdata subclass.
+ :param rdclass: The rdata class.
+ :type rdclass: :py:class:`dns.rdataclass.RdataClass` or ``str``
+ :param rdtype: The rdata type.
+ :type rdtype: :py:class:`dns.rdatatype.RdataType` or ``str``
+ :param parser: The wire format parser, restricted to the rdata length.
+ :type parser: :py:class:`dns.wire.Parser`
+ :param origin: If not ``None``, names will be relativized to this origin.
+ :type origin: :py:class:`dns.name.Name` or ``None``
+ :returns: An instance of the chosen :py:class:`Rdata` subclass.
+ :rtype: :py:class:`Rdata`
"""
rdclass = dns.rdataclass.RdataClass.make(rdclass)
Once a class is chosen, its from_wire() class method is called
with the parameters to this function.
- *rdclass*, an ``int``, the rdataclass.
-
- *rdtype*, an ``int``, the rdatatype.
-
- *wire*, a ``bytes``, the wire-format message.
-
- *current*, an ``int``, the offset in wire of the beginning of
- the rdata.
-
- *rdlen*, an ``int``, the length of the wire-format rdata
-
- *origin*, a ``dns.name.Name`` (or ``None``). If not ``None``,
- then names will be relativized to this origin.
-
- Returns an instance of the chosen Rdata subclass.
+ :param rdclass: The rdata class.
+ :type rdclass: :py:class:`dns.rdataclass.RdataClass` or ``str``
+ :param rdtype: The rdata type.
+ :type rdtype: :py:class:`dns.rdatatype.RdataType` or ``str``
+ :param wire: The wire-format message.
+ :type wire: bytes
+ :param current: The offset of the start of the rdata in *wire*.
+ :type current: int
+ :param rdlen: The length of the rdata in wire format.
+ :type rdlen: int
+ :param origin: If not ``None``, names will be relativized to this origin.
+ :type origin: :py:class:`dns.name.Name` or ``None``
+ :returns: An instance of the chosen :py:class:`Rdata` subclass.
+ :rtype: :py:class:`Rdata`
"""
parser = dns.wire.Parser(wire, current)
with parser.restrict_to(rdlen):
) -> None:
"""Dynamically register a module to handle an rdatatype.
- *implementation*, a subclass of ``dns.rdata.Rdata`` implementing the type,
- or a module containing such a class named by its text form.
-
- *rdtype*, an ``int``, the rdatatype to register.
-
- *rdtype_text*, a ``str``, the textual form of the rdatatype.
-
- *is_singleton*, a ``bool``, indicating if the type is a singleton (i.e.
- RRsets of the type can have only one member.)
-
- *rdclass*, the rdataclass of the type, or ``dns.rdataclass.ANY`` if
- it applies to all classes.
+ :param implementation: A subclass of :py:class:`dns.rdata.Rdata` implementing
+ the type, or a module containing such a class named by its text form.
+ :param rdtype: The rdatatype to register.
+ :type rdtype: int
+ :param rdtype_text: The textual form of the rdatatype.
+ :type rdtype_text: str
+ :param is_singleton: If ``True``, RRsets of this type can have only one member.
+ :type is_singleton: bool
+ :param rdclass: The rdata class, or ``dns.rdataclass.ANY`` for all classes.
+ :type rdclass: :py:class:`dns.rdataclass.RdataClass`
"""
rdtype = dns.rdatatype.RdataType.make(rdtype)
For example, "IN" and "CLASS1" will both result in a value of 1.
- Raises ``dns.rdatatype.UnknownRdataclass`` if the class is unknown.
-
- Raises ``ValueError`` if the rdata class value is not >= 0 and <= 65535.
-
- Returns a ``dns.rdataclass.RdataClass``.
+ :raises dns.rdataclass.UnknownRdataclass: If the class is unknown.
+ :raises ValueError: If the rdata class value is not >= 0 and <= 65535.
+ :rtype: :py:class:`dns.rdataclass.RdataClass`
"""
return RdataClass.from_text(text)
If the value has a known mnemonic, it will be used, otherwise the
DNS generic class syntax will be used.
- Raises ``ValueError`` if the rdata class value is not >= 0 and <= 65535.
-
- Returns a ``str``.
+ :raises ValueError: If the rdata class value is not >= 0 and <= 65535.
+ :rtype: str
"""
return RdataClass.to_text(value)
The currently defined metaclasses are ANY and NONE.
- *rdclass* is a ``dns.rdataclass.RdataClass``.
+ :param rdclass: The rdata class to check.
+ :type rdclass: :py:class:`dns.rdataclass.RdataClass`
"""
if rdclass in _metaclasses:
:py:class:`dns.rdata.RdataStyle`. See those classes
for a description of their options.
- *override_rdclass*, a ``dns.rdataclass.RdataClass`` or ``None``.
- If not ``None``, use this class instead of the Rdataset's class.
+ .. attribute:: override_rdclass
- *want_comments*, a ``bool``. If ``True``, emit comments for rdata
- which have them. The default is ``False``.
+ A :py:class:`dns.rdataclass.RdataClass` or ``None``. If not ``None``,
+ use this class instead of the Rdataset's class.
- *omit_rdclass*, a ``bool``. If ``True``, do not print the RdataClass.
- The default is ``False``.
+ .. attribute:: want_comments
- *omit_ttl*, a ``bool``. If ``True``, do not print the TTL.
- The default is ``False``. Use of this option may lose information.
+ A ``bool``. If ``True``, emit comments for rdata which have them.
+ The default is ``False``.
- *want_generic*, a ``bool``. If ``True``, print RdataClass, RdataType,
- and Rdatas in the generic format, a.k.a. the "unknown rdata format".
- The default is ``False``.
+ .. attribute:: omit_rdclass
- *deduplicate_names*, a ``bool``. If ``True``, print whitespace instead of the
- owner name if the owner name of an RR is the same as the prior RR's owner name.
- The default is ``False``.
+ A ``bool``. If ``True``, do not print the RdataClass. The default is
+ ``False``.
- *first_name_is_duplicate*, a ``bool``. If ``True``, consider the first owner name
- of the rdataset as a duplicate too, and emit whitespace for it as well. A sample
- use is in emitting a Node of multiple rdatasets and the current rdataset is not
- the first to be emitted. The default is ``False``.
+ .. attribute:: omit_ttl
- *default_ttl*, an ``int`` or ``None``. If ``None``, the default, there is no
- default TTL. If an integer is specified, then any TTL matching that value will
- be omitted. When emitting a zonefile, a setting other than ``None`` will cause
- a ``$TTL`` directive to be emitted.
+ A ``bool``. If ``True``, do not print the TTL. The default is
+ ``False``. Use of this option may lose information.
- *name_just*, an ``int``. The owner name field justification. Negative values
- are left justified, and positive values are right justified. A value of zero,
- the default, means that no justification is performed.
+ .. attribute:: want_generic
- *ttl_just*, an ``int``. The TTL field justification. Negative values
- are left justified, and positive values are right justified. A value of zero,
- the default, means that no justification is performed.
+ A ``bool``. If ``True``, print RdataClass, RdataType, and Rdatas in
+ the generic format (the "unknown rdata format"). The default is
+ ``False``.
- *rdclass_just*, an ``int``. The RdataClass name field justification. Negative values
- are left justified, and positive values are right justified. A value of zero,
- the default, means that no justification is performed.
+ .. attribute:: deduplicate_names
- *rdtype_just*, an ``int``. The RdataType field justification. Negative values
- are left justified, and positive values are right justified. A value of zero,
- the default, means that no justification is performed.
+ A ``bool``. If ``True``, print whitespace instead of the owner name
+ when the owner name of an RR is the same as the prior RR's owner name.
+ The default is ``False``.
+
+ .. attribute:: first_name_is_duplicate
+
+ A ``bool``. If ``True``, consider the first owner name of the rdataset
+ as a duplicate too, emitting whitespace for it as well. Useful when
+ emitting a Node of multiple rdatasets and the current rdataset is not
+ the first. The default is ``False``.
+
+ .. attribute:: default_ttl
+
+ An ``int`` or ``None``. If ``None`` (the default), there is no default
+ TTL. If an integer is specified, any TTL matching that value will be
+ omitted. When emitting a zonefile, a value other than ``None`` will
+ cause a ``$TTL`` directive to be emitted.
+
+ .. attribute:: name_just
+
+ An ``int``. The owner name field justification. Negative values are
+ left-justified, positive values are right-justified. Zero (the default)
+ means no justification.
+
+ .. attribute:: ttl_just
+
+ An ``int``. The TTL field justification. Negative values are
+ left-justified, positive values are right-justified. Zero (the default)
+ means no justification.
+
+ .. attribute:: rdclass_just
+
+ An ``int``. The RdataClass field justification. Negative values are
+ left-justified, positive values are right-justified. Zero (the default)
+ means no justification.
+
+ .. attribute:: rdtype_just
+
+ An ``int``. The RdataType field justification. Negative values are
+ left-justified, positive values are right-justified. Zero (the default)
+ means no justification.
"""
override_rdclass: dns.rdataclass.RdataClass | None = None
):
"""Create a new rdataset of the specified class and type.
- *rdclass*, a ``dns.rdataclass.RdataClass``, the rdataclass.
-
- *rdtype*, an ``dns.rdatatype.RdataType``, the rdatatype.
-
- *covers*, an ``dns.rdatatype.RdataType``, the covered rdatatype.
-
- *ttl*, an ``int``, the TTL.
+ :param rdclass: The rdataclass.
+ :type rdclass: :py:class:`dns.rdataclass.RdataClass`
+ :param rdtype: The rdatatype.
+ :type rdtype: :py:class:`dns.rdatatype.RdataType`
+ :param covers: The covered rdatatype.
+ :type covers: :py:class:`dns.rdatatype.RdataType`
+ :param ttl: The TTL.
+ :type ttl: int
"""
super().__init__()
TTL or the specified TTL. If the set contains no rdatas, set the TTL
to the specified TTL.
- *ttl*, an ``int`` or ``str``.
+ :param ttl: The candidate TTL value.
+ :type ttl: int or str
"""
ttl = dns.ttl.make(ttl)
if len(self) == 0:
If the optional *ttl* parameter is supplied, then
``self.update_ttl(ttl)`` will be called prior to adding the rdata.
- *rd*, a ``dns.rdata.Rdata``, the rdata
-
- *ttl*, an ``int``, the TTL.
-
- Raises ``dns.rdataset.IncompatibleTypes`` if the type and class
- do not match the type and class of the rdataset.
-
- Raises ``dns.rdataset.DifferingCovers`` if the type is a signature
- type and the covered type does not match that of the rdataset.
+ :param rd: The rdata to add.
+ :type rd: :py:class:`dns.rdata.Rdata`
+ :param ttl: The TTL.
+ :type ttl: int or ``None``
+ :raises dns.rdataset.IncompatibleTypes: If the type and class do not
+ match the type and class of the rdataset.
+ :raises dns.rdataset.DifferingCovers: If the type is a signature type
+ and the covered type does not match that of the rdataset.
"""
#
def update(self, other):
"""Add all rdatas in other to self.
- *other*, a ``dns.rdataset.Rdataset``, the rdataset from which
- to update.
+ :param other: The rdataset from which to update.
+ :type other: :py:class:`dns.rdataset.Rdataset`
"""
self.update_ttl(other.ttl)
Any additional keyword arguments are passed on to the rdata
``to_text()`` method.
- *name*, a ``dns.name.Name``. If name is not ``None``, emit RRs with
- *name* as the owner name.
-
- *origin*, a ``dns.name.Name`` or ``None``, the origin for relative
- names.
-
- *relativize*, a ``bool``. If ``True``, names will be relativized
- to *origin*.
-
- *override_rdclass*, a ``dns.rdataclass.RdataClass`` or ``None``.
- If not ``None``, when rendering, emit records as if they were of this class.
-
- *want_comments*, a ``bool``. If ``True``, emit comments for rdata
- which have them. The default is ``False``.
-
- *style*, a :py:class:`dns.rdataset.RdatasetStyle` or ``None`` (the default). If
- specified, the style overrides the other parameters except for *name*.
+ :param name: If not ``None``, emit RRs with this as the owner name.
+ :type name: :py:class:`dns.name.Name` or ``None``
+ :param origin: The origin for relative names.
+ :type origin: :py:class:`dns.name.Name` or ``None``
+ :param relativize: If ``True``, names will be relativized to *origin*.
+ :type relativize: bool
+ :param override_rdclass: If not ``None``, emit records as if they were
+ of this class.
+ :type override_rdclass: :py:class:`dns.rdataclass.RdataClass` or ``None``
+ :param want_comments: If ``True``, emit comments for rdata which have
+ them. The default is ``False``.
+ :type want_comments: bool
+ :param style: If specified, overrides the other parameters except
+ *name*.
+ :type style: :py:class:`dns.rdataset.RdatasetStyle` or ``None``
"""
if style is None:
kw = kw.copy()
) -> int:
"""Convert the rdataset to wire format.
- *name*, a ``dns.name.Name`` is the owner name to use.
-
- *file* is the file where the name is emitted (typically a
- BytesIO file).
-
- *compress*, a ``dict``, is the compression table to use. If
- ``None`` (the default), names will not be compressed.
-
- *origin* is a ``dns.name.Name`` or ``None``. If the name is
- relative and origin is not ``None``, then *origin* will be appended
- to it.
-
- *override_rdclass*, an ``int``, is used as the class instead of the
- class of the rdataset. This is useful when rendering rdatasets
- associated with dynamic updates.
-
- *want_shuffle*, a ``bool``. If ``True``, then the order of the
- Rdatas within the Rdataset will be shuffled before rendering.
-
- Returns an ``int``, the number of records emitted.
+ :param name: The owner name to use.
+ :type name: :py:class:`dns.name.Name`
+ :param file: The file where the name is emitted (typically a
+ ``BytesIO`` file).
+ :param compress: The compression table to use. If ``None`` (the
+ default), names will not be compressed.
+ :type compress: dict or ``None``
+ :param origin: If the name is relative and *origin* is not ``None``,
+ *origin* will be appended to it.
+ :type origin: :py:class:`dns.name.Name` or ``None``
+ :param override_rdclass: If not ``None``, used as the class instead of
+ the class of the rdataset. Useful for dynamic update rendering.
+ :type override_rdclass: int or ``None``
+ :param want_shuffle: If ``True``, the order of Rdatas within the
+ Rdataset will be shuffled before rendering.
+ :type want_shuffle: bool
+
+ :returns: The number of records emitted.
+ :rtype: int
"""
if override_rdclass is not None:
"""Create an rdataset with the specified class, type, and TTL, and with
the specified list of rdatas in text format.
- *idna_codec*, a ``dns.name.IDNACodec``, specifies the IDNA
- encoder/decoder to use; if ``None``, the default IDNA 2003
- encoder/decoder is used.
-
- *origin*, a ``dns.name.Name`` (or ``None``), the
- origin to use for relative names.
-
- *relativize*, a ``bool``. If true, name will be relativized.
-
- *relativize_to*, a ``dns.name.Name`` (or ``None``), the origin to use
- when relativizing names. If not set, the *origin* value will be used.
-
- Returns a ``dns.rdataset.Rdataset`` object.
+ :param idna_codec: Specifies the IDNA encoder/decoder. If ``None``, the
+ default IDNA 2003 encoder/decoder is used.
+ :type idna_codec: :py:class:`dns.name.IDNACodec` or ``None``
+ :param origin: The origin to use for relative names.
+ :type origin: :py:class:`dns.name.Name` or ``None``
+ :param relativize: If ``True``, names will be relativized.
+ :type relativize: bool
+ :param relativize_to: The origin to use when relativizing names. If not
+ set, *origin* is used.
+ :type relativize_to: :py:class:`dns.name.Name` or ``None``
+
+ :rtype: :py:class:`dns.rdataset.Rdataset`
"""
rdclass = dns.rdataclass.RdataClass.make(rdclass)
"""Create an rdataset with the specified class, type, and TTL, and with
the specified rdatas in text format.
- Returns a ``dns.rdataset.Rdataset`` object.
+ :rtype: :py:class:`dns.rdataset.Rdataset`
"""
return from_text_list(rdclass, rdtype, ttl, cast(Collection[str], text_rdatas))
"""Create an rdataset with the specified TTL, and with
the specified list of rdata objects.
- Returns a ``dns.rdataset.Rdataset`` object.
+ :rtype: :py:class:`dns.rdataset.Rdataset`
"""
if len(rdatas) == 0:
"""Create an rdataset with the specified TTL, and with
the specified rdata objects.
- Returns a ``dns.rdataset.Rdataset`` object.
+ :rtype: :py:class:`dns.rdataset.Rdataset`
"""
return from_rdata_list(ttl, cast(Collection[dns.rdata.Rdata], rdatas))
For example, "NS" and "TYPE2" will both result in a value of 2.
- Raises ``dns.rdatatype.UnknownRdatatype`` if the type is unknown.
-
- Raises ``ValueError`` if the rdata type value is not >= 0 and <= 65535.
-
- Returns a ``dns.rdatatype.RdataType``.
+ :raises dns.rdatatype.UnknownRdatatype: If the type is unknown.
+ :raises ValueError: If the rdata type value is not >= 0 and <= 65535.
+ :rtype: :py:class:`dns.rdatatype.RdataType`
"""
return RdataType.from_text(text)
If the value has a known mnemonic, it will be used, otherwise the
DNS generic type syntax will be used.
- Raises ``ValueError`` if the rdata type value is not >= 0 and <= 65535.
-
- Returns a ``str``.
+ :raises ValueError: If the rdata type value is not >= 0 and <= 65535.
+ :rtype: str
"""
return RdataType.to_text(value)
def is_metatype(rdtype: RdataType) -> bool:
"""True if the specified type is a metatype.
- *rdtype* is a ``dns.rdatatype.RdataType``.
-
The currently defined metatypes are TKEY, TSIG, IXFR, AXFR, MAILA,
MAILB, ANY, OPT, and NXNAME.
- Returns a ``bool``.
+ :param rdtype: The rdata type to check.
+ :type rdtype: :py:class:`dns.rdatatype.RdataType`
+ :rtype: bool
"""
return (256 > rdtype >= 128) or rdtype in _metatypes
The currently defined singleton types are CNAME, DNAME, NSEC, NXT, and
SOA.
- *rdtype* is an ``int``.
-
- Returns a ``bool``.
+ :param rdtype: The rdata type to check.
+ :type rdtype: :py:class:`dns.rdatatype.RdataType`
+ :rtype: bool
"""
if rdtype in _singletons:
) -> None:
"""Dynamically register an rdatatype.
- *rdtype*, a ``dns.rdatatype.RdataType``, the rdatatype to register.
-
- *rdtype_text*, a ``str``, the textual form of the rdatatype.
-
- *is_singleton*, a ``bool``, indicating if the type is a singleton (i.e.
- RRsets of the type can have only one member.)
+ :param rdtype: The rdatatype to register.
+ :type rdtype: :py:class:`dns.rdatatype.RdataType`
+ :param rdtype_text: The textual form of the rdatatype.
+ :type rdtype_text: str
+ :param is_singleton: If ``True``, RRsets of this type can have only one
+ member.
+ :type is_singleton: bool
"""
_registered_by_text[rdtype_text] = rdtype
def __init__(self, rdclass, rdtype, options):
"""Initialize an OPT rdata.
- *rdclass*, an ``int`` is the rdataclass of the Rdata,
- which is also the payload size.
-
- *rdtype*, an ``int`` is the rdatatype of the Rdata.
-
- *options*, a tuple of ``bytes``
+ :param rdclass: The rdataclass of the Rdata, which is also the
+ payload size.
+ :type rdclass: int
+ :param rdtype: The rdatatype of the Rdata.
+ :type rdtype: int
+ :param options: The EDNS options.
+ :type options: tuple of :py:class:`dns.edns.Option`
"""
super().__init__(rdclass, rdtype)
):
"""Initialize a TSIG rdata.
- *rdclass*, an ``int`` is the rdataclass of the Rdata.
-
- *rdtype*, an ``int`` is the rdatatype of the Rdata.
-
- *algorithm*, a ``dns.name.Name``.
-
- *time_signed*, an ``int``.
-
- *fudge*, an ``int`.
-
- *mac*, a ``bytes``
-
- *original_id*, an ``int``
-
- *error*, an ``int``
-
- *other*, a ``bytes``
+ :param rdclass: The rdataclass of the Rdata.
+ :type rdclass: int
+ :param rdtype: The rdatatype of the Rdata.
+ :type rdtype: int
+ :param algorithm: The TSIG algorithm name.
+ :type algorithm: :py:class:`dns.name.Name`
+ :param time_signed: The time signed (seconds since epoch).
+ :type time_signed: int
+ :param fudge: The fudge (seconds of error permitted in time_signed).
+ :type fudge: int
+ :param mac: The message authentication code.
+ :type mac: bytes
+ :param original_id: The original message ID.
+ :type original_id: int
+ :param error: The TSIG error code.
+ :type error: int
+ :param other: Other data (typically empty).
+ :type other: bytes
"""
super().__init__(rdclass, rdtype)
def key_id(self) -> int:
"""Return the key id (a 16-bit number) for the specified key.
- *key*, a ``dns.rdtypes.ANY.DNSKEY.DNSKEY``
-
- Returns an ``int`` between 0 and 65535
+ :rtype: int
"""
wire = self.to_wire()
):
"""Initialize a TXT-like rdata.
- *rdclass*, an ``int`` is the rdataclass of the Rdata.
-
- *rdtype*, an ``int`` is the rdatatype of the Rdata.
-
- *strings*, a tuple of ``bytes``
+ :param rdclass: The rdataclass of the Rdata.
+ :type rdclass: int
+ :param rdtype: The rdatatype of the Rdata.
+ :type rdtype: int
+ :param strings: The strings.
+ :type strings: tuple of bytes
"""
super().__init__(rdclass, rdtype)
self.strings: tuple[bytes] = self._as_tuple(
def qnames(self):
"""All of the names that were tried.
- Returns a list of ``dns.name.Name``.
+ :rtype: list[:py:class:`dns.name.Name`]
"""
return self.kwargs["qnames"]
def responses(self):
"""A map from queried names to their NXDOMAIN responses.
- Returns a dict mapping a ``dns.name.Name`` to a
- ``dns.message.Message``.
+ :rtype: dict[:py:class:`dns.name.Name`, :py:class:`dns.message.Message`]
"""
return self.kwargs["responses"]
def response(self, qname):
"""The response for query *qname*.
- Returns a ``dns.message.Message``.
+ :param qname: The query name.
+ :type qname: :py:class:`dns.name.Name`
+ :rtype: :py:class:`dns.message.Message`
"""
return self.kwargs["responses"][qname]
"""Simple thread-safe DNS answer cache."""
def __init__(self, cleaning_interval: float = 300.0) -> None:
- """*cleaning_interval*, a ``float`` is the number of seconds between
- periodic cleanings.
+ """Initialize the cache.
+
+ :param cleaning_interval: Seconds between periodic cache cleanings.
+ :type cleaning_interval: float
"""
super().__init__()
self.next_cleaning = now + self.cleaning_interval
def get(self, key: CacheKey) -> Answer | None:
- """Get the answer associated with *key*.
-
- Returns None if no answer is cached for the key.
+ """Get the answer associated with *key*, or ``None`` if not cached.
- *key*, a ``(dns.name.Name, dns.rdatatype.RdataType, dns.rdataclass.RdataClass)``
- tuple whose values are the query name, rdtype, and rdclass respectively.
-
- Returns a ``dns.resolver.Answer`` or ``None``.
+ :param key: A (name, rdtype, rdclass) tuple identifying the query.
+ :type key: tuple[:py:class:`dns.name.Name`, :py:class:`dns.rdatatype.RdataType`, :py:class:`dns.rdataclass.RdataClass`]
+ :returns: The cached answer, or ``None`` if not found or expired.
+ :rtype: :py:class:`dns.resolver.Answer` or ``None``
"""
with self.lock:
return v
def put(self, key: CacheKey, value: Answer) -> None:
- """Associate key and value in the cache.
-
- *key*, a ``(dns.name.Name, dns.rdatatype.RdataType, dns.rdataclass.RdataClass)``
- tuple whose values are the query name, rdtype, and rdclass respectively.
+ """Associate *key* with *value* in the cache.
- *value*, a ``dns.resolver.Answer``, the answer.
+ :param key: A (name, rdtype, rdclass) tuple identifying the query.
+ :param value: The answer to cache.
+ :type value: :py:class:`dns.resolver.Answer`
"""
with self.lock:
def flush(self, key: CacheKey | None = None) -> None:
"""Flush the cache.
- If *key* is not ``None``, only that item is flushed. Otherwise the entire cache
- is flushed.
-
- *key*, a ``(dns.name.Name, dns.rdatatype.RdataType, dns.rdataclass.RdataClass)``
- tuple whose values are the query name, rdtype, and rdclass respectively.
+ :param key: If not ``None``, flush only this entry; otherwise flush
+ the entire cache.
"""
with self.lock:
"""
def __init__(self, max_size: int = 100000) -> None:
- """*max_size*, an ``int``, is the maximum number of nodes to cache;
- it must be greater than 0.
+ """Initialize an LRU cache.
+
+ :param max_size: The maximum number of nodes to cache; must be greater
+ than 0.
+ :type max_size: int
"""
super().__init__()
def get(self, key: CacheKey) -> Answer | None:
"""Get the answer associated with *key*.
- Returns None if no answer is cached for the key.
-
- *key*, a ``(dns.name.Name, dns.rdatatype.RdataType, dns.rdataclass.RdataClass)``
- tuple whose values are the query name, rdtype, and rdclass respectively.
+ Returns ``None`` if no answer is cached for the key.
- Returns a ``dns.resolver.Answer`` or ``None``.
+ :param key: A ``(dns.name.Name, dns.rdatatype.RdataType,
+ dns.rdataclass.RdataClass)`` tuple whose values are the query
+ name, rdtype, and rdclass respectively.
+ :type key: tuple
+ :rtype: :py:class:`dns.resolver.Answer` or ``None``
"""
with self.lock:
def put(self, key: CacheKey, value: Answer) -> None:
"""Associate key and value in the cache.
- *key*, a ``(dns.name.Name, dns.rdatatype.RdataType, dns.rdataclass.RdataClass)``
- tuple whose values are the query name, rdtype, and rdclass respectively.
-
- *value*, a ``dns.resolver.Answer``, the answer.
+ :param key: A ``(dns.name.Name, dns.rdatatype.RdataType,
+ dns.rdataclass.RdataClass)`` tuple whose values are the query
+ name, rdtype, and rdclass respectively.
+ :type key: tuple
+ :param value: The answer to cache.
+ :type value: :py:class:`dns.resolver.Answer`
"""
with self.lock:
def flush(self, key: CacheKey | None = None) -> None:
"""Flush the cache.
- If *key* is not ``None``, only that item is flushed. Otherwise the entire cache
- is flushed.
-
- *key*, a ``(dns.name.Name, dns.rdatatype.RdataType, dns.rdataclass.RdataClass)``
- tuple whose values are the query name, rdtype, and rdclass respectively.
+ :param key: If not ``None``, flush only this entry; otherwise flush
+ the entire cache. The key is a ``(dns.name.Name,
+ dns.rdatatype.RdataType, dns.rdataclass.RdataClass)`` tuple.
+ :type key: tuple or ``None``
"""
with self.lock:
) -> tuple[dns.message.QueryMessage | None, Answer | None]:
"""Get the next request to send, and check the cache.
- Returns a (request, answer) tuple. At most one of request or
- answer will not be None.
+ :returns: A (request, answer) tuple; at most one element is not ``None``.
+ :rtype: tuple[:py:class:`dns.message.QueryMessage` or ``None``, :py:class:`dns.resolver.Answer` or ``None``]
"""
# We return a tuple instead of Union[Message,Answer] as it lets
def __init__(
self, filename: str = "/etc/resolv.conf", configure: bool = True
) -> None:
- """*filename*, a ``str`` or file object, specifying a file
- in standard /etc/resolv.conf format. This parameter is meaningful
- only when *configure* is true and the platform is POSIX.
-
- *configure*, a ``bool``. If True (the default), the resolver
- instance is configured in the normal fashion for the operating
- system the resolver is running on. (I.e. by reading a
- /etc/resolv.conf file on POSIX systems and from the registry
- on Windows systems.)
+ """Initialize a resolver.
+
+ :param filename: A ``str`` or file object specifying a file in
+ standard ``/etc/resolv.conf`` format. Meaningful only when
+ *configure* is ``True`` and the platform is POSIX.
+ :type filename: str or file
+ :param configure: If ``True`` (the default), configure the resolver
+ for the operating system (reads ``/etc/resolv.conf`` on POSIX,
+ registry on Windows).
+ :type configure: bool
"""
self.reset()
) -> None:
"""Configure EDNS behavior.
- *edns*, an ``int``, is the EDNS level to use. Specifying
- ``None``, ``False``, or ``-1`` means "do not use EDNS", and in this case
- the other parameters are ignored. Specifying ``True`` is
- equivalent to specifying 0, i.e. "use EDNS0".
-
- *ednsflags*, an ``int``, the EDNS flag values.
-
- *payload*, an ``int``, is the EDNS sender's payload field, which is the
- maximum size of UDP datagram the sender can handle. I.e. how big
- a response to this message can be.
-
- *options*, a list of ``dns.edns.Option`` objects or ``None``, the EDNS
- options.
+ :param edns: The EDNS level to use. ``None``, ``False``, or ``-1``
+ means do not use EDNS (other parameters are ignored). ``True``
+ is equivalent to ``0`` (EDNS0).
+ :type edns: int or bool or ``None``
+ :param ednsflags: The EDNS flag values.
+ :type ednsflags: int
+ :param payload: The EDNS sender's payload field — the maximum UDP
+ datagram size the sender can handle.
+ :type payload: int
+ :param options: EDNS options, or ``None``.
+ :type options: list[:py:class:`dns.edns.Option`] or ``None``
"""
if edns is None or edns is False:
self.ednsoptions = options
def set_flags(self, flags: int) -> None:
- """Overrides the default flags with your own.
+ """Override the default query flags.
- *flags*, an ``int``, the message flags to use.
+ :param flags: The message flags to use.
+ :type flags: int
"""
self.flags = flags
def nameservers(
self, nameservers: Sequence[str | dns.nameserver.Nameserver]
) -> None:
- """
- *nameservers*, a ``list`` or ``tuple`` of nameservers, where a nameserver is either
- a string interpretable as a nameserver, or a ``dns.nameserver.Nameserver``
- instance.
+ """Set the resolver's nameservers.
- Raises ``ValueError`` if *nameservers* is not a list of nameservers.
+ :param nameservers: A list or tuple of nameservers, where each entry
+ is either a string (IP address or HTTPS URL) or a
+ :py:class:`dns.nameserver.Nameserver` instance.
+ :type nameservers: list or tuple
+ :raises ValueError: If *nameservers* is not a valid list of nameservers.
"""
# We just call _enrich_nameservers() for checking
self._enrich_nameservers(nameservers, self.nameserver_ports, self.port)
) -> Answer: # pylint: disable=arguments-differ
"""Query nameservers to find the answer to the question.
- The *qname*, *rdtype*, and *rdclass* parameters may be objects
- of the appropriate type, or strings that can be converted into objects
- of the appropriate type.
-
- *qname*, a ``dns.name.Name`` or ``str``, the query name.
-
- *rdtype*, an ``int`` or ``str``, the query type.
-
- *rdclass*, an ``int`` or ``str``, the query class.
-
- *tcp*, a ``bool``. If ``True``, use TCP to make the query.
-
- *source*, a ``str`` or ``None``. If not ``None``, bind to this IP
- address when making queries.
-
- *raise_on_no_answer*, a ``bool``. If ``True``, raise
- ``dns.resolver.NoAnswer`` if there's no answer to the question.
-
- *source_port*, an ``int``, the port from which to send the message.
-
- *lifetime*, a ``float``, how many seconds a query should run
- before timing out.
-
- *search*, a ``bool`` or ``None``, determines whether the
- search list configured in the system's resolver configuration
- are used for relative names, and whether the resolver's domain
- may be added to relative names. The default is ``None``,
- which causes the value of the resolver's
- ``use_search_by_default`` attribute to be used.
-
- Raises ``dns.resolver.LifetimeTimeout`` if no answers could be found
- in the specified lifetime.
-
- Raises ``dns.resolver.NXDOMAIN`` if the query name does not exist.
-
- Raises ``dns.resolver.YXDOMAIN`` if the query name is too long after
- DNAME substitution.
-
- Raises ``dns.resolver.NoAnswer`` if *raise_on_no_answer* is
- ``True`` and the query name exists but has no RRset of the
- desired type and class.
-
- Raises ``dns.resolver.NoNameservers`` if no non-broken
- nameservers are available to answer the question.
-
- Returns a ``dns.resolver.Answer`` instance.
-
+ The *qname*, *rdtype*, and *rdclass* parameters may be objects of
+ the appropriate type, or strings that will be converted automatically.
+
+ :param qname: The query name.
+ :type qname: :py:class:`dns.name.Name` or str
+ :param rdtype: The query type.
+ :type rdtype: :py:class:`dns.rdatatype.RdataType` or str or int
+ :param rdclass: The query class.
+ :type rdclass: :py:class:`dns.rdataclass.RdataClass` or str or int
+ :param tcp: If ``True``, use TCP to make the query.
+ :type tcp: bool
+ :param source: If not ``None``, bind to this IP address when making
+ queries.
+ :type source: str or ``None``
+ :param raise_on_no_answer: If ``True``, raise
+ :py:exc:`dns.resolver.NoAnswer` if there is no answer.
+ :type raise_on_no_answer: bool
+ :param source_port: The port from which to send the message.
+ :type source_port: int
+ :param lifetime: How many seconds a query should run before timing out.
+ :type lifetime: float or ``None``
+ :param search: Whether to use the search list for relative names.
+ ``None`` uses the resolver's ``use_search_by_default`` setting.
+ :type search: bool or ``None``
+ :raises dns.resolver.LifetimeTimeout: If no answers could be found in
+ the specified lifetime.
+ :raises dns.resolver.NXDOMAIN: If the query name does not exist.
+ :raises dns.resolver.YXDOMAIN: If the query name is too long after
+ DNAME substitution.
+ :raises dns.resolver.NoAnswer: If *raise_on_no_answer* is ``True`` and
+ the query name exists but has no RRset of the desired type/class.
+ :raises dns.resolver.NoNameservers: If no non-broken nameservers are
+ available to answer the question.
+ :rtype: :py:class:`dns.resolver.Answer`
"""
resolution = _Resolution(
def resolve_address(self, ipaddr: str, *args: Any, **kwargs: Any) -> Answer:
"""Use a resolver to run a reverse query for PTR records.
- This utilizes the resolve() method to perform a PTR lookup on the
- specified IP address.
-
- *ipaddr*, a ``str``, the IPv4 or IPv6 address you want to get
- the PTR record for.
+ :param ipaddr: The IPv4 or IPv6 address to look up.
+ :type ipaddr: str
- All other arguments that can be passed to the resolve() function
- except for rdtype and rdclass are also supported by this
- function.
+ All other keyword arguments accepted by
+ :py:meth:`~dns.resolver.Resolver.resolve` (except *rdtype* and
+ *rdclass*) are also supported.
"""
# We make a modified kwargs for type checking happiness, as otherwise
# we get a legit warning about possibly having rdtype and rdclass
) -> HostAnswers:
"""Use a resolver to query for address records.
- This utilizes the resolve() method to perform A and/or AAAA lookups on
- the specified name.
+ :param name: The name to resolve.
+ :type name: :py:class:`dns.name.Name` or str
+ :param family: The address family. ``socket.AF_UNSPEC`` (the default)
+ retrieves both A and AAAA records.
+ :type family: int
- *qname*, a ``dns.name.Name`` or ``str``, the name to resolve.
-
- *family*, an ``int``, the address family. If socket.AF_UNSPEC
- (the default), both A and AAAA records will be retrieved.
-
- All other arguments that can be passed to the resolve() function
- except for rdtype and rdclass are also supported by this
- function.
+ All other keyword arguments accepted by
+ :py:meth:`~dns.resolver.Resolver.resolve` (except *rdtype* and
+ *rdclass*) are also supported.
"""
# We make a modified kwargs for type checking happiness, as otherwise
# we get a legit warning about possibly having rdtype and rdclass
The canonical name is the name the resolver uses for queries
after all CNAME and DNAME renamings have been applied.
- *name*, a ``dns.name.Name`` or ``str``, the query name.
-
- This method can raise any exception that ``resolve()`` can
- raise, other than ``dns.resolver.NoAnswer`` and
- ``dns.resolver.NXDOMAIN``.
+ :param name: The query name.
+ :type name: :py:class:`dns.name.Name` or str
+ :rtype: :py:class:`dns.name.Name`
- Returns a ``dns.name.Name``.
+ This method can raise any exception that
+ :py:meth:`~dns.resolver.Resolver.resolve` can raise, other than
+ :py:exc:`dns.resolver.NoAnswer` and :py:exc:`dns.resolver.NXDOMAIN`.
"""
try:
answer = self.resolve(name, raise_on_no_answer=False)
) -> dns.name.Name: # pyright: ignore
"""Find the name of the zone which contains the specified name.
- *name*, an absolute ``dns.name.Name`` or ``str``, the query name.
-
- *rdclass*, an ``int``, the query class.
-
- *tcp*, a ``bool``. If ``True``, use TCP to make the query.
-
- *resolver*, a ``dns.resolver.Resolver`` or ``None``, the resolver to use.
- If ``None``, the default, then the default resolver is used.
-
- *lifetime*, a ``float``, the total time to allow for the queries needed
- to determine the zone. If ``None``, the default, then only the individual
- query limits of the resolver apply.
-
- Raises ``dns.resolver.NoRootSOA`` if there is no SOA RR at the DNS
- root. (This is only likely to happen if you're using non-default
- root servers in your network and they are misconfigured.)
-
- Raises ``dns.resolver.LifetimeTimeout`` if the answer could not be
- found in the allotted lifetime.
-
- Returns a ``dns.name.Name``.
+ :param name: An absolute query name.
+ :type name: :py:class:`dns.name.Name` or str
+ :param rdclass: The query class.
+ :type rdclass: :py:class:`dns.rdataclass.RdataClass`
+ :param tcp: If ``True``, use TCP to make the query.
+ :type tcp: bool
+ :param resolver: The resolver to use. If ``None``, the default resolver
+ is used.
+ :type resolver: :py:class:`dns.resolver.Resolver` or ``None``
+ :param lifetime: Total time to allow for the queries. If ``None``, only
+ the individual query limits of the resolver apply.
+ :type lifetime: float or ``None``
+ :raises dns.resolver.NoRootSOA: If there is no SOA RR at the DNS root.
+ :raises dns.resolver.LifetimeTimeout: If the answer could not be found
+ within the allotted lifetime.
+ :rtype: :py:class:`dns.name.Name`
"""
if isinstance(name, str):
) -> Resolver:
"""Make a stub resolver using the specified destination as the full resolver.
- *where*, a ``dns.name.Name`` or ``str`` the domain name or IP address of the
- full resolver.
-
- *port*, an ``int``, the port to use. If not specified, the default is 53.
-
- *family*, an ``int``, the address family to use. This parameter is used if
- *where* is not an address. The default is ``socket.AF_UNSPEC`` in which case
- the first address returned by ``resolve_name()`` will be used, otherwise the
- first address of the specified family will be used.
-
- *resolver*, a ``dns.resolver.Resolver`` or ``None``, the resolver to use for
- resolution of hostnames. If not specified, the default resolver will be used.
-
- Returns a ``dns.resolver.Resolver`` or raises an exception.
+ :param where: The domain name or IP address of the full resolver.
+ :type where: :py:class:`dns.name.Name` or str
+ :param port: The port to use. Default is 53.
+ :type port: int
+ :param family: The address family. Used only when *where* is not an
+ address literal. ``socket.AF_UNSPEC`` (default) uses the first
+ address returned; otherwise the first address of the given family.
+ :type family: int
+ :param resolver: The resolver to use for hostname resolution. If
+ ``None``, the default resolver is used.
+ :type resolver: :py:class:`dns.resolver.Resolver` or ``None``
+ :rtype: :py:class:`dns.resolver.Resolver`
"""
if resolver is None:
resolver = get_default_resolver()
"""Convert an IPv4 or IPv6 address in textual form into a Name object whose
value is the reverse-map domain name of the address.
- *text*, a ``str``, is an IPv4 or IPv6 address in textual form
- (e.g. '127.0.0.1', '::1')
-
- *v4_origin*, a ``dns.name.Name`` to append to the labels corresponding to
- the address if the address is an IPv4 address, instead of the default
- (in-addr.arpa.)
-
- *v6_origin*, a ``dns.name.Name`` to append to the labels corresponding to
- the address if the address is an IPv6 address, instead of the default
- (ip6.arpa.)
-
- Raises ``dns.exception.SyntaxError`` if the address is badly formed.
-
- Returns a ``dns.name.Name``.
+ :param text: An IPv4 or IPv6 address in textual form (e.g. ``'127.0.0.1'``,
+ ``'::1'``).
+ :type text: str
+ :param v4_origin: Domain to append for IPv4 addresses instead of
+ ``in-addr.arpa.``
+ :type v4_origin: :py:class:`dns.name.Name`
+ :param v6_origin: Domain to append for IPv6 addresses instead of
+ ``ip6.arpa.``
+ :type v6_origin: :py:class:`dns.name.Name`
+ :raises dns.exception.SyntaxError: If the address is badly formed.
+ :rtype: :py:class:`dns.name.Name`
"""
try:
) -> str:
"""Convert a reverse map domain name into textual address form.
- *name*, a ``dns.name.Name``, an IPv4 or IPv6 address in reverse-map name
- form.
-
- *v4_origin*, a ``dns.name.Name`` representing the top-level domain for
- IPv4 addresses, instead of the default (in-addr.arpa.)
-
- *v6_origin*, a ``dns.name.Name`` representing the top-level domain for
- IPv4 addresses, instead of the default (ip6.arpa.)
-
- Raises ``dns.exception.SyntaxError`` if the name does not have a
- reverse-map form.
-
- Returns a ``str``.
+ :param name: An IPv4 or IPv6 address in reverse-map name form.
+ :type name: :py:class:`dns.name.Name`
+ :param v4_origin: Top-level domain for IPv4 addresses (default
+ ``in-addr.arpa.``).
+ :type v4_origin: :py:class:`dns.name.Name`
+ :param v6_origin: Top-level domain for IPv6 addresses (default
+ ``ip6.arpa.``).
+ :type v6_origin: :py:class:`dns.name.Name`
+ :raises dns.exception.SyntaxError: If the name does not have a
+ reverse-map form.
+ :rtype: str
"""
if name.is_subdomain(v4_origin):
Any additional keyword arguments are passed on to the rdata
``to_text()`` method.
- *origin*, a ``dns.name.Name`` or ``None``, the origin for relative
- names.
-
- *relativize*, a ``bool``. If ``True``, names will be relativized
- to *origin*.
-
- *want_comments*, a ``bool``. If ``True``, emit comments for rdata
- which have them. The default is ``False``.
-
- *style*, a :py:class:`dns.rdataset.RdatasetStyle` or ``None`` (the default). If
- specified, the style overrides the other parameters.
+ :param origin: The origin for relative names.
+ :type origin: :py:class:`dns.name.Name` or ``None``
+ :param relativize: If ``True``, names will be relativized to *origin*.
+ :type relativize: bool
+ :param want_comments: If ``True``, emit comments for rdata which have
+ them. The default is ``False``.
+ :type want_comments: bool
+ :param style: If specified, overrides the other parameters.
+ :type style: :py:class:`dns.rdataset.RdatasetStyle` or ``None``
"""
if style is None:
kw = kw.copy()
*style*, a :py:class:`dns.rdataset.RdatasetStyle` or ``None`` (the default). If
specified, the style overrides the other parameters.
- returns a ``str``.
+ :rtype: str
"""
if self.deleting is not None:
style = style.replace(override_rdclass=self.deleting)
All keyword arguments are passed to ``dns.rdataset.to_wire()``; see
that function for details.
- Returns an ``int``, the number of records emitted.
+ :returns: The number of records emitted.
+ :rtype: int
"""
return super().to_wire(self.name, file, compress, origin, self.deleting, **kw)
def to_rdataset(self) -> dns.rdataset.Rdataset:
"""Convert an RRset into an Rdataset.
- Returns a ``dns.rdataset.Rdataset``.
+ :rtype: :py:class:`dns.rdataset.Rdataset`
"""
return dns.rdataset.from_rdata_list(self.ttl, list(self))
"""Create an RRset with the specified name, TTL, class, and type, and with
the specified list of rdatas in text format.
- *idna_codec*, a ``dns.name.IDNACodec``, specifies the IDNA
- encoder/decoder to use; if ``None``, the default IDNA 2003
- encoder/decoder is used.
-
- *origin*, a ``dns.name.Name`` (or ``None``), the
- origin to use for relative names.
-
- *relativize*, a ``bool``. If true, name will be relativized.
-
- *relativize_to*, a ``dns.name.Name`` (or ``None``), the origin to use
- when relativizing names. If not set, the *origin* value will be used.
-
- Returns a ``dns.rrset.RRset`` object.
+ :param idna_codec: Specifies the IDNA encoder/decoder. If ``None``, the
+ default IDNA 2003 encoder/decoder is used.
+ :type idna_codec: :py:class:`dns.name.IDNACodec` or ``None``
+ :param origin: The origin to use for relative names.
+ :type origin: :py:class:`dns.name.Name` or ``None``
+ :param relativize: If ``True``, names will be relativized.
+ :type relativize: bool
+ :param relativize_to: The origin to use when relativizing names. If not
+ set, *origin* is used.
+ :type relativize_to: :py:class:`dns.name.Name` or ``None``
+ :rtype: :py:class:`dns.rrset.RRset`
"""
if isinstance(name, str):
"""Create an RRset with the specified name, TTL, class, and type and with
the specified rdatas in text format.
- Returns a ``dns.rrset.RRset`` object.
+ :rtype: :py:class:`dns.rrset.RRset`
"""
return from_text_list(
"""Create an RRset with the specified name and TTL, and with
the specified list of rdata objects.
- *idna_codec*, a ``dns.name.IDNACodec``, specifies the IDNA
- encoder/decoder to use; if ``None``, the default IDNA 2003
- encoder/decoder is used.
-
- Returns a ``dns.rrset.RRset`` object.
-
+ :param idna_codec: Specifies the IDNA encoder/decoder. If ``None``, the
+ default IDNA 2003 encoder/decoder is used.
+ :type idna_codec: :py:class:`dns.name.IDNACodec` or ``None``
+ :rtype: :py:class:`dns.rrset.RRset`
"""
if isinstance(name, str):
"""Create an RRset with the specified name and TTL, and with
the specified rdata objects.
- Returns a ``dns.rrset.RRset`` object.
+ :rtype: :py:class:`dns.rrset.RRset`
"""
return from_rdata_list(name, ttl, cast(Collection[dns.rdata.Rdata], rdatas))
def issubset(self, other):
"""Is this set a subset of *other*?
- Returns a ``bool``.
+ :rtype: bool
"""
if not isinstance(other, Set):
def issuperset(self, other):
"""Is this set a superset of *other*?
- Returns a ``bool``.
+ :rtype: bool
"""
if not isinstance(other, Set):
def writer(self, replacement: bool = False) -> "Transaction":
"""Begin a writable transaction.
- *replacement*, a ``bool``. If `True`, the content of the
- transaction completely replaces any prior content. If False,
- the default, then the content of the transaction updates the
- existing content.
+ :param bool replacement: If ``True``, the content of the transaction
+ completely replaces any prior content. If ``False`` (the default),
+ the content of the transaction updates the existing content.
"""
raise NotImplementedError # pragma: no cover
def origin_information(
self,
) -> tuple[dns.name.Name | None, bool, dns.name.Name | None]:
- """Returns a tuple
-
- (absolute_origin, relativize, effective_origin)
-
- giving the absolute name of the default origin for any
- relative domain names, the "effective origin", and whether
- names should be relativized. The "effective origin" is the
- absolute origin if relativize is False, and the empty name if
- relativize is true. (The effective origin is provided even
- though it can be computed from the absolute_origin and
- relativize setting because it avoids a lot of code
- duplication.)
-
- If the returned names are `None`, then no origin information is
- available.
+ """Return origin information for the transaction manager.
This information is used by code working with transactions to
allow it to coordinate relativization. The transaction code
itself takes what it gets (i.e. does not change name
relativity).
+ :returns: A tuple ``(absolute_origin, relativize, effective_origin)``
+ giving the absolute name of the default origin for any relative
+ domain names, whether names should be relativized, and the
+ "effective origin". The effective origin is the absolute origin if
+ *relativize* is ``False``, and the empty name if *relativize* is
+ ``True``. (The effective origin is provided even though it can be
+ computed from the absolute origin and relativize setting because it
+ avoids a lot of code duplication.) If the returned names are
+ ``None``, then no origin information is available.
+ :rtype: tuple[:py:class:`dns.name.Name` or ``None``, bool,
+ :py:class:`dns.name.Name` or ``None``]
"""
raise NotImplementedError # pragma: no cover
covers: dns.rdatatype.RdataType | str = dns.rdatatype.NONE,
) -> dns.rdataset.Rdataset:
"""Return the rdataset associated with *name*, *rdtype*, and *covers*,
- or `None` if not found.
+ or ``None`` if not found.
Note that the returned rdataset is immutable.
"""
def get_node(self, name: dns.name.Name) -> dns.node.Node | None:
"""Return the node at *name*, if any.
- Returns an immutable node or ``None``.
+ :returns: An immutable node, or ``None`` if *name* does not exist.
+ :rtype: :py:class:`dns.node.ImmutableNode` or ``None``
"""
return _ensure_immutable_node(self._get_node(name))
- name, rdata...
- Raises dns.transaction.DeleteNotExact if some of the records
- are not in the existing set.
-
+ :raises: :py:exc:`dns.transaction.DeleteNotExact` if some of the
+ records are not in the existing set.
"""
self._check_ended()
self._check_read_only()
) -> None:
"""Update the serial number.
- *value*, an `int`, is an increment if *relative* is `True`, or the
- actual value to set if *relative* is `False`.
-
- Raises `KeyError` if there is no SOA rdataset at *name*.
-
- Raises `ValueError` if *value* is negative or if the increment is
- so large that it would cause the new serial to be less than the
- prior value.
+ :param int value: An increment if *relative* is ``True``, or the
+ actual value to set if *relative* is ``False``.
+ :param bool relative: Whether *value* is a relative increment or an
+ absolute value. The default is ``True``.
+ :param name: The name of the SOA record to update.
+ :type name: :py:class:`dns.name.Name`
+ :raises KeyError: If there is no SOA rdataset at *name*.
+ :raises ValueError: If *value* is negative or if the increment is
+ so large that it would cause the new serial to be less than the
+ prior value.
"""
self._check_ended()
if value < 0:
def changed(self) -> bool:
"""Has this transaction changed anything?
- For read-only transactions, the result is always `False`.
+ For read-only transactions, the result is always ``False``.
- For writable transactions, the result is `True` if at some time
+ For writable transactions, the result is ``True`` if at some time
during the life of the transaction, the content was changed.
"""
self._check_ended()
Normally transactions are used as context managers and commit
or rollback automatically, but it may be done explicitly if needed.
- A ``dns.transaction.Ended`` exception will be raised if you try
- to use a transaction after it has been committed or rolled back.
- Raises an exception if the commit fails (in which case the transaction
- is also rolled back.
+ :raises: :py:exc:`dns.transaction.AlreadyEnded` if the transaction
+ has already been committed or rolled back.
+ :raises: An exception if the commit fails, in which case the
+ transaction is also rolled back.
"""
self._end(True)
Normally transactions are used as context managers and commit
or rollback automatically, but it may be done explicitly if needed.
- A ``dns.transaction.AlreadyEnded`` exception will be raised if you try
- to use a transaction after it has been committed or rolled back.
-
Rollback cannot otherwise fail.
+
+ :raises: :py:exc:`dns.transaction.AlreadyEnded` if the transaction
+ has already been committed or rolled back.
"""
self._end(False)
self,
) -> Iterator[tuple[dns.name.Name, dns.rdataset.Rdataset]]:
"""Iterate all the rdatasets in the transaction, returning
- (`dns.name.Name`, `dns.rdataset.Rdataset`) tuples.
+ (:py:class:`dns.name.Name`, :py:class:`dns.rdataset.Rdataset`) tuples.
- Note that as is usual with python iterators, adding or removing items
- while iterating will invalidate the iterator and may raise `RuntimeError`
- or fail to iterate over all entries."""
+ Note that as is usual with Python iterators, adding or removing items
+ while iterating will invalidate the iterator and may raise
+ :py:exc:`RuntimeError` or fail to iterate over all entries."""
self._check_ended()
return self._iterate_rdatasets()
def iterate_names(self) -> Iterator[dns.name.Name]:
"""Iterate all the names in the transaction.
- Note that as is usual with python iterators, adding or removing names
- while iterating will invalidate the iterator and may raise `RuntimeError`
- or fail to iterate over all entries."""
+ Note that as is usual with Python iterators, adding or removing names
+ while iterating will invalidate the iterator and may raise
+ :py:exc:`RuntimeError` or fail to iterate over all entries."""
self._check_ended()
return self._iterate_names()
def _get_rdataset(self, name, rdtype, covers):
"""Return the rdataset associated with *name*, *rdtype*, and *covers*,
- or `None` if not found.
+ or ``None`` if not found.
"""
raise NotImplementedError # pragma: no cover
def _name_exists(self, name):
"""Does name exist?
- Returns a bool.
+ :rtype: bool
"""
raise NotImplementedError # pragma: no cover
def _end_transaction(self, commit):
"""End the transaction.
- *commit*, a bool. If ``True``, commit the transaction, otherwise
- roll it back.
-
- If committing and the commit fails, then roll back and raise an
- exception.
+ :param bool commit: If ``True``, commit the transaction; otherwise
+ roll it back. If committing and the commit fails, then roll back
+ and raise an exception.
"""
raise NotImplementedError # pragma: no cover
def _get_node(self, name):
"""Return the node at *name*, if any.
- Returns a node or ``None``.
+ :returns: The node, or ``None`` if *name* does not exist.
+ :rtype: :py:class:`dns.node.Node` or ``None``
"""
raise NotImplementedError # pragma: no cover
The BIND 8 units syntax for TTLs (e.g. '1w6d4h3m10s') is supported.
- *text*, a ``str``, the textual TTL.
-
- Raises ``dns.ttl.BadTTL`` if the TTL is not well-formed.
-
- Returns an ``int``.
+ :param text: The textual TTL.
+ :type text: str
+ :raises dns.ttl.BadTTL: If the TTL is not well-formed.
+ :rtype: int
"""
if text.isdigit():
See the documentation of the Message class for a complete
description of the keyring dictionary.
- *zone*, a ``dns.name.Name``, ``str``, or ``None``, the zone
- which is being updated. ``None`` should only be used by dnspython's
- message constructors, as a zone is required for the convenience
- methods like ``add()``, ``replace()``, etc.
-
- *rdclass*, an ``int`` or ``str``, the class of the zone.
+ :param zone: The zone which is being updated. ``None`` should only be
+ used by dnspython's message constructors, as a zone is required for
+ the convenience methods like ``add()``, ``replace()``, etc.
+ :type zone: :py:class:`dns.name.Name`, str, or ``None``
+ :param rdclass: The class of the zone.
+ :type rdclass: int or str
The *keyring*, *keyname*, and *keyalgorithm* parameters are passed to
``use_tsig()``; see its documentation for details.
):
"""Initialize a versioned zone object.
- *origin* is the origin of the zone. It may be a ``dns.name.Name``,
- a ``str``, or ``None``. If ``None``, then the zone's origin will
- be set by the first ``$ORIGIN`` line in a zone file.
-
- *rdclass*, an ``int``, the zone's rdata class; the default is class IN.
-
- *relativize*, a ``bool``, determine's whether domain names are
- relativized to the zone's origin. The default is ``True``.
-
- *pruning policy*, a function taking a ``Zone`` and a ``Version`` and returning
- a ``bool``, or ``None``. Should the version be pruned? If ``None``,
- the default policy, which retains one version is used.
+ :param origin: The origin of the zone. It may be a
+ :py:class:`dns.name.Name`, a ``str``, or ``None``. If ``None``,
+ then the zone's origin will be set by the first ``$ORIGIN`` line
+ in a zone file.
+ :type origin: :py:class:`dns.name.Name`, str, or ``None``
+ :param rdclass: The zone's rdata class; the default is class IN.
+ :type rdclass: :py:class:`dns.rdataclass.RdataClass`
+ :param bool relativize: Whether domain names are relativized to the
+ zone's origin. The default is ``True``.
+ :param pruning_policy: A callable taking a
+ :py:class:`dns.versioned.Zone` and a :py:class:`dns.zone.Version`
+ and returning a ``bool`` if the version should be pruned. If
+ ``None``, the default policy (retain one version) is used.
+ :type pruning_policy: Callable or ``None``
"""
super().__init__(origin, rdclass, relativize)
self._versions: collections.deque[Version] = collections.deque()
def set_max_versions(self, max_versions: int | None) -> None:
"""Set a pruning policy that retains up to the specified number
- of versions
+ of versions.
+
+ :param max_versions: The maximum number of versions to retain, or
+ ``None`` for no limit.
+ :type max_versions: int or ``None``
"""
if max_versions is not None and max_versions < 1:
raise ValueError("max versions must be at least 1")
) -> None:
"""Set the pruning policy for the zone.
- The *policy* function takes a `Version` and returns `True` if
- the version should be pruned, and `False` otherwise. `None`
- may also be specified for policy, in which case the default policy
- is used.
+ The *policy* function takes a :py:class:`dns.zone.Version` and returns
+ ``True`` if the version should be pruned, and ``False`` otherwise.
+ ``None`` may also be specified for policy, in which case the default
+ policy is used.
Pruning checking proceeds from the least version and the first
- time the function returns `False`, the checking stops. I.e. the
+ time the function returns ``False``, the checking stops. I.e. the
retained versions are always a consecutive sequence.
+
+ :param policy: The pruning policy callable, or ``None`` to use the
+ default policy.
+ :type policy: Callable or ``None``
"""
if policy is None:
policy = self._default_pruning_policy
"""Helper class for parsing DNS wire format."""
def __init__(self, wire: bytes, current: int = 0):
- """Initialize a Parser
+ """Initialize a Parser.
- *wire*, a ``bytes`` contains the data to be parsed, and possibly other data.
- Typically it is the whole message or a slice of it.
-
- *current*, an `int`, the offset within *wire* where parsing should begin.
+ :param wire: The data to be parsed (typically a whole message or a slice of it).
+ :type wire: bytes
+ :param current: The offset within *wire* where parsing should begin.
+ :type current: int
"""
self.wire = wire
self.current = 0
*serial* is the base serial number for IXFRs, and is required in
that case.
- *is_udp*, a ``bool`` indidicates if UDP is being used for this
- XFR.
+ :param is_udp: Whether UDP is being used for this XFR.
+ :type is_udp: bool
"""
self.txn_manager = txn_manager
self.txn: dns.transaction.Transaction | None = None
) -> tuple[dns.message.QueryMessage, int | None]:
"""Make an AXFR or IXFR query.
- *txn_manager* is a ``dns.transaction.TransactionManager``, typically a
- ``dns.zone.Zone``.
-
- *serial* is an ``int`` or ``None``. If 0, then IXFR will be
- attempted using the most recent serial number from the
- *txn_manager*; it is the caller's responsibility to ensure there
- are no write transactions active that could invalidate the
- retrieved serial. If a serial cannot be determined, AXFR will be
- forced. Other integer values are the starting serial to use.
- ``None`` forces an AXFR.
+ :param txn_manager: The transaction manager for this transfer, typically
+ a :py:class:`dns.zone.Zone`.
+ :type txn_manager: :py:class:`dns.transaction.TransactionManager`
+ :param serial: If ``0``, IXFR is attempted using the most recent serial
+ from *txn_manager* (caller must ensure no write transactions are
+ active that could invalidate the retrieved serial). If a serial
+ cannot be determined, AXFR is forced. Other integer values are the
+ starting serial to use. ``None`` forces an AXFR.
+ :type serial: int or ``None``
Please see the documentation for :py:func:`dns.message.make_query` and
:py:func:`dns.message.Message.use_tsig` for details on the other parameters
to this function.
- Returns a `(query, serial)` tuple.
+ :returns: A ``(query, serial)`` tuple.
+ :rtype: tuple
"""
zone_origin, _, origin = txn_manager.origin_information()
if zone_origin is None:
@dataclasses.dataclass(frozen=True)
class ZoneStyle(dns.node.NodeStyle):
- """Zone text styles
+ """Zone text styles.
- A ``ZoneStyle`` is also a :py:class:`dns.name.NameStyle` and a
- :py:class:`dns.rdata.RdataStyle`, a :py:class:`dns.rdataset.RdatasetStyle`,
- and a :py:class:`dns.node.NodeStyle`.
+ A :py:class:`dns.zone.ZoneStyle` is also a :py:class:`dns.name.NameStyle`,
+ :py:class:`dns.rdata.RdataStyle`, :py:class:`dns.rdataset.RdatasetStyle`,
+ and :py:class:`dns.node.NodeStyle`.
See those classes for a description of their options.
- *sorted*, a ``bool``. If True, the default, then the file
- will be written with the names sorted in DNSSEC order from
- least to greatest. Otherwise the names will be written in
- whatever order they happen to have in the zone's dictionary.
-
- *nl*, a ``str`` or ``None`` (the default). The end of line string,
- or if ``None``, the output will use the platform's native
- end-of-line marker (i.e. LF on POSIX, CRLF on Windows).
-
- *want_origin*, a ``bool``. If ``True``, emit a $ORIGIN line at
- the start of the output. If ``False``, the default, do not emit
- one.
-
- *want_unicode_directive*, a ``bool``. If ``True`` and the zone
- has a non-empty ``unicode`` attribute, then emit a ``$UNICODE``
- line in the output. This directive is not standard, but allows
- dnspython and other aware software to read and write Unicode zonefiles
- without changing the rendering of names and TXT-like records.
+ :param bool sorted: If ``True`` (the default), the file will be written
+ with the names sorted in DNSSEC order from least to greatest.
+ Otherwise the names will be written in whatever order they happen
+ to have in the zone's dictionary.
+ :param nl: The end of line string. If ``None`` (the default), the
+ output will use the platform's native end-of-line marker (i.e. LF
+ on POSIX, CRLF on Windows).
+ :type nl: str or ``None``
+ :param bool want_origin: If ``True``, emit a ``$ORIGIN`` line at the
+ start of the output. If ``False`` (the default), do not emit one.
+ :param bool want_unicode_directive: If ``True`` and the zone has a
+ non-empty ``unicode`` attribute, then emit a ``$UNICODE`` line in
+ the output. This directive is not standard, but allows dnspython
+ and other aware software to read and write Unicode zonefiles without
+ changing the rendering of names and TXT-like records.
"""
sorted: bool = True
):
"""Initialize a zone object.
- *origin* is the origin of the zone. It may be a ``dns.name.Name``,
- a ``str``, or ``None``. If ``None``, then the zone's origin will
- be set by the first ``$ORIGIN`` line in a zone file.
-
- *rdclass*, an ``int``, the zone's rdata class; the default is class IN.
-
- *relativize*, a ``bool``, determine's whether domain names are
- relativized to the zone's origin. The default is ``True``.
+ :param origin: The origin of the zone. It may be a
+ :py:class:`dns.name.Name`, a ``str``, or ``None``. If ``None``,
+ then the zone's origin will be set by the first ``$ORIGIN`` line
+ in a zone file.
+ :type origin: :py:class:`dns.name.Name`, str, or ``None``
+ :param rdclass: The zone's rdata class; the default is class IN.
+ :type rdclass: :py:class:`dns.rdataclass.RdataClass`
+ :param bool relativize: Whether domain names are relativized to the
+ zone's origin. The default is ``True``.
"""
if origin is not None:
"""Two zones are equal if they have the same origin, class, and
nodes.
- Returns a ``bool``.
+ :rtype: bool
"""
if not isinstance(other, Zone):
def __ne__(self, other):
"""Are two zones not equal?
- Returns a ``bool``.
+ :rtype: bool
"""
return not self.__eq__(other)
) -> dns.node.Node:
"""Find a node in the zone, possibly creating it.
- *name*: the name of the node to find.
- The value may be a ``dns.name.Name`` or a ``str``. If absolute, the
- name must be a subdomain of the zone's origin. If ``zone.relativize``
- is ``True``, then the name will be relativized.
-
- *create*, a ``bool``. If true, the node will be created if it does
- not exist.
-
- Raises ``KeyError`` if the name is not known and create was
- not specified, or if the name was not a subdomain of the origin.
-
- Returns a ``dns.node.Node``.
+ :param name: The name of the node to find. The value may be a
+ :py:class:`dns.name.Name` or a ``str``. If absolute, the name
+ must be a subdomain of the zone's origin. If ``zone.relativize``
+ is ``True``, then the name will be relativized.
+ :type name: :py:class:`dns.name.Name` or str
+ :param bool create: If ``True``, the node will be created if it does
+ not exist.
+ :raises KeyError: if the name is not known and *create* was not
+ specified, or if the name was not a subdomain of the origin.
+ :rtype: :py:class:`dns.node.Node`
"""
name = self._validate_name(name)
) -> dns.node.Node | None:
"""Get a node in the zone, possibly creating it.
- This method is like ``find_node()``, except it returns None instead
- of raising an exception if the node does not exist and creation
- has not been requested.
-
- *name*: the name of the node to find.
- The value may be a ``dns.name.Name`` or a ``str``. If absolute, the
- name must be a subdomain of the zone's origin. If ``zone.relativize``
- is ``True``, then the name will be relativized.
-
- *create*, a ``bool``. If true, the node will be created if it does
- not exist.
-
- Returns a ``dns.node.Node`` or ``None``.
+ This method is like :py:meth:`find_node`, except it returns ``None``
+ instead of raising an exception if the node does not exist and
+ creation has not been requested.
+
+ :param name: The name of the node to find. The value may be a
+ :py:class:`dns.name.Name` or a ``str``. If absolute, the name
+ must be a subdomain of the zone's origin. If ``zone.relativize``
+ is ``True``, then the name will be relativized.
+ :type name: :py:class:`dns.name.Name` or str
+ :param bool create: If ``True``, the node will be created if it does
+ not exist.
+ :rtype: :py:class:`dns.node.Node` or ``None``
"""
try:
def delete_node(self, name: dns.name.Name | str) -> None:
"""Delete the specified node if it exists.
- *name*: the name of the node to find.
- The value may be a ``dns.name.Name`` or a ``str``. If absolute, the
- name must be a subdomain of the zone's origin. If ``zone.relativize``
- is ``True``, then the name will be relativized.
-
It is not an error if the node does not exist.
+
+ :param name: The name of the node to delete. The value may be a
+ :py:class:`dns.name.Name` or a ``str``. If absolute, the name
+ must be a subdomain of the zone's origin. If ``zone.relativize``
+ is ``True``, then the name will be relativized.
+ :type name: :py:class:`dns.name.Name` or str
"""
name = self._validate_name(name)
The rdataset returned is not a copy; changes to it will change
the zone.
- KeyError is raised if the name or type are not found.
-
- *name*: the name of the node to find.
- The value may be a ``dns.name.Name`` or a ``str``. If absolute, the
- name must be a subdomain of the zone's origin. If ``zone.relativize``
- is ``True``, then the name will be relativized.
-
- *rdtype*, a ``dns.rdatatype.RdataType`` or ``str``, the rdata type desired.
-
- *covers*, a ``dns.rdatatype.RdataType`` or ``str`` the covered type.
- Usually this value is ``dns.rdatatype.NONE``, but if the
- rdtype is ``dns.rdatatype.SIG`` or ``dns.rdatatype.RRSIG``,
- then the covers value will be the rdata type the SIG/RRSIG
- covers. The library treats the SIG and RRSIG types as if they
- were a family of types, e.g. RRSIG(A), RRSIG(NS), RRSIG(SOA).
- This makes RRSIGs much easier to work with than if RRSIGs
- covering different rdata types were aggregated into a single
- RRSIG rdataset.
-
- *create*, a ``bool``. If true, the node will be created if it does
- not exist.
-
- Raises ``KeyError`` if the name is not known and create was
- not specified, or if the name was not a subdomain of the origin.
-
- Returns a ``dns.rdataset.Rdataset``.
+ :param name: The name of the node to find. The value may be a
+ :py:class:`dns.name.Name` or a ``str``. If absolute, the name
+ must be a subdomain of the zone's origin. If ``zone.relativize``
+ is ``True``, then the name will be relativized.
+ :type name: :py:class:`dns.name.Name` or str
+ :param rdtype: The rdata type desired.
+ :type rdtype: :py:class:`dns.rdatatype.RdataType` or str
+ :param covers: The covered type. Usually :py:attr:`dns.rdatatype.NONE`,
+ but if *rdtype* is :py:attr:`dns.rdatatype.SIG` or
+ :py:attr:`dns.rdatatype.RRSIG`, then this is the rdata type the
+ SIG/RRSIG covers. The library treats the SIG and RRSIG types as
+ a family of types, e.g. RRSIG(A), RRSIG(NS), RRSIG(SOA).
+ :type covers: :py:class:`dns.rdatatype.RdataType` or str
+ :param bool create: If ``True``, the node will be created if it does
+ not exist.
+ :raises KeyError: if the name or type are not found and *create* was
+ not specified, or if the name was not a subdomain of the origin.
+ :rtype: :py:class:`dns.rdataset.Rdataset`
"""
name = self._validate_name(name)
) -> dns.rdataset.Rdataset | None:
"""Look for an rdataset with the specified name and type in the zone.
- This method is like ``find_rdataset()``, except it returns None instead
- of raising an exception if the rdataset does not exist and creation
- has not been requested.
+ This method is like :py:meth:`find_rdataset`, except it returns
+ ``None`` instead of raising an exception if the rdataset does not
+ exist and creation has not been requested.
The rdataset returned is not a copy; changes to it will change
the zone.
- *name*: the name of the node to find.
- The value may be a ``dns.name.Name`` or a ``str``. If absolute, the
- name must be a subdomain of the zone's origin. If ``zone.relativize``
- is ``True``, then the name will be relativized.
-
- *rdtype*, a ``dns.rdatatype.RdataType`` or ``str``, the rdata type desired.
-
- *covers*, a ``dns.rdatatype.RdataType`` or ``str``, the covered type.
- Usually this value is ``dns.rdatatype.NONE``, but if the
- rdtype is ``dns.rdatatype.SIG`` or ``dns.rdatatype.RRSIG``,
- then the covers value will be the rdata type the SIG/RRSIG
- covers. The library treats the SIG and RRSIG types as if they
- were a family of types, e.g. RRSIG(A), RRSIG(NS), RRSIG(SOA).
- This makes RRSIGs much easier to work with than if RRSIGs
- covering different rdata types were aggregated into a single
- RRSIG rdataset.
-
- *create*, a ``bool``. If true, the node will be created if it does
- not exist.
-
- Raises ``KeyError`` if the name is not known and create was
- not specified, or if the name was not a subdomain of the origin.
-
- Returns a ``dns.rdataset.Rdataset`` or ``None``.
+ :param name: The name of the node to find. The value may be a
+ :py:class:`dns.name.Name` or a ``str``. If absolute, the name
+ must be a subdomain of the zone's origin. If ``zone.relativize``
+ is ``True``, then the name will be relativized.
+ :type name: :py:class:`dns.name.Name` or str
+ :param rdtype: The rdata type desired.
+ :type rdtype: :py:class:`dns.rdatatype.RdataType` or str
+ :param covers: The covered type. Usually :py:attr:`dns.rdatatype.NONE`,
+ but if *rdtype* is :py:attr:`dns.rdatatype.SIG` or
+ :py:attr:`dns.rdatatype.RRSIG`, then this is the rdata type the
+ SIG/RRSIG covers. The library treats the SIG and RRSIG types as
+ a family of types, e.g. RRSIG(A), RRSIG(NS), RRSIG(SOA).
+ :type covers: :py:class:`dns.rdatatype.RdataType` or str
+ :param bool create: If ``True``, the node will be created if it does
+ not exist.
+ :rtype: :py:class:`dns.rdataset.Rdataset` or ``None``
"""
try:
"""Delete the rdataset matching *rdtype* and *covers*, if it
exists at the node specified by *name*.
- It is not an error if the node does not exist, or if there is no matching
- rdataset at the node.
-
- If the node has no rdatasets after the deletion, it will itself be deleted.
-
- *name*: the name of the node to find. The value may be a ``dns.name.Name`` or a
- ``str``. If absolute, the name must be a subdomain of the zone's origin. If
- ``zone.relativize`` is ``True``, then the name will be relativized.
-
- *rdtype*, a ``dns.rdatatype.RdataType`` or ``str``, the rdata type desired.
-
- *covers*, a ``dns.rdatatype.RdataType`` or ``str`` or ``None``, the covered
- type. Usually this value is ``dns.rdatatype.NONE``, but if the rdtype is
- ``dns.rdatatype.SIG`` or ``dns.rdatatype.RRSIG``, then the covers value will be
- the rdata type the SIG/RRSIG covers. The library treats the SIG and RRSIG types
- as if they were a family of types, e.g. RRSIG(A), RRSIG(NS), RRSIG(SOA). This
- makes RRSIGs much easier to work with than if RRSIGs covering different rdata
- types were aggregated into a single RRSIG rdataset.
+ It is not an error if the node does not exist, or if there is no
+ matching rdataset at the node. If the node has no rdatasets after
+ the deletion, it will itself be deleted.
+
+ :param name: The name of the node. The value may be a
+ :py:class:`dns.name.Name` or a ``str``. If absolute, the name
+ must be a subdomain of the zone's origin. If ``zone.relativize``
+ is ``True``, then the name will be relativized.
+ :type name: :py:class:`dns.name.Name` or str
+ :param rdtype: The rdata type desired.
+ :type rdtype: :py:class:`dns.rdatatype.RdataType` or str
+ :param covers: The covered type. Usually :py:attr:`dns.rdatatype.NONE`,
+ but if *rdtype* is :py:attr:`dns.rdatatype.SIG` or
+ :py:attr:`dns.rdatatype.RRSIG`, then this is the rdata type the
+ SIG/RRSIG covers. The library treats the SIG and RRSIG types as
+ a family of types, e.g. RRSIG(A), RRSIG(NS), RRSIG(SOA).
+ :type covers: :py:class:`dns.rdatatype.RdataType` or str
"""
name = self._validate_name(name)
) -> None:
"""Replace an rdataset at name.
- It is not an error if there is no rdataset matching I{replacement}.
+ It is not an error if there is no rdataset matching *replacement*.
Ownership of the *replacement* object is transferred to the zone;
in other words, this method does not store a copy of *replacement*
- at the node, it stores *replacement* itself.
-
- If the node does not exist, it is created.
-
- *name*: the name of the node to find.
- The value may be a ``dns.name.Name`` or a ``str``. If absolute, the
- name must be a subdomain of the zone's origin. If ``zone.relativize``
- is ``True``, then the name will be relativized.
-
- *replacement*, a ``dns.rdataset.Rdataset``, the replacement rdataset.
+ at the node, it stores *replacement* itself. If the node does not
+ exist, it is created.
+
+ :param name: The name of the node. The value may be a
+ :py:class:`dns.name.Name` or a ``str``. If absolute, the name
+ must be a subdomain of the zone's origin. If ``zone.relativize``
+ is ``True``, then the name will be relativized.
+ :type name: :py:class:`dns.name.Name` or str
+ :param replacement: The replacement rdataset.
+ :type replacement: :py:class:`dns.rdataset.Rdataset`
"""
if replacement.rdclass != self.rdclass:
and return an RRset encapsulating it.
This method is less efficient than the similar
- ``find_rdataset()`` because it creates an RRset instead of
- returning the matching rdataset. It may be more convenient
- for some uses since it returns an object which binds the owner
- name to the rdataset.
+ :py:meth:`find_rdataset` because it creates an RRset instead of
+ returning the matching rdataset. It may be more convenient for some
+ uses since it returns an object which binds the owner name to the
+ rdataset.
This method may not be used to create new nodes or rdatasets;
- use ``find_rdataset`` instead.
-
- *name*: the name of the node to find.
- The value may be a ``dns.name.Name`` or a ``str``. If absolute, the
- name must be a subdomain of the zone's origin. If ``zone.relativize``
- is ``True``, then the name will be relativized.
-
- *rdtype*, a ``dns.rdatatype.RdataType`` or ``str``, the rdata type desired.
-
- *covers*, a ``dns.rdatatype.RdataType`` or ``str``, the covered type.
- Usually this value is ``dns.rdatatype.NONE``, but if the
- rdtype is ``dns.rdatatype.SIG`` or ``dns.rdatatype.RRSIG``,
- then the covers value will be the rdata type the SIG/RRSIG
- covers. The library treats the SIG and RRSIG types as if they
- were a family of types, e.g. RRSIG(A), RRSIG(NS), RRSIG(SOA).
- This makes RRSIGs much easier to work with than if RRSIGs
- covering different rdata types were aggregated into a single
- RRSIG rdataset.
-
- *create*, a ``bool``. If true, the node will be created if it does
- not exist.
-
- Raises ``KeyError`` if the name is not known and create was
- not specified, or if the name was not a subdomain of the origin.
-
- Returns a ``dns.rrset.RRset`` or ``None``.
+ use :py:meth:`find_rdataset` instead.
+
+ :param name: The name of the node to find. The value may be a
+ :py:class:`dns.name.Name` or a ``str``. If absolute, the name
+ must be a subdomain of the zone's origin. If ``zone.relativize``
+ is ``True``, then the name will be relativized.
+ :type name: :py:class:`dns.name.Name` or str
+ :param rdtype: The rdata type desired.
+ :type rdtype: :py:class:`dns.rdatatype.RdataType` or str
+ :param covers: The covered type. Usually :py:attr:`dns.rdatatype.NONE`,
+ but if *rdtype* is :py:attr:`dns.rdatatype.SIG` or
+ :py:attr:`dns.rdatatype.RRSIG`, then this is the rdata type the
+ SIG/RRSIG covers. The library treats the SIG and RRSIG types as
+ a family of types, e.g. RRSIG(A), RRSIG(NS), RRSIG(SOA).
+ :type covers: :py:class:`dns.rdatatype.RdataType` or str
+ :raises KeyError: if the name or type are not found, or if the name
+ was not a subdomain of the origin.
+ :rtype: :py:class:`dns.rrset.RRset`
"""
vname = self._validate_name(name)
"""Look for an rdataset with the specified name and type in the zone,
and return an RRset encapsulating it.
- This method is less efficient than the similar ``get_rdataset()``
+ This method is less efficient than the similar :py:meth:`get_rdataset`
because it creates an RRset instead of returning the matching
- rdataset. It may be more convenient for some uses since it
- returns an object which binds the owner name to the rdataset.
+ rdataset. It may be more convenient for some uses since it returns
+ an object which binds the owner name to the rdataset.
This method may not be used to create new nodes or rdatasets;
- use ``get_rdataset()`` instead.
-
- *name*: the name of the node to find.
- The value may be a ``dns.name.Name`` or a ``str``. If absolute, the
- name must be a subdomain of the zone's origin. If ``zone.relativize``
- is ``True``, then the name will be relativized.
-
- *rdtype*, a ``dns.rdataset.Rdataset`` or ``str``, the rdata type desired.
-
- *covers*, a ``dns.rdataset.Rdataset`` or ``str``, the covered type.
- Usually this value is ``dns.rdatatype.NONE``, but if the
- rdtype is ``dns.rdatatype.SIG`` or ``dns.rdatatype.RRSIG``,
- then the covers value will be the rdata type the SIG/RRSIG
- covers. The library treats the SIG and RRSIG types as if they
- were a family of types, e.g. RRSIG(A), RRSIG(NS), RRSIG(SOA).
- This makes RRSIGs much easier to work with than if RRSIGs
- covering different rdata types were aggregated into a single
- RRSIG rdataset.
-
- *create*, a ``bool``. If true, the node will be created if it does
- not exist.
-
- Returns a ``dns.rrset.RRset`` or ``None``.
+ use :py:meth:`get_rdataset` instead.
+
+ :param name: The name of the node to find. The value may be a
+ :py:class:`dns.name.Name` or a ``str``. If absolute, the name
+ must be a subdomain of the zone's origin. If ``zone.relativize``
+ is ``True``, then the name will be relativized.
+ :type name: :py:class:`dns.name.Name` or str
+ :param rdtype: The rdata type desired.
+ :type rdtype: :py:class:`dns.rdatatype.RdataType` or str
+ :param covers: The covered type. Usually :py:attr:`dns.rdatatype.NONE`,
+ but if *rdtype* is :py:attr:`dns.rdatatype.SIG` or
+ :py:attr:`dns.rdatatype.RRSIG`, then this is the rdata type the
+ SIG/RRSIG covers. The library treats the SIG and RRSIG types as
+ a family of types, e.g. RRSIG(A), RRSIG(NS), RRSIG(SOA).
+ :type covers: :py:class:`dns.rdatatype.RdataType` or str
+ :rtype: :py:class:`dns.rrset.RRset` or ``None``
"""
try:
rdtype: dns.rdatatype.RdataType | str = dns.rdatatype.ANY,
covers: dns.rdatatype.RdataType | str = dns.rdatatype.NONE,
) -> Iterator[tuple[dns.name.Name, dns.rdataset.Rdataset]]:
- """Return a generator which yields (name, rdataset) tuples for
- all rdatasets in the zone which have the specified *rdtype*
- and *covers*. If *rdtype* is ``dns.rdatatype.ANY``, the default,
+ """Return a generator which yields ``(name, rdataset)`` tuples for
+ all rdatasets in the zone which have the specified *rdtype* and
+ *covers*. If *rdtype* is :py:attr:`dns.rdatatype.ANY` (the default),
then all rdatasets will be matched.
- *rdtype*, a ``dns.rdataset.Rdataset`` or ``str``, the rdata type desired.
-
- *covers*, a ``dns.rdataset.Rdataset`` or ``str``, the covered type.
- Usually this value is ``dns.rdatatype.NONE``, but if the
- rdtype is ``dns.rdatatype.SIG`` or ``dns.rdatatype.RRSIG``,
- then the covers value will be the rdata type the SIG/RRSIG
- covers. The library treats the SIG and RRSIG types as if they
- were a family of types, e.g. RRSIG(A), RRSIG(NS), RRSIG(SOA).
- This makes RRSIGs much easier to work with than if RRSIGs
- covering different rdata types were aggregated into a single
- RRSIG rdataset.
+ :param rdtype: The rdata type desired.
+ :type rdtype: :py:class:`dns.rdatatype.RdataType` or str
+ :param covers: The covered type. Usually :py:attr:`dns.rdatatype.NONE`,
+ but if *rdtype* is :py:attr:`dns.rdatatype.SIG` or
+ :py:attr:`dns.rdatatype.RRSIG`, then this is the rdata type the
+ SIG/RRSIG covers. The library treats the SIG and RRSIG types as
+ a family of types, e.g. RRSIG(A), RRSIG(NS), RRSIG(SOA).
+ :type covers: :py:class:`dns.rdatatype.RdataType` or str
"""
rdtype = dns.rdatatype.RdataType.make(rdtype)
rdtype: dns.rdatatype.RdataType | str = dns.rdatatype.ANY,
covers: dns.rdatatype.RdataType | str = dns.rdatatype.NONE,
) -> Iterator[tuple[dns.name.Name, int, dns.rdata.Rdata]]:
- """Return a generator which yields (name, ttl, rdata) tuples for
- all rdatas in the zone which have the specified *rdtype*
- and *covers*. If *rdtype* is ``dns.rdatatype.ANY``, the default,
- then all rdatas will be matched.
-
- *rdtype*, a ``dns.rdataset.Rdataset`` or ``str``, the rdata type desired.
-
- *covers*, a ``dns.rdataset.Rdataset`` or ``str``, the covered type.
- Usually this value is ``dns.rdatatype.NONE``, but if the
- rdtype is ``dns.rdatatype.SIG`` or ``dns.rdatatype.RRSIG``,
- then the covers value will be the rdata type the SIG/RRSIG
- covers. The library treats the SIG and RRSIG types as if they
- were a family of types, e.g. RRSIG(A), RRSIG(NS), RRSIG(SOA).
- This makes RRSIGs much easier to work with than if RRSIGs
- covering different rdata types were aggregated into a single
- RRSIG rdataset.
+ """Return a generator which yields ``(name, ttl, rdata)`` tuples for
+ all rdatas in the zone which have the specified *rdtype* and *covers*.
+ If *rdtype* is :py:attr:`dns.rdatatype.ANY` (the default), then all
+ rdatas will be matched.
+
+ :param rdtype: The rdata type desired.
+ :type rdtype: :py:class:`dns.rdatatype.RdataType` or str
+ :param covers: The covered type. Usually :py:attr:`dns.rdatatype.NONE`,
+ but if *rdtype* is :py:attr:`dns.rdatatype.SIG` or
+ :py:attr:`dns.rdatatype.RRSIG`, then this is the rdata type the
+ SIG/RRSIG covers. The library treats the SIG and RRSIG types as
+ a family of types, e.g. RRSIG(A), RRSIG(NS), RRSIG(SOA).
+ :type covers: :py:class:`dns.rdatatype.RdataType` or str
"""
rdtype = dns.rdatatype.RdataType.make(rdtype)
) -> None:
"""Write a zone to a file.
- *f*, a file or `str`. If *f* is a string, it is treated
- as the name of a file to open.
-
- *sorted*, a ``bool``. If True, the default, then the file
- will be written with the names sorted in DNSSEC order from
- least to greatest. Otherwise the names will be written in
- whatever order they happen to have in the zone's dictionary.
-
- *relativize*, a ``bool``. If True, the default, then domain
- names in the output will be relativized to the zone's origin
- if possible.
-
- *nl*, a ``str``, ``bytes``, or None. The end of line string. If not
- ``None``, the output will use the platform's native
- end-of-line marker (i.e. LF on POSIX, CRLF on Windows).
-
- *want_comments*, a ``bool``. If ``True``, emit end-of-line comments
- as part of writing the file. If ``False``, the default, do not
- emit them.
-
- *want_origin*, a ``bool``. If ``True``, emit a $ORIGIN line at
- the start of the file. If ``False``, the default, do not emit
- one.
+ :param f: A file object or a ``str`` filename. If a string, it is
+ treated as the name of a file to open.
+ :param bool sorted: If ``True`` (the default), the file will be
+ written with the names sorted in DNSSEC order from least to
+ greatest. Otherwise the names will be written in whatever order
+ they happen to have in the zone's dictionary.
+ :param bool relativize: If ``True`` (the default), domain names in
+ the output will be relativized to the zone's origin if possible.
+ :param nl: The end of line string. If ``None`` (the default), the
+ output will use the platform's native end-of-line marker (i.e. LF
+ on POSIX, CRLF on Windows).
+ :type nl: str, bytes, or ``None``
+ :param bool want_comments: If ``True``, emit end-of-line comments as
+ part of writing the file. If ``False`` (the default), do not
+ emit them.
+ :param bool want_origin: If ``True``, emit a ``$ORIGIN`` line at the
+ start of the file. If ``False`` (the default), do not emit one.
+ :param style: If specified, the style overrides the other parameters.
+ :type style: :py:class:`dns.zone.ZoneStyle` or ``None``
"""
if style is None:
kw = {}
) -> None:
"""Write a zone to a styled file.
- *f*, a file or `str`. If *f* is a string, it is treated
- as the name of a file to open.
+ :param style: The style to apply.
+ :type style: :py:class:`dns.zone.ZoneStyle`
+ :param f: A file object or a ``str`` filename. If a string, it is
+ treated as the name of a file to open.
"""
# Apply style items we learned from $UNICODE when we loaded the zone (if any).
) -> str:
"""Return a zone's text as though it were written to a file.
- *sorted*, a ``bool``. If True, the default, then the file
- will be written with the names sorted in DNSSEC order from
- least to greatest. Otherwise the names will be written in
- whatever order they happen to have in the zone's dictionary.
-
- *relativize*, a ``bool``. If True, the default, then domain
- names in the output will be relativized to the zone's origin
- if possible.
-
- *nl*, a ``str`` or None. The end of line string. If not
- ``None``, the output will use the platform's native
- end-of-line marker (i.e. LF on POSIX, CRLF on Windows).
-
- *want_comments*, a ``bool``. If ``True``, emit end-of-line comments
- as part of writing the file. If ``False``, the default, do not
- emit them.
-
- *want_origin*, a ``bool``. If ``True``, emit a $ORIGIN line at
- the start of the output. If ``False``, the default, do not emit
- one.
-
- *style*, a :py:class:`dns.zone.ZoneStyle` or ``None`` (the default). If specified,
- the style overrides the other parameters.
-
- Returns a ``str``.
+ :param bool sorted: If ``True`` (the default), the output will be
+ written with the names sorted in DNSSEC order from least to
+ greatest. Otherwise the names will be written in whatever order
+ they happen to have in the zone's dictionary.
+ :param bool relativize: If ``True`` (the default), domain names in
+ the output will be relativized to the zone's origin if possible.
+ :param nl: The end of line string. If ``None`` (the default), the
+ output will use the platform's native end-of-line marker (i.e. LF
+ on POSIX, CRLF on Windows).
+ :type nl: str or ``None``
+ :param bool want_comments: If ``True``, emit end-of-line comments as
+ part of the output. If ``False`` (the default), do not emit them.
+ :param bool want_origin: If ``True``, emit a ``$ORIGIN`` line at the
+ start of the output. If ``False`` (the default), do not emit one.
+ :param style: If specified, the style overrides the other parameters.
+ :type style: :py:class:`dns.zone.ZoneStyle` or ``None``
+ :rtype: str
"""
temp_buffer = io.StringIO()
self.to_file(temp_buffer, sorted, relativize, nl, want_comments, want_origin)
See the documentation for :py:class:`dns.zone.ZoneStyle` for a description
of the style parameters.
+
+ :param style: The style to apply.
+ :type style: :py:class:`dns.zone.ZoneStyle`
+ :rtype: str
"""
temp_buffer = io.StringIO()
def check_origin(self) -> None:
"""Do some simple checking of the zone's origin.
- Raises ``dns.zone.NoSOA`` if there is no SOA RRset.
-
- Raises ``dns.zone.NoNS`` if there is no NS RRset.
-
- Raises ``KeyError`` if there is no origin node.
+ :raises dns.zone.NoSOA: if there is no SOA RRset.
+ :raises dns.zone.NoNS: if there is no NS RRset.
+ :raises KeyError: if there is no origin node.
"""
if self.relativize:
name = dns.name.empty
) -> dns.rdtypes.ANY.SOA.SOA:
"""Get the zone SOA rdata.
- Raises ``dns.zone.NoSOA`` if there is no SOA RRset.
-
- Returns a ``dns.rdtypes.ANY.SOA.SOA`` Rdata.
+ :raises dns.zone.NoSOA: if there is no SOA RRset.
+ :rtype: :py:class:`dns.rdtypes.ANY.SOA.SOA`
"""
if self.relativize:
origin_name = dns.name.empty
) -> Zone:
"""Build a zone object from a zone file format string.
- *text*, a ``str``, the zone file format input.
-
- *origin*, a ``dns.name.Name``, a ``str``, or ``None``. The origin
- of the zone; if not specified, the first ``$ORIGIN`` statement in the
- zone file will determine the origin of the zone.
-
- *rdclass*, a ``dns.rdataclass.RdataClass``, the zone's rdata class; the default is
- class IN.
-
- *relativize*, a ``bool``, determine's whether domain names are
- relativized to the zone's origin. The default is ``True``.
-
- *zone_factory*, the zone factory to use or ``None``. If ``None``, then
- ``dns.zone.Zone`` will be used. The value may be any class or callable
- that returns a subclass of ``dns.zone.Zone``.
-
- *filename*, a ``str`` or ``None``, the filename to emit when
- describing where an error occurred; the default is ``'<string>'``.
-
- *allow_include*, a ``bool``. If ``True``, the default, then ``$INCLUDE``
- directives are permitted. If ``False``, then encoutering a ``$INCLUDE``
- will raise a ``SyntaxError`` exception.
-
- *check_origin*, a ``bool``. If ``True``, the default, then sanity
- checks of the origin node will be made by calling the zone's
- ``check_origin()`` method.
-
- *idna_codec*, a ``dns.name.IDNACodec``, specifies the IDNA
- encoder/decoder. If ``None``, the default IDNA encoder/decoder
- is used.
-
- *allow_directives*, a ``bool`` or an iterable of `str`. If ``True``, the default,
- then directives are permitted, and the *allow_include* parameter controls whether
- ``$INCLUDE`` is permitted. If ``False`` or an empty iterable, then no directive
- processing is done and any directive-like text will be treated as a regular owner
- name. If a non-empty iterable, then only the listed directives (including the
- ``$``) are allowed.
-
- Raises ``dns.zone.NoSOA`` if there is no SOA RRset.
-
- Raises ``dns.zone.NoNS`` if there is no NS RRset.
-
- Raises ``KeyError`` if there is no origin node.
-
- Returns a subclass of ``dns.zone.Zone``.
+ :param str text: The zone file format input.
+ :param origin: The origin of the zone. If not specified, the first
+ ``$ORIGIN`` statement in the zone file will determine the origin.
+ :type origin: :py:class:`dns.name.Name`, str, or ``None``
+ :param rdclass: The zone's rdata class; the default is class IN.
+ :type rdclass: :py:class:`dns.rdataclass.RdataClass`
+ :param bool relativize: Whether domain names are relativized to the
+ zone's origin. The default is ``True``.
+ :param zone_factory: The zone factory to use. If ``None``, then
+ :py:class:`dns.zone.Zone` will be used. The value may be any class
+ or callable that returns a subclass of :py:class:`dns.zone.Zone`.
+ :param filename: The filename to emit when describing where an error
+ occurred; the default is ``'<string>'``.
+ :type filename: str or ``None``
+ :param bool allow_include: If ``True`` (the default), then ``$INCLUDE``
+ directives are permitted. If ``False``, then encountering a
+ ``$INCLUDE`` will raise a :py:exc:`SyntaxError`.
+ :param bool check_origin: If ``True`` (the default), then sanity checks
+ of the origin node will be made by calling
+ :py:meth:`dns.zone.Zone.check_origin`.
+ :param idna_codec: The IDNA encoder/decoder. If ``None``, the default
+ IDNA encoder/decoder is used.
+ :type idna_codec: :py:class:`dns.name.IDNACodec` or ``None``
+ :param allow_directives: If ``True`` (the default), directives are
+ permitted and *allow_include* controls ``$INCLUDE``. If ``False``
+ or an empty iterable, no directive processing is done. If a
+ non-empty iterable, only the listed directives (including the ``$``)
+ are allowed.
+ :type allow_directives: bool or Iterable[str]
+ :raises dns.zone.NoSOA: if there is no SOA RRset.
+ :raises dns.zone.NoNS: if there is no NS RRset.
+ :raises KeyError: if there is no origin node.
+ :returns: A subclass of :py:class:`dns.zone.Zone`.
"""
return _from_text(
text,
) -> Zone:
"""Read a zone file and build a zone object.
- *f*, a file or ``str``. If *f* is a string, it is treated
- as the name of a file to open.
-
- *origin*, a ``dns.name.Name``, a ``str``, or ``None``. The origin
- of the zone; if not specified, the first ``$ORIGIN`` statement in the
- zone file will determine the origin of the zone.
-
- *rdclass*, an ``int``, the zone's rdata class; the default is class IN.
-
- *relativize*, a ``bool``, determine's whether domain names are
- relativized to the zone's origin. The default is ``True``.
-
- *zone_factory*, the zone factory to use or ``None``. If ``None``, then
- ``dns.zone.Zone`` will be used. The value may be any class or callable
- that returns a subclass of ``dns.zone.Zone``.
-
- *filename*, a ``str`` or ``None``, the filename to emit when
- describing where an error occurred; the default is ``'<string>'``.
-
- *allow_include*, a ``bool``. If ``True``, the default, then ``$INCLUDE``
- directives are permitted. If ``False``, then encoutering a ``$INCLUDE``
- will raise a ``SyntaxError`` exception.
-
- *check_origin*, a ``bool``. If ``True``, the default, then sanity
- checks of the origin node will be made by calling the zone's
- ``check_origin()`` method.
-
- *idna_codec*, a ``dns.name.IDNACodec``, specifies the IDNA
- encoder/decoder. If ``None``, the default IDNA 2003 encoder/decoder
- is used.
-
- *allow_directives*, a ``bool`` or an iterable of `str`. If ``True``, the default,
- then directives are permitted, and the *allow_include* parameter controls whether
- ``$INCLUDE`` is permitted. If ``False`` or an empty iterable, then no directive
- processing is done and any directive-like text will be treated as a regular owner
- name. If a non-empty iterable, then only the listed directives (including the
- ``$``) are allowed.
-
- Raises ``dns.zone.NoSOA`` if there is no SOA RRset.
-
- Raises ``dns.zone.NoNS`` if there is no NS RRset.
-
- Raises ``KeyError`` if there is no origin node.
-
- Returns a subclass of ``dns.zone.Zone``.
+ :param f: A file object or a ``str`` filename. If a string, it is
+ treated as the name of a file to open.
+ :param origin: The origin of the zone. If not specified, the first
+ ``$ORIGIN`` statement in the zone file will determine the origin.
+ :type origin: :py:class:`dns.name.Name`, str, or ``None``
+ :param rdclass: The zone's rdata class; the default is class IN.
+ :type rdclass: :py:class:`dns.rdataclass.RdataClass`
+ :param bool relativize: Whether domain names are relativized to the
+ zone's origin. The default is ``True``.
+ :param zone_factory: The zone factory to use. If ``None``, then
+ :py:class:`dns.zone.Zone` will be used. The value may be any class
+ or callable that returns a subclass of :py:class:`dns.zone.Zone`.
+ :param filename: The filename to emit when describing where an error
+ occurred; the default is ``'<string>'``.
+ :type filename: str or ``None``
+ :param bool allow_include: If ``True`` (the default), then ``$INCLUDE``
+ directives are permitted. If ``False``, then encountering a
+ ``$INCLUDE`` will raise a :py:exc:`SyntaxError`.
+ :param bool check_origin: If ``True`` (the default), then sanity checks
+ of the origin node will be made by calling
+ :py:meth:`dns.zone.Zone.check_origin`.
+ :param idna_codec: The IDNA encoder/decoder. If ``None``, the default
+ IDNA encoder/decoder is used.
+ :type idna_codec: :py:class:`dns.name.IDNACodec` or ``None``
+ :param allow_directives: If ``True`` (the default), directives are
+ permitted and *allow_include* controls ``$INCLUDE``. If ``False``
+ or an empty iterable, no directive processing is done. If a
+ non-empty iterable, only the listed directives (including the ``$``)
+ are allowed.
+ :type allow_directives: bool or Iterable[str]
+ :raises dns.zone.NoSOA: if there is no SOA RRset.
+ :raises dns.zone.NoNS: if there is no NS RRset.
+ :raises KeyError: if there is no origin node.
+ :returns: A subclass of :py:class:`dns.zone.Zone`.
"""
if isinstance(f, str):
) -> Zone:
"""Convert the output of a zone transfer generator into a zone object.
- *xfr*, a generator of ``dns.message.Message`` objects, typically
- ``dns.query.xfr()``.
-
- *relativize*, a ``bool``, determine's whether domain names are
- relativized to the zone's origin. The default is ``True``.
- It is essential that the relativize setting matches the one specified
- to the generator.
-
- *check_origin*, a ``bool``. If ``True``, the default, then sanity
- checks of the origin node will be made by calling the zone's
- ``check_origin()`` method.
-
- Raises ``dns.zone.NoSOA`` if there is no SOA RRset.
-
- Raises ``dns.zone.NoNS`` if there is no NS RRset.
-
- Raises ``KeyError`` if there is no origin node.
-
- Raises ``ValueError`` if no messages are yielded by the generator.
-
- Returns a subclass of ``dns.zone.Zone``.
+ :param xfr: A generator of :py:class:`dns.message.Message` objects,
+ typically from :py:func:`dns.query.xfr`.
+ :param zone_factory: The zone factory to use. If ``None``, then
+ :py:class:`dns.zone.Zone` will be used.
+ :param bool relativize: Whether domain names are relativized to the
+ zone's origin. The default is ``True``. It is essential that this
+ setting matches the one specified to the generator.
+ :param bool check_origin: If ``True`` (the default), then sanity checks
+ of the origin node will be made by calling
+ :py:meth:`dns.zone.Zone.check_origin`.
+ :raises dns.zone.NoSOA: if there is no SOA RRset.
+ :raises dns.zone.NoNS: if there is no NS RRset.
+ :raises KeyError: if there is no origin node.
+ :raises ValueError: if no messages are yielded by the generator.
+ :returns: A subclass of :py:class:`dns.zone.Zone`.
"""
z = None
def read(self) -> None:
"""Read a DNS zone file and build a zone object.
- @raises dns.zone.NoSOA: No SOA RR was found at the zone origin
- @raises dns.zone.NoNS: No NS RRset was found at the zone origin
+ :raises dns.zone.NoSOA: if there is no SOA RR at the zone origin.
+ :raises dns.zone.NoNS: if there is no NS RRset at the zone origin.
"""
try:
"""Read one or more rrsets from the specified text, possibly subject
to restrictions.
- *text*, a file object or a string, is the input to process.
-
- *name*, a string, ``dns.name.Name``, or ``None``, is the owner name of
- the rrset. If not ``None``, then the owner name is "forced", and the
- input must not specify an owner name. If ``None``, then any owner names
- are allowed and must be present in the input.
-
- *ttl*, an ``int``, string, or None. If not ``None``, the the TTL is
- forced to be the specified value and the input must not specify a TTL.
- If ``None``, then a TTL may be specified in the input. If it is not
- specified, then the *default_ttl* will be used.
-
- *rdclass*, a ``dns.rdataclass.RdataClass``, string, or ``None``. If
- not ``None``, then the class is forced to the specified value, and the
- input must not specify a class. If ``None``, then the input may specify
- a class that matches *default_rdclass*. Note that it is not possible to
- return rrsets with differing classes; specifying ``None`` for the class
- simply allows the user to optionally type a class as that may be convenient
- when cutting and pasting.
-
- *default_rdclass*, a ``dns.rdataclass.RdataClass`` or string. The class
- of the returned rrsets.
-
- *rdtype*, a ``dns.rdatatype.RdataType``, string, or ``None``. If not
- ``None``, then the type is forced to the specified value, and the
- input must not specify a type. If ``None``, then a type must be present
- for each RR.
-
- *default_ttl*, an ``int``, string, or ``None``. If not ``None``, then if
- the TTL is not forced and is not specified, then this value will be used.
- if ``None``, then if the TTL is not forced an error will occur if the TTL
- is not specified.
-
- *idna_codec*, a ``dns.name.IDNACodec``, specifies the IDNA
- encoder/decoder. If ``None``, the default IDNA 2003 encoder/decoder
- is used. Note that codecs only apply to the owner name; dnspython does
- not do IDNA for names in rdata, as there is no IDNA zonefile format.
-
- *origin*, a string, ``dns.name.Name``, or ``None``, is the origin for any
- relative names in the input, and also the origin to relativize to if
- *relativize* is ``True``.
-
- *relativize*, a bool. If ``True``, names are relativized to the *origin*;
- if ``False`` then any relative names in the input are made absolute by
- appending the *origin*.
+ :param text: The input to process, either a file object or a string.
+ :param name: The owner name of the rrset. If not ``None``, the owner
+ name is forced and the input must not specify one. If ``None``,
+ any owner names are allowed and must be present in the input.
+ :type name: str, :py:class:`dns.name.Name`, or ``None``
+ :param ttl: If not ``None``, the TTL is forced to the specified value
+ and the input must not specify a TTL. If ``None``, a TTL may be
+ specified in the input; if not specified, *default_ttl* will be used.
+ :type ttl: int, str, or ``None``
+ :param rdclass: If not ``None``, the class is forced to the specified
+ value and the input must not specify a class. If ``None``, the input
+ may optionally specify a class matching *default_rdclass*. Note that
+ rrsets with differing classes cannot be returned; ``None`` here simply
+ allows the user to optionally write a class in the input.
+ :type rdclass: :py:class:`dns.rdataclass.RdataClass`, str, or ``None``
+ :param default_rdclass: The class of the returned rrsets.
+ :type default_rdclass: :py:class:`dns.rdataclass.RdataClass` or str
+ :param rdtype: If not ``None``, the type is forced to the specified value
+ and the input must not specify a type. If ``None``, a type must be
+ present for each RR.
+ :type rdtype: :py:class:`dns.rdatatype.RdataType`, str, or ``None``
+ :param default_ttl: If not ``None``, and the TTL is not forced and not
+ specified in the input, this value will be used. If ``None``, an
+ error will occur if the TTL is not forced and not specified.
+ :type default_ttl: int, str, or ``None``
+ :param idna_codec: The IDNA encoder/decoder. If ``None``, the default
+ IDNA encoder/decoder is used. Note that codecs only apply to the
+ owner name; dnspython does not do IDNA for names in rdata.
+ :type idna_codec: :py:class:`dns.name.IDNACodec` or ``None``
+ :param origin: The origin for any relative names in the input, and also
+ the origin to relativize to if *relativize* is ``True``.
+ :type origin: str, :py:class:`dns.name.Name`, or ``None``
+ :param bool relativize: If ``True``, names are relativized to *origin*;
+ if ``False``, relative names in the input are made absolute by
+ appending *origin*.
+ :rtype: list[:py:class:`dns.rrset.RRset`]
"""
if isinstance(origin, str):
origin = dns.name.from_text(origin, dns.name.root, idna_codec)
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
+ rm -rf _build
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) -n $(O)
with the ``sniffio`` module if it is installed. If sniffio is not available,
dnspython will try to detect asyncio directly.
+.. autoclass:: dns.asyncbackend.Backend
+ :members:
+
+.. autoclass:: dns.asyncbackend.DatagramSocket
+ :members:
+
+.. autoclass:: dns.asyncbackend.StreamSocket
+ :members:
+
.. autofunction:: dns.asyncbackend.get_default_backend
.. autofunction:: dns.asyncbackend.set_default_backend
.. autofunction:: dns.asyncbackend.sniff
DNS Query Support
=================
-The ``dns.asyncquery`` module is for sending messages to DNS servers, and
+The :py:mod:`dns.asyncquery` module is for sending messages to DNS servers, and
processing their responses. If you want "stub resolver" behavior, then
-you should use the higher level ``dns.asyncresolver`` module; see
+you should use the higher level :py:mod:`dns.asyncresolver` module; see
:ref:`async_resolver`.
For UDP and TCP, the module provides a single "do everything" query
The dns.asyncresolver.Resolver Class
------------------------------------
-The async resolver is a subclass of ``dns.resolver.Resolver`` and has the
+The async resolver is a subclass of :py:class:`dns.resolver.Resolver` and has the
same attributes. The methods are similar, but I/O methods like ``resolve()``
are asynchronous.
Asynchronous I/O Support
========================
-The ``dns.asyncquery`` and ``dns.asyncresolver`` modules offer
-asynchronous APIs equivalent to those of ``dns.query`` and
-``dns.resolver``.
+The :py:mod:`dns.asyncquery` and :py:mod:`dns.asyncresolver` modules offer
+asynchronous APIs equivalent to those of :py:mod:`dns.query` and
+:py:mod:`dns.resolver`.
Dnspython presents a uniform API, but offers two different backend
implementations, to support the Trio and asyncio libraries.
# ones.
extensions = [
"sphinx.ext.autodoc",
+ "sphinx.ext.intersphinx",
"sphinx.ext.viewcode",
"sphinx.ext.githubpages",
"sphinx.ext.todo",
]
+intersphinx_mapping = {
+ "python": ("https://docs.python.org/3", None),
+ "cryptography": ("https://cryptography.io/en/latest/", None)
+}
+
+nitpick_ignore = [
+ ("py:class", "dns.tokenizer.Tokenizer"),
+ ("py:class", "dns.wirebase.Parser"),
+ ("py:class", "dns.wire.Parser"),
+ ("py:class", "dns.btree.BTreeDict"),
+ ("py:class", "dns.btree.BTree"),
+ # Private async backend classes (underscore-prefixed, not publicly documented)
+ ("py:class", "dns._asyncbackend.Backend"),
+ ("py:class", "dns._asyncbackend.DatagramSocket"),
+ ("py:class", "dns._asyncbackend.StreamSocket"),
+ # TSIG module not yet documented
+ ("py:class", "dns.tsig.Key"),
+ ("py:class", "dns.tsig.HMACTSig"),
+ ("py:class", "dns.tsig.GSSTSig"),
+ # Malformed dict[] type annotation cross-ref from autodoc
+ ("py:class", "dict[~dns.name.Name"),
+ # Public async backend module classes (implementation detail)
+ ("py:class", "dns.asyncbackend.Backend"),
+ # Python built-in file object (old-style type annotation)
+ ("py:class", "file"),
+ # socket module class (from dns.query sock parameters)
+ ("py:class", "socket"),
+ # External libraries not in intersphinx
+ ("py:class", "httpx.AsyncClient"),
+ ("py:class", "dns.quic.AsyncQuicConnection"),
+]
+
# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]
.. autofunction:: dns.dnssec.default_rrset_signer()
.. autofunction:: dns.dnssec.sign_zone()
-DNSSEC Algorithms
------------------
+DNSSEC Policy
+-------------
+
+.. autoclass:: dns.dnssec.Policy
+ :members:
+
+DNSSEC Algorithm Types
+----------------------
+
+.. autoclass:: dns.dnssectypes.Algorithm
+ :members:
+
+.. autoclass:: dns.dnssectypes.DSDigest
+ :members:
+
+DNSSEC Algorithm Implementations
+---------------------------------
+
+.. autoclass:: dns.dnssecalgs.base.GenericPublicKey
+ :members:
+
+.. autoclass:: dns.dnssecalgs.base.GenericPrivateKey
+ :members:
+
+DNSSEC Algorithm Constants
+---------------------------
.. autodata:: dns.dnssec.RSAMD5
.. autodata:: dns.dnssec.DH
the query methods to use in more complex situations, e.g. with TSIG or
EDNS.
+.. autoexception:: dns.xfr.UseTCP
+
.. autoclass:: dns.xfr.Inbound
:members:
.. attribute:: sections
- A list of lists of ``dns.rrset.RRset`` objects.
+ A list of lists of :py:class:`dns.rrset.RRset` objects.
.. attribute:: edns
.. attribute:: options
- The EDNS options, a list of ``dns.edns.Option`` objects. The default
+ The EDNS options, a list of :py:class:`dns.edns.Option` objects. The default
is the empty list.
.. attribute:: request_payload
.. attribute:: keyname
- The TSIG keyname to use, a ``dns.name.Name``. The default is ``None``.
+ The TSIG keyname to use, a :py:class:`dns.name.Name`. The default is ``None``.
.. attribute:: keyalgorithm
- A ``dns.name.Name``, the TSIG algorithm to use. Defaults to
+ A :py:class:`dns.name.Name`, the TSIG algorithm to use. Defaults to
``dns.tsig.default_algorithm``. Constants for TSIG algorithms are
defined the in ``dns.tsig`` module.
.. attribute:: origin
- A ``dns.name.Name``. The origin of the zone in messages which are
+ A :py:class:`dns.name.Name`. The origin of the zone in messages which are
used for zone transfers or for DNS dynamic updates. The default
is ``None``.
.. attribute:: wire
A ``bytes`` or ``None``, the encoded wire format data used to create this
- message with ``dns.message.from_wire()`` or the output most recently generated by
+ message with :py:func:`dns.message.from_wire` or the output most recently generated by
``to_wire()``.
.. autoclass:: dns.message.MessageStyle
mechanism for the protocol. EDNS *options* are typed data, and are
treated much like Rdata. For example, if dnspython encounters the EDNS
``ECS`` option code when parsing a DNS wire format message, it
-will create a ``dns.edns.ECSOption`` object to represent it.
+will create a :py:class:`dns.edns.ECSOption` object to represent it.
.. autoclass:: dns.edns.OptionType
Making DNS Messages
-------------------
+.. autoexception:: dns.message.Truncated
+
+.. autoclass:: dns.message.CopyMode
+ :members:
+
.. autofunction:: dns.message.from_file
.. autofunction:: dns.message.from_text
.. autofunction:: dns.message.from_wire
or replying to. Opcodes are embedded in the flags field in the DNS
header.
+.. autoclass:: dns.opcode.Opcode
+ :members:
+
.. autodata:: dns.opcode.QUERY
.. autodata:: dns.opcode.IQUERY
.. autodata:: dns.opcode.STATUS
The dns.message.QueryMessage Class
----------------------------------
-The ``dns.message.QueryMessage`` class is used for ordinary DNS query messages.
+.. autoexception:: dns.message.NotQueryResponse
+.. autoexception:: dns.message.ChainTooLong
+.. autoexception:: dns.message.AnswerForNXDOMAIN
+
+The :py:class:`dns.message.QueryMessage` class is used for ordinary DNS query messages.
.. autoclass:: dns.message.QueryMessage
:members:
The dns.message.ChainingResult Class
------------------------------------
-Objects of the ``dns.message.ChainingResult`` class are returned by the
-``dns.message.QueryMessage.resolve_chaining()`` method.
+Objects of the :py:class:`dns.message.ChainingResult` class are returned by the
+:py:meth:`dns.message.QueryMessage.resolve_chaining` method.
.. autoclass:: dns.message.ChainingResult
:members:
in use, then the rcode is encoded using bits form both the header and
the EDNS OPT RR.
+.. autoclass:: dns.rcode.Rcode
+ :members:
+
.. autodata:: dns.rcode.NOERROR
.. autodata:: dns.rcode.FORMERR
.. autodata:: dns.rcode.SERVFAIL
The dns.update.UpdateMessage Class
----------------------------------
-The ``dns.update.UpdateMessage`` class is used for DNS Dynamic Update
+The :py:class:`dns.update.UpdateMessage` class is used for DNS Dynamic Update
messages. It provides section access using the DNS Dynamic Update
section names, and a variety of convenience methods for constructing
dynamic updates.
DNS Messages
============
-Objects of the dns.message.Message class and its subclasses represent
+Objects of the :py:class:`dns.message.Message` class and its subclasses represent
a single DNS message, as defined by `RFC 1035
<https://tools.ietf.org/html/rfc1035>`_ and its many updates and
extensions.
.. autoclass:: dns.name.Name
:members:
:inherited-members:
+ :special-members: __init__
.. attribute:: labels
labels in the name, in order from least-significant label
(i.e. farthest from the origin) to most-significant label.
- .. method:: __init__(labels)
-
- Initialize a name using *labels*, an iterable of ``bytes`` or ``str``.
+ :type: tuple[bytes, ...]
.. data:: dns.name.root
according to the user's desire.
The default codec to use for all of dnspython can be set by calling
-py:func:`dns.name.set_default_idna_codec()`. The default default codec is
-``dns.name.IDNA_2008_Practical`` if the ``idna`` module is installed, and
-``dns.name.IDNA_2003_Practical`` otherwise.
+:py:func:`dns.name.set_default_idna_codec`. The default default codec is
+:py:data:`dns.name.IDNA_2008_Practical` if the ``idna`` module is installed, and
+:py:data:`dns.name.IDNA_2003_Practical` otherwise.
.. autoclass:: dns.name.IDNACodec
:members:
.. data:: dns.name.IDNA_2003
- A synonym for ``dns.name.IDNA_2003_Practical``.
+ A synonym for :py:data:`dns.name.IDNA_2003_Practical`.
.. data:: dns.name.IDNA_2008_Practical
The "UTS 46" codec encodes using IDNA 2008 rules with UTS 46
compatibility processing in the "transitional mode" and decodes
punycode without checking for IDNA 2008 compliance. This codec
- is the same as ``dns.name.IDNA_2008_UTS_46`` in idna 3.11 and
+ is the same as :py:data:`dns.name.IDNA_2008_UTS_46` in idna 3.11 and
later as transitional support has been removed.
.. data:: dns.name.IDNA_2008
- A synonym for ``dns.name.IDNA_2008_Practical``.
+ A synonym for :py:data:`dns.name.IDNA_2008_Practical`.
.. data:: dns.name.IDNA_DEFAULT
DNS Names
=========
-Objects of the dns.name.Name class represent an immutable domain name.
+Objects of the :py:class:`dns.name.Name` class represent an immutable domain name.
The representation is a tuple of labels, with each label being a ``bytes``
object in the DNS wire format. Typically names are not created by
supplying the labels tuple directly, but rather by converting from DNS
in the DNS wire protocol are always absolute. Dnspython's functions to
make names from text also default to an origin of the root name, and thus
to make a relative name using them you must specify an origin of None or
-``dns.name.empty``.
+:py:data:`dns.name.empty`.
Names are compared and ordered according to the rules of the DNS. The
order is the DNSSEC canonical ordering. Relative names always sort before
DNS Query Support
=================
-The ``dns.query`` module is for sending messages to DNS servers, and
+The :py:mod:`dns.query` module is for sending messages to DNS servers, and
processing their responses. If you want "stub resolver" behavior, then
-you should use the higher level ``dns.resolver`` module; see :ref:`resolver`.
+you should use the higher level :py:mod:`dns.resolver` module; see :ref:`resolver`.
For UDP and TCP, the module provides a single "do everything" query
function, and also provides the send and receive halves of this function
As of dnspython 2.1, :py:func:`dns.query.xfr` is deprecated. Please use
:py:func:`dns.query.inbound_xfr` instead.
+.. autoclass:: dns.query.HTTPVersion
+ :members:
+
.. autoclass:: dns.query.UDPMode
.. autofunction:: dns.query.inbound_xfr
======================
All Rdata objects are instances of some subclass of
-``dns.rdata.Rdata``, and are immutable. The Rdata factory functions
+:py:class:`dns.rdata.Rdata`, and are immutable. The Rdata factory functions
described in :ref:`rdata-make` will create objects which are instances
of the most appropriate subclass. For example, a AAAA record will be
-an instance of the ``dns.rdtypes.IN.AAAA`` class, but a record of
+an instance of the :py:class:`dns.rdtypes.IN.AAAA.AAAA` class, but a record of
TYPE12345, which we don't know anything specific about, will be an
-instance of ``dns.rdata.GenericRdata``.
+instance of :py:class:`dns.rdata.GenericRdata`.
Rdata of the same type and class are ordered. For rdata that do not
contain domain names, or which contain absolute domain names, the
set API, but are also ordered.
An ``RRset`` is a subclass of ``Rdataset`` that also has an owner
-name, i.e. a ``dns.name.Name`` that says where in the DNS tree this
+name, i.e. a :py:class:`dns.name.Name` that says where in the DNS tree this
set is located.
A ``Node`` is a set of ``Rdataset`` objects, the Rdatasets being
.. autoclass:: dns.node.Node
:members:
+.. autoclass:: dns.node.ImmutableNode
+ :members:
+
.. autoclass:: dns.node.NodeKind
:members:
.. autoclass:: dns.rdtypes.ANY.AFSDB.AFSDB
:members:
+.. autoclass:: dns.rdtypes.ANY.AMTRELAY.Relay
+ :members:
+
.. autoclass:: dns.rdtypes.ANY.AMTRELAY.AMTRELAY
:members:
.. attribute:: precedence
- An ``int``, the 8-bit unsigned integer preference.
+ An ``int``, the 8-bit unsigned integer preference.
.. attribute:: discovery_optional
- A ``bool``, specifying whether discovery is optional or not.
+ A ``bool``, specifying whether discovery is optional or not.
.. attribute:: relay_type
- An ``int``, the 8-bit unsigned integer relay type.
+ An ``int``, the 8-bit unsigned integer relay type.
.. attribute:: relay
- A ``dns.rdtypes.ANY.AMTRELAY.Relay`` instance, the relay.
+ A :py:class:`dns.rdtypes.ANY.AMTRELAY.Relay` instance, the relay.
.. autoclass:: dns.rdtypes.ANY.AVC.AVC
:members:
.. attribute:: target
- A ``dns.name.Name``, the target name.
+ A :py:class:`dns.name.Name`, the target name.
.. autoclass:: dns.rdtypes.ANY.CSYNC.CSYNC
:members:
.. attribute:: target
- A ``dns.name.Name``, the target name.
+ A :py:class:`dns.name.Name`, the target name.
.. autoclass:: dns.rdtypes.ANY.DNSKEY.DNSKEY
:members:
A ``bytes``, the digest of the key.
+.. autoclass:: dns.rdtypes.ANY.DSYNC.Scheme
+ :members:
+
.. autoclass:: dns.rdtypes.ANY.DSYNC.DSYNC
:members:
.. attribute:: rrtype
- A ``dns.rdatatype.RdataType``, the type this DSYNC record will notify about.
+ A :py:class:`dns.rdatatype.RdataType`, the type this DSYNC record will notify about.
.. attribute:: scheme
- A ``dns.rdtypes.ANY.DSYNC.Scheme`` the scheme to use, typically
+ A :py:class:`dns.rdtypes.ANY.DSYNC.Scheme` the scheme to use, typically
``dns.rdtypes.ANY.DSYNC.Scheme.NOTIFY``.
.. attribute:: port
.. attribute:: target
- A ``dns.name.Name``, the hostname of the notification receiver.
+ A :py:class:`dns.name.Name`, the hostname of the notification receiver.
.. autoclass:: dns.rdtypes.ANY.EUI48.EUI48
:members:
.. attribute:: servers
- A tuple of ``dns.name.Name`` objects, the rendezvous servers.
+ A tuple of :py:class:`dns.name.Name` objects, the rendezvous servers.
.. autoclass:: dns.rdtypes.ANY.ISDN.ISDN
:members:
.. attribute:: fqdn
- A ``dns.name.Name``, the domain name of a locator.
+ A :py:class:`dns.name.Name`, the domain name of a locator.
.. autoclass:: dns.rdtypes.ANY.MX.MX
:members:
.. attribute:: exchange
- A ``dns.name.Name``, the exchange name.
+ A :py:class:`dns.name.Name`, the exchange name.
.. autoclass:: dns.rdtypes.ANY.NID.NID
:members:
.. attribute:: target
- A ``dns.name.Name``, the target name.
+ A :py:class:`dns.name.Name`, the target name.
.. autoclass:: dns.rdtypes.ANY.NSEC.NSEC
:members:
.. attribute:: next
- A ``dns.name.Name``, the next name
+ A :py:class:`dns.name.Name`, the next name
.. attribute:: windows
.. attribute:: target
- A ``dns.name.Name``, the target name.
+ A :py:class:`dns.name.Name`, the target name.
.. autoclass:: dns.rdtypes.ANY.RESINFO.RESINFO
:members:
.. attribute:: mbox
- A ``dns.name.Name``, the responsible person's mailbox.
+ A :py:class:`dns.name.Name`, the responsible person's mailbox.
.. attribute:: txt
- A ``dns.name.Name``, the owner name of a node with TXT records,
+ A :py:class:`dns.name.Name`, the owner name of a node with TXT records,
or the root name if no TXT records are associated with this RP.
.. autoclass:: dns.rdtypes.ANY.RRSIG.RRSIG
.. attribute:: signer
- A ``dns.name.Name``, the signer.
+ A :py:class:`dns.name.Name`, the signer.
.. attribute:: signature
.. attribute:: exchange
- A ``dns.name.Name``, the exchange name.
+ A :py:class:`dns.name.Name`, the exchange name.
.. autoclass:: dns.rdtypes.ANY.SMIMEA.SMIMEA
:members:
.. attribute:: mname
- A ``dns.name.Name``, the MNAME (master name).
+ A :py:class:`dns.name.Name`, the MNAME (master name).
.. attribute:: rname
- A ``dns.name.Name``, the RNAME (responsible name).
+ A :py:class:`dns.name.Name`, the RNAME (responsible name).
.. attribute:: serial
.. attribute:: target
- A ``dns.name.Name``, the target.
+ A :py:class:`dns.name.Name`, the target.
.. autoclass:: dns.rdtypes.ANY.WALLET.WALLET
:members:
.. attribute:: items
- A tuple of ``dns.rdtypes.IN.APL.APLItem``.
+ A tuple of :py:class:`dns.rdtypes.IN.APL.APLItem`.
.. autoclass:: dns.rdtypes.IN.DHCID.DHCID
:members:
.. attribute:: target
- A ``dns.name.Name``, the target name.
+ A :py:class:`dns.name.Name`, the target name.
.. attribute:: params
- A ``dict[dns.rdtypes.svcbbase.ParamKey, dns.rdtypes.svcbbase.Param]``, the
+ A dict mapping :py:class:`dns.rdtypes.svcbbase.ParamKey` to :py:class:`dns.rdtypes.svcbbase.Param`, the
parameters. See the dedicated section :ref:`svcb-https-params` below for
more information on the parameter types.
.. attribute:: gateway
- The gateway. This value may be ``None``, a ``str` with an IPv4 or
- IPV6 address, or a ``dns.name.Name``.
+ The gateway. This value may be ``None``, a ``str`` with an IPv4 or
+ IPV6 address, or a :py:class:`dns.name.Name`.
.. attribute:: key
.. attribute:: exchange
- A ``dns.name.Name``, the exchange name.
+ A :py:class:`dns.name.Name`, the exchange name.
.. autoclass:: dns.rdtypes.IN.NAPTR.NAPTR
:members:
.. attribute:: replacement
- A ``dns.name.Name``, the replacement name.
+ A :py:class:`dns.name.Name`, the replacement name.
.. autoclass:: dns.rdtypes.IN.NSAP.NSAP
:members:
.. attribute:: target
- A ``dns.name.Name``, the target name.
+ A :py:class:`dns.name.Name`, the target name.
.. autoclass:: dns.rdtypes.IN.PX.PX
:members:
.. attribute:: map822
- A ``dns.name.Name``, the map822 name.
+ A :py:class:`dns.name.Name`, the map822 name.
.. attribute:: mapx400
- A ``dns.name.Name``, the mapx400 name.
+ A :py:class:`dns.name.Name`, the mapx400 name.
.. autoclass:: dns.rdtypes.IN.SRV.SRV
:members:
.. attribute:: target
- A ``dns.name.Name``, the target host.
+ A :py:class:`dns.name.Name`, the target host.
.. autoclass:: dns.rdtypes.IN.SVCB.SVCB
:members:
.. attribute:: target
- A ``dns.name.Name``, the target name.
+ A :py:class:`dns.name.Name`, the target name.
.. attribute:: params
- A ``dict[dns.rdtypes.svcbbase.ParamKey, dns.rdtypes.svcbbase.Param]``, the
+ A dict mapping :py:class:`dns.rdtypes.svcbbase.ParamKey` to :py:class:`dns.rdtypes.svcbbase.Param`, the
parameters. See the dedicated section :ref:`svcb-https-params` below for
more information on the parameter types.
.. attribute:: keys
- A tuple of ``ParamKey``, the keys which are mandatory.
+ A tuple of :py:class:`dns.rdtypes.svcbbase.ParamKey`, the keys which are mandatory.
.. autoclass:: dns.rdtypes.svcbbase.ALPNParam
:members:
*rdataclass* and *rdatatype*. The class is almost always `IN`, the Internet
class, and may often be omitted in the dnspython APIs.
-The ``dns.rdataclass`` module provides constants for each defined
-rdata class, as well as some helpful functions. The ``dns.rdatatype``
+The :py:mod:`dns.rdataclass` module provides constants for each defined
+rdata class, as well as some helpful functions. The :py:mod:`dns.rdatatype`
module does the same for rdata types. Examples of the constants are::
dns.rdataclass.IN
:annotation: = 104
.. py:data:: dns.rdatatype.NINFO
:annotation: = 56
+.. py:data:: dns.rdatatype.NONE
+ :annotation: = 0
.. py:data:: dns.rdatatype.NS
:annotation: = 2
.. py:data:: dns.rdatatype.NSAP
:annotation: = 51
.. py:data:: dns.rdatatype.NULL
:annotation: = 10
+.. py:data:: dns.rdatatype.NXNAME
+ :annotation: = 128
.. py:data:: dns.rdatatype.NXT
:annotation: = 30
.. py:data:: dns.rdatatype.OPENPGPKEY
.. attribute:: domain
- A ``dns.name.Name``, the domain of this host.
+ A :py:class:`dns.name.Name`, the domain of this host.
.. attribute:: nameservers
- A ``list`` of ``str`` or ``dns.nameserver.Nameserver``. A string may be
+ A ``list`` of ``str`` or :py:class:`dns.nameserver.Nameserver`. A string may be
an IPv4 or IPv6 address, or an https URL.
This field is actually a property, and returns a tuple as of dnspython 2.4.
Assigning this field converts any strings into
- ``dns.nameserver.Nameserver`` instances.
+ :py:class:`dns.nameserver.Nameserver` instances.
.. attribute:: search
- A ``list`` of dns.name.Name objects. If the query name is a
+ A ``list`` of :py:class:`dns.name.Name` objects. If the query name is a
relative name, the resolver will construct absolute query names
to try by appending values from the search list.
A ``float``, the number of seconds to spend trying to get an
answer to the question. If the lifetime expires a
- ``dns.exception.Timeout`` exception will be raised.
+ :py:exc:`dns.exception.Timeout` exception will be raised.
.. attribute:: cache
An object implementing the caching protocol, e.g. a
- ``dns.resolver.Cache`` or a ``dns.resolver.LRUCache``. The default
+ :py:class:`dns.resolver.Cache` or a :py:class:`dns.resolver.LRUCache`. The default
is ``None``, in which case there is no local caching.
.. attribute:: retry_servfail
.. attribute:: keyname
- A ``dns.name.Name`` or ``None``, the name of the TSIG key to
+ A :py:class:`dns.name.Name` or ``None``, the name of the TSIG key to
use; defaults to ``None``. The key must be defined in the
keyring.
.. attribute:: keyalgorithm
- A ``dns.name.Name`` or ``str``, the TSIG algorithm to use.
+ A :py:class:`dns.name.Name` or ``str``, the TSIG algorithm to use.
.. attribute:: edns
.. attribute:: flags
An ``int`` or ``None``, the message flags to use. If ``None``,
- then the default flags as set by the ``dns.message.Message``
+ then the default flags as set by the :py:class:`dns.message.Message`
constructor will be used.
+.. autoclass:: dns.resolver.HostAnswers
+ :members:
+
.. autoclass:: dns.resolver.Answer
:members:
.. attribute:: qname
- A ``dns.name.Name``, the query name.
+ A :py:class:`dns.name.Name`, the query name.
.. attribute:: rdclass
.. attribute:: response
- A ``dns.message.QueryMessage``, the response message.
+ A :py:class:`dns.message.QueryMessage`, the response message.
.. attribute:: rrset
- A ``dns.rrset.RRset`` or ``None``, the answer RRset.
+ A :py:class:`dns.rrset.RRset` or ``None``, the answer RRset.
.. attribute:: expiration
.. attribute:: canonical_name
- A ``dns.name.Name``, the canonical name of the query name,
+ A :py:class:`dns.name.Name`, the canonical name of the query name,
i.e. the owner name of the answer RRset after any CNAME and DNAME
chaining.
The dns.nameserver.Nameserver Classes
-------------------------------------
-The ``dns.nameserver.Nameserver`` abstract class represents a remote recursive resolver,
+The :py:class:`dns.nameserver.Nameserver` abstract class represents a remote recursive resolver,
and is used by the stub resolver to answer queries.
.. autoclass:: dns.nameserver.Nameserver
The dns.nameserver.Do53Nameserver Class
---------------------------------------
-The ``dns.nameserver.Do53Nameserver`` class is a ``dns.nameserver.Nameserver`` class used
+The :py:class:`dns.nameserver.Do53Nameserver` class is a :py:class:`dns.nameserver.Nameserver` class used
to make regular UDP/TCP DNS queries, typically over port 53, to a recursive server.
.. autoclass:: dns.nameserver.Do53Nameserver
The dns.nameserver.DoTNameserver Class
---------------------------------------
-The ``dns.nameserver.DoTNameserver`` class is a ``dns.nameserver.Nameserver`` class used
+The :py:class:`dns.nameserver.DoTNameserver` class is a :py:class:`dns.nameserver.Nameserver` class used
to make DNS-over-TLS (DoT) queries to a recursive server.
.. autoclass:: dns.nameserver.DoTNameserver
The dns.nameserver.DoHNameserver Class
---------------------------------------
-The ``dns.nameserver.DoHNameserver`` class is a ``dns.nameserver.Nameserver`` class used
+The :py:class:`dns.nameserver.DoHNameserver` class is a :py:class:`dns.nameserver.Nameserver` class used
to make DNS-over-HTTPS (DoH) queries to a recursive server.
.. autoclass:: dns.nameserver.DoHNameserver
The dns.nameserver.DoQNameserver Class
---------------------------------------
-The ``dns.nameserver.DoQNameserver`` class is a ``dns.nameserver.Nameserver`` class used
+The :py:class:`dns.nameserver.DoQNameserver` class is a :py:class:`dns.nameserver.Nameserver` class used
to make DNS-over-QUIC (DoQ) queries to a recursive server.
.. autoclass:: dns.nameserver.DoQNameserver
web-crawling application associates an ``LRUCache`` with a Resolver, it will
be safe to have many crawler threads doing resolutions.
-The ``dns.query`` methods are also thread-safe. One caveat with these
+The :py:mod:`dns.query` methods are also thread-safe. One caveat with these
functions is that if a socket or other context (e.g. a Requests
session or an SSL context) is passed to the function instead of
allowing the function to create it, then it is up to the application to
* Python 3.8 or newer is required.
-* The stub resolver now uses instances of ``dns.nameserver.Nameserver`` to represent
+* The stub resolver now uses instances of :py:class:`dns.nameserver.Nameserver` to represent
remote recursive resolvers, and can communicate using
DNS over UDP/TCP, HTTPS, TLS, and QUIC. In additional to being able to specify
- an IPv4, IPv6, or HTTPS URL as a nameserver, instances of ``dns.nameserver.Nameserver``
+ an IPv4, IPv6, or HTTPS URL as a nameserver, instances of :py:class:`dns.nameserver.Nameserver`
are now permitted.
* The DNS-over-HTTPS bootstrap address no longer causes URL rewriting.
non-zero pad option will be automatically padded appropriately when
converted to wire format.
-* ``dns.zone.from_text()`` and ``dns.zone.from_file()`` now have an
+* :py:func:`dns.zone.from_text` and :py:func:`dns.zone.from_file` now have an
``allow_directives`` parameter to allow finer control over how directives
in zonefiles are processed.
is subject to change in future releases. For asynchronous I/O, both
asyncio and Trio are supported, but Curio is not.
-* DNSSEC signing support has been added to the ``dns.dnssec`` module, along with
+* DNSSEC signing support has been added to the :py:mod:`dns.dnssec` module, along with
a number of functions to help generate DS, CDS, and CDNSKEY RRsets. Thank you
very much Jakob Schlyter!
* DNS-over-HTTPS is now supported for asynchronous queries and resolutions.
-* ``dns.zonefile.read_rrsets()`` has been added, which allows rrsets in zonefile
+* :py:func:`dns.zonefile.read_rrsets` has been added, which allows rrsets in zonefile
format, or a restrition of it, to be read. This function is useful for
applications that want to read DNS data in text format, but do not want to
use a Zone.
* The license is now the ISC license.
-* Rdata is now immutable. Use ``dns.rdata.Rdata.replace()`` to make a new
+* Rdata is now immutable. Use :py:meth:`dns.rdata.Rdata.replace` to make a new
Rdata based on an existing one.
* dns.resolver.resolve() has been added, allowing control of whether search
behavior can be set at in the resolver object with the
``use_search_by_default`` parameter. The default is False.
-* DNS-over-TLS is supported with ``dns.query.tls()``.
+* DNS-over-TLS is supported with :py:func:`dns.query.tls`.
-* DNS-over-HTTPS is supported with ``dns.query.https()``, and the resolver
+* DNS-over-HTTPS is supported with :py:func:`dns.query.https`, and the resolver
will use DNS-over-HTTPS for a nameserver which is an HTTPS URL.
* Basic query and resolver support for the Trio, Curio, and asyncio
- asynchronous I/O libraries has been added in ``dns.asyncquery`` and
- ``dns.asyncresolver``. This API should be viewed as experimental as
+ asynchronous I/O libraries has been added in :py:mod:`dns.asyncquery` and
+ :py:mod:`dns.asyncresolver`. This API should be viewed as experimental as
asynchronous I/O support in dnspython is still evolving.
* TSIG now defaults to using SHA-256.
The dns.zone.Zone Class
-----------------------
-The ``Zone`` class provides a non-thread-safe implementation of a DNS zone,
-as well as a lightweight translation mechanism that allows it to be atomically
-updated. For more complicated transactional needs, or for concurrency, please
-use the :py:class:`dns.versioned.Zone` class (described below).
+The :py:class:`dns.zone.Zone` class provides a non-thread-safe implementation
+of a DNS zone, as well as a lightweight translation mechanism that allows it
+to be atomically updated. For more complicated transactional needs, or for
+concurrency, please use the :py:class:`dns.versioned.Zone` class (described
+below).
.. autoclass:: dns.zone.Zone
:members:
.. attribute:: rdclass
- The zone's rdata class, an ``int``; the default is class IN.
+ The zone's rdata class; the default is class IN.
+
+ :type: :py:class:`dns.rdataclass.RdataClass`
.. attribute:: origin
- The origin of the zone, a ``dns.name.Name``.
+ The origin of the zone.
+
+ :type: :py:class:`dns.name.Name`
.. attribute:: nodes
- A dictionary mapping the names of nodes in the zone to the nodes
- themselves.
+ A dictionary mapping the names of nodes in the zone to the nodes
+ themselves.
.. attribute:: relativize
- A ``bool``, which is ``True`` if names in the zone should be relativized.
+ ``True`` if names in the zone should be relativized.
-A ``Zone`` has a class attribute ``node_factory`` which is used to
-create new nodes and defaults to ``dns.node.Node``. ``Zone`` may be
-subclassed if a different node factory is desired.
-The node factory is a class or callable that returns a subclass of
-``dns.node.Node``.
+ :type: bool
+
+A :py:class:`dns.zone.Zone` has a class attribute ``node_factory`` which is
+used to create new nodes and defaults to :py:class:`dns.node.Node`.
+:py:class:`dns.zone.Zone` may be subclassed if a different node factory is
+desired. The node factory is a class or callable that returns a subclass of
+:py:class:`dns.node.Node`.
.. autoclass:: dns.zone.ZoneStyle
:members:
The dns.versioned.Zone Class
----------------------------
-A versioned Zone is a subclass of ``Zone`` that provides a thread-safe
-multiversioned transactional API. There can be many concurrent
-readers, of possibly different versions, and at most one active
-writer. Others cannot see the changes being made by the writer until
+A :py:class:`dns.versioned.Zone` is a subclass of :py:class:`dns.zone.Zone`
+that provides a thread-safe multiversioned transactional API. There can be
+many concurrent readers, of possibly different versions, and at most one
+active writer. Others cannot see the changes being made by the writer until
it commits. Versions are immutable once committed.
The read-only parts of the standard zone API continue to be available, and
are equivalent to doing a single-query read-only transaction. Note that
unless reading is done through a transaction, version stability is not
guaranteed between successive calls. Attempts to use zone API methods
-that directly manipulate the zone, e.g. ``replace_rdataset`` will result
-in a ``UseTransaction`` exception.
+that directly manipulate the zone, e.g.
+:py:meth:`dns.zone.Zone.replace_rdataset`, will result in a
+:py:exc:`dns.versioned.UseTransaction` exception.
-Transactions are context managers, and are created with ``reader()`` or
-``writer()``. For example:
+Transactions are context managers, and are created with
+:py:meth:`dns.versioned.Zone.reader` or
+:py:meth:`dns.versioned.Zone.writer`. For example:
::
'10.0.0.1'))
txn.set_serial()
-See below for more information on the ``Transaction`` API.
+See below for more information on the :py:class:`dns.transaction.Transaction`
+API.
+
+.. autoexception:: dns.versioned.UseTransaction
.. autoclass:: dns.versioned.Zone
:exclude-members: delete_node, delete_rdataset, replace_rdataset
.. attribute:: rdclass
- The zone's rdata class, an ``int``; the default is class IN.
+ The zone's rdata class; the default is class IN.
+
+ :type: :py:class:`dns.rdataclass.RdataClass`
.. attribute:: origin
- The origin of the zone, a ``dns.name.Name``.
+ The origin of the zone.
+
+ :type: :py:class:`dns.name.Name`
.. attribute:: nodes
- A dictionary mapping the names of nodes in the zone to the nodes
- themselves.
+ A dictionary mapping the names of nodes in the zone to the nodes
+ themselves.
.. attribute:: relativize
- A ``bool``, which is ``True`` if names in the zone should be relativized.
+ ``True`` if names in the zone should be relativized.
+
+ :type: bool
+
+
+The Version Classes
+-------------------
+
+.. autoclass:: dns.zone.Version
+ :members:
+
+.. autoclass:: dns.zone.WritableVersion
+ :members:
+
+.. autoclass:: dns.zone.ImmutableVersion
+ :members:
+
+.. autoclass:: dns.zone.VersionedNode
+ :members:
+
+.. autoclass:: dns.zone.ImmutableVersionedNode
+ :members:
+
+
+The Zone Transaction Class
+--------------------------
+
+.. autoclass:: dns.zone.Transaction
+ :members:
The TransactionManager Class
.. autoclass:: dns.transaction.Transaction
:members:
+.. autoexception:: dns.transaction.AlreadyEnded
+
+.. autoexception:: dns.transaction.DeleteNotExact
+
+.. autoexception:: dns.transaction.ReadOnly
+
+
+The dns.btreezone.Zone Class
+----------------------------
+
+:py:class:`dns.btreezone.Zone` is a subclass of :py:class:`dns.versioned.Zone`
+backed by a :py:class:`dns.btree.BTreeDict`. It maintains names in DNS
+canonical (sorted) order, automatically tracks
+:py:class:`dns.btreezone.NodeFlags` (``ORIGIN``, ``DELEGATION``, and ``GLUE``)
+on every node as rdatasets are added or removed, and shares BTree structure
+between versions for efficient copy-on-write behaviour.
+
+Committed versions expose :py:meth:`~dns.btreezone.ImmutableVersion.bounds`,
+which returns the nearest names and closest encloser for any query name. This
+information is useful both for constructing authoritative responses and for
+generating on-the-fly DNSSEC signatures.
+
+.. autoclass:: dns.btreezone.Zone
+ :members:
+
+The btreezone Node Classes
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. autoclass:: dns.btreezone.NodeFlags
+ :members:
+ :inherited-members:
+
+.. autoclass:: dns.btreezone.Node
+ :members:
+
+.. autoclass:: dns.btreezone.ImmutableNode
+ :members:
+
+The btreezone Version Classes
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. autoclass:: dns.btreezone.Delegations
+ :members:
+
+.. autoclass:: dns.btreezone.WritableVersion
+ :members:
+
+.. autoclass:: dns.btreezone.ImmutableVersion
+ :members:
+ :inherited-members:
+
+.. autoclass:: dns.btreezone.Bounds
+ :members:
+
The RRSet Reader
----------------
-``dns.zonefile.read_rrsets()`` reads one or more RRsets from text format. It
+:py:func:`dns.zonefile.read_rrsets` reads one or more RRsets from text format. It
is designed to be used in situations where you are processing DNS data in
text format, but do not want or need a valid zone. For example, a DNS registry
web application might want to allow the user to input RRs.
restrictions of that format, and converts it to a sequence of operations
in a transaction.
-This class is primarily used by ``dns.zone.Zone.from_text()`` and
-``dns.zonefile.read_rrsets``, but may be useful for other software which needs
+This class is primarily used by :py:func:`dns.zone.from_text` and
+:py:func:`dns.zonefile.read_rrsets`, but may be useful for other software which needs
to process the zonefile format.
.. autoclass:: dns.zonefile.Reader