Labels: enhancement, good first issue
Context
dotflow/core/task.py:217-243 emits a DeprecationWarning on every get and every set of the deprecated Task.error property. Legacy consumers reading error in a hot path pay the cost on each access. Test runs with -W error (which converts warnings to exceptions) fail spuriously when a downstream library still references the old attribute.
Concept
Warn once per process. Use a module-level flag.
Proposed change
# dotflow/core/task.py
_ERROR_DEPRECATION_WARNED = False
@property
def error(self):
global _ERROR_DEPRECATION_WARNED
if not _ERROR_DEPRECATION_WARNED:
warnings.warn(
"'error' is deprecated, use 'errors' instead. "
"Note: 'TaskError.exception' is now a string "
"(e.g. 'ValueError'), not an Exception object.",
DeprecationWarning,
stacklevel=2,
)
_ERROR_DEPRECATION_WARNED = True
if not self.errors:
return TaskError()
return self.errors[-1]
Apply the same pattern to the setter.
Acceptance criteria
Labels:
enhancement,good first issueContext
dotflow/core/task.py:217-243emits aDeprecationWarningon every get and every set of the deprecatedTask.errorproperty. Legacy consumers readingerrorin a hot path pay the cost on each access. Test runs with-W error(which converts warnings to exceptions) fail spuriously when a downstream library still references the old attribute.Concept
Warn once per process. Use a module-level flag.
Proposed change
Apply the same pattern to the setter.
Acceptance criteria
errorgetter anderrorsetter use the flagTask.erroraccessed N times →pytest.warnscatchesexactly one warning