コード例 #1
0
def document_configuration(cls, ruleset="std"):
    """Add a 'Configuration' section to a Rule docstring.

    Utilize the the metadata in config_info to dynamically
    document the configuration options for a given rule.

    This is a little hacky, but it allows us to propagate configuration
    options in the docs, from a single source of truth.
    """
    if ruleset == "std":
        config_info = get_config_info()
    else:  # pragma: no cover
        raise (
            NotImplementedError(
                "Add another config info dict for the new ruleset here!"
            )
        )

    config_doc = "\n    **Configuration**\n"
    try:
        for keyword in sorted(cls.config_keywords):
            try:
                info_dict = config_info[keyword]
            except KeyError:  # pragma: no cover
                raise KeyError(
                    "Config value {!r} for rule {} is not configured in "
                    "`config_info`.".format(keyword, cls.__name__)
                )
            config_doc += "\n    * ``{}``: {}".format(keyword, info_dict["definition"])
            if (
                config_doc[-1] != "."
                and config_doc[-1] != "?"
                and config_doc[-1] != "\n"
            ):
                config_doc += "."
            if "validation" in info_dict:
                config_doc += " Must be one of ``{}``.".format(info_dict["validation"])
    except AttributeError:
        rules_logger.info(f"No config_keywords defined for {cls.__name__}")
        return cls
    # Add final blank line
    config_doc += "\n"

    if "**Anti-pattern**" in cls.__doc__:
        # Match `**Anti-pattern**`, then insert configuration before
        # the first occurrences
        pattern = re.compile("(\\s{4}\\*\\*Anti-pattern\\*\\*)", flags=re.MULTILINE)
        cls.__doc__ = pattern.sub(f"\n{config_doc}\n\\1", cls.__doc__, count=1)
    else:
        # Match last `\n` or `.`, then append configuration
        pattern = re.compile("(\\.|\\n)$", flags=re.MULTILINE)
        cls.__doc__ = pattern.sub(f"\\1\n{config_doc}\n", cls.__doc__, count=1)
    return cls
コード例 #2
0
def document_configuration(cls, ruleset="std"):
    """Add a 'Configuration' section to a Rule docstring.

    Utilize the the metadata in config_info to dynamically
    document the configuration options for a given rule.

    This is a little hacky, but it allows us to propagate configuration
    options in the docs, from a single source of truth.
    """
    if ruleset == "std":
        config_info = get_config_info()
    else:
        raise (
            NotImplementedError(
                "Add another config info dict for the new ruleset here!"
            )
        )

    config_doc = "\n    | **Configuration**"
    try:
        for keyword in sorted(cls.config_keywords):
            try:
                info_dict = config_info[keyword]
            except KeyError:
                raise KeyError(
                    "Config value {!r} for rule {} is not configured in `config_info`.".format(
                        keyword, cls.__name__
                    )
                )
            config_doc += "\n    |     `{0}`: {1}.".format(
                keyword, info_dict["definition"]
            )
            if "validation" in info_dict:
                config_doc += " Must be one of {0}.".format(info_dict["validation"])
            config_doc += "\n    |"
    except AttributeError:
        rules_logger.info("No config_keywords defined for {0}".format(cls.__name__))
        return cls
    # Add final blank line
    config_doc += "\n"
    # Add the configuration section immediately after the class description
    # docstring by inserting after the first line break, or first period,
    # if there is no line break.
    end_of_class_description = "." if "\n" not in cls.__doc__ else "\n"

    cls.__doc__ = cls.__doc__.replace(end_of_class_description, "\n" + config_doc, 1)
    return cls