python - Fabric import bug: "fab task" vs. "from fabfile import task; task()" -
this has python's import mechanism, , using import inside function. using python 2.7.9 , fabric 1.10.0, create following 3 files:
fabfile.py:
from import another_hello def hello(): print 'hello, world' another_hello() another.py:
def another_hello(): secret import text print 'hello, world!' print 'text: ' + text secret/__init__.py: (also create folder secret/)
text = 'secret' now try fab hello. complains:
file "/home/sergey/projects/bask/service/t/fabfile.py", line 4, in hello another_hello() file "/home/sergey/projects/bask/service/t/another.py", line 2, in another_hello secret import text importerror: no module named secret at same time, can start interpreter , type from fab import hello; hello(). works perfectly:
in [2]: fabfile import hello; hello() hello, world hello, world! text: secret why difference?
now, have found hack makes work. add import secret beginning of fabfile.py. think happens fab tool works proper pythonpath when opens fabfile.py find particular task, once has imported task , started running it, changes, doesn't have access original folder longer.
is hack way go? doesn't break encapsulation, last, since fabfile.py supposed know all indirect dependencies of function or method invokes? perhaps it's argument against import statements inside functions?
this known problem in fabric. there several issues regarding in fabric's issue tracker on github. see issue #256 example.
workarounds
you can put
from secret import text on first line of another.py or add current directory module search path.
def another_hello(): import sys sys.path.insert(0, '') secret import text print 'hello, world!' print 'text: ' + text