Skip to content

Commit 3952d06

Browse files
Convert "Version" types to "str" outside of validation (#151)
* Convert "Version" types to "str" outside of validation * feat: validate versions but "type" it as a str * feat: add tests and allow models to be built with explicit None values * docs: update test docstrings * docs: changelog and version
1 parent 2797f67 commit 3952d06

File tree

6 files changed

+77
-15
lines changed

6 files changed

+77
-15
lines changed

CHANGELOG.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,13 @@ The types of changes are:
1414
- `Fixed` for any bug fixes.
1515
- `Security` in case of vulnerabilities.
1616

17-
## [Unreleased](https://github.com/ethyca/fideslang/compare/2.0.0...main)
17+
## [Unreleased](https://github.com/ethyca/fideslang/compare/2.0.1...main)
18+
19+
## [2.0.1](https://github.com/ethyca/fideslang/compare/2.0.0...2.0.1)
20+
21+
### Changed
22+
23+
- Fix validation around the new FidesVersion type [#151](https://github.com/ethyca/fideslang/pull/151)
1824

1925
### Fixed
2026

scripts/export_default_taxonomy.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,6 @@ def export_yaml() -> None:
3030
print(f"> Writing YAML to {output_filename}")
3131
resources = [x.dict() for x in getattr(DEFAULT_TAXONOMY, resource_type)]
3232

33-
# Clean up specific data types
34-
35-
resources = [
36-
{
37-
key: str(value) if isinstance(value, Version) else value
38-
for key, value in resource.items()
39-
}
40-
for resource in resources
41-
]
42-
4333
write_manifest(
4434
output_filename,
4535
manifest=resources,

src/fideslang/models.py

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,11 @@ class DefaultModel(BaseModel):
9191
A model meant to be inherited by versioned parts of the Default Taxonomy.
9292
"""
9393

94-
version_added: Optional[FidesVersion] = Field(
94+
version_added: Optional[str] = Field(
9595
default=None,
9696
description="The version of Fideslang in which this label was added.",
9797
)
98-
version_deprecated: Optional[FidesVersion] = Field(
98+
version_deprecated: Optional[str] = Field(
9999
default=None,
100100
description="The version of Fideslang in which this label was deprecated.",
101101
)
@@ -114,6 +114,34 @@ class DefaultModel(BaseModel):
114114
)
115115
_is_deprecated_if_replaced: classmethod = is_deprecated_if_replaced_validator
116116

117+
@validator("version_added")
118+
@classmethod
119+
def validate_verion_added(
120+
cls, version_added: Optional[str], values: Dict
121+
) -> Optional[str]:
122+
"""
123+
Validate that the `version_added` field is a proper FidesVersion
124+
"""
125+
if not version_added:
126+
return None
127+
128+
FidesVersion.validate(version_added)
129+
return version_added
130+
131+
@validator("version_deprecated")
132+
@classmethod
133+
def validate_version_deprecated(
134+
cls, version_deprecated: Optional[str], values: Dict
135+
) -> Optional[str]:
136+
"""
137+
Validate that the `version_deprecated` is a proper FidesVersion
138+
"""
139+
if not version_deprecated:
140+
return None
141+
142+
FidesVersion.validate(version_deprecated)
143+
return version_deprecated
144+
117145

118146
class DataResponsibilityTitle(str, Enum):
119147
"""

src/fideslang/validation.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,14 +91,18 @@ def no_self_reference(value: FidesKey, values: Dict) -> FidesKey:
9191

9292

9393
def deprecated_version_later_than_added(
94-
version_deprecated: FidesVersion, values: Dict
95-
) -> FidesVersion:
94+
version_deprecated: Optional[FidesVersion], values: Dict
95+
) -> Optional[FidesVersion]:
9696
"""
9797
Check to make sure that the deprecated version is later than the added version.
9898
9999
This will also catch errors where the deprecated version is defined but the added
100100
version is empty.
101101
"""
102+
103+
if not version_deprecated:
104+
return None
105+
102106
if version_deprecated < values.get("version_added", Version("0")):
103107
raise FidesValidationError(
104108
"Deprecated version number can't be earlier than version added!"

tests/fideslang/test_default_taxonomy.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ def test_taxonomy_count(self, type_and_count: Tuple[str, int]) -> None:
2020
expected_count = type_and_count[1]
2121
assert len(getattr(DEFAULT_TAXONOMY, data_type)) == expected_count
2222

23+
@pytest.mark.parametrize("data_type", taxonomy_counts.keys())
24+
def test_are_set_as_default(self, data_type: str) -> None:
25+
assert all([x.is_default for x in getattr(DEFAULT_TAXONOMY, data_type)])
26+
2327
@pytest.mark.parametrize("data_type", taxonomy_counts.keys())
2428
def test_key_uniqueness(self, data_type: str) -> None:
2529
keys = [x.fides_key for x in getattr(DEFAULT_TAXONOMY, data_type)]

tests/fideslang/test_validation.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,36 @@ def test_deprecated_after_added(self, TaxonomyClass):
8484
version_deprecated="0.2",
8585
)
8686

87+
@pytest.mark.parametrize("TaxonomyClass", DEFAULT_TAXONOMY_CLASSES)
88+
def test_built_from_dict_with_empty_versions(self, TaxonomyClass) -> None:
89+
"""Try building from a dictionary with explicit None values."""
90+
TaxonomyClass.parse_obj(
91+
{
92+
"organization_fides_key": 1,
93+
"fides_key": "user",
94+
"name": "Custom Test Data",
95+
"description": "Custom Test Data Category",
96+
"version_deprecated": None,
97+
"version_added": None,
98+
"replaced_by": None,
99+
"is_default": False,
100+
}
101+
)
102+
103+
@pytest.mark.parametrize("TaxonomyClass", DEFAULT_TAXONOMY_CLASSES)
104+
def test_built_with_empty_versions(self, TaxonomyClass) -> None:
105+
"""Try building directly with explicit None values."""
106+
TaxonomyClass(
107+
organization_fides_key=1,
108+
fides_key="user",
109+
name="Custom Test Data",
110+
description="Custom Test Data Category",
111+
version_deprecated=None,
112+
version_added=None,
113+
replaced_by=None,
114+
is_default=False,
115+
)
116+
87117
@pytest.mark.parametrize("TaxonomyClass", DEFAULT_TAXONOMY_CLASSES)
88118
def test_deprecated_not_added(self, TaxonomyClass):
89119
"""Can't be deprecated without being added in an earlier version."""

0 commit comments

Comments
 (0)