We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Task name is overridden by include_role, and is not evaluated in output
<!---
Verify first that your issue/request is not already reported on GitHub.
THIS FORM WILL BE READ BY A MACHINE, COMPLETE ALL SECTIONS AS DESCRIBED.
Also test if the latest release, and devel branch are affected too.
ALWAYS add information AFTER (OUTSIDE) these html comments.
Otherwise it may end up being automatically closed by our bot. -->

##### SUMMARY
<!--- Explain the problem briefly -->
When using `include_role`, the `name` parameter given to it appears to override the `name` parameter given to the task itself. Additionally, if jinja2 was being used to determine which role to include, that is not evaluated and is printed raw, which is not useful to an observer.

##### ISSUE TYPE
 - Bug Report

##### COMPONENT NAME
<!--- Insert, BELOW THIS COMMENT, the name of the module, plugin, task or feature.
Do not include extra details here, e.g. "vyos_command" not "the network module vyos_command" or the full path-->
include_role

##### ANSIBLE VERSION
<!--- Paste, BELOW THIS COMMENT, verbatim output from "ansible --version" between quotes below -->
```
ansible 2.6.1
```

##### CONFIGURATION
<!--- If using Ansible 2.4 or above, paste, BELOW THIS COMMENT, the results of "ansible-config dump --only-changed"
Otherwise, mention any settings you have changed/added/removed in ansible.cfg
(or using the ANSIBLE_* environment variables).-->

##### OS / ENVIRONMENT
<!--- Mention, BELOW THIS COMMENT, the OS you are running Ansible from, and the OS you are
managing, or say "N/A" for anything that is not platform-specific.
Also mention the specific version of what you are trying to control,
e.g. if this is a network bug the version of firmware on the network device.-->
Red Hat Enterprise Linux Server release 7.4 (Maipo)

##### STEPS TO REPRODUCE
<!--- For bugs, show exactly how to reproduce the problem, using a minimal test-case.
For new features, show how the feature would be used. -->

<!--- Paste example playbooks or commands between quotes below -->
Playbook
```yaml
- name: "test"
  hosts: localhost
  gather_facts: no
  connection: local

  vars:
    role_type: a

  tasks:
    - name: Role inclusion test
      include_role:
        name: "role-{{ role_type }}"
```
roles/role-a/tasks/main.yml
```yaml
---
- debug: msg="This is Role A"
```
<!--- You can also paste gist.github.com links for larger files -->

##### EXPECTED RESULTS
```
PLAY [test] ********************************************************************

TASK [Role inclusion test] *****************************************************

TASK [role-a : debug] **********************************************************
[...]
```
Or, less preferably:
```
PLAY [test] ********************************************************************

TASK [include_role : role-a *************************************

TASK [role-a : debug] **********************************************************
[...]
```
##### ACTUAL RESULTS
```
PLAY [test] ********************************************************************

TASK [include_role : role-{{ role_type }}] *************************************

TASK [role-a : debug] **********************************************************
[...]
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `lib/ansible/playbook/role_include.py`
Content:
```
1 
2 #
3 # This file is part of Ansible
4 #
5 # Ansible is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # Ansible is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
17 
18 # Make coding more python3-ish
19 from __future__ import (absolute_import, division, print_function)
20 __metaclass__ = type
21 
22 from os.path import basename
23 
24 from ansible.errors import AnsibleParserError
25 from ansible.playbook.attribute import FieldAttribute
26 from ansible.playbook.block import Block
27 from ansible.playbook.task_include import TaskInclude
28 from ansible.playbook.role import Role
29 from ansible.playbook.role.include import RoleInclude
30 
31 try:
32     from __main__ import display
33 except ImportError:
34     from ansible.utils.display import Display
35     display = Display()
36 
37 __all__ = ['IncludeRole']
38 
39 
40 class IncludeRole(TaskInclude):
41 
42     """
43     A Role include is derived from a regular role to handle the special
44     circumstances related to the `- include_role: ...`
45     """
46 
47     BASE = ('name', 'role')  # directly assigned
48     FROM_ARGS = ('tasks_from', 'vars_from', 'defaults_from')  # used to populate from dict in role
49     OTHER_ARGS = ('apply', 'private', 'public', 'allow_duplicates')  # assigned to matching property
50     VALID_ARGS = tuple(frozenset(BASE + FROM_ARGS + OTHER_ARGS))  # all valid args
51 
52     # =================================================================================
53     # ATTRIBUTES
54 
55     # private as this is a 'module options' vs a task property
56     _allow_duplicates = FieldAttribute(isa='bool', default=True, private=True)
57     _private = FieldAttribute(isa='bool', default=None, private=True)
58     _public = FieldAttribute(isa='bool', default=False, private=True)
59 
60     def __init__(self, block=None, role=None, task_include=None):
61 
62         super(IncludeRole, self).__init__(block=block, role=role, task_include=task_include)
63 
64         self._from_files = {}
65         self._parent_role = role
66         self._role_name = None
67         self._role_path = None
68 
69     def get_name(self):
70         ''' return the name of the task '''
71         return "%s : %s" % (self.action, self._role_name)
72 
73     def get_block_list(self, play=None, variable_manager=None, loader=None):
74 
75         # only need play passed in when dynamic
76         if play is None:
77             myplay = self._parent._play
78         else:
79             myplay = play
80 
81         ri = RoleInclude.load(self._role_name, play=myplay, variable_manager=variable_manager, loader=loader)
82         ri.vars.update(self.vars)
83 
84         # build role
85         actual_role = Role.load(ri, myplay, parent_role=self._parent_role, from_files=self._from_files,
86                                 from_include=True)
87         actual_role._metadata.allow_duplicates = self.allow_duplicates
88 
89         if self.statically_loaded or self.public:
90             myplay.roles.append(actual_role)
91 
92         # save this for later use
93         self._role_path = actual_role._role_path
94 
95         # compile role with parent roles as dependencies to ensure they inherit
96         # variables
97         if not self._parent_role:
98             dep_chain = []
99         else:
100             dep_chain = list(self._parent_role._parents)
101             dep_chain.append(self._parent_role)
102 
103         blocks = actual_role.compile(play=myplay, dep_chain=dep_chain)
104         for b in blocks:
105             b._parent = self
106 
107         # updated available handlers in play
108         handlers = actual_role.get_handler_blocks(play=myplay)
109         for h in handlers:
110             h._parent = self
111         myplay.handlers = myplay.handlers + handlers
112         return blocks, handlers
113 
114     @staticmethod
115     def load(data, block=None, role=None, task_include=None, variable_manager=None, loader=None):
116 
117         ir = IncludeRole(block, role, task_include=task_include).load_data(data, variable_manager=variable_manager, loader=loader)
118 
119         # Validate options
120         my_arg_names = frozenset(ir.args.keys())
121 
122         # name is needed, or use role as alias
123         ir._role_name = ir.args.get('name', ir.args.get('role'))
124         if ir._role_name is None:
125             raise AnsibleParserError("'name' is a required field for %s." % ir.action, obj=data)
126 
127         if 'public' in ir.args and ir.action != 'include_role':
128             raise AnsibleParserError('Invalid options for %s: private' % ir.action, obj=data)
129 
130         if 'private' in ir.args:
131             display.deprecated(
132                 msg='Supplying "private" for "%s" is a no op, and is deprecated' % ir.action,
133                 version='2.8'
134             )
135 
136         # validate bad args, otherwise we silently ignore
137         bad_opts = my_arg_names.difference(IncludeRole.VALID_ARGS)
138         if bad_opts:
139             raise AnsibleParserError('Invalid options for %s: %s' % (ir.action, ','.join(list(bad_opts))), obj=data)
140 
141         # build options for role includes
142         for key in my_arg_names.intersection(IncludeRole.FROM_ARGS):
143             from_key = key.replace('_from', '')
144             ir._from_files[from_key] = basename(ir.args.get(key))
145 
146         apply_attrs = ir.args.pop('apply', {})
147         if apply_attrs and ir.action != 'include_role':
148             raise AnsibleParserError('Invalid options for %s: apply' % ir.action, obj=data)
149         elif apply_attrs:
150             apply_attrs['block'] = []
151             p_block = Block.load(
152                 apply_attrs,
153                 play=block._play,
154                 parent_block=block,
155                 role=role,
156                 task_include=task_include,
157                 use_handlers=block._use_handlers,
158                 variable_manager=variable_manager,
159                 loader=loader,
160             )
161             ir._parent = p_block
162 
163         # manual list as otherwise the options would set other task parameters we don't want.
164         for option in my_arg_names.intersection(IncludeRole.OTHER_ARGS):
165             setattr(ir, option, ir.args.get(option))
166 
167         return ir
168 
169     def copy(self, exclude_parent=False, exclude_tasks=False):
170 
171         new_me = super(IncludeRole, self).copy(exclude_parent=exclude_parent, exclude_tasks=exclude_tasks)
172         new_me.statically_loaded = self.statically_loaded
173         new_me._from_files = self._from_files.copy()
174         new_me._parent_role = self._parent_role
175         new_me._role_name = self._role_name
176         new_me._role_path = self._role_path
177 
178         return new_me
179 
180     def get_include_params(self):
181         v = super(IncludeRole, self).get_include_params()
182         if self._parent_role:
183             v.update(self._parent_role.get_role_params())
184         return v
185
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/lib/ansible/playbook/role_include.py b/lib/ansible/playbook/role_include.py
--- a/lib/ansible/playbook/role_include.py
+++ b/lib/ansible/playbook/role_include.py
@@ -68,7 +68,7 @@
 
     def get_name(self):
         ''' return the name of the task '''
-        return "%s : %s" % (self.action, self._role_name)
+        return self.name or "%s : %s" % (self.action, self._role_name)
 
     def get_block_list(self, play=None, variable_manager=None, loader=None):

{"golden_diff": "diff --git a/lib/ansible/playbook/role_include.py b/lib/ansible/playbook/role_include.py\n--- a/lib/ansible/playbook/role_include.py\n+++ b/lib/ansible/playbook/role_include.py\n@@ -68,7 +68,7 @@\n \n     def get_name(self):\n         ''' return the name of the task '''\n-        return \"%s : %s\" % (self.action, self._role_name)\n+        return self.name or \"%s : %s\" % (self.action, self._role_name)\n \n     def get_block_list(self, play=None, variable_manager=None, loader=None):\n", "issue": "Task name is overridden by include_role, and is not evaluated in output\n<!---\r\nVerify first that your issue/request is not already reported on GitHub.\r\nTHIS FORM WILL BE READ BY A MACHINE, COMPLETE ALL SECTIONS AS DESCRIBED.\r\nAlso test if the latest release, and devel branch are affected too.\r\nALWAYS add information AFTER (OUTSIDE) these html comments.\r\nOtherwise it may end up being automatically closed by our bot. -->\r\n\r\n##### SUMMARY\r\n<!--- Explain the problem briefly -->\r\nWhen using `include_role`, the `name` parameter given to it appears to override the `name` parameter given to the task itself. Additionally, if jinja2 was being used to determine which role to include, that is not evaluated and is printed raw, which is not useful to an observer.\r\n\r\n##### ISSUE TYPE\r\n - Bug Report\r\n\r\n##### COMPONENT NAME\r\n<!--- Insert, BELOW THIS COMMENT, the name of the module, plugin, task or feature.\r\nDo not include extra details here, e.g. \"vyos_command\" not \"the network module vyos_command\" or the full path-->\r\ninclude_role\r\n\r\n##### ANSIBLE VERSION\r\n<!--- Paste, BELOW THIS COMMENT, verbatim output from \"ansible --version\" between quotes below -->\r\n```\r\nansible 2.6.1\r\n```\r\n\r\n##### CONFIGURATION\r\n<!--- If using Ansible 2.4 or above, paste, BELOW THIS COMMENT, the results of \"ansible-config dump --only-changed\"\r\nOtherwise, mention any settings you have changed/added/removed in ansible.cfg\r\n(or using the ANSIBLE_* environment variables).-->\r\n\r\n##### OS / ENVIRONMENT\r\n<!--- Mention, BELOW THIS COMMENT, the OS you are running Ansible from, and the OS you are\r\nmanaging, or say \"N/A\" for anything that is not platform-specific.\r\nAlso mention the specific version of what you are trying to control,\r\ne.g. if this is a network bug the version of firmware on the network device.-->\r\nRed Hat Enterprise Linux Server release 7.4 (Maipo)\r\n\r\n##### STEPS TO REPRODUCE\r\n<!--- For bugs, show exactly how to reproduce the problem, using a minimal test-case.\r\nFor new features, show how the feature would be used. -->\r\n\r\n<!--- Paste example playbooks or commands between quotes below -->\r\nPlaybook\r\n```yaml\r\n- name: \"test\"\r\n  hosts: localhost\r\n  gather_facts: no\r\n  connection: local\r\n\r\n  vars:\r\n    role_type: a\r\n\r\n  tasks:\r\n    - name: Role inclusion test\r\n      include_role:\r\n        name: \"role-{{ role_type }}\"\r\n```\r\nroles/role-a/tasks/main.yml\r\n```yaml\r\n---\r\n- debug: msg=\"This is Role A\"\r\n```\r\n<!--- You can also paste gist.github.com links for larger files -->\r\n\r\n##### EXPECTED RESULTS\r\n```\r\nPLAY [test] ********************************************************************\r\n\r\nTASK [Role inclusion test] *****************************************************\r\n\r\nTASK [role-a : debug] **********************************************************\r\n[...]\r\n```\r\nOr, less preferably:\r\n```\r\nPLAY [test] ********************************************************************\r\n\r\nTASK [include_role : role-a *************************************\r\n\r\nTASK [role-a : debug] **********************************************************\r\n[...]\r\n```\r\n##### ACTUAL RESULTS\r\n```\r\nPLAY [test] ********************************************************************\r\n\r\nTASK [include_role : role-{{ role_type }}] *************************************\r\n\r\nTASK [role-a : debug] **********************************************************\r\n[...]\r\n```\r\n\n", "before_files": [{"content": "\n#\n# This file is part of Ansible\n#\n# Ansible is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# Ansible is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.\n\n# Make coding more python3-ish\nfrom __future__ import (absolute_import, division, print_function)\n__metaclass__ = type\n\nfrom os.path import basename\n\nfrom ansible.errors import AnsibleParserError\nfrom ansible.playbook.attribute import FieldAttribute\nfrom ansible.playbook.block import Block\nfrom ansible.playbook.task_include import TaskInclude\nfrom ansible.playbook.role import Role\nfrom ansible.playbook.role.include import RoleInclude\n\ntry:\n    from __main__ import display\nexcept ImportError:\n    from ansible.utils.display import Display\n    display = Display()\n\n__all__ = ['IncludeRole']\n\n\nclass IncludeRole(TaskInclude):\n\n    \"\"\"\n    A Role include is derived from a regular role to handle the special\n    circumstances related to the `- include_role: ...`\n    \"\"\"\n\n    BASE = ('name', 'role')  # directly assigned\n    FROM_ARGS = ('tasks_from', 'vars_from', 'defaults_from')  # used to populate from dict in role\n    OTHER_ARGS = ('apply', 'private', 'public', 'allow_duplicates')  # assigned to matching property\n    VALID_ARGS = tuple(frozenset(BASE + FROM_ARGS + OTHER_ARGS))  # all valid args\n\n    # =================================================================================\n    # ATTRIBUTES\n\n    # private as this is a 'module options' vs a task property\n    _allow_duplicates = FieldAttribute(isa='bool', default=True, private=True)\n    _private = FieldAttribute(isa='bool', default=None, private=True)\n    _public = FieldAttribute(isa='bool', default=False, private=True)\n\n    def __init__(self, block=None, role=None, task_include=None):\n\n        super(IncludeRole, self).__init__(block=block, role=role, task_include=task_include)\n\n        self._from_files = {}\n        self._parent_role = role\n        self._role_name = None\n        self._role_path = None\n\n    def get_name(self):\n        ''' return the name of the task '''\n        return \"%s : %s\" % (self.action, self._role_name)\n\n    def get_block_list(self, play=None, variable_manager=None, loader=None):\n\n        # only need play passed in when dynamic\n        if play is None:\n            myplay = self._parent._play\n        else:\n            myplay = play\n\n        ri = RoleInclude.load(self._role_name, play=myplay, variable_manager=variable_manager, loader=loader)\n        ri.vars.update(self.vars)\n\n        # build role\n        actual_role = Role.load(ri, myplay, parent_role=self._parent_role, from_files=self._from_files,\n                                from_include=True)\n        actual_role._metadata.allow_duplicates = self.allow_duplicates\n\n        if self.statically_loaded or self.public:\n            myplay.roles.append(actual_role)\n\n        # save this for later use\n        self._role_path = actual_role._role_path\n\n        # compile role with parent roles as dependencies to ensure they inherit\n        # variables\n        if not self._parent_role:\n            dep_chain = []\n        else:\n            dep_chain = list(self._parent_role._parents)\n            dep_chain.append(self._parent_role)\n\n        blocks = actual_role.compile(play=myplay, dep_chain=dep_chain)\n        for b in blocks:\n            b._parent = self\n\n        # updated available handlers in play\n        handlers = actual_role.get_handler_blocks(play=myplay)\n        for h in handlers:\n            h._parent = self\n        myplay.handlers = myplay.handlers + handlers\n        return blocks, handlers\n\n    @staticmethod\n    def load(data, block=None, role=None, task_include=None, variable_manager=None, loader=None):\n\n        ir = IncludeRole(block, role, task_include=task_include).load_data(data, variable_manager=variable_manager, loader=loader)\n\n        # Validate options\n        my_arg_names = frozenset(ir.args.keys())\n\n        # name is needed, or use role as alias\n        ir._role_name = ir.args.get('name', ir.args.get('role'))\n        if ir._role_name is None:\n            raise AnsibleParserError(\"'name' is a required field for %s.\" % ir.action, obj=data)\n\n        if 'public' in ir.args and ir.action != 'include_role':\n            raise AnsibleParserError('Invalid options for %s: private' % ir.action, obj=data)\n\n        if 'private' in ir.args:\n            display.deprecated(\n                msg='Supplying \"private\" for \"%s\" is a no op, and is deprecated' % ir.action,\n                version='2.8'\n            )\n\n        # validate bad args, otherwise we silently ignore\n        bad_opts = my_arg_names.difference(IncludeRole.VALID_ARGS)\n        if bad_opts:\n            raise AnsibleParserError('Invalid options for %s: %s' % (ir.action, ','.join(list(bad_opts))), obj=data)\n\n        # build options for role includes\n        for key in my_arg_names.intersection(IncludeRole.FROM_ARGS):\n            from_key = key.replace('_from', '')\n            ir._from_files[from_key] = basename(ir.args.get(key))\n\n        apply_attrs = ir.args.pop('apply', {})\n        if apply_attrs and ir.action != 'include_role':\n            raise AnsibleParserError('Invalid options for %s: apply' % ir.action, obj=data)\n        elif apply_attrs:\n            apply_attrs['block'] = []\n            p_block = Block.load(\n                apply_attrs,\n                play=block._play,\n                parent_block=block,\n                role=role,\n                task_include=task_include,\n                use_handlers=block._use_handlers,\n                variable_manager=variable_manager,\n                loader=loader,\n            )\n            ir._parent = p_block\n\n        # manual list as otherwise the options would set other task parameters we don't want.\n        for option in my_arg_names.intersection(IncludeRole.OTHER_ARGS):\n            setattr(ir, option, ir.args.get(option))\n\n        return ir\n\n    def copy(self, exclude_parent=False, exclude_tasks=False):\n\n        new_me = super(IncludeRole, self).copy(exclude_parent=exclude_parent, exclude_tasks=exclude_tasks)\n        new_me.statically_loaded = self.statically_loaded\n        new_me._from_files = self._from_files.copy()\n        new_me._parent_role = self._parent_role\n        new_me._role_name = self._role_name\n        new_me._role_path = self._role_path\n\n        return new_me\n\n    def get_include_params(self):\n        v = super(IncludeRole, self).get_include_params()\n        if self._parent_role:\n            v.update(self._parent_role.get_role_params())\n        return v\n", "path": "lib/ansible/playbook/role_include.py"}], "after_files": [{"content": "\n#\n# This file is part of Ansible\n#\n# Ansible is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# Ansible is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.\n\n# Make coding more python3-ish\nfrom __future__ import (absolute_import, division, print_function)\n__metaclass__ = type\n\nfrom os.path import basename\n\nfrom ansible.errors import AnsibleParserError\nfrom ansible.playbook.attribute import FieldAttribute\nfrom ansible.playbook.block import Block\nfrom ansible.playbook.task_include import TaskInclude\nfrom ansible.playbook.role import Role\nfrom ansible.playbook.role.include import RoleInclude\n\ntry:\n    from __main__ import display\nexcept ImportError:\n    from ansible.utils.display import Display\n    display = Display()\n\n__all__ = ['IncludeRole']\n\n\nclass IncludeRole(TaskInclude):\n\n    \"\"\"\n    A Role include is derived from a regular role to handle the special\n    circumstances related to the `- include_role: ...`\n    \"\"\"\n\n    BASE = ('name', 'role')  # directly assigned\n    FROM_ARGS = ('tasks_from', 'vars_from', 'defaults_from')  # used to populate from dict in role\n    OTHER_ARGS = ('apply', 'private', 'public', 'allow_duplicates')  # assigned to matching property\n    VALID_ARGS = tuple(frozenset(BASE + FROM_ARGS + OTHER_ARGS))  # all valid args\n\n    # =================================================================================\n    # ATTRIBUTES\n\n    # private as this is a 'module options' vs a task property\n    _allow_duplicates = FieldAttribute(isa='bool', default=True, private=True)\n    _private = FieldAttribute(isa='bool', default=None, private=True)\n    _public = FieldAttribute(isa='bool', default=False, private=True)\n\n    def __init__(self, block=None, role=None, task_include=None):\n\n        super(IncludeRole, self).__init__(block=block, role=role, task_include=task_include)\n\n        self._from_files = {}\n        self._parent_role = role\n        self._role_name = None\n        self._role_path = None\n\n    def get_name(self):\n        ''' return the name of the task '''\n        return self.name or \"%s : %s\" % (self.action, self._role_name)\n\n    def get_block_list(self, play=None, variable_manager=None, loader=None):\n\n        # only need play passed in when dynamic\n        if play is None:\n            myplay = self._parent._play\n        else:\n            myplay = play\n\n        ri = RoleInclude.load(self._role_name, play=myplay, variable_manager=variable_manager, loader=loader)\n        ri.vars.update(self.vars)\n\n        # build role\n        actual_role = Role.load(ri, myplay, parent_role=self._parent_role, from_files=self._from_files,\n                                from_include=True)\n        actual_role._metadata.allow_duplicates = self.allow_duplicates\n\n        if self.statically_loaded or self.public:\n            myplay.roles.append(actual_role)\n\n        # save this for later use\n        self._role_path = actual_role._role_path\n\n        # compile role with parent roles as dependencies to ensure they inherit\n        # variables\n        if not self._parent_role:\n            dep_chain = []\n        else:\n            dep_chain = list(self._parent_role._parents)\n            dep_chain.append(self._parent_role)\n\n        blocks = actual_role.compile(play=myplay, dep_chain=dep_chain)\n        for b in blocks:\n            b._parent = self\n\n        # updated available handlers in play\n        handlers = actual_role.get_handler_blocks(play=myplay)\n        for h in handlers:\n            h._parent = self\n        myplay.handlers = myplay.handlers + handlers\n        return blocks, handlers\n\n    @staticmethod\n    def load(data, block=None, role=None, task_include=None, variable_manager=None, loader=None):\n\n        ir = IncludeRole(block, role, task_include=task_include).load_data(data, variable_manager=variable_manager, loader=loader)\n\n        # Validate options\n        my_arg_names = frozenset(ir.args.keys())\n\n        # name is needed, or use role as alias\n        ir._role_name = ir.args.get('name', ir.args.get('role'))\n        if ir._role_name is None:\n            raise AnsibleParserError(\"'name' is a required field for %s.\" % ir.action, obj=data)\n\n        if 'public' in ir.args and ir.action != 'include_role':\n            raise AnsibleParserError('Invalid options for %s: private' % ir.action, obj=data)\n\n        if 'private' in ir.args:\n            display.deprecated(\n                msg='Supplying \"private\" for \"%s\" is a no op, and is deprecated' % ir.action,\n                version='2.8'\n            )\n\n        # validate bad args, otherwise we silently ignore\n        bad_opts = my_arg_names.difference(IncludeRole.VALID_ARGS)\n        if bad_opts:\n            raise AnsibleParserError('Invalid options for %s: %s' % (ir.action, ','.join(list(bad_opts))), obj=data)\n\n        # build options for role includes\n        for key in my_arg_names.intersection(IncludeRole.FROM_ARGS):\n            from_key = key.replace('_from', '')\n            ir._from_files[from_key] = basename(ir.args.get(key))\n\n        apply_attrs = ir.args.pop('apply', {})\n        if apply_attrs and ir.action != 'include_role':\n            raise AnsibleParserError('Invalid options for %s: apply' % ir.action, obj=data)\n        elif apply_attrs:\n            apply_attrs['block'] = []\n            p_block = Block.load(\n                apply_attrs,\n                play=block._play,\n                parent_block=block,\n                role=role,\n                task_include=task_include,\n                use_handlers=block._use_handlers,\n                variable_manager=variable_manager,\n                loader=loader,\n            )\n            ir._parent = p_block\n\n        # manual list as otherwise the options would set other task parameters we don't want.\n        for option in my_arg_names.intersection(IncludeRole.OTHER_ARGS):\n            setattr(ir, option, ir.args.get(option))\n\n        return ir\n\n    def copy(self, exclude_parent=False, exclude_tasks=False):\n\n        new_me = super(IncludeRole, self).copy(exclude_parent=exclude_parent, exclude_tasks=exclude_tasks)\n        new_me.statically_loaded = self.statically_loaded\n        new_me._from_files = self._from_files.copy()\n        new_me._parent_role = self._parent_role\n        new_me._role_name = self._role_name\n        new_me._role_path = self._role_path\n\n        return new_me\n\n    def get_include_params(self):\n        v = super(IncludeRole, self).get_include_params()\n        if self._parent_role:\n            v.update(self._parent_role.get_role_params())\n        return v\n", "path": "lib/ansible/playbook/role_include.py"}]}