23andMe / Yamale

A schema and validator for YAML.
MIT License
679 stars 88 forks source link

Abstracting schema (extend base schema) using `include` #182

Closed Yu-AnChen closed 2 years ago

Yu-AnChen commented 2 years ago

First of all, thanks for the great tool! I'm using it in my project and had some issues with the following case

cohort young: list(include('young person'))
---
person:
  name: str()
  is_active: bool()

young person: include('person')
  age: int(min=0, max=50)

old person: include('person')
  age: int(min=51)

I was hoping to create derived schemas (young person and old person) from the "base schema" (person), and the derived schemas would look like these

young person:
  name: str()
  is_active: bool()
  age: int(min=0, max=50)

old person:
  name: str()
  is_active: bool()
  age: int(min=51)

but got an error

ScannerError: mapping values are not allowed in this context

specifically, here are my questions -

  1. Could this be implemented? If so, could you suggest some directions that I can look into?
  2. If it doesn't make much sense to implement this, how would you suggest changing my schema design?

Referencing point 4 in closed issue #8

Thanks!

mildebrandt commented 2 years ago

Hi, thanks for using Yamale!

The error you're getting is from the YAML parser, not Yamale. The issue is here:

young person: include('person')
  age: int(min=0, max=50)

The parser thinks you're trying to set young person to a multi-line scaler value of include('person')\n age: int(min=0, max=50).

Instead, you can use yaml anchors to reference and extend a base mapping. For example:

cohort young: list(include('young person'))
cohort old: list(include('old person'))
---
person: &person
  name: str()
  is_active: bool()

young person:
  <<: *person
  age: int(min=0, max=50)

old person:
  <<: *person
  age: int(min=51)

Let me know if you have any other questions!

Yu-AnChen commented 2 years ago

Thank you so much @mildebrandt for sharing the solution, I can confirm this is a YAML parsing issue and I didn't know yaml anchors syntax, it's super helpful! Closing this issue now :)