prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  false positive on apt_key with data field
  # Issue Type
  - Bug report
  
  # Ansible and Ansible Lint details
  
  ```
  $ ansible --version
  ansible 2.7.4
    config file = /home/lae/.ansible.cfg
    configured module search path = ['/home/lae/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
    ansible python module location = /usr/lib/python3.7/site-packages/ansible
    executable location = /usr/bin/ansible
    python version = 3.7.1 (default, Oct 22 2018, 10:41:28) [GCC 8.2.1 20180831]
  $ ansible-lint --version
  ansible-lint 4.0.0a1
  ```
  
  - ansible installation method: OS
  - ansible-lint installation method: pip
  
  # Desired Behaviour
  
  Rule 405 is meant for remote connections but using `apt_key` with the `data` field doesn't require network connectivity (not sure if there's an appropriate network lookup, but if so, that would be an exception).
  
  # Actual Behaviour
  
  ```yaml
  - name: Trust Proxmox' packaging key
    apt_key:
      data: "{{ lookup('file', pve_release_key) }}"
      id: "{{ pve_release_key_id }}"
      state: present
  ```
  
  The above results in the following.
  
  ```
  [405] Remote package tasks should have a retry
  /home/lae/src/ansible-role-proxmox/tasks/main.yml:47
  Task/Handler: Trust Proxmox' packaging key
  ```
  
  </issue>
  <code>
  [start of lib/ansiblelint/rules/PackageHasRetryRule.py]
  1 # Copyright (c) 2016, Will Thames and contributors
  2 # Copyright (c) 2018, Ansible Project
  3 
  4 from ansiblelint import AnsibleLintRule
  5 
  6 
  7 class PackageHasRetryRule(AnsibleLintRule):
  8     id = '405'
  9     shortdesc = 'Remote package tasks should have a retry'
  10     description = (
  11         'Package operations are unreliable as they require '
  12         'network communication and the availability of remote '
  13         'servers. To mitigate the potential problems, retries '
  14         'should be used via '
  15         '``register: my_result`` and ``until: my_result is succeeded``'
  16     )
  17     severity = 'LOW'
  18     tags = ['module', 'reliability']
  19     version_added = 'v4.0.0'
  20 
  21     # module list generated with:
  22     # find lib/ansible/modules/packaging/ -type f -printf '%f\n' \
  23     #   | sort | awk -F '/' \
  24     #   '/__|dpkg|_repo|_facts|_sub|_chan/{next} {split($NF, words, ".");
  25     #   print "\""words[1]"\","}'
  26     _package_modules = [
  27         "apk",
  28         "apt_key",
  29         "apt",
  30         "apt_rpm",
  31         "bower",
  32         "bundler",
  33         "composer",
  34         "cpanm",
  35         "dnf",
  36         "easy_install",
  37         "flatpak",
  38         "flatpak_remote",
  39         "gem",
  40         "homebrew_cask",
  41         "homebrew",
  42         "homebrew_tap",
  43         "layman",
  44         "macports",
  45         "maven_artifact",
  46         "npm",
  47         "openbsd_pkg",
  48         "opkg",
  49         "package",
  50         "pacman",
  51         "pear",
  52         "pip",
  53         "pkg5_publisher",
  54         "pkg5",
  55         "pkgin",
  56         "pkgng",
  57         "pkgutil",
  58         "portage",
  59         "portinstall",
  60         "rhn_register",
  61         "rpm_key",
  62         "slackpkg",
  63         "snap",
  64         "sorcery",
  65         "svr4pkg",
  66         "swdepot",
  67         "swupd",
  68         "urpmi",
  69         "xbps",
  70         "yarn",
  71         "yum",
  72         "zypper",
  73     ]
  74 
  75     _module_ignore_states = [
  76         "absent",
  77     ]
  78 
  79     _package_name_keys = [
  80         "name",
  81         "package",
  82         "pkg",
  83         "deb",
  84     ]
  85 
  86     # attempt to find package name
  87     def get_package_name(self, action):
  88         for key in self._package_name_keys:
  89             found_package_name = action.get(key)
  90             if found_package_name:
  91                 break
  92         return found_package_name
  93 
  94     def matchtask(self, file, task):
  95         module = task["action"]["__ansible_module__"]
  96 
  97         if module not in self._package_modules:
  98             return False
  99 
  100         is_task_retryable = 'until' in task
  101         if is_task_retryable:
  102             return False
  103 
  104         is_state_whitelisted = task['action'].get('state') in self._module_ignore_states
  105         if is_state_whitelisted:
  106             return False
  107 
  108         found_package_name = self.get_package_name(task['action'])
  109         if not found_package_name:
  110             return True
  111 
  112         is_package_file = '.' in found_package_name
  113         is_package_html = '://' in found_package_name
  114         is_local_package_file = is_package_file and not is_package_html
  115         if is_local_package_file:
  116             return False
  117 
  118         return True
  119
  [end of lib/ansiblelint/rules/PackageHasRetryRule.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/lib/ansiblelint/rules/PackageHasRetryRule.py b/lib/ansiblelint/rules/PackageHasRetryRule.py
  --- a/lib/ansiblelint/rules/PackageHasRetryRule.py
  +++ b/lib/ansiblelint/rules/PackageHasRetryRule.py
  @@ -76,19 +76,24 @@
           "absent",
       ]
   
  +    _module_ignore_parameters = [
  +        "data",
  +    ]
  +
       _package_name_keys = [
           "name",
           "package",
           "pkg",
           "deb",
  +        "key",
       ]
   
  -    # attempt to find package name
       def get_package_name(self, action):
  +        """Attempt to find package name."""
           for key in self._package_name_keys:
               found_package_name = action.get(key)
               if found_package_name:
  -                break
  +                return found_package_name
           return found_package_name
   
       def matchtask(self, file, task):
  @@ -105,6 +110,12 @@
           if is_state_whitelisted:
               return False
   
  +        has_whitelisted_parameter = (
  +            set(self._module_ignore_parameters).intersection(set(task['action']))
  +        )
  +        if has_whitelisted_parameter:
  +            return False
  +
           found_package_name = self.get_package_name(task['action'])
           if not found_package_name:
               return True
  
verification_info: {"golden_diff": "diff --git a/lib/ansiblelint/rules/PackageHasRetryRule.py b/lib/ansiblelint/rules/PackageHasRetryRule.py\n--- a/lib/ansiblelint/rules/PackageHasRetryRule.py\n+++ b/lib/ansiblelint/rules/PackageHasRetryRule.py\n@@ -76,19 +76,24 @@\n         \"absent\",\n     ]\n \n+    _module_ignore_parameters = [\n+        \"data\",\n+    ]\n+\n     _package_name_keys = [\n         \"name\",\n         \"package\",\n         \"pkg\",\n         \"deb\",\n+        \"key\",\n     ]\n \n-    # attempt to find package name\n     def get_package_name(self, action):\n+        \"\"\"Attempt to find package name.\"\"\"\n         for key in self._package_name_keys:\n             found_package_name = action.get(key)\n             if found_package_name:\n-                break\n+                return found_package_name\n         return found_package_name\n \n     def matchtask(self, file, task):\n@@ -105,6 +110,12 @@\n         if is_state_whitelisted:\n             return False\n \n+        has_whitelisted_parameter = (\n+            set(self._module_ignore_parameters).intersection(set(task['action']))\n+        )\n+        if has_whitelisted_parameter:\n+            return False\n+\n         found_package_name = self.get_package_name(task['action'])\n         if not found_package_name:\n             return True\n", "issue": "false positive on apt_key with data field\n# Issue Type\r\n- Bug report\r\n\r\n# Ansible and Ansible Lint details\r\n\r\n```\r\n$ ansible --version\r\nansible 2.7.4\r\n  config file = /home/lae/.ansible.cfg\r\n  configured module search path = ['/home/lae/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']\r\n  ansible python module location = /usr/lib/python3.7/site-packages/ansible\r\n  executable location = /usr/bin/ansible\r\n  python version = 3.7.1 (default, Oct 22 2018, 10:41:28) [GCC 8.2.1 20180831]\r\n$ ansible-lint --version\r\nansible-lint 4.0.0a1\r\n```\r\n\r\n- ansible installation method: OS\r\n- ansible-lint installation method: pip\r\n\r\n# Desired Behaviour\r\n\r\nRule 405 is meant for remote connections but using `apt_key` with the `data` field doesn't require network connectivity (not sure if there's an appropriate network lookup, but if so, that would be an exception).\r\n\r\n# Actual Behaviour\r\n\r\n```yaml\r\n- name: Trust Proxmox' packaging key\r\n  apt_key:\r\n    data: \"{{ lookup('file', pve_release_key) }}\"\r\n    id: \"{{ pve_release_key_id }}\"\r\n    state: present\r\n```\r\n\r\nThe above results in the following.\r\n\r\n```\r\n[405] Remote package tasks should have a retry\r\n/home/lae/src/ansible-role-proxmox/tasks/main.yml:47\r\nTask/Handler: Trust Proxmox' packaging key\r\n```\n", "before_files": [{"content": "# Copyright (c) 2016, Will Thames and contributors\n# Copyright (c) 2018, Ansible Project\n\nfrom ansiblelint import AnsibleLintRule\n\n\nclass PackageHasRetryRule(AnsibleLintRule):\n    id = '405'\n    shortdesc = 'Remote package tasks should have a retry'\n    description = (\n        'Package operations are unreliable as they require '\n        'network communication and the availability of remote '\n        'servers. To mitigate the potential problems, retries '\n        'should be used via '\n        '``register: my_result`` and ``until: my_result is succeeded``'\n    )\n    severity = 'LOW'\n    tags = ['module', 'reliability']\n    version_added = 'v4.0.0'\n\n    # module list generated with:\n    # find lib/ansible/modules/packaging/ -type f -printf '%f\\n' \\\n    #   | sort | awk -F '/' \\\n    #   '/__|dpkg|_repo|_facts|_sub|_chan/{next} {split($NF, words, \".\");\n    #   print \"\\\"\"words[1]\"\\\",\"}'\n    _package_modules = [\n        \"apk\",\n        \"apt_key\",\n        \"apt\",\n        \"apt_rpm\",\n        \"bower\",\n        \"bundler\",\n        \"composer\",\n        \"cpanm\",\n        \"dnf\",\n        \"easy_install\",\n        \"flatpak\",\n        \"flatpak_remote\",\n        \"gem\",\n        \"homebrew_cask\",\n        \"homebrew\",\n        \"homebrew_tap\",\n        \"layman\",\n        \"macports\",\n        \"maven_artifact\",\n        \"npm\",\n        \"openbsd_pkg\",\n        \"opkg\",\n        \"package\",\n        \"pacman\",\n        \"pear\",\n        \"pip\",\n        \"pkg5_publisher\",\n        \"pkg5\",\n        \"pkgin\",\n        \"pkgng\",\n        \"pkgutil\",\n        \"portage\",\n        \"portinstall\",\n        \"rhn_register\",\n        \"rpm_key\",\n        \"slackpkg\",\n        \"snap\",\n        \"sorcery\",\n        \"svr4pkg\",\n        \"swdepot\",\n        \"swupd\",\n        \"urpmi\",\n        \"xbps\",\n        \"yarn\",\n        \"yum\",\n        \"zypper\",\n    ]\n\n    _module_ignore_states = [\n        \"absent\",\n    ]\n\n    _package_name_keys = [\n        \"name\",\n        \"package\",\n        \"pkg\",\n        \"deb\",\n    ]\n\n    # attempt to find package name\n    def get_package_name(self, action):\n        for key in self._package_name_keys:\n            found_package_name = action.get(key)\n            if found_package_name:\n                break\n        return found_package_name\n\n    def matchtask(self, file, task):\n        module = task[\"action\"][\"__ansible_module__\"]\n\n        if module not in self._package_modules:\n            return False\n\n        is_task_retryable = 'until' in task\n        if is_task_retryable:\n            return False\n\n        is_state_whitelisted = task['action'].get('state') in self._module_ignore_states\n        if is_state_whitelisted:\n            return False\n\n        found_package_name = self.get_package_name(task['action'])\n        if not found_package_name:\n            return True\n\n        is_package_file = '.' in found_package_name\n        is_package_html = '://' in found_package_name\n        is_local_package_file = is_package_file and not is_package_html\n        if is_local_package_file:\n            return False\n\n        return True\n", "path": "lib/ansiblelint/rules/PackageHasRetryRule.py"}]}