PySerials 0.0.0.dev1__tar.gz → 0.0.0.dev3__tar.gz

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.
Files changed (22) hide show
  1. {PySerials-0.0.0.dev1 → pyserials-0.0.0.dev3}/PKG-INFO +2 -2
  2. {PySerials-0.0.0.dev1 → pyserials-0.0.0.dev3}/pyproject.toml +2 -2
  3. {PySerials-0.0.0.dev1 → pyserials-0.0.0.dev3}/src/PySerials.egg-info/PKG-INFO +2 -2
  4. {PySerials-0.0.0.dev1 → pyserials-0.0.0.dev3}/src/PySerials.egg-info/SOURCES.txt +6 -2
  5. {PySerials-0.0.0.dev1 → pyserials-0.0.0.dev3}/src/PySerials.egg-info/requires.txt +1 -1
  6. pyserials-0.0.0.dev3/src/pyserials/exception/__init__.py +4 -0
  7. pyserials-0.0.0.dev3/src/pyserials/exception/_base.py +10 -0
  8. pyserials-0.0.0.dev3/src/pyserials/exception/read.py +119 -0
  9. pyserials-0.0.0.dev3/src/pyserials/exception/update.py +131 -0
  10. pyserials-0.0.0.dev3/src/pyserials/exception/validate.py +73 -0
  11. {PySerials-0.0.0.dev1 → pyserials-0.0.0.dev3}/src/pyserials/read.py +7 -16
  12. {PySerials-0.0.0.dev1 → pyserials-0.0.0.dev3}/src/pyserials/update.py +15 -7
  13. {PySerials-0.0.0.dev1 → pyserials-0.0.0.dev3}/src/pyserials/validate.py +39 -13
  14. {PySerials-0.0.0.dev1 → pyserials-0.0.0.dev3}/src/pyserials/write.py +9 -1
  15. PySerials-0.0.0.dev1/src/pyserials/exception.py +0 -140
  16. {PySerials-0.0.0.dev1 → pyserials-0.0.0.dev3}/README.md +0 -0
  17. {PySerials-0.0.0.dev1 → pyserials-0.0.0.dev3}/setup.cfg +0 -0
  18. {PySerials-0.0.0.dev1 → pyserials-0.0.0.dev3}/src/PySerials.egg-info/dependency_links.txt +0 -0
  19. {PySerials-0.0.0.dev1 → pyserials-0.0.0.dev3}/src/PySerials.egg-info/not-zip-safe +0 -0
  20. {PySerials-0.0.0.dev1 → pyserials-0.0.0.dev3}/src/PySerials.egg-info/top_level.txt +0 -0
  21. {PySerials-0.0.0.dev1 → pyserials-0.0.0.dev3}/src/pyserials/__init__.py +0 -0
  22. {PySerials-0.0.0.dev1 → pyserials-0.0.0.dev3}/src/pyserials/format.py +0 -0
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PySerials
3
- Version: 0.0.0.dev1
3
+ Version: 0.0.0.dev3
4
4
  Requires-Python: >=3.10
5
- Requires-Dist: jsonschema<5,>=4.19
5
+ Requires-Dist: jsonschema<5,>=4.21.0
6
6
  Requires-Dist: ruamel.yaml<0.18,>=0.17.32
7
7
  Requires-Dist: ruamel.yaml.string<1,>=0.1.1
8
8
  Requires-Dist: tomlkit<0.12,>=0.11.8
@@ -17,10 +17,10 @@ namespaces = true
17
17
  # ----------------------------------------- Project Metadata -------------------------------------
18
18
  #
19
19
  [project]
20
- version = "0.0.0.dev1"
20
+ version = "0.0.0.dev3"
21
21
  name = "PySerials"
22
22
  dependencies = [
23
- "jsonschema >= 4.19, < 5",
23
+ "jsonschema >= 4.21.0, < 5",
24
24
  "ruamel.yaml >= 0.17.32, < 0.18", # https://yaml.readthedocs.io/en/stable/
25
25
  "ruamel.yaml.string >= 0.1.1, < 1",
26
26
  "tomlkit >= 0.11.8, < 0.12", # https://tomlkit.readthedocs.io/en/stable/,
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PySerials
3
- Version: 0.0.0.dev1
3
+ Version: 0.0.0.dev3
4
4
  Requires-Python: >=3.10
5
- Requires-Dist: jsonschema<5,>=4.19
5
+ Requires-Dist: jsonschema<5,>=4.21.0
6
6
  Requires-Dist: ruamel.yaml<0.18,>=0.17.32
7
7
  Requires-Dist: ruamel.yaml.string<1,>=0.1.1
8
8
  Requires-Dist: tomlkit<0.12,>=0.11.8
@@ -7,9 +7,13 @@ src/PySerials.egg-info/not-zip-safe
7
7
  src/PySerials.egg-info/requires.txt
8
8
  src/PySerials.egg-info/top_level.txt
9
9
  src/pyserials/__init__.py
10
- src/pyserials/exception.py
11
10
  src/pyserials/format.py
12
11
  src/pyserials/read.py
13
12
  src/pyserials/update.py
14
13
  src/pyserials/validate.py
15
- src/pyserials/write.py
14
+ src/pyserials/write.py
15
+ src/pyserials/exception/__init__.py
16
+ src/pyserials/exception/_base.py
17
+ src/pyserials/exception/read.py
18
+ src/pyserials/exception/update.py
19
+ src/pyserials/exception/validate.py
@@ -1,4 +1,4 @@
1
- jsonschema<5,>=4.19
1
+ jsonschema<5,>=4.21.0
2
2
  ruamel.yaml<0.18,>=0.17.32
3
3
  ruamel.yaml.string<1,>=0.1.1
4
4
  tomlkit<0.12,>=0.11.8
@@ -0,0 +1,4 @@
1
+ """Exceptions raised by PySerials."""
2
+
3
+ from pyserials.exception._base import PySerialsException
4
+ from pyserials.exception import read, update, validate
@@ -0,0 +1,10 @@
1
+ """PySerials base Exception class."""
2
+
3
+
4
+ class PySerialsException(Exception):
5
+ """Base class for all exceptions raised by PySerials."""
6
+
7
+ def __init__(self, message: str):
8
+ self.message = message
9
+ super().__init__(message)
10
+ return
@@ -0,0 +1,119 @@
1
+ """Exceptions raised by `pyserials.read` module."""
2
+
3
+
4
+ from typing import Literal as _Literal
5
+ from pathlib import Path as _Path
6
+
7
+ from pyserials.exception._base import PySerialsException as _PySerialsException
8
+
9
+
10
+ class PySerialsReadException(_PySerialsException):
11
+ """Base class for all exceptions raised by `pyserials.read` module."""
12
+
13
+ def __init__(self, message: str, source_type: _Literal["file", "string"]):
14
+ super().__init__(message=f"Failed to read data from {source_type}. {message}.")
15
+ return
16
+
17
+
18
+ class PySerialsReadFromFileException(PySerialsReadException):
19
+ """Base class for all exceptions raised when reading data from a file.
20
+
21
+ Attributes
22
+ ----------
23
+ filepath : pathlib.Path
24
+ The path of the input datafile.
25
+ """
26
+ def __init__(self, message: str, filepath: _Path):
27
+ super().__init__(message=message, source_type="file")
28
+ self.filepath: _Path = filepath
29
+ return
30
+
31
+
32
+ class PySerialsReadFromStringException(PySerialsReadException):
33
+ """Base class for all exceptions raised when reading data from a string.
34
+
35
+ Attributes
36
+ ----------
37
+ data_type : {"json", "yaml", "toml"}
38
+ The type of data.
39
+ """
40
+
41
+ def __init__(self, message: str, data_type: _Literal["json", "yaml", "toml"]):
42
+ super().__init__(message=message, source_type="string")
43
+ self.data_type = data_type
44
+ return
45
+
46
+
47
+ class PySerialsInvalidFileExtensionError(PySerialsReadFromFileException):
48
+ """Exception raised when a file to be read has an unrecognized extension."""
49
+
50
+ def __init__(self, filepath: _Path):
51
+ message = (
52
+ f"The extension of the file at '{filepath}' is invalid; "
53
+ f"expected one of 'json', 'yaml', or 'toml', but got '{filepath.suffix.removeprefix('.')}'. "
54
+ "Please provide the extension explicitly, or rename the file to have a valid extension."
55
+ )
56
+ super().__init__(message=message, filepath=filepath)
57
+ return
58
+
59
+
60
+ class PySerialsMissingFileError(PySerialsReadFromFileException):
61
+ """Exception raised when a file to be read does not exist."""
62
+
63
+ def __init__(self, filepath: _Path):
64
+ message = f"The file at '{filepath}' does not exist."
65
+ super().__init__(message=message, filepath=filepath)
66
+ return
67
+
68
+
69
+ class PySerialsEmptyFileError(PySerialsReadFromFileException):
70
+ """Exception raised when a file to be read is empty."""
71
+
72
+ def __init__(self, filepath: _Path):
73
+ message = f"The file at '{filepath}' is empty."
74
+ super().__init__(message=message, filepath=filepath)
75
+ return
76
+
77
+
78
+ class PySerialsInvalidDataFileError(PySerialsReadFromFileException):
79
+ """Exception raised when a file to be read is invalid.
80
+
81
+ Attributes
82
+ ----------
83
+ data : str
84
+ The input data that was supposed to be read.
85
+ data_type : {"json", "yaml", "toml"}
86
+ The type of data.
87
+ """
88
+
89
+ def __init__(self, filepath: _Path, data_type: _Literal["json", "yaml", "toml"], data: str):
90
+ message = f"The {data_type} file at '{filepath}' is invalid."
91
+ super().__init__(message=message, filepath=filepath)
92
+ self.data = data
93
+ self.data_type = data_type
94
+ return
95
+
96
+
97
+ class PySerialsEmptyStringError(PySerialsReadFromStringException):
98
+ """Exception raised when a string to be read is empty."""
99
+
100
+ def __init__(self, data_type: _Literal["json", "yaml", "toml"]):
101
+ message = f"The {data_type} string is empty."
102
+ super().__init__(message=message, data_type=data_type)
103
+ return
104
+
105
+
106
+ class PySerialsInvalidDataStringError(PySerialsReadFromStringException):
107
+ """Exception raised when a string to be read is invalid.
108
+
109
+ Attributes
110
+ ----------
111
+ data : str
112
+ The input data that was supposed to be read.
113
+ """
114
+
115
+ def __init__(self, data_type: _Literal["json", "yaml", "toml"], data: str):
116
+ message = f"The {data_type} string is invalid."
117
+ super().__init__(message=message, data_type=data_type)
118
+ self.data = data
119
+ return
@@ -0,0 +1,131 @@
1
+ """Exceptions raised by `pyserials.update` module."""
2
+
3
+ from typing import Any as _Any
4
+
5
+ from pyserials.exception._base import PySerialsException as _PySerialsException
6
+
7
+
8
+ class PySerialsUpdateException(_PySerialsException):
9
+ """Base class for all exceptions raised by `pyserials.update` module."""
10
+
11
+ def __init__(self, message: str):
12
+ super().__init__(f"Failed to update data. {message}.")
13
+ return
14
+
15
+
16
+ class PySerialsUpdateDictFromAddonException(PySerialsUpdateException):
17
+ """Base class for all exceptions raised by `pyserials.update.dict_from_addon`.
18
+
19
+ Attributes
20
+ ----------
21
+ address : str
22
+ The address of the data that failed to update.
23
+ value_data : Any
24
+ The value of the data in the source dictionary.
25
+ value_addon : Any
26
+ The value of the data in the addon dictionary.
27
+ """
28
+
29
+ def __init__(
30
+ self,
31
+ message: str,
32
+ address: str,
33
+ value_data: _Any,
34
+ value_addon: _Any,
35
+ ):
36
+ super().__init__(message=message)
37
+ self.address = address
38
+ self.value_data = value_data
39
+ self.value_addon = value_addon
40
+ return
41
+
42
+
43
+ class PySerialsUpdateTemplatedDataException(PySerialsUpdateException):
44
+ """Base class for all exceptions raised by `pyserials.update.templated_data_from_source`.
45
+
46
+ Attributes
47
+ ----------
48
+ templated_data : str
49
+ The templated data that failed to update.
50
+ source_data : dict
51
+ The data that was used to update the template.
52
+ template_start : str
53
+ The start marker of the template.
54
+ template_end : str
55
+ The end marker of the template.
56
+ """
57
+
58
+ def __init__(
59
+ self,
60
+ message: str,
61
+ templated_data: str,
62
+ source_data: dict,
63
+ template_start: str,
64
+ template_end: str
65
+ ):
66
+ super().__init__(message=message)
67
+ self.templated_data = templated_data
68
+ self.source_data = source_data
69
+ self.template_start = template_start
70
+ self.template_end = template_end
71
+ return
72
+
73
+
74
+ class PySerialsDictUpdateTypeMismatchError(PySerialsUpdateDictFromAddonException):
75
+ """Exception raised when a dict update fails due to a type mismatch."""
76
+
77
+ def __init__(self, address: str, value_data: _Any, value_addon: _Any):
78
+ message = (
79
+ f"There was a type mismatch between the source and addon dictionary values at '{address}'; "
80
+ f"the value is of type '{type(value_data).__name__}' in the source data, "
81
+ f"but of type '{type(value_addon).__name__}' in the addon data"
82
+ )
83
+ super().__init__(message=message, address=address, value_data=value_data, value_addon=value_addon)
84
+ return
85
+
86
+
87
+ class PySerialsDictUpdateDuplicationError(PySerialsUpdateDictFromAddonException):
88
+ """Exception raised when a dict update fails due to a duplication."""
89
+
90
+ def __init__(self, address: str, value_data: _Any, value_addon: _Any):
91
+ message = (
92
+ f"There was a duplication in the addon dictionary at '{address}'; "
93
+ f"the value of type '{type(value_addon).__name__}' already exists in the source data"
94
+ )
95
+ super().__init__(message=message, address=address, value_data=value_data, value_addon=value_addon)
96
+ return
97
+
98
+
99
+ class PySerialsTemplateUpdateMissingSourceError(PySerialsUpdateTemplatedDataException):
100
+ """Exception raised when a templated data update fails due to a missing key in source data.
101
+
102
+ Attributes
103
+ ----------
104
+ address_full : str
105
+ The full address in the source data where the key/index is missing.
106
+ address_missing : str
107
+ The key/index that is missing in the source data at `address_full`.
108
+ """
109
+
110
+ def __init__(
111
+ self,
112
+ address_full: str,
113
+ address_missing: str,
114
+ templated_data: str,
115
+ source_data: dict,
116
+ template_start: str,
117
+ template_end: str
118
+ ):
119
+ message = (
120
+ f"The key/index '{address_missing}' is missing in the source data at '{address_full}'"
121
+ )
122
+ super().__init__(
123
+ message=message,
124
+ templated_data=templated_data,
125
+ source_data=source_data,
126
+ template_start=template_start,
127
+ template_end=template_end
128
+ )
129
+ self.address_full = address_full
130
+ self.address_missing = address_missing
131
+ return
@@ -0,0 +1,73 @@
1
+ """Exceptions raised by `pyserials.validate` module."""
2
+
3
+
4
+ from typing import Any as _Any
5
+
6
+ from pyserials.exception._base import PySerialsException as _PySerialsException
7
+
8
+
9
+ class PySerialsValidateException(_PySerialsException):
10
+ """Base class for all exceptions raised by `pyserials.validate` module.
11
+
12
+ Attributes
13
+ ----------
14
+ data : dict | list | str | int | float | bool
15
+ The data that failed validation.
16
+ schema : dict
17
+ The schema that the data failed to validate against.
18
+ validator : Any
19
+ The validator that was used to validate the data against the schema.
20
+ """
21
+
22
+ def __init__(
23
+ self,
24
+ message: str,
25
+ data: dict | list | str | int | float | bool,
26
+ schema: dict,
27
+ validator: _Any,
28
+ ):
29
+ message = (
30
+ "Failed to validate data against schema "
31
+ f"using validator '{validator.__class__.__name__}'; {message}."
32
+ )
33
+ super().__init__(message=message)
34
+ self.data = data
35
+ self.schema = schema
36
+ self.validator = validator
37
+ return
38
+
39
+
40
+ class PySerialsSchemaValidationError(PySerialsValidateException):
41
+ """Exception raised when data validation fails due to the data being invalid against the schema."""
42
+
43
+ def __init__(
44
+ self,
45
+ data: dict | list | str | int | float | bool,
46
+ schema: dict,
47
+ validator: _Any,
48
+ ):
49
+ super().__init__(
50
+ message="the data is invalid",
51
+ data=data,
52
+ schema=schema,
53
+ validator=validator,
54
+ )
55
+ return
56
+
57
+
58
+ class PySerialsInvalidSchemaError(PySerialsValidateException):
59
+ """Exception raised when data validation fails due to the schema being invalid."""
60
+
61
+ def __init__(
62
+ self,
63
+ data: dict | list | str | int | float | bool,
64
+ schema: dict,
65
+ validator: _Any,
66
+ ):
67
+ super().__init__(
68
+ message="the schema is invalid",
69
+ data=data,
70
+ schema=schema,
71
+ validator=validator,
72
+ )
73
+ return
@@ -21,11 +21,7 @@ def from_file(
21
21
  if data_type == "yml":
22
22
  data_type = "yaml"
23
23
  if data_type not in ("json", "yaml", "toml"):
24
- raise _exception.ReadError(
25
- error_type=_exception.ReadErrorType.EXTENSION_INVALID,
26
- source_type="file",
27
- filepath=path,
28
- )
24
+ raise _exception.read.PySerialsInvalidFileExtensionError(filepath=path)
29
25
  if data_type == "json":
30
26
  return json_from_file(path=path, strict=json_strict)
31
27
  if data_type == "yaml":
@@ -139,18 +135,16 @@ def _read_from_file(
139
135
  exception,
140
136
  ):
141
137
  path = _Path(path).resolve()
142
- common_error_args = {"source_type": "file", "data_type": data_type, "filepath": path}
143
138
  if not path.is_file():
144
- raise _exception.ReadError(error_type=_exception.ReadErrorType.FILE_MISSING, **common_error_args)
139
+ raise _exception.read.PySerialsMissingFileError(filepath=path)
145
140
  data = path.read_text()
146
- common_error_args["data"] = data
147
141
  if data.strip() == "":
148
- raise _exception.ReadError(error_type=_exception.ReadErrorType.FILE_EMPTY, **common_error_args)
142
+ raise _exception.read.PySerialsEmptyFileError(filepath=path)
149
143
  try:
150
144
  content = loader(data)
151
145
  except exception as e:
152
- raise _exception.ReadError(
153
- error_type=_exception.ReadErrorType.DATA_INVALID, **common_error_args
146
+ raise _exception.read.PySerialsInvalidDataFileError(
147
+ filepath=path, data_type=data_type, data=data
154
148
  ) from e
155
149
  return content
156
150
 
@@ -161,13 +155,10 @@ def _read_from_string(
161
155
  loader,
162
156
  exception,
163
157
  ):
164
- common_error_args = {"source_type": "string", "data": data, "data_type": data_type}
165
158
  if not data.strip():
166
- raise _exception.ReadError(error_type=_exception.ReadErrorType.STRING_EMPTY, **common_error_args)
159
+ raise _exception.read.PySerialsEmptyStringError(data_type=data_type)
167
160
  try:
168
161
  content = loader(data)
169
162
  except exception as e:
170
- raise _exception.ReadError(
171
- error_type=_exception.ReadErrorType.DATA_INVALID, **common_error_args
172
- ) from e
163
+ raise _exception.read.PySerialsInvalidDataStringError(data_type=data_type, data=data) from e
173
164
  return content
@@ -14,8 +14,7 @@ def dict_from_addon(
14
14
  def recursive(source: dict, add: dict, path: str, log: dict):
15
15
 
16
16
  def raise_duplication_error():
17
- raise _exception.DictUpdateError(
18
- error_type=_exception.UpdateErrorType.DUPLICATION,
17
+ raise _exception.update.PySerialsDictUpdateDuplicationError(
19
18
  address=fullpath,
20
19
  value_data=source[key],
21
20
  value_addon=value,
@@ -28,8 +27,7 @@ def dict_from_addon(
28
27
  source[key] = value
29
28
  continue
30
29
  if type(source[key]) is not type(value):
31
- raise _exception.DictUpdateError(
32
- error_type=_exception.UpdateErrorType.TYPE_MISMATCH,
30
+ raise _exception.update.PySerialsDictUpdateTypeMismatchError(
33
31
  address=fullpath,
34
32
  value_data=source[key],
35
33
  value_addon=value,
@@ -91,6 +89,8 @@ class _TemplateFiller:
91
89
  ):
92
90
  self._data = templated_data
93
91
  self._source = source_data
92
+ self._template_start = template_start
93
+ self._template_end = template_end
94
94
  marker_start = _re.escape(template_start)
95
95
  marker_end = _re.escape(template_end)
96
96
  self._pattern_template_whole = _re.compile(rf"^{marker_start}([\w\.\:\-\[\] ]+){marker_end}$")
@@ -128,12 +128,20 @@ class _TemplateFiller:
128
128
  except (TypeError, KeyError, IndexError) as e:
129
129
  try:
130
130
  next_layer = self._recursive_subst(obj)[curr_add]
131
- except (TypeError, KeyError, IndexError) as e2:
132
- raise KeyError(f"Object '{obj}' has no element '{curr_add}'") from e
131
+ except (TypeError, KeyError, IndexError):
132
+ raise _exception.update.PySerialsTemplateUpdateMissingSourceError(
133
+ address_full=address_full,
134
+ address_missing=curr_add,
135
+ templated_data=self._data,
136
+ source_data=self._source,
137
+ template_start=self._template_start,
138
+ template_end=self._template_end,
139
+ ) from e
133
140
  return recursive_retrieve(next_layer, address)
134
141
 
142
+ address_full = match.strip()
135
143
  parsed_address = []
136
- for add in match.strip().split("."):
144
+ for add in address_full.split("."):
137
145
  name = self._pattern_address_name.match(add).group()
138
146
  indices = self._pattern_address_indices.findall(add)
139
147
  parsed_address.append(name)
@@ -6,9 +6,39 @@ import pyserials.exception as _exception
6
6
  def jsonschema(
7
7
  data: dict | list | str | int | float | bool,
8
8
  schema: dict,
9
- validator: _jsonschema.validators.Validator = _jsonschema.Draft202012Validator,
9
+ validator: _jsonschema.protocols.Validator = _jsonschema.Draft202012Validator,
10
10
  fill_defaults: bool = True,
11
- ) -> None:
11
+ raise_invalid_data: bool = True,
12
+ ) -> bool:
13
+ """
14
+ Validate data against a JSON schema.
15
+
16
+ Parameters
17
+ ----------
18
+ data : dict | list | str | int | float | bool
19
+ The data to validate.
20
+ schema : dict
21
+ The schema to validate the data against.
22
+ validator : jsonschema.protocols.Validator, default: jsonschema.Draft202012Validator
23
+ The JSON schema validator to use.
24
+ fill_defaults : bool, default: True
25
+ Whether to fill in the data with default values from the schema,
26
+ when they are not present.
27
+ raise_invalid_data : bool, default: True
28
+ Whether to raise an exception when the data is invalid against the schema.
29
+
30
+ Returns
31
+ -------
32
+ valid : bool
33
+ Whether the data is valid against the schema.
34
+
35
+ Raises
36
+ ------
37
+ pyserials.exception.PySerialsInvalidSchemaError
38
+ If the schema is invalid.
39
+ pyserials.exception.PySerialsSchemaValidationError
40
+ If the data is invalid against the schema and `raise_invalid_data` is `True`.
41
+ """
12
42
  def _extend_with_default(validator_class):
13
43
  # https://python-jsonschema.readthedocs.io/en/stable/faq/#why-doesn-t-my-schema-s-default-property-set-the-default-on-my-instance
14
44
 
@@ -30,22 +60,18 @@ def jsonschema(
30
60
  return _jsonschema.validators.extend(validator_class, {"properties": set_defaults})
31
61
 
32
62
  validator = _extend_with_default(validator) if fill_defaults else validator
33
- common_error_args = {"data": data, "schema": schema, "validator": validator}
63
+ error_args = {"data": data, "schema": schema, "validator": validator}
34
64
  try:
35
65
  validator(schema).validate(data)
36
- except (_jsonschema.exceptions.ValidationError, _jsonschema.exceptions.FormatError) as e:
37
- raise _exception.ValidationError(
38
- error_type=_exception.ValidationErrorType.DATA_INVALID,
39
- **common_error_args,
40
- ) from e
41
66
  except (
42
67
  _jsonschema.exceptions.SchemaError,
43
68
  _jsonschema.exceptions.UndefinedTypeCheck,
44
69
  _jsonschema.exceptions.UnknownType,
45
70
  _UnresolvableReferencingError,
46
71
  ) as e:
47
- raise _exception.ValidationError(
48
- error_type=_exception.ValidationErrorType.SCHEMA_INVALID,
49
- **common_error_args,
50
- ) from e
51
- return
72
+ raise _exception.validate.PySerialsInvalidSchemaError(**error_args) from e
73
+ except (_jsonschema.exceptions.ValidationError, _jsonschema.exceptions.FormatError) as e:
74
+ if raise_invalid_data:
75
+ raise _exception.validate.PySerialsSchemaValidationError(**error_args) from e
76
+ return False
77
+ return True
@@ -1,5 +1,5 @@
1
1
  from pathlib import Path as _Path
2
-
2
+ import json as _json
3
3
  import ruamel.yaml as _yaml
4
4
  import tomlkit as _tomlkit
5
5
 
@@ -28,3 +28,11 @@ def to_toml_string(
28
28
  sort_keys: bool = True,
29
29
  ) -> str:
30
30
  return _tomlkit.dumps(data, sort_keys=sort_keys)
31
+
32
+
33
+ def to_json_string(
34
+ data: dict | list | str | int | float | bool | _yaml.CommentedMap | _yaml.CommentedSeq,
35
+ sort_keys: bool = True,
36
+ indent: int | None = None,
37
+ ) -> str:
38
+ return _json.dumps(data, indent=indent, sort_keys=sort_keys)
@@ -1,140 +0,0 @@
1
- from typing import Literal as _Literal, Any as _Any
2
- from pathlib import Path as _Path
3
- from enum import Enum as _Enum
4
-
5
-
6
- class ReadErrorType(_Enum):
7
- """Enumeration of all possible read error types."""
8
-
9
- FILE_MISSING = "the file does not exist"
10
- FILE_EMPTY = "the file is empty"
11
- STRING_EMPTY = "the string is empty"
12
- DATA_INVALID = "the data is invalid"
13
- EXTENSION_INVALID = "the file extension is invalid"
14
-
15
-
16
- class ValidationErrorType(_Enum):
17
- """Enumeration of all possible validation error types."""
18
-
19
- SCHEMA_INVALID = "the schema is invalid"
20
- DATA_INVALID = "the data is invalid"
21
-
22
-
23
- class UpdateErrorType(_Enum):
24
- """Enumeration of all possible update error types."""
25
-
26
- TYPE_MISMATCH = (
27
- "type mismatch; the value of '{address}' is of type '{type_source}' in the source data, "
28
- "but of type '{type_addon}' in the addon data"
29
- )
30
- DUPLICATION = (
31
- "duplication; the value of '{address}' with type {type_source} already exists in the source data"
32
- )
33
-
34
-
35
- class PySerialsError(Exception):
36
- """Base class for all PySerials errors."""
37
-
38
- def __init__(self, message: str):
39
- self.message = message
40
- super().__init__(message)
41
- return
42
-
43
-
44
- class ReadError(PySerialsError):
45
- """Base class for all PySerials read errors."""
46
-
47
- def __init__(
48
- self,
49
- error_type: ReadErrorType,
50
- source_type: _Literal["file", "string"],
51
- data_type: _Literal["json", "yaml", "toml"] | None = None,
52
- filepath: _Path | None = None,
53
- data: str | None = None,
54
- ):
55
- self._type = error_type
56
- self._source_type = source_type
57
- self._data_type = data_type
58
- self._filepath = filepath
59
- self._data = data
60
-
61
- message = f"Failed to read {data_type} data from {source_type}; {error_type.value}."
62
- super().__init__(message)
63
- return
64
-
65
- @property
66
- def type(self) -> ReadErrorType:
67
- """The type of error."""
68
- return self._type
69
-
70
- @property
71
- def source_type(self) -> _Literal["file", "string"]:
72
- """Source of the data; either 'string' or 'file'."""
73
- return self._source_type
74
-
75
- @property
76
- def data_type(self) -> _Literal["json", "yaml", "toml"] | None:
77
- """The type of data; either 'json', 'yaml', 'toml', or None, in case of an invalid extension error."""
78
- return self._data_type
79
-
80
- @property
81
- def filepath(self) -> _Path | None:
82
- """The path of the input datafile; available only when source-type is file."""
83
- return self._filepath
84
-
85
- @property
86
- def data(self) -> str | None:
87
- """The input data;
88
- available only when source-type is string, or when the input file was read successfully."""
89
- return self._data
90
-
91
-
92
- class ValidationError(PySerialsError):
93
- """Base class for all PySerials validation errors."""
94
-
95
- def __init__(
96
- self,
97
- error_type: ValidationErrorType,
98
- data: dict | list | str | int | float | bool,
99
- schema: dict,
100
- validator: _Any,
101
- ):
102
- self._type = error_type
103
- self._data = data
104
- self._schema = schema
105
- self._validator = validator
106
-
107
- message = f"Failed to validate data against schema using validator '{validator}'; {error_type.value}."
108
- super().__init__(message)
109
- return
110
-
111
-
112
- class UpdateError(PySerialsError):
113
- """Base class for all PySerials update errors."""
114
-
115
- def __init__(self, message: str):
116
- super().__init__(message)
117
- return
118
-
119
-
120
- class DictUpdateError(UpdateError):
121
- """Base class for all PySerials dict update errors."""
122
-
123
- def __init__(
124
- self,
125
- error_type: UpdateErrorType,
126
- address: str,
127
- value_data: _Any,
128
- value_addon: _Any,
129
- ):
130
- self._type = error_type
131
- self._address = address
132
- self._value_data = value_data
133
- self._value_addon = value_addon
134
-
135
- error_details = error_type.value.format(
136
- address=address, type_source=type(value_data), type_addon=type(value_addon)
137
- )
138
- message = f"Failed to update dictionary due to {error_details}."
139
- super().__init__(message)
140
- return
File without changes
File without changes