From 405250fdb53b559cfcdcf0437a857da74b0213ab Mon Sep 17 00:00:00 2001 From: RavSinghChandan Date: Sat, 31 Oct 2026 07:14:32 +0530 Subject: [PATCH] Read false values of the command-line tool's environment variables as false --- CHANGELOG.md | 1 + email_validator/__main__.py | 3 ++- tests/test_main.py | 13 +++++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 44ccb2f..998333c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ In Development * Python 3.8 and 3.9 are no longer supported. * The `original` field of the returned validated email object incorrectly un-escaped the local part of the email address. Now it returns the original address, without any display name, as passed to validate_email. * add support python3.15 +* The command-line tool now reads `0`, `false`, `no` and `off` in its environment variables (e.g. `CHECK_DELIVERABILITY=0`) as false. Previously any non-empty value turned the option on. * The IPv6 tag of a domain literal is now case-insensitive, as in the RFCs, so `me@[ipv6:::1]` is accepted (and normalized to `me@[IPv6:::1]`) when `allow_domain_literal=True`. 2.3.0 (August 26, 2025) diff --git a/email_validator/__main__.py b/email_validator/__main__.py index 107b08b..2b0b6f1 100644 --- a/email_validator/__main__.py +++ b/email_validator/__main__.py @@ -33,7 +33,8 @@ def main(dns_resolver: Optional[_Resolver] = None) -> None: 'ALLOW_DISPLAY_NAME', 'GLOBALLY_DELIVERABLE', 'CHECK_DELIVERABILITY', 'TEST_ENVIRONMENT'): if varname in os.environ: - options[varname.lower()] = bool(os.environ[varname]) + # Any non-empty string is truthy, so the usual false values are recognized explicitly. + options[varname.lower()] = os.environ[varname].strip().lower() not in ('', '0', 'false', 'no', 'off') for varname in ('DEFAULT_TIMEOUT',): if varname in os.environ: options[varname.lower()] = float(os.environ[varname]) diff --git a/tests/test_main.py b/tests/test_main.py index b8c6583..dccf342 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -81,6 +81,19 @@ def test_main_multi_input(monkeypatch: pytest.MonkeyPatch, capsys: pytest.Captur assert test_cases[3] in stdout +@pytest.mark.parametrize( + ('value', 'allowed'), + [('1', True), ('true', True), ('yes', True), ('0', False), ('false', False), ('FALSE', False), ('no', False), ('', False)] +) +def test_main_boolean_environment_variable(monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str], + value: str, allowed: bool) -> None: + monkeypatch.setenv('ALLOW_DOMAIN_LITERAL', value) + monkeypatch.setattr('sys.argv', ['email_validator', 'me@[127.0.0.1]']) + validator_command_line_tool(dns_resolver=RESOLVER) + stdout, _ = capsys.readouterr() + assert ('A bracketed IP address after the @-sign is not allowed here.' in stdout) is not allowed + + def test_bytes_input() -> None: input_email = b"testaddr@example.tld" valid_email = validate_email(input_email, check_deliverability=False)