-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
feat: add data config checker for property value types #2328
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,7 +10,7 @@ | |
# specific language governing permissions and limitations under the License. | ||
|
||
from datetime import timedelta | ||
from typing import Any, Callable, Dict, List, Tuple, cast | ||
from typing import Callable, Dict, List, cast | ||
|
||
from taipy.common.config._config import _Config | ||
from taipy.common.config.checker._checkers._config_checker import _ConfigChecker | ||
|
@@ -23,27 +23,6 @@ | |
|
||
|
||
class _DataNodeConfigChecker(_ConfigChecker): | ||
_PROPERTIES_TYPES: Dict[str, List[Tuple[Any, List[str]]]] = { | ||
DataNodeConfig._STORAGE_TYPE_VALUE_GENERIC: [ | ||
( | ||
Callable, | ||
[ | ||
DataNodeConfig._OPTIONAL_READ_FUNCTION_GENERIC_PROPERTY, | ||
DataNodeConfig._OPTIONAL_WRITE_FUNCTION_GENERIC_PROPERTY, | ||
], | ||
) | ||
], | ||
DataNodeConfig._STORAGE_TYPE_VALUE_SQL: [ | ||
( | ||
Callable, | ||
[ | ||
DataNodeConfig._REQUIRED_WRITE_QUERY_BUILDER_SQL_PROPERTY, | ||
DataNodeConfig._OPTIONAL_APPEND_QUERY_BUILDER_SQL_PROPERTY, | ||
], | ||
), | ||
], | ||
} | ||
|
||
def __init__(self, config: _Config, collector: IssueCollector): | ||
super().__init__(config, collector) | ||
|
||
|
@@ -67,7 +46,7 @@ def _check(self) -> IssueCollector: | |
self._check_scope(data_node_config_id, data_node_config) | ||
self._check_validity_period(data_node_config_id, data_node_config) | ||
self._check_required_properties(data_node_config_id, data_node_config) | ||
self._check_class_type(data_node_config_id, data_node_config) | ||
self._check_property_types(data_node_config_id, data_node_config) | ||
self._check_generic_read_write_fct_and_args(data_node_config_id, data_node_config) | ||
self._check_exposed_type(data_node_config_id, data_node_config) | ||
return self._collector | ||
|
@@ -217,25 +196,26 @@ def _check_generic_read_write_fct_and_args(self, data_node_config_id: str, data_ | |
f"DataNodeConfig `{data_node_config_id}` must be populated with a Callable function.", | ||
) | ||
|
||
def _check_class_type(self, data_node_config_id: str, data_node_config: DataNodeConfig): | ||
if data_node_config.storage_type in self._PROPERTIES_TYPES.keys(): | ||
for class_type, prop_keys in self._PROPERTIES_TYPES[data_node_config.storage_type]: | ||
for prop_key in prop_keys: | ||
prop_value = data_node_config.properties.get(prop_key) if data_node_config.properties else None | ||
if prop_value and not isinstance(prop_value, class_type): | ||
self._error( | ||
prop_key, | ||
prop_value, | ||
f"`{prop_key}` of DataNodeConfig `{data_node_config_id}` must be" | ||
f" populated with a {'Callable' if class_type == Callable else class_type.__name__}.", | ||
) | ||
if class_type == Callable and callable(prop_value) and prop_value.__name__ == "<lambda>": | ||
self._error( | ||
prop_key, | ||
prop_value, | ||
f"`{prop_key}` of DataNodeConfig `{data_node_config_id}` must be" | ||
f" populated with a serializable Callable function but not a lambda.", | ||
) | ||
def _check_property_types(self, data_node_config_id: str, data_node_config: DataNodeConfig): | ||
if property_types := data_node_config._PROPERTIES_TYPES.get(data_node_config.storage_type): | ||
for prop_key, prop_type in property_types.items(): | ||
prop_value = data_node_config.properties.get(prop_key) if data_node_config.properties else None | ||
|
||
if prop_value and not isinstance(prop_value, prop_type): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Can we imagine Does it make sense, or is it just over-engineering? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. isinstance can take a tuple of type as the second parameter. So we only need to define the proprety as a tuple of expected types and it should be good to go. I had to do that for a couple of properties already. |
||
self._error( | ||
prop_key, | ||
prop_value, | ||
f"`{prop_key}` of DataNodeConfig `{data_node_config_id}` must be" | ||
f" populated with a {prop_type}.", | ||
) | ||
|
||
if prop_type == Callable and callable(prop_value) and prop_value.__name__ == "<lambda>": | ||
self._error( | ||
prop_key, | ||
prop_value, | ||
f"`{prop_key}` of DataNodeConfig `{data_node_config_id}` must be" | ||
f" populated with a serializable typing.Callable function but not a lambda.", | ||
) | ||
|
||
def _check_exposed_type(self, data_node_config_id: str, data_node_config: DataNodeConfig): | ||
if not isinstance(data_node_config.exposed_type, str): | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you help propagate this change on enterprise as well? I'm quite certain it will fail on enterprise :D thanks!