2020from itertools import zip_longest
2121from typing import TYPE_CHECKING , Any , TypeVar , Union , cast , get_args , get_origin
2222
23+ from typing_extensions import assert_never
24+
2325from .declarations import *
2426from .pretty import *
2527from .thunk import Thunk
3638 "RuntimeClass" ,
3739 "RuntimeExpr" ,
3840 "RuntimeFunction" ,
41+ "create_callable" ,
3942 "define_expr_method" ,
4043 "resolve_callable" ,
4144 "resolve_type_annotation" ,
@@ -340,7 +343,7 @@ def __repr__(self) -> str:
340343
341344 # Make hashable so can go in Union
342345 def __hash__ (self ) -> int :
343- return hash (( id ( self .__egg_decls_thunk__ ), self . __egg_tp__ ) )
346+ return hash (self .__egg_tp__ )
344347
345348 def __eq__ (self , other : object ) -> bool :
346349 """
@@ -478,6 +481,9 @@ def __str__(self) -> str:
478481 bound_tp_params = args
479482 return pretty_callable_ref (self .__egg_decls__ , self .__egg_ref__ , first_arg , bound_tp_params )
480483
484+ def __repr__ (self ) -> str :
485+ return str (self )
486+
481487
482488def to_py_signature (sig : FunctionSignature , decls : Declarations , optional_args : bool ) -> Signature :
483489 """
@@ -670,11 +676,12 @@ def resolve_callable(callable: object) -> tuple[CallableRef, Declarations]:
670676 """
671677 Resolves a runtime callable into a ref
672678 """
679+ # TODO: Make runtime class work with __match_args__
680+ if isinstance (callable , RuntimeClass ):
681+ return InitRef (callable .__egg_tp__ .name ), callable .__egg_decls__
673682 match callable :
674683 case RuntimeFunction (decls , ref , _):
675684 return ref (), decls ()
676- case RuntimeClass (thunk , tp ):
677- return InitRef (tp .name ), thunk ()
678685 case RuntimeExpr (decl_thunk , expr_thunk ):
679686 if not isinstance ((expr := expr_thunk ().expr ), CallDecl ) or not isinstance (
680687 expr .callable , ConstantRef | ClassVariableRef
@@ -683,3 +690,23 @@ def resolve_callable(callable: object) -> tuple[CallableRef, Declarations]:
683690 return expr .callable , decl_thunk ()
684691 case _:
685692 raise NotImplementedError (f"Cannot turn { callable } of type { type (callable )} into a callable ref" )
693+
694+
695+ def create_callable (decls : Declarations , ref : CallableRef ) -> RuntimeClass | RuntimeFunction | RuntimeExpr :
696+ """
697+ Creates a callable object from a callable ref. This might not actually be callable, if the ref is a constant
698+ or classvar then it is a value
699+ """
700+ match ref :
701+ case InitRef (name ):
702+ return RuntimeClass (Thunk .value (decls ), TypeRefWithVars (name ))
703+ case FunctionRef () | MethodRef () | ClassMethodRef () | PropertyRef () | UnnamedFunctionRef ():
704+ bound = JustTypeRef (ref .class_name ) if isinstance (ref , ClassMethodRef ) else None
705+ return RuntimeFunction (Thunk .value (decls ), Thunk .value (ref ), bound )
706+ case ConstantRef (name ):
707+ tp = decls ._constants [name ].type_ref
708+ case ClassVariableRef (cls_name , var_name ):
709+ tp = decls ._classes [cls_name ].class_variables [var_name ].type_ref
710+ case _:
711+ assert_never (ref )
712+ return RuntimeExpr .__from_values__ (decls , TypedExprDecl (tp , CallDecl (ref )))
0 commit comments