Python unittest __del__ behaviour wrt modules

240 views Asked by At

I'm writing a Lua wrapper and the highest level of abstraction calls lua_close in it's __del__ method. As far as I can tell every test of this passes except the setuptools test (i.e. regular unit testing works, unit testing w/ setuptools does not). Am I doing something wrong, or is there a bug in setuptools/unittest?

My setup.py:

from setuptools import setup

setup(name="PyLua",
      version="0.1",
      description="A cffi based lua package.",
      packages=['lua'],
      author="Alex Orange",
      author_email="[email protected]",
      license="AGPLv3",
      test_suite='test',
     )

My lua/lua.py:

from math import sin

class Test(object):
    def __del__(self):
        print sin(1)

My test/lua.py:

from __future__ import absolute_import

import unittest

def load_tests(loader, tests, pattern):
    suite = unittest.TestSuite()
    tests = loader.loadTestsFromTestCase(RealCodeTestCase)
    suite.addTests(tests)
    return suite


class RealCodeTestCase(unittest.TestCase):
    def setUp(self):
        from lua.lua import Test
        self.L = Test()

    def testCallStuff(self):
        self.assertEqual(1,1)

My test2.py:

import unittest
import test.lua

suite = unittest.TestLoader().loadTestsFromTestCase(test.lua.RealCodeTestCase)
unittest.TextTestRunner(verbosity=2).run(suite)

Results of python setup.py test:

running test
running egg_info
writing PyLua.egg-info/PKG-INFO
writing top-level names to PyLua.egg-info/top_level.txt
writing dependency_links to PyLua.egg-info/dependency_links.txt
reading manifest file 'PyLua.egg-info/SOURCES.txt'
writing manifest file 'PyLua.egg-info/SOURCES.txt'
running build_ext
testCallStuff (test.lua.RealCodeTestCase) ... ok

----------------------------------------------------------------------
Ran 1 test in 0.001s

OK
Exception TypeError: "'NoneType' object is not callable" in <bound method Test.__del__ of <lua.lua.Test object at 0x7fa546ccc350>> ignored

Results of python test2.py

testCallStuff (test.lua.RealCodeTestCase) ... ok

----------------------------------------------------------------------
Ran 1 test in 0.002s

OK
0.841470984808

P.S. Python is CPython-2.7

1

There are 1 answers

1
AudioBubble On

It appears you can prevent this from happening by providing an explicit tearDown in your test:

class RealCodeTestCase(unittest.TestCase):
    def setUp(self):
        from lua.lua import Test
        self.L = Test()

    def tearDown(self):
        del self.L

    def testCallStuff(self):
        self.assertEqual(1,1)

I don't really know why the error occurs, but since the tearDown method prevents the error, my guess is that behind the scenes, setuptools implements its own variant of tearDown, which clears a bit too much, including imports, such as the from math import sin.

The error message indicates sin can't be called, since while the name exists, it has been turned into a None. I can only guess this happens somewhere in that tearDown method implemented by setuptools.