summaryrefslogtreecommitdiff
path: root/Lib/ipaddress.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/ipaddress.py')
-rw-r--r--Lib/ipaddress.py72
1 files changed, 72 insertions, 0 deletions
diff --git a/Lib/ipaddress.py b/Lib/ipaddress.py
index 873c764408..c389f05288 100644
--- a/Lib/ipaddress.py
+++ b/Lib/ipaddress.py
@@ -618,6 +618,78 @@ class _BaseAddress(_IPAddressBase):
def __reduce__(self):
return self.__class__, (self._ip,)
+ def __format__(self, fmt):
+ """Returns an IP address as a formatted string.
+
+ Supported presentation types are:
+ 's': returns the IP address as a string (default)
+ 'b' or 'n': converts to binary and returns a zero-padded string
+ 'X' or 'x': converts to upper- or lower-case hex and returns a zero-padded string
+
+ For binary and hex presentation types, the alternate form specifier
+ '#' and the grouping option '_' are supported.
+ """
+
+
+ # Support string formatting
+ if not fmt or fmt[-1] == 's':
+ # let format() handle it
+ return format(str(self), fmt)
+
+ # From here on down, support for 'bnXx'
+
+ import re
+ fmt_re = '^(?P<alternate>#?)(?P<grouping>_?)(?P<fmt_base>[xbnX]){1}$'
+ m = re.match(fmt_re, fmt)
+ if not m:
+ return super().__format__(fmt)
+
+ groupdict = m.groupdict()
+ alternate = groupdict['alternate']
+ grouping = groupdict['grouping']
+ fmt_base = groupdict['fmt_base']
+
+ # Set some defaults
+ if fmt_base == 'n':
+ if self._version == 4:
+ fmt_base = 'b' # Binary is default for ipv4
+ if self._version == 6:
+ fmt_base = 'x' # Hex is default for ipv6
+
+ # Handle binary formatting
+ if fmt_base == 'b':
+ if self._version == 4:
+ # resulting string is '0b' + 32 bits
+ # plus 7 _ if needed
+ padlen = IPV4LENGTH+2 + (7*len(grouping))
+ elif self._version == 6:
+ # resulting string is '0b' + 128 bits
+ # plus 31 _ if needed
+ padlen = IPV6LENGTH+2 + (31*len(grouping))
+
+ # Handle hex formatting
+ elif fmt_base in 'Xx':
+ if self._version == 4:
+ # resulting string is '0x' + 8 hex digits
+ # plus a single _ if needed
+ padlen = int(IPV4LENGTH/4)+2 + len(grouping)
+ elif self._version == 6:
+ # resulting string is '0x' + 32 hex digits
+ # plus 7 _ if needed
+ padlen = int(IPV6LENGTH/4)+2 + (7*len(grouping))
+
+ retstr = f'{int(self):#0{padlen}{grouping}{fmt_base}}'
+
+ if fmt_base == 'X':
+ retstr = retstr.upper()
+
+ # If alternate is not set, strip the two leftmost
+ # characters ('0b')
+ if not alternate:
+ retstr = retstr[2:]
+
+ return retstr
+
@functools.total_ordering
class _BaseNetwork(_IPAddressBase):