Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JSONSchema (SchemaStore, validate-pyproject) #16491

Open
henryiii opened this issue Nov 14, 2023 · 0 comments
Open

JSONSchema (SchemaStore, validate-pyproject) #16491

henryiii opened this issue Nov 14, 2023 · 0 comments
Labels
feature topic-configuration Configuration files and flags

Comments

@henryiii
Copy link
Contributor

henryiii commented Nov 14, 2023

Feature

I'd like to see a mypy.schema.json JSONSchema provided for the pyproject.toml configuration, similar to ruff.schema.json, scikt-build.schema.json, etc. This would enable most editors to assist users in configuring mypy and would allow validate-pyproject to check the tool.mypy section. SchemaStore already has ruff, poetry, setuptools, scikit-build, and hatch.

Pitch

Ideally it should be generated. I didn't see a nice declarative spot for configuration (like a dataclass), just a vanilla class in mypy.options. So I processed the docs page instead. Here's my initial attempt at a script, which could be placed in misc/make_schema.py:

from __future__ import annotations

import dataclasses
import json
import re
import textwrap
from collections.abc import Generator, Sequence
from pathlib import Path
from typing import Any

DIR = Path(__file__).parent.resolve()


@dataclasses.dataclass(frozen=True)
class ConfigOpt:
    name: str
    type_str: str
    is_global: bool
    description: str
    default: str | None

    def define(self) -> dict[str, str]:
        retval: dict[str, Any] = {"description": self.description}
        if self.default is not None:
            match self.type_str:
                case "boolean":
                    retval["default"] = {"true": True, "false": False}[self.default.lower()]
                case "integer":
                    retval["integer"] = int(self.default)
                case "string":
                    retval["default"] = self.default.strip("`")
                case _:
                    msg = f"Default not suppored for {self.type_str}"
                    raise RuntimeError(msg)
        match self.type_str:
            case "boolean" | "integer" | "string":
                retval["type"] = self.type_str
            case "comma-separated list of strings" | "regular expression":
                retval["oneOf"] = [
                    {"type": "string"},
                    {"type": "array", "items": {"type": "string"}},
                ]
            case _:
                msg = f"{self.type_str} not supported for type"
                raise RuntimeError(msg)

        return retval


def parse_rst_docs(txt: str) -> Generator[ConfigOpt, None, None]:
    for match in re.finditer(r".. confval:: ([^\s]*)\n\n((?:    .*\n|\n)*)", txt):
        name, body = match.groups()
        body = textwrap.dedent(body)
        body_match = re.match(r":type: (.*?)\n(?::default: (.*?)\n)?(.*)$", body, re.DOTALL)
        assert body_match is not None
        type_str, default, inner = body_match.groups()
        is_global = "only be set in the global section" in body
        description = inner.strip().split("\n\n")[0].replace("\n", " ")
        yield ConfigOpt(
            name=name,
            type_str=type_str,
            is_global=is_global,
            description=description,
            default=default,
        )


def make_schema(opts: Sequence[ConfigOpt]) -> dict[str, Any]:
    definitions = {s.name: s.define() for s in opts}
    overrides = {s.name: {"$ref": f"#/properties/{s.name}"} for s in opts if not s.is_global}
    module = {
        "oneOf": [
            {"type": "string"},
            {"type": "array", "items": {"type": "string"}, "minItems": 1},
        ]
    }

    return {
        "$id": "https://json.schemastore.org/mypy.json",
        "$schema": "http://json-schema.org/draft-07/schema#",
        "additionalProperties": False,
        "type": "object",
        "properties": {
            **definitions,
            "overrides": {
                "type": "array",
                "items": {
                    "type": "object",
                    "additionalProperties": False,
                    "required": ["module"],
                    "minProperties": 2,
                    "properties": {"module": module, **overrides},
                },
            },
        },
    }


if __name__ == "__main__":
    filepath = DIR.parent / "docs/source/config_file.rst"
    opts = parse_rst_docs(filepath.read_text())
    print(json.dumps(make_schema(list(opts)), indent=2))

This produces a pretty good schema file (which I am ready to contribute to SchemaStore). A few questions:

  • Would you accept this as misc/make_schema.py? Ideally even placing the generated schema somewhere (with a check to regenerate it)? It's not really a user file, so I used Python 3.10+.
  • I'm not including things not in the docs, including show_error_codes. Is there anything not documented that should be added?
  • I'm assuming all arrays are also specifiable as strings, based on the implementation. Is that correct? Also, a schema can be stricter than the code.
  • I'm not processing the rst into anything else for the descriptions. Also only taking the first paragraph. Not sure what's best, might ask when submitting to SchemaStore.
Full generated schema:
{
  "$id": "https://json.schemastore.org/mypy.json",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "additionalProperties": false,
  "type": "object",
  "properties": {
    "mypy_path": {
      "description": "Specifies the paths to use, after trying the paths from ``MYPYPATH`` environment variable.  Useful if you'd like to keep stubs in your repo, along with the config file. Multiple paths are always separated with a ``:`` or ``,`` regardless of the platform. User home directory and environment variables will be expanded.",
      "type": "string"
    },
    "files": {
      "description": "A comma-separated list of paths which should be checked by mypy if none are given on the command line. Supports recursive file globbing using :py:mod:`glob`, where ``*`` (e.g. ``*.py``) matches files in the current directory and ``**/`` (e.g. ``**/*.py``) matches files in any directories below the current one. User home directory and environment variables will be expanded.",
      "oneOf": [
        {
          "type": "string"
        },
        {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      ]
    },
    "modules": {
      "description": "A comma-separated list of packages which should be checked by mypy if none are given on the command line. Mypy *will not* recursively type check any submodules of the provided module.",
      "oneOf": [
        {
          "type": "string"
        },
        {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      ]
    },
    "packages": {
      "description": "A comma-separated list of packages which should be checked by mypy if none are given on the command line.  Mypy *will* recursively type check any submodules of the provided package. This flag is identical to :confval:`modules` apart from this behavior.",
      "oneOf": [
        {
          "type": "string"
        },
        {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      ]
    },
    "exclude": {
      "description": "A regular expression that matches file names, directory names and paths which mypy should ignore while recursively discovering files to check. Use forward slashes (``/``) as directory separators on all platforms.",
      "oneOf": [
        {
          "type": "string"
        },
        {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      ]
    },
    "namespace_packages": {
      "description": "Enables :pep:`420` style namespace packages.  See the corresponding flag :option:`--no-namespace-packages <mypy --no-namespace-packages>` for more information.",
      "default": true,
      "type": "boolean"
    },
    "explicit_package_bases": {
      "description": "This flag tells mypy that top-level packages will be based in either the current directory, or a member of the ``MYPYPATH`` environment variable or :confval:`mypy_path` config option. This option is only useful in the absence of `__init__.py`. See :ref:`Mapping file paths to modules <mapping-paths-to-modules>` for details.",
      "default": false,
      "type": "boolean"
    },
    "ignore_missing_imports": {
      "description": "Suppresses error messages about imports that cannot be resolved.",
      "default": false,
      "type": "boolean"
    },
    "follow_imports": {
      "description": "Directs what to do with imports when the imported module is found as a ``.py`` file and not part of the files, modules and packages provided on the command line.",
      "default": "normal",
      "type": "string"
    },
    "follow_imports_for_stubs": {
      "description": "Determines whether to respect the :confval:`follow_imports` setting even for stub (``.pyi``) files.",
      "default": false,
      "type": "boolean"
    },
    "python_executable": {
      "description": "Specifies the path to the Python executable to inspect to collect a list of available :ref:`PEP 561 packages <installed-packages>`. User home directory and environment variables will be expanded. Defaults to the executable used to run mypy.",
      "type": "string"
    },
    "no_site_packages": {
      "description": "Disables using type information in installed packages (see :pep:`561`). This will also disable searching for a usable Python executable. This acts the same as :option:`--no-site-packages <mypy --no-site-packages>` command line flag.",
      "default": false,
      "type": "boolean"
    },
    "no_silence_site_packages": {
      "description": "Enables reporting error messages generated within installed packages (see :pep:`561` for more details on distributing type information). Those error messages are suppressed by default, since you are usually not able to control errors in 3rd party code.",
      "default": false,
      "type": "boolean"
    },
    "python_version": {
      "description": "Specifies the Python version used to parse and check the target program.  The string should be in the format ``MAJOR.MINOR`` -- for example ``2.7``.  The default is the version of the Python interpreter used to run mypy.",
      "type": "string"
    },
    "platform": {
      "description": "Specifies the OS platform for the target program, for example ``darwin`` or ``win32`` (meaning OS X or Windows, respectively). The default is the current platform as revealed by Python's :py:data:`sys.platform` variable.",
      "type": "string"
    },
    "always_true": {
      "description": "Specifies a list of variables that mypy will treat as compile-time constants that are always true.",
      "oneOf": [
        {
          "type": "string"
        },
        {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      ]
    },
    "always_false": {
      "description": "Specifies a list of variables that mypy will treat as compile-time constants that are always false.",
      "oneOf": [
        {
          "type": "string"
        },
        {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      ]
    },
    "disallow_any_unimported": {
      "description": "Disallows usage of types that come from unfollowed imports (anything imported from an unfollowed import is automatically given a type of ``Any``).",
      "default": false,
      "type": "boolean"
    },
    "disallow_any_expr": {
      "description": "Disallows all expressions in the module that have type ``Any``.",
      "default": false,
      "type": "boolean"
    },
    "disallow_any_decorated": {
      "description": "Disallows functions that have ``Any`` in their signature after decorator transformation.",
      "default": false,
      "type": "boolean"
    },
    "disallow_any_explicit": {
      "description": "Disallows explicit ``Any`` in type positions such as type annotations and generic type parameters.",
      "default": false,
      "type": "boolean"
    },
    "disallow_any_generics": {
      "description": "Disallows usage of generic types that do not specify explicit type parameters.",
      "default": false,
      "type": "boolean"
    },
    "disallow_subclassing_any": {
      "description": "Disallows subclassing a value of type ``Any``.",
      "default": false,
      "type": "boolean"
    },
    "disallow_untyped_calls": {
      "description": "Disallows calling functions without type annotations from functions with type annotations. Note that when used in per-module options, it enables/disables this check **inside** the module(s) specified, not for functions that come from that module(s), for example config like this:",
      "default": false,
      "type": "boolean"
    },
    "untyped_calls_exclude": {
      "description": "Selectively excludes functions and methods defined in specific packages, modules, and classes from action of :confval:`disallow_untyped_calls`. This also applies to all submodules of packages (i.e. everything inside a given prefix). Note, this option does not support per-file configuration, the exclusions list is defined globally for all your code.",
      "oneOf": [
        {
          "type": "string"
        },
        {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      ]
    },
    "disallow_untyped_defs": {
      "description": "Disallows defining functions without type annotations or with incomplete type annotations (a superset of :confval:`disallow_incomplete_defs`).",
      "default": false,
      "type": "boolean"
    },
    "disallow_incomplete_defs": {
      "description": "Disallows defining functions with incomplete type annotations, while still allowing entirely unannotated definitions.",
      "default": false,
      "type": "boolean"
    },
    "check_untyped_defs": {
      "description": "Type-checks the interior of functions without type annotations.",
      "default": false,
      "type": "boolean"
    },
    "disallow_untyped_decorators": {
      "description": "Reports an error whenever a function with type annotations is decorated with a decorator without annotations.",
      "default": false,
      "type": "boolean"
    },
    "implicit_optional": {
      "description": "Causes mypy to treat arguments with a ``None`` default value as having an implicit :py:data:`~typing.Optional` type.",
      "default": false,
      "type": "boolean"
    },
    "strict_optional": {
      "description": "Enables or disables strict Optional checks. If False, mypy treats ``None`` as compatible with every type.",
      "default": true,
      "type": "boolean"
    },
    "warn_redundant_casts": {
      "description": "Warns about casting an expression to its inferred type.",
      "default": false,
      "type": "boolean"
    },
    "warn_unused_ignores": {
      "description": "Warns about unneeded ``# type: ignore`` comments.",
      "default": false,
      "type": "boolean"
    },
    "warn_no_return": {
      "description": "Shows errors for missing return statements on some execution paths.",
      "default": true,
      "type": "boolean"
    },
    "warn_return_any": {
      "description": "Shows a warning when returning a value with type ``Any`` from a function declared with a non- ``Any`` return type.",
      "default": false,
      "type": "boolean"
    },
    "warn_unreachable": {
      "description": "Shows a warning when encountering any code inferred to be unreachable or redundant after performing type analysis.",
      "default": false,
      "type": "boolean"
    },
    "ignore_errors": {
      "description": "Ignores all non-fatal errors.",
      "default": false,
      "type": "boolean"
    },
    "allow_untyped_globals": {
      "description": "Causes mypy to suppress errors caused by not being able to fully infer the types of global and class variables.",
      "default": false,
      "type": "boolean"
    },
    "allow_redefinition": {
      "description": "Allows variables to be redefined with an arbitrary type, as long as the redefinition is in the same block and nesting level as the original definition. Example where this can be useful:",
      "default": false,
      "type": "boolean"
    },
    "local_partial_types": {
      "description": "Disallows inferring variable type for ``None`` from two assignments in different scopes. This is always implicitly enabled when using the :ref:`mypy daemon <mypy_daemon>`.",
      "default": false,
      "type": "boolean"
    },
    "disable_error_code": {
      "description": "Allows disabling one or multiple error codes globally.",
      "oneOf": [
        {
          "type": "string"
        },
        {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      ]
    },
    "enable_error_code": {
      "description": "Allows enabling one or multiple error codes globally.",
      "oneOf": [
        {
          "type": "string"
        },
        {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      ]
    },
    "implicit_reexport": {
      "description": "By default, imported values to a module are treated as exported and mypy allows other modules to import them. When false, mypy will not re-export unless the item is imported using from-as or is included in ``__all__``. Note that mypy treats stub files as if this is always disabled. For example:",
      "default": true,
      "type": "boolean"
    },
    "strict_concatenate": {
      "description": "Make arguments prepended via ``Concatenate`` be truly positional-only.",
      "default": false,
      "type": "boolean"
    },
    "strict_equality": {
      "description": "",
      "default": false,
      "type": "boolean"
    },
    "strict": {
      "description": "",
      "default": false,
      "type": "boolean"
    },
    "show_error_context": {
      "description": "Prefixes each error with the relevant context.",
      "default": false,
      "type": "boolean"
    },
    "show_column_numbers": {
      "description": "Shows column numbers in error messages.",
      "default": false,
      "type": "boolean"
    },
    "hide_error_codes": {
      "description": "Hides error codes in error messages. See :ref:`error-codes` for more information.",
      "default": false,
      "type": "boolean"
    },
    "pretty": {
      "description": "Use visually nicer output in error messages: use soft word wrap, show source code snippets, and show error location markers.",
      "default": false,
      "type": "boolean"
    },
    "color_output": {
      "description": "Shows error messages with color enabled.",
      "default": true,
      "type": "boolean"
    },
    "error_summary": {
      "description": "Shows a short summary line after error messages.",
      "default": true,
      "type": "boolean"
    },
    "show_absolute_path": {
      "description": "Show absolute paths to files.",
      "default": false,
      "type": "boolean"
    },
    "force_uppercase_builtins": {
      "description": "Always use ``List`` instead of ``list`` in error messages, even on Python 3.9+.",
      "default": false,
      "type": "boolean"
    },
    "force_union_syntax": {
      "description": "Always use ``Union[]`` and ``Optional[]`` for union types in error messages (instead of the ``|`` operator), even on Python 3.10+.",
      "default": false,
      "type": "boolean"
    },
    "incremental": {
      "description": "Enables :ref:`incremental mode <incremental>`.",
      "default": true,
      "type": "boolean"
    },
    "cache_dir": {
      "description": "Specifies the location where mypy stores incremental cache info. User home directory and environment variables will be expanded. This setting will be overridden by the ``MYPY_CACHE_DIR`` environment variable.",
      "default": ".mypy_cache",
      "type": "string"
    },
    "sqlite_cache": {
      "description": "Use an `SQLite`_ database to store the cache.",
      "default": false,
      "type": "boolean"
    },
    "cache_fine_grained": {
      "description": "Include fine-grained dependency information in the cache for the mypy daemon.",
      "default": false,
      "type": "boolean"
    },
    "skip_version_check": {
      "description": "Makes mypy use incremental cache data even if it was generated by a different version of mypy. (By default, mypy will perform a version check and regenerate the cache if it was written by older versions of mypy.)",
      "default": false,
      "type": "boolean"
    },
    "skip_cache_mtime_checks": {
      "description": "Skip cache internal consistency checks based on mtime.",
      "default": false,
      "type": "boolean"
    },
    "plugins": {
      "description": "A comma-separated list of mypy plugins. See :ref:`extending-mypy-using-plugins`.",
      "oneOf": [
        {
          "type": "string"
        },
        {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      ]
    },
    "pdb": {
      "description": "Invokes :mod:`pdb` on fatal error.",
      "default": false,
      "type": "boolean"
    },
    "show_traceback": {
      "description": "Shows traceback on fatal error.",
      "default": false,
      "type": "boolean"
    },
    "raise_exceptions": {
      "description": "Raise exception on fatal error.",
      "default": false,
      "type": "boolean"
    },
    "custom_typing_module": {
      "description": "Specifies a custom module to use as a substitute for the :py:mod:`typing` module.",
      "type": "string"
    },
    "custom_typeshed_dir": {
      "description": "This specifies the directory where mypy looks for standard library typeshed stubs, instead of the typeshed that ships with mypy.  This is primarily intended to make it easier to test typeshed changes before submitting them upstream, but also allows you to use a forked version of typeshed.",
      "type": "string"
    },
    "warn_incomplete_stub": {
      "description": "Warns about missing type annotations in typeshed.  This is only relevant in combination with :confval:`disallow_untyped_defs` or :confval:`disallow_incomplete_defs`.",
      "default": false,
      "type": "boolean"
    },
    "any_exprs_report": {
      "description": "Causes mypy to generate a text file report documenting how many expressions of type ``Any`` are present within your codebase.",
      "type": "string"
    },
    "cobertura_xml_report": {
      "description": "Causes mypy to generate a Cobertura XML type checking coverage report.",
      "type": "string"
    },
    "linecount_report": {
      "description": "Causes mypy to generate a text file report documenting the functions and lines that are typed and untyped within your codebase.",
      "type": "string"
    },
    "linecoverage_report": {
      "description": "Causes mypy to generate a JSON file that maps each source file's absolute filename to a list of line numbers that belong to typed functions in that file.",
      "type": "string"
    },
    "lineprecision_report": {
      "description": "Causes mypy to generate a flat text file report with per-module statistics of how many lines are typechecked etc.",
      "type": "string"
    },
    "xml_report": {
      "description": "Causes mypy to generate an XML type checking coverage report.",
      "type": "string"
    },
    "junit_xml": {
      "description": "Causes mypy to generate a JUnit XML test result document with type checking results. This can make it easier to integrate mypy with continuous integration (CI) tools.",
      "type": "string"
    },
    "scripts_are_modules": {
      "description": "Makes script ``x`` become module ``x`` instead of ``__main__``.  This is useful when checking multiple scripts in a single run.",
      "default": false,
      "type": "boolean"
    },
    "warn_unused_configs": {
      "description": "Warns about per-module sections in the config file that do not match any files processed when invoking mypy. (This requires turning off incremental mode using :confval:`incremental = False <incremental>`.)",
      "default": false,
      "type": "boolean"
    },
    "verbosity": {
      "description": "Controls how much debug output will be generated.  Higher numbers are more verbose.",
      "integer": 0,
      "type": "integer"
    },
    "overrides": {
      "type": "array",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "module"
        ],
        "minProperties": 2,
        "properties": {
          "module": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "minItems": 1
              }
            ]
          },
          "ignore_missing_imports": {
            "$ref": "#/properties/ignore_missing_imports"
          },
          "follow_imports": {
            "$ref": "#/properties/follow_imports"
          },
          "follow_imports_for_stubs": {
            "$ref": "#/properties/follow_imports_for_stubs"
          },
          "no_site_packages": {
            "$ref": "#/properties/no_site_packages"
          },
          "always_true": {
            "$ref": "#/properties/always_true"
          },
          "always_false": {
            "$ref": "#/properties/always_false"
          },
          "disallow_any_unimported": {
            "$ref": "#/properties/disallow_any_unimported"
          },
          "disallow_any_expr": {
            "$ref": "#/properties/disallow_any_expr"
          },
          "disallow_any_decorated": {
            "$ref": "#/properties/disallow_any_decorated"
          },
          "disallow_any_explicit": {
            "$ref": "#/properties/disallow_any_explicit"
          },
          "disallow_any_generics": {
            "$ref": "#/properties/disallow_any_generics"
          },
          "disallow_subclassing_any": {
            "$ref": "#/properties/disallow_subclassing_any"
          },
          "disallow_untyped_calls": {
            "$ref": "#/properties/disallow_untyped_calls"
          },
          "untyped_calls_exclude": {
            "$ref": "#/properties/untyped_calls_exclude"
          },
          "disallow_untyped_defs": {
            "$ref": "#/properties/disallow_untyped_defs"
          },
          "disallow_incomplete_defs": {
            "$ref": "#/properties/disallow_incomplete_defs"
          },
          "check_untyped_defs": {
            "$ref": "#/properties/check_untyped_defs"
          },
          "disallow_untyped_decorators": {
            "$ref": "#/properties/disallow_untyped_decorators"
          },
          "implicit_optional": {
            "$ref": "#/properties/implicit_optional"
          },
          "strict_optional": {
            "$ref": "#/properties/strict_optional"
          },
          "warn_unused_ignores": {
            "$ref": "#/properties/warn_unused_ignores"
          },
          "warn_no_return": {
            "$ref": "#/properties/warn_no_return"
          },
          "warn_return_any": {
            "$ref": "#/properties/warn_return_any"
          },
          "warn_unreachable": {
            "$ref": "#/properties/warn_unreachable"
          },
          "ignore_errors": {
            "$ref": "#/properties/ignore_errors"
          },
          "allow_untyped_globals": {
            "$ref": "#/properties/allow_untyped_globals"
          },
          "allow_redefinition": {
            "$ref": "#/properties/allow_redefinition"
          },
          "local_partial_types": {
            "$ref": "#/properties/local_partial_types"
          },
          "disable_error_code": {
            "$ref": "#/properties/disable_error_code"
          },
          "enable_error_code": {
            "$ref": "#/properties/enable_error_code"
          },
          "implicit_reexport": {
            "$ref": "#/properties/implicit_reexport"
          },
          "strict_concatenate": {
            "$ref": "#/properties/strict_concatenate"
          },
          "strict_equality": {
            "$ref": "#/properties/strict_equality"
          },
          "strict": {
            "$ref": "#/properties/strict"
          },
          "show_error_context": {
            "$ref": "#/properties/show_error_context"
          },
          "show_column_numbers": {
            "$ref": "#/properties/show_column_numbers"
          },
          "hide_error_codes": {
            "$ref": "#/properties/hide_error_codes"
          },
          "pretty": {
            "$ref": "#/properties/pretty"
          },
          "color_output": {
            "$ref": "#/properties/color_output"
          },
          "error_summary": {
            "$ref": "#/properties/error_summary"
          },
          "show_absolute_path": {
            "$ref": "#/properties/show_absolute_path"
          },
          "force_uppercase_builtins": {
            "$ref": "#/properties/force_uppercase_builtins"
          },
          "force_union_syntax": {
            "$ref": "#/properties/force_union_syntax"
          },
          "incremental": {
            "$ref": "#/properties/incremental"
          },
          "cache_dir": {
            "$ref": "#/properties/cache_dir"
          },
          "sqlite_cache": {
            "$ref": "#/properties/sqlite_cache"
          },
          "cache_fine_grained": {
            "$ref": "#/properties/cache_fine_grained"
          },
          "skip_version_check": {
            "$ref": "#/properties/skip_version_check"
          },
          "skip_cache_mtime_checks": {
            "$ref": "#/properties/skip_cache_mtime_checks"
          },
          "plugins": {
            "$ref": "#/properties/plugins"
          },
          "pdb": {
            "$ref": "#/properties/pdb"
          },
          "show_traceback": {
            "$ref": "#/properties/show_traceback"
          },
          "raise_exceptions": {
            "$ref": "#/properties/raise_exceptions"
          },
          "custom_typing_module": {
            "$ref": "#/properties/custom_typing_module"
          },
          "custom_typeshed_dir": {
            "$ref": "#/properties/custom_typeshed_dir"
          },
          "warn_incomplete_stub": {
            "$ref": "#/properties/warn_incomplete_stub"
          },
          "any_exprs_report": {
            "$ref": "#/properties/any_exprs_report"
          },
          "cobertura_xml_report": {
            "$ref": "#/properties/cobertura_xml_report"
          },
          "linecount_report": {
            "$ref": "#/properties/linecount_report"
          },
          "linecoverage_report": {
            "$ref": "#/properties/linecoverage_report"
          },
          "lineprecision_report": {
            "$ref": "#/properties/lineprecision_report"
          },
          "xml_report": {
            "$ref": "#/properties/xml_report"
          },
          "junit_xml": {
            "$ref": "#/properties/junit_xml"
          },
          "scripts_are_modules": {
            "$ref": "#/properties/scripts_are_modules"
          },
          "warn_unused_configs": {
            "$ref": "#/properties/warn_unused_configs"
          },
          "verbosity": {
            "$ref": "#/properties/verbosity"
          }
        }
      }
    }
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature topic-configuration Configuration files and flags
Projects
None yet
Development

No branches or pull requests

2 participants