A CLI tool for generating type annotations.
Project description
Typewriter
Overview
Typewriter is a Python Typer CLI built on LibCST that normalizes None-related type annotations while preserving formatting and comments.
What it rewrites
Union[T, None]->Optional[T]Union[T1, T2, None]->Optional[Union[T1, T2]]x: T = None->x: Optional[T] = Nonedef f(x: T = None)->def f(x: Optional[T] = None)
Additional behavior:
Anyannotations are left unchanged (for example,x: Any = Nonestays unchanged).- Qualified typing references are preserved (for example,
typing.Union[...]->typing.Optional[...]). - When bare
Optional[...]is introduced, Typewriter addsfrom typing import Optionalwhen needed. Also, ifUnionis no longer needed, Typewriter removes the previously importedUnionfromtyping.
Directory scanning behavior
When you run against a directory, Typewriter recursively processes *.py files and skips common non-source folders such as .git, .venv, venv, __pycache__, build, and dist.
Installation
pip install py-typewriter-cli
Quick Start
Suppose you start with:
from typing import Any, Union
count: int = None
name: str = None
payload: Any = None
def greet(user_id: int = None, msg: Union[str, None] = None) -> Union[str, None]:
if user_id is None:
return None
return f"hello-{user_id}\n{msg}"
Preview changes:
typewriter run path/to/file.py --check
Apply changes:
typewriter run path/to/file.py
Result:
from typing import Optional, Any
count: Optional[int] = None
name: Optional[str] = None
payload: Any = None
def greet(user_id: Optional[int] = None, msg: Optional[str] = None) -> Optional[str]:
if user_id is None:
return None
return f"hello-{user_id}\n{msg}"
Run recursively on a directory:
typewriter run examples
CLI
Typewriter exposes one subcommand: run.
Transform a directory
Recursively transforms all *.py files under the directory.
typewriter run path/to/python_package_or_repo
Transform a single file
typewriter run path/to/python_file.py
Non-.py files are rejected.
Check mode (no writes)
Use --check to see what would change without writing files.
typewriter run path/to/python_dir --check
typewriter run path/to/python_file.py --check
In --check mode, Typewriter prints a unified diff for each file that would change:
Would transform path/to/python_file.py
--- path/to/python_file.py
+++ path/to/python_file.py
@@ ...
-old line
+new line
Exit codes for --check:
0: no changes needed1: changes would be made2: error
Transform an in-memory string
Use --code to transform a string and print the transformed code to stdout (no files are written).
typewriter run --code "var: int = None\\n"
--code is mutually exclusive with PATH. In --check mode, this reports whether the provided code would change:
typewriter run --code "var: int = None\\n" --check
When changes are needed, --check also prints a unified diff labeled provided.
Notes:
PATHand--codeare mutually exclusive.- Literal
\\nsequences in--codeinput are interpreted as newlines.
Motivation
This project was created to resolve issue #2303 in microsoft/playwright-python.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file py_typewriter_cli-0.1.0.tar.gz.
File metadata
- Download URL: py_typewriter_cli-0.1.0.tar.gz
- Upload date:
- Size: 11.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
37e14c611edc58b817e28927cf041c436da3ccf1ea26fa4a6aa34a6ec1b7d53d
|
|
| MD5 |
d40b132c337437d7731582238b0520dd
|
|
| BLAKE2b-256 |
abadc7a0b7236bb4fac85c13baf28f7359945d21b1137445e516de38d201f7be
|
File details
Details for the file py_typewriter_cli-0.1.0-py3-none-any.whl.
File metadata
- Download URL: py_typewriter_cli-0.1.0-py3-none-any.whl
- Upload date:
- Size: 10.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f40ce352a7919c0488e3b22b4ca8e7c9f4db770cc52e318c07096d8ed18a3eb3
|
|
| MD5 |
664a4cd415cc80b52843062cc0346a5a
|
|
| BLAKE2b-256 |
fd9a42e61910eee87103630e434e902461cca5ccfd5d2c73242012b2ea095ab8
|