djangonewbie
djangonewbie

Reputation:

python automatic (or dynamic) import classes in packages

I'm writing some kind of automated test suite and I want to make sure the classes contained in the package 'tests' get imported automatically upon runtime in the main namespace, without adding them to the __init__ file of the package.

So here is the script I have so far:

import os

for dirpath, dirnames, filenames in os.walk('tests'):
    for filename in filenames:
        if filename.lower().endswith(('.pyc', '__init__.py')): continue

        module = ".".join([dirpath, filename.split('.')[0]])

        print module

If I use modulename = __import__(module) the classes get added to the module 'modulename' and not the main namespace.

My question is, how do I import them to the current namespace?

So I can do things like:

testcase = TestCase()
testcase.run()
results = testcase.results()

or whatever in the main script without explicitly importing the classes.

Thanks in advance!

Thank you all for replying and trying to help me out.

Upvotes: 2

Views: 5156

Answers (6)

florisla
florisla

Reputation: 13528

Instead of using __import__ and assign it to a variable like this

modulename = __import__(module)

Use importlib.import_module instead, and don't assign it:

import importlib
importlib.import_module(module)

At least on Python 3.4, this works fine.

Upvotes: 0

Anurag Uniyal
Anurag Uniyal

Reputation: 88757

To get classes from some module, there can be better way but here is generic way to get you started

mod = __import__("mod")
for klass in vars(mod):
    o =  getattr(mod, klass)
    if type(o) == type:
        print o

Upvotes: 3

Bryce Drennan
Bryce Drennan

Reputation: 709

Place this code in __init__.py of the tests package and it will import all tests in the current package and subpackages.

import pkgutil
import unittest

for loader, module_name, is_pkg in pkgutil.walk_packages(__path__):
    module = loader.find_module(module_name).load_module(module_name)
    for name in dir(module):
        obj = getattr(module, name)
        if isinstance(obj, type) and issubclass(obj, unittest.case.TestCase):
            exec ('%s = obj' % obj.__name__)

As others have said, if you're trying to have all of your tests discovered, there are better ways.

Upvotes: 0

Sean
Sean

Reputation: 547

you could use the exec on a formatted string for each module name in your scanned directory:

exec "from %s import *" % moduleName

Upvotes: 0

Noah
Noah

Reputation: 22656

I'm not sure I exactly understand your question, but you might try nose to discover your test suites.

Upvotes: 1

Anurag Uniyal
Anurag Uniyal

Reputation: 88757

I do not fully understand the need because you can collect all the modules and iterate thru test case classes

but if you do want to get all names in current scope use something like

execfile("mod.py")

it will get all classed defined in mod.py into scope

Upvotes: -1

Related Questions