Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #54 +/- ##
==========================================
+ Coverage 92.51% 93.79% +1.28%
==========================================
Files 24 24
Lines 1790 1966 +176
==========================================
+ Hits 1656 1844 +188
+ Misses 134 122 -12 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
Adds first-class IPv6 support across STUN/SIP/RTP and introduces stronger SIP typing primitives (URI/method/status) to make signaling and serialization more robust and explicit.
Changes:
- Decode STUN
MAPPED-ADDRESS/XOR-MAPPED-ADDRESSfor both IPv4 and IPv6 and propagate typedipaddressobjects through STUN/RTP/SIP. - Introduce
SipUri,SIPStatus, andSIPMethod, and update SIP message/protocol code to usephrase+ enum-based status/methods. - Update CLI parsing and docs/tests to reflect IPv6 bracket rules and the new types.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| voip/stun.py | Adds shared address decoding helper and returns typed IPv4/IPv6 addresses. |
| voip/sip/types.py | Adds SipUri, SIPStatus, SIPMethod and expands SIP typing surface. |
| voip/sip/protocol.py | Uses typed addresses, formats IPv6 hosts with brackets, and migrates to SIPStatus/phrase. |
| voip/sip/messages.py | Strengthens request/response types and renames reason → phrase. |
| voip/sip/init.py | Re-exports new SIP types (SipUri, SIPStatus, SIPMethod). |
| voip/rtp.py | Propagates typed public address future result from STUN. |
| voip/ai.py | Avoids appending/speaking empty assistant replies. |
| voip/main.py | Switches AOR parsing to SipUri and adds bracketed IPv6 host:port parsing. |
| tests/test_stun.py | Adds IPv6 STUN attribute builders and coverage for IPv6 parsing paths. |
| tests/test_rtp.py | Updates expectations to typed ipaddress results. |
| tests/test_main.py | Adjusts CLI tests for new parsing flow and transport mocking. |
| tests/sip/test_types.py | Adds coverage for SipUri.parse() and SipUri.__str__() including IPv6. |
| tests/sip/test_protocol.py | Updates protocol tests for typed addresses, phrase, IPv6 SDP addrtype, and header formatting. |
| tests/sip/test_messages.py | Updates message tests for phrase rename. |
| docs/feature_roadmap.md | Documents IPv6 support in STUN/SIP/SDP. |
| README.md | Adds lint suppression for example password literal. |
Comments suppressed due to low confidence (1)
voip/main.py:78
_parse_hostport()will mis-parse an unbracketed IPv6 literal like2001:db8::1ashost='2001:db8::'andport=1because it falls through torpartition(':'). Since the docstring requires brackets for IPv6, consider explicitly detecting unbracketed IPv6 (e.g., multiple ':' characters) and raisingclick.BadParameterwith guidance to use[addr]syntax.
host, _, port_str = value.rpartition(":")
if not host:
return value, default_port
try:
return host, int(port_str)
except ValueError:
raise click.BadParameter(f"Invalid port in {value!r}.", param=param) from None
You can also share your feedback on Copilot code review. Take the survey.
|
@codingjoe I've opened a new pull request, #55, to work on those changes. Once the pull request is ready, I'll request review from you. |
Co-authored-by: Copilot Autofix powered by AI <[email protected]>
… IPv6 tests (#55) `_parse_hostport()` had manual bracket-parsing logic with no tests, silently mishandled unbracketed IPv6 literals, and returned a plain `str` host regardless of whether the value was a numeric IP address. ## Changes - **`voip/__main__.py`**: - Replaced manual bracket/partition logic with a single `HOSTPORT_PATTERN` regex that handles `[IPv6HOST][:PORT]`, `HOST:PORT`, and bare `HOST` forms. - Return type changed from `tuple[str, int]` to `tuple[IPv4Address | IPv6Address | str, int]` — numeric IP literals are parsed into typed address objects; hostnames remain `str`. - Unbracketed IPv6 literals (e.g. `::1`) raise `click.BadParameter` directing the user to bracket notation. - `_parse_stun_server` converts the typed host to `str` for socket/asyncio compatibility. - `_connect_sip` uses `str(proxy_addr[0])` when calling `asyncio.create_connection`. - **`voip/sip/protocol.py`**: `outbound_proxy` type updated to `tuple[IPv4Address | IPv6Address | str, int] | None`. - **`tests/test_main.py`**: New `TestParseHostport` class covering the three key paths: - `[::1]` → `(IPv6Address("::1"), 5061)` (default port) - `[::1]:5061` → `(IPv6Address("::1"), 5061)` (explicit port) - `::1` → `BadParameter("...enclosed in brackets...")` ```python # Before: silently wrong, plain str host _parse_hostport(None, None, "::1") # → ("::", 1) _parse_hostport(None, None, "[::1]") # → ("::1", 5061) # After: explicit error for unbracketed IPv6, typed address objects _parse_hostport(None, None, "::1") # click.BadParameter: IPv6 address must be enclosed in brackets, e.g. [::1]. _parse_hostport(None, None, "[::1]") # → (IPv6Address('::1'), 5061) _parse_hostport(None, None, "1.2.3.4:5060") # → (IPv4Address('1.2.3.4'), 5060) ``` <!-- START COPILOT CODING AGENT TIPS --> --- 📍 Connect Copilot coding agent with [Jira](https://gh.io/cca-jira-docs), [Azure Boards](https://gh.io/cca-azure-boards-docs) or [Linear](https://gh.io/cca-linear-docs) to delegate work to Copilot in one click without leaving your project management tool. --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: codingjoe <[email protected]> Co-authored-by: Johannes Maron <[email protected]> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
No description provided.