Является ли эта ошибка Boost :: Python (Python 3.7) "__init __ () должна возвращать None, а не NoneType" проблемой компоновки? - PullRequest
0 голосов
/ 15 февраля 2019

Обновление

Я не собираюсь добавлять это в качестве ответа, так как до сих пор технически не решил проблему.Но так как я потратил 2,5 дня, пытаясь заставить вещи работать с boost-python3, я потерял желание жить с ним.

Я только что столкнулся с pybind11 (как мои предыдущие длительные поиски инструментов связывания Python не включили его, я не знаю), и я использую это.2,5 дня страданий сравниваются с <20 минутами установки и сборки их <a href="https://github.com/pybind/cmake_example" rel="nofollow noreferrer"> примера cmake ... и весь специфический ад-python-version-dependency-hell исчез.

Это синтаксически похоже на boost-Python, но намного проще в управлении, быстрее, только для заголовков и более многофункциональным.

Yay!

Оригинальный вопрос

Я использую boost :: pythonсвязать класс в Python 3.7.2.

Класс импортируется успешно, но его создание приводит к следующей ошибке:

<my-terminal>$ python
Python 3.7.2 (default, Feb 14 2019, 17:36:47) 
[Clang 10.0.0 (clang-1000.11.45.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import classes
>>> t = classes.World()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __init__() should return None, not 'NoneType'
>>> 

Вот classes.cpp:

#include <boost/python.hpp>
#include <boost/python/list.hpp>
#include <boost/python/extract.hpp>
#include <string>
#include <sstream>
#include <vector>

struct World
{
    void set(std::string msg) { mMsg = msg; }
    void many(boost::python::list msgs) {
        long l = len(msgs);
        std::stringstream ss;
        for (long i = 0; i<l; ++i) {
            if (i>0) ss << ", ";
            std::string s = boost::python::extract<std::string>(msgs[i]);
            ss << s;
        }
        mMsg = ss.str();
    }
    std::string greet() { return mMsg; }
    std::string mMsg;
};

using namespace boost::python;

BOOST_PYTHON_MODULE(classes)
{
    class_<World>("World")
        .def("greet", &World::greet)
        .def("set", &World::set)
        .def("many", &World::many)
    ;
};

Гипотеза

Этот почти идентичный вопрос был решен из-за проблемы Python 2/3 (связывание с Python 3 вместо библиотек Python 2).Поэтому я заподозрил проблему с подключением библиотеки.

Проверка гипотезы

Я не могу заставить работать bjam, и все равно не смог бы переключить все наши системы сборки для одного модуля... поэтому я собираюсь с помощью cmake, который успешно компилируется в classes.so с выводом следующим образом, предлагая найти все правильные включения, библиотеки и исполняемые файлы:

-- Found PythonInterp: /Users/me/.pyenv/versions/boost37/bin/python3 (found suitable version "3.7.2", minimum required is "3") 
PYTHON_VERSION_SUFFIX
-- Boost version: 1.68.0
-- Found the following Boost libraries:
--   python37
-- Found PythonLibs: /usr/local/Frameworks/Python.framework/Versions/3.7/lib/libpython3.7m.dylib (found suitable version "3.7.2", minimum required is "3") 
-- PYTHON_LIBRARIES = /usr/local/Frameworks/Python.framework/Versions/3.7/lib/libpython3.7m.dylib
-- PYTHON_EXECUTABLE = /Users/thc29/.pyenv/versions/boost37/bin/python3
-- PYTHON_INCLUDE_DIRS = /usr/local/Frameworks/Python.framework/Versions/3.7/include/python3.7m
-- Boost_LIBRARIES = /usr/local/lib/libboost_python37-mt.dylib

Содержимое каталога библиотеки Boost-python3:

ls /usr/local/Cellar/boost-python3/1.68.0/lib
libboost_numpy37-mt.a       libboost_numpy37.dylib      libboost_python37.a
libboost_numpy37-mt.dylib   libboost_python37-mt.a      libboost_python37.dylib
libboost_numpy37.a      libboost_python37-mt.dylib

Я использовал brew install boost и brew install boost-python3 --build-from-source с моим активированным python 3.7 virtualenv, чтобы гарантировать, что boost-python3 связан с правильной версией python.

Проверка библиотек ...

otool -L classes.so дает:

classes.so:
    /usr/l/opt/boost-python3/lib/libboost_python37-mt.dylib (compatibility version 0.0.0, current version 0.0.0)
    /usr/local/opt/python/Frameworks/Python.framework/Versions/3.7/Python (compatibility version 3.7.0, current version 3.7.0)
    /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.4)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.200.5)

otool -L /usr/local/opt/boost-python3/lib/libboost_python37-mt.dylib дает:

/usr/local/opt/boost-python3/lib/libboost_python37-mt.dylib:
        /usr/local/opt/boost-python3/lib/libboost_python37-mt.dylib (compatibility version 0.0.0, current version 0.0.0)
        /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.4)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.200.5)

В связанном вопросе, который показал свою проблему.Но здесь все выглядит хорошо!

Никакого прогресса пока нет ...

После мучительного процесса правильной компиляции и проверки ссылок я не могу обнаружить никаких недостатков.Это другая проблема?Или есть проблема со ссылками, которую я не заметил?

Спасибо за любую помощь!

...