Refactor _parse_hostport: regex-based parsing, typed IP return, and IPv6 tests#55
Refactor _parse_hostport: regex-based parsing, typed IP return, and IPv6 tests#55
_parse_hostport: regex-based parsing, typed IP return, and IPv6 tests#55Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## ipv6 #55 +/- ##
==========================================
+ Coverage 93.11% 93.79% +0.68%
==========================================
Files 24 24
Lines 1975 1966 -9
==========================================
+ Hits 1839 1844 +5
+ Misses 136 122 -14 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
…arse_hostport Co-authored-by: codingjoe <[email protected]>
|
Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details. Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
_parse_hostport
…IPv6Address | str Co-authored-by: codingjoe <[email protected]>
|
Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details. Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
_parse_hostport_parse_hostport: regex-based parsing, typed IP return, and IPv6 tests
voip/__main__.py
Outdated
| match = HOSTPORT_PATTERN.fullmatch(value) | ||
| if not match: | ||
| if value.count(":") > 1: | ||
| raise click.BadParameter( | ||
| f"Unclosed bracket in IPv6 address: {value!r}.", param=param | ||
| f"IPv6 address must be enclosed in brackets, e.g. [{value}].", param=param | ||
| ) |
There was a problem hiding this comment.
| match = HOSTPORT_PATTERN.fullmatch(value) | |
| if not match: | |
| if value.count(":") > 1: | |
| raise click.BadParameter( | |
| f"Unclosed bracket in IPv6 address: {value!r}.", param=param | |
| f"IPv6 address must be enclosed in brackets, e.g. [{value}].", param=param | |
| ) | |
| if not (match:= HOSTPORT_PATTERN.fullmatch(value)): | |
| if value.count(":") > 1: | |
| raise click.BadParameter( | |
| f"IPv6 address must be enclosed in brackets, e.g. [{value}].", param=param | |
| ) |
voip/__main__.py
Outdated
| port = int(match.group("port")) if match.group("port") else default_port | ||
| try: | ||
| return host, int(port_str) | ||
| # Parse numeric IP literals into typed address objects; hostnames stay as str. |
There was a problem hiding this comment.
| # Parse numeric IP literals into typed address objects; hostnames stay as str. |
voip/__main__.py
Outdated
| #: Regex that parses ``[IPv6HOST][:PORT]`` or ``HOST[:PORT]`` strings. | ||
| #: Named groups: ``ipv6`` (bare address inside brackets) or ``host`` (plain hostname / | ||
| #: IPv4 literal), and an optional ``port`` suffix. |
There was a problem hiding this comment.
| #: Regex that parses ``[IPv6HOST][:PORT]`` or ``HOST[:PORT]`` strings. | |
| #: Named groups: ``ipv6`` (bare address inside brackets) or ``host`` (plain hostname / | |
| #: IPv4 literal), and an optional ``port`` suffix. |
_parse_hostport()had manual bracket-parsing logic with no tests, silently mishandled unbracketed IPv6 literals, and returned a plainstrhost regardless of whether the value was a numeric IP address.Changes
voip/__main__.py:HOSTPORT_PATTERNregex that handles[IPv6HOST][:PORT],HOST:PORT, and bareHOSTforms.tuple[str, int]totuple[IPv4Address | IPv6Address | str, int]— numeric IP literals are parsed into typed address objects; hostnames remainstr.::1) raiseclick.BadParameterdirecting the user to bracket notation._parse_stun_serverconverts the typed host tostrfor socket/asyncio compatibility._connect_sipusesstr(proxy_addr[0])when callingasyncio.create_connection.voip/sip/protocol.py:outbound_proxytype updated totuple[IPv4Address | IPv6Address | str, int] | None.tests/test_main.py: NewTestParseHostportclass covering the three key paths:[::1]→(IPv6Address("::1"), 5061)(default port)[::1]:5061→(IPv6Address("::1"), 5061)(explicit port)::1→BadParameter("...enclosed in brackets...")📍 Connect Copilot coding agent with Jira, Azure Boards or Linear to delegate work to Copilot in one click without leaving your project management tool.