This document provides a short overview of the main modules that make up Flynt and how they interact. It is intended to help new contributors find their way around the codebase.
Flynt exposes a command line interface (CLI) and a small API:
src/flynt/__main__.py– thepython -m flyntentry point. It simply callsflynt.main().src/flynt/cli.py– parses command line arguments and eventually invokesflynt.api.fstringifywith a configuredStateobject.src/flynt/api.py– high level API used by the CLI and tests. It containsfstringify_code(convert a string),fstringify_files(convert multiple files) andfstringify(resolve paths and run the conversion).
src/flynt/state.py defines the State dataclass. It stores command line
options (e.g. --aggressive, --line-length) as well as counters used for the
final conversion report. CLI arguments and optional pyproject.toml values are
translated into a State instance in cli.py.
Configuration is loaded from a pyproject.toml (found via
find_pyproject_toml in src/flynt/utils/pyproject_finder.py). CLI options
override configuration file values.
For each file, Flynt executes the following steps (implemented mainly in
flynt.api and flynt.code_editor):
- Candidate discovery – Code is parsed into an AST and inspected for
formatting operations that can be transformed. Modules under
src/flynt/candidates/find:- old style
%formatting (ast_percent_candidates.py) .format()calls (ast_call_candidates.py) Candidates are represented byAstChunkobjects which store start and end positions inside the source code.
- old style
- Optional candidate providers – Additional transformations are available
for string concatenations (
src/flynt/string_concat/) and static.join()calls (src/flynt/static_join/). These are enabled through CLI options and use the sameAstChunkabstraction. - Editing –
src/flynt/code_editor.pyorchestrates the process. It keeps the original source lines and walks through the sorted list of candidates. For each candidate it calls a transform function and, if the result fits the current line length constraints, replaces the original code while keeping the rest of the file untouched. The transform function also increments the counters inState. - AST based transformation – The actual conversion logic lives in
src/flynt/transform/. The central functiontransform_chunkcallsfstringify_nodefromFstringifyTransformer.pywhich applies two transformations:percent_transformer.pyconverts%based formatting.format_call_transforms.pyconverts.format()calls. These operate on the AST and return anast.JoinedStrrepresenting the new f-string. After transformation, helper functions inflynt.utils.utilsformat the result back into source code with consistent quoting.
src/flynt/utils/format.pycontains helper logic for detecting and modifying string quoting.src/flynt/utils/utils.pyprovides AST helpers such asast_to_string,ast_formatted_value, and thestr_in_strdetection used to avoid unsafe conversions.src/flynt/linting/fstr_lint.pycontains utilities used by the transformation pipeline to inline nested f-strings and to detect existing f-strings.
Unit and integration tests live in test/. The integration suite in
test/integration/ feeds example files through the public API and verifies the
exact output. Tests are executed with pytest and formatting is enforced via
pre-commit hooks.