Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 23 additions & 23 deletions docs/source/config_file.rst
Original file line number Diff line number Diff line change
Expand Up @@ -802,11 +802,11 @@ section of the command line docs.

.. confval:: extra_checks

:type: boolean
:default: False
:type: boolean
:default: False

This flag enables additional checks that are technically correct but may be impractical.
See :option:`mypy --extra-checks` for more info.
This flag enables additional checks that are technically correct but may be impractical.
See :option:`mypy --extra-checks` for more info.

.. confval:: implicit_reexport

Expand All @@ -830,39 +830,39 @@ section of the command line docs.

.. confval:: strict_equality

:type: boolean
:default: False
:type: boolean
:default: False

Prohibit equality checks, identity checks, and container checks between
non-overlapping types (except ``None``).
Prohibit equality checks, identity checks, and container checks between
non-overlapping types (except ``None``).

.. confval:: strict_equality_for_none

:type: boolean
:default: False
:type: boolean
:default: False

Include ``None`` in strict equality checks (requires :confval:`strict_equality`
to be activated).
Include ``None`` in strict equality checks (requires :confval:`strict_equality`
to be activated).

.. confval:: strict_bytes

:type: boolean
:default: False
:type: boolean
:default: False

Disable treating ``bytearray`` and ``memoryview`` as subtypes of ``bytes``.
This will be enabled by default in *mypy 2.0*.
Disable treating ``bytearray`` and ``memoryview`` as subtypes of ``bytes``.
This will be enabled by default in *mypy 2.0*.

.. confval:: strict

:type: boolean
:default: False
:type: boolean
:default: False

Enable all optional error checking flags. You can see the list of
flags enabled by strict mode in the full :option:`mypy --help`
output.
Enable all optional error checking flags. You can see the list of
flags enabled by strict mode in the full :option:`mypy --help`
output.

Note: the exact list of flags enabled by :confval:`strict` may
change over time.
Note: the exact list of flags enabled by :confval:`strict` may
change over time.


Configuring error messages
Expand Down
119 changes: 119 additions & 0 deletions misc/make_schema.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
from __future__ import annotations

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

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

assert sys.version_info > (3, 9)


@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["default"] = int(self.default)
case "string":
retval["default"] = self.default.strip("`")
case _:
msg = f"Default not supported 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, f"{name} missing type and default!\n{body!r}"
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", " ")
# Patches
if name == "mypy_path":
type_str = "comma-separated list of strings"
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},
]
}

# Improve some fields
definitions["follow_imports"]["enum"] = ["normal", "silent", "skip", "error"]

# Undocumented fields
definitions["show_error_codes"] = {
"type": "boolean",
"default": True,
"description": "DEPRECATED and UNDOCUMENTED: Now defaults to true, use `hide_error_codes` if you need to disable error codes instead.",
"deprecated": True,
}

return {
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://json.schemastore.org/partial-mypy.json",
"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))
Loading