Strange behavior of eval() breaks unittest
Question: I have been prototyping and not minding the low-quality code that assigned a
variable which took it's value from calling eval() on argv, which in turn
picked up it's value in external file containing API keys. To my surprise it
badly crashed unit testing (None of them even ran).

Here is the code snippet which I believe to be the culprit:

    
    
    from sys import argv
    from apikeys import *
    
    
    def setKey(the_key=DCK):
        global CK
        CK = the_key # Currently used key
    
    if len(argv) == 1:
        print('---Executing script. Enter optional arguments if you wish to use special API keys.---')
        setKey()
    elif len(argv) > 1:
        setKey(eval(argv[1]))
    
    TOKEN = rget(DOMAIN+'signin', params={'key':CK}).json['response']['token']
    PARAMS = {'signature':TESTSIG, 'token':TOKEN}
    
    # Rest of the code uses unittests which rely on PARAMS.
    

So I pass one of the variables containing key as it's value to test my script,
it produces the following traceback:

    
    
    [gp@imdev1 dv1/tests]# python 2test_api2.py ANDROID_FILMS_KEY
    Traceback (most recent call last):
      File "2test_api2.py", line 604, in <module>
        unittest.main()
      File "/usr/lib/python2.6/site-packages/unittest2/main.py", line 97, in __init__
        self.parseArgs(argv)
      File "/usr/lib/python2.6/site-packages/unittest2/main.py", line 152, in parseArgs
        self.createTests()
      File "/usr/lib/python2.6/site-packages/unittest2/main.py", line 161, in createTests
        self.module)
      File "/usr/lib/python2.6/site-packages/unittest2/loader.py", line 148, in loadTestsFromNames
        suites = [self.loadTestsFromName(name, module) for name in names]
      File "/usr/lib/python2.6/site-packages/unittest2/loader.py", line 142, in loadTestsFromName
        raise TypeError("don't know how to make test from: %s" % obj)
    TypeError: don't know how to make test from: 9b269ac759211de6b3c8b238bd758ccf
    

9b269ac759211de6b3c8b238bd758ccf is basically the result of running
eval(ANDROID_FILMS_KEY) and running setKey function in a separate script
correctly assigns the API key to CK as string
'9b269ac759211de6b3c8b238bd758ccf'

The kicker is as follows: When CK and PARAMS are used in classes containing
methods that should be unit-tested Python surprisingly raises the bizarre
exception which supposedly tells that unittest doesn't consider
9b269ac759211de6b3c8b238bd758ccf a string?


Answer: The `unittest2` loader _also_ inspects `sys.argv`, to let you limit the
modules loaded for testing [from the command
line](http://www.voidspace.org.uk/python/articles/unittest2.shtml#command-
line-behaviour).

What happens here is that the loader is looking for a test module named
`9b269ac759211de6b3c8b238bd758ccf`.

You'll have to manipulate `sys.argv` from your unittest instead; it's a
standard python list that you can alter. Alternatively, create a `main(args)`
function that, by default, you call with `sys.argv[1:]`:

    
    
    def main(args):
        if not args:
            print('---Executing script. Enter optional arguments if you wish to use special API keys.---')
            setKey()
        else:
            setKey(eval(args[0]))
    
    if __name__ == '__main__':
        import sys
        main(sys.argv[1:])
    

and now you can test `main()` with different arguments without having to rely
on passing arguments to your test script.

