I don't agree. __json__ only matters to people who do JSON encoding/decoding. Other people can safely ignore it.
Which is exactly the attitude I was talking about: for each individual case, people go "oh, I understand magic methods, those are easy". It's the overall process of identifying the need for and gathering consensus on magic methods that is unwieldy (and ultimately fails to scale, leading to non-extensible interfaces by default, with pretty printing being the classic example, and JSON serialisation the latest).
Why do you want to gather consensus? There is a single json serialization module in the stdlib and it's obvious that __json__ can/should be claimed by that module.
Actually, your argument could be returned: if you use generic functions (such as @json.dumps.overload), alternative json serializers won't easily be able to make use of the information, while they could access the __json__ method like the standard json module does.
Is it really harder for people to learn how to write things like:
json.dumps.overload(mytype, mytype.to_json) json.dumps.overload(third_party_type, my_third_party_type_serialiser)
It is certainly more annoying and less natural than: def __json__(self): ....
Sure, generic functions as a paradigm appear more powerful, more decoupled, etc. But in practice __magic__ methods are sufficient for most uses. Practicality beats purity.
That may be why in all the years that the various generic functions libraries have existed, they don't seem to have been really popular compared to the simpler convention of defining fixed method names.
(besides, it wouldn't necessarily be json.dumps that you overload, but some internal function of the json module; making it even less intuitive and easily discoverable)
The generic function registration approach is incidentally discoverable via dir(json.dumps) to see that a function provides the relevant generic function registration methods. Magic method protocols can *only* be discovered by reading documentation.
If help(json.dumps) includes a small blurb about __json__, it makes the information at least as easily discoverable as invoking dir(json.dumps).
Besides, I don't find it shocking if documentation problems have to be solved through documentation.