LINUX.ORG.RU

Импорт модулей в boost::python, замена imp на import.util

 ,


0

3

Есть некоторый legacy код на С++, использующий boost::python и импортирующий самописные пиноновские модули спользуя модуль imp.

Делалось это примерно так:

test_module.py:

def test_out(expr):
    print(expr)

test_imp.cpp:

#include <boost/python.hpp>
#include <stdio.h>

int main()
{
    Py_InitializeEx(0);
    try {
        boost::python::object modImp = boost::python::import("imp");
        PyImport_AddModule("test_module");

        modImp.attr("load_source")("test_module", "test_module.py");

        boost::python::exec("test_out(\"Hello, world!\")", boost::python::import("test_module").attr("__dict__"));
    }
    catch (const boost::python::error_already_set&)
    {
        PyErr_Print();
    }
    Py_Finalize();
}

Но начиная с 3.12’го питона имодуль imp изъяли из обращения. Я попытался переехать на importlib.util как рекомендовано тут, в меру своего понмания переложив это на С++ный код. Получилось что-то вроде этого:

test_import.cpp:

#include <boost/python.hpp>
#include <stdio.h>

int main()
{
    Py_InitializeEx(0);

    try {
        boost::python::object modImpUtil = boost::python::import("importlib.util");

        PyImport_AddModule("test_module");

        boost::python::object spec = modImpUtil.attr("spec_from_file_location")("test_module", "test_module.py");
        boost::python::object mod = modImpUtil.attr("module_from_spec")(spec);
        spec.attr("loader").attr("exec_module")(mod);

        boost::python::exec("test_out(\"Hello, World!\")", boost::python::import("test_module").attr("__dict__"));
    }
    catch (const boost::python::error_already_set&)
    {
        PyErr_Print();
    }
    Py_Finalize();
}

Получилось, но не работает. Пишет NameError: name 'test_out' is not defined

Команды для сборки обоих сишников:

g++ test_imp.cpp -I /usr/include/x86_64-linux-gnu/python3.11 -I /usr/include/python3.11 -lpython3.11 -lboost_python311 -lboost_system -o test_imp

g++ test_import.cpp -I /usr/include/x86_64-linux-gnu/python3.11 -I /usr/include/python3.11 -lpython3.11 -lboost_python311 -lboost_system -o test_import

Я далек от программирования на питоне, поэтому могу упустить что-нибудь очевидное. Но этот код кто-то должен поддерживать. Поэтому с благодарностью приму помощь…

★★★
Ответ на: комментарий от qulinxao3

а сам importlib че не заимпортен как importlib.util ?

А вроде не нужен он, если следовать нити примера… Да и пробовал, не помогает…

shaplov ★★★
() автор топика
Последнее исправление: shaplov (всего исправлений: 1)
Ответ на: комментарий от shaplov

хм чисто телепатно

importlib инициализирует всю машинерию

и если ошибка с ним есть то его убирание «удваивает ошибку»

а сама кста boost/python ваще в курсах что у питона машинерия импортов поплыла(в очередной раз?!)

в телеге есть мелкие(на 1-2к) группы питон ассов :)

qulinxao3 ★★
()
Ответ на: комментарий от qulinxao3

и если ошибка с ним есть то его убирание «удваивает ошибку»

Хорошо… Пусть. Так как правильно запрячь эту лошадь?

в телеге есть мелкие(на 1-2к) группы питон ассов :)

Если какие-то задницы используют не свободное ПО, это не повод делать так же. Пусть они там придаются массовым копирастическим утехам без меня…

shaplov ★★★
() автор топика
Ответ на: комментарий от anonymous

Попробуй не test_out, а test_module.test_out. Предполагаю, что importlib не вносит объекты модуля в глобальное пространство имён.

Не прокатило:

NameError: name 'test_module' is not defined

Видимо и test_module в пространство имен не попадает…

shaplov ★★★
() автор топика