PYInfer: Deep Learning Semantic Type Inference for Python Variables Python类型推断

Abstract

        在本文中,提出了端到端的PYInfer,基于深度学习的类型推断工具,可自动生成Python变量的类型注释。推断变量类型时上下文代码语义非常重要。对于每一个变量的使用,在它的上下文范围内收集一些tokens,然后设计神经网络预测变量类型。由于很难去收集高质量的人工标定的数据集,采用已有的静态分析工具对源码中的变量生产ground truth.

        将类型推断作为一个分类问题,PyInfer能处理用户自定义类型以及为每个变量推断类型概率。

Introduction

        变量类型不一致是动态语言中常见的错误,由于Python的动态属性,解释器无法和静态编程语言编译器一样去检查类型的不一致性,Python的类型检查器利用注释检查类型的一致性。这些工具都需要使用开发者手动写入的类型注释,这个其实很难提供。     

        为方便用户编程和检查类型错误,变量类型推断是一个必要的步骤。深度学习已经应用到使用TypeScript进行JavaScript的类型推断,从而产生包含大量精确注释的语料库。Python和JavaScript数据集的质量相差较多。

        应用静态分析或动态分析的类型推断工具分析时不需要对其进行标记注释类型推断。然而,它们是不精确的,并且忽略了源代码中丰富的自然语言语义。

本篇论文提出PyInfer,对Python变量类型进行推断,因为人工标定的变量数据集不可用,因此采用PySonar2对Python GitHub项目自动产生初始类型注释,然后我们使用一系列的数据清洗技术改进数据集的质量,我们进一步提供注释和上下文信息用来训练深层神经网络的信息,它有效地为每种类型的概率排序。

注释数据集的收集

分析变量类型的源码上下文语义需要大量标注的数据集,我们使用PySonar2生成的包含大量数据类型结果的数据集并使用数据清洗技术提高数据集的质量。

用户自定义类型

由于Python的灵活性,类型可以是用户自定义的并且可以在运行时改变,我们把Python的类型推断作为一个分类任务,在500多个普通类型中覆盖了用户自定义类型。作为一个分类任务,我们的模型为每一个类型提供了置信度。

源码嵌入

源码中包含了大量的变量名和变量使用的语义信息和类型信息,这对类型推断很有帮助。之前的工作使用了word embedding(词嵌入),这些嵌入方式可能会产生OOV问题(超出词表问题),为了解决这个问题,我们使用了BPE算法(字节对编码算法).

上下文代码语义

我们的方法的一个主要观点就是为变量类型推断使用上下文代码语义。我们假设在一个确定的上下文margin内有相关的语义信息来描述变量,我们的方法能够分析变量的语义以及结构语法和语法信息。margin的设置如图所示

对于每一个变量,在它的上下文范围内收集它的源码序列,采用基于attention mechanism(注意力机制)的GRU(门神经网络)分析上下文语义。

把以上集成到一起,我们发明了一个端到端的,高质量的,高效的框架静态推断Python的变量类型。我们的框架还可以扩展到function argument推断,因为我们的方法是基于语义而不是图结构,它可以很容易扩展到其他动态类型语言的变量注释以及检测语义错误。

PyInfer框架

PyInfer模型框架示意图:

把类型推断看作一个分类问题,我们测试了基于出现频率排名的前500种类型,并在一个确定的范围内分析了上下文语义,BPE算法用来获取向量表示,进而使用这些向量嵌入到基于注意力机制的门神经网络中,从上下文中抽取代码语义。然后使用softmax层为每种类型进行概率分类。PyInfer包含四个组件:数据收集与生成,源码嵌入,设计模型,训练模型

A:数据收集与生成

为了将变量类型分类,我们需要一个足够大的标注了类型的数据集。人工标注不可取,使用PySonar2产生初始类型注释,因为PySonar2的分析比较保守,我们忽略了所有不能进行类型推断的变量,并假设剩下的变量的结果就是ground truth,我们也分析了typeshed,probPY和TypeWriter数据集。

表I展示了数据集  Original和Valid表示了在数据清洗及去重之前和之后的数量,typePY是从4577个Github库中收集的源码数据集,probPY是Xu et al工作中提到的数据集,typeshed是人工标定的数据集,只包含了function参数和return values的注释。

我们通过注释top-star的github仓库的Python源码收集typePy,对每一个变量,我们保存它的仓库链接,文件名,变量名,开始和结束的token位置,类型注释以及相关源码。为了获得类型注释,我们采用PySonar2推断每个变量类型。收集数据之后进行数据清洗,消除所有无意义的类型,比如”question mark“,和”None“类型,并且去重。最终获取到42560876种有效注释。

对于probPY数据集,我们利用PySonar2的结果和动态分析相结合的数据,propPY数据集提供了变量名,注释和源码来生成适用于我们的模型的上下文信息。

typeshed数据集包含对Python标准库和第三方包的人工标定的类型注释,然而它只包含function parameters和返回值类型的注释,并且因为频繁的代码更新而没有上下文信息,我们提取参数的注释去评估我们的模型的上下文代码语义的重要性,在合并第三方库和标准库的注释时࿰

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值