-
Hi, #include "nanobind/nanobind.h"
namespace nb = nanobind;
using namespace nb::literals;
struct Scoreboard {
Scoreboard() = default;
};
NB_MODULE(base, m) {
nb::class_<Scoreboard>(m, "Scoreboard", nanobind::dynamic_attr())
.def(nanobind::init<>{});
} import typing
from base import Scoreboard
from dataclasses import dataclass
import dill # pip install dill
import nanobind
class ScoreboardV1(Scoreboard):
pass
@dataclass
class Struct:
scoreboard: typing.Type[Scoreboard]
struct = Struct(scoreboard=ScoreboardV1)
try:
bytes1 = dill.dumps(struct)
struct1 = dill.loads(bytes1)
except Exception as e:
# error out here with msg:
# Can't pickle <class 'nanobind.nb_type_0'>: it's not found as nanobind.nb_type_0
print(f"dill error:\n{e}")
else:
print("dill success") So what is the What is interesting is that if I manually set import nanobind
enable_work_around = True
if enable_work_around:
meta_cls = type(Scoreboard)
setattr(nanobind, "nb_type_0", meta_cls) |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 6 replies
-
It is the nanobind metaclass. In other words, the class that constructs the Python type |
Beta Was this translation helpful? Give feedback.
It is the nanobind metaclass. In other words, the class that constructs the Python type
A
when you callnb::class_<A>
. It cannot be pickled, and I am not sure how it could be pickled. That's because we don't just havenb_type_0
-- it's part of a family of metaclassesnb_type_N
that are created on demand based how how many extra bytes of storageN
are required inside the type object. That extra storage could include arbitrary pointers that don't make sense across Python sessions. All of this is deep inside the C++ guts of nanobind and not accessible through normal Python code.