quasardb 3.14.2.dev1__cp38-cp38-macosx_11_0_arm64.whl → 3.14.2.dev4__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 (95) hide show
  1. quasardb/CMakeFiles/CMakeDirectoryInformation.cmake +1 -1
  2. quasardb/Makefile +20 -20
  3. quasardb/__init__.py +33 -4
  4. quasardb/cmake_install.cmake +7 -1
  5. quasardb/date/CMakeFiles/CMakeDirectoryInformation.cmake +1 -1
  6. quasardb/date/CMakeFiles/Export/a52b05f964b070ee926bcad51d3288af/dateTargets.cmake +13 -13
  7. quasardb/date/Makefile +20 -20
  8. quasardb/date/cmake_install.cmake +7 -1
  9. quasardb/date/dateConfigVersion.cmake +9 -2
  10. quasardb/date/dateTargets.cmake +4 -8
  11. quasardb/libqdb_api.dylib +0 -0
  12. quasardb/numpy/__init__.py +58 -10
  13. quasardb/pandas/__init__.py +58 -102
  14. quasardb/pybind11/CMakeFiles/CMakeDirectoryInformation.cmake +1 -1
  15. quasardb/pybind11/Makefile +20 -20
  16. quasardb/pybind11/cmake_install.cmake +7 -1
  17. quasardb/quasardb.cpython-38-darwin.so +0 -0
  18. quasardb/range-v3/CMakeFiles/CMakeDirectoryInformation.cmake +1 -1
  19. quasardb/range-v3/CMakeFiles/Export/d94ef200eca10a819b5858b33e808f5b/range-v3-targets.cmake +13 -13
  20. quasardb/range-v3/CMakeFiles/range.v3.headers.dir/DependInfo.cmake +6 -2
  21. quasardb/range-v3/CMakeFiles/range.v3.headers.dir/build.make +7 -4
  22. quasardb/range-v3/Makefile +20 -20
  23. quasardb/range-v3/cmake_install.cmake +19 -1
  24. quasardb/range-v3/range-v3-config-version.cmake +9 -2
  25. quasardb/range-v3/range-v3-config.cmake +4 -8
  26. {quasardb-3.14.2.dev1.dist-info → quasardb-3.14.2.dev4.dist-info}/METADATA +5 -8
  27. quasardb-3.14.2.dev4.dist-info/RECORD +45 -0
  28. {quasardb-3.14.2.dev1.dist-info → quasardb-3.14.2.dev4.dist-info}/WHEEL +1 -1
  29. quasardb/CMakeLists.txt +0 -510
  30. quasardb/batch_column.hpp +0 -80
  31. quasardb/batch_inserter.hpp +0 -248
  32. quasardb/blob.hpp +0 -150
  33. quasardb/cluster.cpp +0 -89
  34. quasardb/cluster.hpp +0 -551
  35. quasardb/concepts.hpp +0 -278
  36. quasardb/continuous.cpp +0 -149
  37. quasardb/continuous.hpp +0 -106
  38. quasardb/convert/array.hpp +0 -282
  39. quasardb/convert/point.hpp +0 -330
  40. quasardb/convert/range.hpp +0 -282
  41. quasardb/convert/unicode.hpp +0 -598
  42. quasardb/convert/util.hpp +0 -22
  43. quasardb/convert/value.hpp +0 -711
  44. quasardb/convert.hpp +0 -38
  45. quasardb/detail/qdb_resource.hpp +0 -129
  46. quasardb/detail/ts_column.hpp +0 -224
  47. quasardb/direct_blob.hpp +0 -108
  48. quasardb/direct_handle.hpp +0 -83
  49. quasardb/direct_integer.hpp +0 -94
  50. quasardb/dispatch.hpp +0 -157
  51. quasardb/double.hpp +0 -87
  52. quasardb/entry.hpp +0 -273
  53. quasardb/error.hpp +0 -318
  54. quasardb/handle.cpp +0 -29
  55. quasardb/handle.hpp +0 -98
  56. quasardb/integer.hpp +0 -88
  57. quasardb/logger.cpp +0 -106
  58. quasardb/logger.hpp +0 -228
  59. quasardb/masked_array.hpp +0 -651
  60. quasardb/metrics.cpp +0 -103
  61. quasardb/metrics.hpp +0 -112
  62. quasardb/module.cpp +0 -76
  63. quasardb/module.hpp +0 -24
  64. quasardb/node.hpp +0 -123
  65. quasardb/numpy.cpp +0 -6
  66. quasardb/numpy.hpp +0 -489
  67. quasardb/object_tracker.hpp +0 -283
  68. quasardb/options.hpp +0 -244
  69. quasardb/perf.hpp +0 -336
  70. quasardb/pytypes.hpp +0 -221
  71. quasardb/query.cpp +0 -420
  72. quasardb/query.hpp +0 -92
  73. quasardb/reader/ts_row.hpp +0 -281
  74. quasardb/reader/ts_value.hpp +0 -245
  75. quasardb/remove_cvref.hpp +0 -31
  76. quasardb/string.hpp +0 -160
  77. quasardb/table.cpp +0 -289
  78. quasardb/table.hpp +0 -325
  79. quasardb/table_reader.hpp +0 -220
  80. quasardb/tag.hpp +0 -77
  81. quasardb/timestamp.hpp +0 -97
  82. quasardb/traits.hpp +0 -619
  83. quasardb/ts_iterator.hpp +0 -193
  84. quasardb/utils/blob_deque.hpp +0 -96
  85. quasardb/utils/ostream.hpp +0 -17
  86. quasardb/utils/permutation.hpp +0 -50
  87. quasardb/utils/stable_sort.hpp +0 -25
  88. quasardb/utils/unzip_view.hpp +0 -89
  89. quasardb/utils.cpp +0 -28
  90. quasardb/utils.hpp +0 -174
  91. quasardb/writer.cpp +0 -534
  92. quasardb/writer.hpp +0 -396
  93. quasardb-3.14.2.dev1.dist-info/RECORD +0 -109
  94. {quasardb-3.14.2.dev1.dist-info → quasardb-3.14.2.dev4.dist-info}/LICENSE.md +0 -0
  95. {quasardb-3.14.2.dev1.dist-info → quasardb-3.14.2.dev4.dist-info}/top_level.txt +0 -0
quasardb/perf.hpp DELETED
@@ -1,336 +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 "handle.hpp"
34
- #include <qdb/perf.h>
35
- #include <chrono>
36
- #include <fstream>
37
- #include <iostream>
38
- #include <map>
39
- #include <stack>
40
- #include <vector>
41
-
42
- namespace qdb
43
- {
44
-
45
- inline bool ends_with(std::string const & value, std::string const & ending)
46
- {
47
- if (ending.size() > value.size()) return false;
48
- return std::equal(ending.rbegin(), ending.rend(), value.rbegin());
49
- }
50
-
51
- inline bool is_delta_op(std::string const & op)
52
- {
53
- return ends_with(op, "_starts") || ends_with(op, "_ends");
54
- }
55
-
56
- inline bool is_start_op(std::string const & op)
57
- {
58
- assert(is_delta_op(op) == true);
59
- if (ends_with(op, "_starts"))
60
- {
61
- return true;
62
- }
63
- else if (ends_with(op, "_ends"))
64
- {
65
- return false;
66
- }
67
-
68
- // NOTREACHED
69
- throw std::runtime_error{"Not a start/stop op"};
70
- }
71
-
72
- inline std::pair<bool, std::string> parse_op(std::string const & op)
73
- {
74
- assert(is_delta_op(op) == true);
75
- bool is_start = is_start_op(op);
76
-
77
- if (is_start)
78
- {
79
- // Trim '_starts' (7 char) from the end
80
- return {is_start, op.substr(0, op.size() - 7)};
81
- }
82
-
83
- // Trim '_ends' (5 char) from the end
84
- return {is_start, op.substr(0, op.size() - 5)};
85
- }
86
-
87
- inline std::string perf_label_name(qdb_perf_label_t label)
88
- {
89
- switch (label)
90
- {
91
- case qdb_pl_undefined:
92
- return "undefined";
93
- case qdb_pl_accepted:
94
- return "accepted";
95
- case qdb_pl_received:
96
- return "received";
97
- case qdb_pl_secured:
98
- return "secured";
99
- case qdb_pl_deserialization_starts:
100
- return "deserialization_starts";
101
- case qdb_pl_deserialization_ends:
102
- return "deserialization_ends";
103
- case qdb_pl_entering_chord:
104
- return "entering_chord";
105
- case qdb_pl_processing_starts:
106
- return "processing_starts";
107
- case qdb_pl_dispatch:
108
- return "dispatch";
109
- case qdb_pl_serialization_starts:
110
- return "serialization_starts";
111
- case qdb_pl_serialization_ends:
112
- return "serialization_ends";
113
- case qdb_pl_processing_ends:
114
- return "processing_ends";
115
- case qdb_pl_replying:
116
- return "replying";
117
- case qdb_pl_replied:
118
- return "replied";
119
- case qdb_pl_entry_writing_starts:
120
- return "entry_writing_starts";
121
- case qdb_pl_entry_writing_ends:
122
- return "entry_writing_ends";
123
- case qdb_pl_content_reading_starts:
124
- return "content_reading_starts";
125
- case qdb_pl_content_reading_ends:
126
- return "content_reading_ends";
127
- case qdb_pl_content_writing_starts:
128
- return "content_writing_starts";
129
- case qdb_pl_content_writing_ends:
130
- return "content_writing_ends";
131
- case qdb_pl_directory_reading_starts:
132
- return "directory_reading_starts";
133
- case qdb_pl_directory_reading_ends:
134
- return "directory_reading_ends";
135
- case qdb_pl_directory_writing_starts:
136
- return "directory_writing_starts";
137
- case qdb_pl_directory_writing_ends:
138
- return "directory_writing_ends";
139
- case qdb_pl_entry_trimming_starts:
140
- return "entry_trimming_starts";
141
- case qdb_pl_entry_trimming_ends:
142
- return "entry_trimming_ends";
143
- case qdb_pl_ts_evaluating_starts:
144
- return "ts_evaluating_starts";
145
- case qdb_pl_ts_evaluating_ends:
146
- return "ts_evaluating_ends";
147
- case qdb_pl_ts_bucket_updating_starts:
148
- return "ts_bucket_updating_starts";
149
- case qdb_pl_ts_bucket_updating_ends:
150
- return "ts_bucket_updating_ends";
151
- case qdb_pl_affix_search_starts:
152
- return "affix_search_starts";
153
- case qdb_pl_affix_search_ends:
154
- return "affix_search_ends";
155
- case qdb_pl_eviction_starts:
156
- return "eviction_starts";
157
- case qdb_pl_eviction_ends:
158
- return "eviction_ends";
159
- case qdb_pl_time_vector_tracker_reading_starts:
160
- return "time_vector_tracker_reading_starts";
161
- case qdb_pl_time_vector_tracker_reading_ends:
162
- return "time_vector_tracker_reading_ends";
163
- case qdb_pl_bucket_reading_starts:
164
- return "bucket_reading_starts";
165
- case qdb_pl_bucket_reading_ends:
166
- return "bucket_reading_ends";
167
- case qdb_pl_entries_directory_reading_starts:
168
- return "entries_directory_reading_starts";
169
- case qdb_pl_entries_directory_reading_ends:
170
- return "entries_directory_reading_ends";
171
- case qdb_pl_acl_reading_starts:
172
- return "acl_reading_starts";
173
- case qdb_pl_acl_reading_ends:
174
- return "acl_reading_ends";
175
- case qdb_pl_time_vector_reading_starts:
176
- return "time_vector_reading_starts";
177
- case qdb_pl_time_vector_reading_ends:
178
- return "time_vector_reading_ends";
179
- case qdb_pl_unknown:
180
- return "unknown";
181
- }
182
- return "";
183
- }
184
-
185
- class perf
186
- {
187
- public:
188
- explicit perf(qdb::handle_ptr h)
189
- : _handle{h}
190
- {}
191
-
192
- // we use vectors of pairs instead of maps to keep the order as it is
193
- // provided to us
194
- using measurement = std::pair<std::string, std::chrono::nanoseconds>;
195
- using profile = std::pair<std::string, std::vector<measurement>>;
196
-
197
- std::vector<profile> get_profiles() const
198
- {
199
- std::vector<profile> profiles;
200
-
201
- qdb_perf_profile_t * qdb_profiles = nullptr;
202
- qdb_size_t count = 0;
203
-
204
- qdb::qdb_throw_if_error(*_handle, qdb_perf_get_profiles(*_handle, &qdb_profiles, &count));
205
-
206
- profiles.reserve(count);
207
- std::transform(qdb_profiles, qdb_profiles + count, std::back_inserter(profiles),
208
- [](const qdb_perf_profile_t & prof) {
209
- std::vector<measurement> measurements;
210
- measurements.reserve(prof.count);
211
- std::transform(prof.measurements, prof.measurements + prof.count,
212
- std::back_inserter(measurements), [](const qdb_perf_measurement_t & mes) {
213
- return std::make_pair(
214
- perf_label_name(mes.label), std::chrono::nanoseconds{mes.elapsed});
215
- });
216
- return std::make_pair(std::string{prof.name.data, prof.name.length}, measurements);
217
- });
218
- qdb_release(*_handle, qdb_profiles);
219
-
220
- return profiles;
221
- }
222
-
223
- std::vector<std::string> get_flamegraph(std::string outfile) const
224
- {
225
- std::vector<std::string> ret;
226
-
227
- for (profile p : get_profiles())
228
- {
229
- std::stack<std::string> stack;
230
-
231
- stack.push(p.first); // operation name
232
- std::map<std::string, std::chrono::nanoseconds> last;
233
-
234
- for (measurement m : p.second)
235
- {
236
-
237
- std::chrono::nanoseconds ns = m.second;
238
-
239
- if (is_delta_op(m.first))
240
- {
241
- auto parsed = parse_op(m.first);
242
- bool is_start = parsed.first;
243
- std::string op = parsed.second;
244
-
245
- if (is_start)
246
- {
247
- if (stack.empty())
248
- {
249
- stack.push(op);
250
- }
251
- else
252
- {
253
- stack.push(stack.top() + ";" + op);
254
- }
255
-
256
- // Can't have the same op type nested twice?
257
- assert(last.find(op) == last.end());
258
- last.emplace(op, ns);
259
- }
260
- else
261
- {
262
- // May throw error, we assume an end always has a last
263
- std::chrono::nanoseconds delta = ns - last.at(op);
264
- last.erase(op);
265
-
266
- std::string x = stack.top();
267
- assert(ends_with(x, op));
268
- stack.pop();
269
-
270
- ret.push_back(x + " " + std::to_string(delta.count()));
271
- }
272
- }
273
- }
274
- }
275
-
276
- if (outfile != "")
277
- {
278
- std::ofstream f;
279
- f.open(outfile);
280
-
281
- for (std::string const & row : ret)
282
- {
283
- f << row << std::endl;
284
- }
285
-
286
- f.close();
287
- }
288
-
289
- return ret;
290
- }
291
-
292
- py::object get(bool flamegraph, std::string outfile) const
293
- {
294
- if (flamegraph)
295
- {
296
- return py::cast(get_flamegraph(outfile));
297
- }
298
- else
299
- {
300
- return py::cast(get_profiles());
301
- }
302
- }
303
-
304
- void clear_all_profiles() const
305
- {
306
- qdb::qdb_throw_if_error(*_handle, qdb_perf_clear_all_profiles(*_handle));
307
- }
308
-
309
- void enable_client_tracking() const
310
- {
311
- qdb::qdb_throw_if_error(*_handle, qdb_perf_enable_client_tracking(*_handle));
312
- }
313
-
314
- void disable_client_tracking() const
315
- {
316
- qdb::qdb_throw_if_error(*_handle, qdb_perf_disable_client_tracking(*_handle));
317
- }
318
-
319
- private:
320
- qdb::handle_ptr _handle;
321
- };
322
-
323
- template <typename Module>
324
- static inline void register_perf(Module & m)
325
- {
326
- namespace py = pybind11;
327
-
328
- py::class_<qdb::perf>(m, "Perf")
329
- .def(py::init<qdb::handle_ptr>()) //
330
- .def("get", &qdb::perf::get, py::arg("flame") = false, py::arg("outfile") = "") //
331
- .def("clear", &qdb::perf::clear_all_profiles) //
332
- .def("enable", &qdb::perf::enable_client_tracking) //
333
- .def("disable", &qdb::perf::disable_client_tracking); //
334
- }
335
-
336
- } // namespace qdb
quasardb/pytypes.hpp DELETED
@@ -1,221 +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 <qdb/client.h>
34
- #include <pybind11/pybind11.h>
35
- #include <datetime.h> // from python
36
-
37
- namespace qdb
38
- {
39
- namespace py = pybind11;
40
-
41
- class pytimedelta : public py::object
42
- {
43
- public:
44
- PYBIND11_OBJECT_DEFAULT(pytimedelta, object, PyDelta_Check);
45
-
46
- static pytimedelta from_dsu(py::ssize_t days, py::ssize_t seconds, py::ssize_t usec)
47
- {
48
- return py::reinterpret_steal<pytimedelta>(PyDelta_FromDSU(static_cast<int>(days), static_cast<int>(seconds), static_cast<int>(usec)));
49
- }
50
-
51
- inline int days() const noexcept
52
- {
53
- return PyDateTime_DELTA_GET_DAYS(ptr());
54
- }
55
-
56
- inline int seconds() const noexcept
57
- {
58
- return PyDateTime_DELTA_GET_SECONDS(ptr());
59
- }
60
-
61
- inline int microseconds() const noexcept
62
- {
63
- return PyDateTime_DELTA_GET_MICROSECONDS(ptr());
64
- }
65
- };
66
-
67
- class pytzinfo : public py::object
68
- {
69
- PYBIND11_OBJECT_DEFAULT(pytzinfo, object, PyTZInfo_Check);
70
-
71
- pytimedelta utcoffset(py::object dt) const
72
- {
73
- py::object fn = attr("utcoffset");
74
- return py::reinterpret_borrow<pytimedelta>(fn(dt));
75
- }
76
-
77
- static pytzinfo utc() noexcept
78
- {
79
- #if (PY_VERSION_HEX < 0x03070000)
80
- # pragma message("Python <= 3.6 detected, using slower introspection for UTC timezone lookup")
81
- py::module m = py::module::import("datetime");
82
- py::object ret = m.attr("timezone").attr("utc");
83
- assert(ret.is_none() == false);
84
- return py::reinterpret_borrow<pytzinfo>(ret);
85
- #else
86
- PyObject * ret = PyDateTime_TimeZone_UTC;
87
- #endif
88
- return py::reinterpret_borrow<pytzinfo>(ret);
89
- }
90
- };
91
-
92
- /**
93
- * Wrapper for `datetime.datetime`.
94
- */
95
- class pydatetime : public py::object
96
- {
97
- public:
98
- PYBIND11_OBJECT_DEFAULT(pydatetime, object, PyDateTime_Check);
99
-
100
- static pydatetime from_date_and_time(int year,
101
- int month,
102
- int day,
103
- int hour,
104
- int minute,
105
- int second,
106
- int microsecond,
107
- pytzinfo tz = pytzinfo::utc())
108
- {
109
- assert(-32767 <= year && year <= 32767);
110
- assert(1 <= month && month <= 12);
111
- assert(1 <= day && day <= 31);
112
- assert(0 <= hour && hour <= 23);
113
- assert(0 <= second && second <= 59);
114
- assert(0 <= microsecond && microsecond <= 1'000'000);
115
-
116
- // For funky kwarg syntax from pybind11 with _a literal
117
- using namespace pybind11::literals;
118
-
119
- return py::reinterpret_steal<pydatetime>(
120
- PyDateTime_FromDateAndTime(year, month, day, hour, minute, second, microsecond))
121
-
122
- .replace("tzinfo"_a = tz);
123
- }
124
-
125
- inline int year() const noexcept
126
- {
127
- return PyDateTime_GET_YEAR(ptr());
128
- }
129
-
130
- inline int month() const noexcept
131
- {
132
- return PyDateTime_GET_MONTH(ptr());
133
- }
134
-
135
- inline int day() const noexcept
136
- {
137
- return PyDateTime_GET_DAY(ptr());
138
- }
139
-
140
- inline int hour() const noexcept
141
- {
142
- return PyDateTime_DATE_GET_HOUR(ptr());
143
- }
144
-
145
- inline int minute() const noexcept
146
- {
147
- return PyDateTime_DATE_GET_MINUTE(ptr());
148
- }
149
-
150
- inline int second() const noexcept
151
- {
152
- return PyDateTime_DATE_GET_SECOND(ptr());
153
- }
154
-
155
- inline int microsecond() const noexcept
156
- {
157
- return PyDateTime_DATE_GET_MICROSECOND(ptr());
158
- }
159
-
160
- template <typename... KWargs>
161
- inline pydatetime replace(KWargs &&... args)
162
- {
163
- py::object fn = attr("replace");
164
-
165
- return fn(std::forward<KWargs...>(args...));
166
- }
167
-
168
- /**
169
- * proxy for `datetime.datetime.astimezone()` invoked without any arguments,
170
- * which effectively adds the local time zone to the datetime object.
171
- */
172
- inline pydatetime astimezone() const
173
- {
174
- py::object fn = attr("astimezone");
175
- return fn();
176
- }
177
-
178
- /**
179
- * convert this datetime to another timezone in such a way that the UTC
180
- * representation of both remains the same.
181
- */
182
- inline pydatetime astimezone(pytzinfo tz) const
183
- {
184
- py::object fn = attr("astimezone");
185
- return fn(tz);
186
- }
187
-
188
- inline pytzinfo tzinfo() const noexcept
189
- {
190
-
191
- #if (PY_VERSION_HEX < 0x030A0000)
192
- # pragma message("Python <= 3.9 detected, using slower attribute lookup for tzinfo")
193
- PyObject * tz = PyObject_GetAttrString(ptr(), "tzinfo");
194
- #else
195
- PyObject * tz = PyDateTime_DATE_GET_TZINFO(ptr());
196
- #endif
197
- pytzinfo tz_ = py::reinterpret_borrow<pytzinfo>(tz);
198
-
199
- if (tz_.is_none())
200
- {
201
- // either `datetime.now()` or `datetime.utcnow()`.
202
- //
203
- // since the use of `datetime .utcnow()` is actively discouraged in favor
204
- // of `datetime.now(tz=timezone.utc)`, we are going to assume that no timezone
205
- // means local time.
206
- //
207
- // the most elegant way to handle this is to amend this datetime
208
- // object with the local timezone and recurse.
209
- return astimezone().tzinfo();
210
- }
211
-
212
- return tz_;
213
- }
214
-
215
- inline pytimedelta utcoffset() const noexcept
216
- {
217
- return tzinfo().utcoffset(*this);
218
- }
219
- };
220
-
221
- } // namespace qdb