1 | /* Copyright 2019 The TensorFlow Authors. All Rights Reserved. |
2 | |
3 | Licensed under the Apache License, Version 2.0 (the "License"); |
4 | you may not use this file except in compliance with the License. |
5 | You may obtain a copy of the License at |
6 | |
7 | http://www.apache.org/licenses/LICENSE-2.0 |
8 | |
9 | Unless required by applicable law or agreed to in writing, software |
10 | distributed under the License is distributed on an "AS IS" BASIS, |
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | See the License for the specific language governing permissions and |
13 | limitations under the License. |
14 | ==============================================================================*/ |
15 | |
16 | #include "pybind11/pybind11.h" |
17 | #include "pybind11/pytypes.h" |
18 | |
19 | #ifndef TENSORFLOW_PYTHON_LIB_CORE_PYBIND11_LIB_H_ |
20 | #define TENSORFLOW_PYTHON_LIB_CORE_PYBIND11_LIB_H_ |
21 | |
22 | namespace py = pybind11; |
23 | |
24 | // SWIG struct so pybind11 can handle SWIG objects returned by tf_session |
25 | // until that is converted over to pybind11. |
26 | // This type is intended to be layout-compatible with an initial sequence of |
27 | // certain objects pointed to by a PyObject pointer. The intended use is to |
28 | // first check dynamically that a given PyObject* py has the correct type, |
29 | // and then use `reinterpret_cast<SwigPyObject*>(py)` to retrieve the member |
30 | // `ptr` for further, custom use. SWIG wrapped objects' layout is documented |
31 | // here: http://www.swig.org/Doc4.0/Python.html#Python_nn28 |
32 | typedef struct { |
33 | PyObject_HEAD void* ptr; // This is the pointer to the actual C++ obj. |
34 | void* ty; |
35 | int own; |
36 | PyObject* next; |
37 | PyObject* dict; |
38 | } SwigPyObject; |
39 | |
40 | namespace tensorflow { |
41 | |
42 | // Convert PyObject* to py::object with no error handling. |
43 | |
44 | inline py::object Pyo(PyObject* ptr) { |
45 | return py::reinterpret_steal<py::object>(ptr); |
46 | } |
47 | |
48 | // Raise an exception if the PyErrOccurred flag is set or else return the Python |
49 | // object. |
50 | |
51 | inline py::object PyoOrThrow(PyObject* ptr) { |
52 | if (PyErr_Occurred() || ptr == nullptr) { |
53 | throw py::error_already_set(); |
54 | } |
55 | return Pyo(ptr); |
56 | } |
57 | |
58 | [[noreturn]] inline void ThrowTypeError(const char* error_message) { |
59 | PyErr_SetString(PyExc_TypeError, error_message); |
60 | throw pybind11::error_already_set(); |
61 | } |
62 | |
63 | [[noreturn]] inline void ThrowValueError(const char* error_message) { |
64 | PyErr_SetString(PyExc_ValueError, error_message); |
65 | throw pybind11::error_already_set(); |
66 | } |
67 | |
68 | } // namespace tensorflow |
69 | |
70 | #endif // TENSORFLOW_PYTHON_LIB_CORE_PYBIND11_LIB_H_ |
71 | |