Vault#

class scikitplot.cleanprompt.Vault(mapping=None, grammar_fingerprint=None)[source]#

A closed mapping from placeholder label to original secret.

Parameters:
mappingmapping of str to str, optional

Initial label-to-secret pairs. Copied; the vault does not alias the caller’s dictionary.

grammar_fingerprintstr, optional

Digest of the placeholder grammar that issued these labels — the fingerprint, not the whole policy’s. When set, restoration verifies it.

Raises:
PolicyError

If a label is empty or duplicated with a conflicting value.

Parameters:
  • mapping (Mapping[str, str] | None)

  • grammar_fingerprint (str | None)

Notes

Developer notes. The vault is append-only through add and is not thread-safe for concurrent writes. It does not need to be: one vault belongs to one redaction pass, which is single-threaded by construction. Sharing one vault across documents is the very defect this rewrite retires, so no locking is provided that would make it look supported.

Examples

>>> vault = Vault({"[EMAIL-1]": "a@b.c"})
>>> vault["[EMAIL-1]"]
'a@b.c'
>>> repr(vault)
'Vault(entries=1, closed=False)'
>>> vault.clear()
>>> len(vault)
0
add(label, secret)[source]#

Record one label-to-secret pair.

Parameters:
labelstr

The rendered placeholder, including delimiters.

secretstr

The original text the label stands for.

Raises:
PolicyError

If label is empty, if the vault is closed, or if label is already present with a different secret.

Parameters:
Return type:

None

Notes

Developer notes. Re-adding an identical pair is a no-op rather than an error, because the engine assigns one label per distinct value and may legitimately confirm an existing pair. A conflicting re-add means two different secrets were given the same label, which would make restoration ambiguous; that is always a bug and always raises.

clear()[source]#

Drop every secret and close the vault.

Notes

Developer notes. Values are overwritten before deletion so that any surviving reference to the dictionary observes no plaintext. This does not and cannot guarantee that the interpreter has erased every copy of each string from process memory; see the module-level note.

Return type:

None

property closed: bool#

Whether clear has been called.

Type:

bool

export()[source]#

Return a plain dictionary copy of the mapping, secrets included.

Returns:
dict of str to str

A copy of the label-to-secret mapping.

Raises:
PolicyError

If the vault has been cleared.

Return type:

dict[str, str]

Notes

User notes. This is the deliberate, named way to get the secrets out — for instance to persist a session on the machine that owns the data. Nothing in this submodule calls it implicitly, and no serializer reaches it by accident.

get(label, default=None)[source]#

Return the secret for label, or default.

Parameters:
labelstr

The placeholder to look up.

defaultstr, optional

Returned when label is absent.

Returns:
str or None

The stored secret, or default.

Parameters:
  • label (str)

  • default (str | None)

Return type:

str | None

property grammar_fingerprint: str | None#

Digest of the grammar that issued these labels.

Type:

Str or None

items()[source]#

Return a live view of label-to-secret pairs.

Returns:
ItemsView

The mapping’s items.

Return type:

ItemsView[str, str]

Notes

Developer notes. This exposes secrets and is named plainly rather than hidden, because restoration needs it. Prefer labels in any code path that logs, renders or serializes.

labels()[source]#

Return every label in insertion order.

Returns:
tuple of str

The labels. Safe to log: labels are not secrets.

Return type:

tuple