Skip to content

Make the DEFAULT_TIMEOUT environment variable work in the CLI - #179

Open
feiiiiii5 wants to merge 1 commit into
JoshData:mainfrom
feiiiiii5:fix/cli-default-timeout
Open

feiiiiii5 wants to merge 1 commit into
JoshData:mainfrom
feiiiiii5:fix/cli-default-timeout

Conversation

@feiiiiii5

Copy link
Copy Markdown
Contributor

Setting DEFAULT_TIMEOUT, which email_validator/__main__.py's own header comment documents as the way to set validate_email keyword arguments from the environment, stops the CLI from working at all: DEFAULT_TIMEOUT=5 python -m email_validator test@example.com raises TypeError: validate_email() got an unexpected keyword argument 'default_timeout', once per address and on the STDIN path too.

The loop wrote options['default_timeout'], but the DNS timeout keyword of validate_email() is timeout (validate_email.py:29). Passing timeout is only half of it: validate_email() refuses a timeout together with a dns_resolver (deliverability.py:43-44 raises ValueError), and the STDIN path always has a resolver because the CLI builds one for the whole file. So the timeout now goes to caching_resolver() on that path, and is dropped when the caller injected a resolver that already carries its own lifetime.

Test: .venv/bin/python -m pytest tests/test_main.py -k default_timeout fails on dcc3218 with TypeError: validate_email() got an unexpected keyword argument 'default_timeout' (3 failed, 14 deselected) and passes here (3 passed). The repo's own gates: make lint and make typing are clean, and make test is 1 failed, 322 passed, 1 deselected — that failure is tests/test_syntax.py::test_domain_literal, which fails on base dcc3218 with the same assertion ('[IPv6:::ffff:102:304]' != '[IPv6:::ffff:1.2.3.4]') in code this PR does not touch.

Details

Whether the value lands where it is supposed to: with DEFAULT_TIMEOUT=3 and no injected resolver, dns.resolver.get_default_resolver().lifetime is 3.0 after the CLI runs, versus 15 when the variable is unset. The path is validate_email.py:59-60 then :199-201 then deliverability.py:37-42.

Two of the three new tests pass the test resolver, so they cover "the CLI no longer crashes". The third patches caching_resolver only to assert the number it is handed, because that STDIN branch is the one place where the CLI creates the resolver itself.

DEFAULT_TIMEOUT still breaks the naming rule stated in that header comment ("environment variables of the same name but uppercase", which would be TIMEOUT). I kept the documented name and only wired it to the right keyword, since that is the smaller change and no working behaviour depends on the current name. Say the word if you would rather it be TIMEOUT and I will do it in one commit.

Deliberately not in this PR: the loop above does options[varname.lower()] = bool(os.environ[varname]), so CHECK_DELIVERABILITY=false, 0 and no all turn deliverability checking on, and only an empty string turns it off. That is a different root cause and it needs a decision on which spellings mean false, so I left it for you rather than inventing a convention here.

The CLI passed it to validate_email() as default_timeout, a keyword the
function does not have, so setting it raised TypeError for every address.
Hand the value to the DNS resolver that actually uses it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant