Support string-references for Nested.
E.g. allow back-references or cyclical references.
We could register schema class names whenever Schema is subclassed, which would allow us to do this:
artist = typesystem.Nested('Artist')
A lazy import string would also work:
artist = typesystem.Nested('myproject.schemas:Artist')
fyi, sqlalchemy has a similar problem in its orm layer. one approach used there, in addition to strings (in a semi-global hidden namespace :neutral_face:) is to allow a callable instead to delay resolution.
in practice that could look like this:
artist = typesystem.Nested(lambda: Artist)
which would have all the nice benefits of it actually being code, which is good for linters and editors.
See the example in #46 for how we’ll approach it here.
We won’t allow string references unless it’s a field embedded within a specific namespace.
Namespaces end up being simple dict-like interfaces, and will play nicely with JSON Schema ‘definitions’/‘$ref’
alternatively, with the proper metaclass magic,
my_namespace = typesystem.SchemaNamespace('some-name-could-go-here')
class Album(typesystem.Schema, namespace=my_namespace):
title = typesystem.String(max_length=100)
release_date = typesystem.Date()
artist = typesystem.Nested('Artist')
... which would also open the door for exciting new APIs on a namespace, e.g. bulk creation of json schemas.
The ‘namespace=‘ is an interesting alternative. I’ve not actually seen that style of usage before. I’d suggest that I get #46 complete first, and then we can consider if we want to adjust it.
conceptually, a namespace is indeed a ‘parent’ of a Schema, but pulling new Schema classes out of thin air, which is what happens when subclassing MySchema(my_namespace.Schema) if you look at it, is also a bit weird. it's more of an ‘association’, and a metaclass with a custom argument allows one to encode that quite elegantly, imho.
(another idea is to use class decorators)
a metaclass with a custom argument allows one to encode that quite elegantly, imho.
Very possibly a better alternative. Wanna sketch out how that’d need to work with the metaclass?
(another idea is to use class decorators)
Not keen really.
(yeah agreed, hence the parentheses :wink:)