Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions email_validator/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,15 @@ 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])
# bool() would make any non-empty string True, so e.g.
# CHECK_DELIVERABILITY=false would enable the check.
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])
# DEFAULT_TIMEOUT is a module-level default read by
# caching_resolver(), not a keyword argument of validate_email.
import email_validator
email_validator.DEFAULT_TIMEOUT = int(os.environ[varname])

if len(sys.argv) == 1:
# Validate the email addresses passed line-by-line on STDIN.
Expand Down
37 changes: 37 additions & 0 deletions tests/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,43 @@ def test_main_multi_input(monkeypatch: pytest.MonkeyPatch, capsys: pytest.Captur
assert test_cases[3] in stdout


@pytest.mark.parametrize('value', ['false', 'False', 'FALSE', '0', 'no', 'off', ' '])
def test_main_falsy_boolean_option_from_env(monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str], value: str) -> None:
# Options are set from environment variables of the same name in upper
# case. A falsy value there must turn the option off, not on.
import json
test_email = 'test@xkxufoekjvjfjeodlfmdfjcu.com' # this domain does not exist in DNS
monkeypatch.setenv('CHECK_DELIVERABILITY', value)
monkeypatch.setattr('sys.argv', ['email_validator', test_email])
validator_command_line_tool(dns_resolver=RESOLVER)
stdout, _ = capsys.readouterr()
assert json.loads(str(stdout))["normalized"] == test_email


@pytest.mark.parametrize('value', ['false', 'False', '0', 'no', 'off', ' '])
def test_main_falsy_test_environment_from_env(monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str], value: str) -> None:
# test_environment off means the reserved "test" domain names are rejected.
monkeypatch.setenv('TEST_ENVIRONMENT', value)
monkeypatch.setattr('sys.argv', ['email_validator', 'me@foo.test'])
validator_command_line_tool(dns_resolver=RESOLVER)
stdout, _ = capsys.readouterr()
assert stdout == 'The part after the @-sign is a special-use or reserved name that cannot be used with email.\n'


def test_main_default_timeout_from_env(monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str]) -> None:
import json
import email_validator
test_email = 'google@google.com'
# Set up the restore of the module-level default, which main() overwrites.
monkeypatch.setattr('email_validator.DEFAULT_TIMEOUT', email_validator.DEFAULT_TIMEOUT)
monkeypatch.setenv('DEFAULT_TIMEOUT', '5')
monkeypatch.setattr('sys.argv', ['email_validator', test_email])
validator_command_line_tool(dns_resolver=RESOLVER)
stdout, _ = capsys.readouterr()
assert json.loads(str(stdout))["normalized"] == test_email
assert email_validator.DEFAULT_TIMEOUT == 5


def test_bytes_input() -> None:
input_email = b"testaddr@example.tld"
valid_email = validate_email(input_email, check_deliverability=False)
Expand Down
Loading