一句话:基于九种 pythonic 惯用法的语法模式与原子 AST 重写,自动将非惯用 Python 代码重构为惯用代码。
Python 相比 Java 等语言拥有更多使代码简洁高效的惯用法(pythonic idioms),但程序员常因不了解或不熟悉而写出非惯用代码。作者分析了 GitHub 上 7,638 个 Python 仓库,发现可用 pythonic 惯用法实现的非惯用代码出现频繁且分布广泛,然而尚无工具能自动完成此类重构。本文通过系统对比 Python 与 Java 的抽象语法,归纳出九种 pythonic 惯用法;为每种惯用法定义检测非惯用代码的语法模式;并设计原子 AST 重写操作与重构步骤,实现自动重构工具。评估中,作者在来自 GitHub 的 1,065 个 Python 项目上测试并人工审查了 4,115 次重构,并从重构中随机抽样向 84 个项目提交 90 个 pull request,验证了该工具在真实 Python 代码上的高准确性、实用性与有用性。
Compared to other programming languages (e.g., Java), Python has more idioms to make Python code concise and efficient. Although pythonic idioms are well accepted in the Python community, Python programmers are often faced with many challenges in using them, for example, being unaware of certain pythonic idioms or do not know how to use them properly. Based on an analysis of 7,638 Python repositories on GitHub, we find that non-idiomatic Python code that can be implemented with pythonic idioms occurs frequently and widely. Unfortunately, there is no tool for automatically refactoring such non-idiomatic code into idiomatic code. In this paper, we design and implement an automatic refactoring tool to make Python code idiomatic. We identify nine pythonic idioms by systematically contrasting the abstract syntax grammar of Python and Java. Then we define the syntactic patterns for detecting non-idiomatic code for each pythonic idiom. Finally, we devise atomic AST-rewriting operations and refactoring steps to refactor non-idiomatic code into idiomatic code. We test and review over 4,115 refactorings applied to 1,065 Python projects from GitHub, and submit 90 pull requests for the 90 randomly sampled refactorings to 84 projects. These evaluations confirm the high accuracy, practicality and usefulness of our refactoring tool on real-world Python code.
DOI 原文 ·
@inproceedings{paperbot7136,
title = {Making Python code idiomatic by automatic refactoring non-idiomatic Python code with pythonic idioms},
author = {Zejun Zhang and Zhenchang Xing and Xin Xia and Xiwei Xu and Liming Zhu},
booktitle = {FSE},
year = {2022},
doi = {10.1145/3540250.3549143}
}