From c1b25f2bbbc9e19322e31517023f9f41a6fa33fd Mon Sep 17 00:00:00 2001 From: Fabian Groffen Date: Wed, 9 Dec 2009 17:49:51 +0000 Subject: [PATCH] Merged from trunk -r14969:14975 | 14970 | Don't assign f to sys.stderr inside EOutput._write(). | | zmedico | | | 14971 | When temporarily replacing the sys.std* streams, use the | | zmedico | normal open() func in python3 so that we get the right class | | | (otherwise our code that expects the 'buffer' attribute will | | | break). | | 14972 | Use ImportError handling to import _TextTestResult which | | zmedico | moved from unittest to unittest.runner in python-2.7. Thanks | | | to Arfrever for the suggestion. | | 14973 | Fix handling for TEMP, TMP, and TMPDIR variables: * Add to | | zmedico | whitelist so current values are always used. * Always filter | | | them from the saved environment. * Always add thier values | | | to SANDBOX_WRITE. | | 14974 | When overridding sys.std* in python2, use binary streams. | | zmedico | | | 14975 | Add localization variables (LANG and LC_*) to the | | zmedico | environment whitelist and filter them from the saved | | | environment (so user settings override those of binary | | | packages). Thanks to Fabio Erculiani for | | | reporting. | svn path=/main/branches/prefix/; revision=14977 --- bin/ebuild.sh | 6 ++++ bin/isolated-functions.sh | 7 +++- pym/_emerge/BinpkgVerifier.py | 18 ++++++++-- pym/portage/__init__.py | 12 +++++++ pym/portage/output.py | 1 - pym/portage/tests/__init__.py | 65 +++++------------------------------ 6 files changed, 47 insertions(+), 62 deletions(-) diff --git a/bin/ebuild.sh b/bin/ebuild.sh index f6abc0693..0479f8ccc 100755 --- a/bin/ebuild.sh +++ b/bin/ebuild.sh @@ -11,6 +11,12 @@ PORTAGE_PYM_PATH="${PORTAGE_PYM_PATH:-@PORTAGE_BASE@/pym}" # environment by modifying our PATH. unset BASH_ENV +# Avoid sandbox violations in temporary directories. +for x in TEMP TMP TMPDIR ; do + [[ -n ${!x} ]] && export SANDBOX_WRITE="${SANDBOX_WRITE:+${SANDBOX_WRITE}:}${!x}" +done +unset x + # sandbox's bashrc sources /etc/profile which unsets ROOTPATH, # so we have to back it up and restore it. if [ -n "${PORTAGE_ROOTPATH}" ] ; then diff --git a/bin/isolated-functions.sh b/bin/isolated-functions.sh index 792aad925..ff0a198df 100755 --- a/bin/isolated-functions.sh +++ b/bin/isolated-functions.sh @@ -514,6 +514,11 @@ save_ebuild_env() { unset ECHANGELOG_USER GPG_AGENT_INFO \ SSH_AGENT_PID SSH_AUTH_SOCK STY WINDOW XAUTHORITY + # localization settings + unset LANG LC_COLLATE LC_CTYPE LC_MESSAGES \ + LC_MONETARY LC_NUMERIC LC_TIME LC_PAPER \ + LC_ALL + # CCACHE and DISTCC config unset ${!CCACHE_*} ${!DISTCC_*} @@ -572,7 +577,7 @@ save_ebuild_env() { PROFILE_PATHS PWORKDIR QA_INTERCEPTORS \ RC_DEFAULT_INDENT RC_DOT_PATTERN RC_ENDCOL \ RC_INDENTATION READONLY_EBUILD_METADATA READONLY_PORTAGE_VARS \ - ROOT ROOTPATH RPMDIR STARTDIR TMP TMPDIR USE_EXPAND \ + ROOT ROOTPATH RPMDIR STARTDIR TEMP TMP TMPDIR USE_EXPAND \ WARN XARGS _RC_GET_KV_CACHE # Prefix additions diff --git a/pym/_emerge/BinpkgVerifier.py b/pym/_emerge/BinpkgVerifier.py index d36958717..eebccfa74 100644 --- a/pym/_emerge/BinpkgVerifier.py +++ b/pym/_emerge/BinpkgVerifier.py @@ -29,9 +29,21 @@ class BinpkgVerifier(AsynchronousTask): stderr_orig = sys.stderr log_file = None if self.background and self.logfile is not None: - log_file = codecs.open(_unicode_encode(self.logfile, - encoding=_encodings['fs'], errors='strict'), - mode='a', encoding=_encodings['content'], errors='replace') + if sys.hexversion >= 0x3000000: + # Since we are replacing the sys.std* streams, + # we need to use the normal open() function + # so that we get the right class (otherwise our + # code that expects the 'buffer' attribute + # will break). + log_file = open(_unicode_encode(self.logfile, + encoding=_encodings['fs'], errors='strict'), + mode='a', encoding=_encodings['content'], + errors='backslashreplace') + else: + # For python2, sys.std* are expected to be binary streams. + log_file = open(_unicode_encode(self.logfile, + encoding=_encodings['fs'], errors='strict'), + mode='ab') try: if log_file is not None: sys.stdout = log_file diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index 72afda6e4..499d7eda7 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -1450,6 +1450,18 @@ class config(object): "TERM", "TERMCAP", "USER", ] + # tempdir settings + _environ_whitelist += [ + "TMPDIR", "TEMP", "TMP", + ] + + # localization settings + _environ_whitelist += [ + "LANG", "LC_COLLATE", "LC_CTYPE", "LC_MESSAGES", + "LC_MONETARY", "LC_NUMERIC", "LC_TIME", "LC_PAPER", + "LC_ALL", + ] + # other variables inherited from the calling environment _environ_whitelist += [ "CVS_RSH", "ECHANGELOG_USER", diff --git a/pym/portage/output.py b/pym/portage/output.py index d0e555069..0d5437f8d 100644 --- a/pym/portage/output.py +++ b/pym/portage/output.py @@ -492,7 +492,6 @@ class EOutput(object): # avoid potential UnicodeEncodeError s = _unicode_encode(s, encoding=_encodings['stdio'], errors='backslashreplace') - f = sys.stderr if sys.hexversion >= 0x3000000: f = f.buffer f.write(s) diff --git a/pym/portage/tests/__init__.py b/pym/portage/tests/__init__.py index 0382a2fc1..fec1e238e 100644 --- a/pym/portage/tests/__init__.py +++ b/pym/portage/tests/__init__.py @@ -6,7 +6,11 @@ import sys import time import unittest -from unittest import TestResult + +try: + from unittest.runner import _TextTestResult # new in python-2.7 +except ImportError: + from unittest import _TextTestResult from portage import os from portage import _encodings @@ -70,26 +74,17 @@ def getTests(path, base_path): result.append(unittest.TestLoader().loadTestsFromModule(mod)) return result -class TextTestResult(TestResult): +class TextTestResult(_TextTestResult): """ - We need a subclass of unittest.TestResult to handle tests with TODO - Most of this class is copied from the unittest._TextTestResult that's - included with python-2.6 (but not included with python-2.7). + We need a subclass of unittest._TextTestResult to handle tests with TODO This just adds an addTodo method that can be used to add tests that are marked TODO; these can be displayed later by the test runner. """ - separator1 = '=' * 70 - separator2 = '-' * 70 - def __init__(self, stream, descriptions, verbosity): - unittest.TestResult.__init__(self) - self.stream = stream - self.showAll = verbosity > 1 - self.dots = verbosity == 1 - self.descriptions = descriptions + super(TextTestResult, self).__init__(stream, descriptions, verbosity) self.todoed = [] def addTodo(self, test, info): @@ -106,50 +101,6 @@ class TextTestResult(TestResult): self.printErrorList('FAIL', self.failures) self.printErrorList('TODO', self.todoed) - def getDescription(self, test): - if self.descriptions: - return test.shortDescription() or str(test) - else: - return str(test) - - def startTest(self, test): - TestResult.startTest(self, test) - if self.showAll: - self.stream.write(self.getDescription(test)) - self.stream.write(" ... ") - self.stream.flush() - - def addSuccess(self, test): - TestResult.addSuccess(self, test) - if self.showAll: - self.stream.writeln("ok") - elif self.dots: - self.stream.write('.') - self.stream.flush() - - def addError(self, test, err): - TestResult.addError(self, test, err) - if self.showAll: - self.stream.writeln("ERROR") - elif self.dots: - self.stream.write('E') - self.stream.flush() - - def addFailure(self, test, err): - TestResult.addFailure(self, test, err) - if self.showAll: - self.stream.writeln("FAIL") - elif self.dots: - self.stream.write('F') - self.stream.flush() - - def printErrorList(self, flavour, errors): - for test, err in errors: - self.stream.writeln(self.separator1) - self.stream.writeln("%s: %s" % (flavour,self.getDescription(test))) - self.stream.writeln(self.separator2) - self.stream.writeln("%s" % err) - class TestCase(unittest.TestCase): """ We need a way to mark a unit test as "ok to fail" -- 2.26.2