Index: pychecker/pychecker/checker.py
===================================================================
--- pychecker.orig/pychecker/checker.py
+++ pychecker/pychecker/checker.py
@@ -99,7 +99,7 @@ def _flattenList(list) :
     return new_list
 
 def getModules(arg_list) :
-    "Returns a list of module names that can be imported"
+    "Returns a list of (module names, dirPath) that can be imported"
 
     new_arguments = []
     for arg in arg_list :
@@ -116,6 +116,7 @@ def getModules(arg_list) :
         
     modules = []
     for arg in _flattenList(new_arguments) :
+        arg_dir = None # actual modules will not give us a dir to load from
         # is it a .py file?
         for suf, suflen in zip(PY_SUFFIXES, PY_SUFFIX_LENS):
             if len(arg) > suflen and arg[-suflen:] == suf:
@@ -125,10 +126,12 @@ def getModules(arg_list) :
                     continue
 
                 module_name = os.path.basename(arg)[:-suflen]
-                if arg_dir not in sys.path :
-                    sys.path.insert(0, arg_dir)
+                # THOMAS: this breaks loading two .py files with same name
+                # from different dirs; we would always get the first one
+                #if arg_dir not in sys.path :
+                #    sys.path.insert(0, arg_dir)
                 arg = module_name
-        modules.append(arg)
+        modules.append((arg, arg_dir))
 
     return modules
 
@@ -161,11 +164,13 @@ def _q_find_module(p, path):
                 if os.path.exists(f):
                     return _q_file(file(f)), f, ('.ptl', 'U', 1)
 
-def _findModule(name) :
+def _findModule(name, moduleDir=None) :
     """Returns the result of an imp.find_module(), ie, (file, filename, smt)
        name can be a module or a package name.  It is *not* a filename."""
 
     path = sys.path[:]
+    if moduleDir:
+        path.insert(0, moduleDir)
     packages = string.split(name, '.')
     for p in packages :
         # smt = (suffix, mode, type)
@@ -235,8 +240,9 @@ def _getClassTokens(c) :
 class Class :
     "Class to hold all information about a class"
 
-    def __init__(self, name, module) :
+    def __init__(self, name, pcmodule) :
         self.name = name
+        module = pcmodule.module
         self.classObject = getattr(module, name)
 
         modname = getattr(self.classObject, '__module__', None)
@@ -260,7 +266,9 @@ class Class :
             self.classObject__name__ = name
 
         self.module = sys.modules.get(modname)
-        if not self.module:
+        # if the pcmodule has moduleDir, it means we processed it before,
+        # and deleted it from sys.modules
+        if not self.module and not pcmodule.moduleDir:
             self.module = module
             if modname not in cfg().blacklist:
                 sys.stderr.write("warning: couldn't find real module "
@@ -497,8 +505,13 @@ def _getPyFile(filename):
 class PyCheckerModule :
     "Class to hold all information for a module"
 
-    def __init__(self, moduleName, check = 1) :
+    def __init__(self, moduleName, check = 1, moduleDir=None) :
+        """
+        @param moduleDir: if specified, the directory where the module can
+                          be loaded from
+        """
         self.moduleName = moduleName
+        self.moduleDir = moduleDir
         self.variables = {}
         self.functions = {}
         self.classes = {}
@@ -508,7 +521,12 @@ class PyCheckerModule :
         self.main_code = None
         self.module = None
         self.check = check
-        _allModules[moduleName] = self
+        # FIXME: to make sure we have separate dict entries for different files
+        # with the same module name, we fudge in the moduleDir
+        __name = moduleName
+        if moduleDir:
+            __name = moduleName + moduleDir
+        _allModules[__name] = self
 
     def __str__(self) :
         return self.moduleName
@@ -528,7 +546,9 @@ class PyCheckerModule :
         c.addMembers(classObject)
 
     def addClass(self, name) :
-        self.classes[name] = c = Class(name, self.module)
+        #self.classes[name] = c = Class(name, self.module)
+        # give ourselves, so Class has more context
+        self.classes[name] = c = Class(name, self)
         try:
             objName = utils.safestr(c.classObject)
         except TypeError:
@@ -558,16 +578,19 @@ class PyCheckerModule :
             filename = self.module.__file__
         except AttributeError :
             filename = self.moduleName
+            if self.moduleDir:
+                filename = self.moduleDir + ': ' + filename
         return _getPyFile(filename)
 
     def load(self):
         try :
-            # there's no need to reload modules we already have
-            module = sys.modules.get(self.moduleName)
-            if module :
-                if not _allModules[self.moduleName].module :
-                    return self._initModule(module)
-                return 1
+            # there's no need to reload modules we already have if no moduleDir
+            if not self.moduleDir:
+                module = sys.modules.get(self.moduleName)
+                if module :
+                    if not _allModules[self.moduleName].module :
+                        return self._initModule(module)
+                    return 1
 
             return self._initModule(self.setupMainCode())
         except (SystemExit, KeyboardInterrupt) :
@@ -627,9 +650,19 @@ class PyCheckerModule :
         return 1
 
     def setupMainCode(self) :
-        file, filename, smt = _findModule(self.moduleName)
+        file, filename, smt = _findModule(self.moduleName, self.moduleDir)
         # FIXME: if the smt[-1] == imp.PKG_DIRECTORY : load __all__
+        # HACK: to make sibling imports work, we add self.moduleDir to sys.path
+        # temporarily, and remove it later
+        if self.moduleDir:
+            oldsyspath = sys.path[:]
+            sys.path.insert(0, self.moduleDir)
         module = imp.load_module(self.moduleName, file, filename, smt)
+        if self.moduleDir:
+            sys.path = oldsyspath
+            # to make sure that subsequent modules with the same moduleName
+            # do not persist, and getting their namespace clobbered, delete it
+            del sys.modules[self.moduleName]
         self._setupMainCode(file, filename, module)
         return module
 
@@ -736,10 +769,10 @@ def processFiles(files, cfg = None, pre_
 
     warnings = []
     utils.initConfig(_cfg)
-    for moduleName in getModules(files) :
+    for file, (moduleName, moduleDir) in zip(files, getModules(files)) :
         if callable(pre_process_cb) :
-            pre_process_cb(moduleName)
-        module = PyCheckerModule(moduleName)
+            pre_process_cb("%s (%s)" % (moduleName, file))
+        module = PyCheckerModule(moduleName, moduleDir=moduleDir)
         if not module.load() :
             w = Warning(module.filename(), 1,
                         msgs.Internal("NOT PROCESSED UNABLE TO IMPORT"))