DataExcept 0.2.1__tar.gz → 0.4.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-0.4.0/CHANGELOG.md +276 -0
- {dataexcept-0.2.1 → dataexcept-0.4.0}/CITATION.cff +1 -1
- {dataexcept-0.2.1 → dataexcept-0.4.0}/PKG-INFO +13 -14
- {dataexcept-0.2.1 → dataexcept-0.4.0}/README.md +12 -13
- dataexcept-0.4.0/dataexcept/__init__.py +309 -0
- {dataexcept-0.2.1 → dataexcept-0.4.0}/dataexcept/__main__.py +7 -1
- dataexcept-0.4.0/dataexcept/_validation.py +22 -0
- dataexcept-0.4.0/dataexcept/base.py +67 -0
- {dataexcept-0.2.1 → dataexcept-0.4.0}/dataexcept/database_exceptions.py +7 -3
- {dataexcept-0.2.1 → dataexcept-0.4.0}/dataexcept/dataengineering_exceptions.py +3 -1
- {dataexcept-0.2.1 → dataexcept-0.4.0}/dataexcept/datascience_exceptions/base.py +3 -1
- {dataexcept-0.2.1 → dataexcept-0.4.0}/dataexcept/datascience_exceptions/ingestion.py +5 -4
- {dataexcept-0.2.1 → dataexcept-0.4.0}/dataexcept/datascience_exceptions/operations.py +4 -3
- {dataexcept-0.2.1 → dataexcept-0.4.0}/dataexcept/datascience_exceptions/training.py +9 -8
- dataexcept-0.4.0/dataexcept/exceptions/base.py +7 -0
- {dataexcept-0.2.1 → dataexcept-0.4.0}/dataexcept/exceptions/notification.py +6 -4
- {dataexcept-0.2.1 → dataexcept-0.4.0}/dataexcept/io_exceptions.py +3 -1
- {dataexcept-0.2.1 → dataexcept-0.4.0}/dataexcept/network_exceptions.py +3 -1
- {dataexcept-0.2.1 → dataexcept-0.4.0}/dataexcept/pandas_exceptions.py +3 -1
- {dataexcept-0.2.1 → dataexcept-0.4.0}/dataexcept/pipeline_exceptions.py +6 -3
- dataexcept-0.4.0/dataexcept/redaction.py +114 -0
- {dataexcept-0.2.1 → dataexcept-0.4.0}/dataexcept/security_exceptions.py +8 -3
- {dataexcept-0.2.1 → dataexcept-0.4.0}/pyproject.toml +21 -2
- dataexcept-0.2.1/CHANGELOG.md +0 -132
- dataexcept-0.2.1/dataexcept/__init__.py +0 -94
- dataexcept-0.2.1/dataexcept/exceptions/base.py +0 -4
- {dataexcept-0.2.1 → dataexcept-0.4.0}/LICENSE +0 -0
- {dataexcept-0.2.1 → dataexcept-0.4.0}/dataexcept/_deprecation.py +0 -0
- {dataexcept-0.2.1 → dataexcept-0.4.0}/dataexcept/datascience_exceptions/__init__.py +0 -0
- {dataexcept-0.2.1 → dataexcept-0.4.0}/dataexcept/exceptions/__init__.py +0 -0
- {dataexcept-0.2.1 → dataexcept-0.4.0}/dataexcept/exceptions/authentication.py +0 -0
- {dataexcept-0.2.1 → dataexcept-0.4.0}/dataexcept/exceptions/configuration.py +0 -0
- {dataexcept-0.2.1 → dataexcept-0.4.0}/dataexcept/exceptions/external.py +0 -0
- {dataexcept-0.2.1 → dataexcept-0.4.0}/dataexcept/exceptions/lifecycle.py +0 -0
- {dataexcept-0.2.1 → dataexcept-0.4.0}/dataexcept/exceptions/parsing.py +0 -0
- {dataexcept-0.2.1 → dataexcept-0.4.0}/dataexcept/exceptions/scheduling.py +0 -0
- {dataexcept-0.2.1 → dataexcept-0.4.0}/dataexcept/exceptions/validation.py +0 -0
- {dataexcept-0.2.1 → dataexcept-0.4.0}/dataexcept/job_exceptions.py +0 -0
- {dataexcept-0.2.1 → dataexcept-0.4.0}/dataexcept/logging_helpers.py +0 -0
- {dataexcept-0.2.1 → dataexcept-0.4.0}/dataexcept/py.typed +0 -0
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.4.0] - 2026-08-24
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **`DataExceptError`, the root of the hierarchy.** Every exception the package
|
|
15
|
+
raises now derives from it, so one clause catches the whole library:
|
|
16
|
+
```python
|
|
17
|
+
except DataExceptError:
|
|
18
|
+
...
|
|
19
|
+
```
|
|
20
|
+
The nine domain roots (`JobError`, `DataScienceError`, `PipelineError` and
|
|
21
|
+
the rest) sit beneath it and still catch only their own domain, so granular
|
|
22
|
+
handling is unchanged.
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
|
|
26
|
+
- `SECURITY.md` claimed 0.1.x was the supported version, and `CHECKLIST.md`
|
|
27
|
+
still described an uncommitted lockfile, 30 of 96 top-level exports, 109 tests
|
|
28
|
+
and 85% coverage. Both now match the project.
|
|
29
|
+
- **Coverage is now measured honestly, and gated.** `coverage run -m pytest`
|
|
30
|
+
had no `source` setting, so it counted the tests and examples in the
|
|
31
|
+
denominator — and test files are by definition fully executed. The reported
|
|
32
|
+
figure was inflated: 86% when the package alone was at 79%.
|
|
33
|
+
`[tool.coverage.run]` now restricts measurement to `dataexcept` and enables
|
|
34
|
+
branch coverage, and `fail_under = 91` stops it regressing. The honest number
|
|
35
|
+
is **92%**; the README, checklist and roadmap now quote that rather than the
|
|
36
|
+
inflated one.
|
|
37
|
+
- The CLI is exercised in-process as well as through a subprocess. The
|
|
38
|
+
subprocess tests verify real invocation but coverage cannot see inside them,
|
|
39
|
+
which left `__main__.py` reporting 23% despite being tested. It now reports
|
|
40
|
+
93%.
|
|
41
|
+
|
|
42
|
+
### Fixed
|
|
43
|
+
|
|
44
|
+
- **NumPy scalars are accepted where a number is expected.** Eleven validations
|
|
45
|
+
used `isinstance(value, (int, float))`, which rejects `numpy.float32` and
|
|
46
|
+
`numpy.int64` — a poor answer from a library aimed at data science. They now
|
|
47
|
+
use `numbers.Real`, which NumPy registers its scalar types with, so this needs
|
|
48
|
+
no dependency on NumPy. Arrays and non-numbers are still rejected.
|
|
49
|
+
- **A wrapped exception is now chained.** Constructors that take an underlying
|
|
50
|
+
exception recorded it on an attribute but never set `__cause__`, so a
|
|
51
|
+
traceback did not show what actually failed. `DataExceptError` now mirrors it,
|
|
52
|
+
and Python prints "The above exception was the direct cause of the following
|
|
53
|
+
exception" as if `raise ... from` had been used.
|
|
54
|
+
- `from dataexcept import *` failed under `-W error::DeprecationWarning`,
|
|
55
|
+
because `__all__` listed the deprecated `job_exceptions` module. It is no
|
|
56
|
+
longer advertised there; it remains importable until 1.0.0.
|
|
57
|
+
- A redundant `global` declaration in `examples/lambda_main.py` raised three
|
|
58
|
+
`F824` warnings. CI linted only `dataexcept` and `tests` with flake8 while the
|
|
59
|
+
formatters covered `examples` and `scripts`; flake8 now covers all four.
|
|
60
|
+
- **Four exceptions discarded the reason for the failure.**
|
|
61
|
+
`DataLoadingError`, `MissingDataError`, `ModelSerializationError` and
|
|
62
|
+
`DeploymentError` rendered only their identifying attribute —
|
|
63
|
+
`[DataLoadingError] orders.csv` — while "invalid utf-8", "disk full" or
|
|
64
|
+
"permission denied" sat unseen in `args[0]`. Since logging uses `str(exc)`,
|
|
65
|
+
the part a reader needs never reached the log. All four now render the full
|
|
66
|
+
message, and a test asserts no class drops it.
|
|
67
|
+
- **Exceptions can now cross a process boundary.** They could not be pickled:
|
|
68
|
+
most constructors take several arguments while `Exception.args` holds only
|
|
69
|
+
the rendered message, and the default protocol replays `args` through
|
|
70
|
+
`__init__`. Of 98 classes, 39 raised `TypeError` on unpickling and a further
|
|
71
|
+
47 came back with different state — only 10 round-tripped exactly. Raising
|
|
72
|
+
one inside a `ProcessPoolExecutor` killed the pool with `BrokenProcessPool`.
|
|
73
|
+
`DataExceptError.__reduce__` restores `args` and `__dict__` directly instead
|
|
74
|
+
of replaying `__init__`. All 97 constructible classes now round-trip with
|
|
75
|
+
identical type, message and attributes, covered by a test per class plus a
|
|
76
|
+
real process-pool test.
|
|
77
|
+
- The stability policy and README both claimed `except JobError:` catches
|
|
78
|
+
"anything else this library raises". It did not — there were nine
|
|
79
|
+
disconnected trees under `Exception`, so `JobError` caught neither
|
|
80
|
+
`ModelTrainingError` nor `PipelineError` nor `DatabaseError`. The claim is
|
|
81
|
+
now true of `DataExceptError`, and the docs say which base covers what.
|
|
82
|
+
|
|
83
|
+
### Security
|
|
84
|
+
|
|
85
|
+
- **A release now has to prove where it came from.** The release workflow
|
|
86
|
+
checked only that the tag text matched `pyproject.toml`, so a tag pushed to
|
|
87
|
+
an unreviewed branch could reach the PyPI publishing job. It now refuses to
|
|
88
|
+
build unless the tagged commit is reachable from `main` and the same checks
|
|
89
|
+
branch protection requires are green on that exact commit.
|
|
90
|
+
- The built wheel is tested before it is published. A new `verify-wheel` job
|
|
91
|
+
installs the artifact, deletes the source package so nothing can import it by
|
|
92
|
+
accident, and runs the whole suite against what will actually be uploaded.
|
|
93
|
+
`scripts/check_wheel.py` then asserts the distribution ships `py.typed` and a
|
|
94
|
+
complete `__all__` — a file can be present in the repository and missing from
|
|
95
|
+
the artifact.
|
|
96
|
+
- **Credentials are no longer written into exception messages.** `log_exception`
|
|
97
|
+
logs `str(exc)`, so a failed connection put the database password in the log.
|
|
98
|
+
`InvalidTokenError` embedded the whole token; `DatabaseConnectionError` the
|
|
99
|
+
whole connection URL including username and password; `WebhookError` and
|
|
100
|
+
`ApiError` the URL including any signing or key parameter.
|
|
101
|
+
These are now redacted before being stored or rendered, so the raw value is
|
|
102
|
+
absent from the message, the attributes and a pickle of the exception. A
|
|
103
|
+
secret renders as `***(1a2b3c4d)` — a truncated SHA-256, so the same bad
|
|
104
|
+
credential failing repeatedly stays correlatable in a log without appearing
|
|
105
|
+
in it. Host, port and path survive, because those are what make the error
|
|
106
|
+
actionable.
|
|
107
|
+
`QueryExecutionError` still embeds the SQL it is given; SECURITY.md now says
|
|
108
|
+
so explicitly rather than leaving it to be discovered.
|
|
109
|
+
|
|
110
|
+
## [0.3.0] - 2026-08-24
|
|
111
|
+
|
|
112
|
+
### Added
|
|
113
|
+
|
|
114
|
+
- **Every exception the package defines is now importable from `dataexcept`
|
|
115
|
+
directly.** All 98 classes are exported at the top level, so callers no
|
|
116
|
+
longer need to know which domain module a class lives in. The domain modules
|
|
117
|
+
export the same objects, so `from dataexcept import ValidationError` and
|
|
118
|
+
`from dataexcept.exceptions import ValidationError` are interchangeable and
|
|
119
|
+
`except` behaves identically either way.
|
|
120
|
+
|
|
121
|
+
This was only safe because 0.2.0 removed the two hazards that make a flat
|
|
122
|
+
namespace dangerous: there are no duplicate class names left, and nothing
|
|
123
|
+
shadows a Python builtin. Imports are explicit rather than generated at
|
|
124
|
+
runtime, so type checkers and IDEs see the full surface — the package ships
|
|
125
|
+
`py.typed`.
|
|
126
|
+
- `dataexcept.exceptions` and `dataexcept.logging_helpers` are now named in
|
|
127
|
+
`__all__` alongside the other domain modules; the stability policy already
|
|
128
|
+
described them as public.
|
|
129
|
+
- Tests covering the public surface: every exception the package defines must
|
|
130
|
+
be exported and resolve, each top-level export must be the *same object* as
|
|
131
|
+
the submodule one, no exported name may shadow a builtin, no two exceptions
|
|
132
|
+
may share a name, and `from dataexcept import *` must expose the documented
|
|
133
|
+
surface. Verified these fail when an unexported exception is introduced.
|
|
134
|
+
- Tests that `poetry.lock` is committed, and that `docs/requirements.txt`
|
|
135
|
+
agrees with the Poetry `docs` group — the two list the same packages and
|
|
136
|
+
could drift apart silently.
|
|
137
|
+
|
|
138
|
+
### Changed
|
|
139
|
+
|
|
140
|
+
- `poetry.lock` is committed, and CI installs from it. Every job previously ran
|
|
141
|
+
`pip install black flake8 isort mypy ruff` unpinned, so a new release of any
|
|
142
|
+
linter could turn the build red with no commit to point at. `poetry check
|
|
143
|
+
--lock` now fails the build if the lock and `pyproject.toml` disagree.
|
|
144
|
+
- The coverage badge is generated by `scripts/coverage_badge.py` instead of
|
|
145
|
+
the `coverage-badge` package. That package still imports `pkg_resources`,
|
|
146
|
+
removed in setuptools 81, so using it required pinning `setuptools<81` — and
|
|
147
|
+
dependency review flagged a moderate-severity advisory against the version
|
|
148
|
+
that pin selected. Its last release was August 2024. Generating the SVG
|
|
149
|
+
directly removes the dependency, the pin and the advisory together; the
|
|
150
|
+
output is byte-identical to the published badge apart from the percentage.
|
|
151
|
+
|
|
152
|
+
## [0.2.1] - 2026-08-24
|
|
153
|
+
|
|
154
|
+
Documentation and CLI fixes. 0.2.0's README is what PyPI renders as the
|
|
155
|
+
project description, and its quick-start example did not run.
|
|
156
|
+
|
|
157
|
+
### Fixed
|
|
158
|
+
|
|
159
|
+
- `python -m dataexcept --version` reported `__main__.py` as the program name
|
|
160
|
+
instead of `dataexcept`, because argparse defaults `prog` to `sys.argv[0]`.
|
|
161
|
+
- `dataexcept list` imported the deprecated `job_exceptions` shim to build its
|
|
162
|
+
output, so it emitted a `DeprecationWarning` at anyone who merely wanted to
|
|
163
|
+
see what the package offers, and it advertised `ConnectionError` and
|
|
164
|
+
`TimeoutError` alongside their replacements. Deprecated modules are now
|
|
165
|
+
skipped; the listing is 98 names, matching the classes the package defines.
|
|
166
|
+
- README's quick-start example began `from dataexcept import ValidationError,
|
|
167
|
+
ModelTrainingError`, which raises `ImportError` — `ModelTrainingError` is in
|
|
168
|
+
`dataexcept.datascience_exceptions` and is not re-exported at the top level.
|
|
169
|
+
- `docs/advanced_usage.md` taught `from dataexcept.job_exceptions import
|
|
170
|
+
JobError`, the deprecated path.
|
|
171
|
+
- README's comparison table showed exception messages without the
|
|
172
|
+
`[ClassName]` prefix the classes actually emit, its sample `dataexcept list`
|
|
173
|
+
output did not match the real alphabetical listing, its exception count and
|
|
174
|
+
CLI version were stale, and its end-to-end example used `np.log` without
|
|
175
|
+
importing numpy.
|
|
176
|
+
|
|
177
|
+
### Added
|
|
178
|
+
|
|
179
|
+
- Tests that read the documentation: every `from dataexcept... import ...` in
|
|
180
|
+
README and `docs/` must resolve, no example may import a deprecated module,
|
|
181
|
+
and the README's exception count must match the package. Checked that these
|
|
182
|
+
fail when the original defects are reintroduced.
|
|
183
|
+
|
|
184
|
+
## [0.2.0] - 2026-08-24
|
|
185
|
+
|
|
186
|
+
### Changed
|
|
187
|
+
|
|
188
|
+
- **`ConnectionError` is now `ServiceConnectionError`, and `TimeoutError` is
|
|
189
|
+
now `OperationTimeoutError`.** The old names shadowed Python builtins without
|
|
190
|
+
inheriting from them, so after `from dataexcept import ConnectionError` an
|
|
191
|
+
`except ConnectionError:` in that module silently stopped catching real
|
|
192
|
+
socket failures.
|
|
193
|
+
- **`datascience_exceptions.SerializationError` is now
|
|
194
|
+
`ModelSerializationError`**, and **`pipeline_exceptions.FeatureEngineeringError`
|
|
195
|
+
is now `FeaturePreprocessingError`.** Each of those names previously referred
|
|
196
|
+
to two different classes in different modules, so catching one silently
|
|
197
|
+
missed the other.
|
|
198
|
+
- Project metadata moved from Poetry's `[tool.poetry]` table to the standard
|
|
199
|
+
PEP 621 `[project]` table, clearing every `poetry check` deprecation. The
|
|
200
|
+
license is now an SPDX expression (PEP 639), so the built metadata carries
|
|
201
|
+
`License-Expression: MIT` and the redundant license classifier is gone.
|
|
202
|
+
Wheel and sdist contents are otherwise unchanged.
|
|
203
|
+
- `dataexcept.job_exceptions` now names its removal version, 1.0.0, in both the
|
|
204
|
+
warning and the module docstring.
|
|
205
|
+
|
|
206
|
+
### Deprecated
|
|
207
|
+
|
|
208
|
+
- `ConnectionError`, `TimeoutError`, `datascience_exceptions.SerializationError`
|
|
209
|
+
and `pipeline_exceptions.FeatureEngineeringError`. All four still resolve, to
|
|
210
|
+
the **same class object** as their replacement, so existing `except` clauses
|
|
211
|
+
keep working; touching one emits a `DeprecationWarning` naming the
|
|
212
|
+
replacement and 1.0.0 as the removal. Importing the package does not warn.
|
|
213
|
+
Find remaining uses with `python -W error::DeprecationWarning -m pytest`.
|
|
214
|
+
|
|
215
|
+
### Added
|
|
216
|
+
|
|
217
|
+
- A published [API stability policy](https://diogoribeiro7.github.io/DataExcept/stability/)
|
|
218
|
+
stating what is public, what each kind of change costs in version terms, the
|
|
219
|
+
deprecation process, and how to migrate off the 0.2.0 renames.
|
|
220
|
+
- Security scanning: CodeQL, and pip-audit against the runtime and
|
|
221
|
+
documentation dependency sets, on push, pull request and weekly — advisories
|
|
222
|
+
are published against code that has not changed. Pull requests also get a
|
|
223
|
+
dependency review failing at moderate severity.
|
|
224
|
+
- Complexity and security linting via ruff's mccabe (`C90`) and flake8-bandit
|
|
225
|
+
(`S`) rule sets, so neither needs a separate tool. Complexity is capped at 8;
|
|
226
|
+
the highest score in the package is 6.
|
|
227
|
+
- A regression guard that fails if any exported name ever shadows a builtin
|
|
228
|
+
again.
|
|
229
|
+
- `__all__` on `dataexcept.logging_helpers`, the one public module without one.
|
|
230
|
+
|
|
231
|
+
### Fixed
|
|
232
|
+
|
|
233
|
+
- `dataexcept.__version__` and `tests/test_version.py` read the version out of
|
|
234
|
+
`pyproject.toml` when the package is not installed, and were still looking in
|
|
235
|
+
`[tool.poetry]`. They now read `[project]`.
|
|
236
|
+
- `examples/example_usage.py` raised `TimeoutError` with keyword arguments the
|
|
237
|
+
builtin does not accept — a live instance of the shadowing hazard.
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
## [0.1.0] - 2026-08-24
|
|
241
|
+
|
|
242
|
+
First public release.
|
|
243
|
+
|
|
244
|
+
### Added
|
|
245
|
+
|
|
246
|
+
- Hierarchical exception classes for data science, machine learning and data
|
|
247
|
+
engineering workflows. Catch a specific failure or a broad category, and get
|
|
248
|
+
a message that names the value that caused it rather than a bare
|
|
249
|
+
`ValueError`.
|
|
250
|
+
- Domain modules for validation, configuration, authentication, parsing,
|
|
251
|
+
serialization, scheduling, notification, lifecycle and external-service
|
|
252
|
+
errors, plus dedicated pandas, database, network, I/O, pipeline and security
|
|
253
|
+
exception groups.
|
|
254
|
+
- `dataexcept.logging_helpers` with `log_exception`, `log_and_raise` and
|
|
255
|
+
`log_then_raise`, for logging exceptions with structured context and
|
|
256
|
+
re-raising without losing the traceback.
|
|
257
|
+
- A `dataexcept` command-line entry point that lists the exported exception
|
|
258
|
+
classes and reports the installed version.
|
|
259
|
+
- A `py.typed` marker, backed by a mypy-clean codebase that CI enforces, so
|
|
260
|
+
downstream type checkers get annotations that are actually correct.
|
|
261
|
+
- Documentation at
|
|
262
|
+
[diogoribeiro7.github.io/DataExcept](https://diogoribeiro7.github.io/DataExcept/),
|
|
263
|
+
including an API reference generated from the docstrings.
|
|
264
|
+
|
|
265
|
+
### Notes
|
|
266
|
+
|
|
267
|
+
- Supports Python 3.10 through 3.13.
|
|
268
|
+
- Published to PyPI via OIDC trusted publishing; no long-lived API token is
|
|
269
|
+
involved in a release.
|
|
270
|
+
|
|
271
|
+
[Unreleased]: https://github.com/DiogoRibeiro7/DataExcept/compare/v0.4.0...HEAD
|
|
272
|
+
[0.4.0]: https://github.com/DiogoRibeiro7/DataExcept/compare/v0.3.0...v0.4.0
|
|
273
|
+
[0.3.0]: https://github.com/DiogoRibeiro7/DataExcept/compare/v0.2.1...v0.3.0
|
|
274
|
+
[0.2.1]: https://github.com/DiogoRibeiro7/DataExcept/compare/v0.2.0...v0.2.1
|
|
275
|
+
[0.2.0]: https://github.com/DiogoRibeiro7/DataExcept/compare/v0.1.0...v0.2.0
|
|
276
|
+
[0.1.0]: https://github.com/DiogoRibeiro7/DataExcept/releases/tag/v0.1.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: DataExcept
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: A Python package providing structured, easily-extendable custom exception types.
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
License-File: LICENSE
|
|
@@ -41,12 +41,13 @@ Description-Content-Type: text/markdown
|
|
|
41
41
|
|
|
42
42
|
## 🎯 Key Features
|
|
43
43
|
|
|
44
|
-
- **🏗️ Hierarchical Structure**: Catch specific
|
|
45
|
-
-
|
|
46
|
-
-
|
|
44
|
+
- **🏗️ Hierarchical Structure**: Catch one specific error, a whole domain, or everything via `DataExceptError`
|
|
45
|
+
- **📦 One Import**: Every exception is available from `dataexcept` directly, or from its domain module — same objects either way
|
|
46
|
+
- **📊 Data Science Focused**: 99 exception classes covering ML pipelines, feature engineering, model training
|
|
47
|
+
- **🔧 Production Ready**: Logging helpers, error context, and exceptions that survive a process boundary intact
|
|
47
48
|
- **📚 Academic Quality**: Proper documentation, type hints, and citation support
|
|
48
49
|
- **🐍 Python 3.10+**: Modern Python with full type safety
|
|
49
|
-
- **🧪 Well Tested**:
|
|
50
|
+
- **🧪 Well Tested**: 690+ tests at 92% branch coverage of the package, gated in CI
|
|
50
51
|
|
|
51
52
|
## 📦 Quick Installation
|
|
52
53
|
|
|
@@ -67,8 +68,7 @@ poetry install
|
|
|
67
68
|
### Basic Usage
|
|
68
69
|
|
|
69
70
|
```python
|
|
70
|
-
from dataexcept import ValidationError
|
|
71
|
-
from dataexcept.datascience_exceptions import DataLoadingError, ModelTrainingError
|
|
71
|
+
from dataexcept import DataLoadingError, ModelTrainingError, ValidationError
|
|
72
72
|
import pandas as pd
|
|
73
73
|
|
|
74
74
|
# Data validation with context
|
|
@@ -105,8 +105,7 @@ def load_dataset(file_path: str) -> pd.DataFrame:
|
|
|
105
105
|
### Exception Hierarchies
|
|
106
106
|
|
|
107
107
|
```python
|
|
108
|
-
from dataexcept import
|
|
109
|
-
from dataexcept.datascience_exceptions import ModelTrainingError, ConvergenceError
|
|
108
|
+
from dataexcept import ConvergenceError, DataExceptError, ModelTrainingError
|
|
110
109
|
|
|
111
110
|
try:
|
|
112
111
|
# Your ML pipeline
|
|
@@ -119,8 +118,8 @@ except ModelTrainingError:
|
|
|
119
118
|
# Handle any training-related error
|
|
120
119
|
logger.error("Training failed, falling back to simpler model")
|
|
121
120
|
train_simple_model()
|
|
122
|
-
except
|
|
123
|
-
# Handle
|
|
121
|
+
except DataExceptError:
|
|
122
|
+
# Handle anything else DataExcept raised
|
|
124
123
|
logger.error("Job failed, notifying administrators")
|
|
125
124
|
send_alert()
|
|
126
125
|
```
|
|
@@ -214,7 +213,7 @@ except Exception as exc:
|
|
|
214
213
|
### Command Line Interface
|
|
215
214
|
|
|
216
215
|
```bash
|
|
217
|
-
# List every exception class the package exports (
|
|
216
|
+
# List every exception class the package exports (99 of them, alphabetically)
|
|
218
217
|
$ dataexcept list
|
|
219
218
|
ApiError
|
|
220
219
|
AuthenticationError
|
|
@@ -225,7 +224,7 @@ BiasDetectionError
|
|
|
225
224
|
|
|
226
225
|
# Check version
|
|
227
226
|
$ dataexcept --version
|
|
228
|
-
dataexcept 0.
|
|
227
|
+
dataexcept 0.4.0
|
|
229
228
|
```
|
|
230
229
|
|
|
231
230
|
## 🎯 Use Cases
|
|
@@ -375,7 +374,7 @@ If you use DataExcept in your research, please cite it:
|
|
|
375
374
|
author = {Ribeiro, Diogo},
|
|
376
375
|
title = {DataExcept: Structured Exception Handling for Data Science},
|
|
377
376
|
url = {https://github.com/DiogoRibeiro7/DataExcept},
|
|
378
|
-
version = {0.
|
|
377
|
+
version = {0.4.0},
|
|
379
378
|
year = {2026},
|
|
380
379
|
publisher = {GitHub}
|
|
381
380
|
}
|
|
@@ -15,12 +15,13 @@
|
|
|
15
15
|
|
|
16
16
|
## 🎯 Key Features
|
|
17
17
|
|
|
18
|
-
- **🏗️ Hierarchical Structure**: Catch specific
|
|
19
|
-
-
|
|
20
|
-
-
|
|
18
|
+
- **🏗️ Hierarchical Structure**: Catch one specific error, a whole domain, or everything via `DataExceptError`
|
|
19
|
+
- **📦 One Import**: Every exception is available from `dataexcept` directly, or from its domain module — same objects either way
|
|
20
|
+
- **📊 Data Science Focused**: 99 exception classes covering ML pipelines, feature engineering, model training
|
|
21
|
+
- **🔧 Production Ready**: Logging helpers, error context, and exceptions that survive a process boundary intact
|
|
21
22
|
- **📚 Academic Quality**: Proper documentation, type hints, and citation support
|
|
22
23
|
- **🐍 Python 3.10+**: Modern Python with full type safety
|
|
23
|
-
- **🧪 Well Tested**:
|
|
24
|
+
- **🧪 Well Tested**: 690+ tests at 92% branch coverage of the package, gated in CI
|
|
24
25
|
|
|
25
26
|
## 📦 Quick Installation
|
|
26
27
|
|
|
@@ -41,8 +42,7 @@ poetry install
|
|
|
41
42
|
### Basic Usage
|
|
42
43
|
|
|
43
44
|
```python
|
|
44
|
-
from dataexcept import ValidationError
|
|
45
|
-
from dataexcept.datascience_exceptions import DataLoadingError, ModelTrainingError
|
|
45
|
+
from dataexcept import DataLoadingError, ModelTrainingError, ValidationError
|
|
46
46
|
import pandas as pd
|
|
47
47
|
|
|
48
48
|
# Data validation with context
|
|
@@ -79,8 +79,7 @@ def load_dataset(file_path: str) -> pd.DataFrame:
|
|
|
79
79
|
### Exception Hierarchies
|
|
80
80
|
|
|
81
81
|
```python
|
|
82
|
-
from dataexcept import
|
|
83
|
-
from dataexcept.datascience_exceptions import ModelTrainingError, ConvergenceError
|
|
82
|
+
from dataexcept import ConvergenceError, DataExceptError, ModelTrainingError
|
|
84
83
|
|
|
85
84
|
try:
|
|
86
85
|
# Your ML pipeline
|
|
@@ -93,8 +92,8 @@ except ModelTrainingError:
|
|
|
93
92
|
# Handle any training-related error
|
|
94
93
|
logger.error("Training failed, falling back to simpler model")
|
|
95
94
|
train_simple_model()
|
|
96
|
-
except
|
|
97
|
-
# Handle
|
|
95
|
+
except DataExceptError:
|
|
96
|
+
# Handle anything else DataExcept raised
|
|
98
97
|
logger.error("Job failed, notifying administrators")
|
|
99
98
|
send_alert()
|
|
100
99
|
```
|
|
@@ -188,7 +187,7 @@ except Exception as exc:
|
|
|
188
187
|
### Command Line Interface
|
|
189
188
|
|
|
190
189
|
```bash
|
|
191
|
-
# List every exception class the package exports (
|
|
190
|
+
# List every exception class the package exports (99 of them, alphabetically)
|
|
192
191
|
$ dataexcept list
|
|
193
192
|
ApiError
|
|
194
193
|
AuthenticationError
|
|
@@ -199,7 +198,7 @@ BiasDetectionError
|
|
|
199
198
|
|
|
200
199
|
# Check version
|
|
201
200
|
$ dataexcept --version
|
|
202
|
-
dataexcept 0.
|
|
201
|
+
dataexcept 0.4.0
|
|
203
202
|
```
|
|
204
203
|
|
|
205
204
|
## 🎯 Use Cases
|
|
@@ -349,7 +348,7 @@ If you use DataExcept in your research, please cite it:
|
|
|
349
348
|
author = {Ribeiro, Diogo},
|
|
350
349
|
title = {DataExcept: Structured Exception Handling for Data Science},
|
|
351
350
|
url = {https://github.com/DiogoRibeiro7/DataExcept},
|
|
352
|
-
version = {0.
|
|
351
|
+
version = {0.4.0},
|
|
353
352
|
year = {2026},
|
|
354
353
|
publisher = {GitHub}
|
|
355
354
|
}
|