Extract email from a full address. Example:
      'John Doe <jdoe+github@foo.com>' -> jdoe@foo.com

    >>> parse("John Doe <me+github.com@someorg.com")
    ('me', 'someorg.com')
    >>> parse(42)  # doctest: +IGNORE_EXCEPTION_DETAIL
    Traceback (most recent call last):
        ...
    InvalidEmail: 'Invalid email: 42'
    >>> parse(None)  # doctest: +IGNORE_EXCEPTION_DETAIL
    Traceback (most recent call last):
        ...
    InvalidEmail: 'None or NaN is not a valid email address'

def parse(raw_email):
    # type: (six.string_types) -> Tuple[six.string_types, six.string_types]
    """Extract email from a full address. Example:
      'John Doe <jdoe+github@foo.com>' -> jdoe@foo.com

    >>> parse("John Doe <me+github.com@someorg.com")
    ('me', 'someorg.com')
    >>> parse(42)  # doctest: +IGNORE_EXCEPTION_DETAIL
    Traceback (most recent call last):
        ...
    InvalidEmail: 'Invalid email: 42'
    >>> parse(None)  # doctest: +IGNORE_EXCEPTION_DETAIL
    Traceback (most recent call last):
        ...
    InvalidEmail: 'None or NaN is not a valid email address'
    """
    if not isinstance(raw_email, six.string_types):
        raise InvalidEmail("Invalid email: %s" % raw_email)
    if not raw_email or pd.isnull(raw_email):
        raise InvalidEmail("None or NaN is not a valid email address")
    email = raw_email.split("<", 1)[-1].split(">", 1)[0]
    chunks = email.split("@", 3)
    # git-svn generates emails with several @, e.g.:
    # <rossberg@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
    if len(chunks) < 2:
        raise InvalidEmail("Invalid email")
    uname = chunks[0].rsplit(" ", 1)[-1]
    addr_domain = chunks[1].split(" ", 1)[0]

    return uname.split("+", 1)[0], addr_domain