ARROW-834: Python Support creating from iterables - #602

Closed
holdenk wants to merge 31 commits into
apache:masterfrom
holdenk:ARROW-834-csupport-creating-from-iterables
Closed

ARROW-834: Python Support creating from iterables#602
holdenk wants to merge 31 commits into
apache:masterfrom
holdenk:ARROW-834-csupport-creating-from-iterables

Conversation

@holdenk

Copy link
Copy Markdown
Contributor

Support creating arrow arrays from iterables.
Possible follow up TODO (or possibly belongs in this issue); throw a clear exception when passed an iterator rather than an iterable.

@holdenkholdenk changed the title [ARROW-834][Python] Support creating from iterables[WIP][ARROW-834][Python] Support creating from iterablesApr 26, 2017
@holdenk

Copy link
Copy Markdown
ContributorAuthor

cc @BryanCutler this is the PR I mentioned earlier, if you have a chance to take a look I'd appreciate it (since I this is my first dive into the C side of Python Arrow API).

@wesmwesm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nice! Thanks for doing some refactoring -- I saw some error handling issues if you don't mind doing a little extra scrubbing. I am not sure the inlining / CRTP issue is worth doing a lot of work over, we might open a JIRA to return to it and add some microbenchmarks so that we can demonstrate performance gains (if any)

while ((item = PyIter_Next(iter))) {
RETURN_NOT_OK(VisitElem(item, level));
}
Py_DECREF(iter);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Put iter in an OwnedRef -- this fails before iteration finishes, this will leak memory

*size += 1;
Py_DECREF(item);
}
Py_DECREF(iter);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same

OwnedRef ref(item);
RETURN_NOT_OK(appendItem(ref));
}
Py_DECREF(iter);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Possibly leak


class BoolConverter : public TypedConverter<BooleanBuilder> {
template <typename BuilderType>
class TypedConverterVisitor : public TypedConverter<BuilderType> {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I see that the base class here SeqConverter does not have a virtual destructor (which can cause a memory leak), can you add one while we're touching this code?

virtual ~SeqConverter() {}

return Status::OK();
}

virtual Status appendItem(OwnedRef &item) = 0;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

use AppendItem(const OwnedRef&) (also capital A) here for immutable reference

// No error checking
RETURN_NOT_OK(CheckPythonBytesAreFixedLength(bytes_obj, expected_length));
RETURN_NOT_OK(typed_builder_->Append(
reinterpret_cast<const uint8_t*>(PyBytes_AS_STRING(bytes_obj))));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

return result of Append

length = PyBytes_GET_SIZE(bytes_obj);
bytes = PyBytes_AS_STRING(bytes_obj);
RETURN_NOT_OK(typed_builder_->Append(bytes, static_cast<int32_t>(length)));
return Status::OK();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Return result of Append

static_cast<int64_t>(PySequence_Size(item_obj));
RETURN_NOT_OK(value_converter_->AppendData(item_obj, list_size));
}
return Status::OK();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Return respective Append result

RETURN_NOT_OK(typed_builder_->AppendNull());
}

return Status::OK();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same as above

Comment threadpython/pyarrow/_array.pyx Outdated


def array(object sequence, DataType type=None, MemoryPool memory_pool=None):
def array(object sequence, DataType type=None, MemoryPool memory_pool=None, size=None):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

line length

@holdenk

Copy link
Copy Markdown
ContributorAuthor

Awesome, thanks for the review @wesm, I'll try and update this on Friday :)

@holdenk

Copy link
Copy Markdown
ContributorAuthor

It seems like this repo has been hit by the weird github bug so I'll resolve the conflicts once the repo comes back. (oi vey).

@wesm

wesm commented Apr 28, 2017

Copy link
Copy Markdown
Member

Good times. The ASF git repos are fine, so you can rebase against master in git://git.apache.org/arrow.git if you like

@BryanCutlerBryanCutler left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for doing this @holdenk, this will be great to have!

I'm just wondering if it is possible to not require size and just append to the buffers with an initial capacity and resize with some strategy as needed? If not maybe it would be better to require the size passed in with the iterable, that way the user will need to do an initial pass instead of doing it internally in Arrow? Just a thought..

if (PySequence_Check(obj)) {
*size = static_cast<int64_t>(PySequence_Size(obj));
} else if (PyObject_HasAttrString(obj, "__iter__")) {
PyObject* iter = PyObject_GetIter(obj);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is assuming that iter(obj) would return a new iterator, but what if the object is already an iterator? I think it would just return itself and can only be iterated over once right?

----------
sequence : sequence-like object of Python objects
sequence : sequence-like or iterable object of Python objects.
If both type and size are specified may be a single use iterable.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Just wondering why type is required for a single use iterable, could you just infer from the first element?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It might be nice to have a maxsize argument instead of an exact size with the interable (so we bail out in the event of infinitely long iterators)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@BryanCutler I think that might not work so well with nulls, to be fair thought the type inference code is a bit difficult to trace in my head so I could be wrong. If people would be OK with it I'd like to take a stab (probably in another PR) at making the type inference a little easier to follow?

@wesm, so right now we use the size to allocate the buffer at the start of each append. If we wanted to allow for underrun we'd have to re-alloc which would maybe not be worth it?

@wesm

wesm commented May 9, 2017

Copy link
Copy Markdown
Member

I can take another look at this if it is close to ready to go? There are some cpplint warnings that need to be fixed (make lint after running cmake)

@wesm

wesm commented May 15, 2017

Copy link
Copy Markdown
Member

@holdenk we are on the cusp of doing a 0.4.0 release, it would be great to get this in. Can you rebase and get the build passing? I can give this another review also

@wesm

wesm commented May 26, 2017

Copy link
Copy Markdown
Member

@holdenk would you be able to update this PR? thanks!

@wesm

wesm commented Jun 9, 2017

Copy link
Copy Markdown
Member

With some linting and a rebase, I think this is a good start to merge. I might want to make another pass on the API (see comment re maxsize) and type inference for sequences.

@wesm

wesm commented Jun 19, 2017

Copy link
Copy Markdown
Member

@holdenk@xhochy we need to rebase and merge this with some small fixes (e.g. adding a maxsize parameter for the iterable). I would like to do some refactoring of pandas_convert.h/cc since it's gotten so big, and we also want to add NumPy-based converters (versus NumPy-intended-for-pandas). Any takers? I can also try to work on this sometime this week

@holdenk

Copy link
Copy Markdown
ContributorAuthor

I'd be happy to do the rebate on this and either do the refactoring as part of it or a separate PR. Sorry for my radio silence, the book I'm working on only recently wrapped up so I've got bandwidth for not directly Spark projects again :)

@holdenk

Copy link
Copy Markdown
ContributorAuthor

So I've done the change for maxsize support in this PR. I'd be happy to re look at the type inference in another PR if that sounds good to people (trying to trace it in my head on a flight got a little too confusing so I think we can probably simplify it, or at least comment it some more for the future).

@holdenk

Copy link
Copy Markdown
ContributorAuthor

Commented the type inference code a bit, it seems like we could probably simplify it, but I don't know what the future plans are around mixed types so I'll just leave it as is for now.

@holdenkholdenk changed the title [WIP][ARROW-834][Python] Support creating from iterables[ARROW-834][Python] Support creating from iterablesJun 20, 2017
Comment threadpython/pyarrow/includes/pyarrow.pxd Outdated
PyOutputStream(object fo)

cdef cppclass PyBytesReader(CBufferReader):
PyBytesReader(object fo)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is a rebase artifact, can you move the relevant new code to libarrow.pxd and remove this file?

@wesm

wesm commented Jun 26, 2017

Copy link
Copy Markdown
Member

Thanks @holdenk, sorry for the delay with this -- it looks like the tests are only failing due to cpplint warnings -- I left a minor comment about a rebase issue with the pyarrow.pxd file that was removed. Could you change the PR title to start with "ARROW-834:"? This file is probably due for some follow up refactoring to abstract out the sequence iteration and simplify the type inference, so we can do that later.

@holdenkholdenk changed the title [ARROW-834][Python] Support creating from iterablesARROW-834: Python Support creating from iterablesJun 27, 2017
@wesm

wesm commented Jun 28, 2017

Copy link
Copy Markdown
Member

A minor remaining buglet:

/Users/travis/build/apache/arrow/cpp/src/arrow/python/builtin_convert.cc:366:12: error: no viable conversion from 'arrow::Status (const std::string &)' to 'arrow::Status'
return Status::NotImplemented;
^~~~~~~~~~~~~~~~~~~~~~
/Users/travis/build/apache/arrow/cpp/src/arrow/status.h:186:16: note: candidate constructor not viable: no known conversion from 'arrow::Status (const std::string &)' to 'const arrow::Status &' for 1st argument
inline Status::Status(const Status& s) {
^
1 error generated.

I'm surprised this didn't fail the gcc Linux build

@holdenk

Copy link
Copy Markdown
ContributorAuthor

huh yeah I don't know what that wasn't caught in the Linux build. Function probably should have been pure virtual anyways, so I changed it to that.

@wesmwesm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

+1, thanks @holdenk!

pribor pushed a commit to GlobalWebIndex/arrow that referenced this pull request Oct 24, 2025
…ache#602)
### Rationale for this change
Multiple threads can attempt to create the same llvm expression in
Gandiva. This isn't allowed with the new JIT compiler, so synchronizing
will prevent this scenario.
### What changes are included in this PR?
Synchronize some methods to avoid adding duplicate llvm expressions.
### Are these changes tested?
Yes, through unit tests in Gandiva.
### Are there any user-facing changes?
No.
ClosesapacheGH-601
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@holdenk@wesm@BryanCutler
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

ARROW-834: Python Support creating from iterables - #602

Closed
holdenk wants to merge 31 commits into
apache:masterfrom
holdenk:ARROW-834-csupport-creating-from-iterables
Closed

ARROW-834: Python Support creating from iterables#602
holdenk wants to merge 31 commits into
apache:masterfrom
holdenk:ARROW-834-csupport-creating-from-iterables

Conversation

@holdenk

Copy link
Copy Markdown
Contributor

Support creating arrow arrays from iterables.
Possible follow up TODO (or possibly belongs in this issue); throw a clear exception when passed an iterator rather than an iterable.

@holdenkholdenk changed the title [ARROW-834][Python] Support creating from iterables[WIP][ARROW-834][Python] Support creating from iterablesApr 26, 2017
@holdenk

Copy link
Copy Markdown
ContributorAuthor

cc @BryanCutler this is the PR I mentioned earlier, if you have a chance to take a look I'd appreciate it (since I this is my first dive into the C side of Python Arrow API).

@wesmwesm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nice! Thanks for doing some refactoring -- I saw some error handling issues if you don't mind doing a little extra scrubbing. I am not sure the inlining / CRTP issue is worth doing a lot of work over, we might open a JIRA to return to it and add some microbenchmarks so that we can demonstrate performance gains (if any)

while ((item = PyIter_Next(iter))) {
RETURN_NOT_OK(VisitElem(item, level));
}
Py_DECREF(iter);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Put iter in an OwnedRef -- this fails before iteration finishes, this will leak memory

*size += 1;
Py_DECREF(item);
}
Py_DECREF(iter);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same

OwnedRef ref(item);
RETURN_NOT_OK(appendItem(ref));
}
Py_DECREF(iter);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Possibly leak


class BoolConverter : public TypedConverter<BooleanBuilder> {
template <typename BuilderType>
class TypedConverterVisitor : public TypedConverter<BuilderType> {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I see that the base class here SeqConverter does not have a virtual destructor (which can cause a memory leak), can you add one while we're touching this code?

virtual ~SeqConverter() {}

return Status::OK();
}

virtual Status appendItem(OwnedRef &item) = 0;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

use AppendItem(const OwnedRef&) (also capital A) here for immutable reference

// No error checking
RETURN_NOT_OK(CheckPythonBytesAreFixedLength(bytes_obj, expected_length));
RETURN_NOT_OK(typed_builder_->Append(
reinterpret_cast<const uint8_t*>(PyBytes_AS_STRING(bytes_obj))));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

return result of Append

length = PyBytes_GET_SIZE(bytes_obj);
bytes = PyBytes_AS_STRING(bytes_obj);
RETURN_NOT_OK(typed_builder_->Append(bytes, static_cast<int32_t>(length)));
return Status::OK();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Return result of Append

static_cast<int64_t>(PySequence_Size(item_obj));
RETURN_NOT_OK(value_converter_->AppendData(item_obj, list_size));
}
return Status::OK();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Return respective Append result

RETURN_NOT_OK(typed_builder_->AppendNull());
}

return Status::OK();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same as above

Comment threadpython/pyarrow/_array.pyx Outdated


def array(object sequence, DataType type=None, MemoryPool memory_pool=None):
def array(object sequence, DataType type=None, MemoryPool memory_pool=None, size=None):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

line length

@holdenk

Copy link
Copy Markdown
ContributorAuthor

Awesome, thanks for the review @wesm, I'll try and update this on Friday :)

@holdenk

Copy link
Copy Markdown
ContributorAuthor

It seems like this repo has been hit by the weird github bug so I'll resolve the conflicts once the repo comes back. (oi vey).

@wesm

wesm commented Apr 28, 2017

Copy link
Copy Markdown
Member

Good times. The ASF git repos are fine, so you can rebase against master in git://git.apache.org/arrow.git if you like

@BryanCutlerBryanCutler left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for doing this @holdenk, this will be great to have!

I'm just wondering if it is possible to not require size and just append to the buffers with an initial capacity and resize with some strategy as needed? If not maybe it would be better to require the size passed in with the iterable, that way the user will need to do an initial pass instead of doing it internally in Arrow? Just a thought..

if (PySequence_Check(obj)) {
*size = static_cast<int64_t>(PySequence_Size(obj));
} else if (PyObject_HasAttrString(obj, "__iter__")) {
PyObject* iter = PyObject_GetIter(obj);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is assuming that iter(obj) would return a new iterator, but what if the object is already an iterator? I think it would just return itself and can only be iterated over once right?

----------
sequence : sequence-like object of Python objects
sequence : sequence-like or iterable object of Python objects.
If both type and size are specified may be a single use iterable.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Just wondering why type is required for a single use iterable, could you just infer from the first element?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It might be nice to have a maxsize argument instead of an exact size with the interable (so we bail out in the event of infinitely long iterators)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@BryanCutler I think that might not work so well with nulls, to be fair thought the type inference code is a bit difficult to trace in my head so I could be wrong. If people would be OK with it I'd like to take a stab (probably in another PR) at making the type inference a little easier to follow?

@wesm, so right now we use the size to allocate the buffer at the start of each append. If we wanted to allow for underrun we'd have to re-alloc which would maybe not be worth it?

@wesm

wesm commented May 9, 2017

Copy link
Copy Markdown
Member

I can take another look at this if it is close to ready to go? There are some cpplint warnings that need to be fixed (make lint after running cmake)

@wesm

wesm commented May 15, 2017

Copy link
Copy Markdown
Member

@holdenk we are on the cusp of doing a 0.4.0 release, it would be great to get this in. Can you rebase and get the build passing? I can give this another review also

@wesm

wesm commented May 26, 2017

Copy link
Copy Markdown
Member

@holdenk would you be able to update this PR? thanks!

@wesm

wesm commented Jun 9, 2017

Copy link
Copy Markdown
Member

With some linting and a rebase, I think this is a good start to merge. I might want to make another pass on the API (see comment re maxsize) and type inference for sequences.

@wesm

wesm commented Jun 19, 2017

Copy link
Copy Markdown
Member

@holdenk@xhochy we need to rebase and merge this with some small fixes (e.g. adding a maxsize parameter for the iterable). I would like to do some refactoring of pandas_convert.h/cc since it's gotten so big, and we also want to add NumPy-based converters (versus NumPy-intended-for-pandas). Any takers? I can also try to work on this sometime this week

@holdenk

Copy link
Copy Markdown
ContributorAuthor

I'd be happy to do the rebate on this and either do the refactoring as part of it or a separate PR. Sorry for my radio silence, the book I'm working on only recently wrapped up so I've got bandwidth for not directly Spark projects again :)

@holdenk

Copy link
Copy Markdown
ContributorAuthor

So I've done the change for maxsize support in this PR. I'd be happy to re look at the type inference in another PR if that sounds good to people (trying to trace it in my head on a flight got a little too confusing so I think we can probably simplify it, or at least comment it some more for the future).

@holdenk

Copy link
Copy Markdown
ContributorAuthor

Commented the type inference code a bit, it seems like we could probably simplify it, but I don't know what the future plans are around mixed types so I'll just leave it as is for now.

@holdenkholdenk changed the title [WIP][ARROW-834][Python] Support creating from iterables[ARROW-834][Python] Support creating from iterablesJun 20, 2017
Comment threadpython/pyarrow/includes/pyarrow.pxd Outdated
PyOutputStream(object fo)

cdef cppclass PyBytesReader(CBufferReader):
PyBytesReader(object fo)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is a rebase artifact, can you move the relevant new code to libarrow.pxd and remove this file?

@wesm

wesm commented Jun 26, 2017

Copy link
Copy Markdown
Member

Thanks @holdenk, sorry for the delay with this -- it looks like the tests are only failing due to cpplint warnings -- I left a minor comment about a rebase issue with the pyarrow.pxd file that was removed. Could you change the PR title to start with "ARROW-834:"? This file is probably due for some follow up refactoring to abstract out the sequence iteration and simplify the type inference, so we can do that later.

@holdenkholdenk changed the title [ARROW-834][Python] Support creating from iterablesARROW-834: Python Support creating from iterablesJun 27, 2017
@wesm

wesm commented Jun 28, 2017

Copy link
Copy Markdown
Member

A minor remaining buglet:

/Users/travis/build/apache/arrow/cpp/src/arrow/python/builtin_convert.cc:366:12: error: no viable conversion from 'arrow::Status (const std::string &)' to 'arrow::Status'
return Status::NotImplemented;
^~~~~~~~~~~~~~~~~~~~~~
/Users/travis/build/apache/arrow/cpp/src/arrow/status.h:186:16: note: candidate constructor not viable: no known conversion from 'arrow::Status (const std::string &)' to 'const arrow::Status &' for 1st argument
inline Status::Status(const Status& s) {
^
1 error generated.

I'm surprised this didn't fail the gcc Linux build

@holdenk

Copy link
Copy Markdown
ContributorAuthor

huh yeah I don't know what that wasn't caught in the Linux build. Function probably should have been pure virtual anyways, so I changed it to that.

@wesmwesm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

+1, thanks @holdenk!

pribor pushed a commit to GlobalWebIndex/arrow that referenced this pull request Oct 24, 2025
…ache#602)
### Rationale for this change
Multiple threads can attempt to create the same llvm expression in
Gandiva. This isn't allowed with the new JIT compiler, so synchronizing
will prevent this scenario.
### What changes are included in this PR?
Synchronize some methods to avoid adding duplicate llvm expressions.
### Are these changes tested?
Yes, through unit tests in Gandiva.
### Are there any user-facing changes?
No.
ClosesapacheGH-601
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@holdenk@wesm@BryanCutler
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

ARROW-834: Python Support creating from iterables - #602

Closed
holdenk wants to merge 31 commits into
apache:masterfrom
holdenk:ARROW-834-csupport-creating-from-iterables
Closed

ARROW-834: Python Support creating from iterables#602
holdenk wants to merge 31 commits into
apache:masterfrom
holdenk:ARROW-834-csupport-creating-from-iterables

Conversation

@holdenk

Copy link
Copy Markdown
Contributor

Support creating arrow arrays from iterables.
Possible follow up TODO (or possibly belongs in this issue); throw a clear exception when passed an iterator rather than an iterable.

@holdenkholdenk changed the title [ARROW-834][Python] Support creating from iterables[WIP][ARROW-834][Python] Support creating from iterablesApr 26, 2017
@holdenk

Copy link
Copy Markdown
ContributorAuthor

cc @BryanCutler this is the PR I mentioned earlier, if you have a chance to take a look I'd appreciate it (since I this is my first dive into the C side of Python Arrow API).

@wesmwesm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nice! Thanks for doing some refactoring -- I saw some error handling issues if you don't mind doing a little extra scrubbing. I am not sure the inlining / CRTP issue is worth doing a lot of work over, we might open a JIRA to return to it and add some microbenchmarks so that we can demonstrate performance gains (if any)

while ((item = PyIter_Next(iter))) {
RETURN_NOT_OK(VisitElem(item, level));
}
Py_DECREF(iter);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Put iter in an OwnedRef -- this fails before iteration finishes, this will leak memory

*size += 1;
Py_DECREF(item);
}
Py_DECREF(iter);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same

OwnedRef ref(item);
RETURN_NOT_OK(appendItem(ref));
}
Py_DECREF(iter);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Possibly leak


class BoolConverter : public TypedConverter<BooleanBuilder> {
template <typename BuilderType>
class TypedConverterVisitor : public TypedConverter<BuilderType> {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I see that the base class here SeqConverter does not have a virtual destructor (which can cause a memory leak), can you add one while we're touching this code?

virtual ~SeqConverter() {}

return Status::OK();
}

virtual Status appendItem(OwnedRef &item) = 0;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

use AppendItem(const OwnedRef&) (also capital A) here for immutable reference

// No error checking
RETURN_NOT_OK(CheckPythonBytesAreFixedLength(bytes_obj, expected_length));
RETURN_NOT_OK(typed_builder_->Append(
reinterpret_cast<const uint8_t*>(PyBytes_AS_STRING(bytes_obj))));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

return result of Append

length = PyBytes_GET_SIZE(bytes_obj);
bytes = PyBytes_AS_STRING(bytes_obj);
RETURN_NOT_OK(typed_builder_->Append(bytes, static_cast<int32_t>(length)));
return Status::OK();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Return result of Append

static_cast<int64_t>(PySequence_Size(item_obj));
RETURN_NOT_OK(value_converter_->AppendData(item_obj, list_size));
}
return Status::OK();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Return respective Append result

RETURN_NOT_OK(typed_builder_->AppendNull());
}

return Status::OK();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same as above

Comment threadpython/pyarrow/_array.pyx Outdated


def array(object sequence, DataType type=None, MemoryPool memory_pool=None):
def array(object sequence, DataType type=None, MemoryPool memory_pool=None, size=None):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

line length

@holdenk

Copy link
Copy Markdown
ContributorAuthor

Awesome, thanks for the review @wesm, I'll try and update this on Friday :)

@holdenk

Copy link
Copy Markdown
ContributorAuthor

It seems like this repo has been hit by the weird github bug so I'll resolve the conflicts once the repo comes back. (oi vey).

@wesm

wesm commented Apr 28, 2017

Copy link
Copy Markdown
Member

Good times. The ASF git repos are fine, so you can rebase against master in git://git.apache.org/arrow.git if you like

@BryanCutlerBryanCutler left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for doing this @holdenk, this will be great to have!

I'm just wondering if it is possible to not require size and just append to the buffers with an initial capacity and resize with some strategy as needed? If not maybe it would be better to require the size passed in with the iterable, that way the user will need to do an initial pass instead of doing it internally in Arrow? Just a thought..

if (PySequence_Check(obj)) {
*size = static_cast<int64_t>(PySequence_Size(obj));
} else if (PyObject_HasAttrString(obj, "__iter__")) {
PyObject* iter = PyObject_GetIter(obj);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is assuming that iter(obj) would return a new iterator, but what if the object is already an iterator? I think it would just return itself and can only be iterated over once right?

----------
sequence : sequence-like object of Python objects
sequence : sequence-like or iterable object of Python objects.
If both type and size are specified may be a single use iterable.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Just wondering why type is required for a single use iterable, could you just infer from the first element?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It might be nice to have a maxsize argument instead of an exact size with the interable (so we bail out in the event of infinitely long iterators)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@BryanCutler I think that might not work so well with nulls, to be fair thought the type inference code is a bit difficult to trace in my head so I could be wrong. If people would be OK with it I'd like to take a stab (probably in another PR) at making the type inference a little easier to follow?

@wesm, so right now we use the size to allocate the buffer at the start of each append. If we wanted to allow for underrun we'd have to re-alloc which would maybe not be worth it?

@wesm

wesm commented May 9, 2017

Copy link
Copy Markdown
Member

I can take another look at this if it is close to ready to go? There are some cpplint warnings that need to be fixed (make lint after running cmake)

@wesm

wesm commented May 15, 2017

Copy link
Copy Markdown
Member

@holdenk we are on the cusp of doing a 0.4.0 release, it would be great to get this in. Can you rebase and get the build passing? I can give this another review also

@wesm

wesm commented May 26, 2017

Copy link
Copy Markdown
Member

@holdenk would you be able to update this PR? thanks!

@wesm

wesm commented Jun 9, 2017

Copy link
Copy Markdown
Member

With some linting and a rebase, I think this is a good start to merge. I might want to make another pass on the API (see comment re maxsize) and type inference for sequences.

@wesm

wesm commented Jun 19, 2017

Copy link
Copy Markdown
Member

@holdenk@xhochy we need to rebase and merge this with some small fixes (e.g. adding a maxsize parameter for the iterable). I would like to do some refactoring of pandas_convert.h/cc since it's gotten so big, and we also want to add NumPy-based converters (versus NumPy-intended-for-pandas). Any takers? I can also try to work on this sometime this week

@holdenk

Copy link
Copy Markdown
ContributorAuthor

I'd be happy to do the rebate on this and either do the refactoring as part of it or a separate PR. Sorry for my radio silence, the book I'm working on only recently wrapped up so I've got bandwidth for not directly Spark projects again :)

@holdenk

Copy link
Copy Markdown
ContributorAuthor

So I've done the change for maxsize support in this PR. I'd be happy to re look at the type inference in another PR if that sounds good to people (trying to trace it in my head on a flight got a little too confusing so I think we can probably simplify it, or at least comment it some more for the future).

@holdenk

Copy link
Copy Markdown
ContributorAuthor

Commented the type inference code a bit, it seems like we could probably simplify it, but I don't know what the future plans are around mixed types so I'll just leave it as is for now.

@holdenkholdenk changed the title [WIP][ARROW-834][Python] Support creating from iterables[ARROW-834][Python] Support creating from iterablesJun 20, 2017
Comment threadpython/pyarrow/includes/pyarrow.pxd Outdated
PyOutputStream(object fo)

cdef cppclass PyBytesReader(CBufferReader):
PyBytesReader(object fo)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is a rebase artifact, can you move the relevant new code to libarrow.pxd and remove this file?

@wesm

wesm commented Jun 26, 2017

Copy link
Copy Markdown
Member

Thanks @holdenk, sorry for the delay with this -- it looks like the tests are only failing due to cpplint warnings -- I left a minor comment about a rebase issue with the pyarrow.pxd file that was removed. Could you change the PR title to start with "ARROW-834:"? This file is probably due for some follow up refactoring to abstract out the sequence iteration and simplify the type inference, so we can do that later.

@holdenkholdenk changed the title [ARROW-834][Python] Support creating from iterablesARROW-834: Python Support creating from iterablesJun 27, 2017
@wesm

wesm commented Jun 28, 2017

Copy link
Copy Markdown
Member

A minor remaining buglet:

/Users/travis/build/apache/arrow/cpp/src/arrow/python/builtin_convert.cc:366:12: error: no viable conversion from 'arrow::Status (const std::string &)' to 'arrow::Status'
return Status::NotImplemented;
^~~~~~~~~~~~~~~~~~~~~~
/Users/travis/build/apache/arrow/cpp/src/arrow/status.h:186:16: note: candidate constructor not viable: no known conversion from 'arrow::Status (const std::string &)' to 'const arrow::Status &' for 1st argument
inline Status::Status(const Status& s) {
^
1 error generated.

I'm surprised this didn't fail the gcc Linux build

@holdenk

Copy link
Copy Markdown
ContributorAuthor

huh yeah I don't know what that wasn't caught in the Linux build. Function probably should have been pure virtual anyways, so I changed it to that.

@wesmwesm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

+1, thanks @holdenk!

pribor pushed a commit to GlobalWebIndex/arrow that referenced this pull request Oct 24, 2025
…ache#602)
### Rationale for this change
Multiple threads can attempt to create the same llvm expression in
Gandiva. This isn't allowed with the new JIT compiler, so synchronizing
will prevent this scenario.
### What changes are included in this PR?
Synchronize some methods to avoid adding duplicate llvm expressions.
### Are these changes tested?
Yes, through unit tests in Gandiva.
### Are there any user-facing changes?
No.
ClosesapacheGH-601
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@holdenk@wesm@BryanCutler
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

ARROW-834: Python Support creating from iterables - #602

Closed
holdenk wants to merge 31 commits into
apache:masterfrom
holdenk:ARROW-834-csupport-creating-from-iterables
Closed

ARROW-834: Python Support creating from iterables#602
holdenk wants to merge 31 commits into
apache:masterfrom
holdenk:ARROW-834-csupport-creating-from-iterables

Conversation

@holdenk

Copy link
Copy Markdown
Contributor

Support creating arrow arrays from iterables.
Possible follow up TODO (or possibly belongs in this issue); throw a clear exception when passed an iterator rather than an iterable.

@holdenkholdenk changed the title [ARROW-834][Python] Support creating from iterables[WIP][ARROW-834][Python] Support creating from iterablesApr 26, 2017
@holdenk

Copy link
Copy Markdown
ContributorAuthor

cc @BryanCutler this is the PR I mentioned earlier, if you have a chance to take a look I'd appreciate it (since I this is my first dive into the C side of Python Arrow API).

@wesmwesm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nice! Thanks for doing some refactoring -- I saw some error handling issues if you don't mind doing a little extra scrubbing. I am not sure the inlining / CRTP issue is worth doing a lot of work over, we might open a JIRA to return to it and add some microbenchmarks so that we can demonstrate performance gains (if any)

while ((item = PyIter_Next(iter))) {
RETURN_NOT_OK(VisitElem(item, level));
}
Py_DECREF(iter);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Put iter in an OwnedRef -- this fails before iteration finishes, this will leak memory

*size += 1;
Py_DECREF(item);
}
Py_DECREF(iter);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same

OwnedRef ref(item);
RETURN_NOT_OK(appendItem(ref));
}
Py_DECREF(iter);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Possibly leak


class BoolConverter : public TypedConverter<BooleanBuilder> {
template <typename BuilderType>
class TypedConverterVisitor : public TypedConverter<BuilderType> {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I see that the base class here SeqConverter does not have a virtual destructor (which can cause a memory leak), can you add one while we're touching this code?

virtual ~SeqConverter() {}

return Status::OK();
}

virtual Status appendItem(OwnedRef &item) = 0;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

use AppendItem(const OwnedRef&) (also capital A) here for immutable reference

// No error checking
RETURN_NOT_OK(CheckPythonBytesAreFixedLength(bytes_obj, expected_length));
RETURN_NOT_OK(typed_builder_->Append(
reinterpret_cast<const uint8_t*>(PyBytes_AS_STRING(bytes_obj))));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

return result of Append

length = PyBytes_GET_SIZE(bytes_obj);
bytes = PyBytes_AS_STRING(bytes_obj);
RETURN_NOT_OK(typed_builder_->Append(bytes, static_cast<int32_t>(length)));
return Status::OK();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Return result of Append

static_cast<int64_t>(PySequence_Size(item_obj));
RETURN_NOT_OK(value_converter_->AppendData(item_obj, list_size));
}
return Status::OK();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Return respective Append result

RETURN_NOT_OK(typed_builder_->AppendNull());
}

return Status::OK();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same as above

Comment threadpython/pyarrow/_array.pyx Outdated


def array(object sequence, DataType type=None, MemoryPool memory_pool=None):
def array(object sequence, DataType type=None, MemoryPool memory_pool=None, size=None):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

line length

@holdenk

Copy link
Copy Markdown
ContributorAuthor

Awesome, thanks for the review @wesm, I'll try and update this on Friday :)

@holdenk

Copy link
Copy Markdown
ContributorAuthor

It seems like this repo has been hit by the weird github bug so I'll resolve the conflicts once the repo comes back. (oi vey).

@wesm

wesm commented Apr 28, 2017

Copy link
Copy Markdown
Member

Good times. The ASF git repos are fine, so you can rebase against master in git://git.apache.org/arrow.git if you like

@BryanCutlerBryanCutler left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for doing this @holdenk, this will be great to have!

I'm just wondering if it is possible to not require size and just append to the buffers with an initial capacity and resize with some strategy as needed? If not maybe it would be better to require the size passed in with the iterable, that way the user will need to do an initial pass instead of doing it internally in Arrow? Just a thought..

if (PySequence_Check(obj)) {
*size = static_cast<int64_t>(PySequence_Size(obj));
} else if (PyObject_HasAttrString(obj, "__iter__")) {
PyObject* iter = PyObject_GetIter(obj);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is assuming that iter(obj) would return a new iterator, but what if the object is already an iterator? I think it would just return itself and can only be iterated over once right?

----------
sequence : sequence-like object of Python objects
sequence : sequence-like or iterable object of Python objects.
If both type and size are specified may be a single use iterable.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Just wondering why type is required for a single use iterable, could you just infer from the first element?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It might be nice to have a maxsize argument instead of an exact size with the interable (so we bail out in the event of infinitely long iterators)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@BryanCutler I think that might not work so well with nulls, to be fair thought the type inference code is a bit difficult to trace in my head so I could be wrong. If people would be OK with it I'd like to take a stab (probably in another PR) at making the type inference a little easier to follow?

@wesm, so right now we use the size to allocate the buffer at the start of each append. If we wanted to allow for underrun we'd have to re-alloc which would maybe not be worth it?

@wesm

wesm commented May 9, 2017

Copy link
Copy Markdown
Member

I can take another look at this if it is close to ready to go? There are some cpplint warnings that need to be fixed (make lint after running cmake)

@wesm

wesm commented May 15, 2017

Copy link
Copy Markdown
Member

@holdenk we are on the cusp of doing a 0.4.0 release, it would be great to get this in. Can you rebase and get the build passing? I can give this another review also

@wesm

wesm commented May 26, 2017

Copy link
Copy Markdown
Member

@holdenk would you be able to update this PR? thanks!

@wesm

wesm commented Jun 9, 2017

Copy link
Copy Markdown
Member

With some linting and a rebase, I think this is a good start to merge. I might want to make another pass on the API (see comment re maxsize) and type inference for sequences.

@wesm

wesm commented Jun 19, 2017

Copy link
Copy Markdown
Member

@holdenk@xhochy we need to rebase and merge this with some small fixes (e.g. adding a maxsize parameter for the iterable). I would like to do some refactoring of pandas_convert.h/cc since it's gotten so big, and we also want to add NumPy-based converters (versus NumPy-intended-for-pandas). Any takers? I can also try to work on this sometime this week

@holdenk

Copy link
Copy Markdown
ContributorAuthor

I'd be happy to do the rebate on this and either do the refactoring as part of it or a separate PR. Sorry for my radio silence, the book I'm working on only recently wrapped up so I've got bandwidth for not directly Spark projects again :)

@holdenk

Copy link
Copy Markdown
ContributorAuthor

So I've done the change for maxsize support in this PR. I'd be happy to re look at the type inference in another PR if that sounds good to people (trying to trace it in my head on a flight got a little too confusing so I think we can probably simplify it, or at least comment it some more for the future).

@holdenk

Copy link
Copy Markdown
ContributorAuthor

Commented the type inference code a bit, it seems like we could probably simplify it, but I don't know what the future plans are around mixed types so I'll just leave it as is for now.

@holdenkholdenk changed the title [WIP][ARROW-834][Python] Support creating from iterables[ARROW-834][Python] Support creating from iterablesJun 20, 2017
Comment threadpython/pyarrow/includes/pyarrow.pxd Outdated
PyOutputStream(object fo)

cdef cppclass PyBytesReader(CBufferReader):
PyBytesReader(object fo)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is a rebase artifact, can you move the relevant new code to libarrow.pxd and remove this file?

@wesm

wesm commented Jun 26, 2017

Copy link
Copy Markdown
Member

Thanks @holdenk, sorry for the delay with this -- it looks like the tests are only failing due to cpplint warnings -- I left a minor comment about a rebase issue with the pyarrow.pxd file that was removed. Could you change the PR title to start with "ARROW-834:"? This file is probably due for some follow up refactoring to abstract out the sequence iteration and simplify the type inference, so we can do that later.

@holdenkholdenk changed the title [ARROW-834][Python] Support creating from iterablesARROW-834: Python Support creating from iterablesJun 27, 2017
@wesm

wesm commented Jun 28, 2017

Copy link
Copy Markdown
Member

A minor remaining buglet:

/Users/travis/build/apache/arrow/cpp/src/arrow/python/builtin_convert.cc:366:12: error: no viable conversion from 'arrow::Status (const std::string &)' to 'arrow::Status'
return Status::NotImplemented;
^~~~~~~~~~~~~~~~~~~~~~
/Users/travis/build/apache/arrow/cpp/src/arrow/status.h:186:16: note: candidate constructor not viable: no known conversion from 'arrow::Status (const std::string &)' to 'const arrow::Status &' for 1st argument
inline Status::Status(const Status& s) {
^
1 error generated.

I'm surprised this didn't fail the gcc Linux build

@holdenk

Copy link
Copy Markdown
ContributorAuthor

huh yeah I don't know what that wasn't caught in the Linux build. Function probably should have been pure virtual anyways, so I changed it to that.

@wesmwesm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

+1, thanks @holdenk!

pribor pushed a commit to GlobalWebIndex/arrow that referenced this pull request Oct 24, 2025
…ache#602)
### Rationale for this change
Multiple threads can attempt to create the same llvm expression in
Gandiva. This isn't allowed with the new JIT compiler, so synchronizing
will prevent this scenario.
### What changes are included in this PR?
Synchronize some methods to avoid adding duplicate llvm expressions.
### Are these changes tested?
Yes, through unit tests in Gandiva.
### Are there any user-facing changes?
No.
ClosesapacheGH-601
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@holdenk@wesm@BryanCutler
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

ARROW-834: Python Support creating from iterables - #602

Closed
holdenk wants to merge 31 commits into
apache:masterfrom
holdenk:ARROW-834-csupport-creating-from-iterables
Closed

ARROW-834: Python Support creating from iterables#602
holdenk wants to merge 31 commits into
apache:masterfrom
holdenk:ARROW-834-csupport-creating-from-iterables

Conversation

@holdenk

Copy link
Copy Markdown
Contributor

Support creating arrow arrays from iterables.
Possible follow up TODO (or possibly belongs in this issue); throw a clear exception when passed an iterator rather than an iterable.

@holdenkholdenk changed the title [ARROW-834][Python] Support creating from iterables[WIP][ARROW-834][Python] Support creating from iterablesApr 26, 2017
@holdenk

Copy link
Copy Markdown
ContributorAuthor

cc @BryanCutler this is the PR I mentioned earlier, if you have a chance to take a look I'd appreciate it (since I this is my first dive into the C side of Python Arrow API).

@wesmwesm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nice! Thanks for doing some refactoring -- I saw some error handling issues if you don't mind doing a little extra scrubbing. I am not sure the inlining / CRTP issue is worth doing a lot of work over, we might open a JIRA to return to it and add some microbenchmarks so that we can demonstrate performance gains (if any)

while ((item = PyIter_Next(iter))) {
RETURN_NOT_OK(VisitElem(item, level));
}
Py_DECREF(iter);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Put iter in an OwnedRef -- this fails before iteration finishes, this will leak memory

*size += 1;
Py_DECREF(item);
}
Py_DECREF(iter);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same

OwnedRef ref(item);
RETURN_NOT_OK(appendItem(ref));
}
Py_DECREF(iter);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Possibly leak


class BoolConverter : public TypedConverter<BooleanBuilder> {
template <typename BuilderType>
class TypedConverterVisitor : public TypedConverter<BuilderType> {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I see that the base class here SeqConverter does not have a virtual destructor (which can cause a memory leak), can you add one while we're touching this code?

virtual ~SeqConverter() {}

return Status::OK();
}

virtual Status appendItem(OwnedRef &item) = 0;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

use AppendItem(const OwnedRef&) (also capital A) here for immutable reference

// No error checking
RETURN_NOT_OK(CheckPythonBytesAreFixedLength(bytes_obj, expected_length));
RETURN_NOT_OK(typed_builder_->Append(
reinterpret_cast<const uint8_t*>(PyBytes_AS_STRING(bytes_obj))));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

return result of Append

length = PyBytes_GET_SIZE(bytes_obj);
bytes = PyBytes_AS_STRING(bytes_obj);
RETURN_NOT_OK(typed_builder_->Append(bytes, static_cast<int32_t>(length)));
return Status::OK();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Return result of Append

static_cast<int64_t>(PySequence_Size(item_obj));
RETURN_NOT_OK(value_converter_->AppendData(item_obj, list_size));
}
return Status::OK();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Return respective Append result

RETURN_NOT_OK(typed_builder_->AppendNull());
}

return Status::OK();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same as above

Comment threadpython/pyarrow/_array.pyx Outdated


def array(object sequence, DataType type=None, MemoryPool memory_pool=None):
def array(object sequence, DataType type=None, MemoryPool memory_pool=None, size=None):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

line length

@holdenk

Copy link
Copy Markdown
ContributorAuthor

Awesome, thanks for the review @wesm, I'll try and update this on Friday :)

@holdenk

Copy link
Copy Markdown
ContributorAuthor

It seems like this repo has been hit by the weird github bug so I'll resolve the conflicts once the repo comes back. (oi vey).

@wesm

wesm commented Apr 28, 2017

Copy link
Copy Markdown
Member

Good times. The ASF git repos are fine, so you can rebase against master in git://git.apache.org/arrow.git if you like

@BryanCutlerBryanCutler left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for doing this @holdenk, this will be great to have!

I'm just wondering if it is possible to not require size and just append to the buffers with an initial capacity and resize with some strategy as needed? If not maybe it would be better to require the size passed in with the iterable, that way the user will need to do an initial pass instead of doing it internally in Arrow? Just a thought..

if (PySequence_Check(obj)) {
*size = static_cast<int64_t>(PySequence_Size(obj));
} else if (PyObject_HasAttrString(obj, "__iter__")) {
PyObject* iter = PyObject_GetIter(obj);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is assuming that iter(obj) would return a new iterator, but what if the object is already an iterator? I think it would just return itself and can only be iterated over once right?

----------
sequence : sequence-like object of Python objects
sequence : sequence-like or iterable object of Python objects.
If both type and size are specified may be a single use iterable.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Just wondering why type is required for a single use iterable, could you just infer from the first element?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It might be nice to have a maxsize argument instead of an exact size with the interable (so we bail out in the event of infinitely long iterators)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@BryanCutler I think that might not work so well with nulls, to be fair thought the type inference code is a bit difficult to trace in my head so I could be wrong. If people would be OK with it I'd like to take a stab (probably in another PR) at making the type inference a little easier to follow?

@wesm, so right now we use the size to allocate the buffer at the start of each append. If we wanted to allow for underrun we'd have to re-alloc which would maybe not be worth it?

@wesm

wesm commented May 9, 2017

Copy link
Copy Markdown
Member

I can take another look at this if it is close to ready to go? There are some cpplint warnings that need to be fixed (make lint after running cmake)

@wesm

wesm commented May 15, 2017

Copy link
Copy Markdown
Member

@holdenk we are on the cusp of doing a 0.4.0 release, it would be great to get this in. Can you rebase and get the build passing? I can give this another review also

@wesm

wesm commented May 26, 2017

Copy link
Copy Markdown
Member

@holdenk would you be able to update this PR? thanks!

@wesm

wesm commented Jun 9, 2017

Copy link
Copy Markdown
Member

With some linting and a rebase, I think this is a good start to merge. I might want to make another pass on the API (see comment re maxsize) and type inference for sequences.

@wesm

wesm commented Jun 19, 2017

Copy link
Copy Markdown
Member

@holdenk@xhochy we need to rebase and merge this with some small fixes (e.g. adding a maxsize parameter for the iterable). I would like to do some refactoring of pandas_convert.h/cc since it's gotten so big, and we also want to add NumPy-based converters (versus NumPy-intended-for-pandas). Any takers? I can also try to work on this sometime this week

@holdenk

Copy link
Copy Markdown
ContributorAuthor

I'd be happy to do the rebate on this and either do the refactoring as part of it or a separate PR. Sorry for my radio silence, the book I'm working on only recently wrapped up so I've got bandwidth for not directly Spark projects again :)

@holdenk

Copy link
Copy Markdown
ContributorAuthor

So I've done the change for maxsize support in this PR. I'd be happy to re look at the type inference in another PR if that sounds good to people (trying to trace it in my head on a flight got a little too confusing so I think we can probably simplify it, or at least comment it some more for the future).

@holdenk

Copy link
Copy Markdown
ContributorAuthor

Commented the type inference code a bit, it seems like we could probably simplify it, but I don't know what the future plans are around mixed types so I'll just leave it as is for now.

@holdenkholdenk changed the title [WIP][ARROW-834][Python] Support creating from iterables[ARROW-834][Python] Support creating from iterablesJun 20, 2017
Comment threadpython/pyarrow/includes/pyarrow.pxd Outdated
PyOutputStream(object fo)

cdef cppclass PyBytesReader(CBufferReader):
PyBytesReader(object fo)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is a rebase artifact, can you move the relevant new code to libarrow.pxd and remove this file?

@wesm

wesm commented Jun 26, 2017

Copy link
Copy Markdown
Member

Thanks @holdenk, sorry for the delay with this -- it looks like the tests are only failing due to cpplint warnings -- I left a minor comment about a rebase issue with the pyarrow.pxd file that was removed. Could you change the PR title to start with "ARROW-834:"? This file is probably due for some follow up refactoring to abstract out the sequence iteration and simplify the type inference, so we can do that later.

@holdenkholdenk changed the title [ARROW-834][Python] Support creating from iterablesARROW-834: Python Support creating from iterablesJun 27, 2017
@wesm

wesm commented Jun 28, 2017

Copy link
Copy Markdown
Member

A minor remaining buglet:

/Users/travis/build/apache/arrow/cpp/src/arrow/python/builtin_convert.cc:366:12: error: no viable conversion from 'arrow::Status (const std::string &)' to 'arrow::Status'
return Status::NotImplemented;
^~~~~~~~~~~~~~~~~~~~~~
/Users/travis/build/apache/arrow/cpp/src/arrow/status.h:186:16: note: candidate constructor not viable: no known conversion from 'arrow::Status (const std::string &)' to 'const arrow::Status &' for 1st argument
inline Status::Status(const Status& s) {
^
1 error generated.

I'm surprised this didn't fail the gcc Linux build

@holdenk

Copy link
Copy Markdown
ContributorAuthor

huh yeah I don't know what that wasn't caught in the Linux build. Function probably should have been pure virtual anyways, so I changed it to that.

@wesmwesm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

+1, thanks @holdenk!

pribor pushed a commit to GlobalWebIndex/arrow that referenced this pull request Oct 24, 2025
…ache#602)
### Rationale for this change
Multiple threads can attempt to create the same llvm expression in
Gandiva. This isn't allowed with the new JIT compiler, so synchronizing
will prevent this scenario.
### What changes are included in this PR?
Synchronize some methods to avoid adding duplicate llvm expressions.
### Are these changes tested?
Yes, through unit tests in Gandiva.
### Are there any user-facing changes?
No.
ClosesapacheGH-601
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@holdenk@wesm@BryanCutler
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

ARROW-834: Python Support creating from iterables - #602

Closed
holdenk wants to merge 31 commits into
apache:masterfrom
holdenk:ARROW-834-csupport-creating-from-iterables
Closed

ARROW-834: Python Support creating from iterables#602
holdenk wants to merge 31 commits into
apache:masterfrom
holdenk:ARROW-834-csupport-creating-from-iterables

Conversation

@holdenk

Copy link
Copy Markdown
Contributor

Support creating arrow arrays from iterables.
Possible follow up TODO (or possibly belongs in this issue); throw a clear exception when passed an iterator rather than an iterable.

@holdenkholdenk changed the title [ARROW-834][Python] Support creating from iterables[WIP][ARROW-834][Python] Support creating from iterablesApr 26, 2017
@holdenk

Copy link
Copy Markdown
ContributorAuthor

cc @BryanCutler this is the PR I mentioned earlier, if you have a chance to take a look I'd appreciate it (since I this is my first dive into the C side of Python Arrow API).

@wesmwesm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nice! Thanks for doing some refactoring -- I saw some error handling issues if you don't mind doing a little extra scrubbing. I am not sure the inlining / CRTP issue is worth doing a lot of work over, we might open a JIRA to return to it and add some microbenchmarks so that we can demonstrate performance gains (if any)

while ((item = PyIter_Next(iter))) {
RETURN_NOT_OK(VisitElem(item, level));
}
Py_DECREF(iter);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Put iter in an OwnedRef -- this fails before iteration finishes, this will leak memory

*size += 1;
Py_DECREF(item);
}
Py_DECREF(iter);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same

OwnedRef ref(item);
RETURN_NOT_OK(appendItem(ref));
}
Py_DECREF(iter);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Possibly leak


class BoolConverter : public TypedConverter<BooleanBuilder> {
template <typename BuilderType>
class TypedConverterVisitor : public TypedConverter<BuilderType> {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I see that the base class here SeqConverter does not have a virtual destructor (which can cause a memory leak), can you add one while we're touching this code?

virtual ~SeqConverter() {}

return Status::OK();
}

virtual Status appendItem(OwnedRef &item) = 0;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

use AppendItem(const OwnedRef&) (also capital A) here for immutable reference

// No error checking
RETURN_NOT_OK(CheckPythonBytesAreFixedLength(bytes_obj, expected_length));
RETURN_NOT_OK(typed_builder_->Append(
reinterpret_cast<const uint8_t*>(PyBytes_AS_STRING(bytes_obj))));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

return result of Append

length = PyBytes_GET_SIZE(bytes_obj);
bytes = PyBytes_AS_STRING(bytes_obj);
RETURN_NOT_OK(typed_builder_->Append(bytes, static_cast<int32_t>(length)));
return Status::OK();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Return result of Append

static_cast<int64_t>(PySequence_Size(item_obj));
RETURN_NOT_OK(value_converter_->AppendData(item_obj, list_size));
}
return Status::OK();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Return respective Append result

RETURN_NOT_OK(typed_builder_->AppendNull());
}

return Status::OK();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same as above

Comment threadpython/pyarrow/_array.pyx Outdated


def array(object sequence, DataType type=None, MemoryPool memory_pool=None):
def array(object sequence, DataType type=None, MemoryPool memory_pool=None, size=None):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

line length

@holdenk

Copy link
Copy Markdown
ContributorAuthor

Awesome, thanks for the review @wesm, I'll try and update this on Friday :)

@holdenk

Copy link
Copy Markdown
ContributorAuthor

It seems like this repo has been hit by the weird github bug so I'll resolve the conflicts once the repo comes back. (oi vey).

@wesm

wesm commented Apr 28, 2017

Copy link
Copy Markdown
Member

Good times. The ASF git repos are fine, so you can rebase against master in git://git.apache.org/arrow.git if you like

@BryanCutlerBryanCutler left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for doing this @holdenk, this will be great to have!

I'm just wondering if it is possible to not require size and just append to the buffers with an initial capacity and resize with some strategy as needed? If not maybe it would be better to require the size passed in with the iterable, that way the user will need to do an initial pass instead of doing it internally in Arrow? Just a thought..

if (PySequence_Check(obj)) {
*size = static_cast<int64_t>(PySequence_Size(obj));
} else if (PyObject_HasAttrString(obj, "__iter__")) {
PyObject* iter = PyObject_GetIter(obj);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is assuming that iter(obj) would return a new iterator, but what if the object is already an iterator? I think it would just return itself and can only be iterated over once right?

----------
sequence : sequence-like object of Python objects
sequence : sequence-like or iterable object of Python objects.
If both type and size are specified may be a single use iterable.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Just wondering why type is required for a single use iterable, could you just infer from the first element?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It might be nice to have a maxsize argument instead of an exact size with the interable (so we bail out in the event of infinitely long iterators)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@BryanCutler I think that might not work so well with nulls, to be fair thought the type inference code is a bit difficult to trace in my head so I could be wrong. If people would be OK with it I'd like to take a stab (probably in another PR) at making the type inference a little easier to follow?

@wesm, so right now we use the size to allocate the buffer at the start of each append. If we wanted to allow for underrun we'd have to re-alloc which would maybe not be worth it?

@wesm

wesm commented May 9, 2017

Copy link
Copy Markdown
Member

I can take another look at this if it is close to ready to go? There are some cpplint warnings that need to be fixed (make lint after running cmake)

@wesm

wesm commented May 15, 2017

Copy link
Copy Markdown
Member

@holdenk we are on the cusp of doing a 0.4.0 release, it would be great to get this in. Can you rebase and get the build passing? I can give this another review also

@wesm

wesm commented May 26, 2017

Copy link
Copy Markdown
Member

@holdenk would you be able to update this PR? thanks!

@wesm

wesm commented Jun 9, 2017

Copy link
Copy Markdown
Member

With some linting and a rebase, I think this is a good start to merge. I might want to make another pass on the API (see comment re maxsize) and type inference for sequences.

@wesm

wesm commented Jun 19, 2017

Copy link
Copy Markdown
Member

@holdenk@xhochy we need to rebase and merge this with some small fixes (e.g. adding a maxsize parameter for the iterable). I would like to do some refactoring of pandas_convert.h/cc since it's gotten so big, and we also want to add NumPy-based converters (versus NumPy-intended-for-pandas). Any takers? I can also try to work on this sometime this week

@holdenk

Copy link
Copy Markdown
ContributorAuthor

I'd be happy to do the rebate on this and either do the refactoring as part of it or a separate PR. Sorry for my radio silence, the book I'm working on only recently wrapped up so I've got bandwidth for not directly Spark projects again :)

@holdenk

Copy link
Copy Markdown
ContributorAuthor

So I've done the change for maxsize support in this PR. I'd be happy to re look at the type inference in another PR if that sounds good to people (trying to trace it in my head on a flight got a little too confusing so I think we can probably simplify it, or at least comment it some more for the future).

@holdenk

Copy link
Copy Markdown
ContributorAuthor

Commented the type inference code a bit, it seems like we could probably simplify it, but I don't know what the future plans are around mixed types so I'll just leave it as is for now.

@holdenkholdenk changed the title [WIP][ARROW-834][Python] Support creating from iterables[ARROW-834][Python] Support creating from iterablesJun 20, 2017
Comment threadpython/pyarrow/includes/pyarrow.pxd Outdated
PyOutputStream(object fo)

cdef cppclass PyBytesReader(CBufferReader):
PyBytesReader(object fo)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is a rebase artifact, can you move the relevant new code to libarrow.pxd and remove this file?

@wesm

wesm commented Jun 26, 2017

Copy link
Copy Markdown
Member

Thanks @holdenk, sorry for the delay with this -- it looks like the tests are only failing due to cpplint warnings -- I left a minor comment about a rebase issue with the pyarrow.pxd file that was removed. Could you change the PR title to start with "ARROW-834:"? This file is probably due for some follow up refactoring to abstract out the sequence iteration and simplify the type inference, so we can do that later.

@holdenkholdenk changed the title [ARROW-834][Python] Support creating from iterablesARROW-834: Python Support creating from iterablesJun 27, 2017
@wesm

wesm commented Jun 28, 2017

Copy link
Copy Markdown
Member

A minor remaining buglet:

/Users/travis/build/apache/arrow/cpp/src/arrow/python/builtin_convert.cc:366:12: error: no viable conversion from 'arrow::Status (const std::string &)' to 'arrow::Status'
return Status::NotImplemented;
^~~~~~~~~~~~~~~~~~~~~~
/Users/travis/build/apache/arrow/cpp/src/arrow/status.h:186:16: note: candidate constructor not viable: no known conversion from 'arrow::Status (const std::string &)' to 'const arrow::Status &' for 1st argument
inline Status::Status(const Status& s) {
^
1 error generated.

I'm surprised this didn't fail the gcc Linux build

@holdenk

Copy link
Copy Markdown
ContributorAuthor

huh yeah I don't know what that wasn't caught in the Linux build. Function probably should have been pure virtual anyways, so I changed it to that.

@wesmwesm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

+1, thanks @holdenk!

pribor pushed a commit to GlobalWebIndex/arrow that referenced this pull request Oct 24, 2025
…ache#602)
### Rationale for this change
Multiple threads can attempt to create the same llvm expression in
Gandiva. This isn't allowed with the new JIT compiler, so synchronizing
will prevent this scenario.
### What changes are included in this PR?
Synchronize some methods to avoid adding duplicate llvm expressions.
### Are these changes tested?
Yes, through unit tests in Gandiva.
### Are there any user-facing changes?
No.
ClosesapacheGH-601
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@holdenk@wesm@BryanCutler
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

ARROW-834: Python Support creating from iterables - #602

Closed
holdenk wants to merge 31 commits into
apache:masterfrom
holdenk:ARROW-834-csupport-creating-from-iterables
Closed

ARROW-834: Python Support creating from iterables#602
holdenk wants to merge 31 commits into
apache:masterfrom
holdenk:ARROW-834-csupport-creating-from-iterables

Conversation

@holdenk

Copy link
Copy Markdown
Contributor

Support creating arrow arrays from iterables.
Possible follow up TODO (or possibly belongs in this issue); throw a clear exception when passed an iterator rather than an iterable.

@holdenkholdenk changed the title [ARROW-834][Python] Support creating from iterables[WIP][ARROW-834][Python] Support creating from iterablesApr 26, 2017
@holdenk

Copy link
Copy Markdown
ContributorAuthor

cc @BryanCutler this is the PR I mentioned earlier, if you have a chance to take a look I'd appreciate it (since I this is my first dive into the C side of Python Arrow API).

@wesmwesm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nice! Thanks for doing some refactoring -- I saw some error handling issues if you don't mind doing a little extra scrubbing. I am not sure the inlining / CRTP issue is worth doing a lot of work over, we might open a JIRA to return to it and add some microbenchmarks so that we can demonstrate performance gains (if any)

while ((item = PyIter_Next(iter))) {
RETURN_NOT_OK(VisitElem(item, level));
}
Py_DECREF(iter);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Put iter in an OwnedRef -- this fails before iteration finishes, this will leak memory

*size += 1;
Py_DECREF(item);
}
Py_DECREF(iter);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same

OwnedRef ref(item);
RETURN_NOT_OK(appendItem(ref));
}
Py_DECREF(iter);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Possibly leak


class BoolConverter : public TypedConverter<BooleanBuilder> {
template <typename BuilderType>
class TypedConverterVisitor : public TypedConverter<BuilderType> {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I see that the base class here SeqConverter does not have a virtual destructor (which can cause a memory leak), can you add one while we're touching this code?

virtual ~SeqConverter() {}

return Status::OK();
}

virtual Status appendItem(OwnedRef &item) = 0;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

use AppendItem(const OwnedRef&) (also capital A) here for immutable reference

// No error checking
RETURN_NOT_OK(CheckPythonBytesAreFixedLength(bytes_obj, expected_length));
RETURN_NOT_OK(typed_builder_->Append(
reinterpret_cast<const uint8_t*>(PyBytes_AS_STRING(bytes_obj))));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

return result of Append

length = PyBytes_GET_SIZE(bytes_obj);
bytes = PyBytes_AS_STRING(bytes_obj);
RETURN_NOT_OK(typed_builder_->Append(bytes, static_cast<int32_t>(length)));
return Status::OK();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Return result of Append

static_cast<int64_t>(PySequence_Size(item_obj));
RETURN_NOT_OK(value_converter_->AppendData(item_obj, list_size));
}
return Status::OK();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Return respective Append result

RETURN_NOT_OK(typed_builder_->AppendNull());
}

return Status::OK();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same as above

Comment threadpython/pyarrow/_array.pyx Outdated


def array(object sequence, DataType type=None, MemoryPool memory_pool=None):
def array(object sequence, DataType type=None, MemoryPool memory_pool=None, size=None):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

line length

@holdenk

Copy link
Copy Markdown
ContributorAuthor

Awesome, thanks for the review @wesm, I'll try and update this on Friday :)

@holdenk

Copy link
Copy Markdown
ContributorAuthor

It seems like this repo has been hit by the weird github bug so I'll resolve the conflicts once the repo comes back. (oi vey).

@wesm

wesm commented Apr 28, 2017

Copy link
Copy Markdown
Member

Good times. The ASF git repos are fine, so you can rebase against master in git://git.apache.org/arrow.git if you like

@BryanCutlerBryanCutler left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for doing this @holdenk, this will be great to have!

I'm just wondering if it is possible to not require size and just append to the buffers with an initial capacity and resize with some strategy as needed? If not maybe it would be better to require the size passed in with the iterable, that way the user will need to do an initial pass instead of doing it internally in Arrow? Just a thought..

if (PySequence_Check(obj)) {
*size = static_cast<int64_t>(PySequence_Size(obj));
} else if (PyObject_HasAttrString(obj, "__iter__")) {
PyObject* iter = PyObject_GetIter(obj);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is assuming that iter(obj) would return a new iterator, but what if the object is already an iterator? I think it would just return itself and can only be iterated over once right?

----------
sequence : sequence-like object of Python objects
sequence : sequence-like or iterable object of Python objects.
If both type and size are specified may be a single use iterable.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Just wondering why type is required for a single use iterable, could you just infer from the first element?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It might be nice to have a maxsize argument instead of an exact size with the interable (so we bail out in the event of infinitely long iterators)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@BryanCutler I think that might not work so well with nulls, to be fair thought the type inference code is a bit difficult to trace in my head so I could be wrong. If people would be OK with it I'd like to take a stab (probably in another PR) at making the type inference a little easier to follow?

@wesm, so right now we use the size to allocate the buffer at the start of each append. If we wanted to allow for underrun we'd have to re-alloc which would maybe not be worth it?

@wesm

wesm commented May 9, 2017

Copy link
Copy Markdown
Member

I can take another look at this if it is close to ready to go? There are some cpplint warnings that need to be fixed (make lint after running cmake)

@wesm

wesm commented May 15, 2017

Copy link
Copy Markdown
Member

@holdenk we are on the cusp of doing a 0.4.0 release, it would be great to get this in. Can you rebase and get the build passing? I can give this another review also

@wesm

wesm commented May 26, 2017

Copy link
Copy Markdown
Member

@holdenk would you be able to update this PR? thanks!

@wesm

wesm commented Jun 9, 2017

Copy link
Copy Markdown
Member

With some linting and a rebase, I think this is a good start to merge. I might want to make another pass on the API (see comment re maxsize) and type inference for sequences.

@wesm

wesm commented Jun 19, 2017

Copy link
Copy Markdown
Member

@holdenk@xhochy we need to rebase and merge this with some small fixes (e.g. adding a maxsize parameter for the iterable). I would like to do some refactoring of pandas_convert.h/cc since it's gotten so big, and we also want to add NumPy-based converters (versus NumPy-intended-for-pandas). Any takers? I can also try to work on this sometime this week

@holdenk

Copy link
Copy Markdown
ContributorAuthor

I'd be happy to do the rebate on this and either do the refactoring as part of it or a separate PR. Sorry for my radio silence, the book I'm working on only recently wrapped up so I've got bandwidth for not directly Spark projects again :)

@holdenk

Copy link
Copy Markdown
ContributorAuthor

So I've done the change for maxsize support in this PR. I'd be happy to re look at the type inference in another PR if that sounds good to people (trying to trace it in my head on a flight got a little too confusing so I think we can probably simplify it, or at least comment it some more for the future).

@holdenk

Copy link
Copy Markdown
ContributorAuthor

Commented the type inference code a bit, it seems like we could probably simplify it, but I don't know what the future plans are around mixed types so I'll just leave it as is for now.

@holdenkholdenk changed the title [WIP][ARROW-834][Python] Support creating from iterables[ARROW-834][Python] Support creating from iterablesJun 20, 2017
Comment threadpython/pyarrow/includes/pyarrow.pxd Outdated
PyOutputStream(object fo)

cdef cppclass PyBytesReader(CBufferReader):
PyBytesReader(object fo)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is a rebase artifact, can you move the relevant new code to libarrow.pxd and remove this file?

@wesm

wesm commented Jun 26, 2017

Copy link
Copy Markdown
Member

Thanks @holdenk, sorry for the delay with this -- it looks like the tests are only failing due to cpplint warnings -- I left a minor comment about a rebase issue with the pyarrow.pxd file that was removed. Could you change the PR title to start with "ARROW-834:"? This file is probably due for some follow up refactoring to abstract out the sequence iteration and simplify the type inference, so we can do that later.

@holdenkholdenk changed the title [ARROW-834][Python] Support creating from iterablesARROW-834: Python Support creating from iterablesJun 27, 2017
@wesm

wesm commented Jun 28, 2017

Copy link
Copy Markdown
Member

A minor remaining buglet:

/Users/travis/build/apache/arrow/cpp/src/arrow/python/builtin_convert.cc:366:12: error: no viable conversion from 'arrow::Status (const std::string &)' to 'arrow::Status'
return Status::NotImplemented;
^~~~~~~~~~~~~~~~~~~~~~
/Users/travis/build/apache/arrow/cpp/src/arrow/status.h:186:16: note: candidate constructor not viable: no known conversion from 'arrow::Status (const std::string &)' to 'const arrow::Status &' for 1st argument
inline Status::Status(const Status& s) {
^
1 error generated.

I'm surprised this didn't fail the gcc Linux build

@holdenk

Copy link
Copy Markdown
ContributorAuthor

huh yeah I don't know what that wasn't caught in the Linux build. Function probably should have been pure virtual anyways, so I changed it to that.

@wesmwesm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

+1, thanks @holdenk!

pribor pushed a commit to GlobalWebIndex/arrow that referenced this pull request Oct 24, 2025
…ache#602)
### Rationale for this change
Multiple threads can attempt to create the same llvm expression in
Gandiva. This isn't allowed with the new JIT compiler, so synchronizing
will prevent this scenario.
### What changes are included in this PR?
Synchronize some methods to avoid adding duplicate llvm expressions.
### Are these changes tested?
Yes, through unit tests in Gandiva.
### Are there any user-facing changes?
No.
ClosesapacheGH-601
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@holdenk@wesm@BryanCutler
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

ARROW-834: Python Support creating from iterables - #602

Closed
holdenk wants to merge 31 commits into
apache:masterfrom
holdenk:ARROW-834-csupport-creating-from-iterables
Closed

ARROW-834: Python Support creating from iterables#602
holdenk wants to merge 31 commits into
apache:masterfrom
holdenk:ARROW-834-csupport-creating-from-iterables

Conversation

@holdenk

Copy link
Copy Markdown
Contributor

Support creating arrow arrays from iterables.
Possible follow up TODO (or possibly belongs in this issue); throw a clear exception when passed an iterator rather than an iterable.

@holdenkholdenk changed the title [ARROW-834][Python] Support creating from iterables[WIP][ARROW-834][Python] Support creating from iterablesApr 26, 2017
@holdenk

Copy link
Copy Markdown
ContributorAuthor

cc @BryanCutler this is the PR I mentioned earlier, if you have a chance to take a look I'd appreciate it (since I this is my first dive into the C side of Python Arrow API).

@wesmwesm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nice! Thanks for doing some refactoring -- I saw some error handling issues if you don't mind doing a little extra scrubbing. I am not sure the inlining / CRTP issue is worth doing a lot of work over, we might open a JIRA to return to it and add some microbenchmarks so that we can demonstrate performance gains (if any)

while ((item = PyIter_Next(iter))) {
RETURN_NOT_OK(VisitElem(item, level));
}
Py_DECREF(iter);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Put iter in an OwnedRef -- this fails before iteration finishes, this will leak memory

*size += 1;
Py_DECREF(item);
}
Py_DECREF(iter);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same

OwnedRef ref(item);
RETURN_NOT_OK(appendItem(ref));
}
Py_DECREF(iter);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Possibly leak


class BoolConverter : public TypedConverter<BooleanBuilder> {
template <typename BuilderType>
class TypedConverterVisitor : public TypedConverter<BuilderType> {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I see that the base class here SeqConverter does not have a virtual destructor (which can cause a memory leak), can you add one while we're touching this code?

virtual ~SeqConverter() {}

return Status::OK();
}

virtual Status appendItem(OwnedRef &item) = 0;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

use AppendItem(const OwnedRef&) (also capital A) here for immutable reference

// No error checking
RETURN_NOT_OK(CheckPythonBytesAreFixedLength(bytes_obj, expected_length));
RETURN_NOT_OK(typed_builder_->Append(
reinterpret_cast<const uint8_t*>(PyBytes_AS_STRING(bytes_obj))));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

return result of Append

length = PyBytes_GET_SIZE(bytes_obj);
bytes = PyBytes_AS_STRING(bytes_obj);
RETURN_NOT_OK(typed_builder_->Append(bytes, static_cast<int32_t>(length)));
return Status::OK();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Return result of Append

static_cast<int64_t>(PySequence_Size(item_obj));
RETURN_NOT_OK(value_converter_->AppendData(item_obj, list_size));
}
return Status::OK();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Return respective Append result

RETURN_NOT_OK(typed_builder_->AppendNull());
}

return Status::OK();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same as above

Comment threadpython/pyarrow/_array.pyx Outdated


def array(object sequence, DataType type=None, MemoryPool memory_pool=None):
def array(object sequence, DataType type=None, MemoryPool memory_pool=None, size=None):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

line length

@holdenk

Copy link
Copy Markdown
ContributorAuthor

Awesome, thanks for the review @wesm, I'll try and update this on Friday :)

@holdenk

Copy link
Copy Markdown
ContributorAuthor

It seems like this repo has been hit by the weird github bug so I'll resolve the conflicts once the repo comes back. (oi vey).

@wesm

wesm commented Apr 28, 2017

Copy link
Copy Markdown
Member

Good times. The ASF git repos are fine, so you can rebase against master in git://git.apache.org/arrow.git if you like

@BryanCutlerBryanCutler left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for doing this @holdenk, this will be great to have!

I'm just wondering if it is possible to not require size and just append to the buffers with an initial capacity and resize with some strategy as needed? If not maybe it would be better to require the size passed in with the iterable, that way the user will need to do an initial pass instead of doing it internally in Arrow? Just a thought..

if (PySequence_Check(obj)) {
*size = static_cast<int64_t>(PySequence_Size(obj));
} else if (PyObject_HasAttrString(obj, "__iter__")) {
PyObject* iter = PyObject_GetIter(obj);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is assuming that iter(obj) would return a new iterator, but what if the object is already an iterator? I think it would just return itself and can only be iterated over once right?

----------
sequence : sequence-like object of Python objects
sequence : sequence-like or iterable object of Python objects.
If both type and size are specified may be a single use iterable.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Just wondering why type is required for a single use iterable, could you just infer from the first element?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It might be nice to have a maxsize argument instead of an exact size with the interable (so we bail out in the event of infinitely long iterators)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@BryanCutler I think that might not work so well with nulls, to be fair thought the type inference code is a bit difficult to trace in my head so I could be wrong. If people would be OK with it I'd like to take a stab (probably in another PR) at making the type inference a little easier to follow?

@wesm, so right now we use the size to allocate the buffer at the start of each append. If we wanted to allow for underrun we'd have to re-alloc which would maybe not be worth it?

@wesm

wesm commented May 9, 2017

Copy link
Copy Markdown
Member

I can take another look at this if it is close to ready to go? There are some cpplint warnings that need to be fixed (make lint after running cmake)

@wesm

wesm commented May 15, 2017

Copy link
Copy Markdown
Member

@holdenk we are on the cusp of doing a 0.4.0 release, it would be great to get this in. Can you rebase and get the build passing? I can give this another review also

@wesm

wesm commented May 26, 2017

Copy link
Copy Markdown
Member

@holdenk would you be able to update this PR? thanks!

@wesm

wesm commented Jun 9, 2017

Copy link
Copy Markdown
Member

With some linting and a rebase, I think this is a good start to merge. I might want to make another pass on the API (see comment re maxsize) and type inference for sequences.

@wesm

wesm commented Jun 19, 2017

Copy link
Copy Markdown
Member

@holdenk@xhochy we need to rebase and merge this with some small fixes (e.g. adding a maxsize parameter for the iterable). I would like to do some refactoring of pandas_convert.h/cc since it's gotten so big, and we also want to add NumPy-based converters (versus NumPy-intended-for-pandas). Any takers? I can also try to work on this sometime this week

@holdenk

Copy link
Copy Markdown
ContributorAuthor

I'd be happy to do the rebate on this and either do the refactoring as part of it or a separate PR. Sorry for my radio silence, the book I'm working on only recently wrapped up so I've got bandwidth for not directly Spark projects again :)

@holdenk

Copy link
Copy Markdown
ContributorAuthor

So I've done the change for maxsize support in this PR. I'd be happy to re look at the type inference in another PR if that sounds good to people (trying to trace it in my head on a flight got a little too confusing so I think we can probably simplify it, or at least comment it some more for the future).

@holdenk

Copy link
Copy Markdown
ContributorAuthor

Commented the type inference code a bit, it seems like we could probably simplify it, but I don't know what the future plans are around mixed types so I'll just leave it as is for now.

@holdenkholdenk changed the title [WIP][ARROW-834][Python] Support creating from iterables[ARROW-834][Python] Support creating from iterablesJun 20, 2017
Comment threadpython/pyarrow/includes/pyarrow.pxd Outdated
PyOutputStream(object fo)

cdef cppclass PyBytesReader(CBufferReader):
PyBytesReader(object fo)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is a rebase artifact, can you move the relevant new code to libarrow.pxd and remove this file?

@wesm

wesm commented Jun 26, 2017

Copy link
Copy Markdown
Member

Thanks @holdenk, sorry for the delay with this -- it looks like the tests are only failing due to cpplint warnings -- I left a minor comment about a rebase issue with the pyarrow.pxd file that was removed. Could you change the PR title to start with "ARROW-834:"? This file is probably due for some follow up refactoring to abstract out the sequence iteration and simplify the type inference, so we can do that later.

@holdenkholdenk changed the title [ARROW-834][Python] Support creating from iterablesARROW-834: Python Support creating from iterablesJun 27, 2017
@wesm

wesm commented Jun 28, 2017

Copy link
Copy Markdown
Member

A minor remaining buglet:

/Users/travis/build/apache/arrow/cpp/src/arrow/python/builtin_convert.cc:366:12: error: no viable conversion from 'arrow::Status (const std::string &)' to 'arrow::Status'
return Status::NotImplemented;
^~~~~~~~~~~~~~~~~~~~~~
/Users/travis/build/apache/arrow/cpp/src/arrow/status.h:186:16: note: candidate constructor not viable: no known conversion from 'arrow::Status (const std::string &)' to 'const arrow::Status &' for 1st argument
inline Status::Status(const Status& s) {
^
1 error generated.

I'm surprised this didn't fail the gcc Linux build

@holdenk

Copy link
Copy Markdown
ContributorAuthor

huh yeah I don't know what that wasn't caught in the Linux build. Function probably should have been pure virtual anyways, so I changed it to that.

@wesmwesm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

+1, thanks @holdenk!

pribor pushed a commit to GlobalWebIndex/arrow that referenced this pull request Oct 24, 2025
…ache#602)
### Rationale for this change
Multiple threads can attempt to create the same llvm expression in
Gandiva. This isn't allowed with the new JIT compiler, so synchronizing
will prevent this scenario.
### What changes are included in this PR?
Synchronize some methods to avoid adding duplicate llvm expressions.
### Are these changes tested?
Yes, through unit tests in Gandiva.
### Are there any user-facing changes?
No.
ClosesapacheGH-601
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@holdenk@wesm@BryanCutler