Support serializing ipaddress objs with jsonutils

Fixes jsonutils.to_primitive so that it can serialize ipaddress
objects, as used by Python 3 or through the backport in
global-requirements.txt. Current support for netaddr is maintained.

Change-Id: I6aa1ecd5be754f61cdda4e47bc0e0180e232b366
Closes-bug: 1590076
This commit is contained in:
Jim Baker 2016-06-07 11:33:17 -06:00
parent 8a4cac92bc
commit 8943c73662
3 changed files with 19 additions and 1 deletions

View File

@ -43,6 +43,7 @@ from oslo_utils import timeutils
import six
import six.moves.xmlrpc_client as xmlrpclib
ipaddress = importutils.try_import("ipaddress")
netaddr = importutils.try_import("netaddr")
_nasty_type_tests = [inspect.ismodule, inspect.isclass, inspect.ismethod,
@ -109,6 +110,11 @@ def to_primitive(value, convert_instances=False, convert_datetime=True,
if netaddr and isinstance(value, netaddr.IPAddress):
return six.text_type(value)
if ipaddress and isinstance(value,
(ipaddress.IPv4Address,
ipaddress.IPv6Address)):
return six.text_type(value)
# value of itertools.count doesn't get caught by nasty_type_tests
# and results in infinite loop when list(value) is called.
if type(value) == itertools.count:

View File

@ -15,6 +15,7 @@
import collections
import datetime
import ipaddress
import json
import mock
@ -301,11 +302,21 @@ class ToPrimitiveTestCase(test_base.BaseTestCase):
ret = jsonutils.to_primitive(l4_obj, max_depth=4)
self.assertEqual(ret, json_l4)
def test_ipaddr(self):
def test_ipaddr_using_netaddr(self):
thing = {'ip_addr': netaddr.IPAddress('1.2.3.4')}
ret = jsonutils.to_primitive(thing)
self.assertEqual({'ip_addr': '1.2.3.4'}, ret)
def test_ipaddr_using_ipaddress_v4(self):
thing = {'ip_addr': ipaddress.ip_address(u'192.168.0.1')}
ret = jsonutils.to_primitive(thing)
self.assertEqual({'ip_addr': '192.168.0.1'}, ret)
def test_ipaddr_using_ipaddress_v6(self):
thing = {'ip_addr': ipaddress.ip_address(u'2001:db8::')}
ret = jsonutils.to_primitive(thing)
self.assertEqual({'ip_addr': '2001:db8::'}, ret)
def test_message_with_param(self):
msg = self.trans_fixture.lazy('A message with param: %s')
msg = msg % 'test_domain'

View File

@ -2,6 +2,7 @@
# of appearance. Changing the order has an impact on the overall integration
# process, which may cause wedges in the gate later.
hacking<0.11,>=0.10.0
ipaddress>=1.0.7;python_version<'3.3' # PSF
mock>=2.0 # BSD
netaddr!=0.7.16,>=0.7.12 # BSD