{"id":13468579,"url":"https://github.com/ikamensh/flynt","last_synced_at":"2026-04-07T19:02:31.360Z","repository":{"id":37484351,"uuid":"174731004","full_name":"ikamensh/flynt","owner":"ikamensh","description":"A tool to automatically convert old string literal formatting to f-strings","archived":false,"fork":false,"pushed_at":"2026-03-27T15:12:56.000Z","size":657,"stargazers_count":727,"open_issues_count":5,"forks_count":37,"subscribers_count":11,"default_branch":"master","last_synced_at":"2026-03-27T22:43:49.665Z","etag":null,"topics":["linter","python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ikamensh.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2019-03-09T18:26:38.000Z","updated_at":"2026-03-27T15:13:00.000Z","dependencies_parsed_at":"2025-06-04T18:56:33.907Z","dependency_job_id":"a7338875-2d04-4728-a6ad-d7461de7a068","html_url":"https://github.com/ikamensh/flynt","commit_stats":{"total_commits":354,"total_committers":29,"mean_commits":"12.206896551724139","dds":0.5480225988700564,"last_synced_commit":"651c822fdcf45fffcf9743dc755085f32acb65e3"},"previous_names":[],"tags_count":48,"template":false,"template_full_name":null,"purl":"pkg:github/ikamensh/flynt","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ikamensh%2Fflynt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ikamensh%2Fflynt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ikamensh%2Fflynt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ikamensh%2Fflynt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ikamensh","download_url":"https://codeload.github.com/ikamensh/flynt/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ikamensh%2Fflynt/sbom","scorecard":{"id":483515,"data":{"date":"2025-08-11","repo":{"name":"github.com/ikamensh/flynt","commit":"2eb0297b81ece720847301dd05c5dace9062f343"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.8,"checks":[{"name":"Maintained","score":10,"reason":"30 commit(s) and 26 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":0,"reason":"Found 2/29 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/ikamensh/flynt/build.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/ikamensh/flynt/build.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/ikamensh/flynt/build.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pre-commit.yml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/ikamensh/flynt/pre-commit.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pre-commit.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/ikamensh/flynt/pre-commit.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/pre-commit.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/ikamensh/flynt/pre-commit.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:38: update your workflow using https://app.stepsecurity.io/secureworkflow/ikamensh/flynt/test.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:41: update your workflow using https://app.stepsecurity.io/secureworkflow/ikamensh/flynt/test.yml/master?enable=pin","Warn: pipCommand not pinned by hash: .github/workflows/build.yml:20","Warn: pipCommand not pinned by hash: .github/workflows/test.yml:50","Info:   0 out of   7 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned","Info:   0 out of   2 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/build.yml:1","Warn: no topLevel permission defined: .github/workflows/pre-commit.yml:1","Warn: no topLevel permission defined: .github/workflows/test.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 18 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-19T17:13:24.943Z","repository_id":37484351,"created_at":"2025-08-19T17:13:24.943Z","updated_at":"2025-08-19T17:13:24.943Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31524531,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-07T16:28:08.000Z","status":"ssl_error","status_checked_at":"2026-04-07T16:28:06.951Z","response_time":105,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["linter","python"],"created_at":"2024-07-31T15:01:13.998Z","updated_at":"2026-04-07T19:02:31.355Z","avatar_url":"https://github.com/ikamensh.png","language":"Python","funding_links":[],"categories":["Python","🤩 Status: *awesome*","UNIX-way formatters"],"sub_categories":["Development"],"readme":"### A new tool: try [kodo](https://github.com/ikamensh/kodo), open source agentic coding orchestrator.\n\n# flynt - string formatting converter\n\n\u003cp align=\"center\"\u003e\n\u003ca href=\"https://github.com/ikamensh/flynt/actions\"\u003e\u003cimg alt=\"Actions Status\" src=\"https://github.com/ikamensh/flynt/workflows/Test/badge.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/ikamensh/flynt/blob/main/LICENSE\"\u003e\u003cimg alt=\"License: MIT\" src=\"https://black.readthedocs.io/en/stable/_static/license.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://pypi.org/project/flynt/\"\u003e\u003cimg alt=\"PyPI\" src=\"https://img.shields.io/pypi/v/flynt\"\u003e\u003c/a\u003e\n\u003ca href=\"https://pepy.tech/project/flynt\"\u003e\u003cimg alt=\"Downloads\" src=\"https://pepy.tech/badge/flynt\"\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/psf/black\"\u003e\u003cimg alt=\"Code style: black\" src=\"https://img.shields.io/badge/code%20style-black-000000.svg\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n`flynt` is a command line tool to automatically convert a project's Python code from old \"%-formatted\" and .format(...) strings into Python 3.6+'s \"f-strings\".\n\nF-Strings:\n\n\u003e Not only are they more readable, more concise, and less prone to error than other ways of formatting, but they are also faster!\n\n### Installation\n\n`pip install flynt`. It requires Python version 3.9+.\n\n### Usage\n\n*Flynt will modify the files it runs on. Add your project to version control system before using flynt.*\n\nTo run: `flynt {source_file_or_directory}`\n\n* Given a single file, it will 'f-stringify' it: replace all applicable string formatting in this file (file will be modified).\n* Given a folder, it will search the folder recursively and f-stringify all the .py files it finds. It skips some hard-coded folder names: `blacklist = {'.tox', 'venv', 'site-packages', '.eggs'}`.\n\nIt turns the code it runs on into Python 3.6+, since 3.6 is when \"f-strings\" were introduced.\n\n### Command line options\n\nFrom the output of `flynt -h`:\n\n\u003c!-- begin-options --\u003e\n```\nusage: flynt [-h] [-v | -q] [--no-multiline | -ll LINE_LENGTH] [-d |\n             --stdout] [-s] [--no-tp] [--no-tf] [-tc] [-tj] [-f]\n             [-a] [-e EXCLUDE [EXCLUDE ...]] [-nb] [--version]\n             [--report]\n             [src ...]\n\nflynt v.1.0.3\n\npositional arguments:\n  src                   source file(s) or directory (or a single `-`\n                        to read stdin and output to stdout)\n\noptions:\n  -h, --help            show this help message and exit\n  -v, --verbose         run with verbose output\n  -q, --quiet           run without outputting statistics to stdout\n  --no-multiline        convert only single line expressions\n  -ll, --line-length LINE_LENGTH\n                        for expressions spanning multiple lines,\n                        convert only if the resulting single line\n                        will fit into the line length limit. Default\n                        value is 88 characters.\n  -d, --dry-run         Do not change the files in-place and print\n                        the diff instead. Note that this must be\n                        used in conjunction with '--fail-on-change'\n                        when used for linting purposes.\n  --stdout              Do not change the files in-place and print\n                        the result instead. This argument implies\n                        --quiet, i.e. no statistics are printed to\n                        stdout, only the resulting code. It is\n                        incompatible with --dry-run and --verbose.\n  -s, --string          Interpret the input as a Python code snippet\n                        and print the converted version. The snippet\n                        must use single quotes or escaped double\n                        quotes.\n  --no-tp, --no-transform-percent\n                        Don't transform % formatting to f-strings\n                        (default: do so)\n  --no-tf, --no-transform-format\n                        Don't transform .format formatting to\n                        f-strings (default: do so)\n  -tc, --transform-concats\n                        Replace string concatenations (defined as +\n                        operations involving string literals) with\n                        f-strings. Available only if flynt is\n                        installed with a 3.9+ interpreter.\n  -tj, --transform-joins\n                        Replace static joins (where the joiner is a\n                        string literal and the joinee is a static-\n                        length list) with f-strings. Available only\n                        if flynt is installed with a 3.9+\n                        interpreter.\n  -f, --fail-on-change  Fail when changing files (for linting\n                        purposes)\n  -a, --aggressive      Include conversions with potentially changed\n                        behavior. Use -aa to omit int() wrapping for\n                        %d conversions.\n  -e, --exclude EXCLUDE [EXCLUDE ...]\n                        ignore files with given strings in it's\n                        absolute path.\n  -nb, --notebook       Also search and transform Jupyter notebooks\n                        (.ipynb files). Warning: feature in alpha\n                        and was not thoroughly tested.\n  --version             Print the current version number and exit.\n  --report              Show detailed conversion report\n\n```\n\n### Sample output of a successful run:\n```\n$ git clone https://github.com/pallets/flask.git\nCloning into 'flask'...\n...\nResolving deltas: 100% (12203/12203), done.\n\n$ flynt flask\nRunning flynt v.1.0.3\nModified 21 of 70 files in 0.79s\n$\n```\n\n### Pre-commit hook\n\nTo make sure all formatted strings are always converted to f-strings, you can\nadd flynt to your [pre-commit](https://www.pre-commit.com) hooks.\n\nAdd a new section to `.pre-commit-config.yaml`:\n```\n-   repo: https://github.com/ikamensh/flynt/\n    rev: ''\n    hooks:\n    -   id: flynt\n```\n\nThis will run flynt on all modified files before committing.\n\nYou can skip conversion of certain lines by adding `# noqa [: anything else] flynt [anything else]` or `# flynt: skip`\n\n\n### Configuration files\n\nSince v0.71 flynt can be configured using `pyproject.toml` file on a per-project basis. \nUse same arguments as in CLI, and add them to `[tool.flynt]` section. CLI arguments takes precedence over the config file.\nIt can also be configured globally with a toml file located in `~/.config/flynt.toml` on Unix / `~/.flynt.toml` on Windows.\n\n### About\n\nRead up on f-strings here:\n- https://realpython.com/python-f-strings/\n- https://www.python.org/dev/peps/pep-0498/\n\nAfter obsessively refactoring a project at work, and not even covering 50% of f-string candidates, I realized there was some place for automation. Also it was very interesting to work with ast module.\n\n### Dangers of conversion\nIt is not guaranteed that formatted strings will be exactly the same as before conversion.\n\n`'%s' % var` is converted to `f'{var}'`. There is a case when this will behave different from the original -  if var is a tuple of one element. In this case, %s displays the element, and f-string displays the tuple. Example:\n\n```\nfoo = (1,)\nprint('%s' % foo) # prints '1'\nprint(f'{foo}')   # prints '(1,)'\n```\n\nFurthermore, some arguments cause formatting of strings to throw exceptions. One example where f-strings are inconsistent with previous formatting is %d vs {:d} - new format no longer accepts floats. While most cases are covered by taking the formatting specifiers to the f-strings format, the precise exception behaviour might differ as well. Make sure you have sufficient test coverage.\n\n### Other Credits / Dependencies / Links\n\n- Python's built-in `ast.unparse` is used to turn the transformed AST back into code.\n- Thanks to folks from [pyddf](https://www.pyddf.de/) for their support, advice and participation during spring hackathon 2019, in particular Holger Hass, Farid Muradov, Charlie Clark.\n- Logic finding the pyproject.toml and parsing it was partially copied from [black](https://github.com/psf/black) \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fikamensh%2Fflynt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fikamensh%2Fflynt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fikamensh%2Fflynt/lists"}