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