|
14 | 14 | TypeVar, |
15 | 15 | ) |
16 | 16 | from typing_extensions import Self |
17 | | - |
| 17 | +import weakref |
18 | 18 |
|
19 | 19 | from gel._internal import _qb |
20 | 20 | from gel._internal._schemapath import ( |
@@ -300,13 +300,30 @@ def combine_dicts( |
300 | 300 | return result |
301 | 301 |
|
302 | 302 |
|
303 | | -# TODO: We should cache the results of this |
| 303 | +_type_intersection_cache: weakref.WeakKeyDictionary[ |
| 304 | + type[AbstractGelModel], |
| 305 | + weakref.WeakKeyDictionary[ |
| 306 | + type[AbstractGelModel], |
| 307 | + type[ |
| 308 | + BaseGelModelIntersection[ |
| 309 | + type[AbstractGelModel], type[AbstractGelModel] |
| 310 | + ] |
| 311 | + ], |
| 312 | + ], |
| 313 | +] = weakref.WeakKeyDictionary() |
| 314 | + |
| 315 | + |
304 | 316 | def create_intersection( |
305 | 317 | lhs: _T_Lhs, |
306 | 318 | rhs: _T_Rhs, |
307 | 319 | ) -> type[BaseGelModelIntersection[_T_Lhs, _T_Rhs]]: |
308 | 320 | """Create a runtime intersection type which acts like a GelModel.""" |
309 | 321 |
|
| 322 | + if (lhs_entry := _type_intersection_cache.get(lhs)) and ( |
| 323 | + rhs_entry := lhs_entry.get(rhs) |
| 324 | + ): |
| 325 | + return rhs_entry # type: ignore[return-value] |
| 326 | + |
310 | 327 | # Combine pointer reflections from args |
311 | 328 | ptr_reflections: dict[str, _qb.GelPointerReflection] = combine_dicts( |
312 | 329 | lhs.__gel_reflection__.pointers, |
@@ -403,4 +420,8 @@ def process_path_alias( |
403 | 420 | for p_name, path_alias in path_aliases.items(): |
404 | 421 | setattr(result, p_name, path_alias) |
405 | 422 |
|
| 423 | + if lhs not in _type_intersection_cache: |
| 424 | + _type_intersection_cache[lhs] = weakref.WeakKeyDictionary() |
| 425 | + _type_intersection_cache[lhs][rhs] = result |
| 426 | + |
406 | 427 | return result |
0 commit comments