You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
It first sets enclosing_dir to be the parent directory of whatever file the import resolved to (this is tasks.py for modules, and __init__.py within the package directory for packages). Then, it checks if the discovered ModuleSpec has a non-empty entry for .parent, which would indicate that the imported tasks is a package. If it is a package, it sets module_parent to be one level above enclosing_dir. If it is not a package, module_parent is set to be enclosing_dir.
Bug
This is all correct, however the path that gets inserted into the path is always enclosing_dir, notmodule_parent. If we have:
foo
| -- pyinvoke
| -- tasks.py
and then resolve the ModuleSpec for tasks, we correctly insert /foo/pyinvoke into the path. However, if we have:
foo
| -- pyinvoke
| -- tasks
| -- __init__.py
we end up inserting /foo/pyinvoke/tasks into the path, which is wrong, the path inserted should still be /foo/pyinvoke.
Note: #944 is similar but predates the refactor to load that happened in 2.1.3. In aa8b815 logic was added to fix the search path for config files, but that did not extend to search path for packages.
Note 2: This is all fine and dandy for most use cases where everything lives in tasks or tasks.py. This only broke because we have the following structure:
From within foo_task.py we have from barutils.bar import bartender, which won't work when the inserted path is /foo/pyinvoke/tasks/ since barutils isn't in tasks.
I've compared sys.path between venvs with invoke==1.7.1 and invoke==2.2.0. When invoke is run from project directory (I will use examples above) /foo, in the former version sys.path gives ['/foo/pyinvoke', ...] but for latter version it returns ['/foo/pyinvoke/tasks', ...] which is the reason why I can't import from module on the same level as /foo/barutils.
Moreover all commands in invoke -l changed from barutils.command-x to just command-x.
Currently I have no other solution for this broken version than "hacking" sys.path by replacing manually the first path which still leaves all commands changed to version without barutils..
Hack is to add this to foo_task.py:
Background
In
loader.py
,invoke
uses thisload
function to load thetasks
collection. This function attempts to detect whethertasks
is a module or a package:invoke/invoke/loader.py
Lines 49 to 96 in 07b836f
It first sets
enclosing_dir
to be the parent directory of whatever file the import resolved to (this istasks.py
for modules, and__init__.py
within the package directory for packages). Then, it checks if the discoveredModuleSpec
has a non-empty entry for.parent
, which would indicate that the importedtasks
is a package. If it is a package, it setsmodule_parent
to be one level aboveenclosing_dir
. If it is not a package,module_parent
is set to beenclosing_dir
.Bug
This is all correct, however the path that gets inserted into the path is always
enclosing_dir
, notmodule_parent
. If we have:and then resolve the
ModuleSpec
fortasks
, we correctly insert/foo/pyinvoke
into the path. However, if we have:we end up inserting
/foo/pyinvoke/tasks
into the path, which is wrong, the path inserted should still be/foo/pyinvoke
.Note: #944 is similar but predates the refactor to
load
that happened in 2.1.3. In aa8b815 logic was added to fix the search path for config files, but that did not extend to search path for packages.Note 2: This is all fine and dandy for most use cases where everything lives in
tasks
ortasks.py
. This only broke because we have the following structure:From within
foo_task.py
we havefrom barutils.bar import bartender
, which won't work when the inserted path is/foo/pyinvoke/tasks/
sincebarutils
isn't intasks
.Solution?
I'd like to propose that in:
invoke/invoke/loader.py
Line 85 in 07b836f
we replace
enclosing_dir
withmodule_parent
.@bitprophet if this fix seems reasonable I can put in a PR and add some tests for this.
The text was updated successfully, but these errors were encountered: