Interaction btw unittest.assertRaises and __getattr__. Bug?

I

Inyeol

Unittest assertRaises cannot handle exception raised inside
__getattr__ method. Is it a bug? or am I missing something obvious?

Here is a sample of this problem:

-------------------------------------------------------------
import unittest

class C():

def simple_attr(self):
raise AttributeError

def __getattr__(self, name):
raise AttributeError

class Test(unittest.TestCase):

def test_simple_attr(self):
c = C()
self.assertRaises(AttributeError, c.simple_attr)

def test_getattr(self):
c = C()
self.assertRaises(AttributeError, c.foo)

unittest.main()
-----------------------------------------------------

Unittest assertRaises handles simple attribute lookup but the
exception inside __getattr__ bypasses unittest and generates
traceback:
------------------------------------------------------
E.
======================================================================
ERROR: test_getattr (__main__.Test)
----------------------------------------------------------------------
Traceback (most recent call last):
File "xxx.py", line 19, in test_getattr
self.assertRaises(AttributeError, c.foo)
File "xxx.py", line 9, in __getattr__
raise AttributeError
AttributeError

----------------------------------------------------------------------
Ran 2 tests in 0.000s

FAILED (errors=1)
--------------------------------------------------------------------------------------------------


It doesn't matter what kind of exception it raises. Any exception
inside __getattr__ bypasses assertRaises.
This happens both with 3.1.2 and 2.6.5. Any idea?

Inyeol
 
B

Benjamin Peterson

Inyeol said:
or am I missing something obvious?

The attribute access is evaluated before the call to assertRaises, so unittest
never has a cache to cache it.
 
C

Chris Rebert

The attribute access is evaluated before the call to assertRaises, so unittest
never has a
cache to cache it.

or rather, "chance to catch it."

Seems there were 2 typos.

Cheers,
Chris
 
C

Chris Torek

Inyeol said:
import unittest
class C():
def __getattr__(self, name):
raise AttributeError
class Test(unittest.TestCase):
def test_getattr(self):
c = C()
self.assertRaises(AttributeError, c.foo)
unittest.main()

As Benjamin Peterson noted, the error occurs "too soon", so that
the unittest code never has a chance to see it.

The "something obvious" is to defer the evaluation just long enough:

self.assertRaises(AttributeError, lambda: c.foo)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top