quasardb 3.14.2.dev3__cp38-cp38-macosx_11_0_arm64.whl → 3.14.2.dev5__cp38-cp38-macosx_11_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of quasardb might be problematic. Click here for more details.

Files changed (105) hide show
  1. quasardb/CMakeFiles/CMakeDirectoryInformation.cmake +2 -2
  2. quasardb/Makefile +20 -20
  3. quasardb/__init__.py +21 -7
  4. quasardb/cmake_install.cmake +10 -4
  5. quasardb/date/CMakeFiles/CMakeDirectoryInformation.cmake +2 -2
  6. quasardb/date/CMakeFiles/Export/a52b05f964b070ee926bcad51d3288af/dateTargets.cmake +2 -2
  7. quasardb/date/Makefile +20 -20
  8. quasardb/date/cmake_install.cmake +10 -4
  9. quasardb/date/dateConfigVersion.cmake +0 -0
  10. quasardb/date/dateTargets.cmake +2 -2
  11. quasardb/extensions/writer.py +59 -61
  12. quasardb/firehose.py +24 -22
  13. quasardb/libqdb_api.dylib +0 -0
  14. quasardb/numpy/__init__.py +181 -120
  15. quasardb/pandas/__init__.py +145 -95
  16. quasardb/pool.py +13 -2
  17. quasardb/pybind11/CMakeFiles/CMakeDirectoryInformation.cmake +2 -2
  18. quasardb/pybind11/Makefile +20 -20
  19. quasardb/pybind11/cmake_install.cmake +7 -1
  20. quasardb/quasardb.cpython-38-darwin.so +0 -0
  21. quasardb/range-v3/CMakeFiles/CMakeDirectoryInformation.cmake +2 -2
  22. quasardb/range-v3/CMakeFiles/Export/d94ef200eca10a819b5858b33e808f5b/range-v3-targets.cmake +2 -2
  23. quasardb/range-v3/CMakeFiles/range.v3.headers.dir/build.make +18 -15
  24. quasardb/range-v3/Makefile +25 -25
  25. quasardb/range-v3/cmake_install.cmake +13 -7
  26. quasardb/range-v3/range-v3-config-version.cmake +0 -0
  27. quasardb/range-v3/range-v3-config.cmake +2 -2
  28. quasardb/stats.py +92 -80
  29. quasardb/table_cache.py +5 -1
  30. {quasardb-3.14.2.dev3.dist-info → quasardb-3.14.2.dev5.dist-info}/METADATA +3 -6
  31. quasardb-3.14.2.dev5.dist-info/RECORD +45 -0
  32. {quasardb-3.14.2.dev3.dist-info → quasardb-3.14.2.dev5.dist-info}/WHEEL +1 -1
  33. quasardb/CMakeLists.txt +0 -517
  34. quasardb/batch_column.hpp +0 -80
  35. quasardb/batch_inserter.hpp +0 -248
  36. quasardb/blob.hpp +0 -150
  37. quasardb/cluster.cpp +0 -102
  38. quasardb/cluster.hpp +0 -593
  39. quasardb/concepts.hpp +0 -322
  40. quasardb/continuous.cpp +0 -199
  41. quasardb/continuous.hpp +0 -109
  42. quasardb/convert/array.hpp +0 -299
  43. quasardb/convert/point.hpp +0 -330
  44. quasardb/convert/range.hpp +0 -282
  45. quasardb/convert/unicode.hpp +0 -598
  46. quasardb/convert/util.hpp +0 -22
  47. quasardb/convert/value.hpp +0 -782
  48. quasardb/convert.hpp +0 -38
  49. quasardb/detail/invoke.hpp +0 -0
  50. quasardb/detail/qdb_resource.hpp +0 -129
  51. quasardb/detail/retry.cpp +0 -30
  52. quasardb/detail/retry.hpp +0 -147
  53. quasardb/detail/sleep.hpp +0 -53
  54. quasardb/detail/ts_column.hpp +0 -224
  55. quasardb/detail/writer.cpp +0 -440
  56. quasardb/detail/writer.hpp +0 -550
  57. quasardb/direct_blob.hpp +0 -108
  58. quasardb/direct_handle.hpp +0 -83
  59. quasardb/direct_integer.hpp +0 -94
  60. quasardb/dispatch.hpp +0 -157
  61. quasardb/double.hpp +0 -87
  62. quasardb/entry.hpp +0 -273
  63. quasardb/error.hpp +0 -393
  64. quasardb/handle.cpp +0 -29
  65. quasardb/handle.hpp +0 -98
  66. quasardb/integer.hpp +0 -88
  67. quasardb/logger.cpp +0 -106
  68. quasardb/logger.hpp +0 -228
  69. quasardb/masked_array.hpp +0 -658
  70. quasardb/metrics.cpp +0 -103
  71. quasardb/metrics.hpp +0 -112
  72. quasardb/module.cpp +0 -92
  73. quasardb/module.hpp +0 -24
  74. quasardb/node.hpp +0 -132
  75. quasardb/numpy.cpp +0 -6
  76. quasardb/numpy.hpp +0 -489
  77. quasardb/object_tracker.hpp +0 -282
  78. quasardb/options.hpp +0 -273
  79. quasardb/perf.hpp +0 -336
  80. quasardb/properties.cpp +0 -41
  81. quasardb/properties.hpp +0 -85
  82. quasardb/pytypes.hpp +0 -221
  83. quasardb/query.cpp +0 -420
  84. quasardb/query.hpp +0 -92
  85. quasardb/reader.cpp +0 -282
  86. quasardb/reader.hpp +0 -256
  87. quasardb/remove_cvref.hpp +0 -31
  88. quasardb/string.hpp +0 -160
  89. quasardb/table.cpp +0 -257
  90. quasardb/table.hpp +0 -366
  91. quasardb/tag.hpp +0 -77
  92. quasardb/timestamp.hpp +0 -97
  93. quasardb/traits.hpp +0 -642
  94. quasardb/ts_iterator.hpp +0 -193
  95. quasardb/utils/blob_deque.hpp +0 -96
  96. quasardb/utils/ostream.hpp +0 -17
  97. quasardb/utils/permutation.hpp +0 -50
  98. quasardb/utils/stable_sort.hpp +0 -25
  99. quasardb/utils/unzip_view.hpp +0 -89
  100. quasardb/utils.cpp +0 -28
  101. quasardb/utils.hpp +0 -174
  102. quasardb/writer.hpp +0 -354
  103. quasardb-3.14.2.dev3.dist-info/RECORD +0 -115
  104. {quasardb-3.14.2.dev3.dist-info → quasardb-3.14.2.dev5.dist-info}/LICENSE.md +0 -0
  105. {quasardb-3.14.2.dev3.dist-info → quasardb-3.14.2.dev5.dist-info}/top_level.txt +0 -0
quasardb/numpy.hpp DELETED
@@ -1,489 +0,0 @@
1
- /*
2
- *
3
- * Official Python API
4
- *
5
- * Copyright (c) 2009-2024, quasardb SAS. All rights reserved.
6
- * All rights reserved.
7
- *
8
- * Redistribution and use in source and binary forms, with or without
9
- * modification, are permitted provided that the following conditions are met:
10
- *
11
- * * Redistributions of source code must retain the above copyright
12
- * notice, this list of conditions and the following disclaimer.
13
- * * Redistributions in binary form must reproduce the above copyright
14
- * notice, this list of conditions and the following disclaimer in the
15
- * documentation and/or other materials provided with the distribution.
16
- * * Neither the name of quasardb nor the names of its contributors may
17
- * be used to endorse or promote products derived from this software
18
- * without specific prior written permission.
19
- *
20
- * THIS SOFTWARE IS PROVIDED BY QUASARDB AND CONTRIBUTORS ``AS IS'' AND ANY
21
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
- * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
24
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
- */
31
- #pragma once
32
-
33
- #include "concepts.hpp"
34
- #include "error.hpp"
35
- #include "traits.hpp"
36
- #include "qdb/ts.h"
37
- #include <pybind11/chrono.h>
38
- #include <pybind11/numpy.h>
39
- #include <pybind11/pybind11.h>
40
- #include <pybind11/pytypes.h>
41
- #include <time.h>
42
-
43
- // A datetime64 in numpy is modeled as a scalar array, which is not integrated
44
- // into pybind's adapters of numpy.
45
- //
46
- // In order to still be able to natively create numpy datetime64 instances, the
47
- // code below proxies the data structures that live inside the numpy code. This
48
- // will allow us to interact with the objects natively.
49
- //
50
- // This works both ways: we can accepts numpy.datetime64 as arguments, but also
51
- // create/return them.
52
- //
53
- // Sourced from:
54
- // https://raw.githubusercontent.com/numpy/numpy/master/numpy/core/include/numpy/arrayscalars.h
55
- // https://raw.githubusercontent.com/numpy/numpy/master/numpy/core/include/numpy/ndarraytypes.h
56
- // https://github.com/numpy/numpy/blob/master/numpy/core/include/numpy/npy_common.h#L1077
57
- //
58
- // Begin numpy proxy
59
- //
60
- // From:
61
- // https://raw.githubusercontent.com/numpy/numpy/master/numpy/core/include/numpy/ndarraytypes.h
62
- typedef enum
63
- {
64
- /* Force signed enum type, must be -1 for code compatibility */
65
- NPY_FR_ERROR = -1, /* error or undetermined */
66
-
67
- /* Start of valid units */
68
- NPY_FR_Y = 0, /* Years */
69
- NPY_FR_M = 1, /* Months */
70
- NPY_FR_W = 2, /* Weeks */
71
- /* Gap where 1.6 NPY_FR_B (value 3) was */
72
- NPY_FR_D = 4, /* Days */
73
- NPY_FR_h = 5, /* hours */
74
- NPY_FR_m = 6, /* minutes */
75
- NPY_FR_s = 7, /* seconds */
76
- NPY_FR_ms = 8, /* milliseconds */
77
- NPY_FR_us = 9, /* microseconds */
78
- NPY_FR_ns = 10, /* nanoseconds */
79
- NPY_FR_ps = 11, /* picoseconds */
80
- NPY_FR_fs = 12, /* femtoseconds */
81
- NPY_FR_as = 13, /* attoseconds */
82
- NPY_FR_GENERIC = 14 /* unbound units, can convert to anything */
83
- } NPY_DATETIMEUNIT;
84
-
85
- // From:
86
- // https://raw.githubusercontent.com/numpy/numpy/master/numpy/core/include/numpy/ndarraytypes.h
87
- typedef struct
88
- {
89
- NPY_DATETIMEUNIT base;
90
- int num;
91
- } PyArray_DatetimeMetaData;
92
-
93
- // numpy uses their own npy_int64, the definition of which I would like to omit (probing
94
- // these things is complex).
95
- //
96
- // For simplicity's sake, we typedef it as a std::int64_t, because the intention is for it
97
- // to be a 64bit int anyway.
98
- //
99
- // See also:
100
- // https://github.com/numpy/numpy/blob/master/numpy/core/include/numpy/npy_common.h#L1077
101
- typedef std::int64_t npy_datetime;
102
-
103
- // From:
104
- // https://raw.githubusercontent.com/numpy/numpy/master/numpy/core/include/numpy/arrayscalars.h
105
- typedef struct
106
- {
107
- PyObject_HEAD npy_datetime obval;
108
- PyArray_DatetimeMetaData obmeta;
109
- } PyDatetimeScalarObject;
110
-
111
- // End numpy proxy
112
-
113
- namespace qdb
114
- {
115
- namespace numpy
116
- {
117
- namespace detail
118
- {
119
- inline std::time_t mkgmtime(std::tm * t) noexcept
120
- {
121
- #ifdef _WIN32
122
- return _mkgmtime(t);
123
- #else
124
- return ::timegm(t);
125
- #endif
126
- }
127
-
128
- inline std::string to_string(py::dtype const & dt) noexcept
129
- {
130
- return dt.attr("name").cast<py::str>();
131
- }
132
-
133
- inline std::string to_string(py::type const & t) noexcept
134
- {
135
- return t.cast<py::str>();
136
- }
137
-
138
- }; // namespace detail
139
-
140
- namespace py = pybind11;
141
-
142
- static inline std::int64_t datetime64_to_int64(py::object v)
143
- {
144
- if (v.is_none())
145
- {
146
- throw qdb::invalid_argument_exception{"Unable to convert None object time datetime64"};
147
- };
148
-
149
- using namespace std::chrono;
150
- try
151
- {
152
- // Starting version 3.8, Python does not allow implicit casting from numpy.datetime64
153
- // to an int, so we explicitly do it here.
154
- return v.cast<std::int64_t>();
155
- }
156
- catch (py::cast_error const & /*e*/)
157
- {
158
- throw qdb::invalid_datetime_exception{v};
159
- }
160
- }
161
-
162
- // Takes a `py::dtype` and converts it to our own internal dtype tag
163
- inline decltype(auto) dtype_object_to_tag(py::dtype dt){
164
-
165
- };
166
-
167
- // Everything below is custom code
168
- namespace array
169
- {
170
-
171
- template <concepts::dtype T>
172
- using value_type_t = typename T::value_type;
173
-
174
- /**
175
- * Ensures that an array matches a certain dtype, raises an exception if not.
176
- */
177
- template <concepts::dtype T>
178
- py::array ensure(py::array const & xs)
179
- {
180
- py::dtype dt = xs.dtype();
181
-
182
- if (T::is_dtype(dt) == false) [[unlikely]]
183
- {
184
- std::string msg = std::string{"Provided np.ndarray dtype '"} + detail::to_string(dt)
185
- + std::string{"' incompatbile with expected dtype '"}
186
- + detail::to_string(T::dtype()) + std::string{"'"};
187
- throw qdb::incompatible_type_exception{msg};
188
- }
189
-
190
- return xs;
191
- };
192
-
193
- template <concepts::dtype T>
194
- [[nodiscard]] py::array ensure(py::handle const & h)
195
- {
196
- if (py::isinstance<py::array>(h)) [[likely]]
197
- {
198
- return ensure<T>(py::array::ensure(h));
199
- }
200
- else if (py::isinstance<py::list>(h))
201
- {
202
- return ensure<T>(py::cast<py::array>(h));
203
- }
204
-
205
- throw qdb::incompatible_type_exception{
206
- "Expected a numpy.ndarray or list, got: " + detail::to_string(py::type::of(h))};
207
- };
208
-
209
- /**
210
- * Fixed width dtypes, length is fixed based on the dtype. This does *not* mean that every
211
- * dtype has the same width, it can still be that this loop is used for float16 and int64
212
- * and whatnot.
213
- */
214
- template <concepts::dtype T>
215
- requires(concepts::fixed_width_dtype<T>)
216
- inline value_type_t<T> * fill_with_mask(value_type_t<T> const * input,
217
- bool const * mask,
218
- std::size_t size,
219
- std::size_t /* itemsize */,
220
- value_type_t<T> fill_value,
221
- value_type_t<T> * dst)
222
- {
223
- value_type_t<T> const * end = input + size;
224
-
225
- // XXX(leon): *HOT* loop, can we get rid of the conditional branch?
226
- for (auto cur = input; cur != end; ++cur, ++mask, ++dst)
227
- {
228
- *dst = *mask ? fill_value : *cur;
229
- }
230
-
231
- return dst;
232
- };
233
-
234
- /**
235
- * Variable-length encoding: significantly more tricky, since every array has a different
236
- * "length" for all items.
237
- */
238
- template <concepts::dtype T>
239
- requires(concepts::variable_width_dtype<T>)
240
- inline value_type_t<T> * fill_with_mask(value_type_t<T> const * input,
241
- bool const * mask,
242
- std::size_t size,
243
- std::size_t itemsize,
244
- value_type_t<T> fill_value,
245
- value_type_t<T> * dst)
246
- {
247
- // code_point == 4 for e.g. UTF-32, which implies "4 bytes per char". Because in such a
248
- // case, we are iterating using a wchar_t (which is already 4 bytes), we need to reduce
249
- // our "stride" size by this factor.
250
- std::size_t stride_size = itemsize / T::code_point_size;
251
-
252
- // pre-fill a vector with our fill value, which we will be copying into all the right
253
- // places into the resulting data.
254
- std::vector<value_type_t<T>> fill_value_(stride_size, fill_value);
255
-
256
- value_type_t<T> const * cur = input;
257
-
258
- // XXX(leon): *HOT* loop; is there a way to vectorize this stuff, and/or
259
- // get rid of some branches?
260
- //
261
- // One simple approach would be to pre-fill the destination array with
262
- // our fill value, so that we can get rid of a branch below.
263
- //
264
- // Is there a SIMD version possible here?
265
-
266
- for (std::size_t i = 0; i < size; ++i, cur += stride_size, ++mask, dst += stride_size)
267
- {
268
- if (*mask == true)
269
- {
270
- // We could probably get away with *just* setting *dst to the fill value, instead
271
- // of setting the whole range.
272
- std::copy(std::cbegin(fill_value_), std::cend(fill_value_), dst);
273
- }
274
- else
275
- {
276
- std::copy(cur, cur + stride_size, dst);
277
- }
278
- }
279
-
280
- return dst;
281
- };
282
-
283
- template <concepts::dtype T>
284
- inline py::array fill_with_mask(
285
- py::array const & input, py::array const & mask, value_type_t<T> fill_value)
286
- {
287
- array::ensure<T>(input);
288
-
289
- py::array::ShapeContainer shape{{input.size()}};
290
- py::array ret{input.dtype(), shape};
291
-
292
- assert(input.size() == mask.size());
293
- assert(input.size() == ret.size());
294
-
295
- fill_with_mask<T>(static_cast<value_type_t<T> const *>(input.data()),
296
- static_cast<bool const *>(mask.data()), static_cast<std::size_t>(input.size()),
297
- static_cast<std::size_t>(input.itemsize()), fill_value,
298
- static_cast<value_type_t<T> *>(ret.mutable_data()));
299
- return ret;
300
- };
301
-
302
- template <concepts::dtype T>
303
- static inline py::array fill_with_mask(py::array const & input, py::array const & mask)
304
- {
305
- return fill_with_mask(input, mask, T::null_value());
306
- };
307
-
308
- template <typename ValueType>
309
- static void fill(py::array & xs, ValueType x) noexcept
310
- {
311
- // For now, don't support multi-dimensional arrays (e.g. matrices) and
312
- // only plain vanilla arrays. Apart from some additional wrestling with
313
- // numpy / pybind APIs, it's possible to implement though.
314
- assert(xs.ndim() == 1);
315
-
316
- std::size_t n = xs.shape(0);
317
-
318
- if (n > 0) [[likely]]
319
- {
320
- ValueType * y = xs.mutable_unchecked<ValueType>().mutable_data();
321
- std::fill(y, y + n, x);
322
- }
323
- }
324
-
325
- // Create empty array, do not fill any values.
326
- template <typename ValueType>
327
- requires(std::is_trivial_v<ValueType>)
328
- static py::array initialize(py::array::ShapeContainer shape) noexcept
329
- {
330
- return py::array(py::dtype::of<ValueType>(), shape);
331
- }
332
-
333
- // Create empty array, filled with `x`
334
- template <typename ValueType>
335
- requires(std::is_trivial_v<ValueType>)
336
- static py::array initialize(py::array::ShapeContainer shape, ValueType x) noexcept
337
- {
338
- py::array xs = initialize<ValueType>(shape);
339
- fill(xs, x);
340
- return xs;
341
- }
342
-
343
- // Create empty array, do not fill any values.
344
- template <typename ValueType>
345
- requires(std::is_trivial_v<ValueType>)
346
- static py::array initialize(py::ssize_t size) noexcept
347
- {
348
- return initialize<ValueType>({size});
349
- }
350
-
351
- // Create empty array, filled with `x`
352
- template <typename ValueType>
353
- requires(std::is_trivial_v<ValueType>)
354
- static py::array initialize(py::ssize_t size, ValueType x) noexcept
355
- {
356
- return initialize<ValueType>(py::array::ShapeContainer{size}, x);
357
- }
358
-
359
- template <concepts::dtype T>
360
- static py::array initialize(py::array::ShapeContainer shape, value_type_t<T> x) noexcept
361
- {
362
- py::array xs = py::array(T::dtype(), shape);
363
- fill(xs, x);
364
-
365
- return xs;
366
- }
367
-
368
- template <concepts::dtype D>
369
- static py::array initialize(py::ssize_t size, value_type_t<D> x) noexcept
370
- {
371
- return initialize<D>(py::array::ShapeContainer{size}, x);
372
- }
373
-
374
- template <concepts::dtype T>
375
- requires(concepts::fixed_width_dtype<T>)
376
- py::array of_list(py::list xs)
377
- {
378
- using value_type = typename T::value_type;
379
- std::array<py::ssize_t, 1> shape{{static_cast<py::ssize_t>(xs.size())}};
380
- py::array xs_(T::dtype(), shape);
381
- value_type * xs__ = xs_.mutable_unchecked<value_type>().mutable_data();
382
-
383
- std::transform(std::begin(xs), std::end(xs), xs__, [](py::handle x) -> value_type {
384
- if (x.is_none())
385
- {
386
- return T::null_value();
387
- }
388
- else
389
- {
390
- return py::cast<value_type>(x);
391
- };
392
- });
393
-
394
- return ensure<T>(xs_);
395
- };
396
-
397
- template <concepts::dtype T>
398
- requires(concepts::fixed_width_dtype<T>)
399
- std::pair<py::array, py::array> of_list_with_mask(py::list xs)
400
- {
401
- std::array<py::ssize_t, 1> shape{{static_cast<py::ssize_t>(xs.size())}};
402
-
403
- py::array data = of_list<T>(xs);
404
- py::array mask = py::array{py::dtype::of<bool>(), shape};
405
- bool * mask_ = static_cast<bool *>(mask.mutable_data());
406
-
407
- auto is_none = [](py::handle x) -> bool { return x.is_none(); };
408
-
409
- std::transform(std::begin(xs), std::end(xs), mask_, is_none);
410
-
411
- return std::make_pair(data, mask);
412
- };
413
-
414
- } // namespace array
415
-
416
- namespace detail
417
- {
418
-
419
- inline static PyTypeObject * get_datetime64_type() noexcept
420
- {
421
- // Note that this type is not shipped with pybind by default, and we made
422
- // local modifications to the pybind/numpy.hpp code to look up this
423
- // type at runtime.
424
- return py::detail::npy_api::get().PyDatetimeArrType_;
425
- }
426
-
427
- /**
428
- * Allocate a new numpy.datetime64 python object. This invokes the numpy code
429
- * dynamically loaded at runtime.
430
- */
431
- inline static PyDatetimeScalarObject * new_datetime64()
432
- {
433
- PyTypeObject * type = detail::get_datetime64_type();
434
- assert(type != nullptr);
435
-
436
- // Allocate memory
437
- PyObject * res = type->tp_alloc(type, 1);
438
- // Call constructor.
439
-
440
- // TODO(leon): this _might_ not be strictly necessary, as there might
441
- // be a better way to allocate this object.
442
- #if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 8
443
- PyObject * tmp = PyObject_INIT_VAR(res, type, sizeof(PyDatetimeScalarObject));
444
- #else
445
- PyVarObject * tmp = PyObject_INIT_VAR(res, type, sizeof(PyDatetimeScalarObject));
446
- #endif
447
-
448
- return reinterpret_cast<PyDatetimeScalarObject *>(tmp);
449
- }
450
-
451
- inline bool PyDatetime64_Check(PyObject * o)
452
- {
453
- // TODO(leon): validate that object is actually a PyDatetime64ScalarObject (how?)
454
- return true;
455
- }
456
-
457
- /**
458
- * Convert nanoseconds int64 to a numpy datetime. Returns a new reference to a PyObject *.
459
- */
460
- inline static PyObject * to_datetime64(std::int64_t ts)
461
- {
462
- PyDatetimeScalarObject * res = detail::new_datetime64();
463
-
464
- res->obmeta.num = 1; // refcount ?
465
- res->obmeta.base = NPY_FR_ns; // our timestamps are always in ns
466
- res->obval = ts;
467
-
468
- // Ensure that we create a new reference for the caller
469
- Py_INCREF(res);
470
-
471
- return reinterpret_cast<PyObject *>(res);
472
- }
473
-
474
- } // namespace detail
475
-
476
- class datetime64 : public py::object
477
- {
478
- public:
479
- PYBIND11_OBJECT_DEFAULT(datetime64, object, detail::PyDatetime64_Check)
480
-
481
- explicit datetime64(std::int64_t ts)
482
- : py::object(py::reinterpret_steal<py::object>(detail::to_datetime64(ts)))
483
- {}
484
-
485
- explicit datetime64(qdb_timespec_t const & ts);
486
- };
487
-
488
- } // namespace numpy
489
- } // namespace qdb