From 3db69a1ff681f58484b66308428bc50d50b37ca4 Mon Sep 17 00:00:00 2001 From: cmoineau <cyril.moineau@cea.fr> Date: Fri, 23 Aug 2024 09:01:42 +0000 Subject: [PATCH] [ExportLib] Make _export_node_registry a classproperty, allowing to separate registry between instance. --- aidge_core/export_utils/export_registry.py | 63 +++++++++++++++------- 1 file changed, 45 insertions(+), 18 deletions(-) diff --git a/aidge_core/export_utils/export_registry.py b/aidge_core/export_utils/export_registry.py index 50699b484..ce8a8ae7e 100644 --- a/aidge_core/export_utils/export_registry.py +++ b/aidge_core/export_utils/export_registry.py @@ -1,35 +1,57 @@ -from typing import Dict, List, Set +from typing import Dict, List, Set, Type import aidge_core from aidge_core.export_utils import ExportNode - +from abc import ABC from enum import Enum # Language LANGUAGE = Enum('LANGUAGE', ['Cpp/C']) + +class classproperty: + """Helper class to define class properties, + Is equiavlent to applying the decorator ``@property`` and ``@classmethod``. + But these two decorator are exclusive with python > 12. + See discussion https://discuss.python.org/t/add-a-supported-read-only-classproperty-decorator-in-the-stdlib/18090/12 + """ + + def __init__(self, fget): + self.fget = fget + + def __get__(self, instance, owner): + return self.fget(owner) + + # TODO: very naive implementation ! # error handling should be added ! -class ExportLib(): # Should be abstract ? +class ExportLib(ABC): """Aidge export lib, define a registry """ # PUBLIC # Lib name usefull ? # Help define namespace - name:str = None + name: str = None # key: Path where static file is # Value: Path where to copy the file relative to the export root - static_files:Dict[str, str] = {} + static_files: Dict[str, str] = {} # PRIVATE - # Registry of exportNode - _export_node_registry:Dict[str, List[ExportNode]] = {} + # Registry of exportNode, class level dictionnary, shared accross all ExportLib + _cls_export_node_registry: Dict[Type, Dict[str, List['ExportNode']]] = {} + + @classproperty + def _export_node_registry(cls) -> Dict[str, List['ExportNode']]: + """Define as a class property to access the registry at class level while keeping it at instance level. + + :return: The export node registry specific to the class + :rtype: Dict[str, List[ExportNode]] + """ + return cls._cls_export_node_registry.setdefault(cls, {}) # The language type usefull ? _language: LANGUAGE = None - _compilo:str = None + _compilo: str = None - def __init__(self) -> None: - raise RuntimeError("ExportLib should not be instanciated") @classmethod - def exportable(cls, node:aidge_core.Node)->bool: + def exportable(cls, node: aidge_core.Node) -> bool: """ :param node: aidge_node to try to export :type node: aidge_core.Node @@ -44,15 +66,17 @@ class ExportLib(): # Should be abstract ? if i.exportable(node): return True return False + @classmethod - def supported_operators(cls)->Set[str]: + def supported_operators(cls) -> Set[str]: """ :return: Set of operator supported by this ExportLib :rtype: Set[str] """ return cls._export_node_registry.keys() + @classmethod - def get_export_node(cls, node:aidge_core.Node)->ExportNode: + def get_export_node(cls, node: aidge_core.Node) -> ExportNode: """ :param node: Node to transform :type node: :py:class:`aidge_core.Node` @@ -60,19 +84,23 @@ class ExportLib(): # Should be abstract ? :rtype: ExportNode """ if not cls.exportable(node): - raise ValueError(f"Node {node.type()} is not exportable by ExportLib {cls.name} !") + raise ValueError( + f"Node {node.type()} is not exportable by ExportLib {cls.name} !") if len(cls._export_node_registry[node.type()]) != 1: - raise RuntimeError("ExportLib registry doesn't support when multiple export node are available yet ...") + raise RuntimeError( + "ExportLib registry doesn't support when multiple export node are available yet ...") else: return cls._export_node_registry[node.type()][0] + @classmethod - def add_export_node(cls, key:str, eNode:ExportNode)->None: + def add_export_node(cls, key: str, eNode: ExportNode) -> None: if key not in cls._export_node_registry: cls._export_node_registry[key] = [eNode] else: cls._export_node_registry[key].append(eNode) -def operator_register(lib: ExportLib, key:str, *args): + +def operator_register(lib: ExportLib, key: str, *args): """Helper decorator to register an :py:class:`ExportNode` to an :py:class:`ExportLib` """ def decorator(operator): @@ -81,4 +109,3 @@ def operator_register(lib: ExportLib, key:str, *args): lib.add_export_node(key, operator) return wrapper return decorator - -- GitLab