fix: normalize_port raises a clear error on missing/empty port

canonical_key/key()/burn on a portless proxy url used to raise a bare
ValueError from int('') instead of naming the problem, breaking burn()'s
documented not-in-pool contract. normalize_port now raises a legible
'missing port' ValueError; to_proxy() on a portless url still succeeds.

Signed-off-by: disqualifier <dev@disqualifier.me>
This commit is contained in:
2026-07-03 16:15:06 -04:00
parent 84127a93ff
commit bac459c5b5
3 changed files with 20 additions and 3 deletions
+14
View File
@@ -149,6 +149,9 @@ key (`host:port:user:pass`, or `host:port` auth-less; the port is normalized so
differing only by password are distinct slots. `burn` on a proxy not in the pool raises differing only by password are distinct slots. `burn` on a proxy not in the pool raises
`ValueError`; `restore` on a proxy not in the pool logs a warning and no-ops (matching `ValueError`; `restore` on a proxy not in the pool logs a warning and no-ops (matching
`remove`'s contract, as of v0.3.0 — previously it silently did nothing with no signal). `remove`'s contract, as of v0.3.0 — previously it silently did nothing with no signal).
A **portless** url (`http://user:pass@host`, no `:port`) parses fine via `to_proxy()`,
but keying it (`canonical_key`/`.key()`/`burn`/`add`/`remove`) raises `ValueError`
naming the missing port — a proxy needs a port to have a canonical identity.
### Cooldown ### Cooldown
@@ -209,6 +212,17 @@ await reset("https://provider/reset-url") # rotate upstream ip
## Changelog ## Changelog
### v0.3.2
- **Portless proxy url now fails loud and legible.** `canonical_key`/`.key()`
(and therefore `burn`/`add`/`remove`) on a proxy url with no `:port`
(`http://user:pass@host`) used to raise a bare `ValueError("invalid literal
for int() with base 10: ''")` from `normalize_port('')` — an unrelated `int()`
error that broke `burn()`'s documented "raises ValueError naming the key if
not in pool" contract. `normalize_port` now raises `ValueError("missing port:
...")` naming the problem instead. `to_proxy()` on a portless url still
succeeds (construction tolerates a missing port); only keying it raises.
### v0.3.1 ### v0.3.1
- **Docs-only de-bloat pass.** Compressed module/internal docstrings and comments, - **Docs-only de-bloat pass.** Compressed module/internal docstrings and comments,
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
[project] [project]
name = "aioproxies" name = "aioproxies"
version = "0.3.1" version = "0.3.2"
description = "proxy parsing, formatting, health, and pool management for aiohttp/aioweb, camoufox, and socks5" description = "proxy parsing, formatting, health, and pool management for aiohttp/aioweb, camoufox, and socks5"
requires-python = ">=3.10" requires-python = ">=3.10"
dependencies = [] dependencies = []
+5 -2
View File
@@ -19,9 +19,12 @@ SCHEME_SOCKS5 = "socks5"
def normalize_port(port: Union[str, int]) -> str: def normalize_port(port: Union[str, int]) -> str:
"""canonical port string: parsed to int, rendered without zero-padding """canonical port string: parsed to int, rendered without zero-padding
keeps host:080 and host:80 as one canonical key. raises ValueError on a keeps host:080 and host:80 as one canonical key. raises ValueError naming the
non-integer port rather than silently keying it as-is. missing port if empty/None (e.g. a portless proxy url), or on a non-integer
port, rather than silently keying it as-is.
""" """
if port is None or port == "":
raise ValueError("missing port: proxy url or spec has no port")
return str(int(port)) return str(int(port))