Skip to content

Phone

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

Canonicalizes one phone number per call to E.164 (or to tel-URI / split form when requested).

In plain language: give it "+1 555 123 4567" and it hands back "+15551234567" if the numbering plan says the number is valid. National-shaped numbers like "(555) 234-5678" carry no country code, so they need default_country="US" (→ "+15552345678"); without it they are INVALID.


What it recognizes — and what it does not

Section titled “What it recognizes — and what it does not”
RecognizesDoes not recognize
E.164 international (+1 5551234567)Text that only mentions a country without digits
00-prefix international (0044 20 ...)Extensions without a dialable number
tel: URI (tel:+1-555-123-4567)Plain prose — MISSING
NANP / national numbers ((555) 234-5678) — only when a default_country is provided that is in the NANPNational-shaped input without default_country — recognized but INVALID

Default output_format is "e164".

output_formatRendersExample
(default) e164 / None / "default"+ + country code + national significant number+15551234567
rfc3966tel: URItel:+15551234567
split+ + country code + space + national significant number (uniform for every country code)+1 5551234567

national (bare national significant number) was de-offered per ADR-0011 — it dropped the country code and could not re-enter under the default contract. Phone.create_contract(output_format="national") raises ContractError with a migration message naming split.

from paxman.capabilities import Phone
import paxman
paxman.register_all_shipped()
paxman.canonicalize(
"+1 555 123 4567", Phone.create_contract()
).canonicalized_value # "+15551234567"
paxman.canonicalize(
"+15551234567", Phone.create_contract(output_format="rfc3966")
).canonicalized_value # "tel:+15551234567"
paxman.canonicalize(
"+15551234567", Phone.create_contract(output_format="split")
).canonicalized_value # "+1 5551234567"
# National-shaped input needs default_country
paxman.canonicalize(
"(555) 234-5678", Phone.create_contract(default_country="US")
).canonicalized_value # "+15552345678"

contract = Phone.create_contract(
default_country=None, # str | None — uppercase alpha-2, e.g. "US"
output_format=None, # "e164" (default), "rfc3966", "split"
# plus every common field: excluded_rules / pinned_rules / year / extra_grammars
)
  • When default_country is None, national-shaped input is recognized but never validated → INVALID. International, 00-prefix, and tel: forms validate without it because the country code is in the number itself.
  • default_country is input-only: it resolves national-shaped input and plays no role in output rendering. output_format="split" re-enters param-free under the default contract (uniform +CC NSN for every country code; the space is presentation-only). rfc3966 is the only extension-preserving format.
  • default_country must be uppercase alpha-2 when present; otherwise ContractError at construction.

InputContractStatusWhy
+1 555 123 4567anySUCCESS→ +15551234567
(555) 234-5678defaults (default_country=None)INVALIDrecognized but needs a default country to validate
(555) 234-5678default_country="US"SUCCESS→ +15552345678
helloanyMISSINGno phone pattern
Two distinct numbersanyraises MultipleMentionsErrorsplit first

import paxman
from paxman.capabilities import Phone
from paxman.core.domain import Resolution
paxman.register_all_shipped()
c_intl = Phone.create_contract()
c_us = Phone.create_contract(default_country="US")
c_rfc = Phone.create_contract(output_format="rfc3966", default_country="US")
rows = ["+1 555 123 4567", "(555) 234-5678", "0044 20 7946 0958", "hello"]
for text in rows:
for label, c in [("intl", c_intl), ("US", c_us), ("rfc3966+US", c_rfc)]:
try:
r = paxman.canonicalize(text, c)
except Exception as e:
print(f"{text!r:25} [{label}] → exception {type(e).__name__}")
continue
val = r.canonicalized_value if r.status == Resolution.SUCCESS else "—"
print(f"{text!r:25} [{label:12}] → {r.status.value:10} {val!r}")

  • ITU-T E.164 — international numbering plan.
  • RFC 3966 — tel: URI.
  • NANP — North American Numbering Plan (when relevant).

See also: Execution Result, Segmentation.