gpt4 book ai didi

Windows 上的 python libclang 绑定(bind)无法从 sublime text 初始化翻译单元

转载 作者:可可西里 更新时间:2023-11-01 14:35:34 32 4
gpt4 key购买 nike

简短说明:使用 libclang 自动完成代码不适用于与 Sublime Text 3 捆绑在一起的 python。

详细信息:Github 上的存储库中有一个可验证的小示例

本质上,有一个脚本使用略有改动的 cindex.py(兼容 python 3 和 clang 3.8)并从测试源文件构建翻译单元。然后它重新解析它并尝试完成。

该脚本在 Powershell 中使用 Python 3.3.5 时按预期工作。

当放入 Sublime Text 3 的 Packages 文件夹时,它会产生错误。 Sublime Text 3 报告的 Python 版本是 3.3.6。错误:

Traceback (most recent call last):
File "C:\Program Files\Sublime Text 3\sublime_plugin.py", line 78, in reload_plugin
m = importlib.import_module(modulename)
File "./python3.3/importlib/__init__.py", line 90, in import_module
File "<frozen importlib._bootstrap>", line 1584, in _gcd_import
File "<frozen importlib._bootstrap>", line 1565, in _find_and_load
File "<frozen importlib._bootstrap>", line 1532, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 584, in _check_name_wrapper
File "<frozen importlib._bootstrap>", line 1022, in load_module
File "<frozen importlib._bootstrap>", line 1003, in load_module
File "<frozen importlib._bootstrap>", line 560, in module_for_loader_wrapper
File "<frozen importlib._bootstrap>", line 868, in _load_module
File "<frozen importlib._bootstrap>", line 313, in _call_with_frames_removed
File "C:\Users\igor\AppData\Roaming\Sublime Text 3\Packages\test_clang\script.py", line 21, in <module>
tu = TU.from_source(filename=filename)
File "C:\Users\igor\AppData\Roaming\Sublime Text 3\Packages\test_clang\clang\cindex38.py", line 2372, in from_source
raise TranslationUnitLoadError("Error parsing translation unit.")
clang.cindex38.TranslationUnitLoadError: Error parsing translation unit.

这是因为 cindex.py 中 libclang 返回的翻译单元的 ptr 是 None。对我来说唯一奇怪的是它只发生在与 sublime text 3 捆绑在一起的 python 中。

其他人也会这样吗?有谁知道可能是什么原因或如何调试它?

如果您无法运行此处提供的示例,也可以随时 ping 我。

UPD:在测试项目的问题中,我们发现 sublime text 中捆绑的不是 ctypes。将 sublime text 中的替换为系统中安装的会产生相同的错误。

UPD2:我已经精简了测试存储库中的 cindex.py 文件,只包含遇到相同问题所需的最少代码在问题中描述。也许这将有助于产生关于可能出错的新想法?此外,我想明确指出,相同的代码在 Linux 和 OSX 上的工作方式完全符合预期。

最佳答案

事实证明,此故障的可调试性很差。我追踪了一堆 libclang 绑定(bind)源,希望找到一种解决方法,以解决围绕从 python 抛出的 TranslationUnitLoadError 缺乏可调试性的问题。

即使您使用 ctypes errcheck callback,这里似乎也存在一些基本限制。像下面...

# MODIFIED cindex.py

def errcheck_callable(result, func, arguments):
print(f"ERROR---result={result}, func={func}, arguments={arguments}")
import pdb
pdb.set_trace()

functionList = [
...
("clang_parseTranslationUnit",
[Index, c_interop_string, c_void_p, c_int, c_void_p, c_int, c_int],
c_object_p,
errcheck_callable, # <--- makes this dll function a bit more debugable during call to `register_function`
),
...
]

但是在翻译单元故障期间触发的错误回调中没有太多内容:

> /Users/USERX/python3.7/site-packages/clang/cindex.py(155)errcheck_callable()
-> print(f"ERROR---result={result}, func={func}, arguments={arguments}")
ERROR---result=<clang.cindex.LP_c_void_p object at 0x10b1aa9d8>, func=<_FuncPtr object at 0x10b1bf5c0>, arguments=(<clang.cindex.Index object at 0x10aea1e48>, None, <clang.cindex.c_char_p_Array_62 object at 0x10b1aa620>, 62, None, 0, 0)
(Pdb) result.contents
*** ValueError: NULL pointer access

有一个未决的FIXME comment几年前添加了关于 libclang 的 clang_parseTranslationUnit 固有的可调试性差距。

# FIXME: Make libclang expose additional error information in this scenario.

关于这篇文章 Dealing with parse errors with Python bindings of libclang 进行了一些讨论.最好的建议似乎来自将调试器附加到 libclang 的想法:

...you might be able to get a debugger to break on clang_parseTranslationUnit and inspect the error state there.



要深入了解一些内部结构,基本上 libclang 是通过 ctypes call 加载到 python 中的。到 cdll.LoadLibrary 创建一个 CDLL实例。然后,在 functionList 中定义为一组元组的一组硬编码函数全部通过 register_functions 注册,以赋予它们更深的 python 存在。实际的 TranslationUnitLoadError 得到 raised在类方法 TranslationUnit.from_source 中直接调用行中的 libclang 函数

ptr = conf.lib.clang_createTranslationUnit(index, fspath(filename))

我相信这是可调试性被截断的地方,因为底层 source因为 python 绑定(bind)是 C,而不是 C++,所以没有像 SEHException 这样冒泡的异常处理。对于 .net 会。使用该运行时,您可以调试非托管代码。然而这里没有等价物。

您可以从其 source 的调用堆栈向下追踪翻译单元变量 TU ...

CXTranslationUnit
clang_parseTranslationUnit(CXIndex CIdx,
const char *source_filename,
const char *const *command_line_args,
int num_command_line_args,
struct CXUnsavedFile *unsaved_files,
unsigned num_unsaved_files,
unsigned options) {
CXTranslationUnit TU;
enum CXErrorCode Result = clang_parseTranslationUnit2(
CIdx, source_filename, command_line_args, num_command_line_args,
unsaved_files, num_unsaved_files, options, &TU);

如果我发现任何更实质性的东西,我会更新这个答案。鉴于这种可调试性差距,像这样直接从 C++ 进行 libclang 分析可能会更有成效 fella可以,或者使用命令行工具 clang-query 详细说明 here

关于Windows 上的 python libclang 绑定(bind)无法从 sublime text 初始化翻译单元,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37774599/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com