Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
5142603
Add support for pycares 5
bdraco Dec 11, 2025
9d8a68e
Add support for pycares 5
bdraco Dec 11, 2025
361fb62
Add support for pycares 5
bdraco Dec 11, 2025
212aa30
fixes
bdraco Dec 11, 2025
db65ca3
fixes
bdraco Dec 11, 2025
78e350d
fixes
bdraco Dec 11, 2025
ce2d3f4
fixes
bdraco Dec 11, 2025
1cb6720
fixes
bdraco Dec 11, 2025
b264b62
fixes
bdraco Dec 11, 2025
dc2aab9
fixes
bdraco Dec 11, 2025
5419903
compat tests
bdraco Dec 11, 2025
4dd4f80
fixes
bdraco Dec 11, 2025
741a22f
fixes
bdraco Dec 11, 2025
2801db7
minimize change
bdraco Dec 11, 2025
bf68807
minimize change
bdraco Dec 11, 2025
f218c46
minimize change
bdraco Dec 11, 2025
4a29cad
minimize change
bdraco Dec 11, 2025
5061ac0
minimize change
bdraco Dec 11, 2025
f119bce
more typing fixes
bdraco Dec 11, 2025
a5b24b8
more typing fixes
bdraco Dec 11, 2025
42b7419
more typing fixes
bdraco Dec 11, 2025
3dc5199
more typing fixes
bdraco Dec 11, 2025
e5d7690
more typing fixes
bdraco Dec 11, 2025
2e0af6f
socket state fallback path test
bdraco Dec 11, 2025
824ea45
fix win32 test
bdraco Dec 11, 2025
3a9fce0
more typing
bdraco Dec 11, 2025
a5ef8f7
add missing coverage
bdraco Dec 11, 2025
84c4ed8
more windows test fixes
bdraco Dec 11, 2025
f8b5ce3
pycares no longer works with pypy
bdraco Dec 11, 2025
d3f7f69
make sure it works on 3.14t as well
bdraco Dec 11, 2025
ea162cd
fix missing coverage
bdraco Dec 11, 2025
b299d69
restore some lost coverage
bdraco Dec 11, 2025
fad285d
typing fixes
bdraco Dec 11, 2025
6540001
restore some missing coverage
bdraco Dec 11, 2025
e98a218
restore some missing coverage
bdraco Dec 11, 2025
450166d
missing classifer
bdraco Dec 11, 2025
108ac66
tweaks
bdraco Dec 11, 2025
2fc55b1
revert
bdraco Dec 11, 2025
6f88df0
back compat for nameservers
bdraco Dec 11, 2025
9428d46
deprecate query, add query_dns
bdraco Dec 11, 2025
c76550c
update docs
bdraco Dec 11, 2025
68cb7a0
add some more cover
bdraco Dec 11, 2025
2858193
add some more cover
bdraco Dec 11, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 1 addition & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: [ '3.9', '3.10', '3.11', '3.12', '3.13', '3.14' ]
exclude:
- os: macos-latest
python-version: 3.9
include:
- python-version: pypy-3.9
os: ubuntu-latest
python-version: [ '3.10', '3.11', '3.12', '3.13', '3.14', '3.14t' ]
timeout-minutes: 15
steps:
- name: Checkout
Expand Down
76 changes: 57 additions & 19 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,13 @@ Example
import asyncio
import aiodns

loop = asyncio.get_event_loop()
resolver = aiodns.DNSResolver(loop=loop)
async def main():
resolver = aiodns.DNSResolver()
result = await resolver.query_dns('google.com', 'A')
for record in result.answer:
print(record.data.addr)

async def query(name, query_type):
return await resolver.query(name, query_type)

coro = query('google.com', 'A')
result = loop.run_until_complete(coro)
asyncio.run(main())


The following query types are supported: A, AAAA, ANY, CAA, CNAME, MX, NAPTR, NS, PTR, SOA, SRV, TXT.
Expand All @@ -37,27 +36,66 @@ API

The API is pretty simple, the following functions are provided in the ``DNSResolver`` class:

* ``query(host, type)``: Do a DNS resolution of the given type for the given hostname. It returns an
instance of ``asyncio.Future``. The actual result of the DNS query is taken directly from pycares.
As of version 1.0.0 of aiodns (and pycares, for that matter) results are always namedtuple-like
objects with different attributes. Please check the `documentation
<http://pycares.readthedocs.org/latest/channel.html#pycares.Channel.query>`_
for the result fields.
* ``query_dns(host, type)``: Do a DNS resolution of the given type for the given hostname. It returns an
instance of ``asyncio.Future``. The result is a ``pycares.DNSResult`` object with ``answer``,
``authority``, and ``additional`` attributes containing lists of ``pycares.DNSRecord`` objects.
Each record has ``type``, ``ttl``, and ``data`` attributes. Check the `pycares documentation
<https://pycares.readthedocs.io/>`_ for details on the data attributes for each record type.
* ``query(host, type)``: **Deprecated** - use ``query_dns()`` instead. This method returns results
in a legacy format compatible with aiodns 3.x for backward compatibility.
* ``gethostbyname(host, socket_family)``: Do a DNS resolution for the given
hostname and the desired type of address family (i.e. ``socket.AF_INET``).
While ``query()`` always performs a request to a DNS server,
While ``query_dns()`` always performs a request to a DNS server,
``gethostbyname()`` first looks into ``/etc/hosts`` and thus can resolve
local hostnames (such as ``localhost``). Please check `the documentation
<http://pycares.readthedocs.io/latest/channel.html#pycares.Channel.gethostbyname>`_
for the result fields. The actual result of the call is a ``asyncio.Future``.
local hostnames (such as ``localhost``). The actual result of the call is a ``asyncio.Future``.
* ``gethostbyaddr(name)``: Make a reverse lookup for an address.
* ``getaddrinfo(host, family, port, proto, type, flags)``: Resolve a host and port into a list of
address info entries.
* ``getnameinfo(sockaddr, flags)``: Resolve a socket address to a host and port.
* ``cancel()``: Cancel all pending DNS queries. All futures will get ``DNSError`` exception set, with
``ARES_ECANCELLED`` errno.
* ``close()``: Close the resolver. This releases all resources and cancels any pending queries. It must be called
when the resolver is no longer needed (e.g., application shutdown). The resolver should only be closed from the
event loop that created the resolver.


Migrating from aiodns 3.x
=========================

aiodns 4.x introduces a new ``query_dns()`` method that returns native pycares 5.x result types.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps a link to the pycares docs where the result types are described would help?

The old ``query()`` method is deprecated but continues to work for backward compatibility.

.. code:: python

# Old API (deprecated)
result = await resolver.query('example.com', 'MX')
for record in result:
print(record.host, record.priority)

# New API (recommended)
result = await resolver.query_dns('example.com', 'MX')
for record in result.answer:
print(record.data.exchange, record.data.priority)


Future migration to aiodns 5.x
------------------------------

The temporary ``query_dns()`` naming allows gradual migration without breaking changes:

+-----------+---------------------------------------+--------------------------------------------+
| Version | ``query()`` | ``query_dns()`` |
+===========+=======================================+============================================+
| **4.x** | Deprecated, returns compat types | New API, returns pycares 5.x types |
+-----------+---------------------------------------+--------------------------------------------+
| **5.x** | New API, returns pycares 5.x types | Alias to ``query()`` for back compat |
+-----------+---------------------------------------+--------------------------------------------+

In aiodns 5.x, ``query()`` will become the primary API returning native pycares 5.x types,
and ``query_dns()`` will remain as an alias for backward compatibility. This allows downstream
projects to migrate at their own pace.


Async Context Manager Support
=============================

Expand All @@ -67,7 +105,7 @@ for scenarios where automatic cleanup is desired:
.. code:: python

async with aiodns.DNSResolver() as resolver:
result = await resolver.query('example.com', 'A')
result = await resolver.query_dns('example.com', 'A')
# resolver.close() is called automatically when exiting the context

**Important**: This pattern is discouraged for most applications because ``DNSResolver`` instances
Expand Down Expand Up @@ -101,7 +139,7 @@ This may have other implications for the rest of your codebase, so make sure to
Running the test suite
======================

To run the test suite: ``python tests.py``
To run the test suite: ``python -m pytest tests/``


Author
Expand Down
Loading