def _is_valid_optional(content_type: str) -> bool: """ Evaluate whether the format of an 'optional' content type in a protocol specification is valid. :param content_type: an 'optional' content type. :return: Boolean result """ content_type = content_type.strip() if not content_type.startswith("pt:optional"): return False if not _has_matched_brackets(content_type): return False if not _has_brackets(content_type): return False sub_types = _get_sub_types_of_compositional_types(content_type) if len(sub_types) != 1: return False sub_type = sub_types[0] return (_is_valid_ct(sub_type) or _is_valid_pt(sub_type) or _is_valid_set(sub_type) or _is_valid_list(sub_type) or _is_valid_dict(sub_type) or _is_valid_union(sub_type))
def _is_valid_union(content_type: str) -> bool: """ Evaluate whether the format of a 'union' content type in a protocol specification is valid. :param content_type: an 'union' content type. :return: Boolean result """ content_type = content_type.strip() if not content_type.startswith("pt:union"): return False if not _has_matched_brackets(content_type): return False if not _has_brackets(content_type): return False sub_types = _get_sub_types_of_compositional_types(content_type) # check there are at least two subtypes in the union if len(sub_types) < 2: return False # check there are no duplicate subtypes in the union sub_types_set = set(sub_types) if len(sub_types) != len(sub_types_set): return False for sub_type in sub_types: if not (_is_valid_ct(sub_type) or _is_valid_pt(sub_type) or _is_valid_set(sub_type) or _is_valid_list(sub_type) or _is_valid_dict(sub_type)): return False return True
def _is_valid_dict(content_type: str) -> bool: """ Evaluate whether the format of a 'dict' content type in a protocol specification is valid. :param content_type: a 'dict' content type. :return: Boolean result """ content_type = content_type.strip() if not content_type.startswith("pt:dict"): return False if not _has_matched_brackets(content_type): return False if not _has_brackets(content_type): return False sub_types = _get_sub_types_of_compositional_types(content_type) if len(sub_types) != 2: return False sub_type_1 = sub_types[0] sub_type_2 = sub_types[1] return _is_valid_pt(sub_type_1) and _is_valid_pt(sub_type_2)
def _optional_specification_type_to_python_type( specification_type: str) -> str: """ Convert a 'pt:optional' specification type into its python equivalent. :param specification_type: a protocol specification data type :return: The equivalent data type in Python """ element_type = _get_sub_types_of_compositional_types(specification_type)[0] element_type_in_python = _specification_type_to_python_type(element_type) python_type = "Optional[{}]".format(element_type_in_python) return python_type
def test_get_sub_types_of_compositional_types_negative(self, ): """Negative test the '_get_sub_types_of_compositional_types' method""" composition_type_1 = "pt:int" with self.assertRaises(SyntaxError) as cm: _get_sub_types_of_compositional_types(composition_type_1) self.assertEqual( str(cm.exception), "{} is not a valid compositional type.".format(composition_type_1), ) composition_type_2 = "pt:int[pt:DataModel]" with self.assertRaises(SyntaxError) as cm: _get_sub_types_of_compositional_types(composition_type_2) self.assertEqual( str(cm.exception), "{} is not a valid compositional type.".format(composition_type_2), ) composition_type_3 = "pt:dict[pt:set[int, pt:list[pt:bool]]" with self.assertRaises(SyntaxError) as cm: _get_sub_types_of_compositional_types(composition_type_3) self.assertEqual( str(cm.exception), "Bad formatting. No matching close bracket ']' for the open bracket at pt:set[", )
def _pct_specification_type_to_python_type(specification_type: str) -> str: """ Convert a primitive collection specification type into its python equivalent. :param specification_type: a protocol specification data type :return: The equivalent data type in Python """ element_type = _get_sub_types_of_compositional_types(specification_type)[0] element_type_in_python = _specification_type_to_python_type(element_type) if specification_type.startswith("pt:set"): python_type = "FrozenSet[{}]".format(element_type_in_python) else: python_type = "Tuple[{}, ...]".format(element_type_in_python) return python_type
def _is_valid_set(content_type: str) -> bool: content_type = content_type.strip() if not content_type.startswith("pt:set"): return False if not _has_brackets(content_type): return False sub_types = _get_sub_types_of_compositional_types(content_type) if len(sub_types) != 1: return False sub_type = sub_types[0] return _is_valid_pt(sub_type)
def _mt_specification_type_to_python_type(specification_type: str) -> str: """ Convert a 'pt:union' specification type into its python equivalent. :param specification_type: a protocol specification data type :return: The equivalent data type in Python """ sub_types = _get_sub_types_of_compositional_types(specification_type) python_type = "Union[" for sub_type in sub_types: python_type += "{}, ".format( _specification_type_to_python_type(sub_type)) python_type = python_type[:-2] python_type += "]" return python_type
def _pmt_specification_type_to_python_type(specification_type: str) -> str: """ Convert a primitive mapping specification type into its python equivalent. :param specification_type: a protocol specification data type :return: The equivalent data type in Python """ element_types = _get_sub_types_of_compositional_types(specification_type) element1_type_in_python = _specification_type_to_python_type( element_types[0]) element2_type_in_python = _specification_type_to_python_type( element_types[1]) python_type = "Dict[{}, {}]".format(element1_type_in_python, element2_type_in_python) return python_type
def _is_valid_dict(content_type: str) -> bool: content_type = content_type.strip() if not content_type.startswith("pt:dict"): return False if not _has_brackets(content_type): return False sub_types = _get_sub_types_of_compositional_types(content_type) if len(sub_types) != 2: return False sub_type_1 = sub_types[0] sub_type_2 = sub_types[1] return _is_valid_pt(sub_type_1) and _is_valid_pt(sub_type_2)
def _is_valid_optional(content_type: str) -> bool: content_type = content_type.strip() if not content_type.startswith("pt:optional"): return False if not _has_brackets(content_type): return False sub_types = _get_sub_types_of_compositional_types(content_type) if len(sub_types) != 1: return False sub_type = sub_types[0] return (_is_valid_ct(sub_type) or _is_valid_pt(sub_type) or _is_valid_set(sub_type) or _is_valid_list(sub_type) or _is_valid_dict(sub_type) or _is_valid_union(sub_type))
def _is_valid_union(content_type: str) -> bool: content_type = content_type.strip() if not content_type.startswith("pt:union"): return False if not _has_brackets(content_type): return False sub_types = _get_sub_types_of_compositional_types(content_type) for sub_type in sub_types: if not (_is_valid_ct(sub_type) or _is_valid_pt(sub_type) or _is_valid_set(sub_type) or _is_valid_list(sub_type) or _is_valid_dict(sub_type)): return False return True
def test_get_sub_types_of_compositional_types_positive(self, ): """Positive test the '_get_sub_types_of_compositional_types' method.""" composition_type_1 = "pt:set[pt:int, integer, bool]" expected_1 = ("pt:int", "integer", "bool") assert _get_sub_types_of_compositional_types( composition_type_1) == expected_1 composition_type_2 = "FrozenSet[something, anotherthing]" expected_2 = ("something", "anotherthing") assert _get_sub_types_of_compositional_types( composition_type_2) == expected_2 composition_type_3 = "pt:list[pt:str]" expected_3 = ("pt:str", ) assert _get_sub_types_of_compositional_types( composition_type_3) == expected_3 composition_type_4 = "Tuple[bytes, ...]" expected_4 = ("bytes", ) assert _get_sub_types_of_compositional_types( composition_type_4) == expected_4 composition_type_5 = "pt:dict[pt:int, pt:int]" expected_5 = ("pt:int", "pt:int") assert _get_sub_types_of_compositional_types( composition_type_5) == expected_5 composition_type_6 = "Dict[bool, float]" expected_6 = ("bool", "float") assert _get_sub_types_of_compositional_types( composition_type_6) == expected_6 composition_type_7 = "pt:union[ct:DataModel, pt:bytes, pt:int, pt:bool, pt:float, pt:str, pt:set[pt:int], pt:list[pt:bool], pt:dict[pt:str,pt:str]]" expected_7 = ( "ct:DataModel", "pt:bytes", "pt:int", "pt:bool", "pt:float", "pt:str", "pt:set[pt:int]", "pt:list[pt:bool]", "pt:dict[pt:str,pt:str]", ) assert _get_sub_types_of_compositional_types( composition_type_7) == expected_7 composition_type_8 = "Union[int, Tuple[bool, ...]]" expected_8 = ("int", "Tuple[bool, ...]") assert _get_sub_types_of_compositional_types( composition_type_8) == expected_8 composition_type_9 = ( "Union[DataModel, FrozenSet[int], Tuple[bool, ...], bytes, Dict[bool,float], int, " "FrozenSet[bool], Dict[int, str], Tuple[str, ...], bool, float, str, Dict[str, str]]" ) expected_9 = ( "DataModel", "FrozenSet[int]", "Tuple[bool, ...]", "bytes", "Dict[bool,float]", "int", "FrozenSet[bool]", "Dict[int, str]", "Tuple[str, ...]", "bool", "float", "str", "Dict[str, str]", ) assert _get_sub_types_of_compositional_types( composition_type_9) == expected_9 composition_type_10 = "pt:optional[pt:union[ct:DataModel, pt:bytes, pt:int, pt:bool, pt:float, pt:str, pt:set[pt:int], pt:list[pt:bool], pt:dict[pt:str,pt:str]]]" expected_10 = ( "pt:union[ct:DataModel, pt:bytes, pt:int, pt:bool, pt:float, pt:str, pt:set[pt:int], pt:list[pt:bool], pt:dict[pt:str,pt:str]]", ) assert _get_sub_types_of_compositional_types( composition_type_10) == expected_10 composition_type_11 = "Optional[Union[DataModel, bytes, int, bool, float, str, FrozenSet[int], Tuple[bool, ...], Dict[str,str]]]" expected_11 = ( "Union[DataModel, bytes, int, bool, float, str, FrozenSet[int], Tuple[bool, ...], Dict[str,str]]", ) assert _get_sub_types_of_compositional_types( composition_type_11) == expected_11