DataExcept 0.4.3__tar.gz → 1.1.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.
Files changed (38) hide show
  1. {dataexcept-0.4.3 → dataexcept-1.1.0}/CHANGELOG.md +60 -1
  2. {dataexcept-0.4.3 → dataexcept-1.1.0}/CITATION.cff +2 -2
  3. {dataexcept-0.4.3 → dataexcept-1.1.0}/PKG-INFO +4 -3
  4. {dataexcept-0.4.3 → dataexcept-1.1.0}/README.md +3 -2
  5. {dataexcept-0.4.3 → dataexcept-1.1.0}/dataexcept/__init__.py +7 -24
  6. {dataexcept-0.4.3 → dataexcept-1.1.0}/dataexcept/__main__.py +1 -8
  7. {dataexcept-0.4.3 → dataexcept-1.1.0}/dataexcept/datascience_exceptions/__init__.py +0 -11
  8. {dataexcept-0.4.3 → dataexcept-1.1.0}/dataexcept/exceptions/__init__.py +0 -13
  9. {dataexcept-0.4.3 → dataexcept-1.1.0}/dataexcept/pipeline_exceptions.py +0 -10
  10. dataexcept-1.1.0/dataexcept/wrapping.py +103 -0
  11. {dataexcept-0.4.3 → dataexcept-1.1.0}/pyproject.toml +1 -1
  12. dataexcept-0.4.3/dataexcept/_deprecation.py +0 -38
  13. dataexcept-0.4.3/dataexcept/job_exceptions.py +0 -71
  14. {dataexcept-0.4.3 → dataexcept-1.1.0}/LICENSE +0 -0
  15. {dataexcept-0.4.3 → dataexcept-1.1.0}/dataexcept/_validation.py +0 -0
  16. {dataexcept-0.4.3 → dataexcept-1.1.0}/dataexcept/base.py +0 -0
  17. {dataexcept-0.4.3 → dataexcept-1.1.0}/dataexcept/database_exceptions.py +0 -0
  18. {dataexcept-0.4.3 → dataexcept-1.1.0}/dataexcept/dataengineering_exceptions.py +0 -0
  19. {dataexcept-0.4.3 → dataexcept-1.1.0}/dataexcept/datascience_exceptions/base.py +0 -0
  20. {dataexcept-0.4.3 → dataexcept-1.1.0}/dataexcept/datascience_exceptions/ingestion.py +0 -0
  21. {dataexcept-0.4.3 → dataexcept-1.1.0}/dataexcept/datascience_exceptions/operations.py +0 -0
  22. {dataexcept-0.4.3 → dataexcept-1.1.0}/dataexcept/datascience_exceptions/training.py +0 -0
  23. {dataexcept-0.4.3 → dataexcept-1.1.0}/dataexcept/exceptions/authentication.py +0 -0
  24. {dataexcept-0.4.3 → dataexcept-1.1.0}/dataexcept/exceptions/base.py +0 -0
  25. {dataexcept-0.4.3 → dataexcept-1.1.0}/dataexcept/exceptions/configuration.py +0 -0
  26. {dataexcept-0.4.3 → dataexcept-1.1.0}/dataexcept/exceptions/external.py +0 -0
  27. {dataexcept-0.4.3 → dataexcept-1.1.0}/dataexcept/exceptions/lifecycle.py +0 -0
  28. {dataexcept-0.4.3 → dataexcept-1.1.0}/dataexcept/exceptions/notification.py +0 -0
  29. {dataexcept-0.4.3 → dataexcept-1.1.0}/dataexcept/exceptions/parsing.py +0 -0
  30. {dataexcept-0.4.3 → dataexcept-1.1.0}/dataexcept/exceptions/scheduling.py +0 -0
  31. {dataexcept-0.4.3 → dataexcept-1.1.0}/dataexcept/exceptions/validation.py +0 -0
  32. {dataexcept-0.4.3 → dataexcept-1.1.0}/dataexcept/io_exceptions.py +0 -0
  33. {dataexcept-0.4.3 → dataexcept-1.1.0}/dataexcept/logging_helpers.py +0 -0
  34. {dataexcept-0.4.3 → dataexcept-1.1.0}/dataexcept/network_exceptions.py +0 -0
  35. {dataexcept-0.4.3 → dataexcept-1.1.0}/dataexcept/pandas_exceptions.py +0 -0
  36. {dataexcept-0.4.3 → dataexcept-1.1.0}/dataexcept/py.typed +0 -0
  37. {dataexcept-0.4.3 → dataexcept-1.1.0}/dataexcept/redaction.py +0 -0
  38. {dataexcept-0.4.3 → dataexcept-1.1.0}/dataexcept/security_exceptions.py +0 -0
@@ -7,6 +7,63 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.1.0] - 2026-09-02
11
+
12
+ ### Added
13
+
14
+ - **`wrap` and `wrapping`**, for turning a third-party exception into a
15
+ DataExcept one:
16
+
17
+ ```python
18
+ with wrapping(OSError, DataLoadingError, source=path):
19
+ frame = pd.read_csv(path)
20
+ ```
21
+
22
+ The hand-written form is easy to get subtly wrong: a missing `from exc` loses
23
+ the traceback, the original passed to the wrong parameter is not recorded,
24
+ and a broad `except` relabels a `KeyboardInterrupt` as a data error. These
25
+ settle the wiring — the original goes to whichever constructor parameter
26
+ takes a cause (`original`, `original_exception` or `cause`) and is set as
27
+ `__cause__` either way, which matters because only 17 of the 100 classes
28
+ record one on an attribute.
29
+ - Guidance in the advanced usage guide on building a project-specific
30
+ hierarchy on these bases, and what deriving from a domain root gets you.
31
+
32
+ ## [1.0.0] - 2026-08-25
33
+
34
+ First stable release. The public API is frozen; see the
35
+ [stability policy](https://diogoribeiro7.github.io/DataExcept/stability/)
36
+ and the [migration guide](https://diogoribeiro7.github.io/DataExcept/migration/).
37
+
38
+ ### Added
39
+
40
+ - A [migration guide](https://diogoribeiro7.github.io/DataExcept/migration/)
41
+ covering every rename between 0.1 and 1.0, with the one-line check for
42
+ whether any of it applies to you:
43
+ `python -W error::DeprecationWarning -m pytest` on 0.4.3.
44
+
45
+ ### Changed
46
+
47
+ - **The public API is frozen.** The stability policy no longer carries a
48
+ pre-1.0 caveat: nothing public is renamed or removed outside a major release,
49
+ and anything that will be removed is deprecated first.
50
+
51
+ ### Removed
52
+
53
+ - **`dataexcept.job_exceptions`**, deprecated since 0.1.0. Every name it
54
+ exported is available from `dataexcept.exceptions` and from the top-level
55
+ package, and they are the same class objects, so this is a change of import
56
+ line only.
57
+ - **The four aliases introduced in 0.2.0**: `ConnectionError`,
58
+ `TimeoutError`, `datascience_exceptions.SerializationError` and
59
+ `pipeline_exceptions.FeatureEngineeringError`. Each has emitted a
60
+ `DeprecationWarning` naming 1.0.0 as its removal since 0.2.0.
61
+ `SerializationError` and `FeatureEngineeringError` remain exported — the
62
+ rename applied to the *duplicate* in each pair, and the original kept its
63
+ name.
64
+ - The deprecation machinery itself (`dataexcept._deprecation`), which nothing
65
+ uses now.
66
+
10
67
  ### Fixed
11
68
 
12
69
  - The release workflow's `verify-wheel` job installed a hand-written list of
@@ -474,7 +531,9 @@ First public release.
474
531
  - Published to PyPI via OIDC trusted publishing; no long-lived API token is
475
532
  involved in a release.
476
533
 
477
- [Unreleased]: https://github.com/DiogoRibeiro7/DataExcept/compare/v0.4.3...HEAD
534
+ [Unreleased]: https://github.com/DiogoRibeiro7/DataExcept/compare/v1.1.0...HEAD
535
+ [1.1.0]: https://github.com/DiogoRibeiro7/DataExcept/compare/v1.0.0...v1.1.0
536
+ [1.0.0]: https://github.com/DiogoRibeiro7/DataExcept/compare/v0.4.3...v1.0.0
478
537
  [0.4.3]: https://github.com/DiogoRibeiro7/DataExcept/compare/v0.4.2...v0.4.3
479
538
  [0.4.2]: https://github.com/DiogoRibeiro7/DataExcept/compare/v0.4.1...v0.4.2
480
539
  [0.4.1]: https://github.com/DiogoRibeiro7/DataExcept/compare/v0.4.0...v0.4.1
@@ -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: "0.4.3"
4
+ version: "1.1.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-08-25"
14
+ date-released: "2026-09-02"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: DataExcept
3
- Version: 0.4.3
3
+ Version: 1.1.0
4
4
  Summary: A Python package providing structured, easily-extendable custom exception types.
5
5
  License-Expression: MIT
6
6
  License-File: LICENSE
@@ -225,7 +225,7 @@ BiasDetectionError
225
225
 
226
226
  # Check version
227
227
  $ dataexcept --version
228
- dataexcept 0.4.3
228
+ dataexcept 1.0.0
229
229
  ```
230
230
 
231
231
  ## 🎯 Use Cases
@@ -362,6 +362,7 @@ through [SECURITY.md](SECURITY.md), not the public issue tracker.
362
362
  - **Full Documentation**: [diogoribeiro7.github.io/DataExcept](https://diogoribeiro7.github.io/DataExcept/)
363
363
  - **API Reference**: [API Docs](https://diogoribeiro7.github.io/DataExcept/api/)
364
364
  - **API Stability**: [What is public and what may change](https://diogoribeiro7.github.io/DataExcept/stability/)
365
+ - **Upgrading from 0.x**: [Migration guide](https://diogoribeiro7.github.io/DataExcept/migration/)
365
366
  - **Advanced Usage**: [Advanced Guide](https://diogoribeiro7.github.io/DataExcept/advanced_usage/)
366
367
  - **CLI Reference**: [CLI Guide](https://diogoribeiro7.github.io/DataExcept/cli/)
367
368
  - **Changelog**: [CHANGELOG.md](CHANGELOG.md)
@@ -375,7 +376,7 @@ If you use DataExcept in your research, please cite it:
375
376
  author = {Ribeiro, Diogo},
376
377
  title = {DataExcept: Structured Exception Handling for Data Science},
377
378
  url = {https://github.com/DiogoRibeiro7/DataExcept},
378
- version = {0.4.3},
379
+ version = {1.0.0},
379
380
  year = {2026},
380
381
  publisher = {GitHub}
381
382
  }
@@ -198,7 +198,7 @@ BiasDetectionError
198
198
 
199
199
  # Check version
200
200
  $ dataexcept --version
201
- dataexcept 0.4.3
201
+ dataexcept 1.0.0
202
202
  ```
203
203
 
204
204
  ## 🎯 Use Cases
@@ -335,6 +335,7 @@ through [SECURITY.md](SECURITY.md), not the public issue tracker.
335
335
  - **Full Documentation**: [diogoribeiro7.github.io/DataExcept](https://diogoribeiro7.github.io/DataExcept/)
336
336
  - **API Reference**: [API Docs](https://diogoribeiro7.github.io/DataExcept/api/)
337
337
  - **API Stability**: [What is public and what may change](https://diogoribeiro7.github.io/DataExcept/stability/)
338
+ - **Upgrading from 0.x**: [Migration guide](https://diogoribeiro7.github.io/DataExcept/migration/)
338
339
  - **Advanced Usage**: [Advanced Guide](https://diogoribeiro7.github.io/DataExcept/advanced_usage/)
339
340
  - **CLI Reference**: [CLI Guide](https://diogoribeiro7.github.io/DataExcept/cli/)
340
341
  - **Changelog**: [CHANGELOG.md](CHANGELOG.md)
@@ -348,7 +349,7 @@ If you use DataExcept in your research, please cite it:
348
349
  author = {Ribeiro, Diogo},
349
350
  title = {DataExcept: Structured Exception Handling for Data Science},
350
351
  url = {https://github.com/DiogoRibeiro7/DataExcept},
351
- version = {0.4.3},
352
+ version = {1.0.0},
352
353
  year = {2026},
353
354
  publisher = {GitHub}
354
355
  }
@@ -4,8 +4,8 @@ Every exception the package defines is importable straight from here::
4
4
 
5
5
  from dataexcept import ValidationError, ModelTrainingError
6
6
 
7
- They all derive from :class:`DataExceptError`, so one clause catches anything
8
- this package raises::
7
+ They all derive from :class:`DataExceptError`, so one clause catches every
8
+ operational exception this package raises::
9
9
 
10
10
  except DataExceptError:
11
11
  ...
@@ -22,8 +22,7 @@ try: # Python >=3.11
22
22
  except ModuleNotFoundError: # pragma: no cover - fallback for Python <3.11
23
23
  import tomli as tomllib # type: ignore
24
24
 
25
- from importlib import import_module, metadata
26
- from typing import Any
25
+ from importlib import metadata
27
26
 
28
27
  from . import ( # noqa: F401
29
28
  database_exceptions,
@@ -37,7 +36,6 @@ from . import ( # noqa: F401
37
36
  pipeline_exceptions,
38
37
  security_exceptions,
39
38
  )
40
- from ._deprecation import resolve_deprecated
41
39
  from .base import DataExceptError, UnpicklableCause, UnpicklableValue
42
40
  from .database_exceptions import (
43
41
  DatabaseConnectionError,
@@ -161,6 +159,7 @@ from .security_exceptions import (
161
159
  InvalidTokenError,
162
160
  SecurityError,
163
161
  )
162
+ from .wrapping import wrap, wrapping
164
163
 
165
164
  __all__ = [
166
165
  # The root of the hierarchy: catches every operational exception the
@@ -268,15 +267,15 @@ __all__ = [
268
267
  "UnderfittingError",
269
268
  "ValidationError",
270
269
  "WebhookError",
270
+ # Turning a third-party exception into one of these.
271
+ "wrap",
272
+ "wrapping",
271
273
  # Logging helpers.
272
274
  "Context",
273
275
  "log_and_raise",
274
276
  "log_exception",
275
277
  "log_then_raise",
276
278
  # Domain modules, for callers who prefer a qualified import.
277
- # job_exceptions is deliberately absent: it is deprecated, and listing it
278
- # makes `from dataexcept import *` emit a DeprecationWarning, which turns
279
- # into an error under -W error::DeprecationWarning. It stays importable.
280
279
  "database_exceptions",
281
280
  "dataengineering_exceptions",
282
281
  "datascience_exceptions",
@@ -295,19 +294,3 @@ except metadata.PackageNotFoundError: # pragma: no cover - fallback during dev
295
294
  _root = Path(__file__).resolve().parents[1]
296
295
  with open(_root / "pyproject.toml", "rb") as _f:
297
296
  __version__ = tomllib.load(_f)["project"]["version"]
298
-
299
-
300
- #: Renamed in 0.2.0 because they shadowed Python builtins without inheriting
301
- #: from them. Each alias is the same class object as its replacement.
302
- _DEPRECATED_ALIASES = {
303
- "ConnectionError": ServiceConnectionError,
304
- "TimeoutError": OperationTimeoutError,
305
- }
306
-
307
-
308
- def __getattr__(name: str) -> Any:
309
- if name == "job_exceptions":
310
- module = import_module("dataexcept.job_exceptions")
311
- globals()[name] = module
312
- return module
313
- return resolve_deprecated(__name__, _DEPRECATED_ALIASES, name)
@@ -12,14 +12,9 @@ from typing import Iterable
12
12
  from . import __path__ as _PKG_PATH
13
13
  from . import __version__
14
14
 
15
- #: Deprecated compatibility shims. Listing these would advertise names that are
16
- #: scheduled for removal, and importing them emits a DeprecationWarning at
17
- #: anyone who merely wanted to see what the package offers.
18
- _DEPRECATED_MODULES = frozenset({"dataexcept.job_exceptions"})
19
-
20
15
 
21
16
  def _iter_exception_modules() -> Iterable[ModuleType]:
22
- """Yield every non-deprecated submodule that explicitly defines ``__all__``."""
17
+ """Yield every submodule that explicitly defines ``__all__``."""
23
18
  allowed_suffixes = ("exceptions", "_exceptions")
24
19
  # dataexcept.base holds DataExceptError, the root of the hierarchy, and
25
20
  # does not match the suffix rule.
@@ -33,8 +28,6 @@ def _iter_exception_modules() -> Iterable[ModuleType]:
33
28
  and module_info.name not in always_include
34
29
  ):
35
30
  continue
36
- if module_info.name in _DEPRECATED_MODULES:
37
- continue
38
31
  try:
39
32
  module = import_module(module_info.name)
40
33
  except ImportError as exc: # pragma: no cover - defensive guard
@@ -1,8 +1,5 @@
1
1
  """Custom exceptions for data science workflows."""
2
2
 
3
- from typing import Any
4
-
5
- from .._deprecation import resolve_deprecated
6
3
  from .base import DataScienceError
7
4
  from .ingestion import (
8
5
  DataAugmentationError,
@@ -86,11 +83,3 @@ __all__ = [
86
83
  "FeatureScalingError",
87
84
  "ModelCompatibilityError",
88
85
  ]
89
-
90
- #: Renamed in 0.2.0: this named the same thing as
91
- #: ``dataexcept.exceptions.SerializationError`` while being a different class.
92
- _DEPRECATED_ALIASES = {"SerializationError": ModelSerializationError}
93
-
94
-
95
- def __getattr__(name: str) -> Any:
96
- return resolve_deprecated(__name__, _DEPRECATED_ALIASES, name)
@@ -1,7 +1,5 @@
1
1
  # __init__.py
2
- from typing import Any
3
2
 
4
- from .._deprecation import resolve_deprecated
5
3
  from .authentication import AuthenticationError, AuthorizationError
6
4
  from .base import JobError
7
5
  from .configuration import ConfigurationError
@@ -37,14 +35,3 @@ __all__ = [
37
35
  "WebhookError",
38
36
  "JobCancellationError",
39
37
  ]
40
-
41
- #: Renamed in 0.2.0 because they shadowed Python builtins without inheriting
42
- #: from them. The alias is the same class object, so ``except`` keeps working.
43
- _DEPRECATED_ALIASES = {
44
- "ConnectionError": ServiceConnectionError,
45
- "TimeoutError": OperationTimeoutError,
46
- }
47
-
48
-
49
- def __getattr__(name: str) -> Any:
50
- return resolve_deprecated(__name__, _DEPRECATED_ALIASES, name)
@@ -4,7 +4,6 @@ from __future__ import annotations
4
4
 
5
5
  from typing import Any, Optional
6
6
 
7
- from ._deprecation import resolve_deprecated
8
7
  from .base import DataExceptError
9
8
  from .redaction import redact_if_url, redact_url
10
9
 
@@ -210,12 +209,3 @@ __all__ = [
210
209
  "TypeCheckError",
211
210
  "DataFetchError",
212
211
  ]
213
-
214
- #: Renamed in 0.2.0: this named the same thing as
215
- #: ``dataexcept.datascience_exceptions.FeatureEngineeringError`` while being a
216
- #: different class, so catching one silently missed the other.
217
- _DEPRECATED_ALIASES = {"FeatureEngineeringError": FeaturePreprocessingError}
218
-
219
-
220
- def __getattr__(name: str) -> Any:
221
- return resolve_deprecated(__name__, _DEPRECATED_ALIASES, name)
@@ -0,0 +1,103 @@
1
+ """Turning a third-party exception into a DataExcept one.
2
+
3
+ The pattern this replaces is everywhere in pipeline code::
4
+
5
+ try:
6
+ frame = pd.read_csv(path)
7
+ except OSError as exc:
8
+ raise DataLoadingError(path, exc) from exc
9
+
10
+ It is easy to write and easy to get subtly wrong: forget the ``from exc`` and
11
+ the traceback stops showing what actually failed; pass the original to the
12
+ wrong parameter and it is not recorded at all; catch too broadly and a
13
+ ``KeyboardInterrupt`` becomes a data-loading error.
14
+
15
+ :func:`wrap` and :func:`wrapping` do the same thing with the wiring settled.
16
+ The original is passed to whichever constructor parameter takes a cause --
17
+ ``original``, ``original_exception`` or ``cause``, whichever that class uses --
18
+ and set as ``__cause__`` either way, so a traceback always shows both.
19
+ """
20
+
21
+ from __future__ import annotations
22
+
23
+ import contextlib
24
+ import inspect
25
+ from typing import Any, Iterator, Tuple, Type, Union
26
+
27
+ from .base import DataExceptError
28
+
29
+ __all__ = ["wrap", "wrapping"]
30
+
31
+ #: Constructor parameter names used across the package for a wrapped
32
+ #: exception. Checked in this order; the first the target accepts wins.
33
+ _CAUSE_PARAMETERS = ("original", "original_exception", "cause")
34
+
35
+ Catchable = Union[Type[BaseException], Tuple[Type[BaseException], ...]]
36
+
37
+
38
+ def _cause_parameter(target: Type[DataExceptError]) -> str | None:
39
+ """Return the parameter of *target* that takes a wrapped exception."""
40
+ try:
41
+ parameters = inspect.signature(target.__init__).parameters
42
+ except (TypeError, ValueError): # pragma: no cover - builtins and C types
43
+ return None
44
+ for name in _CAUSE_PARAMETERS:
45
+ if name in parameters:
46
+ return name
47
+ return None
48
+
49
+
50
+ def wrap(
51
+ original: BaseException,
52
+ target: Type[DataExceptError],
53
+ /,
54
+ **kwargs: Any,
55
+ ) -> DataExceptError:
56
+ """Build *target* from *original*, recording it as the cause.
57
+
58
+ Extra keyword arguments go to the constructor::
59
+
60
+ raise wrap(exc, DataLoadingError, source=path) from exc
61
+
62
+ If *target* accepts a cause parameter, *original* is passed to it. Either
63
+ way ``__cause__`` is set, so a traceback shows the underlying failure even
64
+ for a class that records nothing.
65
+
66
+ An explicit ``original``/``cause`` keyword wins, so a caller can still say
67
+ exactly what they mean.
68
+ """
69
+ parameter = _cause_parameter(target)
70
+ if parameter is not None and parameter not in kwargs:
71
+ kwargs[parameter] = original
72
+
73
+ exception = target(**kwargs)
74
+ # Set unconditionally: the target may record nothing, and the point is that
75
+ # the traceback shows what actually failed.
76
+ exception.__cause__ = original
77
+ return exception
78
+
79
+
80
+ @contextlib.contextmanager
81
+ def wrapping(
82
+ catch: Catchable,
83
+ target: Type[DataExceptError],
84
+ /,
85
+ **kwargs: Any,
86
+ ) -> Iterator[None]:
87
+ """Translate *catch* raised inside the block into *target*.
88
+
89
+ ::
90
+
91
+ with wrapping(OSError, DataLoadingError, source=path):
92
+ frame = pd.read_csv(path)
93
+
94
+ Only exceptions matching *catch* are translated; everything else propagates
95
+ untouched, including anything already raised by this package. Because
96
+ *catch* is given explicitly there is no default broad ``except``, so a
97
+ ``KeyboardInterrupt`` or a bug in the block is never relabelled as a data
98
+ error.
99
+ """
100
+ try:
101
+ yield
102
+ except catch as exc:
103
+ raise wrap(exc, target, **kwargs) from exc
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "DataExcept"
3
- version = "0.4.3"
3
+ version = "1.1.0"
4
4
  description = "A Python package providing structured, easily-extendable custom exception types."
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -1,38 +0,0 @@
1
- """Internal support for names that have been renamed.
2
-
3
- A rename keeps the old name working as an alias bound to the *same* class
4
- object, so an existing ``except OldName:`` keeps catching exactly what it
5
- caught before -- the alias is not a separate class.
6
-
7
- Access goes through a PEP 562 module ``__getattr__`` rather than a plain
8
- ``OldName = NewName`` assignment, because an assignment cannot warn. This is
9
- private; see the stability policy for the user-facing contract.
10
- """
11
-
12
- from __future__ import annotations
13
-
14
- import warnings
15
- from typing import Any, Mapping
16
-
17
- #: Version in which every currently deprecated alias is removed.
18
- REMOVED_IN = "1.0.0"
19
-
20
-
21
- def resolve_deprecated(module: str, aliases: Mapping[str, Any], name: str) -> Any:
22
- """Return the target of the deprecated *name*, warning first.
23
-
24
- Raises ``AttributeError`` for anything not in *aliases*, so normal
25
- attribute lookup on the module keeps behaving normally.
26
- """
27
- try:
28
- target = aliases[name]
29
- except KeyError:
30
- raise AttributeError(f"module {module!r} has no attribute {name!r}") from None
31
- warnings.warn(
32
- f"{module}.{name} is deprecated and will be removed in {REMOVED_IN}; "
33
- f"use {target.__name__} instead",
34
- DeprecationWarning,
35
- # resolve_deprecated -> __getattr__ -> the caller we want to blame.
36
- stacklevel=3,
37
- )
38
- return target
@@ -1,71 +0,0 @@
1
- """Backward compatible job-related exceptions.
2
-
3
- .. deprecated:: 0.1.0
4
- Use :mod:`dataexcept.exceptions` instead. This module is scheduled for
5
- removal in 1.0.0; see the stability policy in the documentation.
6
-
7
- This module re-exports the core job exceptions defined in
8
- :mod:`dataexcept.exceptions`. Importing it emits a :class:`DeprecationWarning`.
9
- Every name it exports is available from :mod:`dataexcept.exceptions` and from
10
- the top-level :mod:`dataexcept` package, so the migration is a change of import
11
- line only -- the classes are identical objects, not replacements, so existing
12
- ``except`` clauses keep working during the transition.
13
- """
14
-
15
- from __future__ import annotations
16
-
17
- import warnings
18
-
19
- from .exceptions import (
20
- AuthenticationError,
21
- AuthorizationError,
22
- ConfigurationError,
23
- CronExpressionError,
24
- DependencyError,
25
- DeserializationError,
26
- EmailError,
27
- JobCancellationError,
28
- JobError,
29
- NotificationError,
30
- OperationTimeoutError,
31
- ParsingError,
32
- ResourceNotFoundError,
33
- ScheduleConflictError,
34
- SerializationError,
35
- ServiceConnectionError,
36
- ValidationError,
37
- WebhookError,
38
- )
39
-
40
- # This module is itself deprecated, so it binds the pre-0.2.0 names directly
41
- # rather than going through the alias machinery and warning a second time.
42
- ConnectionError = ServiceConnectionError
43
- TimeoutError = OperationTimeoutError
44
-
45
- __all__ = [
46
- "JobError",
47
- "ValidationError",
48
- "ConfigurationError",
49
- "ConnectionError",
50
- "TimeoutError",
51
- "ResourceNotFoundError",
52
- "DependencyError",
53
- "AuthenticationError",
54
- "AuthorizationError",
55
- "ParsingError",
56
- "SerializationError",
57
- "DeserializationError",
58
- "ScheduleConflictError",
59
- "CronExpressionError",
60
- "NotificationError",
61
- "EmailError",
62
- "WebhookError",
63
- "JobCancellationError",
64
- ]
65
-
66
- warnings.warn(
67
- "dataexcept.job_exceptions is deprecated and will be removed in 1.0.0; "
68
- "use dataexcept.exceptions instead",
69
- DeprecationWarning,
70
- stacklevel=2,
71
- )
File without changes