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