0

When error occured Python prints something like this:

Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "<stdin>", line 8, in m
  File "<stdin>", line 5, in exec_st
  File "<stdin>", line 9, in exec_assign
  File "<stdin>", line 48, in ref_by_id
IndexError: list index out of range

where 2, ... , 48 are relative line numbers which are not very convenient. How to print absolute line numbers in such error messages?

EDIT: Maybe it's a dumb question, but answer will facilitate development a little. I'm printing text in several files. When done, press shortcut which runs python and copies contents of current file to console. Proposed solution forces to press excess keystrokes (Ctrl+S, Alt+Tab) and create additional files. I hope I have put it clear.

5
  • 4
    Run your program from a file rather than entering at the console or piping it in? Commented Jun 8, 2012 at 2:56
  • Thank you, but I want programmatic solution also. Commented Jun 8, 2012 at 3:05
  • 2
    Maybe you could expand your question some? It's not clear to me what you mean by absolute/relative line number. And I'm simply baffled by all the "<stdin>"s up there. What are you trying to do, and why? In particular, what is the objection to running your program from a disk file (which I think would solve your problem)? Commented Jun 8, 2012 at 3:12
  • This looks somewhat relevant: stackoverflow.com/questions/1278705/… Commented Jun 8, 2012 at 3:14
  • Maybe you could present to us a (very simplified) version of your input, the actual output you're getting, and what you'd like to get? Commented Jun 8, 2012 at 3:18

2 Answers 2

2

A few minutes of hacking around gives me this Read-Eval-Print Loop in Python 2.7:

#!/usr/bin/env python
import code
import sys

LINE_NUMBER=0

def reset_linenum():
    global LINE_NUMBER
    LINE_NUMBER=-1

def resettable_REPL():
    global LINE_NUMBER
    BUFFERED_LINES=[]
    ii=code.InteractiveInterpreter({"reset_linenum":reset_linenum})
    while True:
        try:
            BUFFERED_LINES.append(raw_input("!"+sys.ps1)+'\n')
            while (BUFFERED_LINES[-1][:1] in " \t" or
                   ii.runsource("\n"*LINE_NUMBER+"".join(BUFFERED_LINES), "console")):
                BUFFERED_LINES.append(raw_input("!"+sys.ps2)+'\n')
            LINE_NUMBER+=len(BUFFERED_LINES)
            BUFFERED_LINES=[]
        except EOFError:
            break

if __name__=='__main__':
    resettable_REPL()

It's a bit hackish, but it keeps track of line numbers as the session continues, and allows the current count to be reset by a call to reset_linenum(). An example session:

!!!> print "hello"              # line 1
hello
!!!> def badfunc():             # line 2
!...     raise Exception("doh") # line 3
!!!> badfunc()                  # line 4
Traceback (most recent call last):
  File "console", line 4, in <module>
  File "console", line 3, in badfunc
Exception: doh
!!!> ?                          # line 5
  File "console", line 5
    ?
    ^
SyntaxError: invalid syntax
!!!> reset_linenum()            # RESET
!!!> raise Exception("!")       # line 1
Traceback (most recent call last):
  File "console", line 1, in <module>
Exception: !
!!!> 

EDIT: Fixed REPL to not execute indented blocks quite so prematurely.

Sign up to request clarification or add additional context in comments.

3 Comments

Super! Though it's a bit buggy and overkill, I think. ` !!!> # unique string id !!!> def usid(): !... global Uid !!!> Uid += 1 File "<string>", line None SyntaxError: unexpected indent (console, line 4) !!!> return str(Uid) # File "<string>", line None SyntaxError: unexpected indent (console, line 5)`
Yup, caught that problem after initial post. Try now?
It works. If nobody will post more "lightweight" answer I'll accept this.
1

Doing this on Linux? Instead of having your hotkey invoke python directly, have it invoke this shell script:

#!/bin/bash
cat > /tmp/$$.py
/usr/bin/env python /tmp/$$.py
rm -f $$.py

You might also try (might even work on Windows):

import sys
exec(compile("".join([line for line in sys.stdin]), "console", "single"))

3 Comments

How to exit from input to "compile"? Ctrl+D prints "^D", Ctrl+C prints "Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyboardInterrupt"
It's Ctrl+Z hotkey. But second snippet doesn't work properly, unfortunately.
shrug Overkill? Underkill? A much simpler approach, with correspondingly less functionality

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.