typesystem icon indicating copy to clipboard operation
typesystem copied to clipboard

Support string-references for Nested.

Open lovelydinosaur opened this issue 7 years ago • 9 comments

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')

lovelydinosaur avatar Mar 01 '19 10:03 lovelydinosaur

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.

wbolster avatar Mar 08 '19 15:03 wbolster

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’

lovelydinosaur avatar Mar 08 '19 15:03 lovelydinosaur

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.

wbolster avatar Mar 08 '19 15:03 wbolster

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.

lovelydinosaur avatar Mar 08 '19 15:03 lovelydinosaur

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.

wbolster avatar Mar 08 '19 15:03 wbolster

(another idea is to use class decorators)

wbolster avatar Mar 08 '19 15:03 wbolster

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?

lovelydinosaur avatar Mar 08 '19 15:03 lovelydinosaur

(another idea is to use class decorators)

Not keen really.

lovelydinosaur avatar Mar 08 '19 15:03 lovelydinosaur

(yeah agreed, hence the parentheses :wink:)

wbolster avatar Mar 08 '19 15:03 wbolster