Skip to main content

A CLI tool for generating type annotations.

Project description

Typewriter

Documentation Status GitHub Actions Build Status Coveralls Codecov PyPI Package latest release PyPI Wheel Supported versions Supported implementations

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 = None stays 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 needed
  • 1: changes would be made
  • 2: 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:

  • PATH and --code are mutually exclusive.
  • Literal \\n sequences in --code input are interpreted as newlines.
  • When a directory is provided as PATH, Typewriter will ignore non-.py files and common non-source subdirectories such as .git, .venv, venv, __pycache__, build, and dist.
  • We ignore the more recent PEP 604 syntax of T | None since it is not supported in Python 3.9, which is currently supported by microsoft/playwright-python and 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:

  1. Fork the repository and create a new branch for your feature or bug fix.
  2. Make your changes and commit them with clear messages.
  3. Push your branch to your fork and open a pull request against the main branch of the original repository.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

py_typewriter_cli-1.0.0.tar.gz (11.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

py_typewriter_cli-1.0.0-py3-none-any.whl (10.4 kB view details)

Uploaded Python 3

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

Hashes for py_typewriter_cli-1.0.0.tar.gz
Algorithm Hash digest
SHA256 1ff9a6740bc7f1e53e1ba96956b312fb5af77b62b3b12b873dd61be9dd968cc8
MD5 33aa613658fceb83cb649e2041853fb7
BLAKE2b-256 88e8ea5721e1fe39d0328a2c33aa6b407fcf0e3b3d898cc3a805f61f74c02e96

See more details on using hashes here.

File details

Details for the file py_typewriter_cli-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for py_typewriter_cli-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5444cfdcd5076521f5a4c68033b794709e39fd5c40413cadbfd591206ba051a9
MD5 5e7c32794cb99b82f510a95afeb4de05
BLAKE2b-256 3e840d612a8609498f0fbc603c24daacf981a19762d08c657b0e1fcb97af04c6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page