Skip to content
Development
Skill

/pyrefly-type-coverage

Migrate a file to use stricter Pyrefly type checking with annotations required for all functions, classes, and attributes.

From plugin
pytorch
102k16 skills
Install
$ npx -y skills add pytorch/pytorch --skill pyrefly-type-coverage --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/pyrefly-type-coverage

Context preview

The summary Claude sees to decide when to auto-load this skill.

Migrate a file to use stricter Pyrefly type checking with annotations required for all functions, classes, and attributes.

SKILL.md

pyrefly-type-coverage.SKILL.md
name: pyrefly-type-coverage
description: Migrate a file to use stricter Pyrefly type checking with annotations required for all functions, classes, and attributes.

Pyrefly Type Coverage Skill

Prerequisites

  • The file must live in a project with a `pyrefly.toml`.
  • `pyrefly`, `lintrunner`, and the project's test runner must be on PATH. **If any

are missing, stop and ask whether a conda environment needs activating** — don't install or substitute (per repo CLAUDE.md).

Step 1: Remove file-level type-check suppressions

Delete any of these from the top of the file (pyrefly honors `# mypy: ignore-errors` for mypy compat, so that one must go too):

# pyre-ignore-all-errors
# pyre-ignore-all-errors[16,21,53,56]
# @lint-ignore-every PYRELINT
# mypy: ignore-errors

Step 2: Add a sub-config entry to `pyrefly.toml`

[[sub-config]]
matches = "path/to/directory/**"
[sub-config.errors]
implicit-import = false
implicit-any = true
bad-param-name-override = false
unannotated-return = true
unannotated-parameter = true

**IMPORTANT**: Setting any error key in `[sub-config.errors]` overrides only that key relative to the parent — but enabling `unannotated-return` / `unannotated-parameter` / `implicit-any` will resurface errors that were previously hidden file-wide. If you see unrelated errors (e.g., `bad-param-name-override`) flooding the output, mirror the parent config's setting for that key in the sub-config to silence them.

Step 3: Run pyrefly

pyrefly check <FILENAME>

**Goal:** resolve all `unannotated-return`, `unannotated-parameter`, and `implicit-any` errors by adding annotations — see Step 4's ladder. These three target categories are always resolvable; **never** suppress them with `# pyrefly: ignore`. The single exception is `@compatibility(is_backward_compatible=True)` (Step 4).

Other categories (`bad-argument-type`, `missing-attribute`, …) are real type bugs. Handle them by where pyrefly reports them:

  • **Reported in another file** (path != target): leave it. Don't widen scope. If

the error is now blocking the target, suppress at the report site with `# pyrefly: ignore[<category>] # TODO`.

  • **Reported in the target file but the message names a symbol defined elsewhere**

(e.g., `bad-return` because an imported function's annotation is wrong): suppress locally with the same TODO comment. Don't invent a `cast()` that papers over the upstream gap.

  • **Reported in the target file, originates locally**: fix it.

Use `# pyrefly: ignore[...]` only as a last resort, and only on non-target categories.

Step 4: Add annotations

Examine call sites when the right type isn't obvious from the function body.

Annotation conventions

  • Use PEP 604 / PEP 585 syntax (`int | None`, `list[str]`) — assume Python >= 3.10.
  • Prefer `collections.abc` over `typing` for ABCs (`Callable`, `Sequence`, `Generator`, ...).
  • For generic helpers, import from `typing` when available on the project's minimum

Python version, and from `typing_extensions` only when you need a newer feature (e.g., `Self` and `override` if supporting < 3.11/3.12, or PEP 696 `default=` for `TypeVar` / `ParamSpec`). Don't blanket-import from `typing_extensions`.

  • Always parameterize `Callable` (never bare `Callable`). Prefer

`Callable[..., object]`; reach for `Callable[..., Any]` only when a caller genuinely consumes the dynamic return — if the result is just passed through (or the callable isn't even invoked), `object` is stricter and equally correct. (See ParamSpec below for the signature-preserving wrapper case.)

  • Give any module-local global you **introduce** a leading underscore —

`TypeVar`/`ParamSpec` (matching the string arg: `_T = TypeVar("_T")`, `_P = ParamSpec("_P")`, `_R = TypeVar("_R")`), `TypeAlias`es, helper constants, and sentinels alike. This is the prevailing torch convention for non-public names (`_P` outnumbers `P` ~6:1 in the tree). Exceptions (leave un-underscored): a name imported by other modules, listed in `__all__`, or used as a runtime token (e.g. an annotation-string dispatch marker). Applies only to names you add — do **not** rename pre-existing globals; that's an unrelated refactor outside this skill's scope.

  • A boolean predicate — `is_*`/`has_*` name, takes a broad type (often `object`),

returns `bool` — usually wants `TypeGuard[X]` (or `TypeIs[X]`, which also narrows the negative branch). `TypeGuard` is in `typing` (>= 3.10, so import from there); `TypeIs` only entered `typing` in 3.13, so import it from `typing_extensions` (>= 4.10) to stay 3.10-compatible. An `issubclass`-style helper taking `klass: type[_T]` should return `TypeGuard[type[_T]]`. Prefer an explicit `isinstance(x, type)` guard over `try/except TypeError` around `issubclass()` — clearer, and it lets the checker narrow.

  • When a return type is *derived from* a parameter — passthroughs/identity

functions, "return one of these args" helpers, decorators, registries keyed by type — reach for a `TypeVar` (or, for a callable arg whose signature flows through, `Callable[_P, _R]` with `ParamSpec`/`TypeVar`) rather than widening to `object`/`Any`. "Output type == some input type" is exactly what a `TypeVar` encodes; `object` in / `object` out discards it. Caveat: if the function *transforms* the value so the output type differs from the input (e.g. converts an array to an int), a single `TypeVar` is wrong — name the actual domain type instead.

  • Class attributes assigned in `__init__` should get a class-level annotation so pyrefly can see them.
  • Break import cycles with `if TYPE_CHECKING:` — annotation-only imports go inside the

guard, and use `from __future__ import annotations` (or string forward refs) so runtime imports stay lazy:

  from __future__ import annotations
  from typing import TYPE_CHECKING
  if TYPE_CHECKING:
      from torch.fx import GraphModule
  def transform(gm: GraphModule)
Read more
Ships withpytorch

Tensors and Dynamic neural networks in Python with strong GPU acceleration

Get the whole plugin

Other skills on pytorch.