DataExcept 1.2.0__tar.gz → 1.3.0__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.
- {dataexcept-1.2.0 → dataexcept-1.3.0}/CHANGELOG.md +25 -1
- {dataexcept-1.2.0 → dataexcept-1.3.0}/CITATION.cff +2 -2
- {dataexcept-1.2.0 → dataexcept-1.3.0}/PKG-INFO +6 -16
- {dataexcept-1.2.0 → dataexcept-1.3.0}/README.md +5 -15
- {dataexcept-1.2.0 → dataexcept-1.3.0}/dataexcept/serialization.py +33 -5
- {dataexcept-1.2.0 → dataexcept-1.3.0}/pyproject.toml +1 -1
- {dataexcept-1.2.0 → dataexcept-1.3.0}/LICENSE +0 -0
- {dataexcept-1.2.0 → dataexcept-1.3.0}/dataexcept/__init__.py +0 -0
- {dataexcept-1.2.0 → dataexcept-1.3.0}/dataexcept/__main__.py +0 -0
- {dataexcept-1.2.0 → dataexcept-1.3.0}/dataexcept/_validation.py +0 -0
- {dataexcept-1.2.0 → dataexcept-1.3.0}/dataexcept/base.py +0 -0
- {dataexcept-1.2.0 → dataexcept-1.3.0}/dataexcept/database_exceptions.py +0 -0
- {dataexcept-1.2.0 → dataexcept-1.3.0}/dataexcept/dataengineering_exceptions.py +0 -0
- {dataexcept-1.2.0 → dataexcept-1.3.0}/dataexcept/datascience_exceptions/__init__.py +0 -0
- {dataexcept-1.2.0 → dataexcept-1.3.0}/dataexcept/datascience_exceptions/base.py +0 -0
- {dataexcept-1.2.0 → dataexcept-1.3.0}/dataexcept/datascience_exceptions/ingestion.py +0 -0
- {dataexcept-1.2.0 → dataexcept-1.3.0}/dataexcept/datascience_exceptions/operations.py +0 -0
- {dataexcept-1.2.0 → dataexcept-1.3.0}/dataexcept/datascience_exceptions/training.py +0 -0
- {dataexcept-1.2.0 → dataexcept-1.3.0}/dataexcept/exceptions/__init__.py +0 -0
- {dataexcept-1.2.0 → dataexcept-1.3.0}/dataexcept/exceptions/authentication.py +0 -0
- {dataexcept-1.2.0 → dataexcept-1.3.0}/dataexcept/exceptions/base.py +0 -0
- {dataexcept-1.2.0 → dataexcept-1.3.0}/dataexcept/exceptions/configuration.py +0 -0
- {dataexcept-1.2.0 → dataexcept-1.3.0}/dataexcept/exceptions/external.py +0 -0
- {dataexcept-1.2.0 → dataexcept-1.3.0}/dataexcept/exceptions/lifecycle.py +0 -0
- {dataexcept-1.2.0 → dataexcept-1.3.0}/dataexcept/exceptions/notification.py +0 -0
- {dataexcept-1.2.0 → dataexcept-1.3.0}/dataexcept/exceptions/parsing.py +0 -0
- {dataexcept-1.2.0 → dataexcept-1.3.0}/dataexcept/exceptions/scheduling.py +0 -0
- {dataexcept-1.2.0 → dataexcept-1.3.0}/dataexcept/exceptions/validation.py +0 -0
- {dataexcept-1.2.0 → dataexcept-1.3.0}/dataexcept/io_exceptions.py +0 -0
- {dataexcept-1.2.0 → dataexcept-1.3.0}/dataexcept/logging_helpers.py +0 -0
- {dataexcept-1.2.0 → dataexcept-1.3.0}/dataexcept/network_exceptions.py +0 -0
- {dataexcept-1.2.0 → dataexcept-1.3.0}/dataexcept/pandas_exceptions.py +0 -0
- {dataexcept-1.2.0 → dataexcept-1.3.0}/dataexcept/pipeline_exceptions.py +0 -0
- {dataexcept-1.2.0 → dataexcept-1.3.0}/dataexcept/py.typed +0 -0
- {dataexcept-1.2.0 → dataexcept-1.3.0}/dataexcept/redaction.py +0 -0
- {dataexcept-1.2.0 → dataexcept-1.3.0}/dataexcept/security_exceptions.py +0 -0
- {dataexcept-1.2.0 → dataexcept-1.3.0}/dataexcept/wrapping.py +0 -0
|
@@ -7,6 +7,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.3.0] - 2026-09-03
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **Structured `ExceptionGroup` support** on Python 3.11+:
|
|
15
|
+
`exception_to_dict` and `exception_to_json` now preserve group members under
|
|
16
|
+
an `exceptions` field, including nested groups, instead of flattening
|
|
17
|
+
concurrent failures into one rendered message.
|
|
18
|
+
- Group members use the same public-attribute, redaction, cycle and shared
|
|
19
|
+
`max_depth` guarantees as ordinary causes and contexts. Python 3.10 remains
|
|
20
|
+
supported without an `exceptiongroup` backport or additional runtime
|
|
21
|
+
dependency.
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- Hostile or malformed exception-group member metadata now degrades to the
|
|
26
|
+
ordinary exception record rather than allowing serialization itself to fail.
|
|
27
|
+
- The README now uses a PyPI-backed version badge and avoids hard-coded version
|
|
28
|
+
and citation values that can drift between releases. The documented exception
|
|
29
|
+
count is contract-tested against the package.
|
|
30
|
+
- The roadmap now records a future language-neutral envelope schema and optional
|
|
31
|
+
Pino interoperability track without claiming Node.js/Pino support today.
|
|
32
|
+
|
|
10
33
|
## [1.2.0] - 2026-09-02
|
|
11
34
|
|
|
12
35
|
### Added
|
|
@@ -547,7 +570,8 @@ First public release.
|
|
|
547
570
|
- Published to PyPI via OIDC trusted publishing; no long-lived API token is
|
|
548
571
|
involved in a release.
|
|
549
572
|
|
|
550
|
-
[Unreleased]: https://github.com/DiogoRibeiro7/DataExcept/compare/v1.
|
|
573
|
+
[Unreleased]: https://github.com/DiogoRibeiro7/DataExcept/compare/v1.3.0...HEAD
|
|
574
|
+
[1.3.0]: https://github.com/DiogoRibeiro7/DataExcept/compare/v1.2.0...v1.3.0
|
|
551
575
|
[1.2.0]: https://github.com/DiogoRibeiro7/DataExcept/compare/v1.1.0...v1.2.0
|
|
552
576
|
[1.1.0]: https://github.com/DiogoRibeiro7/DataExcept/compare/v1.0.0...v1.1.0
|
|
553
577
|
[1.0.0]: https://github.com/DiogoRibeiro7/DataExcept/compare/v0.4.3...v1.0.0
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
cff-version: 1.2.0
|
|
2
2
|
message: "If you use this software, please cite it using the following metadata."
|
|
3
3
|
title: "DataExcept"
|
|
4
|
-
version: "1.
|
|
4
|
+
version: "1.3.0"
|
|
5
5
|
authors:
|
|
6
6
|
- family-names: "Ribeiro"
|
|
7
7
|
given-names: "Diogo"
|
|
@@ -11,4 +11,4 @@ authors:
|
|
|
11
11
|
type: software
|
|
12
12
|
url: "https://github.com/DiogoRibeiro7/DataExcept"
|
|
13
13
|
repository-code: "https://github.com/DiogoRibeiro7/DataExcept"
|
|
14
|
-
date-released: "2026-09-
|
|
14
|
+
date-released: "2026-09-03"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: DataExcept
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.0
|
|
4
4
|
Summary: A Python package providing structured, easily-extendable custom exception types.
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
License-File: LICENSE
|
|
@@ -27,7 +27,7 @@ Description-Content-Type: text/markdown
|
|
|
27
27
|
|
|
28
28
|
# DataExcept
|
|
29
29
|
|
|
30
|
-
[](https://github.com/DiogoRibeiro7/DataExcept/actions/workflows/ci.yml) [](https://github.com/DiogoRibeiro7/DataExcept/actions/workflows/ci.yml) [](https://pypi.org/project/DataExcept/) [](https://pypi.org/project/DataExcept/) [](https://diogoribeiro7.github.io/DataExcept/htmlcov/) [](https://diogoribeiro7.github.io/DataExcept/) [](https://opensource.org/licenses/MIT) [](https://github.com/psf/black) [](https://mypy-lang.org/)
|
|
31
31
|
|
|
32
32
|
**DataExcept** is a production-ready Python library that provides **structured, hierarchical exception classes** specifically designed for **data science**, **machine learning**, and **data engineering** workflows. Stop debugging generic `ValueError`s and `RuntimeError`s -- get meaningful, actionable error messages that help you understand exactly what went wrong in your data pipeline.
|
|
33
33
|
|
|
@@ -223,9 +223,9 @@ BatchProcessingError
|
|
|
223
223
|
BiasDetectionError
|
|
224
224
|
...
|
|
225
225
|
|
|
226
|
-
# Check version
|
|
226
|
+
# Check the installed version
|
|
227
227
|
$ dataexcept --version
|
|
228
|
-
dataexcept
|
|
228
|
+
dataexcept <installed version>
|
|
229
229
|
```
|
|
230
230
|
|
|
231
231
|
## 🎯 Use Cases
|
|
@@ -369,18 +369,8 @@ through [SECURITY.md](SECURITY.md), not the public issue tracker.
|
|
|
369
369
|
|
|
370
370
|
## 🎓 Citation
|
|
371
371
|
|
|
372
|
-
If you use DataExcept in your research, please cite
|
|
373
|
-
|
|
374
|
-
```bibtex
|
|
375
|
-
@software{ribeiro_dataexcept_2026,
|
|
376
|
-
author = {Ribeiro, Diogo},
|
|
377
|
-
title = {DataExcept: Structured Exception Handling for Data Science},
|
|
378
|
-
url = {https://github.com/DiogoRibeiro7/DataExcept},
|
|
379
|
-
version = {1.0.0},
|
|
380
|
-
year = {2026},
|
|
381
|
-
publisher = {GitHub}
|
|
382
|
-
}
|
|
383
|
-
```
|
|
372
|
+
If you use DataExcept in your research, please cite the exact release you used.
|
|
373
|
+
The canonical release metadata is maintained in [CITATION.cff](CITATION.cff).
|
|
384
374
|
|
|
385
375
|
## 📄 License
|
|
386
376
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# DataExcept
|
|
2
2
|
|
|
3
|
-
[](https://github.com/DiogoRibeiro7/DataExcept/actions/workflows/ci.yml) [](https://github.com/DiogoRibeiro7/DataExcept/actions/workflows/ci.yml) [](https://pypi.org/project/DataExcept/) [](https://pypi.org/project/DataExcept/) [](https://diogoribeiro7.github.io/DataExcept/htmlcov/) [](https://diogoribeiro7.github.io/DataExcept/) [](https://opensource.org/licenses/MIT) [](https://github.com/psf/black) [](https://mypy-lang.org/)
|
|
4
4
|
|
|
5
5
|
**DataExcept** is a production-ready Python library that provides **structured, hierarchical exception classes** specifically designed for **data science**, **machine learning**, and **data engineering** workflows. Stop debugging generic `ValueError`s and `RuntimeError`s -- get meaningful, actionable error messages that help you understand exactly what went wrong in your data pipeline.
|
|
6
6
|
|
|
@@ -196,9 +196,9 @@ BatchProcessingError
|
|
|
196
196
|
BiasDetectionError
|
|
197
197
|
...
|
|
198
198
|
|
|
199
|
-
# Check version
|
|
199
|
+
# Check the installed version
|
|
200
200
|
$ dataexcept --version
|
|
201
|
-
dataexcept
|
|
201
|
+
dataexcept <installed version>
|
|
202
202
|
```
|
|
203
203
|
|
|
204
204
|
## 🎯 Use Cases
|
|
@@ -342,18 +342,8 @@ through [SECURITY.md](SECURITY.md), not the public issue tracker.
|
|
|
342
342
|
|
|
343
343
|
## 🎓 Citation
|
|
344
344
|
|
|
345
|
-
If you use DataExcept in your research, please cite
|
|
346
|
-
|
|
347
|
-
```bibtex
|
|
348
|
-
@software{ribeiro_dataexcept_2026,
|
|
349
|
-
author = {Ribeiro, Diogo},
|
|
350
|
-
title = {DataExcept: Structured Exception Handling for Data Science},
|
|
351
|
-
url = {https://github.com/DiogoRibeiro7/DataExcept},
|
|
352
|
-
version = {1.0.0},
|
|
353
|
-
year = {2026},
|
|
354
|
-
publisher = {GitHub}
|
|
355
|
-
}
|
|
356
|
-
```
|
|
345
|
+
If you use DataExcept in your research, please cite the exact release you used.
|
|
346
|
+
The canonical release metadata is maintained in [CITATION.cff](CITATION.cff).
|
|
357
347
|
|
|
358
348
|
## 📄 License
|
|
359
349
|
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import builtins
|
|
5
6
|
import json
|
|
6
7
|
import math
|
|
7
8
|
from collections.abc import Mapping, Sequence, Set
|
|
@@ -13,6 +14,7 @@ __all__ = ["exception_to_dict", "exception_to_json"]
|
|
|
13
14
|
|
|
14
15
|
_MAX_VALUE_DEPTH = 8
|
|
15
16
|
_NOT_SCALAR = object()
|
|
17
|
+
_EXCEPTION_GROUP_TYPE = getattr(builtins, "BaseExceptionGroup", None)
|
|
16
18
|
|
|
17
19
|
|
|
18
20
|
def _redact_export_text(text: str) -> str:
|
|
@@ -112,12 +114,24 @@ def _attributes(exc: BaseException) -> dict[str, Any]:
|
|
|
112
114
|
result[name] = _json_safe(value)
|
|
113
115
|
return result
|
|
114
116
|
except Exception:
|
|
115
|
-
# This code runs at an error-transport boundary. A hostile __dict__,
|
|
116
|
-
# custom mapping, iterator or key must not replace the original failure
|
|
117
|
-
# with a serialization failure.
|
|
118
117
|
return {}
|
|
119
118
|
|
|
120
119
|
|
|
120
|
+
def _group_members(exc: BaseException) -> Sequence[BaseException] | None:
|
|
121
|
+
"""Return exception-group members without importing a 3.11-only symbol."""
|
|
122
|
+
if _EXCEPTION_GROUP_TYPE is None or not isinstance(exc, _EXCEPTION_GROUP_TYPE):
|
|
123
|
+
return None
|
|
124
|
+
try:
|
|
125
|
+
members: object = getattr(exc, "exceptions", None)
|
|
126
|
+
if not isinstance(members, tuple):
|
|
127
|
+
return None
|
|
128
|
+
if not all(isinstance(member, BaseException) for member in members):
|
|
129
|
+
return None
|
|
130
|
+
return members
|
|
131
|
+
except Exception:
|
|
132
|
+
return None
|
|
133
|
+
|
|
134
|
+
|
|
121
135
|
def _exception_record(
|
|
122
136
|
exc: BaseException,
|
|
123
137
|
*,
|
|
@@ -149,6 +163,19 @@ def _exception_record(
|
|
|
149
163
|
if attributes:
|
|
150
164
|
record["attributes"] = attributes
|
|
151
165
|
|
|
166
|
+
members = _group_members(exc)
|
|
167
|
+
if members is not None:
|
|
168
|
+
record["exceptions"] = [
|
|
169
|
+
_exception_record(
|
|
170
|
+
member,
|
|
171
|
+
include_attributes=include_attributes,
|
|
172
|
+
max_depth=max_depth,
|
|
173
|
+
depth=depth + 1,
|
|
174
|
+
seen=seen,
|
|
175
|
+
)
|
|
176
|
+
for member in members
|
|
177
|
+
]
|
|
178
|
+
|
|
152
179
|
if exc.__cause__ is not None:
|
|
153
180
|
record["cause"] = _exception_record(
|
|
154
181
|
exc.__cause__,
|
|
@@ -179,8 +206,9 @@ def exception_to_dict(
|
|
|
179
206
|
"""Return a strict JSON-safe structured representation of *exc*.
|
|
180
207
|
|
|
181
208
|
The representation contains the exception type, module and rendered
|
|
182
|
-
message, optionally public instance attributes,
|
|
183
|
-
chains
|
|
209
|
+
message, optionally public instance attributes, bounded cause/context
|
|
210
|
+
chains, and on Python 3.11+ the member tree of exception groups. Traceback
|
|
211
|
+
frames and private attributes are deliberately excluded.
|
|
184
212
|
"""
|
|
185
213
|
if not isinstance(exc, BaseException):
|
|
186
214
|
raise TypeError("exc must be an exception instance")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|