Skip to content
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

If an object has a __json__ method, use it when encoding #157

Merged
merged 1 commit into from
Jan 15, 2016

Conversation

mitar
Copy link
Contributor

@mitar mitar commented Dec 19, 2014

It should return a raw JSON string which will be directly included in the resulting JSON when encoding.

Similar to #130, but it allows an object to return already encoded string which is then included as it is in the output. This allows one to pass embed existing JSON strings inside a larger structure, without a need to deserialize and serialize again.

It should return a raw JSON string which will be directly included in
the resulting JSON when encoding.
@mitar
Copy link
Contributor Author

mitar commented Dec 29, 2014

Fixed Travis CI tests.

@rodrigopr
Copy link

+1 for this feature

@snario
Copy link

snario commented Apr 28, 2015

+1

7 similar comments
@tupy
Copy link

tupy commented May 11, 2015

+1

@gabrielpjordao
Copy link

+1

@rafaelverger
Copy link

+1

@caio-nas
Copy link

+1

@andersonba
Copy link

+1

@marciovicente
Copy link

+1

@helielson
Copy link

+1

@tekknolagi
Copy link
Contributor

+1 and bump. @esnme?

@tekknolagi
Copy link
Contributor

@jskorpan

@marcgear
Copy link

+1

@Jahaja
Copy link
Contributor

Jahaja commented Jan 15, 2016

Thanks, Looks good. The only problem I could see with this PR is that it means that ujson.encode can output invalid json and it could be pretty hard to find such a bug. But I guess it's the risk you'll take if you try to optimise using stuff like this.

@mitar
Copy link
Contributor Author

mitar commented Jan 15, 2016

Yes. I do not think we should try to verify that. This is your responsibility. Luckily, JSON is nicely recursive, so if the output of __json__ is valid JSON, then also the whole result is valid JSON.

Jahaja added a commit that referenced this pull request Jan 15, 2016
If an object has a __json__ method, use it when encoding
@Jahaja Jahaja merged commit 86bb8ff into ultrajson:master Jan 15, 2016
@Jahaja
Copy link
Contributor

Jahaja commented Jan 15, 2016

Agree, thanks again.

@@ -579,7 +592,7 @@ void Object_beginTypeContext (JSOBJ _obj, JSONTypeContext *tc)
return;
}
else
if (PyString_Check(obj))
if (PyString_Check(obj) && !PyObject_HasAttrString(obj, "__json__"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @mitar, What's the use-case that warranted this particular change? It looks like this is a performance regression.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So that one can have strings with __json__ method. If a string does not have __json__ method, we go by the normal flow, if it has, we use it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So far I did follow. But not why one would need it. What's the actual use-case for that? Furthermore why would only the string type have a __json__ method but not the other types?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll leaning towards removing this and thus limiting the __json__ functionality to objects.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the idea is a bit that you can have a magical string, which behaves in one way when used as a string, but another (optimized) when used as a JSON. Specifically, you can have a JSON serialization, which is a string, but also when serialized, it is not converted to a string (so no double encoding), but output directly, because it already contains a proper JSON serialization.

Example use for me is how to properly serialize GeoJSON Django fields. I create a GeoJSON string class, and then returned it as an optimized value. In this way existing codebase which expects strings work well, but when the time for serialization to JSON comes, one can quickly render JSON, because it is already there. Moreover, if you serialize to XML, instead, then the string is used as string, so you get embedded JSON inside XML, which is also good in the case of GeoJSON.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the explanation. However this is too much of an edge-case to justify the performance penalty as it stands.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious, what was the % of the performance hit in your tests because of that?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was the cause if this one: #223

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet