Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix relative imports in args rule #4216

Merged
merged 3 commits into from
Jun 19, 2024
Merged

Fix relative imports in args rule #4216

merged 3 commits into from
Jun 19, 2024

Conversation

corubba
Copy link
Contributor

@corubba corubba commented Jun 7, 2024

The args rule loads modules used in/by tasks using pythons importlib. When doing so it uses the ansible full-qualified collection name (fqcn), which works fine if the module only uses absolute imports. But if the to-be-loaded module uses relative imports, it breaks because the fqcn is different from the python qualified name (local.testcollection.module_with_relative_import vs ansible_collections.local.testcollection.plugins.modules.module_with_relative_import). As importlib and python have no idea about ansible collections, it will look for the wrong packages/modules, which manifests on the user-side in warnings like this:

% ansible-lint -vv examples/playbooks/module_relative_import.yml
[...]
DEBUG    Running rule args
WARNING  Ignored exception from ArgsRule.matchtasks while processing examples/playbooks/module_relative_import.yml (playbook): No module named 'local'
DEBUG    Ignored exception details
Traceback (most recent call last):
  File "/tmp/ansible-lint/src/ansiblelint/_internal/rules.py", line 94, in getmatches
    matches.extend(method(file))
                   ^^^^^^^^^^^^
  File "/tmp/ansible-lint/src/ansiblelint/rules/__init__.py", line 178, in matchtasks
    result = self.matchtask(task, file=file)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/tmp/ansible-lint/src/ansiblelint/rules/args.py", line 161, in matchtask
    spec.loader.exec_module(module)
  File "<frozen importlib._bootstrap_external>", line 995, in exec_module
  File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
  File "/tmp/ansible-lint/collections/ansible_collections/local/testcollection/plugins/modules/module_with_relative_import.py", line 3, in <module> 
    from ..module_utils import MY_STRING
ModuleNotFoundError: No module named 'local'
[...]

It is looking for a module (or rather package) named local because that is the parent-package in the fqcn, while the actual parent is plugins. #2813 isn't really clear on why the fqcn was used.

For testing, I added a whole local collection, which is a first in the repo and may be a bit "too much". Any advice for a better solution is appreciated.

I initially ran into this issue with the containers.podman.podman_container module, in case you want an actual example from the wild.

Fixes #4208

@corubba
Copy link
Contributor Author

corubba commented Jun 8, 2024

I give up, no idea how to make the linters happy(er).

@ssbarnea ssbarnea enabled auto-merge (squash) June 19, 2024 14:49
@corubba
Copy link
Contributor Author

corubba commented Jun 19, 2024

Just realized this is the same problem as in #4208 , and used the provided reproduce-playbook from the issue to confirm this PR fixes it too.

@ssbarnea ssbarnea merged commit 47b10b2 into ansible:main Jun 19, 2024
25 checks passed
@corubba corubba deleted the bugfix/module-relative-import branch June 19, 2024 23:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Archived in project
2 participants