From 9a3c0139a6de5566b557d33982206abc5d5fa895 Mon Sep 17 00:00:00 2001 From: anders-albert Date: Wed, 21 Aug 2024 18:13:11 +0200 Subject: [PATCH 1/9] tests: Added failing test --- tests/test_unit/test_api/test_generate_sdk.py | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/tests/test_unit/test_api/test_generate_sdk.py b/tests/test_unit/test_api/test_generate_sdk.py index 2b232c91e..1365ba18a 100644 --- a/tests/test_unit/test_api/test_generate_sdk.py +++ b/tests/test_unit/test_api/test_generate_sdk.py @@ -69,6 +69,23 @@ def test_generate_sdk_with_illegal_property_names(self, tmp_path: Path) -> None: module = vars(importlib.import_module(top_level_package)) assert client_name in module + def test_generate_sdk_with_reverse_direct_relation_without_target(self, tmp_path: Path) -> None: + client_name = "ReverseDirectRelationClient" + top_level_package = "reverse_direct_relation_model" + + generate_sdk( + DATA_MODEL_WITH_REVERSE_DIRECT_RELATION_WITHOUT_TARGET, + top_level_package=top_level_package, + output_dir=tmp_path, + overwrite=True, + client_name=client_name, + default_instance_space="reverse_direct_relation_space", + ) + + with append_to_sys_path(str(tmp_path)): + module = vars(importlib.import_module(top_level_package)) + assert client_name in module + DATA_MODEL_WITH_VIEW_NAMED_FIELD = dm.DataModel( space="field_space", @@ -212,3 +229,63 @@ def test_generate_sdk_with_illegal_property_names(self, tmp_path: Path) -> None: ) ], ) + +DATA_MODEL_WITH_REVERSE_DIRECT_RELATION_WITHOUT_TARGET = dm.DataModel( + space="reverse_direct_relation_space", + external_id="ReverseDirectRelationModel", + version="1", + is_global=False, + last_updated_time=0, + created_time=0, + description=None, + name=None, + views=[ + dm.View( + space="reverse_direct_relation_space", + name="ReverseDirectRelationTarget", + external_id="ReverseDirectRelationTarget", + version="1", + properties={ + "name": dm.MappedProperty( + container=dm.ContainerId("reverse_direct_relation_space", "ReverseDirectRelation"), + container_property_identifier="name", + type=dm.Text(), + nullable=False, + auto_increment=False, + immutable=False, + ), + }, + description=None, + is_global=False, + last_updated_time=0, + created_time=0, + used_for="node", + implements=None, + writable=True, + filter=None, + ), + dm.View( + space="reverse_direct_relation_space", + name="ReverseDirectRelation", + external_id="ReverseDirectRelation", + version="1", + properties={ + "pointingToNonExisting": dm.MultiReverseDirectRelation( + source=dm.ViewId("reverse_direct_relation_space", "ReverseDirectRelationTarget", "1"), + through=dm.PropertyId( + source=dm.ViewId("reverse_direct_relation_space", "ReverseDirectRelation", "1"), + property="NonExisting", + ), + ), + }, + description=None, + is_global=False, + last_updated_time=0, + created_time=0, + used_for="node", + implements=None, + writable=True, + filter=None, + ), + ], +) From 243f796fc3a12414500ceb92573a90b6f6e6491e Mon Sep 17 00:00:00 2001 From: anders-albert Date: Wed, 21 Aug 2024 18:37:52 +0200 Subject: [PATCH 2/9] fix: Graceful handling of reverse direct relation missing target --- cognite/pygen/_core/generators.py | 8 ++++++++ cognite/pygen/_core/models/data_classes.py | 11 ++++++++++- cognite/pygen/_core/models/fields/base.py | 10 +++++++++- .../pygen/_core/models/fields/connections.py | 18 ++++++++++++++++++ tests/test_unit/test_api/test_generate_sdk.py | 2 +- 5 files changed, 46 insertions(+), 3 deletions(-) diff --git a/cognite/pygen/_core/generators.py b/cognite/pygen/_core/generators.py index 00e41a999..456308e67 100644 --- a/cognite/pygen/_core/generators.py +++ b/cognite/pygen/_core/generators.py @@ -211,12 +211,19 @@ def __init__( self._logger = logger or print seen_views: set[dm.ViewId] = set() unique_views: list[dm.View] = [] + # Used to verify that reverse direct relation's targets exist. + direct_relations_by_view_id: dict[dm.ViewId, set[str]] = {} for view in itertools.chain.from_iterable(model.views for model in data_models): view_id = view.as_id() if view_id in seen_views: continue unique_views.append(view) seen_views.add(view_id) + direct_relations_by_view_id[view_id] = { + prop_name + for prop_name, prop in view.properties.items() + if isinstance(prop, dm.MappedProperty) and isinstance(prop.type, dm.DirectRelation) + } self.api_by_type_by_view_id = self.create_api_by_view_id_type( unique_views, @@ -252,6 +259,7 @@ def __init__( edge_class_by_view_id, unique_views, self.has_default_instance_space, + direct_relations_by_view_id, config, ) diff --git a/cognite/pygen/_core/models/data_classes.py b/cognite/pygen/_core/models/data_classes.py index 7bd932e3a..d4249c9b0 100644 --- a/cognite/pygen/_core/models/data_classes.py +++ b/cognite/pygen/_core/models/data_classes.py @@ -146,6 +146,7 @@ def update_fields( edge_class_by_view_id: dict[dm.ViewId, EdgeDataClass], views: list[dm.View], has_default_instance_space: bool, + direct_relations_by_view_id: dict[dm.ViewId, set[str]], config: pygen_config.PygenConfig, ) -> None: """Update the fields of the data class. @@ -164,6 +165,7 @@ def update_fields( # This is the default value for pydantic_field, it will be updated later pydantic_field=self.pydantic_field, has_default_instance_space=has_default_instance_space, + direct_relations_by_view_id=direct_relations_by_view_id, ) if field_ is None: # Reverse direct relations are skipped @@ -664,6 +666,7 @@ def update_fields( edge_class_by_view_id: dict[dm.ViewId, EdgeDataClass], views: list[dm.View], has_default_instance_space: bool, + direct_relations_by_view_id: dict[dm.ViewId, set[str]], config: pygen_config.PygenConfig, ): """Update the fields of the data class.""" @@ -699,5 +702,11 @@ def update_fields( ) self.fields.append(self._end_node_field) super().update_fields( - properties, node_class_by_view_id, edge_class_by_view_id, views, has_default_instance_space, config + properties, + node_class_by_view_id, + edge_class_by_view_id, + views, + has_default_instance_space, + direct_relations_by_view_id, + config, ) diff --git a/cognite/pygen/_core/models/fields/base.py b/cognite/pygen/_core/models/fields/base.py index b69c7eba6..8ff145205 100644 --- a/cognite/pygen/_core/models/fields/base.py +++ b/cognite/pygen/_core/models/fields/base.py @@ -57,6 +57,7 @@ def from_property( view_id: dm.ViewId, pydantic_field: Literal["Field", "pydantic.Field"], has_default_instance_space: bool, + direct_relations_by_view_id: dict[dm.ViewId, set[str]], ) -> Field | None: from .cdf_reference import CDFExternalField from .connections import BaseConnectionField @@ -86,7 +87,14 @@ def from_property( isinstance(prop, dm.MappedProperty) and isinstance(prop.type, dm.DirectRelation) ): return BaseConnectionField.load( - base, prop, variable, node_class_by_view_id, edge_class_by_view_id, has_default_instance_space + base, + prop, + variable, + node_class_by_view_id, + edge_class_by_view_id, + has_default_instance_space, + view_id, + direct_relations_by_view_id, ) elif isinstance(prop, dm.MappedProperty) and isinstance(prop.type, dm.CDFExternalIdReference): return CDFExternalField.load(base, prop, variable) diff --git a/cognite/pygen/_core/models/fields/connections.py b/cognite/pygen/_core/models/fields/connections.py index 3f54c385a..d64e4cad3 100644 --- a/cognite/pygen/_core/models/fields/connections.py +++ b/cognite/pygen/_core/models/fields/connections.py @@ -231,10 +231,28 @@ def load( node_class_by_view_id: dict[dm.ViewId, NodeDataClass], edge_class_by_view_id: dict[dm.ViewId, EdgeDataClass], has_default_instance_space: bool, + view_id: dm.ViewId, + direct_relations_by_view_id: dict[dm.ViewId, set[str]], ) -> Field | None: """Load a connection field from a property""" if not isinstance(prop, (dm.EdgeConnection, dm.MappedProperty, ReverseDirectRelation)): return None + if isinstance(prop, ReverseDirectRelation): + field_string = f"{view_id}.{base.prop_name}" + target = ( + direct_relations_by_view_id.get(prop.through.source) + if isinstance(prop.through.source, dm.ViewId) + else None + ) + if target is None or prop.through.property not in target: + target_str = ( + f"{prop.through.source}.{prop.through.property}" if target is not None else prop.through.source + ) + warnings.warn( + f"Target {target_str} does not exists. " f"Skipping reverse direct relation {field_string}", + stacklevel=2, + ) + return None edge_type = prop.type if isinstance(prop, dm.EdgeConnection) else None direction: Literal["outwards", "inwards"] if isinstance(prop, dm.EdgeConnection): diff --git a/tests/test_unit/test_api/test_generate_sdk.py b/tests/test_unit/test_api/test_generate_sdk.py index 1365ba18a..e4bb1615e 100644 --- a/tests/test_unit/test_api/test_generate_sdk.py +++ b/tests/test_unit/test_api/test_generate_sdk.py @@ -273,7 +273,7 @@ def test_generate_sdk_with_reverse_direct_relation_without_target(self, tmp_path "pointingToNonExisting": dm.MultiReverseDirectRelation( source=dm.ViewId("reverse_direct_relation_space", "ReverseDirectRelationTarget", "1"), through=dm.PropertyId( - source=dm.ViewId("reverse_direct_relation_space", "ReverseDirectRelation", "1"), + source=dm.ViewId("reverse_direct_relation_space", "ReverseDirectRelationTarget", "1"), property="NonExisting", ), ), From e15476bd71724cf1a47bb008638dd16eaf0aaa33 Mon Sep 17 00:00:00 2001 From: anders-albert Date: Wed, 21 Aug 2024 18:41:58 +0200 Subject: [PATCH 3/9] refactor: use pygen warning --- cognite/pygen/_core/models/fields/connections.py | 9 ++++----- cognite/pygen/warnings.py | 10 ++++++++++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/cognite/pygen/_core/models/fields/connections.py b/cognite/pygen/_core/models/fields/connections.py index d64e4cad3..3a2c39141 100644 --- a/cognite/pygen/_core/models/fields/connections.py +++ b/cognite/pygen/_core/models/fields/connections.py @@ -16,6 +16,8 @@ SingleReverseDirectRelation, ) +from cognite.pygen.warnings import MissingReverseDirectRelationTargetWarning + from .base import Field if TYPE_CHECKING: @@ -246,12 +248,9 @@ def load( ) if target is None or prop.through.property not in target: target_str = ( - f"{prop.through.source}.{prop.through.property}" if target is not None else prop.through.source - ) - warnings.warn( - f"Target {target_str} does not exists. " f"Skipping reverse direct relation {field_string}", - stacklevel=2, + f"{prop.through.source}.{prop.through.property}" if target is not None else str(prop.through.source) ) + warnings.warn(MissingReverseDirectRelationTargetWarning(target_str, field_string), stacklevel=2) return None edge_type = prop.type if isinstance(prop, dm.EdgeConnection) else None direction: Literal["outwards", "inwards"] diff --git a/cognite/pygen/warnings.py b/cognite/pygen/warnings.py index cea855721..881860765 100644 --- a/cognite/pygen/warnings.py +++ b/cognite/pygen/warnings.py @@ -59,3 +59,13 @@ def __str__(self) -> str: f"Name collision detected. The following filter parameter {self.word!r} name is used by pygen." "An underscore will be added to this parameter to avoid name collision." ) + + +class MissingReverseDirectRelationTargetWarning(PygenWarning, UserWarning): + + def __init__(self, target: str, field: str) -> None: + self.target = target + self.field = field + + def __str__(self) -> str: + return f"Target {self.target} does not exists. Skipping reverse direct relation {self.field}." From e6af4e77fd702453041606b9ed81992c66e977c0 Mon Sep 17 00:00:00 2001 From: anders-albert Date: Wed, 21 Aug 2024 18:56:18 +0200 Subject: [PATCH 4/9] fix: better handling of invalid code generation --- cognite/pygen/_generator.py | 8 +++++++- cognite/pygen/warnings.py | 11 +++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/cognite/pygen/_generator.py b/cognite/pygen/_generator.py index 588f02d9f..84ee2e390 100644 --- a/cognite/pygen/_generator.py +++ b/cognite/pygen/_generator.py @@ -5,6 +5,7 @@ import shutil import sys import tempfile +import warnings from collections.abc import Sequence from pathlib import Path from typing import Any, Callable, Literal, Optional, Union, cast, overload @@ -22,6 +23,7 @@ from cognite.pygen.config import PygenConfig from cognite.pygen.exceptions import DataModelNotFound from cognite.pygen.utils.text import to_pascal, to_snake +from cognite.pygen.warnings import InvalidCodeGenerated DataModel = Union[DataModelIdentifier, dm.DataModel[dm.View]] @@ -422,7 +424,11 @@ def write_sdk_to_disk( path.unlink() path.parent.mkdir(parents=True, exist_ok=True) if format_code: - file_content = formatter.format_code(file_content) + try: + file_content = formatter.format_code(file_content) + except Exception as e: + warnings.warn(InvalidCodeGenerated(file_path, str(e)), stacklevel=2) + continue # Encoding and newline are set to ensure consistent file writing across platforms with path.open("w", encoding="utf-8", newline="\n") as f: f.write(file_content) diff --git a/cognite/pygen/warnings.py b/cognite/pygen/warnings.py index 881860765..78c0c56ef 100644 --- a/cognite/pygen/warnings.py +++ b/cognite/pygen/warnings.py @@ -1,6 +1,7 @@ from __future__ import annotations import warnings +from pathlib import Path from cognite.client.data_classes.data_modeling import ViewId @@ -69,3 +70,13 @@ def __init__(self, target: str, field: str) -> None: def __str__(self) -> str: return f"Target {self.target} does not exists. Skipping reverse direct relation {self.field}." + + +class InvalidCodeGenerated(PygenWarning, UserWarning): + + def __init__(self, filepath: str | Path, error_message: str) -> None: + self.filepath = filepath + self.error_message = error_message + + def __str__(self) -> str: + return f"Invalid code generated in {self.filepath}. {self.error_message}" From f6f768876872f062ee727b0dafda9863a8766c69 Mon Sep 17 00:00:00 2001 From: anders-albert Date: Wed, 21 Aug 2024 19:01:45 +0200 Subject: [PATCH 5/9] build: changelog --- docs/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 0514a82b7..c3d1e11e8 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -26,6 +26,8 @@ Changes are grouped as follows ### Fixed - In the generated SDK, fields of `TimeSeries` as now set to `TimeSeriesWrite` in the write Data Class of the generated SDK. +- If an input view had a reverse direct relation, that points to a non-existing target, the generated SDK would raise + a `ValueError`. `pygen` now gracefully handles this case by raising a warning instead. ## [0.99.32] - 24-08-17 ### Added From 2b98c250a3a02da01e1f18da811a368342d9d51f Mon Sep 17 00:00:00 2001 From: anders-albert Date: Wed, 21 Aug 2024 19:04:33 +0200 Subject: [PATCH 6/9] fix: handle view with only dependencies to self --- cognite/pygen/_core/models/data_classes.py | 5 +++++ cognite/pygen/_core/templates/data_class_edge.py.jinja | 2 +- cognite/pygen/_core/templates/data_class_node.py.jinja | 4 ++-- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/cognite/pygen/_core/models/data_classes.py b/cognite/pygen/_core/models/data_classes.py index d4249c9b0..8ac343fc0 100644 --- a/cognite/pygen/_core/models/data_classes.py +++ b/cognite/pygen/_core/models/data_classes.py @@ -420,6 +420,11 @@ def has_dependencies(self) -> bool: """Check if the data class has any dependencies.""" return bool(self.dependencies) + @property + def has_dependencies_not_self(self) -> bool: + """Check if the data class has any dependencies that are not itself.""" + return any(dependency != self for dependency in self.dependencies) + @property def has_edges_or_direct_relations(self) -> bool: """Whether the data class has any fields that are edges or direct relations.""" diff --git a/cognite/pygen/_core/templates/data_class_edge.py.jinja b/cognite/pygen/_core/templates/data_class_edge.py.jinja index e453ae4a1..19897382f 100644 --- a/cognite/pygen/_core/templates/data_class_edge.py.jinja +++ b/cognite/pygen/_core/templates/data_class_edge.py.jinja @@ -29,7 +29,7 @@ from ._core import ({% if has_default_instance_space %} ){% for class_ in unique_start_classes %} from .{{class_.file_name }} import {{ class_.write_name }}{% endfor %}{% for classes in unique_end_classes %} from .{{classes.file_name }} import {{ classes.read_name }}, {{ classes.graphql_name }}, {{ classes.write_name }}{% endfor %} -{% if data_class.has_dependencies %} +{% if data_class.has_dependencies_not_self %} if TYPE_CHECKING:{% for dependency_class in data_class.dependencies %}{% if dependency_class.file_name != data_class.file_name %} from .{{ dependency_class.file_name }} import {{ dependency_class.read_name }}, {{ dependency_class.graphql_name }}{% if dependency_class.is_writable or dependency_class.is_interface %}, {{ dependency_class.write_name }}{% endif %}{% endif %}{% endfor %} {% endif %} diff --git a/cognite/pygen/_core/templates/data_class_node.py.jinja b/cognite/pygen/_core/templates/data_class_node.py.jinja index e0b7e7e84..56d0c5140 100644 --- a/cognite/pygen/_core/templates/data_class_node.py.jinja +++ b/cognite/pygen/_core/templates/data_class_node.py.jinja @@ -57,7 +57,7 @@ from ._core import ({% if has_default_instance_space %} {{ data_class.filtering_import }}{% endif %} ){% if data_class.implements %}{% for implements in data_class.implements %} from .{{ implements.file_name }} import {{ implements.read_name }}{% if data_class.is_writable or data_class.is_interface %}, {{ implements.write_name }}{% endif %}{% endfor %}{% endif %} -{% if data_class.has_dependencies %} +{% if data_class.has_dependencies_not_self %} if TYPE_CHECKING:{% for dependency_class in data_class.dependencies %}{% if dependency_class.file_name != data_class.file_name %} from .{{ dependency_class.file_name }} import {{ dependency_class.read_name }}, {{ dependency_class.graphql_name }}{% if dependency_class.is_writable or dependency_class.is_interface %}, {{ dependency_class.write_name }}{% endif %}{% endif %}{% endfor %} {% endif %} @@ -193,7 +193,7 @@ class {{ data_class.read_name }}({{ data_class.read_base_class }}{% if is_pydant instances: dict[dm.NodeId{% if has_default_instance_space %} | str{% endif %}, {{ data_class.read_name }}], # type: ignore[override] nodes_by_id: dict[dm.NodeId{% if has_default_instance_space %} | str{% endif %}, DomainModel], edges_by_source_node: dict[dm.NodeId, list[dm.Edge | DomainRelation]], - ) -> None:{% if data_class.has_dependencies %}{% for dependency_class in data_class.dependencies %}{% if dependency_class.file_name != data_class.file_name %} + ) -> None:{% if data_class.has_dependencies_not_self %}{% for dependency_class in data_class.dependencies %}{% if dependency_class.file_name != data_class.file_name %} from .{{ dependency_class.file_name }} import {{ dependency_class.read_name }}{% endif %}{% endfor %} {% endif %}{% if data_class.has_edges_or_direct_relations %} for instance in instances.values():{% for field in data_class.one_to_one_direct_relations_with_source %} From 4826708f6cd50c6e9b0efa21c153aba655a0052d Mon Sep 17 00:00:00 2001 From: anders-albert Date: Wed, 21 Aug 2024 19:06:15 +0200 Subject: [PATCH 7/9] build: changelog --- docs/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index c3d1e11e8..a04de9ea5 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -28,6 +28,7 @@ Changes are grouped as follows SDK. - If an input view had a reverse direct relation, that points to a non-existing target, the generated SDK would raise a `ValueError`. `pygen` now gracefully handles this case by raising a warning instead. +- If a view only had a dependency on itself, `pygen` would generate invalid code. This is now fixed. ## [0.99.32] - 24-08-17 ### Added From 6c9105624646daacdf1dcebdd448f1691934b2f3 Mon Sep 17 00:00:00 2001 From: anders-albert Date: Wed, 21 Aug 2024 19:07:06 +0200 Subject: [PATCH 8/9] build: dump --- cognite/pygen/_version.py | 2 +- docs/CHANGELOG.md | 2 +- docs/quickstart/cdf_streamlit.md | 2 +- .../equipment_unit_pydantic_v1/_api_client.py | 4 ++-- examples-pydantic-v1/omni_multi_pydantic_v1/_api_client.py | 4 ++-- examples-pydantic-v1/omni_pydantic_v1/_api_client.py | 4 ++-- examples-pydantic-v1/omni_sub_pydantic_v1/_api_client.py | 4 ++-- .../scenario_instance_pydantic_v1/client/_api_client.py | 4 ++-- examples-pydantic-v1/windmill_pydantic_v1/_api_client.py | 4 ++-- examples/equipment_unit/_api_client.py | 4 ++-- examples/omni/_api_client.py | 4 ++-- examples/omni_multi/_api_client.py | 4 ++-- examples/omni_sub/_api_client.py | 4 ++-- examples/scenario_instance/client/_api_client.py | 4 ++-- examples/windmill/_api_client.py | 4 ++-- pyproject.toml | 2 +- 16 files changed, 28 insertions(+), 28 deletions(-) diff --git a/cognite/pygen/_version.py b/cognite/pygen/_version.py index 9f0bbddb3..a68b9fd99 100644 --- a/cognite/pygen/_version.py +++ b/cognite/pygen/_version.py @@ -1 +1 @@ -__version__ = "0.99.32" +__version__ = "0.99.33" diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index a04de9ea5..b3e978532 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -13,7 +13,7 @@ Changes are grouped as follows - `Fixed` for any bug fixes. - `Security` in case of vulnerabilities. -## TBD +## [0.99.33] - 24-08-21 ### Added - Support for `files` and `sequences` in the generated SDK. This includes the ability to create and retrieve `files` and `sequences` in the generated SDK. diff --git a/docs/quickstart/cdf_streamlit.md b/docs/quickstart/cdf_streamlit.md index c800e704a..08be09860 100644 --- a/docs/quickstart/cdf_streamlit.md +++ b/docs/quickstart/cdf_streamlit.md @@ -13,7 +13,7 @@ adding `cognite-pygen` to the installed packages under `settings`. pyodide-http==0.2.1 cognite-sdk==7.54.13 pydantic==1.10.7 -cognite-pygen==0.99.32 +cognite-pygen==0.99.33 ``` Note that we also set `pydantic` to a specific version. This is because `pygen` supports both `pydantic` `v1` and `v2`, but diff --git a/examples-pydantic-v1/equipment_unit_pydantic_v1/_api_client.py b/examples-pydantic-v1/equipment_unit_pydantic_v1/_api_client.py index 21ac514dd..1c7822fcb 100644 --- a/examples-pydantic-v1/equipment_unit_pydantic_v1/_api_client.py +++ b/examples-pydantic-v1/equipment_unit_pydantic_v1/_api_client.py @@ -23,7 +23,7 @@ class EquipmentUnitClient: EquipmentUnitClient Generated with: - pygen = 0.99.32 + pygen = 0.99.33 cognite-sdk = 7.54.13 pydantic = 1.10.7 @@ -41,7 +41,7 @@ def __init__(self, config_or_client: CogniteClient | ClientConfig): else: raise ValueError(f"Expected CogniteClient or ClientConfig, got {type(config_or_client)}") # The client name is used for aggregated logging of Pygen Usage - client.config.client_name = "CognitePygen:0.99.32" + client.config.client_name = "CognitePygen:0.99.33" self._client = client diff --git a/examples-pydantic-v1/omni_multi_pydantic_v1/_api_client.py b/examples-pydantic-v1/omni_multi_pydantic_v1/_api_client.py index c2cc63d63..73c31016a 100644 --- a/examples-pydantic-v1/omni_multi_pydantic_v1/_api_client.py +++ b/examples-pydantic-v1/omni_multi_pydantic_v1/_api_client.py @@ -111,7 +111,7 @@ class OmniMultiClient: OmniMultiClient Generated with: - pygen = 0.99.32 + pygen = 0.99.33 cognite-sdk = 7.54.13 pydantic = 1.10.7 @@ -125,7 +125,7 @@ def __init__(self, config_or_client: CogniteClient | ClientConfig): else: raise ValueError(f"Expected CogniteClient or ClientConfig, got {type(config_or_client)}") # The client name is used for aggregated logging of Pygen Usage - client.config.client_name = "CognitePygen:0.99.32" + client.config.client_name = "CognitePygen:0.99.33" self.omni_multi_a = OmniMultiAAPIs(client) self.omni_multi_b = OmniMultiBAPIs(client) diff --git a/examples-pydantic-v1/omni_pydantic_v1/_api_client.py b/examples-pydantic-v1/omni_pydantic_v1/_api_client.py index d26a9a1c6..34e049a39 100644 --- a/examples-pydantic-v1/omni_pydantic_v1/_api_client.py +++ b/examples-pydantic-v1/omni_pydantic_v1/_api_client.py @@ -41,7 +41,7 @@ class OmniClient: OmniClient Generated with: - pygen = 0.99.32 + pygen = 0.99.33 cognite-sdk = 7.54.13 pydantic = 1.10.7 @@ -59,7 +59,7 @@ def __init__(self, config_or_client: CogniteClient | ClientConfig): else: raise ValueError(f"Expected CogniteClient or ClientConfig, got {type(config_or_client)}") # The client name is used for aggregated logging of Pygen Usage - client.config.client_name = "CognitePygen:0.99.32" + client.config.client_name = "CognitePygen:0.99.33" self._client = client diff --git a/examples-pydantic-v1/omni_sub_pydantic_v1/_api_client.py b/examples-pydantic-v1/omni_sub_pydantic_v1/_api_client.py index b73fc5e0a..7fe610c52 100644 --- a/examples-pydantic-v1/omni_sub_pydantic_v1/_api_client.py +++ b/examples-pydantic-v1/omni_sub_pydantic_v1/_api_client.py @@ -23,7 +23,7 @@ class OmniSubClient: OmniSubClient Generated with: - pygen = 0.99.32 + pygen = 0.99.33 cognite-sdk = 7.54.13 pydantic = 1.10.7 @@ -41,7 +41,7 @@ def __init__(self, config_or_client: CogniteClient | ClientConfig): else: raise ValueError(f"Expected CogniteClient or ClientConfig, got {type(config_or_client)}") # The client name is used for aggregated logging of Pygen Usage - client.config.client_name = "CognitePygen:0.99.32" + client.config.client_name = "CognitePygen:0.99.33" self._client = client diff --git a/examples-pydantic-v1/scenario_instance_pydantic_v1/client/_api_client.py b/examples-pydantic-v1/scenario_instance_pydantic_v1/client/_api_client.py index bd1c0ef2d..b290e201a 100644 --- a/examples-pydantic-v1/scenario_instance_pydantic_v1/client/_api_client.py +++ b/examples-pydantic-v1/scenario_instance_pydantic_v1/client/_api_client.py @@ -21,7 +21,7 @@ class ScenarioInstanceClient: ScenarioInstanceClient Generated with: - pygen = 0.99.32 + pygen = 0.99.33 cognite-sdk = 7.54.13 pydantic = 1.10.7 @@ -39,7 +39,7 @@ def __init__(self, config_or_client: CogniteClient | ClientConfig): else: raise ValueError(f"Expected CogniteClient or ClientConfig, got {type(config_or_client)}") # The client name is used for aggregated logging of Pygen Usage - client.config.client_name = "CognitePygen:0.99.32" + client.config.client_name = "CognitePygen:0.99.33" self._client = client diff --git a/examples-pydantic-v1/windmill_pydantic_v1/_api_client.py b/examples-pydantic-v1/windmill_pydantic_v1/_api_client.py index 338371de7..1196d0f10 100644 --- a/examples-pydantic-v1/windmill_pydantic_v1/_api_client.py +++ b/examples-pydantic-v1/windmill_pydantic_v1/_api_client.py @@ -31,7 +31,7 @@ class WindmillClient: WindmillClient Generated with: - pygen = 0.99.32 + pygen = 0.99.33 cognite-sdk = 7.54.13 pydantic = 1.10.7 @@ -49,7 +49,7 @@ def __init__(self, config_or_client: CogniteClient | ClientConfig): else: raise ValueError(f"Expected CogniteClient or ClientConfig, got {type(config_or_client)}") # The client name is used for aggregated logging of Pygen Usage - client.config.client_name = "CognitePygen:0.99.32" + client.config.client_name = "CognitePygen:0.99.33" self._client = client diff --git a/examples/equipment_unit/_api_client.py b/examples/equipment_unit/_api_client.py index 8d3fff063..c78c99dd7 100644 --- a/examples/equipment_unit/_api_client.py +++ b/examples/equipment_unit/_api_client.py @@ -23,7 +23,7 @@ class EquipmentUnitClient: EquipmentUnitClient Generated with: - pygen = 0.99.32 + pygen = 0.99.33 cognite-sdk = 7.54.13 pydantic = 2.8.2 @@ -41,7 +41,7 @@ def __init__(self, config_or_client: CogniteClient | ClientConfig): else: raise ValueError(f"Expected CogniteClient or ClientConfig, got {type(config_or_client)}") # The client name is used for aggregated logging of Pygen Usage - client.config.client_name = "CognitePygen:0.99.32" + client.config.client_name = "CognitePygen:0.99.33" self._client = client diff --git a/examples/omni/_api_client.py b/examples/omni/_api_client.py index ac53036ce..35934712b 100644 --- a/examples/omni/_api_client.py +++ b/examples/omni/_api_client.py @@ -41,7 +41,7 @@ class OmniClient: OmniClient Generated with: - pygen = 0.99.32 + pygen = 0.99.33 cognite-sdk = 7.54.13 pydantic = 2.8.2 @@ -59,7 +59,7 @@ def __init__(self, config_or_client: CogniteClient | ClientConfig): else: raise ValueError(f"Expected CogniteClient or ClientConfig, got {type(config_or_client)}") # The client name is used for aggregated logging of Pygen Usage - client.config.client_name = "CognitePygen:0.99.32" + client.config.client_name = "CognitePygen:0.99.33" self._client = client diff --git a/examples/omni_multi/_api_client.py b/examples/omni_multi/_api_client.py index 4bedb1869..edc3af1b1 100644 --- a/examples/omni_multi/_api_client.py +++ b/examples/omni_multi/_api_client.py @@ -111,7 +111,7 @@ class OmniMultiClient: OmniMultiClient Generated with: - pygen = 0.99.32 + pygen = 0.99.33 cognite-sdk = 7.54.13 pydantic = 2.8.2 @@ -125,7 +125,7 @@ def __init__(self, config_or_client: CogniteClient | ClientConfig): else: raise ValueError(f"Expected CogniteClient or ClientConfig, got {type(config_or_client)}") # The client name is used for aggregated logging of Pygen Usage - client.config.client_name = "CognitePygen:0.99.32" + client.config.client_name = "CognitePygen:0.99.33" self.omni_multi_a = OmniMultiAAPIs(client) self.omni_multi_b = OmniMultiBAPIs(client) diff --git a/examples/omni_sub/_api_client.py b/examples/omni_sub/_api_client.py index 3f1264724..0a3ed0e99 100644 --- a/examples/omni_sub/_api_client.py +++ b/examples/omni_sub/_api_client.py @@ -23,7 +23,7 @@ class OmniSubClient: OmniSubClient Generated with: - pygen = 0.99.32 + pygen = 0.99.33 cognite-sdk = 7.54.13 pydantic = 2.8.2 @@ -41,7 +41,7 @@ def __init__(self, config_or_client: CogniteClient | ClientConfig): else: raise ValueError(f"Expected CogniteClient or ClientConfig, got {type(config_or_client)}") # The client name is used for aggregated logging of Pygen Usage - client.config.client_name = "CognitePygen:0.99.32" + client.config.client_name = "CognitePygen:0.99.33" self._client = client diff --git a/examples/scenario_instance/client/_api_client.py b/examples/scenario_instance/client/_api_client.py index 09e09509b..f167991f5 100644 --- a/examples/scenario_instance/client/_api_client.py +++ b/examples/scenario_instance/client/_api_client.py @@ -21,7 +21,7 @@ class ScenarioInstanceClient: ScenarioInstanceClient Generated with: - pygen = 0.99.32 + pygen = 0.99.33 cognite-sdk = 7.54.13 pydantic = 2.8.2 @@ -39,7 +39,7 @@ def __init__(self, config_or_client: CogniteClient | ClientConfig): else: raise ValueError(f"Expected CogniteClient or ClientConfig, got {type(config_or_client)}") # The client name is used for aggregated logging of Pygen Usage - client.config.client_name = "CognitePygen:0.99.32" + client.config.client_name = "CognitePygen:0.99.33" self._client = client diff --git a/examples/windmill/_api_client.py b/examples/windmill/_api_client.py index 7a717734f..32f63d69e 100644 --- a/examples/windmill/_api_client.py +++ b/examples/windmill/_api_client.py @@ -31,7 +31,7 @@ class WindmillClient: WindmillClient Generated with: - pygen = 0.99.32 + pygen = 0.99.33 cognite-sdk = 7.54.13 pydantic = 2.8.2 @@ -49,7 +49,7 @@ def __init__(self, config_or_client: CogniteClient | ClientConfig): else: raise ValueError(f"Expected CogniteClient or ClientConfig, got {type(config_or_client)}") # The client name is used for aggregated logging of Pygen Usage - client.config.client_name = "CognitePygen:0.99.32" + client.config.client_name = "CognitePygen:0.99.33" self._client = client diff --git a/pyproject.toml b/pyproject.toml index d4fb9f991..837a77271 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "cognite-pygen" -version = "0.99.32" +version = "0.99.33" description = "Cognite Python SDK Generator" readme = "README.md" authors = ["Cognite "] From fac9b44f6c637fbf2267e820021e4d0fdfe5c8b2 Mon Sep 17 00:00:00 2001 From: anders-albert Date: Wed, 21 Aug 2024 19:20:31 +0200 Subject: [PATCH 9/9] tests: updated test + regen --- .../omni_typed_pydantic_v1/typed.py | 48 +++++++++---------- examples/omni_typed/typed.py | 48 +++++++++---------- tests/test_unit/test_models/conftest.py | 17 ++++++- .../test_models/test_data_classes.py | 9 +++- tests/test_unit/test_models/test_fields.py | 1 + 5 files changed, 73 insertions(+), 50 deletions(-) diff --git a/examples-pydantic-v1/omni_typed_pydantic_v1/typed.py b/examples-pydantic-v1/omni_typed_pydantic_v1/typed.py index 31d203d3e..66072fce7 100644 --- a/examples-pydantic-v1/omni_typed_pydantic_v1/typed.py +++ b/examples-pydantic-v1/omni_typed_pydantic_v1/typed.py @@ -11,14 +11,14 @@ ) -class CDFExternalReferencesListedProperties: +class _CDFExternalReferencesListedProperties: @classmethod def get_source(cls) -> ViewId: return ViewId("pygen-models", "CDFExternalReferencesListed", "1") -class CDFExternalReferencesListedApply(CDFExternalReferencesListedProperties, TypedNodeApply): +class CDFExternalReferencesListedApply(_CDFExternalReferencesListedProperties, TypedNodeApply): """This represents the writing format of cdf external references listed. It is used to when data is written to CDF. @@ -54,7 +54,7 @@ def __init__( self.timeseries = timeseries -class CDFExternalReferencesListed(CDFExternalReferencesListedProperties, TypedNode): +class CDFExternalReferencesListed(_CDFExternalReferencesListedProperties, TypedNode): """This represents the reading format of cdf external references listed. It is used to when data is read from CDF. @@ -105,7 +105,7 @@ def as_write(self) -> CDFExternalReferencesListedApply: ) -class DependentOnNonWritableProperties: +class _DependentOnNonWritableProperties: a_value = PropertyOptions("aValue") @classmethod @@ -113,7 +113,7 @@ def get_source(cls) -> ViewId: return ViewId("pygen-models", "DependentOnNonWritable", "1") -class DependentOnNonWritableApply(DependentOnNonWritableProperties, TypedNodeApply): +class DependentOnNonWritableApply(_DependentOnNonWritableProperties, TypedNodeApply): """This represents the writing format of dependent on non writable. It is used to when data is written to CDF. @@ -143,7 +143,7 @@ def __init__( self.a_value = a_value -class DependentOnNonWritable(DependentOnNonWritableProperties, TypedNode): +class DependentOnNonWritable(_DependentOnNonWritableProperties, TypedNode): """This represents the reading format of dependent on non writable. It is used to when data is read from CDF. @@ -186,7 +186,7 @@ def as_write(self) -> DependentOnNonWritableApply: ) -class MainInterfaceProperties: +class _MainInterfaceProperties: main_value = PropertyOptions("mainValue") @classmethod @@ -194,7 +194,7 @@ def get_source(cls) -> ViewId: return ViewId("pygen-models", "MainInterface", "1") -class MainInterfaceApply(MainInterfaceProperties, TypedNodeApply): +class MainInterfaceApply(_MainInterfaceProperties, TypedNodeApply): """This represents the writing format of main interface. It is used to when data is written to CDF. @@ -224,7 +224,7 @@ def __init__( self.main_value = main_value -class MainInterface(MainInterfaceProperties, TypedNode): +class MainInterface(_MainInterfaceProperties, TypedNode): """This represents the reading format of main interface. It is used to when data is read from CDF. @@ -267,7 +267,7 @@ def as_write(self) -> MainInterfaceApply: ) -class PrimitiveNullableProperties: +class _PrimitiveNullableProperties: float_32 = PropertyOptions("float32") float_64 = PropertyOptions("float64") int_32 = PropertyOptions("int32") @@ -279,7 +279,7 @@ def get_source(cls) -> ViewId: return ViewId("pygen-models", "PrimitiveNullable", "1") -class PrimitiveNullableApply(PrimitiveNullableProperties, TypedNodeApply): +class PrimitiveNullableApply(_PrimitiveNullableProperties, TypedNodeApply): """This represents the writing format of primitive nullable. It is used to when data is written to CDF. @@ -333,7 +333,7 @@ def __init__( self.timestamp = timestamp -class PrimitiveNullable(PrimitiveNullableProperties, TypedNode): +class PrimitiveNullable(_PrimitiveNullableProperties, TypedNode): """This represents the reading format of primitive nullable. It is used to when data is read from CDF. @@ -408,7 +408,7 @@ def as_write(self) -> PrimitiveNullableApply: ) -class PrimitiveRequiredListedProperties: +class _PrimitiveRequiredListedProperties: float_32 = PropertyOptions("float32") float_64 = PropertyOptions("float64") int_32 = PropertyOptions("int32") @@ -420,7 +420,7 @@ def get_source(cls) -> ViewId: return ViewId("pygen-models", "PrimitiveRequiredListed", "1") -class PrimitiveRequiredListedApply(PrimitiveRequiredListedProperties, TypedNodeApply): +class PrimitiveRequiredListedApply(_PrimitiveRequiredListedProperties, TypedNodeApply): """This represents the writing format of primitive required listed. It is used to when data is written to CDF. @@ -474,7 +474,7 @@ def __init__( self.timestamp = timestamp -class PrimitiveRequiredListed(PrimitiveRequiredListedProperties, TypedNode): +class PrimitiveRequiredListed(_PrimitiveRequiredListedProperties, TypedNode): """This represents the reading format of primitive required listed. It is used to when data is read from CDF. @@ -549,7 +549,7 @@ def as_write(self) -> PrimitiveRequiredListedApply: ) -class SubInterfaceProperties: +class _SubInterfaceProperties: sub_value = PropertyOptions("subValue") @classmethod @@ -557,7 +557,7 @@ def get_source(cls) -> ViewId: return ViewId("pygen-models", "SubInterface", "1") -class SubInterfaceApply(SubInterfaceProperties, MainInterfaceApply): +class SubInterfaceApply(_SubInterfaceProperties, MainInterfaceApply): """This represents the writing format of sub interface. It is used to when data is written to CDF. @@ -589,7 +589,7 @@ def __init__( self.sub_value = sub_value -class SubInterface(SubInterfaceProperties, MainInterface): +class SubInterface(_SubInterfaceProperties, MainInterface): """This represents the reading format of sub interface. It is used to when data is read from CDF. @@ -644,7 +644,7 @@ def as_write(self) -> SubInterfaceApply: ) -class Implementation1Properties: +class _Implementation1Properties: value_2 = PropertyOptions("value2") value_1 = PropertyOptions("value1") @@ -653,7 +653,7 @@ def get_source(cls) -> ViewId: return ViewId("pygen-models", "Implementation1", "1") -class Implementation1Apply(Implementation1Properties, SubInterfaceApply): +class Implementation1Apply(_Implementation1Properties, SubInterfaceApply): """This represents the writing format of implementation 1. It is used to when data is written to CDF. @@ -692,7 +692,7 @@ def __init__( self.value_1 = value_1 -class Implementation1(Implementation1Properties, SubInterface): +class Implementation1(_Implementation1Properties, SubInterface): """This represents the reading format of implementation 1. It is used to when data is read from CDF. @@ -755,13 +755,13 @@ def as_write(self) -> Implementation1Apply: ) -class Implementation2Properties: +class _Implementation2Properties: @classmethod def get_source(cls) -> ViewId: return ViewId("pygen-models", "Implementation2", "1") -class Implementation2Apply(Implementation2Properties, SubInterfaceApply): +class Implementation2Apply(_Implementation2Properties, SubInterfaceApply): """This represents the writing format of implementation 2. It is used to when data is written to CDF. @@ -794,7 +794,7 @@ def __init__( ) -class Implementation2(Implementation2Properties, SubInterface): +class Implementation2(_Implementation2Properties, SubInterface): """This represents the reading format of implementation 2. It is used to when data is read from CDF. diff --git a/examples/omni_typed/typed.py b/examples/omni_typed/typed.py index 31d203d3e..66072fce7 100644 --- a/examples/omni_typed/typed.py +++ b/examples/omni_typed/typed.py @@ -11,14 +11,14 @@ ) -class CDFExternalReferencesListedProperties: +class _CDFExternalReferencesListedProperties: @classmethod def get_source(cls) -> ViewId: return ViewId("pygen-models", "CDFExternalReferencesListed", "1") -class CDFExternalReferencesListedApply(CDFExternalReferencesListedProperties, TypedNodeApply): +class CDFExternalReferencesListedApply(_CDFExternalReferencesListedProperties, TypedNodeApply): """This represents the writing format of cdf external references listed. It is used to when data is written to CDF. @@ -54,7 +54,7 @@ def __init__( self.timeseries = timeseries -class CDFExternalReferencesListed(CDFExternalReferencesListedProperties, TypedNode): +class CDFExternalReferencesListed(_CDFExternalReferencesListedProperties, TypedNode): """This represents the reading format of cdf external references listed. It is used to when data is read from CDF. @@ -105,7 +105,7 @@ def as_write(self) -> CDFExternalReferencesListedApply: ) -class DependentOnNonWritableProperties: +class _DependentOnNonWritableProperties: a_value = PropertyOptions("aValue") @classmethod @@ -113,7 +113,7 @@ def get_source(cls) -> ViewId: return ViewId("pygen-models", "DependentOnNonWritable", "1") -class DependentOnNonWritableApply(DependentOnNonWritableProperties, TypedNodeApply): +class DependentOnNonWritableApply(_DependentOnNonWritableProperties, TypedNodeApply): """This represents the writing format of dependent on non writable. It is used to when data is written to CDF. @@ -143,7 +143,7 @@ def __init__( self.a_value = a_value -class DependentOnNonWritable(DependentOnNonWritableProperties, TypedNode): +class DependentOnNonWritable(_DependentOnNonWritableProperties, TypedNode): """This represents the reading format of dependent on non writable. It is used to when data is read from CDF. @@ -186,7 +186,7 @@ def as_write(self) -> DependentOnNonWritableApply: ) -class MainInterfaceProperties: +class _MainInterfaceProperties: main_value = PropertyOptions("mainValue") @classmethod @@ -194,7 +194,7 @@ def get_source(cls) -> ViewId: return ViewId("pygen-models", "MainInterface", "1") -class MainInterfaceApply(MainInterfaceProperties, TypedNodeApply): +class MainInterfaceApply(_MainInterfaceProperties, TypedNodeApply): """This represents the writing format of main interface. It is used to when data is written to CDF. @@ -224,7 +224,7 @@ def __init__( self.main_value = main_value -class MainInterface(MainInterfaceProperties, TypedNode): +class MainInterface(_MainInterfaceProperties, TypedNode): """This represents the reading format of main interface. It is used to when data is read from CDF. @@ -267,7 +267,7 @@ def as_write(self) -> MainInterfaceApply: ) -class PrimitiveNullableProperties: +class _PrimitiveNullableProperties: float_32 = PropertyOptions("float32") float_64 = PropertyOptions("float64") int_32 = PropertyOptions("int32") @@ -279,7 +279,7 @@ def get_source(cls) -> ViewId: return ViewId("pygen-models", "PrimitiveNullable", "1") -class PrimitiveNullableApply(PrimitiveNullableProperties, TypedNodeApply): +class PrimitiveNullableApply(_PrimitiveNullableProperties, TypedNodeApply): """This represents the writing format of primitive nullable. It is used to when data is written to CDF. @@ -333,7 +333,7 @@ def __init__( self.timestamp = timestamp -class PrimitiveNullable(PrimitiveNullableProperties, TypedNode): +class PrimitiveNullable(_PrimitiveNullableProperties, TypedNode): """This represents the reading format of primitive nullable. It is used to when data is read from CDF. @@ -408,7 +408,7 @@ def as_write(self) -> PrimitiveNullableApply: ) -class PrimitiveRequiredListedProperties: +class _PrimitiveRequiredListedProperties: float_32 = PropertyOptions("float32") float_64 = PropertyOptions("float64") int_32 = PropertyOptions("int32") @@ -420,7 +420,7 @@ def get_source(cls) -> ViewId: return ViewId("pygen-models", "PrimitiveRequiredListed", "1") -class PrimitiveRequiredListedApply(PrimitiveRequiredListedProperties, TypedNodeApply): +class PrimitiveRequiredListedApply(_PrimitiveRequiredListedProperties, TypedNodeApply): """This represents the writing format of primitive required listed. It is used to when data is written to CDF. @@ -474,7 +474,7 @@ def __init__( self.timestamp = timestamp -class PrimitiveRequiredListed(PrimitiveRequiredListedProperties, TypedNode): +class PrimitiveRequiredListed(_PrimitiveRequiredListedProperties, TypedNode): """This represents the reading format of primitive required listed. It is used to when data is read from CDF. @@ -549,7 +549,7 @@ def as_write(self) -> PrimitiveRequiredListedApply: ) -class SubInterfaceProperties: +class _SubInterfaceProperties: sub_value = PropertyOptions("subValue") @classmethod @@ -557,7 +557,7 @@ def get_source(cls) -> ViewId: return ViewId("pygen-models", "SubInterface", "1") -class SubInterfaceApply(SubInterfaceProperties, MainInterfaceApply): +class SubInterfaceApply(_SubInterfaceProperties, MainInterfaceApply): """This represents the writing format of sub interface. It is used to when data is written to CDF. @@ -589,7 +589,7 @@ def __init__( self.sub_value = sub_value -class SubInterface(SubInterfaceProperties, MainInterface): +class SubInterface(_SubInterfaceProperties, MainInterface): """This represents the reading format of sub interface. It is used to when data is read from CDF. @@ -644,7 +644,7 @@ def as_write(self) -> SubInterfaceApply: ) -class Implementation1Properties: +class _Implementation1Properties: value_2 = PropertyOptions("value2") value_1 = PropertyOptions("value1") @@ -653,7 +653,7 @@ def get_source(cls) -> ViewId: return ViewId("pygen-models", "Implementation1", "1") -class Implementation1Apply(Implementation1Properties, SubInterfaceApply): +class Implementation1Apply(_Implementation1Properties, SubInterfaceApply): """This represents the writing format of implementation 1. It is used to when data is written to CDF. @@ -692,7 +692,7 @@ def __init__( self.value_1 = value_1 -class Implementation1(Implementation1Properties, SubInterface): +class Implementation1(_Implementation1Properties, SubInterface): """This represents the reading format of implementation 1. It is used to when data is read from CDF. @@ -755,13 +755,13 @@ def as_write(self) -> Implementation1Apply: ) -class Implementation2Properties: +class _Implementation2Properties: @classmethod def get_source(cls) -> ViewId: return ViewId("pygen-models", "Implementation2", "1") -class Implementation2Apply(Implementation2Properties, SubInterfaceApply): +class Implementation2Apply(_Implementation2Properties, SubInterfaceApply): """This represents the writing format of implementation 2. It is used to when data is written to CDF. @@ -794,7 +794,7 @@ def __init__( ) -class Implementation2(Implementation2Properties, SubInterface): +class Implementation2(_Implementation2Properties, SubInterface): """This represents the reading format of implementation 2. It is used to when data is read from CDF. diff --git a/tests/test_unit/test_models/conftest.py b/tests/test_unit/test_models/conftest.py index 781f30a01..235948cea 100644 --- a/tests/test_unit/test_models/conftest.py +++ b/tests/test_unit/test_models/conftest.py @@ -25,12 +25,27 @@ def omni_field_factory( pygen_config: PygenConfig, ) -> Callable[[str, str], Field]: node_class_by_view_id, edge_class_by_view_id = omni_data_classes_by_view_id + direct_relations_by_view_id: dict[dm.ViewId, set[str]] = {} + for view in omni_views.values(): + direct_relations_by_view_id[view.as_id()] = { + prop_name + for prop_name, prop in view.properties.items() + if isinstance(prop, dm.MappedProperty) and isinstance(prop.type, dm.DirectRelation) + } def factory(view_ext_id: str, property_name: str) -> Field: view = omni_views[view_ext_id] prop = view.properties[property_name] return Field.from_property( - property_name, prop, node_class_by_view_id, edge_class_by_view_id, pygen_config, view.as_id(), "Field", True + property_name, + prop, + node_class_by_view_id, + edge_class_by_view_id, + pygen_config, + view.as_id(), + "Field", + True, + direct_relations_by_view_id, ) return factory diff --git a/tests/test_unit/test_models/test_data_classes.py b/tests/test_unit/test_models/test_data_classes.py index ec7ff6d22..b2df60c78 100644 --- a/tests/test_unit/test_models/test_data_classes.py +++ b/tests/test_unit/test_models/test_data_classes.py @@ -20,7 +20,13 @@ def test_dependency_named_Field(self, pygen_config: PygenConfig) -> None: # Act for data_class, view in zip(node_class_by_view_id.values(), views): data_class.update_fields( - view.properties, node_class_by_view_id, edge_class_by_view_id, list(views), True, pygen_config + view.properties, + node_class_by_view_id, + edge_class_by_view_id, + list(views), + True, + {}, + pygen_config, ) # Assert @@ -62,6 +68,7 @@ def test_data_class_is_time(self, pygen_config: PygenConfig) -> None: {}, [view], True, + {}, pygen_config, ) diff --git a/tests/test_unit/test_models/test_fields.py b/tests/test_unit/test_models/test_fields.py index 3ad3548ec..d824385ae 100644 --- a/tests/test_unit/test_models/test_fields.py +++ b/tests/test_unit/test_models/test_fields.py @@ -62,6 +62,7 @@ def test_field_from_property_expect_warning(name: str, expected_name, pygen_conf dm.ViewId("a", "b", "c"), pydantic_field="Field", has_default_instance_space=True, + direct_relations_by_view_id={}, ) # Assert