1

I am having some difficulties with exception handling in Python 3. In both Python 2.7 and 3.8, I have this snippet that gives you an idea of how I handle errors/exceptions:

## 
def tearDown(self):
  type_except, value, traceback = sys.exc_info()
  print("This is the exception type:", type_except)
  if not type_except:
    self.info("This was successful")
  elif type_except is self.failureException:
    self.warning(self.failure_message(type_except, value, tb))
    self.info("This failed")
  else:
    self.error(self.error_message(type_except, value, tb))
    self.info("This resulted in an ERROR")

In Python 2, everything works as expected, and when I have an exception, I get the error message, and I get this when I print what type_except is:

This is the exception type:

<type 'exceptions.AssertionError'>

In Python 3, when running the same test, that fails for the same reason, I get a tuple of Nones in sys.exc_info() instead. Thus, my failed tests pass.

Python 3:

This is the exception type: None

Does anyone know why this might be happening? I looked at the definitions of sys.exc_info() for both 2.7 and 3.8, but they seem the same.

--

More information: The test is as follows:

def test1_simpleLoad(self):
        '''Perform a simple load from a xxx server'''
        try:
            # Create session, connects to websocket, loads a wordset
            # Load wordset
            #compares expected response 
        finally:
            self._websocket.cleanup()

At the end of every test, the tearDown class is called, which was the code provided above ^

user_314
  • 79
  • 5
  • 1
    You need to provide a true [MCVE]; you don't actually show the code *catching* the exception. Python 3 is more aggressive about cleaning up after caught exceptions (to avoid leaving reference cycles around), and you don't show the `raise` or `try`/`except` at all. – ShadowRanger Nov 27 '20 at 20:27
  • @ShadowRanger Thank you. a minimal reproducible example is hard because this is all company code and its linked to a bunch of different files. I have given brief code on the test and tearDown class ^. The issue is that, in Python 2 and Python 3 the tests run and fail at the exact same point, but for some reason exceptions aren't logged in Python 3. sys.exc_info() is always None for Python 3. – user_314 Nov 30 '20 at 18:58
  • I doubt that `exc_info` has changed at all - more likely your unit test framework changed when `tearDown` is called. `exc_info` only works if you are *currently* handling an exception; it's possible that `tearDown` is only called after all exceptions have already been handled. – 0x5453 Nov 30 '20 at 19:08
  • @user_314 You can create a minimal test without company code, which just raises an error, as if it was a failing test. Make that kind of example which has the described behaviour. – zvone Nov 30 '20 at 19:08
  • 1
    @0x5453: Actually, while `exc_info` itself didn't change, Python started clearing exception information more aggressively in Python 3, which, among other things, means it doesn't survive long enough to be seen in a `unittest.TestCase`'s `tearDown` method. [The duplicate I linked](https://stackoverflow.com/q/4414234/364696) has solutions (with various degrees of hackery and reliance on non-public attributes) for code that needs this information. – ShadowRanger Nov 30 '20 at 19:20

0 Answers0