import re


def extract_vid_pid(info_string):
    """
    Try different methods of extracting vendor and product IDs from a string.

    The output from serial.tools.list_ports.comports() varies so
    widely from machine to machine and OS to OS, the only option we
    have right now is to add to a list of patterns that we have seen so
    far and compare the output.

    info_string -- the string possibly containing vendor and product IDs.

    Returns a tuple of (vendor ID, product ID) if a device is found.
    If an ID isn't found, returns None.
    """

    DEVICE_STRING_PATTERNS = [
        # '...VID:PID=XXXX:XXXX...'
        re.compile('.*VID:PID=([0-9A-Fa-f]{0,4}):([0-9A-Fa-f]{0,4}).*'),

        # '...VID_XXXX...PID_XXXX...'
        re.compile('.*VID_([0-9A-Fa-f]{0,4}).*PID_([0-9A-Fa-f]{0,4}).*')
    ]

    for p in DEVICE_STRING_PATTERNS:
        match = p.match(info_string)
        if match:
            return int(match.group(1), 16), int(match.group(2), 16)
    return None