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

KeyError with nested patternProperties #28

Closed
j616 opened this issue Sep 20, 2018 · 8 comments
Closed

KeyError with nested patternProperties #28

j616 opened this issue Sep 20, 2018 · 8 comments

Comments

@j616
Copy link

j616 commented Sep 20, 2018

When an object using patternProperties is further down the tree than another patternProperties field you get a KeyError.

Example schema:-

{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "type": "object",
    "patternProperties": {
        "^foo:": {
            "type": "object",
            "properties": {
                "baz": {
                    "type": "object",
                    "patternProperties": {
                        "^b": {
                            "type": "object"
                        }
                    }
                },
                "bit": {
                    "type": "object"
                }
            },
            "required": [
                "baz",
                "bit"
            ]
        }
    }
}

Example document to validate against it :-

{
    "foo:bar": {
        "baz": {
            "bat": {
            }
        },
        "bit": {
        }
    }
}

This results in :-

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 38, in validate
KeyError: 'bit'

The following schema where the second patternProperties is replaced with a regular properties validates correctly:-

{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "type": "object",
    "patternProperties": {
        "^foo:": {
            "type": "object",
            "properties": {
                "baz": {
                    "type": "object",
                    "properties": {
                        "bat": {
                            "type": "object"
                        }
                    }
                },
                "bit": {
                    "type": "object"
                }
            },
            "required": [
                "baz",
                "bit"
            ]
        }
    }
}

The following where the first patterProperties is replaced also validates correctly:-

{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "type": "object",
    "properties": {
        "foo:bar": {
            "type": "object",
            "properties": {
                "baz": {
                    "type": "object",
                    "patternProperties": {
                        "^b": {
                            "type": "object"
                        }
                    }
                },
                "bit": {
                    "type": "object"
                }
            },
            "required": [
                "baz",
                "bit"
            ]
        }
    }
}
@j616
Copy link
Author

j616 commented Sep 21, 2018

Doing some more digging with this. Turned out I was still on 1.6. Now on 2.3. The test case above no longer fails for me but I'm still getting the same sort of error on slightly more complex cases. I'll try and put together a new test case.

@j616
Copy link
Author

j616 commented Sep 21, 2018

I don't have much more useful info yet, but it does seem that the problem is non-deterministic. Running the same time multiple times results in different key errors (in the example above, they would be with keys at the baz/bit level) or occasionally results in the document validating successfully...

@j616
Copy link
Author

j616 commented Sep 26, 2018

Any chance someone could take a look at this?

@FrederikP
Copy link
Contributor

FrederikP commented Sep 26, 2018

Just discovered a bug related to this by using your example schema and data and debugging into the generated code (using compile_to_code). The key error is reproducable for me.
There is an issue with variables being overwritten, because in python the scopes of variables are not very strict. I'm not very familiar with the code, but maybe I can find a way to fix this.

The issue seems to be with self.l('for key, val in {variable}.items():'): from generate_pattern_properties. When these statements are nested, key and val get overwritten in certain circumstances. In your example this leads to val being assigned an empty object in the deeper object and then when it wants to check for bit, it uses this empty object instead of the correct one that was assigned earlier.

Also looking at the way this is built, I'm not sure that similiar issues can not be forced when it comes to nested properties with the same property names. Fully classifying all variables based on the properties would fix this.

e.g. data.item.foo.bar_value, data.item.foo.bar_key

@horejsek
Copy link
Owner

I plan to look at it tomorrow.

@FrederikP
Copy link
Contributor

Okay, my first naive idea was to use something like:
{name}_key, {name}_val
but the name template variable seems to be only made for use in strings and not in the code as it can depend on one more formatting step.

I'll let you look into it @horejsek . If you have any questions about what I found out, let me know. When debugging the generated code using the example from this issue, the problem becomes clear quite quickly.

@horejsek
Copy link
Owner

horejsek commented Sep 26, 2018

Thanks @FrederikP, you found the bug. :-) The same problem was on more places. It's fixed in master. I plan to do more stuff tomorrow, do you want to release it today or can you wait till tomorrow, @j616?

@j616
Copy link
Author

j616 commented Sep 26, 2018

I can wait until tomorrow. For now it's useful to know I don't have to find a work around and to know I'm not doing anything silly on my end! Thanks.

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

3 participants