prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  cfn-lint 0.49.1 does not catch `/` as an invalid character in a Mapping element name
  *cfn-lint version: cfn-lint 0.49.1*
  
  *cfn-lint did not catch `/` as an invalid character in a Mapping element name*
  
  cfn-lint passed successfully with this mapping included in the template:
  ```yaml
  Mappings:
    NameServers:
      10.90.0.0/16:
        NameServer1: 10.90.0.10
        NameServer2: 10.90.4.10
      10.91.0.0/16:
        NameServer1: 10.91.0.10
        NameServer2: 10.91.4.10
  ```
  
  However AWS rejected it:
  > Template format error: Mappings element name '10.93.0.0/16' must be non-empty and can contain only alphanumerics, '-' or '.'
  
  ![Screen Shot 2021-05-12 at 11 34 41](https://user-images.githubusercontent.com/7205587/117905164-0e917c00-b316-11eb-8132-2da240ff892a.png)
  
  
  </issue>
  <code>
  [start of src/cfnlint/rules/mappings/KeyName.py]
  1 """
  2 Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
  3 SPDX-License-Identifier: MIT-0
  4 """
  5 import re
  6 import six
  7 from cfnlint.rules import CloudFormationLintRule
  8 from cfnlint.rules import RuleMatch
  9 from cfnlint.helpers import REGEX_ALPHANUMERIC
  10 
  11 
  12 class KeyName(CloudFormationLintRule):
  13     """Check if Mapping Keys are type string"""
  14     id = 'E7003'
  15     shortdesc = 'Mapping keys are strings and alphanumeric'
  16     description = 'Check if Mappings keys are properly typed as strings and alphanumeric'
  17     source_url = 'https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/mappings-section-structure.html'
  18     tags = ['mappings']
  19 
  20     def check_key(self, key, path, check_alphanumeric=True):
  21         """ Check the key name for string and alphanumeric"""
  22         matches = []
  23         if not isinstance(key, six.string_types):
  24             message = 'Mapping key ({0}) has to be a string.'
  25             matches.append(RuleMatch(path[:], message.format(key)))
  26         elif not re.match(REGEX_ALPHANUMERIC, key) and check_alphanumeric:
  27             message = 'Mapping key ({0}) has invalid name. Name has to be alphanumeric.'
  28             matches.append(RuleMatch(path[:], message.format(key)))
  29 
  30         return matches
  31 
  32     def match(self, cfn):
  33         matches = []
  34 
  35         mappings = cfn.template.get('Mappings', {})
  36         for mapping_name, mapping_value in mappings.items():
  37             if isinstance(mapping_value, dict):
  38                 for key_name, key_value in mapping_value.items():
  39                     matches.extend(self.check_key(
  40                         key_name, ['Mappings', mapping_name, key_name], False))
  41                     if isinstance(key_value, dict):
  42                         for sub_key_name, _ in key_value.items():
  43                             matches.extend(
  44                                 self.check_key(
  45                                     sub_key_name, ['Mappings', mapping_name, key_name, sub_key_name]))
  46 
  47         return matches
  48
  [end of src/cfnlint/rules/mappings/KeyName.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/mappings/KeyName.py b/src/cfnlint/rules/mappings/KeyName.py
  --- a/src/cfnlint/rules/mappings/KeyName.py
  +++ b/src/cfnlint/rules/mappings/KeyName.py
  @@ -17,14 +17,26 @@
       source_url = 'https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/mappings-section-structure.html'
       tags = ['mappings']
   
  -    def check_key(self, key, path, check_alphanumeric=True):
  +    def check_attribute(self, key, path):
  +        """ Check the key name for string and alphanumeric"""
  +        matches = []
  +        if not isinstance(key, six.string_types):
  +            message = 'Mapping attribute ({0}) has to be a string.'
  +            matches.append(RuleMatch(path[:], message.format(key)))
  +        elif not re.match(REGEX_ALPHANUMERIC, key):
  +            message = 'Mapping attribute ({0}) has invalid name. Name has to be alphanumeric.'
  +            matches.append(RuleMatch(path[:], message.format(key)))
  +
  +        return matches
  +
  +    def check_key(self, key, path):
           """ Check the key name for string and alphanumeric"""
           matches = []
           if not isinstance(key, six.string_types):
               message = 'Mapping key ({0}) has to be a string.'
               matches.append(RuleMatch(path[:], message.format(key)))
  -        elif not re.match(REGEX_ALPHANUMERIC, key) and check_alphanumeric:
  -            message = 'Mapping key ({0}) has invalid name. Name has to be alphanumeric.'
  +        elif not re.match('^[a-zA-Z0-9.-]{1,255}$', key):
  +            message = 'Mapping key ({0}) has invalid name. Name has to be alphanumeric, \'-\' or \'.\''
               matches.append(RuleMatch(path[:], message.format(key)))
   
           return matches
  @@ -37,11 +49,11 @@
               if isinstance(mapping_value, dict):
                   for key_name, key_value in mapping_value.items():
                       matches.extend(self.check_key(
  -                        key_name, ['Mappings', mapping_name, key_name], False))
  +                        key_name, ['Mappings', mapping_name, key_name]))
                       if isinstance(key_value, dict):
                           for sub_key_name, _ in key_value.items():
                               matches.extend(
  -                                self.check_key(
  +                                self.check_attribute(
                                       sub_key_name, ['Mappings', mapping_name, key_name, sub_key_name]))
   
           return matches
  
verification_info: {"golden_diff": "diff --git a/src/cfnlint/rules/mappings/KeyName.py b/src/cfnlint/rules/mappings/KeyName.py\n--- a/src/cfnlint/rules/mappings/KeyName.py\n+++ b/src/cfnlint/rules/mappings/KeyName.py\n@@ -17,14 +17,26 @@\n     source_url = 'https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/mappings-section-structure.html'\n     tags = ['mappings']\n \n-    def check_key(self, key, path, check_alphanumeric=True):\n+    def check_attribute(self, key, path):\n+        \"\"\" Check the key name for string and alphanumeric\"\"\"\n+        matches = []\n+        if not isinstance(key, six.string_types):\n+            message = 'Mapping attribute ({0}) has to be a string.'\n+            matches.append(RuleMatch(path[:], message.format(key)))\n+        elif not re.match(REGEX_ALPHANUMERIC, key):\n+            message = 'Mapping attribute ({0}) has invalid name. Name has to be alphanumeric.'\n+            matches.append(RuleMatch(path[:], message.format(key)))\n+\n+        return matches\n+\n+    def check_key(self, key, path):\n         \"\"\" Check the key name for string and alphanumeric\"\"\"\n         matches = []\n         if not isinstance(key, six.string_types):\n             message = 'Mapping key ({0}) has to be a string.'\n             matches.append(RuleMatch(path[:], message.format(key)))\n-        elif not re.match(REGEX_ALPHANUMERIC, key) and check_alphanumeric:\n-            message = 'Mapping key ({0}) has invalid name. Name has to be alphanumeric.'\n+        elif not re.match('^[a-zA-Z0-9.-]{1,255}$', key):\n+            message = 'Mapping key ({0}) has invalid name. Name has to be alphanumeric, \\'-\\' or \\'.\\''\n             matches.append(RuleMatch(path[:], message.format(key)))\n \n         return matches\n@@ -37,11 +49,11 @@\n             if isinstance(mapping_value, dict):\n                 for key_name, key_value in mapping_value.items():\n                     matches.extend(self.check_key(\n-                        key_name, ['Mappings', mapping_name, key_name], False))\n+                        key_name, ['Mappings', mapping_name, key_name]))\n                     if isinstance(key_value, dict):\n                         for sub_key_name, _ in key_value.items():\n                             matches.extend(\n-                                self.check_key(\n+                                self.check_attribute(\n                                     sub_key_name, ['Mappings', mapping_name, key_name, sub_key_name]))\n \n         return matches\n", "issue": "cfn-lint 0.49.1 does not catch `/` as an invalid character in a Mapping element name\n*cfn-lint version: cfn-lint 0.49.1*\r\n\r\n*cfn-lint did not catch `/` as an invalid character in a Mapping element name*\r\n\r\ncfn-lint passed successfully with this mapping included in the template:\r\n```yaml\r\nMappings:\r\n  NameServers:\r\n    10.90.0.0/16:\r\n      NameServer1: 10.90.0.10\r\n      NameServer2: 10.90.4.10\r\n    10.91.0.0/16:\r\n      NameServer1: 10.91.0.10\r\n      NameServer2: 10.91.4.10\r\n```\r\n\r\nHowever AWS rejected it:\r\n> Template format error: Mappings element name '10.93.0.0/16' must be non-empty and can contain only alphanumerics, '-' or '.'\r\n\r\n![Screen Shot 2021-05-12 at 11 34 41](https://user-images.githubusercontent.com/7205587/117905164-0e917c00-b316-11eb-8132-2da240ff892a.png)\r\n\n", "before_files": [{"content": "\"\"\"\nCopyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\nSPDX-License-Identifier: MIT-0\n\"\"\"\nimport re\nimport six\nfrom cfnlint.rules import CloudFormationLintRule\nfrom cfnlint.rules import RuleMatch\nfrom cfnlint.helpers import REGEX_ALPHANUMERIC\n\n\nclass KeyName(CloudFormationLintRule):\n    \"\"\"Check if Mapping Keys are type string\"\"\"\n    id = 'E7003'\n    shortdesc = 'Mapping keys are strings and alphanumeric'\n    description = 'Check if Mappings keys are properly typed as strings and alphanumeric'\n    source_url = 'https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/mappings-section-structure.html'\n    tags = ['mappings']\n\n    def check_key(self, key, path, check_alphanumeric=True):\n        \"\"\" Check the key name for string and alphanumeric\"\"\"\n        matches = []\n        if not isinstance(key, six.string_types):\n            message = 'Mapping key ({0}) has to be a string.'\n            matches.append(RuleMatch(path[:], message.format(key)))\n        elif not re.match(REGEX_ALPHANUMERIC, key) and check_alphanumeric:\n            message = 'Mapping key ({0}) has invalid name. Name has to be alphanumeric.'\n            matches.append(RuleMatch(path[:], message.format(key)))\n\n        return matches\n\n    def match(self, cfn):\n        matches = []\n\n        mappings = cfn.template.get('Mappings', {})\n        for mapping_name, mapping_value in mappings.items():\n            if isinstance(mapping_value, dict):\n                for key_name, key_value in mapping_value.items():\n                    matches.extend(self.check_key(\n                        key_name, ['Mappings', mapping_name, key_name], False))\n                    if isinstance(key_value, dict):\n                        for sub_key_name, _ in key_value.items():\n                            matches.extend(\n                                self.check_key(\n                                    sub_key_name, ['Mappings', mapping_name, key_name, sub_key_name]))\n\n        return matches\n", "path": "src/cfnlint/rules/mappings/KeyName.py"}]}