prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Exception processing E3037 for AWS::S3::Bucket.Transition.TransitionDate
  ```
  $ cfn-lint --version
  cfn-lint 0.44.5
  ```
  
  The `TransitionDate` property is defined with `PrimitiveType: "Timestamp"`:
  
  ```yaml
  AWSTemplateFormatVersion: 2010-09-09
  
  Resources:
    Bucket:
      Type: AWS::S3::Bucket
      Properties:
        LifecycleConfiguration:
          Rules:
            - Status: Enabled
              Transitions:
                - StorageClass: INTELLIGENT_TIERING
                  TransitionDate: 2021-01-01T00:00:00.000Z
  ```
  
  This is a valid template and can be successfully deployed, but `cfn-lint` fails with:
  
  ```
  $ cfn-lint scratch.yml
  E0002 Unknown exception while processing rule E3037: Object of type datetime is not JSON serializable
  scratch.yml:1:1
  ```
  
  Running with `--debug` shows the exception is generated at https://github.com/aws-cloudformation/cfn-python-lint/blob/c7658511bd7066417682103f21f71983c67ea6d0/src/cfnlint/rules/resources/properties/ListDuplicates.py#L36
  
  Quoting the TransitionDate value suppresses this error, e.g. `TransitionDate: "2021-01-01T00:00:00.000Z"`
  
  --- 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/ListDuplicates.py`
  Content:
  ```
  1 """
  2 Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
  3 SPDX-License-Identifier: MIT-0
  4 """
  5 import hashlib
  6 import json
  7 from cfnlint.rules import CloudFormationLintRule
  8 from cfnlint.rules import RuleMatch
  9 
  10 from cfnlint.helpers import RESOURCE_SPECS
  11 
  12 
  13 class ListDuplicates(CloudFormationLintRule):
  14     """Check if duplicates exist in a List"""
  15     id = 'E3037'
  16     shortdesc = 'Check if a list has duplicate values'
  17     description = 'Certain lists don\'t support duplicate items. ' \
  18                   'Check when duplicates are provided but not supported.'
  19     source_url = 'https://github.com/aws-cloudformation/cfn-python-lint/blob/master/docs/cfn-resource-specification.md#allowedvalue'
  20     tags = ['resources', 'property', 'list']
  21 
  22     def initialize(self, cfn):
  23         """Initialize the rule"""
  24         for resource_type_spec in RESOURCE_SPECS.get(cfn.regions[0]).get('ResourceTypes'):
  25             self.resource_property_types.append(resource_type_spec)
  26         for property_type_spec in RESOURCE_SPECS.get(cfn.regions[0]).get('PropertyTypes'):
  27             self.resource_sub_property_types.append(property_type_spec)
  28 
  29     def _check_duplicates(self, values, path, scenario=None):
  30         """ Check for Duplicates """
  31         matches = []
  32 
  33         list_items = []
  34         if isinstance(values, list):
  35             for index, value in enumerate(values):
  36                 value_hash = hashlib.sha1(json.dumps(
  37                     value, sort_keys=True).encode('utf-8')).hexdigest()
  38                 if value_hash in list_items:
  39                     if not scenario:
  40                         message = 'List has a duplicate value at {0}'
  41                         matches.append(
  42                             RuleMatch(path + [index], message.format('/'.join(map(str, path + [index])))))
  43                     else:
  44                         scenario_text = ' and '.join(
  45                             ['condition "%s" is %s' % (k, v) for (k, v) in scenario.items()])
  46                         message = 'List has a duplicate value at {0} when {1}'
  47                         matches.append(RuleMatch(path, message.format(
  48                             '/'.join(map(str, path)), scenario_text)))
  49 
  50                 list_items.append(value_hash)
  51 
  52         return matches
  53 
  54     def check_duplicates(self, values, path, cfn):
  55         """ Check for duplicates """
  56         matches = []
  57 
  58         if isinstance(values, list):
  59             matches.extend(self._check_duplicates(values, path))
  60         elif isinstance(values, dict):
  61             props = cfn.get_object_without_conditions(values)
  62             for prop in props:
  63                 matches.extend(self._check_duplicates(
  64                     prop.get('Object'), path, prop.get('Scenario')))
  65 
  66         return matches
  67 
  68     def check(self, cfn, properties, value_specs, path):
  69         """Check itself"""
  70         matches = list()
  71         for p_value, p_path in properties.items_safe(path[:]):
  72             for prop in p_value:
  73                 if prop in value_specs:
  74                     property_type = value_specs.get(prop).get('Type')
  75                     duplicates_allowed = value_specs.get(prop).get('DuplicatesAllowed', True)
  76                     if property_type == 'List' and not duplicates_allowed:
  77                         matches.extend(
  78                             self.check_duplicates(
  79                                 p_value[prop], p_path + [prop], cfn
  80                             )
  81                         )
  82 
  83         return matches
  84 
  85     def match_resource_sub_properties(self, properties, property_type, path, cfn):
  86         """Match for sub properties"""
  87         matches = list()
  88 
  89         specs = RESOURCE_SPECS.get(cfn.regions[0]).get(
  90             'PropertyTypes').get(property_type, {}).get('Properties', {})
  91         matches.extend(self.check(cfn, properties, specs, path))
  92 
  93         return matches
  94 
  95     def match_resource_properties(self, properties, resource_type, path, cfn):
  96         """Check CloudFormation Properties"""
  97         matches = list()
  98 
  99         specs = RESOURCE_SPECS.get(cfn.regions[0]).get(
  100             'ResourceTypes').get(resource_type, {}).get('Properties', {})
  101         matches.extend(self.check(cfn, properties, specs, path))
  102 
  103         return matches
  104
  ```
  --- 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/ListDuplicates.py b/src/cfnlint/rules/resources/properties/ListDuplicates.py
  --- a/src/cfnlint/rules/resources/properties/ListDuplicates.py
  +++ b/src/cfnlint/rules/resources/properties/ListDuplicates.py
  @@ -34,7 +34,7 @@
           if isinstance(values, list):
               for index, value in enumerate(values):
                   value_hash = hashlib.sha1(json.dumps(
  -                    value, sort_keys=True).encode('utf-8')).hexdigest()
  +                    value, sort_keys=True, default=str).encode('utf-8')).hexdigest()
                   if value_hash in list_items:
                       if not scenario:
                           message = 'List has a duplicate value at {0}'
  
verification_info: {"golden_diff": "diff --git a/src/cfnlint/rules/resources/properties/ListDuplicates.py b/src/cfnlint/rules/resources/properties/ListDuplicates.py\n--- a/src/cfnlint/rules/resources/properties/ListDuplicates.py\n+++ b/src/cfnlint/rules/resources/properties/ListDuplicates.py\n@@ -34,7 +34,7 @@\n         if isinstance(values, list):\n             for index, value in enumerate(values):\n                 value_hash = hashlib.sha1(json.dumps(\n-                    value, sort_keys=True).encode('utf-8')).hexdigest()\n+                    value, sort_keys=True, default=str).encode('utf-8')).hexdigest()\n                 if value_hash in list_items:\n                     if not scenario:\n                         message = 'List has a duplicate value at {0}'\n", "issue": "Exception processing E3037 for AWS::S3::Bucket.Transition.TransitionDate\n```\r\n$ cfn-lint --version\r\ncfn-lint 0.44.5\r\n```\r\n\r\nThe `TransitionDate` property is defined with `PrimitiveType: \"Timestamp\"`:\r\n\r\n```yaml\r\nAWSTemplateFormatVersion: 2010-09-09\r\n\r\nResources:\r\n  Bucket:\r\n    Type: AWS::S3::Bucket\r\n    Properties:\r\n      LifecycleConfiguration:\r\n        Rules:\r\n          - Status: Enabled\r\n            Transitions:\r\n              - StorageClass: INTELLIGENT_TIERING\r\n                TransitionDate: 2021-01-01T00:00:00.000Z\r\n```\r\n\r\nThis is a valid template and can be successfully deployed, but `cfn-lint` fails with:\r\n\r\n```\r\n$ cfn-lint scratch.yml\r\nE0002 Unknown exception while processing rule E3037: Object of type datetime is not JSON serializable\r\nscratch.yml:1:1\r\n```\r\n\r\nRunning with `--debug` shows the exception is generated at https://github.com/aws-cloudformation/cfn-python-lint/blob/c7658511bd7066417682103f21f71983c67ea6d0/src/cfnlint/rules/resources/properties/ListDuplicates.py#L36\r\n\r\nQuoting the TransitionDate value suppresses this error, e.g. `TransitionDate: \"2021-01-01T00:00:00.000Z\"`\n", "before_files": [{"content": "\"\"\"\nCopyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\nSPDX-License-Identifier: MIT-0\n\"\"\"\nimport hashlib\nimport json\nfrom cfnlint.rules import CloudFormationLintRule\nfrom cfnlint.rules import RuleMatch\n\nfrom cfnlint.helpers import RESOURCE_SPECS\n\n\nclass ListDuplicates(CloudFormationLintRule):\n    \"\"\"Check if duplicates exist in a List\"\"\"\n    id = 'E3037'\n    shortdesc = 'Check if a list has duplicate values'\n    description = 'Certain lists don\\'t support duplicate items. ' \\\n                  'Check when duplicates are provided but not supported.'\n    source_url = 'https://github.com/aws-cloudformation/cfn-python-lint/blob/master/docs/cfn-resource-specification.md#allowedvalue'\n    tags = ['resources', 'property', 'list']\n\n    def initialize(self, cfn):\n        \"\"\"Initialize the rule\"\"\"\n        for resource_type_spec in RESOURCE_SPECS.get(cfn.regions[0]).get('ResourceTypes'):\n            self.resource_property_types.append(resource_type_spec)\n        for property_type_spec in RESOURCE_SPECS.get(cfn.regions[0]).get('PropertyTypes'):\n            self.resource_sub_property_types.append(property_type_spec)\n\n    def _check_duplicates(self, values, path, scenario=None):\n        \"\"\" Check for Duplicates \"\"\"\n        matches = []\n\n        list_items = []\n        if isinstance(values, list):\n            for index, value in enumerate(values):\n                value_hash = hashlib.sha1(json.dumps(\n                    value, sort_keys=True).encode('utf-8')).hexdigest()\n                if value_hash in list_items:\n                    if not scenario:\n                        message = 'List has a duplicate value at {0}'\n                        matches.append(\n                            RuleMatch(path + [index], message.format('/'.join(map(str, path + [index])))))\n                    else:\n                        scenario_text = ' and '.join(\n                            ['condition \"%s\" is %s' % (k, v) for (k, v) in scenario.items()])\n                        message = 'List has a duplicate value at {0} when {1}'\n                        matches.append(RuleMatch(path, message.format(\n                            '/'.join(map(str, path)), scenario_text)))\n\n                list_items.append(value_hash)\n\n        return matches\n\n    def check_duplicates(self, values, path, cfn):\n        \"\"\" Check for duplicates \"\"\"\n        matches = []\n\n        if isinstance(values, list):\n            matches.extend(self._check_duplicates(values, path))\n        elif isinstance(values, dict):\n            props = cfn.get_object_without_conditions(values)\n            for prop in props:\n                matches.extend(self._check_duplicates(\n                    prop.get('Object'), path, prop.get('Scenario')))\n\n        return matches\n\n    def check(self, cfn, properties, value_specs, path):\n        \"\"\"Check itself\"\"\"\n        matches = list()\n        for p_value, p_path in properties.items_safe(path[:]):\n            for prop in p_value:\n                if prop in value_specs:\n                    property_type = value_specs.get(prop).get('Type')\n                    duplicates_allowed = value_specs.get(prop).get('DuplicatesAllowed', True)\n                    if property_type == 'List' and not duplicates_allowed:\n                        matches.extend(\n                            self.check_duplicates(\n                                p_value[prop], p_path + [prop], cfn\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 = list()\n\n        specs = RESOURCE_SPECS.get(cfn.regions[0]).get(\n            'PropertyTypes').get(property_type, {}).get('Properties', {})\n        matches.extend(self.check(cfn, properties, specs, path))\n\n        return matches\n\n    def match_resource_properties(self, properties, resource_type, path, cfn):\n        \"\"\"Check CloudFormation Properties\"\"\"\n        matches = list()\n\n        specs = RESOURCE_SPECS.get(cfn.regions[0]).get(\n            'ResourceTypes').get(resource_type, {}).get('Properties', {})\n        matches.extend(self.check(cfn, properties, specs, path))\n\n        return matches\n", "path": "src/cfnlint/rules/resources/properties/ListDuplicates.py"}], "after_files": [{"content": "\"\"\"\nCopyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\nSPDX-License-Identifier: MIT-0\n\"\"\"\nimport hashlib\nimport json\nfrom cfnlint.rules import CloudFormationLintRule\nfrom cfnlint.rules import RuleMatch\n\nfrom cfnlint.helpers import RESOURCE_SPECS\n\n\nclass ListDuplicates(CloudFormationLintRule):\n    \"\"\"Check if duplicates exist in a List\"\"\"\n    id = 'E3037'\n    shortdesc = 'Check if a list has duplicate values'\n    description = 'Certain lists don\\'t support duplicate items. ' \\\n                  'Check when duplicates are provided but not supported.'\n    source_url = 'https://github.com/aws-cloudformation/cfn-python-lint/blob/master/docs/cfn-resource-specification.md#allowedvalue'\n    tags = ['resources', 'property', 'list']\n\n    def initialize(self, cfn):\n        \"\"\"Initialize the rule\"\"\"\n        for resource_type_spec in RESOURCE_SPECS.get(cfn.regions[0]).get('ResourceTypes'):\n            self.resource_property_types.append(resource_type_spec)\n        for property_type_spec in RESOURCE_SPECS.get(cfn.regions[0]).get('PropertyTypes'):\n            self.resource_sub_property_types.append(property_type_spec)\n\n    def _check_duplicates(self, values, path, scenario=None):\n        \"\"\" Check for Duplicates \"\"\"\n        matches = []\n\n        list_items = []\n        if isinstance(values, list):\n            for index, value in enumerate(values):\n                value_hash = hashlib.sha1(json.dumps(\n                    value, sort_keys=True, default=str).encode('utf-8')).hexdigest()\n                if value_hash in list_items:\n                    if not scenario:\n                        message = 'List has a duplicate value at {0}'\n                        matches.append(\n                            RuleMatch(path + [index], message.format('/'.join(map(str, path + [index])))))\n                    else:\n                        scenario_text = ' and '.join(\n                            ['condition \"%s\" is %s' % (k, v) for (k, v) in scenario.items()])\n                        message = 'List has a duplicate value at {0} when {1}'\n                        matches.append(RuleMatch(path, message.format(\n                            '/'.join(map(str, path)), scenario_text)))\n\n                list_items.append(value_hash)\n\n        return matches\n\n    def check_duplicates(self, values, path, cfn):\n        \"\"\" Check for duplicates \"\"\"\n        matches = []\n\n        if isinstance(values, list):\n            matches.extend(self._check_duplicates(values, path))\n        elif isinstance(values, dict):\n            props = cfn.get_object_without_conditions(values)\n            for prop in props:\n                matches.extend(self._check_duplicates(\n                    prop.get('Object'), path, prop.get('Scenario')))\n\n        return matches\n\n    def check(self, cfn, properties, value_specs, path):\n        \"\"\"Check itself\"\"\"\n        matches = list()\n        for p_value, p_path in properties.items_safe(path[:]):\n            for prop in p_value:\n                if prop in value_specs:\n                    property_type = value_specs.get(prop).get('Type')\n                    duplicates_allowed = value_specs.get(prop).get('DuplicatesAllowed', True)\n                    if property_type == 'List' and not duplicates_allowed:\n                        matches.extend(\n                            self.check_duplicates(\n                                p_value[prop], p_path + [prop], cfn\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 = list()\n\n        specs = RESOURCE_SPECS.get(cfn.regions[0]).get(\n            'PropertyTypes').get(property_type, {}).get('Properties', {})\n        matches.extend(self.check(cfn, properties, specs, path))\n\n        return matches\n\n    def match_resource_properties(self, properties, resource_type, path, cfn):\n        \"\"\"Check CloudFormation Properties\"\"\"\n        matches = list()\n\n        specs = RESOURCE_SPECS.get(cfn.regions[0]).get(\n            'ResourceTypes').get(resource_type, {}).get('Properties', {})\n        matches.extend(self.check(cfn, properties, specs, path))\n\n        return matches\n", "path": "src/cfnlint/rules/resources/properties/ListDuplicates.py"}]}