Auto-generate PORTAGE_GRP/USERNAME for prefix.
[portage.git] / pym / portage / package / ebuild / config.py
1 # Copyright 2010-2011 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
3
4 __all__ = [
5         'autouse', 'best_from_dict', 'check_config_instance', 'config',
6 ]
7
8 import copy
9 from itertools import chain
10 import grp
11 import logging
12 import platform
13 import pwd
14 import re
15 import sys
16 import warnings
17
18 from _emerge.Package import Package
19 import portage
20 portage.proxy.lazyimport.lazyimport(globals(),
21         'portage.data:portage_gid',
22 )
23 from portage import bsd_chflags, \
24         load_mod, os, selinux, _unicode_decode
25 from portage.const import CACHE_PATH, \
26         DEPCACHE_PATH, INCREMENTALS, MAKE_CONF_FILE, \
27         MODULES_FILE_PATH, \
28         PRIVATE_PATH, PROFILE_PATH, USER_CONFIG_PATH, \
29         USER_VIRTUALS_FILE
30 from portage.const import _SANDBOX_COMPAT_LEVEL
31 from portage.dbapi import dbapi
32 from portage.dbapi.porttree import portdbapi
33 from portage.dbapi.vartree import vartree
34 from portage.dep import Atom, isvalidatom, match_from_list, use_reduce, _repo_separator, _slot_separator
35 from portage.eapi import eapi_exports_AA, eapi_exports_merge_type, \
36         eapi_supports_prefix, eapi_exports_replace_vars
37 from portage.env.loaders import KeyValuePairFileLoader
38 from portage.exception import InvalidDependString, PortageException
39 from portage.localization import _
40 from portage.output import colorize
41 from portage.process import fakeroot_capable, sandbox_capable
42 from portage.repository.config import load_repository_config
43 from portage.util import ensure_dirs, getconfig, grabdict, \
44         grabdict_package, grabfile, grabfile_package, LazyItemsDict, \
45         normalize_path, shlex_split, stack_dictlist, stack_dicts, stack_lists, \
46         writemsg, writemsg_level
47 from portage.versions import catpkgsplit, catsplit, cpv_getkey
48
49 from portage.package.ebuild._config import special_env_vars
50 from portage.package.ebuild._config.env_var_validation import validate_cmd_var
51 from portage.package.ebuild._config.features_set import features_set
52 from portage.package.ebuild._config.KeywordsManager import KeywordsManager
53 from portage.package.ebuild._config.LicenseManager import LicenseManager
54 from portage.package.ebuild._config.UseManager import UseManager
55 from portage.package.ebuild._config.LocationsManager import LocationsManager
56 from portage.package.ebuild._config.MaskManager import MaskManager
57 from portage.package.ebuild._config.VirtualsManager import VirtualsManager
58 from portage.package.ebuild._config.helper import ordered_by_atom_specificity, prune_incremental
59
60 if sys.hexversion >= 0x3000000:
61         basestring = str
62
63 def autouse(myvartree, use_cache=1, mysettings=None):
64         warnings.warn("portage.autouse() is deprecated",
65                 DeprecationWarning, stacklevel=2)
66         return ""
67
68 def check_config_instance(test):
69         if not isinstance(test, config):
70                 raise TypeError("Invalid type for config object: %s (should be %s)" % (test.__class__, config))
71
72 def best_from_dict(key, top_dict, key_order, EmptyOnError=1, FullCopy=1, AllowEmpty=1):
73         for x in key_order:
74                 if x in top_dict and key in top_dict[x]:
75                         if FullCopy:
76                                 return copy.deepcopy(top_dict[x][key])
77                         else:
78                                 return top_dict[x][key]
79         if EmptyOnError:
80                 return ""
81         else:
82                 raise KeyError("Key not found in list; '%s'" % key)
83
84 def _lazy_iuse_regex(iuse_implicit):
85         """
86         The PORTAGE_IUSE value is lazily evaluated since re.escape() is slow
87         and the value is only used when an ebuild phase needs to be executed
88         (it's used only to generate QA notices).
89         """
90         # Escape anything except ".*" which is supposed to pass through from
91         # _get_implicit_iuse().
92         regex = sorted(re.escape(x) for x in iuse_implicit)
93         regex = "^(%s)$" % "|".join(regex)
94         regex = regex.replace("\\.\\*", ".*")
95         return regex
96
97 class _iuse_implicit_match_cache(object):
98
99         def __init__(self, settings):
100                 self._iuse_implicit_re = re.compile("^(%s)$" % \
101                         "|".join(settings._get_implicit_iuse()))
102                 self._cache = {}
103
104         def __call__(self, flag):
105                 """
106                 Returns True if the flag is matched, False otherwise.
107                 """
108                 try:
109                         return self._cache[flag]
110                 except KeyError:
111                         m = self._iuse_implicit_re.match(flag) is not None
112                         self._cache[flag] = m
113                         return m
114
115 class config(object):
116         """
117         This class encompasses the main portage configuration.  Data is pulled from
118         ROOT/PORTDIR/profiles/, from ROOT/etc/make.profile incrementally through all
119         parent profiles as well as from ROOT/PORTAGE_CONFIGROOT/* for user specified
120         overrides.
121
122         Generally if you need data like USE flags, FEATURES, environment variables,
123         virtuals ...etc you look in here.
124         """
125
126         _setcpv_aux_keys = ('DEFINED_PHASES', 'DEPEND', 'EAPI',
127                 'INHERITED', 'IUSE', 'REQUIRED_USE', 'KEYWORDS', 'LICENSE', 'PDEPEND',
128                 'PROPERTIES', 'PROVIDE', 'RDEPEND', 'SLOT',
129                 'repository', 'RESTRICT', 'LICENSE',)
130
131         _module_aliases = {
132                 "cache.metadata_overlay.database" : "portage.cache.flat_hash.database",
133                 "portage.cache.metadata_overlay.database" : "portage.cache.flat_hash.database",
134         }
135
136         _case_insensitive_vars = special_env_vars.case_insensitive_vars
137         _default_globals = special_env_vars.default_globals
138         _env_blacklist = special_env_vars.env_blacklist
139         _environ_filter = special_env_vars.environ_filter
140         _environ_whitelist = special_env_vars.environ_whitelist
141         _environ_whitelist_re = special_env_vars.environ_whitelist_re
142         _global_only_vars = special_env_vars.global_only_vars
143
144         def __init__(self, clone=None, mycpv=None, config_profile_path=None,
145                 config_incrementals=None, config_root=None, target_root=None,
146                 _eprefix=None, local_config=True, env=None, _unmatched_removal=False):
147                 """
148                 @param clone: If provided, init will use deepcopy to copy by value the instance.
149                 @type clone: Instance of config class.
150                 @param mycpv: CPV to load up (see setcpv), this is the same as calling init with mycpv=None
151                 and then calling instance.setcpv(mycpv).
152                 @type mycpv: String
153                 @param config_profile_path: Configurable path to the profile (usually PROFILE_PATH from portage.const)
154                 @type config_profile_path: String
155                 @param config_incrementals: List of incremental variables
156                         (defaults to portage.const.INCREMENTALS)
157                 @type config_incrementals: List
158                 @param config_root: path to read local config from (defaults to "/", see PORTAGE_CONFIGROOT)
159                 @type config_root: String
160                 @param target_root: __init__ override of $ROOT env variable.
161                 @type target_root: String
162                 @param _eprefix: set the EPREFIX variable (private, used by internal tests)
163                 @type _eprefix: String
164                 @param local_config: Enables loading of local config (/etc/portage); used most by repoman to
165                 ignore local config (keywording and unmasking)
166                 @type local_config: Boolean
167                 @param env: The calling environment which is used to override settings.
168                         Defaults to os.environ if unspecified.
169                 @type env: dict
170                 @param _unmatched_removal: Enabled by repoman when the
171                         --unmatched-removal option is given.
172                 @type _unmatched_removal: Boolean
173                 """
174
175                 # rename local _eprefix variable for convenience
176                 eprefix = _eprefix
177                 del _eprefix
178
179                 # When initializing the global portage.settings instance, avoid
180                 # raising exceptions whenever possible since exceptions thrown
181                 # from 'import portage' or 'import portage.exceptions' statements
182                 # can practically render the api unusable for api consumers.
183                 tolerant = hasattr(portage, '_initializing_globals')
184                 self._tolerant = tolerant
185
186                 self.locked   = 0
187                 self.mycpv    = None
188                 self._setcpv_args_hash = None
189                 self.puse     = ""
190                 self._penv    = []
191                 self.modifiedkeys = []
192                 self.uvlist = []
193                 self._accept_chost_re = None
194                 self._accept_properties = None
195                 self._features_overrides = []
196                 self._make_defaults = None
197
198                 # _unknown_features records unknown features that
199                 # have triggered warning messages, and ensures that
200                 # the same warning isn't shown twice.
201                 self._unknown_features = set()
202
203                 self.local_config = local_config
204
205                 if clone:
206                         # For immutable attributes, use shallow copy for
207                         # speed and memory conservation.
208                         self._tolerant = clone._tolerant
209                         self.categories = clone.categories
210                         self.depcachedir = clone.depcachedir
211                         self.incrementals = clone.incrementals
212                         self.module_priority = clone.module_priority
213                         self.profile_path = clone.profile_path
214                         self.profiles = clone.profiles
215                         self.packages = clone.packages
216                         self.repositories = clone.repositories
217                         self._iuse_implicit_match = clone._iuse_implicit_match
218                         self._non_user_variables = clone._non_user_variables
219                         self._env_d_blacklist = clone._env_d_blacklist
220                         self._repo_make_defaults = clone._repo_make_defaults
221                         self.usemask = clone.usemask
222                         self.useforce = clone.useforce
223                         self.puse = clone.puse
224                         self.user_profile_dir = clone.user_profile_dir
225                         self.local_config = clone.local_config
226                         self.make_defaults_use = clone.make_defaults_use
227                         self.mycpv = clone.mycpv
228                         self._setcpv_args_hash = clone._setcpv_args_hash
229
230                         # immutable attributes (internal policy ensures lack of mutation)
231                         self._keywords_manager = clone._keywords_manager
232                         self._use_manager = clone._use_manager
233                         self._mask_manager = clone._mask_manager
234
235                         # shared mutable attributes
236                         self._unknown_features = clone._unknown_features
237
238                         self.modules         = copy.deepcopy(clone.modules)
239                         self._penv = copy.deepcopy(clone._penv)
240
241                         self.configdict = copy.deepcopy(clone.configdict)
242                         self.configlist = [
243                                 self.configdict['env.d'],
244                                 self.configdict['repo'],
245                                 self.configdict['pkginternal'],
246                                 self.configdict['globals'],
247                                 self.configdict['defaults'],
248                                 self.configdict['conf'],
249                                 self.configdict['pkg'],
250                                 self.configdict['env'],
251                         ]
252                         self.lookuplist = self.configlist[:]
253                         self.lookuplist.reverse()
254                         self._use_expand_dict = copy.deepcopy(clone._use_expand_dict)
255                         self.backupenv  = self.configdict["backupenv"]
256                         self.prevmaskdict = copy.deepcopy(clone.prevmaskdict)
257                         self.pprovideddict = copy.deepcopy(clone.pprovideddict)
258                         self.features = features_set(self)
259                         self.features._features = copy.deepcopy(clone.features._features)
260                         self._features_overrides = copy.deepcopy(clone._features_overrides)
261
262                         #Strictly speaking _license_manager is not immutable. Users need to ensure that
263                         #extract_global_changes() is called right after __init__ (if at all).
264                         #It also has the mutable member _undef_lic_groups. It is used to track
265                         #undefined license groups, to not display an error message for the same
266                         #group again and again. Because of this, it's useful to share it between
267                         #all LicenseManager instances.
268                         self._license_manager = clone._license_manager
269
270                         self._virtuals_manager = copy.deepcopy(clone._virtuals_manager)
271
272                         self._accept_properties = copy.deepcopy(clone._accept_properties)
273                         self._ppropertiesdict = copy.deepcopy(clone._ppropertiesdict)
274                         self._penvdict = copy.deepcopy(clone._penvdict)
275                         self._expand_map = copy.deepcopy(clone._expand_map)
276
277                 else:
278                         locations_manager = LocationsManager(config_root=config_root,
279                                 config_profile_path=config_profile_path, eprefix=eprefix,
280                                 local_config=local_config, target_root=target_root)
281
282                         eprefix = locations_manager.eprefix
283                         config_root = locations_manager.config_root
284                         abs_user_config = locations_manager.abs_user_config
285
286                         make_conf = getconfig(
287                                 os.path.join(config_root, MAKE_CONF_FILE),
288                                 tolerant=tolerant, allow_sourcing=True) or {}
289
290                         make_conf.update(getconfig(
291                                 os.path.join(abs_user_config, 'make.conf'),
292                                 tolerant=tolerant, allow_sourcing=True,
293                                 expand=make_conf) or {})
294
295                         # Allow ROOT setting to come from make.conf if it's not overridden
296                         # by the constructor argument (from the calling environment).
297                         locations_manager.set_root_override(make_conf.get("ROOT"))
298                         target_root = locations_manager.target_root
299                         eroot = locations_manager.eroot
300                         self.global_config_path = locations_manager.global_config_path
301
302                         # The expand_map is used for variable substitution
303                         # in getconfig() calls, and the getconfig() calls
304                         # update expand_map with the value of each variable
305                         # assignment that occurs. Variable substitution occurs
306                         # in the following order, which corresponds to the
307                         # order of appearance in self.lookuplist:
308                         #
309                         #   * env.d
310                         #   * make.globals
311                         #   * make.defaults
312                         #   * make.conf
313                         #
314                         # Notably absent is "env", since we want to avoid any
315                         # interaction with the calling environment that might
316                         # lead to unexpected results.
317                         expand_map = {}
318                         self._expand_map = expand_map
319
320                         # Allow make.globals to set default paths relative to ${EPREFIX}.
321                         expand_map["EPREFIX"] = eprefix
322
323                         env_d = getconfig(os.path.join(eroot, "etc", "profile.env"),
324                                 expand=expand_map)
325
326                         make_globals = getconfig(os.path.join(
327                                 self.global_config_path, 'make.globals'), expand=expand_map)
328                         if make_globals is None:
329                                 make_globals = {}
330
331                         for k, v in self._default_globals.items():
332                                 make_globals.setdefault(k, v)
333
334                         if config_incrementals is None:
335                                 self.incrementals = INCREMENTALS
336                         else:
337                                 self.incrementals = config_incrementals
338                         if not isinstance(self.incrementals, frozenset):
339                                 self.incrementals = frozenset(self.incrementals)
340
341                         self.module_priority    = ("user", "default")
342                         self.modules            = {}
343                         modules_file = os.path.join(config_root, MODULES_FILE_PATH)
344                         modules_loader = KeyValuePairFileLoader(modules_file, None, None)
345                         modules_dict, modules_errors = modules_loader.load()
346                         self.modules["user"] = modules_dict
347                         if self.modules["user"] is None:
348                                 self.modules["user"] = {}
349                         user_auxdbmodule = \
350                                 self.modules["user"].get("portdbapi.auxdbmodule")
351                         if user_auxdbmodule is not None and \
352                                 user_auxdbmodule in self._module_aliases:
353                                 warnings.warn("'%s' is deprecated: %s" %
354                                 (user_auxdbmodule, modules_file))
355
356                         self.modules["default"] = {
357                                 "portdbapi.auxdbmodule":  "portage.cache.flat_hash.database",
358                         }
359
360                         self.configlist=[]
361
362                         # back up our incremental variables:
363                         self.configdict={}
364                         self._use_expand_dict = {}
365                         # configlist will contain: [ env.d, globals, defaults, conf, pkg, backupenv, env ]
366                         self.configlist.append({})
367                         self.configdict["env.d"] = self.configlist[-1]
368
369                         self.configlist.append({})
370                         self.configdict["repo"] = self.configlist[-1]
371
372                         self.configlist.append({})
373                         self.configdict["pkginternal"] = self.configlist[-1]
374
375                         # env_d will be None if profile.env doesn't exist.
376                         if env_d:
377                                 self.configdict["env.d"].update(env_d)
378
379                         # backupenv is used for calculating incremental variables.
380                         if env is None:
381                                 env = os.environ
382
383                         # Avoid potential UnicodeDecodeError exceptions later.
384                         env_unicode = dict((_unicode_decode(k), _unicode_decode(v))
385                                 for k, v in env.items())
386
387                         self.backupenv = env_unicode
388
389                         if env_d:
390                                 # Remove duplicate values so they don't override updated
391                                 # profile.env values later (profile.env is reloaded in each
392                                 # call to self.regenerate).
393                                 for k, v in env_d.items():
394                                         try:
395                                                 if self.backupenv[k] == v:
396                                                         del self.backupenv[k]
397                                         except KeyError:
398                                                 pass
399                                 del k, v
400
401                         self.configdict["env"] = LazyItemsDict(self.backupenv)
402
403                         self.configlist.append(make_globals)
404                         self.configdict["globals"]=self.configlist[-1]
405
406                         self.make_defaults_use = []
407
408                         known_repos = []
409                         for confs in [make_globals, make_conf, self.configdict["env"]]:
410                                 known_repos.extend(confs.get("PORTDIR", '').split())
411                                 known_repos.extend(confs.get("PORTDIR_OVERLAY", '').split())
412                         known_repos = frozenset(known_repos)
413
414                         locations_manager.load_profiles(known_repos)
415
416                         profiles_complex = locations_manager.profiles_complex
417                         self.profiles = locations_manager.profiles
418                         self.profile_path = locations_manager.profile_path
419                         self.user_profile_dir = locations_manager.user_profile_dir
420
421                         packages_list = [grabfile_package(os.path.join(x, "packages"),
422                                 verify_eapi=True) for x in self.profiles]
423                         self.packages = tuple(stack_lists(packages_list, incremental=1))
424
425                         # revmaskdict
426                         self.prevmaskdict={}
427                         for x in self.packages:
428                                 # Negative atoms are filtered by the above stack_lists() call.
429                                 if not isinstance(x, Atom):
430                                         x = Atom(x.lstrip('*'))
431                                 self.prevmaskdict.setdefault(x.cp, []).append(x)
432
433
434                         mygcfg = {}
435                         if self.profiles:
436                                 mygcfg_dlists = [getconfig(os.path.join(x, "make.defaults"),
437                                         expand=expand_map) for x in self.profiles]
438                                 self._make_defaults = mygcfg_dlists
439                                 mygcfg = stack_dicts(mygcfg_dlists,
440                                         incrementals=self.incrementals)
441                                 if mygcfg is None:
442                                         mygcfg = {}
443                         self.configlist.append(mygcfg)
444                         self.configdict["defaults"]=self.configlist[-1]
445
446                         mygcfg = getconfig(
447                                 os.path.join(config_root, MAKE_CONF_FILE),
448                                 tolerant=tolerant, allow_sourcing=True,
449                                 expand=expand_map) or {}
450
451                         mygcfg.update(getconfig(
452                                 os.path.join(abs_user_config, 'make.conf'),
453                                 tolerant=tolerant, allow_sourcing=True,
454                                 expand=expand_map) or {})
455
456                         # Don't allow the user to override certain variables in make.conf
457                         profile_only_variables = self.configdict["defaults"].get(
458                                 "PROFILE_ONLY_VARIABLES", "").split()
459                         profile_only_variables = stack_lists([profile_only_variables])
460                         non_user_variables = set()
461                         non_user_variables.update(profile_only_variables)
462                         non_user_variables.update(self._env_blacklist)
463                         non_user_variables.update(self._global_only_vars)
464                         non_user_variables = frozenset(non_user_variables)
465                         self._non_user_variables = non_user_variables
466
467                         self._env_d_blacklist = frozenset(chain(
468                                 profile_only_variables,
469                                 self._env_blacklist,
470                         ))
471                         env_d = self.configdict["env.d"]
472                         for k in self._env_d_blacklist:
473                                 env_d.pop(k, None)
474
475                         for k in profile_only_variables:
476                                 mygcfg.pop(k, None)
477
478                         self.configlist.append(mygcfg)
479                         self.configdict["conf"]=self.configlist[-1]
480
481                         self.configlist.append(LazyItemsDict())
482                         self.configdict["pkg"]=self.configlist[-1]
483
484                         self.configdict["backupenv"] = self.backupenv
485
486                         # Don't allow the user to override certain variables in the env
487                         for k in profile_only_variables:
488                                 self.backupenv.pop(k, None)
489
490                         self.configlist.append(self.configdict["env"])
491
492                         # make lookuplist for loading package.*
493                         self.lookuplist=self.configlist[:]
494                         self.lookuplist.reverse()
495
496                         # Blacklist vars that could interfere with portage internals.
497                         for blacklisted in self._env_blacklist:
498                                 for cfg in self.lookuplist:
499                                         cfg.pop(blacklisted, None)
500                                 self.backupenv.pop(blacklisted, None)
501                         del blacklisted, cfg
502
503                         self["PORTAGE_CONFIGROOT"] = config_root
504                         self.backup_changes("PORTAGE_CONFIGROOT")
505                         self["ROOT"] = target_root
506                         self.backup_changes("ROOT")
507
508                         self["EPREFIX"] = eprefix
509                         self.backup_changes("EPREFIX")
510                         self["EROOT"] = eroot
511                         self.backup_changes("EROOT")
512
513                         self["PORTAGE_SANDBOX_COMPAT_LEVEL"] = _SANDBOX_COMPAT_LEVEL
514                         self.backup_changes("PORTAGE_SANDBOX_COMPAT_LEVEL")
515
516                         self._ppropertiesdict = portage.dep.ExtendedAtomDict(dict)
517                         self._penvdict = portage.dep.ExtendedAtomDict(dict)
518
519                         #Loading Repositories
520                         self.repositories = load_repository_config(self)
521
522                         #filling PORTDIR and PORTDIR_OVERLAY variable for compatibility
523                         main_repo = self.repositories.mainRepo()
524                         if main_repo is not None:
525                                 main_repo = main_repo.user_location
526                                 self["PORTDIR"] = main_repo
527                                 self.backup_changes("PORTDIR")
528
529                         # repoman controls PORTDIR_OVERLAY via the environment, so no
530                         # special cases are needed here.
531                         portdir_overlay = list(self.repositories.repoUserLocationList())
532                         if portdir_overlay and portdir_overlay[0] == self["PORTDIR"]:
533                                 portdir_overlay = portdir_overlay[1:]
534
535                         new_ov = []
536                         if portdir_overlay:
537                                 shell_quote_re = re.compile(r"[\s\\\"'$`]")
538                                 for ov in portdir_overlay:
539                                         ov = normalize_path(ov)
540                                         if os.path.isdir(ov):
541                                                 if shell_quote_re.search(ov) is not None:
542                                                         ov = portage._shell_quote(ov)
543                                                 new_ov.append(ov)
544                                         else:
545                                                 writemsg(_("!!! Invalid PORTDIR_OVERLAY"
546                                                         " (not a dir): '%s'\n") % ov, noiselevel=-1)
547
548                         self["PORTDIR_OVERLAY"] = " ".join(new_ov)
549                         self.backup_changes("PORTDIR_OVERLAY")
550
551                         locations_manager.set_port_dirs(self["PORTDIR"], self["PORTDIR_OVERLAY"])
552
553                         self._repo_make_defaults = {}
554                         for repo in self.repositories.repos_with_profiles():
555                                 d = getconfig(os.path.join(repo.location, "profiles", "make.defaults"),
556                                         expand=self.configdict["globals"].copy()) or {}
557                                 if d:
558                                         for k in chain(self._env_blacklist,
559                                                 profile_only_variables, self._global_only_vars):
560                                                 d.pop(k, None)
561                                 self._repo_make_defaults[repo.name] = d
562
563                         #Read package.keywords and package.accept_keywords.
564                         self._keywords_manager = KeywordsManager(profiles_complex, abs_user_config, \
565                                 local_config, global_accept_keywords=self.configdict["defaults"].get("ACCEPT_KEYWORDS", ""))
566
567                         #Read all USE related files from profiles and optionally from user config.
568                         self._use_manager = UseManager(self.repositories, profiles_complex, abs_user_config, user_config=local_config)
569                         #Initialize all USE related variables we track ourselves.
570                         self.usemask = self._use_manager.getUseMask()
571                         self.useforce = self._use_manager.getUseForce()
572                         self.configdict["conf"]["USE"] = \
573                                 self._use_manager.extract_global_USE_changes( \
574                                         self.configdict["conf"].get("USE", ""))
575
576                         #Read license_groups and optionally license_groups and package.license from user config
577                         self._license_manager = LicenseManager(locations_manager.profile_locations, \
578                                 abs_user_config, user_config=local_config)
579                         #Extract '*/*' entries from package.license
580                         self.configdict["conf"]["ACCEPT_LICENSE"] = \
581                                 self._license_manager.extract_global_changes( \
582                                         self.configdict["conf"].get("ACCEPT_LICENSE", ""))
583
584                         #Read package.mask and package.unmask from profiles and optionally from user config
585                         self._mask_manager = MaskManager(self.repositories, profiles_complex,
586                                 abs_user_config, user_config=local_config,
587                                 strict_umatched_removal=_unmatched_removal)
588
589                         self._virtuals_manager = VirtualsManager(self.profiles)
590
591                         if local_config:
592                                 #package.properties
593                                 propdict = grabdict_package(os.path.join(
594                                         abs_user_config, "package.properties"), recursive=1, allow_wildcard=True, \
595                                         allow_repo=True, verify_eapi=False)
596                                 v = propdict.pop("*/*", None)
597                                 if v is not None:
598                                         if "ACCEPT_PROPERTIES" in self.configdict["conf"]:
599                                                 self.configdict["conf"]["ACCEPT_PROPERTIES"] += " " + " ".join(v)
600                                         else:
601                                                 self.configdict["conf"]["ACCEPT_PROPERTIES"] = " ".join(v)
602                                 for k, v in propdict.items():
603                                         self._ppropertiesdict.setdefault(k.cp, {})[k] = v
604
605                                 #package.env
606                                 penvdict = grabdict_package(os.path.join(
607                                         abs_user_config, "package.env"), recursive=1, allow_wildcard=True, \
608                                         allow_repo=True, verify_eapi=False)
609                                 v = penvdict.pop("*/*", None)
610                                 if v is not None:
611                                         global_wildcard_conf = {}
612                                         self._grab_pkg_env(v, global_wildcard_conf)
613                                         incrementals = self.incrementals
614                                         conf_configdict = self.configdict["conf"]
615                                         for k, v in global_wildcard_conf.items():
616                                                 if k in incrementals:
617                                                         if k in conf_configdict:
618                                                                 conf_configdict[k] = \
619                                                                         conf_configdict[k] + " " + v
620                                                         else:
621                                                                 conf_configdict[k] = v
622                                                 else:
623                                                         conf_configdict[k] = v
624                                                 expand_map[k] = v
625
626                                 for k, v in penvdict.items():
627                                         self._penvdict.setdefault(k.cp, {})[k] = v
628
629                         #getting categories from an external file now
630                         self.categories = [grabfile(os.path.join(x, "categories")) \
631                                 for x in locations_manager.profile_and_user_locations]
632                         category_re = dbapi._category_re
633                         # categories used to be a tuple, but now we use a frozenset
634                         # for hashed category validation in pordbapi.cp_list()
635                         self.categories = frozenset(
636                                 x for x in stack_lists(self.categories, incremental=1)
637                                 if category_re.match(x) is not None)
638
639                         archlist = [grabfile(os.path.join(x, "arch.list")) \
640                                 for x in locations_manager.profile_and_user_locations]
641                         archlist = stack_lists(archlist, incremental=1)
642                         self.configdict["conf"]["PORTAGE_ARCHLIST"] = " ".join(archlist)
643
644                         pkgprovidedlines = [grabfile(
645                                 os.path.join(x.location, "package.provided"),
646                                 recursive=x.portage1_directories)
647                                 for x in profiles_complex]
648                         pkgprovidedlines = stack_lists(pkgprovidedlines, incremental=1)
649                         has_invalid_data = False
650                         for x in range(len(pkgprovidedlines)-1, -1, -1):
651                                 myline = pkgprovidedlines[x]
652                                 if not isvalidatom("=" + myline):
653                                         writemsg(_("Invalid package name in package.provided: %s\n") % \
654                                                 myline, noiselevel=-1)
655                                         has_invalid_data = True
656                                         del pkgprovidedlines[x]
657                                         continue
658                                 cpvr = catpkgsplit(pkgprovidedlines[x])
659                                 if not cpvr or cpvr[0] == "null":
660                                         writemsg(_("Invalid package name in package.provided: ")+pkgprovidedlines[x]+"\n",
661                                                 noiselevel=-1)
662                                         has_invalid_data = True
663                                         del pkgprovidedlines[x]
664                                         continue
665                                 if cpvr[0] == "virtual":
666                                         writemsg(_("Virtual package in package.provided: %s\n") % \
667                                                 myline, noiselevel=-1)
668                                         has_invalid_data = True
669                                         del pkgprovidedlines[x]
670                                         continue
671                         if has_invalid_data:
672                                 writemsg(_("See portage(5) for correct package.provided usage.\n"),
673                                         noiselevel=-1)
674                         self.pprovideddict = {}
675                         for x in pkgprovidedlines:
676                                 x_split = catpkgsplit(x)
677                                 if x_split is None:
678                                         continue
679                                 mycatpkg = cpv_getkey(x)
680                                 if mycatpkg in self.pprovideddict:
681                                         self.pprovideddict[mycatpkg].append(x)
682                                 else:
683                                         self.pprovideddict[mycatpkg]=[x]
684
685                         # reasonable defaults; this is important as without USE_ORDER,
686                         # USE will always be "" (nothing set)!
687                         if "USE_ORDER" not in self:
688                                 self.backupenv["USE_ORDER"] = "env:pkg:conf:defaults:pkginternal:repo:env.d"
689
690                         self.depcachedir = DEPCACHE_PATH
691                         if eprefix:
692                                 # See comments about make.globals and EPREFIX
693                                 # above. DEPCACHE_PATH is similar.
694                                 if target_root == "/":
695                                         # case (1) above
696                                         self.depcachedir = os.path.join(eprefix,
697                                                 DEPCACHE_PATH.lstrip(os.sep))
698                                 else:
699                                         # case (2) above
700                                         # For now, just assume DEPCACHE_PATH is relative
701                                         # to EPREFIX.
702                                         # TODO: Pass in more info to the constructor,
703                                         # so we know the host system configuration.
704                                         self.depcachedir = os.path.join(eprefix,
705                                                 DEPCACHE_PATH.lstrip(os.sep))
706
707                         if self.get("PORTAGE_DEPCACHEDIR", None):
708                                 self.depcachedir = self["PORTAGE_DEPCACHEDIR"]
709                         self["PORTAGE_DEPCACHEDIR"] = self.depcachedir
710                         self.backup_changes("PORTAGE_DEPCACHEDIR")
711
712                         if "CBUILD" not in self and "CHOST" in self:
713                                 self["CBUILD"] = self["CHOST"]
714                                 self.backup_changes("CBUILD")
715
716                         if "USERLAND" not in self:
717                                 # Set default USERLAND so that our test cases can assume that
718                                 # it's always set. This allows isolated-functions.sh to avoid
719                                 # calling uname -s when sourced.
720                                 system = platform.system()
721                                 if system is not None and \
722                                         (system.endswith("BSD") or system == "DragonFly"):
723                                         self["USERLAND"] = "BSD"
724                                 else:
725                                         self["USERLAND"] = "GNU"
726                                 self.backup_changes("USERLAND")
727
728                         default_inst_ids = {
729                                 "PORTAGE_INST_GID": "0",
730                                 "PORTAGE_INST_UID": "0",
731                         }
732
733                         if eprefix:
734                                 # For prefix environments, default to the UID and GID of
735                                 # the top-level EROOT directory.
736                                 try:
737                                         eroot_st = os.stat(eroot)
738                                 except OSError:
739                                         pass
740                                 else:
741                                         default_inst_ids["PORTAGE_INST_GID"] = str(eroot_st.st_gid)
742                                         default_inst_ids["PORTAGE_INST_UID"] = str(eroot_st.st_uid)
743
744                                         if "PORTAGE_USERNAME" not in self:
745                                                 try:
746                                                         pwd_struct = pwd.getpwuid(eroot_st.st_uid)
747                                                 except KeyError:
748                                                         pass
749                                                 else:
750                                                         self["PORTAGE_USERNAME"] = pwd_struct.pw_name
751                                                         self.backup_changes("PORTAGE_USERNAME")
752
753                                         if "PORTAGE_GRPNAME" not in self:
754                                                 try:
755                                                         grp_struct = grp.getgrgid(eroot_st.st_gid)
756                                                 except KeyError:
757                                                         pass
758                                                 else:
759                                                         self["PORTAGE_GRPNAME"] = grp_struct.gr_name
760                                                         self.backup_changes("PORTAGE_GRPNAME")
761
762                         for var, default_val in default_inst_ids.items():
763                                 try:
764                                         self[var] = str(int(self.get(var, default_val)))
765                                 except ValueError:
766                                         writemsg(_("!!! %s='%s' is not a valid integer.  "
767                                                 "Falling back to %s.\n") % (var, self[var], default_val),
768                                                 noiselevel=-1)
769                                         self[var] = default_val
770                                 self.backup_changes(var)
771
772                         # initialize self.features
773                         self.regenerate()
774
775                         if bsd_chflags:
776                                 self.features.add('chflags')
777
778                         if 'parse-eapi-ebuild-head' in self.features:
779                                 portage._validate_cache_for_unsupported_eapis = False
780
781                         self._iuse_implicit_match = _iuse_implicit_match_cache(self)
782
783                         self._validate_commands()
784
785                 for k in self._case_insensitive_vars:
786                         if k in self:
787                                 self[k] = self[k].lower()
788                                 self.backup_changes(k)
789
790                 if mycpv:
791                         self.setcpv(mycpv)
792
793         @property
794         def mygcfg(self):
795                 warnings.warn("portage.config.mygcfg is deprecated", stacklevel=3)
796                 return {}
797
798         def _validate_commands(self):
799                 for k in special_env_vars.validate_commands:
800                         v = self.get(k)
801                         if v is not None:
802                                 valid, v_split = validate_cmd_var(v)
803
804                                 if not valid:
805                                         if v_split:
806                                                 writemsg_level(_("%s setting is invalid: '%s'\n") % \
807                                                         (k, v), level=logging.ERROR, noiselevel=-1)
808
809                                         # before deleting the invalid setting, backup
810                                         # the default value if available
811                                         v = self.configdict['globals'].get(k)
812                                         if v is not None:
813                                                 default_valid, v_split = validate_cmd_var(v)
814                                                 if not default_valid:
815                                                         if v_split:
816                                                                 writemsg_level(
817                                                                         _("%s setting from make.globals" + \
818                                                                         " is invalid: '%s'\n") % \
819                                                                         (k, v), level=logging.ERROR, noiselevel=-1)
820                                                         # make.globals seems corrupt, so try for
821                                                         # a hardcoded default instead
822                                                         v = self._default_globals.get(k)
823
824                                         # delete all settings for this key,
825                                         # including the invalid one
826                                         del self[k]
827                                         self.backupenv.pop(k, None)
828                                         if v:
829                                                 # restore validated default
830                                                 self.configdict['globals'][k] = v
831
832         def _init_dirs(self):
833                 """
834                 Create a few directories that are critical to portage operation
835                 """
836                 if not os.access(self["EROOT"], os.W_OK):
837                         return
838
839                 #                                gid, mode, mask, preserve_perms
840                 dir_mode_map = {
841                         "tmp"             : (         -1, 0o1777,  0,  True),
842                         "var/tmp"         : (         -1, 0o1777,  0,  True),
843                         PRIVATE_PATH      : (portage_gid, 0o2750, 0o2, False),
844                         CACHE_PATH        : (portage_gid,  0o755, 0o2, False)
845                 }
846
847                 for mypath, (gid, mode, modemask, preserve_perms) \
848                         in dir_mode_map.items():
849                         mydir = os.path.join(self["EROOT"], mypath)
850                         if preserve_perms and os.path.isdir(mydir):
851                                 # Only adjust permissions on some directories if
852                                 # they don't exist yet. This gives freedom to the
853                                 # user to adjust permissions to suit their taste.
854                                 continue
855                         try:
856                                 ensure_dirs(mydir, gid=gid, mode=mode, mask=modemask)
857                         except PortageException as e:
858                                 writemsg(_("!!! Directory initialization failed: '%s'\n") % mydir,
859                                         noiselevel=-1)
860                                 writemsg("!!! %s\n" % str(e),
861                                         noiselevel=-1)
862
863         @property
864         def pkeywordsdict(self):
865                 result = self._keywords_manager.pkeywordsdict.copy()
866                 for k, v in result.items():
867                         result[k] = v.copy()
868                 return result
869
870         @property
871         def pmaskdict(self):
872                 return self._mask_manager._pmaskdict.copy()
873
874         @property
875         def punmaskdict(self):
876                 return self._mask_manager._punmaskdict.copy()
877
878         def expandLicenseTokens(self, tokens):
879                 """ Take a token from ACCEPT_LICENSE or package.license and expand it
880                 if it's a group token (indicated by @) or just return it if it's not a
881                 group.  If a group is negated then negate all group elements."""
882                 return self._license_manager.expandLicenseTokens(tokens)
883
884         def validate(self):
885                 """Validate miscellaneous settings and display warnings if necessary.
886                 (This code was previously in the global scope of portage.py)"""
887
888                 groups = self["ACCEPT_KEYWORDS"].split()
889                 archlist = self.archlist()
890                 if not archlist:
891                         writemsg(_("--- 'profiles/arch.list' is empty or "
892                                 "not available. Empty portage tree?\n"), noiselevel=1)
893                 else:
894                         for group in groups:
895                                 if group not in archlist and \
896                                         not (group.startswith("-") and group[1:] in archlist) and \
897                                         group not in ("*", "~*", "**"):
898                                         writemsg(_("!!! INVALID ACCEPT_KEYWORDS: %s\n") % str(group),
899                                                 noiselevel=-1)
900
901                 abs_profile_path = os.path.join(self["PORTAGE_CONFIGROOT"],
902                         PROFILE_PATH)
903                 if (not self.profile_path or \
904                         not os.path.exists(os.path.join(self.profile_path, "parent"))) and \
905                         os.path.exists(os.path.join(self["PORTDIR"], "profiles")):
906                         writemsg(_("\n\n!!! %s is not a symlink and will probably prevent most merges.\n") % abs_profile_path,
907                                 noiselevel=-1)
908                         writemsg(_("!!! It should point into a profile within %s/profiles/\n") % self["PORTDIR"])
909                         writemsg(_("!!! (You can safely ignore this message when syncing. It's harmless.)\n\n\n"))
910
911                 abs_user_virtuals = os.path.join(self["PORTAGE_CONFIGROOT"],
912                         USER_VIRTUALS_FILE)
913                 if os.path.exists(abs_user_virtuals):
914                         writemsg("\n!!! /etc/portage/virtuals is deprecated in favor of\n")
915                         writemsg("!!! /etc/portage/profile/virtuals. Please move it to\n")
916                         writemsg("!!! this new location.\n\n")
917
918                 if not sandbox_capable and \
919                         ("sandbox" in self.features or "usersandbox" in self.features):
920                         if self.profile_path is not None and \
921                                 os.path.realpath(self.profile_path) == \
922                                 os.path.realpath(os.path.join(
923                                 self["PORTAGE_CONFIGROOT"], PROFILE_PATH)):
924                                 # Don't show this warning when running repoman and the
925                                 # sandbox feature came from a profile that doesn't belong
926                                 # to the user.
927                                 writemsg(colorize("BAD", _("!!! Problem with sandbox"
928                                         " binary. Disabling...\n\n")), noiselevel=-1)
929
930                 if "fakeroot" in self.features and \
931                         not fakeroot_capable:
932                         writemsg(_("!!! FEATURES=fakeroot is enabled, but the "
933                                 "fakeroot binary is not installed.\n"), noiselevel=-1)
934
935         def load_best_module(self,property_string):
936                 best_mod = best_from_dict(property_string,self.modules,self.module_priority)
937                 mod = None
938                 try:
939                         mod = load_mod(best_mod)
940                 except ImportError:
941                         if best_mod in self._module_aliases:
942                                 mod = load_mod(self._module_aliases[best_mod])
943                         elif not best_mod.startswith("cache."):
944                                 raise
945                         else:
946                                 best_mod = "portage." + best_mod
947                                 try:
948                                         mod = load_mod(best_mod)
949                                 except ImportError:
950                                         raise
951                 return mod
952
953         def lock(self):
954                 self.locked = 1
955
956         def unlock(self):
957                 self.locked = 0
958
959         def modifying(self):
960                 if self.locked:
961                         raise Exception(_("Configuration is locked."))
962
963         def backup_changes(self,key=None):
964                 self.modifying()
965                 if key and key in self.configdict["env"]:
966                         self.backupenv[key] = copy.deepcopy(self.configdict["env"][key])
967                 else:
968                         raise KeyError(_("No such key defined in environment: %s") % key)
969
970         def reset(self, keeping_pkg=0, use_cache=None):
971                 """
972                 Restore environment from self.backupenv, call self.regenerate()
973                 @param keeping_pkg: Should we keep the setcpv() data or delete it.
974                 @type keeping_pkg: Boolean
975                 @rype: None
976                 """
977
978                 if use_cache is not None:
979                         warnings.warn("The use_cache parameter for config.reset() is deprecated and without effect.",
980                                 DeprecationWarning, stacklevel=2)
981
982                 self.modifying()
983                 self.configdict["env"].clear()
984                 self.configdict["env"].update(self.backupenv)
985
986                 self.modifiedkeys = []
987                 if not keeping_pkg:
988                         self.mycpv = None
989                         self._setcpv_args_hash = None
990                         self.puse = ""
991                         del self._penv[:]
992                         self.configdict["pkg"].clear()
993                         self.configdict["pkginternal"].clear()
994                         self.configdict["repo"].clear()
995                         self.configdict["defaults"]["USE"] = \
996                                 " ".join(self.make_defaults_use)
997                         self.usemask = self._use_manager.getUseMask()
998                         self.useforce = self._use_manager.getUseForce()
999                 self.regenerate()
1000
1001         class _lazy_vars(object):
1002
1003                 __slots__ = ('built_use', 'settings', 'values')
1004
1005                 def __init__(self, built_use, settings):
1006                         self.built_use = built_use
1007                         self.settings = settings
1008                         self.values = None
1009
1010                 def __getitem__(self, k):
1011                         if self.values is None:
1012                                 self.values = self._init_values()
1013                         return self.values[k]
1014
1015                 def _init_values(self):
1016                         values = {}
1017                         settings = self.settings
1018                         use = self.built_use
1019                         if use is None:
1020                                 use = frozenset(settings['PORTAGE_USE'].split())
1021
1022                         values['ACCEPT_LICENSE'] = settings._license_manager.get_prunned_accept_license( \
1023                                 settings.mycpv, use, settings['LICENSE'], settings['SLOT'], settings.get('PORTAGE_REPO_NAME'))
1024                         values['PORTAGE_RESTRICT'] = self._restrict(use, settings)
1025                         return values
1026
1027                 def _restrict(self, use, settings):
1028                         try:
1029                                 restrict = set(use_reduce(settings['RESTRICT'], uselist=use, flat=True))
1030                         except InvalidDependString:
1031                                 restrict = set()
1032                         return ' '.join(sorted(restrict))
1033
1034         class _lazy_use_expand(object):
1035                 """
1036                 Lazily evaluate USE_EXPAND variables since they are only needed when
1037                 an ebuild shell is spawned. Variables values are made consistent with
1038                 the previously calculated USE settings.
1039                 """
1040
1041                 def __init__(self, use, usemask, iuse_implicit,
1042                         use_expand_split, use_expand_dict):
1043                         self._use = use
1044                         self._usemask = usemask
1045                         self._iuse_implicit = iuse_implicit
1046                         self._use_expand_split = use_expand_split
1047                         self._use_expand_dict = use_expand_dict
1048
1049                 def __getitem__(self, key):
1050                         prefix = key.lower() + '_'
1051                         prefix_len = len(prefix)
1052                         expand_flags = set( x[prefix_len:] for x in self._use \
1053                                 if x[:prefix_len] == prefix )
1054                         var_split = self._use_expand_dict.get(key, '').split()
1055                         # Preserve the order of var_split because it can matter for things
1056                         # like LINGUAS.
1057                         var_split = [ x for x in var_split if x in expand_flags ]
1058                         var_split.extend(expand_flags.difference(var_split))
1059                         has_wildcard = '*' in expand_flags
1060                         if has_wildcard:
1061                                 var_split = [ x for x in var_split if x != "*" ]
1062                         has_iuse = set()
1063                         for x in self._iuse_implicit:
1064                                 if x[:prefix_len] == prefix:
1065                                         has_iuse.add(x[prefix_len:])
1066                         if has_wildcard:
1067                                 # * means to enable everything in IUSE that's not masked
1068                                 if has_iuse:
1069                                         usemask = self._usemask
1070                                         for suffix in has_iuse:
1071                                                 x = prefix + suffix
1072                                                 if x not in usemask:
1073                                                         if suffix not in expand_flags:
1074                                                                 var_split.append(suffix)
1075                                 else:
1076                                         # If there is a wildcard and no matching flags in IUSE then
1077                                         # LINGUAS should be unset so that all .mo files are
1078                                         # installed.
1079                                         var_split = []
1080                         # Make the flags unique and filter them according to IUSE.
1081                         # Also, continue to preserve order for things like LINGUAS
1082                         # and filter any duplicates that variable may contain.
1083                         filtered_var_split = []
1084                         remaining = has_iuse.intersection(var_split)
1085                         for x in var_split:
1086                                 if x in remaining:
1087                                         remaining.remove(x)
1088                                         filtered_var_split.append(x)
1089                         var_split = filtered_var_split
1090
1091                         if var_split:
1092                                 value = ' '.join(var_split)
1093                         else:
1094                                 # Don't export empty USE_EXPAND vars unless the user config
1095                                 # exports them as empty.  This is required for vars such as
1096                                 # LINGUAS, where unset and empty have different meanings.
1097                                 if has_wildcard:
1098                                         # ebuild.sh will see this and unset the variable so
1099                                         # that things like LINGUAS work properly
1100                                         value = '*'
1101                                 else:
1102                                         if has_iuse:
1103                                                 value = ''
1104                                         else:
1105                                                 # It's not in IUSE, so just allow the variable content
1106                                                 # to pass through if it is defined somewhere.  This
1107                                                 # allows packages that support LINGUAS but don't
1108                                                 # declare it in IUSE to use the variable outside of the
1109                                                 # USE_EXPAND context.
1110                                                 value = None
1111
1112                         return value
1113
1114         def setcpv(self, mycpv, use_cache=None, mydb=None):
1115                 """
1116                 Load a particular CPV into the config, this lets us see the
1117                 Default USE flags for a particular ebuild as well as the USE
1118                 flags from package.use.
1119
1120                 @param mycpv: A cpv to load
1121                 @type mycpv: string
1122                 @param mydb: a dbapi instance that supports aux_get with the IUSE key.
1123                 @type mydb: dbapi or derivative.
1124                 @rtype: None
1125                 """
1126
1127                 if use_cache is not None:
1128                         warnings.warn("The use_cache parameter for config.setcpv() is deprecated and without effect.",
1129                                 DeprecationWarning, stacklevel=2)
1130
1131                 self.modifying()
1132
1133                 pkg = None
1134                 built_use = None
1135                 explicit_iuse = None
1136                 if not isinstance(mycpv, basestring):
1137                         pkg = mycpv
1138                         mycpv = pkg.cpv
1139                         mydb = pkg.metadata
1140                         explicit_iuse = pkg.iuse.all
1141                         args_hash = (mycpv, id(pkg))
1142                         if pkg.built:
1143                                 built_use = pkg.use.enabled
1144                 else:
1145                         args_hash = (mycpv, id(mydb))
1146
1147                 if args_hash == self._setcpv_args_hash:
1148                         return
1149                 self._setcpv_args_hash = args_hash
1150
1151                 has_changed = False
1152                 self.mycpv = mycpv
1153                 cat, pf = catsplit(mycpv)
1154                 cp = cpv_getkey(mycpv)
1155                 cpv_slot = self.mycpv
1156                 pkginternaluse = ""
1157                 iuse = ""
1158                 pkg_configdict = self.configdict["pkg"]
1159                 previous_iuse = pkg_configdict.get("IUSE")
1160                 previous_features = pkg_configdict.get("FEATURES")
1161
1162                 aux_keys = self._setcpv_aux_keys
1163
1164                 # Discard any existing metadata and package.env settings from
1165                 # the previous package instance.
1166                 pkg_configdict.clear()
1167
1168                 pkg_configdict["CATEGORY"] = cat
1169                 pkg_configdict["PF"] = pf
1170                 repository = None
1171                 if mydb:
1172                         if not hasattr(mydb, "aux_get"):
1173                                 for k in aux_keys:
1174                                         if k in mydb:
1175                                                 # Make these lazy, since __getitem__ triggers
1176                                                 # evaluation of USE conditionals which can't
1177                                                 # occur until PORTAGE_USE is calculated below.
1178                                                 pkg_configdict.addLazySingleton(k,
1179                                                         mydb.__getitem__, k)
1180                         else:
1181                                 # When calling dbapi.aux_get(), grab USE for built/installed
1182                                 # packages since we want to save it PORTAGE_BUILT_USE for
1183                                 # evaluating conditional USE deps in atoms passed via IPC to
1184                                 # helpers like has_version and best_version.
1185                                 aux_keys = list(aux_keys)
1186                                 aux_keys.append('USE')
1187                                 for k, v in zip(aux_keys, mydb.aux_get(self.mycpv, aux_keys)):
1188                                         pkg_configdict[k] = v
1189                                 built_use = frozenset(pkg_configdict.pop('USE').split())
1190                                 if not built_use:
1191                                         # Empty USE means this dbapi instance does not contain
1192                                         # built packages.
1193                                         built_use = None
1194
1195                         repository = pkg_configdict.pop("repository", None)
1196                         if repository is not None:
1197                                 pkg_configdict["PORTAGE_REPO_NAME"] = repository
1198                         slot = pkg_configdict["SLOT"]
1199                         iuse = pkg_configdict["IUSE"]
1200                         if pkg is None:
1201                                 cpv_slot = "%s:%s" % (self.mycpv, slot)
1202                         else:
1203                                 cpv_slot = pkg
1204                         pkginternaluse = []
1205                         for x in iuse.split():
1206                                 if x.startswith("+"):
1207                                         pkginternaluse.append(x[1:])
1208                                 elif x.startswith("-"):
1209                                         pkginternaluse.append(x)
1210                         pkginternaluse = " ".join(pkginternaluse)
1211                 if pkginternaluse != self.configdict["pkginternal"].get("USE", ""):
1212                         self.configdict["pkginternal"]["USE"] = pkginternaluse
1213                         has_changed = True
1214
1215                 repo_env = []
1216                 if repository and repository != Package.UNKNOWN_REPO:
1217                         repos = []
1218                         try:
1219                                 repos.extend(repo.name for repo in
1220                                         self.repositories[repository].masters)
1221                         except KeyError:
1222                                 pass
1223                         repos.append(repository)
1224                         for repo in repos:
1225                                 d = self._repo_make_defaults.get(repo)
1226                                 if d is None:
1227                                         d = {}
1228                                 else:
1229                                         # make a copy, since we might modify it with
1230                                         # package.use settings
1231                                         d = d.copy()
1232                                 cpdict = self._use_manager._repo_puse_dict.get(repo, {}).get(cp)
1233                                 if cpdict:
1234                                         repo_puse = ordered_by_atom_specificity(cpdict, cpv_slot)
1235                                         if repo_puse:
1236                                                 for x in repo_puse:
1237                                                         d["USE"] = d.get("USE", "") + " " + " ".join(x)
1238                                 if d:
1239                                         repo_env.append(d)
1240
1241                 if repo_env or self.configdict["repo"]:
1242                         self.configdict["repo"].clear()
1243                         self.configdict["repo"].update(stack_dicts(repo_env,
1244                                 incrementals=self.incrementals))
1245                         has_changed = True
1246
1247                 defaults = []
1248                 for i, pkgprofileuse_dict in enumerate(self._use_manager._pkgprofileuse):
1249                         if self.make_defaults_use[i]:
1250                                 defaults.append(self.make_defaults_use[i])
1251                         cpdict = pkgprofileuse_dict.get(cp)
1252                         if cpdict:
1253                                 pkg_defaults = ordered_by_atom_specificity(cpdict, cpv_slot)
1254                                 if pkg_defaults:
1255                                         defaults.extend(pkg_defaults)
1256                 defaults = " ".join(defaults)
1257                 if defaults != self.configdict["defaults"].get("USE",""):
1258                         self.configdict["defaults"]["USE"] = defaults
1259                         has_changed = True
1260
1261                 useforce = self._use_manager.getUseForce(cpv_slot)
1262                 if useforce != self.useforce:
1263                         self.useforce = useforce
1264                         has_changed = True
1265
1266                 usemask = self._use_manager.getUseMask(cpv_slot)
1267                 if usemask != self.usemask:
1268                         self.usemask = usemask
1269                         has_changed = True
1270
1271                 oldpuse = self.puse
1272                 self.puse = self._use_manager.getPUSE(cpv_slot)
1273                 if oldpuse != self.puse:
1274                         has_changed = True
1275                 self.configdict["pkg"]["PKGUSE"] = self.puse[:] # For saving to PUSE file
1276                 self.configdict["pkg"]["USE"]    = self.puse[:] # this gets appended to USE
1277
1278                 if previous_features:
1279                         # The package from the previous setcpv call had package.env
1280                         # settings which modified FEATURES. Therefore, trigger a
1281                         # regenerate() call in order to ensure that self.features
1282                         # is accurate.
1283                         has_changed = True
1284
1285                 self._penv = []
1286                 cpdict = self._penvdict.get(cp)
1287                 if cpdict:
1288                         penv_matches = ordered_by_atom_specificity(cpdict, cpv_slot)
1289                         if penv_matches:
1290                                 for x in penv_matches:
1291                                         self._penv.extend(x)
1292
1293                 protected_pkg_keys = set(pkg_configdict)
1294                 protected_pkg_keys.discard('USE')
1295
1296                 # If there are _any_ package.env settings for this package
1297                 # then it automatically triggers config.reset(), in order
1298                 # to account for possible incremental interaction between
1299                 # package.use, package.env, and overrides from the calling
1300                 # environment (configdict['env']).
1301                 if self._penv:
1302                         has_changed = True
1303                         # USE is special because package.use settings override
1304                         # it. Discard any package.use settings here and they'll
1305                         # be added back later.
1306                         pkg_configdict.pop('USE', None)
1307                         self._grab_pkg_env(self._penv, pkg_configdict,
1308                                 protected_keys=protected_pkg_keys)
1309
1310                         # Now add package.use settings, which override USE from
1311                         # package.env
1312                         if self.puse:
1313                                 if 'USE' in pkg_configdict:
1314                                         pkg_configdict['USE'] = \
1315                                                 pkg_configdict['USE'] + " " + self.puse
1316                                 else:
1317                                         pkg_configdict['USE'] = self.puse
1318
1319                 if has_changed:
1320                         self.reset(keeping_pkg=1)
1321
1322                 env_configdict = self.configdict['env']
1323
1324                 # Ensure that "pkg" values are always preferred over "env" values.
1325                 # This must occur _after_ the above reset() call, since reset()
1326                 # copies values from self.backupenv.
1327                 for k in protected_pkg_keys:
1328                         env_configdict.pop(k, None)
1329
1330                 lazy_vars = self._lazy_vars(built_use, self)
1331                 env_configdict.addLazySingleton('ACCEPT_LICENSE',
1332                         lazy_vars.__getitem__, 'ACCEPT_LICENSE')
1333                 env_configdict.addLazySingleton('PORTAGE_RESTRICT',
1334                         lazy_vars.__getitem__, 'PORTAGE_RESTRICT')
1335
1336                 if built_use is not None:
1337                         pkg_configdict['PORTAGE_BUILT_USE'] = ' '.join(built_use)
1338
1339                 # If reset() has not been called, it's safe to return
1340                 # early if IUSE has not changed.
1341                 if not has_changed and previous_iuse == iuse:
1342                         return
1343
1344                 # Filter out USE flags that aren't part of IUSE. This has to
1345                 # be done for every setcpv() call since practically every
1346                 # package has different IUSE.
1347                 use = set(self["USE"].split())
1348                 if explicit_iuse is None:
1349                         explicit_iuse = frozenset(x.lstrip("+-") for x in iuse.split())
1350                 iuse_implicit_match = self._iuse_implicit_match
1351                 portage_iuse = self._get_implicit_iuse()
1352                 portage_iuse.update(explicit_iuse)
1353
1354                 # PORTAGE_IUSE is not always needed so it's lazily evaluated.
1355                 self.configdict["env"].addLazySingleton(
1356                         "PORTAGE_IUSE", _lazy_iuse_regex, portage_iuse)
1357
1358                 ebuild_force_test = self.get("EBUILD_FORCE_TEST") == "1"
1359                 if ebuild_force_test and \
1360                         not hasattr(self, "_ebuild_force_test_msg_shown"):
1361                                 self._ebuild_force_test_msg_shown = True
1362                                 writemsg(_("Forcing test.\n"), noiselevel=-1)
1363                 if "test" in self.features:
1364                         if "test" in self.usemask and not ebuild_force_test:
1365                                 # "test" is in IUSE and USE=test is masked, so execution
1366                                 # of src_test() probably is not reliable. Therefore,
1367                                 # temporarily disable FEATURES=test just for this package.
1368                                 self["FEATURES"] = " ".join(x for x in self.features \
1369                                         if x != "test")
1370                                 use.discard("test")
1371                         else:
1372                                 use.add("test")
1373                                 if ebuild_force_test and "test" in self.usemask:
1374                                         self.usemask = \
1375                                                 frozenset(x for x in self.usemask if x != "test")
1376
1377                 # Allow _* flags from USE_EXPAND wildcards to pass through here.
1378                 use.difference_update([x for x in use \
1379                         if (x not in explicit_iuse and \
1380                         not iuse_implicit_match(x)) and x[-2:] != '_*'])
1381
1382                 # Use the calculated USE flags to regenerate the USE_EXPAND flags so
1383                 # that they are consistent. For optimal performance, use slice
1384                 # comparison instead of startswith().
1385                 use_expand_split = set(x.lower() for \
1386                         x in self.get('USE_EXPAND', '').split())
1387                 lazy_use_expand = self._lazy_use_expand(use, self.usemask,
1388                         portage_iuse, use_expand_split, self._use_expand_dict)
1389
1390                 use_expand_iuses = {}
1391                 for x in portage_iuse:
1392                         x_split = x.split('_')
1393                         if len(x_split) == 1:
1394                                 continue
1395                         for i in range(len(x_split) - 1):
1396                                 k = '_'.join(x_split[:i+1])
1397                                 if k in use_expand_split:
1398                                         v = use_expand_iuses.get(k)
1399                                         if v is None:
1400                                                 v = set()
1401                                                 use_expand_iuses[k] = v
1402                                         v.add(x)
1403                                         break
1404
1405                 # If it's not in IUSE, variable content is allowed
1406                 # to pass through if it is defined somewhere.  This
1407                 # allows packages that support LINGUAS but don't
1408                 # declare it in IUSE to use the variable outside of the
1409                 # USE_EXPAND context.
1410                 for k, use_expand_iuse in use_expand_iuses.items():
1411                         if k + '_*' in use:
1412                                 use.update( x for x in use_expand_iuse if x not in usemask )
1413                         k = k.upper()
1414                         self.configdict['env'].addLazySingleton(k,
1415                                 lazy_use_expand.__getitem__, k)
1416
1417                 # Filtered for the ebuild environment. Store this in a separate
1418                 # attribute since we still want to be able to see global USE
1419                 # settings for things like emerge --info.
1420
1421                 self.configdict["env"]["PORTAGE_USE"] = \
1422                         " ".join(sorted(x for x in use if x[-2:] != '_*'))
1423
1424         def _grab_pkg_env(self, penv, container, protected_keys=None):
1425                 if protected_keys is None:
1426                         protected_keys = ()
1427                 abs_user_config = os.path.join(
1428                         self['PORTAGE_CONFIGROOT'], USER_CONFIG_PATH)
1429                 non_user_variables = self._non_user_variables
1430                 # Make a copy since we don't want per-package settings
1431                 # to pollute the global expand_map.
1432                 expand_map = self._expand_map.copy()
1433                 incrementals = self.incrementals
1434                 for envname in penv:
1435                         penvfile = os.path.join(abs_user_config, "env", envname)
1436                         penvconfig = getconfig(penvfile, tolerant=self._tolerant,
1437                                 allow_sourcing=True, expand=expand_map)
1438                         if penvconfig is None:
1439                                 writemsg("!!! %s references non-existent file: %s\n" % \
1440                                         (os.path.join(abs_user_config, 'package.env'), penvfile),
1441                                         noiselevel=-1)
1442                         else:
1443                                 for k, v in penvconfig.items():
1444                                         if k in protected_keys or \
1445                                                 k in non_user_variables:
1446                                                 writemsg("!!! Illegal variable " + \
1447                                                         "'%s' assigned in '%s'\n" % \
1448                                                         (k, penvfile), noiselevel=-1)
1449                                         elif k in incrementals:
1450                                                 if k in container:
1451                                                         container[k] = container[k] + " " + v
1452                                                 else:
1453                                                         container[k] = v
1454                                         else:
1455                                                 container[k] = v
1456
1457         def _get_implicit_iuse(self):
1458                 """
1459                 Some flags are considered to
1460                 be implicit members of IUSE:
1461                   * Flags derived from ARCH
1462                   * Flags derived from USE_EXPAND_HIDDEN variables
1463                   * Masked flags, such as those from {,package}use.mask
1464                   * Forced flags, such as those from {,package}use.force
1465                   * build and bootstrap flags used by bootstrap.sh
1466                 """
1467                 iuse_implicit = set()
1468                 # Flags derived from ARCH.
1469                 arch = self.configdict["defaults"].get("ARCH")
1470                 if arch:
1471                         iuse_implicit.add(arch)
1472                 iuse_implicit.update(self.get("PORTAGE_ARCHLIST", "").split())
1473
1474                 # Flags derived from USE_EXPAND_HIDDEN variables
1475                 # such as ELIBC, KERNEL, and USERLAND.
1476                 use_expand_hidden = self.get("USE_EXPAND_HIDDEN", "").split()
1477                 for x in use_expand_hidden:
1478                         iuse_implicit.add(x.lower() + "_.*")
1479
1480                 # Flags that have been masked or forced.
1481                 iuse_implicit.update(self.usemask)
1482                 iuse_implicit.update(self.useforce)
1483
1484                 # build and bootstrap flags used by bootstrap.sh
1485                 iuse_implicit.add("build")
1486                 iuse_implicit.add("bootstrap")
1487
1488                 # Controlled by FEATURES=test. Make this implicit, so handling
1489                 # of FEATURES=test is consistent regardless of explicit IUSE.
1490                 # Users may use use.mask/package.use.mask to control
1491                 # FEATURES=test for all ebuilds, regardless of explicit IUSE.
1492                 iuse_implicit.add("test")
1493
1494                 return iuse_implicit
1495
1496         def _getUseMask(self, pkg):
1497                 return self._use_manager.getUseMask(pkg)
1498
1499         def _getUseForce(self, pkg):
1500                 return self._use_manager.getUseForce(pkg)
1501
1502         def _getMaskAtom(self, cpv, metadata):
1503                 """
1504                 Take a package and return a matching package.mask atom, or None if no
1505                 such atom exists or it has been cancelled by package.unmask. PROVIDE
1506                 is not checked, so atoms will not be found for old-style virtuals.
1507
1508                 @param cpv: The package name
1509                 @type cpv: String
1510                 @param metadata: A dictionary of raw package metadata
1511                 @type metadata: dict
1512                 @rtype: String
1513                 @return: A matching atom string or None if one is not found.
1514                 """
1515                 return self._mask_manager.getMaskAtom(cpv, metadata["SLOT"], metadata.get('repository'))
1516
1517         def _getRawMaskAtom(self, cpv, metadata):
1518                 """
1519                 Take a package and return a matching package.mask atom, or None if no
1520                 such atom exists or it has been cancelled by package.unmask. PROVIDE
1521                 is not checked, so atoms will not be found for old-style virtuals.
1522
1523                 @param cpv: The package name
1524                 @type cpv: String
1525                 @param metadata: A dictionary of raw package metadata
1526                 @type metadata: dict
1527                 @rtype: String
1528                 @return: A matching atom string or None if one is not found.
1529                 """
1530                 return self._mask_manager.getRawMaskAtom(cpv, metadata["SLOT"], metadata.get('repository'))
1531
1532
1533         def _getProfileMaskAtom(self, cpv, metadata):
1534                 """
1535                 Take a package and return a matching profile atom, or None if no
1536                 such atom exists. Note that a profile atom may or may not have a "*"
1537                 prefix. PROVIDE is not checked, so atoms will not be found for
1538                 old-style virtuals.
1539
1540                 @param cpv: The package name
1541                 @type cpv: String
1542                 @param metadata: A dictionary of raw package metadata
1543                 @type metadata: dict
1544                 @rtype: String
1545                 @return: A matching profile atom string or None if one is not found.
1546                 """
1547
1548                 warnings.warn("The config._getProfileMaskAtom() method is deprecated.",
1549                         DeprecationWarning, stacklevel=2)
1550
1551                 cp = cpv_getkey(cpv)
1552                 profile_atoms = self.prevmaskdict.get(cp)
1553                 if profile_atoms:
1554                         pkg = "".join((cpv, _slot_separator, metadata["SLOT"]))
1555                         repo = metadata.get("repository")
1556                         if repo and repo != Package.UNKNOWN_REPO:
1557                                 pkg = "".join((pkg, _repo_separator, repo))
1558                         pkg_list = [pkg]
1559                         for x in profile_atoms:
1560                                 if match_from_list(x, pkg_list):
1561                                         continue
1562                                 return x
1563                 return None
1564
1565         def _getKeywords(self, cpv, metadata):
1566                 return self._keywords_manager.getKeywords(cpv, metadata["SLOT"], \
1567                         metadata.get("KEYWORDS", ""), metadata.get("repository"))
1568
1569         def _getMissingKeywords(self, cpv, metadata):
1570                 """
1571                 Take a package and return a list of any KEYWORDS that the user may
1572                 need to accept for the given package. If the KEYWORDS are empty
1573                 and the the ** keyword has not been accepted, the returned list will
1574                 contain ** alone (in order to distinguish from the case of "none
1575                 missing").
1576
1577                 @param cpv: The package name (for package.keywords support)
1578                 @type cpv: String
1579                 @param metadata: A dictionary of raw package metadata
1580                 @type metadata: dict
1581                 @rtype: List
1582                 @return: A list of KEYWORDS that have not been accepted.
1583                 """
1584
1585                 # Hack: Need to check the env directly here as otherwise stacking
1586                 # doesn't work properly as negative values are lost in the config
1587                 # object (bug #139600)
1588                 backuped_accept_keywords = self.configdict["backupenv"].get("ACCEPT_KEYWORDS", "")
1589                 global_accept_keywords = self["ACCEPT_KEYWORDS"]
1590
1591                 return self._keywords_manager.getMissingKeywords(cpv, metadata["SLOT"], \
1592                         metadata.get("KEYWORDS", ""), metadata.get('repository'), \
1593                         global_accept_keywords, backuped_accept_keywords)
1594
1595         def _getRawMissingKeywords(self, cpv, metadata):
1596                 """
1597                 Take a package and return a list of any KEYWORDS that the user may
1598                 need to accept for the given package. If the KEYWORDS are empty,
1599                 the returned list will contain ** alone (in order to distinguish
1600                 from the case of "none missing").  This DOES NOT apply any user config
1601                 package.accept_keywords acceptance.
1602
1603                 @param cpv: The package name (for package.keywords support)
1604                 @type cpv: String
1605                 @param metadata: A dictionary of raw package metadata
1606                 @type metadata: dict
1607                 @rtype: List
1608                 @return: lists of KEYWORDS that have not been accepted
1609                 and the keywords it looked for.
1610                 """
1611                 return self._keywords_manager.getRawMissingKeywords(cpv, metadata["SLOT"], \
1612                         metadata.get("KEYWORDS", ""), metadata.get('repository'), \
1613                         self.get("ACCEPT_KEYWORDS", ""))
1614
1615         def _getPKeywords(self, cpv, metadata):
1616                 global_accept_keywords = self.get("ACCEPT_KEYWORDS", "")
1617
1618                 return self._keywords_manager.getPKeywords(cpv, metadata["SLOT"], \
1619                         metadata.get('repository'), global_accept_keywords)
1620
1621         def _getMissingLicenses(self, cpv, metadata):
1622                 """
1623                 Take a LICENSE string and return a list of any licenses that the user
1624                 may need to accept for the given package.  The returned list will not
1625                 contain any licenses that have already been accepted.  This method
1626                 can throw an InvalidDependString exception.
1627
1628                 @param cpv: The package name (for package.license support)
1629                 @type cpv: String
1630                 @param metadata: A dictionary of raw package metadata
1631                 @type metadata: dict
1632                 @rtype: List
1633                 @return: A list of licenses that have not been accepted.
1634                 """
1635                 return self._license_manager.getMissingLicenses( \
1636                         cpv, metadata["USE"], metadata["LICENSE"], metadata["SLOT"], metadata.get('repository'))
1637
1638         def _getMissingProperties(self, cpv, metadata):
1639                 """
1640                 Take a PROPERTIES string and return a list of any properties the user
1641                 may need to accept for the given package.  The returned list will not
1642                 contain any properties that have already been accepted.  This method
1643                 can throw an InvalidDependString exception.
1644
1645                 @param cpv: The package name (for package.properties support)
1646                 @type cpv: String
1647                 @param metadata: A dictionary of raw package metadata
1648                 @type metadata: dict
1649                 @rtype: List
1650                 @return: A list of properties that have not been accepted.
1651                 """
1652                 accept_properties = self._accept_properties
1653                 cp = cpv_getkey(cpv)
1654                 cpdict = self._ppropertiesdict.get(cp)
1655                 if cpdict:
1656                         cpv_slot = "%s:%s" % (cpv, metadata["SLOT"])
1657                         pproperties_list = ordered_by_atom_specificity(cpdict, cpv_slot, repo=metadata.get('repository'))
1658                         if pproperties_list:
1659                                 accept_properties = list(self._accept_properties)
1660                                 for x in pproperties_list:
1661                                         accept_properties.extend(x)
1662
1663                 properties_str = metadata.get("PROPERTIES", "")
1664                 properties = set(use_reduce(properties_str, matchall=1, flat=True))
1665                 properties.discard('||')
1666
1667                 acceptable_properties = set()
1668                 for x in accept_properties:
1669                         if x == '*':
1670                                 acceptable_properties.update(properties)
1671                         elif x == '-*':
1672                                 acceptable_properties.clear()
1673                         elif x[:1] == '-':
1674                                 acceptable_properties.discard(x[1:])
1675                         else:
1676                                 acceptable_properties.add(x)
1677
1678                 if "?" in properties_str:
1679                         use = metadata["USE"].split()
1680                 else:
1681                         use = []
1682
1683                 properties_struct = use_reduce(properties_str, uselist=use, opconvert=True)
1684                 return self._getMaskedProperties(properties_struct, acceptable_properties)
1685
1686         def _getMaskedProperties(self, properties_struct, acceptable_properties):
1687                 if not properties_struct:
1688                         return []
1689                 if properties_struct[0] == "||":
1690                         ret = []
1691                         for element in properties_struct[1:]:
1692                                 if isinstance(element, list):
1693                                         if element:
1694                                                 tmp = self._getMaskedProperties(
1695                                                         element, acceptable_properties)
1696                                                 if not tmp:
1697                                                         return []
1698                                                 ret.extend(tmp)
1699                                 else:
1700                                         if element in acceptable_properties:
1701                                                 return[]
1702                                         ret.append(element)
1703                         # Return all masked properties, since we don't know which combination
1704                         # (if any) the user will decide to unmask
1705                         return ret
1706
1707                 ret = []
1708                 for element in properties_struct:
1709                         if isinstance(element, list):
1710                                 if element:
1711                                         ret.extend(self._getMaskedProperties(element,
1712                                                 acceptable_properties))
1713                         else:
1714                                 if element not in acceptable_properties:
1715                                         ret.append(element)
1716                 return ret
1717
1718         def _accept_chost(self, cpv, metadata):
1719                 """
1720                 @return True if pkg CHOST is accepted, False otherwise.
1721                 """
1722                 if self._accept_chost_re is None:
1723                         accept_chost = self.get("ACCEPT_CHOSTS", "").split()
1724                         if not accept_chost:
1725                                 chost = self.get("CHOST")
1726                                 if chost:
1727                                         accept_chost.append(chost)
1728                         if not accept_chost:
1729                                 self._accept_chost_re = re.compile(".*")
1730                         elif len(accept_chost) == 1:
1731                                 try:
1732                                         self._accept_chost_re = re.compile(r'^%s$' % accept_chost[0])
1733                                 except re.error as e:
1734                                         writemsg(_("!!! Invalid ACCEPT_CHOSTS value: '%s': %s\n") % \
1735                                                 (accept_chost[0], e), noiselevel=-1)
1736                                         self._accept_chost_re = re.compile("^$")
1737                         else:
1738                                 try:
1739                                         self._accept_chost_re = re.compile(
1740                                                 r'^(%s)$' % "|".join(accept_chost))
1741                                 except re.error as e:
1742                                         writemsg(_("!!! Invalid ACCEPT_CHOSTS value: '%s': %s\n") % \
1743                                                 (" ".join(accept_chost), e), noiselevel=-1)
1744                                         self._accept_chost_re = re.compile("^$")
1745
1746                 pkg_chost = metadata.get('CHOST', '')
1747                 return not pkg_chost or \
1748                         self._accept_chost_re.match(pkg_chost) is not None
1749
1750         def setinst(self, mycpv, mydbapi):
1751                 """This updates the preferences for old-style virtuals,
1752                 affecting the behavior of dep_expand() and dep_check()
1753                 calls. It can change dbapi.match() behavior since that
1754                 calls dep_expand(). However, dbapi instances have
1755                 internal match caches that are not invalidated when
1756                 preferences are updated here. This can potentially
1757                 lead to some inconsistency (relevant to bug #1343)."""
1758                 self.modifying()
1759
1760                 # Grab the virtuals this package provides and add them into the tree virtuals.
1761                 if not hasattr(mydbapi, "aux_get"):
1762                         provides = mydbapi["PROVIDE"]
1763                 else:
1764                         provides = mydbapi.aux_get(mycpv, ["PROVIDE"])[0]
1765                 if not provides:
1766                         return
1767                 if isinstance(mydbapi, portdbapi):
1768                         self.setcpv(mycpv, mydb=mydbapi)
1769                         myuse = self["PORTAGE_USE"]
1770                 elif not hasattr(mydbapi, "aux_get"):
1771                         myuse = mydbapi["USE"]
1772                 else:
1773                         myuse = mydbapi.aux_get(mycpv, ["USE"])[0]
1774                 virts = use_reduce(provides, uselist=myuse.split(), flat=True)
1775
1776                 # Ensure that we don't trigger the _treeVirtuals
1777                 # assertion in VirtualsManager._compile_virtuals().
1778                 self.getvirtuals()
1779                 self._virtuals_manager.add_depgraph_virtuals(mycpv, virts)
1780
1781         def reload(self):
1782                 """Reload things like /etc/profile.env that can change during runtime."""
1783                 env_d_filename = os.path.join(self["EROOT"], "etc", "profile.env")
1784                 self.configdict["env.d"].clear()
1785                 env_d = getconfig(env_d_filename, expand=False)
1786                 if env_d:
1787                         # env_d will be None if profile.env doesn't exist.
1788                         for k in self._env_d_blacklist:
1789                                 env_d.pop(k, None)
1790                         self.configdict["env.d"].update(env_d)
1791
1792         def regenerate(self, useonly=0, use_cache=None):
1793                 """
1794                 Regenerate settings
1795                 This involves regenerating valid USE flags, re-expanding USE_EXPAND flags
1796                 re-stacking USE flags (-flag and -*), as well as any other INCREMENTAL
1797                 variables.  This also updates the env.d configdict; useful in case an ebuild
1798                 changes the environment.
1799
1800                 If FEATURES has already stacked, it is not stacked twice.
1801
1802                 @param useonly: Only regenerate USE flags (not any other incrementals)
1803                 @type useonly: Boolean
1804                 @rtype: None
1805                 """
1806
1807                 if use_cache is not None:
1808                         warnings.warn("The use_cache parameter for config.regenerate() is deprecated and without effect.",
1809                                 DeprecationWarning, stacklevel=2)
1810
1811                 self.modifying()
1812
1813                 if useonly:
1814                         myincrementals=["USE"]
1815                 else:
1816                         myincrementals = self.incrementals
1817                 myincrementals = set(myincrementals)
1818
1819                 # Process USE last because it depends on USE_EXPAND which is also
1820                 # an incremental!
1821                 myincrementals.discard("USE")
1822
1823                 mydbs = self.configlist[:-1]
1824                 mydbs.append(self.backupenv)
1825
1826                 # ACCEPT_LICENSE is a lazily evaluated incremental, so that * can be
1827                 # used to match all licenses without every having to explicitly expand
1828                 # it to all licenses.
1829                 if self.local_config:
1830                         mysplit = []
1831                         for curdb in mydbs:
1832                                 mysplit.extend(curdb.get('ACCEPT_LICENSE', '').split())
1833                         mysplit = prune_incremental(mysplit)
1834                         accept_license_str = ' '.join(mysplit)
1835                         self.configlist[-1]['ACCEPT_LICENSE'] = accept_license_str
1836                         self._license_manager.set_accept_license_str(accept_license_str)
1837                 else:
1838                         # repoman will accept any license
1839                         self._license_manager.set_accept_license_str("*")
1840
1841                 # ACCEPT_PROPERTIES works like ACCEPT_LICENSE, without groups
1842                 if self.local_config:
1843                         mysplit = []
1844                         for curdb in mydbs:
1845                                 mysplit.extend(curdb.get('ACCEPT_PROPERTIES', '').split())
1846                         mysplit = prune_incremental(mysplit)
1847                         self.configlist[-1]['ACCEPT_PROPERTIES'] = ' '.join(mysplit)
1848                         if tuple(mysplit) != self._accept_properties:
1849                                 self._accept_properties = tuple(mysplit)
1850                 else:
1851                         # repoman will accept any property
1852                         self._accept_properties = ('*',)
1853
1854                 increment_lists = {}
1855                 for k in myincrementals:
1856                         incremental_list = []
1857                         increment_lists[k] = incremental_list
1858                         for curdb in mydbs:
1859                                 v = curdb.get(k)
1860                                 if v is not None:
1861                                         incremental_list.append(v.split())
1862
1863                 if 'FEATURES' in increment_lists:
1864                         increment_lists['FEATURES'].append(self._features_overrides)
1865
1866                 myflags = set()
1867                 for mykey, incremental_list in increment_lists.items():
1868
1869                         myflags.clear()
1870                         for mysplit in incremental_list:
1871
1872                                 for x in mysplit:
1873                                         if x=="-*":
1874                                                 # "-*" is a special "minus" var that means "unset all settings".
1875                                                 # so USE="-* gnome" will have *just* gnome enabled.
1876                                                 myflags.clear()
1877                                                 continue
1878
1879                                         if x[0]=="+":
1880                                                 # Not legal. People assume too much. Complain.
1881                                                 writemsg(colorize("BAD",
1882                                                         _("%s values should not start with a '+': %s") % (mykey,x)) \
1883                                                         + "\n", noiselevel=-1)
1884                                                 x=x[1:]
1885                                                 if not x:
1886                                                         continue
1887
1888                                         if (x[0]=="-"):
1889                                                 myflags.discard(x[1:])
1890                                                 continue
1891
1892                                         # We got here, so add it now.
1893                                         myflags.add(x)
1894
1895                         #store setting in last element of configlist, the original environment:
1896                         if myflags or mykey in self:
1897                                 self.configlist[-1][mykey] = " ".join(sorted(myflags))
1898
1899                 # Do the USE calculation last because it depends on USE_EXPAND.
1900                 use_expand = self.get("USE_EXPAND", "").split()
1901                 use_expand_dict = self._use_expand_dict
1902                 use_expand_dict.clear()
1903                 for k in use_expand:
1904                         v = self.get(k)
1905                         if v is not None:
1906                                 use_expand_dict[k] = v
1907
1908                 # In order to best accomodate the long-standing practice of
1909                 # setting default USE_EXPAND variables in the profile's
1910                 # make.defaults, we translate these variables into their
1911                 # equivalent USE flags so that useful incremental behavior
1912                 # is enabled (for sub-profiles).
1913                 configdict_defaults = self.configdict['defaults']
1914                 if self._make_defaults is not None:
1915                         for i, cfg in enumerate(self._make_defaults):
1916                                 if not cfg:
1917                                         self.make_defaults_use.append("")
1918                                         continue
1919                                 use = cfg.get("USE", "")
1920                                 expand_use = []
1921                                 for k in use_expand_dict:
1922                                         v = cfg.get(k)
1923                                         if v is None:
1924                                                 continue
1925                                         prefix = k.lower() + '_'
1926                                         if k in myincrementals:
1927                                                 for x in v.split():
1928                                                         if x[:1] == '-':
1929                                                                 expand_use.append('-' + prefix + x[1:])
1930                                                         else:
1931                                                                 expand_use.append(prefix + x)
1932                                         else:
1933                                                 for x in v.split():
1934                                                         expand_use.append(prefix + x)
1935                                 if expand_use:
1936                                         expand_use.append(use)
1937                                         use  = ' '.join(expand_use)
1938                                 self.make_defaults_use.append(use)
1939                         self.make_defaults_use = tuple(self.make_defaults_use)
1940                         configdict_defaults['USE'] = ' '.join(
1941                                 stack_lists([x.split() for x in self.make_defaults_use]))
1942                         # Set to None so this code only runs once.
1943                         self._make_defaults = None
1944
1945                 if not self.uvlist:
1946                         for x in self["USE_ORDER"].split(":"):
1947                                 if x in self.configdict:
1948                                         self.uvlist.append(self.configdict[x])
1949                         self.uvlist.reverse()
1950
1951                 # For optimal performance, use slice
1952                 # comparison instead of startswith().
1953                 iuse = self.configdict["pkg"].get("IUSE")
1954                 if iuse is not None:
1955                         iuse = [x.lstrip("+-") for x in iuse.split()]
1956                 myflags = set()
1957                 for curdb in self.uvlist:
1958                         cur_use_expand = [x for x in use_expand if x in curdb]
1959                         mysplit = curdb.get("USE", "").split()
1960                         if not mysplit and not cur_use_expand:
1961                                 continue
1962                         for x in mysplit:
1963                                 if x == "-*":
1964                                         myflags.clear()
1965                                         continue
1966
1967                                 if x[0] == "+":
1968                                         writemsg(colorize("BAD", _("USE flags should not start "
1969                                                 "with a '+': %s\n") % x), noiselevel=-1)
1970                                         x = x[1:]
1971                                         if not x:
1972                                                 continue
1973
1974                                 if x[0] == "-":
1975                                         if x[-2:] == '_*':
1976                                                 prefix = x[1:-1]
1977                                                 prefix_len = len(prefix)
1978                                                 myflags.difference_update(
1979                                                         [y for y in myflags if \
1980                                                         y[:prefix_len] == prefix])
1981                                         myflags.discard(x[1:])
1982                                         continue
1983
1984                                 if iuse is not None and x[-2:] == '_*':
1985                                         # Expand wildcards here, so that cases like
1986                                         # USE="linguas_* -linguas_en_US" work correctly.
1987                                         prefix = x[:-1]
1988                                         prefix_len = len(prefix)
1989                                         has_iuse = False
1990                                         for y in iuse:
1991                                                 if y[:prefix_len] == prefix:
1992                                                         has_iuse = True
1993                                                         myflags.add(y)
1994                                         if not has_iuse:
1995                                                 # There are no matching IUSE, so allow the
1996                                                 # wildcard to pass through. This allows
1997                                                 # linguas_* to trigger unset LINGUAS in
1998                                                 # cases when no linguas_ flags are in IUSE.
1999                                                 myflags.add(x)
2000                                 else:
2001                                         myflags.add(x)
2002
2003                         if curdb is configdict_defaults:
2004                                 # USE_EXPAND flags from make.defaults are handled
2005                                 # earlier, in order to provide useful incremental
2006                                 # behavior (for sub-profiles).
2007                                 continue
2008
2009                         for var in cur_use_expand:
2010                                 var_lower = var.lower()
2011                                 is_not_incremental = var not in myincrementals
2012                                 if is_not_incremental:
2013                                         prefix = var_lower + "_"
2014                                         prefix_len = len(prefix)
2015                                         for x in list(myflags):
2016                                                 if x[:prefix_len] == prefix:
2017                                                         myflags.remove(x)
2018                                 for x in curdb[var].split():
2019                                         if x[0] == "+":
2020                                                 if is_not_incremental:
2021                                                         writemsg(colorize("BAD", _("Invalid '+' "
2022                                                                 "operator in non-incremental variable "
2023                                                                  "'%s': '%s'\n") % (var, x)), noiselevel=-1)
2024                                                         continue
2025                                                 else:
2026                                                         writemsg(colorize("BAD", _("Invalid '+' "
2027                                                                 "operator in incremental variable "
2028                                                                  "'%s': '%s'\n") % (var, x)), noiselevel=-1)
2029                                                 x = x[1:]
2030                                         if x[0] == "-":
2031                                                 if is_not_incremental:
2032                                                         writemsg(colorize("BAD", _("Invalid '-' "
2033                                                                 "operator in non-incremental variable "
2034                                                                  "'%s': '%s'\n") % (var, x)), noiselevel=-1)
2035                                                         continue
2036                                                 myflags.discard(var_lower + "_" + x[1:])
2037                                                 continue
2038                                         myflags.add(var_lower + "_" + x)
2039
2040                 if hasattr(self, "features"):
2041                         self.features._features.clear()
2042                 else:
2043                         self.features = features_set(self)
2044                 self.features._features.update(self.get('FEATURES', '').split())
2045                 self.features._sync_env_var()
2046                 self.features._validate()
2047
2048                 myflags.update(self.useforce)
2049                 arch = self.configdict["defaults"].get("ARCH")
2050                 if arch:
2051                         myflags.add(arch)
2052
2053                 myflags.difference_update(self.usemask)
2054                 self.configlist[-1]["USE"]= " ".join(sorted(myflags))
2055
2056                 if self.mycpv is None:
2057                         # Generate global USE_EXPAND variables settings that are
2058                         # consistent with USE, for display by emerge --info. For
2059                         # package instances, these are instead generated via
2060                         # setcpv().
2061                         for k in use_expand:
2062                                 prefix = k.lower() + '_'
2063                                 prefix_len = len(prefix)
2064                                 expand_flags = set( x[prefix_len:] for x in myflags \
2065                                         if x[:prefix_len] == prefix )
2066                                 var_split = use_expand_dict.get(k, '').split()
2067                                 var_split = [ x for x in var_split if x in expand_flags ]
2068                                 var_split.extend(sorted(expand_flags.difference(var_split)))
2069                                 if var_split:
2070                                         self.configlist[-1][k] = ' '.join(var_split)
2071                                 elif k in self:
2072                                         self.configlist[-1][k] = ''
2073
2074         @property
2075         def virts_p(self):
2076                 warnings.warn("portage config.virts_p attribute " + \
2077                         "is deprecated, use config.get_virts_p()",
2078                         DeprecationWarning, stacklevel=2)
2079                 return self.get_virts_p()
2080
2081         @property
2082         def virtuals(self):
2083                 warnings.warn("portage config.virtuals attribute " + \
2084                         "is deprecated, use config.getvirtuals()",
2085                         DeprecationWarning, stacklevel=2)
2086                 return self.getvirtuals()
2087
2088         def get_virts_p(self):
2089                 # Ensure that we don't trigger the _treeVirtuals
2090                 # assertion in VirtualsManager._compile_virtuals().
2091                 self.getvirtuals()
2092                 return self._virtuals_manager.get_virts_p()
2093
2094         def getvirtuals(self):
2095                 if self._virtuals_manager._treeVirtuals is None:
2096                         #Hack around the fact that VirtualsManager needs a vartree
2097                         #and vartree needs a config instance.
2098                         #This code should be part of VirtualsManager.getvirtuals().
2099                         if self.local_config:
2100                                 temp_vartree = vartree(settings=self)
2101                                 self._virtuals_manager._populate_treeVirtuals(temp_vartree)
2102                         else:
2103                                 self._virtuals_manager._treeVirtuals = {}
2104
2105                 return self._virtuals_manager.getvirtuals()
2106
2107         def _populate_treeVirtuals_if_needed(self, vartree):
2108                 """Reduce the provides into a list by CP."""
2109                 if self._virtuals_manager._treeVirtuals is None:
2110                         if self.local_config:
2111                                 self._virtuals_manager._populate_treeVirtuals(vartree)
2112                         else:
2113                                 self._virtuals_manager._treeVirtuals = {}
2114
2115         def __delitem__(self,mykey):
2116                 self.pop(mykey)
2117
2118         def __getitem__(self, key):
2119                 try:
2120                         return self._getitem(key)
2121                 except KeyError:
2122                         return '' # for backward compat, don't raise KeyError
2123
2124         def _getitem(self, mykey):
2125
2126                 # These ones point to temporary values when
2127                 # portage plans to update itself.
2128                 if mykey == "PORTAGE_BIN_PATH":
2129                         return portage._bin_path
2130                 elif mykey == "PORTAGE_PYM_PATH":
2131                         return portage._pym_path
2132                 elif mykey == "PORTAGE_GID":
2133                         return _unicode_decode(str(portage_gid))
2134
2135                 for d in self.lookuplist:
2136                         try:
2137                                 return d[mykey]
2138                         except KeyError:
2139                                 pass
2140
2141                 raise KeyError(mykey)
2142
2143         def get(self, k, x=None):
2144                 try:
2145                         return self._getitem(k)
2146                 except KeyError:
2147                         return x
2148
2149         def pop(self, key, *args):
2150                 self.modifying()
2151                 if len(args) > 1:
2152                         raise TypeError(
2153                                 "pop expected at most 2 arguments, got " + \
2154                                 repr(1 + len(args)))
2155                 v = self
2156                 for d in reversed(self.lookuplist):
2157                         v = d.pop(key, v)
2158                 if v is self:
2159                         if args:
2160                                 return args[0]
2161                         raise KeyError(key)
2162                 return v
2163
2164         def __contains__(self, mykey):
2165                 """Called to implement membership test operators (in and not in)."""
2166                 try:
2167                          self._getitem(mykey)
2168                 except KeyError:
2169                         return False
2170                 else:
2171                         return True
2172
2173         def setdefault(self, k, x=None):
2174                 v = self.get(k)
2175                 if v is not None:
2176                         return v
2177                 else:
2178                         self[k] = x
2179                         return x
2180
2181         def keys(self):
2182                 return list(self)
2183
2184         def __iter__(self):
2185                 keys = set()
2186                 keys.add("PORTAGE_BIN_PATH")
2187                 keys.add("PORTAGE_PYM_PATH")
2188                 keys.add("PORTAGE_GID")
2189                 for d in self.lookuplist:
2190                         keys.update(d)
2191                 return iter(keys)
2192
2193         def iterkeys(self):
2194                 return iter(self)
2195
2196         def iteritems(self):
2197                 for k in self:
2198                         yield (k, self._getitem(k))
2199
2200         def items(self):
2201                 return list(self.iteritems())
2202
2203         def __setitem__(self,mykey,myvalue):
2204                 "set a value; will be thrown away at reset() time"
2205                 if not isinstance(myvalue, basestring):
2206                         raise ValueError("Invalid type being used as a value: '%s': '%s'" % (str(mykey),str(myvalue)))
2207
2208                 # Avoid potential UnicodeDecodeError exceptions later.
2209                 mykey = _unicode_decode(mykey)
2210                 myvalue = _unicode_decode(myvalue)
2211
2212                 self.modifying()
2213                 self.modifiedkeys.append(mykey)
2214                 self.configdict["env"][mykey]=myvalue
2215
2216         def environ(self):
2217                 "return our locally-maintained environment"
2218                 mydict={}
2219                 environ_filter = self._environ_filter
2220
2221                 eapi = self.get('EAPI')
2222                 phase = self.get('EBUILD_PHASE')
2223                 filter_calling_env = False
2224                 if self.mycpv is not None and \
2225                         phase not in ('clean', 'cleanrm', 'depend', 'fetch'):
2226                         temp_dir = self.get('T')
2227                         if temp_dir is not None and \
2228                                 os.path.exists(os.path.join(temp_dir, 'environment')):
2229                                 filter_calling_env = True
2230
2231                 environ_whitelist = self._environ_whitelist
2232                 for x in self:
2233                         if x in environ_filter:
2234                                 continue
2235                         myvalue = self[x]
2236                         if not isinstance(myvalue, basestring):
2237                                 writemsg(_("!!! Non-string value in config: %s=%s\n") % \
2238                                         (x, myvalue), noiselevel=-1)
2239                                 continue
2240                         if filter_calling_env and \
2241                                 x not in environ_whitelist and \
2242                                 not self._environ_whitelist_re.match(x):
2243                                 # Do not allow anything to leak into the ebuild
2244                                 # environment unless it is explicitly whitelisted.
2245                                 # This ensures that variables unset by the ebuild
2246                                 # remain unset (bug #189417).
2247                                 continue
2248                         mydict[x] = myvalue
2249                 if "HOME" not in mydict and "BUILD_PREFIX" in mydict:
2250                         writemsg("*** HOME not set. Setting to "+mydict["BUILD_PREFIX"]+"\n")
2251                         mydict["HOME"]=mydict["BUILD_PREFIX"][:]
2252
2253                 if filter_calling_env:
2254                         if phase:
2255                                 whitelist = []
2256                                 if "rpm" == phase:
2257                                         whitelist.append("RPMDIR")
2258                                 for k in whitelist:
2259                                         v = self.get(k)
2260                                         if v is not None:
2261                                                 mydict[k] = v
2262
2263                 # At some point we may want to stop exporting FEATURES to the ebuild
2264                 # environment, in order to prevent ebuilds from abusing it. In
2265                 # preparation for that, export it as PORTAGE_FEATURES so that bashrc
2266                 # users will be able to migrate any FEATURES conditional code to
2267                 # use this alternative variable.
2268                 mydict["PORTAGE_FEATURES"] = self["FEATURES"]
2269
2270                 # Filtered by IUSE and implicit IUSE.
2271                 mydict["USE"] = self.get("PORTAGE_USE", "")
2272
2273                 # Don't export AA to the ebuild environment in EAPIs that forbid it
2274                 if not eapi_exports_AA(eapi):
2275                         mydict.pop("AA", None)
2276
2277                 if not eapi_exports_merge_type(eapi):
2278                         mydict.pop("MERGE_TYPE", None)
2279
2280                 # Prefix variables are supported beginning with EAPI 3, or when
2281                 # force-prefix is in FEATURES, since older EAPIs would otherwise be
2282                 # useless with prefix configurations. This brings compatibility with
2283                 # the prefix branch of portage, which also supports EPREFIX for all
2284                 # EAPIs (for obvious reasons).
2285                 if phase == 'depend' or eapi is None or \
2286                         ('force-prefix' not in self.features and
2287                         not eapi_supports_prefix(eapi)):
2288                         mydict.pop("ED", None)
2289                         mydict.pop("EPREFIX", None)
2290                         mydict.pop("EROOT", None)
2291
2292                 if phase == 'depend':
2293                         mydict.pop('FILESDIR', None)
2294
2295                 if phase not in ("pretend", "setup", "preinst", "postinst") or \
2296                         not eapi_exports_replace_vars(eapi):
2297                         mydict.pop("REPLACING_VERSIONS", None)
2298
2299                 if phase not in ("prerm", "postrm") or \
2300                         not eapi_exports_replace_vars(eapi):
2301                         mydict.pop("REPLACED_BY_VERSION", None)
2302
2303                 return mydict
2304
2305         def thirdpartymirrors(self):
2306                 if getattr(self, "_thirdpartymirrors", None) is None:
2307                         profileroots = [os.path.join(self["PORTDIR"], "profiles")]
2308                         for x in shlex_split(self.get("PORTDIR_OVERLAY", "")):
2309                                 profileroots.insert(0, os.path.join(x, "profiles"))
2310                         thirdparty_lists = [grabdict(os.path.join(x, "thirdpartymirrors")) for x in profileroots]
2311                         self._thirdpartymirrors = stack_dictlist(thirdparty_lists, incremental=True)
2312                 return self._thirdpartymirrors
2313
2314         def archlist(self):
2315                 _archlist = []
2316                 for myarch in self["PORTAGE_ARCHLIST"].split():
2317                         _archlist.append(myarch)
2318                         _archlist.append("~" + myarch)
2319                 return _archlist
2320
2321         def selinux_enabled(self):
2322                 if getattr(self, "_selinux_enabled", None) is None:
2323                         self._selinux_enabled = 0
2324                         if "selinux" in self["USE"].split():
2325                                 if selinux:
2326                                         if selinux.is_selinux_enabled() == 1:
2327                                                 self._selinux_enabled = 1
2328                                         else:
2329                                                 self._selinux_enabled = 0
2330                                 else:
2331                                         writemsg(_("!!! SELinux module not found. Please verify that it was installed.\n"),
2332                                                 noiselevel=-1)
2333                                         self._selinux_enabled = 0
2334
2335                 return self._selinux_enabled
2336
2337         if sys.hexversion >= 0x3000000:
2338                 keys = __iter__
2339                 items = iteritems