asdf-format/asdf

`load_schema` does not resolve local references

braingram opened this issue · 0 comments

Description of the problem

Documentation for asdf.schema.load_schema states that if resolve_references is True resolve all $ref references.

This does not appear to be working as intended for local references.

Here is a minimal example:

import io
import yaml
import asdf
import pprint


schema_id = "asdf://example.com/foo-1.0.0"
schema = {
    "$schema": "http://stsci.edu/schemas/asdf/asdf-schema-1.0.0",
    "id": schema_id,
    "definitions": {
        "inline": {
            "anyOf": [
                {"type": "number"},
                {"$ref": "#/definitions/inline"},
            ],
        },
    },
    "type": "object",
    "properties": {
        "inline": {
            "$ref": "#/definitions/inline",
        },
    },
}

sio = io.StringIO()
yaml.dump(schema, sio, Dumper=yaml.SafeDumper)

cfg = asdf.get_config()
cfg.add_resource_mapping({schema_id: sio.getvalue().encode('ascii')})

loaded_resolved = asdf.schema.load_schema(schema_id, resolve_references=True)
pprint.pprint(loaded_resolved)

returns:

{'$schema': 'http://stsci.edu/schemas/asdf/asdf-schema-1.0.0',
 'definitions': {'inline': {'anyOf': [{'type': 'number'},
                                      {'anyOf': [{'type': 'number'},
                                                 {'$ref': '#/definitions/inline'}]}]}},
 'id': 'asdf://example.com/foo-1.0.0',
 'properties': {'inline': {'anyOf': [{'type': 'number'},
                                     {'$ref': '#/definitions/inline'}]}},
 'type': 'object'}

Note that the two remaining $refs. Also note that if these are resolved, the resulting schema will be recursive and a subsequent call to check_schema will fail due to maxiumum recursion depth.

A non-toy example involves the commonly used ndarray schema:
https://github.com/asdf-format/asdf-standard/blob/cafd84a04c48a0f99bef8018420e6a4e89e2db5b/resources/schemas/stsci.edu/asdf/core/ndarray-1.0.0.yaml#L267

Loading the schema (using resolve_references=True) returns a schema that contains $ref entries:

import asdf
loaded = asdf.schema.load_schema('http://stsci.edu/schemas/asdf/core/ndarray-1.0.0', resolve_references=True)
assert '$ref' in loaded['definitions']['inline-data']['items']['anyOf'][-2]['items']['anyOf'][-2]