You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
repr(user) and str(user) show [sealed] for every encrypted field and omit Ignore fields. A class that defines its own __repr__ or __str__ is refused at decoration unless the decorator is given redact=False. Cipher(User) can be constructed with credentials present and refuses a class that was not decorated, a class whose declaration changed since decoration, a subclass of a declared class, and the decorator refuses to declare a class twice.
Codes: DECLARATION_REPR_PRESENT, DECLARATION_NOT_DECORATED, DECLARATION_CLASS_CHANGED, DECLARATION_ALREADY_DECLARED. Cipher holds the plan and nothing else yet; encrypt, decrypt and query arrive in later tickets. Credentials: Cipher construction reads the CS_* variables once through the engine's AutoStrategy and refuses when they are absent, but makes no request yet.
Amendment: error codes are now lower_snake_case. See the amendment on #1341. Read each code in this issue in lower case, such as declaration_no_marker for DECLARATION_NO_MARKER.
Acceptance criteria
Redacted repr and str on all five class kinds; Ignore fields absent from the output.
A hand-written __repr__ is refused with REPR_PRESENT; redact=False lets it through and the test asserts plaintext then appears in repr (so the escape hatch is visibly dangerous).
Cipher(Undecorated) raises NOT_DECORATED.
Adding an annotation to the class after decoration makes Cipher(cls) raise CLASS_CHANGED.
Cipher(SubclassOfDeclared) raises NOT_DECORATED; decorating the same class twice raises ALREADY_DECLARED.
Cipher(User) without CS_* variables raises a StashError from the engine's credential discovery, not a Python KeyError.
Activity
encryptto a live Postgres row #1389