Skip to content

Commit

Permalink
Check names of additional attribute keys (#196)
Browse files Browse the repository at this point in the history
* Add check for illegal additional attribute keys

* Add test with illegal additional attribute name

* Add two more examples of illegal attribute keys

* Fix validator after merging main

* Fix test after merging main
  • Loading branch information
phackstock authored Nov 22, 2022
1 parent ea02177 commit 98b1fb0
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 2 deletions.
15 changes: 14 additions & 1 deletion nomenclature/code.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import re
from keyword import iskeyword
from typing import Any, Dict, List, Optional, Set, Union

from pydantic import BaseModel, Field
from pydantic import BaseModel, Field, validator


class Code(BaseModel):
Expand All @@ -11,6 +12,18 @@ class Code(BaseModel):
description: Optional[str]
extra_attributes: Dict[str, Any] = {}

@validator("extra_attributes")
def check_attribute_names(cls, v, values):
# Check that attributes only contains keys which are valid identifiers
if illegal_keys := [
key for key in v.keys() if not key.isidentifier() or iskeyword(key)
]:
raise ValueError(
"Only valid identifiers are allowed as attribute keys. Found "
f"'{illegal_keys}' in '{values['name']}' which are not allowed."
)
return v

@classmethod
def from_dict(cls, mapping) -> "Code":
if isinstance(mapping, str):
Expand Down
9 changes: 8 additions & 1 deletion tests/test_code.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import pytest

from nomenclature.code import VariableCode
from nomenclature.code import Code, VariableCode


def test_variable_without_unit_raises():
Expand All @@ -23,6 +23,13 @@ def test_variable_alias_setting():
)


@pytest.mark.parametrize("illegal_key", ["contains-hyphen", "also not allowed", "True"])
def test_illegal_additional_attribute(illegal_key):
match = f"{illegal_key}.*'code1'.*not allowed"
with pytest.raises(ValueError, match=match):
Code(name="code1", extra_attributes={illegal_key: True})


def test_variable_multiple_units():
"""Test that a VariableCode with multiple units works"""
var = VariableCode.from_dict({"Var1": {"unit": ["unit1", "unit2"]}})
Expand Down

0 comments on commit 98b1fb0

Please sign in to comment.