|
| 1 | +# SPDX-FileCopyrightText: Copyright DB InfraGO AG |
| 2 | +# SPDX-License-Identifier: Apache-2.0 |
| 3 | + |
| 4 | +__all__ = [ |
| 5 | + "Element", |
| 6 | + "FragmentType", |
| 7 | + "Loader", |
| 8 | + "ModelInfo", |
| 9 | +] |
| 10 | + |
| 11 | +import dataclasses |
| 12 | +import enum |
| 13 | +import pathlib |
| 14 | +from collections.abc import Iterator, Mapping |
| 15 | +from contextlib import AbstractContextManager |
| 16 | +from typing import TYPE_CHECKING, Any, Generic, Protocol, TypeAlias, TypeVar |
| 17 | + |
| 18 | +from lxml import etree |
| 19 | +from typing_extensions import Self |
| 20 | + |
| 21 | +from capellambse import filehandler |
| 22 | + |
| 23 | +_E_co = TypeVar("_E_co", covariant=True, bound="Element") |
| 24 | +_E = TypeVar("_E", bound="Element") |
| 25 | +_Q = TypeVar("_Q") |
| 26 | +Loader: TypeAlias = ( |
| 27 | + "_Loader[Element, etree.QName] | _Loader[etree._Element, etree.QName]" |
| 28 | +) |
| 29 | + |
| 30 | + |
| 31 | +class FragmentType(enum.Enum): |
| 32 | + """The type of an XML fragment.""" |
| 33 | + |
| 34 | + SEMANTIC = enum.auto() |
| 35 | + VISUAL = enum.auto() |
| 36 | + OTHER = enum.auto() |
| 37 | + |
| 38 | + |
| 39 | +@dataclasses.dataclass |
| 40 | +class ModelInfo: |
| 41 | + url: str | None |
| 42 | + title: str | None |
| 43 | + entrypoint: pathlib.PurePosixPath |
| 44 | + resources: dict[str, filehandler.abc.HandlerInfo] |
| 45 | + capella_version: str |
| 46 | + viewpoints: dict[str, str] |
| 47 | + |
| 48 | + |
| 49 | +class _Tree(Protocol[_E_co, _Q]): |
| 50 | + @property |
| 51 | + def root(self) -> _E_co: ... |
| 52 | + @property |
| 53 | + def fragment_type(self) -> FragmentType: ... |
| 54 | + |
| 55 | + def iterall(self, /) -> Iterator[_E_co]: ... |
| 56 | + def iter_qtypes(self, /) -> Iterator[_Q]: ... |
| 57 | + def iter_qtype(self, qtype: _Q, /) -> Iterator[_E_co]: ... |
| 58 | + |
| 59 | + def add_namespace(self, uri: str, alias: str, /) -> str: ... |
| 60 | + |
| 61 | + |
| 62 | +class _Loader(Protocol, Generic[_E, _Q]): |
| 63 | + @property |
| 64 | + def trees(self) -> Mapping[pathlib.PurePosixPath, _Tree[_E, _Q]]: ... |
| 65 | + @property |
| 66 | + def resources(self) -> dict[str, filehandler.FileHandler]: ... |
| 67 | + |
| 68 | + def get_model_info(self, /) -> ModelInfo: ... |
| 69 | + |
| 70 | + def find_fragment(self, elem: _E, /) -> pathlib.PurePosixPath: ... |
| 71 | + def iterancestors(self, elem: _E, /) -> Iterator[_E]: ... |
| 72 | + def iterdescendants(self, elem: _E, /) -> Iterator[_E]: ... |
| 73 | + def iterchildren(self, elem: _E, tag: str, /) -> Iterator[_E]: ... |
| 74 | + def find_references(self, target_id: str, /) -> Iterator[_E]: ... |
| 75 | + |
| 76 | + def create_link( |
| 77 | + self, |
| 78 | + source: _E, |
| 79 | + target: _E, |
| 80 | + *, |
| 81 | + include_target_type: bool | None = None, |
| 82 | + ) -> str: ... |
| 83 | + def follow_link(self, source: _E | None, id: str, /) -> _E: ... |
| 84 | + def follow_links( |
| 85 | + self, |
| 86 | + source: _E, |
| 87 | + id_list: str, |
| 88 | + /, |
| 89 | + *, |
| 90 | + ignore_broken: bool = ..., |
| 91 | + ) -> list[_E]: ... |
| 92 | + |
| 93 | + def new_uuid( |
| 94 | + self, |
| 95 | + parent: _E, |
| 96 | + /, |
| 97 | + *, |
| 98 | + want: str | None = ..., |
| 99 | + ) -> AbstractContextManager[str]: ... |
| 100 | + def idcache_index(self, subtree: _E, /) -> None: ... |
| 101 | + def idcache_remove(self, subtree: _E, /) -> None: ... |
| 102 | + def idcache_rebuild(self, /) -> None: ... |
| 103 | + |
| 104 | + def activate_viewpoint(self, name: str, version: str, /) -> None: ... |
| 105 | + def update_namespaces(self, /) -> None: ... |
| 106 | + def save(self, /, **kw: Any) -> None: ... |
| 107 | + |
| 108 | + def write_tmp_project_dir( |
| 109 | + self, / |
| 110 | + ) -> AbstractContextManager[pathlib.Path]: ... |
| 111 | + |
| 112 | + |
| 113 | +class Element(Protocol): |
| 114 | + @property |
| 115 | + def tag(self) -> str: ... |
| 116 | + |
| 117 | + def iterchildren(self, tag: str = ..., /) -> Iterator[Self]: ... |
| 118 | + |
| 119 | + |
| 120 | +if TYPE_CHECKING: |
| 121 | + |
| 122 | + def __protocol_compliance_check() -> None: |
| 123 | + from capellambse import loader # noqa: PLC0415 |
| 124 | + |
| 125 | + tree: _Tree |
| 126 | + tree = loader.ModelFile() # type: ignore[call-arg] |
| 127 | + del tree |
| 128 | + |
| 129 | + elm: Element |
| 130 | + elm = etree._Element() |
| 131 | + del elm |
| 132 | + |
| 133 | + ldr: Loader |
| 134 | + ldr = loader.MelodyLoader() # type: ignore[call-arg] |
| 135 | + del ldr |
0 commit comments