prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  E2520 raised for mutually exclusive properties when using Conditions
  ### CloudFormation Lint Version
  
  cfn-lint 0.80.2
  
  ### What operating system are you using?
  
  Windows
  
  ### Describe the bug
  
  [E2520](https://github.com/aws-cloudformation/cfn-lint/blob/main/docs/rules.md#E2520) is raised for mutually exclusive properties when using Conditions
  
  ```
  cfn-lint -t ./template.yaml
  E2520 Property SourceSecurityGroupId should NOT exist with CidrIp for Resources/Ingress/Properties
  .\template.yaml:13:7
  ```
  
  The same was working prior `0.79.11`. PR  [2875](https://github.com/aws-cloudformation/cfn-lint/pull/2875) seems to be the cause.
  
  ```
  > cfn-lint --version            
  cfn-lint 0.79.10
  > cfn-lint -t ./template.yaml   
  > echo $lastexitcode
  0
  ```
  
  ### Expected behavior
  
  E2520 is ignored for mutually exclusive properties that use the same Condition and Fn::If intrinsic function which makes sure only one of the properties has value.
  
  ### Reproduction template
  
  ```yaml
  AWSTemplateFormatVersion: 2010-09-09
  Parameters:
    pCidr:
      Type: String
      Default: ''
  Conditions:
    cIsCidr: !Not [!Equals [!Ref pCidr, '']]
  Resources:
    Ingress:
      Type: AWS::EC2::SecurityGroupIngress
      Properties:
        SourceSecurityGroupId: !If [ cIsCidr, !Ref AWS::NoValue, sg-abc12345 ]
        CidrIp: !If [ cIsCidr, !Ref pCidr, !Ref AWS::NoValue ]
        IpProtocol: "-1"
        GroupId: sg-abc1234567
  ```
  
  --- 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/resources/properties/Exclusive.py`
  Content:
  ```
  1 """
  2 Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
  3 SPDX-License-Identifier: MIT-0
  4 """
  5 import cfnlint.helpers
  6 from cfnlint.data import AdditionalSpecs
  7 from cfnlint.rules import CloudFormationLintRule, RuleMatch
  8 
  9 
  10 class Exclusive(CloudFormationLintRule):
  11     """Check Properties Resource Configuration"""
  12 
  13     id = "E2520"
  14     shortdesc = "Check Properties that are mutually exclusive"
  15     description = (
  16         "Making sure CloudFormation properties that are exclusive are not defined"
  17     )
  18     source_url = "https://github.com/aws-cloudformation/cfn-python-lint"
  19     tags = ["resources"]
  20 
  21     def __init__(self):
  22         """Init"""
  23         super().__init__()
  24         exclusivespec = cfnlint.helpers.load_resource(AdditionalSpecs, "Exclusive.json")
  25         self.resource_types_specs = exclusivespec["ResourceTypes"]
  26         self.property_types_specs = exclusivespec["PropertyTypes"]
  27         for resource_type_spec in self.resource_types_specs:
  28             self.resource_property_types.append(resource_type_spec)
  29         for property_type_spec in self.property_types_specs:
  30             self.resource_sub_property_types.append(property_type_spec)
  31 
  32     def check(self, properties, exclusions, path, cfn):
  33         """Check itself"""
  34         matches = []
  35         for p_value, p_path in properties.items_safe(path[:]):
  36             for k, v in exclusions.items():
  37                 property_sets = cfn.get_object_without_conditions(p_value, [k] + v)
  38                 for property_set in property_sets:
  39                     obj = property_set["Object"].clean()
  40                     for prop in obj:
  41                         if prop in exclusions:
  42                             for excl_property in exclusions[prop]:
  43                                 if excl_property in obj:
  44                                     if property_set["Scenario"] is None:
  45                                         message = "Property {0} should NOT exist with {1} for {2}"
  46                                         matches.append(
  47                                             RuleMatch(
  48                                                 p_path + [prop],
  49                                                 message.format(
  50                                                     excl_property,
  51                                                     prop,
  52                                                     "/".join(map(str, p_path)),
  53                                                 ),
  54                                             )
  55                                         )
  56                                     else:
  57                                         scenario_text = " and ".join(
  58                                             [
  59                                                 f'when condition "{k}" is {v}'
  60                                                 for (k, v) in property_set[
  61                                                     "Scenario"
  62                                                 ].items()
  63                                             ]
  64                                         )
  65                                         message = "Property {0} should NOT exist with {1} {2} for {3}"
  66                                         matches.append(
  67                                             RuleMatch(
  68                                                 p_path + [prop],
  69                                                 message.format(
  70                                                     excl_property,
  71                                                     prop,
  72                                                     scenario_text,
  73                                                     "/".join(map(str, p_path)),
  74                                                 ),
  75                                             )
  76                                         )
  77 
  78         return matches
  79 
  80     def match_resource_sub_properties(self, properties, property_type, path, cfn):
  81         """Match for sub properties"""
  82         matches = []
  83 
  84         exclusions = self.property_types_specs.get(property_type, {})
  85         matches.extend(self.check(properties, exclusions, path, cfn))
  86 
  87         return matches
  88 
  89     def match_resource_properties(self, properties, resource_type, path, cfn):
  90         """Check CloudFormation Properties"""
  91         matches = []
  92 
  93         exclusions = self.resource_types_specs.get(resource_type, {})
  94         matches.extend(self.check(properties, exclusions, path, cfn))
  95 
  96         return matches
  97
  ```
  --- 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/resources/properties/Exclusive.py b/src/cfnlint/rules/resources/properties/Exclusive.py
  --- a/src/cfnlint/rules/resources/properties/Exclusive.py
  +++ b/src/cfnlint/rules/resources/properties/Exclusive.py
  @@ -38,7 +38,7 @@
                   for property_set in property_sets:
                       obj = property_set["Object"].clean()
                       for prop in obj:
  -                        if prop in exclusions:
  +                        if prop == k:
                               for excl_property in exclusions[prop]:
                                   if excl_property in obj:
                                       if property_set["Scenario"] is None:
  
verification_info: {"golden_diff": "diff --git a/src/cfnlint/rules/resources/properties/Exclusive.py b/src/cfnlint/rules/resources/properties/Exclusive.py\n--- a/src/cfnlint/rules/resources/properties/Exclusive.py\n+++ b/src/cfnlint/rules/resources/properties/Exclusive.py\n@@ -38,7 +38,7 @@\n                 for property_set in property_sets:\n                     obj = property_set[\"Object\"].clean()\n                     for prop in obj:\n-                        if prop in exclusions:\n+                        if prop == k:\n                             for excl_property in exclusions[prop]:\n                                 if excl_property in obj:\n                                     if property_set[\"Scenario\"] is None:\n", "issue": "E2520 raised for mutually exclusive properties when using Conditions\n### CloudFormation Lint Version\n\ncfn-lint 0.80.2\n\n### What operating system are you using?\n\nWindows\n\n### Describe the bug\n\n[E2520](https://github.com/aws-cloudformation/cfn-lint/blob/main/docs/rules.md#E2520) is raised for mutually exclusive properties when using Conditions\r\n\r\n```\r\ncfn-lint -t ./template.yaml\r\nE2520 Property SourceSecurityGroupId should NOT exist with CidrIp for Resources/Ingress/Properties\r\n.\\template.yaml:13:7\r\n```\r\n\r\nThe same was working prior `0.79.11`. PR  [2875](https://github.com/aws-cloudformation/cfn-lint/pull/2875) seems to be the cause.\r\n\r\n```\r\n> cfn-lint --version            \r\ncfn-lint 0.79.10\r\n> cfn-lint -t ./template.yaml   \r\n> echo $lastexitcode\r\n0\r\n```\n\n### Expected behavior\n\nE2520 is ignored for mutually exclusive properties that use the same Condition and Fn::If intrinsic function which makes sure only one of the properties has value.\n\n### Reproduction template\n\n```yaml\r\nAWSTemplateFormatVersion: 2010-09-09\r\nParameters:\r\n  pCidr:\r\n    Type: String\r\n    Default: ''\r\nConditions:\r\n  cIsCidr: !Not [!Equals [!Ref pCidr, '']]\r\nResources:\r\n  Ingress:\r\n    Type: AWS::EC2::SecurityGroupIngress\r\n    Properties:\r\n      SourceSecurityGroupId: !If [ cIsCidr, !Ref AWS::NoValue, sg-abc12345 ]\r\n      CidrIp: !If [ cIsCidr, !Ref pCidr, !Ref AWS::NoValue ]\r\n      IpProtocol: \"-1\"\r\n      GroupId: sg-abc1234567\r\n```\n", "before_files": [{"content": "\"\"\"\nCopyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\nSPDX-License-Identifier: MIT-0\n\"\"\"\nimport cfnlint.helpers\nfrom cfnlint.data import AdditionalSpecs\nfrom cfnlint.rules import CloudFormationLintRule, RuleMatch\n\n\nclass Exclusive(CloudFormationLintRule):\n    \"\"\"Check Properties Resource Configuration\"\"\"\n\n    id = \"E2520\"\n    shortdesc = \"Check Properties that are mutually exclusive\"\n    description = (\n        \"Making sure CloudFormation properties that are exclusive are not defined\"\n    )\n    source_url = \"https://github.com/aws-cloudformation/cfn-python-lint\"\n    tags = [\"resources\"]\n\n    def __init__(self):\n        \"\"\"Init\"\"\"\n        super().__init__()\n        exclusivespec = cfnlint.helpers.load_resource(AdditionalSpecs, \"Exclusive.json\")\n        self.resource_types_specs = exclusivespec[\"ResourceTypes\"]\n        self.property_types_specs = exclusivespec[\"PropertyTypes\"]\n        for resource_type_spec in self.resource_types_specs:\n            self.resource_property_types.append(resource_type_spec)\n        for property_type_spec in self.property_types_specs:\n            self.resource_sub_property_types.append(property_type_spec)\n\n    def check(self, properties, exclusions, path, cfn):\n        \"\"\"Check itself\"\"\"\n        matches = []\n        for p_value, p_path in properties.items_safe(path[:]):\n            for k, v in exclusions.items():\n                property_sets = cfn.get_object_without_conditions(p_value, [k] + v)\n                for property_set in property_sets:\n                    obj = property_set[\"Object\"].clean()\n                    for prop in obj:\n                        if prop in exclusions:\n                            for excl_property in exclusions[prop]:\n                                if excl_property in obj:\n                                    if property_set[\"Scenario\"] is None:\n                                        message = \"Property {0} should NOT exist with {1} for {2}\"\n                                        matches.append(\n                                            RuleMatch(\n                                                p_path + [prop],\n                                                message.format(\n                                                    excl_property,\n                                                    prop,\n                                                    \"/\".join(map(str, p_path)),\n                                                ),\n                                            )\n                                        )\n                                    else:\n                                        scenario_text = \" and \".join(\n                                            [\n                                                f'when condition \"{k}\" is {v}'\n                                                for (k, v) in property_set[\n                                                    \"Scenario\"\n                                                ].items()\n                                            ]\n                                        )\n                                        message = \"Property {0} should NOT exist with {1} {2} for {3}\"\n                                        matches.append(\n                                            RuleMatch(\n                                                p_path + [prop],\n                                                message.format(\n                                                    excl_property,\n                                                    prop,\n                                                    scenario_text,\n                                                    \"/\".join(map(str, p_path)),\n                                                ),\n                                            )\n                                        )\n\n        return matches\n\n    def match_resource_sub_properties(self, properties, property_type, path, cfn):\n        \"\"\"Match for sub properties\"\"\"\n        matches = []\n\n        exclusions = self.property_types_specs.get(property_type, {})\n        matches.extend(self.check(properties, exclusions, path, cfn))\n\n        return matches\n\n    def match_resource_properties(self, properties, resource_type, path, cfn):\n        \"\"\"Check CloudFormation Properties\"\"\"\n        matches = []\n\n        exclusions = self.resource_types_specs.get(resource_type, {})\n        matches.extend(self.check(properties, exclusions, path, cfn))\n\n        return matches\n", "path": "src/cfnlint/rules/resources/properties/Exclusive.py"}], "after_files": [{"content": "\"\"\"\nCopyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\nSPDX-License-Identifier: MIT-0\n\"\"\"\nimport cfnlint.helpers\nfrom cfnlint.data import AdditionalSpecs\nfrom cfnlint.rules import CloudFormationLintRule, RuleMatch\n\n\nclass Exclusive(CloudFormationLintRule):\n    \"\"\"Check Properties Resource Configuration\"\"\"\n\n    id = \"E2520\"\n    shortdesc = \"Check Properties that are mutually exclusive\"\n    description = (\n        \"Making sure CloudFormation properties that are exclusive are not defined\"\n    )\n    source_url = \"https://github.com/aws-cloudformation/cfn-python-lint\"\n    tags = [\"resources\"]\n\n    def __init__(self):\n        \"\"\"Init\"\"\"\n        super().__init__()\n        exclusivespec = cfnlint.helpers.load_resource(AdditionalSpecs, \"Exclusive.json\")\n        self.resource_types_specs = exclusivespec[\"ResourceTypes\"]\n        self.property_types_specs = exclusivespec[\"PropertyTypes\"]\n        for resource_type_spec in self.resource_types_specs:\n            self.resource_property_types.append(resource_type_spec)\n        for property_type_spec in self.property_types_specs:\n            self.resource_sub_property_types.append(property_type_spec)\n\n    def check(self, properties, exclusions, path, cfn):\n        \"\"\"Check itself\"\"\"\n        matches = []\n        for p_value, p_path in properties.items_safe(path[:]):\n            for k, v in exclusions.items():\n                property_sets = cfn.get_object_without_conditions(p_value, [k] + v)\n                for property_set in property_sets:\n                    obj = property_set[\"Object\"].clean()\n                    for prop in obj:\n                        if prop == k:\n                            for excl_property in exclusions[prop]:\n                                if excl_property in obj:\n                                    if property_set[\"Scenario\"] is None:\n                                        message = \"Property {0} should NOT exist with {1} for {2}\"\n                                        matches.append(\n                                            RuleMatch(\n                                                p_path + [prop],\n                                                message.format(\n                                                    excl_property,\n                                                    prop,\n                                                    \"/\".join(map(str, p_path)),\n                                                ),\n                                            )\n                                        )\n                                    else:\n                                        scenario_text = \" and \".join(\n                                            [\n                                                f'when condition \"{k}\" is {v}'\n                                                for (k, v) in property_set[\n                                                    \"Scenario\"\n                                                ].items()\n                                            ]\n                                        )\n                                        message = \"Property {0} should NOT exist with {1} {2} for {3}\"\n                                        matches.append(\n                                            RuleMatch(\n                                                p_path + [prop],\n                                                message.format(\n                                                    excl_property,\n                                                    prop,\n                                                    scenario_text,\n                                                    \"/\".join(map(str, p_path)),\n                                                ),\n                                            )\n                                        )\n\n        return matches\n\n    def match_resource_sub_properties(self, properties, property_type, path, cfn):\n        \"\"\"Match for sub properties\"\"\"\n        matches = []\n\n        exclusions = self.property_types_specs.get(property_type, {})\n        matches.extend(self.check(properties, exclusions, path, cfn))\n\n        return matches\n\n    def match_resource_properties(self, properties, resource_type, path, cfn):\n        \"\"\"Check CloudFormation Properties\"\"\"\n        matches = []\n\n        exclusions = self.resource_types_specs.get(resource_type, {})\n        matches.extend(self.check(properties, exclusions, path, cfn))\n\n        return matches\n", "path": "src/cfnlint/rules/resources/properties/Exclusive.py"}]}