Skip to content

fix: propagate input stream in Command.call() for interactive questions - #532

Open
binggao1230 wants to merge 2 commits into
python-poetry:mainfrom
binggao1230:fix/call-propagate-stream-for-interactive-questions
Open

binggao1230 wants to merge 2 commits into
python-poetry:mainfrom
binggao1230:fix/call-propagate-stream-for-interactive-questions

Conversation

@binggao1230

Copy link
Copy Markdown

Problem

When a command uses call() to invoke another command that contains interactive questions (confirm, ask, choice), the callee crashes with:

AttributeError: 'NoneType' object has no attribute 'readline'

Root cause: call() constructs a fresh StringInput whose _stream defaults to None, but never copies the parent IO's stream. When the callee calls:

confirm() → Question.ask() → io.read_line() → input.read_line() → self._stream.readline()

self._stream is None, causing the crash.

Fix

Propagate self._io.input.stream to the new StringInput before passing it to _run_command:

string_input = StringInput(args or "")
string_input.set_stream(self._io.input.stream)

Test

Added test_call_propagates_stream_for_confirm which exercises a caller→callee chain where the callee uses confirm(), providing inputs="yes\n" through ApplicationTester. Before this fix the test raises AttributeError; after it passes.

Fixes #333


This pull request was prepared with the assistance of AI, under my direction and review.

When a command uses call() to invoke another command that contains
interactive questions (confirm, ask, choice), the callee's input
stream was None, causing an AttributeError on readline().

The root cause: call() constructs a fresh StringInput whose _stream
defaults to None, but never copies the parent IO's stream. When the
callee calls confirm() → Question.ask() → io.read_line() →
input.read_line() → self._stream.readline(), the None stream raises
'NoneType' object has no attribute 'readline'.

Fix: propagate self._io.input.stream to the new StringInput before
passing it to _run_command, so the callee reads from the same stream
as the caller.

Fixes python-poetry#333
@dosubot dosubot Bot added the size:XS This PR changes 0-9 lines, ignoring generated files. label Jun 24, 2026
@binggao1230

Copy link
Copy Markdown
Author

Pushed a follow-up for the red checks:

  • added news/333.bugfix.md for the bug fix
  • ran pre-commit run --all-files; it reformatted the new Command.call() return line, and the follow-up includes that formatting change

Verification:

  • uv run --with towncrier towncrier check --compare-with origin/main -> found news/333.bugfix.md
  • uv run --with pre-commit pre-commit run --all-files -> passed
  • uv run --with pytest python -m pytest tests/commands/test_command.py -q -> 6 passed
  • git diff --check --cached -> passed before commit

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XS This PR changes 0-9 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Using Call on a Command that Uses Confirm Doesn't Work

1 participant