Coverage for pyTooling / GenericPath / __init__.py: 97%
54 statements
« prev ^ index » next coverage.py v7.13.3, created at 2026-02-07 17:18 +0000
« prev ^ index » next coverage.py v7.13.3, created at 2026-02-07 17:18 +0000
1# ==================================================================================================================== #
2# _____ _ _ ____ _ ____ _ _ #
3# _ __ _ |_ _|__ ___ | (_)_ __ __ _ / ___| ___ _ __ ___ _ __(_) ___| _ \ __ _| |_| |__ #
4# | '_ \| | | || |/ _ \ / _ \| | | '_ \ / _` || | _ / _ \ '_ \ / _ \ '__| |/ __| |_) / _` | __| '_ \ #
5# | |_) | |_| || | (_) | (_) | | | | | | (_| || |_| | __/ | | | __/ | | | (__| __/ (_| | |_| | | | #
6# | .__/ \__, ||_|\___/ \___/|_|_|_| |_|\__, (_)____|\___|_| |_|\___|_| |_|\___|_| \__,_|\__|_| |_| #
7# |_| |___/ |___/ #
8# ==================================================================================================================== #
9# Authors: #
10# Patrick Lehmann #
11# #
12# License: #
13# ==================================================================================================================== #
14# Copyright 2017-2026 Patrick Lehmann - Bötzingen, Germany #
15# #
16# Licensed under the Apache License, Version 2.0 (the "License"); #
17# you may not use this file except in compliance with the License. #
18# You may obtain a copy of the License at #
19# #
20# http://www.apache.org/licenses/LICENSE-2.0 #
21# #
22# Unless required by applicable law or agreed to in writing, software #
23# distributed under the License is distributed on an "AS IS" BASIS, #
24# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
25# See the License for the specific language governing permissions and #
26# limitations under the License. #
27# #
28# SPDX-License-Identifier: Apache-2.0 #
29# ==================================================================================================================== #
30#
31"""A generic path to derive domain specific path libraries."""
32from typing import List, Optional as Nullable, Type
34from pyTooling.Decorators import export
35from pyTooling.MetaClasses import ExtendedType
38@export
39class Base(metaclass=ExtendedType, mixin=True):
40 """Base-mixin-class for all :mod:`pyTooling.GenericPath` path elements."""
42 DELIMITER = "/" #: Path element delimiter sign.
44 _parent: Nullable["Base"] #: Reference to the parent object.
46 def __init__(self, parent: Nullable["Base"] = None) -> None:
47 """
48 Initialize the base-mixin-class with a parent reference.
50 :param parent: Optional parent reference.
51 """
52 self._parent = parent
55@export
56class RootMixIn(Base, mixin=True):
57 """Mixin-class for root elements in a path system."""
59 def __init__(self) -> None:
60 """
61 Initialize the mixin-class for a root element.
62 """
63 super().__init__(None)
66@export
67class ElementMixIn(Base, mixin=True):
68 """Mixin-class for elements in a path system."""
70 _elementName: str #: Name of the path element.
72 def __init__(self, parent: Base, elementName: str) -> None:
73 """
74 Initialize the mixin-class for a path element.
76 :param parent: Reference to a parent path element.
77 :param elementName: Name of the path element.
78 """
79 super().__init__(parent)
81 self._elementName = elementName
83 def __str__(self) -> str:
84 return self._elementName
87@export
88class PathMixIn(metaclass=ExtendedType, mixin=True):
89 """Mixin-class for a path."""
91 ELEMENT_DELIMITER = "/" #: Path element delimiter sign.
92 ROOT_DELIMITER = "/" #: Root element delimiter sign.
94 _isAbsolute: bool #: True, if the path is absolute.
95 _elements: List[ElementMixIn] #: List of path elements.
97 def __init__(self, elements: List[ElementMixIn], isAbsolute: bool) -> None:
98 """
99 Initialize the mixin-class for a path.
101 :param elements: Reference to a parent path element.
102 :param isAbsolute: Assign to true, if a path is absolute, otherwise false.
103 """
104 self._isAbsolute = isAbsolute
105 self._elements = elements
107 def __len__(self) -> int:
108 """
109 Returns the number of path elements.
111 :returns: Number of path elements.
112 """
113 return len(self._elements)
115 def __str__(self) -> str:
116 result = self.ROOT_DELIMITER if self._isAbsolute else ""
118 if len(self._elements) > 0: 118 ↛ 124line 118 didn't jump to line 124 because the condition on line 118 was always true
119 result = result + str(self._elements[0])
121 for element in self._elements[1:]:
122 result = result + self.ELEMENT_DELIMITER + str(element)
124 return result
126 @classmethod
127 def Parse(
128 cls,
129 path: str,
130 root: RootMixIn,
131 pathCls: Type["PathMixIn"],
132 elementCls: Type[ElementMixIn]
133 ) -> "PathMixIn":
134 """
135 Parses a string representation of a path and returns a path instance.
137 :param path: Path to be parsed.
138 :param root:
139 :param pathCls: Type used to create the path.
140 :param elementCls: Type used to create the path elements.
141 :return:
142 """
143 if path.startswith(cls.ROOT_DELIMITER):
144 isAbsolute = True
145 path = path[len(cls.ELEMENT_DELIMITER):]
146 else:
147 isAbsolute = False
149 parent = root
150 elements = []
151 for part in path.split(cls.ELEMENT_DELIMITER):
152 element = elementCls(parent, part)
153 parent = element
154 elements.append(element)
156 return pathCls(elements, isAbsolute)
159@export
160class SystemMixIn(metaclass=ExtendedType, mixin=True):
161 """Mixin-class for a path system."""