{"id":13468492,"url":"https://github.com/facebookincubator/Bowler","last_synced_at":"2025-03-26T05:31:08.502Z","repository":{"id":41203219,"uuid":"136534335","full_name":"facebookincubator/Bowler","owner":"facebookincubator","description":"Safe code refactoring for modern Python.","archived":false,"fork":false,"pushed_at":"2024-06-21T03:38:05.000Z","size":1092,"stargazers_count":1590,"open_issues_count":55,"forks_count":104,"subscribers_count":37,"default_branch":"main","last_synced_at":"2025-03-26T00:09:09.376Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://pybowler.io/","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/facebookincubator.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","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}},"created_at":"2018-06-07T21:44:17.000Z","updated_at":"2025-03-25T04:01:27.000Z","dependencies_parsed_at":"2024-01-12T21:19:53.980Z","dependency_job_id":"e17144e0-a593-4458-8a02-b743f215383f","html_url":"https://github.com/facebookincubator/Bowler","commit_stats":{"total_commits":134,"total_committers":27,"mean_commits":4.962962962962963,"dds":0.6940298507462687,"last_synced_commit":"92c9eeb7eebab8a1b65a989d0cf3b4947773ea2b"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/facebookincubator%2FBowler","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/facebookincubator%2FBowler/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/facebookincubator%2FBowler/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/facebookincubator%2FBowler/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/facebookincubator","download_url":"https://codeload.github.com/facebookincubator/Bowler/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245597240,"owners_count":20641861,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2024-07-31T15:01:12.183Z","updated_at":"2025-03-26T05:31:08.475Z","avatar_url":"https://github.com/facebookincubator.png","language":"Python","readme":"\u003ca href=\"https://pybowler.io\"\u003e\u003cimg alt=\"Bowler\" height=\"96\" src=\"https://github.com/facebookincubator/Bowler/raw/main/website/static/img/logo/Bowler_FullColor_DarkText.png\" /\u003e\u003c/a\u003e\n\n**Safe code refactoring for modern Python projects.**\n\n[![build status](https://github.com/facebookincubator/Bowler/workflows/Build/badge.svg)](https://github.com/facebookincubator/Bowler/actions)\n[![code coverage](https://img.shields.io/codecov/c/github/facebookincubator/Bowler)](https://codecov.io/gh/facebookincubator/Bowler)\n[![version](https://img.shields.io/pypi/v/bowler.svg)](https://pypi.org/project/bowler)\n[![changelog](https://img.shields.io/badge/change-log-blue.svg)](https://github.com/facebookincubator/bowler/blob/main/CHANGELOG.md)\n[![license](https://img.shields.io/pypi/l/bowler.svg)](https://github.com/facebookincubator/bowler/blob/main/LICENSE)\n[![code style](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)\n\n\nCurrent Development Status\n--------------------------\n\nBowler 0.x is based on fissix (a fork of lib2to3) which was never intended to be a\nstable api.  We've pretty much reached the limit of being able to add new language\nfeatures, so while we can support 3.8's walrus, that's basically the last it's going to\nget.\n\nSee discussion for [`f(**not x)`](https://bugs.python.org/issue36541) for one example --\na proper fix for things like this would mean invalidating all current patterns since\nthere's no way to match against a specific revision of the grammar.\n\nIf you need to do codemods today, we recommend looking at \n[LibCST codemods](https://libcst.readthedocs.io/en/stable/codemods_tutorial.html) which\nare a bit more verbose, but work well on modern python grammars.  We have contributed\n[support for Python 3.0-3.3 grammars](https://github.com/Instagram/LibCST/pull/261)\nand have a draft PR going even further [back to 2.3](https://github.com/Instagram/LibCST/pull/275).\n\nThe longer term plan for Bowler is to build Bowler 2.x on top of libcst's parser, while\nstill supporting a very simple fluent api.  That's unlikely to materialize in a final\nrelease during 2021.\n\n\nOverview\n--------\n\nBowler is a refactoring tool for manipulating Python at the syntax tree level. It enables\nsafe, large scale code modifications while guaranteeing that the resulting code compiles\nand runs. It provides both a simple command line interface and a fluent API in Python for\ngenerating complex code modifications in code.\n\nBowler uses a \"fluent\" `Query` API to build refactoring scripts through a series\nof selectors, filters, and modifiers.  Many simple modifications are already possible\nusing the existing API, but you can also provide custom selectors, filters, and\nmodifiers as needed to build more complex or custom refactorings.  See the\n[Query Reference](https://pybowler.io/docs/api-query) for more details.\n\nUsing the query API to rename a single function, and generate an interactive diff from\nthe results, would look something like this:\n\n```python\nquery = (\n    Query(\u003cpaths to modify\u003e)\n    .select_function(\"old_name\")\n    .rename(\"new_name\")\n    .diff(interactive=True)\n)\n```\n\nFor more details or documentation, check out https://pybowler.io\n\n\nInstalling Bowler\n-----------------\n\nBowler supports modifications to code from any version of Python 2 or 3, but it\nrequires Python 3.6 or higher to run. Bowler can be easily installed using most common\nPython packaging tools. We recommend installing the latest stable release from\n[PyPI][] with `pip`:\n\n```bash\npip install bowler\n```\n\nYou can also install a development version from source by checking out the Git repo:\n\n```bash\ngit clone https://github.com/facebookincubator/bowler\ncd bowler\npython setup.py install\n```\n\n\nLicense\n-------\n\nBowler is MIT licensed, as found in the `LICENSE` file.\n\n\n[PyPI]: https://pypi.org/p/bowler\n","funding_links":[],"categories":["Python","Code Analysis","Libraries/Tools for refactoring","Libraries and refactoring"],"sub_categories":["Debian"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffacebookincubator%2FBowler","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffacebookincubator%2FBowler","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffacebookincubator%2FBowler/lists"}