Skip to content

Commit

Permalink
Prevent abstract Types from beeing instantiated (#842)
Browse files Browse the repository at this point in the history
* init

* add: is_abstract check and typehints

* change import for Node

* change import for Node

* remove nodeclass-typehints due to import error

* add test for instantiate abstract type

* edit: change ValueError to UaError

* edit: test
  • Loading branch information
AndreasHeine authored Mar 24, 2022
1 parent 729ef89 commit eabd784
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 1 deletion.
13 changes: 12 additions & 1 deletion asyncua/common/instantiate_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

import logging

from typing import Union

from asyncua import ua
from .ua_utils import get_node_supertypes, is_child_present
from .copy_node_util import _rdesc_from_node, _read_and_copy_attrs
Expand All @@ -12,13 +14,22 @@
logger = logging.getLogger(__name__)


async def instantiate(parent, node_type, nodeid=None, bname=None, dname=None, idx=0, instantiate_optional=True):
async def is_abstract(node_type) -> bool:
result = await node_type.read_attribute(ua.AttributeIds.IsAbstract)
return result.Value.Value


async def instantiate(parent, node_type, nodeid: ua.NodeId=None, bname: Union[str, ua.QualifiedName]=None, dname: ua.LocalizedText=None, idx: int=0, instantiate_optional: bool=True):
"""
instantiate a node type under a parent node.
nodeid and browse name of new node can be specified, or just namespace index
If they exists children of the node type, such as components, variables and
properties are also instantiated
"""
abstract = await is_abstract(node_type)
if abstract:
raise ua.UaError(f"InstantiationError NodeId: {node_type.nodeid} is abstract and cant be instantiated!")

rdesc = await _rdesc_from_node(parent, node_type)
rdesc.TypeDefinition = node_type.nodeid

Expand Down
6 changes: 6 additions & 0 deletions tests/test_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -1010,6 +1010,12 @@ async def test_instantiate_string_nodeid(opc):
await opc.opc.delete_nodes([dev_t])


async def test_instantiate_abstract(opc):
finit_statemachine_type = opc.opc.get_node("ns=0;i=2771") # IsAbstract=True
with pytest.raises(ua.UaError):
node = await instantiate(opc.opc.nodes.objects, finit_statemachine_type, bname="2:TestFiniteStateMachine")


async def test_variable_with_datatype(opc):
v1 = await opc.opc.nodes.objects.add_variable(
3, 'VariableEnumType1', ua.ApplicationType.ClientAndServer, datatype=ua.NodeId(ua.ObjectIds.ApplicationType)
Expand Down

0 comments on commit eabd784

Please sign in to comment.