xref: /openbmc/sdbusplus/tools/sdbusplus/path.py (revision 3baa3045)
1import re
2
3from .namedelement import NamedElement
4
5""" Class for parsing 'path' definition elements from an interface.
6"""
7
8
9class Path(NamedElement):
10    def __init__(self, segment=False, **kwargs):
11        if "namespace" in kwargs:
12            kwargs["name"] = "NamespacePath"
13            self.value = kwargs.pop("namespace")
14        elif "instance" in kwargs:
15            kwargs["name"] = "InstancePath"
16            self.value = kwargs.pop("instance")
17        else:
18            self.value = kwargs.pop("value", "")
19
20        # Validate path/segment format.
21        if len(self.value) == 0:
22            if segment:
23                self.value = NamedElement(name=kwargs["name"]).snake_case
24            else:
25                raise ValueError("Invalid empty path.")
26        if not segment and self.value[0] != "/":
27            raise ValueError(f"Paths must start with /: {self.value}")
28        if segment and self.value[0] == "/":
29            raise ValueError(f"Segments cannot start with /: {self.value}")
30        segments = self.value.split("/")
31        if not segment:
32            segments = segments[1:]
33        for s in segments:
34            if len(s) == 0:
35                raise ValueError(
36                    f"Paths cannot have consecutive /: {self.value} {s}"
37                )
38            if re.search("[^a-zA-Z0-9_]", s):
39                raise ValueError(
40                    f"Path contains illegal characters: {self.value}"
41                )
42
43        self.segments = [
44            Path(segment=True, **s) for s in kwargs.pop("segments", [])
45        ]
46
47        super(Path, self).__init__(**kwargs)
48