Repository: seandstewart/typical (language: python)

Issue:
Email Validator is too strict.
* typical version: current
* Python version: 3.8
* Operating System: n/a

### Description

The current regex for the email validator is too strict and doesn't allow for special characters such as apostrophes in the username, which are explicitly allowed for in the RFC.

https://help.returnpath.com/hc/en-us/articles/220560587-What-are-the-rules-for-email-address-syntax-

### What I Did



Discussion / hints:

Fix patch:
diff --git a/pyproject.toml b/pyproject.toml
index 1b9c8dcb..d666fba1 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,7 +1,7 @@
 [tool.poetry]
 name = "typical"
 packages = [{include = "typic"}]
-version = "2.1.0"
+version = "2.1.1"
 description = "Typical: Python's Typing Toolkit."
 authors = ["Sean Stewart <sean_stewart@me.com>"]
 license = "MIT"
diff --git a/typic/types/email.py b/typic/types/email.py
index 7c6abdfc..7182bf91 100644
--- a/typic/types/email.py
+++ b/typic/types/email.py
@@ -24,6 +24,7 @@ class EmailValueError(NetworkAddressValueError):
 
 
 # http://emailregex.com/
+# https://help.returnpath.com/hc/en-us/articles/220560587-What-are-the-rules-for-email-address-syntax-
 # expanding a bit for more specific detection
 # also violating DRY :'( by copying the host regex from URL,
 # but hey, this means we're more compliant with RFC 5322,
@@ -34,7 +35,7 @@ class EmailValueError(NetworkAddressValueError):
         ^
         ((?P<name>([A-Z]+\s?)+)\s<)?
         # user
-        (?P<username>([A-Z0-9]([_.+-])?)*[A-Z0-9]+)
+        (?P<username>([A-Z0-9]([!#$%&'*=?^`{|_.+-])?)*[A-Z0-9]+)
         @
         # host
         (?P<host>(?:


Test patch:
diff --git a/tests/custom_types/test_email.py b/tests/custom_types/test_email.py
index 7d4dbcee..c5dce3c6 100644
--- a/tests/custom_types/test_email.py
+++ b/tests/custom_types/test_email.py
@@ -7,7 +7,7 @@
 
 from typic.types import email
 
-EMAIL_RAW = "foo.bar@foobar.net"
+EMAIL_RAW = "o'foo.bar@foobar.net"
 EMAIL = email.Email(EMAIL_RAW)
 PRETTY_EMAIL_RAW = f"Foo Bar <{EMAIL_RAW}>"
 PRETTY_EMAIL = email.Email(PRETTY_EMAIL_RAW)
@@ -16,11 +16,11 @@
 @pytest.mark.parametrize(
     argnames=("name", "expected", "eml"),
     argvalues=[
-        ("username", "foo.bar", EMAIL),
+        ("username", "o'foo.bar", EMAIL),
         ("host", "foobar.net", EMAIL),
         ("address", EMAIL_RAW, EMAIL),
         ("address_encoded", quote(EMAIL_RAW), EMAIL),
-        ("username", "foo.bar", PRETTY_EMAIL),
+        ("username", "o'foo.bar", PRETTY_EMAIL),
         ("name", "Foo Bar", PRETTY_EMAIL),
         ("address", PRETTY_EMAIL_RAW, PRETTY_EMAIL),
         ("address_encoded", f"Foo Bar <{quote(EMAIL_RAW)}>", PRETTY_EMAIL),