26

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
pms
  • 4,508
  • 4
  • 25
  • 30
  • 2
    +1: I've been caught out by missing the line break after a block many times and never found a satisfactory explanation as to why it's different to a non-interactive session. – johnsyweb Oct 10 '11 at 12:07
  • 1
    that's the thing, actually this is my style of working with python right now, and because of this i need to put empty lines in the source files which i'm working on (and testing via copy-paste)... that's irritating – pms Oct 10 '11 at 12:43

9 Answers9

28

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:

Enter image description here

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:

Enter image description here

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
rplnt
  • 2,341
  • 16
  • 14
  • 1
    `ipython`, good as it is, barfs on this sample too: `SyntaxError: invalid syntax`. Try it! – johnsyweb Oct 10 '11 at 12:06
  • 1
    @Johnsyweb I'm at windows ATM and `%paste` doesn't seem to work at all (something with tkinter_clipboard). So I can't really try it. But the `%cpaste` mentioned in @naufraghi's answer works fine even with this example. – rplnt Oct 10 '11 at 12:16
  • 1
    @Johnsyweb Works for me, see examples added in my edit. However, I have a pretty recent build of ipython and I'm aware this is something that was definitely b0rked in the past. – wim Oct 10 '11 at 14:21
  • 2
    Please note that this does not "allow you to paste", this is apparently supposed to grab code from the selection (or maybe the clipboard) and run it *automagically*, while `%cpaste`, suggested in another answer, effectively *allows* you to paste manually. – njsg Mar 25 '12 at 10:20
  • For multi-line paste, there is also [DreamPie](http://www.dreampie.org/index.html) for Linux and Windows. – otterb Nov 20 '12 at 21:40
  • Would've been better if it supported just turning off auto-indent & manual paste... Inside a VM + Docker environment, I get `ERROR: Getting text from the clipboard on this platform requires Tkinter.` I suspect that you'd see the same result when pasting on a remote headless VM. Aside from X11 forwarding + clipboard support, not sure how to workaround this. – TrinitronX Jan 21 '16 at 16:44
  • After pasting multi-line text into the interpreter, you see the following messsage: – Gürol Canbek Apr 16 '16 at 14:11
  • "If you want to paste code into IPython, try the %paste and %cpaste magic functions." For %paste you may need to install python-tk package. Using %cpaste should be OK. – Gürol Canbek Apr 16 '16 at 14:22
21

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 
naufraghi
  • 1,514
  • 13
  • 16
11

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

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Awais
  • 1,803
  • 22
  • 26
7

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.

johnsyweb
  • 136,902
  • 23
  • 188
  • 247
  • 1
    yes, i've noticed this, but copy-paste testing of my sources is my python work-style right now and this thing imposes on me to put redundant empty lines everywhere... – pms Oct 10 '11 at 12:46
  • 1
    It's curious, as — IMHO — one would expect text run using shebang lines to run sligthlty in the same way as if it were sent to the stdin of the interpreter. – njsg Mar 25 '12 at 10:22
  • @Johnsyweb - unit tests are a way to go, but sometimes you work with legacy systems that are hard to unit test, or with infrastructure that runs on older Python versions without unit test support (like wlst scripts that run on jython 2.2.) – luis.espinal Jun 17 '16 at 13:43
  • This is the solution without using any tool like IPython (although I think that's a very good tool) – Ignacio Chiazzo Mar 29 '17 at 23:33
6

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)
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
eqzx
  • 5,323
  • 4
  • 37
  • 54
2

If you are like me and use Notepad++ (to copy and paste from), try to replace tabs by spaces by going to menu SettingsPreferencesLanguage and check the replace by spaces.

I had this problem myself for so long and I found out that python.exe recognizes spaces.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Flavio Rajta
  • 271
  • 3
  • 3
1

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.

Vic
  • 593
  • 7
  • 11
0
exec(pyperclip.paste())

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

mikey
  • 2,158
  • 1
  • 19
  • 24
-1

One other solution I recently found for a similar problem:

$ python << EOF
if 1:
   print "foo"
print "bar"

EOF
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
patentfox
  • 1,436
  • 2
  • 13
  • 28