From: Fabian Groffen Date: Sun, 8 Mar 2009 21:09:37 +0000 (-0000) Subject: Merged from trunk -r12779:12785 X-Git-Url: http://git.tremily.us/gitweb.cgi?a=commitdiff_plain;h=3143a8918472ee93acc1edc63b271214e53464b1;p=portage.git Merged from trunk -r12779:12785 | 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 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 for reporting. | svn path=/main/branches/prefix/; revision=12789 --- diff --git a/bin/ebuild.sh b/bin/ebuild.sh index 60453d592..9a3443fbb 100755 --- a/bin/ebuild.sh +++ b/bin/ebuild.sh @@ -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 diff --git a/pym/portage/cache/flat_hash.py b/pym/portage/cache/flat_hash.py index f6bf6d078..ac1b7f190 100644 --- a/pym/portage/cache/flat_hash.py +++ b/pym/portage/cache/flat_hash.py @@ -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): diff --git a/pym/portage/cache/metadata.py b/pym/portage/cache/metadata.py index 22cf51e56..4f74b767d 100644 --- a/pym/portage/cache/metadata.py +++ b/pym/portage/cache/metadata.py @@ -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) diff --git a/pym/portage/util.py b/pym/portage/util.py index 2d965355e..938eb89a7 100644 --- a/pym/portage/util.py +++ b/pym/portage/util.py @@ -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