• 
      

    Add a common mixin class for handling invalidation.

    Review Request #15170 — Created July 15, 2026 and updated

    Information

    cryptozoology
    master

    Reviewers

    Sensitive data (keys, secrets) are intended to be invalidated early,
    keeping the data safe and out of memory as best as possible.

    This class implements this as a mixin class. It handles invalidation
    when the instance falls out of scope, and allows the object to be used
    as a context manager, invalidating on exit.

    Unit tests pass.

    Summary ID
    Add a common mixin class for handling invalidation.
    Sensitive data (keys, secrets) are intended to be invalidated early, keeping the data safe and out of memory as best as possible. This class implements this as a mixin class. It handles invalidation when the instance falls out of scope, and allows the object to be used as a context manager, invalidating on exit.
    7545462ea83693d7a39ab6c19687196949dfcf3d
    Description From Last Updated

    Instead of methods that raise NotImplementedError, how about subclassing abc.ABC and marking those with @abstractmethod?

    david david

    Should probably change this to say self?

    david david

    __exit__ never gets called with kwargs. Can we use the standard signature? def __exit( self, exc_type: type[BaseException] | None, exc_value: …

    david david

    If a subclass raises an exception from __init__, __del__ could get called on a partially-constructed instance. If the implementation of …

    david david

    It's harmless here, but just to model goot behavior, can we call super().__init__()?

    david david

    Since this is greenfield, can we use pytest test cases and real docstrings instead of a UnitTest subclass?

    david david

    typo: exceptio -> exception

    david david

    This was copy/pasted without updating to match the test.

    david david
    chipx86
    Review request changed
    Change Summary:

    Removed the changes to BaseKey. Changing the order of commits.

    Commits:
    Summary ID
    Add a common mixin class for handling invalidation.
    Sensitive data (keys, secrets) are intended to be invalidated early, keeping the data safe and out of memory as best as possible. This class implements this as a mixin class. It handles invalidation when the instance falls out of scope, and allows the object to be used as a context manager, invalidating on exit.
    e713456079169d085dbd89d8a9e54ae804b475cf
    Add a common mixin class for handling invalidation.
    Sensitive data (keys, secrets) are intended to be invalidated early, keeping the data safe and out of memory as best as possible. This class implements this as a mixin class. It handles invalidation when the instance falls out of scope, and allows the object to be used as a context manager, invalidating on exit.
    7545462ea83693d7a39ab6c19687196949dfcf3d

    Checks run (2 succeeded)

    flake8 passed.
    JSHint passed.
    david
    1. 
        
    2. cryptozoology/utils/invalidation.py (Diff revision 2)
       
       
      Show all issues

      Instead of methods that raise NotImplementedError, how about subclassing abc.ABC and marking those with @abstractmethod?

    3. cryptozoology/utils/invalidation.py (Diff revision 2)
       
       
      Show all issues

      Should probably change this to say self?

    4. cryptozoology/utils/invalidation.py (Diff revision 2)
       
       
      Show all issues

      __exit__ never gets called with kwargs. Can we use the standard signature?

      def __exit(
          self,
          exc_type: type[BaseException] | None,
          exc_value: BaseException | None,
          traceback: TracebackType | None,
      ) -> None:
      
    5. cryptozoology/utils/invalidation.py (Diff revision 2)
       
       
       
       
       
       
       
      Show all issues

      If a subclass raises an exception from __init__, __del__ could get called on a partially-constructed instance. If the implementation of invalidate() then assumes an attribute it set, it will AttributeError, and python will silently swallow it (I think it prints to stderr, but that's not the best for a library). This could leave the object not fully invalidated.

      Can we document in here that the implementation must be able to handle partially-constructed instances, and cannot assume that all attributes have been set?

      We also should document that this method needs to be idempotent, since it can get called first from __exit__ and then again from __del__

    6. cryptozoology/utils/tests/test_invalidatable_mixin.py (Diff revision 2)
       
       
       
       
       
       
      Show all issues

      It's harmless here, but just to model goot behavior, can we call super().__init__()?

    7. Show all issues

      Since this is greenfield, can we use pytest test cases and real docstrings instead of a UnitTest subclass?

    8. Show all issues

      typo: exceptio -> exception

    9. Show all issues

      This was copy/pasted without updating to match the test.

    10.