Skip to content

pyright: 15 errors to 0, by narrowing where the code already guarantees it - #139

Merged
soodoku merged 1 commit into
masterfrom
fix/pyright
Aug 16, 2026
Merged

pyright: 15 errors to 0, by narrowing where the code already guarantees it#139
soodoku merged 1 commit into
masterfrom
fix/pyright

Conversation

@soodoku

@soodoku soodoku commented Aug 16, 2026

Copy link
Copy Markdown
Member

Every one of these was code that is correct today and could not be shown to be. No behaviour changes.

pred_census_ln.py — 4

The validation raises when stats is None and either prior or coverage was given, and every use of stats sits inside one of those two conditions — a chain no checker follows through a compound and:

if (prior is not None or coverage is not None) and stats is None:
    raise ValueError(...)
...
if coverage is not None:
    qhat = stats["conformal_quantiles"][...]   # pyright: stats may be None

Asserted at the three use points, which also states the invariant for the next reader. The coverage validation is now a nested if rather than a compound one, which reads better anyway.

pred_wiki_origin.py — 2

The base declares VOCABFN/RACEFN as str | None because non-LSTM models have neither; this model sets both.

Narrowing them in the subclass does not work — a mutable ClassVar is invariant, so str is not assignable to str | None. I tried it and it traded two errors for two different ones, so it is narrowed at the call site instead.

dict_models.py — 9

pandas-stubs types df[key] as Series | DataFrame, because a column label could be duplicated. A scalar key yields a Series and a list key a DataFrame — which the stubs cannot express. Five Series call sites and one DataFrame assignment are cast, each with the reason.

census_marginal returns a cached value the branch above always sets, so that is asserted rather than cast.

Verification

pyright 15 → 0, ruff check and ruff format --check clean, 211 tests pass.

Combined with the earlier scoping PR, this repo goes from 130 pyright errors and 12,249 codespell findings to zero of each.

…es it

Every one of these was code that is correct today and could not be shown to be.

**pred_census_ln.py (4).** The validation raises when `stats is None` and
either `prior` or `coverage` was given, and every use of `stats` sits inside
one of those two conditions -- a chain no checker follows through a compound
`and`. Asserted at the three use points, which also states the invariant for
the next reader. The `coverage` validation is now a nested `if` rather than a
compound one, which reads better anyway.

**pred_wiki_origin.py (2).** The base declares VOCABFN and RACEFN as
`str | None` because non-LSTM models have neither. This model sets both.
Narrowing them in the subclass does not work -- a mutable ClassVar is
invariant, so `str` is not assignable to `str | None`, and trying it traded two
errors for two different ones. Narrowed at the call site instead.

**dict_models.py (9).** pandas-stubs types `df[key]` as `Series | DataFrame`,
because a column label could be duplicated; a scalar key yields a Series and a
list key a DataFrame, which the stubs cannot express. Five Series call sites
and one DataFrame assignment are now cast, with the reason. `census_marginal`
returns a cached value the branch above always sets, so that is asserted rather
than cast.

No behaviour changes: 211 tests pass, ruff and format clean.
@soodoku
soodoku merged commit 7ba3cea into master Aug 16, 2026
15 checks passed
@soodoku
soodoku deleted the fix/pyright branch August 16, 2026 03:44
soodoku added a commit that referenced this pull request Aug 20, 2026
…es it (#139)

Every one of these was code that is correct today and could not be shown to be.

**pred_census_ln.py (4).** The validation raises when `stats is None` and
either `prior` or `coverage` was given, and every use of `stats` sits inside
one of those two conditions -- a chain no checker follows through a compound
`and`. Asserted at the three use points, which also states the invariant for
the next reader. The `coverage` validation is now a nested `if` rather than a
compound one, which reads better anyway.

**pred_wiki_origin.py (2).** The base declares VOCABFN and RACEFN as
`str | None` because non-LSTM models have neither. This model sets both.
Narrowing them in the subclass does not work -- a mutable ClassVar is
invariant, so `str` is not assignable to `str | None`, and trying it traded two
errors for two different ones. Narrowed at the call site instead.

**dict_models.py (9).** pandas-stubs types `df[key]` as `Series | DataFrame`,
because a column label could be duplicated; a scalar key yields a Series and a
list key a DataFrame, which the stubs cannot express. Five Series call sites
and one DataFrame assignment are now cast, with the reason. `census_marginal`
returns a cached value the branch above always sets, so that is asserted rather
than cast.

No behaviour changes: 211 tests pass, ruff and format clean.
soodoku added a commit that referenced this pull request Aug 20, 2026
…es it (#139)

Every one of these was code that is correct today and could not be shown to be.

**pred_census_ln.py (4).** The validation raises when `stats is None` and
either `prior` or `coverage` was given, and every use of `stats` sits inside
one of those two conditions -- a chain no checker follows through a compound
`and`. Asserted at the three use points, which also states the invariant for
the next reader. The `coverage` validation is now a nested `if` rather than a
compound one, which reads better anyway.

**pred_wiki_origin.py (2).** The base declares VOCABFN and RACEFN as
`str | None` because non-LSTM models have neither. This model sets both.
Narrowing them in the subclass does not work -- a mutable ClassVar is
invariant, so `str` is not assignable to `str | None`, and trying it traded two
errors for two different ones. Narrowed at the call site instead.

**dict_models.py (9).** pandas-stubs types `df[key]` as `Series | DataFrame`,
because a column label could be duplicated; a scalar key yields a Series and a
list key a DataFrame, which the stubs cannot express. Five Series call sites
and one DataFrame assignment are now cast, with the reason. `census_marginal`
returns a cached value the branch above always sets, so that is asserted rather
than cast.

No behaviour changes: 211 tests pass, ruff and format clean.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant