Skip to content

Commit f183ffd

Browse files
authored
Allow log float non-JSON compliant values (#30)
1 parent 4c54f56 commit f183ffd

File tree

3 files changed

+92
-5
lines changed

3 files changed

+92
-5
lines changed

hack/ci_assets/function/main.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,17 @@
2020

2121

2222
def handler(context: nuclio_sdk.Context, event: nuclio_sdk.Event):
23+
headers = {
24+
ensure_str(header): ensure_str(value) for header, value in event.headers.items()
25+
}
2326
context.logger.debug_with(
2427
"Received request",
2528
event=json.dumps(
2629
{
2730
"id": event.id,
2831
"eventType": event.trigger.kind,
2932
"contentType": event.content_type,
30-
"headers": {
31-
ensure_str(header): ensure_str(value)
32-
for header, value in event.headers.items()
33-
},
33+
"headers": headers,
3434
"timestamp": event.timestamp.isoformat("T") + "Z",
3535
"path": event.path,
3636
"url": event.url,
@@ -46,7 +46,7 @@ def handler(context: nuclio_sdk.Context, event: nuclio_sdk.Event):
4646
),
4747
)
4848
return context.Response(
49-
headers=event.headers,
49+
headers=headers,
5050
body={
5151
"sdk_version": get_sdk_version(),
5252
},

nuclio_sdk/json_encoder.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,73 @@
1313
# limitations under the License.
1414

1515
import json
16+
import json.encoder
1617

1718

1819
# JSON encoder that can encode custom stuff
1920
class Encoder(json.JSONEncoder):
21+
def __init__(self, **kwargs):
22+
super(Encoder, self).__init__(**kwargs)
23+
self.nan_str = "NaN"
24+
25+
def iterencode(self, o, _one_shot=False):
26+
"""
27+
Encode the given object and yield each string
28+
representation as available.
29+
30+
For example::
31+
32+
for chunk in JSONEncoder().iterencode(bigobject):
33+
mysocket.write(chunk)
34+
35+
"""
36+
if self.check_circular:
37+
markers = {}
38+
else:
39+
markers = None
40+
if self.ensure_ascii:
41+
_encoder = json.encoder.encode_basestring_ascii
42+
else:
43+
_encoder = json.encoder.encode_basestring
44+
45+
def floatstr(
46+
o,
47+
allow_nan=self.allow_nan,
48+
nan_str=self.nan_str,
49+
_repr=float.__repr__,
50+
_inf=json.encoder.INFINITY,
51+
_neginf=-json.encoder.INFINITY,
52+
):
53+
if o != o:
54+
text = '"{0}"'.format(nan_str)
55+
elif o == _inf:
56+
text = '"Infinity"'
57+
elif o == _neginf:
58+
text = '"-Infinity"'
59+
else:
60+
return _repr(o)
61+
62+
if not allow_nan:
63+
raise ValueError(
64+
"Out of range float values are not JSON compliant: " + repr(o)
65+
)
66+
67+
return text
68+
69+
_iterencode = json.encoder._make_iterencode(
70+
markers,
71+
self.default,
72+
_encoder,
73+
self.indent,
74+
floatstr,
75+
self.key_separator,
76+
self.item_separator,
77+
self.sort_keys,
78+
self.skipkeys,
79+
_one_shot,
80+
)
81+
return _iterencode(o, 0)
82+
2083
def default(self, obj):
2184

2285
# EAFP all the way. Leave the unused "exc" in for debugging ease

nuclio_sdk/test/test_logger.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,30 @@ def test_log_with_date(self):
6565
self._io.getvalue(),
6666
)
6767

68+
def test_log_nan(self):
69+
self._logger.info_with(self._testMethodName, nan=float("NaN"))
70+
self.assertIn(self._testMethodName, self._io.getvalue())
71+
self.assertIn(
72+
'"with": {"nan": "NaN"}',
73+
self._io.getvalue(),
74+
)
75+
76+
def test_log_infinity(self):
77+
self._logger.info_with(self._testMethodName, nan=float("Infinity"))
78+
self.assertIn(self._testMethodName, self._io.getvalue())
79+
self.assertIn(
80+
'"with": {"nan": "Infinity"}',
81+
self._io.getvalue(),
82+
)
83+
84+
def test_log_minus_infinity(self):
85+
self._logger.info_with(self._testMethodName, nan=float("-Infinity"))
86+
self.assertIn(self._testMethodName, self._io.getvalue())
87+
self.assertIn(
88+
'"with": {"nan": "-Infinity"}',
89+
self._io.getvalue(),
90+
)
91+
6892
def test_fail_to_log(self):
6993
"""
7094
Do not fail logging when an object is not log-able

0 commit comments

Comments
 (0)