From ba60578faef87986ccbb3ce7fc720fb43ea88b91 Mon Sep 17 00:00:00 2001 From: Wes McKinney Date: Mon, 8 Jul 2019 14:56:56 -0500 Subject: [PATCH] Use atexit module for extension type finalization --- python/pyarrow/types.pxi | 51 +++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/python/pyarrow/types.pxi b/python/pyarrow/types.pxi index 79e9713d76a..0c3f8b01967 100644 --- a/python/pyarrow/types.pxi +++ b/python/pyarrow/types.pxi @@ -15,6 +15,7 @@ # specific language governing permissions and limitations # under the License. +import atexit import re import warnings @@ -589,32 +590,6 @@ cdef class UnknownExtensionType(ExtensionType): return self.serialized -cdef class _ExtensionTypesInitializer: - # - # A private object that handles process-wide registration of the Python - # ExtensionType. - # - - def __cinit__(self): - cdef: - DataType storage_type - shared_ptr[CExtensionType] cpy_ext_type - - # Make a dummy C++ ExtensionType - storage_type = null() - check_status(CPyExtensionType.FromClass(storage_type.sp_type, - ExtensionType, &cpy_ext_type)) - check_status( - RegisterPyExtensionType( cpy_ext_type)) - - def __dealloc__(self): - # This needs to be done explicitly before the Python interpreter is - # finalized. If the C++ type is destroyed later in the process - # teardown stage, it will invoke CPython APIs such as Py_DECREF - # with a destroyed interpreter. - check_status(UnregisterPyExtensionType()) - - cdef class Field: """ A named field, with a data type, nullability, and optional metadata. @@ -1863,4 +1838,26 @@ def is_float_value(object obj): return IsPyFloat(obj) -_extension_types_initializer = _ExtensionTypesInitializer() +def _register_py_extension_type(): + cdef: + DataType storage_type + shared_ptr[CExtensionType] cpy_ext_type + + # Make a dummy C++ ExtensionType + storage_type = null() + check_status(CPyExtensionType.FromClass(storage_type.sp_type, + ExtensionType, &cpy_ext_type)) + check_status( + RegisterPyExtensionType( cpy_ext_type)) + + +def _unregister_py_extension_type(): + # This needs to be done explicitly before the Python interpreter is + # finalized. If the C++ type is destroyed later in the process + # teardown stage, it will invoke CPython APIs such as Py_DECREF + # with a destroyed interpreter. + check_status(UnregisterPyExtensionType()) + + +_register_py_extension_type() +atexit.register(_unregister_py_extension_type)