# Buggy code
def to_py(self, value: _StrUnset) -> typing.Union[usertypes.Unset, None, QFont]:
    self._basic_py_validation(value, str)
    if isinstance(value, usertypes.Unset):
        return value
    elif not value:
        return None

    font = QFont()
    font.setStyle(QFont.StyleNormal)
    font.setWeight(QFont.Normal)

    match = self.font_regex.fullmatch(value)
    if not match:  # pragma: no cover
        # This should never happen, as the regex always matches everything
        # as family.
        raise configexc.ValidationError(value, "must be a valid font")

    style = match.group("style")
    weight = match.group("weight")
    namedweight = match.group("namedweight")
    size = match.group("size")
    family_str = match.group("family")

    style_map = {
        "normal": QFont.StyleNormal,
        "italic": QFont.StyleItalic,
        "oblique": QFont.StyleOblique,
    }
    if style:
        font.setStyle(style_map[style])

    weight_map = {
        "normal": QFont.Normal,
        "bold": QFont.Bold,
    }
    if namedweight:
        font.setWeight(weight_map[namedweight])
    elif weight:
        # based on qcssparser.cpp:setFontWeightFromValue
        font.setWeight(min(int(weight) // 8, 99))

    if size:
        if size == "default_size":
            size = self.default_size

        if size.lower().endswith("pt"):
            font.setPointSizeF(float(size[:-2]))
        elif size.lower().endswith("px"):
            font.setPixelSize(int(size[:-2]))
        else:
            # This should never happen as the regex only lets pt/px
            # through.
            raise ValueError(
                "Unexpected size unit in {!r}!".format(size)
            )  # pragma: no cover

    families = self._parse_families(family_str)
    if hasattr(font, "setFamilies"):
        # Added in Qt 5.13
        font.setFamily(families.family)  # type: ignore
        font.setFamilies(list(families))
    else:  # pragma: no cover
        font.setFamily(families.to_str(quote=False))

    return font


# Traceback (configexc.ConfigFileError)
Traceback (most recent call last): File "/usr/lib/python3.8/site-packages/qutebrowser/config/configinit.py", line 67, in early_init configfiles.read_config_py(config_file) File "/usr/lib/python3.8/site-packages/qutebrowser/config/configfiles.py", line 743, in read_config_py raise configexc.ConfigFileErrors('config.py', api.errors) qutebrowser.config.configexc.ConfigFileErrors: Errors occurred while reading config.py: Unhandled exception - AttributeError: 'NoneType' object has no attribute 'lower'

# Fixed code
def to_py(self, value: _StrUnset) -> typing.Union[usertypes.Unset, None, QFont]:
    self._basic_py_validation(value, str)
    if isinstance(value, usertypes.Unset):
        return value
    elif not value:
        return None

    font = QFont()
    font.setStyle(QFont.StyleNormal)
    font.setWeight(QFont.Normal)

    match = self.font_regex.fullmatch(value)
    if not match:  # pragma: no cover
        # This should never happen, as the regex always matches everything
        # as family.
        raise configexc.ValidationError(value, "must be a valid font")

    style = match.group("style")
    weight = match.group("weight")
    namedweight = match.group("namedweight")
    size = match.group("size")
    family_str = match.group("family")

    style_map = {
        "normal": QFont.StyleNormal,
        "italic": QFont.StyleItalic,
        "oblique": QFont.StyleOblique,
    }
    if style:
        font.setStyle(style_map[style])

    weight_map = {
        "normal": QFont.Normal,
        "bold": QFont.Bold,
    }
    if namedweight:
        font.setWeight(weight_map[namedweight])
    elif weight:
        # based on qcssparser.cpp:setFontWeightFromValue
        font.setWeight(min(int(weight) // 8, 99))

    if size:
        if size == "default_size":
            size = self.default_size

        if size is None:
            # initial validation before default_size is set up.
            pass
        elif size.lower().endswith("pt"):
            font.setPointSizeF(float(size[:-2]))
        elif size.lower().endswith("px"):
            font.setPixelSize(int(size[:-2]))
        else:
            # This should never happen as the regex only lets pt/px
            # through.
            raise ValueError(
                "Unexpected size unit in {!r}!".format(size)
            )  # pragma: no cover

    families = self._parse_families(family_str)
    if hasattr(font, "setFamilies"):
        # Added in Qt 5.13
        font.setFamily(families.family)  # type: ignore
        font.setFamilies(list(families))
    else:  # pragma: no cover
        font.setFamily(families.to_str(quote=False))

    return font