I would like to write unit tests to test whether a dependency exists between two python packages. E.g.:
a/
__init__.py
models.py
views.py
...
b/
__init__.py
models.py
views.py
...
a unit test to check that modules in package b don’t import anything from modules in package a. The only solution I have so far is to scan the files and check that there isn’t a “from a” or “import a” in the source code. Are there other ways of doing this? One of the requirements is that a/ and b/ must be in the same directory level.
I would like to have this unit test because I want to be sure that I can use package b in other projects without package a, and also not have other developers write code that will make b dependent on a.
Python is too dynamic to do this 100% correctly. Consider that you can import modules by calling
__import__, which takes a string argument so the name of the module to import can be constructed at runtime. Also,__import__is a function, so it could be bound to other names, so you can’t even be sure of detecting all the cases when something is being imported.And it’s technically possible for a module to call a function from another module, which imports a module and returns it. So you definitely can’t do this by analysing just package
b.And then there’s
execto execute arbitrary python code constructed at runtime…The closest you could get is probably to try and make your unit test exercise
bwhenais on thePYTHONPATH, and also whenaisn’t on thePYTHONPATH. Still not foolproof, as that only tells you thatbcompleted all the tests withoutaon thePYTHONPATH, not that it doesn’t ever needafor anything. And if you’re really unlucky,bdoes something really stupid and fiddles withsys.pathin flight and manages to importaanyway somehow.If, however, this is all your your own code and you know you don’t do this kind of wacky crap, then a simple script that scans the files for
importstatements is probably your best bet. It would probably work very very often on random other people’s code too. It’s just not possible to do the job perfectly with full generality.