Python question: how to pass method to func that fails when its passed

Childs

Lifer
Jul 9, 2000
11,313
7
81
I dont know if that makes any sense, but basically I am automating something and I know some things will fail because, well, they don't work from time to time. I still want to check everything at regular intervals. If I use a try and except block, I can move on no prob. Problem is I can have a zillion of these kinds of methods to check, and putting them all in try/except blocks is a pain in the ass. So I want to write a function that will catch the exception and move on. Here is some simple sample code:

Code:
#!/usr/bin/env python

import traceback


class TestMe:
	
	def failMe(self, str):
		raise NameError(str)
		# cause an exception to test checkIt func

def checkIt(objMethod):

	try:
		objMethod
		# Normally do more, like write status for a report
	except:
		print traceback.format_exc()
		# write fail status to a report, just printing exception in this example


newObj = TestMe()

checkIt(newObj.failMe("Forced to fail."))	

print "Do more things, like more checkIt() tests"

Now, the problem is newObj.failMe("Forced to fail.") fails before it gets to checkIt:

Code:
someones-Mac-mini:~ somedude$ ./catchFail.py 
Traceback (most recent call last):
  File "./catchFail.py", line 21, in <module>
    checkIt(newObj.failMe("Forced to fail."))	
  File "./catchFail.py", line 16, in failMe
    raise NameError(str)
NameError: Forced to fail.

Is this possible, or do I have to bite the bullet and do:

Code:
try:
	newObj.failMe("Forced to fail.")
except:
	print traceback.format_exc()

each time I want to validate a method is working?
 

Iluvatar

Member
Dec 22, 2000
91
0
66
You're actually passing the result of the failMe call to checkIt, not the method itself. To do what you want, you'll need to pass the method and its arguments separately. Something like:

Code:
def checkIt(objMethod, *args):
	try:
		objMethod(*args)
	except:
		print traceback.format_exc()

checkIt(newObj.failMe,  "Forced to fail.")
 

Childs

Lifer
Jul 9, 2000
11,313
7
81
I looked at doing that, but the problem was due to the objects I was using I wasn't sure how to pass it and the args. Here is a better example of the type of methods I was checking:

obj()[str].obj()[str].method(value)

So it would be something like:

Code:
codecType = "H.264"
propertyName = "entropy"
entropyMode = "CABAC"
newName = "%s - %s - %s" % (codecType, propertyName, entropyMode)

codec()[codecType].properties()[propertyName].setValue(entropyMode)
myCopy = codec()[codecType].properties()[propertyName].newCopy(newName)

Would it simply be:

Code:
checkIt(codec()[codecType].properties()[propertyName].setValue, entropyMode)
myCopy = checkIt(codec()[codecType].properties()[propertyName].newCopy, newName)

I have some holiday prep to do, but I will try this in my code tonight. Any thoughts are appreciated.

EDIT:

Thanks Iluvatar, this works great. For some reason when I looked at it before I didnt have it clear in my head that codec()[codecType].properties()[propertyName] is just an object, and I think I tried to pass all the variables I was using to specify the object as args in *args. I remember reading about this on stackoverflow, but for some reason it didnt click then. I guess I needed time to forget whatever it was I was doing wrong. Thanks again!
 
Last edited: