我正在尝试确定python包的公共部分的接口更改为以前的版本。这是为了帮助进行语义版本控制(MAJOR_CHANGE.MINOR_CHANGE.PATCH)我能想到的最好方法是:
基本上,问题是,对于这些更改,比较2个存根文件包的最佳方法是什么?我们可以比较AST文件,虽然这些文件不包含类型信息(我们可以尝试使用它来解决https://github.com/python/typed_ast)
此处的示例存根文件:
# Stubs for positioning.point (Python 3.6)
#
# NOTE: This dynamically typed stub was automatically generated by stubgen.
import numpy as np
from .exceptions import UnacceptableCartesianCoordinates
from .frame import Frame
from .methods import check_frames_have_common_parent, get_coordinates_of_point_in_frame, lowest_common_parent
from typing import Any
class Point:
def __init__(self, frame: Frame, point_coordinates: np.ndarray) -> None: ...
@classmethod
def from_cartesian(cls: Any, frame: Frame, x: float, y: float, z: float) -> Point: ...
@classmethod
def from_cylindrical(cls: Any, frame: Frame, r: float, phi: float, z: float) -> Point: ...
@classmethod
def from_spherical(cls: Any, frame: Frame, r: float, theta: float, phi: float) -> Point: ...
@classmethod
def from_old_point_in_new_frame(cls: Any, old_point: Point, new_frame: Frame) -> Point: ...
@classmethod
def at_origin(cls: Any, frame: Frame) -> Point: ...
@property
def frame(self): ...
def __eq__(self, other: Any) -> bool: ...
编辑:
要更加清晰(并使用花哨的图表!)我希望比较2个包A和B之间的公共接口。使用类型信息生成公共接口的最佳方法是使用stubgen。因此,包的公共接口将由.pyi
个文件包定义。
然后我们使用一个新的魔术工具(称为snappy,如interface-diff
)来比较A和B的两个接口。在最高级别,我们将比较接口时有4个潜在的结果。
1)主要 - 从A中删除的东西而不是添加到B的东西
2)主要 - 从A中删除的东西和添加到B的东西
3)MINOR - 将事物添加到B而不是从A
中删除4)PATCH - A == B
如果有人能让我走上正确的路线,我很高兴自己写这个:)
答案 0 :(得分:0)
您需要的是每个存根的抽象语法树(AST)。没有新节点意味着补丁,新叶节点可能意味着较小(取决于节点的语言和位置),新的非叶节点意味着主要节点。但这并不是真正的整个解决方案,因为并非所有重大变化都会出现在接口存根上。您还需要进行功能验证,即现有接口的任何新实现,实际上满足记录的行为(合同)以及使用任何新接口都不会破坏旧接口。
您应该能够在公开的Python实现中找到好的解析器/ AST实现。您可以使用旧的和新的实现的AST来查找现有接口背后的潜在重大变化!