Uh oh!
There was an error while loading. Please reload this page.
gh-81022: Supporting customization of float encoding in JSON - #13233
gh-81022: Supporting customization of float encoding in JSON#13233Lee-W wants to merge 9 commits into
Conversation
the-knights-who-say-ni
commented
May 10, 2019
Hello, and thanks for your contribution! I'm a bot set up to make sure that the project can legally accept your contribution by verifying you have signed the PSF contributor agreement (CLA). Our records indicate we have not received your CLA. For legal reasons we need you to sign this before we can look at your contribution. Please follow the steps outlined in the CPython devguide to rectify this issue. If you have recently signed the CLA, please wait at least one business day You can check yourself to see if the CLA has been received. Thanks again for your contribution, we look forward to reviewing it! |
mitar
left a comment
There was a problem hiding this comment.
I think also some tests would be useful?
Uh oh!
There was an error while loading. Please reload this page.
Lee-W
commented
Jul 17, 2019
@mitar I've added a test for the newly added |
cmnord
commented
Jul 23, 2019
Rather than add another argument to these functions, why not un-nest |
mitar
commented
Jul 23, 2019
I think the idea is that one can also use C code-path for this? Why it is an argument for decoding and not a method? |
@mitar I don't fully understand your comment. Could you clarify what you mean? What I meant is that it would be nice to be able to do the following: importjsonimportnumpyasnpclassMyJSONEncoder(json.JSONEncoder):
deffloatstr(self, o, _repr=float.__repr__, _inf=json.INFINITY, _neginf=-json.INFINITY):
ifo!=o:
text="None"elifo==_inf:
text="Infinity"elifo==_neginf:
text="-Infinity"else:
return_repr(o)
ifnotself.allow_nan:
raiseValueError(
"Out of range float values are not JSON compliant: "+repr(o)
)
returntextassertjson.dumps(np.nan) =="None"So rather than adding a new argument to many functions, we could achieve the same goal of custom float encoding this way. What do you mean by "C code-path" and "decoding and not a method"? |
mitar
commented
Jul 23, 2019
|
cmnord
commented
Jul 23, 2019
@mitar thanks for clarifying, I think I understand now. 🙂 |
mitar
commented
Jul 23, 2019
If you do have time, you could try to measure how much does this really benefit. You could try moving parsing of floats to a class in decoding. And see if that really slows down things. Personally I also do not like extra functions, especially if we already have a nice class to put methods on. |
Lee-W
commented
Nov 10, 2019
@mitar Could you please explain more on what should I measure? It seems you already explain it. Thanks 🙂 |
mitar
commented
Nov 11, 2019
I would propose that you measure and compare two cases a) having methods on the class b) having functions directly provided. |
Lee-W
commented
Nov 12, 2019
I've tested on importjsonimporttimeitINFINITY=json.encoder.INFINITYclassMyJSONEncoder(json.JSONEncoder):
deffloatstr(self, obj, _repr=float.__repr__, _inf=INFINITY, _neginf=-INFINITY):
ifobj!=obj:
text="None"elifobj==json.encoder.INFINITY:
text="Infinity"elifobj==-json.encoder.INFINITY:
text="-Infinity"else:
returnfloat.__repr__(obj)
ifnotself.allow_nan:
raiseValueError(
"Out of range float values are not JSON compliant: "+repr(obj)
)
returntextdeffloatstr(obj, allow_nan=True, _repr=float.__repr__, _inf=INFINITY, _neginf=-INFINITY):
ifobj!=obj:
text="None"elifobj==json.encoder.INFINITY:
text="Infinity"elifobj==-json.encoder.INFINITY:
text="-Infinity"else:
returnfloat.__repr__(obj)
ifnotallow_nan:
raiseValueError(
"Out of range float values are not JSON compliant: "+repr(obj)
)
returntextobj= {
'inf': float('inf'),
'-inf': -float('-inf'),
'nan': float('nan'),
'2': 2.23,
}
print('Encode')
print('Default: ', timeit.timeit(lambda: json.dumps(obj), number=10000))
print('Argument: ', timeit.timeit(lambda: json.dumps(obj, encode_float=floatstr), number=10000))
print('Class: ', timeit.timeit(lambda: json.dumps(obj, cls=MyJSONEncoder), number=10000)) |
Lee-W
commented
Jan 11, 2020
@mitar Do I need to do other experiments on it? Or, would the above one be sufficient? 🙂 |
mitar
commented
Jan 11, 2020
I will leave to somebody else from the Python team to way in here. |
mitar
commented
Dec 15, 2020
@Lee-W Please update the PR, there is now a merge conflict. I really like this PR, could somebody from Python core team review/merge this? |
Lee-W
commented
Dec 16, 2020
@mitar Thanks for reminding. I just fix the conflict. |
| "Out of range float values are not JSON compliant: " + | ||
| repr(o)) | ||
| return text |
There was a problem hiding this comment.
Minor comment: why move the floatstr function definition inline here? it could stay as a regular method in the class, then the line below would be self.encode_float = self.floatstr and still work.
martin-remy
commented
Oct 20, 2022
@python's team : What's going on ? |
* To enable customize float encoding
Uh oh!
There was an error while loading. Please reload this page.
merwok
commented
Jun 4, 2023
As I noted on the ticket, this should be discussed to reach agreement on the need and the shape of the feature first. |
Lee-W
commented
Aug 6, 2023
Got it. I just wanted to resolve the previous conflict. As this is not yet agreed, let me close this PR |
Add an
encode_floatargument to JSONEncoder for supporting customization float encoding