Add per-report-type mailbox delete options (#858)

* Add per-report-type mailbox delete options (#256)

Add four new [mailbox] options — delete_aggregate, delete_failure,
delete_smtp_tls, and delete_invalid — each defaulting to the value of
the overall delete option and individually overridable, so e.g.
delete = True with delete_failure = False deletes processed aggregate
and SMTP TLS report messages while archiving failure reports, and
delete_invalid = False keeps unparseable messages in the Invalid
archive subfolder for debugging.

get_dmarc_reports_from_mailbox() and watch_inbox() gained matching
bool | None keyword arguments (None = inherit from delete), resolved
once up front; the delete/test mutual-exclusion guard now checks the
effective per-type flags. The Gmail deletion-scope guard covers any
effective flag and forces all five options off when the scope is
missing. PARSEDMARC_MAILBOX_DELETE_* env vars work automatically.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Document per-type delete kwargs as bool | None with explicit inheritance

Copilot review: the docstrings typed the four per-report-type delete
parameters as plain bool, but None (the default) is the inheritance
mechanism — a library caller couldn't tell from the docs that None,
not False, means "inherit delete".

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Cover disposal error branches; scope the config= docstring claim

Codecov flagged the delete-error handler in the new per-type disposal
loop as the one uncovered patch line. Add two Maildir tests driving a
backend whose first delete/move call raises: the error is logged, the
affected message stays in the INBOX, and disposal continues to the
next report type. The move-error branch gets the symmetric test from
the same harness.

Copilot review: the config= docstring paragraph claimed all keyword
arguments listed above it are ignored when config= is provided, which
now falsely included the four per-type delete options. Scope the claim
to the parsing/enrichment arguments ParserConfig actually carries and
state that mailbox-handling arguments always apply.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Sean Whalen
2026-07-26 13:31:37 -04:00
committed by GitHub
co-authored by Claude Fable 5
parent 264b9a4556
commit ae5f4c7915
6 changed files with 725 additions and 66 deletions
+23
View File
@@ -216,6 +216,29 @@ The full set of configuration options are:
messages as they arrive or poll MS Graph for new messages
- `delete` - bool: Delete messages after processing them,
instead of archiving them
- `delete_aggregate` - bool: Delete aggregate report messages
after processing them, instead of archiving them
(Default: the value of `delete`)
- `delete_failure` - bool: Delete failure report messages
after processing them, instead of archiving them
(Default: the value of `delete`)
- `delete_smtp_tls` - bool: Delete SMTP TLS report messages
after processing them, instead of archiving them
(Default: the value of `delete`)
- `delete_invalid` - bool: Delete messages that could not be
parsed, instead of archiving them in the `Invalid`
subfolder, where they can be inspected for debugging
(Default: the value of `delete`)
:::{note}
Each of these four options overrides `delete` for one kind of
message only, and the other three keep inheriting `delete`. So
`delete = True` combined with `delete_failure = False` archives
failure report messages while deleting processed aggregate and
SMTP TLS report messages — and unparseable ones, unless
`delete_invalid = False` is set as well.
:::
- `test` - bool: Do not move or delete messages
- `batch_size` - int: Number of messages to read and process
before saving. Default `10`. Use `0` for no limit.