Skip to content

Vector - Support Single-Pass Iterables#275

Merged
hunter-ni merged 4 commits into
mainfrom
users/hunter-ni/vector-initialize-support-single-pass-iterable
Jun 2, 2026
Merged

Vector - Support Single-Pass Iterables#275
hunter-ni merged 4 commits into
mainfrom
users/hunter-ni/vector-initialize-support-single-pass-iterable

Conversation

@hunter-ni
Copy link
Copy Markdown
Contributor

@hunter-ni hunter-ni commented May 28, 2026

What does this Pull Request accomplish?

This set of changes updates the Vector data type so that both Vector initialization and __setitem__ support as input Iterable objects that can only be successfully iterated a single time, such as generator functions.

Prior to these changes, the behaviors of Vector were the following:

__init__:

    def get_values() -> Iterable[float]:
        yield 20.2
        yield 30.3
        yield 40.4

    test_vector = Vector(get_values())

    # Expected Behavior: test_vector holds [20.2, 30.3, 40.4]
    # Actual Behavior:   test_vector is empty

__setitem__:

    def get_values() -> Iterable[float]:
        yield 6.5
        yield 7.5

    test_vector = Vector([1.5, 2.5, 3.5], "volts")

    test_vector[0:2] = get_values()

    # Expected Behavior: test_vector now holds the following elements: [6.5, 7.5, 3.5]
    # Actual Behavior:   test_vector now holds the following elements: [3.5]

In essence, because the Iterable being supplied to __init__ or __setitem__ in these scenarios only supports being iterated once and the implementations of these methods were iterating over the provided Iterable twice, first for data validation and then again for actual value assignment, the actual value assignment was reading an Iterable that had already been exhausted. As a result, supplying an Iterable of such a form resulted in behavior as if an empty Iterable had been supplied into the method in question.

Since the Vector data type provides a type hint indicating that Iterable[TScalar] is the expected type for the values/value parameter in these cases, we should be robust in handling all Iterables (including single-pass ones).

Implementation

  • Updated __init__ to create a list of the supplied values before iterating through these values and performing element-level validation on them, rather than doing so after this validation has taken place
  • Updated __setitem__ to create a list wrapper for the incoming Iterable if the Iterable is not a Sequence (and we cannot be assured of multi-pass iteration support)

Why should this Pull Request be merged?

This PR addresses a behavioral issue in which Vector was not handling certain types of Iterables as input in an intuitive or expected manner.

What testing has been done?

Added new test cases in test_vector.py covering usage of single-pass iterables with __init__ and __setitem__

…an only be iterated once.

Signed-off-by: Hunter Kennon hunter.kennon@emerson.com
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 28, 2026

Test Results

    50 files  +    1      50 suites  +1   19m 51s ⏱️ +45s
 2 326 tests +   17   2 326 ✅ +   17   0 💤 ±0  0 ❌ ±0 
59 628 runs  +2 314  59 616 ✅ +2 314  12 💤 ±0  0 ❌ ±0 

Results for commit c6b51ad. ± Comparison against base commit 602a649.

This pull request removes 2 and adds 19 tests. Note that renamed tests count towards both.
tests.unit.vector.test_vector ‑ test___float_data_value___create___creates_scalar_data_with_data_and_default_units
tests.unit.vector.test_vector ‑ test___str_data_value___create___creates_scalar_data_with_data_and_default_units
tests.unit.vector.test_vector ‑ test___empty_generator_data_values___create___raises_type_error
tests.unit.vector.test_vector ‑ test___float_data_values___create___creates_with_float_data_and_default_units
tests.unit.vector.test_vector ‑ test___generator_data_values___create___creates_with_data_and_default_units
tests.unit.vector.test_vector ‑ test___invalid_generator_data_values___create___raises_type_error
tests.unit.vector.test_vector ‑ test___str_data_values___create___creates_with_str_data_and_default_units
tests.unit.vector.test_vector ‑ test___vector_with_data___set_item_at_slice_with_generator___values_set_correctly
tests.unit.waveform.test_analog_waveform ‑ test___various_values___repr___looks_ok[value12-nitypes.waveform.AnalogWaveform(3, int32, raw_data=array([1, 2, 3]), timing=nitypes.waveform.Timing(nitypes.waveform.SampleIntervalMode.REGULAR, sample_interval=datetime.timedelta(microseconds=1000)))]
tests.unit.waveform.test_analog_waveform ‑ test___various_values___repr___looks_ok[value13-nitypes.waveform.AnalogWaveform(3, int32, raw_data=array([1, 2, 3]), extended_properties={'NI_ChannelName': 'Dev1/ai0', 'NI_UnitDescription': 'Volts'})]
tests.unit.waveform.test_analog_waveform ‑ test___various_values___repr___looks_ok[value14-nitypes.waveform.AnalogWaveform(3, int32, raw_data=array([1, 2, 3]), scale_mode=nitypes.waveform.LinearScaleMode(2.0, 1.0))]
tests.unit.waveform.test_analog_waveform ‑ test___various_values___repr___looks_ok[value4-nitypes.waveform.AnalogWaveform(5, int32, raw_data=array([0, 0, 0, 0, 0]))]
…

♻️ This comment has been updated with latest results.

Comment thread src/nitypes/vector.py
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates Vector to correctly handle single-pass iterables, such as generators, during construction and slice assignment.

Changes:

  • Materializes constructor input before validation to avoid exhausting generators.
  • Materializes non-Sequence slice assignment inputs before validation/assignment.
  • Adds unit tests for generator inputs in __init__ and __setitem__.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/nitypes/vector.py Updates Vector initialization and slice assignment to support single-pass iterables.
tests/unit/vector/test_vector.py Adds generator-based tests and renames a couple of existing test cases for consistency.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tests/unit/vector/test_vector.py Outdated
hunter-ni added 2 commits May 28, 2026 16:09
Signed-off-by: Hunter Kennon hunter.kennon@emerson.com
… order of set elements in string representation

Signed-off-by: Hunter Kennon hunter.kennon@emerson.com
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

@hunter-ni hunter-ni requested a review from a team May 28, 2026 21:28
@hunter-ni hunter-ni marked this pull request as ready for review May 28, 2026 21:28
@hunter-ni hunter-ni requested review from bkeryan and csjall as code owners May 28, 2026 21:28
Copy link
Copy Markdown
Collaborator

@bkeryan bkeryan left a comment

Choose a reason for hiding this comment

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

Approved with suggestions

Comment thread tests/unit/vector/test_vector.py Outdated
Comment thread src/nitypes/vector.py
Signed-off-by: Hunter Kennon hunter.kennon@emerson.com
@hunter-ni hunter-ni requested a review from a team June 2, 2026 14:41
@hunter-ni hunter-ni merged commit 9957eea into main Jun 2, 2026
37 checks passed
@hunter-ni hunter-ni deleted the users/hunter-ni/vector-initialize-support-single-pass-iterable branch June 2, 2026 17:47
Sign up for free to 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.

4 participants