From: Bob Halley Date: Wed, 19 Aug 2020 02:23:22 +0000 (-0700) Subject: store reference to manager in all txns; add origin_information() X-Git-Tag: v2.1.0rc1~69 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1b2af789ffc6c8da54dda199a94c9d79797d356c;p=thirdparty%2Fdnspython.git store reference to manager in all txns; add origin_information() --- diff --git a/dns/masterfile.py b/dns/masterfile.py index 30553b53..66bb6a3a 100644 --- a/dns/masterfile.py +++ b/dns/masterfile.py @@ -42,19 +42,15 @@ class Reader: """Read a DNS master file into a transaction.""" - def __init__(self, tok, origin, rdclass, relativize, txn, - allow_include=False): - if isinstance(origin, str): - origin = dns.name.from_text(origin) + def __init__(self, tok, rdclass, txn, allow_include=False): self.tok = tok - self.current_origin = origin - self.relativize = relativize + (self.zone_origin, self.relativize) = txn.manager.origin_information() + self.current_origin = self.zone_origin self.last_ttl = 0 self.last_ttl_known = False self.default_ttl = 0 self.default_ttl_known = False self.last_name = self.current_origin - self.zone_origin = origin self.zone_rdclass = rdclass self.txn = txn self.saved_state = [] diff --git a/dns/transaction.py b/dns/transaction.py index aec06626..eae2920c 100644 --- a/dns/transaction.py +++ b/dns/transaction.py @@ -20,13 +20,30 @@ class TransactionManager: def writer(self, replacement=False): """Begin a writable transaction. - *replacement*, a `bool`. If `True`, the content of the + *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. """ raise NotImplementedError # pragma: no cover + def origin_information(self): + """Returns an (origin: ``dns.name.Name``, relativize: ``bool``) tuple + giving the absolute name of the default origin for any + relative domain names, and whether names should be relativized + to that origin. + + If the returned name is `None`, then no origin information is + available. + + 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). + + """ + raise NotImplementedError # pragma: no cover + class DeleteNotExact(dns.exception.DNSException): """Existing data did not match data specified by an exact delete.""" @@ -42,7 +59,8 @@ class AlreadyEnded(dns.exception.DNSException): class Transaction: - def __init__(self, replacement=False, read_only=False): + def __init__(self, manager, replacement=False, read_only=False): + self.manager = manager self.replacement = replacement self.read_only = read_only self._ended = False diff --git a/dns/versioned.py b/dns/versioned.py index e070c1a9..99c30e49 100644 --- a/dns/versioned.py +++ b/dns/versioned.py @@ -234,7 +234,7 @@ class Zone(dns.zone.Zone): raise KeyError('serial not found') else: version = self._versions[-1] - txn = Transaction(False, self, version) + txn = Transaction(self, False, version) self._readers.add(txn) return txn @@ -252,7 +252,7 @@ class Zone(dns.zone.Zone): # give up the lock, so that we hold the lock as # short a time as possible. This is why we call # _setup_version() below. - self._write_txn = Transaction(replacement, self) + self._write_txn = Transaction(self, replacement) # give up our exclusive right to make a Transaction self._write_event = None break @@ -403,12 +403,15 @@ class Zone(dns.zone.Zone): class Transaction(dns.transaction.Transaction): - def __init__(self, replacement, zone, version=None): + def __init__(self, zone, replacement, version=None): read_only = version is not None - super().__init__(replacement, read_only) - self.zone = zone + super().__init__(zone, replacement, read_only) self.version = version + @property + def zone(self): + return self.manager + def _setup_version(self): assert self.version is None self.version = WritableVersion(self.zone, self.replacement) diff --git a/dns/zone.py b/dns/zone.py index e85603b4..11c4c336 100644 --- a/dns/zone.py +++ b/dns/zone.py @@ -643,10 +643,13 @@ class Zone(dns.transaction.TransactionManager): raise NoNS def reader(self): - return Transaction(False, True, self) + return Transaction(self, False, True) def writer(self, replacement=False): - return Transaction(replacement, False, self) + return Transaction(self, replacement, False) + + def origin_information(self): + return (self.origin, self.relativize) class Transaction(dns.transaction.Transaction): @@ -654,11 +657,14 @@ class Transaction(dns.transaction.Transaction): _deleted_rdataset = dns.rdataset.Rdataset(dns.rdataclass.ANY, dns.rdatatype.ANY) - def __init__(self, replacement, read_only, zone): - super().__init__(replacement, read_only) - self.zone = zone + def __init__(self, zone, replacement, read_only): + super().__init__(zone, replacement, read_only) self.rdatasets = {} + @property + def zone(self): + return self.manager + def _get_rdataset(self, name, rdclass, rdtype, covers): if rdclass != self.zone.rdclass: raise ValueError(f'class {rdclass} != ' + @@ -805,7 +811,7 @@ def from_text(text, origin=None, rdclass=dns.rdataclass.IN, zone = zone_factory(origin, rdclass, relativize=relativize) with zone.writer(True) as txn: tok = dns.tokenizer.Tokenizer(text, filename, idna_codec=idna_codec) - reader = dns.masterfile.Reader(tok, origin, rdclass, relativize, txn, + reader = dns.masterfile.Reader(tok, rdclass, txn, allow_include=allow_include) try: reader.read() diff --git a/tests/test_transaction.py b/tests/test_transaction.py index 3dcaba03..bf7b130b 100644 --- a/tests/test_transaction.py +++ b/tests/test_transaction.py @@ -18,14 +18,17 @@ class DB(dns.transaction.TransactionManager): self.rdatasets = {} def reader(self): - return Transaction(False, True, self) + return Transaction(self, False, True) def writer(self, replacement=False): - return Transaction(replacement, False, self) + return Transaction(self, replacement, False) + + def origin_information(self): + return (None, True) class Transaction(dns.transaction.Transaction): - def __init__(self, replacement, read_only, db): + def __init__(self, db, replacement, read_only): super().__init__(replacement) self.db = db self.rdatasets = {}