Allow multiple statements in code.InteractiveConsole.push #51989
Copy link
Copy link
Open
Labels
stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-featureA feature request or enhancementA feature request or enhancement
Description
| BPO | 7741 |
|---|---|
| Nosy | @ncoghlan, @kristjanvalur, @merwok, @asvetlov |
| Dependencies | |
| Files |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee = None
closed_at = None
created_at = <Date 2010-01-19.14:52:01.447>
labels = ['type-feature', 'library']
title = 'Allow multiple statements in code.InteractiveConsole.push'
updated_at = <Date 2012-12-09.22:47:37.469>
user = 'https://github.com/kristjanvalur'bugs.python.org fields:
activity = <Date 2012-12-09.22:47:37.469>
actor = 'cjw296'
assignee = 'none'
closed = False
closed_date = None
closer = None
components = ['Library (Lib)']
creation = <Date 2010-01-19.14:52:01.447>
creator = 'kristjan.jonsson'
dependencies = ['16649']
files = ['15950', '26939', '26940']
hgrepos = []
issue_num = 7741
keywords = ['patch', 'needs review']
message_count = 15.0
messages = ['98056', '98057', '98058', '98182', '168719', '168720', '168721', '168844', '168848', '168868', '177160', '177185', '177200', '177205', '177210']
nosy_count = 5.0
nosy_names = ['ncoghlan', 'kristjan.jonsson', 'eric.araujo', 'asvetlov', 'aliles']
pr_nums = []
priority = 'low'
resolution = None
stage = 'test needed'
status = 'open'
superseder = None
type = 'enhancement'
url = 'https://bugs.python.org/issue7741'
versions = ['Python 3.4']Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-featureA feature request or enhancementA feature request or enhancement
Activity
kristjanvalur commentedon Jan 19, 2010
The code.InteractiveConsole() is useful to emulate a python console. However, any code currently "push"ed to it must be single statements. This is because it passes the ´single´ symbol mode to the underlying compile function.
This patch allows the caller of InteractiveConsole.push to specify a different mode, e.g. ´exec´. This is useful if one wants to paste entire code snippets into the console. Without it, pasting the following:
'if True:\n print 1\nprint 2' Won't run. pushing such multiline code snippets with an additional 'exec' argument will allow it to work.
Patch included.
kristjanvalur commentedon Jan 19, 2010
Note, there are no regression tests for the code module.
kristjanvalur commentedon Jan 19, 2010
Here is how to test this manually:
from code import InteractiveConsole
c = InteractiveConsole()
s = "if True:\n print 1\nprint 2"
c.push(s) #fails
c.push(s, "exec") #succeeds
cjw296 commentedon Jan 23, 2010
Please can you starts a small test suite for the code module that tests the fix you are proposing and include it as another patch?
aliles commentedon Aug 21, 2012
Patch option 1 of 2.
Incorporates Kristjan's patch and adds unit tests. This has the side effect of changing InteractiveConsole's behaviour with respect to displayhook(). I'm unsure if this is desirable.
aliles commentedon Aug 21, 2012
Patch option 2 of 2.
Alternative patch that adds a new method to InteractiveConsole to split the string into multiple lines, feeding each line to interpreter using push().
This doesn't change the behaviour regarding the displayhook. But this may not meet Kristjan's original goals.
aliles commentedon Aug 21, 2012
A quick note regarding the last two patches submitted. These patches add unit tests using the test suite added for Issue bpo-12643. This limits the patches suitable to Python 3.3 and up.
kristjanvalur commentedon Aug 22, 2012
What's the purpose of the new patch, particularly 2/2 since it is equivalent to multiple push() calls?
I.e. since this issue has laid dormant for two years, what prompts the sudden activity?
ncoghlan commentedon Aug 22, 2012
Aaron was looking for something to work on for the PyConAU sprints, and set himself the task of closing as many issues related to the code module as possible.
The main outcome of that was the new test suite added in bpo-12643, which should make it easier to work on the module (at least in 3.3+)
aliles commentedon Aug 22, 2012
I agree that the second patch adds little value to InteractiveConsole.
A third alternative would be to accept default grammar start symbol to be passed to __init__(). Although this would prevent mixing use of 'single' with 'exec'.
ncoghlan commentedon Dec 8, 2012
OK, after a long detour that delved deep into codeop and the vagaries of PyCF_DONT_IMPLY_DEDENT (due to a problem that turned out to be due to a missing "\n" in a test case I added), my main conclusion is:
Coupling the "single vs multiple statement" decision to the "implicit print after every call" decision is *really* annoying. The latter should be its own flag *or else* also implied by the "DONT_IMPLY_DEDENT" flag that is already passed to the compiler by codeop.
If *that* gets fixed, then the code module could simply switch over to compiling in exec mode always, without any side effects on the implicit display of expression results.
aliles commentedon Dec 8, 2012
Should a new issue be created to decouple "print after every call" from the
single vs multiple statement condition that is a blocker for this issue? Or
can it be resolved here?
On Sunday, 9 December 2012, Nick Coghlan wrote:
ncoghlan commentedon Dec 9, 2012
More implicit magic seems like a bad idea, so I've split out a proposal for an explicit PyCF_DISPLAY_EXPRESSION_RESULTS flag as bpo-16649.
The behaviour would then be selectable regardless of the compilation mode, but would remain the default for "single".
kristjanvalur commentedon Dec 9, 2012
Sounds fine.
Just a note to my original intent in bpo-7741:
We were using the InteractiveConsole class to implement a remote web-based console for our EVE servers. Often, as a means to hot-fix certain issues, we would paste code snippets into these windows to define functions, execute code, etc. Previously we had our own console like implementation, but the interactive features of the InteractiveConsole were _really_ nice, but lacking in multi-line support. We have had the stdlib patched as per my original suggestion for the past few years to support it.
ncoghlan commentedon Dec 9, 2012
Good to know - I guess in most circumstances copy-and-paste already works, because the input will be arriving via a line-buffered IO stream.
I was thinking that with bpo-16649 implemented, it would be possible to simply switch from "single" to "exec", without users needing to request the multi-statement support explicitly. However, I'm now back to wondering if such a change might have a few unforeseen consequences I haven't thought of.
So if that seems like too much of a risk to backwards compatibility, how about moving the "symbol" argument to __init__, rather than needing to supply it with each call to push?