Commit graph

494 commits

Author SHA1 Message Date
Gregory P. Smith using claude.ai/code
15f8a93bcb
Support universal_newlines and use _translate_newlines in run_pipeline
- Factor out _translate_newlines() as a module-level function, have
  Popen's method delegate to it for code sharing
- Remove rejection of universal_newlines kwarg in run_pipeline(), treat
  it the same as text=True (consistent with Popen behavior)
- Use _translate_newlines() for text mode decoding in run_pipeline()
  to properly handle \r\n and \r newline sequences
- Update documentation to remove mention of universal_newlines rejection
- Update test to verify universal_newlines=True works like text=True

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-29 09:27:29 +00:00
Gregory P. Smith using claude.ai/code
df8f082f59
Fix memoryview and closed stdin handling in _communicate_streams_posix
Apply the same fixes from Popen._communicate() to _communicate_streams_posix
for run_pipeline():

1. Handle non-byte memoryview input by casting to byte view (gh-134453):
   Non-byte memoryviews (e.g., int32 arrays) had incorrect length tracking
   because len() returns element count, not byte count. Now cast to "b"
   view for correct progress tracking.

2. Handle ValueError on stdin.flush() when stdin is closed (gh-74389):
   Ignore ValueError from flush() if stdin is already closed, matching
   the BrokenPipeError handling.

Add tests for memoryview input to run_pipeline:
- test_pipeline_memoryview_input: basic byte memoryview
- test_pipeline_memoryview_input_nonbyte: int32 array memoryview

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2025-11-29 08:46:22 +00:00
Gregory P. Smith using claude.ai/code
d420f29e2b
Fix _communicate_streams_windows to avoid blocking with large input
Move stdin writing to a background thread in _communicate_streams_windows
to avoid blocking indefinitely when writing large input to a pipeline
where the subprocess doesn't consume stdin quickly.

This mirrors the fix made to Popen._communicate() for Windows in
commit 5b1862b (gh-87512).

Add test_pipeline_timeout_large_input to verify that TimeoutExpired
is raised promptly when run_pipeline() is called with large input
and a timeout, even when the first process is slow to consume stdin.

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2025-11-29 08:41:25 +00:00
Gregory P. Smith using claude.ai/code
a3e98a73be
Improve test_pipeline_large_data_with_stderr to use large stderr
Update the test to write 64KB to stderr from each process (128KB total)
instead of just small status messages. This better tests that the
multiplexed I/O handles concurrent large data on both stdout and stderr
without deadlocking.

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2025-11-29 08:04:35 +00:00
Gregory P. Smith using claude.ai/code
2470e14a70
Add deadlock prevention tests for run_pipeline()
Add three tests that verify the multiplexed I/O implementation
properly handles large data volumes that would otherwise cause
pipe buffer deadlocks:

- test_pipeline_large_data_no_deadlock: 256KB through 2-stage pipeline
- test_pipeline_large_data_three_stages: 128KB through 3-stage pipeline
- test_pipeline_large_data_with_stderr: 64KB with concurrent stderr

These tests would timeout or deadlock without proper multiplexing.

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2025-11-29 08:04:34 +00:00
Gregory P. Smith using claude.ai/code
e3a2fbe6da
Add subprocess.run_pipeline() for command pipe chaining
Add a new run_pipeline() function to the subprocess module that enables
running multiple commands connected via pipes, similar to shell pipelines.

New API:
- run_pipeline(*commands, ...) - Run a pipeline of commands
- PipelineResult - Return type with commands, returncodes, stdout, stderr
- PipelineError - Raised when check=True and any command fails

Features:
- Supports arbitrary number of commands (minimum 2)
- capture_output, input, timeout, and check parameters like run()
- stdin= connects to first process, stdout= connects to last process
- Text mode support via text=True, encoding, errors
- All processes share a single stderr pipe for simplicity
- "pipefail" semantics: check=True fails if any command fails

Unlike run(), this function does not accept universal_newlines.
Use text=True instead.

Example:
    result = subprocess.run_pipeline(
        ['cat', 'file.txt'],
        ['grep', 'pattern'],
        ['wc', '-l'],
        capture_output=True, text=True
    )

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2025-11-29 08:04:33 +00:00
Gregory P. Smith
5b1862bdd8
gh-87512: Fix subprocess using timeout= on Windows blocking with a large input= (GH-142058)
On Windows, Popen._communicate() previously wrote to stdin synchronously, which could block indefinitely if the subprocess didn't consume input= quickly and the pipe buffer filled up. The timeout= parameter was only checked when joining the reader threads, not during the stdin write.

This change moves the Windows stdin writing to a background thread (similar to how stdout/stderr are read in threads), allowing the timeout to be properly enforced. If timeout expires, TimeoutExpired is raised promptly and the writer thread continues in the background. Subsequent calls to communicate() will join the existing writer thread.

Adds test_communicate_timeout_large_input to verify that TimeoutExpired is raised promptly when communicate() is called with large input and a timeout, even when the subprocess doesn't consume stdin quickly.

This test already passed on POSIX (where select() is used) but failed on Windows where the stdin write blocks without checking the timeout.

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2025-11-28 22:07:03 -08:00
Gregory P. Smith
923056b2d4
gh-74389: gh-70560: subprocess.Popen.communicate() now ignores stdin.flush error when closed (GH-142061)
gh-70560: gh-74389: subprocess.Popen.communicate() now ignores stdin.flush error when closed

with a unittest and news entry.
2025-11-29 05:03:06 +00:00
Gregory P. Smith
cc6bc4c97f
GH-134453: Fix subprocess memoryview input handling on POSIX (GH-134949)
Fix inconsistent subprocess.Popen.communicate() behavior between Windows
and POSIX when using memoryview objects with non-byte elements as input.

On POSIX systems, the code was incorrectly comparing bytes written against
element count instead of byte count, causing data truncation for large
inputs with non-byte element types.

Changes:
- Cast memoryview inputs to byte view when input is already a memoryview
- Fix progress tracking to use len(input_view) instead of len(self._input)
- Add comprehensive test coverage for memoryview inputs

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* old-man-yells-at-ReST
* Update 2025-05-30-18-37-44.gh-issue-134453.kxkA-o.rst
* assertIsNone review feedback
* fix memoryview_nonbytes test to fail without our fix on main, and have a nicer error.

Thanks to Peter Bierma @ZeroIntensity for the code review.
2025-11-29 04:25:06 +00:00
Artur Jamro
526d7a8bb4
gh-141473: Fix subprocess.Popen.communicate to send input to stdin upon a subsequent post-timeout call (GH-141477)
* gh-141473: Fix subprocess.Popen.communicate to send input to stdin
* Docs: Clarify that `input` is one time only on `communicate()`
* NEWS entry
* Add a regression test.

---------

Co-authored-by: Gregory P. Smith <greg@krypto.org>
2025-11-28 18:04:52 -08:00
Serhiy Storchaka
2602d8ae98
gh-71339: Use new assertion methods in tests (GH-129046) 2025-05-22 13:17:22 +03:00
Gregory P. Smith
b64aa302d7
[tests] test_subprocess maybe avoid a timeout race condition? (#133420)
The few buildbot failures on https://github.com/python/cpython/pull/133103
are possibly just due to racing a child process launch and exit?
2025-05-04 21:02:16 -07:00
Nadeshiko Manju
2bbcaedb75
gh-133089: Use original timeout value for TimeoutExpired when the func subprocess.run is called with a timeout (GH-133103)
Signed-off-by: Manjusaka <me@manjusaka.me>
Co-authored-by: Gregory P. Smith <greg@krypto.org>
2025-05-05 01:15:31 +00:00
Serhiy Storchaka
f7b24ffefd
gh-124986: Fix test_no_leaking in test_subprocess on NetBSD and FreeBSD (GH-132476)
On platforms where the file descriptor limit is larger than FD_SETSIZE
that test was always skipped (FreeBSD) or always failing (NetBSD).
2025-04-14 09:15:12 +03:00
Pablo Galindo Salgado
a931a8b324
gh-117174: Add a new route in linecache to fetch interactive source code (#117500) 2025-03-10 21:54:05 +00:00
Victor Stinner
67a942d427
gh-116742: Fix subprocess test_check_output_timeout() (#130836)
Fix a race condition in test_check_output_timeout() of
test_subprocess. Don't write into stdout anymore, since there is no
reliable way to synchronize the parent and the child processes.

Change the timeout from 3 seconds to 0.1 seconds, and remove
@requires_resource('walltime') decorator.
2025-03-05 10:51:33 +00:00
Cody Maloney
9ad57cf58b
gh-120754: Add a strace helper and test set of syscalls for open().read(), Take 2 (#123413) 2024-11-02 20:37:21 -07:00
Shantanu
52caaef6d0
Revert "GH-120754: Add a strace helper and test set of syscalls for o… (#123303)
Revert "GH-120754: Add a strace helper and test set of syscalls for open().read() (#121143)"

This reverts commit e38d0afe35.
2024-08-24 21:54:31 +00:00
Cody Maloney
e38d0afe35
GH-120754: Add a strace helper and test set of syscalls for open().read() (#121143) 2024-08-24 13:42:41 -07:00
Cody Maloney
a9344cdffa
gh-121381 Remove subprocess._USE_VFORK escape hatch (#121383)
This flag was added as an escape hatch in gh-91401 and backported to
Python 3.10. The flag broke at some point between its addition and now.
As there is currently no publicly known environments that require this,
remove it rather than work on fixing it.

This leaves the flag in the subprocess module to not break code which
may have used / checked the flag itself.

discussion: https://discuss.python.org/t/subprocess-use-vfork-escape-hatch-broken-fix-or-remove/56915/2
2024-07-30 18:39:54 -07:00
sobolevn
e2822360da
gh-121571: Do not use EnvironmentError in tests, use OSError instead (#121572) 2024-07-10 13:11:46 +03:00
Serhiy Storchaka
0152dc4ff5
gh-119064: Use os_helper.FakePath instead of pathlib.Path in tests (GH-119065) 2024-05-16 10:25:10 +03:00
Paulo Neves
4abca7e1e7
gh-98966: Handle stdout=subprocess.STDOUT (GH-98967)
Explicitly handle the case where stdout=STDOUT
as otherwise the existing error handling gets
confused and reports hard to understand errors.

Signed-off-by: Paulo Neves <ptsneves@gmail.com>
2024-03-26 13:37:50 +01:00
Sam Gross
60e105c1c1
gh-113964: Don't prevent new threads until all non-daemon threads exit (#116677)
Starting in Python 3.12, we prevented calling fork() and starting new threads
during interpreter finalization (shutdown). This has led to a number of
regressions and flaky tests. We should not prevent starting new threads
(or `fork()`) until all non-daemon threads exit and finalization starts in
earnest.

This changes the checks to use `_PyInterpreterState_GetFinalizing(interp)`,
which is set immediately before terminating non-daemon threads.
2024-03-19 14:40:20 -04:00
Victor Stinner
27cf3ed00c
gh-90872: Fix subprocess.Popen.wait() for negative timeout (#116989)
On Windows, subprocess.Popen.wait() no longer calls
WaitForSingleObject() with a negative timeout: pass 0 ms if the
timeout is negative.
2024-03-19 14:42:44 +01:00
Serhiy Storchaka
311d1e2701
gh-104522: Fix test_subprocess failure when build Python in the root home directory (GH-114236)
* gh-104522: Fix test_subprocess failure when build Python in the root home directory

EPERM is raised when setreuid() fails.
EACCES is set in execve() when the test user has not access to sys.executable.
2024-01-18 10:52:59 +00:00
Serhiy Storchaka
e2c097ebde
gh-104522: Fix OSError raised when run a subprocess (#114195)
Only set filename to cwd if it was caused by failed chdir(cwd).

_fork_exec() now returns "noexec:chdir" for failed chdir(cwd).

Co-authored-by: Robert O'Shea <PurityLake@users.noreply.github.com>
2024-01-17 16:52:42 -08:00
AN Long
fafb3275f2
gh-87868: Skip test_one_environment_variable in test_subprocess when the platform or build cannot do that (#113867)
* improve the assert for test_one_environment_variable
* skip some test in test_subprocess when python is configured with shared
* also skip the test if AddressSanitizer is enabled

---------

Co-authored-by: Steve Dower <steve.dower@microsoft.com>
2024-01-10 15:17:05 -08:00
AN Long
c31be58da8
gh-87868: Sort and remove duplicates in getenvironment() (GH-102731)
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
Co-authored-by: Pieter Eendebak <pieter.eendebak@gmail.com>
Co-authored-by: Erlend E. Aasland <erlend.aasland@protonmail.com>
2024-01-09 15:58:26 +00:00
Jakub Kulík
2b93f52242
gh-113117: Support posix_spawn in subprocess.Popen with close_fds=True (#113118)
Add support for `os.POSIX_SPAWN_CLOSEFROM` and
`posix_spawn_file_actions_addclosefrom_np` and have the `subprocess` module use
them when available.  This means `posix_spawn` can now be used in the default
`close_fds=True` situation on many platforms.

Co-authored-by: Gregory P. Smith [Google LLC] <greg@krypto.org>
2023-12-17 21:34:57 +00:00
Gregory P. Smith
10e9bb13b8
gh-112334: Regression test that vfork is used when expected. (#112734)
Regression test that vfork is used when expected by subprocess.

This is written integration test style, it uses strace if it is present and appears to work to find out what system call actually gets used in different scenarios.

Test coverage is added for the default behavior and that of each of the specific arguments that must disable the use of vfork.  obviously not an entire test matrix, but it covers the most important aspects.

If there are ever issues with this test being flaky or failing on new platforms, rather than try and adapt it for all possible platforms, feel free to narrow the range it gets tested on when appropriate. That is not likely to reduce coverage.
2023-12-09 00:18:35 +00:00
Gregory P. Smith
9fe7655c6c
gh-112334: Restore subprocess's use of vfork() & fix extra_groups=[] behavior (#112617)
Restore `subprocess`'s intended use of `vfork()` by default for performance on Linux;
also fixes the behavior of `extra_groups=[]` which was unintentionally broken in 3.12.0:

Fixed a performance regression in 3.12's :mod:`subprocess` on Linux where it
would no longer use the fast-path ``vfork()`` system call when it could have
due to a logic bug, instead falling back to the safe but slower ``fork()``.

Also fixed a security bug introduced in 3.12.0.  If a value of ``extra_groups=[]``
was passed to :mod:`subprocess.Popen` or related APIs, the underlying
``setgroups(0, NULL)`` system call to clear the groups list would not be made
in the child process prior to ``exec()``.

The security issue was identified via code inspection in the process of
fixing the first bug.  Thanks to @vain for the detailed report and
analysis in the initial bug on Github.

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
2023-12-04 15:08:19 -08:00
Pablo Galindo Salgado
90a1b2859f
gh-67224: Show source lines in tracebacks when using the -c option when running Python (#111200) 2023-10-26 15:17:28 +09:00
Victor Stinner
d023d4166b
gh-110184: Fix subprocess test_pipesize_default() (#110465)
For proc.stdin, get the size of the read end of the test pipe.

Use subprocess context manager ("with proc:").
2023-10-06 15:44:53 +02:00
Serhiy Storchaka
1e0d62793a
gh-108416: Mark slow but not CPU bound test methods with requires_resource('walltime') (GH-108480) 2023-09-05 17:56:30 +03:00
Serhiy Storchaka
f3ba0a74cd
gh-108416: Mark slow test methods with @requires_resource('cpu') (GH-108421)
Only mark tests which spend significant system or user time,
by itself or in subprocesses.
2023-09-02 07:45:34 +03:00
Steve Dower
4cefe3cf10
gh-105436: Ignore unrelated errors when checking empty env (GH-105742) 2023-06-14 00:00:16 +01:00
Dora203
4f7d3b602d
gh-105436: The environment block should end with two null wchar_t values (GH-105495) 2023-06-12 17:14:55 +01:00
chgnrdv
ce558e69d4
gh-104690 Disallow thread creation and fork at interpreter finalization (#104826)
Disallow thread creation and fork at interpreter finalization.

in the following functions, check if interpreter is finalizing and raise `RuntimeError` with appropriate message:
* `_thread.start_new_thread` and thus `threading`
* `posix.fork`
* `posix.fork1`
* `posix.forkpty`
* `_posixsubprocess.fork_exec` when a `preexec_fn=` is supplied.

---------

Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
Co-authored-by: Gregory P. Smith <greg@krypto.org>
2023-06-04 04:06:45 +00:00
chgnrdv
c3f43bfb4b
gh-104472: Skip test_subprocess.ProcessTestCase.test_empty_env if ASAN is enabled (#104667)
Skip test_subprocess.ProcessTestCase.test_empty_env if ASAN is enabled.
2023-05-19 19:25:51 +00:00
Hyunkyun Moon
2f62a5da94
gh-95672 skip fcntl when pipesize is smaller than pagesize (gh-102163) 2023-03-01 23:56:19 +09:00
Hyunkyun Moon
d5c7954d0c
gh-95672 fix typo SkitTest to SkipTest (gh-102119)
Co-authored-by: HyunKyun Moon <hyunkyun.moon@linecorp.com>
2023-02-22 02:39:00 +09:00
Victor Stinner
038b151963
gh-100005: Skip test_script_as_dev_fd() on FreeBSD (#100006)
On FreeBSD, skip test_script_as_dev_fd() of test_cmd_line_script if
fdescfs is not mounted (at /dev/fd).
2022-12-05 14:23:35 +01:00
Serhiy Storchaka
76f43fc09a
gh-60203: Always pass True/False as boolean arguments in tests (GH-99983)
Unless we explicitly test non-bool values.
2022-12-04 14:28:56 +02:00
andrei kulakov
db64fb9bbe
gh-97825: fix AttributeError when calling subprocess.check_output(input=None) with encoding or errors args (#97826)
* fix AttributeError, add unit test
2022-10-04 17:47:49 -07:00
Gregory P. Smith
f6dd14c653
gh-82616: Add process_group support to subprocess.Popen (#23930)
One more thing that can help prevent people from using `preexec_fn`.

Also adds conditional skips to two tests exposing ASAN flakiness on the Ubuntu 20.04 Address Sanitizer Github CI system. When that build is run on more modern systems the "problem" does not show up. It seems ASAN implementation related.

Co-authored-by: Zackery Spytz <zspytz@gmail.com>
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
2022-05-05 16:22:32 -07:00
Dennis Sweeney
b9636180b3
gh-91954: Use shell=True in test_subprocess.test_encoding_warning (GH-92090) 2022-04-30 20:38:19 -04:00
Inada Naoki
354ace8b07
gh-91954: Emit EncodingWarning from locale and subprocess (GH-91977)
locale.getpreferredencoding() and subprocess.Popen() emit EncodingWarning
2022-04-30 15:53:29 +09:00
Gregory P. Smith
cd5726fe67
gh-91401: Add a failsafe way to disable vfork. (#91490)
Just in case there is ever an issue with _posixsubprocess's use of
vfork() due to the complexity of using it properly and potential
directions that Linux platforms where it defaults to on could take, this
adds a failsafe so that users can disable its use entirely by setting
a global flag.

No known reason to disable it exists. But it'd be a shame to encounter
one and not be able to use CPython without patching and rebuilding it.

See the linked issue for some discussion on reasoning.

Also documents the existing way to disable posix_spawn.
2022-04-25 16:19:39 -07:00
Christian Heimes
082d3495d0
bpo-40280: Emscripten fork_exec now fails early (GH-32224) 2022-04-01 21:20:56 +02:00