If deepcopy() raises a TypeError for a lazy item that has been added via a
authorZac Medico <zmedico@gentoo.org>
Tue, 24 Feb 2009 05:14:37 +0000 (05:14 -0000)
committerZac Medico <zmedico@gentoo.org>
Tue, 24 Feb 2009 05:14:37 +0000 (05:14 -0000)
call to LazyItemsDict.addLazySingleton(), automatically evaluate the
the singleton and instead call deepcopy() on the result.

svn path=/main/trunk/; revision=12704

pym/portage/util.py

index 2cb14b34d1848c52aeac69d4f141085831c9012d..92f658c5881c61f89185fd90aa0dd7894e0f9876 100644 (file)
@@ -1139,6 +1139,10 @@ class LazyItemsDict(dict):
 
                If deepcopy() needs to work, this problem can be avoided by
                implementing lazy items with normal (non-bound) functions.
+
+               If deepcopy() raises a TypeError for a lazy item that has been added
+               via a call to addLazySingleton(), the singleton will be automatically
+               evaluated and deepcopy() will instead be called on the result.
                """
                if memo is None:
                        memo = {}
@@ -1148,9 +1152,17 @@ class LazyItemsDict(dict):
                for k in self:
                        k_copy = deepcopy(k, memo)
                        if k in self.lazy_items:
-                               dict.__setitem__(result, k_copy, None)
-                               result.lazy_items[k_copy] = \
-                                       deepcopy(self.lazy_items[k], memo)
+                               lazy_item = self.lazy_items[k]
+                               try:
+                                       result.lazy_items[k_copy] = deepcopy(lazy_item, memo)
+                               except TypeError:
+                                       # If deepcopy fails for a lazy singleton, try to
+                                       # evaluate the singleton and deepcopy the result.
+                                       if not isinstance(lazy_item[0], self._SingletonWrapper):
+                                               raise
+                                       dict.__setitem__(result, k_copy, deepcopy(self[k], memo))
+                               else:
+                                       dict.__setitem__(result, k_copy, None)
                        else:
                                dict.__setitem__(result, k_copy, deepcopy(self[k], memo))
                return result