[Jython-checkins] jython: os.system should use changes to os.environ in subprocesses
jim.baker
jython-checkins at python.org
Tue Oct 27 00:55:56 EDT 2015
https://hg.python.org/jython/rev/cbdeff5f17f5
changeset: 7768:cbdeff5f17f5
user: Jim Baker <jim.baker at rackspace.com>
date: Mon Oct 26 22:55:51 2015 -0600
summary:
os.system should use changes to os.environ in subprocesses
Fixes http://bugs.jython.org/issue2416
files:
Lib/subprocess.py | 55 ++++++++++++++++-------------
Lib/test/test_os_jy.py | 19 +++++++++-
2 files changed, 49 insertions(+), 25 deletions(-)
diff --git a/Lib/subprocess.py b/Lib/subprocess.py
--- a/Lib/subprocess.py
+++ b/Lib/subprocess.py
@@ -768,6 +768,31 @@
raise
+if jython:
+ def _setup_env(env, builder_env):
+ """Carefully merge env with ProcessBuilder's only
+ overwriting key/values that differ
+
+ System.getenv (Map<String, String>) may be backed by
+ <byte[], byte[]> on UNIX platforms where these are really
+ bytes. ProcessBuilder's env inherits its contents and will
+ maintain those byte values (which may be butchered as
+ Strings) for the subprocess if they haven't been modified.
+ """
+ # Determine what's safe to merge
+ merge_env = dict((key, value) for key, value in env.iteritems()
+ if key not in builder_env or
+ builder_env.get(key) != value)
+
+ # Prune anything not in env
+ entries = builder_env.entrySet().iterator()
+ for entry in entries:
+ if entry.getKey() not in env:
+ entries.remove()
+
+ builder_env.putAll(merge_env)
+
+
class Popen(object):
def __init__(self, args, bufsize=0, executable=None,
stdin=None, stdout=None, stderr=None,
@@ -1268,28 +1293,6 @@
return _CouplerThread(*args, **kwargs)
- def _setup_env(self, env, builder_env):
- """Carefully merge env with ProcessBuilder's only
- overwriting key/values that differ
-
- System.getenv (Map<String, String>) may be backed by
- <byte[], byte[]> on UNIX platforms where these are really
- bytes. ProcessBuilder's env inherits its contents and will
- maintain those byte values (which may be butchered as
- Strings) for the subprocess if they haven't been modified.
- """
- # Determine what's safe to merge
- merge_env = dict((key, value) for key, value in env.iteritems()
- if key not in builder_env or
- builder_env.get(key) != value)
-
- # Prune anything not in env
- entries = builder_env.entrySet().iterator()
- for entry in entries:
- if entry.getKey() not in env:
- entries.remove()
-
- builder_env.putAll(merge_env)
def _execute_child(self, args, executable, preexec_fn, close_fds,
@@ -1328,8 +1331,8 @@
builder.redirectError(java.lang.ProcessBuilder.Redirect.INHERIT)
# os.environ may be inherited for compatibility with CPython
- self._setup_env(dict(os.environ if env is None else env),
- builder.environment())
+ _setup_env(dict(os.environ if env is None else env),
+ builder.environment())
if cwd is None:
cwd = os.getcwd()
@@ -1888,11 +1891,15 @@
args = _escape_args(args)
args = _shell_command + args
cwd = os.getcwd()
+
+
+
builder = java.lang.ProcessBuilder(args)
builder.directory(java.io.File(cwd))
builder.redirectInput(java.lang.ProcessBuilder.Redirect.INHERIT)
builder.redirectOutput(java.lang.ProcessBuilder.Redirect.INHERIT)
builder.redirectError(java.lang.ProcessBuilder.Redirect.INHERIT)
+ _setup_env(dict(os.environ), builder.environment())
try:
return builder.start().waitFor()
except (java.io.IOException,
diff --git a/Lib/test/test_os_jy.py b/Lib/test/test_os_jy.py
--- a/Lib/test/test_os_jy.py
+++ b/Lib/test/test_os_jy.py
@@ -359,7 +359,7 @@
# would fail with an import error due to creating a circular
# import chain. This root cause is because the os module
# imports the subprocess module for the system function; but
- # the subprocess module imports from os. Verrifies that this
+ # the subprocess module imports from os. Verifies that this is
# managed by making the import late; also verify the
# monkeypatching optimization is successful by calling
# os.system twice.
@@ -371,6 +371,23 @@
.replace("\r", ""), # in case of running on Windows
"42\n47\n")
+ def test_system_uses_os_environ(self):
+ """Writing to os.environ is made available as env vars in os.system subprocesses"""
+ # This test likely requires additional customization for
+ # environments like AS/400, but I do not have current access.
+ # Verifies fix for http://bugs.jython.org/issue2416
+ if os._name == "nt":
+ echo_command = 'echo %TEST_ENVVAR%'
+ else:
+ echo_command = 'echo $TEST_ENVVAR'
+ with test_support.temp_cwd() as temp_cwd:
+ self.assertEqual(
+ subprocess.check_output(
+ [sys.executable, "-c",
+ "import os; os.environ['TEST_ENVVAR'] = 'works on 2.7.1+'; os.system('%s')" % echo_command])\
+ .replace("\r", ""), # in case of running on Windows
+ "works on 2.7.1+\n")
+
@unittest.skipUnless(hasattr(os, 'link'), "os.link not available")
class LinkTestCase(unittest.TestCase):
--
Repository URL: https://hg.python.org/jython
More information about the Jython-checkins
mailing list