From 41a53f4247ded683fb521d8ce34e1535f6441a87 Mon Sep 17 00:00:00 2001 From: Artur Shiriev Date: Mon, 24 Aug 2026 15:46:49 +0300 Subject: [PATCH] chore(lint): drop the empty __slots__ DependencyPathMixin was lying about ty 0.0.74 began enforcing __slots__ and reported seven diagnostics against DependencyPathMixin, which declared __slots__ = () on a class whose base is object while its own __init__ set _base_message and dependency_path and prepend_step set args. The diagnostic is correct: instantiated on its own the class raises AttributeError. The empty __slots__ asserted the class had no instance attributes, and it had two. Deleting the line lets the mixing-in classes' declarations stand on their own and leaves attributes in slots: __dict__ is still {} after __init__. Instances grow 16 bytes on the nine mixin users, on the error path only. The "Empty __slots__" docstring paragraph goes with it. It explained the deleted line, and its claim that "each concrete error declares the slots itself" was only true for ScopeNotInitializedError and ScopeSkippedError; the resolution branch inherits both slots from ResolutionError. --- modern_di/exceptions.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/modern_di/exceptions.py b/modern_di/exceptions.py index 2055dee6..e64b60bf 100644 --- a/modern_di/exceptions.py +++ b/modern_di/exceptions.py @@ -102,14 +102,8 @@ class DependencyPathMixin: chain of provider names as it propagates back up to the caller. With an empty `dependency_path` (the error never passed through a resolution frame) `_render_body` returns the base message unchanged. - - Empty `__slots__`: each concrete error declares the `_base_message`/`dependency_path` slots - itself, avoiding the `TypeError: multiple bases have instance lay-out conflict` that a slotted - mixin combined with an `Exception` subclass would otherwise raise. """ - __slots__ = () - def __init__(self, message: str) -> None: self._base_message = message self.dependency_path: list[ResolutionStep] = []