Skip to content
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -1668,6 +1668,7 @@
#### [nirfsg] Unreleased
- Added
- Enabled selected public APIs
- Enabled custom object expansion for repeated capabilities
- Basic example
- Documentation for APIs (not final)
- Changed
Expand Down
1 change: 1 addition & 0 deletions build/helper/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
from build.helper.metadata_filters import filter_library_functions # noqa: F401
from build.helper.metadata_filters import filter_parameters # noqa: F401
from build.helper.metadata_filters import filter_public_functions # noqa: F401
from build.helper.metadata_filters import filter_rep_cap_supported_attributes

from build.helper.metadata_find import find_custom_type # noqa: F401
from build.helper.metadata_find import find_session_handle_parameter # noqa: F401
Expand Down
4 changes: 4 additions & 0 deletions build/helper/metadata_add_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from .helper import get_python_type_for_api_type
from .metadata_filters import filter_codegen_attributes
from .metadata_filters import filter_codegen_functions
from .metadata_filters import filter_rep_cap_supported_attributes
from .metadata_find import find_custom_type
from .metadata_find import find_size_parameter
from .metadata_merge_dicts import merge_helper
Expand Down Expand Up @@ -721,6 +722,9 @@ def add_all_config_metadata(config):
if 'uses_nitclk' not in config:
config['uses_nitclk'] = False

if 'repeated_capability_object_type' not in config:
config['repeated_capability_object_type'] = {'python': 'session'}

return config


Expand Down
9 changes: 9 additions & 0 deletions build/helper/metadata_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -450,4 +450,13 @@ def filter_codegen_enums(enums):
'''Returns enum metadata only for those enums to be included in codegen'''
return {k: v for k, v in enums.items() if v['codegen_method'] != 'no'}

def filter_rep_cap_supported_attributes(attributes, rep_cap_name):
'''Returns attribute metadata only for those attributes that support the specified repeated capability.
Args:
attributes: Dictionary of attribute metadata.
rep_cap_name: The name of the repeated capability to filter by.
Returns:
Dictionary of attributes that support the specified repeated capability.
'''
return {k: v for k, v in attributes.items() if rep_cap_name in v.get('supported_rep_caps', [])}
Comment on lines +453 to +465

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is good, but what about filter_rep_cap_supported_functions?


87 changes: 87 additions & 0 deletions build/templates/session.py.mako
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,83 @@ class _Lock(object):

% endif
% if len(config['repeated_capabilities']) > 0:
% if config['repeated_capability_object_type']['python'] == 'applicable-attributes-only':
% for rep_cap in config['repeated_capabilities']:

class _RepeatedCapability${rep_cap['python_name'].capitalize()}(object):
% for attribute in helper.sorted_attrs(helper.filter_rep_cap_supported_attributes(attributes, rep_cap['python_name'])):
<%
helper.add_attribute_rep_cap_tip(attributes[attribute], config)
%>\
% if attributes[attribute]['enum']:
% if helper.enum_uses_converter(enums[attributes[attribute]['enum']]):
${attributes[attribute]['python_name']} = _attributes.AttributeEnumWithConverter(_attributes.AttributeEnum(_attributes.Attribute${attributes[attribute]['type']}, enums.${enums[attributes[attribute]['enum']]['python_name']}, ${attribute}), _converters.${enums[attributes[attribute]['enum']]['enum_to_converted_value_function_name']}, _converters.${enums[attributes[attribute]['enum']]['converted_value_to_enum_function_name']})
% else:
${attributes[attribute]['python_name']} = _attributes.AttributeEnum(_attributes.Attribute${attributes[attribute]['type']}, enums.${enums[attributes[attribute]['enum']]['python_name']}, ${attribute})
% endif
% else:
${attributes[attribute]['python_name']} = _attributes.${attributes[attribute]['attribute_class']}(${attribute})
% endif
% if 'documentation' in attributes[attribute] and len(helper.get_documentation_for_node_docstring(attributes[attribute], config, indent=4).strip()) > 0:
'''Type: ${attributes[attribute]['type_in_documentation']}

${helper.get_documentation_for_node_docstring(attributes[attribute], config, indent=4)}
'''
% endif
% endfor
def __init__(self, session, repeated_capability_list):
object.__setattr__(self, '_session', session)
object.__setattr__(self, '_repeated_capability_list', repeated_capability_list)
object.__setattr__(self, '_prefix', '${rep_cap["prefix"]}')
object.__setattr__(self, '_current_repeated_capability_list', repeated_capability_list if len(repeated_capability_list) > 0 else [''])
object.__setattr__(self, '_separator', '')

def __setattr__(self, key, value):
if key not in dir(self):
raise AttributeError("'{0}' object has no attribute '{1}'".format(type(self).__name__, key))
object.__setattr__(self, key, value)

def __getitem__(self, repeated_capability):
'''Set/get properties or call methods with a repeated capability (i.e. channels)'''
rep_caps_list = _converters.convert_repeated_capabilities(repeated_capability, self._prefix)
complete_rep_cap_list = [
current_rep_cap + self._separator + rep_cap
for current_rep_cap in self._current_repeated_capability_list
for rep_cap in rep_caps_list
]
object.__setattr__(self, '_current_repeated_capability_list', complete_rep_cap_list)
self._current_repeated_capability_list = complete_rep_cap_list

return self

def _get_attribute_vi_real64(self, attribute):
repeated_capability = ','.join(self._current_repeated_capability_list)
value = self._session._interpreter.get_attribute_vi_real64(repeated_capability, attribute)
return value

def _set_attribute_vi_real64(self, attribute, value):
repeated_capability = ','.join(self._current_repeated_capability_list)
self._session._interpreter.set_attribute_vi_real64(repeated_capability, attribute, value)

def _get_attribute_vi_int32(self, attribute):
repeated_capability = ','.join(self._current_repeated_capability_list)
value = self._session._interpreter.get_attribute_vi_int32(repeated_capability, attribute)
return value

def _set_attribute_vi_int32(self, attribute, value):
repeated_capability = ','.join(self._current_repeated_capability_list)
self._session._interpreter.set_attribute_vi_int32(repeated_capability, attribute, value)

def _get_attribute_vi_string(self, attribute):
repeated_capability = ','.join(self._current_repeated_capability_list)
value = self._session._interpreter.get_attribute_vi_string(repeated_capability, attribute)
return value

def _set_attribute_vi_string(self, attribute, value):
repeated_capability = ','.join(self._current_repeated_capability_list)
self._session._interpreter.set_attribute_vi_string(repeated_capability, attribute, value)
% endfor
% else:
class _RepeatedCapabilities(object):
def __init__(self, session, prefix, current_repeated_capability_list):
self._session = session
Expand Down Expand Up @@ -128,6 +205,7 @@ class _NoChannel(object):
self._session._repeated_capability = self._repeated_capability_cache


% endif
% endif
class _SessionBase(object):
'''Base class for all ${config['driver_name']} sessions.'''
Expand All @@ -137,6 +215,11 @@ class _SessionBase(object):

% for attribute in helper.sorted_attrs(helper.filter_codegen_attributes(attributes)):
<%
# Skip attributes with repeated capability expansion set to "applicable-attributes-only"
if 'repeated_capability_type' in attributes[attribute]:
rep_cap_type = attributes[attribute]['repeated_capability_type']
if any(rep_cap.get('python_name') == rep_cap_type and config['repeated_capability_object_type'] == 'applicable-attributes-only' for rep_cap in config['repeated_capabilities']):
continue
helper.add_attribute_rep_cap_tip(attributes[attribute], config)
%>\
%if attributes[attribute]['enum']:
Expand Down Expand Up @@ -179,7 +262,11 @@ constructor_params = helper.filter_parameters(init_function['parameters'], helpe
% if len(config['repeated_capabilities']) > 0:
# Instantiate any repeated capability objects
% for rep_cap in config['repeated_capabilities']:
% if config['repeated_capability_object_type']['python'] == 'applicable-attributes-only':
self.${rep_cap['python_name']} = _RepeatedCapability${rep_cap['python_name'].capitalize()}(self, repeated_capability_list)
% else:
self.${rep_cap['python_name']} = _RepeatedCapabilities(self, '${rep_cap["prefix"]}', repeated_capability_list)
% endif
% endfor

% endif
Expand Down
Loading
Loading