32#include "pybind11/pybind11.h"
34#include "ndarray/pybind11.h"
47using namespace pybind11::literals;
53using cpputils::python::WrapperCollection;
57using PyBaseRecord = py::class_<BaseRecord, std::shared_ptr<BaseRecord>>;
58using PyBaseTable = py::class_<BaseTable, std::shared_ptr<BaseTable>>;
61void declareBaseRecordOverloads(PyBaseRecord &cls,
std::string const &suffix) {
62 using Getter =
typename Field<T>::Value (BaseRecord::*)(const Key<
T> &) const;
63 using Setter = void (BaseRecord::*)(const Key<
T> &, const typename Field<
T>::Value &);
69void declareBaseRecordArrayOverloads(PyBaseRecord &cls,
std::string const &suffix) {
70 auto getter = [](BaseRecord &self, Key<Array<T>>
const &key) -> ndarray::Array<T, 1, 1> {
73 auto setter = [](BaseRecord &self, Key<Array<T>>
const &key, py::object
const &
value) {
74 if (key.getSize() == 0) {
77 self.set(key, py::cast<ndarray::Array<T, 1, 1>>(value));
82 auto v = py::cast<ndarray::Array<T const, 1, 0>>(
value);
83 ndarray::ArrayRef<T, 1, 1>
ref = self[key];
84 if (v.size() !=
ref.size()) {
86 pex::exceptions::LengthError,
87 (boost::format(
"Array sizes do not agree: %s != %s") % v.size() %
ref.size()).str());
93 cls.def((
"get" + suffix).c_str(), getter);
94 cls.def((
"set" + suffix).c_str(), setter);
97PyBaseRecord declareBaseRecord(WrapperCollection &wrappers) {
98 return wrappers.wrapType(PyBaseRecord(wrappers.module,
"BaseRecord"), [](
auto &mod,
auto &cls) {
99 cpputils::python::addSharedPtrEquality<BaseRecord>(cls);
100 cls.def(
"assign", (void (BaseRecord::*)(BaseRecord const &)) & BaseRecord::assign);
102 (void (BaseRecord::*)(BaseRecord const &, SchemaMapper const &)) & BaseRecord::assign);
103 cls.def(
"getSchema", &BaseRecord::getSchema);
104 cls.def(
"getTable", &BaseRecord::getTable);
105 cls.def_property_readonly(
"schema", &BaseRecord::getSchema);
106 cls.def_property_readonly(
"table", &BaseRecord::getTable);
108 declareBaseRecordOverloads<double>(cls,
"D");
109 declareBaseRecordOverloads<float>(cls,
"F");
110 declareBaseRecordOverloads<lsst::afw::table::Flag>(cls,
"Flag");
111 declareBaseRecordOverloads<std::uint8_t>(cls,
"B");
112 declareBaseRecordOverloads<std::uint16_t>(cls,
"U");
113 declareBaseRecordOverloads<std::int32_t>(cls,
"I");
114 declareBaseRecordOverloads<std::int64_t>(cls,
"L");
115 declareBaseRecordOverloads<std::string>(cls,
"String");
116 declareBaseRecordOverloads<lsst::geom::Angle>(cls,
"Angle");
117 declareBaseRecordArrayOverloads<std::uint8_t>(cls,
"ArrayB");
118 declareBaseRecordArrayOverloads<std::uint16_t>(cls,
"ArrayU");
119 declareBaseRecordArrayOverloads<int>(cls,
"ArrayI");
120 declareBaseRecordArrayOverloads<float>(cls,
"ArrayF");
121 declareBaseRecordArrayOverloads<double>(cls,
"ArrayD");
122 cpputils::python::addOutputOp(cls,
"__str__");
126 auto getter = [](py::object const &self, py::object key) -> py::object {
127 py::object schema = self.attr(
"schema");
128 if (py::isinstance<py::str>(key) || py::isinstance<py::bytes>(key)) {
129 key = schema.attr(
"find")(key).attr(
"key");
131 return key.attr(
"get")(self);
133 auto setter = [](py::object
const &self, py::object key, py::object
const &
value) ->
void {
134 py::object
schema = self.attr(
"schema");
135 if (py::isinstance<py::str>(key) || py::isinstance<py::bytes>(key)) {
136 key =
schema.attr(
"find")(key).attr(
"key");
138 key.attr(
"set")(self,
value);
144 cls.def(
"get", getter);
145 cls.def(
"__getitem__", getter);
146 cls.def(
"set", setter);
147 cls.def(
"__setitem__", setter);
151PyBaseTable declareBaseTable(WrapperCollection &wrappers) {
152 return wrappers.wrapType(PyBaseTable(wrappers.module,
"BaseTable"), [](
auto &mod,
auto &cls) {
153 cpputils::python::addSharedPtrEquality<BaseTable>(cls);
154 cls.def_static(
"make", &BaseTable::make);
155 cls.def(
"getMetadata", &BaseTable::getMetadata);
156 cls.def(
"setMetadata", &BaseTable::setMetadata,
"metadata"_a);
157 cls.def(
"popMetadata", &BaseTable::popMetadata);
158 cls.def_property(
"metadata", &BaseTable::getMetadata, &BaseTable::setMetadata);
159 cls.def(
"makeRecord", &BaseTable::makeRecord);
160 cls.def(
"copyRecord",
161 (std::shared_ptr<BaseRecord>(BaseTable::*)(BaseRecord const &)) & BaseTable::copyRecord);
162 cls.def(
"copyRecord",
163 (std::shared_ptr<BaseRecord>(BaseTable::*)(BaseRecord const &, SchemaMapper const &)) &
164 BaseTable::copyRecord);
165 cls.def(
"getSchema", &BaseTable::getSchema);
166 cls.def_property_readonly(
"schema", &BaseTable::getSchema);
167 cls.def(
"getBufferSize", &BaseTable::getBufferSize);
168 cls.def(
"clone", &BaseTable::clone);
169 cls.def(
"preallocate", &BaseTable::preallocate);
180 auto clsBaseCatalog = table::python::declareCatalog<BaseRecord>(wrappers,
"Base");
181 auto clsBaseColumnView = table::python::declareColumnView<BaseRecord>(wrappers,
"Base");
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Tag types used to declare specialized field types.
Field< T >::Value get(Key< T > const &key) const
Return the value of a field for the given key.
void set(Key< T > const &key, U const &value)
Set value of a field for the given key.
A helper class for subdividing pybind11 module across multiple translation units (i....
void addSignatureDependency(std::string const &name)
Indicate an external module that provides a type used in function/method signatures.
void wrapBase(WrapperCollection &wrappers)
T Value
the type returned by BaseRecord::get