Boost.Python TypeError:__init __()应该返回None而不是'NoneType'-但没有明显的链接器或版本问题 [英] Boost.Python TypeError: __init__() should return None not 'NoneType' - but no obvious linker or version problem
问题描述
我正在构建用于通过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屋!