Restrictions

The following section contains a list of all restrictions inside a function using the nivs_rt_sequence decorator. If you violate any of the following rules, a TranslateError occurs.

Assignment

  • To assign values to an existing variable, you must use the value property of the object.

    int_var = I32Value(0)
    int_array_var = I32ValueArray([1, 2, 3])
    # Invalid value assignments
    int_var = 5
    int_array_var = [2, 3, 4]
    int_array_var[2] = 5
    # Valid value assignments
    int_var.value = 5
    int_array_var.value = [2, 3, 4]
    int_array_var[2].value = 5
    
  • Redefining a variable is not allowed.

    int_var = I32Value(0)
    int_var = DoubleValue(1.0) # The variable is already defined.
    

Conditional

  • If statements only allow for boolean checks. You cannot use numbers, numeric data type declarations, or numeric variables inside If statements.

    # Invalid conditions
    int_var = I32Value(0)
    if 1:
    if I32Value(0):
    if int_var.value:
    # Valid conditions
    bool_var = BooleanValue(True)
    if True:
    if False:
    if BooleanValue(True):
    if bool_var.value
    
  • You cannot use numeric constants or data type declarations inside If expressions.

    # Invalid conditions
    int_var = I32Value(0)
    int_var.value = 1 if 1 else 2
    int_var.value = 1 if DoubleValue(1) else 2
    int_var.value = 1 if int_var.value else 2
    # Valid conditions
    bool_var = BooleanValue(True)
    int_var.value = 1 if True else 2
    int_var.value = 1 if BooleanValue(True) else 2
    int_var.value = 1 if bool_var.value else 2
    

Data Types

  • Vector channel references will only work when you run sequences deterministically.

  • Channel references are the only data type declarations you can initialize with strings. All other data type declarations will fail.
    • Note: The BooleanValue data type is an exception to this rule. You can initialize BooleanValue with ‘true’ ‘false’ ‘True’ and ‘False’.

    # Invalid variable declarations
    bool_var = BooleanValue("string")
    double_var = DoubleValue("3.0")
    int32_var = I32Value("1")
    int64_var = I64Value("1")
    uint32_var = U32Value("1")
    uint64_var = U64Value("1")
    bool_array_var = BooleanValueArray([True, "False"])
    double_array_var = DoubleValueArray([3.0, 5.0, "6.0"])
    int32_array_var = I32ValueArray([1, 2, "3"])
    int64_array_var = I64ValueArray([1, 2, "3"])
    uint32_array_var = U32ValueArray([1, 2, "3"])
    uint64_array_var = U64ValueArray([1, 2, "3"])
    
  • Signed integers cannot use the full range of values.

    int32_invalid_var = I32Value(0xFFFFFFFF)
    int32_last_valid_var = I32Value(0x7FFFFFFF)
    int64_invalid_var = I64Value(0xFFFFFFFFFFFFFFFF)
    int64_last_valid_var = I64Value(0x7FFFFFFFFFFFFFFF)
    

Error Generation

  • When you generate an error, you can only use integer constants for the error code parameter, strings for the error message parameter, and ErrorAction members as the error action parameter.

    # Valid statement
    generate_error(-1, "My error", ErrorAction.AbortSequence)
    # Invalid statements
    int_var = I32Value(-1)
    generate_error(int_var.value, "My error", ErrorAction.AbortSequence)
    generate_error(-1, 2, ErrorAction.AbortSequence)
    generate_error(-1, "My error", 3)
    

Functions

Built-in Math Functions

  • You cannot pass down an NI VeriStand data type directly as a parameter of the built-in math functions. As an alternative, you can pass a variable or data type declaration to these functions using the value property.

    int_var = I32Value(-1)
    # Invalid usage
    int_var.value = abs(I32Value(-1))
    # Valid usages
    int_var.value = abs(I32Value(-1).value)
    int_var.value = abs(int_var.value)
    
  • BooleanValue for abs behaves differently between Python and Stimulus Profile Editor.

    bool_var = BooleanValue(-5)
    bool_var.value = abs(bool_var.value)
    return bool_var.value # This returns False in the Stimulus Profile Editor but returns True in Python.
    

Built-in VeriStand Functions

  • Some of these functions are not implemented in Python. Please refer to Library for more information.

Function Definitions

  • You cannot define new functions inside an if block, a loop, or a task.

  • The *args and kwargs variables are not supported.

Loops

  • For Loops do not support:
    • else blocks

    • ranges with a start value

    • ranges with a step value

    • ranges that use a channel reference

    • ranges that use array constants

    # The following statements are invalid:
    for x in range(5):
        pass
    else:
        pass
    for x in range(2, 5):
    for x in range(2, 5, 2):
    channel_ref = ChannelReference('Aliases/DesiredRPM')
    for x in range(channel_ref.value):
    for x in [1, 2, 3]:
    
  • While Loops do not support:
    • using else blocks

    • using a numeric constant as the condition

    • using break statements

    # The following statements are invalid:
    int_var = I32Value(5)
    while 1:
    while int_var:
    while int_var.value:
    while True:
        pass
    else:
        pass
    while True:
        break
    

Operators

Add

  • You cannot use several pluses one after another. Always use one plus sign. If you violate this rule, a TranslateError occurs.

    int_var = I32Value(0)
    int_var.value = 1 +++ 2 # This is not supported.
    int_var.value = 1 + 2 # Always use a single plus.
    

Arithmetic Shift

  • You cannot use double data types to the left of an arithmetic shift operation in Python.

    double_var = DoubleValue(5.0)
    # The following statements only work when the code is run deterministically.
    double_var.value = DoubleValue(3.0) << 5
    double_var.value = 3.0 >> 5
    double_var.value = double_var.value >> 5
    
  • You cannot use double or boolean data types to the right of an arithmetic shift operation.

    bool_var = BooleanValue(True)
    bool_var.value = 5 >> BooleanValue(True)
    bool_var.value = 5 << True
    bool_var.value = 5 << bool_var.value
    double_var = DoubleValue(5.0)
    double_var.value = 5 >> DoubleValue(3.0)
    double_var.value = 5 << 3.0
    double_var.value = 5 << double_var.value
    
  • You cannot use a negative number to the right of an arithmetic shift operation. As an alternative, use the opposite operation with a positive value.

    int_var = I32Value(1)
    int_var.value = int_var.value >> -2 # This is not allowed.
    int_var.value = int_var.value << 2 # Use this instead.
    

Bitwise Operators

  • You cannot use bitwise operations on float or boolean values in Python.

    bool_var = BooleanValue(False)
    double_var = DoubleValue(1.0)
    # The following statements only work when the code is run deterministically.
    bool_var.value = BooleanValue(True) & BooleanValue(True)
    double_var.value = 3.5 | 2.5
    double_var.value = DoubleValue(3.5) ^ DoubleValue(2.5)
    

Comparison Operators

  • You cannot use cascading comparison operators. Only use one comparison operator at a time.

    int_var = I32Value(0)
    int_var.value = 1 == 2 == 3 == 4 # This is not allowed.
    

Logical Operators

  • Logical operators only accept boolean values.

  • You cannot use cascading logical operators. Only use one logical operator at a time.

Unary Invert

  • The unary inversion operator (~) only accepts integer values.

Parameters

  • If you need to pass an immutable object (such as the value property of an NI VeriStand data type) by reference, you must run your code deterministically. Otherwise, the parameter will not actually pass by reference when you run the code in Python.

    @NivsParam('param', DoubleValue(0), NivsParam.BY_REF)
    @nivs_rt_sequence
    def _increment_by_ref(param):
        param.value += 1
        return param.value
    
    
    @nivs_rt_sequence
    def call_increment_by_ref():
        int_var = I32Value(1)
        _increment_by_ref(int_var.value)
        return int_var.value # This will return 1 in Python and 2 in the Stimulus Profile Editor.
    

Return Statements

  • A function can only have a single return statement and it has to be the last line of the function.

  • You cannot use return statements inside an if block, a try block, a finally block, a loop, a multitask, or a task.

  • Return statements can only return scalar values through the value property.

    int_var = I32Value(1)
    int_array_var = I32ValueArray([1, 2, 3])
    # Invalid return statements
    return int_var
    return int_array_var
    return DoubleValueArray[1.0, 2.0]
    # Valid return statements
    return int_var.value
    return int_array_var[0].value
    

Tasks

  • You cannot create more than one task with the same name.

    with multitask() as mt:
        @task(mt)
        def f1():
            pass
        @task(mt)
        def f1(): # Task with the same name already exists.
            pass
    
  • You cannot create parameters for tasks or multitasks.

    with multitask(param) as mt: # Parameter not allowed.
        @task(mt)
        def f1(param_task): # Parameter not allowed.
    

Try

  • Try is only allowed to be the first statement of a function.

  • You cannot use a try statement within:
    • another try statement

    • an if block

    • an else block

    • a loop

    • a task

    • a multitask

  • You cannot use a try statement with except or orelse.

Yield

  • You cannot use yield as an operator or parameter.