prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  E3001 Missing properties raised as an error when they're not required
  *cfn-lint version: 0.4.2*
  
  *Description of issue.*
  
  An error about missing properties is not always useful. There are resources which don't necessarily need properties.
  
  Please provide as much information as possible:
  * Template linting issues:
  ```
      "WaitCondition": {
        "Type": "AWS::CloudFormation::WaitCondition",
        "CreationPolicy": {
          "ResourceSignal": {
            "Timeout": "PT15M",
            "Count": {
              "Ref": "TargetCapacity"
            }
          }
        }
      }
  ```
  Getting `E3001 Properties not defined for resource WaitCondition`
  
  * Feature request:
  
  I'm not sure if there's a list of resources which don't need properties in many situations. S3 buckets and WaitCondition seem like good candidates for not raising this.
  [AWS docs](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html) say:
  > Use the optional Parameters section to customize your templates.
  so it doesn't sound like it needs to be provided.
  
  </issue>
  <code>
  [start of src/cfnlint/rules/resources/Configuration.py]
  1 """
  2   Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
  3 
  4   Permission is hereby granted, free of charge, to any person obtaining a copy of this
  5   software and associated documentation files (the "Software"), to deal in the Software
  6   without restriction, including without limitation the rights to use, copy, modify,
  7   merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
  8   permit persons to whom the Software is furnished to do so.
  9 
  10   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
  11   INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  12   PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  13   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  14   OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  15   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  16 """
  17 from cfnlint import CloudFormationLintRule
  18 from cfnlint import RuleMatch
  19 import cfnlint.helpers
  20 
  21 
  22 class Configuration(CloudFormationLintRule):
  23     """Check Base Resource Configuration"""
  24     id = 'E3001'
  25     shortdesc = 'Basic CloudFormation Resource Check'
  26     description = 'Making sure the basic CloudFormation resources ' + \
  27                   'are properly configured'
  28     source_url = 'https://github.com/awslabs/cfn-python-lint'
  29     tags = ['resources']
  30 
  31     def match(self, cfn):
  32         """Check CloudFormation Resources"""
  33 
  34         matches = list()
  35 
  36         valid_attributes = [
  37             'CreationPolicy',
  38             'DeletionPolicy',
  39             'DependsOn',
  40             'Metadata',
  41             'UpdatePolicy',
  42             'Properties',
  43             'Type',
  44             'Condition'
  45         ]
  46 
  47         valid_custom_attributes = [
  48             'Version',
  49             'Properties',
  50             'DependsOn',
  51             'Metadata',
  52             'Condition',
  53             'Type',
  54         ]
  55 
  56         resources = cfn.template.get('Resources', {})
  57         if not isinstance(resources, dict):
  58             message = 'Resource not properly configured'
  59             matches.append(RuleMatch(['Resources'], message))
  60         else:
  61             for resource_name, resource_values in cfn.template.get('Resources', {}).items():
  62                 self.logger.debug('Validating resource %s base configuration', resource_name)
  63                 if not isinstance(resource_values, dict):
  64                     message = 'Resource not properly configured at {0}'
  65                     matches.append(RuleMatch(
  66                         ['Resources', resource_name],
  67                         message.format(resource_name)
  68                     ))
  69                     continue
  70                 resource_type = resource_values.get('Type', '')
  71                 check_attributes = []
  72                 if resource_type.startswith('Custom::') or resource_type == 'AWS::CloudFormation::CustomResource':
  73                     check_attributes = valid_custom_attributes
  74                 else:
  75                     check_attributes = valid_attributes
  76 
  77                 for property_key, _ in resource_values.items():
  78                     if property_key not in check_attributes:
  79                         message = 'Invalid resource attribute {0} for resource {1}'
  80                         matches.append(RuleMatch(
  81                             ['Resources', resource_name, property_key],
  82                             message.format(property_key, resource_name)))
  83 
  84                 resource_type = resource_values.get('Type', '')
  85                 if not resource_type:
  86                     message = 'Type not defined for resource {0}'
  87                     matches.append(RuleMatch(
  88                         ['Resources', resource_name],
  89                         message.format(resource_name)
  90                     ))
  91                 else:
  92                     self.logger.debug('Check resource types by region...')
  93                     for region, specs in cfnlint.helpers.RESOURCE_SPECS.items():
  94                         if region in cfn.regions:
  95                             if resource_type not in specs['ResourceTypes']:
  96                                 if not resource_type.startswith(('Custom::', 'AWS::Serverless::')):
  97                                     message = 'Invalid or unsupported Type {0} for resource {1} in {2}'
  98                                     matches.append(RuleMatch(
  99                                         ['Resources', resource_name, 'Type'],
  100                                         message.format(resource_type, resource_name, region)
  101                                     ))
  102 
  103                 if 'Properties' not in resource_values:
  104                     resource_spec = cfnlint.helpers.RESOURCE_SPECS['us-east-1']
  105                     if resource_type in resource_spec['ResourceTypes']:
  106                         properties_spec = resource_spec['ResourceTypes'][resource_type]['Properties']
  107                         # pylint: disable=len-as-condition
  108                         if len(properties_spec) > 0:
  109                             required = 0
  110                             for _, property_spec in properties_spec.items():
  111                                 if property_spec.get('Required', False):
  112                                     required += 1
  113                             if required > 0:
  114                                 message = 'Properties not defined for resource {0}'
  115                                 matches.append(RuleMatch(
  116                                     ['Resources', resource_name],
  117                                     message.format(resource_name)
  118                                 ))
  119 
  120         return matches
  121
  [end of src/cfnlint/rules/resources/Configuration.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/src/cfnlint/rules/resources/Configuration.py b/src/cfnlint/rules/resources/Configuration.py
  --- a/src/cfnlint/rules/resources/Configuration.py
  +++ b/src/cfnlint/rules/resources/Configuration.py
  @@ -111,10 +111,13 @@
                                   if property_spec.get('Required', False):
                                       required += 1
                               if required > 0:
  -                                message = 'Properties not defined for resource {0}'
  -                                matches.append(RuleMatch(
  -                                    ['Resources', resource_name],
  -                                    message.format(resource_name)
  -                                ))
  +                                if resource_type == 'AWS::CloudFormation::WaitCondition' and 'CreationPolicy' in resource_values.keys():
  +                                    self.logger.debug('Exception to required properties section as CreationPolicy is defined.')
  +                                else:
  +                                    message = 'Properties not defined for resource {0}'
  +                                    matches.append(RuleMatch(
  +                                        ['Resources', resource_name],
  +                                        message.format(resource_name)
  +                                    ))
   
           return matches
  
verification_info: {"golden_diff": "diff --git a/src/cfnlint/rules/resources/Configuration.py b/src/cfnlint/rules/resources/Configuration.py\n--- a/src/cfnlint/rules/resources/Configuration.py\n+++ b/src/cfnlint/rules/resources/Configuration.py\n@@ -111,10 +111,13 @@\n                                 if property_spec.get('Required', False):\n                                     required += 1\n                             if required > 0:\n-                                message = 'Properties not defined for resource {0}'\n-                                matches.append(RuleMatch(\n-                                    ['Resources', resource_name],\n-                                    message.format(resource_name)\n-                                ))\n+                                if resource_type == 'AWS::CloudFormation::WaitCondition' and 'CreationPolicy' in resource_values.keys():\n+                                    self.logger.debug('Exception to required properties section as CreationPolicy is defined.')\n+                                else:\n+                                    message = 'Properties not defined for resource {0}'\n+                                    matches.append(RuleMatch(\n+                                        ['Resources', resource_name],\n+                                        message.format(resource_name)\n+                                    ))\n \n         return matches\n", "issue": "E3001 Missing properties raised as an error when they're not required\n*cfn-lint version: 0.4.2*\r\n\r\n*Description of issue.*\r\n\r\nAn error about missing properties is not always useful. There are resources which don't necessarily need properties.\r\n\r\nPlease provide as much information as possible:\r\n* Template linting issues:\r\n```\r\n    \"WaitCondition\": {\r\n      \"Type\": \"AWS::CloudFormation::WaitCondition\",\r\n      \"CreationPolicy\": {\r\n        \"ResourceSignal\": {\r\n          \"Timeout\": \"PT15M\",\r\n          \"Count\": {\r\n            \"Ref\": \"TargetCapacity\"\r\n          }\r\n        }\r\n      }\r\n    }\r\n```\r\nGetting `E3001 Properties not defined for resource WaitCondition`\r\n\r\n* Feature request:\r\n\r\nI'm not sure if there's a list of resources which don't need properties in many situations. S3 buckets and WaitCondition seem like good candidates for not raising this.\r\n[AWS docs](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html) say:\r\n> Use the optional Parameters section to customize your templates.\r\nso it doesn't sound like it needs to be provided.\n", "before_files": [{"content": "\"\"\"\n  Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.\n\n  Permission is hereby granted, free of charge, to any person obtaining a copy of this\n  software and associated documentation files (the \"Software\"), to deal in the Software\n  without restriction, including without limitation the rights to use, copy, modify,\n  merge, publish, distribute, sublicense, and/or sell copies of the Software, and to\n  permit persons to whom the Software is furnished to do so.\n\n  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n  INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\n  PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\"\"\"\nfrom cfnlint import CloudFormationLintRule\nfrom cfnlint import RuleMatch\nimport cfnlint.helpers\n\n\nclass Configuration(CloudFormationLintRule):\n    \"\"\"Check Base Resource Configuration\"\"\"\n    id = 'E3001'\n    shortdesc = 'Basic CloudFormation Resource Check'\n    description = 'Making sure the basic CloudFormation resources ' + \\\n                  'are properly configured'\n    source_url = 'https://github.com/awslabs/cfn-python-lint'\n    tags = ['resources']\n\n    def match(self, cfn):\n        \"\"\"Check CloudFormation Resources\"\"\"\n\n        matches = list()\n\n        valid_attributes = [\n            'CreationPolicy',\n            'DeletionPolicy',\n            'DependsOn',\n            'Metadata',\n            'UpdatePolicy',\n            'Properties',\n            'Type',\n            'Condition'\n        ]\n\n        valid_custom_attributes = [\n            'Version',\n            'Properties',\n            'DependsOn',\n            'Metadata',\n            'Condition',\n            'Type',\n        ]\n\n        resources = cfn.template.get('Resources', {})\n        if not isinstance(resources, dict):\n            message = 'Resource not properly configured'\n            matches.append(RuleMatch(['Resources'], message))\n        else:\n            for resource_name, resource_values in cfn.template.get('Resources', {}).items():\n                self.logger.debug('Validating resource %s base configuration', resource_name)\n                if not isinstance(resource_values, dict):\n                    message = 'Resource not properly configured at {0}'\n                    matches.append(RuleMatch(\n                        ['Resources', resource_name],\n                        message.format(resource_name)\n                    ))\n                    continue\n                resource_type = resource_values.get('Type', '')\n                check_attributes = []\n                if resource_type.startswith('Custom::') or resource_type == 'AWS::CloudFormation::CustomResource':\n                    check_attributes = valid_custom_attributes\n                else:\n                    check_attributes = valid_attributes\n\n                for property_key, _ in resource_values.items():\n                    if property_key not in check_attributes:\n                        message = 'Invalid resource attribute {0} for resource {1}'\n                        matches.append(RuleMatch(\n                            ['Resources', resource_name, property_key],\n                            message.format(property_key, resource_name)))\n\n                resource_type = resource_values.get('Type', '')\n                if not resource_type:\n                    message = 'Type not defined for resource {0}'\n                    matches.append(RuleMatch(\n                        ['Resources', resource_name],\n                        message.format(resource_name)\n                    ))\n                else:\n                    self.logger.debug('Check resource types by region...')\n                    for region, specs in cfnlint.helpers.RESOURCE_SPECS.items():\n                        if region in cfn.regions:\n                            if resource_type not in specs['ResourceTypes']:\n                                if not resource_type.startswith(('Custom::', 'AWS::Serverless::')):\n                                    message = 'Invalid or unsupported Type {0} for resource {1} in {2}'\n                                    matches.append(RuleMatch(\n                                        ['Resources', resource_name, 'Type'],\n                                        message.format(resource_type, resource_name, region)\n                                    ))\n\n                if 'Properties' not in resource_values:\n                    resource_spec = cfnlint.helpers.RESOURCE_SPECS['us-east-1']\n                    if resource_type in resource_spec['ResourceTypes']:\n                        properties_spec = resource_spec['ResourceTypes'][resource_type]['Properties']\n                        # pylint: disable=len-as-condition\n                        if len(properties_spec) > 0:\n                            required = 0\n                            for _, property_spec in properties_spec.items():\n                                if property_spec.get('Required', False):\n                                    required += 1\n                            if required > 0:\n                                message = 'Properties not defined for resource {0}'\n                                matches.append(RuleMatch(\n                                    ['Resources', resource_name],\n                                    message.format(resource_name)\n                                ))\n\n        return matches\n", "path": "src/cfnlint/rules/resources/Configuration.py"}]}