Merge or update a JSONGrammar#

from __future__ import annotations

import contextlib
from copy import deepcopy

from gemseo.core.grammars.errors import InvalidDataError
from gemseo.core.grammars.json_grammar import JSONGrammar

Create the JSON grammars#

The first grammar has the elements name1 and name2 that shall be integers. The second grammar has the elements name2 and name3 that shall be strings.

grammar_1 = JSONGrammar("grammar_1")
grammar_1.update_from_file("grammar_1.json")

grammar_2 = JSONGrammar("grammar_2")
grammar_2.update_from_file("grammar_2.json")

Keep a pristine copy of the first grammar such that we can experiment more than once on it.

grammar_1_copy = deepcopy(grammar_1)

Update without merge#

By default, the update method acts like for a dictionary, i.e. an already existing key has its value overriden. Here the value for the element name2 is now string.

grammar_1.update(grammar_2)
grammar_1
Grammar name: grammar_1
  • Required elements:
  • Optional elements:
    • name1:
      • Type: integer
      • Default: N/A
    • name2:
      • Type: string
      • Default: N/A
    • name3:
      • Type: string
      • Default: N/A


On validation, the allowed type is only the one from the second grammar.

with contextlib.suppress(InvalidDataError):
    grammar_1.validate({"name2": 0})

grammar_1.validate({"name2": "a string"})
ERROR - 16:23:05: Grammar grammar_1: validation failed.
ERROR - 16:23:05: error: data.name2 must be string

Update with merge#

First use the initial grammar from its copy.

grammar_1 = grammar_1_copy

When merging elements, an already existing element of the grammar will have both the old and the new value.

grammar_1.update(grammar_2, merge=True)
grammar_1
Grammar name: grammar_1
  • Required elements:
  • Optional elements:
    • name1:
      • Type: integer
      • Default: N/A
    • name2:
      • Type: ['integer', 'string']
      • Default: N/A
    • name3:
      • Type: string
      • Default: N/A


On validation, the allowed types can be any of the types from the original grammars, here either integer or string.

grammar_1.validate({"name2": 0})
grammar_1.validate({"name2": "a string"})

Total running time of the script: (0 minutes 0.004 seconds)

Gallery generated by Sphinx-Gallery