Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Mapping Type #41

Open
crdoconnor opened this issue Oct 7, 2018 · 2 comments
Open

New Mapping Type #41

crdoconnor opened this issue Oct 7, 2018 · 2 comments

Comments

@crdoconnor
Copy link
Owner

crdoconnor commented Oct 7, 2018

Create a new kind of mapping validator where it looks for one key and then once it sees that key it expects several others (some may be optional).

Primary use case is here : https://github.com/hitchdev/seleniumdirector/blob/master/seleniumdirector/webdirector.py where the following groups of keys in the mapping are acceptable:

  • id, in iframe, which, but parent, subelements (in iframe, which, but parent, subelements) all optional
  • class, in iframe, which, but parent, subelements (ditto, all optional)
  • attribute, in iframe, which, but parent, subelements (ditto, all optional)
  • text is, in iframe, which, but parent, subelements (ditto, all optional)
  • text contains, in iframe, which, but parent, subelements (ditto, all optional)

However id, class, attribute, text is and text contains should never be seen together, however - using the current validator, every key is optional.

@bt2901
Copy link

bt2901 commented Sep 29, 2019

I'm interested in something similar: some sort of Map() | Map(). The use case:

We have a sequence of building blocks (taken together, they specify a training process for a particular topic model). There is a small list of building blocks available (at the moment, only two: CubeCreator and RegularizerModifierCube), but each takes a lot of input parameters. Different blocks require different parameters, however.

For now, I'm handling the situation like this:

base_schema = Map({
    'stages': Seq(Any()),
...
})
SUPPORTED_CUBES = [CubeCreator, RegularizersModifierCube]

def build_schema_for_cubes():
    """
    Returns
    -------
    dict
        each element is str -> strictyaml.Map
        where key is name of cube,
        value is a schema used for validation and type-coercion
    """
    schemas = {}
    for class_of_object in SUPPORTED_CUBES:
        res = build_schema_from_signature(class_of_object)
        res = Map(res)

        specific_schema = Map({class_of_object.__name__: res})
        schemas[class_of_object.__name__] = specific_schema
    return schemas

parsed = load(yaml_string, base_schema)
schemas = build_schema_for_cubes()

for i, stage in enumerate(parsed['stages']):
    assert len(stage) == 1
    name = list(stage.data)[0]

    if name not in schemas:
        raise ValueError(f"Unsupported stage ID: {name} at line {stage.start_line}")
    local_schema = schemas[name]

    stage.revalidate(local_schema)

Is there a better way?

@crdoconnor
Copy link
Owner Author

No, that looks pretty much exactly how I'd do it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants