Skip to content

Add partial bundled type stubs - #115

Open
heejaechang wants to merge 2 commits into
dbcli:mainfrom
heejaechang:heejaechang-add-complete-bundled-stubs
Open

Add partial bundled type stubs#115
heejaechang wants to merge 2 commits into
dbcli:mainfrom
heejaechang:heejaechang-add-complete-bundled-stubs

Conversation

@heejaechang

@heejaechang heejaechang commented Jul 28, 2026

Copy link
Copy Markdown

Summary

  • ship py.typed and complete sidecar stubs for seven self-contained modules: compat, utils, preprocessors, and the CSV/JSON/TSV/vertical adapters
  • preserve the exact 115-export runtime API and leave every runtime .py file unchanged
  • intentionally leave config.py, tabulate_adapter.py, output_formatter.py, and the aggregate tabular_output module unstubbed because their complete surfaces close over the real untyped ConfigObj identity or mutated/private tabulate state

Type completeness

Fresh installed-wheel pyright --verifytypes cli_helpers --outputjson, unfiltered (ignoreUnknownTypesFromImports=false) and without types-Pygments:

Known Ambiguous Unknown Score
Baseline 16 17 82 13.91%
This PR 69 11 35 60.00%

All 54 exports in the seven touched modules are known. The 115-name export set is unchanged and no previously known export regresses.

Validation

  • exact touched-module public-name, positional signature/default-presence, class, field, and inheritance parity; explicit keyword-only refinements are limited to kwargs consumed by the runtime adapters, while arbitrary ignored kwargs remain accepted
  • strict installed-wheel Pyright and mypy positive consumers pass at Python 3.10; malformed format names, data, CSV/vertical adapter options, column marker classes, separators, non-float encoder return assumptions, and all four invalid preprocessor protocol implementations are rejected by both
  • unflagged mypy.stubtest passes for the independently loadable top-level touched modules; nested/full stubtest reaches the intentionally unstubbed aggregate and remains blocked by tabulate's private _table_formats mutation and the untyped aggregate formatter registry rather than being suppressed
  • 89 tests pass / 3 skip with Pygments; 84 pass / 8 skip without Pygments
  • Python 3.6-target Pyright check passes for every added stub
  • runtime checks cover lazy row consumption, header/data relationships, invalid formats, accepted and ignored CSV/vertical adapter kwargs, finite column marker behavior, JSON Decimal encoding, mutable writer copy/deepcopy/pickle behavior, and utility contracts
  • wheel and sdist build, modern Twine checks, check-manifest, and setup.py check pass; both archives contain exactly the marker plus seven stubs, and the wheel contains no tests
  • policy scan finds no Any, casts, ignores, checker suppressions, noqa, or allowlists in authored typing artifacts or fixtures

Clean-main limitations were reproduced unchanged: Coverage 4.3 and Sphinx 1.5 fail on Python 3.12 regex handling, tox 2.7 and Twine 1.12 fail with current setuptools because pkg_resources is absent, and current Black reports the same 10 pre-existing files. Python 3.6/3.7 and GNU make were unavailable on this Windows host; Python 3.9 cannot resolve tabulate 0.10 because tabulate now requires Python 3.10+.

Ship complete sidecar stubs for self-contained modules while leaving ConfigObj- and tabulate-bound modules untouched.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@rolandwalker

Copy link
Copy Markdown
Contributor

Hi! This looks neat, but I'm unsure about merging until cli_helpers is brought up to a minimum of Python 3.10, and all dbcli projects are on the newer cli_helpers.

Do you have any thoughts about that?

@heejaechang

heejaechang commented Jul 28, 2026

Copy link
Copy Markdown
Author

Thanks — I checked this against the published metadata and the current dbcli consumers.

The marker and sidecars do not impose a runtime Python 3.10 requirement: .pyi and py.typed are package data and are not imported or executed by Python. Pyright accepts all added stubs with pythonVersion=3.6.

However, I would not publish this change while cli_helpers still declares Python >=3.6. A checker that itself supports Python 3.6 (mypy 0.971 with --python-version 3.6) rejects the Literal imports from stdlib typing, which only provides Literal from Python 3.8 onward. Making the stubs checker-compatible with the declared floor would require a conditional typing_extensions dependency/import; weakening the literal contracts would lose useful validation. That extra compatibility work does not seem worthwhile because cli_helpers 2.15.1 is already effectively Python 3.10+: it requires tabulate ~=0.10.0, whose published Requires-Python is >=3.10, and json_output_adapter uses zip(..., strict=True). The package metadata still says >=3.6, so that is already stale independently of this PR.

The downstream state is mixed:

  • mycli, pgcli, and litecli current main all declare Python >=3.10; their cli_helpers constraints are respectively ~=2.15.1, >=2.4.0, and >=2.2.1.
  • athenacli still advertises Python 3.6–3.8 and uses cli_helpers[styles]>=1.1.0.
  • mssql-cli still advertises Python 2.7 and 3.5–3.9 and selects cli_helpers[styles]>=2.0.0 for Python 3.

So I agree that the release containing this PR should be coordinated with correcting cli_helpers to a 3.10 floor and deciding what to do with the legacy consumers. Merging earlier would not itself change any installed package or force a downstream upgrade, so whether to wait on the merge as well is a maintainer release-workflow choice. I have not changed the PR: once the declared floor is 3.10, these stubs need no compatibility adjustment.

Type the consumed CSV and vertical adapter options, constrain formatter column markers to the runtime set, and expose the JSON encoder's successful float result.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
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.

2 participants