Summary of changes since 1.2.0:
* dns/rdtypes/ANY/TXT.py (TXT.from_text): The masterfile parser
incorrectly rejected TXT records where a value was not quoted.
* dns/message.py: Added make_response(), which creates a skeletal
response for the specified query. Added opcode() and set_opcode()
convenience methods to the Message class. Added the request_payload
attribute to the Message class.
* dns/zone.py (from_xfr): dns.zone.from_xfr() in relativization
mode incorrectly set zone.origin to the empty name.
* dns/name.py (Name.to_wire): The 'file' parameter to
Name.to_wire() is now optional; if omitted, the wire form will
be returned as the value of the function.
* dns/message.py (Message.find_rrset): find_rrset() now uses an
index, vastly improving the from_wire() performance of large
messages such as zone transfers.
* dns/query.py: sending queries to a nameserver via IPv6 now
works.
* dns/inet.py (af_for_address): Add af_for_address(), which looks
at a textual-form address and attempts to determine which address
family it is.
* dns/query.py: the default for the 'af' parameter of the udp(),
tcp(), and xfr() functions has been changed from AF_INET to None,
which causes dns.inet.af_for_address() to be used to determine the
address family. If dns.inet.af_for_address() can't figure it out,
we fall back to AF_INET and hope for the best.
* dns/rdtypes/ANY/NSEC.py (NSEC.from_text): The NSEC text format
does not allow specifying types by number, so we shouldn't either.
* dns/renderer.py: the renderer module didn't import random,
causing an exception to be raised if a query id wasn't provided
when a Renderer was created.
* dns/resolver.py (Resolver.query): the resolver wasn't catching
dns.exception.Timeout, so a timeout erroneously caused the whole
resolution to fail instead of just going on to the next server.
* dns/rdtypes/ANY/LOC.py (LOC.from_text): LOC milliseconds values
were converted incorrectly if the length of the milliseconds
string was less than 3.
* dns/update.py (Update.delete): We erroneously specified a
"deleting" value of dns.rdatatype.NONE instead of
dns.rdataclass.NONE when the thing being deleted was either an
Rdataset instance or an Rdata instance.
* dns/rdtypes/ANY/SSHFP.py: Added support for the proposed SSHFP
RR type.
* dns/rdata.py (from_text): The masterfile reader did not
accept the unknown RR syntax when used with a known RR type.
* dns/name.py (from_text): dns.name.from_text() did not raise
an exception if a backslash escape ended prematurely.
* dns/zone.py (_MasterReader._rr_line): The masterfile reader
erroneously treated lines starting with leading whitespace but
not having any RR definition as an error. It now treats
them like a blank line (which is not an error).
* Added support for new DNSSEC types RRSIG, NSEC, and DNSKEY.
* dns/query.py (_connect): Windows returns EWOULDBLOCK instead
of EINPROGRESS when trying to connect a nonblocking socket.
* dns/rdtypes/ANY/LOC.py (LOC.to_wire): We encoded and decoded LOC
incorrectly, since we were interpreting the values of altitiude,
size, hprec, and vprec in meters instead of centimeters.
* dns/rdtypes/IN/WKS.py (WKS.from_wire): The WKS protocol value is
encoded with just one octet, not two!
* dns/resolver.py (Cache.maybe_clean): The cleaner deleted items
from the dictionary while iterating it, causing a RuntimeError
to be raised. Thanks to Mark R. Levinson for the bug report,
regression test, and fix.
Changes in 1.2.0:
- Timeout support has been overhauled. It now works on Python 2.2 as
well as 2.3, and the total time spent processing a query is now much
more controllable than before since the timeout is now on the whole
query instead of just on individual network calls.
- The master file reader now gives the filename and line number of
the offending input when a syntax error occurs.
- $INCLUDE is now supported in DNS master files. Processing of
$INCLUDE can also be disabled if desired.
- BIND 8 style TTLs, e.g. "1w2d3h4m5s", are accepted when reading a
master file, but will never be emitted.
- Basic zone sanity checks are made after a zone is
loaded. Specifically, the zone must have SOA and NS rdatasets at its
origin.
Summary of changes from 1.0.0:
* Message sections are now lists of RRsets, not lists of nodes.
* Nodes no longer have names; owner names are associated with
nodes in the Zone object's nodes dictionary.
* Many tests have been added to the test suite; dnspython 1.0.0
had 47 tests, 1.1.0 has 275. The improved testing uncovered a
number of bugs, all of which have been fixed.
* The NameDict class provides a dictionary whose keys are DNS
names. In addition to behaving like a normal Python dictionary,
it also provides the get_deepest_match() method. If, for
example, you had a dictionary containing the keys foo.com and
com, then get_deepest_match() of the name a.b.foo.com would
match the foo.com key.
* A new Renderer class for those applications which want finer
control over the DNS wire format message generation process.
* Support for a "TooBig" exception if the size of wire format
output exceeds a specified limit.
* Zones now have find_rrset() and find_rdataset() convenience
methods. They let you retrieve rdata with the specified name
and type in one call, e.g.:
rrset = zone.find_rrset('foo', 'mx')
* Other new zone convenience methods include: find_node(),
delete_node(), delete_rdataset(), replace_rdataset(),
iterate_rdatasets(), and iterate_rdatas().
* get_ variants of find_ methods are provided; the difference is
that get_ methods return None if the desired object doesn't
exist, whereas the find_ methods raise an exception.
* Zones now have a to_file() method.
* The message and zone from_file() methods allow Unicode filenames
on platforms (and versions of python) which support
them. Universal newline support is also used if available.
* The Zone class now implements more of the standard mapping
interface. E.g. you can say zone.keys(), zone.get('name'),
zone.iteritems(), etc. __iter__() has been changed to iterate
the keys rather than values to match the standard mapping
interface's behavior.
* Rdatasets support more set operations
* Zone and Node factories may be specified, allowing applications
to subclass Zone or Node and yet still use the algorithms which
build zones from master files or AXFR data.
* dns.ipv6.inet_ntoa() now minimizes the text representation of
IPv6 addresses in the usual way,
e.g. "0000:0000:0000:0000:0000:0000:0000:0001" is minimized to
"::1".
* dns.query functions now take an optional address family parameter.
All known bugs from 1.0.0 are fixed in this release.
Changes from 1.0.0b3:
* dns/rdata.py: Rdatas now implement rich comparisons instead of
__cmp__.
* dns/name.py: Names now implement rich comparisons instead of
__cmp__.
* dns/inet.py (inet_ntop): Always use our code, since the code
in the socket module doesn't support AF_INET6 conversions if
IPv6 sockets are not available on the system.
* dns/resolver.py (Answer.__init__): A dangling CNAME chain was
not raising NoAnswer.
* Added a simple resolver Cache class.
* Added an expiration attribute to answer instances.
dnspython is a DNS toolkit for Python. It provides both high and low
level access to DNS. The high level classes perform queries for data
of a given name, type, and class, and return an answer set. The low
level classes allow direct manipulation of DNS zones, messages, names,
and records.