Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions cpp/src/arrow/python/extension_type.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
// under the License.

#include <memory>
#include <sstream>
#include <utility>

#include "arrow/python/extension_type.h"
Expand Down Expand Up @@ -71,6 +72,16 @@ PyObject* DeserializeExtInstance(PyObject* type_class,

static const char* kExtensionName = "arrow.py_extension_type";

std::string PyExtensionType::ToString() const {
PyAcquireGIL lock;

std::stringstream ss;
OwnedRef instance(GetInstance());
ss << "extension<" << this->extension_name() << "<" << Py_TYPE(instance.obj())->tp_name
<< ">>";
return ss.str();
}
Copy link
Member

@pitrou pitrou Oct 5, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This works fine, but there is one thing missing. Since ToString can be called from arbitrary C++ code, the GIL needs to be taken. This is achieved by adding:

PyAcquireGIL lock;

at the beginning of this method definition.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Amended commit to add PyAcquireGIL, thanks.


PyExtensionType::PyExtensionType(std::shared_ptr<DataType> storage_type, PyObject* typ,
PyObject* inst)
: ExtensionType(storage_type),
Expand Down
2 changes: 2 additions & 0 deletions cpp/src/arrow/python/extension_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ class ARROW_PYTHON_EXPORT PyExtensionType : public ExtensionType {
// Implement extensionType API
std::string extension_name() const override { return extension_name_; }

std::string ToString() const override;

bool ExtensionEquals(const ExtensionType& other) const override;

std::shared_ptr<Array> MakeArray(std::shared_ptr<ArrayData> data) const override;
Expand Down
5 changes: 5 additions & 0 deletions docs/source/developers/python.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ We follow a similar PEP8-like coding style to the `pandas project
<https://github.com/pandas-dev/pandas>`_. To check style issues, use the
:ref:`Archery <archery>` subcommand ``lint``:

.. code-block:: shell

pip install -e arrow/dev/archery
pip install -r arrow/dev/archery/requirements-lint.txt

.. code-block:: shell

archery lint --python
Expand Down
12 changes: 12 additions & 0 deletions python/pyarrow/tests/test_extension_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,18 @@ def test_ext_type_basics():
assert ty.extension_name == "arrow.py_extension_type"


def test_ext_type_str():
ty = IntegerType()
expected = "extension<arrow.py_extension_type<IntegerType>>"
assert str(ty) == expected
assert pa.DataType.__str__(ty) == expected


def test_ext_type_repr():
ty = IntegerType()
assert repr(ty) == "IntegerType(DataType(int64))"


def test_ext_type__lifetime():
ty = UuidType()
wr = weakref.ref(ty)
Expand Down
4 changes: 4 additions & 0 deletions python/pyarrow/types.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,10 @@ cdef class ExtensionType(BaseExtensionType):
else:
return NotImplemented

def __repr__(self):
fmt = '{0.__class__.__name__}({1})'
return fmt.format(self, repr(self.storage_type))

def __arrow_ext_serialize__(self):
"""
Serialized representation of metadata to reconstruct the type object.
Expand Down