aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'portage_with_autodep/pym/portage/__init__.py')
-rw-r--r--portage_with_autodep/pym/portage/__init__.py208
1 files changed, 127 insertions, 81 deletions
diff --git a/portage_with_autodep/pym/portage/__init__.py b/portage_with_autodep/pym/portage/__init__.py
index 431dc26..2bce5d7 100644
--- a/portage_with_autodep/pym/portage/__init__.py
+++ b/portage_with_autodep/pym/portage/__init__.py
@@ -1,8 +1,10 @@
# portage.py -- core Portage functionality
-# Copyright 1998-2011 Gentoo Foundation
+# Copyright 1998-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-VERSION="2.2.0_alpha108"
+from __future__ import unicode_literals
+
+VERSION="2.2.8-r1"
# ===========================================================================
# START OF IMPORTS -- START OF IMPORTS -- START OF IMPORTS -- START OF IMPORT
@@ -16,14 +18,6 @@ try:
errno.ESTALE = -1
import re
import types
-
- # Try the commands module first, since this allows us to eliminate
- # the subprocess module from the baseline imports under python2.
- try:
- from commands import getstatusoutput as subprocess_getstatusoutput
- except ImportError:
- from subprocess import getstatusoutput as subprocess_getstatusoutput
-
import platform
# Temporarily delete these imports, to ensure that only the
@@ -70,6 +64,7 @@ try:
'match_from_list,match_to_list',
'portage.dep.dep_check:dep_check,dep_eval,dep_wordreduce,dep_zapdeps',
'portage.eclass_cache',
+ 'portage.elog',
'portage.exception',
'portage.getbinpkg',
'portage.locks',
@@ -114,6 +109,7 @@ try:
'cpv_getkey@getCPFromCPV,endversion_keys,' + \
'suffix_value@endversion,pkgcmp,pkgsplit,vercmp,ververify',
'portage.xpak',
+ 'subprocess',
'time',
)
@@ -178,6 +174,15 @@ _encodings = {
}
if sys.hexversion >= 0x3000000:
+
+ def _decode_argv(argv):
+ # With Python 3, the surrogateescape encoding error handler makes it
+ # possible to access the original argv bytes, which can be useful
+ # if their actual encoding does no match the filesystem encoding.
+ fs_encoding = sys.getfilesystemencoding()
+ return [_unicode_decode(x.encode(fs_encoding, 'surrogateescape'))
+ for x in argv]
+
def _unicode_encode(s, encoding=_encodings['content'], errors='backslashreplace'):
if isinstance(s, str):
s = s.encode(encoding, errors)
@@ -187,7 +192,13 @@ if sys.hexversion >= 0x3000000:
if isinstance(s, bytes):
s = str(s, encoding=encoding, errors=errors)
return s
+
+ _native_string = _unicode_decode
else:
+
+ def _decode_argv(argv):
+ return [_unicode_decode(x) for x in argv]
+
def _unicode_encode(s, encoding=_encodings['content'], errors='backslashreplace'):
if isinstance(s, unicode):
s = s.encode(encoding, errors)
@@ -198,6 +209,17 @@ else:
s = unicode(s, encoding=encoding, errors=errors)
return s
+ _native_string = _unicode_encode
+
+if sys.hexversion >= 0x20605f0:
+ def _native_kwargs(kwargs):
+ return kwargs
+else:
+ # Avoid "TypeError: keywords must be strings" issue triggered
+ # by unicode_literals: http://bugs.python.org/issue4978
+ def _native_kwargs(kwargs):
+ return dict((_native_string(k), v) for k, v in kwargs.iteritems())
+
class _unicode_func_wrapper(object):
"""
Wraps a function, converts arguments from unicode to bytes,
@@ -215,7 +237,7 @@ class _unicode_func_wrapper(object):
self._func = func
self._encoding = encoding
- def __call__(self, *args, **kwargs):
+ def _process_args(self, args, kwargs):
encoding = self._encoding
wrapped_args = [_unicode_encode(x, encoding=encoding, errors='strict')
@@ -227,6 +249,13 @@ class _unicode_func_wrapper(object):
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)
+
rval = self._func(*wrapped_args, **wrapped_kwargs)
# Don't use isinstance() since we don't want to convert subclasses
@@ -294,12 +323,17 @@ class _unicode_module_wrapper(object):
import os as _os
_os_overrides = {
id(_os.fdopen) : _os.fdopen,
- id(_os.mkfifo) : _os.mkfifo,
id(_os.popen) : _os.popen,
id(_os.read) : _os.read,
id(_os.system) : _os.system,
}
+
+try:
+ _os_overrides[id(_os.mkfifo)] = _os.mkfifo
+except AttributeError:
+ pass # Jython
+
if hasattr(_os, 'statvfs'):
_os_overrides[id(_os.statvfs)] = _os.statvfs
@@ -334,16 +368,25 @@ except (ImportError, OSError) as e:
_python_interpreter = os.path.realpath(sys.executable)
_bin_path = PORTAGE_BIN_PATH
_pym_path = PORTAGE_PYM_PATH
+_working_copy = VERSION == "HEAD"
+
+# Api consumers included in portage should set this to True.
+_internal_caller = False
-if sys.hexversion >= 0x3030000:
- # Workaround for http://bugs.python.org/issue14007
- def _test_xml_etree_ElementTree_TreeBuilder_type():
- import subprocess
- p = subprocess.Popen([_python_interpreter, "-c",
- "import sys, xml.etree.ElementTree; sys.exit(not isinstance(xml.etree.ElementTree.TreeBuilder, type))"])
- if p.wait() != 0:
- sys.modules["_elementtree"] = None
- _test_xml_etree_ElementTree_TreeBuilder_type()
+_sync_disabled_warnings = False
+
+def _get_stdin():
+ """
+ Buggy code in python's multiprocessing/process.py closes sys.stdin
+ and reassigns it to open(os.devnull), but fails to update the
+ corresponding __stdin__ reference. So, detect that case and handle
+ it appropriately.
+ """
+ if not sys.__stdin__.closed:
+ return sys.__stdin__
+ return sys.stdin
+
+_shell_quote_re = re.compile(r"[\s><=*\\\"'$`]")
def _shell_quote(s):
"""
@@ -351,6 +394,8 @@ def _shell_quote(s):
escape any backslashes, double-quotes, dollar signs, or
backquotes in the string.
"""
+ if _shell_quote_re.search(s) is None:
+ return s
for letter in "\\\"$`":
if letter in s:
s = s.replace(letter, "\\" + letter)
@@ -364,8 +409,27 @@ if platform.system() in ('FreeBSD',):
@classmethod
def chflags(cls, path, flags, opts=""):
- cmd = 'chflags %s %o %s' % (opts, flags, _shell_quote(path))
- status, output = subprocess_getstatusoutput(cmd)
+ cmd = ['chflags']
+ if opts:
+ cmd.append(opts)
+ cmd.append('%o' % (flags,))
+ cmd.append(path)
+
+ if sys.hexversion < 0x3020000 and sys.hexversion >= 0x3000000:
+ # Python 3.1 _execvp throws TypeError for non-absolute executable
+ # path passed as bytes (see http://bugs.python.org/issue8513).
+ fullname = process.find_binary(cmd[0])
+ if fullname is None:
+ raise exception.CommandNotFound(cmd[0])
+ cmd[0] = fullname
+
+ encoding = _encodings['fs']
+ cmd = [_unicode_encode(x, encoding=encoding, errors='strict')
+ for x in cmd]
+ proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+ output = proc.communicate()[0]
+ status = proc.wait()
if os.WIFEXITED(status) and os.WEXITSTATUS(status) == os.EX_OK:
return
# Try to generate an ENOENT error if appropriate.
@@ -378,6 +442,7 @@ if platform.system() in ('FreeBSD',):
raise portage.exception.CommandNotFound('chflags')
# Now we're not sure exactly why it failed or what
# the real errno was, so just report EPERM.
+ output = _unicode_decode(output, encoding=encoding)
e = OSError(errno.EPERM, output)
e.errno = errno.EPERM
e.filename = path
@@ -406,7 +471,15 @@ def getcwd():
getcwd()
def abssymlink(symlink, target=None):
- "This reads symlinks, resolving the relative symlinks, and returning the absolute."
+ """
+ This reads symlinks, resolving the relative symlinks,
+ and returning the absolute.
+ @param symlink: path of symlink (must be absolute)
+ @param target: the target of the symlink (as returned
+ by readlink)
+ @rtype: str
+ @return: the absolute path of the symlink target
+ """
if target is not None:
mylink = target
else:
@@ -418,8 +491,9 @@ def abssymlink(symlink, target=None):
_doebuild_manifest_exempt_depend = 0
-_testing_eapis = frozenset(["4-python"])
-_deprecated_eapis = frozenset(["4_pre1", "3_pre2", "3_pre1"])
+_testing_eapis = frozenset(["4-python", "4-slot-abi", "5-progress", "5-hdepend"])
+_deprecated_eapis = frozenset(["4_pre1", "3_pre2", "3_pre1", "5_pre1", "5_pre2"])
+_supported_eapis = frozenset([str(x) for x in range(portage.const.EAPI)] + list(_testing_eapis) + list(_deprecated_eapis))
def _eapi_is_deprecated(eapi):
return eapi in _deprecated_eapis
@@ -476,14 +550,13 @@ auxdbkeys = (
'RESTRICT', 'HOMEPAGE', 'LICENSE', 'DESCRIPTION',
'KEYWORDS', 'INHERITED', 'IUSE', 'REQUIRED_USE',
'PDEPEND', 'PROVIDE', 'EAPI',
- 'PROPERTIES', 'DEFINED_PHASES', 'UNUSED_05', 'UNUSED_04',
+ 'PROPERTIES', 'DEFINED_PHASES', 'HDEPEND', 'UNUSED_04',
'UNUSED_03', 'UNUSED_02', 'UNUSED_01',
)
auxdbkeylen=len(auxdbkeys)
def portageexit():
- if data.secpass > 1 and os.environ.get("SANDBOX_ON") != "1":
- close_portdbapi_caches()
+ pass
class _trees_dict(dict):
__slots__ = ('_running_eroot', '_target_eroot',)
@@ -494,13 +567,6 @@ class _trees_dict(dict):
def create_trees(config_root=None, target_root=None, trees=None, env=None,
eprefix=None):
- if trees is not None:
- # clean up any existing portdbapi instances
- for myroot in trees:
- portdb = trees[myroot]["porttree"].dbapi
- portdb.close_caches()
- portdbapi.portdbapi_instances.remove(portdb)
- del trees[myroot]["porttree"], myroot, portdb
if trees is None:
trees = _trees_dict()
@@ -518,7 +584,7 @@ def create_trees(config_root=None, target_root=None, trees=None, env=None,
trees._target_eroot = settings['EROOT']
myroots = [(settings['EROOT'], settings)]
- if settings["ROOT"] == "/":
+ if settings["ROOT"] == "/" and settings["EPREFIX"] == const.EPREFIX:
trees._running_eroot = trees._target_eroot
else:
@@ -526,15 +592,15 @@ def create_trees(config_root=None, target_root=None, trees=None, env=None,
# 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 ('PATH', 'PORTAGE_GRPNAME', 'PORTAGE_USERNAME',
- 'SSH_AGENT_PID', 'SSH_AUTH_SOCK', 'TERM',
+ for k in ('PATH', 'PORTAGE_GRPNAME', 'PORTAGE_REPOSITORIES', 'PORTAGE_USERNAME',
+ 'PYTHONPATH', 'SSH_AGENT_PID', 'SSH_AUTH_SOCK', 'TERM',
'ftp_proxy', 'http_proxy', 'no_proxy',
'__PORTAGE_TEST_HARDLINK_LOCKS'):
v = settings.get(k)
if v is not None:
clean_env[k] = v
settings = config(config_root=None, target_root="/",
- env=clean_env, eprefix=eprefix)
+ env=clean_env, eprefix=None)
settings.lock()
trees._running_eroot = settings['EROOT']
myroots.append((settings['EROOT'], settings))
@@ -558,11 +624,17 @@ if VERSION == 'HEAD':
if VERSION is not self:
return VERSION
if os.path.isdir(os.path.join(PORTAGE_BASE_PATH, '.git')):
- status, output = subprocess_getstatusoutput((
- "cd %s ; git describe --tags || exit $? ; " + \
+ encoding = _encodings['fs']
+ cmd = [BASH_BINARY, "-c", ("cd %s ; git describe --tags || 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))
+ "exit 0") % _shell_quote(PORTAGE_BASE_PATH)]
+ cmd = [_unicode_encode(x, encoding=encoding, errors='strict')
+ for x in cmd]
+ proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+ output = _unicode_decode(proc.communicate()[0], encoding=encoding)
+ status = proc.wait()
if os.WIFEXITED(status) and os.WEXITSTATUS(status) == os.EX_OK:
output_lines = output.splitlines()
if output_lines:
@@ -591,34 +663,17 @@ if VERSION == 'HEAD':
return VERSION
VERSION = _LazyVersion()
-if "_legacy_globals_constructed" in globals():
- # The module has been reloaded, so perform any relevant cleanup
- # and prevent memory leaks.
- if "db" in _legacy_globals_constructed:
- try:
- db
- except NameError:
- pass
- else:
- if isinstance(db, dict) and db:
- for _x in db.values():
- try:
- if "porttree" in _x.lazy_items:
- continue
- except (AttributeError, TypeError):
- continue
- try:
- _x = _x["porttree"].dbapi
- except (AttributeError, KeyError):
- continue
- if not isinstance(_x, portdbapi):
- continue
- _x.close_caches()
- try:
- portdbapi.portdbapi_instances.remove(_x)
- except ValueError:
- pass
- del _x
+_legacy_global_var_names = ("archlist", "db", "features",
+ "groups", "mtimedb", "mtimedbfile", "pkglines",
+ "portdb", "profiledir", "root", "selinux_enabled",
+ "settings", "thirdpartymirrors")
+
+def _reset_legacy_globals():
+
+ global _legacy_globals_constructed
+ _legacy_globals_constructed = set()
+ for k in _legacy_global_var_names:
+ globals()[k] = _LegacyGlobalProxy(k)
class _LegacyGlobalProxy(proxy.objectproxy.ObjectProxy):
@@ -633,16 +688,7 @@ class _LegacyGlobalProxy(proxy.objectproxy.ObjectProxy):
from portage._legacy_globals import _get_legacy_global
return _get_legacy_global(name)
-_legacy_global_var_names = ("archlist", "db", "features",
- "groups", "mtimedb", "mtimedbfile", "pkglines",
- "portdb", "profiledir", "root", "selinux_enabled",
- "settings", "thirdpartymirrors")
-
-for k in _legacy_global_var_names:
- globals()[k] = _LegacyGlobalProxy(k)
-del k
-
-_legacy_globals_constructed = set()
+_reset_legacy_globals()
def _disable_legacy_globals():
"""