|  | @@ -0,0 +1,104 @@
 | 
	
		
			
				|  |  | +from .exception import pini_exception
 | 
	
		
			
				|  |  | +from .exception import pini_type_exception
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +class key:
 | 
	
		
			
				|  |  | +    def __init__(self):
 | 
	
		
			
				|  |  | +        self.__name: str | None = None
 | 
	
		
			
				|  |  | +        self.__value: str | int | float | None = None
 | 
	
		
			
				|  |  | +        self.__comment: str | None = None
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @property
 | 
	
		
			
				|  |  | +    def name(self) -> str | None:
 | 
	
		
			
				|  |  | +        return self.__name
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @property
 | 
	
		
			
				|  |  | +    def value(self) -> str | int | float | None:
 | 
	
		
			
				|  |  | +        return self.__value
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @property
 | 
	
		
			
				|  |  | +    def comment(self) -> str | None:
 | 
	
		
			
				|  |  | +        return self.__comment
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @property
 | 
	
		
			
				|  |  | +    def value_type(self) -> str:
 | 
	
		
			
				|  |  | +        if self.__value is None:
 | 
	
		
			
				|  |  | +            return "None"
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return type(self.__value).__name__
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @name.setter
 | 
	
		
			
				|  |  | +    def name(self, target: str | None) -> None:
 | 
	
		
			
				|  |  | +        if type(target) is str:
 | 
	
		
			
				|  |  | +            target = target.strip()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if target is not None and type(target) is not str:
 | 
	
		
			
				|  |  | +            raise TypeError("Name of the key must be str or None.")
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        self.__name = target
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @value.setter
 | 
	
		
			
				|  |  | +    def value(self, target: str | int | float | None) -> None:
 | 
	
		
			
				|  |  | +        if type(target) is str:
 | 
	
		
			
				|  |  | +            self.__value = target.strip()
 | 
	
		
			
				|  |  | +            return
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +        if type(target) is int or type(target) is float or target is None:
 | 
	
		
			
				|  |  | +            self.__value = target
 | 
	
		
			
				|  |  | +            return
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        raise TypeError("Value must be str, int, float or None.")
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @comment.setter
 | 
	
		
			
				|  |  | +    def comment(self, target: str | None) -> None:
 | 
	
		
			
				|  |  | +        if type(target) is str:
 | 
	
		
			
				|  |  | +            target = target.strip()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if type(target) is not str and target is not None:
 | 
	
		
			
				|  |  | +            raise TypeError("Comment must be str or None.")
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        self.__comment = target
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    def get(self, empty: str | int | float | None) -> str | int | float | None:
 | 
	
		
			
				|  |  | +        checked = type(empty) is str
 | 
	
		
			
				|  |  | +        checked = checked or type(empty) is int
 | 
	
		
			
				|  |  | +        checked = checked or type(empty) is float
 | 
	
		
			
				|  |  | +        checked = checked or empty is None
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if not checked:
 | 
	
		
			
				|  |  | +            raise TypeError("Default value for empty key type is not valid.")
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if self.__value is None:
 | 
	
		
			
				|  |  | +            return empty
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if type(empty) is not type(self.__value):
 | 
	
		
			
				|  |  | +            error = "Type of the " + self.name + " is not valid. "
 | 
	
		
			
				|  |  | +            error = error + "It must be in " + type(empty).__name__ + ". "
 | 
	
		
			
				|  |  | +            error = error + "It is " + type(self.__value).__name__ + "."
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            raise pini_type_exception(error)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return self.__value
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    def __str__(self) -> str:
 | 
	
		
			
				|  |  | +        comment = ""
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        if self.__comment is not None:
 | 
	
		
			
				|  |  | +            comment = "# " + self.__comment
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if self.__name is None:
 | 
	
		
			
				|  |  | +            return comment
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        content = self.__name + " = "
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if self.__value is not None:
 | 
	
		
			
				|  |  | +            content = content + str(self.__value)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if self.__value is None:
 | 
	
		
			
				|  |  | +            content = "### " + content
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        if len(comment) > 0:
 | 
	
		
			
				|  |  | +            content = content + (" " * (4 - (len(content) % 4)))
 | 
	
		
			
				|  |  | +            content = content + comment
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return content
 | 
	
		
			
				|  |  | +
 |