diff options
Diffstat (limited to 'lib/portage/__init__.py')
-rw-r--r-- | lib/portage/__init__.py | 156 |
1 files changed, 76 insertions, 80 deletions
diff --git a/lib/portage/__init__.py b/lib/portage/__init__.py index 13af8da09..aa81bdb4c 100644 --- a/lib/portage/__init__.py +++ b/lib/portage/__init__.py @@ -1,13 +1,13 @@ -# Copyright 1998-2021 Gentoo Authors +# Copyright 1998-2023 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 # pylint: disable=ungrouped-imports -VERSION = "HEAD" - # =========================================================================== # START OF IMPORTS -- START OF IMPORTS -- START OF IMPORTS -- START OF IMPORT # =========================================================================== +from portage import installation + try: import asyncio import sys @@ -16,7 +16,7 @@ try: if not hasattr(errno, "ESTALE"): # ESTALE may not be defined on some systems, such as interix. errno.ESTALE = -1 - import multiprocessing.util + import functools import re import types import platform @@ -48,11 +48,10 @@ except ImportError as e: sys.stderr.write( "!!! gone wrong. Here is the information we got for this exception:\n" ) - sys.stderr.write(" " + str(e) + "\n\n") + sys.stderr.write(f" {e}\n\n") raise try: - import portage.proxy.lazyimport import portage.proxy as proxy @@ -93,7 +92,7 @@ try: + "doebuild_environment,spawn,spawnebuild", "portage.package.ebuild.config:autouse,best_from_dict," + "check_config_instance,config", - "portage.package.ebuild.deprecated_profile_check:" + "deprecated_profile_check", + "portage.package.ebuild.deprecated_profile_check:deprecated_profile_check", "portage.package.ebuild.digestcheck:digestcheck", "portage.package.ebuild.digestgen:digestgen", "portage.package.ebuild.fetch:fetch", @@ -124,6 +123,7 @@ try: + "cpv_getkey@getCPFromCPV,endversion_keys," + "suffix_value@endversion,pkgcmp,pkgsplit,vercmp,ververify", "portage.xpak", + "portage.gpkg", "subprocess", "time", ) @@ -183,9 +183,10 @@ except ImportError as e: "!!! There is a README.RESCUE file that details the steps required to perform\n" ) sys.stderr.write("!!! a recovery of portage.\n") - sys.stderr.write(" " + str(e) + "\n\n") + sys.stderr.write(f" {e}\n\n") raise +utf8_mode = sys.getfilesystemencoding() == "utf-8" # We use utf_8 encoding everywhere. Previously, we used # sys.getfilesystemencoding() for the 'merge' encoding, but that had @@ -259,23 +260,21 @@ class _unicode_func_wrapper: self._encoding = encoding def _process_args(self, args, kwargs): - encoding = self._encoding wrapped_args = [ _unicode_encode(x, encoding=encoding, errors="strict") for x in args ] if kwargs: - wrapped_kwargs = dict( - (k, _unicode_encode(v, encoding=encoding, errors="strict")) + wrapped_kwargs = { + k: _unicode_encode(v, encoding=encoding, errors="strict") for k, v in kwargs.items() - ) + } else: wrapped_kwargs = {} return (wrapped_args, wrapped_kwargs) def __call__(self, *args, **kwargs): - encoding = self._encoding wrapped_args, wrapped_kwargs = self._process_args(args, kwargs) @@ -321,6 +320,9 @@ class _unicode_module_wrapper: object.__setattr__(self, "_cache", cache) def __getattribute__(self, attr): + if utf8_mode: + return getattr(object.__getattribute__(self, "_mod"), attr) + cache = object.__getattribute__(self, "_cache") if cache is not None: result = cache.get(attr) @@ -347,30 +349,6 @@ class _unicode_module_wrapper: return result -class _eintr_func_wrapper: - """ - Wraps a function and handles EINTR by calling the function as - many times as necessary (until it returns without raising EINTR). - """ - - __slots__ = ("_func",) - - def __init__(self, func): - self._func = func - - def __call__(self, *args, **kwargs): - - while True: - try: - rval = self._func(*args, **kwargs) - break - except EnvironmentError as e: - if e.errno != errno.EINTR: - raise - - return rval - - import os as _os _os_overrides = { @@ -378,14 +356,11 @@ _os_overrides = { id(_os.popen): _os.popen, id(_os.read): _os.read, id(_os.system): _os.system, - id(_os.waitpid): _eintr_func_wrapper(_os.waitpid), + id(_os.waitpid): _os.waitpid, } -try: - _os_overrides[id(_os.mkfifo)] = _os.mkfifo -except AttributeError: - pass # Jython +_os_overrides[id(_os.mkfifo)] = _os.mkfifo if hasattr(_os, "statvfs"): _os_overrides[id(_os.statvfs)] = _os.statvfs @@ -408,7 +383,7 @@ try: _selinux_merge = _unicode_module_wrapper(_selinux, encoding=_encodings["merge"]) except (ImportError, OSError) as e: if isinstance(e, OSError): - sys.stderr.write("!!! SELinux not loaded: %s\n" % str(e)) + sys.stderr.write(f"!!! SELinux not loaded: {e}\n") del e _selinux = None selinux = None @@ -446,7 +421,7 @@ class _ForkWatcher: _ForkWatcher.hook(_ForkWatcher) -multiprocessing.util.register_after_fork(_ForkWatcher, _ForkWatcher.hook) +os.register_at_fork(after_in_child=functools.partial(_ForkWatcher.hook, _ForkWatcher)) def getpid(): @@ -481,10 +456,10 @@ def _shell_quote(s): """ if _shell_quote_re.search(s) is None: return s - for letter in '\\"$`': + for letter in r"\"$`": if letter in s: - s = s.replace(letter, "\\" + letter) - return '"%s"' % s + s = s.replace(letter, rf"\{letter}") + return f'"{s}"' bsd_chflags = None @@ -497,9 +472,9 @@ if platform.system() in ("FreeBSD",): def load_mod(name): - modname = ".".join(name.split(".")[:-1]) - mod = __import__(modname) components = name.split(".") + modname = ".".join(components[:-1]) + mod = __import__(modname) for comp in components[1:]: mod = getattr(mod, comp) return mod @@ -533,7 +508,7 @@ def abssymlink(symlink, target=None): mylink = os.readlink(symlink) if mylink[0] != "/": mydir = os.path.dirname(symlink) - mylink = mydir + "/" + mylink + mylink = f"{mydir}/{mylink}" return os.path.normpath(mylink) @@ -545,19 +520,22 @@ _deprecated_eapis = frozenset( "3_pre1", "3_pre2", "4_pre1", - "4-python", "4-slot-abi", "5_pre1", "5_pre2", - "5-progress", "6_pre1", "7_pre1", ] ) + +from itertools import chain + _supported_eapis = frozenset( - [str(x) for x in range(portage.const.EAPI + 1)] - + list(_testing_eapis) - + list(_deprecated_eapis) + chain( + (str(x) for x in range(portage.const.EAPI + 1)), + _testing_eapis, + _deprecated_eapis, + ) ) @@ -567,7 +545,6 @@ def _eapi_is_deprecated(eapi): def eapi_is_supported(eapi): eapi = str(eapi).strip() - return eapi in _supported_eapis @@ -596,7 +573,7 @@ def _parse_eapi_ebuild_head(f): def _movefile(src, dest, **kwargs): """Calls movefile and raises a PortageException if an error occurs.""" if movefile(src, dest, **kwargs) is None: - raise portage.exception.PortageException("mv '%s' '%s'" % (src, dest)) + raise portage.exception.PortageException(f"mv '{src}' '{dest}'") auxdbkeys = ( @@ -641,6 +618,15 @@ class _trees_dict(dict): def create_trees( config_root=None, target_root=None, trees=None, env=None, sysroot=None, eprefix=None ): + if utf8_mode: + config_root = ( + os.fsdecode(config_root) if isinstance(config_root, bytes) else config_root + ) + target_root = ( + os.fsdecode(target_root) if isinstance(target_root, bytes) else target_root + ) + sysroot = os.fsdecode(sysroot) if isinstance(sysroot, bytes) else sysroot + eprefix = os.fsdecode(eprefix) if isinstance(eprefix, bytes) else eprefix if trees is None: trees = _trees_dict() @@ -667,12 +653,10 @@ def create_trees( if settings["ROOT"] == "/" and settings["EPREFIX"] == const.EPREFIX: trees._running_eroot = trees._target_eroot else: - # When ROOT != "/" we only want overrides from the calling # environment to apply to the config that's associated # with ROOT != "/", so pass a nearly empty dict for the env parameter. - clean_env = {} - for k in ( + env_sequence = ( "PATH", "PORTAGE_GRPNAME", "PORTAGE_REPOSITORIES", @@ -686,18 +670,29 @@ def create_trees( "https_proxy", "no_proxy", "__PORTAGE_TEST_HARDLINK_LOCKS", - ): - v = settings.get(k) - if v is not None: - clean_env[k] = v + ) + env = ((k, settings.get(k)) for k in env_sequence) + clean_env = {k: v for k, v in env if v is not None} + if depcachedir is not None: clean_env["PORTAGE_DEPCACHEDIR"] = depcachedir - settings = config( + mysettings = config( config_root=None, target_root="/", env=clean_env, sysroot="/", eprefix=None ) - settings.lock() - trees._running_eroot = settings["EROOT"] - myroots.append((settings["EROOT"], settings)) + mysettings.lock() + trees._running_eroot = mysettings["EROOT"] + myroots.append((mysettings["EROOT"], mysettings)) + + if settings["SYSROOT"] != "/" and settings["SYSROOT"] != settings["ROOT"]: + mysettings = config( + config_root=settings["SYSROOT"], + target_root=settings["SYSROOT"], + env=clean_env, + sysroot=settings["SYSROOT"], + eprefix="", + ) + mysettings.lock() + myroots.append((mysettings["EROOT"], mysettings)) for myroot, mysettings in myroots: trees[myroot] = portage.util.LazyItemsDict(trees.get(myroot, {})) @@ -712,7 +707,7 @@ def create_trees( return trees -if VERSION == "HEAD": +if installation.TYPE == installation.TYPES.SOURCE: class _LazyVersion(proxy.objectproxy.ObjectProxy): def _get_target(self): @@ -725,12 +720,11 @@ if VERSION == "HEAD": BASH_BINARY, "-c", ( - "cd %s ; git describe --match 'portage-*' || exit $? ; " - + 'if [ -n "`git diff-index --name-only --diff-filter=M HEAD`" ] ; ' - + "then echo modified ; git rev-list --format=%%ct -n 1 HEAD ; fi ; " - + "exit 0" - ) - % _shell_quote(PORTAGE_BASE_PATH), + f"cd {_shell_quote(PORTAGE_BASE_PATH)} ; git describe --match 'portage-*' || exit $? ; " + 'if [ -n "`git diff-index --name-only --diff-filter=M HEAD`" ] ; ' + "then echo modified ; git rev-list --format=%%ct -n 1 HEAD ; fi ; " + "exit 0" + ), ] cmd = [ _unicode_encode(x, encoding=encoding, errors="strict") for x in cmd @@ -749,7 +743,7 @@ if VERSION == "HEAD": patchlevel = False if len(version_split) > 2: patchlevel = True - VERSION = "%s_p%s" % (VERSION, version_split[2]) + VERSION = f"{VERSION}_p{version_split[2]}" if len(output_lines) > 1 and output_lines[1] == "modified": head_timestamp = None if len(output_lines) > 3: @@ -764,14 +758,17 @@ if VERSION == "HEAD": ): timestamp = timestamp - head_timestamp if not patchlevel: - VERSION = "%s_p0" % (VERSION,) - VERSION = "%s_p%d" % (VERSION, timestamp) + VERSION = f"{VERSION}_p0" + VERSION = f"{VERSION}_p{timestamp}" return VERSION VERSION = "HEAD" return VERSION VERSION = _LazyVersion() +else: + VERSION = "@VERSION@" + _legacy_global_var_names = ( "archlist", "db", @@ -790,7 +787,6 @@ _legacy_global_var_names = ( def _reset_legacy_globals(): - global _legacy_globals_constructed _legacy_globals_constructed = set() for k in _legacy_global_var_names: @@ -798,7 +794,6 @@ def _reset_legacy_globals(): class _LegacyGlobalProxy(proxy.objectproxy.ObjectProxy): - __slots__ = ("_name",) def __init__(self, name): @@ -825,3 +820,4 @@ def _disable_legacy_globals(): global _legacy_global_var_names for k in _legacy_global_var_names: globals().pop(k, None) + portage.data._initialized_globals.clear() |