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

Fix many more pytype changes for matter_idl #26371

Merged
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
27 changes: 13 additions & 14 deletions scripts/py_matter_idl/matter_idl/generators/bridge/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.

import logging
import os
import re
from typing import Tuple, Union

from matter_idl.generators import CodeGenerator, GeneratorStorage
from matter_idl.generators.types import (BasicInteger, BasicString, FundamentalType, IdlBitmapType, IdlEnumType, IdlType,
Expand All @@ -38,40 +38,39 @@ def create_lookup_context(idl: Idl, cluster: Cluster) -> TypeLookupContext:
return TypeLookupContext(idl, cluster)


def get_field_info(definition: Field, cluster: Cluster, idl: Idl):
def get_field_info(definition: Field, cluster: Cluster, idl: Idl) -> Tuple[str, str, Union[str, int, None], str]:
context = create_lookup_context(idl, cluster)
actual = ParseDataType(definition.data_type, context)

if type(actual) == IdlEnumType or type(actual) == IdlBitmapType:
if isinstance(actual, (IdlEnumType, IdlBitmapType)):
actual = actual.base_type

if type(actual) == BasicString:
if isinstance(actual, BasicString):
return 'OctetString', 'char', actual.max_length, \
'ZCL_%s_ATTRIBUTE_TYPE' % actual.idl_name.upper()

if type(actual) == BasicInteger:
if isinstance(actual, BasicInteger):
name = actual.idl_name.upper()
ty = "int%d_t" % actual.power_of_two_bits
if not actual.is_signed:
ty = "u" + ty
return "", ty, actual.byte_count, "ZCL_%s_ATTRIBUTE_TYPE" % name
if type(actual) == FundamentalType:
if isinstance(actual, FundamentalType):
if actual == FundamentalType.BOOL:
return "", "bool", 1, "ZCL_BOOLEAN_ATTRIBUTE_TYPE"
if actual == FundamentalType.FLOAT:
elif actual == FundamentalType.FLOAT:
return "", "float", 4, "ZCL_SINGLE_ATTRIBUTE_TYPE"
if actual == FundamentalType.DOUBLE:
elif actual == FundamentalType.DOUBLE:
return "", "double", 8, "ZCL_DOUBLE_ATTRIBUTE_TYPE"
logging.warn('Unknown fundamental type: %r' % actual)
return None
if type(actual) == IdlType:
else:
raise Exception('Unknown fundamental type: %r' % actual)
if isinstance(actual, IdlType):
return '', actual.idl_name, 'sizeof(%s)' % actual.idl_name, \
'ZCL_STRUCT_ATTRIBUTE_TYPE'
logging.warn('Unknown type: %r' % actual)
return None
raise Exception('UNKNOWN TYPE: %s' % actual)


def get_raw_size_and_type(attr: Attribute, cluster: Cluster, idl: Idl):
def get_raw_size_and_type(attr: Attribute, cluster: Cluster, idl: Idl) -> str:
container, cType, size, matterType = get_field_info(
attr.definition, cluster, idl)
if attr.definition.is_list:
Expand Down
38 changes: 18 additions & 20 deletions scripts/py_matter_idl/matter_idl/generators/java/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import enum
import logging
import os
from typing import List, Set, Union
from typing import List, Optional, Set

from matter_idl.generators import CodeGenerator, GeneratorStorage
from matter_idl.generators.types import (BasicInteger, BasicString, FundamentalType, IdlBitmapType, IdlEnumType, IdlType,
Expand Down Expand Up @@ -57,24 +57,22 @@ class GlobalType:
]


def _UnderlyingType(field: Field, context: TypeLookupContext) -> Union[str, None]:
def _UnderlyingType(field: Field, context: TypeLookupContext) -> Optional[str]:
actual = ParseDataType(field.data_type, context)
if type(actual) == IdlEnumType:
actual = actual.base_type
elif type(actual) == IdlBitmapType:
if isinstance(actual, (IdlEnumType, IdlBitmapType)):
actual = actual.base_type

if type(actual) == BasicString:
if isinstance(actual, BasicString):
if actual.is_binary:
return 'OctetString'
else:
return 'CharString'
elif type(actual) == BasicInteger:
elif isinstance(actual, BasicInteger):
if actual.is_signed:
return "Int{}s".format(actual.power_of_two_bits)
else:
return "Int{}u".format(actual.power_of_two_bits)
elif type(actual) == FundamentalType:
elif isinstance(actual, FundamentalType):
if actual == FundamentalType.BOOL:
return 'Boolean'
elif actual == FundamentalType.FLOAT:
Expand All @@ -87,7 +85,7 @@ def _UnderlyingType(field: Field, context: TypeLookupContext) -> Union[str, None
return None


def FieldToGlobalName(field: Field, context: TypeLookupContext) -> Union[str, None]:
def FieldToGlobalName(field: Field, context: TypeLookupContext) -> Optional[str]:
"""Global names are used for generic callbacks shared across
all clusters (e.g. for bool/float/uint32 and similar)
"""
Expand Down Expand Up @@ -246,7 +244,7 @@ def attributesWithSupportedCallback(attrs, context: TypeLookupContext):
# except non-list structures
if not attr.definition.is_list:
underlying = ParseDataType(attr.definition.data_type, context)
if type(underlying) == IdlType:
if isinstance(underlying, IdlType):
continue

yield attr
Expand Down Expand Up @@ -419,7 +417,7 @@ def get_underlying_enum(self):
def boxed_java_type(self):
t = ParseDataType(self.data_type, self.context)

if type(t) == FundamentalType:
if isinstance(t, FundamentalType):
if t == FundamentalType.BOOL:
return "Boolean"
elif t == FundamentalType.FLOAT:
Expand All @@ -428,23 +426,23 @@ def boxed_java_type(self):
return "Double"
else:
raise Exception("Unknown fundamental type")
elif type(t) == BasicInteger:
elif isinstance(t, BasicInteger):
# the >= 3 will include int24_t to be considered "long"
if t.byte_count >= 3:
return "Long"
else:
return "Integer"
elif type(t) == BasicString:
elif isinstance(t, BasicString):
if t.is_binary:
return "byte[]"
else:
return "String"
elif type(t) == IdlEnumType:
elif isinstance(t, IdlEnumType):
if t.base_type.byte_count >= 3:
return "Long"
else:
return "Integer"
elif type(t) == IdlBitmapType:
elif isinstance(t, IdlBitmapType):
if t.base_type.byte_count >= 3:
return "Long"
else:
Expand All @@ -463,7 +461,7 @@ def boxed_java_signature(self):

t = ParseDataType(self.data_type, self.context)

if type(t) == FundamentalType:
if isinstance(t, FundamentalType):
if t == FundamentalType.BOOL:
return "Ljava/lang/Boolean;"
elif t == FundamentalType.FLOAT:
Expand All @@ -472,22 +470,22 @@ def boxed_java_signature(self):
return "Ljava/lang/Double;"
else:
raise Exception("Unknown fundamental type")
elif type(t) == BasicInteger:
elif isinstance(t, BasicInteger):
if t.byte_count >= 3:
return "Ljava/lang/Long;"
else:
return "Ljava/lang/Integer;"
elif type(t) == BasicString:
elif isinstance(t, BasicString):
if t.is_binary:
return "[B"
else:
return "Ljava/lang/String;"
elif type(t) == IdlEnumType:
elif isinstance(t, IdlEnumType):
if t.base_type.byte_count >= 3:
return "Ljava/lang/Long;"
else:
return "Ljava/lang/Integer;"
elif type(t) == IdlBitmapType:
elif isinstance(t, IdlBitmapType):
if t.base_type.byte_count >= 3:
return "Ljava/lang/Long;"
else:
Expand Down
10 changes: 5 additions & 5 deletions scripts/py_matter_idl/matter_idl/generators/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,11 @@ class IdlEnumType:

@property
def byte_count(self):
return self.base_type.byte_count()
return self.base_type.byte_count

@property
def bits(self):
return self.base_type.bits()
return self.base_type.bits


@dataclass
Expand All @@ -129,11 +129,11 @@ class IdlBitmapType:

@property
def byte_count(self):
return self.base_type.byte_count()
return self.base_type.byte_count

@property
def bits(self):
return self.base_type.bits()
return self.base_type.bits


class IdlItemType(enum.Enum):
Expand Down Expand Up @@ -353,7 +353,7 @@ def is_bitmap_type(self, name: str):
return any(map(lambda s: s.name == name, self.all_bitmaps))


def ParseDataType(data_type: DataType, lookup: TypeLookupContext) -> Union[BasicInteger, BasicString, FundamentalType, IdlType]:
def ParseDataType(data_type: DataType, lookup: TypeLookupContext) -> Union[BasicInteger, BasicString, FundamentalType, IdlType, IdlEnumType, IdlBitmapType]:
"""
Given a AST data type and a lookup context, match it to a type that can be later
be used for generation.
Expand Down
30 changes: 22 additions & 8 deletions scripts/py_matter_idl/matter_idl/lint/lint_rules_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import os
import xml.etree.ElementTree
from dataclasses import dataclass
from typing import List, Mapping
from typing import List, MutableMapping

from lark import Lark
from lark.visitors import Discard, Transformer, v_args
Expand All @@ -21,7 +21,12 @@
RequiredCommandsRule)


def parseNumberString(n):
class ElementNotFoundError(Exception):
def __init__(self, name):
super().__init__(f"Could not find {name}")


def parseNumberString(n: str) -> int:
if n.startswith('0x'):
return int(n[2:], 16)
else:
Expand Down Expand Up @@ -59,7 +64,11 @@ def DecodeClusterFromXml(element: xml.etree.ElementTree.Element):
# - attribute with side, code and optional attributes

try:
name = element.find('name').text.replace(' ', '')
name = element.find('name')
if not name or not name.text:
raise ElementNotFoundError('name')

name = name.text.replace(' ', '')
required_attributes = []
required_commands = []

Expand All @@ -75,8 +84,9 @@ def DecodeClusterFromXml(element: xml.etree.ElementTree.Element):
# or
# <attribute ...><description>myName</description><access .../>...</attribute>
attr_name = attr.text
if attr.find('description') is not None:
attr_name = attr.find('description').text
description = attr.find('description')
if description is not None:
attr_name = description.text

required_attributes.append(
RequiredAttribute(
Expand All @@ -94,9 +104,13 @@ def DecodeClusterFromXml(element: xml.etree.ElementTree.Element):
required_commands.append(RequiredCommand(
name=cmd.attrib["name"], code=parseNumberString(cmd.attrib['code'])))

code = element.find('code')
if not code:
raise Exception("Failed to find cluster code")

return DecodedCluster(
name=name,
code=parseNumberString(element.find('code').text),
code=parseNumberString(code.text),
required_attributes=required_attributes,
required_commands=required_commands
)
Expand Down Expand Up @@ -132,7 +146,7 @@ def __init__(self):
"Required commands")

# Map cluster names to the underlying code
self._cluster_codes: Mapping[str, int] = {}
self._cluster_codes: MutableMapping[str, int] = {}

def GetLinterRules(self):
return [self._required_attributes_rule, self._required_commands_rule]
Expand Down Expand Up @@ -300,7 +314,7 @@ def CreateParser(file_name: str):
@click.option(
'--log-level',
default='INFO',
type=click.Choice(__LOG_LEVELS__.keys(), case_sensitive=False),
type=click.Choice(list(__LOG_LEVELS__.keys()), case_sensitive=False),
help='Determines the verbosity of script output.')
@click.argument('filename')
def main(log_level, filename=None):
Expand Down
26 changes: 20 additions & 6 deletions scripts/py_matter_idl/matter_idl/lint/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,21 @@

from abc import ABC, abstractmethod
from dataclasses import dataclass, field
from typing import List, Mapping, Optional
from typing import List, MutableMapping, Optional

from matter_idl.matter_idl_types import ClusterSide, Idl, ParseMetaData


class MissingIdlError(Exception):
def __init__(self):
super().__init__("Missing IDL data")


@dataclass
class LocationInFile:
file_name: str
line: int
column: int
line: Optional[int]
column: Optional[int]

def __init__(self, file_name: str, meta: ParseMetaData):
self.file_name = file_name
Expand Down Expand Up @@ -91,7 +96,7 @@ def _AddLintError(self, text, location):

def _ParseLocation(self, meta: Optional[ParseMetaData]) -> Optional[LocationInFile]:
"""Create a location in the current file that is being parsed. """
if not meta or not self._idl.parse_file_name:
if not meta or not self._idl or not self._idl.parse_file_name:
return None
return LocationInFile(self._idl.parse_file_name, meta)

Expand Down Expand Up @@ -145,6 +150,9 @@ def _ServerClusterDefinition(self, name: str, location: Optional[LocationInFile]

On error returns None and _lint_errors is updated internlly
"""
if not self._idl:
raise MissingIdlError()

cluster_definition = [
c for c in self._idl.clusters if c.name == name and c.side == ClusterSide.SERVER
]
Expand All @@ -161,6 +169,9 @@ def _ServerClusterDefinition(self, name: str, location: Optional[LocationInFile]
return cluster_definition[0]

def _LintImpl(self):
if not self._idl:
raise MissingIdlError()

for endpoint in self._idl.endpoints:

cluster_codes = set()
Expand Down Expand Up @@ -223,8 +234,8 @@ def __init__(self, name):
super(RequiredCommandsRule, self).__init__(name)

# Maps cluster id to mandatory cluster requirement
self._mandatory_commands: Mapping[int,
List[ClusterCommandRequirement]] = {}
self._mandatory_commands: MutableMapping[int,
List[ClusterCommandRequirement]] = {}

def __repr__(self):
result = "RequiredCommandsRule{\n"
Expand All @@ -248,6 +259,9 @@ def RequireCommand(self, cmd: ClusterCommandRequirement):
self._mandatory_commands[cmd.cluster_code] = [cmd]

def _LintImpl(self):
if not self._idl:
raise MissingIdlError()

for cluster in self._idl.clusters:
if cluster.side != ClusterSide.SERVER:
continue # only validate server-side:
Expand Down
Loading