Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What about enumerations? #59

Open
barnou-psee opened this issue Oct 11, 2022 · 0 comments
Open

What about enumerations? #59

barnou-psee opened this issue Oct 11, 2022 · 0 comments

Comments

@barnou-psee
Copy link

Hi,

I must say I really like the idea of this utility to ease my parameters structures usage in Python. I encountered an issue with bound enumerations. I use enumerations quite a lot in C++ mainly in factories. I can easily have a nlohmann converters for them, I can easily bind them, but I'm lost when trying to have the two functionalities working together.

It's quite logic since the nlohmann json bindings expect classic types and I guess enumerations fall into a special structures. I tried to get how I could handle those errors but I struggle finding how I could do that.

module.cpp

#include 

#include "nlohmann/json.hpp"
// This is where I copied pybind11_json.hpp
#include "converters/json.h"

#define MODULE_NAME footest

namespace testing_pybind11_json {

enum class Foo : uint32_t { ZERO, ONE, TWO, THREE };
NLOHMANN_JSON_SERIALIZE_ENUM(Foo,
{{Foo::ZERO, "ZERO"},
{Foo::ONE, "ONE"},
{Foo::TWO, "TWO"},
{Foo::THREE, "THREE"}})

void print_json(const nlohmann::json &j) {
std::cout << std::endl << std::setw(4) << j.dump() << std::endl;
}

void print_dict(const py::dict &d) {
nlohmann::json j;
j = d;
std::cout << std::endl << std::setw(4) << j.dump() << std::endl;
}

} // namespace testing_pybind11_json

PYBIND11_MODULE(MODULE_NAME, m) {
Py_Initialize();
PyEval_InitThreads();

py::enum_<testing_pybind11_json::Foo>(m, "Foo")
    .value("ZERO", testing_pybind11_json::Foo::ZERO)
    .value("ONE", testing_pybind11_json::Foo::ONE)
    .value("TWO", testing_pybind11_json::Foo::TWO)
    .value("THREE", testing_pybind11_json::Foo::THREE);
m.def("print_json", &testing_pybind11_json::print_json);
m.def("print_dict", &testing_pybind11_json::print_dict);

}

footest_pytest.cpp

import footest
import pytest

@pytest.mark.module("binding.utils")
def pytestcase_testing_pybind11_print_json():
footest.print_json({'a': 1, 'b': 2})
footest.print_json({'a': 1, 'b': 2, 'c': footest.Foo.ONE})

@pytest.mark.module("binding.utils")
def pytestcase_testing_pybind11_print_dict():
footest.print_dict({'a': 1, 'b': 2})
footest.print_dict({'a': 1, 'b': 2, 'c': footest.Foo.ONE})

It returns me different type of error depending on the function I'm using.

With print_json: it tries to use directly type_caster but seems to fall in a strange case.

    @pytest.mark.module("binding.utils")
    def pytestcase_testing_pybind11_print_json():
        mci.print_json({'a': 1, 'b': 2})
>       mci.print_json({'a': 1, 'b': 2, 'c': mci.Foo.ONE})
E       TypeError: print_json(): incompatible function arguments. The following argument types are supported:
E           1. (arg0: json) -> None
E       
E       Invoked with: {'a': 1, 'b': 2, 'c': <Foo.ONE: 1>}

sdk/modules/computational_imaging/python/tests/bindings/calibration_pytest.py:148: TypeError

With print_dict: I avoid using type_caster but calls directly the to_json function which goes well until the incompatible enum.

    @pytest.mark.module("binding.utils")
    def pytestcase_testing_pybind11_print_dict():
        mci.print_dict({'a': 1, 'b': 2})
>       mci.print_dict({'a': 1, 'b': 2, 'c': mci.Foo.ONE})
E       RuntimeError: to_json not implemented for this type of object: <Foo.ONE: 1>

sdk/modules/computational_imaging/python/tests/bindings/calibration_pytest.py:154: RuntimeError

I don't know if it's even possible to catch the enumeration case and call the to_json / from_json of the underlying enumeration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant