From b2de0a0e391659a1f1418c84379aba6df73513cc Mon Sep 17 00:00:00 2001 From: dlrsp-dev Date: Mon, 7 Sep 2026 00:54:18 +0200 Subject: [PATCH 1/2] fix(mail): resolve identity env file path at call time Default env_file was bound at import, so monkeypatched paths and CI hosts never saw the identity file and fell back to unknown+hostname. --- src/django_errors/mail_identity.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/django_errors/mail_identity.py b/src/django_errors/mail_identity.py index 5cc380fa..bb1f7b09 100644 --- a/src/django_errors/mail_identity.py +++ b/src/django_errors/mail_identity.py @@ -43,12 +43,13 @@ def identity_tag( role: Optional[str] = None, hostname: Optional[str] = None, install_tag: Optional[str] = None, - env_file: str | Path = _DEFAULT_ENV_FILE, + env_file: str | Path | None = None, environ: Optional[Mapping[str, str]] = None, ) -> str: """Return the compact identity tag for this host.""" env = environ if environ is not None else os.environ - file_vars = _read_env_file(env_file) + # Resolve default at call time so tests can monkeypatch ``_DEFAULT_ENV_FILE``. + file_vars = _read_env_file(_DEFAULT_ENV_FILE if env_file is None else env_file) cached = (env.get("SH_MAIL_IDENTITY_TAG") or file_vars.get("SH_MAIL_IDENTITY_TAG") or "").strip() if cached and scope is None and role is None and hostname is None and install_tag is None: @@ -81,15 +82,16 @@ def subject_prefix( kind: str = "app", *, environ: Optional[Mapping[str, str]] = None, - env_file: str | Path = _DEFAULT_ENV_FILE, + env_file: str | Path | None = None, ) -> str: """Return ``[kind]`` with trailing space (Django EMAIL_SUBJECT_PREFIX).""" env = environ if environ is not None else os.environ - file_vars = _read_env_file(env_file) + resolved = _DEFAULT_ENV_FILE if env_file is None else env_file + file_vars = _read_env_file(resolved) explicit = (env.get("EMAIL_SUBJECT_PREFIX") or file_vars.get("EMAIL_SUBJECT_PREFIX") or "").rstrip() if explicit and kind == "app": return f"{explicit} " if not explicit.endswith(" ") else explicit - return f"[{kind}]{identity_tag(environ=env, env_file=env_file)} " + return f"[{kind}]{identity_tag(environ=env, env_file=resolved)} " def prefix_subject(subject: str, *, kind: str = "app") -> str: From c5f44eed5b396b184f64382d8ed3e0bc7a9346d1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 6 Sep 2026 22:54:35 +0000 Subject: [PATCH 2/2] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/django_errors/mail_identity.py | 56 +++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 13 deletions(-) diff --git a/src/django_errors/mail_identity.py b/src/django_errors/mail_identity.py index bb1f7b09..d35ee8cd 100644 --- a/src/django_errors/mail_identity.py +++ b/src/django_errors/mail_identity.py @@ -39,24 +39,46 @@ def _read_env_file(path: str | Path) -> dict[str, str]: def identity_tag( *, - scope: Optional[str] = None, - role: Optional[str] = None, - hostname: Optional[str] = None, - install_tag: Optional[str] = None, + scope: str | None = None, + role: str | None = None, + hostname: str | None = None, + install_tag: str | None = None, env_file: str | Path | None = None, - environ: Optional[Mapping[str, str]] = None, + environ: Mapping[str, str] | None = None, ) -> str: """Return the compact identity tag for this host.""" env = environ if environ is not None else os.environ # Resolve default at call time so tests can monkeypatch ``_DEFAULT_ENV_FILE``. - file_vars = _read_env_file(_DEFAULT_ENV_FILE if env_file is None else env_file) + file_vars = _read_env_file( + _DEFAULT_ENV_FILE if env_file is None else env_file + ) - cached = (env.get("SH_MAIL_IDENTITY_TAG") or file_vars.get("SH_MAIL_IDENTITY_TAG") or "").strip() - if cached and scope is None and role is None and hostname is None and install_tag is None: + cached = ( + env.get("SH_MAIL_IDENTITY_TAG") + or file_vars.get("SH_MAIL_IDENTITY_TAG") + or "" + ).strip() + if ( + cached + and scope is None + and role is None + and hostname is None + and install_tag is None + ): return cached - scope_v = (scope or env.get("SH_OS_Scope") or file_vars.get("SH_OS_Scope") or "unknown").strip() - role_v = (role or env.get("SH_Host_Role") or file_vars.get("SH_Host_Role") or "unknown").strip() + scope_v = ( + scope + or env.get("SH_OS_Scope") + or file_vars.get("SH_OS_Scope") + or "unknown" + ).strip() + role_v = ( + role + or env.get("SH_Host_Role") + or file_vars.get("SH_Host_Role") + or "unknown" + ).strip() host_v = ( hostname or env.get("SH_OS_HostName") @@ -66,7 +88,11 @@ def identity_tag( install_v = ( install_tag if install_tag is not None - else (env.get("SH_Mail_InstallTag") or file_vars.get("SH_Mail_InstallTag") or "") + else ( + env.get("SH_Mail_InstallTag") + or file_vars.get("SH_Mail_InstallTag") + or "" + ) ).strip() if scope_v == "PROD" and role_v in _PROD_COMPACT_ROLES: @@ -81,14 +107,18 @@ def identity_tag( def subject_prefix( kind: str = "app", *, - environ: Optional[Mapping[str, str]] = None, + environ: Mapping[str, str] | None = None, env_file: str | Path | None = None, ) -> str: """Return ``[kind]`` with trailing space (Django EMAIL_SUBJECT_PREFIX).""" env = environ if environ is not None else os.environ resolved = _DEFAULT_ENV_FILE if env_file is None else env_file file_vars = _read_env_file(resolved) - explicit = (env.get("EMAIL_SUBJECT_PREFIX") or file_vars.get("EMAIL_SUBJECT_PREFIX") or "").rstrip() + explicit = ( + env.get("EMAIL_SUBJECT_PREFIX") + or file_vars.get("EMAIL_SUBJECT_PREFIX") + or "" + ).rstrip() if explicit and kind == "app": return f"{explicit} " if not explicit.endswith(" ") else explicit return f"[{kind}]{identity_tag(environ=env, env_file=resolved)} "