datavalue 0.1.5__py3-none-any.whl → 0.1.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
datavalue/__init__.py CHANGED
@@ -1,2 +1,3 @@
1
1
  # Library import
2
- from .classes.primitive_data import PrimitiveData
2
+ from .classes.primitive_data import PrimitiveData
3
+ from .classes.complex_data import ComplexData
@@ -0,0 +1,130 @@
1
+ # Library import
2
+ from typing import Type, Optional, Any, Iterable
3
+ from .. import exceptions
4
+ from .primitive_data import PrimitiveData
5
+
6
+ # Classes definition
7
+ class ComplexData:
8
+ def __init__(self,
9
+ data_type: Type[list] | Type[tuple] | Type[set] | Type[frozenset] | Type[dict],
10
+ value: Any,
11
+ maximum_length: Optional[int] = None, minimum_length: Optional[int] = None,
12
+ possible_values: Optional[Iterable] = None,
13
+
14
+ data_class: Optional[bool] = False
15
+ ) -> None:
16
+ # Instance properties assignment
17
+ self.data_type = data_type
18
+ self.value = value
19
+ self.maximum_length = maximum_length; self.minimum_length = minimum_length
20
+ self.possible_values = possible_values
21
+ self.data_class = data_class
22
+
23
+ # Validate constructor parameters
24
+ if self.possible_values:
25
+ # Base validation: it has to be a collection
26
+ if not isinstance(self.possible_values, (list, tuple)):
27
+ raise ValueError(f"The possible values has to be a list/tuple. Received: {type(self.possible_values).__name__}")
28
+
29
+ # Validation to collections (list, tuple, set, frozenset)
30
+ if self.data_type != dict:
31
+ if not isinstance(self.possible_values, (list, tuple)):
32
+ raise ValueError(f"Possible values for {self.data_type.__name__} must be exactly one list/tuple containing the options.")
33
+
34
+ # Specific validation for dicts
35
+ else: # self.data_type == dict
36
+ if len(self.possible_values) not in (1, 2):
37
+ raise ValueError("Possible values for dict must be 1 (keys) or 2 (keys, values) list/tuples.")
38
+
39
+ # Validate the first element
40
+ if not isinstance(self.possible_values[0], (list, tuple)):
41
+ raise ValueError("The first element of possible_values for dict must be a list/tuple of keys.")
42
+
43
+ # Validate the second element
44
+ if len(self.possible_values) == 2 and not isinstance(self.possible_values[1], (list, tuple)):
45
+ raise ValueError("The second element of possible_values for dict must be a list/tuple of value validators.")
46
+
47
+ # Execute instance data validation
48
+ if not self.data_class:
49
+ self.validate()
50
+
51
+ # Private methods
52
+ def _is_match(self, element: Any, schema: Any) -> bool:
53
+ # Validate data types
54
+ if isinstance(schema, (PrimitiveData, ComplexData)):
55
+ try:
56
+ return schema.validate(element)
57
+ except:
58
+ return False
59
+
60
+ # Validate class data types
61
+ if isinstance(schema, type):
62
+ return isinstance(element, schema)
63
+
64
+ # Validate literal values
65
+ return element == schema
66
+
67
+ def _validate_collection(self, data: Any) -> bool:
68
+ element_index: int = 0
69
+ for element in data:
70
+ if not any(self._is_match(element, validator) for validator in self.possible_values):
71
+ raise ValueError(f"[ComplexData] Element: {element}, on index: {element_index} is not allowed.")
72
+ element_index += 1
73
+
74
+ # Return results
75
+ return True
76
+
77
+ def _validate_dictionary(self, data: Any) -> bool:
78
+ # Validate keys and (if applies) values
79
+ if not isinstance(self.possible_values, (list, tuple)) or len(self.possible_values) != 2:
80
+ keys_schema = self.possible_values
81
+ values_schema = None
82
+ else:
83
+ keys_schema, values_schema = self.possible_values
84
+
85
+ for key, value in data.items():
86
+ # Validación de Claves (Debe ser un iterable de opciones)
87
+ if keys_schema:
88
+ if not any(self._is_match(key, validator) for validator in keys_schema):
89
+ raise ValueError(f"[ComplexData] Invalid key: {key}")
90
+
91
+ # Validación de Valores
92
+ if values_schema:
93
+ if not any(self._is_match(value, validator) for validator in values_schema):
94
+ raise ValueError(f"[ComplexData] Invalid value '{value}' for key '{key}'")
95
+
96
+ return True
97
+
98
+ # Public methods
99
+ def validate(self, data: Any = None) -> bool:
100
+ # Determine objective data
101
+ if data is None:
102
+ objective_data = self.value
103
+ else:
104
+ objective_data = data
105
+
106
+ # Data type validation
107
+ if not isinstance(objective_data, self.data_type):
108
+ raise exceptions.DataTypeException(
109
+ f"Incorrect data type.\nExpected: {self.data_type.__name__} - Received: {type(objective_data).__name__}"
110
+ )
111
+
112
+ # Length validation
113
+ current_length = len(objective_data)
114
+
115
+ if self.minimum_length is not None and current_length < self.minimum_length:
116
+ raise ValueError(f"Minimum length not reached: {current_length} < {self.minimum_length}")
117
+
118
+ if self.maximum_length is not None and current_length > self.maximum_length:
119
+ raise ValueError(f"Maximum length reached: {current_length} > {self.maximum_length}")
120
+
121
+ # Content validation and recurse
122
+ if self.possible_values:
123
+ # Validate dictionaries
124
+ if isinstance(objective_data, dict):
125
+ self._validate_dictionary(objective_data)
126
+ else:
127
+ self._validate_collection(objective_data)
128
+
129
+ # Return results
130
+ return True
@@ -2,6 +2,7 @@
2
2
  import re
3
3
  from typing import Type, Optional, Any, Iterable, Union
4
4
  from .. import exceptions
5
+ import json
5
6
 
6
7
  # Classes definition
7
8
  class PrimitiveData:
@@ -54,6 +55,18 @@ class PrimitiveData:
54
55
  "REGULAR_EXPRESSION":self.regular_expression,
55
56
  "DATA_CLASS":self.data_class
56
57
  }
58
+
59
+ def to_json(self) -> str:
60
+ return json.dumps(self.to_dict(), indent=4)
61
+
62
+ def from_json(self, text_content: str) -> dict:
63
+ data_table = json.loads(text_content)
64
+ local_table = self.to_dict()
65
+
66
+ for element in data_table:
67
+ if element not in local_table: raise ValueError(f"The loaded table has a unknown value: {element}")
68
+
69
+ return data_table
57
70
 
58
71
  def validate(self, data: Optional[Any] = None) -> bool:
59
72
  # Define the data to validate
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: datavalue
3
- Version: 0.1.5
3
+ Version: 0.1.6
4
4
  Summary: Librería de tipos de datos primitivos y complejos
5
5
  Author: Specter
6
6
  Requires-Python: >=3.10
@@ -0,0 +1,9 @@
1
+ datavalue/__init__.py,sha256=-JBKpLEehjnezX3sTbpnB2px3izjHxZ_IEL_40iRHMM,112
2
+ datavalue/classes/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
3
+ datavalue/classes/complex_data.py,sha256=Z6LjGqjXyGLjzrAVs09M4NfQz9P7H-ZIrijR1s-Mg_0,5581
4
+ datavalue/classes/primitive_data.py,sha256=2IPScXGKuam32jdx1hbk0VxKS3mowwSBdM45Iigir3k,5691
5
+ datavalue/exceptions/__init__.py,sha256=T9X1N0kAv6RNTuTNQR7aTAxxvF25ihMsrtZGD-QZrBI,361
6
+ datavalue-0.1.6.dist-info/METADATA,sha256=rSve4eGV5Wh8RpQRvp5Ig-wWH2RZjHkYMj93C-qNSrY,1597
7
+ datavalue-0.1.6.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
8
+ datavalue-0.1.6.dist-info/top_level.txt,sha256=tVZ_--yYzvlZ2XTCkdORn4KKL7BwXPZUOVpL6PBJaRY,10
9
+ datavalue-0.1.6.dist-info/RECORD,,
@@ -1,9 +0,0 @@
1
- datavalue/__init__.py,sha256=QHthd6CQaDPqpvS3ay1r_Z7WvIleUXbTAottuML8nPA,66
2
- datavalue/classes/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
3
- datavalue/classes/primitive_data.py,sha256=qsKlds33RqR0bIGjy-5kgZdNBcrBMITbrvVx4HqeO-M,5281
4
- datavalue/exceptions/__init__.py,sha256=T9X1N0kAv6RNTuTNQR7aTAxxvF25ihMsrtZGD-QZrBI,361
5
- tests/test.py,sha256=8-AhuPJk0Yxt49MmbbdqGamhWM87T9mkbfmIU3BZZJk,1845
6
- datavalue-0.1.5.dist-info/METADATA,sha256=71CLQrhr8mhSMINt4ha0p1PxHdOtOcPRIKGWss2LvD0,1597
7
- datavalue-0.1.5.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
8
- datavalue-0.1.5.dist-info/top_level.txt,sha256=zlD2cuGB4gcH2hf8HIBij-0hqp_7e-c2e5nn6-A9j1Y,16
9
- datavalue-0.1.5.dist-info/RECORD,,
tests/test.py DELETED
@@ -1,62 +0,0 @@
1
- # Library import
2
- from datavalue import PrimitiveData
3
-
4
- # Phone number validation
5
- print("="*10)
6
- print("Validating phone number...")
7
- phone_number = PrimitiveData(
8
- data_type=str,
9
- value="+34600111222",
10
- minimum_length=7, # Minimum character length
11
- maximum_length=15, # Maximum character length
12
- minimum_size=None, # Not validate the minimum number
13
- maximum_size=None, # Not validate the maximum number,
14
- possible_values=None, # Not specify obligatory possible values
15
- regular_expression=r"^\+[1-9]\d{6,14}$"
16
- )
17
-
18
- print("Phone number validated sucessfully:", phone_number.value)
19
-
20
- # Connection port validation
21
- print("="*10)
22
- print("Validating connection port...")
23
- connection_port = PrimitiveData(
24
- data_type=int,
25
- value=45321,
26
- minimum_length=1, # Maximum digits
27
- maximum_length=5, # Minimum digits
28
- minimum_size=1, # Minimum numerical value
29
- maximum_size=65535, # Maximum numerical value
30
- possible_values=None, # Possible options
31
- regular_expression=None # Regular expression applied
32
- )
33
- print("Connection port validated:", connection_port.value)
34
-
35
- # Transport protocol validation
36
- print("="*10)
37
- print("Validating transport protocol...")
38
- transport_protocol = PrimitiveData(
39
- data_type=str,
40
- value="TCP",
41
- maximum_length=None,
42
- minimum_length=None,
43
- minimum_size=None,
44
- maximum_size=None,
45
- possible_values=("TCP", "UDP"),
46
- regular_expression=None
47
- )
48
- print("Transport protocol validated:", transport_protocol.value)
49
-
50
- # Validating IPv4 address
51
- print("="*10)
52
- print("Validating IPv4 address...")
53
- ip_address = PrimitiveData(
54
- data_type=str,
55
- value="192.168.0.1",
56
- maximum_length=15,
57
- minimum_length=7,
58
- maximum_size=None, minimum_size=None,
59
- possible_values=None,
60
- regular_expression=r"^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"
61
- )
62
- print("IPv4 address validated:", ip_address.value)