We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Any capitalization of "nan" or "inf" is interpreted as a float, not a symbol
For example:

    => (setv Nan 5)
      File "<input>", line 1, column 7

      (setv Nan 5)
            ^--^
    HyTypeError: b"Can't assign or delete a HyFloat"

The fact that Hy accepts literals for floating-point infinity and NaN, albeit unintentional, is a nice feature that we might as well keep. But, Hy ought to recognize only one capitalization.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `hy/models.py`
Content:
```
1 # Copyright 2017 the authors.
2 # This file is part of Hy, which is free software licensed under the Expat
3 # license. See the LICENSE.
4 
5 from __future__ import unicode_literals
6 from hy._compat import PY3, str_type, bytes_type, long_type, string_types
7 from fractions import Fraction
8 
9 
10 class HyObject(object):
11     """
12     Generic Hy Object model. This is helpful to inject things into all the
13     Hy lexing Objects at once.
14     """
15 
16     def replace(self, other):
17         if isinstance(other, HyObject):
18             for attr in ["start_line", "end_line",
19                          "start_column", "end_column"]:
20                 if not hasattr(self, attr) and hasattr(other, attr):
21                     setattr(self, attr, getattr(other, attr))
22         else:
23             raise TypeError("Can't replace a non Hy object with a Hy object")
24 
25         return self
26 
27 
28 _wrappers = {}
29 
30 
31 def wrap_value(x):
32     """Wrap `x` into the corresponding Hy type.
33 
34     This allows replace_hy_obj to convert a non Hy object to a Hy object.
35 
36     This also allows a macro to return an unquoted expression transparently.
37 
38     """
39 
40     wrapper = _wrappers.get(type(x))
41     if wrapper is None:
42         return x
43     else:
44         return wrapper(x)
45 
46 
47 def replace_hy_obj(obj, other):
48 
49     if isinstance(obj, HyObject):
50         return obj.replace(other)
51 
52     wrapped_obj = wrap_value(obj)
53 
54     if isinstance(wrapped_obj, HyObject):
55         return wrapped_obj.replace(other)
56     else:
57         raise TypeError("Don't know how to wrap a %s object to a HyObject"
58                         % type(obj))
59 
60 
61 class HyString(HyObject, str_type):
62     """
63     Generic Hy String object. Helpful to store string literals from Hy
64     scripts. It's either a ``str`` or a ``unicode``, depending on the
65     Python version.
66     """
67     pass
68 
69 _wrappers[str_type] = HyString
70 
71 
72 class HyBytes(HyObject, bytes_type):
73     """
74     Generic Hy Bytes object. It's either a ``bytes`` or a ``str``, depending
75     on the Python version.
76     """
77     pass
78 
79 _wrappers[bytes_type] = HyBytes
80 
81 
82 class HySymbol(HyString):
83     """
84     Hy Symbol. Basically a String.
85     """
86 
87     def __init__(self, string):
88         self += string
89 
90 _wrappers[bool] = lambda x: HySymbol("True") if x else HySymbol("False")
91 _wrappers[type(None)] = lambda foo: HySymbol("None")
92 
93 
94 class HyKeyword(HyObject, str_type):
95     """Generic Hy Keyword object. It's either a ``str`` or a ``unicode``,
96     depending on the Python version.
97     """
98 
99     PREFIX = "\uFDD0"
100 
101     def __new__(cls, value):
102         if not value.startswith(cls.PREFIX):
103             value = cls.PREFIX + value
104 
105         obj = str_type.__new__(cls, value)
106         return obj
107 
108 
109 def strip_digit_separators(number):
110     return (number.replace("_", "").replace(",", "")
111             if isinstance(number, string_types)
112             else number)
113 
114 
115 class HyInteger(HyObject, long_type):
116     """
117     Internal representation of a Hy Integer. May raise a ValueError as if
118     int(foo) was called, given HyInteger(foo). On python 2.x long will
119     be used instead
120     """
121 
122     def __new__(cls, number, *args, **kwargs):
123         if isinstance(number, string_types):
124             number = strip_digit_separators(number)
125             bases = {"0x": 16, "0o": 8, "0b": 2}
126             for leader, base in bases.items():
127                 if number.startswith(leader):
128                     # We've got a string, known leader, set base.
129                     number = long_type(number, base=base)
130                     break
131             else:
132                 # We've got a string, no known leader; base 10.
133                 number = long_type(number, base=10)
134         else:
135             # We've got a non-string; convert straight.
136             number = long_type(number)
137         return super(HyInteger, cls).__new__(cls, number)
138 
139 
140 _wrappers[int] = HyInteger
141 if not PY3:  # do not add long on python3
142     _wrappers[long_type] = HyInteger
143 
144 
145 class HyFloat(HyObject, float):
146     """
147     Internal representation of a Hy Float. May raise a ValueError as if
148     float(foo) was called, given HyFloat(foo).
149     """
150 
151     def __new__(cls, number, *args, **kwargs):
152         number = float(strip_digit_separators(number))
153         return super(HyFloat, cls).__new__(cls, number)
154 
155 _wrappers[float] = HyFloat
156 
157 
158 class HyComplex(HyObject, complex):
159     """
160     Internal representation of a Hy Complex. May raise a ValueError as if
161     complex(foo) was called, given HyComplex(foo).
162     """
163 
164     def __new__(cls, number, *args, **kwargs):
165         number = complex(strip_digit_separators(number))
166         return super(HyComplex, cls).__new__(cls, number)
167 
168 _wrappers[complex] = HyComplex
169 
170 
171 class HyList(HyObject, list):
172     """
173     Hy List. Basically just a list.
174     """
175 
176     def replace(self, other):
177         for x in self:
178             replace_hy_obj(x, other)
179 
180         HyObject.replace(self, other)
181         return self
182 
183     def __add__(self, other):
184         return self.__class__(super(HyList, self).__add__(other))
185 
186     def __getslice__(self, start, end):
187         return self.__class__(super(HyList, self).__getslice__(start, end))
188 
189     def __getitem__(self, item):
190         ret = super(HyList, self).__getitem__(item)
191 
192         if isinstance(item, slice):
193             return self.__class__(ret)
194 
195         return ret
196 
197     def __repr__(self):
198         return "[%s]" % (" ".join([repr(x) for x in self]))
199 
200 _wrappers[list] = lambda l: HyList(wrap_value(x) for x in l)
201 _wrappers[tuple] = lambda t: HyList(wrap_value(x) for x in t)
202 
203 
204 class HyDict(HyList):
205     """
206     HyDict (just a representation of a dict)
207     """
208 
209     def __repr__(self):
210         return "{%s}" % (" ".join([repr(x) for x in self]))
211 
212     def keys(self):
213         return self[0::2]
214 
215     def values(self):
216         return self[1::2]
217 
218     def items(self):
219         return list(zip(self.keys(), self.values()))
220 
221 _wrappers[dict] = lambda d: HyDict(wrap_value(x) for x in sum(d.items(), ()))
222 
223 
224 class HyExpression(HyList):
225     """
226     Hy S-Expression. Basically just a list.
227     """
228 
229     def __repr__(self):
230         return "(%s)" % (" ".join([repr(x) for x in self]))
231 
232 _wrappers[HyExpression] = lambda e: HyExpression(wrap_value(x) for x in e)
233 _wrappers[Fraction] = lambda e: HyExpression(
234     [HySymbol("fraction"), wrap_value(e.numerator), wrap_value(e.denominator)])
235 
236 
237 class HySet(HyList):
238     """
239     Hy set (just a representation of a set)
240     """
241 
242     def __repr__(self):
243         return "#{%s}" % (" ".join([repr(x) for x in self]))
244 
245 _wrappers[set] = lambda s: HySet(wrap_value(x) for x in s)
246 
247 
248 class HyCons(HyObject):
249     """
250     HyCons: a cons object.
251 
252     Building a HyCons of something and a HyList really builds a HyList
253     """
254 
255     __slots__ = ["car", "cdr"]
256 
257     def __new__(cls, car, cdr):
258         if isinstance(cdr, list):
259 
260             # Keep unquotes in the cdr of conses
261             if type(cdr) == HyExpression:
262                 if len(cdr) > 0 and type(cdr[0]) == HySymbol:
263                     if cdr[0] in ("unquote", "unquote_splice"):
264                         return super(HyCons, cls).__new__(cls)
265 
266             return cdr.__class__([wrap_value(car)] + cdr)
267 
268         elif cdr is None:
269             return HyExpression([wrap_value(car)])
270 
271         else:
272             return super(HyCons, cls).__new__(cls)
273 
274     def __init__(self, car, cdr):
275         self.car = wrap_value(car)
276         self.cdr = wrap_value(cdr)
277 
278     def __getitem__(self, n):
279         if n == 0:
280             return self.car
281         if n == slice(1, None):
282             return self.cdr
283 
284         raise IndexError(
285             "Can only get the car ([0]) or the cdr ([1:]) of a HyCons")
286 
287     def __setitem__(self, n, new):
288         if n == 0:
289             self.car = new
290             return
291         if n == slice(1, None):
292             self.cdr = new
293             return
294 
295         raise IndexError(
296             "Can only set the car ([0]) or the cdr ([1:]) of a HyCons")
297 
298     def __iter__(self):
299         yield self.car
300         try:
301             iterator = (i for i in self.cdr)
302         except TypeError:
303             if self.cdr is not None:
304                 yield self.cdr
305                 raise TypeError("Iteration on malformed cons")
306         else:
307             for i in iterator:
308                 yield i
309 
310     def replace(self, other):
311         if self.car is not None:
312             replace_hy_obj(self.car, other)
313         if self.cdr is not None:
314             replace_hy_obj(self.cdr, other)
315 
316         HyObject.replace(self, other)
317 
318     def __repr__(self):
319         if isinstance(self.cdr, self.__class__):
320             return "(%s %s)" % (repr(self.car), repr(self.cdr)[1:-1])
321         else:
322             return "(%s . %s)" % (repr(self.car), repr(self.cdr))
323 
324     def __eq__(self, other):
325         return (
326             isinstance(other, self.__class__) and
327             self.car == other.car and
328             self.cdr == other.cdr
329         )
330
```
--- 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()

```

diff --git a/hy/models.py b/hy/models.py
--- a/hy/models.py
+++ b/hy/models.py
@@ -3,6 +3,7 @@
 # license. See the LICENSE.
 
 from __future__ import unicode_literals
+from math import isnan, isinf
 from hy._compat import PY3, str_type, bytes_type, long_type, string_types
 from fractions import Fraction
 
@@ -142,15 +143,24 @@
     _wrappers[long_type] = HyInteger
 
 
+def check_inf_nan_cap(arg, value):
+    if isinstance(arg, string_types):
+        if isinf(value) and "Inf" not in arg:
+            raise ValueError('Inf must be capitalized as "Inf"')
+        if isnan(value) and "NaN" not in arg:
+            raise ValueError('NaN must be capitalized as "NaN"')
+
+
 class HyFloat(HyObject, float):
     """
     Internal representation of a Hy Float. May raise a ValueError as if
     float(foo) was called, given HyFloat(foo).
     """
 
-    def __new__(cls, number, *args, **kwargs):
-        number = float(strip_digit_separators(number))
-        return super(HyFloat, cls).__new__(cls, number)
+    def __new__(cls, num, *args, **kwargs):
+        value = super(HyFloat, cls).__new__(cls, strip_digit_separators(num))
+        check_inf_nan_cap(num, value)
+        return value
 
 _wrappers[float] = HyFloat
 
@@ -161,9 +171,18 @@
     complex(foo) was called, given HyComplex(foo).
     """
 
-    def __new__(cls, number, *args, **kwargs):
-        number = complex(strip_digit_separators(number))
-        return super(HyComplex, cls).__new__(cls, number)
+    def __new__(cls, num, *args, **kwargs):
+        value = super(HyComplex, cls).__new__(cls, strip_digit_separators(num))
+        if isinstance(num, string_types):
+            p1, _, p2 = num.lstrip("+-").replace("-", "+").partition("+")
+            if p2:
+                check_inf_nan_cap(p1, value.real)
+                check_inf_nan_cap(p2, value.imag)
+            elif "j" in p1:
+                check_inf_nan_cap(p1, value.imag)
+            else:
+                check_inf_nan_cap(p1, value.real)
+        return value
 
 _wrappers[complex] = HyComplex

{"golden_diff": "diff --git a/hy/models.py b/hy/models.py\n--- a/hy/models.py\n+++ b/hy/models.py\n@@ -3,6 +3,7 @@\n # license. See the LICENSE.\n \n from __future__ import unicode_literals\n+from math import isnan, isinf\n from hy._compat import PY3, str_type, bytes_type, long_type, string_types\n from fractions import Fraction\n \n@@ -142,15 +143,24 @@\n     _wrappers[long_type] = HyInteger\n \n \n+def check_inf_nan_cap(arg, value):\n+    if isinstance(arg, string_types):\n+        if isinf(value) and \"Inf\" not in arg:\n+            raise ValueError('Inf must be capitalized as \"Inf\"')\n+        if isnan(value) and \"NaN\" not in arg:\n+            raise ValueError('NaN must be capitalized as \"NaN\"')\n+\n+\n class HyFloat(HyObject, float):\n     \"\"\"\n     Internal representation of a Hy Float. May raise a ValueError as if\n     float(foo) was called, given HyFloat(foo).\n     \"\"\"\n \n-    def __new__(cls, number, *args, **kwargs):\n-        number = float(strip_digit_separators(number))\n-        return super(HyFloat, cls).__new__(cls, number)\n+    def __new__(cls, num, *args, **kwargs):\n+        value = super(HyFloat, cls).__new__(cls, strip_digit_separators(num))\n+        check_inf_nan_cap(num, value)\n+        return value\n \n _wrappers[float] = HyFloat\n \n@@ -161,9 +171,18 @@\n     complex(foo) was called, given HyComplex(foo).\n     \"\"\"\n \n-    def __new__(cls, number, *args, **kwargs):\n-        number = complex(strip_digit_separators(number))\n-        return super(HyComplex, cls).__new__(cls, number)\n+    def __new__(cls, num, *args, **kwargs):\n+        value = super(HyComplex, cls).__new__(cls, strip_digit_separators(num))\n+        if isinstance(num, string_types):\n+            p1, _, p2 = num.lstrip(\"+-\").replace(\"-\", \"+\").partition(\"+\")\n+            if p2:\n+                check_inf_nan_cap(p1, value.real)\n+                check_inf_nan_cap(p2, value.imag)\n+            elif \"j\" in p1:\n+                check_inf_nan_cap(p1, value.imag)\n+            else:\n+                check_inf_nan_cap(p1, value.real)\n+        return value\n \n _wrappers[complex] = HyComplex\n", "issue": "Any capitalization of \"nan\" or \"inf\" is interpreted as a float, not a symbol\nFor example:\r\n\r\n    => (setv Nan 5)\r\n      File \"<input>\", line 1, column 7\r\n\r\n      (setv Nan 5)\r\n            ^--^\r\n    HyTypeError: b\"Can't assign or delete a HyFloat\"\r\n\r\nThe fact that Hy accepts literals for floating-point infinity and NaN, albeit unintentional, is a nice feature that we might as well keep. But, Hy ought to recognize only one capitalization.\n", "before_files": [{"content": "# Copyright 2017 the authors.\n# This file is part of Hy, which is free software licensed under the Expat\n# license. See the LICENSE.\n\nfrom __future__ import unicode_literals\nfrom hy._compat import PY3, str_type, bytes_type, long_type, string_types\nfrom fractions import Fraction\n\n\nclass HyObject(object):\n    \"\"\"\n    Generic Hy Object model. This is helpful to inject things into all the\n    Hy lexing Objects at once.\n    \"\"\"\n\n    def replace(self, other):\n        if isinstance(other, HyObject):\n            for attr in [\"start_line\", \"end_line\",\n                         \"start_column\", \"end_column\"]:\n                if not hasattr(self, attr) and hasattr(other, attr):\n                    setattr(self, attr, getattr(other, attr))\n        else:\n            raise TypeError(\"Can't replace a non Hy object with a Hy object\")\n\n        return self\n\n\n_wrappers = {}\n\n\ndef wrap_value(x):\n    \"\"\"Wrap `x` into the corresponding Hy type.\n\n    This allows replace_hy_obj to convert a non Hy object to a Hy object.\n\n    This also allows a macro to return an unquoted expression transparently.\n\n    \"\"\"\n\n    wrapper = _wrappers.get(type(x))\n    if wrapper is None:\n        return x\n    else:\n        return wrapper(x)\n\n\ndef replace_hy_obj(obj, other):\n\n    if isinstance(obj, HyObject):\n        return obj.replace(other)\n\n    wrapped_obj = wrap_value(obj)\n\n    if isinstance(wrapped_obj, HyObject):\n        return wrapped_obj.replace(other)\n    else:\n        raise TypeError(\"Don't know how to wrap a %s object to a HyObject\"\n                        % type(obj))\n\n\nclass HyString(HyObject, str_type):\n    \"\"\"\n    Generic Hy String object. Helpful to store string literals from Hy\n    scripts. It's either a ``str`` or a ``unicode``, depending on the\n    Python version.\n    \"\"\"\n    pass\n\n_wrappers[str_type] = HyString\n\n\nclass HyBytes(HyObject, bytes_type):\n    \"\"\"\n    Generic Hy Bytes object. It's either a ``bytes`` or a ``str``, depending\n    on the Python version.\n    \"\"\"\n    pass\n\n_wrappers[bytes_type] = HyBytes\n\n\nclass HySymbol(HyString):\n    \"\"\"\n    Hy Symbol. Basically a String.\n    \"\"\"\n\n    def __init__(self, string):\n        self += string\n\n_wrappers[bool] = lambda x: HySymbol(\"True\") if x else HySymbol(\"False\")\n_wrappers[type(None)] = lambda foo: HySymbol(\"None\")\n\n\nclass HyKeyword(HyObject, str_type):\n    \"\"\"Generic Hy Keyword object. It's either a ``str`` or a ``unicode``,\n    depending on the Python version.\n    \"\"\"\n\n    PREFIX = \"\\uFDD0\"\n\n    def __new__(cls, value):\n        if not value.startswith(cls.PREFIX):\n            value = cls.PREFIX + value\n\n        obj = str_type.__new__(cls, value)\n        return obj\n\n\ndef strip_digit_separators(number):\n    return (number.replace(\"_\", \"\").replace(\",\", \"\")\n            if isinstance(number, string_types)\n            else number)\n\n\nclass HyInteger(HyObject, long_type):\n    \"\"\"\n    Internal representation of a Hy Integer. May raise a ValueError as if\n    int(foo) was called, given HyInteger(foo). On python 2.x long will\n    be used instead\n    \"\"\"\n\n    def __new__(cls, number, *args, **kwargs):\n        if isinstance(number, string_types):\n            number = strip_digit_separators(number)\n            bases = {\"0x\": 16, \"0o\": 8, \"0b\": 2}\n            for leader, base in bases.items():\n                if number.startswith(leader):\n                    # We've got a string, known leader, set base.\n                    number = long_type(number, base=base)\n                    break\n            else:\n                # We've got a string, no known leader; base 10.\n                number = long_type(number, base=10)\n        else:\n            # We've got a non-string; convert straight.\n            number = long_type(number)\n        return super(HyInteger, cls).__new__(cls, number)\n\n\n_wrappers[int] = HyInteger\nif not PY3:  # do not add long on python3\n    _wrappers[long_type] = HyInteger\n\n\nclass HyFloat(HyObject, float):\n    \"\"\"\n    Internal representation of a Hy Float. May raise a ValueError as if\n    float(foo) was called, given HyFloat(foo).\n    \"\"\"\n\n    def __new__(cls, number, *args, **kwargs):\n        number = float(strip_digit_separators(number))\n        return super(HyFloat, cls).__new__(cls, number)\n\n_wrappers[float] = HyFloat\n\n\nclass HyComplex(HyObject, complex):\n    \"\"\"\n    Internal representation of a Hy Complex. May raise a ValueError as if\n    complex(foo) was called, given HyComplex(foo).\n    \"\"\"\n\n    def __new__(cls, number, *args, **kwargs):\n        number = complex(strip_digit_separators(number))\n        return super(HyComplex, cls).__new__(cls, number)\n\n_wrappers[complex] = HyComplex\n\n\nclass HyList(HyObject, list):\n    \"\"\"\n    Hy List. Basically just a list.\n    \"\"\"\n\n    def replace(self, other):\n        for x in self:\n            replace_hy_obj(x, other)\n\n        HyObject.replace(self, other)\n        return self\n\n    def __add__(self, other):\n        return self.__class__(super(HyList, self).__add__(other))\n\n    def __getslice__(self, start, end):\n        return self.__class__(super(HyList, self).__getslice__(start, end))\n\n    def __getitem__(self, item):\n        ret = super(HyList, self).__getitem__(item)\n\n        if isinstance(item, slice):\n            return self.__class__(ret)\n\n        return ret\n\n    def __repr__(self):\n        return \"[%s]\" % (\" \".join([repr(x) for x in self]))\n\n_wrappers[list] = lambda l: HyList(wrap_value(x) for x in l)\n_wrappers[tuple] = lambda t: HyList(wrap_value(x) for x in t)\n\n\nclass HyDict(HyList):\n    \"\"\"\n    HyDict (just a representation of a dict)\n    \"\"\"\n\n    def __repr__(self):\n        return \"{%s}\" % (\" \".join([repr(x) for x in self]))\n\n    def keys(self):\n        return self[0::2]\n\n    def values(self):\n        return self[1::2]\n\n    def items(self):\n        return list(zip(self.keys(), self.values()))\n\n_wrappers[dict] = lambda d: HyDict(wrap_value(x) for x in sum(d.items(), ()))\n\n\nclass HyExpression(HyList):\n    \"\"\"\n    Hy S-Expression. Basically just a list.\n    \"\"\"\n\n    def __repr__(self):\n        return \"(%s)\" % (\" \".join([repr(x) for x in self]))\n\n_wrappers[HyExpression] = lambda e: HyExpression(wrap_value(x) for x in e)\n_wrappers[Fraction] = lambda e: HyExpression(\n    [HySymbol(\"fraction\"), wrap_value(e.numerator), wrap_value(e.denominator)])\n\n\nclass HySet(HyList):\n    \"\"\"\n    Hy set (just a representation of a set)\n    \"\"\"\n\n    def __repr__(self):\n        return \"#{%s}\" % (\" \".join([repr(x) for x in self]))\n\n_wrappers[set] = lambda s: HySet(wrap_value(x) for x in s)\n\n\nclass HyCons(HyObject):\n    \"\"\"\n    HyCons: a cons object.\n\n    Building a HyCons of something and a HyList really builds a HyList\n    \"\"\"\n\n    __slots__ = [\"car\", \"cdr\"]\n\n    def __new__(cls, car, cdr):\n        if isinstance(cdr, list):\n\n            # Keep unquotes in the cdr of conses\n            if type(cdr) == HyExpression:\n                if len(cdr) > 0 and type(cdr[0]) == HySymbol:\n                    if cdr[0] in (\"unquote\", \"unquote_splice\"):\n                        return super(HyCons, cls).__new__(cls)\n\n            return cdr.__class__([wrap_value(car)] + cdr)\n\n        elif cdr is None:\n            return HyExpression([wrap_value(car)])\n\n        else:\n            return super(HyCons, cls).__new__(cls)\n\n    def __init__(self, car, cdr):\n        self.car = wrap_value(car)\n        self.cdr = wrap_value(cdr)\n\n    def __getitem__(self, n):\n        if n == 0:\n            return self.car\n        if n == slice(1, None):\n            return self.cdr\n\n        raise IndexError(\n            \"Can only get the car ([0]) or the cdr ([1:]) of a HyCons\")\n\n    def __setitem__(self, n, new):\n        if n == 0:\n            self.car = new\n            return\n        if n == slice(1, None):\n            self.cdr = new\n            return\n\n        raise IndexError(\n            \"Can only set the car ([0]) or the cdr ([1:]) of a HyCons\")\n\n    def __iter__(self):\n        yield self.car\n        try:\n            iterator = (i for i in self.cdr)\n        except TypeError:\n            if self.cdr is not None:\n                yield self.cdr\n                raise TypeError(\"Iteration on malformed cons\")\n        else:\n            for i in iterator:\n                yield i\n\n    def replace(self, other):\n        if self.car is not None:\n            replace_hy_obj(self.car, other)\n        if self.cdr is not None:\n            replace_hy_obj(self.cdr, other)\n\n        HyObject.replace(self, other)\n\n    def __repr__(self):\n        if isinstance(self.cdr, self.__class__):\n            return \"(%s %s)\" % (repr(self.car), repr(self.cdr)[1:-1])\n        else:\n            return \"(%s . %s)\" % (repr(self.car), repr(self.cdr))\n\n    def __eq__(self, other):\n        return (\n            isinstance(other, self.__class__) and\n            self.car == other.car and\n            self.cdr == other.cdr\n        )\n", "path": "hy/models.py"}], "after_files": [{"content": "# Copyright 2017 the authors.\n# This file is part of Hy, which is free software licensed under the Expat\n# license. See the LICENSE.\n\nfrom __future__ import unicode_literals\nfrom math import isnan, isinf\nfrom hy._compat import PY3, str_type, bytes_type, long_type, string_types\nfrom fractions import Fraction\n\n\nclass HyObject(object):\n    \"\"\"\n    Generic Hy Object model. This is helpful to inject things into all the\n    Hy lexing Objects at once.\n    \"\"\"\n\n    def replace(self, other):\n        if isinstance(other, HyObject):\n            for attr in [\"start_line\", \"end_line\",\n                         \"start_column\", \"end_column\"]:\n                if not hasattr(self, attr) and hasattr(other, attr):\n                    setattr(self, attr, getattr(other, attr))\n        else:\n            raise TypeError(\"Can't replace a non Hy object with a Hy object\")\n\n        return self\n\n\n_wrappers = {}\n\n\ndef wrap_value(x):\n    \"\"\"Wrap `x` into the corresponding Hy type.\n\n    This allows replace_hy_obj to convert a non Hy object to a Hy object.\n\n    This also allows a macro to return an unquoted expression transparently.\n\n    \"\"\"\n\n    wrapper = _wrappers.get(type(x))\n    if wrapper is None:\n        return x\n    else:\n        return wrapper(x)\n\n\ndef replace_hy_obj(obj, other):\n\n    if isinstance(obj, HyObject):\n        return obj.replace(other)\n\n    wrapped_obj = wrap_value(obj)\n\n    if isinstance(wrapped_obj, HyObject):\n        return wrapped_obj.replace(other)\n    else:\n        raise TypeError(\"Don't know how to wrap a %s object to a HyObject\"\n                        % type(obj))\n\n\nclass HyString(HyObject, str_type):\n    \"\"\"\n    Generic Hy String object. Helpful to store string literals from Hy\n    scripts. It's either a ``str`` or a ``unicode``, depending on the\n    Python version.\n    \"\"\"\n    pass\n\n_wrappers[str_type] = HyString\n\n\nclass HyBytes(HyObject, bytes_type):\n    \"\"\"\n    Generic Hy Bytes object. It's either a ``bytes`` or a ``str``, depending\n    on the Python version.\n    \"\"\"\n    pass\n\n_wrappers[bytes_type] = HyBytes\n\n\nclass HySymbol(HyString):\n    \"\"\"\n    Hy Symbol. Basically a String.\n    \"\"\"\n\n    def __init__(self, string):\n        self += string\n\n_wrappers[bool] = lambda x: HySymbol(\"True\") if x else HySymbol(\"False\")\n_wrappers[type(None)] = lambda foo: HySymbol(\"None\")\n\n\nclass HyKeyword(HyObject, str_type):\n    \"\"\"Generic Hy Keyword object. It's either a ``str`` or a ``unicode``,\n    depending on the Python version.\n    \"\"\"\n\n    PREFIX = \"\\uFDD0\"\n\n    def __new__(cls, value):\n        if not value.startswith(cls.PREFIX):\n            value = cls.PREFIX + value\n\n        obj = str_type.__new__(cls, value)\n        return obj\n\n\ndef strip_digit_separators(number):\n    return (number.replace(\"_\", \"\").replace(\",\", \"\")\n            if isinstance(number, string_types)\n            else number)\n\n\nclass HyInteger(HyObject, long_type):\n    \"\"\"\n    Internal representation of a Hy Integer. May raise a ValueError as if\n    int(foo) was called, given HyInteger(foo). On python 2.x long will\n    be used instead\n    \"\"\"\n\n    def __new__(cls, number, *args, **kwargs):\n        if isinstance(number, string_types):\n            number = strip_digit_separators(number)\n            bases = {\"0x\": 16, \"0o\": 8, \"0b\": 2}\n            for leader, base in bases.items():\n                if number.startswith(leader):\n                    # We've got a string, known leader, set base.\n                    number = long_type(number, base=base)\n                    break\n            else:\n                # We've got a string, no known leader; base 10.\n                number = long_type(number, base=10)\n        else:\n            # We've got a non-string; convert straight.\n            number = long_type(number)\n        return super(HyInteger, cls).__new__(cls, number)\n\n\n_wrappers[int] = HyInteger\nif not PY3:  # do not add long on python3\n    _wrappers[long_type] = HyInteger\n\n\ndef check_inf_nan_cap(arg, value):\n    if isinstance(arg, string_types):\n        if isinf(value) and \"Inf\" not in arg:\n            raise ValueError('Inf must be capitalized as \"Inf\"')\n        if isnan(value) and \"NaN\" not in arg:\n            raise ValueError('NaN must be capitalized as \"NaN\"')\n\n\nclass HyFloat(HyObject, float):\n    \"\"\"\n    Internal representation of a Hy Float. May raise a ValueError as if\n    float(foo) was called, given HyFloat(foo).\n    \"\"\"\n\n    def __new__(cls, num, *args, **kwargs):\n        value = super(HyFloat, cls).__new__(cls, strip_digit_separators(num))\n        check_inf_nan_cap(num, value)\n        return value\n\n_wrappers[float] = HyFloat\n\n\nclass HyComplex(HyObject, complex):\n    \"\"\"\n    Internal representation of a Hy Complex. May raise a ValueError as if\n    complex(foo) was called, given HyComplex(foo).\n    \"\"\"\n\n    def __new__(cls, num, *args, **kwargs):\n        value = super(HyComplex, cls).__new__(cls, strip_digit_separators(num))\n        if isinstance(num, string_types):\n            p1, _, p2 = num.lstrip(\"+-\").replace(\"-\", \"+\").partition(\"+\")\n            if p2:\n                check_inf_nan_cap(p1, value.real)\n                check_inf_nan_cap(p2, value.imag)\n            elif \"j\" in p1:\n                check_inf_nan_cap(p1, value.imag)\n            else:\n                check_inf_nan_cap(p1, value.real)\n        return value\n\n_wrappers[complex] = HyComplex\n\n\nclass HyList(HyObject, list):\n    \"\"\"\n    Hy List. Basically just a list.\n    \"\"\"\n\n    def replace(self, other):\n        for x in self:\n            replace_hy_obj(x, other)\n\n        HyObject.replace(self, other)\n        return self\n\n    def __add__(self, other):\n        return self.__class__(super(HyList, self).__add__(other))\n\n    def __getslice__(self, start, end):\n        return self.__class__(super(HyList, self).__getslice__(start, end))\n\n    def __getitem__(self, item):\n        ret = super(HyList, self).__getitem__(item)\n\n        if isinstance(item, slice):\n            return self.__class__(ret)\n\n        return ret\n\n    def __repr__(self):\n        return \"[%s]\" % (\" \".join([repr(x) for x in self]))\n\n_wrappers[list] = lambda l: HyList(wrap_value(x) for x in l)\n_wrappers[tuple] = lambda t: HyList(wrap_value(x) for x in t)\n\n\nclass HyDict(HyList):\n    \"\"\"\n    HyDict (just a representation of a dict)\n    \"\"\"\n\n    def __repr__(self):\n        return \"{%s}\" % (\" \".join([repr(x) for x in self]))\n\n    def keys(self):\n        return self[0::2]\n\n    def values(self):\n        return self[1::2]\n\n    def items(self):\n        return list(zip(self.keys(), self.values()))\n\n_wrappers[dict] = lambda d: HyDict(wrap_value(x) for x in sum(d.items(), ()))\n\n\nclass HyExpression(HyList):\n    \"\"\"\n    Hy S-Expression. Basically just a list.\n    \"\"\"\n\n    def __repr__(self):\n        return \"(%s)\" % (\" \".join([repr(x) for x in self]))\n\n_wrappers[HyExpression] = lambda e: HyExpression(wrap_value(x) for x in e)\n_wrappers[Fraction] = lambda e: HyExpression(\n    [HySymbol(\"fraction\"), wrap_value(e.numerator), wrap_value(e.denominator)])\n\n\nclass HySet(HyList):\n    \"\"\"\n    Hy set (just a representation of a set)\n    \"\"\"\n\n    def __repr__(self):\n        return \"#{%s}\" % (\" \".join([repr(x) for x in self]))\n\n_wrappers[set] = lambda s: HySet(wrap_value(x) for x in s)\n\n\nclass HyCons(HyObject):\n    \"\"\"\n    HyCons: a cons object.\n\n    Building a HyCons of something and a HyList really builds a HyList\n    \"\"\"\n\n    __slots__ = [\"car\", \"cdr\"]\n\n    def __new__(cls, car, cdr):\n        if isinstance(cdr, list):\n\n            # Keep unquotes in the cdr of conses\n            if type(cdr) == HyExpression:\n                if len(cdr) > 0 and type(cdr[0]) == HySymbol:\n                    if cdr[0] in (\"unquote\", \"unquote_splice\"):\n                        return super(HyCons, cls).__new__(cls)\n\n            return cdr.__class__([wrap_value(car)] + cdr)\n\n        elif cdr is None:\n            return HyExpression([wrap_value(car)])\n\n        else:\n            return super(HyCons, cls).__new__(cls)\n\n    def __init__(self, car, cdr):\n        self.car = wrap_value(car)\n        self.cdr = wrap_value(cdr)\n\n    def __getitem__(self, n):\n        if n == 0:\n            return self.car\n        if n == slice(1, None):\n            return self.cdr\n\n        raise IndexError(\n            \"Can only get the car ([0]) or the cdr ([1:]) of a HyCons\")\n\n    def __setitem__(self, n, new):\n        if n == 0:\n            self.car = new\n            return\n        if n == slice(1, None):\n            self.cdr = new\n            return\n\n        raise IndexError(\n            \"Can only set the car ([0]) or the cdr ([1:]) of a HyCons\")\n\n    def __iter__(self):\n        yield self.car\n        try:\n            iterator = (i for i in self.cdr)\n        except TypeError:\n            if self.cdr is not None:\n                yield self.cdr\n                raise TypeError(\"Iteration on malformed cons\")\n        else:\n            for i in iterator:\n                yield i\n\n    def replace(self, other):\n        if self.car is not None:\n            replace_hy_obj(self.car, other)\n        if self.cdr is not None:\n            replace_hy_obj(self.cdr, other)\n\n        HyObject.replace(self, other)\n\n    def __repr__(self):\n        if isinstance(self.cdr, self.__class__):\n            return \"(%s %s)\" % (repr(self.car), repr(self.cdr)[1:-1])\n        else:\n            return \"(%s . %s)\" % (repr(self.car), repr(self.cdr))\n\n    def __eq__(self, other):\n        return (\n            isinstance(other, self.__class__) and\n            self.car == other.car and\n            self.cdr == other.cdr\n        )\n", "path": "hy/models.py"}]}