def parse_datetime(dt_str: str) -> Optional[dt.datetime]:
    "Parse a string and return a datetime.datetime.\n\n    This function supports time zone offsets. When the input contains one,\n    the output uses a timezone with a fixed offset from UTC.\n    Raises ValueError if the input is well formatted but not a valid datetime.\n    Returns None if the input isn't well formatted.\n    "
    match = DATETIME_RE.match(dt_str)
    if (not match):
        return None
    kws: Dict[(str, Any)] = match.groupdict()
    if kws['microsecond']:
        kws['microsecond'] = kws['microsecond'].ljust(6, '0')
    tzinfo_str = kws.pop('tzinfo')
    tzinfo: Optional[dt.tzinfo] = None
    if (tzinfo_str == 'Z'):
        tzinfo = UTC
    elif (tzinfo_str is not None):
        offset_mins = (int(tzinfo_str[(- 2):]) if (len(tzinfo_str) > 3) else 0)
        offset_hours = int(tzinfo_str[1:3])
        offset = dt.timedelta(hours=offset_hours, minutes=offset_mins)
        if (tzinfo_str[0] == '-'):
            offset = (- offset)
        tzinfo = dt.timezone(offset)
    kws = {k: int(v) for (k, v) in kws.items() if (v is not None)}
    kws['tzinfo'] = tzinfo
    return dt.datetime(**kws)
Parse a string and return a datetime.datetime.

This function supports time zone offsets. When the input contains one,
the output uses a timezone with a fixed offset from UTC.
Raises ValueError if the input is well formatted but not a valid datetime.
Returns None if the input isn't well formatted.
def parse_datetime(dt_str: str) -> Optional[dt.datetime]:
    "Parse a string and return a datetime.datetime.\n\n    This function supports time zone offsets. When the input contains one,\n    the output uses a timezone with a fixed offset from UTC.\n    Raises ValueError if the input is well formatted but not a valid datetime.\n    Returns None if the input isn't well formatted.\n    "
    match = DATETIME_RE.match(dt_str)
    if (not match):
        return None
    kws: Dict[(str, Any)] = match.groupdict()
    if kws['microsecond']:
        kws['microsecond'] = kws['microsecond'].ljust(6, '0')
    tzinfo_str = kws.pop('tzinfo')
    tzinfo: Optional[dt.tzinfo] = None
    if (tzinfo_str == 'Z'):
        tzinfo = UTC
    elif (tzinfo_str is not None):
        offset_mins = (int(tzinfo_str[(- 2):]) if (len(tzinfo_str) > 3) else 0)
        offset_hours = int(tzinfo_str[1:3])
        offset = dt.timedelta(hours=offset_hours, minutes=offset_mins)
        if (tzinfo_str[0] == '-'):
            offset = (- offset)
        tzinfo = dt.timezone(offset)
    kws = {k: int(v) for (k, v) in kws.items() if (v is not None)}
    kws['tzinfo'] = tzinfo
    return dt.datetime(**kws)