diff --git a/src/clp_ffi_py/ir/native/PyDeserializer.cpp b/src/clp_ffi_py/ir/native/PyDeserializer.cpp index 30a74e7..dc911d6 100644 --- a/src/clp_ffi_py/ir/native/PyDeserializer.cpp +++ b/src/clp_ffi_py/ir/native/PyDeserializer.cpp @@ -159,6 +159,16 @@ CLP_FFI_PY_METHOD auto PyDeserializer_dealloc(PyDeserializer* self) -> void { } } // namespace +auto PyDeserializer::module_level_init(PyObject* py_module) -> bool { + static_assert(std::is_trivially_destructible()); + auto* type{py_reinterpret_cast(PyType_FromSpec(&PyDeserializer_type_spec))}; + m_py_type.reset(type); + if (nullptr == type) { + return false; + } + return add_python_type(get_py_type(), "Deserializer", py_module); +} + auto PyDeserializer::init( PyObject* input_stream, Py_ssize_t buffer_capacity, @@ -273,16 +283,6 @@ auto PyDeserializer::deserialize_log_event() -> PyObject* { Py_RETURN_NONE; } -auto PyDeserializer::module_level_init(PyObject* py_module) -> bool { - static_assert(std::is_trivially_destructible()); - auto* type{py_reinterpret_cast(PyType_FromSpec(&PyDeserializer_type_spec))}; - m_py_type.reset(type); - if (nullptr == type) { - return false; - } - return add_python_type(get_py_type(), "Deserializer", py_module); -} - auto PyDeserializer::handle_log_event(clp::ffi::KeyValuePairLogEvent&& log_event) -> IRErrorCode { if (has_unreleased_deserialized_log_event()) { // This situation may occur if the deserializer methods return an error after the last diff --git a/src/clp_ffi_py/ir/native/PyDeserializer.hpp b/src/clp_ffi_py/ir/native/PyDeserializer.hpp index a6d5982..5df68f6 100644 --- a/src/clp_ffi_py/ir/native/PyDeserializer.hpp +++ b/src/clp_ffi_py/ir/native/PyDeserializer.hpp @@ -30,6 +30,24 @@ class PyDeserializer { */ static constexpr Py_ssize_t cDefaultBufferCapacity{65'536}; + /** + * Gets the `PyTypeObject` that represents `PyDeserializer`'s Python type. This type is + * dynamically created and initialized during the execution of + * `PyDeserializer::module_level_init`. + * @return Python type object associated with `PyDeserializer`. + */ + [[nodiscard]] static auto get_py_type() -> PyTypeObject* { return m_py_type.get(); } + + /** + * Creates and initializes `PyDeserializer` as a Python type, and then incorporates this + * type as a Python object into the py_module module. + * @param py_module This is the Python module where the initialized `PyDeserializer` will be + * incorporated. + * @return true on success. + * @return false on failure with the relevant Python exception and error set. + */ + [[nodiscard]] static auto module_level_init(PyObject* py_module) -> bool; + // Delete default constructor to disable direct instantiation. PyDeserializer() = delete; @@ -91,24 +109,6 @@ class PyDeserializer { */ [[nodiscard]] auto deserialize_log_event() -> PyObject*; - /** - * Gets the `PyTypeObject` that represents `PyDeserializer`'s Python type. This type is - * dynamically created and initialized during the execution of - * `PyDeserializer::module_level_init`. - * @return Python type object associated with `PyDeserializer`. - */ - [[nodiscard]] static auto get_py_type() -> PyTypeObject* { return m_py_type.get(); } - - /** - * Creates and initializes `PyDeserializer` as a Python type, and then incorporates this - * type as a Python object into the py_module module. - * @param py_module This is the Python module where the initialized `PyDeserializer` will be - * incorporated. - * @return true on success. - * @return false on failure with the relevant Python exception and error set. - */ - [[nodiscard]] static auto module_level_init(PyObject* py_module) -> bool; - private: /** * Class that implements `clp::ffi::ir_stream::IrUnitHandlerInterface` for deserializing @@ -181,6 +181,8 @@ class PyDeserializer { using Deserializer = clp::ffi::ir_stream::Deserializer; + static inline PyObjectStaticPtr m_py_type{nullptr}; + // Methods /** * Implements `IrUnitHandler::EndOfStreamHandle`. @@ -244,8 +246,6 @@ class PyDeserializer { gsl::owner m_deserializer; gsl::owner m_deserialized_log_event; // NOLINTEND(cppcoreguidelines-owning-memory) - - static inline PyObjectStaticPtr m_py_type{nullptr}; }; } // namespace clp_ffi_py::ir::native diff --git a/src/clp_ffi_py/ir/native/PyKeyValuePairLogEvent.cpp b/src/clp_ffi_py/ir/native/PyKeyValuePairLogEvent.cpp index 2190be9..16f4215 100644 --- a/src/clp_ffi_py/ir/native/PyKeyValuePairLogEvent.cpp +++ b/src/clp_ffi_py/ir/native/PyKeyValuePairLogEvent.cpp @@ -652,6 +652,35 @@ auto decode_as_encoded_text_ast(Value const& val) -> std::optional } } // namespace +auto PyKeyValuePairLogEvent::create(clp::ffi::KeyValuePairLogEvent kv_log_event) + -> PyKeyValuePairLogEvent* { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast) + PyKeyValuePairLogEvent* self{PyObject_New(PyKeyValuePairLogEvent, get_py_type())}; + if (nullptr == self) { + return nullptr; + } + self->default_init(); + if (false == self->init(std::move(kv_log_event))) { + return nullptr; + } + return self; +} + +auto PyKeyValuePairLogEvent::get_py_type() -> PyTypeObject* { + return m_py_type.get(); +} + +auto PyKeyValuePairLogEvent::module_level_init(PyObject* py_module) -> bool { + static_assert(std::is_trivially_destructible()); + auto* type{py_reinterpret_cast(PyType_FromSpec(&PyKeyValuePairLogEvent_type_spec)) + }; + m_py_type.reset(type); + if (nullptr == type) { + return false; + } + return add_python_type(get_py_type(), "KeyValuePairLogEvent", py_module); +} + auto PyKeyValuePairLogEvent::init(clp::ffi::KeyValuePairLogEvent kv_pair_log_event) -> bool { m_kv_pair_log_event = new (std::nothrow) clp::ffi::KeyValuePairLogEvent{std::move(kv_pair_log_event)}; @@ -688,33 +717,4 @@ auto PyKeyValuePairLogEvent::init(clp::ffi::KeyValuePairLogEvent kv_pair_log_eve return nullptr; } } - -auto PyKeyValuePairLogEvent::create(clp::ffi::KeyValuePairLogEvent kv_log_event) - -> PyKeyValuePairLogEvent* { - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast) - PyKeyValuePairLogEvent* self{PyObject_New(PyKeyValuePairLogEvent, get_py_type())}; - if (nullptr == self) { - return nullptr; - } - self->default_init(); - if (false == self->init(std::move(kv_log_event))) { - return nullptr; - } - return self; -} - -auto PyKeyValuePairLogEvent::get_py_type() -> PyTypeObject* { - return m_py_type.get(); -} - -auto PyKeyValuePairLogEvent::module_level_init(PyObject* py_module) -> bool { - static_assert(std::is_trivially_destructible()); - auto* type{py_reinterpret_cast(PyType_FromSpec(&PyKeyValuePairLogEvent_type_spec)) - }; - m_py_type.reset(type); - if (nullptr == type) { - return false; - } - return add_python_type(get_py_type(), "KeyValuePairLogEvent", py_module); -} } // namespace clp_ffi_py::ir::native diff --git a/src/clp_ffi_py/ir/native/PyKeyValuePairLogEvent.hpp b/src/clp_ffi_py/ir/native/PyKeyValuePairLogEvent.hpp index 3e97d07..8eb6cf2 100644 --- a/src/clp_ffi_py/ir/native/PyKeyValuePairLogEvent.hpp +++ b/src/clp_ffi_py/ir/native/PyKeyValuePairLogEvent.hpp @@ -15,6 +15,33 @@ namespace clp_ffi_py::ir::native { */ class PyKeyValuePairLogEvent { public: + /** + * CPython-level factory function. + * @param kv_log_event + * @return a new reference of a `PyKeyValuePairLogEvent` object that is initialized with the + * given kv log event. + * @return nullptr on failure with the relevant Python exception and error set. + */ + [[nodiscard]] static auto create(clp::ffi::KeyValuePairLogEvent kv_log_event) + -> PyKeyValuePairLogEvent*; + + /** + * Gets the `PyTypeObject` that represents `PyKeyValuePair`'s Python type. This type is + * dynamically created and initialized during the execution of `module_level_init`. + * @return Python type object associated with `PyKeyValuePairLogEvent`. + */ + [[nodiscard]] static auto get_py_type() -> PyTypeObject*; + + /** + * Creates and initializes `PyKeyValuePairLogEvent` as a Python type, and then incorporates this + * type as a Python object into the py_module module. + * @param py_module The Python module where the initialized `PyKeyValuePairLogEvent` will be + * incorporated. + * @return true on success. + * @return false on failure with the relevant Python exception and error set. + */ + [[nodiscard]] static auto module_level_init(PyObject* py_module) -> bool; + // Delete default constructor to disable direct instantiation. PyKeyValuePairLogEvent() = delete; @@ -64,40 +91,13 @@ class PyKeyValuePairLogEvent { */ [[nodiscard]] auto to_dict() -> PyDictObject*; - /** - * CPython-level factory function. - * @param kv_log_event - * @return a new reference of a `PyKeyValuePairLogEvent` object that is initialized with the - * given kv log event. - * @return nullptr on failure with the relevant Python exception and error set. - */ - [[nodiscard]] static auto create(clp::ffi::KeyValuePairLogEvent kv_log_event) - -> PyKeyValuePairLogEvent*; - - /** - * Gets the `PyTypeObject` that represents `PyKeyValuePair`'s Python type. This type is - * dynamically created and initialized during the execution of `module_level_init`. - * @return Python type object associated with `PyKeyValuePairLogEvent`. - */ - [[nodiscard]] static auto get_py_type() -> PyTypeObject*; - - /** - * Creates and initializes `PyKeyValuePairLogEvent` as a Python type, and then incorporates this - * type as a Python object into the py_module module. - * @param py_module The Python module where the initialized `PyKeyValuePairLogEvent` will be - * incorporated. - * @return true on success. - * @return false on failure with the relevant Python exception and error set. - */ - [[nodiscard]] static auto module_level_init(PyObject* py_module) -> bool; - private: - PyObject_HEAD; + static inline PyObjectStaticPtr m_py_type{nullptr}; + // Variables + PyObject_HEAD; // NOLINTNEXTLINE(cppcoreguidelines-owning-memory) gsl::owner m_kv_pair_log_event; - - static inline PyObjectStaticPtr m_py_type{nullptr}; }; } // namespace clp_ffi_py::ir::native diff --git a/src/clp_ffi_py/ir/native/PySerializer.cpp b/src/clp_ffi_py/ir/native/PySerializer.cpp index 70b6145..5412f88 100644 --- a/src/clp_ffi_py/ir/native/PySerializer.cpp +++ b/src/clp_ffi_py/ir/native/PySerializer.cpp @@ -395,6 +395,16 @@ CLP_FFI_PY_METHOD auto PySerializer_dealloc(PySerializer* self) -> void { } } // namespace +auto PySerializer::module_level_init(PyObject* py_module) -> bool { + static_assert(std::is_trivially_destructible()); + auto* type{py_reinterpret_cast(PyType_FromSpec(&PySerializer_type_spec))}; + m_py_type.reset(type); + if (nullptr == type) { + return false; + } + return add_python_type(get_py_type(), "Serializer", py_module); +} + auto PySerializer::init( PyObject* output_stream, PySerializer::ClpIrSerializer serializer, @@ -502,16 +512,6 @@ auto PySerializer::close() -> bool { return true; } -auto PySerializer::module_level_init(PyObject* py_module) -> bool { - static_assert(std::is_trivially_destructible()); - auto* type{py_reinterpret_cast(PyType_FromSpec(&PySerializer_type_spec))}; - m_py_type.reset(type); - if (nullptr == type) { - return false; - } - return add_python_type(get_py_type(), "Serializer", py_module); -} - auto PySerializer::write_ir_buf_to_output_stream() -> bool { if (false == assert_is_not_closed()) { return false; diff --git a/src/clp_ffi_py/ir/native/PySerializer.hpp b/src/clp_ffi_py/ir/native/PySerializer.hpp index 30cb899..74100fc 100644 --- a/src/clp_ffi_py/ir/native/PySerializer.hpp +++ b/src/clp_ffi_py/ir/native/PySerializer.hpp @@ -24,6 +24,28 @@ class PySerializer { using ClpIrSerializer = clp::ffi::ir_stream::Serializer; using BufferView = ClpIrSerializer::BufferView; + /** + * The default buffer size limit. Any change to the value should also be applied to `__init__`'s + * doc string and Python stub file. + */ + static constexpr size_t cDefaultBufferSizeLimit{65'536}; + + /** + * Gets the `PyTypeObject` that represents `PySerializer`'s Python type. This type is + * dynamically created and initialized during the execution of `module_level_init`. + * @return Python type object associated with `PySerializer`. + */ + [[nodiscard]] static auto get_py_type() -> PyTypeObject* { return m_py_type.get(); } + + /** + * Creates and initializes `PySerializer` as a Python type, and then incorporates this + * type as a Python object into the py_module module. + * @param py_module The Python module where the initialized `PySerializer` will be incorporated. + * @return true on success. + * @return false on failure with the relevant Python exception and error set. + */ + [[nodiscard]] static auto module_level_init(PyObject* py_module) -> bool; + // Delete default constructor to disable direct instantiation. PySerializer() = delete; @@ -36,12 +58,6 @@ class PySerializer { // Destructor ~PySerializer() = default; - /** - * The default buffer size limit. Any change to the value should also be applied to `__init__`'s - * doc string and Python stub file. - */ - static constexpr size_t cDefaultBufferSizeLimit{65'536}; - /** * Initializes the underlying data with the given inputs. Since the memory allocation of * `PySerializer` is handled by CPython's allocator, cpp constructors will not be explicitly @@ -106,23 +122,9 @@ class PySerializer { */ [[nodiscard]] auto close() -> bool; - /** - * Gets the `PyTypeObject` that represents `PySerializer`'s Python type. This type is - * dynamically created and initialized during the execution of `module_level_init`. - * @return Python type object associated with `PySerializer`. - */ - [[nodiscard]] static auto get_py_type() -> PyTypeObject* { return m_py_type.get(); } - - /** - * Creates and initializes `PySerializer` as a Python type, and then incorporates this - * type as a Python object into the py_module module. - * @param py_module The Python module where the initialized `PySerializer` will be incorporated. - * @return true on success. - * @return false on failure with the relevant Python exception and error set. - */ - [[nodiscard]] static auto module_level_init(PyObject* py_module) -> bool; - private: + static inline PyObjectStaticPtr m_py_type{nullptr}; + /** * Asserts the serializer has not been closed. * @return true on success, false if it's already been closed with `IOError` set. @@ -179,8 +181,6 @@ class PySerializer { gsl::owner m_serializer; Py_ssize_t m_num_total_bytes_serialized; Py_ssize_t m_buffer_size_limit; - - static inline PyObjectStaticPtr m_py_type{nullptr}; }; } // namespace clp_ffi_py::ir::native