TypePHP 编译器 https://swoole.com/aot/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

4.1 KiB

Python 工具子模块

TypePHP 将 Python IDE helper 生成器和 Python 源码转换器集成到了 tpc。两者位于独立的 src/PythonTools 目录,只复用 tpc 命令入口,不进入正常的 PHP 预处理、C++ 生成和编译流水线。

Python namespace IDE helper

./tpc --gen-python-helper math
./tpc --gen-python-helper numpy.linalg
./tpc --gen-python-helper numpy --output-dir .ide-helper

命令通过 PHPy 导入指定 Python module,并使用 Python inspect API 采集函数、参数、类、方法和 module attribute。PHPy 扩展以及目标 Python module 必须安装在执行 tpc 的主机环境中。

默认生成文件位于当前目录的 ide-helper 中。--output-dir 可以替换这个输出根目录,既支持 相对当前目录的路径,也支持绝对路径:

ide-helper/python/math.php
ide-helper/python/numpy/linalg.php
ide-helper/PyObject.php

首次生成 module helper 时,会同时生成公共的 PyObject.php。它包含 PyObject 的动态访问、调用、 数组访问、迭代以及 toArray()toValue() 等方法提示,供所有 Python module helper 共享。若该文件 已经存在,生成器会保留原文件,不进行覆盖。

生成内容使用 TypePHP 的 module-as-namespace 形式,例如 python\math\sqrt(),并兼容普通 useuse functionuse const 的 IDE 名称解析。文件末尾包含 die,用于在误执行时明确 终止程序。helper 只能交给 IDE 索引,不能被 include,也不能加入 TypePHP 项目的 sources 或编译输入。

PyObject::IDE_HELPER_ONLY 是所有 helper 共用的提示常量。非 void stub 的方法体使用 die(\PyObject::IDE_HELPER_ONLY),以满足 IDE 对返回类型控制流的检查,不会再产生“缺少 return 语句”的诊断。module attribute 使用命名空间 const 声明,支持 IDE 的常量补全和 use const。 PHP 8.1 及以上允许在常量初始化表达式中使用 new。module attribute 因此直接使用仅供 IDE 分析的 PyObject 实例作为占位值:

const pi = new \PyObject();

这样 IDE 会将常量精确识别为 PyObject,而不是从 null 推断出错误类型。

公共 PyObject helper 还声明了 TypePHP 的虚拟关键词方法,包括 toInt()toFloat()toString()toBool()toStream()、高精度类型转换、toObject()toAny()toRef()。 这些声明仅用于 IDE 补全;调用会在编译期展开,并不是 PHPy PyObject 运行时类的实体方法。 toArray()toValue() 则仍是 PHPy 提供的真实方法。

Python class 的构造函数会显式调用 parent::__construct()。Python 对象若定义了 count(),helper 不会重复声明它,因为 PyObject::count(): int 已用于 PHP Countable。需要调用 Python 自身的 count() 时,应显式写为 $object->__call('count', $arguments)

PHP function/class 名称大小写不敏感,而 Python 名称大小写敏感;PHP 保留字也不能声明为普通 stub symbol。生成器会以注释报告无法用合法 PHP 声明表达的符号,不会擅自重命名 Python API。

Python 转 TypePHP

./tpc --convert-python-to-php script.py > script.php

转换器调用 PATH 中的 python3 解析 Python AST,然后输出使用 TypePHP Python namespace 语法的 PHP 源码。普通 module import 会转换为 namespace import:

import math
print(math.sqrt(16))
use python\math;

function main(): void
{
    python\print(math\sqrt(16));
}

当前支持普通 import、函数、赋值、调用、容器字面量、基础运算、单项比较、if/while/for、 lambda 和基础 f-string。module 顶层变量会转换为 PHP global,以保持函数读取 module 变量的能力。

转换器遵循“不能可靠保持语义就拒绝”的原则。class、async、generator、try/with、decorator、 destructuring assignment、chained comparison、嵌套函数以及 loop-else 等尚未完成的语法会抛出带 源文件和行号的错误,不会生成看似可用但语义错误的 PHP 代码。