Commit 36673c75 authored by Alexander Schrode's avatar Alexander Schrode Committed by GitHub

Allow List,Union,Optional named fields (#1454)

* Allow List,Union,Optional named fields

Fixes #1441

* use typing
parent 8b72a632
...@@ -5,7 +5,8 @@ import uuid ...@@ -5,7 +5,8 @@ import uuid
import logging import logging
import re import re
import keyword import keyword
from typing import Union, List, TYPE_CHECKING, Tuple, Optional, Any, Dict, Set import typing
from typing import Union, List, TYPE_CHECKING, Tuple, Any, Dict, Set
from dataclasses import dataclass, field from dataclasses import dataclass, field
from asyncua import ua from asyncua import ua
...@@ -228,22 +229,22 @@ class {struct_name}{base_class}: ...@@ -228,22 +229,22 @@ class {struct_name}{base_class}:
if sfield.ValueRank >= 1 and uatype == 'Char': if sfield.ValueRank >= 1 and uatype == 'Char':
uatype = 'String' uatype = 'String'
elif sfield.ValueRank >= 1 or sfield.ArrayDimensions: elif sfield.ValueRank >= 1 or sfield.ArrayDimensions:
uatype = f"List[{uatype}]" uatype = f"typing.List[{uatype}]"
if sfield.IsOptional: if sfield.IsOptional:
uatype = f"Optional[{uatype}]" uatype = f"typing.Optional[{uatype}]"
default_value = 'None' default_value = 'None'
fields.append((fname, uatype, default_value)) fields.append((fname, uatype, default_value))
if is_union: if is_union:
# Generate getter and setter to mimic opc ua union access # Generate getter and setter to mimic opc ua union access
names = [f[1] for f in fields] names = [f[1] for f in fields]
code += " _union_types = [" + ','.join(names) + "]\n" code += " _union_types = [" + ','.join(names) + "]\n"
code += " Value: Union[None, " + ','.join(names) + "] = field(default=None, init=False)" code += " Value: typing.Union[None, " + ','.join(names) + "] = field(default=None, init=False)"
for enc_idx, fd in enumerate(fields): for enc_idx, fd in enumerate(fields):
name, uatype, _ = fd name, uatype, _ = fd
code += f''' code += f'''
@property @property
def {name}(self) -> Optional[{uatype}]: def {name}(self) -> typing.Optional[{uatype}]:
if self.Encoding == {enc_idx + 1}: if self.Encoding == {enc_idx + 1}:
return self.Value return self.Value
return None return None
...@@ -281,14 +282,10 @@ async def _generate_object(name, sdef, data_type=None, env=None, enum=False, opt ...@@ -281,14 +282,10 @@ async def _generate_object(name, sdef, data_type=None, env=None, enum=False, opt
env['IntFlag'] = IntFlag env['IntFlag'] = IntFlag
if "dataclass" not in env: if "dataclass" not in env:
env['dataclass'] = dataclass env['dataclass'] = dataclass
if "Optional" not in env: if "typing" not in env:
env['Optional'] = Optional env['typing'] = typing
if "List" not in env:
env['List'] = List
if "field" not in env: if "field" not in env:
env['field'] = field env['field'] = field
if "Union" not in env:
env['Union'] = Union
# generate classe add it to env dict # generate classe add it to env dict
if enum: if enum:
code = make_enum_code(name, sdef, option_set) code = make_enum_code(name, sdef, option_set)
......
...@@ -2036,6 +2036,7 @@ async def test_custom_struct_with_strange_chars(opc): ...@@ -2036,6 +2036,7 @@ async def test_custom_struct_with_strange_chars(opc):
[ [
new_struct_field('My"Bool', ua.VariantType.Boolean), new_struct_field('My"Bool', ua.VariantType.Boolean),
new_struct_field("My'UInt32", ua.VariantType.UInt32, array=True), new_struct_field("My'UInt32", ua.VariantType.UInt32, array=True),
new_struct_field("List", ua.VariantType.UInt32, array=True),
], ],
) )
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment