From 7afbc993f0b59d0fc45b2738d179fd50cd486a5d Mon Sep 17 00:00:00 2001 From: Davanum Srinivas Date: Thu, 12 Jan 2017 12:26:37 -0500 Subject: Automatically convert process_input to bytes On py35, if process_input is a string we end with an Error: TypeError: memoryview: a bytes-like object is required, not 'str' A whole lot of code in os-brick/cinder/neutron currently need to be fixed. Hardest problem is tracking down every instance of this problem and trying to test/fix it at source. See example of cinder/os-brick/oslo.rootwrap/oslo.privep code problem here: http://logs.openstack.org/43/418643/2/check/gate-rally-dsvm-py35-cinder-nv/6efa7b5/logs/screen-n-cpu.txt.gz?level=ERROR It's just better to fix it in one spot and pass the correct thing to subprocess.communicate Change-Id: I88d1510a7ba4c020f73452f0b80e996c22b1edf1 --- oslo_concurrency/processutils.py | 10 ++++++++-- oslo_concurrency/tests/unit/test_processutils.py | 8 ++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/oslo_concurrency/processutils.py b/oslo_concurrency/processutils.py index 7fa294e..9e619b9 100644 --- a/oslo_concurrency/processutils.py +++ b/oslo_concurrency/processutils.py @@ -28,6 +28,7 @@ import sys import time import enum +from oslo_utils import encodeutils from oslo_utils import importutils from oslo_utils import strutils from oslo_utils import timeutils @@ -188,7 +189,7 @@ def execute(*cmd, **kwargs): :param cwd: Set the current working directory :type cwd: string :param process_input: Send to opened process. - :type process_input: string + :type process_input: string or bytes :param env_variables: Environment variables and their values that will be set for the process. :type env_variables: dict @@ -259,6 +260,9 @@ def execute(*cmd, **kwargs): process. If this parameter is used, the child process will be spawned by a wrapper process which will set limits before spawning the command. + .. versionchanged:: 3.17 + *process_input* can now be either bytes or string on python3. + .. versionchanged:: 3.4 Added *prlimit* optional parameter. @@ -266,7 +270,7 @@ def execute(*cmd, **kwargs): Added *cwd* optional parameter. .. versionchanged:: 1.9 - Added *binary* optional parameter. On Python 3, *stdout* and *stdout* + Added *binary* optional parameter. On Python 3, *stdout* and *stderr* are now returned as Unicode strings by default, or bytes if *binary* is true. @@ -279,6 +283,8 @@ def execute(*cmd, **kwargs): cwd = kwargs.pop('cwd', None) process_input = kwargs.pop('process_input', None) + if process_input is not None: + process_input = encodeutils.to_utf8(process_input) env_variables = kwargs.pop('env_variables', None) check_exit_code = kwargs.pop('check_exit_code', [0]) ignore_exit_code = False diff --git a/oslo_concurrency/tests/unit/test_processutils.py b/oslo_concurrency/tests/unit/test_processutils.py index 9227ea1..df010a1 100644 --- a/oslo_concurrency/tests/unit/test_processutils.py +++ b/oslo_concurrency/tests/unit/test_processutils.py @@ -236,6 +236,14 @@ exit 1 cwd=tmpdir) self.assertIn(tmpdir, out) + def test_process_input_with_string(self): + code = ';'.join(('import sys', + 'print(len(sys.stdin.readlines()))')) + args = [sys.executable, '-c', code] + input = "\n".join(['foo', 'bar', 'baz']) + stdout, stderr = processutils.execute(*args, process_input=input) + self.assertEqual("3", stdout.rstrip()) + def test_check_exit_code_list(self): processutils.execute('/usr/bin/env', 'sh', '-c', 'exit 101', check_exit_code=(101, 102)) -- cgit v1.2.1