Skip to content
Open
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
30 changes: 12 additions & 18 deletions pydantic/v1/networks.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import re
from functools import lru_cache
from ipaddress import (
IPv4Address,
IPv4Interface,
Expand Down Expand Up @@ -121,8 +122,7 @@ def url_regex() -> Pattern[str]:


def multi_host_url_regex() -> Pattern[str]:
"""
Compiled multi host url regex.
"""Compiled multi host url regex.

Additionally to `url_regex` it allows to match multiple hosts.
E.g. host1.db.net,host2.db.net
Expand All @@ -138,23 +138,19 @@ def multi_host_url_regex() -> Pattern[str]:
return _multi_host_url_regex_cache


@lru_cache(maxsize=None)
def ascii_domain_regex() -> Pattern[str]:
global _ascii_domain_regex_cache
if _ascii_domain_regex_cache is None:
ascii_chunk = r'[_0-9a-z](?:[-_0-9a-z]{0,61}[_0-9a-z])?'
ascii_domain_ending = r'(?P<tld>\.[a-z]{2,63})?\.?'
_ascii_domain_regex_cache = re.compile(
fr'(?:{ascii_chunk}\.)*?{ascii_chunk}{ascii_domain_ending}', re.IGNORECASE
)
return _ascii_domain_regex_cache
ascii_chunk = r'[_0-9a-z](?:[-_0-9a-z]{0,61}[_0-9a-z])?'
ascii_domain_ending = r'(?P<tld>\.[a-z]{2,63})?\.?'
return re.compile(rf'(?:{ascii_chunk}\.)*?{ascii_chunk}{ascii_domain_ending}', re.IGNORECASE)


def int_domain_regex() -> Pattern[str]:
global _int_domain_regex_cache
if _int_domain_regex_cache is None:
int_chunk = r'[_0-9a-\U00040000](?:[-_0-9a-\U00040000]{0,61}[_0-9a-\U00040000])?'
int_domain_ending = r'(?P<tld>(\.[^\W\d_]{2,63})|(\.(?:xn--)[_0-9a-z-]{2,63}))?\.?'
_int_domain_regex_cache = re.compile(fr'(?:{int_chunk}\.)*?{int_chunk}{int_domain_ending}', re.IGNORECASE)
_int_domain_regex_cache = re.compile(rf'(?:{int_chunk}\.)*?{int_chunk}{int_domain_ending}', re.IGNORECASE)
return _int_domain_regex_cache


Expand Down Expand Up @@ -287,8 +283,7 @@ def validate(cls, value: Any, field: 'ModelField', config: 'BaseConfig') -> 'Any

@classmethod
def _build_url(cls, m: Match[str], url: str, parts: 'Parts') -> 'AnyUrl':
"""
Validate hosts and build the AnyUrl object. Split from `validate` so this method
"""Validate hosts and build the AnyUrl object. Split from `validate` so this method
can be altered in `MultiHostDsn`.
"""
host, tld, host_type, rebuild = cls.validate_host(parts)
Expand Down Expand Up @@ -318,8 +313,7 @@ def _validate_port(port: Optional[str]) -> None:

@classmethod
def validate_parts(cls, parts: 'Parts', validate_port: bool = True) -> 'Parts':
"""
A method used to validate parts of a URL.
"""A method used to validate parts of a URL.
Could be overridden to set default values for parts if missing
"""
scheme = parts['scheme']
Expand Down Expand Up @@ -437,7 +431,7 @@ def validate_parts(cls, parts: 'Parts', validate_port: bool = True) -> 'Parts':

@classmethod
def _build_url(cls, m: Match[str], url: str, parts: 'Parts') -> 'MultiHostDsn':
hosts_parts: List['HostParts'] = []
hosts_parts: List[HostParts] = []
host_re = host_regex()
for host in m.groupdict()['hosts'].split(','):
d: Parts = host_re.match(host).groupdict() # type: ignore
Expand Down Expand Up @@ -709,8 +703,8 @@ def validate(cls, value: NetworkType) -> Union[IPv4Network, IPv6Network]:


def validate_email(value: Union[str]) -> Tuple[str, str]:
"""
Email address validation using https://pypi.org/project/email-validator/
"""Email address validation using https://pypi.org/project/email-validator/

Notes:
* raw ip address (literal) domain parts are not allowed.
* "John Doe <[email protected]>" style "pretty" email addresses are processed
Expand Down
Loading