Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

code.interact() will exit the whole process when given exit() or quit() #102895

Closed
gaogaotiantian opened this issue Mar 22, 2023 · 5 comments
Closed
Labels
stdlib Python modules in the Lib dir type-feature A feature request or enhancement

Comments

@gaogaotiantian
Copy link
Member

gaogaotiantian commented Mar 22, 2023

code.interact() is provided as a method to embed an interactive shell in arbitrary python code. It was used in pdb for interact command.

However, when the user needs to exit, they probably will use a very familiar command exit() (or quit()), then they'll realize that the whole process is terminated. In most of the cases, that's not the expected bahavior. The user probably just wants to exit the interpreter and go back to the original code.

Ctrl+D(Ctrl+Z then enter) works as expected because there's logic to handle that specifically.

Simply catching SystemExit won't work because builtins.exit() and builtins.quit() (if provided) will also close sys.stdin (weird behavior to me) and it's not trivial to reopen stdin.

To provide a more reasonable and unified behavior, we can replace the exit and quit in builtins in the interactive shell, and switch back after. This will also make pdb happier.

Linked PRs

@iritkatriel
Copy link
Member

We would only consider this a bug if behaviour contradicts the documentation. Is this the case?

@ambv
Copy link
Contributor

ambv commented Mar 27, 2023

You want to change the behavior of a library that's been like this since 1998. It's not clear to me that making exit() and quit() continue the program would be indeed what the user expects. It's perfectly valid to expect to be able to issue any command and have it behave like it was issued from the code itself. So it's subjective, I guess.

Even if we agree to introduce this behavior, code.interact() specifically says in its docstring that "This is a backwards compatible interface to the InteractiveConsole class."

Therefore, any additional functionality would have to live in the class as a non-default option.

@ambv ambv added type-feature A feature request or enhancement and removed type-bug An unexpected behavior, bug, or error labels Mar 27, 2023
@gaogaotiantian
Copy link
Member Author

I understood this will break the backward compatibility. I considered this as a bug mainly because - when you type exit in code.interact(), it will display the normal exit message (its repr) - Use exit() or Ctrl-D (i.e. EOF) to exit. However, the two methods now have different behavior, where Ctrl-D exits the code shell only and exit() terminates the process.

I hit this issue when I was trying to test pdb.interact and realized that it's difficult to exit from the code shell with the script, but now that I think about it, I can simply raise a SystemExit.

But, now that we are on that topic, the actual issue evolves - when the users are using pdb.interact, then they use exit() in the interactive shell, I think most of the times they did not expect to exit the process completely. However, the current behavior of code.interact made it almost impossible to recover from an exit() in the interactive shell, which means an exit() in pdb.interact will just break the whole process being debugged. (and of course in theory that's not code.interact's consideration, just to point it out)

@gaogaotiantian
Copy link
Member Author

I think we can provide user an option to enable this feature? Keep all the default behavior as before, but add an optional replace_exit(or some better name) argument so the users can have an interactive shell that can do exit().

@gaogaotiantian
Copy link
Member Author

I made a modification to the implementation.

Now this feature will be hidden behind a new option for InteractiveConsole - block_exit. By default, block_exit will be False and everything would behave as before. If the user enabled the option, the interactive shell would block the exit() function from exiting the process, and only exit the interactive shell. The option is available on both the initializer of InteractiveConsole and code.interact().

If this is something we can do, I'll work on the documetation for the explanation.

brandtbucher pushed a commit that referenced this issue Oct 18, 2023
aisk pushed a commit to aisk/cpython that referenced this issue Feb 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stdlib Python modules in the Lib dir type-feature A feature request or enhancement
Projects
None yet
Development

No branches or pull requests

5 participants