# Buggy code
def to_py(self, value):
    self._basic_py_validation(value, str)
    if not value:
        return None

    style_map = {
        "normal": QFont.StyleNormal,
        "italic": QFont.StyleItalic,
        "oblique": QFont.StyleOblique,
    }
    weight_map = {
        "normal": QFont.Normal,
        "bold": QFont.Bold,
    }
    font = QFont()
    font.setStyle(QFont.StyleNormal)
    font.setWeight(QFont.Normal)

    match = self.font_regex.match(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 = match.group("family")
    if style:
        font.setStyle(style_map[style])
    if namedweight:
        font.setWeight(weight_map[namedweight])
    if weight:
        # based on qcssparser.cpp:setFontWeightFromValue
        font.setWeight(min(int(weight) / 8, 99))
    if 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

    if family == "monospace":
        family = self.monospace_fonts
    # The Qt CSS parser handles " and ' before passing the string to
    # QFont.setFamily. We could do proper CSS-like parsing here, but since
    # hopefully nobody will ever have a font with quotes in the family (if
    # that's even possible), we take a much more naive approach.
    family = family.replace('"', "").replace("'", "")
    font.setFamily(family)

    return font


# Traceback (AttributeError)
Errors occurred while reading config.py:
Unhandled exception: 'NoneType' object has no attribute 'replace'
Traceback (most recent call last):
File "/home/bitraid/bin/qutebrowser/qutebrowser/config/configfiles.py", line 406, in read_config_py
exec(code, module.__dict__)
File "/home/bitraid/.config/qutebrowser/config.py", line 3, in <module>
c.fonts.debug_console = '14px monospace'
File "/home/bitraid/bin/qutebrowser/qutebrowser/config/config.py", line 460, in __setattr__
self._config.set_obj(name, value)
File "/home/bitraid/bin/qutebrowser/qutebrowser/config/config.py", line 323, in set_obj
self._set_value(self.get_opt(name), value)
File "/home/bitraid/bin/qutebrowser/qutebrowser/config/config.py", line 257, in _set_value
opt.typ.to_py(value)  # for validation
File "/home/bitraid/bin/qutebrowser/qutebrowser/config/configtypes.py", line 1077, in to_py
family = family.replace('"', '').replace("'", '')
AttributeError: 'NoneType' object has no attribute 'replace'

# Fixed code
def to_py(self, value):
    self._basic_py_validation(value, str)
    if not value:
        return None

    style_map = {
        "normal": QFont.StyleNormal,
        "italic": QFont.StyleItalic,
        "oblique": QFont.StyleOblique,
    }
    weight_map = {
        "normal": QFont.Normal,
        "bold": QFont.Bold,
    }
    font = QFont()
    font.setStyle(QFont.StyleNormal)
    font.setWeight(QFont.Normal)

    match = self.font_regex.match(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 = match.group("family")
    if style:
        font.setStyle(style_map[style])
    if namedweight:
        font.setWeight(weight_map[namedweight])
    if weight:
        # based on qcssparser.cpp:setFontWeightFromValue
        font.setWeight(min(int(weight) / 8, 99))
    if 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

    if family == "monospace" and self.monospace_fonts is not None:
        family = self.monospace_fonts
    # The Qt CSS parser handles " and ' before passing the string to
    # QFont.setFamily. We could do proper CSS-like parsing here, but since
    # hopefully nobody will ever have a font with quotes in the family (if
    # that's even possible), we take a much more naive approach.
    family = family.replace('"', "").replace("'", "")
    font.setFamily(family)

    return font