From f987f22e9d09e704caf24bd634af557eb3bb3eb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fred=20Lef=C3=A9v=C3=A8re-Laoide?= <90181748+FredLL-Avaiga@users.noreply.github.com> Date: Thu, 18 Jul 2024 22:09:39 +0200 Subject: [PATCH] filter with non identifier property names (#1551) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * filter with non identifier property names resolves #1545 * use contains with list compare str in lowercase * fab's comments Co-authored-by: Fabien Lelaquais <86590727+FabienLelaquais@users.noreply.github.com> * mypy * Update config.pyi * ignore line too long in this doc string * handle noqa 501 on doc * Update config.pyi * fab's comment * fab's comment --------- Co-authored-by: Fred Lefévère-Laoide Co-authored-by: Fabien Lelaquais <86590727+FabienLelaquais@users.noreply.github.com> Co-authored-by: FredLL-Avaiga --- taipy/config/config.pyi | 65 +++++++++++---------------- taipy/config/stubs/generate_pyi.py | 3 +- taipy/core/config/data_node_config.py | 65 +++++++++++---------------- taipy/gui/gui.py | 2 +- taipy/gui_core/_adapters.py | 42 +++++++++++++++-- 5 files changed, 94 insertions(+), 83 deletions(-) diff --git a/taipy/config/config.pyi b/taipy/config/config.pyi index 1ce54681d1..455fb76557 100644 --- a/taipy/config/config.pyi +++ b/taipy/config/config.pyi @@ -271,14 +271,13 @@ class Config: The default value is `Scope.SCENARIO`. validity_period (Optional[timedelta]): The duration since the last edit date for which the data node can be considered up-to-date. Once the validity period has passed, the data node is considered stale and - relevant tasks will run even if they are skippable (see the - [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). + relevant tasks will run even if they are skippable (see the [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). If *validity_period* is set to None, the data node is always up-to-date. **properties (dict[str, any]): A keyworded variable length list of additional arguments. Returns: The default data node configuration. - """ + """ # noqa: E501 @classmethod def configure_data_node_from( @@ -323,14 +322,13 @@ class Config: `(Config.)set_default_data_node_configuration()^`). validity_period (Optional[timedelta]): The duration since the last edit date for which the data node can be considered up-to-date. Once the validity period has passed, the data node is considered stale and - relevant tasks will run even if they are skippable (see the - [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). + relevant tasks will run even if they are skippable (see the [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). If *validity_period* is set to None, the data node is always up-to-date. **properties (dict[str, any]): A keyworded variable length list of additional arguments. Returns: The new data node configuration. - """ + """ # noqa: E501 @classmethod def configure_csv_data_node( @@ -357,14 +355,13 @@ class Config: The default value is `Scope.SCENARIO`. validity_period (Optional[timedelta]): The duration since the last edit date for which the data node can be considered up-to-date. Once the validity period has passed, the data node is considered stale and - relevant tasks will run even if they are skippable (see the - [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). + relevant tasks will run even if they are skippable (see the [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). If *validity_period* is set to None, the data node is always up-to-date. **properties (dict[str, any]): A keyworded variable length list of additional arguments. Returns: The new CSV data node configuration. - """ + """ # noqa: E501 @classmethod def configure_json_data_node( @@ -390,13 +387,12 @@ class Config: The default value is `Scope.SCENARIO`. validity_period (Optional[timedelta]): The duration since the last edit date for which the data node can be considered up-to-date. Once the validity period has passed, the data node is considered stale and - relevant tasks will run even if they are skippable (see the - [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). + relevant tasks will run even if they are skippable (see the [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). If *validity_period* is set to None, the data node is always up-to-date. **properties (dict[str, any]): A keyworded variable length list of additional arguments. Returns: The new JSON data node configuration. - """ + """ # noqa: E501 @classmethod def configure_parquet_data_node( @@ -434,14 +430,13 @@ class Config: The default value is `Scope.SCENARIO`. validity_period (Optional[timedelta]): The duration since the last edit date for which the data node can be considered up-to-date. Once the validity period has passed, the data node is considered stale and - relevant tasks will run even if they are skippable (see the - [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). + relevant tasks will run even if they are skippable (see the [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). If *validity_period* is set to None, the data node is always up-to-date. **properties (dict[str, any]): A keyworded variable length list of additional arguments. Returns: The new Parquet data node configuration. - """ + """ # noqa: E501 @classmethod def configure_excel_data_node( @@ -469,14 +464,13 @@ class Config: The default value is `Scope.SCENARIO`. validity_period (Optional[timedelta]): The duration since the last edit date for which the data node can be considered up-to-date. Once the validity period has passed, the data node is considered stale and - relevant tasks will run even if they are skippable (see the - [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). + relevant tasks will run even if they are skippable (see the [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). If *validity_period* is set to None, the data node is always up-to-date. **properties (dict[str, any]): A keyworded variable length list of additional arguments. Returns: The new Excel data node configuration. - """ + """ # noqa: E501 @classmethod def configure_generic_data_node( @@ -505,13 +499,12 @@ class Config: The default value is `Scope.SCENARIO`. validity_period (Optional[timedelta]): The duration since the last edit date for which the data node can be considered up-to-date. Once the validity period has passed, the data node is considered stale and - relevant tasks will run even if they are skippable (see the - [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). + relevant tasks will run even if they are skippable (see the [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). If *validity_period* is set to None, the data node is always up-to-date. **properties (dict[str, any]): A keyworded variable length list of additional arguments. Returns: The new Generic data node configuration. - """ + """ # noqa: E501 @classmethod def configure_in_memory_data_node( @@ -534,14 +527,13 @@ class Config: The default value is `Scope.SCENARIO`. validity_period (Optional[timedelta]): The duration since the last edit date for which the data node can be considered up-to-date. Once the validity period has passed, the data node is considered stale and - relevant tasks will run even if they are skippable (see the - [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). + relevant tasks will run even if they are skippable (see the [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). If *validity_period* is set to None, the data node is always up-to-date. **properties (dict[str, any]): A keyworded variable length list of additional arguments. Returns: The new *in-memory* data node configuration. - """ + """ # noqa: E501 @classmethod def configure_pickle_data_node( @@ -566,14 +558,13 @@ class Config: The default value is `Scope.SCENARIO`. validity_period (Optional[timedelta]): The duration since the last edit date for which the data node can be considered up-to-date. Once the validity period has passed, the data node is considered stale and - relevant tasks will run even if they are skippable (see the - [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). + relevant tasks will run even if they are skippable (see the [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). If *validity_period* is set to None, the data node is always up-to-date. **properties (dict[str, any]): A keyworded variable length list of additional arguments. Returns: The new pickle data node configuration. - """ + """ # noqa: E501 @classmethod def configure_sql_table_data_node( @@ -624,14 +615,13 @@ class Config: The default value is `Scope.SCENARIO`. validity_period (Optional[timedelta]): The duration since the last edit date for which the data node can be considered up-to-date. Once the validity period has passed, the data node is considered stale and - relevant tasks will run even if they are skippable (see the - [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). + relevant tasks will run even if they are skippable (see the [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). If *validity_period* is set to None, the data node is always up-to-date. **properties (dict[str, any]): A keyworded variable length list of additional arguments. Returns: The new SQL data node configuration. - """ + """ # noqa: E501 @classmethod def configure_sql_data_node( @@ -688,13 +678,12 @@ class Config: The default value is `Scope.SCENARIO`. validity_period (Optional[timedelta]): The duration since the last edit date for which the data node can be considered up-to-date. Once the validity period has passed, the data node is considered stale and - relevant tasks will run even if they are skippable (see the - [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). + relevant tasks will run even if they are skippable (see the [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). If *validity_period* is set to None, the data node is always up-to-date. **properties (dict[str, any]): A keyworded variable length list of additional arguments. Returns: The new SQL data node configuration. - """ + """ # noqa: E501 @classmethod def configure_mongo_collection_data_node( @@ -737,14 +726,13 @@ class Config: The default value is `Scope.SCENARIO`. validity_period (Optional[timedelta]): The duration since the last edit date for which the data node can be considered up-to-date. Once the validity period has passed, the data node is considered stale and - relevant tasks will run even if they are skippable (see the - [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). + relevant tasks will run even if they are skippable (see the [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). If *validity_period* is set to None, the data node is always up-to-date. **properties (dict[str, any]): A keyworded variable length list of additional arguments. Returns: The new Mongo collection data node configuration. - """ + """ # noqa: E501 @classmethod def configure_s3_object_data_node( @@ -775,14 +763,13 @@ class Config: The default value is `Scope.SCENARIO`. validity_period (Optional[timedelta]): The duration since the last edit date for which the data node can be considered up-to-date. Once the validity period has passed, the data node is considered stale and - relevant tasks will run even if they are skippable (see the - [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). + relevant tasks will run even if they are skippable (see the [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). If *validity_period* is set to None, the data node is always up-to-date. **properties (dict[str, any]): A keyworded variable length list of additional arguments. Returns: The new S3 object data node configuration. - """ + """ # noqa: E501 @staticmethod def configure_task( diff --git a/taipy/config/stubs/generate_pyi.py b/taipy/config/stubs/generate_pyi.py index 923365087c..5c6f6a9d04 100644 --- a/taipy/config/stubs/generate_pyi.py +++ b/taipy/config/stubs/generate_pyi.py @@ -14,6 +14,7 @@ from pathlib import Path from typing import List +_end_doc = re.compile(r'\"\"\"\s*(#\s*noqa\s*:\s*E501)?\s*\n') def _get_function_delimiters(initial_line, lines): begin = end = initial_line @@ -28,7 +29,7 @@ def _get_function_delimiters(initial_line, lines): if '"""' in lines[end + 1]: while True: - if '"""\n' in lines[end]: + if _end_doc.search(lines[end]): break end += 1 return begin, end + 1 diff --git a/taipy/core/config/data_node_config.py b/taipy/core/config/data_node_config.py index 815984c33a..126a598bb4 100644 --- a/taipy/core/config/data_node_config.py +++ b/taipy/core/config/data_node_config.py @@ -411,14 +411,13 @@ def _set_default_configuration( The default value is `Scope.SCENARIO`. validity_period (Optional[timedelta]): The duration since the last edit date for which the data node can be considered up-to-date. Once the validity period has passed, the data node is considered stale and - relevant tasks will run even if they are skippable (see the - [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). + relevant tasks will run even if they are skippable (see the [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). If *validity_period* is set to None, the data node is always up-to-date. **properties (dict[str, any]): A keyworded variable length list of additional arguments. Returns: The default data node configuration. - """ + """ # noqa: E501 section = DataNodeConfig(_Config.DEFAULT_KEY, storage_type, scope, validity_period, **properties) Config._register_default(section) return Config.sections[DataNodeConfig.name][_Config.DEFAULT_KEY] @@ -471,14 +470,13 @@ def _configure( `(Config.)set_default_data_node_configuration()^`). validity_period (Optional[timedelta]): The duration since the last edit date for which the data node can be considered up-to-date. Once the validity period has passed, the data node is considered stale and - relevant tasks will run even if they are skippable (see the - [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). + relevant tasks will run even if they are skippable (see the [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). If *validity_period* is set to None, the data node is always up-to-date. **properties (dict[str, any]): A keyworded variable length list of additional arguments. Returns: The new data node configuration. - """ + """ # noqa: E501 configuration_map: Dict[str, Callable] = { cls._STORAGE_TYPE_VALUE_PICKLE: cls._configure_pickle, cls._STORAGE_TYPE_VALUE_SQL_TABLE: cls._configure_sql_table, @@ -523,14 +521,13 @@ def _configure_csv( The default value is `Scope.SCENARIO`. validity_period (Optional[timedelta]): The duration since the last edit date for which the data node can be considered up-to-date. Once the validity period has passed, the data node is considered stale and - relevant tasks will run even if they are skippable (see the - [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). + relevant tasks will run even if they are skippable (see the [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). If *validity_period* is set to None, the data node is always up-to-date. **properties (dict[str, any]): A keyworded variable length list of additional arguments. Returns: The new CSV data node configuration. - """ + """ # noqa: E501 if default_path is not None: properties[cls._OPTIONAL_DEFAULT_PATH_CSV_PROPERTY] = default_path if encoding is not None: @@ -566,13 +563,12 @@ def _configure_json( The default value is `Scope.SCENARIO`. validity_period (Optional[timedelta]): The duration since the last edit date for which the data node can be considered up-to-date. Once the validity period has passed, the data node is considered stale and - relevant tasks will run even if they are skippable (see the - [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). + relevant tasks will run even if they are skippable (see the [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). If *validity_period* is set to None, the data node is always up-to-date. **properties (dict[str, any]): A keyworded variable length list of additional arguments. Returns: The new JSON data node configuration. - """ + """ # noqa: E501 if default_path is not None: properties[cls._OPTIONAL_DEFAULT_PATH_JSON_PROPERTY] = default_path if encoding is not None: @@ -620,14 +616,13 @@ def _configure_parquet( The default value is `Scope.SCENARIO`. validity_period (Optional[timedelta]): The duration since the last edit date for which the data node can be considered up-to-date. Once the validity period has passed, the data node is considered stale and - relevant tasks will run even if they are skippable (see the - [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). + relevant tasks will run even if they are skippable (see the [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). If *validity_period* is set to None, the data node is always up-to-date. **properties (dict[str, any]): A keyworded variable length list of additional arguments. Returns: The new Parquet data node configuration. - """ + """ # noqa: E501 if default_path is not None: properties[cls._OPTIONAL_DEFAULT_PATH_PARQUET_PROPERTY] = default_path if engine is not None: @@ -669,14 +664,13 @@ def _configure_excel( The default value is `Scope.SCENARIO`. validity_period (Optional[timedelta]): The duration since the last edit date for which the data node can be considered up-to-date. Once the validity period has passed, the data node is considered stale and - relevant tasks will run even if they are skippable (see the - [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). + relevant tasks will run even if they are skippable (see the [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). If *validity_period* is set to None, the data node is always up-to-date. **properties (dict[str, any]): A keyworded variable length list of additional arguments. Returns: The new Excel data node configuration. - """ + """ # noqa: E501 if default_path is not None: properties[cls._OPTIONAL_DEFAULT_PATH_EXCEL_PROPERTY] = default_path if has_header is not None: @@ -715,13 +709,12 @@ def _configure_generic( The default value is `Scope.SCENARIO`. validity_period (Optional[timedelta]): The duration since the last edit date for which the data node can be considered up-to-date. Once the validity period has passed, the data node is considered stale and - relevant tasks will run even if they are skippable (see the - [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). + relevant tasks will run even if they are skippable (see the [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). If *validity_period* is set to None, the data node is always up-to-date. **properties (dict[str, any]): A keyworded variable length list of additional arguments. Returns: The new Generic data node configuration. - """ + """ # noqa: E501 if read_fct is not None: properties[cls._OPTIONAL_READ_FUNCTION_GENERIC_PROPERTY] = read_fct if write_fct is not None: @@ -754,14 +747,13 @@ def _configure_in_memory( The default value is `Scope.SCENARIO`. validity_period (Optional[timedelta]): The duration since the last edit date for which the data node can be considered up-to-date. Once the validity period has passed, the data node is considered stale and - relevant tasks will run even if they are skippable (see the - [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). + relevant tasks will run even if they are skippable (see the [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). If *validity_period* is set to None, the data node is always up-to-date. **properties (dict[str, any]): A keyworded variable length list of additional arguments. Returns: The new *in-memory* data node configuration. - """ + """ # noqa: E501 if default_data is not None: properties[cls._OPTIONAL_DEFAULT_DATA_IN_MEMORY_PROPERTY] = default_data @@ -790,14 +782,13 @@ def _configure_pickle( The default value is `Scope.SCENARIO`. validity_period (Optional[timedelta]): The duration since the last edit date for which the data node can be considered up-to-date. Once the validity period has passed, the data node is considered stale and - relevant tasks will run even if they are skippable (see the - [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). + relevant tasks will run even if they are skippable (see the [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). If *validity_period* is set to None, the data node is always up-to-date. **properties (dict[str, any]): A keyworded variable length list of additional arguments. Returns: The new pickle data node configuration. - """ + """ # noqa: E501 if default_path is not None: properties[cls._OPTIONAL_DEFAULT_PATH_PICKLE_PROPERTY] = default_path if default_data is not None: @@ -854,14 +845,13 @@ def _configure_sql_table( The default value is `Scope.SCENARIO`. validity_period (Optional[timedelta]): The duration since the last edit date for which the data node can be considered up-to-date. Once the validity period has passed, the data node is considered stale and - relevant tasks will run even if they are skippable (see the - [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). + relevant tasks will run even if they are skippable (see the [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). If *validity_period* is set to None, the data node is always up-to-date. **properties (dict[str, any]): A keyworded variable length list of additional arguments. Returns: The new SQL data node configuration. - """ + """ # noqa: E501 properties.update( { cls._REQUIRED_DB_NAME_SQL_PROPERTY: db_name, @@ -946,13 +936,12 @@ def _configure_sql( The default value is `Scope.SCENARIO`. validity_period (Optional[timedelta]): The duration since the last edit date for which the data node can be considered up-to-date. Once the validity period has passed, the data node is considered stale and - relevant tasks will run even if they are skippable (see the - [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). + relevant tasks will run even if they are skippable (see the [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). If *validity_period* is set to None, the data node is always up-to-date. **properties (dict[str, any]): A keyworded variable length list of additional arguments. Returns: The new SQL data node configuration. - """ + """ # noqa: E501 properties.update( { cls._REQUIRED_DB_NAME_SQL_PROPERTY: db_name, @@ -1026,14 +1015,13 @@ def _configure_mongo_collection( The default value is `Scope.SCENARIO`. validity_period (Optional[timedelta]): The duration since the last edit date for which the data node can be considered up-to-date. Once the validity period has passed, the data node is considered stale and - relevant tasks will run even if they are skippable (see the - [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). + relevant tasks will run even if they are skippable (see the [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). If *validity_period* is set to None, the data node is always up-to-date. **properties (dict[str, any]): A keyworded variable length list of additional arguments. Returns: The new Mongo collection data node configuration. - """ + """ # noqa: E501 properties.update( { cls._REQUIRED_DB_NAME_MONGO_PROPERTY: db_name, @@ -1089,14 +1077,13 @@ def _configure_s3_object( The default value is `Scope.SCENARIO`. validity_period (Optional[timedelta]): The duration since the last edit date for which the data node can be considered up-to-date. Once the validity period has passed, the data node is considered stale and - relevant tasks will run even if they are skippable (see the - [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). + relevant tasks will run even if they are skippable (see the [Task configs page](../../userman/task-orchestration/scenario-config.md#from-task-configurations) for more details). If *validity_period* is set to None, the data node is always up-to-date. **properties (dict[str, any]): A keyworded variable length list of additional arguments. Returns: The new S3 object data node configuration. - """ + """ # noqa: E501 properties.update( { cls._REQUIRED_AWS_ACCESS_KEY_ID_PROPERTY: aws_access_key, diff --git a/taipy/gui/gui.py b/taipy/gui/gui.py index 8c41cf4708..0933ebaa76 100644 --- a/taipy/gui/gui.py +++ b/taipy/gui/gui.py @@ -1514,7 +1514,7 @@ def invoke_callback( The first parameter of this function **must** be a `State^`. args (Optional[Sequence]): The remaining arguments, as a List or a Tuple. module_context (Optional[str]): the name of the module that will be used. - """ + """ # noqa: E501 this_sid = None if request: # avoid messing with the client_id => Set(ws id) diff --git a/taipy/gui_core/_adapters.py b/taipy/gui_core/_adapters.py index 930fb7b9ac..fa2d3ae11b 100644 --- a/taipy/gui_core/_adapters.py +++ b/taipy/gui_core/_adapters.py @@ -244,14 +244,50 @@ def get_hash(): "contains": contains, } + +def _filter_value(base_val: t.Any, operator: t.Callable, val: t.Any, adapt: t.Optional[t.Callable] = None): + if isinstance(base_val, (datetime, date)): + base_val = base_val.isoformat() + val = adapt(base_val, val) if adapt else val + if isinstance(base_val, str) and isinstance(val, str): + base_val = base_val.lower() + val = val.lower() + return operator(base_val, val) + +def _adapt_type(base_val, val): + # try casting the filter to the value + if isinstance(val, str) and not isinstance(base_val, str): + if isinstance(base_val, bool) and _is_boolean(val): + return _is_true(val) + else: + try: + return type(base_val)(val) + except Exception: + # forget it + pass + return val + def _filter_iterable(list_val: Iterable, operator: t.Callable, val: t.Any): - return next(filter(lambda v: operator(v, val), list_val), None) is not None + if operator is contains: + types = {type(v) for v in list_val} + if len(types) == 1: + typed_val = next(v for v in list_val) + if isinstance(typed_val, (datetime, date)): + list_val = [v.isoformat() for v in list_val] + else: + val = _adapt_type(typed_val, val) + return contains(list(list_val), val) + return next(filter(lambda v: _filter_value(v, operator, val), list_val), None) is not None + def _invoke_action( ent: t.Any, col: str, col_type: str, is_dn: bool, action: str, val: t.Any, col_fn: t.Optional[str] ) -> bool: if ent is None: return False + if not (col_fn or col).isidentifier(): + _warn(f'Error filtering with "{col_fn or col}": not a valid Python identifier.') + return True try: if col_type == "any": # when a property is not found, return True only if action is not equals @@ -262,7 +298,7 @@ def _invoke_action( cur_val = cur_val() if col_fn else cur_val if isinstance(cur_val, Iterable): return _filter_iterable(cur_val, op, val) - return op(cur_val.isoformat() if isinstance(cur_val, (datetime, date)) else cur_val, val) + return _filter_value(cur_val, op, val, _adapt_type) except Exception as e: if _is_debugging(): _warn(f"Error filtering with {col} {action} {val} on {ent}.", e) @@ -349,7 +385,7 @@ def get(self): [ (attr, self.get_type(attr), self.get_enums().get(attr)) if self.full_desc() else (attr,) for attr in flist - if attr and isinstance(attr, str) + if attr ] ) return None