fhi
fhi

Reputation: 43

python: crash inside try statement, expected behaivour?

I have had a similar problem in the past, python code crashing inside a try statement. The code fails because neither the file or the directory that it is trying to open exist. But as it is inside a try statement, i dont understand why the code breaks.

{To save any reader from spending too much time trying to understand the premise of the code. It is trying to find vertices for a region file, from;

a) a master file, if it doesnt exist or it is bad, try (b)

b) a file specific to its name, if it doesnt exist or it is bad, do (c)

c) to create a new one }

p.s. The following code is inelegant and probably won't be the final solution to what im trying to do.

    try:
        x1,y1, x2,y2 = np.loadtxt('regions/master.reg')
        plt.plot([x1,x1,x2,x2,x1],[y1,y2,y2,y1,y1], c='k')
        plt.draw()
        if (raw_input('Master Acceptable? (y/n): ') =='n'): raise(NameError)
    except NameError:
        try:
            x1,y1, x2,y2 = np.loadtxt('regions/'+self.name[:-5]+'.reg')
            plt.plot([x1,x1,x2,x2,x1],[y1,y2,y2,y1,y1], c='r')
            plt.draw()
            if raw_input('Reg Acceptable? (y/n): ') =='n': raise(NameError)

        except NameError:
            quality = False
            while not quality:
                x1=int(input('x, top left: '))
                y1=int(input('y, top right: '))
                x2=int(input('x, bottom left: '))
                y2=int(input('y, bottom right: '))
                plt.plot([x1,x1,x2,x2,x1],[y1,y2,y2,y1,y1], c='r')
                plt.draw()
                if raw_input('Acceptable? (y/n): ') =='y': quality=True

And the error (just saying that the file doesnt exist)

File "pre_science.py", line 45, in crop
  x1,y1, x2,y2 = np.loadtxt('regions/master.reg')
File "/usr/local/lib/python2.7/dist-packages/numpy/lib/npyio.py", line 917, in loadtxt
  fh = np.lib._datasource.open(fname, 'rt', encoding=encoding)
File "/usr/local/lib/python2.7/dist-packages/numpy/lib/_datasource.py", line 260, in open
  return ds.open(path, mode, encoding=encoding, newline=newline)
File "/usr/local/lib/python2.7/dist-packages/numpy/lib/_datasource.py", line 616, in open
  raise IOError("%s not found." % path)
IOError: regions/master.reg not found.

So my question being, is this an expected behaviour?

Upvotes: 0

Views: 382

Answers (3)

RaamEE
RaamEE

Reputation: 3497

You're specifying in your try-except block that you're expecting a NameError, but you're getting an IOError.

By using

try:
    ....
except NameError:
    ....

you're handling only exceptions of type NameError. All other exceptions (in your case IOError) that are thrown up are not handled anywhere, thus crashing your code.

Remove the NameError after the expect or add additional expected errors in the following manner

try:
    ....
expect NameError, IOError:
    ....

Upvotes: 1

Daniel
Daniel

Reputation: 42748

NameError is the wrong exception type, use OSError:

try:
    x1,y1, x2,y2 = np.loadtxt('regions/master.reg')
    plt.plot([x1,x1,x2,x2,x1],[y1,y2,y2,y1,y1], c='k')
    plt.draw()
    if raw_input('Master Acceptable? (y/n): ') =='n': raise OSError()
except OSError:
    try:
        x1,y1, x2,y2 = np.loadtxt('regions/'+self.name[:-5]+'.reg')
        plt.plot([x1,x1,x2,x2,x1],[y1,y2,y2,y1,y1], c='r')
        plt.draw()
        if raw_input('Reg Acceptable? (y/n): ') =='n': raise OSError()
    except OSError:
        while True:
            x1=int(input('x, top left: '))
            y1=int(input('y, top right: '))
            x2=int(input('x, bottom left: '))
            y2=int(input('y, bottom right: '))
            plt.plot([x1,x1,x2,x2,x1],[y1,y2,y2,y1,y1], c='r')
            plt.draw()
            if raw_input('Acceptable? (y/n): ') =='y':
                break

In general, NameError should not be used as user-generated exception, because a NameError indicates nearly always a programming error.

In the spirit of «don't repeat yourself» the restructured code look's like this:

from functools import partial
from itertools import cycle, chain

def input_rect():
    x1 = int(raw_input('x, top left: '))
    y1 = int(raw_input('y, top right: '))
    x2 = int(raw_input('x, bottom left: '))
    y2 = int(raw_input('y, bottom right: '))

for reader in chain([
        partial(np.loadtxt, 'regions/master.reg'),
        partial(np.loadtxt, 'regions/'+self.name[:-5]+'.reg'),
    ], cycle([input_rect]))
    try:
        x1, y1, x2, y2 = reader()
    except (ValueError, OSError):
        pass
    else:
        plt.plot([x1,x1,x2,x2,x1],[y1,y2,y2,y1,y1], c='r')
        plt.draw()
        if raw_input('Acceptable? (y/n): ') == 'y':
            break

Upvotes: 0

Sunitha
Sunitha

Reputation: 12015

You are trying to catch only NameError. Make it to catch both IOError and NameError

try:
    ...
    ...
except (IOError, NameError):
    ...
    ...

Upvotes: 0

Related Questions