fix(resolver): handle None result.service from getnameinfo()#12392
fix(resolver): handle None result.service from getnameinfo()#12392rnagulapalle wants to merge 6 commits into
Conversation
getnameinfo() returns a NameinfoResult where service is typed as str | None. Passing None directly to int() fails mypy's arg-type check. Fall back to the original numeric port when service is None. Fixes mypy error: Argument 1 to "int" has incompatible type "str | None"; expected "str | Buffer | SupportsInt | ..."
for more information, see https://pre-commit.ci
|
Closing — will be re-raised by Phalanx CI Fixer autonomously. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #12392 +/- ##
===========================================
- Coverage 98.94% 47.29% -51.66%
===========================================
Files 131 131
Lines 46683 46706 +23
Branches 2421 2421
===========================================
- Hits 46189 22088 -24101
- Misses 369 23996 +23627
- Partials 125 622 +497
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
Merging this PR will not alter performance
Comparing Footnotes
|
|
@rnagulapalle could you use our PR template instead of replacing it? |
| int(result.service) | ||
| if result.service is not None | ||
| else address[1] |
There was a problem hiding this comment.
Is there a situation where result.service != address[1]?
Resolve the resolver test conflict while keeping the upstream DNSError regression coverage. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Updated the PR description to follow the repository template. Thanks for the pointer. |
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Fixes two bugs in AsyncResolver: an IndexError when handling aiodns.error.DNSError with a single argument, and handling of None for result.service returned by getnameinfo() for link-local IPv6 addresses.
Changes:
- Corrected the length check from
>= 1to>= 2when accessingexc.args[1]in DNS error handling. - Added a fallback to
address[1]for the port whenresult.serviceisNonein the link-local IPv6 path. - Added tests for the single-arg DNSError case and for extracting port from
getnameinfo(), and updated the test fixture to accept a configurableservice.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| aiohttp/resolver.py | Off-by-one fix in DNSError handling and None-safe port extraction from getnameinfo(). |
| tests/test_resolver.py | New tests for the bugfixes and updated fake getnameinfo helper to accept a service argument. |
| CHANGES/12253.bugfix.rst | News fragment describing both fixes. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| def __init__(self, host: str, service: str = "0") -> None: | ||
| self.node = host | ||
| self.service = None | ||
| self.service = service |
| except aiodns.error.DNSError as exc: | ||
| msg = exc.args[1] if len(exc.args) >= 1 else "DNS lookup failed" | ||
| msg = exc.args[1] if len(exc.args) >= 2 else "DNS lookup failed" | ||
| raise OSError(None, msg) from exc |
Could you also answer the inline question? I'm unclear if there should be an if condition there at all. |
What do these changes do?
Handle the rare async resolver path where
aiodns/pycaresreturns a link-local IPv6getnameinfo()result withservice=None.The resolver now falls back to the numeric port from the original address tuple instead of passing
Nonetoint().Are there changes in behavior for the user?
Yes. Link-local IPv6 resolution through
AsyncResolverno longer raises whenresult.serviceisNone; it keeps the original port value instead.Is it a substantial burden for the maintainers to support this?
No. The change is limited to the existing link-local IPv6 resolver branch and mirrors the fallback behavior already used by the non-link-local IPv6 and IPv4 paths, which keep
address[1]as the port.Related issue number
No linked issue.
Checklist
CONTRIBUTORS.txtCHANGES/folder<issue_or_pr_num>.<type>.rst(e.g.588.bugfix.rst)number after creating the PR
.bugfix: A bug fix for something the maintainers deemed animproper undesired behavior that got corrected to match
pre-agreed expectations.
.feature: A new behavior, public APIs. That sort of stuff..deprecation: A declaration of future API removals and breakingchanges in behavior.
.breaking: When something public is removed in a breaking way.Could be deprecated in an earlier release.
.doc: Notable updates to the documentation structure or buildprocess.
.packaging: Notes for downstreams about unobvious side effectsand tooling. Changes in the test invocation considerations and
runtime assumptions.
.contrib: Stuff that affects the contributor experience. e.g.Running tests, building the docs, setting up the development
environment.
.misc: Changes that are hard to assign to any of the abovecategories.
Test plan
python3 -m py_compile aiohttp/resolver.py tests/test_resolver.py