From 1ae5d468c071925398046dc6a85ca89e65c9dbdb Mon Sep 17 00:00:00 2001 From: Thanassis Tsiodras Date: Fri, 8 Jul 2016 14:02:06 +0200 Subject: [PATCH] More type annotations --- dmt/A_mappers/rtds_A_mapper.py | 9 +- dmt/B_mappers/python_B_mapper.py | 18 +++- dmt/commonPy/aadlAST.py | 118 +++++++++++++---------- dmt/commonPy/asnAST.py | 160 ++++++++++++++++--------------- dmt/commonPy/utility.py | 22 ++--- 5 files changed, 182 insertions(+), 145 deletions(-) diff --git a/dmt/A_mappers/rtds_A_mapper.py b/dmt/A_mappers/rtds_A_mapper.py index c81aae7..3136834 100644 --- a/dmt/A_mappers/rtds_A_mapper.py +++ b/dmt/A_mappers/rtds_A_mapper.py @@ -23,22 +23,25 @@ to RTDS. It is used by the backend of Semantix's code generator A.''' import re +from ..commonPy.cleanupNodes import SetOfBadTypenames +from ..commonPy.asnParser import AST_Leaftypes, AsnNode + g_outputDir = "" g_asnFile = "" -def Version(): +def Version() -> None: print("Code generator: " + "$Id: og_A_mapper.py 1879 2010-05-17 10:13:12Z ttsiodras $") # pragma: no cover -def OnStartup(unused_modelingLanguage, asnFile, outputDir, unused_badTypes): +def OnStartup(unused_modelingLanguage: str, asnFile: str, outputDir: str, unused_badTypes: SetOfBadTypenames) -> None: global g_asnFile g_asnFile = asnFile global g_outputDir g_outputDir = outputDir -def OnBasic(unused_nodeTypename, unused_node, unused_leafTypeDict): +def OnBasic(unused_nodeTypename: str, unused_node: AsnNode, unused_leafTypeDict: AST_Leaftypes) -> None: pass diff --git a/dmt/B_mappers/python_B_mapper.py b/dmt/B_mappers/python_B_mapper.py index 5535564..0da0f2e 100644 --- a/dmt/B_mappers/python_B_mapper.py +++ b/dmt/B_mappers/python_B_mapper.py @@ -23,6 +23,9 @@ import os from typing import Set, Dict # NOQA pylint: disable=unused-import +from ..commonPy.aadlAST import ApLevelContainer, Param +from ..commonPy.asnParser import AST_Leaftypes, AST_Lookup, AsnNode + g_HeaderFile = None g_SourceFile = None g_PythonFile = None @@ -37,15 +40,22 @@ g_asn_name = "" g_outputDir = "" g_maybeFVname = "" g_perFV = set() # type: Set[str] -g_langPerSP = {} # type: Dict[str, str] +g_langPerSP = {} # type: Dict[ApLevelContainer, str] -def CleanName(name): +def CleanName(name: str) -> str: return re.sub(r'[^a-zA-Z0-9_]', '_', name) # Called once per RI (i.e. per SUBPROGRAM IMPLEMENTATION) -def OnStartup(modelingLanguage, asnFile, subProgram, unused_subProgramImplementation, outputDir, maybeFVname, unused_useOSS): +def OnStartup( + modelingLanguage: str, + asnFile: str, + subProgram: ApLevelContainer, + unused_subProgramImplementation: str, + outputDir: str, + maybeFVname: str, + unused_useOSS: bool) -> None: g_langPerSP[subProgram] = modelingLanguage CleanSP = CleanName(subProgram._id) @@ -227,7 +237,7 @@ def OnStartup(modelingLanguage, asnFile, subProgram, unused_subProgramImplementa g_SourceFile.write('}\n') -def Common(unused_nodeTypename, unused_node, unused_subProgram, unused_subProgramImplementation, unused_param, unused_leafTypeDict, unused_names): +def Common(unused_nodeTypename: str, unused_node: AsnNode, unused_subProgram: ApLevelContainer, unused_subProgramImplementation: str, unused_param: Param, unused_leafTypeDict: AST_Leaftypes, unused_names: AST_Lookup) -> None: pass diff --git a/dmt/commonPy/aadlAST.py b/dmt/commonPy/aadlAST.py index 190fc7e..68bee89 100644 --- a/dmt/commonPy/aadlAST.py +++ b/dmt/commonPy/aadlAST.py @@ -37,7 +37,7 @@ # # Charge for Runtimes None None -from typing import Tuple, Dict # NOQA pylint: disable=unused-import +from typing import Tuple, Union, Dict, Any # NOQA pylint: disable=unused-import g_apLevelContainers = {} # type: Dict[str, ApLevelContainer] @@ -49,102 +49,106 @@ g_threadImplementations = [] # type: List[Tuple[str,str,str,str]] class AadlParameter: - def __init__(self, direction, typ): + def __init__(self, direction: str, typ: str) -> None: assert direction in ['IN', 'OUT', 'INOUT'] self._direction = direction self._type = typ class AadlSubProgramFeature: - def __init__(self, iid, parameter): + def __init__(self, iid: str, parameter: AadlParameter) -> None: self._id = iid self._parameter = parameter class AadlPropertyAssociationNoModes: - def __init__(self, name, pe): + def __init__(self, name: str, pe: Any) -> None: self._name = name self._propertyExpressionOrList = pe class AadlPort: - def __init__(self, direction, typ): + def __init__(self, direction: str, typ: str) -> None: self._direction = direction self._type = typ class AadlEventPort: - def __init__(self, direction, sp): + def __init__(self, direction: str, sp: 'ApLevelContainer') -> None: self._direction = direction self._sp = sp - def __repr__(self): + def __repr__(self) -> str: result = "AadlEventPort(" + self._direction + "," if self._sp: - result += self._sp + result += str(self._sp) result += ")" return result class AadlEventDataPort(AadlPort): - def __init__(self, direction, typ): + def __init__(self, direction: str, typ: str) -> None: AadlPort.__init__(self, direction, typ) class AadlThreadFeature: - def __init__(self, iid, port): + def __init__(self, iid: str, port: AadlPort) -> None: assert isinstance(port, AadlPort) self._id = iid self._port = port class AadlProcessFeature: - def __init__(self, iid, port): + def __init__(self, iid: str, port: AadlPort) -> None: assert isinstance(port, AadlPort) self._id = iid self._port = port class AadlContainedPropertyAssociation: - def __init__(self, name, value): + def __init__(self, name: str, value: Any) -> None: self._name = name self._value = value class Signal: - def __init__(self, asnFilename, asnNodename, asnSize): + def __init__(self, asnFilename: str, asnNodename: str, asnSize: int) -> None: self._asnFilename = asnFilename self._asnNodename = asnNodename self._asnSize = asnSize -class Port: - def __init__(self, signal): - self._signal = signal - - -class DualPort(Port): - def __init__(self, signal): - Port.__init__(self, signal) - - -class UniPort(Port): - def __init__(self, signal): - Port.__init__(self, signal) - - -class IncomingUniPort(UniPort): - def __init__(self, signal): - UniPort.__init__(self, signal) - - -class OutgoingUniPort(UniPort): - def __init__(self, signal): - UniPort.__init__(self, signal) +# class Port: +# def __init__(self, signal): +# self._signal = signal +# +# +# class DualPort(Port): +# def __init__(self, signal): +# Port.__init__(self, signal) +# +# +# class UniPort(Port): +# def __init__(self, signal): +# Port.__init__(self, signal) +# +# +# class IncomingUniPort(UniPort): +# def __init__(self, signal): +# UniPort.__init__(self, signal) +# +# +# class OutgoingUniPort(UniPort): +# def __init__(self, signal): +# UniPort.__init__(self, signal) class Param: - def __init__(self, aplcID, iid, signal, sourceElement): + def __init__(self, + aplcID: str, + iid: str, + signal: Signal, + sourceElement: Union[AadlPort, AadlEventDataPort, AadlParameter]) -> None: self._id = iid # It is the Process, Thread or Subprogram ID self._aplcID = aplcID @@ -154,48 +158,60 @@ class Param: class InParam(Param): - def __init__(self, aplcID, iid, signal, sourceElement): + def __init__(self, + aplcID: str, + iid: str, + signal: Signal, + sourceElement: Union[AadlPort, AadlEventDataPort, AadlParameter]) -> None: Param.__init__(self, aplcID, iid, signal, sourceElement) class OutParam(Param): - def __init__(self, aplcID, iid, signal, sourceElement): + def __init__(self, + aplcID: str, + iid: str, + signal: Signal, + sourceElement: Union[AadlPort, AadlEventDataPort, AadlParameter]) -> None: Param.__init__(self, aplcID, iid, signal, sourceElement) class InOutParam(Param): - def __init__(self, aplcID, iid, signal, sourceElement): + def __init__(self, + aplcID: str, + iid: str, + signal: Signal, + sourceElement: Union[AadlPort, AadlEventDataPort, AadlParameter]) -> None: Param.__init__(self, aplcID, iid, signal, sourceElement) +class UniquePortIdentifier: + def __init__(self, componentId: str, portId: str) -> None: + self._componentId = componentId + self._portId = portId + + class ApLevelContainer: - def __init__(self, iid): + def __init__(self, iid: str) -> None: self._id = iid self._params = [] # type: List[Param] self._connections = [] # type: List[Connection] self._language = None # type: str - def AddConnection(self, srcUniquePortId, destUniquePortId): + def AddConnection(self, srcUniquePortId: UniquePortIdentifier, destUniquePortId: UniquePortIdentifier) -> None: if srcUniquePortId._componentId is None: srcUniquePortId._componentId = self._id if destUniquePortId._componentId is None: destUniquePortId._componentId = self._id self._connections.append(Connection(srcUniquePortId, destUniquePortId)) - def AddParam(self, param: Param): + def AddParam(self, param: Param) -> None: self._params.append(param) - def SetLanguage(self, language: str): + def SetLanguage(self, language: str) -> None: self._language = language -class UniquePortIdentifier: - def __init__(self, componentId, portId): - self._componentId = componentId - self._portId = portId - - class Connection: - def __init__(self, fromC, toC): + def __init__(self, fromC: UniquePortIdentifier, toC: UniquePortIdentifier) -> None: self._from = fromC self._to = toC diff --git a/dmt/commonPy/asnAST.py b/dmt/commonPy/asnAST.py index 5448034..ddca1a9 100644 --- a/dmt/commonPy/asnAST.py +++ b/dmt/commonPy/asnAST.py @@ -75,36 +75,38 @@ # | AsnMetaMember | # +-----------------------------+ -from typing import Union, Dict # NOQA pylint: disable=unused-import +from typing import List, Union, Dict, Any # NOQA pylint: disable=unused-import from . import utility +Lookup = Dict[str, 'AsnNode'] + class AsnNode(object): - def __init__(self, asnFilename): + def __init__(self, asnFilename: str) -> None: self._leafType = "unknown" self._asnFilename = asnFilename self._lineno = -1 self._isArtificial = False - def Location(self): + def Location(self) -> str: return "file %s, line %d" % (self._asnFilename, int(self._lineno)) # pragma: no cover - def IdenticalPerSMP2(self, _, __, ___): # pylint: disable=no-self-use + def IdenticalPerSMP2(self, _: 'AsnNode', __: Lookup, ___: Lookup) -> bool: # pylint: disable=no-self-use utility.panic("internal error: Must be defined in derived class...") - def AsASN1(self, _): # pylint: disable=no-self-use + def AsASN1(self, _: Lookup) -> str: # pylint: disable=no-self-use utility.panic("internal error: Must be defined in derived class...") class AsnBasicNode(AsnNode): - def __init__(self, asnFilename): + def __init__(self, asnFilename: str) -> None: AsnNode.__init__(self, asnFilename) class AsnComplexNode(AsnNode): - def __init__(self, asnFilename): + def __init__(self, asnFilename: str) -> None: AsnNode.__init__(self, asnFilename) ######################################################### @@ -112,9 +114,9 @@ class AsnComplexNode(AsnNode): ######################################################### -def CommonIdenticalRangePerSMP2(range1, range2): +def CommonIdenticalRangePerSMP2(range1: List[int], range2: List[int]) -> bool: # pylint: disable=invalid-sequence-index '''Helper for SMP2 comparisons of types with ranges.''' - def collapseSpan(r): + def collapseSpan(r: List[int]) -> List[int]: # pylint: disable=invalid-sequence-index if len(r) == 2 and r[0] == r[1]: return [r[0]] return r @@ -135,7 +137,7 @@ Members: ''' validOptions = ['bDefaultValue', 'lineno', 'asnFilename'] - def __init__(self, **args): + def __init__(self, **args: Any) -> None: AsnBasicNode.__init__(self, args.get('asnFilename', '')) self._name = "BOOLEAN" # default in case of SEQUENCE_OF BOOLEAN self._leafType = "BOOLEAN" @@ -144,16 +146,16 @@ Members: for i in args.keys(): assert i in AsnBool.validOptions - def __repr__(self): + def __repr__(self) -> str: result = self._leafType if self._bDefaultValue is not None: result += ", default value " + self._bDefaultValue # pragma: no cover return result - def IdenticalPerSMP2(self, other, _, __): + def IdenticalPerSMP2(self, other: AsnNode, _: Lookup, __: Lookup) -> bool: return isinstance(other, AsnBool) - def AsASN1(self, _): + def AsASN1(self, _: Lookup) -> str: return 'BOOLEAN' @@ -167,7 +169,7 @@ Members: ''' validOptions = ['range', 'iDefaultValue', 'lineno', 'asnFilename'] - def __init__(self, **args): + def __init__(self, **args: Any) -> None: AsnBasicNode.__init__(self, args.get('asnFilename', '')) self._name = "INTEGER" # default in case of SEQUENCE_OF INTEGER self._leafType = "INTEGER" @@ -177,7 +179,7 @@ Members: for i in args.keys(): assert i in AsnInt.validOptions - def __repr__(self): + def __repr__(self) -> str: result = self._leafType if self._range: result += " within [%s,%s]" % (self._range[0], self._range[1]) @@ -185,10 +187,10 @@ Members: result += " with default value of %s" % self._iDefaultValue # pragma: no cover return result - def IdenticalPerSMP2(self, other, _, __): + def IdenticalPerSMP2(self, other: AsnNode, _: Lookup, __: Lookup) -> bool: return isinstance(other, AsnInt) and CommonIdenticalRangePerSMP2(self._range, other._range) - def AsASN1(self, _): + def AsASN1(self, _: Lookup) -> str: ret = 'INTEGER' if self._range: ret += ' (' + str(self._range[0]) + ' .. ' + str(self._range[1]) + ')' @@ -210,7 +212,7 @@ Members: ''' validOptions = ['range', 'mantissa', 'base', 'exponent', 'defaultValue', 'lineno', 'asnFilename'] - def __init__(self, **args): + def __init__(self, **args: Any) -> None: AsnBasicNode.__init__(self, args.get('asnFilename', '')) self._name = "REAL" # default in case of SEQUENCE_OF REAL self._leafType = "REAL" @@ -223,7 +225,7 @@ Members: for i in args.keys(): assert i in AsnReal.validOptions - def __repr__(self): + def __repr__(self) -> str: result = self._leafType if self._mantissaRange is not None: result += ", mantissa range is" # pragma: no cover @@ -242,10 +244,10 @@ Members: result += " within [%s,%s]" % (self._range[0], self._range[1]) return result - def IdenticalPerSMP2(self, other, _, __): + def IdenticalPerSMP2(self, other: AsnNode, _: Lookup, __: Lookup) -> bool: return isinstance(other, AsnReal) and CommonIdenticalRangePerSMP2(self._range, other._range) - def AsASN1(self, _): + def AsASN1(self, _: Lookup) -> str: ret = 'REAL' if self._range: ret += ' (' + ("%f" % self._range[0]) + ' .. ' + ("%f" % self._range[1]) + ')' @@ -261,7 +263,7 @@ Members: ''' validOptions = ['range', 'lineno', 'asnFilename'] - def __init__(self, **args): + def __init__(self, **args: Any) -> None: AsnBasicNode.__init__(self, args.get('asnFilename', '')) self._leafType = "unknown" self._lineno = args.get('lineno', None) @@ -273,17 +275,17 @@ Members: for i in args.keys(): assert i in AsnString.validOptions - def __repr__(self): + def __repr__(self) -> str: result = self._leafType if self._range: result += ", length within " result += str(self._range) return result - def IdenticalPerSMP2(self, other, _, __): + def IdenticalPerSMP2(self, other: AsnNode, _: Lookup, __: Lookup) -> bool: return isinstance(other, AsnString) and CommonIdenticalRangePerSMP2(self._range, other._range) - def AsASN1(self, _): + def AsASN1(self, _: Lookup) -> str: ret = 'OCTET STRING' if self._range: if len(self._range) > 1 and self._range[0] != self._range[1]: @@ -296,7 +298,7 @@ Members: class AsnOctetString(AsnString): '''This class stores the semantic content of an ASN.1 OCTET STRING.''' - def __init__(self, **args): + def __init__(self, **args: Any) -> None: AsnString.__init__(self, **args) self._name = "OCTET STRING" # default in case of SEQUENCE_OF OCTET STRING self._leafType = "OCTET STRING" @@ -312,7 +314,7 @@ class AsnOctetString(AsnString): class AsnUTF8String(AsnString): '''This class stores the semantic content of an ASN.1 UTF8String.''' - def __init__(self, **args): + def __init__(self, **args: Any) -> None: AsnString.__init__(self, **args) # pragma: no cover self._name = "UTF8String" # default in case of SEQUENCE_OF UTF8String # pragma: no cover self._leafType = "UTF8String" # pragma: no cover @@ -321,7 +323,7 @@ class AsnUTF8String(AsnString): class AsnAsciiString(AsnString): '''This class stores the semantic content of an ASN.1 AsciiString.''' - def __init__(self, **args): + def __init__(self, **args: Any) -> None: AsnString.__init__(self, **args) # pragma: no cover self._name = "AsciiString" # default in case of SEQUENCE_OF AsciiString # pragma: no cover self._leafType = "AsciiString" # pragma: no cover @@ -330,7 +332,7 @@ class AsnAsciiString(AsnString): class AsnNumberString(AsnString): '''This class stores the semantic content of an ASN.1 NumberString.''' - def __init__(self, **args): + def __init__(self, **args: Any) -> None: AsnString.__init__(self, **args) # pragma: no cover self._name = "NumberString" # default in case of SEQUENCE_OF NumberString # pragma: no cover self._leafType = "NumberString" # pragma: no cover @@ -339,7 +341,7 @@ class AsnNumberString(AsnString): class AsnVisibleString(AsnString): '''This class stores the semantic content of an ASN.1 VisibleString.''' - def __init__(self, **args): + def __init__(self, **args: Any) -> None: AsnString.__init__(self, **args) # pragma: no cover self._name = "VisibleString" # default in case of SEQUENCE_OF VisibleString # pragma: no cover self._leafType = "VisibleString" # pragma: no cover @@ -348,7 +350,7 @@ class AsnVisibleString(AsnString): class AsnPrintableString(AsnString): '''This class stores the semantic content of an ASN.1 PrintableString.''' - def __init__(self, **args): + def __init__(self, **args: Any) -> None: AsnString.__init__(self, **args) # pragma: no cover self._name = "PrintableString" # default in case of SEQUENCE_OF PrintableString # pragma: no cover self._leafType = "PrintableString" # pragma: no cover @@ -372,7 +374,7 @@ Members: ''' validOptions = ['members', 'default', 'lineno', 'asnFilename'] - def __init__(self, **args): + def __init__(self, **args: Any) -> None: AsnComplexNode.__init__(self, args.get('asnFilename', '')) self._name = "ENUMERATED" # default in case of SEQUENCE_OF ENUMERATED self._leafType = "ENUMERATED" @@ -395,7 +397,7 @@ Members: else: existing[elem[0]] = 1 - def __repr__(self): + def __repr__(self) -> str: result = self._leafType assert self._members != [] for member in self._members: @@ -403,17 +405,20 @@ Members: result += str(member) return result - def IdenticalPerSMP2(self, other, _, __): + def IdenticalPerSMP2(self, other: AsnNode, _: Lookup, __: Lookup) -> bool: return isinstance(other, AsnEnumerated) and sorted(self._members) == sorted(other._members) - def AsASN1(self, _): + def AsASN1(self, _: Lookup) -> str: ret = [] for m in self._members: ret.append(m[0] + '(' + m[1] + ')') return 'ENUMERATED {' + ", ".join(ret) + "}" -def CommonIdenticalCheck(me, other, mynames, othernames): +TypeWithMembers = Union['AsnSequence', 'AsnSet', 'AsnChoice'] + + +def CommonIdenticalCheck(me: TypeWithMembers, other: TypeWithMembers, mynames: Lookup, othernames: Lookup) -> bool: # sort members on variable name myMembers = [y[1] for y in sorted((x[0], x[1]) for x in me._members)] otherMembers = [y[1] for y in sorted((x[0], x[1]) for x in other._members)] @@ -434,7 +439,7 @@ def CommonIdenticalCheck(me, other, mynames, othernames): return all(x.IdenticalPerSMP2(y, mynames, othernames) for x, y in zip(myMembers, otherMembers)) -def CommonAsASN1(kind, node, typeDict): +def CommonAsASN1(kind: str, node: TypeWithMembers, typeDict: Lookup) -> str: ret = [] for m in node._members: child = m[1] @@ -459,7 +464,7 @@ Members: ''' validOptions = ['members', 'lineno', 'asnFilename'] - def __init__(self, **args): + def __init__(self, **args: Any) -> None: AsnComplexNode.__init__(self, args.get('asnFilename', '')) self._name = "SEQUENCE" self._leafType = "SEQUENCE" @@ -477,7 +482,7 @@ Members: else: existing[elem[0]] = 1 - def __repr__(self): + def __repr__(self) -> str: result = self._leafType assert self._members != [] for member in self._members: @@ -485,14 +490,14 @@ Members: result += str(member) return result - def IdenticalPerSMP2(self, other, mynames, othernames): + def IdenticalPerSMP2(self, other: AsnNode, mynames: Lookup, othernames: Lookup) -> bool: # to allow for SMP2 mappings, where there's no AsnSet # return isinstance(other, AsnSequence) and CommonIdenticalCheck(self, other, mynames, othernames) return \ - (isinstance(other, AsnSet) or isinstance(other, AsnSequence)) and \ + isinstance(other, (AsnSet, AsnSequence, AsnChoice)) and \ CommonIdenticalCheck(self, other, mynames, othernames) - def AsASN1(self, typeDict=None): + def AsASN1(self, typeDict: Lookup=None) -> str: if typeDict is None: typeDict = {} return CommonAsASN1('SEQUENCE', self, typeDict) @@ -500,7 +505,7 @@ Members: class AsnSet(AsnComplexNode): - def __init__(self, **args): + def __init__(self, **args: Any) -> None: AsnComplexNode.__init__(self, args.get('asnFilename', '')) self._name = "SET" self._leafType = "SET" @@ -518,7 +523,7 @@ class AsnSet(AsnComplexNode): else: existing[elem[0]] = 1 - def __repr__(self): + def __repr__(self) -> str: result = self._leafType assert self._members != [] for member in self._members: @@ -526,14 +531,14 @@ class AsnSet(AsnComplexNode): result += str(member) return result - def IdenticalPerSMP2(self, other, mynames, othernames): + def IdenticalPerSMP2(self, other: AsnNode, mynames: Lookup, othernames: Lookup) -> bool: # to allow for SMP2 mappings, where there's no AsnSet # return isinstance(other, AsnSet) and CommonIdenticalCheck(self, other, mynames, othernames) return \ - (isinstance(other, AsnSet) or isinstance(other, AsnSequence)) and \ + isinstance(other, (AsnSet, AsnSequence, AsnChoice)) and \ CommonIdenticalCheck(self, other, mynames, othernames) - def AsASN1(self, typeDict=None): + def AsASN1(self, typeDict: Lookup=None) -> str: if typeDict is None: typeDict = {} return CommonAsASN1('SET', self, typeDict) @@ -550,7 +555,7 @@ Members: ''' validOptions = ['members', 'lineno', 'asnFilename'] - def __init__(self, **args): + def __init__(self, **args: Any) -> None: AsnComplexNode.__init__(self, args.get('asnFilename', '')) self._name = "CHOICE" # default in case of SEQUENCE_OF CHOICE self._leafType = "CHOICE" @@ -568,7 +573,7 @@ Members: else: existing[elem[0]] = 1 - def __repr__(self): + def __repr__(self) -> str: result = self._leafType assert self._members != [] for member in self._members: @@ -576,16 +581,19 @@ Members: result += str(member) return result - def IdenticalPerSMP2(self, other, mynames, othernames): + def IdenticalPerSMP2(self, other: AsnNode, mynames: Lookup, othernames: Lookup) -> bool: return isinstance(other, AsnChoice) and CommonIdenticalCheck(self, other, mynames, othernames) - def AsASN1(self, typeDict=None): + def AsASN1(self, typeDict: Lookup=None) -> str: if typeDict is None: typeDict = {} return CommonAsASN1('CHOICE', self, typeDict) -def CommonIdenticalArrayCheck(me, other, mynames, othernames): +TypeWithRange = Union['AsnSequenceOf', 'AsnSetOf'] + + +def CommonIdenticalArrayCheck(me: TypeWithRange, other: TypeWithRange, mynames: Lookup, othernames: Lookup) -> bool: if not CommonIdenticalRangePerSMP2(me._range, other._range): return False cont = [[me._containedType, mynames], [other._containedType, othernames]] @@ -599,7 +607,7 @@ def CommonIdenticalArrayCheck(me, other, mynames, othernames): return cont[0][0].IdenticalPerSMP2(cont[1][0], mynames, othernames) -def CommonAsASN1array(kind, node, typeDict): +def CommonAsASN1array(kind: str, node: TypeWithRange, typeDict: Lookup) -> str: contained = node._containedType while isinstance(contained, str): if contained not in typeDict: @@ -625,7 +633,7 @@ Members: ''' validOptions = ['range', 'containedType', 'lineno', 'asnFilename'] - def __init__(self, **args): + def __init__(self, **args: Any) -> None: AsnComplexNode.__init__(self, args.get('asnFilename', '')) self._range = args.get('range', []) self._containedType = args.get('containedType', None) @@ -635,7 +643,7 @@ Members: for i in args.keys(): assert i in AsnSequenceOf.validOptions - def __repr__(self): + def __repr__(self) -> str: result = self._leafType if self._range: result += ", valid sizes in " @@ -645,12 +653,12 @@ Members: result += str(self._containedType) return result - def IdenticalPerSMP2(self, other, mynames, othernames): + def IdenticalPerSMP2(self, other: AsnNode, mynames: Lookup, othernames: Lookup) -> bool: return \ - (isinstance(other, AsnSequenceOf) or isinstance(other, AsnSetOf)) and \ + isinstance(other, (AsnSequenceOf, AsnSetOf)) and \ CommonIdenticalArrayCheck(self, other, mynames, othernames) - def AsASN1(self, typeDict=None): + def AsASN1(self, typeDict: Lookup=None) -> str: if typeDict is None: typeDict = {} return CommonAsASN1array('SEQUENCE', self, typeDict) @@ -658,7 +666,7 @@ Members: class AsnSetOf(AsnComplexNode): - def __init__(self, **args): + def __init__(self, **args: Any) -> None: AsnComplexNode.__init__(self, args.get('asnFilename', '')) self._range = args.get('range', []) self._containedType = args.get('containedType', None) @@ -668,7 +676,7 @@ class AsnSetOf(AsnComplexNode): for i in args.keys(): assert i in AsnSequenceOf.validOptions - def __repr__(self): + def __repr__(self) -> str: result = self._leafType if self._range: result += ", valid sizes in " @@ -678,12 +686,12 @@ class AsnSetOf(AsnComplexNode): result += str(self._containedType) return result - def IdenticalPerSMP2(self, other, mynames, othernames): + def IdenticalPerSMP2(self, other: AsnNode, mynames: Lookup, othernames: Lookup) -> bool: return \ - (isinstance(other, AsnSequenceOf) or isinstance(other, AsnSetOf)) and \ + isinstance(other, (AsnSequenceOf, AsnSetOf)) and \ CommonIdenticalArrayCheck(self, other, mynames, othernames) - def AsASN1(self, typeDict=None): + def AsASN1(self, typeDict: Lookup=None) -> str: if typeDict is None: typeDict = {} return CommonAsASN1array('SET', self, typeDict) @@ -698,7 +706,7 @@ Members: ''' validOptions = ['containedType', 'Min', 'Max', 'lineno', 'asnFilename'] - def __init__(self, **args): + def __init__(self, **args: Any) -> None: AsnNode.__init__(self, args.get('asnFilename', '')) self._leafType = args.get('containedType', None) self._containedType = args.get('containedType', None) @@ -708,13 +716,13 @@ Members: for i in args.keys(): assert i in AsnMetaMember.validOptions -# def __repr__(self): -# result = self._leafType -# assert self._leafType != None -# result += ", contained member is " -# result += " of type " -# result += self._containedType -# return result + def __repr__(self) -> str: + result = self._leafType + assert self._leafType is not None + result += ", contained member is " + result += " of type " + result += self._containedType + return result class AsnMetaType(AsnNode): @@ -730,7 +738,7 @@ e.g.: ''' validOptions = ['containedType', 'Min', 'Max', 'lineno', 'asnFilename'] - def __init__(self, **args): + def __init__(self, **args: Any) -> None: AsnNode.__init__(self, args.get('asnFilename', '')) self._leafType = args.get('containedType', None) self._containedType = args.get('containedType', None) @@ -740,7 +748,7 @@ e.g.: for i in args.keys(): assert i in AsnMetaType.validOptions - def __repr__(self): + def __repr__(self) -> str: result = "typedefed to " + self._leafType # pragma: no cover if self._Min is not None: result += ", min=" + str(self._Min) # pragma: no cover @@ -752,15 +760,15 @@ e.g.: # Helper functions -def isSequenceVariable(node): +def isSequenceVariable(node: Union[AsnString, AsnSequenceOf, AsnSetOf]) -> bool: return len(node._range) == 2 and node._range[0] != node._range[1] -def sourceSequenceLimit(node, srcCVariable): +def sourceSequenceLimit(node: Union[AsnString, AsnSequenceOf, AsnSetOf], srcCVariable: str) -> str: return str(node._range[-1]) if not isSequenceVariable(node) else "%s.nCount" % srcCVariable -def targetSequenceLimit(node, dstCVariable): +def targetSequenceLimit(node: Union[AsnString, AsnSequenceOf, AsnSetOf], dstCVariable: str) -> str: return str(node._range[-1]) if not isSequenceVariable(node) else "%s.nCount" % dstCVariable # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 diff --git a/dmt/commonPy/utility.py b/dmt/commonPy/utility.py index 1c46d85..21501a3 100644 --- a/dmt/commonPy/utility.py +++ b/dmt/commonPy/utility.py @@ -43,17 +43,17 @@ import re import platform import traceback -from typing import Dict, Union, Match # NOQA pylint: disable=unused-import +from typing import Dict, Union, Match, Any # NOQA pylint: disable=unused-import from . import configMT -def inform(fmt: str, *args) -> None: +def inform(fmt: str, *args: Any) -> None: if configMT.verbose: print(fmt % args) -def warn(fmt: str, *args) -> None: +def warn(fmt: str, *args: Any) -> None: sys.stderr.write(("WARNING: " + fmt) % args) sys.stderr.write("\n") @@ -108,42 +108,42 @@ def readContexts(tapNumbers: str) -> Dict[str, str]: class Matcher: - def __init__(self, pattern, flags=0): + def __init__(self, pattern: str, flags: Any=0) -> None: self._pattern = re.compile(pattern, flags) self._lastOne = None # type: Union[str, None] self._match = None # type: Union[Match, None] self._search = None # type: Union[Match, None] - def match(self, line): + def match(self, line: str) -> Match: self._match = re.match(self._pattern, line) self._lastOne = 'Match' return self._match - def search(self, line): + def search(self, line: str) -> Match: self._search = re.search(self._pattern, line) self._lastOne = 'Search' return self._search - def group(self, idx): + def group(self, idx: int) -> str: if self._lastOne == 'Match': return self._match.group(idx) elif self._lastOne == 'Search': return self._search.group(idx) else: - return panic( + panic( "Matcher group called with index " "%d before match/search!\n" % idx) - def groups(self): + def groups(self) -> Any: if self._lastOne == 'Match': return self._match.groups() elif self._lastOne == 'Search': return self._search.groups() else: - return panic("Matcher groups called with match/search!\n") + panic("Matcher groups called with match/search!\n") -def mysystem(cmd): +def mysystem(cmd: str) -> int: p = platform.system() if p == "Windows" or p.startswith("CYGWIN"): return os.system('"' + cmd + '"') -- GitLab