Can someone please make it more pythonic or better?

J Kenneth King james at agentultra.com
Mon Apr 19 17:30:37 CEST 2010


Oltmans <rolf.oltmans at gmail.com> writes:

> Greetings Python superstars,
>
> I've a directory structure like following
>
> tests /
> 	__init__.py
> 	testfile.py
>
> testfile.py contains following code
>
> import unittest
>
> class Calculator(unittest.TestCase):
>     def test_add(self):
>         print 'just add'
>     def test_divide(self):
>         print 'diviide'
>     def test_multiply(self):
>         print 'mul'
>
>
> class Car(unittest.TestCase):
>     def test_start(self):
>         print 'start'
>     def test_move_right(self):
>         print 'move right'
>     def test_move_left(self):
>         print 'move left'
>     def test_stop(self):
>         print 'stop'
>
>
> Now give the following user-input I want to get all test-names.
> user-input = tests.testfile (get all test-names from all
> unittest.TestCase derived classes in test.testfile)
> user-input = tests.testfile.Car (get all test-names from the Car
> class)
> user-input = tests.testfile.Cacr.test_stop
>
> and I'm doing it this the following way and I really think there has
> to be more readable, more pythonic and more possibly short way to do
> it
>
> import unittest
> import sys
> import inspect
>
> def get_test_names(full_name,module):
>     name = full_name.split('.')
>     loader = unittest.TestLoader()
>     if len(name) == 4:
>         return full_name
>     elif len(name) == 3:
>         exec "from %s.%s import %s" %(module,name[1],name[2])
>         return loader.getTestCaseNames(eval(name[2]))
>     elif len(name) == 2:
>         exec 'from %s import %s' % (module,name[1])
>         tests = []
>         for _name, obj in inspect.getmembers(sys.modules[full_name]):
>             if inspect.isclass(obj) and
> issubclass(obj,unittest.TestCase):
>                 exec "from %s.%s import %s" %
> (module,name[1],obj.__name__)
>                 tests.append(loader.getTestCaseNames(obj))
>         return tests
>
>
>
> if __name__ == "__main__":
>     input = "tests.testfile"
>     module = input.split('.')[0]
>     _tests = get_test_names(input,module)
>     print _tests
>
>
> So guys, can you kindly point me to a more Pythonic, more readable and
> possible more short way to acheive this? I will really appreciate any
> help. Many thanks in advance.

First of all, exec is bad if it's going to be processing user input.

You might want to:

>> help(__import__)

It will give you an idea on how to hook into python's import machinery
for tasks such as this.

You could also modify the function's arglist to remove the
string-splitting you're doing.  Those "magic numbers" stick out a bit.
One can understand what they're for after reading the code in this case,
but it's not quite necessary if you make a keyword argument for package
names you can pass into the 'fromlist' argument in __import__.

ie:

def get_test_names(module_name, packagelist=[]):
    ...

hth,

j_king

>
> Best regards,
> Oltmans



More information about the Python-list mailing list