Do not sort keys of serialised dicts

Several times I’ve run into a situation where I expected the keys of a serialised dict to be in a certain order. For example: when presenting a series of fields or plots to the user.

In recent python the key order is preserved.
Anvil tries to be helpful by sorting the keys when the dict is serialised when sent to the client. Please don’t.

You can’t rely on the fact that python now preserves key order.

In any web app, data between server and client is serialised as JSON in which key order is neither maintained or guaranteed by design.

Until the RFC changes, there’s nothing anvil or any other framework can do about that (and the RFC is not likely to change any time soon).

I can imagine serializing a dict as a JSON Array (of 2-element Arrays) so that the order could be preserved. I imagine that would impact performance somewhat, but it does seem possible, no?

Here’s a workaround you can employ if you need to guaranteed dictionary order between server and client.

@owen.campbell With respect to python you are not correct: in python 3.6 it was considered an implementation detail, in 3.7 it is a language feature (see What’s New In Python 3.7 — Python 3.9.6 documentation).

With json I don’t know, but having the order not guaranteed is not the same as having them sorted.

Thanks for the tip! I’ll give it a try.

At first I thought this solution would require ‘translating’ dicts to odicts, but it seems you handle this more or less transparently with a decorator. Cool.

Something for anvil-extras?

1 Like

My point was that, regardless of the guarantee Python might make, you can’t rely on it for an object that gets serialised to JSON. You can happily rely on the guarantee within the server but, once the serialisation occurs, you can no longer do so.

However, as @stucork describes, you can define your own portable class to ensure the serialisation takes place in the manner you want.

1 Like

With regards to JSON you are technically right. But Anvil being what it is (“python everywhere”) it should make an effort to hide the JSON limitations, I think.

Since there is a run-time cost, per remote procedure call, for doing that, it should be opt-in, on a per-call basis, so that you can choose to incur the cost when it matters, and skip it when it doesn’t. Which is the vast majority of the time.

Makes sense.
OTOH, how are the keys sorted? That is not a JSON effect, but done by Anvil, right? Why not leave out the sorting then?

I have no idea. For all I know, it’s being done by some low-level library underneath Anvil.

JSON is used by many things, not just Python. So it makes sense that a low-level JSON library might try to “add value” for these other users, by default. Sorting a JSON object’s keys does that, by putting data that is, by definition, unordered, into a consistent, predictable order.

If other waypoints along the network have become dependent on that ordering, it would be hard to turn off.

1 Like