99#ifndef PYBIND11_JSON_HPP
1010#define PYBIND11_JSON_HPP
1111
12+ #include < set>
1213#include < string>
1314#include < vector>
1415
@@ -67,8 +68,12 @@ namespace pyjson
6768 }
6869 }
6970
70- inline nl::json to_json (const py::handle& obj)
71+ inline nl::json to_json (const py::handle& obj, std::set< const PyObject*>& refs )
7172 {
73+ if (auto [_, unique] = refs.insert (obj.ptr ()); !unique) {
74+ throw std::runtime_error (" Circular reference detected" );
75+ }
76+
7277 if (obj.ptr () == nullptr || obj.is_none ())
7378 {
7479 return nullptr ;
@@ -121,7 +126,7 @@ namespace pyjson
121126 auto out = nl::json::array ();
122127 for (const py::handle value : obj)
123128 {
124- out.push_back (to_json (value));
129+ out.push_back (to_json (value, refs ));
125130 }
126131 return out;
127132 }
@@ -130,12 +135,19 @@ namespace pyjson
130135 auto out = nl::json::object ();
131136 for (const py::handle key : obj)
132137 {
133- out[py::str (key).cast <std::string>()] = to_json (obj[key]);
138+ out[py::str (key).cast <std::string>()] = to_json (obj[key], refs );
134139 }
135140 return out;
136141 }
137142 throw std::runtime_error (" to_json not implemented for this type of object: " + py::repr (obj).cast <std::string>());
138143 }
144+
145+ inline nl::json to_json (const py::handle& obj)
146+ {
147+ std::set<const PyObject*> refs;
148+ return to_json (obj, refs);
149+ }
150+
139151}
140152
141153// nlohmann_json serializers
0 commit comments