[Python-checkins] cpython: Issue #23133: Pickling of ipaddress objects now produces more compact and
serhiy.storchaka
python-checkins at python.org
Sun Jan 18 21:37:26 CET 2015
https://hg.python.org/cpython/rev/781b54f7bccc
changeset: 94212:781b54f7bccc
parent: 94210:15f46b850257
user: Serhiy Storchaka <storchaka at gmail.com>
date: Sun Jan 18 22:36:33 2015 +0200
summary:
Issue #23133: Pickling of ipaddress objects now produces more compact and
portable representation.
files:
Lib/ipaddress.py | 21 +++++++++++-----
Lib/test/test_ipaddress.py | 31 ++++++++++++++++++++-----
Misc/NEWS | 3 ++
3 files changed, 41 insertions(+), 14 deletions(-)
diff --git a/Lib/ipaddress.py b/Lib/ipaddress.py
--- a/Lib/ipaddress.py
+++ b/Lib/ipaddress.py
@@ -567,6 +567,9 @@
except ValueError:
cls._report_invalid_netmask(ip_str)
+ def __reduce__(self):
+ return self.__class__, (str(self),)
+
class _BaseAddress(_IPAddressBase):
@@ -576,11 +579,6 @@
used by single IP addresses.
"""
- def __init__(self, address):
- if (not isinstance(address, bytes)
- and '/' in str(address)):
- raise AddressValueError("Unexpected '/' in %r" % address)
-
def __int__(self):
return self._ip
@@ -626,6 +624,9 @@
def _get_address_key(self):
return (self._version, self)
+ def __reduce__(self):
+ return self.__class__, (self._ip,)
+
class _BaseNetwork(_IPAddressBase):
@@ -1295,7 +1296,6 @@
AddressValueError: If ipaddress isn't a valid IPv4 address.
"""
- _BaseAddress.__init__(self, address)
_BaseV4.__init__(self, address)
# Efficient constructor from integer.
@@ -1313,6 +1313,8 @@
# Assume input argument to be string or any object representation
# which converts into a formatted IP string.
addr_str = str(address)
+ if '/' in addr_str:
+ raise AddressValueError("Unexpected '/' in %r" % address)
self._ip = self._ip_int_from_string(addr_str)
@property
@@ -1446,6 +1448,8 @@
def __hash__(self):
return self._ip ^ self._prefixlen ^ int(self.network.network_address)
+ __reduce__ = _IPAddressBase.__reduce__
+
@property
def ip(self):
return IPv4Address(self._ip)
@@ -1920,7 +1924,6 @@
AddressValueError: If address isn't a valid IPv6 address.
"""
- _BaseAddress.__init__(self, address)
_BaseV6.__init__(self, address)
# Efficient constructor from integer.
@@ -1938,6 +1941,8 @@
# Assume input argument to be string or any object representation
# which converts into a formatted IP string.
addr_str = str(address)
+ if '/' in addr_str:
+ raise AddressValueError("Unexpected '/' in %r" % address)
self._ip = self._ip_int_from_string(addr_str)
@property
@@ -2134,6 +2139,8 @@
def __hash__(self):
return self._ip ^ self._prefixlen ^ int(self.network.network_address)
+ __reduce__ = _IPAddressBase.__reduce__
+
@property
def ip(self):
return IPv6Address(self._ip)
diff --git a/Lib/test/test_ipaddress.py b/Lib/test/test_ipaddress.py
--- a/Lib/test/test_ipaddress.py
+++ b/Lib/test/test_ipaddress.py
@@ -8,6 +8,7 @@
import re
import contextlib
import operator
+import pickle
import ipaddress
@@ -82,6 +83,13 @@
self.assertRaises(TypeError, hex, self.factory(1))
self.assertRaises(TypeError, bytes, self.factory(1))
+ def pickle_test(self, addr):
+ for proto in range(pickle.HIGHEST_PROTOCOL + 1):
+ with self.subTest(proto=proto):
+ x = self.factory(addr)
+ y = pickle.loads(pickle.dumps(x, proto))
+ self.assertEqual(y, x)
+
class CommonTestMixin_v4(CommonTestMixin):
@@ -247,6 +255,9 @@
assertBadOctet("257.0.0.0", 257)
assertBadOctet("192.168.0.999", 999)
+ def test_pickle(self):
+ self.pickle_test('192.0.2.1')
+
class AddressTestCase_v6(BaseTestCase, CommonTestMixin_v6):
factory = ipaddress.IPv6Address
@@ -379,6 +390,9 @@
assertBadPart("02001:db8::", "02001")
assertBadPart('2001:888888::1', "888888")
+ def test_pickle(self):
+ self.pickle_test('2001:db8::')
+
class NetmaskTestMixin_v4(CommonTestMixin_v4):
"""Input validation on interfaces and networks is very similar"""
@@ -446,6 +460,11 @@
class InterfaceTestCase_v4(BaseTestCase, NetmaskTestMixin_v4):
factory = ipaddress.IPv4Interface
+ def test_pickle(self):
+ self.pickle_test('192.0.2.0/27')
+ self.pickle_test('192.0.2.0/31') # IPV4LENGTH - 1
+ self.pickle_test('192.0.2.0') # IPV4LENGTH
+
class NetworkTestCase_v4(BaseTestCase, NetmaskTestMixin_v4):
factory = ipaddress.IPv4Network
@@ -500,6 +519,11 @@
assertBadNetmask("::1", "pudding")
assertBadNetmask("::", "::")
+ def test_pickle(self):
+ self.pickle_test('2001:db8::1000/124')
+ self.pickle_test('2001:db8::1000/127') # IPV6LENGTH - 1
+ self.pickle_test('2001:db8::1000') # IPV6LENGTH
+
class InterfaceTestCase_v6(BaseTestCase, NetmaskTestMixin_v6):
factory = ipaddress.IPv6Interface
@@ -774,13 +798,6 @@
self.assertEqual(128, ipaddress._count_righthand_zero_bits(0, 128))
self.assertEqual("IPv4Network('1.2.3.0/24')", repr(self.ipv4_network))
- def testMissingAddressVersion(self):
- class Broken(ipaddress._BaseAddress):
- pass
- broken = Broken('127.0.0.1')
- with self.assertRaisesRegex(NotImplementedError, "Broken.*version"):
- broken.version
-
def testMissingNetworkVersion(self):
class Broken(ipaddress._BaseNetwork):
pass
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -203,6 +203,9 @@
Library
-------
+- Issue #23133: Pickling of ipaddress objects now produces more compact and
+ portable representation.
+
- Issue #23248: Update ssl error codes from latest OpenSSL git master.
- Issue #23266: Much faster implementation of ipaddress.collapse_addresses()
--
Repository URL: https://hg.python.org/cpython
More information about the Python-checkins
mailing list