与 cppyy 混淆重载方法和错误处理

confusion with cppyy for overloaded methods and error handling

我有一个 c++ class 有几个构造函数:

MyClass(const std::string& configfilename);
MyClass(const MyClass& other);

我有 python 这个 class 的绑定是用 cppyy 生成的 - 我自己不这样做,这是我正在使用的框架的所有部分( CERN ROOT,如果你想知道的话)。

现在,我有一段 python 代码实例化了我的 class,带有一个很好的 try-except 块:

try:
  obj = MyClass(args.config)
except ConfigFileNotFoundError:
  print("config file "+args.config+" was not found!")
  exit(0)

现在,为了测试,我正在使用错误的配置文件执行此操作。但是我得到的大致是这样的:

TypeError: none of the 2 overloaded methods succeeded. Full details:
MyClass(const std::string&) => ConfigFileNotFoundError
MyClass::MyClass(const MyClass&) =>  TypeError

所以我想知道: 由于 cppyy 似乎用 try/except 块处理函数重载,是否有任何合理的方法来为此类应用程序进行错误处理?

我很想真正得到 ConfigFileNotFoundError 来正确处理它,而不是得到这个 TypeError。另外,是什么决定了我最终得到的实际错误 class - 它取决于重载在头文件中出现的顺序吗?

任何帮助、建议或关于在哪里可以找到更多信息的指示都将不胜感激。

cppyy 不使用 try/except 进行重载解析,因此也没有设置 __context____cause__。更准确地说:C++ 异常不是处理程序期间发生的错误。相反,as-yet 未解决的重载被优先考虑,然后按顺序尝试,不区分 Python 失败(例如,来自参数转换)或 C++ 失败(任何自动转换为 Python例外)。这是 run-time 模板实例化和 SFINAE 之前的历史工件:它允许在 pre-instantiated 模板中进行更详细的 run-time 类型匹配。

如果所有重载都失败(Python 或 C++),则汇总收集到的错误。 Python 仍然需要异常类型,但是,如果收集到的类型中的异常类型不同,则会引发通用 TypeError,消息字符串由所有收集到的异常组成。这就是这里发生的事情:C++ 在一个重载中引发了 ConfigFileNotFoundError,在另一个重载中由于参数转换失败 TypeError

cppyy 存储库现在有了改进;与 2.3.0 一起发布,在这种情况下(单个重载在参数匹配中成功但在被调用方中失败),你将获得实际的 ConfigFileNotFoundError 实例,只要其 class 是从 std::exception 公开派生的(但我认为它已经这样做了,否则您发布的错误报告看起来会大不相同)。

(请注意,CERN 的 ROOT 包含一个旧的 cppyy 分支,它有很多分歧;如果那个分支对你很重要,你必须请求他们在那里进行单独的更新。)