Best Python code snippet using fMBT_python
types.py
Source:types.py  
1from concat.orderedset import OrderedSet2from concat.typecheck import (3    AttributeError,4    StackMismatchError,5    TypeError,6)7import concat.typecheck8from typing import (9    Optional,10    Dict,11    Iterable,12    Iterator,13    Sequence,14    Tuple,15    Union,16    List,17    Iterator,18    Set,19    Mapping,20    NoReturn,21    cast,22    overload,23    TYPE_CHECKING,24)25from typing_extensions import Literal26import abc27import collections.abc28import builtins29if TYPE_CHECKING:30    from concat.typecheck import Substitutions31class Type(abc.ABC):32    # TODO: Fully replace with <=.33    def is_subtype_of(self, supertype: 'Type') -> bool:34        return (35            supertype is self36            or isinstance(self, IndividualType)37            and supertype is object_type38        )39    def __le__(self, other: object) -> bool:40        if not isinstance(other, Type):41            return NotImplemented42        return self.is_subtype_of(other)43    def __eq__(self, other: object) -> bool:44        if self is other:45            return True46        if not isinstance(other, Type):47            return NotImplemented48        return self <= other and other <= self49    def get_type_of_attribute(self, name: str) -> 'IndividualType':50        raise AttributeError(self, name)51    def has_attribute(self, name: str) -> bool:52        try:53            self.get_type_of_attribute(name)54            return True55        except AttributeError:56            return False57    @abc.abstractproperty58    def attributes(self) -> Mapping[str, 'Type']:59        pass60    @abc.abstractmethod61    def free_type_variables(self) -> OrderedSet['_Variable']:62        pass63    @abc.abstractmethod64    def apply_substitution(65        self, _: 'concat.typecheck.Substitutions'66    ) -> Union['Type', Sequence['StackItemType']]:67        pass68    @abc.abstractmethod69    def constrain_and_bind_supertype_variables(70        self, supertype: 'Type', rigid_variables: Set['_Variable']71    ) -> 'Substitutions':72        pass73    @abc.abstractmethod74    def constrain_and_bind_subtype_variables(75        self, supertype: 'Type', rigid_variables: Set['_Variable']76    ) -> 'Substitutions':77        pass78    def constrain(self, supertype: 'Type') -> None:79        if not self.is_subtype_of(supertype):80            raise TypeError(81                '{} is not a subtype of {}'.format(self, supertype)82            )83    def instantiate(self) -> 'Type':84        return self85class IndividualType(Type, abc.ABC):86    def to_for_all(self) -> Type:87        return ForAll([], self)88    def __and__(self, other: object) -> 'IndividualType':89        raise NotImplementedError('take advantage of constraints instead')90    def is_subtype_of(self, supertype: Type) -> bool:91        if isinstance(supertype, _OptionalType):92            if (93                self == none_type94                or not supertype.type_arguments95                or isinstance(supertype.type_arguments[0], IndividualType)96                and self.is_subtype_of(supertype.type_arguments[0])97            ):98                return True99            return False100        return super().is_subtype_of(supertype)101class _Variable(Type, abc.ABC):102    """Objects that represent type variables.103    Every type variable object is assumed to be unique. Thus, fresh type104    variables can be made simply by creating new objects. They can also be105    compared by identity."""106    def apply_substitution(107        self, sub: 'concat.typecheck.Substitutions'108    ) -> Union[IndividualType, '_Variable', 'TypeSequence']:109        if self in sub:110            return sub[self]  # type: ignore111        return self112    def free_type_variables(self) -> OrderedSet['_Variable']:113        return OrderedSet({self})114class IndividualVariable(_Variable, IndividualType):115    def __init__(self) -> None:116        super().__init__()117    def constrain_and_bind_supertype_variables(118        self, supertype: Type, rigid_variables: Set['_Variable']119    ) -> 'Substitutions':120        from concat.typecheck import Substitutions121        if self is supertype or supertype == object_type:122            return Substitutions()123        if not isinstance(supertype, IndividualType):124            raise TypeError(125                '{} must be an individual type: expected {}'.format(126                    supertype, self127                )128            )129        if self in rigid_variables:130            raise TypeError(131                '{} is considered fixed here and cannot become a subtype of {}'.format(132                    self, supertype133                )134            )135        if (136            isinstance(supertype, IndividualVariable)137            and supertype not in rigid_variables138        ):139            return Substitutions({supertype: self})140        # Let's not support bounded quantification or inferring the types of141        # named functions. Thus, the subtype constraint should fail here.142        raise TypeError(143            '{} is an individual type variable and cannot be a subtype of {}'.format(144                self, supertype145            )146        )147    def constrain_and_bind_subtype_variables(148        self, supertype: Type, rigid_variables: Set['_Variable']149    ) -> 'Substitutions':150        from concat.typecheck import Substitutions151        if self is supertype:152            return Substitutions()153        if supertype == object_type:154            return Substitutions({self: object_type})155        if not isinstance(supertype, IndividualType):156            raise TypeError(157                '{} must be an individual type: expected {}'.format(158                    supertype, self159                )160            )161        if self in rigid_variables:162            raise TypeError(163                '{} is considered fixed here and cannot become a subtype of {}'.format(164                    self, supertype165                )166            )167        return Substitutions({self: supertype})168    # __hash__ by object identity is used since that's the only way for two169    # type variables to be ==.170    def __hash__(self) -> int:171        return hash(id(self))172    def __str__(self) -> str:173        return '`t_{}'.format(id(self))174    def __repr__(self) -> str:175        return '<individual variable {}>'.format(id(self))176    def apply_substitution(177        self, sub: 'concat.typecheck.Substitutions'178    ) -> IndividualType:179        return cast(IndividualType, super().apply_substitution(sub))180    @property181    def attributes(self) -> NoReturn:182        raise TypeError(183            '{} is an individual type variable, so its attributes are unknown'.format(184                self185            )186        )187class SequenceVariable(_Variable):188    def __init__(self) -> None:189        super().__init__()190    def __str__(self) -> str:191        return '*t_{}'.format(id(self))192    def __hash__(self) -> int:193        return hash(id(self))194    def constrain_and_bind_supertype_variables(195        self, supertype: Type, rigid_variables: Set['_Variable']196    ) -> 'Substitutions':197        from concat.typecheck import Substitutions198        if not isinstance(supertype, (SequenceVariable, TypeSequence)):199            raise TypeError(200                '{} must be a sequence type, not {}'.format(self, supertype)201            )202        if self in rigid_variables:203            raise Exception('todo')204        # occurs check205        if self is not supertype and self in supertype.free_type_variables():206            raise TypeError(207                '{} cannot be a subtype of {} because it appears in {}'.format(208                    self, supertype, supertype209                )210            )211        if isinstance(supertype, SequenceVariable):212            return Substitutions({supertype: self})213        return Substitutions()214    def constrain_and_bind_subtype_variables(215        self, supertype: Type, rigid_variables: Set['_Variable']216    ) -> 'Substitutions':217        from concat.typecheck import Substitutions218        if not isinstance(supertype, (SequenceVariable, TypeSequence)):219            raise TypeError(220                '{} must be a sequence type, not {}'.format(self, supertype)221            )222        if self in rigid_variables:223            raise TypeError(224                '{} is fixed here and cannot become a subtype of another type'.format(225                    self226                )227            )228        # occurs check229        if self is not supertype and self in supertype.free_type_variables():230            raise TypeError(231                '{} cannot be a subtype of {} because it appears in {}'.format(232                    self, supertype, supertype233                )234            )235        return Substitutions({self: supertype})236    def get_type_of_attribute(self, name: str) -> NoReturn:237        raise TypeError(238            'the sequence type {} does not hold attributes'.format(self)239        )240    @property241    def attributes(self) -> NoReturn:242        raise TypeError(243            'the sequence type {} does not hold attributes'.format(self)244        )245class TypeSequence(Type, Iterable['StackItemType']):246    def __init__(self, sequence: Sequence['StackItemType']) -> None:247        self._rest: Optional[SequenceVariable]248        if sequence and isinstance(sequence[0], SequenceVariable):249            self._rest = sequence[0]250            self._individual_types = sequence[1:]251        else:252            self._rest = None253            self._individual_types = sequence254    def as_sequence(self) -> Sequence['StackItemType']:255        if self._rest is not None:256            return [self._rest, *self._individual_types]257        return self._individual_types258    def apply_substitution(self, sub) -> 'TypeSequence':259        subbed_types: List[StackItemType] = []260        for type in self:261            subbed_type: Union[StackItemType, Sequence[StackItemType]] = sub(262                type263            )264            if isinstance(subbed_type, TypeSequence):265                subbed_types += [*subbed_type]266            else:267                subbed_types.append(subbed_type)268        return TypeSequence(subbed_types)269    def is_subtype_of(self, supertype: Type) -> bool:270        if (271            isinstance(supertype, SequenceVariable)272            and not self._individual_types273            and self._rest is supertype274        ):275            return True276        elif isinstance(supertype, TypeSequence):277            if self._is_empty() and supertype._is_empty():278                return True279            elif not self._individual_types:280                if (281                    self._rest282                    and supertype._rest283                    and not supertype._individual_types284                ):285                    return self._rest is supertype._rest286                else:287                    return False288            elif self._individual_types and supertype._individual_types:289                if (290                    not self._individual_types[-1]291                    <= supertype._individual_types[-1]292                ):293                    return False294                return self[:-1] <= supertype[:-1]295            else:296                return False297        else:298            raise TypeError(299                '{} must be a sequence type, not {}'.format(self, supertype)300            )301    def constrain_and_bind_supertype_variables(302        self, supertype: Type, rigid_variables: Set['_Variable']303    ) -> 'Substitutions':304        """Check that self is a subtype of supertype.305        Free type variables that appear in the supertype type sequence are set306        to be equal to their counterparts in the subtype sequence so that type307        information can be propagated into calls of named functions.308        """309        from concat.typecheck import Substitutions310        if (311            isinstance(supertype, SequenceVariable)312            and supertype not in rigid_variables313        ):314            return Substitutions({supertype: self})315        elif isinstance(supertype, TypeSequence):316            if self._is_empty() and supertype._is_empty():317                return Substitutions()318            elif (319                self._is_empty()320                and supertype._rest321                and not supertype._individual_types322                and supertype._rest not in rigid_variables323            ):324                return Substitutions({supertype._rest: self})325            elif (326                supertype._is_empty()327                and self._rest328                and not self._individual_types329            ):330                raise StackMismatchError(self, supertype)331            elif not self._individual_types:332                if (333                    self._rest334                    and supertype._rest335                    and not supertype._individual_types336                    and supertype._rest not in rigid_variables337                ):338                    return Substitutions({supertype._rest: self._rest})339                elif self._is_empty() and supertype._is_empty():340                    return Substitutions()341                elif (342                    self._is_empty()343                    and supertype._rest344                    and not supertype._individual_types345                    and supertype._rest not in rigid_variables346                ):347                    return Substitutions({supertype._rest: self})348                else:349                    raise StackMismatchError(self, supertype)350            elif (351                not supertype._individual_types352                and supertype._rest353                and supertype._rest not in self.free_type_variables()354                and supertype._rest not in rigid_variables355            ):356                return Substitutions({supertype._rest: self})357            elif self._individual_types and supertype._individual_types:358                sub = self._individual_types[359                    -1360                ].constrain_and_bind_supertype_variables(361                    supertype._individual_types[-1], rigid_variables362                )363                # constrain individual variables in the second sequence type to364                # be *equal* to the corresponding type in the first sequence365                # type.366                is_variable = isinstance(367                    supertype._individual_types[-1], IndividualVariable368                )369                if (370                    is_variable371                    and supertype._individual_types[-1] not in rigid_variables372                ):373                    sub = Substitutions(374                        {375                            supertype._individual_types[376                                -1377                            ]: self._individual_types[-1]378                        }379                    )(sub)380                try:381                    sub = sub(382                        self[:-1]383                    ).constrain_and_bind_supertype_variables(384                        sub(supertype[:-1]), rigid_variables385                    )(386                        sub387                    )388                    return sub389                except StackMismatchError:390                    raise StackMismatchError(self, supertype)391            else:392                raise StackMismatchError(self, supertype)393        else:394            raise TypeError(395                '{} must be a sequence type, not {}'.format(self, supertype)396            )397    def constrain_and_bind_subtype_variables(398        self, supertype: Type, rigid_variables: Set['_Variable']399    ) -> 'Substitutions':400        from concat.typecheck import Substitutions401        if isinstance(supertype, SequenceVariable) and (402            not self._rest or self._individual_types403        ):404            raise StackMismatchError(self, TypeSequence([supertype]))405        elif isinstance(supertype, TypeSequence):406            if self._is_empty() and supertype._is_empty():407                return Substitutions()408            elif (409                self._is_empty()410                and supertype._rest411                and not supertype._individual_types412                and supertype._rest not in rigid_variables413            ):414                raise StackMismatchError(self, supertype)415            elif (416                supertype._is_empty()417                and self._rest418                and not self._individual_types419                and self._rest not in rigid_variables420            ):421                return Substitutions({self._rest: supertype})422            elif not self._individual_types:423                if (424                    self._rest425                    and self._rest not in rigid_variables426                    and self._rest not in supertype.free_type_variables()427                ):428                    return Substitutions({self._rest: supertype})429                elif self._is_empty() and supertype._is_empty():430                    return Substitutions()431                elif (432                    self._is_empty()433                    and supertype._rest434                    and not supertype._individual_types435                ):436                    # QUESTION: Should this be allowed? I'm being defensive here.437                    raise StackMismatchError(self, supertype)438                else:439                    raise StackMismatchError(self, supertype)440            elif (441                not supertype._individual_types442                and supertype._rest443                and supertype._rest not in self.free_type_variables()444                and supertype._rest not in rigid_variables445            ):446                raise StackMismatchError(self, supertype)447            elif self._individual_types and supertype._individual_types:448                sub = self._individual_types[449                    -1450                ].constrain_and_bind_subtype_variables(451                    supertype._individual_types[-1], rigid_variables452                )453                is_variable = isinstance(454                    self._individual_types[-1], IndividualVariable455                )456                if (457                    is_variable458                    and self._individual_types[-1] not in rigid_variables459                ):460                    sub = Substitutions(461                        {462                            self._individual_types[463                                -1464                            ]: supertype._individual_types[-1]465                        }466                    )(sub)467                try:468                    sub = sub(self[:-1]).constrain_and_bind_subtype_variables(469                        sub(supertype[:-1]), rigid_variables470                    )(sub)471                    return sub472                except StackMismatchError:473                    raise StackMismatchError(self, supertype)474            else:475                raise StackMismatchError(self, supertype)476        else:477            raise TypeError(478                '{} must be a sequence type, not {}'.format(self, supertype)479            )480    def free_type_variables(self) -> OrderedSet['_Variable']:481        ftv: OrderedSet[_Variable] = OrderedSet([])482        for t in self:483            ftv |= t.free_type_variables()484        return ftv485    @property486    def attributes(self) -> NoReturn:487        raise TypeError(488            'the sequence type {} does not hold attributes'.format(self)489        )490    def __bool__(self) -> bool:491        return not self._is_empty()492    def _is_empty(self) -> bool:493        return self._rest is None and not self._individual_types494    @overload495    def __getitem__(self, key: int) -> 'StackItemType':496        ...497    @overload498    def __getitem__(self, key: slice) -> 'TypeSequence':499        ...500    def __getitem__(501        self, key: Union[int, slice]502    ) -> Union['StackItemType', 'TypeSequence']:503        if isinstance(key, int):504            return self.as_sequence()[key]505        return TypeSequence(self.as_sequence()[key])506    def __str__(self) -> str:507        return '[' + ', '.join(str(t) for t in self) + ']'508    def __repr__(self) -> str:509        return 'TypeSequence([' + ', '.join(repr(t) for t in self) + '])'510    def __iter__(self) -> Iterator['StackItemType']:511        return iter(self.as_sequence())512    def __hash__(self) -> int:513        return hash(tuple(self.as_sequence()))514# TODO: Actually get rid of ForAll uses. This is a temporary measure since I515# don't want to do that work right now.516def ForAll(type_parameters: Sequence['_Variable'], type: Type) -> Type:517    return ObjectType(IndividualVariable(), type.attributes, type_parameters,)518# TODO: Rename to StackEffect at all use sites.519class _Function(IndividualType):520    def __init__(521        self,522        input: Iterable['StackItemType'],523        output: Iterable['StackItemType'],524    ) -> None:525        super().__init__()526        self.input = TypeSequence(tuple(input))527        self.output = TypeSequence(tuple(output))528    def __iter__(self) -> Iterator['TypeSequence']:529        return iter((self.input, self.output))530    def generalized_wrt(self, gamma: Dict[str, Type]) -> Type:531        return ObjectType(532            IndividualVariable(),533            {'__call__': self,},534            list(535                self.free_type_variables()536                - _free_type_variables_of_mapping(gamma)537            ),538        )539    def can_be_complete_program(self) -> bool:540        """Returns true iff the function type is a subtype of ( -- *out)."""541        out_var = SequenceVariable()542        return self.is_subtype_of(_Function([], [out_var]))543    def __hash__(self) -> int:544        # FIXME: Alpha equivalence545        return hash((self.input, self.output))546    def is_subtype_of(547        self,548        supertype: Type,549        _sub: Optional['concat.typecheck.Substitutions'] = None,550    ) -> bool:551        if super().is_subtype_of(supertype):552            return True553        if isinstance(supertype, _Function):554            if len(tuple(self.input)) != len(tuple(supertype.input)) or len(555                tuple(self.output)556            ) != len(tuple(supertype.output)):557                return False558            # Sequence variables are handled through renaming.559            if _sub is None:560                _sub = concat.typecheck.Substitutions()561            input_rename_result = self._rename_sequence_variable(562                tuple(self.input), tuple(supertype.input), _sub563            )564            output_rename_result = self._rename_sequence_variable(565                tuple(supertype.output), tuple(self.output), _sub566            )567            if not (input_rename_result and output_rename_result):568                return False569            # TODO: What about individual type variables. We should be careful570            # with renaming those, too.571            # input types are contravariant572            for type_from_self, type_from_supertype in zip(573                self.input, supertype.input574            ):575                type_from_self, type_from_supertype = (576                    cast(StackItemType, _sub(type_from_self)),577                    cast(StackItemType, _sub(type_from_supertype)),578                )579                if isinstance(type_from_supertype, _Function):580                    if not type_from_supertype.is_subtype_of(581                        type_from_self, _sub582                    ):583                        return False584                elif not type_from_supertype.is_subtype_of(type_from_self):585                    return False586            # output types are covariant587            for type_from_self, type_from_supertype in zip(588                self.output, supertype.output589            ):590                type_from_self, type_from_supertype = (591                    cast(StackItemType, _sub(type_from_self)),592                    cast(StackItemType, _sub(type_from_supertype)),593                )594                if isinstance(type_from_self, _Function):595                    if not type_from_self.is_subtype_of(596                        type_from_supertype, _sub597                    ):598                        return False599                elif not type_from_self.is_subtype_of(type_from_supertype):600                    return False601            return True602        return False603    def constrain_and_bind_supertype_variables(604        self, supertype: Type, rigid_variables: Set['_Variable']605    ) -> 'Substitutions':606        if not isinstance(supertype, StackEffect):607            raise TypeError(608                '{} is not a subtype of {}'.format(self, supertype)609            )610        # Remember that the input should be contravariant!611        # QUESTION: Constrain the supertype variables here during contravariance check?612        sub = supertype.input.constrain_and_bind_subtype_variables(613            self.input, rigid_variables614        )615        sub = sub(self.output).constrain_and_bind_supertype_variables(616            sub(supertype.output), rigid_variables617        )(sub)618        return sub619    def constrain_and_bind_subtype_variables(620        self, supertype: Type, rigid_variables: Set['_Variable']621    ) -> 'Substitutions':622        if not isinstance(supertype, StackEffect):623            raise TypeError(624                '{} is not a subtype of {}'.format(self, supertype)625            )626        # Remember that the input should be contravariant!627        # QUESTION: Constrain the supertype variables here during contravariance check?628        sub = supertype.input.constrain_and_bind_supertype_variables(629            self.input, rigid_variables630        )631        sub = sub(self.output).constrain_and_bind_subtype_variables(632            sub(supertype.output), rigid_variables633        )(sub)634        return sub635    def free_type_variables(self) -> OrderedSet['_Variable']:636        return (637            self.input.free_type_variables()638            | self.output.free_type_variables()639        )640    @staticmethod641    def _rename_sequence_variable(642        supertype_list: Sequence['StackItemType'],643        subtype_list: Sequence['StackItemType'],644        sub: 'concat.typecheck.Substitutions',645    ) -> bool:646        both_lists_nonempty = supertype_list and subtype_list647        if (648            both_lists_nonempty649            and isinstance(supertype_list[0], SequenceVariable)650            and isinstance(subtype_list[0], SequenceVariable)651        ):652            if supertype_list[0] not in sub:653                sub[supertype_list[0]] = subtype_list[0]654            else:655                if sub(supertype_list[0]) is not subtype_list[0]:656                    return False657        return True658    def __repr__(self) -> str:659        return '{}({!r}, {!r})'.format(660            type(self).__qualname__, self.input, self.output661        )662    def __str__(self) -> str:663        in_types = ' '.join(map(str, self.input))664        out_types = ' '.join(map(str, self.output))665        return '({} -- {})'.format(in_types, out_types)666    def __and__(self, other: object) -> IndividualType:667        if isinstance(other, _Function):668            input = _intersect_sequences(tuple(self.input), tuple(other.input))669            output = _intersect_sequences(670                tuple(self.output), tuple(other.output)671            )672            return _Function(input, output)673        return super().__and__(other)674    def get_type_of_attribute(self, name: str) -> '_Function':675        if name == '__call__':676            return self677        raise AttributeError(self, name)678    @property679    def attributes(self) -> Mapping[str, 'StackEffect']:680        return {'__call__': self}681    def apply_substitution(682        self, sub: 'concat.typecheck.Substitutions'683    ) -> '_Function':684        return _Function(sub(self.input), sub(self.output))685    def bind(self) -> '_Function':686        return _Function(self.input[:-1], self.output)687class QuotationType(_Function):688    def __init__(self, fun_type: _Function) -> None:689        super().__init__(fun_type.input, fun_type.output)690    def is_subtype_of(691        self,692        supertype: Type,693        _sub: Optional['concat.typecheck.Substitutions'] = None,694    ) -> bool:695        if super().is_subtype_of(supertype, _sub):696            return True697        if supertype == iterable_type:698            return True699        return False700    def constrain_and_bind_supertype_variables(701        self, supertype: Type, rigid_variables: Set['_Variable']702    ) -> 'Substitutions':703        if (704            isinstance(supertype, ObjectType)705            and supertype.head == iterable_type706        ):707            # FIXME: Don't present new variables every time.708            # FIXME: Account for the types of the elements of the quotation.709            in_var = IndividualVariable()710            out_var = IndividualVariable()711            quotation_iterable_type = iterable_type[712                _Function([in_var], [out_var]),713            ]714            return quotation_iterable_type.constrain_and_bind_supertype_variables(715                supertype, rigid_variables716            )717        return super().constrain_and_bind_supertype_variables(718            supertype, rigid_variables719        )720    def constrain_and_bind_subtype_variables(721        self, supertype: Type, rigid_variables: Set['_Variable']722    ) -> 'Substitutions':723        if (724            isinstance(supertype, ObjectType)725            and supertype.head == iterable_type726        ):727            # FIXME: Don't present new variables every time.728            # FIXME: Account for the types of the elements of the quotation.729            in_var = IndividualVariable()730            out_var = IndividualVariable()731            quotation_iterable_type = iterable_type[732                _Function([in_var], [out_var]),733            ]734            return quotation_iterable_type.constrain_and_bind_subtype_variables(735                supertype, rigid_variables736            )737        return super().constrain_and_bind_subtype_variables(738            supertype, rigid_variables739        )740    def apply_substitution(741        self, sub: 'concat.typecheck.Substitutions'742    ) -> 'QuotationType':743        return QuotationType(super().apply_substitution(sub))744def _intersect_sequences(745    seq1: Sequence['StackItemType'], seq2: Sequence['StackItemType']746) -> Sequence['StackItemType']:747    raise NotImplementedError('stop using _IntersectionType')748# FIXME: This should be a method on types749def inst(sigma: _Function) -> IndividualType:750    """This is based on the inst function described by Kleffner."""751    if isinstance(sigma, _Function):752        input = [753            inst(type) if isinstance(type, _Function) else type754            for type in sigma.input755        ]756        output = [757            inst(type) if isinstance(type, _Function) else type758            for type in sigma.output759        ]760        return _Function(input, output)761    raise builtins.TypeError(type(sigma))762StackItemType = Union[SequenceVariable, IndividualType]763def _free_type_variables_of_mapping(764    attributes: Mapping[str, Type]765) -> OrderedSet[_Variable]:766    ftv: OrderedSet[_Variable] = OrderedSet([])767    for sigma in attributes.values():768        ftv |= sigma.free_type_variables()769    return ftv770def init_primitives():771    pass772TypeArguments = Sequence[Union[StackItemType, TypeSequence]]773class ObjectType(IndividualType):774    """The representation of types of objects, based on a gradual typing paper.775    That paper is "Design and Evaluation of Gradual Typing for Python"776    (Vitousek et al. 2014)."""777    def __init__(778        self,779        self_type: IndividualVariable,780        # Attributes can be universally quantified since ObjectType allows it.781        attributes: Dict[str, IndividualType],782        type_parameters: Sequence[_Variable] = (),783        nominal_supertypes: Sequence[IndividualType] = (),784        nominal: bool = False,785        _type_arguments: TypeArguments = (),786        _head: Optional['ObjectType'] = None,787        **_other_kwargs,788    ) -> None:789        # There should be no need to make the self_type variable unique because790        # it is treated as a bound variable in apply_substitution. In other791        # words, it is removed from any substitution received.792        self._self_type = self_type793        self._attributes = attributes794        self._type_parameters = type_parameters795        self._nominal_supertypes = nominal_supertypes796        self._nominal = nominal797        self._type_arguments: TypeArguments = _type_arguments798        self._head = _head or self799        self._internal_name: Optional[str] = None800        self._internal_name = self._head._internal_name801        self._other_kwargs = _other_kwargs.copy()802        if '_type_arguments' in self._other_kwargs:803            del self._other_kwargs['_type_arguments']804        if 'nominal' in self._other_kwargs:805            del self._other_kwargs['nominal']806        self._instantiations: Dict[TypeArguments, ObjectType] = {}807    def apply_substitution(808        self,809        sub: 'concat.typecheck.Substitutions',810        _should_quantify_over_type_parameters=True,811    ) -> 'ObjectType':812        from concat.typecheck import Substitutions813        if _should_quantify_over_type_parameters:814            sub = Substitutions(815                {816                    a: i817                    for a, i in sub.items()818                    # Don't include self_type in substitution, it is bound.819                    if a not in self._type_parameters820                    and a is not self._self_type821                }822            )823            # if no free type vars will be substituted, just return self824            if not any(825                free_var in sub for free_var in self.free_type_variables()826            ):827                return self828        else:829            sub = Substitutions(830                {a: i for a, i in sub.items() if a is not self._self_type}831            )832            # if no free type vars will be substituted, just return self833            if not any(834                free_var in sub835                for free_var in {836                    *self.free_type_variables(),837                    *self._type_parameters,838                }839            ):840                return self841        attributes = cast(842            Dict[str, IndividualType],843            {attr: sub(t) for attr, t in self._attributes.items()},844        )845        nominal_supertypes = [846            sub(supertype) for supertype in self._nominal_supertypes847        ]848        type_arguments = [849            cast(Union[StackItemType, TypeSequence], sub(type_argument))850            for type_argument in self._type_arguments851        ]852        subbed_type = type(self)(853            self._self_type,854            attributes,855            type_parameters=self._type_parameters,856            nominal_supertypes=nominal_supertypes,857            nominal=self._nominal,858            _type_arguments=type_arguments,859            # head is only used to keep track of where a type came from, so860            # there's no need to substitute it861            _head=self._head,862            **self._other_kwargs,863        )864        if self._internal_name is not None:865            subbed_type.set_internal_name(self._internal_name)866        return subbed_type867    def is_subtype_of(self, supertype: 'Type') -> bool:868        from concat.typecheck import Substitutions869        if supertype in self._nominal_supertypes or self is supertype:870            return True871        if isinstance(supertype, (_Function, PythonFunctionType)):872            if '__call__' not in self._attributes:873                return False874            return self._attributes['__call__'] <= supertype875        if not isinstance(supertype, ObjectType):876            return super().is_subtype_of(supertype)877        if self._arity != supertype._arity:878            return False879        if self._arity == 0 and supertype is object_type:880            return True881        if supertype._nominal and self._head is not supertype._head:882            return False883        # instantiate these types in a way such that alpha equivalence is not884        # an issue885        # NOTE: I assume the parameters are in the same order, which is886        # fragile.887        parameter_pairs = zip(self.type_parameters, supertype.type_parameters)888        if not all(type(a) == type(b) for a, b in parameter_pairs):889            return False890        self = self.instantiate()891        supertype = supertype.instantiate()892        parameter_sub = Substitutions(893            {894                **dict(zip(self.type_arguments, supertype.type_arguments)),895                self.self_type: supertype.self_type,896            }897        )898        self = parameter_sub(self)899        for attr, attr_type in supertype._attributes.items():900            if attr not in self._attributes:901                return False902            sub = concat.typecheck.Substitutions(903                {self._self_type: supertype._self_type}904            )905            if not (906                cast(IndividualType, sub(self._attributes[attr])) <= attr_type907            ):908                return False909        return True910    def constrain_and_bind_supertype_variables(911        self, supertype: Type, rigid_variables: Set['_Variable']912    ) -> 'Substitutions':913        from concat.typecheck import Substitutions914        if (915            isinstance(supertype, IndividualVariable)916            and supertype not in rigid_variables917        ):918            return Substitutions({supertype: self})919        elif isinstance(supertype, (SequenceVariable, TypeSequence)):920            raise TypeError(921                '{} is an individual type, but {} is a sequence type'.format(922                    self, supertype923                )924            )925        elif isinstance(supertype, StackEffect):926            if self._arity != 0:927                raise TypeError(928                    'type constructor {} expected at least one argument and cannot be a stack effect (expected effect {})'.format(929                        self, supertype930                    )931                )932            # We know self is not a type constructor here, so there's no need933            # to worry about variable binding934            return self.get_type_of_attribute(935                '__call__'936            ).constrain_and_bind_supertype_variables(937                supertype, rigid_variables938            )939        elif not isinstance(supertype, ObjectType):940            raise NotImplementedError(supertype)941        if self._arity != supertype._arity:942            raise TypeError(943                '{} and {} do not have the same arity'.format(self, supertype)944            )945        # every object type with zero arity is a subtype of object_type946        if self._arity == 0 and supertype == object_type:947            return Substitutions()948        # Don't forget that there's nominal subtyping too.949        if supertype._nominal:950            if (951                supertype not in self._nominal_supertypes952                and supertype != self953                and self._head != supertype._head954            ):955                raise TypeError(956                    '{} is not a subtype of {}'.format(self, supertype)957                )958        # constraining to an optional type959        if (960            supertype._head == optional_type961            and supertype._arity == 0962            and self._arity == 0963        ):964            try:965                return self.constrain_and_bind_supertype_variables(966                    none_type, rigid_variables967                )968            except TypeError:969                return self.constrain_and_bind_supertype_variables(970                    supertype._type_arguments[0], rigid_variables971                )972        # don't constrain the type arguments, constrain those based on973        # the attributes974        sub = Substitutions()975        for name in supertype._attributes:976            type = self.get_type_of_attribute(name)977            # We must not bind any type parameters in self or supertype!978            rigid_variables = (979                rigid_variables980                | set(self.type_parameters)981                | set(supertype.type_parameters)982            )983            sub = type.constrain_and_bind_supertype_variables(984                supertype.get_type_of_attribute(name), rigid_variables985            )(sub)986        return sub987    def constrain_and_bind_subtype_variables(988        self, supertype: Type, rigid_variables: Set['_Variable']989    ) -> 'Substitutions':990        from concat.typecheck import Substitutions991        if isinstance(supertype, IndividualVariable):992            raise TypeError(993                '{} is unknown here and cannot be a supertype of {}'.format(994                    supertype, self995                )996            )997        elif isinstance(supertype, (SequenceVariable, TypeSequence)):998            raise TypeError(999                '{} is an individual type, but {} is a sequence type'.format(1000                    self, supertype1001                )1002            )1003        elif isinstance(supertype, StackEffect):1004            if self._arity != 0:1005                raise TypeError(1006                    'type constructor {} expected at least one argument and cannot be a stack effect (expected effect {})'.format(1007                        self, supertype1008                    )1009                )1010            # We know self is not a type constructor here, so there's no need1011            # to worry about variable binding1012            return self.get_type_of_attribute(1013                '__call__'1014            ).constrain_and_bind_subtype_variables(supertype, rigid_variables)1015        elif not isinstance(supertype, ObjectType):1016            raise NotImplementedError(supertype)1017        if self._arity != supertype._arity:1018            raise TypeError(1019                '{} and {} do not have the same arity'.format(self, supertype)1020            )1021        # every object type with zero arity is a subtype of object_type1022        if self._arity == 0 and supertype == object_type:1023            return Substitutions()1024        # Don't forget that there's nominal subtyping too.1025        if supertype._nominal:1026            if (1027                supertype not in self._nominal_supertypes1028                and supertype != self1029                and self._head != supertype._head1030            ):1031                raise TypeError(1032                    '{} is not a subtype of {}'.format(self, supertype)1033                )1034        # constraining to an optional type1035        if (1036            supertype._head == optional_type1037            and supertype._arity == 01038            and self._arity == 01039        ):1040            try:1041                return self.constrain_and_bind_subtype_variables(1042                    none_type, rigid_variables1043                )1044            except TypeError:1045                return self.constrain_and_bind_subtype_variables(1046                    supertype._type_arguments[0], rigid_variables1047                )1048        # don't constrain the type arguments, constrain those based on1049        # the attributes1050        sub = Substitutions()1051        for name in supertype._attributes:1052            type = self.get_type_of_attribute(name)1053            # We must not bind any type parameters in self or supertype!1054            rigid_variables = (1055                rigid_variables1056                | set(self.type_parameters)1057                | set(supertype.type_parameters)1058            )1059            sub = type.constrain_and_bind_subtype_variables(1060                supertype.get_type_of_attribute(name), rigid_variables1061            )(sub)1062        return sub1063    def get_type_of_attribute(self, attribute: str) -> IndividualType:1064        if attribute not in self._attributes:1065            raise AttributeError(self, attribute)1066        self_sub = concat.typecheck.Substitutions({self._self_type: self})1067        return self_sub(self._attributes[attribute])1068    def __repr__(self) -> str:1069        return '{}({!r}, {!r}, {!r}, {!r}, {!r}, {!r}, {!r})'.format(1070            type(self).__qualname__,1071            self._self_type,1072            self._attributes,1073            self._type_parameters,1074            self._nominal_supertypes,1075            self._nominal,1076            self._type_arguments,1077            None if self._head is self else self._head,1078        )1079    def free_type_variables(self) -> OrderedSet[_Variable]:1080        ftv = _free_type_variables_of_mapping(self.attributes)1081        for arg in self.type_arguments:1082            ftv |= arg.free_type_variables()1083        # QUESTION: Include supertypes?1084        ftv -= {self.self_type, *self.type_parameters}1085        return ftv1086    def __str__(self) -> str:1087        if self._internal_name is not None:1088            if len(self._type_arguments) > 0:1089                return (1090                    self._internal_name1091                    + '['1092                    + ', '.join(map(str, self._type_arguments))1093                    + ']'1094                )1095            return self._internal_name1096        assert self._internal_name is None1097        return '{}({}, {}, {}, {}, {}, {}, {})'.format(1098            type(self).__qualname__,1099            self._self_type,1100            _mapping_to_str(self._attributes),1101            _iterable_to_str(self._type_parameters),1102            _iterable_to_str(self._nominal_supertypes),1103            self._nominal,1104            _iterable_to_str(self._type_arguments),1105            None if self._head is self else self._head,1106        )1107    def set_internal_name(self, name: str) -> None:1108        self._internal_name = name1109    _hash_variable = None1110    def __hash__(self) -> int:1111        from concat.typecheck import Substitutions1112        if ObjectType._hash_variable is None:1113            ObjectType._hash_variable = IndividualVariable()1114        sub = Substitutions({self._self_type: ObjectType._hash_variable})1115        type_to_hash = sub(self)1116        return hash(1117            (1118                tuple(type_to_hash._attributes.items()),1119                tuple(type_to_hash._type_parameters),1120                tuple(type_to_hash._nominal_supertypes),1121                type_to_hash._nominal,1122                # FIXME: I get 'not hashable' errors about this.1123                # tuple(type_to_hash._type_arguments),1124                None if type_to_hash._head == self else type_to_hash._head,1125            )1126        )1127    def __getitem__(1128        self, type_arguments: Sequence[StackItemType]1129    ) -> 'ObjectType':1130        from concat.typecheck import Substitutions1131        if self._arity != len(type_arguments):1132            raise TypeError(1133                'type constructor {} given {} arguments, expected {} arguments'.format(1134                    self, len(type_arguments), self._arity1135                )1136            )1137        type_arguments = tuple(type_arguments)1138        if type_arguments in self._instantiations:1139            return self._instantiations[type_arguments]1140        sub = Substitutions(zip(self._type_parameters, type_arguments))1141        result = self.apply_substitution(1142            sub, _should_quantify_over_type_parameters=False1143        )1144        # HACK: We remove the parameters and add arguments through mutation.1145        result._type_parameters = ()1146        result._type_arguments = type_arguments1147        self._instantiations[type_arguments] = result1148        return result1149    def instantiate(self) -> 'ObjectType':1150        # Avoid overwriting the type arguments if type is already instantiated.1151        if self._arity == 0:1152            return self1153        fresh_variables = [type(a)() for a in self._type_parameters]1154        return self[fresh_variables]1155    @property1156    def attributes(self) -> Dict[str, IndividualType]:1157        return self._attributes1158    @property1159    def self_type(self) -> IndividualVariable:1160        return self._self_type1161    @property1162    def type_arguments(self) -> TypeArguments:1163        return self._type_arguments1164    @property1165    def head(self) -> 'ObjectType':1166        return self._head1167    @property1168    def type_parameters(self) -> Sequence[_Variable]:1169        return self._type_parameters1170    @property1171    def nominal_supertypes(self) -> Sequence[IndividualType]:1172        return self._nominal_supertypes1173    @property1174    def _arity(self) -> int:1175        return len(self._type_parameters)1176class ClassType(ObjectType):1177    """The representation of types of classes, like in "Design and Evaluation of Gradual Typing for Python" (Vitousek et al. 2014)."""1178    def is_subtype_of(self, supertype: Type) -> bool:1179        if (1180            not supertype.has_attribute('__call__')1181            or '__init__' not in self._attributes1182        ):1183            return super().is_subtype_of(supertype)1184        bound_init = self._attributes['__init__'].bind()1185        return bound_init <= supertype1186class PythonFunctionType(ObjectType):1187    def __init__(1188        self,1189        self_type: IndividualVariable,1190        *args,1191        _overloads: Sequence[1192            Tuple[Sequence[StackItemType], IndividualType]1193        ] = (),1194        type_parameters=(),1195        **kwargs,1196    ) -> None:1197        self._kwargs = kwargs.copy()1198        # HACK: I shouldn't have to manipulate arguments like this1199        if 'type_parameters' in self._kwargs:1200            del self._kwargs['type_parameters']1201        super().__init__(1202            self_type,1203            *args,1204            **self._kwargs,1205            _overloads=_overloads,1206            type_parameters=type_parameters,1207        )1208        assert (1209            self._arity == 01210            and len(self._type_arguments) == 21211            or self._arity == 21212            and len(self._type_arguments) == 01213        )1214        if self._arity == 0:1215            assert isinstance(self.input, collections.abc.Sequence)1216        self._args = list(args)1217        self._overloads = _overloads1218        if '_head' in self._kwargs:1219            del self._kwargs['_head']1220        self._head: PythonFunctionType1221    def __str__(self) -> str:1222        if not self._type_arguments:1223            return 'py_function_type'1224        return 'py_function_type[{}, {}]'.format(1225            _iterable_to_str(self.input), self.output1226        )1227    def get_type_of_attribute(self, attribute: str) -> IndividualType:1228        from concat.typecheck import Substitutions1229        sub = Substitutions({self._self_type: self})1230        if attribute == '__call__':1231            return self1232        else:1233            return super().get_type_of_attribute(attribute)1234    def __getitem__(1235        self, arguments: Tuple[TypeSequence, IndividualType]1236    ) -> 'PythonFunctionType':1237        assert self._arity == 21238        input = arguments[0]1239        output = arguments[1]1240        return PythonFunctionType(1241            self._self_type,1242            *self._args,1243            **{1244                **self._kwargs,1245                '_type_arguments': (input, output),1246                'type_parameters': (),1247            },1248            _overloads=[],1249            _head=self,1250        )1251    def apply_substitution(1252        self, sub: 'concat.typecheck.Substitutions'1253    ) -> 'PythonFunctionType':1254        if self._arity == 0:1255            type = py_function_type[1256                sub(TypeSequence(self.input)), sub(self.output)1257            ]1258            for overload in self._overloads:1259                # This is one of the few places where a type should be mutated.1260                type._add_overload(1261                    [sub(i) for i in overload[0]], sub(overload[1])1262                )1263            return type1264        return self1265    @property1266    def input(self) -> Sequence[StackItemType]:1267        assert self._arity == 01268        if isinstance(self._type_arguments[0], SequenceVariable):1269            return (self._type_arguments[0],)1270        assert not isinstance(self._type_arguments[0], IndividualType)1271        return tuple(self._type_arguments[0])1272    @property1273    def output(self) -> IndividualType:1274        assert self._arity == 01275        assert isinstance(self._type_arguments[1], IndividualType)1276        return self._type_arguments[1]1277    def select_overload(1278        self, input_types: Sequence[StackItemType]1279    ) -> Tuple['PythonFunctionType', 'Substitutions']:1280        for overload in [(self.input, self.output), *self._overloads]:1281            try:1282                sub = TypeSequence(1283                    input_types1284                ).constrain_and_bind_supertype_variables(1285                    TypeSequence(overload[0]), set()1286                )1287            except TypeError:1288                continue1289            return (1290                sub(py_function_type[TypeSequence(overload[0]), overload[1]]),1291                sub,1292            )1293        raise TypeError(1294            'no overload of {} matches types {}'.format(self, input_types)1295        )1296    def with_overload(1297        self, input: Sequence[StackItemType], output: IndividualType1298    ) -> 'PythonFunctionType':1299        return PythonFunctionType(1300            self._self_type,1301            *self._args,1302            **self._kwargs,1303            _overloads=[*self._overloads, (input, output)],1304            _head=py_function_type,1305        )1306    def _add_overload(1307        self, input: Sequence[StackItemType], output: IndividualType1308    ) -> None:1309        self._overloads.append((input, output))1310    def bind(self) -> 'PythonFunctionType':1311        assert self._arity == 01312        inputs = self.input[1:]1313        output = self.output1314        return self._head[TypeSequence(inputs), output]1315    def is_subtype_of(self, supertype: Type) -> bool:1316        if isinstance(supertype, PythonFunctionType):1317            # NOTE: make sure types are of same kind (arity)1318            if len(self._type_parameters) != len(supertype._type_parameters):1319                return False1320            if len(self._type_parameters) == 2:1321                # both are py_function_type1322                return True1323            assert isinstance(supertype._type_arguments[0], TypeSequence)1324            assert isinstance(self._type_arguments[1], IndividualType)1325            return (1326                supertype._type_arguments[0] <= self._type_arguments[0]1327                and self._type_arguments[1] <= supertype._type_arguments[1]1328            )1329        else:1330            return super().is_subtype_of(supertype)1331class _NoReturnType(ObjectType):1332    def __init__(self) -> None:1333        x = IndividualVariable()1334        super().__init__(x, {})1335    def is_subtype_of(self, _: Type) -> Literal[True]:1336        return True1337    def apply_substitution(1338        self, sub: 'concat.typecheck.Substitutions'1339    ) -> '_NoReturnType':1340        return self1341    def __repr__(self) -> str:1342        return '{}()'.format(type(self).__qualname__)1343class _OptionalType(ObjectType):1344    def __init__(self, _type_arguments=[]) -> None:1345        x = IndividualVariable()1346        type_var = IndividualVariable()1347        if len(_type_arguments) > 0:1348            super().__init__(x, {}, [], _type_arguments=_type_arguments)1349        else:1350            super().__init__(x, {}, [type_var])1351    def __getitem__(1352        self, type_arguments: Sequence[StackItemType]1353    ) -> '_OptionalType':1354        assert len(type_arguments) == 11355        return _OptionalType(type_arguments)1356    # def constrain(self, supertype, )1357    def apply_substitution(1358        self, sub: 'concat.typecheck.Substitutions'1359    ) -> '_OptionalType':1360        return _OptionalType(tuple(sub(TypeSequence(self._type_arguments))))1361def _iterable_to_str(iterable: Iterable) -> str:1362    return '[' + ', '.join(map(str, iterable)) + ']'1363def _mapping_to_str(mapping: Mapping) -> str:1364    return (1365        '{'1366        + ', '.join(1367            '{}: {}'.format(key, value) for key, value in mapping.items()1368        )1369        + '}'1370    )1371# expose _Function as StackEffect1372StackEffect = _Function1373_x = IndividualVariable()1374float_type = ObjectType(_x, {}, nominal=True)1375no_return_type = _NoReturnType()1376object_type = ObjectType(_x, {}, nominal=True)1377object_type.set_internal_name('object_type')1378_arg_type_var = SequenceVariable()1379_return_type_var = IndividualVariable()1380py_function_type = PythonFunctionType(1381    _x, {}, type_parameters=[_arg_type_var, _return_type_var]1382)1383py_function_type.set_internal_name('py_function_type')1384_invert_result_var = IndividualVariable()1385invertible_type = ObjectType(1386    _x,1387    {'__invert__': py_function_type[TypeSequence([]), _invert_result_var]},1388    [_invert_result_var],1389)1390_sub_operand_type = IndividualVariable()1391_sub_result_type = IndividualVariable()1392# FIXME: Add reverse_substractable_type for __rsub__1393subtractable_type = ObjectType(1394    _x,1395    {1396        '__sub__': py_function_type[1397            TypeSequence([_sub_operand_type]), _sub_result_type1398        ]1399    },1400    [_sub_operand_type, _sub_result_type],1401)1402bool_type = ObjectType(_x, {}, nominal=True)1403bool_type.set_internal_name('bool_type')1404_int_add_type = py_function_type[TypeSequence([object_type]), _x]1405int_type = ObjectType(1406    _x,1407    {1408        '__add__': _int_add_type,1409        '__invert__': py_function_type[TypeSequence([]), _x],1410        '__sub__': _int_add_type,1411        '__invert__': py_function_type[TypeSequence([]), _x],1412        '__le__': py_function_type[TypeSequence([_x]), bool_type],1413    },1414    nominal=True,1415)1416int_type.set_internal_name('int_type')1417# FIXME: Use an iterator interface instead of _x1418_result_type = IndividualVariable()1419iterable_type = ObjectType(1420    _x, {'__iter__': py_function_type[TypeSequence([]), _x]}, [_result_type]1421)1422iterable_type.set_internal_name('iterable_type')1423context_manager_type = ObjectType(1424    _x,1425    {1426        # TODO: Add argument and return types. I think I'll need a special1427        # py_function representation for that.1428        '__enter__': py_function_type,1429        '__exit__': py_function_type,1430    },1431)1432context_manager_type.set_internal_name('context_manager_type')1433optional_type = _OptionalType()1434optional_type.set_internal_name('optional_type')1435none_type = ObjectType(_x, {})1436none_type.set_internal_name('none_type')1437dict_type = ObjectType(1438    _x, {'__iter__': py_function_type[TypeSequence([]), object_type]}1439)1440dict_type.set_internal_name('dict_type')1441file_type = ObjectType(1442    _x,1443    {1444        'seek': py_function_type[TypeSequence([int_type]), int_type],1445        'read': py_function_type,1446        '__enter__': py_function_type,1447        '__exit__': py_function_type,1448    },1449    [],1450    # context_manager_type is a structural supertype1451    [iterable_type],1452    nominal=True,1453)1454file_type.set_internal_name('file_type')1455_start_type_var, _stop_type_var, _step_type_var = (1456    IndividualVariable(),1457    IndividualVariable(),1458    IndividualVariable(),1459)1460slice_type = ObjectType(1461    _x, {}, [_start_type_var, _stop_type_var, _step_type_var], nominal=True1462)1463slice_type.set_internal_name('slice_type')1464_element_type_var = IndividualVariable()1465_list_getitem_type = py_function_type[1466    TypeSequence([int_type]), _element_type_var1467].with_overload((slice_type[(optional_type[int_type,],) * 3],), _x)1468list_type = ObjectType(1469    _x,1470    {1471        '__getitem__': _list_getitem_type,1472        # FIXME: __iter__ should return an iterator.1473        '__iter__': py_function_type[TypeSequence([]), object_type],1474    },1475    [_element_type_var],1476    nominal=True,1477)1478list_type.set_internal_name('list_type')1479_str_getitem_type = py_function_type[1480    TypeSequence([int_type]), _x1481].with_overload(1482    [1483        slice_type[1484            optional_type[int_type,],1485            optional_type[int_type,],1486            optional_type[int_type,],1487        ]1488    ],1489    _x,1490)1491str_type = ObjectType(1492    _x,1493    {1494        '__getitem__': _str_getitem_type,1495        '__add__': py_function_type[TypeSequence([object_type]), _x],1496        'find': py_function_type[1497            TypeSequence(1498                [_x, optional_type[int_type,], optional_type[int_type,]]1499            ),1500            int_type,1501        ],1502    },1503    nominal=True,1504)1505str_type.set_internal_name('str_type')1506ellipsis_type = ObjectType(_x, {})1507not_implemented_type = ObjectType(_x, {})1508tuple_type = ObjectType(1509    _x,1510    {'__getitem__': py_function_type}1511    # iterable_type is a structural supertype1512)1513tuple_type.set_internal_name('tuple_type')1514base_exception_type = ObjectType(_x, {})1515module_type = ObjectType(_x, {})1516_index_type_var = IndividualVariable()1517_result_type_var = IndividualVariable()1518subscriptable_type = ObjectType(1519    IndividualVariable(),1520    {1521        '__getitem__': py_function_type[1522            TypeSequence([_index_type_var]), _result_type_var1523        ],1524    },1525    [_index_type_var, _result_type_var],...Sequence.py
Source:Sequence.py  
1class Sequence(object):2    def __init__(self):3        self.IdSpeaker = ''4        self.IdSession = ''5        self.device = ''6        self.typeSequence = ''7        #self.digits = '';8        self.digitsById = []910    def __init__(self, speakerId, sessionId,device, typeSequence,digitsByID):11        self.IdSpeaker = speakerId12        self.IdSession = sessionId13        self.device = device14        self.typeSequence = typeSequence15        #self.digits = digits;16        self.digitsById = digitsByID171819if __name__ == "__main__":
...__init__.py
Source:__init__.py  
1from ._family import TypeFamily2from .mapping import TypeMapping3from .sequence import TypeSequence4__all__ = [5    "TypeFamily",6    "TypeSequence",7    "TypeMapping",...Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
