power-grid-model 1.10.74__py3-none-win_amd64.whl → 1.12.119__py3-none-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of power-grid-model might be problematic. Click here for more details.

Files changed (67) hide show
  1. power_grid_model/__init__.py +54 -29
  2. power_grid_model/_core/__init__.py +3 -3
  3. power_grid_model/_core/buffer_handling.py +507 -478
  4. power_grid_model/_core/data_handling.py +195 -141
  5. power_grid_model/_core/data_types.py +142 -0
  6. power_grid_model/_core/dataset_definitions.py +109 -109
  7. power_grid_model/_core/enum.py +226 -0
  8. power_grid_model/_core/error_handling.py +215 -202
  9. power_grid_model/_core/errors.py +134 -0
  10. power_grid_model/_core/index_integer.py +17 -17
  11. power_grid_model/_core/options.py +71 -69
  12. power_grid_model/_core/power_grid_core.py +577 -597
  13. power_grid_model/_core/power_grid_dataset.py +545 -528
  14. power_grid_model/_core/power_grid_meta.py +262 -244
  15. power_grid_model/_core/power_grid_model.py +1025 -692
  16. power_grid_model/_core/power_grid_model_c/__init__.py +3 -0
  17. power_grid_model/_core/power_grid_model_c/bin/power_grid_model_c.dll +0 -0
  18. power_grid_model/_core/power_grid_model_c/get_pgm_dll_path.py +63 -0
  19. power_grid_model/_core/power_grid_model_c/include/power_grid_model_c/basics.h +251 -0
  20. power_grid_model/_core/power_grid_model_c/include/power_grid_model_c/buffer.h +108 -0
  21. power_grid_model/_core/power_grid_model_c/include/power_grid_model_c/dataset.h +332 -0
  22. power_grid_model/_core/power_grid_model_c/include/power_grid_model_c/dataset_definitions.h +1060 -0
  23. power_grid_model/_core/power_grid_model_c/include/power_grid_model_c/handle.h +111 -0
  24. power_grid_model/_core/power_grid_model_c/include/power_grid_model_c/meta_data.h +189 -0
  25. power_grid_model/_core/power_grid_model_c/include/power_grid_model_c/model.h +130 -0
  26. power_grid_model/_core/power_grid_model_c/include/power_grid_model_c/options.h +142 -0
  27. power_grid_model/_core/power_grid_model_c/include/power_grid_model_c/serialization.h +118 -0
  28. power_grid_model/_core/power_grid_model_c/include/power_grid_model_c.h +36 -0
  29. power_grid_model/_core/power_grid_model_c/include/power_grid_model_cpp/basics.hpp +65 -0
  30. power_grid_model/_core/power_grid_model_c/include/power_grid_model_cpp/buffer.hpp +61 -0
  31. power_grid_model/_core/power_grid_model_c/include/power_grid_model_cpp/dataset.hpp +224 -0
  32. power_grid_model/_core/power_grid_model_c/include/power_grid_model_cpp/handle.hpp +108 -0
  33. power_grid_model/_core/power_grid_model_c/include/power_grid_model_cpp/meta_data.hpp +84 -0
  34. power_grid_model/_core/power_grid_model_c/include/power_grid_model_cpp/model.hpp +63 -0
  35. power_grid_model/_core/power_grid_model_c/include/power_grid_model_cpp/options.hpp +52 -0
  36. power_grid_model/_core/power_grid_model_c/include/power_grid_model_cpp/serialization.hpp +124 -0
  37. power_grid_model/_core/power_grid_model_c/include/power_grid_model_cpp/utils.hpp +81 -0
  38. power_grid_model/_core/power_grid_model_c/include/power_grid_model_cpp.hpp +19 -0
  39. power_grid_model/_core/power_grid_model_c/lib/cmake/power_grid_model/power_grid_modelConfig.cmake +37 -0
  40. power_grid_model/_core/power_grid_model_c/lib/cmake/power_grid_model/power_grid_modelConfigVersion.cmake +65 -0
  41. power_grid_model/_core/power_grid_model_c/lib/cmake/power_grid_model/power_grid_modelTargets-release.cmake +19 -0
  42. power_grid_model/_core/power_grid_model_c/lib/cmake/power_grid_model/power_grid_modelTargets.cmake +144 -0
  43. power_grid_model/_core/power_grid_model_c/lib/power_grid_model_c.lib +0 -0
  44. power_grid_model/_core/power_grid_model_c/share/LICENSE +292 -0
  45. power_grid_model/_core/power_grid_model_c/share/README.md +15 -0
  46. power_grid_model/_core/serialization.py +319 -317
  47. power_grid_model/_core/typing.py +20 -0
  48. power_grid_model/{_utils.py → _core/utils.py} +798 -783
  49. power_grid_model/data_types.py +321 -319
  50. power_grid_model/enum.py +27 -214
  51. power_grid_model/errors.py +37 -123
  52. power_grid_model/typing.py +43 -48
  53. power_grid_model/utils.py +529 -400
  54. power_grid_model/validation/__init__.py +25 -14
  55. power_grid_model/validation/_rules.py +1167 -904
  56. power_grid_model/validation/_validation.py +1172 -980
  57. power_grid_model/validation/assertions.py +93 -92
  58. power_grid_model/validation/errors.py +602 -520
  59. power_grid_model/validation/utils.py +313 -318
  60. {power_grid_model-1.10.74.dist-info → power_grid_model-1.12.119.dist-info}/METADATA +162 -171
  61. power_grid_model-1.12.119.dist-info/RECORD +65 -0
  62. {power_grid_model-1.10.74.dist-info → power_grid_model-1.12.119.dist-info}/WHEEL +1 -1
  63. power_grid_model-1.12.119.dist-info/entry_points.txt +3 -0
  64. power_grid_model/_core/_power_grid_core.dll +0 -0
  65. power_grid_model-1.10.74.dist-info/RECORD +0 -32
  66. power_grid_model-1.10.74.dist-info/top_level.txt +0 -1
  67. {power_grid_model-1.10.74.dist-info → power_grid_model-1.12.119.dist-info}/licenses/LICENSE +0 -0
@@ -1,597 +1,577 @@
1
- # SPDX-FileCopyrightText: Contributors to the Power Grid Model project <powergridmodel@lfenergy.org>
2
- #
3
- # SPDX-License-Identifier: MPL-2.0
4
-
5
- """
6
- Loader for the dynamic library
7
- """
8
-
9
- import os
10
- import platform
11
- from ctypes import CDLL, POINTER, c_char, c_char_p, c_double, c_size_t, c_void_p
12
- from inspect import signature
13
- from itertools import chain
14
- from pathlib import Path
15
- from typing import Callable
16
-
17
- from power_grid_model._core.index_integer import IdC, IdxC
18
-
19
- # integer index
20
- IdxPtr = POINTER(IdxC)
21
- """Pointer to index."""
22
- IdxDoublePtr = POINTER(IdxPtr)
23
- """Double pointer to index."""
24
- IDPtr = POINTER(IdC)
25
- """Raw pointer to ids."""
26
-
27
- # string data
28
- CStr = c_char_p
29
- """Null terminated string."""
30
- CStrPtr = POINTER(CStr)
31
- """Pointer to null terminated string."""
32
- CharPtr = POINTER(c_char)
33
- """Raw pointer to char."""
34
- CharDoublePtr = POINTER(CharPtr)
35
- """Double pointer to char."""
36
-
37
- # raw data
38
- VoidPtr = c_void_p
39
- """Raw void pointer."""
40
- VoidDoublePtr = POINTER(c_void_p)
41
- """Double pointer to void."""
42
-
43
- # functions with size_t return
44
- _FUNC_SIZE_T_RES = {"meta_class_size", "meta_class_alignment", "meta_attribute_offset"}
45
- _ARGS_TYPE_MAPPING = {bytes: CharPtr, str: CStr, int: IdxC, float: c_double}
46
-
47
- # The c_void_p is extended only for type hinting and type checking; therefore no public methods are required.
48
- # pylint: disable=too-few-public-methods
49
-
50
-
51
- class HandlePtr(c_void_p):
52
- """
53
- Pointer to handle
54
- """
55
-
56
-
57
- class OptionsPtr(c_void_p):
58
- """
59
- Pointer to option
60
- """
61
-
62
-
63
- class ModelPtr(c_void_p):
64
- """
65
- Pointer to model
66
- """
67
-
68
-
69
- class DatasetPtr(c_void_p):
70
- """
71
- Pointer to dataset
72
- """
73
-
74
-
75
- class ConstDatasetPtr(c_void_p):
76
- """
77
- Pointer to writable dataset
78
- """
79
-
80
-
81
- class MutableDatasetPtr(c_void_p):
82
- """
83
- Pointer to writable dataset
84
- """
85
-
86
-
87
- class WritableDatasetPtr(c_void_p):
88
- """
89
- Pointer to writable dataset
90
- """
91
-
92
-
93
- class DatasetInfoPtr(c_void_p):
94
- """
95
- Pointer to dataset info
96
- """
97
-
98
-
99
- class ComponentPtr(c_void_p):
100
- """
101
- Pointer to component
102
- """
103
-
104
-
105
- class AttributePtr(c_void_p):
106
- """
107
- Pointer to attribute
108
- """
109
-
110
-
111
- class DeserializerPtr(c_void_p):
112
- """
113
- Pointer to deserializer
114
- """
115
-
116
-
117
- class SerializerPtr(c_void_p):
118
- """
119
- Pointer to serializer
120
- """
121
-
122
-
123
- def _load_core() -> CDLL:
124
- """
125
-
126
- Returns: DLL/SO object
127
-
128
- """
129
- # first try to find the DLL local
130
- if platform.system() == "Windows":
131
- dll_file = "_power_grid_core.dll"
132
- else:
133
- dll_file = "_power_grid_core.so"
134
- dll_path = Path(__file__).parent / dll_file
135
-
136
- # if local DLL is not found, try to find the DLL from conda environment
137
- if (not dll_path.exists()) and ("CONDA_PREFIX" in os.environ):
138
- if platform.system() == "Windows":
139
- dll_file = "power_grid_model_c.dll"
140
- elif platform.system() == "Darwin":
141
- dll_file = "libpower_grid_model_c.dylib"
142
- elif platform.system() == "Linux":
143
- dll_file = "libpower_grid_model_c.so"
144
- else:
145
- raise NotImplementedError(f"Unsupported platform: {platform.system()}")
146
- # the dll will be found through conda environment
147
- dll_path = Path(dll_file)
148
-
149
- cdll = CDLL(str(dll_path))
150
- # assign return types
151
- # handle
152
- cdll.PGM_create_handle.argtypes = []
153
- cdll.PGM_create_handle.restype = HandlePtr
154
- cdll.PGM_destroy_handle.argtypes = [HandlePtr]
155
- cdll.PGM_destroy_handle.restype = None
156
- return cdll
157
-
158
-
159
- # load dll once
160
- _CDLL: CDLL = _load_core()
161
-
162
-
163
- def make_c_binding(func: Callable):
164
- """
165
- Descriptor to make the function to bind to C
166
-
167
- Args:
168
- func: method object from PowerGridCore
169
-
170
- Returns:
171
- Binded function
172
-
173
- """
174
- name = func.__name__
175
- sig = signature(func)
176
-
177
- # get and convert types, skip first argument, as it is self
178
- py_argnames = list(sig.parameters.keys())[1:]
179
- py_argtypes = [v.annotation for v in sig.parameters.values()][1:]
180
- py_restype = sig.return_annotation
181
- c_argtypes = [_ARGS_TYPE_MAPPING.get(x, x) for x in py_argtypes]
182
- c_restype = _ARGS_TYPE_MAPPING.get(py_restype, py_restype)
183
- if c_restype == IdxC and name in _FUNC_SIZE_T_RES:
184
- c_restype = c_size_t
185
- # set argument in dll
186
- # mostly with handle pointer, except destroy function
187
- is_destroy_func = "destroy" in name
188
- if is_destroy_func:
189
- getattr(_CDLL, f"PGM_{name}").argtypes = c_argtypes
190
- else:
191
- getattr(_CDLL, f"PGM_{name}").argtypes = [HandlePtr] + c_argtypes
192
- getattr(_CDLL, f"PGM_{name}").restype = c_restype
193
-
194
- # binding function
195
- def cbind_func(self, *args, **kwargs):
196
- if "destroy" in name:
197
- c_inputs = []
198
- else:
199
- c_inputs = [self._handle] # pylint: disable=protected-access
200
- args = chain(args, (kwargs[key] for key in py_argnames[len(args) :]))
201
- for arg in args:
202
- if isinstance(arg, str):
203
- c_inputs.append(arg.encode())
204
- else:
205
- c_inputs.append(arg)
206
-
207
- # call
208
- res = getattr(_CDLL, f"PGM_{name}")(*c_inputs)
209
- # convert to string for CStr
210
- if c_restype == CStr:
211
- res = res.decode() if res is not None else ""
212
- return res
213
-
214
- return cbind_func
215
-
216
-
217
- # pylint: disable=too-many-arguments
218
- # pylint: disable=missing-function-docstring
219
- # pylint: disable=too-many-public-methods
220
- class PowerGridCore:
221
- """
222
- DLL caller
223
- """
224
-
225
- _handle: HandlePtr
226
- _instance: "PowerGridCore | None" = None
227
-
228
- # singleton of power grid core
229
- def __new__(cls, *args, **kwargs):
230
- if cls._instance is None:
231
- cls._instance = super().__new__(cls, *args, **kwargs)
232
- cls._instance._handle = _CDLL.PGM_create_handle()
233
- return cls._instance
234
-
235
- def __del__(self):
236
- _CDLL.PGM_destroy_handle(self._handle)
237
-
238
- # not copyable
239
- def __copy__(self):
240
- raise NotImplementedError("Class not copyable")
241
-
242
- def __deepcopy__(self, memodict):
243
- raise NotImplementedError("class not copyable")
244
-
245
- @make_c_binding
246
- def error_code(self) -> int: # type: ignore[empty-body]
247
- pass # pragma: no cover
248
-
249
- @make_c_binding
250
- def error_message(self) -> str: # type: ignore[empty-body]
251
- pass # pragma: no cover
252
-
253
- @make_c_binding
254
- def n_failed_scenarios(self) -> int: # type: ignore[empty-body]
255
- pass # pragma: no cover
256
-
257
- @make_c_binding
258
- def failed_scenarios(self) -> IdxPtr: # type: ignore[empty-body, valid-type] # type: ignore[empty-body]
259
- pass # pragma: no cover
260
-
261
- @make_c_binding
262
- def batch_errors(self) -> CStrPtr: # type: ignore[empty-body, valid-type] # type: ignore[empty-body]
263
- pass # pragma: no cover
264
-
265
- @make_c_binding
266
- def clear_error(self) -> None: # type: ignore[empty-body]
267
- pass # pragma: no cover
268
-
269
- @make_c_binding
270
- def meta_n_datasets(self) -> int: # type: ignore[empty-body]
271
- pass # pragma: no cover
272
-
273
- @make_c_binding
274
- def meta_get_dataset_by_idx(self, idx: int) -> DatasetPtr: # type: ignore[empty-body]
275
- pass # pragma: no cover
276
-
277
- @make_c_binding
278
- def meta_dataset_name(self, dataset: DatasetPtr) -> str: # type: ignore[empty-body]
279
- pass # pragma: no cover
280
-
281
- @make_c_binding
282
- def meta_n_components(self, dataset: DatasetPtr) -> int: # type: ignore[empty-body]
283
- pass # pragma: no cover
284
-
285
- @make_c_binding
286
- def meta_get_component_by_idx(self, dataset: DatasetPtr, idx: int) -> ComponentPtr: # type: ignore[empty-body]
287
- pass # pragma: no cover
288
-
289
- @make_c_binding
290
- def meta_component_name(self, component: ComponentPtr) -> str: # type: ignore[empty-body]
291
- pass # pragma: no cover
292
-
293
- @make_c_binding
294
- def meta_component_alignment(self, component: ComponentPtr) -> int: # type: ignore[empty-body]
295
- pass # pragma: no cover
296
-
297
- @make_c_binding
298
- def meta_component_size(self, component: ComponentPtr) -> int: # type: ignore[empty-body]
299
- pass # pragma: no cover
300
-
301
- @make_c_binding
302
- def meta_n_attributes(self, component: ComponentPtr) -> int: # type: ignore[empty-body]
303
- pass # pragma: no cover
304
-
305
- @make_c_binding
306
- def meta_get_attribute_by_idx(self, component: ComponentPtr, idx: int) -> AttributePtr: # type: ignore[empty-body]
307
- pass # pragma: no cover
308
-
309
- @make_c_binding
310
- def meta_attribute_name(self, attribute: AttributePtr) -> str: # type: ignore[empty-body]
311
- pass # pragma: no cover
312
-
313
- @make_c_binding
314
- def meta_attribute_ctype(self, attribute: AttributePtr) -> int: # type: ignore[empty-body]
315
- pass # pragma: no cover
316
-
317
- @make_c_binding
318
- def meta_attribute_offset(self, attribute: AttributePtr) -> int: # type: ignore[empty-body]
319
- pass # pragma: no cover
320
-
321
- @make_c_binding
322
- def is_little_endian(self) -> int: # type: ignore[empty-body]
323
- pass # pragma: no cover
324
-
325
- @make_c_binding
326
- def create_options(self) -> OptionsPtr: # type: ignore[empty-body]
327
- pass # pragma: no cover
328
-
329
- @make_c_binding
330
- def destroy_options(self, opt: OptionsPtr) -> None: # type: ignore[empty-body]
331
- pass # pragma: no cover
332
-
333
- @make_c_binding
334
- def set_calculation_type(self, opt: OptionsPtr, calculation_type: int) -> None: # type: ignore[empty-body]
335
- pass # pragma: no cover
336
-
337
- @make_c_binding
338
- def set_calculation_method(self, opt: OptionsPtr, method: int) -> None: # type: ignore[empty-body]
339
- pass # pragma: no cover
340
-
341
- @make_c_binding
342
- def set_tap_changing_strategy(
343
- self, opt: OptionsPtr, tap_changing_strategy: int
344
- ) -> None: # type: ignore[empty-body]
345
- pass # pragma: no cover
346
-
347
- @make_c_binding
348
- def set_short_circuit_voltage_scaling(
349
- self, opt: OptionsPtr, short_circuit_voltage_scaling: int
350
- ) -> None: # type: ignore[empty-body]
351
- pass # pragma: no cover
352
-
353
- @make_c_binding
354
- def set_experimental_features(
355
- self, opt: OptionsPtr, experimental_features: int
356
- ) -> None: # type: ignore[empty-body]
357
- pass # pragma: no cover
358
-
359
- @make_c_binding
360
- def set_symmetric(self, opt: OptionsPtr, sym: int) -> None: # type: ignore[empty-body]
361
- pass # pragma: no cover
362
-
363
- @make_c_binding
364
- def set_err_tol(self, opt: OptionsPtr, err_tol: float) -> None: # type: ignore[empty-body]
365
- pass # pragma: no cover
366
-
367
- @make_c_binding
368
- def set_max_iter(self, opt: OptionsPtr, max_iter: int) -> None: # type: ignore[empty-body]
369
- pass # pragma: no cover
370
-
371
- @make_c_binding
372
- def set_threading(self, opt: OptionsPtr, threading: int) -> None: # type: ignore[empty-body]
373
- pass # pragma: no cover
374
-
375
- @make_c_binding
376
- def create_model( # type: ignore[empty-body]
377
- self,
378
- system_frequency: float,
379
- input_data: ConstDatasetPtr, # type: ignore[valid-type]
380
- ) -> ModelPtr:
381
- pass # pragma: no cover
382
-
383
- @make_c_binding
384
- def update_model( # type: ignore[empty-body]
385
- self,
386
- model: ModelPtr,
387
- update_data: ConstDatasetPtr, # type: ignore[valid-type]
388
- ) -> None:
389
- pass # pragma: no cover
390
-
391
- @make_c_binding
392
- def copy_model(self, model: ModelPtr) -> ModelPtr: # type: ignore[empty-body]
393
- pass # pragma: no cover
394
-
395
- @make_c_binding
396
- def get_indexer( # pylint: disable=too-many-positional-arguments
397
- self,
398
- model: ModelPtr,
399
- component: str,
400
- size: int,
401
- ids: IDPtr, # type: ignore[valid-type]
402
- indexer: IdxPtr, # type: ignore[valid-type]
403
- ) -> None: # type: ignore[empty-body]
404
- pass # pragma: no cover
405
-
406
- @make_c_binding
407
- def destroy_model(self, model: ModelPtr) -> None: # type: ignore[empty-body]
408
- pass # pragma: no cover
409
-
410
- @make_c_binding
411
- def calculate( # type: ignore[empty-body]
412
- self,
413
- model: ModelPtr,
414
- opt: OptionsPtr,
415
- output_data: MutableDatasetPtr, # type: ignore[valid-type]
416
- update_data: ConstDatasetPtr, # type: ignore[valid-type]
417
- ) -> None:
418
- pass # pragma: no cover
419
-
420
- @make_c_binding
421
- def dataset_info_name(self, info: DatasetInfoPtr) -> str: # type: ignore[empty-body]
422
- pass # pragma: no cover
423
-
424
- @make_c_binding
425
- def dataset_info_is_batch(self, info: DatasetInfoPtr) -> int: # type: ignore[empty-body]
426
- pass # pragma: no cover
427
-
428
- @make_c_binding
429
- def dataset_info_batch_size(self, info: DatasetInfoPtr) -> int: # type: ignore[empty-body]
430
- pass # pragma: no cover
431
-
432
- @make_c_binding
433
- def dataset_info_n_components(self, info: DatasetInfoPtr) -> int: # type: ignore[empty-body]
434
- pass # pragma: no cover
435
-
436
- @make_c_binding
437
- def dataset_info_component_name(self, info: DatasetInfoPtr, component_idx: int) -> str: # type: ignore[empty-body]
438
- pass # pragma: no cover
439
-
440
- @make_c_binding
441
- def dataset_info_elements_per_scenario( # type: ignore[empty-body]
442
- self, info: DatasetInfoPtr, component_idx: int
443
- ) -> int:
444
- pass # pragma: no cover
445
-
446
- @make_c_binding
447
- def dataset_info_total_elements(self, info: DatasetInfoPtr, component_idx: int) -> int: # type: ignore[empty-body]
448
- pass # pragma: no cover
449
-
450
- @make_c_binding
451
- def dataset_info_has_attribute_indications( # type: ignore[empty-body]
452
- self, info: DatasetInfoPtr, component_idx: int
453
- ) -> int:
454
- pass # pragma: no cover
455
-
456
- @make_c_binding
457
- def dataset_info_n_attribute_indications( # type: ignore[empty-body]
458
- self, info: DatasetInfoPtr, component_idx: int
459
- ) -> int:
460
- pass # pragma: no cover
461
-
462
- @make_c_binding
463
- def dataset_info_attribute_name( # type: ignore[empty-body]
464
- self, info: DatasetInfoPtr, component_idx: int, attribute_idx: int
465
- ) -> str:
466
- pass # pragma: no cover
467
-
468
- @make_c_binding
469
- def create_dataset_mutable( # type: ignore[empty-body]
470
- self, dataset: str, is_batch: int, batch_size: int
471
- ) -> MutableDatasetPtr:
472
- pass # pragma: no cover
473
-
474
- @make_c_binding
475
- def destroy_dataset_mutable(self, dataset: MutableDatasetPtr) -> None: # type: ignore[empty-body]
476
- pass # pragma: no cover
477
-
478
- @make_c_binding
479
- def dataset_mutable_add_buffer( # type: ignore[empty-body] # pylint: disable=too-many-positional-arguments
480
- self,
481
- dataset: MutableDatasetPtr,
482
- component: str,
483
- elements_per_scenario: int,
484
- total_elements: int,
485
- indptr: IdxPtr, # type: ignore[valid-type]
486
- data: VoidPtr, # type: ignore[valid-type]
487
- ) -> None:
488
- pass # pragma: no cover
489
-
490
- @make_c_binding
491
- def dataset_mutable_add_attribute_buffer(
492
- self,
493
- dataset: MutableDatasetPtr,
494
- component: str,
495
- attribute: str,
496
- data: VoidPtr, # type: ignore[valid-type]
497
- ) -> None: # type: ignore[empty-body]
498
- pass # pragma: no cover
499
-
500
- @make_c_binding
501
- def dataset_mutable_get_info(self, dataset: MutableDatasetPtr) -> DatasetInfoPtr: # type: ignore[empty-body]
502
- pass # pragma: no cover
503
-
504
- @make_c_binding
505
- def create_dataset_const_from_mutable( # type: ignore[empty-body]
506
- self, mutable_dataset: MutableDatasetPtr
507
- ) -> ConstDatasetPtr:
508
- pass # pragma: no cover
509
-
510
- @make_c_binding
511
- def destroy_dataset_const(self, dataset: ConstDatasetPtr) -> None: # type: ignore[empty-body]
512
- pass # pragma: no cover
513
-
514
- @make_c_binding
515
- def dataset_const_get_info(self, dataset: ConstDatasetPtr) -> DatasetInfoPtr: # type: ignore[empty-body]
516
- pass # pragma: no cover
517
-
518
- @make_c_binding
519
- def dataset_writable_get_info(self, dataset: WritableDatasetPtr) -> DatasetInfoPtr: # type: ignore[empty-body]
520
- pass # pragma: no cover
521
-
522
- @make_c_binding
523
- def dataset_writable_set_buffer(
524
- self,
525
- dataset: WritableDatasetPtr,
526
- component: str,
527
- indptr: IdxPtr, # type: ignore[valid-type]
528
- data: VoidPtr, # type: ignore[valid-type]
529
- ) -> None: # type: ignore[empty-body]
530
- pass # pragma: no cover
531
-
532
- @make_c_binding
533
- def dataset_writable_set_attribute_buffer(
534
- self,
535
- dataset: WritableDatasetPtr,
536
- component: str,
537
- attribute: str,
538
- data: VoidPtr, # type: ignore[valid-type]
539
- ) -> None: # type: ignore[empty-body]
540
- pass # pragma: no cover
541
-
542
- @make_c_binding
543
- def create_deserializer_from_binary_buffer( # type: ignore[empty-body]
544
- self, data: bytes, size: int, serialization_format: int
545
- ) -> DeserializerPtr:
546
- pass # pragma: no cover
547
-
548
- @make_c_binding
549
- def create_deserializer_from_null_terminated_string( # type: ignore[empty-body]
550
- self, data: str, serialization_format: int
551
- ) -> DeserializerPtr:
552
- pass # pragma: no cover
553
-
554
- @make_c_binding
555
- def deserializer_get_dataset(self, deserializer: DeserializerPtr) -> WritableDatasetPtr: # type: ignore[empty-body]
556
- pass # pragma: no cover
557
-
558
- @make_c_binding
559
- def deserializer_parse_to_buffer(self, deserializer: DeserializerPtr) -> None: # type: ignore[empty-body]
560
- pass # pragma: no cover
561
-
562
- @make_c_binding
563
- def destroy_deserializer(self, deserializer: DeserializerPtr) -> None: # type: ignore[empty-body]
564
- pass # pragma: no cover
565
-
566
- @make_c_binding
567
- def create_serializer( # type: ignore[empty-body]
568
- self, data: ConstDatasetPtr, serialization_format: int
569
- ) -> SerializerPtr:
570
- pass # pragma: no cover
571
-
572
- @make_c_binding
573
- def serializer_get_to_binary_buffer( # type: ignore[empty-body]
574
- self,
575
- serializer: SerializerPtr,
576
- use_compact_list: int,
577
- data: CharDoublePtr, # type: ignore[valid-type]
578
- size: IdxPtr, # type: ignore[valid-type]
579
- ) -> None:
580
- pass # pragma: no cover
581
-
582
- @make_c_binding
583
- def serializer_get_to_zero_terminated_string( # type: ignore[empty-body]
584
- self,
585
- serializer: SerializerPtr,
586
- use_compact_list: int,
587
- indent: int,
588
- ) -> str:
589
- pass # pragma: no cover
590
-
591
- @make_c_binding
592
- def destroy_serializer(self, serializer: SerializerPtr) -> None: # type: ignore[empty-body]
593
- pass # pragma: no cover
594
-
595
-
596
- # make one instance
597
- power_grid_core = PowerGridCore()
1
+ # SPDX-FileCopyrightText: Contributors to the Power Grid Model project <powergridmodel@lfenergy.org>
2
+ #
3
+ # SPDX-License-Identifier: MPL-2.0
4
+
5
+ """
6
+ Loader for the dynamic library
7
+ """
8
+
9
+ import threading
10
+ from collections.abc import Callable
11
+ from ctypes import CDLL, POINTER, c_char, c_char_p, c_double, c_size_t, c_void_p
12
+ from inspect import signature
13
+ from itertools import chain
14
+
15
+ from power_grid_model._core.index_integer import IdC, IdxC
16
+ from power_grid_model._core.power_grid_model_c.get_pgm_dll_path import get_pgm_dll_path
17
+
18
+ # threading local
19
+ _thread_local_data = threading.local()
20
+
21
+
22
+ # integer index
23
+ IdxPtr = POINTER(IdxC)
24
+ """Pointer to index."""
25
+ IdxDoublePtr = POINTER(IdxPtr)
26
+ """Double pointer to index."""
27
+ IDPtr = POINTER(IdC)
28
+ """Raw pointer to ids."""
29
+
30
+ # string data
31
+ CStr = c_char_p
32
+ """Null terminated string."""
33
+ CStrPtr = POINTER(CStr)
34
+ """Pointer to null terminated string."""
35
+ CharPtr = POINTER(c_char)
36
+ """Raw pointer to char."""
37
+ CharDoublePtr = POINTER(CharPtr)
38
+ """Double pointer to char."""
39
+
40
+ # raw data
41
+ VoidPtr = c_void_p
42
+ """Raw void pointer."""
43
+ VoidDoublePtr = POINTER(c_void_p)
44
+ """Double pointer to void."""
45
+
46
+ # functions with size_t return
47
+ _FUNC_SIZE_T_RES = {"meta_class_size", "meta_class_alignment", "meta_attribute_offset"}
48
+ _ARGS_TYPE_MAPPING = {bytes: CharPtr, str: CStr, int: IdxC, float: c_double}
49
+
50
+ # The c_void_p is extended only for type hinting and type checking; therefore no public methods are required.
51
+
52
+
53
+ class HandlePtr(c_void_p):
54
+ """
55
+ Pointer to handle
56
+ """
57
+
58
+
59
+ class OptionsPtr(c_void_p):
60
+ """
61
+ Pointer to option
62
+ """
63
+
64
+
65
+ class ModelPtr(c_void_p):
66
+ """
67
+ Pointer to model
68
+ """
69
+
70
+
71
+ class DatasetPtr(c_void_p):
72
+ """
73
+ Pointer to dataset
74
+ """
75
+
76
+
77
+ class ConstDatasetPtr(c_void_p):
78
+ """
79
+ Pointer to writable dataset
80
+ """
81
+
82
+
83
+ class MutableDatasetPtr(c_void_p):
84
+ """
85
+ Pointer to writable dataset
86
+ """
87
+
88
+
89
+ class WritableDatasetPtr(c_void_p):
90
+ """
91
+ Pointer to writable dataset
92
+ """
93
+
94
+
95
+ class DatasetInfoPtr(c_void_p):
96
+ """
97
+ Pointer to dataset info
98
+ """
99
+
100
+
101
+ class ComponentPtr(c_void_p):
102
+ """
103
+ Pointer to component
104
+ """
105
+
106
+
107
+ class AttributePtr(c_void_p):
108
+ """
109
+ Pointer to attribute
110
+ """
111
+
112
+
113
+ class DeserializerPtr(c_void_p):
114
+ """
115
+ Pointer to deserializer
116
+ """
117
+
118
+
119
+ class SerializerPtr(c_void_p):
120
+ """
121
+ Pointer to serializer
122
+ """
123
+
124
+
125
+ def _load_core() -> CDLL:
126
+ """
127
+
128
+ Returns: DLL/SO object
129
+
130
+ """
131
+ dll_path = get_pgm_dll_path()
132
+ cdll = CDLL(str(dll_path))
133
+ # assign return types
134
+ # handle
135
+ cdll.PGM_create_handle.argtypes = []
136
+ cdll.PGM_create_handle.restype = HandlePtr
137
+ cdll.PGM_destroy_handle.argtypes = [HandlePtr]
138
+ cdll.PGM_destroy_handle.restype = None
139
+ return cdll
140
+
141
+
142
+ # load dll once
143
+ _CDLL: CDLL = _load_core()
144
+
145
+
146
+ def make_c_binding(func: Callable):
147
+ """
148
+ Descriptor to make the function to bind to C
149
+
150
+ Args:
151
+ func: method object from PowerGridCore
152
+
153
+ Returns:
154
+ Binded function
155
+
156
+ """
157
+ name = func.__name__
158
+ sig = signature(func)
159
+
160
+ # get and convert types, skip first argument, as it is self
161
+ py_argnames = list(sig.parameters.keys())[1:]
162
+ py_argtypes = [v.annotation for v in sig.parameters.values()][1:]
163
+ py_restype = sig.return_annotation
164
+ c_argtypes = [_ARGS_TYPE_MAPPING.get(x, x) for x in py_argtypes]
165
+ c_restype = _ARGS_TYPE_MAPPING.get(py_restype, py_restype)
166
+ if c_restype == IdxC and name in _FUNC_SIZE_T_RES:
167
+ c_restype = c_size_t
168
+ # set argument in dll
169
+ # mostly with handle pointer, except destroy function
170
+ is_destroy_func = "destroy" in name
171
+ if is_destroy_func:
172
+ getattr(_CDLL, f"PGM_{name}").argtypes = c_argtypes
173
+ else:
174
+ getattr(_CDLL, f"PGM_{name}").argtypes = [HandlePtr, *c_argtypes]
175
+ getattr(_CDLL, f"PGM_{name}").restype = c_restype
176
+
177
+ # binding function
178
+ def cbind_func(self, *args, **kwargs):
179
+ c_inputs = [] if "destroy" in name else [self._handle]
180
+ args = chain(args, (kwargs[key] for key in py_argnames[len(args) :]))
181
+ for arg in args:
182
+ if isinstance(arg, str):
183
+ c_inputs.append(arg.encode())
184
+ else:
185
+ c_inputs.append(arg)
186
+
187
+ # call
188
+ res = getattr(_CDLL, f"PGM_{name}")(*c_inputs)
189
+ # convert to string for CStr
190
+ if c_restype == CStr:
191
+ res = res.decode() if res is not None else ""
192
+ return res
193
+
194
+ return cbind_func
195
+
196
+
197
+ class PowerGridCore:
198
+ """
199
+ DLL caller
200
+ """
201
+
202
+ _handle: HandlePtr
203
+
204
+ # singleton of power grid core
205
+ def __new__(cls, *args, **kwargs):
206
+ instance = super().__new__(cls, *args, **kwargs)
207
+ instance._handle = _CDLL.PGM_create_handle()
208
+ return instance
209
+
210
+ def __del__(self):
211
+ _CDLL.PGM_destroy_handle(self._handle)
212
+
213
+ # not copyable
214
+ def __copy__(self):
215
+ raise NotImplementedError("Class not copyable")
216
+
217
+ def __deepcopy__(self, memodict):
218
+ raise NotImplementedError("class not copyable")
219
+
220
+ @make_c_binding
221
+ def error_code(self) -> int: # type: ignore[empty-body]
222
+ pass # pragma: no cover
223
+
224
+ @make_c_binding
225
+ def error_message(self) -> str: # type: ignore[empty-body]
226
+ pass # pragma: no cover
227
+
228
+ @make_c_binding
229
+ def n_failed_scenarios(self) -> int: # type: ignore[empty-body]
230
+ pass # pragma: no cover
231
+
232
+ @make_c_binding
233
+ def failed_scenarios(self) -> IdxPtr: # type: ignore[empty-body, valid-type] # type: ignore[empty-body]
234
+ pass # pragma: no cover
235
+
236
+ @make_c_binding
237
+ def batch_errors(self) -> CStrPtr: # type: ignore[empty-body, valid-type] # type: ignore[empty-body]
238
+ pass # pragma: no cover
239
+
240
+ @make_c_binding
241
+ def clear_error(self) -> None: # type: ignore[empty-body]
242
+ pass # pragma: no cover
243
+
244
+ @make_c_binding
245
+ def meta_n_datasets(self) -> int: # type: ignore[empty-body]
246
+ pass # pragma: no cover
247
+
248
+ @make_c_binding
249
+ def meta_get_dataset_by_idx(self, idx: int) -> DatasetPtr: # type: ignore[empty-body]
250
+ pass # pragma: no cover
251
+
252
+ @make_c_binding
253
+ def meta_dataset_name(self, dataset: DatasetPtr) -> str: # type: ignore[empty-body]
254
+ pass # pragma: no cover
255
+
256
+ @make_c_binding
257
+ def meta_n_components(self, dataset: DatasetPtr) -> int: # type: ignore[empty-body]
258
+ pass # pragma: no cover
259
+
260
+ @make_c_binding
261
+ def meta_get_component_by_idx(self, dataset: DatasetPtr, idx: int) -> ComponentPtr: # type: ignore[empty-body]
262
+ pass # pragma: no cover
263
+
264
+ @make_c_binding
265
+ def meta_component_name(self, component: ComponentPtr) -> str: # type: ignore[empty-body]
266
+ pass # pragma: no cover
267
+
268
+ @make_c_binding
269
+ def meta_component_alignment(self, component: ComponentPtr) -> int: # type: ignore[empty-body]
270
+ pass # pragma: no cover
271
+
272
+ @make_c_binding
273
+ def meta_component_size(self, component: ComponentPtr) -> int: # type: ignore[empty-body]
274
+ pass # pragma: no cover
275
+
276
+ @make_c_binding
277
+ def meta_n_attributes(self, component: ComponentPtr) -> int: # type: ignore[empty-body]
278
+ pass # pragma: no cover
279
+
280
+ @make_c_binding
281
+ def meta_get_attribute_by_idx(self, component: ComponentPtr, idx: int) -> AttributePtr: # type: ignore[empty-body]
282
+ pass # pragma: no cover
283
+
284
+ @make_c_binding
285
+ def meta_attribute_name(self, attribute: AttributePtr) -> str: # type: ignore[empty-body]
286
+ pass # pragma: no cover
287
+
288
+ @make_c_binding
289
+ def meta_attribute_ctype(self, attribute: AttributePtr) -> int: # type: ignore[empty-body]
290
+ pass # pragma: no cover
291
+
292
+ @make_c_binding
293
+ def meta_attribute_offset(self, attribute: AttributePtr) -> int: # type: ignore[empty-body]
294
+ pass # pragma: no cover
295
+
296
+ @make_c_binding
297
+ def is_little_endian(self) -> int: # type: ignore[empty-body]
298
+ pass # pragma: no cover
299
+
300
+ @make_c_binding
301
+ def create_options(self) -> OptionsPtr: # type: ignore[empty-body]
302
+ pass # pragma: no cover
303
+
304
+ @make_c_binding
305
+ def destroy_options(self, opt: OptionsPtr) -> None: # type: ignore[empty-body]
306
+ pass # pragma: no cover
307
+
308
+ @make_c_binding
309
+ def set_calculation_type(self, opt: OptionsPtr, calculation_type: int) -> None: # type: ignore[empty-body]
310
+ pass # pragma: no cover
311
+
312
+ @make_c_binding
313
+ def set_calculation_method(self, opt: OptionsPtr, method: int) -> None: # type: ignore[empty-body]
314
+ pass # pragma: no cover
315
+
316
+ @make_c_binding
317
+ def set_tap_changing_strategy(self, opt: OptionsPtr, tap_changing_strategy: int) -> None: # type: ignore[empty-body]
318
+ pass # pragma: no cover
319
+
320
+ @make_c_binding
321
+ def set_short_circuit_voltage_scaling(self, opt: OptionsPtr, short_circuit_voltage_scaling: int) -> None: # type: ignore[empty-body]
322
+ pass # pragma: no cover
323
+
324
+ @make_c_binding
325
+ def set_experimental_features(self, opt: OptionsPtr, experimental_features: int) -> None: # type: ignore[empty-body]
326
+ pass # pragma: no cover
327
+
328
+ @make_c_binding
329
+ def set_symmetric(self, opt: OptionsPtr, sym: int) -> None: # type: ignore[empty-body]
330
+ pass # pragma: no cover
331
+
332
+ @make_c_binding
333
+ def set_err_tol(self, opt: OptionsPtr, err_tol: float) -> None: # type: ignore[empty-body]
334
+ pass # pragma: no cover
335
+
336
+ @make_c_binding
337
+ def set_max_iter(self, opt: OptionsPtr, max_iter: int) -> None: # type: ignore[empty-body]
338
+ pass # pragma: no cover
339
+
340
+ @make_c_binding
341
+ def set_threading(self, opt: OptionsPtr, threading: int) -> None: # type: ignore[empty-body]
342
+ pass # pragma: no cover
343
+
344
+ @make_c_binding
345
+ def create_model( # type: ignore[empty-body]
346
+ self,
347
+ system_frequency: float,
348
+ input_data: ConstDatasetPtr, # type: ignore[valid-type]
349
+ ) -> ModelPtr:
350
+ pass # pragma: no cover
351
+
352
+ @make_c_binding
353
+ def update_model( # type: ignore[empty-body]
354
+ self,
355
+ model: ModelPtr,
356
+ update_data: ConstDatasetPtr, # type: ignore[valid-type]
357
+ ) -> None:
358
+ pass # pragma: no cover
359
+
360
+ @make_c_binding
361
+ def copy_model(self, model: ModelPtr) -> ModelPtr: # type: ignore[empty-body]
362
+ pass # pragma: no cover
363
+
364
+ @make_c_binding
365
+ def get_indexer(
366
+ self,
367
+ model: ModelPtr,
368
+ component: str,
369
+ size: int,
370
+ ids: IDPtr, # type: ignore[valid-type]
371
+ indexer: IdxPtr, # type: ignore[valid-type]
372
+ ) -> None: # type: ignore[empty-body]
373
+ pass # pragma: no cover
374
+
375
+ @make_c_binding
376
+ def destroy_model(self, model: ModelPtr) -> None: # type: ignore[empty-body]
377
+ pass # pragma: no cover
378
+
379
+ @make_c_binding
380
+ def calculate( # type: ignore[empty-body]
381
+ self,
382
+ model: ModelPtr,
383
+ opt: OptionsPtr,
384
+ output_data: MutableDatasetPtr, # type: ignore[valid-type]
385
+ update_data: ConstDatasetPtr, # type: ignore[valid-type]
386
+ ) -> None:
387
+ pass # pragma: no cover
388
+
389
+ @make_c_binding
390
+ def dataset_info_name(self, info: DatasetInfoPtr) -> str: # type: ignore[empty-body]
391
+ pass # pragma: no cover
392
+
393
+ @make_c_binding
394
+ def dataset_info_is_batch(self, info: DatasetInfoPtr) -> int: # type: ignore[empty-body]
395
+ pass # pragma: no cover
396
+
397
+ @make_c_binding
398
+ def dataset_info_batch_size(self, info: DatasetInfoPtr) -> int: # type: ignore[empty-body]
399
+ pass # pragma: no cover
400
+
401
+ @make_c_binding
402
+ def dataset_info_n_components(self, info: DatasetInfoPtr) -> int: # type: ignore[empty-body]
403
+ pass # pragma: no cover
404
+
405
+ @make_c_binding
406
+ def dataset_info_component_name(self, info: DatasetInfoPtr, component_idx: int) -> str: # type: ignore[empty-body]
407
+ pass # pragma: no cover
408
+
409
+ @make_c_binding
410
+ def dataset_info_elements_per_scenario( # type: ignore[empty-body]
411
+ self, info: DatasetInfoPtr, component_idx: int
412
+ ) -> int:
413
+ pass # pragma: no cover
414
+
415
+ @make_c_binding
416
+ def dataset_info_total_elements(self, info: DatasetInfoPtr, component_idx: int) -> int: # type: ignore[empty-body]
417
+ pass # pragma: no cover
418
+
419
+ @make_c_binding
420
+ def dataset_info_has_attribute_indications( # type: ignore[empty-body]
421
+ self, info: DatasetInfoPtr, component_idx: int
422
+ ) -> int:
423
+ pass # pragma: no cover
424
+
425
+ @make_c_binding
426
+ def dataset_info_n_attribute_indications( # type: ignore[empty-body]
427
+ self, info: DatasetInfoPtr, component_idx: int
428
+ ) -> int:
429
+ pass # pragma: no cover
430
+
431
+ @make_c_binding
432
+ def dataset_info_attribute_name( # type: ignore[empty-body]
433
+ self, info: DatasetInfoPtr, component_idx: int, attribute_idx: int
434
+ ) -> str:
435
+ pass # pragma: no cover
436
+
437
+ @make_c_binding
438
+ def create_dataset_mutable( # type: ignore[empty-body]
439
+ self, dataset: str, is_batch: int, batch_size: int
440
+ ) -> MutableDatasetPtr:
441
+ pass # pragma: no cover
442
+
443
+ @make_c_binding
444
+ def destroy_dataset_mutable(self, dataset: MutableDatasetPtr) -> None: # type: ignore[empty-body]
445
+ pass # pragma: no cover
446
+
447
+ @make_c_binding
448
+ def dataset_mutable_add_buffer( # type: ignore[empty-body] # noqa: PLR0913
449
+ self,
450
+ dataset: MutableDatasetPtr,
451
+ component: str,
452
+ elements_per_scenario: int,
453
+ total_elements: int,
454
+ indptr: IdxPtr, # type: ignore[valid-type]
455
+ data: VoidPtr, # type: ignore[valid-type]
456
+ ) -> None:
457
+ pass # pragma: no cover
458
+
459
+ @make_c_binding
460
+ def dataset_mutable_add_attribute_buffer(
461
+ self,
462
+ dataset: MutableDatasetPtr,
463
+ component: str,
464
+ attribute: str,
465
+ data: VoidPtr, # type: ignore[valid-type]
466
+ ) -> None: # type: ignore[empty-body]
467
+ pass # pragma: no cover
468
+
469
+ @make_c_binding
470
+ def dataset_mutable_get_info(self, dataset: MutableDatasetPtr) -> DatasetInfoPtr: # type: ignore[empty-body]
471
+ pass # pragma: no cover
472
+
473
+ @make_c_binding
474
+ def create_dataset_const_from_mutable( # type: ignore[empty-body]
475
+ self, mutable_dataset: MutableDatasetPtr
476
+ ) -> ConstDatasetPtr:
477
+ pass # pragma: no cover
478
+
479
+ @make_c_binding
480
+ def destroy_dataset_const(self, dataset: ConstDatasetPtr) -> None: # type: ignore[empty-body]
481
+ pass # pragma: no cover
482
+
483
+ @make_c_binding
484
+ def dataset_const_get_info(self, dataset: ConstDatasetPtr) -> DatasetInfoPtr: # type: ignore[empty-body]
485
+ pass # pragma: no cover
486
+
487
+ @make_c_binding
488
+ def dataset_const_set_next_cartesian_product_dimension(
489
+ self, dataset: ConstDatasetPtr, next_dataset: ConstDatasetPtr
490
+ ) -> None: # type: ignore[empty-body]
491
+ pass # pragma: no cover
492
+
493
+ @make_c_binding
494
+ def dataset_writable_get_info(self, dataset: WritableDatasetPtr) -> DatasetInfoPtr: # type: ignore[empty-body]
495
+ pass # pragma: no cover
496
+
497
+ @make_c_binding
498
+ def dataset_writable_set_buffer(
499
+ self,
500
+ dataset: WritableDatasetPtr,
501
+ component: str,
502
+ indptr: IdxPtr, # type: ignore[valid-type]
503
+ data: VoidPtr, # type: ignore[valid-type]
504
+ ) -> None: # type: ignore[empty-body]
505
+ pass # pragma: no cover
506
+
507
+ @make_c_binding
508
+ def dataset_writable_set_attribute_buffer(
509
+ self,
510
+ dataset: WritableDatasetPtr,
511
+ component: str,
512
+ attribute: str,
513
+ data: VoidPtr, # type: ignore[valid-type]
514
+ ) -> None: # type: ignore[empty-body]
515
+ pass # pragma: no cover
516
+
517
+ @make_c_binding
518
+ def create_deserializer_from_binary_buffer( # type: ignore[empty-body]
519
+ self, data: bytes, size: int, serialization_format: int
520
+ ) -> DeserializerPtr:
521
+ pass # pragma: no cover
522
+
523
+ @make_c_binding
524
+ def create_deserializer_from_null_terminated_string( # type: ignore[empty-body]
525
+ self, data: str, serialization_format: int
526
+ ) -> DeserializerPtr:
527
+ pass # pragma: no cover
528
+
529
+ @make_c_binding
530
+ def deserializer_get_dataset(self, deserializer: DeserializerPtr) -> WritableDatasetPtr: # type: ignore[empty-body]
531
+ pass # pragma: no cover
532
+
533
+ @make_c_binding
534
+ def deserializer_parse_to_buffer(self, deserializer: DeserializerPtr) -> None: # type: ignore[empty-body]
535
+ pass # pragma: no cover
536
+
537
+ @make_c_binding
538
+ def destroy_deserializer(self, deserializer: DeserializerPtr) -> None: # type: ignore[empty-body]
539
+ pass # pragma: no cover
540
+
541
+ @make_c_binding
542
+ def create_serializer( # type: ignore[empty-body]
543
+ self, data: ConstDatasetPtr, serialization_format: int
544
+ ) -> SerializerPtr:
545
+ pass # pragma: no cover
546
+
547
+ @make_c_binding
548
+ def serializer_get_to_binary_buffer( # type: ignore[empty-body]
549
+ self,
550
+ serializer: SerializerPtr,
551
+ use_compact_list: int,
552
+ data: CharDoublePtr, # type: ignore[valid-type]
553
+ size: IdxPtr, # type: ignore[valid-type]
554
+ ) -> None:
555
+ pass # pragma: no cover
556
+
557
+ @make_c_binding
558
+ def serializer_get_to_zero_terminated_string( # type: ignore[empty-body]
559
+ self,
560
+ serializer: SerializerPtr,
561
+ use_compact_list: int,
562
+ indent: int,
563
+ ) -> str:
564
+ pass # pragma: no cover
565
+
566
+ @make_c_binding
567
+ def destroy_serializer(self, serializer: SerializerPtr) -> None: # type: ignore[empty-body]
568
+ pass # pragma: no cover
569
+
570
+
571
+ # make one instance
572
+ def get_power_grid_core() -> PowerGridCore:
573
+ try:
574
+ return _thread_local_data.power_grid_core
575
+ except AttributeError:
576
+ _thread_local_data.power_grid_core = PowerGridCore()
577
+ return _thread_local_data.power_grid_core