Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Address class #227

Merged
merged 51 commits into from
Mar 21, 2022
Merged

Address class #227

merged 51 commits into from
Mar 21, 2022

Conversation

ItsDrike
Copy link
Member

@ItsDrike ItsDrike commented Feb 22, 2022

This adds an Address class, which is a NamedTuple with multiple custom functionalities related to addresses moved under a single place.

This Address will automatically perform the validity checks on initialization, removing the need for us to manually call ensure_valid function each time we initialize the server class, assuming we construct this class there (or take it as a param). It also makes it easy to validate the address on mutations, since Address class, being a subclass of immutable tuple type, you can't mutate it at all, instead you'd need to make a new address to set the self.address attribute, and again, there are validity checks on initialization, giving us some piece of mind about it.

Because this is a subclass of NamedTuple, it allows us to pass this class to functions which only take a tuple of (host, port), which is quite common, this makes things a bit nicer since it would only allow us to pass addresses passing the validity checks and it's simply neater to do some_func(self.address) than some_func((self.host, self.port)).

Ideally, I'd like to deprecate the host and port attributes of both of the server classes in favor of an address atribute holding this new class. This deprecation will probably be done using properties with deprecation notices, returning self.address.host and self.address.port respectively, though I'd like to use the deprecated decorator from not yet merged #222. But if it's deemed useful enough, these can stay as non-deprecated properties too, I can see people wanting an easy way to get host and port directly, instead of having to do address.host/address.port, if that's desired, please mention it in readme/comment/on discord.

Closes #211

Blocked by:

This adds a new Address NamedTuple class, which we can later use in
multiple places, even pass it to functions which take a pure tuple of
(host, port), since it is a subclass of tuple.

This new class also includes both synchronous and asynchronous methods
for performing A record DNS lookups to get the actual IP from a host.
This can sometimes be useful, for example to know what ip type the
address has (IPv4/IPv6) which is important for making sockets.
@ItsDrike ItsDrike added area: API Related to core API of the project state: WIP Work In Progress type: feature New request or feature labels Feb 22, 2022
While there's nothing technically wrong with Connection clases taking
simple tuples of (host, port), doing that skips address validation
checks, and gives us less freedom to work with later.
Only passing host to _retry_query functions means we need to construct
the address in there, however this is inefficient since this function is
expected to run multiple times and the address will stay the same in
every run.

Even though creating Address instances is relatively fast, since it's
just construction of stdlib's typing.NamedTuple with additional check,
there's no need to do it multiple times anyway.
For some reason, when running tests on macos, DNS A record resulution is
failing with NXDOMAIN when trying to resolve for 'localhost', instead of
properly returning '127.0.0.1'. This issue wasn't previously catched,
before the DNS resolving implementation was catching this NXDOMAIN as a
way to handle for host already being an IP.

This is a temporary fix which adds try-except for NXDOMAIN and sets the
IP to host (just like in the previous implementation), which bypasses
this failure. But this should be removed as soon as we find the root
cause of this mac-os test failure (I don't suppose mac-os actually can't
resolve 'localhost' to IP, though it would seem that way from the
workflow).
This extends 04a8b0a which added temporary support for NXDOMAIN failures
on mac-os. Rather than silently passing on NXDOMAIN, this at least
reports a warning, even though it's not an error which it should be
since again, mac-os has not yet resolved issues described in 04a8b0a
Since tests for SRV resolution were moved to address tests, the server
tests no longer covered the lookup method, so this adds tests to
explicitly test the lookup constructor only
We used __new__ here because NamedTuple didn't allow using __init__
directly, however since then, we've moved from directly using a class
inheriting from NamedTuple to a class inheriting from base class, and
only that base class inherits directly from NamedTuple. This means we
can actually override __init__ here.
@ItsDrike ItsDrike marked this pull request as ready for review March 15, 2022 15:51
@ItsDrike ItsDrike added status: needs review Author is waiting for someone to review and approve and removed state: WIP Work In Progress labels Mar 20, 2022
Copy link
Contributor

@kevinkjt2000 kevinkjt2000 left a comment

Choose a reason for hiding this comment

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

One small testing improvement, and it looks good to me 👍

mcstatus/tests/test_address.py Outdated Show resolved Hide resolved
def const_coro(value: T) -> Callable[..., Awaitable[T]]:
"""This is a helper function, which returns an async func returning value.

This is needed because in python 3.7, Mock.return_value didn't properly cover
Copy link
Contributor

Choose a reason for hiding this comment

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

Oh yeah, I remember this pain. I used to install an async test helper to have AsyncMock.
👍 for avoiding a dependency with a single function.

@ItsDrike ItsDrike merged commit 7e9d5b5 into master Mar 21, 2022
@ItsDrike ItsDrike deleted the address-class branch March 21, 2022 18:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: API Related to core API of the project status: needs review Author is waiting for someone to review and approve type: feature New request or feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Usedns.asyncresolver for asynchronous lookups instead of blocking 'dns.resolver.resolve'
2 participants