MCPcopy Index your code
hub / github.com/JoshData/python-email-validator / validate_email_local_part

Function validate_email_local_part

email_validator/syntax.py:231–389  ·  view source on GitHub ↗

Validates the syntax of the local part of an email address.

(local: str, allow_smtputf8: bool = True, allow_empty_local: bool = False,
                              quoted_local_part: bool = False, strict: bool = False)

Source from the content-addressed store, hash-verified

229
230
231def validate_email_local_part(local: str, allow_smtputf8: bool = True, allow_empty_local: bool = False,
232 quoted_local_part: bool = False, strict: bool = False) -> LocalPartValidationResult:
233 """Validates the syntax of the local part of an email address."""
234
235 if len(local) == 0:
236 if not allow_empty_local:
237 raise EmailSyntaxError("There must be something before the @-sign.")
238
239 # The caller allows an empty local part. Useful for validating certain
240 # Postfix aliases.
241 return {
242 "local_part": local,
243 "ascii_local_part": local,
244 "smtputf8": False,
245 }
246
247 # Check the length of the local part by counting characters.
248 # (RFC 5321 4.5.3.1.1)
249 # We're checking the number of characters here. If the local part
250 # is ASCII-only, then that's the same as bytes (octets). If it's
251 # internationalized, then the UTF-8 encoding may be longer, but
252 # that may not be relevant. We will check the total address length
253 # instead.
254 if strict and len(local) > LOCAL_PART_MAX_LENGTH:
255 reason = get_length_reason(local, limit=LOCAL_PART_MAX_LENGTH)
256 raise EmailSyntaxError(f"The email address is too long before the @-sign {reason}.")
257
258 # Check the local part against the non-internationalized regular expression.
259 # Most email addresses match this regex so it's probably fastest to check this first.
260 # (RFC 5322 3.2.3)
261 # All local parts matching the dot-atom rule are also valid as a quoted string
262 # so if it was originally quoted (quoted_local_part is True) and this regex matches,
263 # it's ok.
264 # (RFC 5321 4.1.2 / RFC 5322 3.2.4).
265 if DOT_ATOM_TEXT.match(local):
266 # It's valid. And since it's just the permitted ASCII characters,
267 # it's normalized and safe. If the local part was originally quoted,
268 # the quoting was unnecessary and it'll be returned as normalized to
269 # non-quoted form.
270
271 # Return the local part and flag that SMTPUTF8 is not needed.
272 return {
273 "local_part": local,
274 "ascii_local_part": local,
275 "smtputf8": False,
276 }
277
278 # The local part failed the basic dot-atom check. Try the extended character set
279 # for internationalized addresses. It's the same pattern but with additional
280 # characters permitted.
281 # RFC 6531 section 3.3.
282 valid: Optional[str] = None
283 requires_smtputf8 = False
284 if DOT_ATOM_TEXT_INTL.match(local):
285 # But international characters in the local part may not be permitted.
286 if not allow_smtputf8:
287 # Check for invalid characters against the non-internationalized
288 # permitted character set.

Callers 1

validate_emailFunction · 0.85

Calls 5

EmailSyntaxErrorClass · 0.85
get_length_reasonFunction · 0.85
safe_character_displayFunction · 0.85
check_unsafe_charsFunction · 0.85
check_dot_atomFunction · 0.85

Tested by

no test coverage detected