pyinvoke / invoke

Pythonic task management & command execution.
http://pyinvoke.org
BSD 2-Clause "Simplified" License
4.31k stars 365 forks source link

Collection mix-up when cross importing invoke tasks #979

Open amenasria opened 6 months ago

amenasria commented 6 months ago

Problem statement

Hey ! Just stumbled upon something working with Invoke and I don't know if that's a feature or a bug so I'm filing a small issue !

TL; DR: When having 2 collections module_a and module_b. If I import my_task_b1 from module_b to module_a, then the module_a.my_task_b1 will be a valid invoke task (i.e I can use it and inv -l lists it as well). I don't think it should be the case.

Steps to reproduce

Install invoke (pip install invoke)(I'm using 2.2.0). Here is the folder architecture:

.
└── tasks
    ├── __init__.py
    ├── module_a.py
    └── module_b.py

__init__.py

from invoke import Collection

from . import (
    module_a,
    module_b
)

ns = Collection()

ns.add_collection(module_a)
ns.add_collection(module_b)

module_a.py

from invoke import task
from .module_b import my_task_b1

@task
def my_task_a(_):
    my_task_b1(_)
    print("Hey there !")

module_b.py

from invoke import task

@task
def my_task_b1(_):
    print("Hola !")

@task
def my_task_b2(_):
    print("Hola !")

When I run inv -l I get the following invoke tasks:

Available tasks:

  module-a.my-task-a
  module-a.my-task-b1
  module-b.my-task-b1
  module-b.my-task-b2

Also running it worka:

> inv module-a.my-task-b1
Hola !

Is this on purpose ? I would expect not to have module-a.my-task-b1 !

Behaviour I would have expected

I would have expected inv -l to output

Available tasks:

  module-a.my-task-a
  module-b.my-task-b1
  module-b.my-task-b2