The dns.zone.Zone Class

The 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 dns.versioned.Zone class (described below).

class dns.zone.Zone(origin: Name | str | None, rdclass: RdataClass = RdataClass.IN, relativize: bool = True)[source]

A DNS zone.

A Zone is a mapping from names to nodes. The zone object may be treated like a Python dictionary, e.g. zone[name] will retrieve the node associated with that name. The name may be a dns.name.Name object, or it may be a string. In either case, if the name is relative it is treated as relative to the origin of the zone.

Initialize a zone object.

Parameters:
  • origin (dns.name.Name, str, or None) – 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 (dns.rdataclass.RdataClass) – The zone’s rdata class; the default is class IN.

  • relativize (bool) – Whether domain names are relativized to the zone’s origin. The default is True.

rdclass

The zone’s rdata class; the default is class IN.

Type:

dns.rdataclass.RdataClass

origin

The origin of the zone.

Type:

dns.name.Name

nodes

A dictionary mapping the names of nodes in the zone to the nodes themselves.

relativize

True if names in the zone should be relativized.

Type:

bool

check_origin() None[source]

Do some simple checking of the zone’s origin.

Raises:
delete_node(name: Name | str) None[source]

Delete the specified node if it exists.

It is not an error if the node does not exist.

Parameters:

name (dns.name.Name or str) – The name of the node to delete. 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.

delete_rdataset(name: Name | str, rdtype: RdataType | str, covers: RdataType | str = RdataType.TYPE0) None[source]

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.

Parameters:
find_node(name: Name | str, create: bool = False) Node[source]

Find a node in the zone, possibly creating it.

Parameters:
  • name (dns.name.Name or str) – 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 (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.

Return type:

dns.node.Node

find_rdataset(name: Name | str, rdtype: RdataType | str, covers: RdataType | str = RdataType.TYPE0, create: bool = False) Rdataset[source]

Look for an rdataset with the specified name and type in the zone, and return an rdataset encapsulating it.

The rdataset returned is not a copy; changes to it will change the zone.

Parameters:
  • name (dns.name.Name or str) – 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 (dns.rdatatype.RdataType or str) – The rdata type desired.

  • covers (dns.rdatatype.RdataType or str) – The covered type. Usually dns.rdatatype.NONE, but if rdtype is dns.rdatatype.SIG or 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).

  • create (bool) – 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.

Return type:

dns.rdataset.Rdataset

find_rrset(name: Name | str, rdtype: RdataType | str, covers: RdataType | str = RdataType.TYPE0) RRset[source]

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 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.

Parameters:
Raises:

KeyError – if the name or type are not found, or if the name was not a subdomain of the origin.

Return type:

dns.rrset.RRset

get_class()[source]

The class of the transaction manager.

get_node(name: Name | str, create: bool = False) Node | None[source]

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.

Parameters:
  • name (dns.name.Name or str) – 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 (bool) – If True, the node will be created if it does not exist.

Return type:

dns.node.Node or None

get_rdataset(name: Name | str, rdtype: RdataType | str, covers: RdataType | str = RdataType.TYPE0, create: bool = False) Rdataset | None[source]

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.

The rdataset returned is not a copy; changes to it will change the zone.

Parameters:
  • name (dns.name.Name or str) – 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 (dns.rdatatype.RdataType or str) – The rdata type desired.

  • covers (dns.rdatatype.RdataType or str) – The covered type. Usually dns.rdatatype.NONE, but if rdtype is dns.rdatatype.SIG or 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).

  • create (bool) – If True, the node will be created if it does not exist.

Return type:

dns.rdataset.Rdataset or None

get_rrset(name: Name | str, rdtype: RdataType | str, covers: RdataType | str = RdataType.TYPE0) RRset | None[source]

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() 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 get_rdataset() instead.

Parameters:
Return type:

dns.rrset.RRset or None

get_soa(txn: Transaction | None = None) SOA[source]

Get the zone SOA rdata.

Raises:

dns.zone.NoSOA – if there is no SOA RRset.

Return type:

dns.rdtypes.ANY.SOA.SOA

iterate_rdatas(rdtype: RdataType | str = RdataType.ANY, covers: RdataType | str = RdataType.TYPE0) Iterator[tuple[Name, int, Rdata]][source]

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.

Parameters:
iterate_rdatasets(rdtype: RdataType | str = RdataType.ANY, covers: RdataType | str = RdataType.TYPE0) Iterator[tuple[Name, Rdataset]][source]

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), then all rdatasets will be matched.

Parameters:
map_factory

alias of dict

node_factory

alias of Node

origin_information() tuple[Name | None, bool, Name | None][source]

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.

Return type:

tuple[dns.name.Name or None, bool, dns.name.Name or None]

reader() Transaction[source]

Begin a read-only transaction.

replace_rdataset(name: Name | str, replacement: Rdataset) None[source]

Replace an rdataset at name.

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.

Parameters:
  • name (dns.name.Name or str) – The name of the node. 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 (dns.rdataset.Rdataset) – The replacement rdataset.

to_file(f: Any, sorted: bool = True, relativize: bool = True, nl: str | bytes | None = None, want_comments: bool = False, want_origin: bool = False, style: ZoneStyle | None = None) None[source]

Write a zone to a file.

Parameters:
  • f – A file object or a str filename. If a string, it is treated as the name of a file to open.

  • sorted (bool) – 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.

  • relativize (bool) – If True (the default), domain names in the output will be relativized to the zone’s origin if possible.

  • nl (str, bytes, or None) – 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).

  • want_comments (bool) – If True, emit end-of-line comments as part of writing the file. If False (the default), do not emit them.

  • want_origin (bool) – If True, emit a $ORIGIN line at the start of the file. If False (the default), do not emit one.

  • style (dns.zone.ZoneStyle or None) – If specified, the style overrides the other parameters.

to_styled_file(style: ZoneStyle, f: Any) None[source]

Write a zone to a styled file.

Parameters:
  • style (dns.zone.ZoneStyle) – The style to apply.

  • f – A file object or a str filename. If a string, it is treated as the name of a file to open.

to_styled_text(style: ZoneStyle)[source]

Return a zone’s styled text as though it were written to a file.

See the documentation for dns.zone.ZoneStyle for a description of the style parameters.

Parameters:

style (dns.zone.ZoneStyle) – The style to apply.

Return type:

str

to_text(sorted: bool = True, relativize: bool = True, nl: str | None = None, want_comments: bool = False, want_origin: bool = False, style: ZoneStyle | None = None) str[source]

Return a zone’s text as though it were written to a file.

Parameters:
  • sorted (bool) – 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.

  • relativize (bool) – If True (the default), domain names in the output will be relativized to the zone’s origin if possible.

  • nl (str or None) – 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).

  • want_comments (bool) – If True, emit end-of-line comments as part of the output. If False (the default), do not emit them.

  • want_origin (bool) – If True, emit a $ORIGIN line at the start of the output. If False (the default), do not emit one.

  • style (dns.zone.ZoneStyle or None) – If specified, the style overrides the other parameters.

Return type:

str

writer(replacement: bool = False) Transaction[source]

Begin a writable transaction.

Parameters:

replacement (bool) – 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.

A dns.zone.Zone has a class attribute node_factory which is used to create new nodes and defaults to dns.node.Node. 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 dns.node.Node.

class dns.zone.ZoneStyle(omit_final_dot: bool = False, idna_codec: IDNACodec | None = None, origin: Name | None = None, relativize: bool = False, txt_is_utf8: bool = False, base64_chunk_size: int = 32, base64_chunk_separator: str = ' ', hex_chunk_size: int = 128, hex_chunk_separator: str = ' ', truncate_crypto: bool = False, override_rdclass: RdataClass | None = None, want_comments: bool = False, omit_rdclass: bool = False, omit_ttl: bool = False, want_generic: bool = False, deduplicate_names: bool = False, first_name_is_duplicate: bool = False, default_ttl: int | None = None, name_just: int = 0, ttl_just: int = 0, rdclass_just: int = 0, rdtype_just: int = 0, sorted: bool = True, nl: str | None = None, want_origin: bool = False, want_unicode_directive: bool = True)[source]

Zone text styles.

A dns.zone.ZoneStyle is also a dns.name.NameStyle, dns.rdata.RdataStyle, dns.rdataset.RdatasetStyle, and dns.node.NodeStyle. See those classes for a description of their options.

Parameters:
  • sorted (bool) – 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.

  • nl (str or None) – 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).

  • want_origin (bool) – If True, emit a $ORIGIN line at the start of the output. If False (the default), do not emit one.

  • want_unicode_directive (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.

The dns.versioned.Zone Class

A dns.versioned.Zone is a subclass of 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. dns.zone.Zone.replace_rdataset(), will result in a dns.versioned.UseTransaction exception.

Transactions are context managers, and are created with dns.versioned.Zone.reader() or dns.versioned.Zone.writer(). For example:

# Print the SOA serial number of the most recent version
with zone.reader() as txn:
    rdataset = txn.get('@', 'in', 'soa')
    print('The most recent serial number is', rdataset[0].serial)

# Write an A RR and increment the SOA serial number to the next value.
with zone.writer() as txn:
    txn.replace('node1', dns.rdataset.from_text('in', 'a', 300,
                '10.0.0.1'))
    txn.set_serial()

See below for more information on the dns.transaction.Transaction API.

exception dns.versioned.UseTransaction(*args, **kwargs)[source]

To alter a versioned zone, use a transaction.

class dns.versioned.Zone(origin: Name | str | None, rdclass: RdataClass = RdataClass.IN, relativize: bool = True, pruning_policy: Callable[[Zone, Version], bool | None] | None = None)[source]

Initialize a versioned zone object.

Parameters:
  • origin (dns.name.Name, str, or None) – 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 (dns.rdataclass.RdataClass) – The zone’s rdata class; the default is class IN.

  • relativize (bool) – Whether domain names are relativized to the zone’s origin. The default is True.

  • pruning_policy (Callable or None) – A callable taking a dns.versioned.Zone and a dns.zone.Version and returning a bool if the version should be pruned. If None, the default policy (retain one version) is used.

rdclass

The zone’s rdata class; the default is class IN.

Type:

dns.rdataclass.RdataClass

origin

The origin of the zone.

Type:

dns.name.Name

nodes

A dictionary mapping the names of nodes in the zone to the nodes themselves.

relativize

True if names in the zone should be relativized.

Type:

bool

find_node(name: Name | str, create: bool = False) Node[source]

Find a node in the zone, possibly creating it.

Parameters:
  • name (dns.name.Name or str) – 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 (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.

Return type:

dns.node.Node

find_rdataset(name: Name | str, rdtype: RdataType | str, covers: RdataType | str = RdataType.TYPE0, create: bool = False) Rdataset[source]

Look for an rdataset with the specified name and type in the zone, and return an rdataset encapsulating it.

The rdataset returned is not a copy; changes to it will change the zone.

Parameters:
  • name (dns.name.Name or str) – 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 (dns.rdatatype.RdataType or str) – The rdata type desired.

  • covers (dns.rdatatype.RdataType or str) – The covered type. Usually dns.rdatatype.NONE, but if rdtype is dns.rdatatype.SIG or 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).

  • create (bool) – 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.

Return type:

dns.rdataset.Rdataset

get_rdataset(name: Name | str, rdtype: RdataType | str, covers: RdataType | str = RdataType.TYPE0, create: bool = False) Rdataset | None[source]

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.

The rdataset returned is not a copy; changes to it will change the zone.

Parameters:
  • name (dns.name.Name or str) – 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 (dns.rdatatype.RdataType or str) – The rdata type desired.

  • covers (dns.rdatatype.RdataType or str) – The covered type. Usually dns.rdatatype.NONE, but if rdtype is dns.rdatatype.SIG or 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).

  • create (bool) – If True, the node will be created if it does not exist.

Return type:

dns.rdataset.Rdataset or None

node_factory

alias of VersionedNode

reader(id: int | None = None, serial: int | None = None) Transaction[source]

Begin a read-only transaction.

set_max_versions(max_versions: int | None) None[source]

Set a pruning policy that retains up to the specified number of versions.

Parameters:

max_versions (int or None) – The maximum number of versions to retain, or None for no limit.

set_pruning_policy(policy: Callable[[Zone, Version], bool | None] | None) None[source]

Set the pruning policy for the zone.

The policy function takes a 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 retained versions are always a consecutive sequence.

Parameters:

policy (Callable or None) – The pruning policy callable, or None to use the default policy.

writer(replacement: bool = False) Transaction[source]

Begin a writable transaction.

Parameters:

replacement (bool) – 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.

The Version Classes

class dns.zone.Version(zone: Zone, id: int, nodes: MutableMapping[Name, Node] | None = None, origin: Name | None = None)[source]
class dns.zone.WritableVersion(zone: Zone, replacement: bool = False)[source]
class dns.zone.ImmutableVersion(*args, **kwargs)[source]
class dns.zone.VersionedNode[source]
class dns.zone.ImmutableVersionedNode(*args, **kwargs)[source]

The Zone Transaction Class

class dns.zone.Transaction(zone: Zone, replacement: bool, version: Version | None = None, make_immutable: bool = False)[source]

The TransactionManager Class

This is the abstract base class of all objects that support transactions.

class dns.transaction.TransactionManager[source]
from_wire_origin() Name | None[source]

Origin to use in from_wire() calls.

get_class() RdataClass[source]

The class of the transaction manager.

origin_information() tuple[Name | None, bool, Name | None][source]

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.

Return type:

tuple[dns.name.Name or None, bool, dns.name.Name or None]

reader() Transaction[source]

Begin a read-only transaction.

writer(replacement: bool = False) Transaction[source]

Begin a writable transaction.

Parameters:

replacement (bool) – 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.

The Transaction Class

class dns.transaction.Transaction(manager: TransactionManager, replacement: bool = False, read_only: bool = False)[source]
add(*args: Any) None[source]

Add records.

The arguments may be:

  • rrset

  • name, rdataset…

  • name, ttl, rdata…

changed() bool[source]

Has this transaction changed anything?

For read-only transactions, the result is always False.

For writable transactions, the result is True if at some time during the life of the transaction, the content was changed.

check_delete_name(check: Callable[[Transaction, Name], None]) None[source]

Call check before putting (storing) an rdataset.

The function is called with the transaction and the name.

The check function may safely make non-mutating transaction method calls, but behavior is undefined if mutating transaction methods are called. The check function should raise an exception if it objects to the put, and otherwise should return None.

check_delete_rdataset(check: Callable[[Transaction, Name, RdataType, RdataType], None]) None[source]

Call check before deleting an rdataset.

The function is called with the transaction, the name, the rdatatype, and the covered rdatatype.

The check function may safely make non-mutating transaction method calls, but behavior is undefined if mutating transaction methods are called. The check function should raise an exception if it objects to the put, and otherwise should return None.

check_put_rdataset(check: Callable[[Transaction, Name, Rdataset], None]) None[source]

Call check before putting (storing) an rdataset.

The function is called with the transaction, the name, and the rdataset.

The check function may safely make non-mutating transaction method calls, but behavior is undefined if mutating transaction methods are called. The check function should raise an exception if it objects to the put, and otherwise should return None.

commit() None[source]

Commit the transaction.

Normally transactions are used as context managers and commit or rollback automatically, but it may be done explicitly if needed.

Raises:

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.

delete(*args: Any) None[source]

Delete records.

It is not an error if some of the records are not in the existing set.

The arguments may be:

  • rrset

  • name

  • name, rdatatype, [covers]

  • name, rdataset…

  • name, rdata…

delete_exact(*args: Any) None[source]

Delete records.

The arguments may be:

  • rrset

  • name

  • name, rdatatype, [covers]

  • name, rdataset…

  • name, rdata…

Raises:

dns.transaction.DeleteNotExact if some of the records are not in the existing set.

get(name: Name | str | None, rdtype: RdataType | str, covers: RdataType | str = RdataType.TYPE0) Rdataset | None[source]

Return the rdataset associated with name, rdtype, and covers, or None if not found.

Note that the returned rdataset is immutable.

get_node(name: Name) Node | None[source]

Return the node at name, if any.

Returns:

An immutable node, or None if name does not exist.

Return type:

dns.node.ImmutableNode or None

iterate_names() Iterator[Name][source]

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.

iterate_rdatasets() Iterator[tuple[Name, Rdataset]][source]

Iterate all the rdatasets in the transaction, returning (dns.name.Name, 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.

name_exists(name: Name | str) bool[source]

Does the specified name exist?

replace(*args: Any) None[source]

Replace the existing rdataset at the name with the specified rdataset, or add the specified rdataset if there was no existing rdataset.

The arguments may be:

  • rrset

  • name, rdataset…

  • name, ttl, rdata…

Note that if you want to replace the entire node, you should do a delete of the name followed by one or more calls to add() or replace().

rollback() None[source]

Rollback the transaction.

Normally transactions are used as context managers and commit or rollback automatically, but it may be done explicitly if needed. Rollback cannot otherwise fail.

Raises:

dns.transaction.AlreadyEnded if the transaction has already been committed or rolled back.

update_serial(value: int = 1, relative: bool = True, name: Name = <DNS name @>) None[source]

Update the serial number.

Parameters:
  • value (int) – An increment if relative is True, or the actual value to set if relative is False.

  • relative (bool) – Whether value is a relative increment or an absolute value. The default is True.

  • name (dns.name.Name) – The name of the SOA record to update.

Raises:
  • KeyError – If there is no SOA rdataset at name.

  • 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.

exception dns.transaction.AlreadyEnded(*args, **kwargs)[source]

Tried to use an already-ended transaction.

exception dns.transaction.DeleteNotExact(*args, **kwargs)[source]

Existing data did not match data specified by an exact delete.

exception dns.transaction.ReadOnly(*args, **kwargs)[source]

Tried to write to a read-only transaction.

The dns.btreezone.Zone Class

dns.btreezone.Zone is a subclass of dns.versioned.Zone backed by a dns.btree.BTreeDict. It maintains names in DNS canonical (sorted) order, automatically tracks 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 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.

class dns.btreezone.Zone(origin: Name | str | None, rdclass: RdataClass = RdataClass.IN, relativize: bool = True, pruning_policy: Callable[[Zone, Version], bool | None] | None = None)[source]

A versioned DNS zone backed by a BTree.

Extends dns.versioned.Zone with:

  • Sorted iteration order: names are always visited in DNS canonical order.

  • Automatic flag tracking: every node is tagged with dns.btreezone.NodeFlags (ORIGIN, DELEGATION, GLUE) as rdatasets are added and removed.

  • Efficient copy-on-write versioning: the underlying dns.btree.BTreeDict shares structure between versions so that creating a new version is cheap.

  • DNSSEC / authoritative-response support: committed versions expose bounds(), which returns the nearest names and closest encloser for any query name.

Initialize a versioned zone object.

Parameters:
  • origin (dns.name.Name, str, or None) – 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 (dns.rdataclass.RdataClass) – The zone’s rdata class; the default is class IN.

  • relativize (bool) – Whether domain names are relativized to the zone’s origin. The default is True.

  • pruning_policy (Callable or None) – A callable taking a dns.versioned.Zone and a dns.zone.Version and returning a bool if the version should be pruned. If None, the default policy (retain one version) is used.

immutable_version_factory

alias of ImmutableVersion

map_factory: Callable[[], MutableMapping[Name, Node]]

alias of BTreeDict[Name, Node]

node_factory

alias of Node

writable_version_factory

alias of WritableVersion

The btreezone Node Classes

class dns.btreezone.NodeFlags(value)[source]

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.

as_integer_ratio()

Return integer ratio.

Return a pair of integers, whose ratio is exactly equal to the original int and with a positive denominator.

>>> (10).as_integer_ratio()
(10, 1)
>>> (-10).as_integer_ratio()
(-10, 1)
>>> (0).as_integer_ratio()
(0, 1)
bit_count()

Number of ones in the binary representation of the absolute value of self.

Also known as the population count.

>>> bin(13)
'0b1101'
>>> (13).bit_count()
3
bit_length()

Number of bits necessary to represent self in binary.

>>> bin(37)
'0b100101'
>>> (37).bit_length()
6
conjugate()

Returns self, the complex conjugate of any int.

denominator

the denominator of a rational number in lowest terms

classmethod from_bytes(bytes, byteorder='big', *, signed=False)

Return the integer represented by the given array of bytes.

bytes

Holds the array of bytes to convert. The argument must either support the buffer protocol or be an iterable object producing bytes. Bytes and bytearray are examples of built-in objects that support the buffer protocol.

byteorder

The byte order used to represent the integer. If byteorder is ‘big’, the most significant byte is at the beginning of the byte array. If byteorder is ‘little’, the most significant byte is at the end of the byte array. To request the native byte order of the host system, use `sys.byteorder’ as the byte order value. Default is to use ‘big’.

signed

Indicates whether two’s complement is used to represent the integer.

imag

the imaginary part of a complex number

numerator

the numerator of a rational number in lowest terms

real

the real part of a complex number

to_bytes(length=1, byteorder='big', *, signed=False)

Return an array of bytes representing an integer.

length

Length of bytes object to use. An OverflowError is raised if the integer is not representable with the given number of bytes. Default is length 1.

byteorder

The byte order used to represent the integer. If byteorder is ‘big’, the most significant byte is at the beginning of the byte array. If byteorder is ‘little’, the most significant byte is at the end of the byte array. To request the native byte order of the host system, use `sys.byteorder’ as the byte order value. Default is to use ‘big’.

signed

Determines whether two’s complement is used to represent the integer. If signed is False and a negative integer is given, an OverflowError is raised.

class dns.btreezone.Node(flags: NodeFlags | None = None)[source]

A BTree zone node, extending dns.node.Node with flags and id fields.

flags

The node’s role flags.

Type:

dns.btreezone.NodeFlags

id

The version id of the last write that touched this node.

Type:

int

is_delegation()[source]

Return True if this node is an NS delegation point.

Return type:

bool

is_glue()[source]

Return True if this node is beneath a delegation point.

Return type:

bool

is_origin()[source]

Return True if this node is the zone origin.

Return type:

bool

is_origin_or_glue()[source]

Return True if this node is at the origin or beneath a delegation.

Return type:

bool

class dns.btreezone.ImmutableNode(*args, **kwargs)[source]

The btreezone Version Classes

class dns.btreezone.Delegations(*, t: int = 127, original: BTree | None = None, in_order: bool = False)[source]

A sorted set of delegation-point names.

Used by dns.btreezone.WritableVersion and dns.btreezone.ImmutableVersion to efficiently determine whether a given name is at or beneath a delegation point.

Create a BTree.

If original is not None, then the BTree is shallow-cloned from original using copy-on-write. Otherwise a new BTree with the specified t value is created.

The BTree is not thread-safe.

get_delegation(name: Name) tuple[Name | None, bool][source]

Get the delegation applicable to name, if it exists.

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).

Return type:

tuple[dns.name.Name or None, bool]

is_glue(name: Name) bool[source]

Is name glue, i.e. is it beneath a delegation?

class dns.btreezone.WritableVersion(zone: Zone, replacement: bool = False)[source]

A mutable version of a dns.btreezone.Zone.

Extends dns.zone.WritableVersion with a 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.

delete_node(name: Name) None[source]

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.

Parameters:

name (dns.name.Name) – The name of the node to delete.

delete_rdataset(name: Name, rdtype: RdataType, covers: RdataType) None[source]

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.

Parameters:
put_rdataset(name: Name, rdataset: Rdataset) None[source]

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.

Parameters:
update_glue_flag(name: Name, is_glue: bool) None[source]

Set or clear the NodeFlags.GLUE flag on all nodes that are subdomains of name.

Parameters:
  • name (dns.name.Name) – The delegation-point name whose subtree should be updated.

  • is_glue (bool) – True to set the GLUE flag; False to clear it.

class dns.btreezone.ImmutableVersion(*args, **kwargs)[source]
bounds(name: Name | str) Bounds[source]

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 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.

The right bound of name is the least successor of name, or None if no name in the zone is greater than name.

The closest encloser of name is name itself, if name is in the zone; otherwise it is the name with the largest number of labels in common with name that is in the zone, either explicitly or by the implied existence of empty non-terminals.

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.

Parameters:

name (dns.name.Name or str) – The name to look up.

Return type:

dns.btreezone.Bounds

class dns.btreezone.Bounds(name: Name, left: Name, right: Name | None, closest_encloser: Name, is_equal: bool, is_delegation: bool)[source]

The result of a bounds() query.

Useful for constructing authoritative responses and for on-the-fly DNSSEC signatures.

name

The queried name.

Type:

dns.name.Name

left

The greatest name in the zone that is less than or equal to name.

Type:

dns.name.Name

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:

dns.name.Name or None

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:

dns.name.Name

is_equal

True if name is present in the zone (i.e. name == left).

Type:

bool

is_delegation

True if the left bound is a delegation point.

Type:

bool