|
15 | 15 |
|
16 | 16 | from .egraph import Expr |
17 | 17 |
|
18 | | -__all__ = ["convert", "converter", "resolve_literal", "convert_to_same_type"] |
| 18 | +__all__ = ["convert", "convert_to_same_type", "converter", "resolve_literal"] |
19 | 19 | # Mapping from (source type, target type) to and function which takes in the runtimes values of the source and return the target |
20 | 20 | TypeName = NewType("TypeName", str) |
21 | 21 | CONVERSIONS: dict[tuple[type | TypeName, TypeName], tuple[int, Callable]] = {} |
22 | 22 | # Global declerations to store all convertable types so we can query if they have certain methods or not |
23 | | -# Defer it as a thunk so we can register conversions without triggering type signature loading |
24 | | -CONVERSIONS_DECLS: Callable[[], Declarations] = Thunk.value(Declarations()) |
| 23 | +_CONVERSION_DECLS = Declarations.create() |
| 24 | +# Defer a list of declerations to be added to the global declerations, so that we can not trigger them procesing |
| 25 | +# until we need them |
| 26 | +_TO_PROCESS_DECLS: list[DeclerationsLike] = [] |
| 27 | + |
| 28 | + |
| 29 | +def _retrieve_conversion_decls() -> Declarations: |
| 30 | + _CONVERSION_DECLS.update(*_TO_PROCESS_DECLS) |
| 31 | + _TO_PROCESS_DECLS.clear() |
| 32 | + return _CONVERSION_DECLS |
| 33 | + |
25 | 34 |
|
26 | 35 | T = TypeVar("T") |
27 | 36 | V = TypeVar("V", bound="Expr") |
@@ -100,25 +109,20 @@ def process_tp(tp: type | RuntimeClass) -> TypeName | type: |
100 | 109 | """ |
101 | 110 | Process a type before converting it, to add it to the global declerations and resolve to a ref. |
102 | 111 | """ |
103 | | - global CONVERSIONS_DECLS |
104 | 112 | if isinstance(tp, RuntimeClass): |
105 | | - CONVERSIONS_DECLS = Thunk.fn(_combine_decls, CONVERSIONS_DECLS, tp) |
| 113 | + _TO_PROCESS_DECLS.append(tp) |
106 | 114 | egg_tp = tp.__egg_tp__ |
107 | 115 | if egg_tp.args: |
108 | 116 | raise TypeError(f"Cannot register a converter for a generic type, got {tp}") |
109 | 117 | return TypeName(egg_tp.name) |
110 | 118 | return tp |
111 | 119 |
|
112 | 120 |
|
113 | | -def _combine_decls(d: Callable[[], Declarations], x: HasDeclerations) -> Declarations: |
114 | | - return Declarations.create(d(), x) |
115 | | - |
116 | | - |
117 | 121 | def min_convertable_tp(a: object, b: object, name: str) -> TypeName: |
118 | 122 | """ |
119 | 123 | Returns the minimum convertable type between a and b, that has a method `name`, raising a ConvertError if no such type exists. |
120 | 124 | """ |
121 | | - decls = CONVERSIONS_DECLS() |
| 125 | + decls = _retrieve_conversion_decls() |
122 | 126 | a_tp = _get_tp(a) |
123 | 127 | b_tp = _get_tp(b) |
124 | 128 | a_converts_to = { |
@@ -161,7 +165,7 @@ def with_type_args(args: tuple[JustTypeRef, ...], decls: Callable[[], Declaratio |
161 | 165 |
|
162 | 166 |
|
163 | 167 | def resolve_literal( |
164 | | - tp: TypeOrVarRef, arg: object, decls: Callable[[], Declarations] = CONVERSIONS_DECLS |
| 168 | + tp: TypeOrVarRef, arg: object, decls: Callable[[], Declarations] = _retrieve_conversion_decls |
165 | 169 | ) -> RuntimeExpr: |
166 | 170 | arg_type = _get_tp(arg) |
167 | 171 |
|
|
0 commit comments