Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add slots to DAQmx-property-containing classes #664

Merged
merged 8 commits into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ All notable changes to this project will be documented in this file.
* ...

* ### Resolved Issues
* ...
* [656: Missing usage of slots in classes with DAQmx attributes](https://github.com/ni/nidaqmx-python/issues/656)

* ### Major Changes
* Added support for mioDAQ configurable digital voltage.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ class ExpirationState:
"""
Represents a DAQmx Watchdog expiration state.
"""
__slots__ = ('_handle', '_physical_channel', '_interpreter')

def __init__(self, task_handle, physical_channel, interpreter):
self._handle = task_handle
self._physical_channel = physical_channel
Expand Down
1 change: 1 addition & 0 deletions generated/nidaqmx/system/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class System:
operations on DAQ hardware, and creates classes from which you can get
information about the hardware.
"""
__slots__ = ('_interpreter')

def __init__(self, grpc_options=None):
"""
Expand Down
2 changes: 2 additions & 0 deletions generated/nidaqmx/system/watchdog.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ class WatchdogTask:
"""
Represents the watchdog configurations for a DAQmx task.
"""
__slots__ = ('_handle', '_close_on_exit', '_saved_name', '_interpreter', '_expiration_states', '__weakref__')

def __init__(self, device_name, task_name='', timeout=10, grpc_options=None):
"""
Creates and configures a task that controls the watchdog timer of a
Expand Down
2 changes: 2 additions & 0 deletions generated/nidaqmx/task/_export_signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ class ExportSignals:
"""
Represents the exported signal configurations for a DAQmx task.
"""
__slots__ = ('_handle', '_interpreter')

def __init__(self, task_handle, interpreter):
self._handle = task_handle
self._interpreter = interpreter
Expand Down
2 changes: 2 additions & 0 deletions generated/nidaqmx/task/_in_stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ class InStream:
used in conjunction with reader classes to read samples from an
NI-DAQmx task.
"""
__slots__ = ('_task', '_handle', '_interpreter', '_timeout')

def __init__(self, task, interpreter):
self._task = task
self._handle = task._handle
Expand Down
2 changes: 2 additions & 0 deletions generated/nidaqmx/task/_out_stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ class OutStream:
used in conjunction with writer classes to write samples to an
NI-DAQmx task.
"""
__slots__ = ('_task', '_handle', '_interpreter', '_auto_start', '_timeout')

def __init__(self, task, interpreter):
self._task = task
self._handle = task._handle
Expand Down
4 changes: 4 additions & 0 deletions generated/nidaqmx/task/_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ class Task:
"""
Represents a DAQmx Task.
"""
__slots__ = ('_handle', '_close_on_exit', '_saved_name', '_grpc_options', '_event_handlers', '_interpreter',
'_ai_channels', '_ao_channels', '_ci_channels', '_co_channels', '_di_channels', '_do_channels',
'_export_signals', '_in_stream', '_timing', '_triggers', '_out_stream', '_event_handler_lock',
'__weakref__')

def __init__(self, new_task_name='', *, grpc_options=None):
"""
Expand Down
2 changes: 2 additions & 0 deletions generated/nidaqmx/task/_timing.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ class Timing:
"""
Represents the timing configurations for a DAQmx task.
"""
__slots__ = ('_handle', '_interpreter')

def __init__(self, task_handle, interpreter):
self._handle = task_handle
self._interpreter = interpreter
Expand Down
2 changes: 2 additions & 0 deletions generated/nidaqmx/task/triggering/_arm_start_trigger.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ class ArmStartTrigger:
"""
Represents the arm start trigger configurations for a DAQmx task.
"""
__slots__ = ('_handle', '_interpreter')

def __init__(self, task_handle, interpreter):
self._handle = task_handle
self._interpreter = interpreter
Expand Down
2 changes: 2 additions & 0 deletions generated/nidaqmx/task/triggering/_handshake_trigger.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ class HandshakeTrigger:
"""
Represents the handshake trigger configurations for a DAQmx task.
"""
__slots__ = ('_handle', '_interpreter')

def __init__(self, task_handle, interpreter):
self._handle = task_handle
self._interpreter = interpreter
Expand Down
2 changes: 2 additions & 0 deletions generated/nidaqmx/task/triggering/_pause_trigger.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ class PauseTrigger:
"""
Represents the pause trigger configurations for a DAQmx task.
"""
__slots__ = ('_handle', '_interpreter')

def __init__(self, task_handle, interpreter):
self._handle = task_handle
self._interpreter = interpreter
Expand Down
2 changes: 2 additions & 0 deletions generated/nidaqmx/task/triggering/_reference_trigger.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ class ReferenceTrigger:
"""
Represents the reference trigger configurations for a DAQmx task.
"""
__slots__ = ('_handle', '_interpreter')

def __init__(self, task_handle, interpreter):
self._handle = task_handle
self._interpreter = interpreter
Expand Down
2 changes: 2 additions & 0 deletions generated/nidaqmx/task/triggering/_start_trigger.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ class StartTrigger:
"""
Represents the start trigger configurations for a DAQmx task.
"""
__slots__ = ('_handle', '_interpreter')

def __init__(self, task_handle, interpreter):
self._handle = task_handle
self._interpreter = interpreter
Expand Down
2 changes: 2 additions & 0 deletions generated/nidaqmx/task/triggering/_triggers.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ class Triggers:
"""
Represents the trigger configurations for a DAQmx task.
"""
__slots__ = ('_handle', '_interpreter', '_arm_start_trigger', '_handshake_trigger', '_pause_trigger', '_reference_trigger', '_start_trigger')

def __init__(self, task_handle, interpreter):
self._handle = task_handle
self._interpreter = interpreter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ class ExpirationState:
"""
Represents a DAQmx Watchdog expiration state.
"""
__slots__ = ('_handle', '_physical_channel', '_interpreter')

def __init__(self, task_handle, physical_channel, interpreter):
self._handle = task_handle
self._physical_channel = physical_channel
Expand Down
1 change: 1 addition & 0 deletions src/codegen/templates/system/system.py.mako
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class System:
operations on DAQ hardware, and creates classes from which you can get
information about the hardware.
"""
__slots__ = ('_interpreter')

def __init__(self, grpc_options=None):
"""
Expand Down
2 changes: 2 additions & 0 deletions src/codegen/templates/system/watchdog.py.mako
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ class WatchdogTask:
"""
Represents the watchdog configurations for a DAQmx task.
"""
__slots__ = ('_handle', '_close_on_exit', '_saved_name', '_interpreter', '_expiration_states', '__weakref__')

def __init__(self, device_name, task_name='', timeout=10, grpc_options=None):
"""
Creates and configures a task that controls the watchdog timer of a
Expand Down
2 changes: 2 additions & 0 deletions src/codegen/templates/task/_export_signals.py.mako
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ class ExportSignals:
"""
Represents the exported signal configurations for a DAQmx task.
"""
__slots__ = ('_handle', '_interpreter')

def __init__(self, task_handle, interpreter):
self._handle = task_handle
self._interpreter = interpreter
Expand Down
2 changes: 2 additions & 0 deletions src/codegen/templates/task/_in_stream.py.mako
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ class InStream:
used in conjunction with reader classes to read samples from an
NI-DAQmx task.
"""
__slots__ = ('_task', '_handle', '_interpreter', '_timeout')

def __init__(self, task, interpreter):
self._task = task
self._handle = task._handle
Expand Down
2 changes: 2 additions & 0 deletions src/codegen/templates/task/_out_stream.py.mako
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ class OutStream:
used in conjunction with writer classes to write samples to an
NI-DAQmx task.
"""
__slots__ = ('_task', '_handle', '_interpreter', '_auto_start', '_timeout')

def __init__(self, task, interpreter):
self._task = task
self._handle = task._handle
Expand Down
2 changes: 2 additions & 0 deletions src/codegen/templates/task/_timing.py.mako
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ class Timing:
"""
Represents the timing configurations for a DAQmx task.
"""
__slots__ = ('_handle', '_interpreter')

def __init__(self, task_handle, interpreter):
self._handle = task_handle
self._interpreter = interpreter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ class ArmStartTrigger:
"""
Represents the arm start trigger configurations for a DAQmx task.
"""
__slots__ = ('_handle', '_interpreter')

def __init__(self, task_handle, interpreter):
self._handle = task_handle
self._interpreter = interpreter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ class HandshakeTrigger:
"""
Represents the handshake trigger configurations for a DAQmx task.
"""
__slots__ = ('_handle', '_interpreter')

def __init__(self, task_handle, interpreter):
self._handle = task_handle
self._interpreter = interpreter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ class PauseTrigger:
"""
Represents the pause trigger configurations for a DAQmx task.
"""
__slots__ = ('_handle', '_interpreter')

def __init__(self, task_handle, interpreter):
self._handle = task_handle
self._interpreter = interpreter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ class ReferenceTrigger:
"""
Represents the reference trigger configurations for a DAQmx task.
"""
__slots__ = ('_handle', '_interpreter')

def __init__(self, task_handle, interpreter):
self._handle = task_handle
self._interpreter = interpreter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ class StartTrigger:
"""
Represents the start trigger configurations for a DAQmx task.
"""
__slots__ = ('_handle', '_interpreter')

def __init__(self, task_handle, interpreter):
self._handle = task_handle
self._interpreter = interpreter
Expand Down
2 changes: 2 additions & 0 deletions src/codegen/templates/task/triggering/_triggers.py.mako
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ class Triggers:
"""
Represents the trigger configurations for a DAQmx task.
"""
__slots__ = ('_handle', '_interpreter', '_arm_start_trigger', '_handshake_trigger', '_pause_trigger', '_reference_trigger', '_start_trigger')

def __init__(self, task_handle, interpreter):
self._handle = task_handle
self._interpreter = interpreter
Expand Down
4 changes: 4 additions & 0 deletions src/handwritten/task/_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ class Task:
"""
Represents a DAQmx Task.
"""
__slots__ = ('_handle', '_close_on_exit', '_saved_name', '_grpc_options', '_event_handlers', '_interpreter',
zhindes marked this conversation as resolved.
Show resolved Hide resolved
'_ai_channels', '_ao_channels', '_ci_channels', '_co_channels', '_di_channels', '_do_channels',
'_export_signals', '_in_stream', '_timing', '_triggers', '_out_stream', '_event_handler_lock',
'__weakref__')

def __init__(self, new_task_name='', *, grpc_options=None):
"""
Expand Down
6 changes: 6 additions & 0 deletions tests/component/system/test_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import nidaqmx
from nidaqmx.constants import PowerUpChannelType
from nidaqmx.error_codes import DAQmxErrors
from nidaqmx.system import System
from nidaqmx.types import AOPowerUpState


Expand Down Expand Up @@ -121,3 +122,8 @@ def test_invalid_power_up_states___set_analog_power_up_states___throws_invalid_a
system.set_analog_power_up_states(device_name, power_up_states)

assert exc_info.value.error_code == DAQmxErrors.INVALID_ATTRIBUTE_VALUE


def test___system___set_nonexistent_property___raises_exception(system: System):
with pytest.raises(AttributeError):
system.nonexistent_property = "foo" # type: ignore[attr-defined]
5 changes: 5 additions & 0 deletions tests/component/task/test_in_stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,3 +219,8 @@ def test___valid_path___start_new_file___returns_assigned_value(ai_task: nidaqmx
ai_task.in_stream.start_new_file(expected_file_path)

assert ai_task.in_stream.logging_file_path == pathlib.Path(expected_file_path)


def test___in_stream___set_nonexistent_property___raises_exception(task: nidaqmx.Task):
with pytest.raises(AttributeError):
task.in_stream.nonexistent_property = "foo" # type: ignore[attr-defined]
5 changes: 5 additions & 0 deletions tests/component/task/test_out_stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,8 @@ def test___odd_sized_array___write___returns_whole_samples(
samples_written = task.out_stream.write(data)

assert samples_written == 9


def test___out_stream___set_nonexistent_property___raises_exception(task: nidaqmx.Task):
with pytest.raises(AttributeError):
task.out_stream.nonexistent_property = "foo" # type: ignore[attr-defined]
5 changes: 5 additions & 0 deletions tests/component/task/test_timing.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,8 @@ def test___timing___cfg_burst_handshaking_export_clock___sets_properties(
sim_6535_di_single_line_task.export_signals.rdy_for_xfer_event_lvl_active_lvl
== ready_event_active_level
)


def test___timing___set_nonexistent_property___raises_exception(task: Task):
with pytest.raises(AttributeError):
task.timing.nonexistent_property = "foo" # type: ignore[attr-defined]
30 changes: 30 additions & 0 deletions tests/component/task/test_triggers_properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,3 +160,33 @@ def test___ai_voltage_time_aware_task___reset_timestamp_property___returns_defau
assert when_value.hour == localized_default_value.hour
assert when_value.minute == localized_default_value.minute
assert when_value.second == localized_default_value.second


def test___trigger___set_nonexistent_property___raises_exception(task: Task):
with pytest.raises(AttributeError):
task.triggers.nonexistent_property = "foo" # type: ignore[attr-defined]


def test___arm_start_trigger___set_nonexistent_property___raises_exception(task: Task):
with pytest.raises(AttributeError):
task.triggers.arm_start_trigger.nonexistent_property = "foo" # type: ignore[attr-defined]


def test___handshake_trigger___set_nonexistent_property___raises_exception(task: Task):
with pytest.raises(AttributeError):
task.triggers.handshake_trigger.nonexistent_property = "foo" # type: ignore[attr-defined]


def test___pause_trigger___set_nonexistent_property___raises_exception(task: Task):
with pytest.raises(AttributeError):
task.triggers.pause_trigger.nonexistent_property = "foo" # type: ignore[attr-defined]


def test___reference_trigger___set_nonexistent_property___raises_exception(task: Task):
with pytest.raises(AttributeError):
task.triggers.reference_trigger.nonexistent_property = "foo" # type: ignore[attr-defined]


def test___start_trigger___set_nonexistent_property___raises_exception(task: Task):
with pytest.raises(AttributeError):
task.triggers.start_trigger.nonexistent_property = "foo" # type: ignore[attr-defined]
8 changes: 8 additions & 0 deletions tests/component/test_export_signals.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import pytest

import nidaqmx


def test___export_signals___set_nonexistent_property___raises_exception(task: nidaqmx.Task):
with pytest.raises(AttributeError):
task.export_signals.nonexistent_property = "foo" # type: ignore[attr-defined]
8 changes: 8 additions & 0 deletions tests/component/test_task.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import weakref

import pytest

import nidaqmx
Expand Down Expand Up @@ -197,3 +199,9 @@ def test___task___add_global_channels___adds_to_channel_names(task: nidaqmx.Task
task.add_global_channels([persisted_channel, persisted_channel2])

assert task.channel_names == [persisted_channel.name, persisted_channel2.name]


def test___task___create_weakref___succeeds(task: nidaqmx.Task):
ref = weakref.ref(task)
task2 = ref()
assert task is task2
5 changes: 5 additions & 0 deletions tests/component/test_task_properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,8 @@ def test___get_devices___shared_interpreter(ai_task: Task):
devices = ai_task.devices

assert all(dev._interpreter is ai_task._interpreter for dev in devices)


def test___task___set_nonexistent_property___raises_exception(task: Task):
with pytest.raises(AttributeError):
task.nonexistent_property = "foo" # type: ignore[attr-defined]
Loading
Loading