Skip to content

IP

This content is for v0.3.0. Switch to the latest version for up-to-date documentation.

Canonicalizes one IP address per call to its normalized textual form.

In plain language: give it "192.168.1.1" or "2001:0db8:0000:0000:0000:0000:0000:0001" and it hands back the normalized address if a spec says it is valid. IPv6 canonicalization follows RFC 5952 so the same address always looks the same.


What it recognizes — and what it does not

Section titled “What it recognizes — and what it does not”
RecognizesDoes not recognize
IPv4 dotted-decimal (192.168.1.1)CIDR notation (192.168.1.0/24) — address only
IPv6 (compressed or expanded, e.g. 2001:db8::1)Hostnames — use URL

Single format — the normalized address. IPv6 is rendered per RFC 5952 (lowercase hex, :: compression, etc.).

output_formatRenders
(only) ip / None / "default"normalized address string
from paxman.capabilities import IP
import paxman
paxman.register_all_shipped()
paxman.canonicalize(
"192.168.1.1", IP.create_contract()
).canonicalized_value # "192.168.1.1"
paxman.canonicalize(
"2001:0db8:0000:0000:0000:0000:0000:0001", IP.create_contract()
).canonicalized_value # "2001:db8::1"

contract = IP.create_contract(
include_ipv6=True, # bool, default True — recognize IPv6
output_format=None, # "ip" (only format)
# plus every common field: excluded_rules / pinned_rules / year / extra_grammars
)
  • With include_ipv6=True (the default) both grammars run. With False, only ipv4_recognition runs — an IPv6 address is then MISSING (never seen), not INVALID.
paxman.canonicalize(
"2001:db8::1", IP.create_contract(include_ipv6=False)
).status.value # "missing"
paxman.canonicalize(
"2001:db8::1", IP.create_contract()
).canonicalized_value # "2001:db8::1"

InputContractStatusWhy
192.168.1.1anySUCCESSnormalized IPv4
2001:db8::1defaultsSUCCESS→ 2001:db8::1 (RFC 5952)
2001:db8::1include_ipv6=FalseMISSINGIPv6 grammar not active
999.999.999.999anyINVALIDrecognized shape but no spec accepts it
helloanyMISSINGno IP pattern
10.0.0.1 and 10.0.0.2 (two distinct values)anyraises MultipleMentionsErrorsplit first

import paxman
from paxman.capabilities import IP
from paxman.core.domain import Resolution
paxman.register_all_shipped()
contract = IP.create_contract()
for text in [
"192.168.1.1",
"2001:0db8:0000:0000:0000:0000:0000:0001",
"999.999.999.999",
"hello",
]:
r = paxman.canonicalize(text, contract)
print(f"{text!r:45} → {r.status.value:10} {r.canonicalized_value!r}")

  • RFC 791 — IPv4 address validation.
  • RFC 5952 — IPv6 text representation and canonical compression.

See also: URL, Execution Result, Segmentation.