Skip to content

feat: fix version handling, expand PEP 604 mode, add configurable skips and gitignore support#5

Merged
danphenderson merged 13 commits into
mainfrom
copilot/improve-version-handling
Mar 21, 2026
Merged

feat: fix version handling, expand PEP 604 mode, add configurable skips and gitignore support#5
danphenderson merged 13 commits into
mainfrom
copilot/improve-version-handling

Conversation

Copilot AI commented Mar 20, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR now includes the original version-handling and import-cleanup fixes, plus the remaining follow-ups requested in review.

Changes Made

Version handling and docs version sourcing

  • Fixes typewriter.__version__ to read the correct distribution name: py-typewriter-cli
  • Adds a fallback to pyproject.toml when distribution metadata is unavailable in source-checkout/dev contexts
  • Restores Python 3.10 compatibility for source-checkout/dev version fallback by loading tomllib when available and falling back to tomli
  • Removes the hard-coded Sphinx version and derives docs version info from typewriter.__version__

Expanded PEP 604 mode

--target-version 3.10 now normalizes more existing typing forms, not just None-containing unions:

  • Union[T, None] -> T | None
  • Optional[T] -> T | None
  • Union[T1, T2] -> T1 | T2
  • Union[T1, T2, None] -> T1 | T2 | None

Default output remains Python 3.9-compatible when --target-version is not provided.

Configurable skips and gitignore support

  • Keeps repeatable --ignore glob patterns for additional file/directory skips
  • Adds --respect-gitignore to honor the nearest .gitignore at or above the scanned directory
  • Preserves the built-in default skip set (.git, .venv, __pycache__, build, dist, etc.)

Import cleanup and naming polish

  • Keeps generalized cleanup for stale typing imports
  • Removes now-unused Optional and Union imports after broader PEP 604 rewrites
  • Renames the misspelled transformer to EnforceOptionalNoneTypes
  • Preserves backward compatibility with a deprecated wrapper for EnforceOptionallNoneTypes

Testing

  • Added regression coverage for:
    • source-checkout version fallback
    • Python 3.10 tomllib/tomli fallback behavior
    • inference-only Optional cleanup in PEP 604 mode
    • Optional[...] and plain Union[...] normalization in PEP 604 mode
    • --respect-gitignore
    • parent .gitignore handling
    • deprecated transformer compatibility behavior
  • Full test suite passes: 96 passed
  • Automated code review completed with no remaining comments
  • CodeQL scan completed with 0 alerts

CI Note

The failing CI jobs were investigated and traced to two separate issues:

  • lint drift (black / flake8 / autoflake), which was corrected
  • Python 3.10 test collection failures caused by an unconditional tomllib import, which was fixed with a tomli fallback

The branch has been updated to address both.


💬 Send tasks to Copilot coding agent from Slack and Teams to turn conversations into code. Copilot posts an update in your thread when it's finished.

Copilot AI and others added 3 commits March 20, 2026 20:13
…alized import cleanup

Co-authored-by: danphenderson <77417639+danphenderson@users.noreply.github.com>
Agent-Logs-Url: https://github.com/danphenderson/python-typewriter/sessions/a5a6da81-2e47-4d6a-b32a-0be87fd3ccca
…port cleanup; update docs

Co-authored-by: danphenderson <77417639+danphenderson@users.noreply.github.com>
Agent-Logs-Url: https://github.com/danphenderson/python-typewriter/sessions/a5a6da81-2e47-4d6a-b32a-0be87fd3ccca
@danphenderson

Copy link
Copy Markdown
Owner

@copilot Please perform a thorough code review of the currently checked out branch for PR #171.

Use the PR description above as context, but review the actual code diff and impacted files rather than relying on the summary alone.

Copilot AI and others added 4 commits March 20, 2026 20:48
Co-authored-by: danphenderson <77417639+danphenderson@users.noreply.github.com>
Agent-Logs-Url: https://github.com/danphenderson/python-typewriter/sessions/6e88a308-9414-4580-a35d-d5fd4e0ce847
Co-authored-by: danphenderson <77417639+danphenderson@users.noreply.github.com>
Agent-Logs-Url: https://github.com/danphenderson/python-typewriter/sessions/6e88a308-9414-4580-a35d-d5fd4e0ce847

Copilot AI commented Mar 20, 2026

Copy link
Copy Markdown
Contributor Author

@copilot Please perform a thorough code review of the currently checked out branch for PR #171.

Use the PR description above as context, but review the actual code diff and impacted files r...

I reviewed the checked-out branch diff against main, found and fixed two follow-up issues, and re-ran validation. The main fixes are in e058ee8 (source-checkout version fallback via pyproject.toml and PEP 604 inference-only Optional import cleanup), with final polish in 28b8add. Current status: 88 passed and CodeQL reports 0 alerts.

@danphenderson

Copy link
Copy Markdown
Owner

This looks solid and addresses the core issues.

Most importantly, it fixes version resolution correctly by using the real distribution name (py-typewriter-cli) and adds a reasonable fallback for source-checkout/dev contexts. It also removes the hard-coded Sphinx version and makes docs derive version info from the package itself.

I also like the added regression coverage and the broader cleanup:

  • --target-version / PEP 604 mode
  • repeatable --ignore
  • generalized cleanup for stale typing imports

Remaining follow-ups are mostly polish:

  • --respect-gitignore is still missing
  • typing-style normalization is still narrow
  • EnforceOptionallNoneTypes still has the spelling typo

Overall, though, this addresses the important fixes.

@copilot can you resolve the remaining follow-ups and fix the failing CI job.

Copilot AI and others added 4 commits March 21, 2026 00:49
Co-authored-by: danphenderson <77417639+danphenderson@users.noreply.github.com>
Agent-Logs-Url: https://github.com/danphenderson/python-typewriter/sessions/6716eb52-f4e5-46be-9433-3955cce0b6c6
Co-authored-by: danphenderson <77417639+danphenderson@users.noreply.github.com>
Agent-Logs-Url: https://github.com/danphenderson/python-typewriter/sessions/6716eb52-f4e5-46be-9433-3955cce0b6c6

Copilot AI commented Mar 21, 2026

Copy link
Copy Markdown
Contributor Author

This looks solid and addresses the core issues.

Most importantly, it fixes version resolution correctly by using the real distribution name (py-typewriter-cli) and adds a reasonable fallback for ...

Addressed in 372b0a0 with final polish through 356e8aa. Added --respect-gitignore, broadened PEP 604 normalization to cover existing Optional[...] and plain Union[...], introduced the correctly spelled EnforceOptionalNoneTypes with a deprecated compatibility wrapper, and fixed the CI lint failures that were coming from Black/flake8 drift. Validation is green locally with 95 passed, final automated review found no comments, and CodeQL reports 0 alerts.

Copilot AI changed the title feat: fix version handling, add PEP 604 mode, configurable skips, generalized import cleanup feat: fix version handling, expand PEP 604 mode, add configurable skips and gitignore support Mar 21, 2026
Copilot AI requested a review from danphenderson March 21, 2026 00:54
@codecov-commenter

Copy link
Copy Markdown

Welcome to Codecov 🎉

Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests.

Thanks for integrating Codecov - We've got you covered ☂️

@danphenderson

Copy link
Copy Markdown
Owner

@copilot there is still two failing CI jobs. For example,

Run python -m pip install -e '.[tests]' --upgrade
Obtaining file:///Users/runner/work/python-typewriter/python-typewriter
  Installing build dependencies: started
  Installing build dependencies: finished with status 'done'
  Checking if build backend supports build_editable: started
  Checking if build backend supports build_editable: finished with status 'done'
  Getting requirements to build editable: started
  Getting requirements to build editable: finished with status 'done'
  Preparing editable metadata (pyproject.toml): started
  Preparing editable metadata (pyproject.toml): finished with status 'done'
Collecting libcst==1.1.0 (from py-typewriter-cli==1.0.0)
  Downloading libcst-1.1.0-cp310-cp310-macosx_11_0_arm64.whl.metadata (17 kB)
Collecting pathspec==1.0.4 (from py-typewriter-cli==1.0.0)
  Downloading pathspec-1.0.4-py3-none-any.whl.metadata (13 kB)
Collecting typer==0.24.1 (from py-typewriter-cli==1.0.0)
  Downloading typer-0.24.1-py3-none-any.whl.metadata (16 kB)
Collecting coverage[toml] (from py-typewriter-cli==1.0.0)
  Downloading coverage-7.13.5-cp310-cp310-macosx_11_0_arm64.whl.metadata (8.5 kB)
Collecting exceptiongroup (from py-typewriter-cli==1.0.0)
  Downloading exceptiongroup-1.3.1-py3-none-any.whl.metadata (6.7 kB)
Collecting pytest (from py-typewriter-cli==1.0.0)
  Downloading pytest-9.0.2-py3-none-any.whl.metadata (7.6 kB)
Collecting pytest-cov (from py-typewriter-cli==1.0.0)
  Downloading pytest_cov-7.0.0-py3-none-any.whl.metadata (31 kB)
Collecting tomli (from py-typewriter-cli==1.0.0)
  Downloading tomli-2.4.0-py3-none-any.whl.metadata (10 kB)
Collecting typing-extensions>=3.7.4.2 (from libcst==1.1.0->py-typewriter-cli==1.0.0)
  Downloading typing_extensions-4.15.0-py3-none-any.whl.metadata (3.3 kB)
Collecting typing-inspect>=0.4.0 (from libcst==1.1.0->py-typewriter-cli==1.0.0)
  Downloading typing_inspect-0.9.0-py3-none-any.whl.metadata (1.5 kB)
Collecting pyyaml>=5.2 (from libcst==1.1.0->py-typewriter-cli==1.0.0)
  Downloading pyyaml-6.0.3-cp310-cp310-macosx_11_0_arm64.whl.metadata (2.4 kB)
Collecting click>=8.2.1 (from typer==0.24.1->py-typewriter-cli==1.0.0)
  Downloading click-8.3.1-py3-none-any.whl.metadata (2.6 kB)
Collecting shellingham>=1.3.0 (from typer==0.24.1->py-typewriter-cli==1.0.0)
  Downloading shellingham-1.5.4-py2.py3-none-any.whl.metadata (3.5 kB)
Collecting rich>=12.3.0 (from typer==0.24.1->py-typewriter-cli==1.0.0)
  Downloading rich-14.3.3-py3-none-any.whl.metadata (18 kB)
Collecting annotated-doc>=0.0.2 (from typer==0.24.1->py-typewriter-cli==1.0.0)
  Downloading annotated_doc-0.0.4-py3-none-any.whl.metadata (6.6 kB)
Collecting markdown-it-py>=2.2.0 (from rich>=12.3.0->typer==0.24.1->py-typewriter-cli==1.0.0)
  Downloading markdown_it_py-4.0.0-py3-none-any.whl.metadata (7.3 kB)
Collecting pygments<3.0.0,>=2.13.0 (from rich>=12.3.0->typer==0.24.1->py-typewriter-cli==1.0.0)
  Downloading pygments-2.19.2-py3-none-any.whl.metadata (2.5 kB)
Collecting mdurl~=0.1 (from markdown-it-py>=2.2.0->rich>=12.3.0->typer==0.24.1->py-typewriter-cli==1.0.0)
  Downloading mdurl-0.1.2-py3-none-any.whl.metadata (1.6 kB)
Collecting mypy-extensions>=0.3.0 (from typing-inspect>=0.4.0->libcst==1.1.0->py-typewriter-cli==1.0.0)
  Downloading mypy_extensions-1.1.0-py3-none-any.whl.metadata (1.1 kB)
Collecting iniconfig>=1.0.1 (from pytest->py-typewriter-cli==1.0.0)
  Downloading iniconfig-2.3.0-py3-none-any.whl.metadata (2.5 kB)
Requirement already satisfied: packaging>=22 in /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages (from pytest->py-typewriter-cli==1.0.0) (26.0)
Collecting pluggy<2,>=1.5 (from pytest->py-typewriter-cli==1.0.0)
  Downloading pluggy-1.6.0-py3-none-any.whl.metadata (4.8 kB)
Downloading libcst-1.1.0-cp310-cp310-macosx_11_0_arm64.whl (2.1 MB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.1/2.1 MB 16.4 MB/s  0:00:00
Downloading pathspec-1.0.4-py3-none-any.whl (55 kB)
Downloading typer-0.24.1-py3-none-any.whl (56 kB)
Downloading annotated_doc-0.0.4-py3-none-any.whl (5.3 kB)
Downloading click-8.3.1-py3-none-any.whl (108 kB)
Downloading pyyaml-6.0.3-cp310-cp310-macosx_11_0_arm64.whl (174 kB)
Downloading rich-14.3.3-py3-none-any.whl (310 kB)
Downloading pygments-2.19.2-py3-none-any.whl (1.2 MB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.2/1.2 MB 92.9 MB/s  0:00:00
Downloading markdown_it_py-4.0.0-py3-none-any.whl (87 kB)
Downloading mdurl-0.1.2-py3-none-any.whl (10.0 kB)
Downloading shellingham-1.5.4-py2.py3-none-any.whl (9.8 kB)
Downloading typing_extensions-4.15.0-py3-none-any.whl (44 kB)
Downloading typing_inspect-0.9.0-py3-none-any.whl (8.8 kB)
Downloading mypy_extensions-1.1.0-py3-none-any.whl (5.0 kB)
Downloading coverage-7.13.5-cp310-cp310-macosx_11_0_arm64.whl (219 kB)
Downloading exceptiongroup-1.3.1-py3-none-any.whl (16 kB)
Downloading pytest-9.0.2-py3-none-any.whl (374 kB)
Downloading pluggy-1.6.0-py3-none-any.whl (20 kB)
Downloading iniconfig-2.3.0-py3-none-any.whl (7.5 kB)
Downloading tomli-2.4.0-py3-none-any.whl (14 kB)
Downloading pytest_cov-7.0.0-py3-none-any.whl (22 kB)
Building wheels for collected packages: py-typewriter-cli
  Building editable for py-typewriter-cli (pyproject.toml): started
  Building editable for py-typewriter-cli (pyproject.toml): finished with status 'done'
  Created wheel for py-typewriter-cli: filename=py_typewriter_cli-1.0.0-0.editable-py3-none-any.whl size=7105 sha256=c45d81421229fa96d9de8e84676e76d6d3084cc868076a485c5408197d1afdc4
  Stored in directory: /private/var/folders/t5/f77_gwnj6p95qxy9py3fckx00000gn/T/pip-ephem-wheel-cache-wj18oi5e/wheels/19/c0/3e/7b10c70e3e2c3df3fdbb23bc2cac0cf21704e84b9f2d9f3457
Successfully built py-typewriter-cli
Installing collected packages: typing-extensions, tomli, shellingham, pyyaml, pygments, pluggy, pathspec, mypy-extensions, mdurl, iniconfig, coverage, click, annotated-doc, typing-inspect, markdown-it-py, exceptiongroup, rich, pytest, libcst, typer, pytest-cov, py-typewriter-cli

Successfully installed annotated-doc-0.0.4 click-8.3.1 coverage-7.13.5 exceptiongroup-1.3.1 iniconfig-2.3.0 libcst-1.1.0 markdown-it-py-4.0.0 mdurl-0.1.2 mypy-extensions-1.1.0 pathspec-1.0.4 pluggy-1.6.0 py-typewriter-cli-1.0.0 pygments-2.19.2 pytest-9.0.2 pytest-cov-7.0.0 pyyaml-6.0.3 rich-14.3.3 shellingham-1.5.4 tomli-2.4.0 typer-0.24.1 typing-extensions-4.15.0 typing-inspect-0.9.0
============================= test session starts ==============================
platform darwin -- Python 3.10.11, pytest-9.0.2, pluggy-1.6.0
rootdir: /Users/runner/work/python-typewriter/python-typewriter
configfile: pyproject.toml
testpaths: tests
plugins: cov-7.0.0
collected 0 items / 4 errors

==================================== ERRORS ====================================
______________________ ERROR collecting tests/test_cli.py ______________________
ImportError while importing test module '/Users/runner/work/python-typewriter/python-typewriter/tests/test_cli.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/importlib/__init__.py:126: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
tests/test_cli.py:3: in <module>
    from typewriter.cli import app
typewriter/__init__.py:4: in <module>
    import tomllib
E   ModuleNotFoundError: No module named 'tomllib'
______________________ ERROR collecting tests/test_cli.py ______________________
ImportError while importing test module '/Users/runner/work/python-typewriter/python-typewriter/tests/test_cli.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/importlib/__init__.py:126: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
tests/test_cli.py:3: in <module>
    from typewriter.cli import app
typewriter/__init__.py:4: in <module>
    import tomllib
E   ModuleNotFoundError: No module named 'tomllib'
____________________ ERROR collecting tests/test_codegen.py ____________________
ImportError while importing test module '/Users/runner/work/python-typewriter/python-typewriter/tests/test_codegen.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/importlib/__init__.py:126: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
tests/test_codegen.py:3: in <module>
    from typewriter.codemod import (
typewriter/__init__.py:4: in <module>
    import tomllib
E   ModuleNotFoundError: No module named 'tomllib'
____________________ ERROR collecting tests/test_codegen.py ____________________
ImportError while importing test module '/Users/runner/work/python-typewriter/python-typewriter/tests/test_codegen.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/importlib/__init__.py:126: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
tests/test_codegen.py:3: in <module>
    from typewriter.codemod import (
typewriter/__init__.py:4: in <module>
    import tomllib
E   ModuleNotFoundError: No module named 'tomllib'
- generated xml file: /Users/runner/work/python-typewriter/python-typewriter/junit.xml -
=========================== short test summary info ============================
ERROR tests/test_cli.py
ERROR tests/test_cli.py
ERROR tests/test_codegen.py
ERROR tests/test_codegen.py
!!!!!!!!!!!!!!!!!!! Interrupted: 4 errors during collection !!!!!!!!!!!!!!!!!!!!
============================== 4 errors in 0.35s ===============================
Error: Process completed with exit code 2.

Please ensure it works for all CI jobs.

Copilot AI and others added 2 commits March 21, 2026 01:04
Co-authored-by: danphenderson <77417639+danphenderson@users.noreply.github.com>
Agent-Logs-Url: https://github.com/danphenderson/python-typewriter/sessions/f3f50c57-7d3f-43b9-86b6-f1de8caf6da4

Copilot AI commented Mar 21, 2026

Copy link
Copy Markdown
Contributor Author

@copilot there is still two failing CI jobs. For example,

...

Fixed in e79762d, polished in ed6e121. The remaining failures were the Ubuntu/macOS Python 3.10 jobs: typewriter/__init__.py was importing tomllib unconditionally, so test collection failed before running any tests. I switched the source-checkout version fallback to load tomllib when available and fall back to tomli, added a regression test for that path, and revalidated with 96 passed, final code review clean, and CodeQL still at 0 alerts.

@danphenderson
danphenderson marked this pull request as ready for review March 21, 2026 01:21
@danphenderson
danphenderson merged commit aa2cc80 into main Mar 21, 2026
11 checks passed
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.

3 participants