Merged from trunk -r12779:12785
authorFabian Groffen <grobian@gentoo.org>
Sun, 8 Mar 2009 21:09:37 +0000 (21:09 -0000)
committerFabian Groffen <grobian@gentoo.org>
Sun, 8 Mar 2009 21:09:37 +0000 (21:09 -0000)
   | 12780   | In LazyItemsDict.__deepcopy__(), enable deepcopy of lazy     |
   | zmedico | items as it was before. This requires                        |
   |         | _LazyItem.__deepcopy__() to be overridden since the default  |
   |         | implementation can fail silently, leaving some attributes    |
   |         | unset.                                                       |

   | 12781   | Implement _getitem instead of __getitem__ so that the base   |
   | zmedico | class __getitem__ implementation is used for _mtime_ and     |
   |         | _eclasses_ handling.                                         |

   | 12782   | Make EXPORT_FUNCTIONS store it's arguments in an environment |
   | zmedico | variable and perform the function generation after the       |
   |         | current inherit call has returned. This way an eclass can    |
   |         | call EXPORT_FUNCTIONS either before or after it inherits     |
   |         | other eclasses, and the result is still the same. Thanks to  |
   |         | Donnie Berkholz <dberkholz@g.o> for reporting.               |

   | 12783   | Fix PECLASS logic inside inherit() so that ECLASS is always  |
   | zmedico | restored to the correct value after recursion (previously it |
   |         | would be restored to the wrong value if more than one eclass |
   |         | was passed into the inherit call).                           |

   | 12784   | Revert previous 2 commits due to bugs.                       |
   | zmedico |                                                              |

   | 12785   | Make EXPORT_FUNCTIONS store it's arguments in an environment |
   | zmedico | variable and perform the function generation after the       |
   |         | current inherit call has returned. This allows an eclass to  |
   |         | call EXPORT_FUNCTIONS either before or after it inherits     |
   |         | other eclasses, and the result is still the same. Thanks to  |
   |         | Donnie Berkholz <dberkholz@g.o> for reporting.               |

svn path=/main/branches/prefix/; revision=12789

bin/ebuild.sh
pym/portage/cache/flat_hash.py
pym/portage/cache/metadata.py
pym/portage/util.py

index 60453d59249f0b1978fac85eee6487fa75fd0049..9a3443fbb2dbe30c1d10299888b1e2322dc0f0b5 100755 (executable)
@@ -1168,7 +1168,11 @@ inherit() {
 
        local location
        local olocation
-       local PECLASS
+       local x
+
+       # These variables must be restored before returning.
+       local PECLASS=$ECLASS
+       local prev_export_funcs_var=$__export_funcs_var
 
        local B_IUSE
        local B_DEPEND
@@ -1178,9 +1182,12 @@ inherit() {
                location="${ECLASSDIR}/${1}.eclass"
                olocation=""
 
-               # PECLASS is used to restore the ECLASS var after recursion.
-               PECLASS="$ECLASS"
                export ECLASS="$1"
+               __export_funcs_var=__export_functions_${ECLASS/-/___}
+               while [[ $__export_funcs_var != ${__export_funcs_var/-/___} ]] ; do
+                       __export_funcs_var=${__export_funcs_var/-/___}
+               done
+               unset $__export_funcs_var
 
                if [ "${EBUILD_PHASE}" != "depend" ] && \
                        [[ ${EBUILD_PHASE} != *rm ]] && \
@@ -1255,13 +1262,27 @@ inherit() {
                #turn on glob expansion
                set +f
 
-               hasq $1 $INHERITED || export INHERITED="$INHERITED $1"
+               if [[ -n ${!__export_funcs_var} ]] ; then
+                       for x in ${!__export_funcs_var} ; do
+                               debug-print "EXPORT_FUNCTIONS: $x -> ${ECLASS}_$x"
+                               [[ $(type -t ${ECLASS}_$x) = function ]] || \
+                                       die "EXPORT_FUNCTIONS: ${ECLASS}_$x is not defined"
+                               eval "$x() { ${ECLASS}_$x \"\$@\" ; }" > /dev/null
+                       done
+               fi
+               unset $__export_funcs_var
 
-               export ECLASS="$PECLASS"
+               hasq $1 $INHERITED || export INHERITED="$INHERITED $1"
 
                shift
        done
        ((--ECLASS_DEPTH)) # Returns 1 when ECLASS_DEPTH reaches 0.
+       if (( ECLASS_DEPTH > 0 )) ; then
+               export ECLASS=$PECLASS
+               __export_funcs_var=$prev_export_funcs_var
+       else
+               unset ECLASS __export_funcs_var
+       fi
        return 0
 }
 
@@ -1271,14 +1292,9 @@ inherit() {
 # src_unpack() { base_src_unpack; }
 EXPORT_FUNCTIONS() {
        if [ -z "$ECLASS" ]; then
-               echo "EXPORT_FUNCTIONS without a defined ECLASS" >&2
-               exit 1
+               die "EXPORT_FUNCTIONS without a defined ECLASS"
        fi
-       while [ "$1" ]; do
-               debug-print "EXPORT_FUNCTIONS: ${1} -> ${ECLASS}_${1}"
-               eval "$1() { ${ECLASS}_$1 \"\$@\" ; }" > /dev/null
-               shift
-       done
+       eval $__export_funcs_var+=\" $*\"
 }
 
 # adds all parameters to E_DEPEND and E_RDEPEND, which get added to DEPEND
index f6bf6d078e774b72563c122e6753f953f3dc89d1..ac1b7f190e055d6a7b527199147ca9acd6feb543 100644 (file)
@@ -23,26 +23,16 @@ class database(fs_template.FsBased):
                if not self.readonly and not os.path.exists(self.location):
                        self._ensure_dirs()
 
-       def __getitem__(self, cpv):
+       def _getitem(self, cpv):
                fp = os.path.join(self.location, cpv)
                try:
                        myf = open(fp, "r")
                        try:
                                d = self._parse_data(myf, cpv)
-                               if "_mtime_" not in d:
-                                       """Backward compatibility with old cache that uses mtime
-                                       mangling."""
-                                       d["_mtime_"] = long(os.fstat(myf.fileno()).st_mtime)
-                               mtime = d.get('_mtime_')
-                               if mtime is None:
-                                       raise cache_errors.CacheCorruption(cpv,
-                                               '_mtime_ field is missing')
-                               try:
-                                       mtime = long(mtime)
-                               except ValueError:
-                                       raise cache_errors.CacheCorruption(cpv,
-                                               '_mtime_ conversion to long failed: %s' % (mtime,))
-                               d['_mtime_'] = mtime
+                               if '_mtime_' not in d:
+                                       # Backward compatibility with old cache
+                                       # that uses mtime mangling.
+                                       d['_mtime_'] = long(os.fstat(myf.fileno()).st_mtime)
                                return d
                        finally:
                                myf.close()
@@ -57,10 +47,6 @@ class database(fs_template.FsBased):
                except ValueError, e:
                        # If a line is missing an "=", the split length is 1 instead of 2.
                        raise cache_errors.CacheCorruption(cpv, e)
-               if "_eclasses_" in d:
-                       d["_eclasses_"] = reconstruct_eclasses(cpv, d["_eclasses_"])
-               else:
-                       d["_eclasses_"] = {}
                return d
 
        def _setitem(self, cpv, values):
index 22cf51e56c82e729bb02910354ec8258e6d055a8..4f74b767d1f168170a6682c046c5eb4916d15bc1 100644 (file)
@@ -21,6 +21,7 @@ class database(flat_hash.database):
                'PDEPEND',   'PROVIDE', 'EAPI', 'PROPERTIES', 'DEFINED_PHASES')
 
        autocommits = True
+       serialize_eclasses = False
 
        _hashed_re = re.compile('^(\\w+)=([^\n]*)')
 
@@ -30,10 +31,6 @@ class database(flat_hash.database):
                self.location = os.path.join(loc, "metadata","cache")
                self.ec = portage.eclass_cache.cache(loc)
 
-       def __getitem__(self, cpv):
-               return flat_hash.database.__getitem__(self, cpv)
-
-
        def _parse_data(self, data, cpv):
                _hashed_re_match = self._hashed_re.match
                data = list(data)
index 2d965355e3c5eef882e6de8b58e2e90328b5d152..938eb89a7bb7c5f93ae4ca4a5df22efcd97a9c87 100644 (file)
@@ -1173,10 +1173,13 @@ class LazyItemsDict(dict):
                        k_copy = deepcopy(k, memo)
                        if k in self.lazy_items:
                                lazy_item = self.lazy_items[k]
-                               if lazy_item.singleton:
+                               try:
+                                       result.lazy_items[k_copy] = deepcopy(lazy_item, memo)
+                               except TypeError:
+                                       if not lazy_item.singleton:
+                                               raise
                                        dict.__setitem__(result, k_copy, deepcopy(self[k], memo))
                                else:
-                                       result.lazy_items[k_copy] = deepcopy(lazy_item, memo)
                                        dict.__setitem__(result, k_copy, None)
                        else:
                                dict.__setitem__(result, k_copy, deepcopy(self[k], memo))
@@ -1198,6 +1201,26 @@ class LazyItemsDict(dict):
                        self.kwargs = kwargs
                        self.singleton = singleton
 
+               def __copy__(self):
+                       return self.__class__(self.func, self.pargs,
+                               self.kwargs, self.singleton)
+
+               def __deepcopy__(self, memo=None):
+                       """
+                       Override this since the default implementation can fail silently,
+                       leaving some attributes unset.
+                       """
+                       if memo is None:
+                               memo = {}
+                       from copy import deepcopy
+                       result = self.__copy__()
+                       memo[id(self)] = result
+                       result.func = deepcopy(self.func, memo)
+                       result.pargs = deepcopy(self.pargs, memo)
+                       result.kwargs = deepcopy(self.kwargs, memo)
+                       result.singleton = deepcopy(self.singleton, memo)
+                       return result
+
 class ConfigProtect(object):
        def __init__(self, myroot, protect_list, mask_list):
                self.myroot = myroot