Skip to content

Fix mypy type errors and achieve 100% appropriate type annotation coverage - #1278

Merged
bact merged 7 commits into
devfrom
copilot/verify-type-annotations
Feb 4, 2026
Merged

Fix mypy type errors and achieve 100% appropriate type annotation coverage#1278
bact merged 7 commits into
devfrom
copilot/verify-type-annotations

Conversation

Copilot AI commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

What do these changes do

Fixes all mypy type checking errors in the codebase (35 original errors + 16 with optional dependencies) and documents that all variables lacking type annotations are correctly unannotated per Python typing specifications. Adds comprehensive analysis showing the codebase has achieved 100% appropriate type coverage for both functions and variables.

What was wrong

The codebase had 35 mypy type errors across 15 files including:

  • Type variance issues with str.maketrans()
  • Attribute redefinition errors from annotated reassignments
  • Callable type signature mismatches
  • Missing or incorrect type ignore comments for optional dependencies
  • Incorrect type annotations on module attribute reassignments

Additionally, the type hint analyzer reported 95.39% variable coverage, creating ambiguity about whether the remaining 58 variables needed annotations.

When compact dependencies (numpy, nlpo3, etc.) were installed, 15 additional mypy errors appeared due to type checking against actual library implementations.

When extra dependencies were installed (along with compact), 1 additional mypy error appeared due to importlib_resources being available.

How this fixes it

Fixed 35 original mypy errors:

  1. Type variance issues (5 errors): Added cast() to handle dict type variance with str.maketrans()
  2. Attribute redefinition (17 errors): Removed type annotations from all attribute reassignments - only first assignment should be annotated
  3. Callable signatures (5 errors): Corrected Callable types from [[str], str] to [[Collection[str]], list[str]] to match actual signatures
  4. Import issues (3 errors): Added proper import-not-found to type ignore comments for optional dependencies
  5. Module attributes (2 errors): Removed type annotations from sys.stdout/sys.stderr reassignments

Additional fixes based on PR review:

  1. Union type correction: Fixed augment/word2vec/core.py model parameter to accept Union[str, "KeyedVectors"] instead of just str
  2. Comprehensive codebase review: Found and fixed 13 additional files with duplicate type annotations on reassignments:
    • transliterate/thaig2p.py, transliterate/thai2rom.py, transliterate/w2p.py
    • tag/thainer.py, tokenize/multi_cut.py, tokenize/attacut.py
    • translate/th_fr.py, translate/zh_th.py, translate/small100.py
    • generate/core.py, augment/lm/fasttext.py

Fixed 15 compact dependency errors:

  1. Removed unused type ignores (3 errors): In tokenize/nlpo3.py, removed import-not-found ignores that became unnecessary when nlpo3 is installed
  2. Fixed numpy return types (11 errors): Added # type: ignore[no-any-return] for numpy array operations where mypy cannot infer exact types from operations like np.exp(), np.array(), etc. Files affected:
    • transliterate/w2p.py, transliterate/thai2rom_onnx.py
    • word_vector/core.py, ulmfit/core.py
    • tag/wangchanberta_onnx.py, summarize/keybert.py
  3. Fixed import type (1 error): Changed umt5_thaig2p import in transliterate/core.py from import-not-found to import-untyped

Fixed 1 extra dependency error:

  1. Removed unused type ignore (1 error): In tools/path.py, removed import-not-found,no-redef ignores that became unnecessary when importlib_resources is installed

Variable coverage analysis:

Analysis of 58 unannotated variables shows all are correctly unannotated:

Category Count Reason
Instance variable reassignments 37 (63.8%) Would trigger mypy no-redef errors
Dictionary subscript operations 14 (24.1%) Cannot annotate dict[key] = value
Module variable reassignments 7 (12.1%) Would trigger mypy no-redef errors

Examples:

# Reassignment after initial annotation (correct - no annotation)
self.history: list[tuple[str, str]] = []  # First assignment
self.history = []  # Reassignment

# Dictionary subscript (correct - cannot annotate)
_dict: dict[str, str] = {}  # Declaration
_dict[key] = value  # Subscript operation

# Union type for flexible parameters
def __init__(self, model: Union[str, "KeyedVectors"], ...):  # Accepts both

# Numpy return type ignore (mypy cannot infer)
def _sigmoid(self, x: np.ndarray) -> np.ndarray:
    return 1 / (1 + np.exp(-x))  # type: ignore[no-any-return]

Documentation added:

  • build_tools/analysis/coverage-analysis.md - Complete breakdown of all 58 cases with file/line references, categorization, and references to PEP 484/526

Test coverage:

The codebase now has 100% appropriate type coverage with zero mypy errors across all dependency configurations:

  • Core tests: 114/114 passing
  • Core + Compact tests: 133/133 passing
  • Core + Compact + Extra tests: 165/165 passing
  • Mypy validation passes in all scenarios (no dependencies, compact dependencies, compact + extra dependencies)

Your checklist for this pull request

  • Passed code styles and structures
  • Passed code linting checks and unit test

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI assigned Copilot and bact Feb 4, 2026
@bact bact added the refactoring a technical improvement which does not add any new features or change existing features. label Feb 4, 2026
@github-actions

github-actions Bot commented Feb 4, 2026

Copy link
Copy Markdown

Hello @Copilot, thank you for submitting a PR! We will respond as soon as possible.

สวัสดี @Copilot ขอบคุณที่ส่ง PR เข้ามา เราจะตอบกลับให้เร็วที่สุดเท่าที่จะทำได้

Co-authored-by: bact <128572+bact@users.noreply.github.com>
Copilot AI changed the title [WIP] Scan codebase for type annotation correctness Fix 35 mypy type errors achieving zero type check failures Feb 4, 2026
Copilot AI requested a review from bact February 4, 2026 16:53
Co-authored-by: bact <128572+bact@users.noreply.github.com>
Copilot AI changed the title Fix 35 mypy type errors achieving zero type check failures Document variable type hint coverage analysis - 100% appropriate coverage achieved Feb 4, 2026
@bact bact added this to the 5.3 milestone Feb 4, 2026
@bact
bact requested a review from Copilot February 4, 2026 17:05
@coveralls

coveralls commented Feb 4, 2026

Copy link
Copy Markdown

Coverage Status

coverage: 64.786%. remained the same
when pulling 2cbacaf on copilot/verify-type-annotations
into 2e0acf8 on dev.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds documentation explaining why the type-hint analyzer reports ~95% variable coverage while the codebase is effectively “100% appropriately typed”, and adjusts a number of assignments/formatting patterns to align with Python typing rules (notably avoiding annotated reassignments that trigger no-redef).

Changes:

  • Added a variable-coverage analysis document describing the 58 “unannotated” cases and why they should remain unannotated.
  • Removed/reworked annotated reassignments (and reformatted long lines) so variables/attributes are annotated once and then reassigned without re-annotation.
  • Tightened a few typing-related details (e.g., str.maketrans table types, type: ignore codes on optional imports).

Reviewed changes

Copilot reviewed 44 out of 44 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
pythainlp/word_vector/core.py Removes annotated attribute reassignments inside load_wordvector() to avoid redundant redefinitions.
pythainlp/wangchanberta/core.py Formatting-only changes for long assignments and function signature wrapping.
pythainlp/util/wordtonum.py Wraps long expression for readability/formatting.
pythainlp/util/thai_lunar_date.py Formats long list literal for readability.
pythainlp/util/thai.py Wraps long constant expression for formatting consistency.
pythainlp/util/syllable.py Formatting + removes a redundant loop-variable annotation.
pythainlp/util/normalize.py Formats long regex compilation and function signature wrapping.
pythainlp/util/keyboard.py Updates maketrans table typing and adds casts to satisfy type checkers.
pythainlp/util/emojiconv.py Formats function signature and lambda expression in regex substitution.
pythainlp/util/digitconv.py Updates maketrans table typing and adds casts.
pythainlp/ulmfit/core.py Refines rule list typing and formats long expressions/assignments.
pythainlp/transliterate/thaig2p.py Wraps device initialization for formatting.
pythainlp/transliterate/thai2rom.py Wraps device init / long calls and method signatures for formatting.
pythainlp/transliterate/royin.py Removes annotated reassignments of _vowel_patterns and formats transformations.
pythainlp/transliterate/core.py Expands type: ignore codes for optional import to include import-not-found.
pythainlp/translate/zh_th.py Formats long transformer initialization assignments.
pythainlp/translate/tokenization_small100.py Wraps long class attributes, call sites, and signatures for formatting.
pythainlp/translate/th_fr.py Formats long transformer initialization assignments.
pythainlp/translate/small100.py Formats long model/tokenizer initialization assignments.
pythainlp/translate/en_th.py Removes annotated reassignment on .cuda() call (keeps the reassignment).
pythainlp/translate/core.py Removes Any usage in reassignments (keeps union-typed self.model) and drops unused import.
pythainlp/translate/init.py Formats __all__ list.
pythainlp/tools/path.py Expands type: ignore codes for optional import to include import-not-found.
pythainlp/tokenize/nlpo3.py Adds import-not-found ignore to one TYPE_CHECKING import and formats constants/errors.
pythainlp/tokenize/multi_cut.py Formats __new__ signature.
pythainlp/tokenize/han_solo.py Formats long assignment for readability.
pythainlp/tokenize/core.py Removes annotated reassignments for attributes already declared/typed.
pythainlp/tag/named_entity.py Formats long instantiation and method signature.
pythainlp/tag/crfchunk.py Formats long context-manager assignment.
pythainlp/spell/words_spelling_correction.py Formatting adjustments for long lines and signatures; minor whitespace normalization.
pythainlp/generate/core.py Formats a long dict comprehension assignment.
pythainlp/cli/init.py Removes annotated reassignment of sys.stdout/stderr and formats long lists.
pythainlp/classify/param_free.py Formats long numpy assignment.
pythainlp/chat/core.py Adds cast() around model output to ensure str and imports cast.
pythainlp/augment/wordnet.py Formats a long wordnet.synsets() call.
pythainlp/augment/word2vec/thai2fit.py Formats Word2VecAug instantiation.
pythainlp/augment/word2vec/ltw2v.py Formats Word2VecAug instantiation.
pythainlp/augment/word2vec/core.py Removes a type: ignore on assignment in the “model already loaded” branch and formats calls.
pythainlp/augment/word2vec/bpemb_wv.py Formats long assignment from augment().
pythainlp/augment/lm/wangchanberta.py Formats tokenizer initialization call.
pythainlp/augment/lm/phayathaibert.py Formats tokenizer/model initialization calls.
pythainlp/augment/lm/fasttext.py Formats model loading calls.
pythainlp/init.py Wraps long constant string for formatting.
build_tools/analysis/coverage-analysis.md Adds documentation explaining the 58 “unannotated variables” cases and why coverage is effectively 100%.

Comment thread pythainlp/augment/word2vec/core.py
Comment thread pythainlp/tokenize/nlpo3.py
Comment thread build_tools/analysis/coverage-analysis.md
Comment thread build_tools/analysis/coverage-analysis.md
@bact

bact commented Feb 4, 2026

Copy link
Copy Markdown
Member

@copilot apply changes based on the comments in this thread and review the variable type annotation reassignments of the entire codebase once again.

…uplicate annotations on reassignments

Co-authored-by: bact <128572+bact@users.noreply.github.com>

Copilot AI commented Feb 4, 2026

Copy link
Copy Markdown
Contributor Author

@copilot apply changes based on the comments in this thread and review the variable type annotation reassignments of th...

Completed in ea77ca3. Applied changes based on review comments:

  1. Fixed augment/word2vec/core.py - Changed model parameter to Union[str, "KeyedVectors"]
  2. Reviewed entire codebase and fixed 13 additional files with duplicate type annotations on reassignments
  3. Verified nlpo3 import structure is correct

All changes tested with mypy (0 errors), ruff (all checks pass), and full test suite (114/114 pass).

Copilot AI changed the title Document variable type hint coverage analysis - 100% appropriate coverage achieved Fix mypy type errors and achieve 100% appropriate type annotation coverage Feb 4, 2026
@bact
bact marked this pull request as ready for review February 4, 2026 17:26
@bact

bact commented Feb 4, 2026

Copy link
Copy Markdown
Member

@copilot run test with "compact" test suite and fix any remaining issues

…and remove unused type ignores

Co-authored-by: bact <128572+bact@users.noreply.github.com>

Copilot AI commented Feb 4, 2026

Copy link
Copy Markdown
Contributor Author

@copilot run test with "compact" test suite and fix any remaining issues

Completed in 931cbfb. Ran compact test suite with all dependencies installed. Fixed 15 mypy errors that only appear when numpy and other compact dependencies are present:

  • Removed 3 unused type: ignore comments in tokenize/nlpo3.py (no longer needed when nlpo3 is installed)
  • Added 11 # type: ignore[no-any-return] for numpy operations where mypy can't infer array types
  • Fixed umt5_thaig2p import to use import-untyped instead of import-not-found

All tests pass: 133/133 (core + compact), mypy: 0 errors, ruff: all checks passed.

@bact

bact commented Feb 4, 2026

Copy link
Copy Markdown
Member

@copilot run test with "extra" test suite and fix any remaining issues

… importlib_resources

Co-authored-by: bact <128572+bact@users.noreply.github.com>

Copilot AI commented Feb 4, 2026

Copy link
Copy Markdown
Contributor Author

@copilot run test with "extra" test suite and fix any remaining issues

Completed in 2cbacaf. Ran extra test suite with all dependencies installed (compact + extra). Fixed 1 mypy error:

  • Removed unused type: ignore in tools/path.py for importlib_resources (no longer needed when the package is installed)

All tests pass: 165/165 (core + compact + extra), mypy: 0 errors with all dependencies, ruff: all checks passed.

@sonarqubecloud

sonarqubecloud Bot commented Feb 4, 2026

Copy link
Copy Markdown

@bact
bact merged commit 59541d6 into dev Feb 4, 2026
31 of 32 checks passed
@bact
bact deleted the copilot/verify-type-annotations branch February 4, 2026 17:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

refactoring a technical improvement which does not add any new features or change existing features.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants