Ask Your Question

Exception does not show which line raised it

asked 2016-03-16 10:12:45 +0100

matlink gravatar image

Hi there,

I'm new to sage, and made some sage scripts to improve my python scripts' performances. Then I load my script into a sage session, and run a test function.

When I get exception, it shows me the traceback with functions names only, without the instruction that triggered it. For example :

sage: f.runtest()
Generating keys ...
ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-3-abdb981a9bdb> in <module>()
----> 1 f.runtest()

<string> in runtest(self)

<string> in KeyGen(self)

/home/hack4u/Download/SageMath/src/sage/rings/rational.pyx in sage.rings.rational.Rational.__mod__ (/home/hack4u/Download/SageMath/src/build/cythonized/sage/rings/rational.c:22716)()
   2541         n = rat.numer() % other
   2542         d = rat.denom() % other
-> 2543         d = d.inverse_mod(other)
   2544         return (n * d) % other

/home/hack4u/Download/SageMath/src/sage/rings/integer.pyx in sage.rings.integer.Integer.inverse_mod (/home/hack4u/Download/SageMath/src/build/cythonized/sage/rings/integer.c:38530)()
   6169         sig_off()
   6170         if r == 0:
-> 6171             raise ZeroDivisionError, "Inverse does not exist."
   6172         return ans

ZeroDivisionError: Inverse does not exist.

And I have no idea which line in KeyGen does trigger that ZeroDivisionError. Any idea ?

edit retag flag offensive close merge delete


I think it's interesting that the traceback isn't longer (maybe use pdb or As to your specific question, maybe knowing what the code is would help find where your problem is. You seem to be looking for an inverse modulo a non-prime for something not in the ring of units, maybe you can see where you do that?

kcrisman gravatar imagekcrisman ( 2016-03-16 13:55:31 +0100 )edit

In fact you didn't read my question. I don't want to resolve the exception, but I want to know which line raised it in my script. As you can see, I'm forced to make prints all along the code to search to place where there is an error. With the classic Python traceback, I can directly see where the error is :

Traceback (most recent call last):
  File "./", line 274, in <module>
    sk,pk = f.KeyGen()
  File "./", line 169, in KeyGen
ZeroDivisionError: division by zero
matlink gravatar imagematlink ( 2016-03-17 10:35:48 +0100 )edit

I did read the question, I'm just saying that as a practical matter that is all I can suggest. I don't know why there isn't a longer traceback, and I agree that is very annoying. Normally it should tell the line but perhaps something about .sage versus .py scripts is the issue.

kcrisman gravatar imagekcrisman ( 2016-03-17 19:06:12 +0100 )edit

1 Answer

Sort by ยป oldest newest most voted

answered 2016-03-17 20:51:05 +0100

nbruin gravatar image

I assume you're using load("..."). As you can see from the traceback, python is registering where it got its source from: "<string>". Ipython just doesn't know how to get line numbers for that, or how to display the string (probably because it has been forgotten). This is the standard behaviour of python's "exec":

Python 2.7.10 (default, Sep 24 2015, 17:50:09) 
[GCC 5.1.1 20150618 (Red Hat 5.1.1-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> exec "def f(): raise RuntimeError\n"
>>> f()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1, in f

(there does seem to be line information here, but the <string> file suggests there's nowhere to look this up)

On ipython's command line and its magic "%load" does store source information beyond a <string> directive.

sage: def f(): raise RuntimeError
sage: f()
RuntimeError                              Traceback (most recent call last)
<ipython-input-31-0ec059b9bfe1> in <module>()
----> 1 f()

<ipython-input-30-5041dc482b26> in f()
----> 1 def f(): raise RuntimeError

(note there's a traceback, and the source file is not just "<string>" but something that looks like a pointer into Ipython's command history)

Short version: as a workaround, you can try %load myfile.sage rather than load("myfile.sage").

In the longer run: someone could look into how Ipython stores source for loaded input and see if sage.repl.load.load can be adapted to make use of this. It might not be so easy: sage's load has to work more generally than just inside Ipython, and has to be efficient there as well. It may not be able to store source in all cases.

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower


Asked: 2016-03-16 10:10:32 +0100

Seen: 806 times

Last updated: Mar 17 '16