From 89e80b212d87f5f69c71f097ac0d08129fe34746 Mon Sep 17 00:00:00 2001 From: Laurynas Jagutis Date: Mon, 11 Nov 2024 18:55:35 +0200 Subject: [PATCH 01/21] python api Signed-off-by: Laurynas Jagutis --- .../vnf_pgm_converter.h | 5 ++- .../src/vnf_pgm_converter.cpp | 2 +- .../_core/power_grid_model_io_core.py | 24 +++++++++++++ .../_core/vnf_converter.py | 34 +++++++++++++++++++ tests/unit/test_vnf_converter.py | 13 +++++++ 5 files changed, 74 insertions(+), 4 deletions(-) create mode 100644 src/power_grid_model_io_native/_core/vnf_converter.py diff --git a/power_grid_model_io_native_c/power_grid_model_io_native_c/include/power_grid_model_io_native_c/vnf_pgm_converter.h b/power_grid_model_io_native_c/power_grid_model_io_native_c/include/power_grid_model_io_native_c/vnf_pgm_converter.h index b11e85e..8d3fa21 100644 --- a/power_grid_model_io_native_c/power_grid_model_io_native_c/include/power_grid_model_io_native_c/vnf_pgm_converter.h +++ b/power_grid_model_io_native_c/power_grid_model_io_native_c/include/power_grid_model_io_native_c/vnf_pgm_converter.h @@ -26,10 +26,9 @@ PGM_IO_API PGM_IO_VnfConverter* PGM_IO_create_vnf_converter(PGM_IO_Handle* handl * @brief Retrieve the transformed input data from .vnf format to PGM format * @param handle * @param converter_ptr A pointer to a PGM_IO_VnfConverter instace. - * @param dataset A pointer to the const dataset supplied by the user. - * @return The pointer to the const dataset instance supplied by the user which has been filled in. + * @return The pointer to the json string instance that holds data in PGM format. */ -PGM_IO_API char const* PGM_IO_get_vnf_input_data(PGM_IO_Handle* handle, PGM_IO_VnfConverter* converter_ptr); +PGM_IO_API char const* PGM_IO_get_pgm_input_data(PGM_IO_Handle* handle, PGM_IO_VnfConverter* converter_ptr); /** * @brief Destroy the PGM_IO_VnfConverter and free up the memory that was dedicated to it. diff --git a/power_grid_model_io_native_c/power_grid_model_io_native_c/src/vnf_pgm_converter.cpp b/power_grid_model_io_native_c/power_grid_model_io_native_c/src/vnf_pgm_converter.cpp index b8065ed..559dc83 100644 --- a/power_grid_model_io_native_c/power_grid_model_io_native_c/src/vnf_pgm_converter.cpp +++ b/power_grid_model_io_native_c/power_grid_model_io_native_c/src/vnf_pgm_converter.cpp @@ -44,7 +44,7 @@ PGM_IO_VnfConverter* PGM_IO_create_vnf_converter(PGM_IO_Handle* handle, char con PGM_IO_regular_error); } -char const* PGM_IO_get_vnf_input_data(PGM_IO_Handle* handle, PGM_IO_VnfConverter* converter_ptr) { +char const* PGM_IO_get_pgm_input_data(PGM_IO_Handle* handle, PGM_IO_VnfConverter* converter_ptr) { return call_with_catch( handle, [converter_ptr] { return convert_input_wrapper(converter_ptr).c_str(); }, PGM_IO_regular_error); } diff --git a/src/power_grid_model_io_native/_core/power_grid_model_io_core.py b/src/power_grid_model_io_native/_core/power_grid_model_io_core.py index 1e2642b..24ea8c3 100644 --- a/src/power_grid_model_io_native/_core/power_grid_model_io_core.py +++ b/src/power_grid_model_io_native/_core/power_grid_model_io_core.py @@ -27,6 +27,18 @@ class HandlePtr(c_void_p): """ +class WritableDatasetPtr(c_void_p): + """ + Pointer to writable dataset + """ + + +class PgmVnfConverterPtr(c_void_p): + """ + Pointer to serializer + """ + + def _load_core() -> CDLL: """ @@ -139,6 +151,18 @@ def error_code(self) -> int: # type: ignore[empty-body] def error_message(self) -> str: # type: ignore[empty-body] pass # pragma: no cover + @make_c_binding + def create_vnf_converter(self, data: str, experimental_features: int) -> PgmVnfConverterPtr: + pass # pragma: no cover + + @make_c_binding + def get_pgm_input_data(self, pgmvnfconverter: PgmVnfConverterPtr) -> str: + pass # pragma: no cover + + @make_c_binding + def destroy_vnf_converter(self, pgmvnfconverter: PgmVnfConverterPtr) -> None: + pass # pragma: no cover + # make one instance pgm_io_core = PowerGridModelIoCore() diff --git a/src/power_grid_model_io_native/_core/vnf_converter.py b/src/power_grid_model_io_native/_core/vnf_converter.py new file mode 100644 index 0000000..7f0f301 --- /dev/null +++ b/src/power_grid_model_io_native/_core/vnf_converter.py @@ -0,0 +1,34 @@ +# SPDX-FileCopyrightText: Contributors to the Power Grid Model project +# +# SPDX-License-Identifier: MPL-2.0 + +from power_grid_model.core.error_handling import assert_no_error + +from power_grid_model_io_native._core.power_grid_model_io_core import PgmVnfConverterPtr, pgm_io_core as pgmic + + +class PgmVnfConverter: + _pgm_vnf_converter: PgmVnfConverterPtr + _serialized_data: str + + def __new__( + cls, + string_buffer: str, + experimental_feature: int, + ): + + instance = super().__new__(cls) + + instance._pgm_vnf_converter = pgmic.create_vnf_converter(string_buffer, experimental_feature) + assert_no_error() + + return instance + + def __del__(self): + if hasattr(self, "_pgm_vnf_converter"): + pgmic.destroy_vnf_converter(self._pgm_vnf_converter) + + def get_pgm_input_data(self): + pgm_data = pgmic.get_pgm_input_data(self._pgm_vnf_converter) + assert_no_error() + self._serialized_data = pgm_data diff --git a/tests/unit/test_vnf_converter.py b/tests/unit/test_vnf_converter.py index f464f29..f31d3ad 100644 --- a/tests/unit/test_vnf_converter.py +++ b/tests/unit/test_vnf_converter.py @@ -1,8 +1,21 @@ # SPDX-FileCopyrightText: Contributors to the Power Grid Model project # # SPDX-License-Identifier: MPL-2.0 +import pytest from power_grid_model_io_native._core.power_grid_model_io_core import pgm_io_core +from power_grid_model_io_native._core.vnf_converter import PgmVnfConverter + + +def test_pgmvnfconverter_constructor_without_experimental_features(): + with pytest.raises(Exception) as e: + _ = PgmVnfConverter("", 0) + print(f"Raised exception: {e.type} - {e.value}") + + +# def test_pgmvnfconverter_constructor_with_experimental_features(): +# converter = PgmVnfConverter("", 1) +# assert converter is not None def test_nothing(): From 44dd218eba7c106933aff94c03f4cbce22f8fae3 Mon Sep 17 00:00:00 2001 From: Laurynas Jagutis Date: Wed, 13 Nov 2024 11:44:00 +0200 Subject: [PATCH 02/21] example tests Signed-off-by: Laurynas Jagutis --- .../_core/power_grid_model_io_core.py | 6 +++--- .../_core/vnf_converter.py | 1 + tests/unit/test_vnf_converter.py | 13 ++++++++++--- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/power_grid_model_io_native/_core/power_grid_model_io_core.py b/src/power_grid_model_io_native/_core/power_grid_model_io_core.py index 24ea8c3..6f747e3 100644 --- a/src/power_grid_model_io_native/_core/power_grid_model_io_core.py +++ b/src/power_grid_model_io_native/_core/power_grid_model_io_core.py @@ -152,15 +152,15 @@ def error_message(self) -> str: # type: ignore[empty-body] pass # pragma: no cover @make_c_binding - def create_vnf_converter(self, data: str, experimental_features: int) -> PgmVnfConverterPtr: + def create_vnf_converter(self, data: str, experimental_features: int) -> PgmVnfConverterPtr: # type: ignore[empty-body] pass # pragma: no cover @make_c_binding - def get_pgm_input_data(self, pgmvnfconverter: PgmVnfConverterPtr) -> str: + def get_pgm_input_data(self, pgmvnfconverter: PgmVnfConverterPtr) -> str: # type: ignore[empty-body] pass # pragma: no cover @make_c_binding - def destroy_vnf_converter(self, pgmvnfconverter: PgmVnfConverterPtr) -> None: + def destroy_vnf_converter(self, pgmvnfconverter: PgmVnfConverterPtr) -> None: # type: ignore[empty-body] pass # pragma: no cover diff --git a/src/power_grid_model_io_native/_core/vnf_converter.py b/src/power_grid_model_io_native/_core/vnf_converter.py index 7f0f301..4fe48dc 100644 --- a/src/power_grid_model_io_native/_core/vnf_converter.py +++ b/src/power_grid_model_io_native/_core/vnf_converter.py @@ -32,3 +32,4 @@ def get_pgm_input_data(self): pgm_data = pgmic.get_pgm_input_data(self._pgm_vnf_converter) assert_no_error() self._serialized_data = pgm_data + return self._serialized_data diff --git a/tests/unit/test_vnf_converter.py b/tests/unit/test_vnf_converter.py index f31d3ad..c63253a 100644 --- a/tests/unit/test_vnf_converter.py +++ b/tests/unit/test_vnf_converter.py @@ -13,9 +13,16 @@ def test_pgmvnfconverter_constructor_without_experimental_features(): print(f"Raised exception: {e.type} - {e.value}") -# def test_pgmvnfconverter_constructor_with_experimental_features(): -# converter = PgmVnfConverter("", 1) -# assert converter is not None +def test_pgmvnfconverter_constructor_with_experimental_features(): + converter = PgmVnfConverter("", 1) + assert hasattr(converter, "_pgm_vnf_converter") + + +def test_get_pgm_input_data(): + converter = PgmVnfConverter("", 1) + result_buffer = converter.get_pgm_input_data() + json_output = '({"version":"1.0","type":"input","is_batch":false,"attributes":{},"data":{}})' + assert result_buffer == json_output def test_nothing(): From eec49e4c9db1af30ba1b7c2712d5d82648de1a86 Mon Sep 17 00:00:00 2001 From: Laurynas Jagutis Date: Wed, 13 Nov 2024 11:45:09 +0200 Subject: [PATCH 03/21] remove unused Signed-off-by: Laurynas Jagutis --- .../_core/power_grid_model_io_core.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/power_grid_model_io_native/_core/power_grid_model_io_core.py b/src/power_grid_model_io_native/_core/power_grid_model_io_core.py index 6f747e3..beb8ea2 100644 --- a/src/power_grid_model_io_native/_core/power_grid_model_io_core.py +++ b/src/power_grid_model_io_native/_core/power_grid_model_io_core.py @@ -26,13 +26,6 @@ class HandlePtr(c_void_p): Pointer to handle """ - -class WritableDatasetPtr(c_void_p): - """ - Pointer to writable dataset - """ - - class PgmVnfConverterPtr(c_void_p): """ Pointer to serializer From 8a06b4ccb2c6bcd9e6316b670d62ecbb4f1e433e Mon Sep 17 00:00:00 2001 From: Laurynas Jagutis Date: Wed, 13 Nov 2024 15:06:59 +0200 Subject: [PATCH 04/21] address comments, add some docstrings to fix checks Signed-off-by: Laurynas Jagutis --- .../power_grid_model_io_native_c/vnf_pgm_converter.h | 3 ++- .../src/vnf_pgm_converter.cpp | 2 +- .../_core/power_grid_model_io_core.py | 3 ++- src/power_grid_model_io_native/_core/vnf_converter.py | 10 ++++++++-- tests/unit/test_vnf_converter.py | 1 + 5 files changed, 14 insertions(+), 5 deletions(-) diff --git a/power_grid_model_io_native_c/power_grid_model_io_native_c/include/power_grid_model_io_native_c/vnf_pgm_converter.h b/power_grid_model_io_native_c/power_grid_model_io_native_c/include/power_grid_model_io_native_c/vnf_pgm_converter.h index 8d3fa21..8330b28 100644 --- a/power_grid_model_io_native_c/power_grid_model_io_native_c/include/power_grid_model_io_native_c/vnf_pgm_converter.h +++ b/power_grid_model_io_native_c/power_grid_model_io_native_c/include/power_grid_model_io_native_c/vnf_pgm_converter.h @@ -28,7 +28,8 @@ PGM_IO_API PGM_IO_VnfConverter* PGM_IO_create_vnf_converter(PGM_IO_Handle* handl * @param converter_ptr A pointer to a PGM_IO_VnfConverter instace. * @return The pointer to the json string instance that holds data in PGM format. */ -PGM_IO_API char const* PGM_IO_get_pgm_input_data(PGM_IO_Handle* handle, PGM_IO_VnfConverter* converter_ptr); +PGM_IO_API char const* PGM_IO_vnf_pgm_converter_get_input_data(PGM_IO_Handle* handle, + PGM_IO_VnfConverter* converter_ptr); /** * @brief Destroy the PGM_IO_VnfConverter and free up the memory that was dedicated to it. diff --git a/power_grid_model_io_native_c/power_grid_model_io_native_c/src/vnf_pgm_converter.cpp b/power_grid_model_io_native_c/power_grid_model_io_native_c/src/vnf_pgm_converter.cpp index 559dc83..824fa96 100644 --- a/power_grid_model_io_native_c/power_grid_model_io_native_c/src/vnf_pgm_converter.cpp +++ b/power_grid_model_io_native_c/power_grid_model_io_native_c/src/vnf_pgm_converter.cpp @@ -44,7 +44,7 @@ PGM_IO_VnfConverter* PGM_IO_create_vnf_converter(PGM_IO_Handle* handle, char con PGM_IO_regular_error); } -char const* PGM_IO_get_pgm_input_data(PGM_IO_Handle* handle, PGM_IO_VnfConverter* converter_ptr) { +char const* PGM_IO_vnf_pgm_converter_get_input_data(PGM_IO_Handle* handle, PGM_IO_VnfConverter* converter_ptr) { return call_with_catch( handle, [converter_ptr] { return convert_input_wrapper(converter_ptr).c_str(); }, PGM_IO_regular_error); } diff --git a/src/power_grid_model_io_native/_core/power_grid_model_io_core.py b/src/power_grid_model_io_native/_core/power_grid_model_io_core.py index beb8ea2..b9bddaf 100644 --- a/src/power_grid_model_io_native/_core/power_grid_model_io_core.py +++ b/src/power_grid_model_io_native/_core/power_grid_model_io_core.py @@ -26,6 +26,7 @@ class HandlePtr(c_void_p): Pointer to handle """ + class PgmVnfConverterPtr(c_void_p): """ Pointer to serializer @@ -149,7 +150,7 @@ def create_vnf_converter(self, data: str, experimental_features: int) -> PgmVnfC pass # pragma: no cover @make_c_binding - def get_pgm_input_data(self, pgmvnfconverter: PgmVnfConverterPtr) -> str: # type: ignore[empty-body] + def vnf_pgm_converter_get_input_data(self, pgmvnfconverter: PgmVnfConverterPtr) -> str: # type: ignore[empty-body] pass # pragma: no cover @make_c_binding diff --git a/src/power_grid_model_io_native/_core/vnf_converter.py b/src/power_grid_model_io_native/_core/vnf_converter.py index 4fe48dc..0e71f3a 100644 --- a/src/power_grid_model_io_native/_core/vnf_converter.py +++ b/src/power_grid_model_io_native/_core/vnf_converter.py @@ -8,6 +8,8 @@ class PgmVnfConverter: + """A converter class which will convert a given string representation of .vnf data to the PowerGridModel format""" + _pgm_vnf_converter: PgmVnfConverterPtr _serialized_data: str @@ -16,7 +18,6 @@ def __new__( string_buffer: str, experimental_feature: int, ): - instance = super().__new__(cls) instance._pgm_vnf_converter = pgmic.create_vnf_converter(string_buffer, experimental_feature) @@ -29,7 +30,12 @@ def __del__(self): pgmic.destroy_vnf_converter(self._pgm_vnf_converter) def get_pgm_input_data(self): - pgm_data = pgmic.get_pgm_input_data(self._pgm_vnf_converter) + """A function of the PgmVnfConverter class which will convert and return the data in PGM format + + Returns: + str: json data in PGM format + """ + pgm_data = pgmic.vnf_pgm_converter_get_input_data(self._pgm_vnf_converter) assert_no_error() self._serialized_data = pgm_data return self._serialized_data diff --git a/tests/unit/test_vnf_converter.py b/tests/unit/test_vnf_converter.py index c63253a..7d4b70d 100644 --- a/tests/unit/test_vnf_converter.py +++ b/tests/unit/test_vnf_converter.py @@ -8,6 +8,7 @@ def test_pgmvnfconverter_constructor_without_experimental_features(): + """_summary_""" with pytest.raises(Exception) as e: _ = PgmVnfConverter("", 0) print(f"Raised exception: {e.type} - {e.value}") From 858e02bad892005caac46d31d74b417489c86e2b Mon Sep 17 00:00:00 2001 From: Laurynas Jagutis Date: Wed, 13 Nov 2024 15:21:22 +0200 Subject: [PATCH 05/21] homogenize, add docstrings to tests Signed-off-by: Laurynas Jagutis --- .../power_grid_model_io_native_c/basics.h | 2 +- .../vnf_pgm_converter.h | 18 +++++++++--------- .../src/vnf_pgm_converter.cpp | 12 ++++++------ tests/unit/test_vnf_converter.py | 9 +++------ 4 files changed, 19 insertions(+), 22 deletions(-) diff --git a/power_grid_model_io_native_c/power_grid_model_io_native_c/include/power_grid_model_io_native_c/basics.h b/power_grid_model_io_native_c/power_grid_model_io_native_c/include/power_grid_model_io_native_c/basics.h index 209b899..d565c59 100644 --- a/power_grid_model_io_native_c/power_grid_model_io_native_c/include/power_grid_model_io_native_c/basics.h +++ b/power_grid_model_io_native_c/power_grid_model_io_native_c/include/power_grid_model_io_native_c/basics.h @@ -68,7 +68,7 @@ typedef int32_t PGM_IO_ID; * @brief Opaque struct for the VnfConverter class. * */ -typedef struct PGM_IO_VnfConverter PGM_IO_VnfConverter; +typedef struct PGM_IO_VnfPgmConverter PGM_IO_VnfPgmConverter; /** * @brief Opaque struct for the handle class. diff --git a/power_grid_model_io_native_c/power_grid_model_io_native_c/include/power_grid_model_io_native_c/vnf_pgm_converter.h b/power_grid_model_io_native_c/power_grid_model_io_native_c/include/power_grid_model_io_native_c/vnf_pgm_converter.h index 8330b28..cf72762 100644 --- a/power_grid_model_io_native_c/power_grid_model_io_native_c/include/power_grid_model_io_native_c/vnf_pgm_converter.h +++ b/power_grid_model_io_native_c/power_grid_model_io_native_c/include/power_grid_model_io_native_c/vnf_pgm_converter.h @@ -13,29 +13,29 @@ extern "C" { #endif /** - * @brief Create the PGM_IO_VnfConverter + * @brief Create the PGM_IO_VnfPgmConverter * @param handle * @param file_buffer A pointer to the null-terminated C string. - * @return The pointer to a PGM_IO_VnfConverter instance. The instance must be freed by + * @return The pointer to a PGM_IO_VnfPgmConverter instance. The instance must be freed by * PGM_IO_destroy_vnf_converter. */ -PGM_IO_API PGM_IO_VnfConverter* PGM_IO_create_vnf_converter(PGM_IO_Handle* handle, char const* file_buffer, - PGM_IO_ExperimentalFeatures experimental_features); +PGM_IO_API PGM_IO_VnfPgmConverter* PGM_IO_create_vnf_converter(PGM_IO_Handle* handle, char const* file_buffer, + PGM_IO_ExperimentalFeatures experimental_features); /** * @brief Retrieve the transformed input data from .vnf format to PGM format * @param handle - * @param converter_ptr A pointer to a PGM_IO_VnfConverter instace. + * @param converter_ptr A pointer to a PGM_IO_VnfPgmConverter instace. * @return The pointer to the json string instance that holds data in PGM format. */ PGM_IO_API char const* PGM_IO_vnf_pgm_converter_get_input_data(PGM_IO_Handle* handle, - PGM_IO_VnfConverter* converter_ptr); + PGM_IO_VnfPgmConverter* converter_ptr); /** - * @brief Destroy the PGM_IO_VnfConverter and free up the memory that was dedicated to it. - * @param converter_ptr A pointer to a PGM_IO_VnfConverter instance. + * @brief Destroy the PGM_IO_VnfPgmConverter and free up the memory that was dedicated to it. + * @param converter_ptr A pointer to a PGM_IO_VnfPgmConverter instance. */ -PGM_IO_API void PGM_IO_destroy_vnf_converter(PGM_IO_VnfConverter* converter_ptr); +PGM_IO_API void PGM_IO_destroy_vnf_converter(PGM_IO_VnfPgmConverter* converter_ptr); #ifdef __cplusplus } diff --git a/power_grid_model_io_native_c/power_grid_model_io_native_c/src/vnf_pgm_converter.cpp b/power_grid_model_io_native_c/power_grid_model_io_native_c/src/vnf_pgm_converter.cpp index 824fa96..52f3c2c 100644 --- a/power_grid_model_io_native_c/power_grid_model_io_native_c/src/vnf_pgm_converter.cpp +++ b/power_grid_model_io_native_c/power_grid_model_io_native_c/src/vnf_pgm_converter.cpp @@ -16,12 +16,12 @@ namespace pgm_io = power_grid_model_io_native; -struct PGM_IO_VnfConverter : public pgm_io::PgmVnfConverter { +struct PGM_IO_VnfPgmConverter : public pgm_io::PgmVnfConverter { using PgmVnfConverter::PgmVnfConverter; }; -PGM_IO_VnfConverter* PGM_IO_create_vnf_converter(PGM_IO_Handle* handle, char const* file_buffer, - PGM_IO_ExperimentalFeatures experimental_features) { +PGM_IO_VnfPgmConverter* PGM_IO_create_vnf_converter(PGM_IO_Handle* handle, char const* file_buffer, + PGM_IO_ExperimentalFeatures experimental_features) { return call_with_catch( handle, [file_buffer, experimental_features] { @@ -37,16 +37,16 @@ PGM_IO_VnfConverter* PGM_IO_create_vnf_converter(PGM_IO_Handle* handle, char con default: throw power_grid_model::MissingCaseForEnumError{"PGM_IO_create_vnf_converter", experimental_features}; } - auto* converter = new PGM_IO_VnfConverter(file_buffer, experimental_feature); + auto* converter = new PGM_IO_VnfPgmConverter(file_buffer, experimental_feature); parse_vnf_file_wrapper(converter); return converter; }, PGM_IO_regular_error); } -char const* PGM_IO_vnf_pgm_converter_get_input_data(PGM_IO_Handle* handle, PGM_IO_VnfConverter* converter_ptr) { +char const* PGM_IO_vnf_pgm_converter_get_input_data(PGM_IO_Handle* handle, PGM_IO_VnfPgmConverter* converter_ptr) { return call_with_catch( handle, [converter_ptr] { return convert_input_wrapper(converter_ptr).c_str(); }, PGM_IO_regular_error); } -void PGM_IO_destroy_vnf_converter(PGM_IO_VnfConverter* converter_ptr) { delete converter_ptr; } +void PGM_IO_destroy_vnf_converter(PGM_IO_VnfPgmConverter* converter_ptr) { delete converter_ptr; } diff --git a/tests/unit/test_vnf_converter.py b/tests/unit/test_vnf_converter.py index 7d4b70d..ebd7f87 100644 --- a/tests/unit/test_vnf_converter.py +++ b/tests/unit/test_vnf_converter.py @@ -8,24 +8,21 @@ def test_pgmvnfconverter_constructor_without_experimental_features(): - """_summary_""" + """A test case for creating pgmvnfconverter without experimental features""" with pytest.raises(Exception) as e: _ = PgmVnfConverter("", 0) print(f"Raised exception: {e.type} - {e.value}") def test_pgmvnfconverter_constructor_with_experimental_features(): + """A test case for creating pgmvnfconverter with experimental features""" converter = PgmVnfConverter("", 1) assert hasattr(converter, "_pgm_vnf_converter") def test_get_pgm_input_data(): + """A test case for obtaining the data in PGM format from pgmvnfconverter""" converter = PgmVnfConverter("", 1) result_buffer = converter.get_pgm_input_data() json_output = '({"version":"1.0","type":"input","is_batch":false,"attributes":{},"data":{}})' assert result_buffer == json_output - - -def test_nothing(): - assert pgm_io_core.error_code() == 0 - assert pgm_io_core.error_message() == "" From 1d45cdaad5a9937707f09193f0a1d10c34c1624d Mon Sep 17 00:00:00 2001 From: Laurynas Jagutis Date: Wed, 13 Nov 2024 15:58:20 +0200 Subject: [PATCH 06/21] fix some github checks Signed-off-by: Laurynas Jagutis --- .../_core/power_grid_model_io_core.py | 6 ++++-- src/power_grid_model_io_native/_core/vnf_converter.py | 4 ++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/power_grid_model_io_native/_core/power_grid_model_io_core.py b/src/power_grid_model_io_native/_core/power_grid_model_io_core.py index b9bddaf..a6d4ffc 100644 --- a/src/power_grid_model_io_native/_core/power_grid_model_io_core.py +++ b/src/power_grid_model_io_native/_core/power_grid_model_io_core.py @@ -29,7 +29,7 @@ class HandlePtr(c_void_p): class PgmVnfConverterPtr(c_void_p): """ - Pointer to serializer + Pointer to PgmVnfConverter """ @@ -146,7 +146,9 @@ def error_message(self) -> str: # type: ignore[empty-body] pass # pragma: no cover @make_c_binding - def create_vnf_converter(self, data: str, experimental_features: int) -> PgmVnfConverterPtr: # type: ignore[empty-body] + def create_vnf_converter( + self, data: str, experimental_features: int + ) -> PgmVnfConverterPtr: # type: ignore[empty-body] pass # pragma: no cover @make_c_binding diff --git a/src/power_grid_model_io_native/_core/vnf_converter.py b/src/power_grid_model_io_native/_core/vnf_converter.py index 0e71f3a..a24bff5 100644 --- a/src/power_grid_model_io_native/_core/vnf_converter.py +++ b/src/power_grid_model_io_native/_core/vnf_converter.py @@ -2,6 +2,10 @@ # # SPDX-License-Identifier: MPL-2.0 +""" +Power grid model io native converter for vnf files +""" + from power_grid_model.core.error_handling import assert_no_error from power_grid_model_io_native._core.power_grid_model_io_core import PgmVnfConverterPtr, pgm_io_core as pgmic From d1d891970c2848d085b81cc2b5810f6a41699d68 Mon Sep 17 00:00:00 2001 From: Laurynas Jagutis Date: Wed, 13 Nov 2024 16:35:33 +0200 Subject: [PATCH 07/21] setup chnage Signed-off-by: Laurynas Jagutis --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 03927ce..30b9f6d 100644 --- a/setup.py +++ b/setup.py @@ -213,7 +213,7 @@ def generate_build_ext(pkg_dir: Path, pkg_name: str): # list of extensions exts = [ CTypesExtension( - name="power_grid_model_io_native._core._power_grid_model_io_core", + name="power_grid_model_io_native._core.power_grid_model_io_core", sources=sources, include_dirs=include_dirs, library_dirs=library_dirs, From a8838e6de06d7d4c8aeb4d838e2551101b20e937 Mon Sep 17 00:00:00 2001 From: Laurynas Jagutis Date: Wed, 13 Nov 2024 16:53:39 +0200 Subject: [PATCH 08/21] manual reformat Signed-off-by: Laurynas Jagutis --- .../_core/power_grid_model_io_core.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/power_grid_model_io_native/_core/power_grid_model_io_core.py b/src/power_grid_model_io_native/_core/power_grid_model_io_core.py index a6d4ffc..2f5d949 100644 --- a/src/power_grid_model_io_native/_core/power_grid_model_io_core.py +++ b/src/power_grid_model_io_native/_core/power_grid_model_io_core.py @@ -147,7 +147,9 @@ def error_message(self) -> str: # type: ignore[empty-body] @make_c_binding def create_vnf_converter( - self, data: str, experimental_features: int + self, + data: str, + experimental_features: int ) -> PgmVnfConverterPtr: # type: ignore[empty-body] pass # pragma: no cover From c8308e895f9e6f92dcc6fc80e0a60171019da424 Mon Sep 17 00:00:00 2001 From: Laurynas Jagutis Date: Wed, 13 Nov 2024 16:58:07 +0200 Subject: [PATCH 09/21] revert Signed-off-by: Laurynas Jagutis --- .../_core/power_grid_model_io_core.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/power_grid_model_io_native/_core/power_grid_model_io_core.py b/src/power_grid_model_io_native/_core/power_grid_model_io_core.py index 2f5d949..a6d4ffc 100644 --- a/src/power_grid_model_io_native/_core/power_grid_model_io_core.py +++ b/src/power_grid_model_io_native/_core/power_grid_model_io_core.py @@ -147,9 +147,7 @@ def error_message(self) -> str: # type: ignore[empty-body] @make_c_binding def create_vnf_converter( - self, - data: str, - experimental_features: int + self, data: str, experimental_features: int ) -> PgmVnfConverterPtr: # type: ignore[empty-body] pass # pragma: no cover From a9d402428317943177d690dac44ea409935721fa Mon Sep 17 00:00:00 2001 From: Laurynas Jagutis Date: Mon, 18 Nov 2024 13:51:51 +0100 Subject: [PATCH 10/21] change import Signed-off-by: Laurynas Jagutis --- tests/unit/test_vnf_converter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/test_vnf_converter.py b/tests/unit/test_vnf_converter.py index ebd7f87..c9a4941 100644 --- a/tests/unit/test_vnf_converter.py +++ b/tests/unit/test_vnf_converter.py @@ -3,7 +3,7 @@ # SPDX-License-Identifier: MPL-2.0 import pytest -from power_grid_model_io_native._core.power_grid_model_io_core import pgm_io_core +# from power_grid_model_io_native._core.power_grid_model_io_core import pgm_io_core from power_grid_model_io_native._core.vnf_converter import PgmVnfConverter From a15b6dfa94b5117c78bc5cf65abfb77e11ca434c Mon Sep 17 00:00:00 2001 From: Laurynas Jagutis Date: Mon, 18 Nov 2024 16:05:15 +0100 Subject: [PATCH 11/21] update submodule Signed-off-by: Laurynas Jagutis --- deps/power-grid-model | 2 +- tests/unit/test_vnf_converter.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/deps/power-grid-model b/deps/power-grid-model index a05b88a..e284632 160000 --- a/deps/power-grid-model +++ b/deps/power-grid-model @@ -1 +1 @@ -Subproject commit a05b88a326583ecfad5bd72d5a2f99ae352d1907 +Subproject commit e284632006accd9d72ebdefca5c1cc77f1f3f1b5 diff --git a/tests/unit/test_vnf_converter.py b/tests/unit/test_vnf_converter.py index c9a4941..e43d846 100644 --- a/tests/unit/test_vnf_converter.py +++ b/tests/unit/test_vnf_converter.py @@ -1,9 +1,9 @@ # SPDX-FileCopyrightText: Contributors to the Power Grid Model project # # SPDX-License-Identifier: MPL-2.0 + import pytest -# from power_grid_model_io_native._core.power_grid_model_io_core import pgm_io_core from power_grid_model_io_native._core.vnf_converter import PgmVnfConverter From 87f851d519533e17dc682bb8d2046e6a16398e75 Mon Sep 17 00:00:00 2001 From: Laurynas Jagutis Date: Tue, 19 Nov 2024 16:16:25 +0100 Subject: [PATCH 12/21] wip Signed-off-by: Laurynas Jagutis --- setup.py | 1 + .../_core/power_grid_model_io_core.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 30b9f6d..9b523cb 100644 --- a/setup.py +++ b/setup.py @@ -178,6 +178,7 @@ def generate_build_ext(pkg_dir: Path, pkg_name: str): libraries: list[str] = [] sources = [ str(pgm_io_c / pgm_io_c / "src" / "handle.cpp"), + str(pgm_io_c / pgm_io_c / "src" / "vnf_pgm_converter.cpp"), ] # macro define_macros = [ diff --git a/src/power_grid_model_io_native/_core/power_grid_model_io_core.py b/src/power_grid_model_io_native/_core/power_grid_model_io_core.py index 34bb783..2679702 100644 --- a/src/power_grid_model_io_native/_core/power_grid_model_io_core.py +++ b/src/power_grid_model_io_native/_core/power_grid_model_io_core.py @@ -40,9 +40,9 @@ def _load_core() -> CDLL: """ if platform.system() == "Windows": - dll_file = "_power_grid_model_io_core.dll" + dll_file = "power_grid_model_io_core.dll" else: - dll_file = "_power_grid_model_io_core.so" + dll_file = "power_grid_model_io_core.so" cdll = CDLL(str(Path(__file__).parent / dll_file)) # assign return types # handle From d26169be4c4f4499cff96e95b177f8d765f21788 Mon Sep 17 00:00:00 2001 From: Laurynas Jagutis Date: Mon, 2 Dec 2024 13:11:58 +0100 Subject: [PATCH 13/21] adjust naming of a test Signed-off-by: Laurynas Jagutis --- tests/c_api_tests/test_c_api_vnf_converter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/c_api_tests/test_c_api_vnf_converter.cpp b/tests/c_api_tests/test_c_api_vnf_converter.cpp index 00ac5a4..d7d14be 100644 --- a/tests/c_api_tests/test_c_api_vnf_converter.cpp +++ b/tests/c_api_tests/test_c_api_vnf_converter.cpp @@ -45,7 +45,7 @@ TEST_CASE("Test PGM_IO_get_vnf_input_data") { auto converter = PGM_IO_create_vnf_converter(handle, "", experimental_feature_flag); CHECK(converter != nullptr); - auto json_result = PGM_IO_get_vnf_input_data(handle, converter); + auto json_result = PGM_IO_vnf_pgm_converter_get_input_data(handle, converter); std::string_view json_string = R"({"version":"1.0","type":"input","is_batch":false,"attributes":{},"data":{}})"; CHECK(json_string == json_result); From 0673fc6d73f37eb276f7d6a7ce0ef1ac6829c955 Mon Sep 17 00:00:00 2001 From: Laurynas Jagutis Date: Mon, 2 Dec 2024 13:19:03 +0100 Subject: [PATCH 14/21] shorten signature of a function Signed-off-by: Laurynas Jagutis --- .../_core/power_grid_model_io_core.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/power_grid_model_io_native/_core/power_grid_model_io_core.py b/src/power_grid_model_io_native/_core/power_grid_model_io_core.py index 2679702..1bc1fb7 100644 --- a/src/power_grid_model_io_native/_core/power_grid_model_io_core.py +++ b/src/power_grid_model_io_native/_core/power_grid_model_io_core.py @@ -146,9 +146,7 @@ def error_message(self) -> str: # type: ignore[empty-body] pass # pragma: no cover @make_c_binding - def create_vnf_converter( - self, data: str, experimental_features: int - ) -> PgmVnfConverterPtr: # type: ignore[empty-body] + def create_vnf_converter(self, data: str, experim_feature: int) -> PgmVnfConverterPtr: # type: ignore[empty-body] pass # pragma: no cover @make_c_binding From 9c2a7b94737d35e6e08ecdd489fe9eaa1a0aa43d Mon Sep 17 00:00:00 2001 From: Laurynas Jagutis Date: Mon, 2 Dec 2024 13:55:56 +0100 Subject: [PATCH 15/21] adjust test and imports Signed-off-by: Laurynas Jagutis --- src/power_grid_model_io_native/_core/vnf_converter.py | 2 +- tests/unit/test_vnf_converter.py | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/power_grid_model_io_native/_core/vnf_converter.py b/src/power_grid_model_io_native/_core/vnf_converter.py index a24bff5..75f1910 100644 --- a/src/power_grid_model_io_native/_core/vnf_converter.py +++ b/src/power_grid_model_io_native/_core/vnf_converter.py @@ -6,7 +6,7 @@ Power grid model io native converter for vnf files """ -from power_grid_model.core.error_handling import assert_no_error +from power_grid_model._core.error_handling import assert_no_error from power_grid_model_io_native._core.power_grid_model_io_core import PgmVnfConverterPtr, pgm_io_core as pgmic diff --git a/tests/unit/test_vnf_converter.py b/tests/unit/test_vnf_converter.py index e43d846..9985613 100644 --- a/tests/unit/test_vnf_converter.py +++ b/tests/unit/test_vnf_converter.py @@ -9,9 +9,8 @@ def test_pgmvnfconverter_constructor_without_experimental_features(): """A test case for creating pgmvnfconverter without experimental features""" - with pytest.raises(Exception) as e: - _ = PgmVnfConverter("", 0) - print(f"Raised exception: {e.type} - {e.value}") + converter = PgmVnfConverter("", 0) + assert not hasattr(converter, "_pgm_vnf_converter") def test_pgmvnfconverter_constructor_with_experimental_features(): @@ -24,5 +23,5 @@ def test_get_pgm_input_data(): """A test case for obtaining the data in PGM format from pgmvnfconverter""" converter = PgmVnfConverter("", 1) result_buffer = converter.get_pgm_input_data() - json_output = '({"version":"1.0","type":"input","is_batch":false,"attributes":{},"data":{}})' + json_output = '{"version":"1.0","type":"input","is_batch":false,"attributes":{},"data":{}}' assert result_buffer == json_output From 0e6f92a5923f91516cf3bca7e74a8da03f0cd550 Mon Sep 17 00:00:00 2001 From: Laurynas Jagutis Date: Mon, 2 Dec 2024 16:39:11 +0100 Subject: [PATCH 16/21] adjust tests and add init file next to the tests Signed-off-by: Laurynas Jagutis --- tests/unit/__init__.py | 3 +++ tests/unit/test_vnf_converter.py | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 tests/unit/__init__.py diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py new file mode 100644 index 0000000..1296dc4 --- /dev/null +++ b/tests/unit/__init__.py @@ -0,0 +1,3 @@ +# SPDX-FileCopyrightText: Contributors to the Power Grid Model project +# +# SPDX-License-Identifier: MPL-2.0 diff --git a/tests/unit/test_vnf_converter.py b/tests/unit/test_vnf_converter.py index 9985613..c538477 100644 --- a/tests/unit/test_vnf_converter.py +++ b/tests/unit/test_vnf_converter.py @@ -10,13 +10,14 @@ def test_pgmvnfconverter_constructor_without_experimental_features(): """A test case for creating pgmvnfconverter without experimental features""" converter = PgmVnfConverter("", 0) - assert not hasattr(converter, "_pgm_vnf_converter") + with pytest.raises(OSError): + _ = converter.get_pgm_input_data() def test_pgmvnfconverter_constructor_with_experimental_features(): """A test case for creating pgmvnfconverter with experimental features""" converter = PgmVnfConverter("", 1) - assert hasattr(converter, "_pgm_vnf_converter") + result_buffer = converter.get_pgm_input_data() def test_get_pgm_input_data(): From cea5ff5c7db07f45e2ac0cce5985c2fa045eaf8b Mon Sep 17 00:00:00 2001 From: Laurynas Jagutis Date: Mon, 2 Dec 2024 17:15:47 +0100 Subject: [PATCH 17/21] adjust test Signed-off-by: Laurynas Jagutis --- tests/unit/test_vnf_converter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/test_vnf_converter.py b/tests/unit/test_vnf_converter.py index c538477..1d8685b 100644 --- a/tests/unit/test_vnf_converter.py +++ b/tests/unit/test_vnf_converter.py @@ -17,7 +17,7 @@ def test_pgmvnfconverter_constructor_without_experimental_features(): def test_pgmvnfconverter_constructor_with_experimental_features(): """A test case for creating pgmvnfconverter with experimental features""" converter = PgmVnfConverter("", 1) - result_buffer = converter.get_pgm_input_data() + _ = converter.get_pgm_input_data() def test_get_pgm_input_data(): From 8b5ba14ae8d6e382e5d3cd56e54e45c175b54be8 Mon Sep 17 00:00:00 2001 From: Laurynas Jagutis Date: Tue, 3 Dec 2024 09:03:12 +0100 Subject: [PATCH 18/21] add __init__.py in test folder Signed-off-by: Laurynas Jagutis --- tests/__init__.py | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 tests/__init__.py diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..1296dc4 --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1,3 @@ +# SPDX-FileCopyrightText: Contributors to the Power Grid Model project +# +# SPDX-License-Identifier: MPL-2.0 From 06e04f1277f64bc7adb35d9c07d47f71376d5834 Mon Sep 17 00:00:00 2001 From: Laurynas Jagutis Date: Tue, 3 Dec 2024 11:28:56 +0100 Subject: [PATCH 19/21] add error handling, finalize tests Signed-off-by: Laurynas Jagutis --- setup.py | 2 +- .../_core/error_handling.py | 187 ++++++++++++++++++ .../_core/power_grid_model_io_core.py | 10 +- .../_core/vnf_converter.py | 3 +- tests/unit/test_vnf_converter.py | 10 +- 5 files changed, 199 insertions(+), 13 deletions(-) create mode 100644 src/power_grid_model_io_native/_core/error_handling.py diff --git a/setup.py b/setup.py index 9b523cb..f52707d 100644 --- a/setup.py +++ b/setup.py @@ -214,7 +214,7 @@ def generate_build_ext(pkg_dir: Path, pkg_name: str): # list of extensions exts = [ CTypesExtension( - name="power_grid_model_io_native._core.power_grid_model_io_core", + name="power_grid_model_io_native._core._power_grid_model_io_core", sources=sources, include_dirs=include_dirs, library_dirs=library_dirs, diff --git a/src/power_grid_model_io_native/_core/error_handling.py b/src/power_grid_model_io_native/_core/error_handling.py new file mode 100644 index 0000000..1073081 --- /dev/null +++ b/src/power_grid_model_io_native/_core/error_handling.py @@ -0,0 +1,187 @@ +# SPDX-FileCopyrightText: Contributors to the Power Grid Model project +# +# SPDX-License-Identifier: MPL-2.0 + +""" +Error handling +""" + +import re + +from power_grid_model.errors import ( + AutomaticTapCalculationError, + ConflictID, + ConflictVoltage, + IDNotFound, + IDWrongType, + InvalidArguments, + InvalidBranch, + InvalidBranch3, + InvalidCalculationMethod, + InvalidMeasuredObject, + InvalidRegulatedObject, + InvalidShortCircuitPhaseOrType, + InvalidTransformerClock, + IterationDiverge, + MaxIterationReached, + MissingCaseForEnumError, + NotObservableError, + PowerGridBatchError, + PowerGridDatasetError, + PowerGridError, + PowerGridNotImplementedError, + PowerGridSerializationError, + PowerGridUnreachableHitError, + SparseMatrixError, +) + +from power_grid_model_io_native._core.power_grid_model_io_core import pgm_io_core as pgmic + +VALIDATOR_MSG = "\nTry validate_input_data() or validate_batch_data() to validate your data.\n" +# error codes +PGM_NO_ERROR = 0 +PGM_REGULAR_ERROR = 1 +PGM_BATCH_ERROR = 2 +PGM_SERIALIZATION_ERROR = 3 + +_MISSING_CASE_FOR_ENUM_RE = re.compile(r" is not implemented for (.+) #(-?\d+)!\n") +_INVALID_ARGUMENTS_RE = re.compile(r" is not implemented for ") # multiple different flavors +_CONFLICT_VOLTAGE_RE = re.compile( + r"Conflicting voltage for line (-?\d+)\n voltage at from node (-?\d+) is (.*)\n" + r" voltage at to node (-?\d+) is (.*)\n" +) +_INVALID_BRANCH_RE = re.compile(r"Branch (-?\d+) has the same from- and to-node (-?\d+),\n This is not allowed!\n") +_INVALID_BRANCH3_RE = re.compile( + r"Branch3 (-?\d+) is connected to the same node at least twice. Node 1\/2\/3: (-?\d+)\/(-?\d+)\/(-?\d+),\n" + r" This is not allowed!\n" +) +_INVALID_TRANSFORMER_CLOCK_RE = re.compile(r"Invalid clock for transformer (-?\d+), clock (-?\d+)\n") +_SPARSE_MATRIX_ERROR_RE = re.compile(r"Sparse matrix error") # multiple different flavors +_NOT_OBSERVABLE_ERROR_RE = re.compile(r"Not enough measurements available for state estimation.\n") +_ITERATION_DIVERGE_RE = re.compile(r"Iteration failed to converge") # potentially multiple different flavors +_MAX_ITERATION_REACHED_RE = re.compile(r"Maximum number of iterations reached") +_CONFLICT_ID_RE = re.compile(r"Conflicting id detected: (-?\d+)\n") +_ID_NOT_FOUND_RE = re.compile(r"The id cannot be found: (-?\d+)\n") +_INVALID_MEASURED_OBJECT_RE = re.compile(r"(\w+) measurement is not supported for object of type (\w+)") +_INVALID_REGULATED_OBJECT_RE = re.compile( + r"(\w+) regulator is not supported for object " +) # potentially multiple different flavors +_AUTOMATIC_TAP_CALCULATION_ERROR_RE = re.compile( + r"Automatic tap changing regulator with tap_side at LV side is not supported. Found at id (-?\d+)\n" +) +_ID_WRONG_TYPE_RE = re.compile(r"Wrong type for object with id (-?\d+)\n") +_INVALID_CALCULATION_METHOD_RE = re.compile(r"The calculation method is invalid for this calculation!") +_INVALID_SHORT_CIRCUIT_PHASE_OR_TYPE_RE = re.compile(r"short circuit type") # multiple different flavors +_POWER_GRID_DATASET_ERROR_RE = re.compile(r"Dataset error: ") # multiple different flavors +_POWER_GRID_UNREACHABLE_HIT_RE = re.compile(r"Unreachable code hit when executing ") # multiple different flavors +_POWER_GRID_SEARCH_OPT_INCMPT_RE = re.compile(r"Search method is incompatible with optimization strategy: ") +_POWER_GRID_NOT_IMPLEMENTED_ERROR_RE = re.compile(r"The functionality is either not supported or not yet implemented!") + +_ERROR_MESSAGE_PATTERNS = { + _MISSING_CASE_FOR_ENUM_RE: MissingCaseForEnumError, + _INVALID_ARGUMENTS_RE: InvalidArguments, + _CONFLICT_VOLTAGE_RE: ConflictVoltage, + _INVALID_BRANCH_RE: InvalidBranch, + _INVALID_BRANCH3_RE: InvalidBranch3, + _INVALID_TRANSFORMER_CLOCK_RE: InvalidTransformerClock, + _SPARSE_MATRIX_ERROR_RE: SparseMatrixError, + _NOT_OBSERVABLE_ERROR_RE: NotObservableError, + _ITERATION_DIVERGE_RE: IterationDiverge, + _MAX_ITERATION_REACHED_RE: MaxIterationReached, + _CONFLICT_ID_RE: ConflictID, + _ID_NOT_FOUND_RE: IDNotFound, + _INVALID_MEASURED_OBJECT_RE: InvalidMeasuredObject, + _INVALID_REGULATED_OBJECT_RE: InvalidRegulatedObject, + _AUTOMATIC_TAP_CALCULATION_ERROR_RE: AutomaticTapCalculationError, + _ID_WRONG_TYPE_RE: IDWrongType, + _INVALID_CALCULATION_METHOD_RE: InvalidCalculationMethod, + _INVALID_SHORT_CIRCUIT_PHASE_OR_TYPE_RE: InvalidShortCircuitPhaseOrType, + _POWER_GRID_DATASET_ERROR_RE: PowerGridDatasetError, + _POWER_GRID_UNREACHABLE_HIT_RE: PowerGridUnreachableHitError, + _POWER_GRID_SEARCH_OPT_INCMPT_RE: PowerGridUnreachableHitError, + _POWER_GRID_NOT_IMPLEMENTED_ERROR_RE: PowerGridNotImplementedError, +} + + +def _interpret_error(message: str, decode_error: bool = True) -> PowerGridError: + if decode_error: + for pattern, type_ in _ERROR_MESSAGE_PATTERNS.items(): + if pattern.search(message) is not None: + return type_(message) + + return PowerGridError(message) + + +def find_error(batch_size: int = 1, decode_error: bool = True) -> RuntimeError | None: + """ + Check if there is an error and return it + + Args: + batch_size: (int, optional): Size of batch. Defaults to 1. + decode_error (bool, optional): Decode the error message(s) to derived error classes. Defaults to True + + Returns: error object, can be none + + """ + error_code: int = pgmic.error_code() + if error_code == PGM_NO_ERROR: + return None + if error_code == PGM_REGULAR_ERROR: + error_message = pgmic.error_message() + error_message += VALIDATOR_MSG + return _interpret_error(error_message, decode_error=decode_error) + if error_code == PGM_BATCH_ERROR: + _ = batch_size + error_message = "There are errors in the batch calculation." + VALIDATOR_MSG + error = PowerGridBatchError(error_message) + return error + if error_code == PGM_SERIALIZATION_ERROR: + return PowerGridSerializationError(pgmic.error_message()) + return RuntimeError("Unknown error!") + + +def assert_no_error(batch_size: int = 1, decode_error: bool = True): + """ + Assert there is no error in the last operation + If there is an error, raise it + + Args: + batch_size (int, optional): Size of batch. Defaults to 1. + decode_error (bool, optional): Decode the error message(s) to derived error classes. Defaults to True + + Returns: + + """ + error = find_error(batch_size=batch_size, decode_error=decode_error) + if error is not None: + raise error + + +def handle_errors( + continue_on_batch_error: bool, batch_size: int = 1, decode_error: bool = True +) -> PowerGridBatchError | None: + """ + Handle any errors in the way that is specified. + + Args: + continue_on_batch_error (bool): Return the error when the error type is a batch error instead of reraising it. + batch_size (int, optional): Size of batch. Defaults to 1. + decode_error (bool, optional): Decode the error message(s) to derived error classes. Defaults to True + + Raises: + error: Any errors previously encountered, unless it was a batch error and continue_on_batch_error was True. + + Returns: + PowerGridBatchError | None: None if there were no errors, or the previously encountered + error if it was a batch error and continue_on_batch_error was True. + """ + error: RuntimeError | None = find_error(batch_size=batch_size, decode_error=decode_error) + if error is None: + return None + + if continue_on_batch_error and isinstance(error, PowerGridBatchError): + # continue on batch error + return error + + # raise normal error + raise error diff --git a/src/power_grid_model_io_native/_core/power_grid_model_io_core.py b/src/power_grid_model_io_native/_core/power_grid_model_io_core.py index 1bc1fb7..920360b 100644 --- a/src/power_grid_model_io_native/_core/power_grid_model_io_core.py +++ b/src/power_grid_model_io_native/_core/power_grid_model_io_core.py @@ -9,7 +9,7 @@ from inspect import signature from itertools import chain from pathlib import Path -from typing import Callable, Optional +from typing import Callable from power_grid_model._core.power_grid_core import CharPtr, CStr, IdxC @@ -40,9 +40,9 @@ def _load_core() -> CDLL: """ if platform.system() == "Windows": - dll_file = "power_grid_model_io_core.dll" + dll_file = "_power_grid_model_io_core.dll" else: - dll_file = "power_grid_model_io_core.so" + dll_file = "_power_grid_model_io_core.so" cdll = CDLL(str(Path(__file__).parent / dll_file)) # assign return types # handle @@ -118,9 +118,9 @@ class PowerGridModelIoCore: """ _handle: HandlePtr - _instance: Optional["PowerGridModelIoCore"] = None + _instance: "PowerGridModelIoCore | None" = None - # singleton of power grid core + # singleton of power grid model io core def __new__(cls, *args, **kwargs): if cls._instance is None: cls._instance = super().__new__(cls, *args, **kwargs) diff --git a/src/power_grid_model_io_native/_core/vnf_converter.py b/src/power_grid_model_io_native/_core/vnf_converter.py index 75f1910..17b4337 100644 --- a/src/power_grid_model_io_native/_core/vnf_converter.py +++ b/src/power_grid_model_io_native/_core/vnf_converter.py @@ -6,8 +6,7 @@ Power grid model io native converter for vnf files """ -from power_grid_model._core.error_handling import assert_no_error - +from power_grid_model_io_native._core.error_handling import assert_no_error from power_grid_model_io_native._core.power_grid_model_io_core import PgmVnfConverterPtr, pgm_io_core as pgmic diff --git a/tests/unit/test_vnf_converter.py b/tests/unit/test_vnf_converter.py index 1d8685b..140c9d2 100644 --- a/tests/unit/test_vnf_converter.py +++ b/tests/unit/test_vnf_converter.py @@ -4,20 +4,20 @@ import pytest +from power_grid_model_io_native._core.error_handling import InvalidArguments, assert_no_error from power_grid_model_io_native._core.vnf_converter import PgmVnfConverter def test_pgmvnfconverter_constructor_without_experimental_features(): """A test case for creating pgmvnfconverter without experimental features""" - converter = PgmVnfConverter("", 0) - with pytest.raises(OSError): - _ = converter.get_pgm_input_data() + with pytest.raises(InvalidArguments): + _ = PgmVnfConverter("", 0) def test_pgmvnfconverter_constructor_with_experimental_features(): """A test case for creating pgmvnfconverter with experimental features""" - converter = PgmVnfConverter("", 1) - _ = converter.get_pgm_input_data() + _ = PgmVnfConverter("", 1) + assert_no_error() def test_get_pgm_input_data(): From 44579e1b1e5dabde6c5c15bc1a716e03d83dce82 Mon Sep 17 00:00:00 2001 From: Laurynas Jagutis Date: Tue, 3 Dec 2024 17:25:05 +0100 Subject: [PATCH 20/21] change error imports Signed-off-by: Laurynas Jagutis --- .../_core/error_handling.py | 101 ++---------------- tests/unit/test_vnf_converter.py | 3 +- 2 files changed, 9 insertions(+), 95 deletions(-) diff --git a/src/power_grid_model_io_native/_core/error_handling.py b/src/power_grid_model_io_native/_core/error_handling.py index 1073081..d110590 100644 --- a/src/power_grid_model_io_native/_core/error_handling.py +++ b/src/power_grid_model_io_native/_core/error_handling.py @@ -6,102 +6,19 @@ Error handling """ -import re - -from power_grid_model.errors import ( - AutomaticTapCalculationError, - ConflictID, - ConflictVoltage, - IDNotFound, - IDWrongType, - InvalidArguments, - InvalidBranch, - InvalidBranch3, - InvalidCalculationMethod, - InvalidMeasuredObject, - InvalidRegulatedObject, - InvalidShortCircuitPhaseOrType, - InvalidTransformerClock, - IterationDiverge, - MaxIterationReached, - MissingCaseForEnumError, - NotObservableError, +from power_grid_model._core.error_handling import ( + _ERROR_MESSAGE_PATTERNS, + PGM_NO_ERROR, + PGM_REGULAR_ERROR, + PGM_SERIALIZATION_ERROR, + VALIDATOR_MSG, PowerGridBatchError, - PowerGridDatasetError, PowerGridError, - PowerGridNotImplementedError, PowerGridSerializationError, - PowerGridUnreachableHitError, - SparseMatrixError, ) from power_grid_model_io_native._core.power_grid_model_io_core import pgm_io_core as pgmic -VALIDATOR_MSG = "\nTry validate_input_data() or validate_batch_data() to validate your data.\n" -# error codes -PGM_NO_ERROR = 0 -PGM_REGULAR_ERROR = 1 -PGM_BATCH_ERROR = 2 -PGM_SERIALIZATION_ERROR = 3 - -_MISSING_CASE_FOR_ENUM_RE = re.compile(r" is not implemented for (.+) #(-?\d+)!\n") -_INVALID_ARGUMENTS_RE = re.compile(r" is not implemented for ") # multiple different flavors -_CONFLICT_VOLTAGE_RE = re.compile( - r"Conflicting voltage for line (-?\d+)\n voltage at from node (-?\d+) is (.*)\n" - r" voltage at to node (-?\d+) is (.*)\n" -) -_INVALID_BRANCH_RE = re.compile(r"Branch (-?\d+) has the same from- and to-node (-?\d+),\n This is not allowed!\n") -_INVALID_BRANCH3_RE = re.compile( - r"Branch3 (-?\d+) is connected to the same node at least twice. Node 1\/2\/3: (-?\d+)\/(-?\d+)\/(-?\d+),\n" - r" This is not allowed!\n" -) -_INVALID_TRANSFORMER_CLOCK_RE = re.compile(r"Invalid clock for transformer (-?\d+), clock (-?\d+)\n") -_SPARSE_MATRIX_ERROR_RE = re.compile(r"Sparse matrix error") # multiple different flavors -_NOT_OBSERVABLE_ERROR_RE = re.compile(r"Not enough measurements available for state estimation.\n") -_ITERATION_DIVERGE_RE = re.compile(r"Iteration failed to converge") # potentially multiple different flavors -_MAX_ITERATION_REACHED_RE = re.compile(r"Maximum number of iterations reached") -_CONFLICT_ID_RE = re.compile(r"Conflicting id detected: (-?\d+)\n") -_ID_NOT_FOUND_RE = re.compile(r"The id cannot be found: (-?\d+)\n") -_INVALID_MEASURED_OBJECT_RE = re.compile(r"(\w+) measurement is not supported for object of type (\w+)") -_INVALID_REGULATED_OBJECT_RE = re.compile( - r"(\w+) regulator is not supported for object " -) # potentially multiple different flavors -_AUTOMATIC_TAP_CALCULATION_ERROR_RE = re.compile( - r"Automatic tap changing regulator with tap_side at LV side is not supported. Found at id (-?\d+)\n" -) -_ID_WRONG_TYPE_RE = re.compile(r"Wrong type for object with id (-?\d+)\n") -_INVALID_CALCULATION_METHOD_RE = re.compile(r"The calculation method is invalid for this calculation!") -_INVALID_SHORT_CIRCUIT_PHASE_OR_TYPE_RE = re.compile(r"short circuit type") # multiple different flavors -_POWER_GRID_DATASET_ERROR_RE = re.compile(r"Dataset error: ") # multiple different flavors -_POWER_GRID_UNREACHABLE_HIT_RE = re.compile(r"Unreachable code hit when executing ") # multiple different flavors -_POWER_GRID_SEARCH_OPT_INCMPT_RE = re.compile(r"Search method is incompatible with optimization strategy: ") -_POWER_GRID_NOT_IMPLEMENTED_ERROR_RE = re.compile(r"The functionality is either not supported or not yet implemented!") - -_ERROR_MESSAGE_PATTERNS = { - _MISSING_CASE_FOR_ENUM_RE: MissingCaseForEnumError, - _INVALID_ARGUMENTS_RE: InvalidArguments, - _CONFLICT_VOLTAGE_RE: ConflictVoltage, - _INVALID_BRANCH_RE: InvalidBranch, - _INVALID_BRANCH3_RE: InvalidBranch3, - _INVALID_TRANSFORMER_CLOCK_RE: InvalidTransformerClock, - _SPARSE_MATRIX_ERROR_RE: SparseMatrixError, - _NOT_OBSERVABLE_ERROR_RE: NotObservableError, - _ITERATION_DIVERGE_RE: IterationDiverge, - _MAX_ITERATION_REACHED_RE: MaxIterationReached, - _CONFLICT_ID_RE: ConflictID, - _ID_NOT_FOUND_RE: IDNotFound, - _INVALID_MEASURED_OBJECT_RE: InvalidMeasuredObject, - _INVALID_REGULATED_OBJECT_RE: InvalidRegulatedObject, - _AUTOMATIC_TAP_CALCULATION_ERROR_RE: AutomaticTapCalculationError, - _ID_WRONG_TYPE_RE: IDWrongType, - _INVALID_CALCULATION_METHOD_RE: InvalidCalculationMethod, - _INVALID_SHORT_CIRCUIT_PHASE_OR_TYPE_RE: InvalidShortCircuitPhaseOrType, - _POWER_GRID_DATASET_ERROR_RE: PowerGridDatasetError, - _POWER_GRID_UNREACHABLE_HIT_RE: PowerGridUnreachableHitError, - _POWER_GRID_SEARCH_OPT_INCMPT_RE: PowerGridUnreachableHitError, - _POWER_GRID_NOT_IMPLEMENTED_ERROR_RE: PowerGridNotImplementedError, -} - def _interpret_error(message: str, decode_error: bool = True) -> PowerGridError: if decode_error: @@ -123,6 +40,7 @@ def find_error(batch_size: int = 1, decode_error: bool = True) -> RuntimeError | Returns: error object, can be none """ + _ = batch_size error_code: int = pgmic.error_code() if error_code == PGM_NO_ERROR: return None @@ -130,11 +48,6 @@ def find_error(batch_size: int = 1, decode_error: bool = True) -> RuntimeError | error_message = pgmic.error_message() error_message += VALIDATOR_MSG return _interpret_error(error_message, decode_error=decode_error) - if error_code == PGM_BATCH_ERROR: - _ = batch_size - error_message = "There are errors in the batch calculation." + VALIDATOR_MSG - error = PowerGridBatchError(error_message) - return error if error_code == PGM_SERIALIZATION_ERROR: return PowerGridSerializationError(pgmic.error_message()) return RuntimeError("Unknown error!") diff --git a/tests/unit/test_vnf_converter.py b/tests/unit/test_vnf_converter.py index 140c9d2..ff9fddc 100644 --- a/tests/unit/test_vnf_converter.py +++ b/tests/unit/test_vnf_converter.py @@ -3,8 +3,9 @@ # SPDX-License-Identifier: MPL-2.0 import pytest +from power_grid_model._core.error_handling import InvalidArguments -from power_grid_model_io_native._core.error_handling import InvalidArguments, assert_no_error +from power_grid_model_io_native._core.error_handling import assert_no_error from power_grid_model_io_native._core.vnf_converter import PgmVnfConverter From f8cebbb899437fd9b5deb68520219bbe478248c0 Mon Sep 17 00:00:00 2001 From: Laurynas Jagutis Date: Wed, 4 Dec 2024 09:54:34 +0100 Subject: [PATCH 21/21] use decoder from PGM, keep a decoder as a comment Signed-off-by: Laurynas Jagutis --- .../_core/error_handling.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/power_grid_model_io_native/_core/error_handling.py b/src/power_grid_model_io_native/_core/error_handling.py index d110590..ace9fc2 100644 --- a/src/power_grid_model_io_native/_core/error_handling.py +++ b/src/power_grid_model_io_native/_core/error_handling.py @@ -7,26 +7,24 @@ """ from power_grid_model._core.error_handling import ( - _ERROR_MESSAGE_PATTERNS, PGM_NO_ERROR, PGM_REGULAR_ERROR, PGM_SERIALIZATION_ERROR, VALIDATOR_MSG, PowerGridBatchError, - PowerGridError, PowerGridSerializationError, + _interpret_error, ) from power_grid_model_io_native._core.power_grid_model_io_core import pgm_io_core as pgmic +# def _interpret_error_pgm_io(message: str, decode_error: bool = True) -> PowerGridError: +# if decode_error: +# for pattern, type_ in _ERROR_MESSAGE_PATTERNS.items(): +# if pattern.search(message) is not None: +# return type_(message) -def _interpret_error(message: str, decode_error: bool = True) -> PowerGridError: - if decode_error: - for pattern, type_ in _ERROR_MESSAGE_PATTERNS.items(): - if pattern.search(message) is not None: - return type_(message) - - return PowerGridError(message) +# return PowerGridError(message) def find_error(batch_size: int = 1, decode_error: bool = True) -> RuntimeError | None: