diff --git a/changelogs/fragments/75604-empty-argument-specs.yml b/changelogs/fragments/75604-empty-argument-specs.yml new file mode 100644 index 00000000000..49db731ad2a --- /dev/null +++ b/changelogs/fragments/75604-empty-argument-specs.yml @@ -0,0 +1,3 @@ +--- +bugfixes: + - roles - fix unexpected ``AttributeError`` when an empty ``argument_specs.yml`` is present (https://github.com/ansible/ansible/pull/75604). diff --git a/lib/ansible/playbook/role/__init__.py b/lib/ansible/playbook/role/__init__.py index 25c3b1679ba..8ee812a6a5d 100644 --- a/lib/ansible/playbook/role/__init__.py +++ b/lib/ansible/playbook/role/__init__.py @@ -294,7 +294,10 @@ class Role(Base, Conditional, Taggable, CollectionSearch): if self._loader.path_exists(full_path): # Note: _load_role_yaml() takes care of rebuilding the path. argument_specs = self._load_role_yaml('meta', main='argument_specs') - return argument_specs.get('argument_specs', {}) + try: + return argument_specs.get('argument_specs') or {} + except AttributeError: + return {} # We did not find the meta/argument_specs.[yml|yaml] file, so use the spec # dict from the role meta data, if it exists. Ansible 2.11 and later will diff --git a/test/integration/targets/roles_arg_spec/roles/empty_argspec/meta/argument_specs.yml b/test/integration/targets/roles_arg_spec/roles/empty_argspec/meta/argument_specs.yml new file mode 100644 index 00000000000..b592aa05b3a --- /dev/null +++ b/test/integration/targets/roles_arg_spec/roles/empty_argspec/meta/argument_specs.yml @@ -0,0 +1,2 @@ +--- +argument_specs: diff --git a/test/integration/targets/roles_arg_spec/roles/empty_argspec/tasks/main.yml b/test/integration/targets/roles_arg_spec/roles/empty_argspec/tasks/main.yml new file mode 100644 index 00000000000..90aab0e0a89 --- /dev/null +++ b/test/integration/targets/roles_arg_spec/roles/empty_argspec/tasks/main.yml @@ -0,0 +1,3 @@ +--- +- debug: + msg: "Role with empty argument_specs key" diff --git a/test/integration/targets/roles_arg_spec/roles/empty_file/meta/argument_specs.yml b/test/integration/targets/roles_arg_spec/roles/empty_file/meta/argument_specs.yml new file mode 100644 index 00000000000..ed97d539c09 --- /dev/null +++ b/test/integration/targets/roles_arg_spec/roles/empty_file/meta/argument_specs.yml @@ -0,0 +1 @@ +--- diff --git a/test/integration/targets/roles_arg_spec/roles/empty_file/tasks/main.yml b/test/integration/targets/roles_arg_spec/roles/empty_file/tasks/main.yml new file mode 100644 index 00000000000..b77b835730a --- /dev/null +++ b/test/integration/targets/roles_arg_spec/roles/empty_file/tasks/main.yml @@ -0,0 +1,3 @@ +--- +- debug: + msg: "Role with empty argument_specs.yml" diff --git a/test/integration/targets/roles_arg_spec/test.yml b/test/integration/targets/roles_arg_spec/test.yml index 06268c6a527..5eca7c73f9c 100644 --- a/test/integration/targets/roles_arg_spec/test.yml +++ b/test/integration/targets/roles_arg_spec/test.yml @@ -338,3 +338,19 @@ - debug: var=ansible_failed_result - fail: msg: "Should not get here" + +- name: "New play to reset vars: Test empty argument_specs.yml" + hosts: localhost + gather_facts: false + tasks: + - name: Import role with an empty argument_specs.yml + import_role: + name: empty_file + +- name: "New play to reset vars: Test empty argument_specs key" + hosts: localhost + gather_facts: false + tasks: + - name: Import role with an empty argument_specs key + import_role: + name: empty_argspec