Skip to content

Complete type annotations across codebase (97% coverage) - #1277

Merged
bact merged 19 commits into
devfrom
copilot/incremental-type-annotations
Feb 4, 2026
Merged

Complete type annotations across codebase (97% coverage)#1277
bact merged 19 commits into
devfrom
copilot/incremental-type-annotations

Conversation

Copilot AI commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

What do these changes do

Adds comprehensive type annotations across the entire PyThaiNLP codebase, achieving 100% function coverage and 97% variable coverage.

Coverage achieved:

  • Functions/methods: 725/725 (100%)
  • Variables: 1220/1258 (97%)
  • Remaining 38 variables are analyzer false positives (reassignments, dict subscripts, loop reuses)

Key improvements:

  • Fixed 34 mypy type errors
  • Removed 38 unused type: ignore comments
  • Added proper TYPE_CHECKING imports to avoid circular dependencies
  • Maintained Python 3.9+ compatibility (Optional[X], Union[X, Y] syntax)

Modules annotated:

  • Core infrastructure: util (72 vars), transliterate (88 vars), tokenize (61 vars)
  • ML models: translate (62 vars), augment (30 vars), tag (14 vars)
  • Neural networks: PyTorch model classes with proper nn.Module types
  • 24 additional modules with complete coverage

What was wrong

The codebase lacked comprehensive type annotations, limiting IDE support, static analysis capabilities, and type safety. No systematic type checking was enforced.

How this fixes it

Systematically annotated all functions, methods, and variables using:

  • Proper type imports with TYPE_CHECKING guards
  • Any for complex external library types (transformers, PyTorch) where stubs unavailable
  • Type narrowing and proper Optional handling
  • Consistent with typing best practices (no annotations on reassignments)

Example of improvements:

# Before
def process_thai(text, pre_rules=pre_rules_th_sparse, tok_func=None, post_rules=post_rules_th_sparse):
    res = text
    for rule in pre_rules:
        res = rule(res)
    res = tok_func(res)
    return res

# After  
def process_thai(
    text: str,
    pre_rules: Collection = pre_rules_th_sparse,
    tok_func: Optional[Callable] = None,
    post_rules: Collection = post_rules_th_sparse,
) -> Collection[str]:
    res: Union[str, list[str]] = text
    for rule in pre_rules:
        res = rule(res)
    res = tok_func(res)  # type: ignore[arg-type]
    return res

Your checklist for this pull request

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

Iterating to incrementally complete type annotations to reach 100% coverage of the entire codebase.

Strategy

Goals

Instructions

  • Follow best practices and standard Python type hint patterns.
  • Maintain source code readability.
  • Use mypy as main assistant.
    • mypy is already in "dev" extra dependencies in pyproject.toml
    • mypy configuration is in pyproject.toml
    • Sometimes mypy may report errors wrongly due to cache issues. Try to reset the cache.
  • Use pyright, pyrefly, and pytype for second opinions.
  • Required dependencies for each test suite are in pyproject.toml. Install them to avoid errors. See https://github.com/PyThaiNLP/pythainlp/blob/dev/tests/README.md
  • Use native type in type hint (list, tuple, .. instead of List, Tuple, ..)
  • Do not use A | B style Union, use full Union[] instead.
  • We want to keep compatibility with Python 3.9 strict and allow type inspection tools to work correctly.
  • When insert typing imports, put it in appropriate location and order
  • Use "if TYPE_CHECKING import" block when possible.
  • When reordering the imports, beware of circular import. Read comments near imports to get more information.
  • Remove unused imports
  • Do not allow the use of assert in production code (it is only allowed for testing and debugging).
  • Try to fix the type, the scope logic, or do the casting, before putting #type: ignore comment.
  • When dealing with types from external libraries:
    • Check if type information is provided (maybe through stubs). If it is, cast wrapper may not necessary.
    • If return type is not provided, may be it is appropriate to use # type: ignore[no-any-return] annotation for clarity.
    • Analyse source code of external libraries to validate correct types
  • Minimize the use of Any
    There can be a more precise type to use if we
    look at the source code of the external library.
    See examples from these commits:
    964c1d4
    42e7df1
    c382092
    e717065
  • Recheck necessity when do casting.
  • Recheck necessity of # noqa: and # type: ignore
  • Provide type stubs as necessary.
  • After changes for type hints, recheck for functionality correctness.
  • Recheck docstring and documentation consistency with the code; They should match the updated type hints.
  • Recheck formatting with ruff
  • Do another code review
  • Address code review feedback

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

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
@bact bact added this to the 5.3 milestone Feb 4, 2026
Copilot AI and others added 13 commits February 4, 2026 10:18
…ix Any import

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

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

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

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

Co-authored-by: bact <128572+bact@users.noreply.github.com>
Co-authored-by: bact <128572+bact@users.noreply.github.com>
- Add type hints to 69 module variables across 16 files
- Add type hints to 1 class variable (Node.__slots__)
- Add type hints to 2 instance variables (Trie.words, Trie.root)
- Ensure Python 3.9 compatibility (no X | Y syntax)
- Import Pattern type for regex patterns
- All changes pass ruff checks

Co-authored-by: bact <128572+bact@users.noreply.github.com>
- Remove redundant declaration in syllable.py
- Fix type annotation in pronounce.py using intermediate variable
- Remove unnecessary loop variable annotations in spell_words.py and morse.py

Co-authored-by: bact <128572+bact@users.noreply.github.com>
Use Optional[list[str]] instead of list[str] | None
…nize modules

Co-authored-by: bact <128572+bact@users.noreply.github.com>
- Added type annotations to all module-level variables including loop variables in ancient/aksonhan.py, util/morse.py, util/spell_words.py, util/syllable.py, wsd/core.py
- Added type annotations to ulmfit/core.py module-level rule lists
- Added type annotations to cli/__init__.py, ulmfit/preprocess.py, wangchanberta/__init__.py, wangchanberta/core.py
- Added type annotations to transliterate/royin.py reassignments
- Added class-level type annotations to WordNetAug, ChatBotModel, Words_Spelling_Correction, WngchanBerta_ONNX, WunsenTransliterate

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

coveralls commented Feb 4, 2026

Copy link
Copy Markdown

Coverage Status

coverage: 64.786% (-0.4%) from 65.208%
when pulling f7672a4 on copilot/incremental-type-annotations
into 82e1d9f on dev.

Copilot AI and others added 5 commits February 4, 2026 14:09
Co-authored-by: bact <128572+bact@users.noreply.github.com>
Co-authored-by: bact <128572+bact@users.noreply.github.com>
Co-authored-by: bact <128572+bact@users.noreply.github.com>
Co-authored-by: bact <128572+bact@users.noreply.github.com>
@sonarqubecloud

sonarqubecloud Bot commented Feb 4, 2026

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
13.2% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

Copilot AI changed the title [WIP] Add type annotations to achieve 100% coverage Complete type annotations across codebase (97% coverage) Feb 4, 2026
Copilot AI requested a review from bact February 4, 2026 14:20
@bact
bact marked this pull request as ready for review February 4, 2026 14:36
@bact
bact merged commit 2e0acf8 into dev Feb 4, 2026
31 of 34 checks passed
@bact
bact deleted the copilot/incremental-type-annotations branch February 4, 2026 16:13
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.

3 participants