|
10 | 10 | TYPE_CHECKING,
|
11 | 11 | Any,
|
12 | 12 | Callable,
|
| 13 | + Dict, |
| 14 | + Generic, |
| 15 | + List, |
13 | 16 | Optional,
|
| 17 | + Set, |
| 18 | + Tuple, |
14 | 19 | Type,
|
15 | 20 | TypeVar,
|
| 21 | + Union, |
16 | 22 | overload,
|
17 | 23 | )
|
18 | 24 |
|
|
42 | 48 | from .object import ObjectVar, ToObjectOperation
|
43 | 49 | from .sequence import ArrayVar, StringVar, ToArrayOperation, ToStringOperation
|
44 | 50 |
|
| 51 | +VAR_TYPE = TypeVar("VAR_TYPE") |
| 52 | + |
45 | 53 |
|
46 | 54 | @dataclasses.dataclass(
|
47 | 55 | eq=False,
|
48 | 56 | frozen=True,
|
49 | 57 | **{"slots": True} if sys.version_info >= (3, 10) else {},
|
50 | 58 | )
|
51 |
| -class ImmutableVar(Var): |
| 59 | +class ImmutableVar(Var, Generic[VAR_TYPE]): |
52 | 60 | """Base class for immutable vars."""
|
53 | 61 |
|
54 | 62 | # The name of the var.
|
@@ -405,6 +413,8 @@ def guess_type(self) -> ImmutableVar:
|
405 | 413 | return self.to(ArrayVar, var_type)
|
406 | 414 | if issubclass(fixed_type, str):
|
407 | 415 | return self.to(StringVar)
|
| 416 | + if issubclass(fixed_type, Base): |
| 417 | + return self.to(ObjectVar, var_type) |
408 | 418 | return self
|
409 | 419 |
|
410 | 420 |
|
@@ -531,3 +541,43 @@ def wrapper(*args: P.args, **kwargs: P.kwargs) -> T:
|
531 | 541 | return wrapper
|
532 | 542 |
|
533 | 543 | return decorator
|
| 544 | + |
| 545 | + |
| 546 | +def unionize(*args: Type) -> Type: |
| 547 | + """Unionize the types. |
| 548 | +
|
| 549 | + Args: |
| 550 | + args: The types to unionize. |
| 551 | +
|
| 552 | + Returns: |
| 553 | + The unionized types. |
| 554 | + """ |
| 555 | + if not args: |
| 556 | + return Any |
| 557 | + first, *rest = args |
| 558 | + if not rest: |
| 559 | + return first |
| 560 | + return Union[first, unionize(*rest)] |
| 561 | + |
| 562 | + |
| 563 | +def figure_out_type(value: Any) -> Type: |
| 564 | + """Figure out the type of the value. |
| 565 | +
|
| 566 | + Args: |
| 567 | + value: The value to figure out the type of. |
| 568 | +
|
| 569 | + Returns: |
| 570 | + The type of the value. |
| 571 | + """ |
| 572 | + if isinstance(value, list): |
| 573 | + return List[unionize(*(figure_out_type(v) for v in value))] |
| 574 | + if isinstance(value, set): |
| 575 | + return Set[unionize(*(figure_out_type(v) for v in value))] |
| 576 | + if isinstance(value, tuple): |
| 577 | + return Tuple[unionize(*(figure_out_type(v) for v in value)), ...] |
| 578 | + if isinstance(value, dict): |
| 579 | + return Dict[ |
| 580 | + unionize(*(figure_out_type(k) for k in value)), |
| 581 | + unionize(*(figure_out_type(v) for v in value.values())), |
| 582 | + ] |
| 583 | + return type(value) |
0 commit comments