# core/producers/tool.mypy.producer.ts

> 54 lines of code and 18 definitions.

Tree: GovLab Quality
Language: typescript
Layer: application
Canonical: https://banes-lab.com/anatomy/quality#file-quality-core-producers-tool-mypy-producer-ts
Source text: https://banes-lab.com/source/quality/core/producers/tool.mypy.producer.ts.txt

Listed in [core/producers](https://banes-lab.com/api/source/quality/core/producers.md), after [core/producers/tool.luacheck.producer.ts](https://banes-lab.com/source/quality/core/producers/tool.luacheck.producer.ts.md) and before [core/producers/tool.oxlint.producer.ts](https://banes-lab.com/source/quality/core/producers/tool.oxlint.producer.ts.md).

## Definitions

- `titleAfter` (lexical_declaration, line 23)
- `rulesOf` (lexical_declaration, line 31)
- `TOOL` (lexical_declaration, line 7)
- `VERSION` (lexical_declaration, line 8)
- `SOURCE_ROOT` (lexical_declaration, line 9)
- `DOCS` (lexical_declaration, line 10)
- `CODE_PREFIX` (lexical_declaration, line 11)
- `LOOKAHEAD` (lexical_declaration, line 12)
- `SOURCES` (lexical_declaration, line 13)
- `codeAt` (lexical_declaration, line 18)
- `text` (lexical_declaration, line 19)
- `title` (lexical_declaration, line 24)
- `lines` (lexical_declaration, line 32)
- `code` (lexical_declaration, line 34)
- `produce` (lexical_declaration, line 53)
- `texts` (lexical_declaration, line 54)
- `rows` (lexical_declaration, line 55)
- `rules` (lexical_declaration, line 56)

## Contained in

- [core/producers](https://banes-lab.com/anatomy/quality/folder-quality-core-producers.md)

## Linked from

- [core/producers](https://banes-lab.com/anatomy/quality/folder-quality-core-producers.md)

## Source

```typescript
import type { CatalogProduct, CatalogRule } from "#types/catalog.types";
import { byRuleId } from "#core/comparators/rule.comparator";
import { defineProducer } from "#core/registries/producer.registry";
import { distinctRules } from "#core/selectors/catalog.selector";
import { remoteText } from "#core/adapters/remote.adapter";

const TOOL = "mypy";
const VERSION = "repo-master";
const SOURCE_ROOT = "https://raw.githubusercontent.com/python/mypy/master/docs/source";
const DOCS = "https://mypy.readthedocs.io/en/stable/error_code_list.html#code-";
const CODE_PREFIX = ".. _code-";
const LOOKAHEAD = 5;
const SOURCES: readonly [string, string][] = [
    ["error_code_list.rst", "default"],
    ["error_code_list2.rst", "optional"],
];

const codeAt = function codeAt(line: string): string | null {
    const text = line.trim();
    return text.startsWith(CODE_PREFIX) && text.endsWith(":") ? text.slice(CODE_PREFIX.length, -1) || null : null;
};

const titleAfter = function titleAfter(lines: readonly string[], index: number): string | null {
    const title = lines
        .slice(index + 1, index + LOOKAHEAD)
        .map((line) => line.trim())
        .find((line) => line !== "" && !line.startsWith("---") && !line.startsWith("==="));
    return title ?? null;
};

const rulesOf = function rulesOf(text: string, kind: string): CatalogRule[] {
    const lines = text.split("\n");
    return lines.flatMap((line, index): CatalogRule[] => {
        const code = codeAt(line);
        return code === null
            ? []
            : [
                  {
                      canonical: null,
                      category: kind,
                      description: titleAfter(lines, index) ?? code,
                      ecosystem: "python",
                      name: code,
                      ruleId: code,
                      tool: TOOL,
                      toolVersion: VERSION,
                      url: `${DOCS}${code}`,
                  },
              ];
    });
};

const produce = async function produce(): Promise<CatalogProduct[]> {
    const texts = await Promise.all(SOURCES.map(async ([file]) => remoteText(`${SOURCE_ROOT}/${file}`)));
    const rows = SOURCES.flatMap(([, kind], index) => rulesOf(texts[index] ?? "", kind));
    const rules = distinctRules(rows).toSorted(byRuleId);
    return [{ rules, source: TOOL, summary: { tool: TOOL, toolVersion: VERSION, total: rules.length } }];
};

defineProducer({ name: TOOL, produce, refresh: "manual" });
```
