mirror of https://github.com/python/cpython
bpo-43776: Remove list call from args in Popen repr (GH-25338)
Removes the `list` call in the Popen `repr`. Current implementation: For cmd = `python --version`, with `shell=True`. ```bash <Popen: returncode: None args: ['p', 'y', 't', 'h', 'o', 'n', ' ', '-', '-',...> ``` For `shell=False` and args=`['python', '--version']`, the output is correct: ```bash <Popen: returncode: None args: ['python', '--version']> ``` With the new changes the `repr` yields: For cmd = `python --version`, with `shell=True`: ```bash <Popen: returncode: None args: 'python --version'> ``` For `shell=False` and args=`['python', '--version']`, the output: ```bash <Popen: returncode: None args: ['python', '--version']> ``` Automerge-Triggered-By: GH:gpshead
This commit is contained in:
parent
f9bedb630e
commit
db0c5b786d
|
@ -1003,7 +1003,7 @@ class Popen:
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
obj_repr = (
|
obj_repr = (
|
||||||
f"<{self.__class__.__name__}: "
|
f"<{self.__class__.__name__}: "
|
||||||
f"returncode: {self.returncode} args: {list(self.args)!r}>"
|
f"returncode: {self.returncode} args: {self.args!r}>"
|
||||||
)
|
)
|
||||||
if len(obj_repr) > 80:
|
if len(obj_repr) > 80:
|
||||||
obj_repr = obj_repr[:76] + "...>"
|
obj_repr = obj_repr[:76] + "...>"
|
||||||
|
|
|
@ -23,6 +23,7 @@ import threading
|
||||||
import gc
|
import gc
|
||||||
import textwrap
|
import textwrap
|
||||||
import json
|
import json
|
||||||
|
import pathlib
|
||||||
from test.support.os_helper import FakePath
|
from test.support.os_helper import FakePath
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -1442,28 +1443,23 @@ class ProcessTestCase(BaseTestCase):
|
||||||
p.communicate(b"x" * 2**20)
|
p.communicate(b"x" * 2**20)
|
||||||
|
|
||||||
def test_repr(self):
|
def test_repr(self):
|
||||||
# Run a command that waits for user input, to check the repr() of
|
path_cmd = pathlib.Path("my-tool.py")
|
||||||
# a Proc object while and after the sub-process runs.
|
pathlib_cls = path_cmd.__class__.__name__
|
||||||
code = 'import sys; input(); sys.exit(57)'
|
|
||||||
cmd = [sys.executable, '-c', code]
|
|
||||||
result = "<Popen: returncode: {}"
|
|
||||||
|
|
||||||
with subprocess.Popen(
|
cases = [
|
||||||
cmd, stdin=subprocess.PIPE, universal_newlines=True) as proc:
|
("ls", True, 123, "<Popen: returncode: 123 args: 'ls'>"),
|
||||||
self.assertIsNone(proc.returncode)
|
('a' * 100, True, 0,
|
||||||
self.assertTrue(
|
"<Popen: returncode: 0 args: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...>"),
|
||||||
repr(proc).startswith(result.format(proc.returncode)) and
|
(["ls"], False, None, "<Popen: returncode: None args: ['ls']>"),
|
||||||
repr(proc).endswith('>')
|
(["ls", '--my-opts', 'a' * 100], False, None,
|
||||||
)
|
"<Popen: returncode: None args: ['ls', '--my-opts', 'aaaaaaaaaaaaaaaaaaaaaaaa...>"),
|
||||||
|
(path_cmd, False, 7, f"<Popen: returncode: 7 args: {pathlib_cls}('my-tool.py')>")
|
||||||
proc.communicate(input='exit...\n')
|
]
|
||||||
proc.wait()
|
with unittest.mock.patch.object(subprocess.Popen, '_execute_child'):
|
||||||
|
for cmd, shell, code, sx in cases:
|
||||||
self.assertIsNotNone(proc.returncode)
|
p = subprocess.Popen(cmd, shell=shell)
|
||||||
self.assertTrue(
|
p.returncode = code
|
||||||
repr(proc).startswith(result.format(proc.returncode)) and
|
self.assertEqual(repr(p), sx)
|
||||||
repr(proc).endswith('>')
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_communicate_epipe_only_stdin(self):
|
def test_communicate_epipe_only_stdin(self):
|
||||||
# Issue 10963: communicate() should hide EPIPE
|
# Issue 10963: communicate() should hide EPIPE
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
When :class:`subprocess.Popen` args are provided as a string or as :class:`pathlib.Path`, the Popen instance repr now shows the right thing.
|
Loading…
Reference in New Issue