Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
edd2e816
Commit
edd2e816
authored
Sep 30, 2012
by
Chris Jerdonek
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issue #15533: Clarify docs and add tests for subprocess.Popen()'s cwd argument.
parent
1281b741
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
101 additions
and
33 deletions
+101
-33
Doc/library/subprocess.rst
Doc/library/subprocess.rst
+4
-4
Lib/test/test_subprocess.py
Lib/test/test_subprocess.py
+94
-29
Misc/NEWS
Misc/NEWS
+3
-0
No files found.
Doc/library/subprocess.rst
View file @
edd2e816
...
...
@@ -415,10 +415,10 @@ functions.
.. versionadded:: 3.2
The *pass_fds* parameter was added.
If *cwd* is not ``None``, the
child's current directory will be changed to *cwd*
before it is executed. Note that this directory is not considered when
searching the executable, so you can't specify the program's path relative to
*cwd*
.
If *cwd* is not ``None``, the
function changes the working directory to
*cwd* before executing the child. In particular, the function looks for
*executable* (or for the first item in *args*) relative to *cwd* if the
executable path is a relative path
.
If *restore_signals* is True (the default) all signals that Python has set to
SIG_IGN are restored to SIG_DFL in the child process before the exec.
...
...
Lib/test/test_subprocess.py
View file @
edd2e816
import
unittest
from
test
import
script_helper
from
test
import
support
import
subprocess
import
sys
...
...
@@ -164,24 +165,106 @@ class ProcessTestCase(BaseTestCase):
p
.
wait
()
self
.
assertEqual
(
p
.
stderr
,
None
)
def
test_executable_with_cwd
(
self
):
python_dir
=
os
.
path
.
dirname
(
os
.
path
.
realpath
(
sys
.
executable
))
p
=
subprocess
.
Popen
([
"somethingyoudonthave"
,
"-c"
,
"import sys; sys.exit(47)"
],
executable
=
sys
.
executable
,
cwd
=
python_dir
)
# For use in the test_cwd* tests below.
def
_normalize_cwd
(
self
,
cwd
):
# Normalize an expected cwd (for Tru64 support).
# We can't use os.path.realpath since it doesn't expand Tru64 {memb}
# strings. See bug #1063571.
original_cwd
=
os
.
getcwd
()
os
.
chdir
(
cwd
)
cwd
=
os
.
getcwd
()
os
.
chdir
(
original_cwd
)
return
cwd
# For use in the test_cwd* tests below.
def
_split_python_path
(
self
):
# Return normalized (python_dir, python_base).
python_path
=
os
.
path
.
realpath
(
sys
.
executable
)
return
os
.
path
.
split
(
python_path
)
# For use in the test_cwd* tests below.
def
_assert_cwd
(
self
,
expected_cwd
,
python_arg
,
**
kwargs
):
# Invoke Python via Popen, and assert that (1) the call succeeds,
# and that (2) the current working directory of the child process
# matches *expected_cwd*.
p
=
subprocess
.
Popen
([
python_arg
,
"-c"
,
"import os, sys; "
"sys.stdout.write(os.getcwd()); "
"sys.exit(47)"
],
stdout
=
subprocess
.
PIPE
,
**
kwargs
)
self
.
addCleanup
(
p
.
stdout
.
close
)
p
.
wait
()
self
.
assertEqual
(
p
.
returncode
,
47
)
self
.
assertEqual
(
47
,
p
.
returncode
)
normcase
=
os
.
path
.
normcase
self
.
assertEqual
(
normcase
(
expected_cwd
),
normcase
(
p
.
stdout
.
read
().
decode
(
"utf-8"
)))
def
test_cwd
(
self
):
# Check that cwd changes the cwd for the child process.
temp_dir
=
tempfile
.
gettempdir
()
temp_dir
=
self
.
_normalize_cwd
(
temp_dir
)
self
.
_assert_cwd
(
temp_dir
,
sys
.
executable
,
cwd
=
temp_dir
)
def
test_cwd_with_relative_arg
(
self
):
# Check that Popen looks for args[0] relative to cwd if args[0]
# is relative.
python_dir
,
python_base
=
self
.
_split_python_path
()
rel_python
=
os
.
path
.
join
(
os
.
curdir
,
python_base
)
with
support
.
temp_cwd
()
as
wrong_dir
:
# Before calling with the correct cwd, confirm that the call fails
# without cwd and with the wrong cwd.
self
.
assertRaises
(
OSError
,
subprocess
.
Popen
,
[
rel_python
])
self
.
assertRaises
(
OSError
,
subprocess
.
Popen
,
[
rel_python
],
cwd
=
wrong_dir
)
python_dir
=
self
.
_normalize_cwd
(
python_dir
)
self
.
_assert_cwd
(
python_dir
,
rel_python
,
cwd
=
python_dir
)
def
test_cwd_with_relative_executable
(
self
):
# Check that Popen looks for executable relative to cwd if executable
# is relative (and that executable takes precedence over args[0]).
python_dir
,
python_base
=
self
.
_split_python_path
()
rel_python
=
os
.
path
.
join
(
os
.
curdir
,
python_base
)
doesntexist
=
"somethingyoudonthave"
with
support
.
temp_cwd
()
as
wrong_dir
:
# Before calling with the correct cwd, confirm that the call fails
# without cwd and with the wrong cwd.
self
.
assertRaises
(
OSError
,
subprocess
.
Popen
,
[
doesntexist
],
executable
=
rel_python
)
self
.
assertRaises
(
OSError
,
subprocess
.
Popen
,
[
doesntexist
],
executable
=
rel_python
,
cwd
=
wrong_dir
)
python_dir
=
self
.
_normalize_cwd
(
python_dir
)
self
.
_assert_cwd
(
python_dir
,
doesntexist
,
executable
=
rel_python
,
cwd
=
python_dir
)
def
test_cwd_with_absolute_arg
(
self
):
# Check that Popen can find the executable when the cwd is wrong
# if args[0] is an absolute path.
python_dir
,
python_base
=
self
.
_split_python_path
()
abs_python
=
os
.
path
.
join
(
python_dir
,
python_base
)
rel_python
=
os
.
path
.
join
(
os
.
curdir
,
python_base
)
with
script_helper
.
temp_dir
()
as
wrong_dir
:
# Before calling with an absolute path, confirm that using a
# relative path fails.
self
.
assertRaises
(
OSError
,
subprocess
.
Popen
,
[
rel_python
],
cwd
=
wrong_dir
)
wrong_dir
=
self
.
_normalize_cwd
(
wrong_dir
)
self
.
_assert_cwd
(
wrong_dir
,
abs_python
,
cwd
=
wrong_dir
)
def
test_executable_with_cwd
(
self
):
python_dir
,
python_base
=
self
.
_split_python_path
()
python_dir
=
self
.
_normalize_cwd
(
python_dir
)
self
.
_assert_cwd
(
python_dir
,
"somethingyoudonthave"
,
executable
=
sys
.
executable
,
cwd
=
python_dir
)
@
unittest
.
skipIf
(
sysconfig
.
is_python_build
(),
"need an installed Python. See #7774"
)
def
test_executable_without_cwd
(
self
):
# For a normal installation, it should work without 'cwd'
# argument. For test runs in the build directory, see #7774.
p
=
subprocess
.
Popen
([
"somethingyoudonthave"
,
"-c"
,
"import sys; sys.exit(47)"
],
executable
=
sys
.
executable
)
p
.
wait
()
self
.
assertEqual
(
p
.
returncode
,
47
)
self
.
_assert_cwd
(
''
,
"somethingyoudonthave"
,
executable
=
sys
.
executable
)
def
test_stdin_pipe
(
self
):
# stdin redirection
...
...
@@ -313,24 +396,6 @@ class ProcessTestCase(BaseTestCase):
rc
=
subprocess
.
call
([
sys
.
executable
,
"-c"
,
cmd
],
stdout
=
1
)
self
.
assertEqual
(
rc
,
2
)
def
test_cwd
(
self
):
tmpdir
=
tempfile
.
gettempdir
()
# We cannot use os.path.realpath to canonicalize the path,
# since it doesn't expand Tru64 {memb} strings. See bug 1063571.
cwd
=
os
.
getcwd
()
os
.
chdir
(
tmpdir
)
tmpdir
=
os
.
getcwd
()
os
.
chdir
(
cwd
)
p
=
subprocess
.
Popen
([
sys
.
executable
,
"-c"
,
'import sys,os;'
'sys.stdout.write(os.getcwd())'
],
stdout
=
subprocess
.
PIPE
,
cwd
=
tmpdir
)
self
.
addCleanup
(
p
.
stdout
.
close
)
normcase
=
os
.
path
.
normcase
self
.
assertEqual
(
normcase
(
p
.
stdout
.
read
().
decode
(
"utf-8"
)),
normcase
(
tmpdir
))
def
test_env
(
self
):
newenv
=
os
.
environ
.
copy
()
newenv
[
"FRUIT"
]
=
"orange"
...
...
Misc/NEWS
View file @
edd2e816
...
...
@@ -597,6 +597,9 @@ Build
Documentation
-------------
- Issue #15533: Clarify docs and add tests for subprocess.Popen()'s cwd
argument.
- Issue #16036: Improve documentation of built-in int()'s signature and
arguments.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment