Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exclude .arpa tld names from domains() strategy #3572

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 4 additions & 1 deletion .readthedocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
version: 2

# Optionally build your docs in additional formats such as PDF and ePub
formats: all
formats:
- htmlzip
- epub
# - pdf # busted by latex crash on unicode U+030A combining ring above, in text() docs

# Optionally set the version of Python and requirements required to build your docs
build:
Expand Down
1 change: 1 addition & 0 deletions AUTHORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ their individual contributions.
* `James Lamb <https://github.com/jameslamb>`_
* `Jenny Rouleau <https://github.com/jennyrou>`_
* `Jens Heinrich <https://github.com/JensHeinrich>`_
* `Jens Tröger <https://github.com/jenstroeger>`_
* `Jeremy Thurgood <https://github.com/jerith>`_
* `J.J. Green <http://soliton.vm.bytemark.co.uk/pub/jjg/>`_
* `JP Viljoen <https://github.com/froztbyte>`_ (froztbyte@froztbyte.net)
Expand Down
8 changes: 8 additions & 0 deletions hypothesis-python/RELEASE.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
RELEASE_TYPE: minor

This release adds an optional ``domains=`` parameter to the
:func:`~hypothesis.strategies.emails` strategy, and excludes
the special-use :wikipedia:`.arpa` domain from the default
strategy (:issue:`3567`).

Thanks to Jens Tröger for reporting and fixing this bug!
10 changes: 6 additions & 4 deletions hypothesis-python/src/hypothesis/provisional.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,16 @@
# The file contains additional information about the date that it was last updated.
try: # pragma: no cover
traversable = resources.files("hypothesis.vendor") / "tlds-alpha-by-domain.txt"
_tlds = traversable.read_text().splitlines()
_comment, *_tlds = traversable.read_text().splitlines()
except (AttributeError, ValueError): # pragma: no cover # .files() was added in 3.9
_tlds = resources.read_text(
_comment, *_tlds = resources.read_text(
"hypothesis.vendor", "tlds-alpha-by-domain.txt"
).splitlines()
assert _comment.startswith("#")

assert _tlds[0].startswith("#")
TOP_LEVEL_DOMAINS = ["COM"] + sorted(_tlds[1:], key=len)
# Remove special-use domain names from the list. For more discussion
# see https://github.com/HypothesisWorks/hypothesis/pull/3572
TOP_LEVEL_DOMAINS = ["COM"] + sorted((d for d in _tlds if d != "ARPA"), key=len)


class DomainNameStrategy(st.SearchStrategy):
Expand Down
17 changes: 13 additions & 4 deletions hypothesis-python/src/hypothesis/strategies/_internal/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -2012,21 +2012,30 @@ def deferred(definition: Callable[[], SearchStrategy[Ex]]) -> SearchStrategy[Ex]
return DeferredStrategy(definition)


def domains():
import hypothesis.provisional

return hypothesis.provisional.domains()


@defines_strategy(force_reusable_values=True)
def emails() -> SearchStrategy[str]:
def emails(
*, domains: SearchStrategy[str] = LazyStrategy(domains, (), {})
) -> SearchStrategy[str]:
"""A strategy for generating email addresses as unicode strings. The
address format is specified in :rfc:`5322#section-3.4.1`. Values shrink
towards shorter local-parts and host domains.

If ``domains`` is given then it must be a strategy that generates domain
names for the emails, defaulting to :func:`~hypothesis.provisional.domains`.

This strategy is useful for generating "user data" for tests, as
mishandling of email addresses is a common source of bugs.
"""
from hypothesis.provisional import domains

local_chars = string.ascii_letters + string.digits + "!#$%&'*+-/=^_`{|}~"
local_part = text(local_chars, min_size=1, max_size=64)
# TODO: include dot-atoms, quoted strings, escaped chars, etc in local part
return builds("{}@{}".format, local_part, domains()).filter(
return builds("{}@{}".format, local_part, domains).filter(
lambda addr: len(addr) <= 254
)

Expand Down
10 changes: 8 additions & 2 deletions hypothesis-python/tests/nocover/test_emails.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,19 @@
# obtain one at https://mozilla.org/MPL/2.0/.

from hypothesis import given
from hypothesis.strategies import emails
from hypothesis.strategies import emails, just


@given(emails())
def test_is_valid_email(address):
def test_is_valid_email(address: str):
local, at_, domain = address.rpartition("@")
assert len(address) <= 254
assert at_ == "@"
assert local
assert domain
assert not domain.lower().endswith(".arpa")


@given(emails(domains=just("mydomain.com")))
def test_can_restrict_email_domains(address: str):
assert address.endswith("@mydomain.com")