ppap4lmp  0.7.2
pybind_json.cpp
Go to the documentation of this file.
1 
8 #include "json.h"
9 #include "pybind.h"
10 #include "pybind_json.h"
11 
12 
13 namespace pybind11
14 {
15  namespace detail
16  {
17  namespace impl
18  {
19  Json to_json(const py::handle& obj)
20  {
21  if (obj.is_none())
22  {
23  return nullptr;
24  }
25  else if (py::isinstance<py::bool_>(obj))
26  {
27  return obj.cast<bool>();
28  }
29  else if (py::isinstance<py::int_>(obj))
30  {
31  return obj.cast<int>();
32  }
33  else if (py::isinstance<py::float_>(obj))
34  {
35  return obj.cast<double>();
36  }
37  else if (py::isinstance<py::str>(obj))
38  {
39  return obj.cast<std::string>();
40  }
41  else if (py::isinstance<py::tuple>(obj) || py::isinstance<py::list>(obj))
42  {
43  Json out;
44 
45  for (const py::handle& value : obj)
46  {
47  out.push_back(to_json(value));
48  }
49 
50  return out;
51  }
52  else if (py::isinstance<py::dict>(obj))
53  {
54  Json out;
55 
56  for (const py::handle& key : obj)
57  {
58  out[key.cast<std::string>()] = to_json(obj[key]);
59  }
60 
61  return out;
62  }
63  else // fallback to slower method
64  {
65  try
66  {
67  return Json::parse(py::cast<std::string>(
68  py::module::import("json").attr("dumps")(py::cast<py::object>(obj))));
69  }
70  catch (...)
71  {
72  throw std::runtime_error(
73  "to_json not implemented for this type of object: "+ obj.cast<std::string>());
74  }
75  }
76  }
77 
78  py::object from_json(const Json& j)
79  {
80  if (j.is_null())
81  {
82  return py::none();
83  }
84  else if (j.is_boolean())
85  {
86  return py::bool_(j.get<bool>());
87  }
88  else if (j.is_number_integer())
89  {
90  return py::int_(j.get<int>());
91  }
92  else if (j.is_number_float())
93  {
94  return py::float_(j.get<double>());
95  }
96  else if (j.is_string())
97  {
98  return py::str(j.get<std::string>());
99  }
100  else if (j.is_array())
101  {
102  py::list obj;
103 
104  for (const auto& el : j)
105  {
106  obj.attr("append")(from_json(el));
107  }
108 
109  return obj;
110  }
111  else // object
112  {
113  py::dict obj;
114 
115  for (Json::const_iterator it = j.cbegin(); it != j.cend(); ++it)
116  {
117  obj[py::str(it.key())] = from_json(it.value());
118  }
119 
120  return obj;
121  }
122  }
123  }
124 
126  handle src, bool)
127  {
128  try
129  {
130  value = impl::to_json(src);
131  }
132  catch (...)
133  {
134  return false;
135  }
136 
137  return true;
138  }
139 
141  Json src, return_value_policy, handle)
142  {
143  return impl::from_json(src).release();
144  }
145  }
146 }
To bind Json to Python, a custom type caster of pybind11* is required.
static handle cast(Json src, return_value_policy, handle)
Casting a Json object from C++ to Python.
nlohmann::json Json
Json is an alias for nlohmann::json.
Definition: json.h:22
This file includes nlohmann/json and defines an alias for a JSON class.
bool load(handle src, bool)
Loading a Json object from Python to C++.
void runtime_error(const Str &msg)
Raise (for Python) and throw (for C++) a runtime error.
This file includes pybind11 and defines an alias for the namespace pybind11.