From 27d653052549e5d1880ab68be12f3b82857506fe Mon Sep 17 00:00:00 2001
From: Zac Medico <zmedico@gentoo.org>
Date: Thu, 23 Jan 2020 12:30:25 -0800
Subject: [PATCH] SonameAtom: implement get/set state methods (bug 706186)

Since SonameAtom instances are immutable, the __getstate__ and
__setstate__ methods need to be implemented for pickle support.

Bug: https://bugs.gentoo.org/706186
Signed-off-by: Zac Medico <zmedico@gentoo.org>
---
 lib/portage/dep/soname/SonameAtom.py            | 17 ++++++++++-------
 .../tests/dep/test_soname_atom_pickle.py        |  2 --
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/lib/portage/dep/soname/SonameAtom.py b/lib/portage/dep/soname/SonameAtom.py
index f32082568d..5743544aad 100644
--- a/lib/portage/dep/soname/SonameAtom.py
+++ b/lib/portage/dep/soname/SonameAtom.py
@@ -10,7 +10,7 @@
 class SonameAtom(object):
 
 	__slots__ = ("multilib_category", "soname", "_hash_key",
-		"_hash_value", "_immutable")
+		"_hash_value")
 
 	# Distiguishes package atoms from other atom types
 	package = False
@@ -21,14 +21,17 @@ def __init__(self, multilib_category, soname):
 		object.__setattr__(self, "_hash_key",
 			(multilib_category, soname))
 		object.__setattr__(self, "_hash_value", hash(self._hash_key))
-		object.__setattr__(self, "_immutable", True)
 
 	def __setattr__(self, name, value):
-		if getattr(self, '_immutable', False):
-			raise AttributeError("SonameAtom instances are immutable",
-				self.__class__, name, value)
-		# This is needed for unpickling.
-		object.__setattr__(self, name, value)
+		raise AttributeError("SonameAtom instances are immutable",
+			self.__class__, name, value)
+
+	def __getstate__(self):
+		return dict((k, getattr(self, k)) for k in self.__slots__)
+
+	def __setstate__(self, state):
+		for k, v in state.items():
+			object.__setattr__(self, k, v)
 
 	def __hash__(self):
 		return self._hash_value
diff --git a/lib/portage/tests/dep/test_soname_atom_pickle.py b/lib/portage/tests/dep/test_soname_atom_pickle.py
index 02965b44fa..c3f339e2db 100644
--- a/lib/portage/tests/dep/test_soname_atom_pickle.py
+++ b/lib/portage/tests/dep/test_soname_atom_pickle.py
@@ -16,8 +16,6 @@ class TestSonameAtomPickle(TestCase):
 	_ALL_PROVIDES = frozenset([SonameAtom('x86_64', 'libc.so.6')])
 
 	def test_soname_atom_pickle(self):
-		if sys.version_info < (3,):
-			self.skipTest('SonameAtom pickle not implemented for python2 (bug 706186)')
 		loop = asyncio._wrap_loop()
 		with ForkExecutor(loop=loop) as executor:
 			result = loop.run_until_complete(loop.run_in_executor(executor, self._get_all_provides))
