Boost.Python TypeError:__init __()应该返回None而不是'NoneType'-但没有明显的链接器或版本问题 [英] Boost.Python TypeError: __init__() should return None not 'NoneType' - but no obvious linker or version problem

查看:97
本文介绍了Boost.Python TypeError:__init __()应该返回None而不是'NoneType'-但没有明显的链接器或版本问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建用于通过python3.7安装的boost接口进行python访问的c ++引擎.这是为:

I'm building a c++ engine for python access via the boost interfaces for a python3.7 installation. This is building for:

Mac OS Mojave  -  10.14.6
Python 3.7.4
Conda 4.8.3 (only crashes in a conda-built environment)
C++: clang version 11.0.0 (clang-1100.0.33.17)
Boost version 1.67.0

python代码失败(据我所知),仅 __ init __ 函数中使用

The python code fails (from what I can tell) only in __init__ functions, with

Traceback (most recent call last):
  File "<string>", line 1, in <module>
TypeError: __init__() should return None, not 'NoneType'

其他堆栈溢出报告(请参阅下面的参考书目)和github线程表明,典型的问题是python版本之间的.dylibs链接错误,或者没有提供答案.但是dylib的不兼容性在这里似乎并非如此.otool -L(或ldd)表示库绑定是一致的,并且应该都很好.这是代码和构建步骤.

Other stack-overflow reports (see biblio below) and github threads suggest the typical issue is a mis-link in .dylibs between python versions, or provide no answers. But dylib incompatibility doesn't seem to be the case here. otool -L (or ldd) indicates library bindings are consistent and all should be well. Here's the code and build steps.

最小代码(在python版本上带有一个小的检查"功能):

Minimal code (with a small "check" function on python version):

#include <iomanip>
#include <patchlevel.h>
#include <boost/python/def.hpp>
#include <boost/python/module.hpp>
#include <boost/python/class.hpp>

namespace R3 {
  class DistanceType {
  public:
    DistanceType(double _val = 0) : val(_val) {}
    double get() const { return val; }
    void set(double _val) { val = _val; }
  private:
    double val;
  };
  void pyversion() {
    int hexversion = PY_VERSION_HEX;
    std::cout << "compiled with python version: " << PY_VERSION
      << " (hex version code) " << std::hex << std::setw(8) << hexversion << '\n';
  }
}

BOOST_PYTHON_MODULE(simplepython) {
  using namespace boost::python;

  class_<R3::DistanceType>("DistanceType", init<double>())
    .add_property("value", &R3::DistanceType::get, &R3::DistanceType::set)
  ;

  boost::python::def("pyversion", R3::pyversion);
}

以下是构建和运行代码的结果:

Here are the results from building and running the code:

>: g++ -I/opt/anaconda3/include/python3.7m -I/opt/anaconda3/include/python3.7m -O2 -fPIC -std=c++11  -Iinclude   -c -o objs/simplepython.o src/simplepython.cpp
>: g++ -Wl,-rpath,/opt/anaconda3/lib -shared -o lib/simplepython.so objs/simplepython.o -L/opt/anaconda3/lib -Llib -lpython3.7m -ldl -framework CoreFoundation -lboost_python37 -lboost_numpy37
>: cd lib
>: python -c 'import simplepython as R3; R3.pyversion(); R3.DistanceType(1)'
compiled with python version: 3.7.4 (hex version code)  30704f0
Traceback (most recent call last):
  File "<string>", line 1, in <module>
TypeError: __init__() should return None, not 'NoneType'

参考书目-相关的堆栈溢出问题报告:

Bibliography - related stack-overflow issue reports:

TypeError:__init __()应该返回None,而不是使用Python Boost的"NoneType"

这是增强吗:: Python(Python 3.7)错误"__init __()应该返回None,而不是'NoneType'".链接问题?

Boost.Python __init __()应该返回None,而不是'NoneType'

推荐答案

事实证明,错误在于静态链接库libpython< version >.为了与conda和非conda环境兼容,c ++/boost构建应动态解析这些符号.以下为我解决了这个问题:

It turns out the error is with the static linked library, libpython<version>. For compatibility with conda and non-conda environments, a c++/boost build should resolve these symbols dynamically. The following solved it for me:

在链接行中,将 -lpython< version> m 替换为 -undefined dynamic_lookup.

In your link line, replace -lpython<version>m with -undefined dynamic_lookup.

CMake :

链接行位于/build/mybinary/CMakeFiles/myextension_py.dir/link.txt 中.目前,似乎必须在CMake版本 3.17.2 中手动编辑link命令.

The link line is available in /build/mybinary/CMakeFiles/myextension_py.dir/link.txt. For now it seems that the link command has to be manually edited in CMake version 3.17.2.

注意:

如果您使用 $(shell python3-config --libs)导出 -l <​​/code>路径,则可能无法解决该问题:在3.8版之前,它包含 -lpython< version> m .由于这种不一致,我暂时只使用自己的扩展数据.

If you use $(shell python3-config --libs) to derive the -l paths, it may defeat the solution: prior to version 3.8 it includes -lpython<version>m. Due to this inconsistency I simply use my own expanded data for the time being.

积分:

感谢 Nehal J Wani 最初报告了此解决方案

Thanks to Nehal J Wani who originally reported this solution here.

感谢 newkid 进行CMake编辑-我在其他帖子中将其复制到了这里.

Thanks newkid for the CMake edit - I copied it here from the other posting.

这篇关于Boost.Python TypeError:__init __()应该返回None而不是'NoneType'-但没有明显的链接器或版本问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆