prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  cloudformation deploy does not honour tabs in JSON templates
  Most of our templates are using tabs for the indentation and everything was fine until we tried to feed the template to `aws cloudformation deploy` which did not like the template despite that every other function in AWS CLI works with the template just fine:
  
  ```
  [galaxy@athena templates]$ aws cloudformation validate-template --template-body file://codepipeline.template
  {
      "CapabilitiesReason": "The following resource(s) require capabilities: [AWS::IAM::Role]", 
      "Description": "Playing with CodeCommit, CodeBuild, and CodeDeploy", 
      "Parameters": [
  ```
  and the only function that fails to parse the template is:
  ```
  [galaxy@athena templates]$ aws cloudformation deploy --stack-name "galaxy-ccc" --template-file codepipeline.template --capabilities CAPABILITY_IAM
  
  while scanning for the next token
  found character '\t' that cannot start any token
    in "<string>", line 2, column 1:
      	"AWSTemplateFormatVersion": "20 ... 
      ^
  ```
  A quick fix is to replace tabs with spaces:
  ```
  [galaxy@athena templates]$ sed 's,\t, ,g' codepipeline.template > c.template
  [galaxy@athena templates]$ aws cloudformation deploy --stack-name "galaxy-ccc" --template-file c.template --capabilities CAPABILITY_IAM
  Waiting for changeset to be created..
  Waiting for stack create/update to complete
  ```
  
  ... but it would mean that we would need to fix all our templates which are valid JSON just to workaround a bug in the tool! :(
  
  </issue>
  <code>
  [start of awscli/customizations/cloudformation/yamlhelper.py]
  1 # Copyright 2012-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
  2 #
  3 # Licensed under the Apache License, Version 2.0 (the "License"). You
  4 # may not use this file except in compliance with the License. A copy of
  5 # the License is located at
  6 #
  7 # http://aws.amazon.com/apache2.0/
  8 #
  9 # or in the "license" file accompanying this file. This file is
  10 # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
  11 # ANY KIND, either express or implied. See the License for the specific
  12 # language governing permissions and limitations under the License.
  13 
  14 import yaml
  15 from awscli.compat import six
  16 from yaml.resolver import ScalarNode, SequenceNode
  17 
  18 
  19 def intrinsics_multi_constructor(loader, tag_prefix, node):
  20     """
  21     YAML constructor to parse CloudFormation intrinsics.
  22     This will return a dictionary with key being the instrinsic name
  23     """
  24 
  25     # Get the actual tag name excluding the first exclamation
  26     tag = node.tag[1:]
  27 
  28     # All CloudFormation intrinsics have prefix Fn:: except Ref
  29     prefix = "Fn::"
  30     if tag == "Ref":
  31         prefix = ""
  32 
  33     cfntag = prefix + tag
  34 
  35     if tag == "GetAtt" and isinstance(node.value, six.string_types):
  36         # ShortHand notation for !GetAtt accepts Resource.Attribute format
  37         # while the standard notation is to use an array
  38         # [Resource, Attribute]. Convert shorthand to standard format
  39         value = node.value.split(".", 1)
  40 
  41     elif isinstance(node, ScalarNode):
  42         # Value of this node is scalar
  43         value = loader.construct_scalar(node)
  44 
  45     elif isinstance(node, SequenceNode):
  46         # Value of this node is an array (Ex: [1,2])
  47         value = loader.construct_sequence(node)
  48 
  49     else:
  50         # Value of this node is an mapping (ex: {foo: bar})
  51         value = loader.construct_mapping(node)
  52 
  53     return {cfntag: value}
  54 
  55 
  56 def yaml_dump(dict_to_dump):
  57     """
  58     Dumps the dictionary as a YAML document
  59     :param dict_to_dump:
  60     :return:
  61     """
  62     return yaml.safe_dump(dict_to_dump, default_flow_style=False)
  63 
  64 
  65 def yaml_parse(yamlstr):
  66 
  67     yaml.SafeLoader.add_multi_constructor("!", intrinsics_multi_constructor)
  68 
  69     return yaml.safe_load(yamlstr)
  70
  [end of awscli/customizations/cloudformation/yamlhelper.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/awscli/customizations/cloudformation/yamlhelper.py b/awscli/customizations/cloudformation/yamlhelper.py
  --- a/awscli/customizations/cloudformation/yamlhelper.py
  +++ b/awscli/customizations/cloudformation/yamlhelper.py
  @@ -10,11 +10,12 @@
   # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
   # ANY KIND, either express or implied. See the License for the specific
   # language governing permissions and limitations under the License.
  -
  +import json
   import yaml
  -from awscli.compat import six
   from yaml.resolver import ScalarNode, SequenceNode
   
  +from awscli.compat import six
  +
   
   def intrinsics_multi_constructor(loader, tag_prefix, node):
       """
  @@ -63,7 +64,13 @@
   
   
   def yaml_parse(yamlstr):
  -
  -    yaml.SafeLoader.add_multi_constructor("!", intrinsics_multi_constructor)
  -
  -    return yaml.safe_load(yamlstr)
  +    """Parse a yaml string"""
  +    try:
  +        # PyYAML doesn't support json as well as it should, so if the input
  +        # is actually just json it is better to parse it with the standard
  +        # json parser.
  +        return json.loads(yamlstr)
  +    except ValueError:
  +        yaml.SafeLoader.add_multi_constructor(
  +            "!", intrinsics_multi_constructor)
  +        return yaml.safe_load(yamlstr)
  
verification_info: {"golden_diff": "diff --git a/awscli/customizations/cloudformation/yamlhelper.py b/awscli/customizations/cloudformation/yamlhelper.py\n--- a/awscli/customizations/cloudformation/yamlhelper.py\n+++ b/awscli/customizations/cloudformation/yamlhelper.py\n@@ -10,11 +10,12 @@\n # distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n # ANY KIND, either express or implied. See the License for the specific\n # language governing permissions and limitations under the License.\n-\n+import json\n import yaml\n-from awscli.compat import six\n from yaml.resolver import ScalarNode, SequenceNode\n \n+from awscli.compat import six\n+\n \n def intrinsics_multi_constructor(loader, tag_prefix, node):\n     \"\"\"\n@@ -63,7 +64,13 @@\n \n \n def yaml_parse(yamlstr):\n-\n-    yaml.SafeLoader.add_multi_constructor(\"!\", intrinsics_multi_constructor)\n-\n-    return yaml.safe_load(yamlstr)\n+    \"\"\"Parse a yaml string\"\"\"\n+    try:\n+        # PyYAML doesn't support json as well as it should, so if the input\n+        # is actually just json it is better to parse it with the standard\n+        # json parser.\n+        return json.loads(yamlstr)\n+    except ValueError:\n+        yaml.SafeLoader.add_multi_constructor(\n+            \"!\", intrinsics_multi_constructor)\n+        return yaml.safe_load(yamlstr)\n", "issue": "cloudformation deploy does not honour tabs in JSON templates\nMost of our templates are using tabs for the indentation and everything was fine until we tried to feed the template to `aws cloudformation deploy` which did not like the template despite that every other function in AWS CLI works with the template just fine:\r\n\r\n```\r\n[galaxy@athena templates]$ aws cloudformation validate-template --template-body file://codepipeline.template\r\n{\r\n    \"CapabilitiesReason\": \"The following resource(s) require capabilities: [AWS::IAM::Role]\", \r\n    \"Description\": \"Playing with CodeCommit, CodeBuild, and CodeDeploy\", \r\n    \"Parameters\": [\r\n```\r\nand the only function that fails to parse the template is:\r\n```\r\n[galaxy@athena templates]$ aws cloudformation deploy --stack-name \"galaxy-ccc\" --template-file codepipeline.template --capabilities CAPABILITY_IAM\r\n\r\nwhile scanning for the next token\r\nfound character '\\t' that cannot start any token\r\n  in \"<string>\", line 2, column 1:\r\n    \t\"AWSTemplateFormatVersion\": \"20 ... \r\n    ^\r\n```\r\nA quick fix is to replace tabs with spaces:\r\n```\r\n[galaxy@athena templates]$ sed 's,\\t, ,g' codepipeline.template > c.template\r\n[galaxy@athena templates]$ aws cloudformation deploy --stack-name \"galaxy-ccc\" --template-file c.template --capabilities CAPABILITY_IAM\r\nWaiting for changeset to be created..\r\nWaiting for stack create/update to complete\r\n```\r\n\r\n... but it would mean that we would need to fix all our templates which are valid JSON just to workaround a bug in the tool! :(\n", "before_files": [{"content": "# Copyright 2012-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"). You\n# may not use this file except in compliance with the License. A copy of\n# the License is located at\n#\n# http://aws.amazon.com/apache2.0/\n#\n# or in the \"license\" file accompanying this file. This file is\n# distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n# ANY KIND, either express or implied. See the License for the specific\n# language governing permissions and limitations under the License.\n\nimport yaml\nfrom awscli.compat import six\nfrom yaml.resolver import ScalarNode, SequenceNode\n\n\ndef intrinsics_multi_constructor(loader, tag_prefix, node):\n    \"\"\"\n    YAML constructor to parse CloudFormation intrinsics.\n    This will return a dictionary with key being the instrinsic name\n    \"\"\"\n\n    # Get the actual tag name excluding the first exclamation\n    tag = node.tag[1:]\n\n    # All CloudFormation intrinsics have prefix Fn:: except Ref\n    prefix = \"Fn::\"\n    if tag == \"Ref\":\n        prefix = \"\"\n\n    cfntag = prefix + tag\n\n    if tag == \"GetAtt\" and isinstance(node.value, six.string_types):\n        # ShortHand notation for !GetAtt accepts Resource.Attribute format\n        # while the standard notation is to use an array\n        # [Resource, Attribute]. Convert shorthand to standard format\n        value = node.value.split(\".\", 1)\n\n    elif isinstance(node, ScalarNode):\n        # Value of this node is scalar\n        value = loader.construct_scalar(node)\n\n    elif isinstance(node, SequenceNode):\n        # Value of this node is an array (Ex: [1,2])\n        value = loader.construct_sequence(node)\n\n    else:\n        # Value of this node is an mapping (ex: {foo: bar})\n        value = loader.construct_mapping(node)\n\n    return {cfntag: value}\n\n\ndef yaml_dump(dict_to_dump):\n    \"\"\"\n    Dumps the dictionary as a YAML document\n    :param dict_to_dump:\n    :return:\n    \"\"\"\n    return yaml.safe_dump(dict_to_dump, default_flow_style=False)\n\n\ndef yaml_parse(yamlstr):\n\n    yaml.SafeLoader.add_multi_constructor(\"!\", intrinsics_multi_constructor)\n\n    return yaml.safe_load(yamlstr)\n", "path": "awscli/customizations/cloudformation/yamlhelper.py"}]}