-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[do-not-merge] Import code from kinto-signer #17
Conversation
@richvdh do you think it makes sense to work on this? I'd be glad to if you think it's a good idea to join forces.... |
oh gosh I'd forgotten about this. will try to take a look. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lepatrem apologies for sitting on this for over a year. I do think it's valuable work so please keep up the good fight.
My main concern with it would be that it uses the native-python stock json
encoder, which is going to be significantly slower than simplejson's c implementation. For my usecase, performance is pretty critical (and I've spent a while benchmarking canonicaljson in the past to optimise it).
On the other hand, given this change won't affect the performance for existing users, I'm quite happy for the functionality to land now, and we can think about how to optimise it further down the line. It would be helpful to include a warning in the docstrings that allow_floats
will harm performance, however.
otherwise, a few nits below.
""" | ||
Mimic JavaScript Number#toString() | ||
""" | ||
if o != o or o == json_encoder.INFINITY or o == -json_encoder.INFINITY: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when is o != o
true, out of interest? a comment might be useful.
""" | ||
if o != o or o == json_encoder.INFINITY or o == -json_encoder.INFINITY: | ||
return "null" | ||
elif 0 < o < 10 ** -6 or o >= 10 ** 21: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
does this not need to check for negative values as well?
return re.sub(r"(\.?0*)e([\-+])0?", r"e\2", fnative) | ||
fnative = format(o, ".8f").lstrip() | ||
# 23.0 --> 23 | ||
return re.sub(r"\.?0+$", "", fnative) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
erm this looks like it will convert 10
to 1
. that may not be a practical concern if format
always returns 10.0
rather than 10
; however I suggest dropping the ?
for clarity/robustness. Similarly at line 57.
@@ -44,26 +45,62 @@ def _default(obj): | |||
obj.__class__.__name__) | |||
|
|||
|
|||
def numberstr(o): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggest calling this _numberstr
if it's meant to be internal.
return re.sub(r"\.?0+$", "", fnative) | ||
|
||
|
||
class FloatEncoder(json.JSONEncoder): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A docstring on this would be nice.
@leplatrem are you interested in continuing to work on this? |
I'm sorry for letting you down here :/ I think I found a more robust approach using Rust, where I can share the same implementation of canonical JSON between Python (pyo3) and JavaScript (WebAssembly). Work in progress: https://github.com/leplatrem/python-canonicaljson-rs/ If you're interested in the changes that I proposed here, I can push some updates based on your comments, otherwise, we shall just abandon the PR. |
@leplatrem honestly I think that if you've found a better solution that works for you, it's probably not worth pursuing this any further. |
Ref #16
This PR is more a request for feedback than anything else :)
Tests pass on Python 3.6 but it might be tedious to port the code for PyPy and Python 2.