from typing import Dict, Iterable, List, Mapping, Optional from .functions import ( Constraint_TypeClassInstanceExists, ConstraintBase, FunctionSignature, TypeConstructorVariable, TypeVariable, TypeVariableContext, ) from .types import Type3 class Type3ClassMethod: __slots__ = ('name', 'signature', ) name: str signature: FunctionSignature def __init__(self, name: str, signature: FunctionSignature) -> None: self.name = name self.signature = signature def __str__(self) -> str: return f'{self.name} :: {self.signature}' def __repr__(self) -> str: return f'Type3ClassMethod({repr(self.name)}, {repr(self.signature)})' Type3ClassArgs = tuple[TypeVariable] | tuple[TypeVariable, TypeVariable] | tuple[TypeConstructorVariable] class Type3Class: __slots__ = ('name', 'args', 'methods', 'operators', 'inherited_classes', ) name: str args: Type3ClassArgs methods: Dict[str, Type3ClassMethod] operators: Dict[str, Type3ClassMethod] inherited_classes: List['Type3Class'] def __init__( self, name: str, args: Type3ClassArgs, methods: Mapping[str, Iterable[Type3 | TypeVariable | list[Type3 | TypeVariable]]], operators: Mapping[str, Iterable[Type3 | TypeVariable | list[Type3 | TypeVariable]]], inherited_classes: Optional[List['Type3Class']] = None, additional_context: Optional[Mapping[str, Iterable[ConstraintBase]]] = None, ) -> None: self.name = name self.args = args self.methods = { k: Type3ClassMethod(k, _create_signature(v, self)) for k, v in methods.items() } self.operators = { k: Type3ClassMethod(k, _create_signature(v, self)) for k, v in operators.items() } self.inherited_classes = inherited_classes or [] if additional_context: for func_name, constraint_list in additional_context.items(): func = self.methods.get(func_name) or self.operators.get(func_name) assert func is not None # type hint func.signature.context.constraints.extend(constraint_list) def __repr__(self) -> str: return self.name def _create_signature( method_arg_list: Iterable[Type3 | TypeVariable | list[Type3 | TypeVariable]], type_class3: Type3Class, ) -> FunctionSignature: context = TypeVariableContext() if not isinstance(type_class3.args[0], TypeConstructorVariable): context.constraints.append(Constraint_TypeClassInstanceExists(type_class3, type_class3.args)) signature_args: list[Type3 | TypeVariable | list[Type3 | TypeVariable]] = [] for method_arg in method_arg_list: if isinstance(method_arg, Type3): signature_args.append(method_arg) continue if isinstance(method_arg, list): signature_args.append(method_arg) continue if isinstance(method_arg, TypeVariable): type_constructor = method_arg.application.constructor if type_constructor is None: signature_args.append(method_arg) continue if (type_constructor, ) == type_class3.args: context.constraints.append(Constraint_TypeClassInstanceExists(type_class3, [method_arg])) signature_args.append(method_arg) continue raise NotImplementedError(method_arg) return FunctionSignature(context, signature_args)