Hi lahwran, all, On Sun, Dec 16, 2012 at 23:34 -0700, lahwran wrote: > Hi, I've got a bit of a problem related to how pytest determines the fully > qualified name for a module. I have a django 1.3 layout project which has > an __init__.py at its root, due to oddities in how django functions. so I > have something like this layout: > > ~/project_venv/ # containing the virtualenv for the project > ~/project_venv/project/ # the directory I cd to when I work > ~/project_venv/project/.git > ~/project_venv/project/__init__.py # because django's stuff doesn't work > without it > ~/project_venv/project/applications/ > ~/project_venv/project/applications/__init__.py > ~/project_venv/project/applications/projectapp/ > ~/project_venv/project/applications/projectapp/__init__.py > ~/project_venv/project/applications/projectapp/some_file.py > ~/project_venv/project/applications/projectapp/some_other_file.py > ~/project_venv/project/applications/projectapp/tests/ > ~/project_venv/project/applications/projectapp/tests/__init__.py > ~/project_venv/project/applications/projectapp/tests/test_some_file.py > ~/project_venv/project/applications/projectapp/tests/test_some_other_file.py > > in test_some_file.py, I have something like: > > from applications.projectapp.some_file import Herp, Derp, doop > > and in test_some_other_file.py, I have something similar: > > from applications.projectapp.some_other_file import Herk, Derk, foo > from applications.projectapp.tests.test_some_file import > SomeTestUtilityThingy > > however, because project/ has an __init__.py, when pytest does its > collection, rather than importing > applications.projectapp.tests.test_some_file, it imports, > project.applications.projectapp.tests.test_some_file! worse, when > test_some_other_file.py imports test_some_file, it creates a *duplicate* - > the import creates an applications.projectapp.tests.test_some_file when > project.applications.projectapp.tests.test_some_file already existed.
evil. If it would be some arbitrary project promoting this strange __init__.py file practice i'd be inclined to say "fix it". If a project like Django really promotes this, then i guess we have to deal with it :/ > so, my question is: how can I tell pytest to please just pretend that > __init__.py doesn't exist? right now I'm using conftest.py to shove > dirname(__file__) onto sys.path, but that was written before I thought to > check if there was an __init__.py in the root of the project. It's tricky business to get sys-path manipulations workable in all the different kind of real life situations. I think nose just adds the dir of the test module to sys.path and imports it, and if another test module with the same basename exists in a different directories unloads the module. Or maybe it even always performs reloading, not sure. In nose2 this mechanism is to be dropped, anyway. In python3 unittest discovery requires a "toplevel" directory setting. If you don't set it from the command line the current working dir is used. Unless i am missing something that makes importing between test modules rather fragile. pytest always tries to import under a fully qualified name by walking the directories up that contain an __init__.py. This avoids the reloading business (which i think is not a good idea, nose2/Jason seem to agree) and, unlike unittest, it gives test modules a reliable cross-importing behaviour. Given the above problem, I think we should refine the pytest algorithm to also take existing sys.path settings into account and stop going further up if we find one. In your situation it would stop at "projects/" even though it contains an __init__.py file which would otherwise lead it to go further up. With python3.3 we need to also allow no __init__.py files at all (the new namespace import stuff) and just check directly for a sys.path that fits. Sounds like a plan? Note that i was also considering inifile-settings or new hooks to influence the behaviour. But this is not easy to get right in all situations. At least i didn't manage. Eventually i came up with the above refinement. It's anyway better if things work by default and you don't have to read lengthy explanations like this mail here :) best, holger _______________________________________________ py-dev mailing list py-dev@codespeak.net http://codespeak.net/mailman/listinfo/py-dev