跳转到主要内容

为Python编写重构代码的全语法树(FST)

项目描述

介绍

Baron是Python的一个全语法树(FST)库。与在创建过程中丢弃一些语法信息(如空行、注释、格式化)的抽象语法树(AST)相反,FST保留一切并保证操作 fst_to_code(code_to_fst(source_code)) == source_code

路线图

当前的路线图就像必要的无聊一样

  • 错误修复
  • 新的小功能(遍历模式,可能生成代码)和性能改进。

安装

pip install baron

基本用法

from baron import parse, dumps

fst = parse(source_code_string)
source_code_string == dumps(fst)

除非你想进行底层操作,否则请使用 RedBaron 而不是直接使用Baron。将Baron视为“Python源代码的字节码”,将RedBaron视为在其之上的一种可用的层。

如果你不知道Baron是什么,或者还不理解它为什么可能对你有用,请阅读「为什么这很重要?」部分

文档

Baron文档可在Read The Docs上找到。

贡献

如果你想实现为较新Python版本的新语法元素,以下是实现该功能的文档步骤: https://github.com/PyCQA/baron/blob/master/add_new_grammar.md

请注意,审查大多数语法修改需要几个小时的高级专注(在这里我们真的负担不起错误),所以如果你的PR看起来像是悬而未决的,请不要失望,对此表示歉意 :/

提前感谢你的工作!

财务支持

Baron和RedBaron是非常先进的工程技术,需要大量的专注时间来完成。截至2018年底,开发主要是由Bram进行的志愿者工作,但现在,为了达到下一个层次,并将这些项目带到您期望的稳定性和质量水平,我们需要您的支持。

您可以通过我们透明的OpenCollective加入我们的贡献者和赞助者,每一次贡献都将被计算,并将主要用于项目的稳定性和质量,同时在侧面继续这些项目的研发工作。

我们的支持者

badge with number of supporters at tier I like this, keep going! badge with number of supporters at tier it looks cool! badge with number of supporters at tier Oh god, that saved me so much time!

为什么这很重要?

FST(有限状态转换)的用法可能一开始并不明显,让我们通过一系列问题来说明它。假设你想编写一个程序,它会

  • 在不与不是变量的事物冲突的情况下(例如:字符串内的内容)重命名源文件中的变量
  • 内联一个函数/方法
  • 从一系列代码行中提取一个函数/方法
  • 将一个类分割成几个类
  • 将一个文件分割成几个模块
  • 将整个代码库从一种ORM转换到另一种
  • 执行IDE/rope未实现的自定义重构操作
  • 实现Smalltalk的Python类浏览器(可以编辑方法代码的整个浏览器,而不仅仅是显示代码)

你可能会感到写出的代码笨拙且薄弱,很可能因为你没有考虑到所有烦人的特殊情况,格式化一直困扰着你。你可能最终会放弃这个任务,因为它太复杂了,真的不值得努力。你缺少一个好的抽象,它可以处理所有的代码结构和格式,这样你就可以专注于你的任务。

FST试图成为这样的抽象。有了它,你现在可以工作在一个代表你代码及其格式的树上了。此外,由于它是代码的确切表示,修改它并将其转换回字符串只会使你在树中修改的地方修改代码。

换句话说,我试图通过Baron实现的,是代码修改代码的编写方式的范式转变,这现在是一个真正值得付出代价的任务(我并不是说这是一个简单的任务,而是一个现实的任务:它仍然是一个复杂的任务)。

其他

拥有FST(或者至少建立在它之上的良好抽象)也使得进行代码生成和代码分析更容易,尽管这两个操作已经相当可行(例如使用ast.py和模板引擎)。

一些技术细节

Baron以JSON(我指的是可以导出到JSON的Python列表和字典)的形式生成FST,以实现最大程度的互操作性。

Baron FST与Python AST非常相似,但进行了一些修改以使人类更直观,因为Python AST是为CPython解释器设计的。

由于直接与JSON交互有点原始,我将在其之上构建一个抽象,使其看起来像BeautifulSoup/jQuery。

项目状态

目前,Baron已经在前100个项目中进行了测试,FST转换完全准确地回到了原始源代码。因此,它可以被认为是相当稳定的,但它离经过实战测试还有很长的路要走。

由于项目非常年轻,除了我的项目外,还没有人使用它,所以我愿意对FST节点进行更改,但一旦它获得一些采用,我将很快变得保守,未来可能只会修改一次或两次,并提供明确的迁移说明。

Baron支持Python 2语法和到Python 3.7的语法。

测试

在baron目录下运行py.test tests/nosetests

社区

您可以在irc.freenode.net#baronirc.freenode.net##python-code-quality找到我们。

行为准则

作为PyCQA的成员,Baron遵循其行为准则

杂项

宣布项目的旧博客文章。并不是特别更新。

变更日志

0.10.1 (2021-12-08)

  • 错误修复:在"a."中,"."部分被错误地识别为浮点数,由bram修复

0.10 (2021-12-08)

0.9 (2019-02-01)

完全支持Python 3.7语法的第一个版本。

0.8 (2018-10-29)

0.7 (2018-08-21)

Python 3

0.6.6 (2017-06-12)

0.6.5 (2017-01-26)

  • 修复了之前的回归修复

0.6.4 (2017-01-14)

  • 修复了在if/def/other之后的": "后面的注释导致的回归

0.6.3 (2017-01-02)

  • 将文件开始或之前有注释的空格处的格式化分组

0.6.2 (2016-03-18)

  • 修复了生成解析缓存文件时的竞争条件
  • 使所有面向用户错误的错误都继承自相同的BaronError类
  • 修复:dotted_name和float_exponant_complex在nodes_rendering_order中缺失

0.6.1 (2015-01-31)

  • 修复:字符串在分组周围的字符串标记(对于字符串链)上具有贪婪行为,这最终导致字符串分组方式不一致
  • 修复:更好地处理数字解析,但并非所有问题都已解决
  • 使所有(预期)错误都继承自相同的BaronError类
  • 修复:如果引号字符串未关闭,解析将正确失败

0.6 (2014-12-11)

  • FST结构修改:def_argument_tuple不再存在,所有参数现在都有一致的结构
    • 将def_argument节点的名称属性重命名为target,类似于assign
    • target属性现在指向一个字典,而不是一个字符串
    • 旧名称->字符串现在是target->name_node
    • def_argument_tuple现在是一个def_argument,其中target指向一个元组
    • 这个特定的元组将只有名称、逗号和元组成员(不再为名称使用def_argument)
  • 新节点:long,在int和long合并之前,这导致了问题

0.5 (2014-11-10)

  • 将"funcdef"节点重命名为"def"节点,使其更加直观。

0.4 (2014-09-29)

  • 在nodes_rendering_order字典中添加了新的渲染类型:string。这消除了键可能指向字典或字符串的歧义,从而迫使第三方工具进行猜测。

0.3.1 (2014-09-04)

  • 如果未使用wheel,则setup.py无法正常工作,因为CHANGELOG文件未包含在MANIFEST.in中

0.3 (2014-08-21)

  • 路径变为一个简单的列表,更容易处理
  • 边界框允许您知道节点的最左和最右位置,请参阅 https://baron.readthedocs.io/en/latest/#bounding-box
  • redbaron被归类为支持python3 https://github.com/PyCQA/baron/pull/51
  • 确保当键是字符串时,它的空值是空字符串而不是None,以避免破坏使用内省来猜测键类型的库
  • 在FST中进行键重命名:"delimiteur" -> "delimiter"
  • name_as_name和dotted_as_name节点不再有"as"键,因为它没有用(可以从"target"键的状态推断出来)
  • dotted_name节点不再存在,它的存在是没有根据的。在import、from_import和decorator节点中,它已被从键替换为字典(其中只包含一个列表)到一个简单的列表。
  • dumps现在接受一个严格的布尔参数来检查在转储时的FST的有效性,但这并不是一个公开的特性,并且可能在未来更改API
  • name_as_name和dotted_as_name的目标空值现在是空字符串,而不是None,因为这是一个字符串类型键
  • 边界框现在包括节点末尾的新行
  • 所有抛出的异常都继承自一个公共基异常,以简化try/catch结构
  • Position的left和right函数成为属性,因此成为属性
  • Position对象可以与其他Position对象或任何可迭代对象进行比较
  • 删除make_position和make_bounding_box函数,改为始终使用相应类的构造函数

0.2 (2014-06-11)

0.1.3 (2014-04-13)

  • 糖语法符号的set没有被dumper处理(据称在pypi top 100中没有人使用此功能)

0.1.2 (2014-04-08)

  • baron.dumps现在接受单个FST节点,它只能处理FST节点列表
  • 如果输入字符串中没有endl节点,则不要添加endl节点
  • 取消统一化call_arguments和function_arguments节点,这只是在制造更多问题
  • 修复https://github.com/PyCQA/redbaron/issues/4
  • 修复baron无法解析"{1,}"的事实(但"{1}"是有效的)

0.1.1 (2014-03-23)

  • 看起来我不知道如何正确编写MANIFEST.in

0.1 (2014-03-22)

  • 初始化

项目详情


下载文件

下载适用于您的平台文件。如果您不确定选择哪一个,请了解更多关于安装包的信息。

源分布

baron-0.10.1.tar.gz (1.0 MB 查看哈希值

上传时间

构建分布

baron-0.10.1-py2.py3-none-any.whl (45.6 kB 查看哈希值

上传时间 Python 2 Python 3

由以下支持