Copy-paste into Python interactive interpreter and indentation - python

This piece of code, file test.py,
if 1:
print "foo"
print "bar"
can be successfully executed with execfile("test.py") or python test.py, but when one tries to copy-paste it into a Python interpreter:
File "<stdin>", line 3
print "bar"
^
SyntaxError: invalid syntax
Why is it so? Can the interpreter by configured in such a way that it would read copy-pasted text successfully?
I guess that may affect typing in the interpreter, but that's OK for me.

Indentation is probably lost or broken.
Have a look at IPython -- it's an enhanced Python interpreter with many convenient features. One of them is a magic function %paste that allows you to paste multiple lines of code.
It also has tab-completion, auto-indentation... and many more. Have a look at their site.
Using %paste in IPython:
And copy-and-paste stuff is one of the things fixed in the Qt console. Here's using a plain old copy-and-paste of your code block that "just works" in the new IPython qtconsole:

I don't know any trick for the standard command prompt, but I can suggest you a more advanced interpreter like IPython that has a special syntax for multi-line paste:
In [1]: %cpaste
Pasting code; enter '--' alone on the line to stop.
:for c in range(3):
: print c
:
:--
0
1
2
Another option is the bpython interpreter that has an automatic paste mode (if you are typing too fast to be an human):
>>> for c in range(3):
... print c
...
0
1
2
>>>
<C-r> Rewind <C-s> Save <F8> Pastebin <F9> Pager <F2> Show Source

Do %autoindent to make automatic indentation off. After that, you can paste your code in IPython.

Continuation lines are needed when entering a multi-line construct.
--Interactive mode, The Python Tutorial (v2) (v3)
So you need to enter:
if 1:
print "foo"
print "bar"
I've yet to find a suitable explanation as to why it's different to a non-interactive session, alas.

All of the current answers suggest you change to IPython. For a Python-only solution, you can use textwrap to remove leading whitespace from lines.
For example,
>>> code=""" x='your pasted code'
y='with common indentation'"""
>>> formatted=textwrap.dedent(code)
>>> exec(formatted)

If you are like me and use Notepad++ (to copy and paste from), try to replace tabs by spaces by going to menu Settings → Preferences → Language and check the replace by spaces.
I had this problem myself for so long and I found out that python.exe recognizes spaces.

If the pasted content has any empty lines, the interpreter triggers evaluation when encountering them. If any line after an empty line has indentation, it will cause an IndentationError since any previous context has been closed.
Solutions:
Delete any empty lines before copying to clipboard.
Add any amount of indentation to empty lines (doesn't need to match code) before copying to clipboard.
Note that spaces vs. tabs does not seem to matter.

exec(pyperclip.paste())
provided you don't mind using exec. Any other third party clipboard package than pyperclip will do I guess.

One other solution I recently found for a similar problem:
$ python << EOF
if 1:
print "foo"
print "bar"
EOF

Related

Python: What Does This Syntax Error Mean? [duplicate]

I think this is perfectly valid.
if False:
print(1)
print(2)
However, it gives me an invalid syntax error in Python REPL.
Why is it?
On Python 3.6.5 (x64), Windows 10 RS4
As pointed out by user2357112, this behaviour is explained in https://docs.python.org/3/tutorial/introduction.html#first-steps-towards-programming,
The body of the loop is indented: indentation is Python’s way of grouping statements. At the interactive prompt, you have to type a tab or space(s) for each indented line. In practice you will prepare more complicated input for Python with a text editor; all decent text editors have an auto-indent facility. When a compound statement is entered interactively, it must be followed by a blank line to indicate completion (since the parser cannot guess when you have typed the last line). Note that each line within a basic block must be indented by the same amount.
The REPL can only read and evaluate one statement at a time.
You entered two statements at once.
This is possible because the REPL cannot decide if the third line is going to continue the if construction or start a whole new statement. It has to assume the former to allow indented blocks at all.
You have to make it clear to the REPL that your previous statement is finished before starting a new one.
Wrong version seems to be the most possible since, in the error it shows print. In the older python versions, print was used as print"ok", I see your operating system is windows so you can just directly download python3 from https://python.org/ have a nice day!

VS Code Python autopep8 does not honor 2 spaces hanging indentation

I'm trying to get autopep8 work to properly indent Python code with 2 spaces instead of 4. I'm using VS Code with Python extension which uses autopep8 for formatting. I found here that autopep8 can be configured to use 2 spaces by
"python.formatting.autopep8Args": ["--indent-size=2"]
But it does not work for me.
My situation is like this. When I press enter, it correctly starts the next line with the same indentation as the previous line. Press enter after an open parenthesis, it correctly starts the new line with 2 more spaces. But when I paste or save (I have "editor.formatOnPaste" and "editor.formatOnSave" set to true), the annoying thing happened: all the 2-space indentation inside the parentheses became 4 (other 2-space indentation are unaffected). Why is it doing this and how can I make it 2 spaces everywhere?
====EDIT====
I found out that the pylint error Wrong hanging indentation (remove 2 spaces). [bad-continuation]. It's because my pylintrc has indent-after-paren=2. I'm wondering if autopep8 or other Python formatter can set this property?
I also had to include this in my array in settings.json, similar to yours.
"--ignore E121"
According to https://pypi.org/project/autopep8/, this setting ensures your indents are a multiple of 4. By not enforcing that, the configured tab size in VSCode is used.
E121 - Fix indentation to be a multiple of four.
That being said, your indentation is still "acceptable" according to pep8, so it actually will not change it to the 4 spaces you are expecting in your parens. I had to outdent mine one level, then when it ran again, it didn't change it.
Unfortunately this is actually just a workaround and it actually negatively affects other indention rules...
You can see in the code for pep8 that they hardcode the default tab size to be the "python way" (4 spaces) in:
https://github.com/hhatto/autopep8/blob/120537a051d7f3cbbb5c4ede19b9e515156bd3d1/autopep8.py#L104
That makes it look like the hanging indent is just not respecting the --indent-size option...
Adding --indent-size=2 --ignore=E121 worked for me.
had the same issue, here is the solution:
Navigate to library directory of your environment
Open autopep8.py
Search for "DEFAULT_INDENT_SIZE" and change it to 2

Why am I getting an invalid syntax error in Python REPL right after IF statement?

I think this is perfectly valid.
if False:
print(1)
print(2)
However, it gives me an invalid syntax error in Python REPL.
Why is it?
On Python 3.6.5 (x64), Windows 10 RS4
As pointed out by user2357112, this behaviour is explained in https://docs.python.org/3/tutorial/introduction.html#first-steps-towards-programming,
The body of the loop is indented: indentation is Python’s way of grouping statements. At the interactive prompt, you have to type a tab or space(s) for each indented line. In practice you will prepare more complicated input for Python with a text editor; all decent text editors have an auto-indent facility. When a compound statement is entered interactively, it must be followed by a blank line to indicate completion (since the parser cannot guess when you have typed the last line). Note that each line within a basic block must be indented by the same amount.
The REPL can only read and evaluate one statement at a time.
You entered two statements at once.
This is possible because the REPL cannot decide if the third line is going to continue the if construction or start a whole new statement. It has to assume the former to allow indented blocks at all.
You have to make it clear to the REPL that your previous statement is finished before starting a new one.
Wrong version seems to be the most possible since, in the error it shows print. In the older python versions, print was used as print"ok", I see your operating system is windows so you can just directly download python3 from https://python.org/ have a nice day!

Indentation error in simple python

Update: The original question was posted using C-RET to run the lines, which produces the error. I get no such error using The menu Python > Eval region, which successfully evaluates the script.
However, using the menu for every execution is really annoying, and moreover I can't run the present line alone with that method. So my problem remains.
Forgive me if I'm missing something obvious, but I can't figure this out.
This code is giving me an IndentationError. I can't imagine what's going on.
for x in range(0, 3):
print "We're on time %d" % (x)
Here's everything related to python in my emacs.el
;; elpy
(add-to-list 'package-archives
'("elpy" . "http://jorgenschaefer.github.io/packages/"))
(package-initialize)
(elpy-enable)
You've mixed tabs and spaces. This can lead to some confusing errors.
I'd suggest using only tabs or only spaces for indentation.
Using only spaces is generally the easier choice. Most editors have an option for automatically converting tabs to spaces. If your editor has this option, turn it on.
You can paste your code in notepad to see.
All commands from menu have a command-name callable via M-x COMMAND RET.
In this case M-x python-send-region RET

Adding line breaks in ipython

If introduce a for loop in iPython, or any multi-line command, how do I go back and add lines to it? I ran this:
for row in table.find_all('tr'):
cells = row.find_all('td')
for c,cell in enumerate(cells):
print c,":",cell.get_text().strip()
try:
this = cells[0]
that = cells[1]
the_docket = cells[2]
other_thign = cells[3]
jumble = re.sub('\s+',' ',str(cells[5])).strip()
except:
"Nope"
And realized I need to add a line to it, but I can't just hit "enter" in iPython, b/c that runs the command. So can I edit that multi-line command w/in iPython?
Been suffering this problem for a while. I just found that when using Ctrl-qCtrl-j (That's lowercase Q, J, no need to hold the shift key) will add a linefeed to an existing IPython edit session.
for li in some_list: print(li)
Moving the cursor after the colon and pressing Ctrl-qCtrl-j
for li in some_list:
print(li)
IPython: 5.2.1, iTerm2: 3.0.15, macOS: 10.12.6
The %edit magic function in iPython lets you edit code in your favorite editor and will then execute it as if it was typed directly. You can also edit code you've already typed into the repl since it's stored in a special variable, for example:
In [1]: def foo(x):
...: print x
...:
In [2]: %edit _i1
There is also a way to add a newline directly in the repl: ctrl-v, ctrl-j
The ctrl-v basically lets you send a control code and then the ctrl-j is the code for a newline (line-feed). It's a bit awkward to type but has the advantage of also working in the regular Python shell as well as in Bash itself.
Edit: At least in iTerm2, you can assign it to a single hotkey as well. I set ctrl-enter to "Send hex codes" of 0x16 0x0a. Could also use cmd-enter or whatever else.
You can use ctrl+on (i.e. press the control button and enter the characters 'o', 'n' while holding it). You can also do it in two steps - ctrl+o ctrl+n but I find the former easier.
ctrl-o - enter the multiline mode
ctrl-n - access command history going forward.
But since there is no forward history, cursor just moves to the next line.
I verified that it works with both IPython 5.3.0 and IPython 7.3.0 on a machine running git bash 2.18.0 + windows 7.
A easy way of doing it is using the ;\ operator. ; to signal that its the end of a command and \ to indicate the the command follows in a new line as follows:
In[4]: password = "123";\
username = "alpha"
This will let you have multiple line commands in ipython without invoking the editor
For completeness: newer IPython versions (0.11+) have a very nice graphical console which allows you to navigate your code with the arrows and even reposition the cursor with the mouse.
In multi-line statements, some keys take on a special function (arrows to navigate, Enter to insert a line break and others). You'll have to position the cursor at the end of the last line of the statement in order to get default behaviour, e.g. get the Up arrow ↑ to mean "previous statement" instead of "move the cursor to the previous line". Or get Enter to mean "execute code" instead of "insert line break in the middle of code".
The documentation on it is a bit sparse and fragmented in different pages, so here are the essential three links for getting started with it:
Intro to the Qt Console
Configuring IPython using nice per-user profile files instead of command line arguments
You are interested in the ipython_qtconsole_config.py
How to get an ipython graphical console on Windows 7?
Type Ctrl+q then Enter. As other pointed out, Ctrl+q lets you send a character code, but hitting Ctrl+q then Enter may be more natural than Ctrl+q then Ctrl+j.
Another option is to type ( then Enter, write, and delete the ( afterwards. This solution is similar to the one where you to type ;\ to say the statement is not completed.
Bit late to the party! But I noticed many people are talking about using Ctrl combinations to add extra lines. This didn't work for me until I saw a comment about it being the Emacs binding. I have set my in line editor to be Vi, if you have too then pressing Esc to go into "Normal" mode on the line before you want to add an extra line then press o (or O if you are after the line). Just like in normal Vi(m). Works for me!

Categories

Resources