summaryrefslogtreecommitdiff
path: root/dns/rdata.py
diff options
context:
space:
mode:
authorBrian Wellington <bwelling@xbill.org>2020-04-02 11:04:08 -0700
committerBrian Wellington <bwelling@xbill.org>2020-04-02 11:04:08 -0700
commit50752b18d423ef0755a4a08cd8ca531698c1165e (patch)
tree190b752378c7bb0656d67a406c87548edbebdf54 /dns/rdata.py
parent84c65c7b30c7bf1fd52fdd5307900e71e479f3f9 (diff)
downloaddnspython-50752b18d423ef0755a4a08cd8ca531698c1165e.tar.gz
Add dns.rdata.Rdata.replace()
Now that Rdata instances are immutable, there needs to be a way to make a new Rdata based on an existing one. replace() creates a clone of the current Rdata, overriding fields with the specified parameters.
Diffstat (limited to 'dns/rdata.py')
-rw-r--r--dns/rdata.py34
1 files changed, 34 insertions, 0 deletions
diff --git a/dns/rdata.py b/dns/rdata.py
index 4e5d36c..ed56535 100644
--- a/dns/rdata.py
+++ b/dns/rdata.py
@@ -21,6 +21,7 @@ from importlib import import_module
from io import BytesIO
import base64
import binascii
+import inspect
import dns.exception
import dns.name
@@ -272,6 +273,39 @@ class Rdata(object):
def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
raise NotImplementedError
+ def replace(self, **kwargs):
+ """
+ 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*.
+ """
+
+ # Get the constructor parameters.
+ parameters = inspect.signature(self.__init__).parameters
+
+ # Ensure that all of the arguments correspond to valid fields.
+ # Don't allow rdclass or rdtype to be changed, though.
+ for key in kwargs:
+ if key not in parameters:
+ raise AttributeError("'{}' object has no attribute '{}'"
+ .format(self.__class__.__name__, key))
+ if key in ('rdclass', 'rdtype'):
+ raise AttributeError("Cannot overwrite '{}' attribute '{}'"
+ .format(self.__class__.__name__, key))
+
+ # Construct the parameter list. For each field, use the value in
+ # kwargs if present, and the current value otherwise.
+ args = (kwargs.get(key, getattr(self, key)) for key in parameters)
+
+ # Create and return the new object.
+ return self.__class__(*args)
+
+
class GenericRdata(Rdata):
"""Generic Rdata Class