Question

I'm currently writing some kind of tiny api to support extending module classes. Users should be able to just write their class name in a config and it gets used in our program. The contract is, that the class' module has a function called create(**kwargs) to return an instance of our base module class, and is placed in a special folder. But the isinstance check Fails as soon as the import is made dynamically.

modules are placed in lib/services/name

module base class (in lib/services/service)

class Service:
    def __init__(self, **kwargs):
        #some initialization

example module class (in lib/services/ping)

class PingService(Service):
    def __init__(self, **kwargs):
        Service.__init__(self,**kwargs)
        # uninteresting init

def create(kwargs):
    return PingService(**kwargs)

importing function

import sys
from lib.services.service import Service

def doimport( clazz, modPart, kw, class_check):
    path = "lib/" + modPart
    sys.path.append(path)
    mod = __import__(clazz)
    item = mod.create(kw)

    if class_check(item):
        print "im happy"
        return item

calling code

class_check = lambda service: isinstance(service, Service)
s = doimport("ping", "services", {},class_check)

print s

from lib.services.ping import create

pingService = create({})
if isinstance(pingService, Service):
    print "why this?"

what the hell am I doing wrong

here is a small example zipped up, just extract and run test.py without arguments zip example

Was it helpful?

Solution

The problem was in your ping.py file. I don't know exactly why, but when dinamically importing it was not accepting the line from service import Service, so you just have to change it to the relative path: from lib.services.service import Service. Adding lib/services to the sys.path could not make it work the inheritance, which I found strange...

Also, I am using imp.load_source which seems more robust:

import os, imp
def doimport( clazz, modPart, kw, class_check):
    path = os.path.join('lib', modPart, clazz + '.py')
    mod = imp.load_source( clazz, path )
    item = mod.create(kw)

    if class_check(item):
        print "im happy"
        return item
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top