Skip to content

Tracking: complete the ty gradual-typing baseline (un-ignore rules; PEP 723 blocker astral-sh/ty#691) #15187

Description

@priya-sundaram-dev

Summary

Follow-up to #15180, which added an informational ty type-check job (.github/workflows/ty.yml, continue-on-error: true, ty check --exit-zero). This issue tracks what it takes to turn that advisory job into a required gate as type hints are added to the algorithms gradually, and records the current blockers.

How the gradual baseline works today

pyproject.toml [tool.ty] pins the interpreter and currently ignores 15 rules so the informational job starts from a green-ish baseline instead of drowning in noise:

call-non-callable, deprecated, invalid-argument-type, invalid-assignment,
invalid-parameter-default, invalid-return-type, invalid-type-arguments,
invalid-type-form, no-matching-overload, not-iterable, not-subscriptable,
parameter-already-assigned, unresolved-attribute, unresolved-import,
unsupported-operator

Requirements to "complete" the work

The work is done rule-by-rule, matching how typing is added to the algorithms incrementally:

  1. Pick one ignored rule from the list above.
  2. Fix the files that trip it — add annotations / correct signatures — as bite-sized good-first-issues. unresolved-import is largely environment noise (third-party stubs) and should be handled by making sure uv sync installs the dep, not by editing code.
  3. Un-ignore the rule: delete its rules.<name> = "ignore" line in [tool.ty] once its diagnostic count is zero on a synced 3.14 env.
  4. When all rules are un-ignored and the baseline is clean, follow the promotion path documented inline in ty.yml: --exit-zero → --exit-zero-on-warning → drop the flag + set continue-on-error: false to make ty a required check.

Blocker: PEP 723 single-file scripts (astral-sh/ty#691)

ty treats a # /// script inline-metadata file as its own project, so it does not inherit the repo's [tool.ty] rule severities. Those files therefore surface the "ignored" diagnostics regardless of config, which will produce false failures the moment any rule is promoted to error. Until astral-sh/ty#691 lands, the options are:

  • run the gate with ty check --exclude-scripts (skips PEP 723 files), or
  • keep the job informational for script files specifically.

Un-ignoring rules for the non-script bulk of the repo can proceed in parallel and does not need to wait on #691.

Note on ty check --fix

For the record (asked on #15180): on the current tree, ty check --fix reports 0 fixed, 36 remaining — i.e. no changes, as expected. ty 0.0.74 ships no autofixes for any of these diagnostic categories yet, and it has no --unsafe-changes flag (the safe/unsafe fix split is a ruff feature ty hasn't implemented). So there is nothing for a "--fix results" PR to contain right now; this is worth revisiting once ty grows fix support.

Activity

  1. priya-sundaram-dev commented on Sep 6, 2026

    @priya-sundaram-dev
    ContributorAuthor

    Agreed, that's the right way to do it — each rule as its own bite-sized task so contributors can grab one without stepping on each other.

    Quick note from actually running the numbers: invalid-return-type and invalid-assignment aren't quite the same shape. On a synced 3.14 env, invalid-assignment is genuinely low-hanging — mostly a handful of files where a narrower annotation or a small signature fix clears it, so it makes a clean standalone good-first-issue. invalid-return-type is a bit larger and tends to cluster with invalid-argument-type (fixing a return annotation often surfaces the next call site), so it may read better as a small group of linked issues rather than one.

    If it helps, the mechanical recipe per rule is:

    1. ty check --exclude-scripts locally on a uv sync'd env, grep the output for the one rule.
    2. Fix just those files, leaving every other ignored rule untouched.
    3. Delete that rule's rules.<name> = "ignore" line in [tool.ty].
    4. Confirm the diagnostic count for it is zero, open the PR.

    I'll carve invalid-assignment out into its own tracked good-first-issue with the current file list so it's ready to grab. Thanks for pushing on this — splitting it up is what will actually get the baseline moving.

  2. priya-sundaram-dev commented on Sep 6, 2026

    @priya-sundaram-dev
    ContributorAuthor

    Carved out the first standalone slice: #15199 — un-ignore invalid-assignment (23 diagnostics across 9 files, all local node-attribute annotation fixes). Ready to grab. I'll open follow-up issues for the other low-hanging rules as I confirm their file lists.

  3. priya-sundaram-dev commented on Sep 6, 2026

    @priya-sundaram-dev
    ContributorAuthor

    Carved the first standalone sub-task per @miragerushton26's suggestion: #15204 — un-ignore invalid-assignment (9 files, 23 spots, all small annotation fixes on linked-list/tree next/previous attributes). It's self-contained and first-timer friendly, with the current file/line list and a one-liner to reproduce.

    I'll keep it linked here as a checklist item and carve the next clean rule (invalid-return-type clusters with invalid-argument-type, so those two are better as a linked pair) once this one has takers.

  4. priya-sundaram-dev commented on Sep 8, 2026

    @priya-sundaram-dev
    ContributorAuthor

    Good question to ask before writing code. Keep it scoped to satisfying the check with the least surface area — don't introduce Protocols or a collections type hierarchy just to make unsupported-operator happy. That kind of abstraction is exactly the noise we're trying to avoid in a learning-resource repo, and it makes the diff hard to review.

    Concretely, I'd triage each diagnostic into one of three buckets rather than reaching for a blanket rule:

    1. Genuine missing dunder that the algorithm actually calls — e.g. a custom Vector/Matrix that supports v1 + v2 in the code but has no __add__. Add the method (or its annotation if it exists but returns an inferred-wrong type). That's a real gap worth fixing.
    2. Real type mismatch — ty is right that the operands can't combine (e.g. str + int, or an Optional[X] that's never narrowed). Fix the logic or narrow with an assert/guard. Don't silence these.
    3. Over-wide annotation — the operand is typed broader than it's ever used (a bare object, or a union that includes a non-arithmetic member). Tighten the annotation so ty can see the operator is valid.

    The thing to avoid is bucket 4: adding speculative __add__/__sub__ stubs to classes that don't actually use those operators, purely to clear a diagnostic. That's dead code and will confuse readers.

    Process-wise, please carve it out as its own sub-issue/PR like #15199 / #15204 — one rule, small diff, and drop the rules.unsupported-operator = "ignore" line only once the count is zero on a synced 3.14 env. If you paste the diagnostic list here first I'm happy to help sort them into the buckets above before you start.

  5. pinned this issue on Sep 10, 2026
  6. kadubhumika commented on Sep 11, 2026

    @kadubhumika
    Contributor

    Hi @cclauss @priya-sundaram-dev , I’ve completed the merge_sort.py work from #15234. I’d like to take another small typing task from #15187. Is there an available rule/sub-issue I can work on should i start work on this ?

  7. priya-sundaram-dev commented on Sep 11, 2026

    @priya-sundaram-dev
    ContributorAuthor

    Thanks @kadubhumika, and nice work finishing the merge_sort.py piece. There's definitely a rule free for you.

    Quick status so we don't collide:

    Good next candidates that tend to be small and mechanical (nice as a self-contained PR):

    • invalid-parameter-default — usually a handful of spots where a default doesn't match the annotation (e.g. def f(x: list = None) → x: list | None = None, or a too-narrow annotation vs. its default).
    • parameter-already-assigned — typically a very short list; a parameter getting assigned a value it already has, or a duplicate keyword.
    • deprecated — a small set of stdlib deprecations.

    Please skip unresolved-import for now — that one is mostly environment noise (third-party stubs) and should be fixed by making sure uv sync installs the dep, not by editing algorithm code.

    Process, same as the earlier sub-issues:

    1. Pick one rule and carve it out as its own sub-issue/PR (one rule, small diff).
    2. Run ty check on a synced 3.14 env and fix the files it flags — annotate/tighten, don't add speculative stubs.
    3. Drop the rules.<name> = "ignore" line in [tool.ty] only once that rule's count is zero.

    If you run ty check locally and paste the per-rule diagnostic counts here, I'll help you pick the smallest one to start with and sort the individual diagnostics into fix buckets before you write any code. Pick whichever of the three above you like and go for it. 🙂

  8. kadubhumika commented on Sep 11, 2026

    @kadubhumika
    Contributor

    Thanks! Yes, sure I’ll take invalid-parameter-default. I’ll run ty check --exclude-scripts, identify the relevant diagnostics, and work on it as a separate PR.

    Also, if there are any other available issues beyond the typing-related ones, I’d be happy to take one up. Please let me know.

  9. priya-sundaram-dev commented on Sep 11, 2026

    @priya-sundaram-dev
    ContributorAuthor

    Great, thanks for taking invalid-parameter-default! One tip: run ty check --exclude-scripts 2>&1 | grep invalid-parameter-default to get just those call sites, then fix them and remove that rule from the [tool.ty.rules] ignore list in the same PR so CI proves it stays clean.

    For non-typing work, the maintainers curate two labels worth watching:

    Pick one that isn't already assigned, comment to claim it, and keep each PR small and focused — that's the fastest path to review here. I can only really speak to the typing thread, so a maintainer is the best person to confirm scope on anything else.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions