Coverage for klayout_pex/pex25d/importers.py: 100%

24 statements  

« prev     ^ index     » next       coverage.py v7.17.2, created at 2026-11-06 13:14 +0000

1# 

2# -------------------------------------------------------------------------------- 

3# SPDX-FileCopyrightText: 2024-2026 Martin Jan Köhler and Harald Pretl 

4# Johannes Kepler University, Institute for Integrated Circuits. 

5# 

6# This file is part of KPEX 

7# (see https://github.com/iic-jku/klayout-pex). 

8# 

9# This program is free software: you can redistribute it and/or modify 

10# it under the terms of the GNU General Public License as published by 

11# the Free Software Foundation, either version 3 of the License, or 

12# (at your option) any later version. 

13# 

14# This program is distributed in the hope that it will be useful, 

15# but WITHOUT ANY WARRANTY; without even the implied warranty of 

16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

17# GNU General Public License for more details. 

18# 

19# You should have received a copy of the GNU General Public License 

20# along with this program. If not, see <http://www.gnu.org/licenses/>. 

21# SPDX-License-Identifier: GPL-3.0-or-later 

22# -------------------------------------------------------------------------------- 

23# 

24 

25""" 

26Translation of external scene descriptions into an unresolved ``PEX25DFile``. 

27 

28The CLI exposes this operation as ``pex25d import``. Importers are plugins in the 

29``klayout_pex.importers.v1`` entry-point group; the built-in ``openrcx-uf`` is a stub. 

30Resolving and validating the result stay with the caller. 

31""" 

32 

33from __future__ import annotations 

34 

35from typing import * 

36 

37from ..plugin_api.v1 import ImporterError, ImporterUnavailable, PEX25DImporter 

38from . import protobuf 

39 

40if TYPE_CHECKING: 

41 from ..plugin.importer_registry import ImporterRegistry 

42 from klayout_pex_protobuf.kpex.pex25d.pex25d_file_pb2 import PEX25DFile 

43 

44 from .diagnostics import DiagnosticsReport 

45 

46 

47class ImporterExecutionError(ImporterError): 

48 """An importer crashed or returned no PEX25DFile; any original exception is the cause.""" 

49 

50 

51def import_file(input_file_path: str, 

52 source: str, 

53 *, 

54 supporting_files: Optional[Mapping[str, str]] = None, 

55 options: Optional[Mapping[str, Any]] = None, 

56 report: Optional[DiagnosticsReport] = None, 

57 registry: Optional[ImporterRegistry] = None) -> PEX25DFile: 

58 """ 

59 Import ``input_file_path`` with the importer ``source`` as an unresolved PEX25DFile. 

60 

61 ``source`` is an importer entry-point name or a qualified ``distribution:name``. 

62 Supporting-file keys and options are defined by the importer, which validates 

63 them. Pass a registry to reuse its metadata snapshot across multiple imports. 

64 

65 ImporterError, NotImplementedError and OSError pass through unchanged; unexpected 

66 exceptions, and results that are not a PEX25DFile, become ImporterExecutionError. 

67 """ 

68 registry = registry if registry is not None else importer_registry() 

69 backend = registry.load(source) 

70 provider = registry.get_info(source).qualified_name 

71 try: 

72 result = backend.import_file(input_file_path, 

73 supporting_files=supporting_files, 

74 options=options, 

75 report=report) 

76 except (ImporterError, NotImplementedError, OSError): 

77 raise 

78 except Exception as exc: 

79 raise ImporterExecutionError( 

80 f"Importer '{provider}' crashed: {type(exc).__name__}: {exc}") from exc 

81 

82 if not isinstance(result, protobuf.pex25d_file_pb2().PEX25DFile): 

83 raise ImporterExecutionError( 

84 f"Importer '{provider}' returned {type(result).__name__}, not a PEX25DFile") 

85 return result 

86 

87 

88def importer_registry() -> ImporterRegistry: 

89 """Discover installed importers alongside the built-in implementations.""" 

90 from ..plugin.importer_registry import ImporterRegistry 

91 return ImporterRegistry({ 

92 'openrcx-uf': create_openrcx_uf_importer, 

93 }) 

94 

95 

96def create_openrcx_uf_importer() -> PEX25DImporter: 

97 """OpenRCX Universal Pattern Format input: a stub, not implemented yet. 

98 

99 Imports raise NotImplementedError; ``klayout_pex/openrcx/pex25d_importer.py`` 

100 holds the template for the implementation. 

101 """ 

102 from ..openrcx.pex25d_importer import OpenRCXUFImporter 

103 return OpenRCXUFImporter()