os.walk error of unhandled stopIteration - python

I have written a python script and wanted to debug it using eric ide. When I was running it, an error popped up saying unhandled StopIteration
My code snippet:
datasetname='../subdataset'
dirs=sorted(next(os.walk(datasetname))[1])
I am new to python and so, I don't really know how to fix this. Why is this error popping up and how do I fix it?

os.walk will generate file names in a directory tree walking it down. It will return the contents for every directory. Since it is a generator it will raise StopIteration exception when there's no more directories to iterate. Typically when you're using it in the for loop you don't see the exception but here you're calling next directly.
If you pass non-existing directory to it will immediately raise the the exception:
>>> next(os.walk('./doesnt-exist'))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
You could modify your code to use for loop instead of next so that you wouldn't have to worry about the exception:
import os
for path, dirs, files in os.walk('./doesnt-exist'):
dirs = sorted(dirs)
break
The other option is to use try/except to catch the exception:
import os
try:
dirs = sorted(next(os.walk('./doesnt-exist')))
except StopIteration:
pass # Some error handling here

Related

python: how to get line text where exception occur, not line number

I am trying to use sys.excepthook
With below hook
def foo(type, value, traceback):
# how to print the line that except occurs
sys.excepthook = foo
and use like below
$ python3
>>> text that cause error
How to define foo such that text that cause error being printed?
EDIT
Let me add the full story, to make it clear. (deserve downvotes? -) )
What I want is not print the line, is
get the line
if the line match some criterion, modify then exec
eg,
if type
>>> import requests
>>> edit requests
get the line that exception occurs, i.e, edit requests
then exec edit(find_file(request))
where edit() use subprocess.call(), find_file use inspect to find the file where an object being defined.
Yes, I know ipython magics, and use it regularlly. this time I am ask to how to define it.
You can use the modul traceback and the passed traceback object's tb_lineno attribute:
import sys
import traceback as tb
def foo(type, value, traceback):
# how to print the line that except occurs
print("The line where the exception occurs: {}".format(tb.linecache.getline(tb.extract_tb(sys.last_traceback)[0].filename, traceback.tb_lineno)))
sys.excepthook = foo
int("text")
Out:
The line where the exception occurs: int("text")
as the the line int("text") line raised an exeption.
We can use the traceback module to help us.
def foo(type, value, trace):
print(trace.msg)
The traceback object will have lots of information about where the error occurred.

IronPython TypeError exception has no traceback

In my code I am having a TypeError exception that is crashing my code. In this one particular program (I created a test file to reproduce the error and couldn't) the traceback only says TypeError: 'int' object is unsubscriptable with no information about where it was occuring. I tried creating my own exception before the function call that this must be happening in by 1[0] and got the same problem. When I try causing a different kind of exception by foo_that_doesn't_exist() I get a proper traceback with where the error occurred. I'm running the IronPython interpreter and because of some dependencies on C# code I can't test with CPython.
EDIT: I tracked down the problem in my own code, and then found a way to reproduce it. The problem can be recreated with:
import traceback
import sys
try:
try:
1[0]
except:
raise
except:
traceback.print_tb(sys.exc_info()[2])
Which returns nothing while:
import traceback
import sys
try:
1[0]
except:
traceback.print_tb(sys.exc_info()[2])
returns
File "a.py", line 6, in <module>
1[0]

python - problems handling exception and continuing

I am building or trying to build a python script which check's a list of ip addresses (ips.txt) for a specific program using the wmi python module. However, no matter how I handle the exceptions on assets with no RPC service running the script stops running on an error. I am using python 2.7.5
Can I catch and pass the error's to proceed?
Can I catch the error and print or return a note that the ip was not alive or rpc was not running?
Thank you in advance
Here is my code:
import wmi
list = open("ips.txt")
for line in list.readlines():
asset = line.strip('\n')
c = wmi.WMI(asset)
try:
for process in c.Win32_Process (name="SbClientManager.exe"):
print asset, process.ProcessId, process.Name
except Exception:
pass
I have tried handling the exceptions in multiple way's to continue parsing my list, but the script continues to error out with the following:
Traceback (most recent call last):
File ".\check_service.py", line 12, in <module>
c = wmi.WMI(asset)
File "C:\Python27\lib\site-packages\wmi.py", line 1290, in connect
handle_com_error ()
File "C:\Python27\lib\site-packages\wmi.py", line 241, in handle_com_error
raise klass (com_error=err)
wmi.x_wmi: <x_wmi: Unexpected COM Error (-2147023174, 'The RPC server is unavailable.', None, None)>
Ultimately, I am just trying to continue the script and catch the error. Maybe a note stating that IP was not responsive would be helpful. Here are the exceptions samples that I have tried:
except Exception:
sys.exc_clear()
except:
pass
except wmi.x_wmi, x:
pass
The traceback you pasted says that the error is in the c = wmi.WMI(asset) line. You need to put that line inside the try block.
Like so:
import wmi
list = open("ips.txt")
bad_assets = []
for line in list.readlines():
asset = line.strip('\n')
try:
c = wmi.WMI(asset)
for process in c.Win32_Process (name="SbClientManager.exe"):
print asset, process.ProcessId, process.Name
except Exception:
bad_assets.append(asset)
Also, trying to catch the right exception is recommended.

Printing an exception

I'm writing a little script which catches an error (or exception). But when the exception occurs I want to have all information like the Traceback, exception name and exception message. It should also act if the exception hadn't been caught but the following code shouldn't be affected (i.d the error should be appear but script doesn't stop working).
For example: in the following code a exception will be thrown. If that happens (and only if it happens) I want to make "cleanup".
try:
1 / 0
except Exception as e:
# Printing the Exception like it would have been done if the exception hadn't been caught:
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# ZeroDivisionError: integer division or modulo by zero
# With the traceback, the exception name and the exception message.
# Doing some additional stuff.
pass
I'm not going to use a logger because the script is very smart (no longer than 100 lines) and it will only be used by me.
Edit: I'm using python 2.x
You'll want to use the traceback module:
import traceback
try:
raise Exception('what')
except Exception:
print(traceback.format_exc())
You can solve:
It should also act if the exception hadn't been caught.
with
try:
1 / 0
except Exception as e:
do_cleanup(e)
raise

Raising builtin exception with default message in python

I'm trying to implement a method that returns an error whenever a certain directory does not exist.
Rather than doing raise OSError("Directory does not exist."), however, I want to use the builtint error message from OSError: OSError: [Errno 2] No such file or directory:. This is because I am raising the exception in the beginning of the method call, rather than later (which would invoke the same message from python, without any necessary raise).
Any pointers? (other than manually doing OSError("[Errno 2] No such file or directory: "))
import os
try:
open('foo')
except IOError as err:
print(err)
print(err.args)
print(err.filename)
produces
[Errno 2] No such file or directory: 'foo'
(2, 'No such file or directory')
foo
So, to generate an OSError with a similar message use
raise OSError(2, 'No such file or directory', 'foo')
To get the error message for a given error code, you might want to use os.strerror:
>>> os.strerror(2)
'No such file or directory'
Also, you might want to use errno module to use the standard abbreviations for those errors:
>>> errno.ENOENT
2
>>> os.strerror(errno.ENOENT)
'No such file or directory'
I think that "exception" is the Python language term for what you are calling "error". So use this term as you search for more information.
You might find it useful to read the Python Standard Library documentation, "6. Built-in Exceptions".
OSError is one of the built-in exceptions. It's defined in the "Built-in Exceptions" section, which adds, "The errno attribute is a numeric error code from errno, and the strerror attribute is the corresponding string, as would be printed by the C function perror(). See the module errno, which contains names for the error codes defined by the underlying operating system."
Running this code:
raise OSError(42, "my exception string", "no_such_file.dat")
gives me this result:
Traceback (most recent call last):
Line 1, in <module>
raise OSError(42, "my exception string", "no_such_file.dat")
OSError: [Errno 42] my exception string: 'no_such_file.dat'
So, I think your code could do something like:
raise OSError(2, "No such file or directory", filename)
I think the real problem here is that you are probably doing a bunch of checks beforehand instead of just trying.
try:
[CODE]
except Exception:
[HANDLING CODE]
is much better than:
if [SPECIAL CASE]:
[HANDLING CODE]
elif [special case]:
[SPECIAL CASE]
[CODE]
try:
# ...
except OSError:
raise OSError("your answer")

Categories