2016-05-01 9 views
0

Zusammenfassung: Mit PyDev kann ich kein Python-Modul (FooTest) zum Importieren eines anderen (FooMock) in den gleichen (Test-) Quellordner bekommen.PyDev aus sekundären Quellordnern importieren

Ich habe zwei Quellordner und vier Python-Module, mit der Verzeichnisstruktur unten. Der minimale Beispielcode steht am Ende der Frage. Obwohl ich viele Informationen zur Verfügung gestellt habe, lassen Sie sich davon nicht einschüchtern - es ist ein einfaches Problemszenario.

PyDevProject/ 
    src/   (source folder for prod code) 
    foo/ 
     __init__.py 
     Bar.py 
     Foo.py 
    test/  (source folder for tests) 
    foo/ 
     __init__.py 
     FooMock.py 
     FooTest.py 

Das Problem hier ist, dass, wenn ich im FooTest Modul zu importieren FooMock Klasse versuchen, ich die folgende Fehlermeldung erhalten (PyUnit läuft die FooTest Tests ausführen):

Finding files... done. 
Importing test modules ... Traceback (most recent call last): 
    File "/Applications/Eclipse.app/Contents/Eclipse/plugins/org.python.pydev_4.5.4.201601292234/pysrc/_pydev_runfiles/pydev_runfiles.py", line 468, in __get_module_from_str 
mod = __import__(modname) 
    File "/Users/me/Development/krtiWorkspace/ImportTest/test/foo/FooTest.py", line 4, in <module> 
    from foo.FooMock import FooMock 
ImportError: No module named FooMock 
ERROR: Module: FooTest could not be imported (file: /Users/me/Development/krtiWorkspace/ImportTest/test/foo/FooTest.py). 
done. 

---------------------------------------------------------------------- 
Ran 0 tests in 0.000s 

OK 

Dinge, die ich habe versucht:

  • Obwohl FooMock und FooTest beide im selben Python-Paket sind, kann FooMock nicht importiert werden.
  • Das Verschieben von FooMock in das Verzeichnis src/ funktioniert, selbst wenn es unter einem eindeutigen Python-Paket platziert wird (solange es unter src/ steht). Aber das ist für mich nicht akzeptabel (um Testcode in den Produktionsquellordnern zu haben).
  • Ich habe sichergestellt, dass die PYTHONPATH-Einstellungen in PyDev festgelegt sind, um anzugeben, dass beide Ordner Quellordner sind.
  • Das Kopieren und Einfügen des FooMock-Codes in den FooTest-Code funktioniert. Aber das ist nicht akzeptabel für mich (da ich FooMock an anderer Stelle in mehreren Testdateien referenzieren möchte und ich nicht möchte, dass mehrere Kopien von FooMock konsequent herumschweben).

Kann ich irgendetwas dagegen tun?

Code:

# Code for Bar.py ----------------------------------------------------- 
class Bar(object): 
    def __init__(self, foo): 
     self.foo = foo 
    def next(self): 
     self.foo.incr() 

# Code for Foo.py ----------------------------------------------------- 
class Foo(object): 
    def __init__(self): 
     self.num = 0 
    def incr(self): 
     self.num = self.num + 1 

# Code for FooMock.py ------------------------------------------------- 
class FooMock(object): 
    def mock_incr(self): 
     self.hit = True 

# Code for FooTest.py ------------------------------------------------- 
import unittest 
from foo.Foo import Foo 
from foo.Bar import Bar 
from foo.FooMock import FooMock 

class Test(unittest.TestCase): 
    def test_Foo(self): 
     foo = Foo() 
     foo.incr() 
     self.assertEquals(1, foo.num, "should be 1") 
    def test_Bar(self): 
     foo = FooMock() 
     bar = Bar(foo) 
     bar.next() 

if __name__ == "__main__": 
    unittest.main() 

Screenshot von Verzeichnis: Image showing directory structure and PYTHONPATH as previously explained

Antwort

0

Sie haben ein Modul foo in Ihrem PYTHONPATH zweimal genannt. In dem ersten Verzeichnis, in dem das Paket foo gefunden wird, gibt es tatsächlich kein Modul mit dem Namen FooMock.

Können Sie das Modul foo unter dem Test Quellverzeichnis zu etwas anderem umbenennen? Wie footests anstelle von foo?

+0

Das war das Problem! Hier nahm ich an, dass dies wie Java war. Anfängerfehler. Danke @Grepe. Um das zu bestätigen, hat das Umbenennen des Test/Foo-Pakets zu Test/Footest Python erlaubt, FooMock zu finden. –

+0

Eine kleine Erweiterung zu meiner Frage: Müssen alle Python-Pakete eindeutig sein? I.e. Kann ich SRC/foo.bar und TEST/tests.foo.bar haben? Ich überprüfe jetzt auf jeden Fall. –

+0

Sie können das Paket erweitern, nachdem Sie es in Ihren Code importiert haben (dies wird als "Affe-Patching" bezeichnet, siehe dieses SO-Thema zum Beispiel: http://stackoverflow.com/questions/5626193/what-is-a) -Monkey-Patch). aber die Art, wie der Import funktioniert, ist, dass er nach dem Paket in jedem der Verzeichnisse sucht, die in Ihrem PYTHONPATH in der Reihenfolge enthalten sind, und sobald es es findet, hört es dort auf. Wenn das Paket mehrere Male im Pfad ist, wird es nur beim ersten Mal eingeschlossen, und nur der Code aus dieser ersten Definition wird verwendet. – grepe