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 in Python source code. It can be used to automatically rewrite type annotations to use Optional instead of Union when None is involved, and to ensure Optional is used for variable and parameter annotations when the default value is None.
What it rewrites:
Union[T, None] -> Optional[T]
Union[T1, T2, None] -> Optional[Union[T1, T2]]
x: T = None -> x: Optional[T] = None
def f(x: T = None) -> def f(x: Optional[T] = None)
Additional notes:
x: Any = Nonestays unchanged.- Qualified typing references are preserved.
- Import statements are added as needed and deduplicated.
Quick Start
Installation for PyPI
pip install py-typewriter-cli # Python 3.10-3.13
Usage
Typewriter exposes one subcommand: run.
Consider example.py with contents:
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}"
To see what would change without writing files, run with --check:
typewriter run path/to/example.py --check
Would transform path/to/example.py
--- path/to/example.py
+++ path/to/example.py
@@ ...
-old line
+new line
In --check mode, Typewriter prints a unified diff of its proposed changes to stdout and provides the following Exit codes:
0: no changes needed1: changes would be made2: error
To apply the detected changes, run without --check:
typewriter run path/to/example.py
Additional features:
To run recursively on all *.py files in a directory:
typewriter run examples # Non-`.py` files are rejected.
To transform an in-memory string and return the result to stdout, use --code:
typewriter run --code "var: int = None\\n"
Additional Details:
PATHand--codeare mutually exclusive.- Literal
\\nsequences in--codeinput are interpreted as newlines. - When a directory is provided as
PATH, Typewriter will ignore non-.pyfiles and common non-source subdirectories such as.git,.venv,venv,__pycache__,build, anddist. - We ignore the more recent
PEP 604syntax ofT | Nonesince it is not supported in Python 3.9, which is currently supported bymicrosoft/playwright-pythonand the ecosystem. However, support for this syntax may be added in the future.
Motivation
Typewriter was created to resolve issue #2303 in microsoft/playwright-python.
The issue highlighted a common inconsistency in the codebase where type annotations involving None were not standardized, leading to confusion and maintenance challenges. Specifically, some type annotations used Union[T, None] while others used Optional[T], and there were cases where variable and parameter annotations did not use Optional even when the default value was None. This made it difficult to maintain a consistent style and to leverage static analysis tools effectively.
Surely, other developers have encountered similar inconsistencies in their codebases, and Typewriter can be a useful tool for anyone looking to standardize a common inconsistency and correct a common issue related to the use of None in type annotations. By using Typewriter,
developers can ensure that their codebase adheres to PEP 484 proposal of requiring optional types to be made explicit.
Contributing
Contributions to Typewriter are welcome! Please follow the fork-and-pull request workflow:
- Fork the repository and create a new branch for your feature or bug fix.
- Make your changes and commit them with clear messages.
- Push your branch to your fork and open a pull request against the
mainbranch of the original repository.
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-1.0.0.tar.gz.
File metadata
- Download URL: py_typewriter_cli-1.0.0.tar.gz
- Upload date:
- Size: 11.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1ff9a6740bc7f1e53e1ba96956b312fb5af77b62b3b12b873dd61be9dd968cc8
|
|
| MD5 |
33aa613658fceb83cb649e2041853fb7
|
|
| BLAKE2b-256 |
88e8ea5721e1fe39d0328a2c33aa6b407fcf0e3b3d898cc3a805f61f74c02e96
|
File details
Details for the file py_typewriter_cli-1.0.0-py3-none-any.whl.
File metadata
- Download URL: py_typewriter_cli-1.0.0-py3-none-any.whl
- Upload date:
- Size: 10.4 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 |
5444cfdcd5076521f5a4c68033b794709e39fd5c40413cadbfd591206ba051a9
|
|
| MD5 |
5e7c32794cb99b82f510a95afeb4de05
|
|
| BLAKE2b-256 |
3e840d612a8609498f0fbc603c24daacf981a19762d08c657b0e1fcb97af04c6
|