In trying to do this (again), I've realized that you *can't* just check for hasattr(obj, '__json__') in a JSONEncoder.default method because default only get's called for types it doesn't know how to serialize; so if you e.g. subclass a dict, default() never gets called for the dict subclass.

https://docs.python.org/3/library/json.html :
> If specified, default should be a function that gets called for objects that can’t otherwise be serialized.

https://github.com/python/cpython/blob/master/Lib/json/encoder.py

https://stackoverflow.com/questions/16405969/how-to-change-json-encoding-behaviour-for-serializable-python-object/17684652#17684652
specifies how to overload _make_iterencode *in pure Python*, but AFAICS that NOPs use of the C-optimized json encoder.

The python json module originally came from simplejson.

Here's simplejson's for_json implementation in pure Python:
https://github.com/simplejson/simplejson/blob/288e4e005c39a2eb855b5225c5dc8ebcb82eee72/simplejson/encoder.py#L515 :

    for_json = _for_json and getattr(value, 'for_json', None)
    if for_json and callable(for_json):
        chunks = _iterencode(for_json(), _current_indent_level)


And simplejson's for_json implementation in C:
https://github.com/simplejson/simplejson/blob/288e4e005c39a2eb855b5225c5dc8ebcb82eee72/simplejson/_speedups.c#L2839

Is there a strong reason that the method would need to be called __json__ instead of 'for_json'?

Passing a spec=None kwarg through to the __json__()/for_json() method would not be compatible with simplejson's existing implementation.
Passing a spec=None kwarg would be necessary to support different JSON standards within the same method; which I think is desirable because JSON/JSON5/JSONLD/JSON_future.

On Wed, Apr 8, 2020 at 5:03 PM Wes Turner <wes.turner@gmail.com> wrote:
I think that we should support the linked data use case with at least:
1. a __json__(obj, spec=None) method and
2. a more-easily modifiable make_iterencode/iterencode implementation in the json module of the standard library.

On Wed, Apr 8, 2020 at 5:00 PM Andrew Barnert <abarnert@yahoo.com> wrote:
On Apr 8, 2020, at 12:55, Wes Turner <wes.turner@gmail.com> wrote:
>
> We should welcome efforts to support linked data in Python.

Fine, but that’s doesn’t meant we should derail every proposal that has anything to do with JSON by turning it into a proposal for linked data, or consider a useful proposal to be useless because it doesn’t give us linked data support on top of whatever it was intended to give us.

> No one cares whether you believe that "semantic web failed" or "those standards are useless":

But no one is saying either of those things. People are saying that the semantic web is irrelevant to this discussion. JSON is useful, JSON Schema is useful, improving Python to make working with ad hoc or Schema-specified JSON is useful, and that’s all equally true whether the semantic web is the one true future or a total failure.

Would a __json__ method protocol improve Python? I don’t think so, but the reasons I don’t think so have nothing to do with LD. Other people do think so, and their reasons also have nothing to do with LD. And the same is true for most of the counter- and side-ideas that have come up in this thread and the last one.

> re: generating JSON schema from type annotations
>
> You can go from python:Str to jsonschema:format:string easily enough,
> but, again, going from python:str to jsonschema:format:email will require either extending the type annotation syntax or modifying a generated schema stub and then changes to which will then need to be ported back to the type annotations.

Sure, but who says you have to store email addresses as str?

    @dataclass
    class Person:
        name: str
        email: Email
        address: Address

The fact that str is a builtin type, Address is a dataclass with a bunch of builtin-typed attributes, and Email is (say) a str subclass (or a dataclass with just a str member or whatever) that knows to render to and from type:string, format:email instead of just type:string doesn’t change the fact that they’re all perfectly good Python types and can all be used as type annotations and can all be mapped to a JSON Schema. How does it know that? Lots of things would work. Which one you use would be up to your JSON Schema-driven serialization library, or to your Python-code-from-JSON-Schema generator tool or your static Schema-from-code generator tool or.whatever. Maybe if we have multiple such libraries in wide use fighting it out, one of them will win. But even if there’s never a category killer, any of them will work fine for the applications that use it.

And of course often just using str for email addresses is fine. There’s a reason the Formats section of the JSON Schema spec is optional and explicitly calls out that many implementations don’t include it. And in some applications it would make more sense to break an email address down into two parts (user and host) and store a dict of those two values instead, and that’s also fine. Would it better serve the needs of the semantic web if the email format were a mandatory rather than optional part of the spec and everyone were required by law to always use it when storing email addresses? Maybe. But neither of those things are true.