prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  E1017 Select does not find already supported function when using complex list with nested Selects
  ### CloudFormation Lint Version
  
  cfn-lint 0.80.4
  
  ### What operating system are you using?
  
  Mac
  
  ### Describe the bug
  
  When launching a template with complex nested Selects and list to extract value from, it seems to be reporting E1017 while it should not. Templates are correctly deployed and work fine on my side.
  
  Output from command
  ```
  E1017 Select should use a supported function of Fn::FindInMap, Fn::GetAtt, Fn::GetAZs, Fn::If, Fn::Split, Fn::Cidr, Ref
  /file1.yml:3189:11
  ```
  
  ### Expected behavior
  
  No E1017 reported by cfn-lint.
  Template is working fine in Cloudformation, E1017 should not be reported.
  
  ### Reproduction template
  
  AWSTemplateFormatVersion: '2010-09-09'
  Description: 'Build EC2 instance'
  
  Resources:
    MountTarget1:
      Type: AWS::EFS::MountTarget
      Properties:
        FileSystemId: fs-1234567svsdabsf76s
  # E1017 STARTS HERE
        SubnetId: !Select
          - 0
          - !Select
            - 0
            - [
                [
                  "subnet-0987sknlnsdoi9j76",
                  "subnet-875jgyjlpzj75j8k0",
                  "subnet-5447hnd6hI8js45js"
              ],
              [
                  "subnet-0987sknlnsdoi9j76",
                  "subnet-875jgyjlpzj75j8k0",
                  "subnet-5447hnd6hI8js45js"
              ],
              [
                  "subnet-0987sknlnsdoi9j76",
                  "subnet-875jgyjlpzj75j8k0",
                  "subnet-5447hnd6hI8js45js"
              ] 
            ]
        SecurityGroups: [sg-00qdqeef0a5c345gf]
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `src/cfnlint/rules/functions/Select.py`
  Content:
  ```
  1 """
  2 Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
  3 SPDX-License-Identifier: MIT-0
  4 """
  5 from cfnlint.rules import CloudFormationLintRule, RuleMatch
  6 
  7 
  8 class Select(CloudFormationLintRule):
  9     """Check if Select values are correct"""
  10 
  11     id = "E1017"
  12     shortdesc = "Select validation of parameters"
  13     description = "Making sure the Select function is properly configured"
  14     source_url = "https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-select.html"
  15     tags = ["functions", "select"]
  16     supported_functions = [
  17         "Fn::FindInMap",
  18         "Fn::GetAtt",
  19         "Fn::GetAZs",
  20         "Fn::If",
  21         "Fn::Split",
  22         "Fn::Cidr",
  23         "Ref",
  24     ]
  25 
  26     def _test_index_obj(self, index_obj, path):
  27         matches = []
  28         if isinstance(index_obj, dict):
  29             if len(index_obj) == 1:
  30                 for index_key, _ in index_obj.items():
  31                     if index_key not in [
  32                         "Ref",
  33                         "Fn::FindInMap",
  34                         "Fn::Select",
  35                     ]:
  36                         message = "Select index should be an Integer or a function Ref, Fn::FindInMap, or Fn::Select for {0}"
  37                         matches.append(
  38                             RuleMatch(
  39                                 path,
  40                                 message.format("/".join(map(str, path))),
  41                             )
  42                         )
  43             else:
  44                 message = "Select index should be an Integer or a function Ref, Fn::FindInMap, or Fn::Select for {0}"
  45                 matches.append(
  46                     RuleMatch(
  47                         path,
  48                         message.format("/".join(map(str, path))),
  49                     )
  50                 )
  51         elif not isinstance(index_obj, int):
  52             try:
  53                 int(index_obj)
  54             except (ValueError, TypeError):
  55                 message = "Select index should be an Integer or a function of Ref, Fn::FindInMap, or Fn::Select for {0}"
  56                 matches.append(
  57                     RuleMatch(path, message.format("/".join(map(str, path))))
  58                 )
  59 
  60         return matches
  61 
  62     def _test_list_obj(self, list_obj, path):
  63         matches = []
  64         if isinstance(list_obj, dict):
  65             if len(list_obj) == 1:
  66                 for key, _ in list_obj.items():
  67                     if key not in self.supported_functions:
  68                         message = "Select should use a supported function of {0}"
  69                         matches.append(
  70                             RuleMatch(
  71                                 path,
  72                                 message.format(
  73                                     ", ".join(map(str, self.supported_functions))
  74                                 ),
  75                             )
  76                         )
  77             else:
  78                 message = "Select should use a supported function of {0}"
  79                 matches.append(
  80                     RuleMatch(
  81                         path,
  82                         message.format(", ".join(map(str, self.supported_functions))),
  83                     )
  84                 )
  85         elif not isinstance(list_obj, list):
  86             message = "Select should be an array of values for {0}"
  87             matches.append(RuleMatch(path, message.format("/".join(map(str, path)))))
  88 
  89         return matches
  90 
  91     def _test_select_obj(self, select_obj, path):
  92         matches = []
  93         if not isinstance(select_obj, list):
  94             message = "Select should be a list of 2 elements for {0}"
  95             matches.append(RuleMatch(path, message.format("/".join(map(str, path)))))
  96             return matches
  97         if len(select_obj) != 2:
  98             message = "Select should be a list of 2 elements for {0}"
  99             matches.append(RuleMatch(path, message.format("/".join(map(str, path)))))
  100             return matches
  101 
  102         index_obj = select_obj[0]
  103         list_of_objs = select_obj[1]
  104         matches.extend(self._test_index_obj(index_obj, path[:] + [0]))
  105         matches.extend(self._test_list_obj(list_of_objs, path[:] + [1]))
  106 
  107         return matches
  108 
  109     def match(self, cfn):
  110         matches = []
  111 
  112         select_objs = cfn.search_deep_keys("Fn::Select")
  113 
  114         for select_obj in select_objs:
  115             select_value_obj = select_obj[-1]
  116             tree = select_obj[:-1]
  117             matches.extend(self._test_select_obj(select_value_obj, tree[:]))
  118 
  119         return matches
  120
  ```
  --- 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()
  
  ```
  
golden_diff: diff --git a/src/cfnlint/rules/functions/Select.py b/src/cfnlint/rules/functions/Select.py
  --- a/src/cfnlint/rules/functions/Select.py
  +++ b/src/cfnlint/rules/functions/Select.py
  @@ -20,6 +20,7 @@
           "Fn::If",
           "Fn::Split",
           "Fn::Cidr",
  +        "Fn::Select",  # issue: 2895
           "Ref",
       ]
  
verification_info: {"golden_diff": "diff --git a/src/cfnlint/rules/functions/Select.py b/src/cfnlint/rules/functions/Select.py\n--- a/src/cfnlint/rules/functions/Select.py\n+++ b/src/cfnlint/rules/functions/Select.py\n@@ -20,6 +20,7 @@\n         \"Fn::If\",\n         \"Fn::Split\",\n         \"Fn::Cidr\",\n+        \"Fn::Select\",  # issue: 2895\n         \"Ref\",\n     ]\n", "issue": "E1017 Select does not find already supported function when using complex list with nested Selects\n### CloudFormation Lint Version\n\ncfn-lint 0.80.4\n\n### What operating system are you using?\n\nMac\n\n### Describe the bug\n\nWhen launching a template with complex nested Selects and list to extract value from, it seems to be reporting E1017 while it should not. Templates are correctly deployed and work fine on my side.\r\n\r\nOutput from command\r\n```\r\nE1017 Select should use a supported function of Fn::FindInMap, Fn::GetAtt, Fn::GetAZs, Fn::If, Fn::Split, Fn::Cidr, Ref\r\n/file1.yml:3189:11\r\n```\n\n### Expected behavior\n\nNo E1017 reported by cfn-lint.\r\nTemplate is working fine in Cloudformation, E1017 should not be reported.\n\n### Reproduction template\n\nAWSTemplateFormatVersion: '2010-09-09'\r\nDescription: 'Build EC2 instance'\r\n\r\nResources:\r\n  MountTarget1:\r\n    Type: AWS::EFS::MountTarget\r\n    Properties:\r\n      FileSystemId: fs-1234567svsdabsf76s\r\n# E1017 STARTS HERE\r\n      SubnetId: !Select\r\n        - 0\r\n        - !Select\r\n          - 0\r\n          - [\r\n              [\r\n                \"subnet-0987sknlnsdoi9j76\",\r\n                \"subnet-875jgyjlpzj75j8k0\",\r\n                \"subnet-5447hnd6hI8js45js\"\r\n            ],\r\n            [\r\n                \"subnet-0987sknlnsdoi9j76\",\r\n                \"subnet-875jgyjlpzj75j8k0\",\r\n                \"subnet-5447hnd6hI8js45js\"\r\n            ],\r\n            [\r\n                \"subnet-0987sknlnsdoi9j76\",\r\n                \"subnet-875jgyjlpzj75j8k0\",\r\n                \"subnet-5447hnd6hI8js45js\"\r\n            ] \r\n          ]\r\n      SecurityGroups: [sg-00qdqeef0a5c345gf]\r\n\n", "before_files": [{"content": "\"\"\"\nCopyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\nSPDX-License-Identifier: MIT-0\n\"\"\"\nfrom cfnlint.rules import CloudFormationLintRule, RuleMatch\n\n\nclass Select(CloudFormationLintRule):\n    \"\"\"Check if Select values are correct\"\"\"\n\n    id = \"E1017\"\n    shortdesc = \"Select validation of parameters\"\n    description = \"Making sure the Select function is properly configured\"\n    source_url = \"https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-select.html\"\n    tags = [\"functions\", \"select\"]\n    supported_functions = [\n        \"Fn::FindInMap\",\n        \"Fn::GetAtt\",\n        \"Fn::GetAZs\",\n        \"Fn::If\",\n        \"Fn::Split\",\n        \"Fn::Cidr\",\n        \"Ref\",\n    ]\n\n    def _test_index_obj(self, index_obj, path):\n        matches = []\n        if isinstance(index_obj, dict):\n            if len(index_obj) == 1:\n                for index_key, _ in index_obj.items():\n                    if index_key not in [\n                        \"Ref\",\n                        \"Fn::FindInMap\",\n                        \"Fn::Select\",\n                    ]:\n                        message = \"Select index should be an Integer or a function Ref, Fn::FindInMap, or Fn::Select for {0}\"\n                        matches.append(\n                            RuleMatch(\n                                path,\n                                message.format(\"/\".join(map(str, path))),\n                            )\n                        )\n            else:\n                message = \"Select index should be an Integer or a function Ref, Fn::FindInMap, or Fn::Select for {0}\"\n                matches.append(\n                    RuleMatch(\n                        path,\n                        message.format(\"/\".join(map(str, path))),\n                    )\n                )\n        elif not isinstance(index_obj, int):\n            try:\n                int(index_obj)\n            except (ValueError, TypeError):\n                message = \"Select index should be an Integer or a function of Ref, Fn::FindInMap, or Fn::Select for {0}\"\n                matches.append(\n                    RuleMatch(path, message.format(\"/\".join(map(str, path))))\n                )\n\n        return matches\n\n    def _test_list_obj(self, list_obj, path):\n        matches = []\n        if isinstance(list_obj, dict):\n            if len(list_obj) == 1:\n                for key, _ in list_obj.items():\n                    if key not in self.supported_functions:\n                        message = \"Select should use a supported function of {0}\"\n                        matches.append(\n                            RuleMatch(\n                                path,\n                                message.format(\n                                    \", \".join(map(str, self.supported_functions))\n                                ),\n                            )\n                        )\n            else:\n                message = \"Select should use a supported function of {0}\"\n                matches.append(\n                    RuleMatch(\n                        path,\n                        message.format(\", \".join(map(str, self.supported_functions))),\n                    )\n                )\n        elif not isinstance(list_obj, list):\n            message = \"Select should be an array of values for {0}\"\n            matches.append(RuleMatch(path, message.format(\"/\".join(map(str, path)))))\n\n        return matches\n\n    def _test_select_obj(self, select_obj, path):\n        matches = []\n        if not isinstance(select_obj, list):\n            message = \"Select should be a list of 2 elements for {0}\"\n            matches.append(RuleMatch(path, message.format(\"/\".join(map(str, path)))))\n            return matches\n        if len(select_obj) != 2:\n            message = \"Select should be a list of 2 elements for {0}\"\n            matches.append(RuleMatch(path, message.format(\"/\".join(map(str, path)))))\n            return matches\n\n        index_obj = select_obj[0]\n        list_of_objs = select_obj[1]\n        matches.extend(self._test_index_obj(index_obj, path[:] + [0]))\n        matches.extend(self._test_list_obj(list_of_objs, path[:] + [1]))\n\n        return matches\n\n    def match(self, cfn):\n        matches = []\n\n        select_objs = cfn.search_deep_keys(\"Fn::Select\")\n\n        for select_obj in select_objs:\n            select_value_obj = select_obj[-1]\n            tree = select_obj[:-1]\n            matches.extend(self._test_select_obj(select_value_obj, tree[:]))\n\n        return matches\n", "path": "src/cfnlint/rules/functions/Select.py"}], "after_files": [{"content": "\"\"\"\nCopyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\nSPDX-License-Identifier: MIT-0\n\"\"\"\nfrom cfnlint.rules import CloudFormationLintRule, RuleMatch\n\n\nclass Select(CloudFormationLintRule):\n    \"\"\"Check if Select values are correct\"\"\"\n\n    id = \"E1017\"\n    shortdesc = \"Select validation of parameters\"\n    description = \"Making sure the Select function is properly configured\"\n    source_url = \"https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-select.html\"\n    tags = [\"functions\", \"select\"]\n    supported_functions = [\n        \"Fn::FindInMap\",\n        \"Fn::GetAtt\",\n        \"Fn::GetAZs\",\n        \"Fn::If\",\n        \"Fn::Split\",\n        \"Fn::Cidr\",\n        \"Fn::Select\",  # issue: 2895\n        \"Ref\",\n    ]\n\n    def _test_index_obj(self, index_obj, path):\n        matches = []\n        if isinstance(index_obj, dict):\n            if len(index_obj) == 1:\n                for index_key, _ in index_obj.items():\n                    if index_key not in [\n                        \"Ref\",\n                        \"Fn::FindInMap\",\n                        \"Fn::Select\",\n                    ]:\n                        message = \"Select index should be an Integer or a function Ref, Fn::FindInMap, or Fn::Select for {0}\"\n                        matches.append(\n                            RuleMatch(\n                                path,\n                                message.format(\"/\".join(map(str, path))),\n                            )\n                        )\n            else:\n                message = \"Select index should be an Integer or a function Ref, Fn::FindInMap, or Fn::Select for {0}\"\n                matches.append(\n                    RuleMatch(\n                        path,\n                        message.format(\"/\".join(map(str, path))),\n                    )\n                )\n        elif not isinstance(index_obj, int):\n            try:\n                int(index_obj)\n            except (ValueError, TypeError):\n                message = \"Select index should be an Integer or a function of Ref, Fn::FindInMap, or Fn::Select for {0}\"\n                matches.append(\n                    RuleMatch(path, message.format(\"/\".join(map(str, path))))\n                )\n\n        return matches\n\n    def _test_list_obj(self, list_obj, path):\n        matches = []\n        if isinstance(list_obj, dict):\n            if len(list_obj) == 1:\n                for key, _ in list_obj.items():\n                    if key not in self.supported_functions:\n                        message = \"Select should use a supported function of {0}\"\n                        matches.append(\n                            RuleMatch(\n                                path,\n                                message.format(\n                                    \", \".join(map(str, self.supported_functions))\n                                ),\n                            )\n                        )\n            else:\n                message = \"Select should use a supported function of {0}\"\n                matches.append(\n                    RuleMatch(\n                        path,\n                        message.format(\", \".join(map(str, self.supported_functions))),\n                    )\n                )\n        elif not isinstance(list_obj, list):\n            message = \"Select should be an array of values for {0}\"\n            matches.append(RuleMatch(path, message.format(\"/\".join(map(str, path)))))\n\n        return matches\n\n    def _test_select_obj(self, select_obj, path):\n        matches = []\n        if not isinstance(select_obj, list):\n            message = \"Select should be a list of 2 elements for {0}\"\n            matches.append(RuleMatch(path, message.format(\"/\".join(map(str, path)))))\n            return matches\n        if len(select_obj) != 2:\n            message = \"Select should be a list of 2 elements for {0}\"\n            matches.append(RuleMatch(path, message.format(\"/\".join(map(str, path)))))\n            return matches\n\n        index_obj = select_obj[0]\n        list_of_objs = select_obj[1]\n        matches.extend(self._test_index_obj(index_obj, path[:] + [0]))\n        matches.extend(self._test_list_obj(list_of_objs, path[:] + [1]))\n\n        return matches\n\n    def match(self, cfn):\n        matches = []\n\n        select_objs = cfn.search_deep_keys(\"Fn::Select\")\n\n        for select_obj in select_objs:\n            select_value_obj = select_obj[-1]\n            tree = select_obj[:-1]\n            matches.extend(self._test_select_obj(select_value_obj, tree[:]))\n\n        return matches\n", "path": "src/cfnlint/rules/functions/Select.py"}]}