URL: https://github.com/freeipa/freeipa/pull/142
Author: dkupka
 Title: #142: CheckedIPAddress: Implement __(g|s)etstate__ and to ensure proper 
(un)pickling
Action: synchronized

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/142/head:pr142
git checkout pr142
From 122f5f802219dd3245d16cbf871452fb3adfbb87 Mon Sep 17 00:00:00 2001
From: David Kupka <dku...@redhat.com>
Date: Thu, 6 Oct 2016 13:31:52 +0200
Subject: [PATCH] UnsafeIPAddress: Implement __(g|s)etstate__ and to ensure
 proper (un)pickling

Missing attributes in instance created by pickle.load cause AttributeError in
second part of ipa-server-install --external-ca.

https://fedorahosted.org/freeipa/ticket/6385
---
 ipapython/ipautil.py | 44 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
index 41544a1..6cb1a2c 100644
--- a/ipapython/ipautil.py
+++ b/ipapython/ipautil.py
@@ -127,12 +127,34 @@ def __init__(self, addr):
         super(UnsafeIPAddress, self).__init__(addr,
                                               flags=self.netaddr_ip_flags)
 
+    def __getstate__(self):
+        state = {attr: getattr(self, attr) for attr in ['_net']}
+        try:
+            state['super_state'] = super(UnsafeIPAddress, self).__getstate__()
+        except AttributeError:
+            # none of base classes implements custom pickling
+            pass
+
+        return state
+
+    def __setstate__(self, state):
+        try:
+            super_state = state.pop('super_state')
+        except KeyError:
+            # no state saved for base classes
+            pass
+        else:
+            super(UnsafeIPAddress, self).__setstate__(super_state)
+
+        self.__dict__.update(state)
+
 
 class CheckedIPAddress(UnsafeIPAddress):
     """IPv4 or IPv6 address with additional constraints.
 
     Reserved or link-local addresses are never accepted.
     """
+
     def __init__(self, addr, match_local=False, parse_netmask=True,
                  allow_loopback=False, allow_multicast=False):
         try:
@@ -142,6 +164,7 @@ def __init__(self, addr, match_local=False, parse_netmask=True,
 
         if isinstance(addr, CheckedIPAddress):
             self.prefixlen = addr.prefixlen
+            self._net = addr._net
             return
 
         if not parse_netmask and self._net:
@@ -205,6 +228,27 @@ def __init__(self, addr, match_local=False, parse_netmask=True,
 
         self.prefixlen = self._net.prefixlen
 
+    def __getstate__(self):
+        state = {attr: getattr(self, attr) for attr in ['prefixlen']}
+        try:
+            state['super_state'] = super(CheckedIPAddress, self).__getstate__()
+        except AttributeError:
+            # none of base classes implements custom pickling
+            pass
+
+        return state
+
+    def __setstate__(self, state):
+        try:
+            super_state = state.pop('super_state')
+        except KeyError:
+            # no state saved for base classes
+            pass
+        else:
+            super(CheckedIPAddress, self).__setstate__(super_state)
+
+        self.__dict__.update(state)
+
     def is_network_addr(self):
         return self == self._net.network
 
-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to